first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
@@ -0,0 +1,5 @@
import * as React from 'react';
import type { IBeakProps } from './Beak.types';
export declare const BEAK_HEIGHT = 10;
export declare const BEAK_WIDTH = 18;
export declare const Beak: React.FunctionComponent<IBeakProps>;
@@ -0,0 +1,69 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Beak = exports.BEAK_WIDTH = exports.BEAK_HEIGHT = void 0;
var React = require("react");
var Utilities_1 = require("../../../Utilities");
var Beak_styles_1 = require("./Beak.styles");
var Positioning_1 = require("../../../Positioning");
exports.BEAK_HEIGHT = 10;
exports.BEAK_WIDTH = 18;
exports.Beak = React.forwardRef(function (props, forwardedRef) {
var left = props.left, top = props.top, bottom = props.bottom, right = props.right, color = props.color, _a = props.direction, direction = _a === void 0 ? Positioning_1.RectangleEdge.top : _a;
var svgHeight;
var svgWidth;
if (direction === Positioning_1.RectangleEdge.top || direction === Positioning_1.RectangleEdge.bottom) {
svgHeight = exports.BEAK_HEIGHT;
svgWidth = exports.BEAK_WIDTH;
}
else {
svgHeight = exports.BEAK_WIDTH;
svgWidth = exports.BEAK_HEIGHT;
}
var pointOne;
var pointTwo;
var pointThree;
var transform;
switch (direction) {
case Positioning_1.RectangleEdge.top:
case Positioning_1.RectangleEdge.right:
pointOne = "0, 0";
pointTwo = "".concat(exports.BEAK_HEIGHT, ", ").concat(exports.BEAK_HEIGHT);
pointThree = "0, ".concat(exports.BEAK_WIDTH);
transform = 'translateX(100%)';
break;
case Positioning_1.RectangleEdge.bottom:
pointOne = "0, 0";
pointTwo = "".concat(exports.BEAK_WIDTH, ", 0");
pointThree = "".concat(exports.BEAK_WIDTH / 2, ", ").concat(exports.BEAK_HEIGHT);
transform = 'translateY(100%)';
break;
case Positioning_1.RectangleEdge.left:
pointOne = "".concat(exports.BEAK_HEIGHT, ", 0");
pointTwo = "0, ".concat(exports.BEAK_HEIGHT);
pointThree = "".concat(exports.BEAK_HEIGHT, ", ").concat(exports.BEAK_WIDTH);
transform = 'translateX(-100%)';
break;
default:
pointOne = "".concat(exports.BEAK_WIDTH / 2, ", 0");
pointTwo = "".concat(exports.BEAK_WIDTH, ", ").concat(exports.BEAK_HEIGHT);
pointThree = "0, ".concat(exports.BEAK_HEIGHT);
transform = 'translateY(-100%)';
break;
}
var getClassNames = (0, Utilities_1.classNamesFunction)();
var classNames = getClassNames(Beak_styles_1.getStyles, {
left: left,
top: top,
bottom: bottom,
right: right,
height: "".concat(svgHeight, "px"),
width: "".concat(svgWidth, "px"),
transform: transform,
color: color,
});
return (React.createElement("div", { className: classNames.root, role: "presentation", ref: forwardedRef },
React.createElement("svg", { height: svgHeight, width: svgWidth, className: classNames.beak },
React.createElement("polygon", { points: pointOne + ' ' + pointTwo + ' ' + pointThree }))));
});
exports.Beak.displayName = 'Beak';
//# sourceMappingURL=Beak.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Beak.js","sourceRoot":"../src/","sources":["components/Coachmark/Beak/Beak.tsx"],"names":[],"mappings":";;;AAAA,6BAA+B;AAC/B,gDAAwD;AACxD,6CAA0C;AAC1C,oDAAqD;AAIxC,QAAA,WAAW,GAAG,EAAE,CAAC;AACjB,QAAA,UAAU,GAAG,EAAE,CAAC;AAEhB,QAAA,IAAI,GAAwC,KAAK,CAAC,UAAU,CACvE,UAAC,KAAK,EAAE,YAAY;IACV,IAAA,IAAI,GAA+D,KAAK,KAApE,EAAE,GAAG,GAA0D,KAAK,IAA/D,EAAE,MAAM,GAAkD,KAAK,OAAvD,EAAE,KAAK,GAA2C,KAAK,MAAhD,EAAE,KAAK,GAAoC,KAAK,MAAzC,EAAE,KAAkC,KAAK,UAAV,EAA7B,SAAS,mBAAG,2BAAa,CAAC,GAAG,KAAA,CAAW;IAEjF,IAAI,SAAiB,CAAC;IACtB,IAAI,QAAgB,CAAC;IAErB,IAAI,SAAS,KAAK,2BAAa,CAAC,GAAG,IAAI,SAAS,KAAK,2BAAa,CAAC,MAAM,EAAE,CAAC;QAC1E,SAAS,GAAG,mBAAW,CAAC;QACxB,QAAQ,GAAG,kBAAU,CAAC;IACxB,CAAC;SAAM,CAAC;QACN,SAAS,GAAG,kBAAU,CAAC;QACvB,QAAQ,GAAG,mBAAW,CAAC;IACzB,CAAC;IAED,IAAI,QAAgB,CAAC;IACrB,IAAI,QAAgB,CAAC;IACrB,IAAI,UAAkB,CAAC;IACvB,IAAI,SAAiB,CAAC;IAEtB,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,2BAAa,CAAC,GAAG,CAAC;QACvB,KAAK,2BAAa,CAAC,KAAK;YACtB,QAAQ,GAAG,MAAM,CAAC;YAClB,QAAQ,GAAG,UAAG,mBAAW,eAAK,mBAAW,CAAE,CAAC;YAC5C,UAAU,GAAG,aAAM,kBAAU,CAAE,CAAC;YAChC,SAAS,GAAG,kBAAkB,CAAC;YAC/B,MAAM;QACR,KAAK,2BAAa,CAAC,MAAM;YACvB,QAAQ,GAAG,MAAM,CAAC;YAClB,QAAQ,GAAG,UAAG,kBAAU,QAAK,CAAC;YAC9B,UAAU,GAAG,UAAG,kBAAU,GAAG,CAAC,eAAK,mBAAW,CAAE,CAAC;YACjD,SAAS,GAAG,kBAAkB,CAAC;YAC/B,MAAM;QACR,KAAK,2BAAa,CAAC,IAAI;YACrB,QAAQ,GAAG,UAAG,mBAAW,QAAK,CAAC;YAC/B,QAAQ,GAAG,aAAM,mBAAW,CAAE,CAAC;YAC/B,UAAU,GAAG,UAAG,mBAAW,eAAK,kBAAU,CAAE,CAAC;YAC7C,SAAS,GAAG,mBAAmB,CAAC;YAChC,MAAM;QACR;YACE,QAAQ,GAAG,UAAG,kBAAU,GAAG,CAAC,QAAK,CAAC;YAClC,QAAQ,GAAG,UAAG,kBAAU,eAAK,mBAAW,CAAE,CAAC;YAC3C,UAAU,GAAG,aAAM,mBAAW,CAAE,CAAC;YACjC,SAAS,GAAG,mBAAmB,CAAC;YAChC,MAAM;IACV,CAAC;IAED,IAAM,aAAa,GAAG,IAAA,8BAAkB,GAAiC,CAAC;IAC1E,IAAM,UAAU,GAAG,aAAa,CAAC,uBAAS,EAAE;QAC1C,IAAI,MAAA;QACJ,GAAG,KAAA;QACH,MAAM,QAAA;QACN,KAAK,OAAA;QACL,MAAM,EAAE,UAAG,SAAS,OAAI;QACxB,KAAK,EAAE,UAAG,QAAQ,OAAI;QACtB,SAAS,WAAA;QACT,KAAK,OAAA;KACN,CAAC,CAAC;IAEH,OAAO,CACL,6BAAK,SAAS,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,EAAC,cAAc,EAAC,GAAG,EAAE,YAAY;QACpE,6BAAK,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,IAAI;YACjE,iCAAS,MAAM,EAAE,QAAQ,GAAG,GAAG,GAAG,QAAQ,GAAG,GAAG,GAAG,UAAU,GAAI,CAC7D,CACF,CACP,CAAC;AACJ,CAAC,CACF,CAAC;AACF,YAAI,CAAC,WAAW,GAAG,MAAM,CAAC","sourcesContent":["import * as React from 'react';\nimport { classNamesFunction } from '../../../Utilities';\nimport { getStyles } from './Beak.styles';\nimport { RectangleEdge } from '../../../Positioning';\nimport type { IBeakProps, IBeakStylesProps } from './Beak.types';\nimport type { IBeakStyles } from './Beak.styles';\n\nexport const BEAK_HEIGHT = 10;\nexport const BEAK_WIDTH = 18;\n\nexport const Beak: React.FunctionComponent<IBeakProps> = React.forwardRef<HTMLDivElement, IBeakProps>(\n (props, forwardedRef) => {\n const { left, top, bottom, right, color, direction = RectangleEdge.top } = props;\n\n let svgHeight: number;\n let svgWidth: number;\n\n if (direction === RectangleEdge.top || direction === RectangleEdge.bottom) {\n svgHeight = BEAK_HEIGHT;\n svgWidth = BEAK_WIDTH;\n } else {\n svgHeight = BEAK_WIDTH;\n svgWidth = BEAK_HEIGHT;\n }\n\n let pointOne: string;\n let pointTwo: string;\n let pointThree: string;\n let transform: string;\n\n switch (direction) {\n case RectangleEdge.top:\n case RectangleEdge.right:\n pointOne = `0, 0`;\n pointTwo = `${BEAK_HEIGHT}, ${BEAK_HEIGHT}`;\n pointThree = `0, ${BEAK_WIDTH}`;\n transform = 'translateX(100%)';\n break;\n case RectangleEdge.bottom:\n pointOne = `0, 0`;\n pointTwo = `${BEAK_WIDTH}, 0`;\n pointThree = `${BEAK_WIDTH / 2}, ${BEAK_HEIGHT}`;\n transform = 'translateY(100%)';\n break;\n case RectangleEdge.left:\n pointOne = `${BEAK_HEIGHT}, 0`;\n pointTwo = `0, ${BEAK_HEIGHT}`;\n pointThree = `${BEAK_HEIGHT}, ${BEAK_WIDTH}`;\n transform = 'translateX(-100%)';\n break;\n default:\n pointOne = `${BEAK_WIDTH / 2}, 0`;\n pointTwo = `${BEAK_WIDTH}, ${BEAK_HEIGHT}`;\n pointThree = `0, ${BEAK_HEIGHT}`;\n transform = 'translateY(-100%)';\n break;\n }\n\n const getClassNames = classNamesFunction<IBeakStylesProps, IBeakStyles>();\n const classNames = getClassNames(getStyles, {\n left,\n top,\n bottom,\n right,\n height: `${svgHeight}px`,\n width: `${svgWidth}px`,\n transform,\n color,\n });\n\n return (\n <div className={classNames.root} role=\"presentation\" ref={forwardedRef}>\n <svg height={svgHeight} width={svgWidth} className={classNames.beak}>\n <polygon points={pointOne + ' ' + pointTwo + ' ' + pointThree} />\n </svg>\n </div>\n );\n },\n);\nBeak.displayName = 'Beak';\n"]}
@@ -0,0 +1,10 @@
import type { IStyle } from '../../../Styling';
import type { IBeakStylesProps } from './Beak.types';
export interface IBeakStyles {
/**
* Style for the root element in the default enabled/unchecked state.
*/
root?: IStyle;
beak?: IStyle;
}
export declare function getStyles(props: IBeakStylesProps): IBeakStyles;
@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStyles = getStyles;
var Styling_1 = require("../../../Styling");
function getStyles(props) {
var _a;
return {
root: [
{
position: 'absolute',
boxShadow: 'inherit',
border: 'none',
boxSizing: 'border-box',
transform: props.transform,
width: props.width,
height: props.height,
left: props.left,
top: props.top,
right: props.right,
bottom: props.bottom,
},
],
beak: {
fill: props.color,
display: 'block',
selectors: (_a = {},
_a[Styling_1.HighContrastSelector] = {
fill: 'windowtext',
},
_a),
},
};
}
//# sourceMappingURL=Beak.styles.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Beak.styles.js","sourceRoot":"../src/","sources":["components/Coachmark/Beak/Beak.styles.ts"],"names":[],"mappings":";;AAYA,8BA2BC;AAvCD,4CAAwD;AAYxD,SAAgB,SAAS,CAAC,KAAuB;;IAC/C,OAAO;QACL,IAAI,EAAE;YACJ;gBACE,QAAQ,EAAE,UAAU;gBACpB,SAAS,EAAE,SAAS;gBACpB,MAAM,EAAE,MAAM;gBACd,SAAS,EAAE,YAAY;gBACvB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,MAAM,EAAE,KAAK,CAAC,MAAM;aACrB;SACF;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,KAAK,CAAC,KAAK;YACjB,OAAO,EAAE,OAAO;YAChB,SAAS;gBACP,GAAC,8BAAoB,IAAG;oBACtB,IAAI,EAAE,YAAY;iBACnB;mBACF;SACF;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { HighContrastSelector } from '../../../Styling';\nimport type { IStyle } from '../../../Styling';\nimport type { IBeakStylesProps } from './Beak.types';\n\nexport interface IBeakStyles {\n /**\n * Style for the root element in the default enabled/unchecked state.\n */\n root?: IStyle;\n beak?: IStyle;\n}\n\nexport function getStyles(props: IBeakStylesProps): IBeakStyles {\n return {\n root: [\n {\n position: 'absolute',\n boxShadow: 'inherit',\n border: 'none',\n boxSizing: 'border-box',\n transform: props.transform,\n width: props.width,\n height: props.height,\n left: props.left,\n top: props.top,\n right: props.right,\n bottom: props.bottom,\n },\n ],\n beak: {\n fill: props.color,\n display: 'block',\n selectors: {\n [HighContrastSelector]: {\n fill: 'windowtext',\n },\n },\n },\n };\n}\n"]}
@@ -0,0 +1,46 @@
import * as React from 'react';
import { RectangleEdge } from '../../../Positioning';
export interface IBeakProps extends React.RefAttributes<HTMLDivElement> {
/**
* @deprecated Not used.
*/
width?: number;
/**
* @deprecated Not used.
*/
height?: number;
/**
* Color of the beak
*/
color?: string;
/**
* Left position of the beak
*/
left?: string;
/**
* Top position of the beak
*/
top?: string;
/**
* Right position of the beak
*/
right?: string;
/**
* Bottom position of the beak
*/
bottom?: string;
/**
* Direction of beak
*/
direction?: RectangleEdge;
}
export interface IBeakStylesProps {
left?: string | undefined;
top?: string | undefined;
bottom?: string | undefined;
right?: string | undefined;
width?: string;
height?: string;
transform?: string;
color?: string;
}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=Beak.types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Beak.types.js","sourceRoot":"../src/","sources":["components/Coachmark/Beak/Beak.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { RectangleEdge } from '../../../Positioning';\n\nexport interface IBeakProps extends React.RefAttributes<HTMLDivElement> {\n /**\n * @deprecated Not used.\n */\n width?: number;\n\n /**\n * @deprecated Not used.\n */\n height?: number;\n\n /**\n * Color of the beak\n */\n color?: string;\n\n /**\n * Left position of the beak\n */\n left?: string;\n\n /**\n * Top position of the beak\n */\n top?: string;\n\n /**\n * Right position of the beak\n */\n right?: string;\n\n /**\n * Bottom position of the beak\n */\n bottom?: string;\n\n /**\n * Direction of beak\n */\n direction?: RectangleEdge;\n}\n\nexport interface IBeakStylesProps {\n left?: string | undefined;\n top?: string | undefined;\n bottom?: string | undefined;\n right?: string | undefined;\n width?: string;\n height?: string;\n transform?: string;\n color?: string;\n}\n"]}
@@ -0,0 +1,11 @@
import * as React from 'react';
import type { ICoachmarkProps } from './Coachmark.types';
export declare const COACHMARK_ATTRIBUTE_NAME = "data-coachmarkid";
/**
* An interface for the cached dimensions of entity inner host.
*/
export interface IEntityRect {
width?: number;
height?: number;
}
export declare const CoachmarkBase: React.FunctionComponent<ICoachmarkProps>;
@@ -0,0 +1,423 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CoachmarkBase = exports.COACHMARK_ATTRIBUTE_NAME = void 0;
var tslib_1 = require("tslib");
// Utilities
var React = require("react");
var Utilities_1 = require("../../Utilities");
var Positioning_1 = require("../../Positioning");
// Component Dependencies
var index_1 = require("./PositioningContainer/index");
var Beak_1 = require("./Beak/Beak");
var DirectionalHint_1 = require("../../common/DirectionalHint");
// Coachmark
var Coachmark_styles_1 = require("./Coachmark.styles");
var FocusTrapZone_1 = require("../../FocusTrapZone");
var react_hooks_1 = require("@fluentui/react-hooks");
var dom_1 = require("../../utilities/dom");
var getClassNames = (0, Utilities_1.classNamesFunction)();
exports.COACHMARK_ATTRIBUTE_NAME = 'data-coachmarkid';
var DEFAULT_PROPS = {
isCollapsed: true,
mouseProximityOffset: 10,
delayBeforeMouseOpen: 3600, // The approximate time the coachmark shows up
delayBeforeCoachmarkAnimation: 0,
isPositionForced: true,
positioningContainerProps: {
directionalHint: DirectionalHint_1.DirectionalHint.bottomAutoEdge,
},
};
function useCollapsedState(props, entityInnerHostElementRef) {
var propsIsCollapsed = props.isCollapsed, onAnimationOpenStart = props.onAnimationOpenStart, onAnimationOpenEnd = props.onAnimationOpenEnd;
/** Is the Coachmark currently collapsed into a tear drop shape */
var _a = React.useState(!!propsIsCollapsed), isCollapsed = _a[0], setIsCollapsed = _a[1];
var setTimeout = (0, react_hooks_1.useSetTimeout)().setTimeout;
// Rather than pushing out logic elsewhere to prevent openCoachmark from being called repeatedly,
// we'll track it here and only invoke the logic once. We do this with a ref, rather than just the state,
// because the openCoachmark callback can be captured in scope for an effect
var hasCoachmarkBeenOpened = React.useRef(!isCollapsed);
var openCoachmark = React.useCallback(function () {
var _a, _b;
if (!hasCoachmarkBeenOpened.current) {
setIsCollapsed(false);
onAnimationOpenStart === null || onAnimationOpenStart === void 0 ? void 0 : onAnimationOpenStart();
(_b = (_a = entityInnerHostElementRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener) === null || _b === void 0 ? void 0 : _b.call(_a, 'transitionend', function () {
// Need setTimeout to trigger narrator
setTimeout(function () {
if (entityInnerHostElementRef.current) {
(0, Utilities_1.focusFirstChild)(entityInnerHostElementRef.current);
}
}, 1000);
onAnimationOpenEnd === null || onAnimationOpenEnd === void 0 ? void 0 : onAnimationOpenEnd();
});
hasCoachmarkBeenOpened.current = true;
}
}, [entityInnerHostElementRef, onAnimationOpenEnd, onAnimationOpenStart, setTimeout]);
React.useEffect(function () {
if (!propsIsCollapsed) {
openCoachmark();
}
// eslint-disable-next-line react-hooks/exhaustive-deps -- should only run if isCollapsed changes
}, [propsIsCollapsed]);
return [isCollapsed, openCoachmark];
}
function usePositionedData() {
var async = (0, react_hooks_1.useAsync)();
/**
* Alignment edge of callout in relation to target
*/
var _a = React.useState(), targetAlignment = _a[0], setTargetAlignment = _a[1];
/**
* Position of Coachmark/TeachingBubble in relation to target
*/
var _b = React.useState(), targetPosition = _b[0], setTargetPosition = _b[1];
var onPositioned = function (_a) {
var alignmentEdge = _a.alignmentEdge, targetEdge = _a.targetEdge;
return async.requestAnimationFrame(function () {
setTargetAlignment(alignmentEdge);
setTargetPosition(targetEdge);
});
};
return [targetAlignment, targetPosition, onPositioned];
}
function useBeakPosition(props, targetAlignment, targetPosition) {
var isRTL = (0, Utilities_1.getRTL)(props.theme);
return React.useMemo(function () {
var beakDirection = targetPosition === undefined ? Positioning_1.RectangleEdge.bottom : (0, Positioning_1.getOppositeEdge)(targetPosition);
var beakPosition = { direction: beakDirection };
var transformOriginX;
var transformOriginY;
var distanceAdjustment = '3px'; // Adjustment distance for Beak to shift towards Coachmark bubble.
switch (beakDirection) {
// If Beak is pointing Up or Down
case Positioning_1.RectangleEdge.top:
case Positioning_1.RectangleEdge.bottom:
// If there is no target alignment, then beak is X-axis centered in callout
if (!targetAlignment) {
beakPosition.left = "calc(50% - ".concat(Beak_1.BEAK_WIDTH / 2, "px)");
transformOriginX = 'center';
}
else {
// Beak is aligned to the left of target
if (targetAlignment === Positioning_1.RectangleEdge.left) {
beakPosition.left = "".concat(Coachmark_styles_1.COACHMARK_WIDTH / 2 - Beak_1.BEAK_WIDTH / 2, "px");
transformOriginX = 'left';
}
else {
// Beak is aligned to the right of target
beakPosition.right = "".concat(Coachmark_styles_1.COACHMARK_WIDTH / 2 - Beak_1.BEAK_WIDTH / 2, "px");
transformOriginX = 'right';
}
}
if (beakDirection === Positioning_1.RectangleEdge.top) {
beakPosition.top = distanceAdjustment;
transformOriginY = 'top';
}
else {
beakPosition.bottom = distanceAdjustment;
transformOriginY = 'bottom';
}
break;
// If Beak is pointing Left or Right
case Positioning_1.RectangleEdge.left:
case Positioning_1.RectangleEdge.right:
// If there is no target alignment, then beak is Y-axis centered in callout
if (!targetAlignment) {
beakPosition.top = "calc(50% - ".concat(Beak_1.BEAK_WIDTH / 2, "px)");
transformOriginY = "center";
}
else {
// Beak is aligned to the top of target
if (targetAlignment === Positioning_1.RectangleEdge.top) {
beakPosition.top = "".concat(Coachmark_styles_1.COACHMARK_WIDTH / 2 - Beak_1.BEAK_WIDTH / 2, "px");
transformOriginY = "top";
}
else {
// Beak is aligned to the bottom of target
beakPosition.bottom = "".concat(Coachmark_styles_1.COACHMARK_WIDTH / 2 - Beak_1.BEAK_WIDTH / 2, "px");
transformOriginY = "bottom";
}
}
if (beakDirection === Positioning_1.RectangleEdge.left) {
if (isRTL) {
beakPosition.right = distanceAdjustment;
}
else {
beakPosition.left = distanceAdjustment;
}
transformOriginX = 'left';
}
else {
if (isRTL) {
beakPosition.left = distanceAdjustment;
}
else {
beakPosition.right = distanceAdjustment;
}
transformOriginX = 'right';
}
break;
}
return [beakPosition, "".concat(transformOriginX, " ").concat(transformOriginY)];
}, [targetAlignment, targetPosition, isRTL]);
}
function useListeners(props, translateAnimationContainer, openCoachmark) {
var _a;
var document = (_a = (0, Utilities_1.getDocument)()) === null || _a === void 0 ? void 0 : _a.documentElement;
(0, react_hooks_1.useOnEvent)(document, 'keydown', function (e) {
var _a, _b;
// Open coachmark if user presses ALT + C (arbitrary keypress for now)
if (
// eslint-disable-next-line @typescript-eslint/no-deprecated
(e.altKey && e.which === Utilities_1.KeyCodes.c) ||
// eslint-disable-next-line @typescript-eslint/no-deprecated
(e.which === Utilities_1.KeyCodes.enter && ((_b = (_a = translateAnimationContainer.current) === null || _a === void 0 ? void 0 : _a.contains) === null || _b === void 0 ? void 0 : _b.call(_a, e.target)))) {
openCoachmark();
}
}, true);
var dismissOnLostFocus = function (ev) {
var _a;
if (props.preventDismissOnLostFocus) {
var clickTarget = ev.target;
var clickedOutsideCallout = translateAnimationContainer.current && !(0, Utilities_1.elementContains)(translateAnimationContainer.current, clickTarget);
var target = props.target;
if (clickedOutsideCallout && clickTarget !== target && !(0, Utilities_1.elementContains)(target, clickTarget)) {
(_a = props.onDismiss) === null || _a === void 0 ? void 0 : _a.call(props, ev);
}
}
};
(0, react_hooks_1.useOnEvent)(document, 'click', dismissOnLostFocus, true);
(0, react_hooks_1.useOnEvent)(document, 'focus', dismissOnLostFocus, true);
}
function useProximityHandlers(props, translateAnimationContainer, openCoachmark, setBounds) {
var _a = (0, react_hooks_1.useSetTimeout)(), setTimeout = _a.setTimeout, clearTimeout = _a.clearTimeout;
/** The target element the mouse would be in proximity to */
var targetElementRect = React.useRef(undefined);
var win = (0, dom_1.useWindowEx)();
var doc = (0, dom_1.useDocumentEx)();
React.useEffect(function () {
var setTargetElementRect = function () {
if (translateAnimationContainer.current) {
targetElementRect.current = translateAnimationContainer.current.getBoundingClientRect();
}
};
var events = new Utilities_1.EventGroup({});
// We don't want the user to immediately trigger the Coachmark when it's opened
setTimeout(function () {
var _a = props.mouseProximityOffset, mouseProximityOffset = _a === void 0 ? 0 : _a;
/** Cached ids returned when setTimeout runs during the window resize event trigger. */
var timeoutIds = [];
// Take the initial measure out of the initial render to prevent an unnecessary render.
setTimeout(function () {
setTargetElementRect();
// When the window resizes we want to async get the bounding client rectangle.
// Every time the event is triggered we want to setTimeout and then clear any previous
// instances of setTimeout.
events.on(win, 'resize', function () {
timeoutIds.forEach(function (value) {
clearTimeout(value);
});
timeoutIds.splice(0, timeoutIds.length); // clear array
timeoutIds.push(setTimeout(function () {
setTargetElementRect();
setBounds(getBounds(props.isPositionForced, props.positioningContainerProps, win));
}, 100));
});
}, 10);
// Every time the document's mouse move is triggered, we want to check if inside of an element
// and set the state with the result.
events.on(doc, 'mousemove', function (e) {
var _a;
var mouseY = e.clientY;
var mouseX = e.clientX;
setTargetElementRect();
if (isInsideElement(targetElementRect.current, mouseX, mouseY, mouseProximityOffset)) {
openCoachmark();
}
(_a = props.onMouseMove) === null || _a === void 0 ? void 0 : _a.call(props, e);
});
}, props.delayBeforeMouseOpen);
return function () { return events.dispose(); };
// eslint-disable-next-line react-hooks/exhaustive-deps -- should only run on mount
}, []);
}
function useComponentRef(props) {
var onDismiss = props.onDismiss;
React.useImperativeHandle(props.componentRef, function (ev) { return ({
dismiss: function () {
onDismiss === null || onDismiss === void 0 ? void 0 : onDismiss(ev);
},
}); }, [onDismiss]);
}
function useAriaAlert(_a) {
var ariaAlertText = _a.ariaAlertText;
var async = (0, react_hooks_1.useAsync)();
/** ARIA alert text to read aloud with Narrator once the Coachmark is mounted */
var _b = React.useState(), alertText = _b[0], setAlertText = _b[1];
React.useEffect(function () {
// Need to add RAF to have narrator read change in alert container
async.requestAnimationFrame(function () {
setAlertText(ariaAlertText);
});
// eslint-disable-next-line react-hooks/exhaustive-deps -- should only run on mount
}, []);
return alertText;
}
function useAutoFocus(_a) {
var preventFocusOnMount = _a.preventFocusOnMount;
var setTimeout = (0, react_hooks_1.useSetTimeout)().setTimeout;
/**
* The cached HTMLElement reference to the Entity Inner Host
* element.
*/
var entityHost = React.useRef(null);
React.useEffect(function () {
if (!preventFocusOnMount) {
setTimeout(function () { var _a; return (_a = entityHost.current) === null || _a === void 0 ? void 0 : _a.focus(); }, 1000);
}
// eslint-disable-next-line react-hooks/exhaustive-deps -- should only run on mount
}, []);
return entityHost;
}
function useEntityHostMeasurements(props, entityInnerHostElementRef) {
/** Is the teaching bubble currently retrieving the original dimensions of the hosted entity. */
var _a = React.useState(!!props.isCollapsed), isMeasuring = _a[0], setIsMeasuring = _a[1];
/** Cached width and height of _entityInnerHostElement */
var _b = React.useState(props.isCollapsed ? { width: 0, height: 0 } : {}), entityInnerHostRect = _b[0], setEntityInnerHostRect = _b[1];
var async = (0, react_hooks_1.useAsync)();
React.useEffect(function () {
async.requestAnimationFrame(function () {
if (entityInnerHostElementRef.current) {
setEntityInnerHostRect({
width: entityInnerHostElementRef.current.offsetWidth,
height: entityInnerHostElementRef.current.offsetHeight,
});
setIsMeasuring(false);
}
});
// eslint-disable-next-line react-hooks/exhaustive-deps -- should only run on mount
}, []);
return [isMeasuring, entityInnerHostRect];
}
function useDeprecationWarning(props) {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line react-hooks/rules-of-hooks -- build-time conditional
(0, react_hooks_1.useWarnings)({
name: COMPONENT_NAME,
props: props,
deprecations: {
teachingBubbleRef: undefined,
collapsed: 'isCollapsed',
beakWidth: undefined,
beakHeight: undefined,
width: undefined,
height: undefined,
},
});
}
}
var COMPONENT_NAME = 'CoachmarkBase';
exports.CoachmarkBase = React.forwardRef(function (propsWithoutDefaults, forwardedRef) {
var props = (0, Utilities_1.getPropsWithDefaults)(DEFAULT_PROPS, propsWithoutDefaults);
var win = (0, dom_1.useWindowEx)();
var entityInnerHostElementRef = React.useRef(null);
var translateAnimationContainer = React.useRef(null);
var _a = usePositionedData(), targetAlignment = _a[0], targetPosition = _a[1], onPositioned = _a[2];
var _b = useCollapsedState(props, entityInnerHostElementRef), isCollapsed = _b[0], openCoachmark = _b[1];
var _c = useBeakPosition(props, targetAlignment, targetPosition), beakPositioningProps = _c[0], transformOrigin = _c[1];
var _d = useEntityHostMeasurements(props, entityInnerHostElementRef), isMeasuring = _d[0], entityInnerHostRect = _d[1];
var _e = React.useState(getBounds(props.isPositionForced, props.positioningContainerProps, win)), bounds = _e[0], setBounds = _e[1];
var alertText = useAriaAlert(props);
var entityHost = useAutoFocus(props);
useListeners(props, translateAnimationContainer, openCoachmark);
useComponentRef(props);
useProximityHandlers(props, translateAnimationContainer, openCoachmark, setBounds);
useDeprecationWarning(props);
React.useEffect(function () {
setBounds(getBounds(props.isPositionForced, props.positioningContainerProps, win));
}, [props.isPositionForced, props.positioningContainerProps, win]);
var beaconColorOne = props.beaconColorOne, beaconColorTwo = props.beaconColorTwo, children = props.children, target = props.target, color = props.color, positioningContainerProps = props.positioningContainerProps, ariaDescribedBy = props.ariaDescribedBy, ariaDescribedByText = props.ariaDescribedByText, ariaLabelledBy = props.ariaLabelledBy, ariaLabelledByText = props.ariaLabelledByText, ariaAlertText = props.ariaAlertText, delayBeforeCoachmarkAnimation = props.delayBeforeCoachmarkAnimation, styles = props.styles, theme = props.theme, className = props.className, persistentBeak = props.persistentBeak;
// Defaulting the main background before passing it to the styles because it is used for `Beak` too.
var defaultColor = color;
if (!defaultColor && theme) {
defaultColor = theme.semanticColors.primaryButtonBackground;
}
var classNames = getClassNames(styles, {
theme: theme,
beaconColorOne: beaconColorOne,
beaconColorTwo: beaconColorTwo,
className: className,
isCollapsed: isCollapsed,
isMeasuring: isMeasuring,
color: defaultColor,
transformOrigin: transformOrigin,
entityHostHeight: entityInnerHostRect.height === undefined ? undefined : "".concat(entityInnerHostRect.height, "px"),
entityHostWidth: entityInnerHostRect.width === undefined ? undefined : "".concat(entityInnerHostRect.width, "px"),
width: "".concat(Coachmark_styles_1.COACHMARK_WIDTH, "px"),
height: "".concat(Coachmark_styles_1.COACHMARK_HEIGHT, "px"),
delayBeforeCoachmarkAnimation: "".concat(delayBeforeCoachmarkAnimation, "ms"),
});
var finalHeight = isCollapsed ? Coachmark_styles_1.COACHMARK_HEIGHT : entityInnerHostRect.height;
var onClickCallout = React.useCallback(function () {
openCoachmark();
}, [openCoachmark]);
return (React.createElement(index_1.PositioningContainer, tslib_1.__assign({ target: target, offsetFromTarget: Beak_1.BEAK_HEIGHT, finalHeight: finalHeight, ref: forwardedRef, onPositioned: onPositioned, bounds: bounds }, positioningContainerProps),
React.createElement("div", { className: classNames.root },
ariaAlertText && (React.createElement("div", { className: classNames.ariaContainer, role: "alert", "aria-hidden": !isCollapsed }, alertText)),
React.createElement("div", { className: classNames.pulsingBeacon }),
React.createElement("div", { className: classNames.translateAnimationContainer, ref: translateAnimationContainer },
React.createElement("div", { className: classNames.scaleAnimationLayer },
React.createElement("div", { className: classNames.rotateAnimationLayer },
(isCollapsed || persistentBeak) && React.createElement(Beak_1.Beak, tslib_1.__assign({}, beakPositioningProps, { color: defaultColor })),
React.createElement("div", { className: classNames.entityHost, ref: entityHost, tabIndex: -1, "data-is-focusable": true, role: "dialog", "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, onClick: onClickCallout },
isCollapsed && [
ariaLabelledBy && (React.createElement("p", { id: ariaLabelledBy, key: 0, className: classNames.ariaContainer }, ariaLabelledByText)),
ariaDescribedBy && (React.createElement("p", { id: ariaDescribedBy, key: 1, className: classNames.ariaContainer }, ariaDescribedByText)),
],
React.createElement(FocusTrapZone_1.FocusTrapZone, { isClickableOutsideFocusTrap: true, forceFocusInsideTrap: false },
React.createElement("div", { className: classNames.entityInnerHost, ref: entityInnerHostElementRef },
React.createElement("div", { className: classNames.childrenContainer, "aria-hidden": isCollapsed }, children))))))))));
});
exports.CoachmarkBase.displayName = COMPONENT_NAME;
function getBounds(isPositionForced, positioningContainerProps, win) {
var _a, _b;
if (isPositionForced) {
// If directionalHint direction is the top or bottom auto edge, then we want to set the left/right bounds
// to the window x-axis to have auto positioning work correctly.
if (positioningContainerProps &&
(positioningContainerProps.directionalHint === DirectionalHint_1.DirectionalHint.topAutoEdge ||
positioningContainerProps.directionalHint === DirectionalHint_1.DirectionalHint.bottomAutoEdge)) {
return {
left: 0,
top: -Infinity,
bottom: Infinity,
right: (_a = win === null || win === void 0 ? void 0 : win.innerWidth) !== null && _a !== void 0 ? _a : 0,
width: (_b = win === null || win === void 0 ? void 0 : win.innerWidth) !== null && _b !== void 0 ? _b : 0,
height: Infinity,
};
}
else {
return {
left: -Infinity,
top: -Infinity,
bottom: Infinity,
right: Infinity,
width: Infinity,
height: Infinity,
};
}
}
else {
return undefined;
}
}
function isInsideElement(
// eslint-disable-next-line @typescript-eslint/no-deprecated
targetElementRect, mouseX, mouseY, mouseProximityOffset) {
if (mouseProximityOffset === void 0) { mouseProximityOffset = 0; }
return (mouseX > targetElementRect.left - mouseProximityOffset &&
mouseX < targetElementRect.left + targetElementRect.width + mouseProximityOffset &&
mouseY > targetElementRect.top - mouseProximityOffset &&
mouseY < targetElementRect.top + targetElementRect.height + mouseProximityOffset);
}
//# sourceMappingURL=Coachmark.base.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
import * as React from 'react';
import type { ICoachmarkProps } from './Coachmark.types';
export declare const Coachmark: React.FunctionComponent<ICoachmarkProps>;
@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Coachmark = void 0;
var Utilities_1 = require("../../Utilities");
var Coachmark_styles_1 = require("./Coachmark.styles");
var Coachmark_base_1 = require("./Coachmark.base");
exports.Coachmark = (0, Utilities_1.styled)(Coachmark_base_1.CoachmarkBase, Coachmark_styles_1.getStyles, undefined, {
scope: 'Coachmark',
});
//# sourceMappingURL=Coachmark.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Coachmark.js","sourceRoot":"../src/","sources":["components/Coachmark/Coachmark.ts"],"names":[],"mappings":";;;AACA,6CAAyC;AACzC,uDAA+C;AAC/C,mDAAiD;AAGpC,QAAA,SAAS,GAA6C,IAAA,kBAAM,EAIvE,8BAAa,EAAE,4BAAS,EAAE,SAAS,EAAE;IACrC,KAAK,EAAE,WAAW;CACnB,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { styled } from '../../Utilities';\nimport { getStyles } from './Coachmark.styles';\nimport { CoachmarkBase } from './Coachmark.base';\nimport type { ICoachmarkProps, ICoachmarkStyleProps, ICoachmarkStyles } from './Coachmark.types';\n\nexport const Coachmark: React.FunctionComponent<ICoachmarkProps> = styled<\n ICoachmarkProps,\n ICoachmarkStyleProps,\n ICoachmarkStyles\n>(CoachmarkBase, getStyles, undefined, {\n scope: 'Coachmark',\n});\n"]}
@@ -0,0 +1,7 @@
import type { ICoachmarkStyleProps, ICoachmarkStyles } from './Coachmark.types';
export declare const COACHMARK_WIDTH = 32;
export declare const COACHMARK_HEIGHT = 32;
export declare const translateOne: () => string;
export declare const scaleOne: () => string;
export declare const rotateOne: () => string;
export declare function getStyles(props: ICoachmarkStyleProps): ICoachmarkStyles;
@@ -0,0 +1,281 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rotateOne = exports.scaleOne = exports.translateOne = exports.COACHMARK_HEIGHT = exports.COACHMARK_WIDTH = void 0;
exports.getStyles = getStyles;
var Styling_1 = require("../../Styling");
var Utilities_1 = require("../../Utilities");
exports.COACHMARK_WIDTH = 32;
exports.COACHMARK_HEIGHT = 32;
exports.translateOne = (0, Utilities_1.memoizeFunction)(function () {
return (0, Styling_1.keyframes)({
'0%': {
transform: 'translate(0, 0)', // orig 25
animationTimingFunction: 'linear',
},
'78.57%': {
transform: 'translate(0, 0)', // orig 25
animationTimingFunction: 'cubic-bezier(0.62, 0, 0.56, 1)',
},
'82.14%': {
transform: 'translate(0, -5px)', // orig 20
animationTimingFunction: 'cubic-bezier(0.58, 0, 0, 1)',
},
'84.88%': {
transform: 'translate(0, 9px)', // 34
animationTimingFunction: 'cubic-bezier(1, 0, 0.56, 1)',
},
'88.1%': {
transform: 'translate(0, -2px)', // orig 23
animationTimingFunction: 'cubic-bezier(0.58, 0, 0.67, 1)',
},
'90.12%': {
transform: 'translate(0, 0)',
animationTimingFunction: 'linear',
},
'100%': {
transform: 'translate(0, 0)',
},
});
});
exports.scaleOne = (0, Utilities_1.memoizeFunction)(function () {
return (0, Styling_1.keyframes)({
'0%': {
transform: ' scale(0)',
animationTimingFunction: 'linear',
},
'14.29%': {
transform: 'scale(0)',
animationTimingFunction: 'cubic-bezier(0.84, 0, 0.52, 0.99)',
},
'16.67%': {
transform: 'scale(1.15)',
animationTimingFunction: 'cubic-bezier(0.48, -0.01, 0.52, 1.01)',
},
'19.05%': {
transform: 'scale(0.95)',
animationTimingFunction: 'cubic-bezier(0.48, 0.02, 0.52, 0.98)',
},
'21.43%': {
transform: 'scale(1)',
animationTimingFunction: 'linear',
},
'42.86%': {
transform: 'scale(1)',
animationTimingFunction: 'cubic-bezier(0.48, -0.02, 0.52, 1.02)',
},
'45.71%': {
transform: 'scale(0.8)',
animationTimingFunction: 'cubic-bezier(0.48, 0.01, 0.52, 0.99)',
},
'50%': {
transform: 'scale(1)',
animationTimingFunction: 'linear',
},
'90.12%': {
transform: 'scale(1)',
animationTimingFunction: 'cubic-bezier(0.48, -0.02, 0.52, 1.02)',
},
'92.98%': {
transform: 'scale(0.8)',
animationTimingFunction: 'cubic-bezier(0.48, 0.01, 0.52, 0.99)',
},
'97.26%': {
transform: 'scale(1)',
animationTimingFunction: 'linear',
},
'100%': {
transform: 'scale(1)',
},
});
});
exports.rotateOne = (0, Utilities_1.memoizeFunction)(function () {
return (0, Styling_1.keyframes)({
'0%': {
transform: 'rotate(0deg)',
animationTimingFunction: 'linear',
},
'83.33%': {
transform: ' rotate(0deg)',
animationTimingFunction: 'cubic-bezier(0.33, 0, 0.67, 1)',
},
'83.93%': {
transform: 'rotate(15deg)',
animationTimingFunction: 'cubic-bezier(0.33, 0, 0.67, 1)',
},
'84.52%': {
transform: 'rotate(-15deg)',
animationTimingFunction: 'cubic-bezier(0.33, 0, 0.67, 1)',
},
'85.12%': {
transform: 'rotate(15deg)',
animationTimingFunction: 'cubic-bezier(0.33, 0, 0.67, 1)',
},
'85.71%': {
transform: 'rotate(-15deg)',
animationTimingFunction: 'cubic-bezier(0.33, 0, 0.67, 1)',
},
'86.31%': {
transform: 'rotate(0deg)',
animationTimingFunction: 'linear',
},
'100%': {
transform: 'rotate(0deg)',
},
});
});
function getStyles(props) {
var _a;
var theme = props.theme, className = props.className, color = props.color, beaconColorOne = props.beaconColorOne, beaconColorTwo = props.beaconColorTwo, delayBeforeCoachmarkAnimation = props.delayBeforeCoachmarkAnimation, isCollapsed = props.isCollapsed, isMeasuring = props.isMeasuring, entityHostHeight = props.entityHostHeight, entityHostWidth = props.entityHostWidth, transformOrigin = props.transformOrigin;
if (!theme) {
throw new Error('theme is undefined or null in base Dropdown getStyles function.');
}
var animationInnerDimension = '35px';
var animationOuterDimension = '150px';
var animationBorderWidth = '10px';
var ContinuousPulse = Styling_1.PulsingBeaconAnimationStyles.continuousPulseAnimationDouble(beaconColorOne ? beaconColorOne : theme.palette.themePrimary, beaconColorTwo ? beaconColorTwo : theme.palette.themeTertiary, animationInnerDimension, animationOuterDimension, animationBorderWidth);
var ContinuousPulseAnimation = Styling_1.PulsingBeaconAnimationStyles.createDefaultAnimation(ContinuousPulse, delayBeforeCoachmarkAnimation);
return {
root: [
theme.fonts.medium,
{
position: 'relative',
},
className,
],
pulsingBeacon: [
{
position: 'absolute',
top: '50%',
left: '50%',
transform: (0, Utilities_1.getRTL)(theme) ? 'translate(50%, -50%)' : 'translate(-50%, -50%)',
width: '0px',
height: '0px',
borderRadius: '225px',
borderStyle: 'solid',
opacity: '0',
},
isCollapsed && ContinuousPulseAnimation,
],
// Translate Animation Layer
translateAnimationContainer: [
{
width: '100%',
height: '100%',
},
isCollapsed && {
animationDuration: '14s',
animationTimingFunction: 'linear',
animationDirection: 'normal',
animationIterationCount: '1',
animationDelay: '0s',
animationFillMode: 'forwards',
animationName: (0, exports.translateOne)(),
transition: 'opacity 0.5s ease-in-out',
},
!isCollapsed && {
opacity: '1',
},
],
// Scale Animation Layer
scaleAnimationLayer: [
{
width: '100%',
height: '100%',
},
isCollapsed && {
animationDuration: '14s',
animationTimingFunction: 'linear',
animationDirection: 'normal',
animationIterationCount: '1',
animationDelay: '0s',
animationFillMode: 'forwards',
animationName: (0, exports.scaleOne)(),
},
],
// Rotate Animation Layer
rotateAnimationLayer: [
{
width: '100%',
height: '100%',
},
isCollapsed && {
animationDuration: '14s',
animationTimingFunction: 'linear',
animationDirection: 'normal',
animationIterationCount: '1',
animationDelay: '0s',
animationFillMode: 'forwards',
animationName: (0, exports.rotateOne)(),
},
!isCollapsed && {
opacity: '1',
},
],
// Layer Host, defaults to collapsed
entityHost: [
{
position: 'relative',
outline: 'none',
overflow: 'hidden',
backgroundColor: color,
borderRadius: exports.COACHMARK_WIDTH,
transition: 'border-radius 250ms, width 500ms, height 500ms cubic-bezier(0.5, 0, 0, 1)',
visibility: 'hidden',
selectors: (_a = {},
_a[Styling_1.HighContrastSelector] = {
backgroundColor: 'Window',
border: '2px solid WindowText',
},
_a[".".concat(Utilities_1.IsFocusVisibleClassName, " &:focus")] = {
outline: "1px solid ".concat(theme.palette.themeTertiary),
},
_a),
},
!isMeasuring &&
isCollapsed && {
width: exports.COACHMARK_WIDTH,
height: exports.COACHMARK_HEIGHT,
},
!isMeasuring && {
visibility: 'visible',
},
!isCollapsed && {
borderRadius: '1px',
opacity: '1',
width: entityHostWidth,
height: entityHostHeight,
},
isCollapsed && {
cursor: 'pointer',
},
],
entityInnerHost: [
{
transition: 'transform 500ms cubic-bezier(0.5, 0, 0, 1)',
transformOrigin: transformOrigin,
transform: 'scale(0)',
},
!isCollapsed && {
width: entityHostWidth,
height: entityHostHeight,
transform: 'scale(1)',
},
!isMeasuring && {
visibility: 'visible',
},
],
childrenContainer: [
{
display: !isMeasuring && isCollapsed ? 'none' : 'block',
},
],
ariaContainer: {
position: 'fixed',
opacity: 0,
height: 0,
width: 0,
pointerEvents: 'none',
},
};
}
//# sourceMappingURL=Coachmark.styles.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,287 @@
import * as React from 'react';
import type { IStyle, ITheme } from '../../Styling';
import type { IPositioningContainerProps } from './PositioningContainer/PositioningContainer.types';
import type { IRefObject, IStyleFunctionOrObject } from '../../Utilities';
import type { ITeachingBubble } from '../../TeachingBubble';
import type { Target } from '@fluentui/react-hooks';
/**
* {@docCategory Coachmark}
*/
export interface ICoachmark {
/**
* Forces the Coachmark to dismiss
*/
dismiss?: (ev?: Event | React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void;
}
/**
* Coachmark component props
* {@docCategory Coachmark}
*/
export interface ICoachmarkProps extends React.RefAttributes<HTMLDivElement> {
/**
* Optional callback to access the `ICoachmark` interface. Use this instead of `ref` for accessing
* the public methods and properties of the component.
*/
componentRef?: IRefObject<ICoachmark>;
/**
* If provided, additional class name to provide on the root element.
*/
className?: string;
/**
* Call to provide customized styling that will layer on top of the variant rules
*/
styles?: IStyleFunctionOrObject<ICoachmarkStyleProps, ICoachmarkStyles>;
/**
* The target that the Coachmark should try to position itself based on.
*/
target: Target;
/**
* Props to pass to the PositioningContainer component. Specify the `directionalHint` to indicate
* on which edge the Coachmark/TeachingBubble should be positioned.
* @defaultvalue `{ directionalHint: DirectionalHint.bottomAutoEdge }`
*/
positioningContainerProps?: IPositioningContainerProps;
/**
* Whether or not to force the Coachmark/TeachingBubble content to fit within the window bounds.
* @defaultvalue true
*/
isPositionForced?: boolean;
/**
* The starting collapsed state for the Coachmark.
* @defaultvalue true
* @deprecated Use `isCollapsed` instead.
*/
collapsed?: boolean;
/**
* The starting collapsed state for the Coachmark.
* @defaultvalue true
*/
isCollapsed?: boolean;
/**
* The distance in pixels the mouse is located before opening up the Coachmark.
* @defaultvalue 10
*/
mouseProximityOffset?: number;
/**
* Callback when the opening animation begins.
*/
onAnimationOpenStart?: () => void;
/**
* Callback when the opening animation completes.
*/
onAnimationOpenEnd?: () => void;
/**
* @deprecated No longer used.
*/
beakWidth?: number;
/**
* @deprecated No longer used.
*/
beakHeight?: number;
/**
* Delay before allowing mouse movements to open the Coachmark.
* @defaultvalue 3600
*/
delayBeforeMouseOpen?: number;
/**
* Delay in milliseconds before Coachmark animation appears.
* @defaultvalue 0
*/
delayBeforeCoachmarkAnimation?: number;
/**
* Callback to run when the mouse moves.
*/
onMouseMove?: (e: MouseEvent) => void;
/**
* @deprecated No longer used.
*/
width?: number;
/**
* @deprecated No longer used.
*/
height?: number;
/**
* Color of the Coachmark/TeachingBubble.
*/
color?: string;
/**
* Beacon color one.
*/
beaconColorOne?: string;
/**
* Beacon color two.
*/
beaconColorTwo?: string;
/**
* Text for screen reader to announce when Coachmark is displayed
*/
ariaAlertText?: string;
/**
* @deprecated Not used. Coachmark uses `focusFirstChild` utility instead to focus on TeachingBubbleContent.
*/
teachingBubbleRef?: ITeachingBubble;
/**
* ID used for the internal element which contains label text for the Coachmark
* (don't render an element with this ID yourself).
*/
ariaLabelledBy?: string;
/**
* ID used for the internal element which contains description text for the Coachmark
* (don't render an element with this ID yourself).
*/
ariaDescribedBy?: string;
/**
* Defines the text content for the `ariaLabelledBy` element.
* Not used unless `ariaLabelledBy` is also provided.
*/
ariaLabelledByText?: string;
/**
* Defines the text content for the `ariaDescribedBy` element
* Not used unless `ariaDescribedBy` is also provided.
*/
ariaDescribedByText?: string;
/**
* If true then the Coachmark will not dismiss when it loses focus
* @defaultvalue false
*/
preventDismissOnLostFocus?: boolean;
/**
* If true then the Coachmark beak (arrow pointing towards target) will always be visible as long as
* Coachmark is visible
* @defaultvalue false
*/
persistentBeak?: boolean;
/**
* If true then focus will not be set to the Coachmark when it mounts. Useful in cases where focus on coachmark
* is causing other components in page to dismiss upon losing focus.
* @defaultvalue false
*/
preventFocusOnMount?: boolean;
/**
* Callback when the Coachmark tries to close.
*/
onDismiss?: (ev?: Event | React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void;
/**
* Theme provided by higher order component.
*/
theme?: ITheme;
/**
* Child nodes to render inside the Coachmark dialog
*/
children?: React.ReactNode;
}
/**
* The props needed to construct styles.
* {@docCategory Coachmark}
*/
export interface ICoachmarkStyleProps {
/**
* ClassName to provide on the root style area.
*/
className?: string;
/**
* Current theme.
*/
theme?: ITheme;
/**
* Is the Coachmark collapsed.
* @deprecated Use `isCollapsed` instead.
*/
collapsed?: boolean;
/**
* Is the Coachmark collapsed
*/
isCollapsed: boolean;
/**
* Is the component taking measurements
*/
isMeasuring: boolean;
/**
* The height measured before the component has been mounted in pixels
*/
entityHostHeight?: string;
/**
* The width measured in pixels
*/
entityHostWidth?: string;
/**
* Width of the coachmark
*/
width?: string;
/**
* Height of the coachmark
*/
height?: string;
/**
* Color
*/
color?: string;
/**
* Beacon color one
*/
beaconColorOne?: string;
/**
* Beacon color two
*/
beaconColorTwo?: string;
/**
* Transform origin for teaching bubble content
*/
transformOrigin?: string;
/**
* Delay time for the animation to start
*/
delayBeforeCoachmarkAnimation?: string;
}
/**
* Represents the stylable areas of the control.
* {@docCategory Coachmark}
*/
export interface ICoachmarkStyles {
/**
* Style for the root element in the default enabled/unchecked state.
*/
root?: IStyle;
/**
* The pulsing beacon that animates when the Coachmark is collapsed.
*/
pulsingBeacon?: IStyle;
/**
* The layer, or div, that the translate animation will be applied to.
*/
translateAnimationContainer?: IStyle;
/**
* The layer the Scale animation will be applied to.
*/
scaleAnimationLayer?: IStyle;
/**
* The layer the Rotate animation will be applied to.
*/
rotateAnimationLayer?: IStyle;
/**
* The layer that content/components/elements will be hosted in.
*/
entityHost?: IStyle;
/**
* The inner layer that components will be hosted in
* (primary purpose is scaling the layer down while the Coachmark collapses)
*/
entityInnerHost: IStyle;
/**
* The layer that directly contains the TeachingBubbleContent
*/
childrenContainer: IStyle;
/**
* The styles applied when the Coachmark has collapsed.
*/
collapsed?: IStyle;
/**
* The styles applied to the ARIA attribute container
*/
ariaContainer?: IStyle;
}
/**
* @deprecated No longer used.
* {@docCategory Coachmark}
*/
export type ICoachmarkTypes = ICoachmarkProps;
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=Coachmark.types.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
import * as React from 'react';
import type { IPositioningContainerProps } from './PositioningContainer.types';
export declare function useHeightOffset({ finalHeight }: IPositioningContainerProps, contentHost: React.RefObject<HTMLDivElement | null>): number;
export declare const PositioningContainer: React.FunctionComponent<IPositioningContainerProps>;
@@ -0,0 +1,290 @@
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PositioningContainer = void 0;
exports.useHeightOffset = useHeightOffset;
var tslib_1 = require("tslib");
var React = require("react");
var PositioningContainer_styles_1 = require("./PositioningContainer.styles");
var Styling_1 = require("../../../Styling");
var Layer_1 = require("../../../Layer");
// Utilites/Helpers
var DirectionalHint_1 = require("../../../common/DirectionalHint");
var Utilities_1 = require("../../../Utilities");
var Positioning_1 = require("../../../Positioning");
var Styling_2 = require("../../../Styling");
var react_hooks_1 = require("@fluentui/react-hooks");
var dom_1 = require("../../../utilities/dom");
var OFF_SCREEN_STYLE = { opacity: 0 };
// In order for some of the max height logic to work properly we need to set the border.
// The value is arbitrary.
var BORDER_WIDTH = 1;
var SLIDE_ANIMATIONS = (_a = {},
_a[Positioning_1.RectangleEdge.top] = 'slideUpIn20',
_a[Positioning_1.RectangleEdge.bottom] = 'slideDownIn20',
_a[Positioning_1.RectangleEdge.left] = 'slideLeftIn20',
_a[Positioning_1.RectangleEdge.right] = 'slideRightIn20',
_a);
var DEFAULT_PROPS = {
preventDismissOnScroll: false,
offsetFromTarget: 0,
minPagePadding: 8,
directionalHint: DirectionalHint_1.DirectionalHint.bottomAutoEdge,
};
function useBounds(props, targetWindow) {
/** The bounds used when determining if and where the PositioningContainer should be placed. */
var getBounds = function () {
var currentBounds = props.bounds;
if (!currentBounds) {
currentBounds = {
top: 0 + props.minPagePadding,
left: 0 + props.minPagePadding,
right: targetWindow.innerWidth - props.minPagePadding,
bottom: targetWindow.innerHeight - props.minPagePadding,
width: targetWindow.innerWidth - props.minPagePadding * 2,
height: targetWindow.innerHeight - props.minPagePadding * 2,
};
}
return currentBounds;
};
return getBounds;
}
function usePositionState(props, positionedHost, contentHost, targetRef, getCachedBounds) {
var async = (0, react_hooks_1.useAsync)();
var doc = (0, dom_1.useDocumentEx)();
var win = (0, dom_1.useWindowEx)();
/**
* Current set of calculated positions for the outermost parent container.
*/
var _a = React.useState(), positions = _a[0], setPositions = _a[1];
var positionAttempts = React.useRef(0);
var updateAsyncPosition = function () {
async.requestAnimationFrame(function () { return updatePosition(); });
};
var updatePosition = function () {
var offsetFromTarget = props.offsetFromTarget, onPositioned = props.onPositioned;
var hostElement = positionedHost.current;
var positioningContainerElement = contentHost.current;
if (hostElement && positioningContainerElement) {
var currentProps = tslib_1.__assign({}, props);
currentProps.bounds = getCachedBounds();
currentProps.target = targetRef.current;
var target = currentProps.target;
if (target) {
// Check if the target is an Element or a MouseEvent and the document contains it
// or don't check anything else if the target is a Point or Rectangle
if ((!target.getBoundingClientRect && !target.preventDefault) ||
(doc === null || doc === void 0 ? void 0 : doc.body.contains(target))) {
currentProps.gapSpace = offsetFromTarget;
var newPositions = (0, Positioning_1.positionElement)(currentProps, hostElement, positioningContainerElement, undefined, win);
// Set the new position only when the positions are not exists or one of the new positioningContainer
// positions are different. The position should not change if the position is within 2 decimal places.
if ((!positions && newPositions) ||
(positions && newPositions && !arePositionsEqual(positions, newPositions) && positionAttempts.current < 5)) {
// We should not reposition the positioningContainer more than a few times, if it is then the content is
// likely resizing and we should stop trying to reposition to prevent a stack overflow.
positionAttempts.current++;
setPositions(newPositions);
onPositioned === null || onPositioned === void 0 ? void 0 : onPositioned(newPositions);
}
else {
positionAttempts.current = 0;
onPositioned === null || onPositioned === void 0 ? void 0 : onPositioned(newPositions);
}
}
else if (positions !== undefined) {
setPositions(undefined);
}
}
else if (positions !== undefined) {
setPositions(undefined);
}
}
};
React.useEffect(updateAsyncPosition);
return [positions, updateAsyncPosition];
}
function useSetInitialFocus(_a, contentHost, positions) {
var setInitialFocus = _a.setInitialFocus;
var didSetInitialFocus = React.useRef(false);
React.useEffect(function () {
if (!didSetInitialFocus.current && contentHost.current && setInitialFocus && positions) {
didSetInitialFocus.current = true;
(0, Utilities_1.focusFirstChild)(contentHost.current);
}
});
}
function useMaxHeight(_a, targetRef, getCachedBounds) {
var directionalHintFixed = _a.directionalHintFixed, offsetFromTarget = _a.offsetFromTarget, directionalHint = _a.directionalHint, target = _a.target;
/**
* The maximum height the PositioningContainer can grow to
* without going beyond the window or target bounds
*/
var maxHeight = React.useRef(undefined);
var win = (0, dom_1.useWindowEx)();
// If the target element changed, reset the max height. If we are tracking
// target with class name, always reset because we do not know if
// fabric has rendered a new element and disposed the old element.
if (typeof target === 'string') {
maxHeight.current = undefined;
}
React.useEffect(function () {
maxHeight.current = undefined;
}, [target, offsetFromTarget]);
/**
* Return the maximum height the container can grow to
* without going out of the specified bounds
*/
var getCachedMaxHeight = function () {
if (!maxHeight.current) {
if (directionalHintFixed && targetRef.current) {
var gapSpace = offsetFromTarget ? offsetFromTarget : 0;
maxHeight.current = (0, Positioning_1.getMaxHeight)(targetRef.current, directionalHint, gapSpace, getCachedBounds(), undefined, win);
}
else {
maxHeight.current = getCachedBounds().height - BORDER_WIDTH * 2;
}
}
return maxHeight.current;
};
return getCachedMaxHeight;
}
function useAutoDismissEvents(_a, positionedHost, targetWindow, targetRef, positions, updateAsyncPosition) {
var onDismiss = _a.onDismiss, preventDismissOnScroll = _a.preventDismissOnScroll;
var async = (0, react_hooks_1.useAsync)();
var onResize = React.useCallback(function (ev) {
if (onDismiss) {
onDismiss(ev);
}
else {
updateAsyncPosition();
}
}, [onDismiss, updateAsyncPosition]);
var dismissOnLostFocus = React.useCallback(function (ev) {
var target = ev.target;
var clickedOutsideCallout = positionedHost.current && !(0, Utilities_1.elementContains)(positionedHost.current, target);
if ((!targetRef.current && clickedOutsideCallout) ||
(ev.target !== targetWindow &&
clickedOutsideCallout &&
(targetRef.current.stopPropagation ||
!targetRef.current ||
(target !== targetRef.current && !(0, Utilities_1.elementContains)(targetRef.current, target))))) {
onResize(ev);
}
}, [onResize, positionedHost, targetRef, targetWindow]);
var dismissOnScroll = React.useCallback(function (ev) {
if (positions && !preventDismissOnScroll) {
dismissOnLostFocus(ev);
}
}, [dismissOnLostFocus, positions, preventDismissOnScroll]);
React.useEffect(function () {
var events = new Utilities_1.EventGroup({});
// This is added so the positioningContainer will dismiss when the window is scrolled
// but not when something inside the positioningContainer is scrolled. The delay seems
// to be required to avoid React firing an async focus event in IE from
// the target changing focus quickly prior to rendering the positioningContainer.
async.setTimeout(function () {
var _a, _b;
events.on(targetWindow, 'scroll', async.throttle(dismissOnScroll, 10), true);
events.on(targetWindow, 'resize', async.throttle(onResize, 10), true);
events.on((_a = targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.document) === null || _a === void 0 ? void 0 : _a.body, 'focus', dismissOnLostFocus, true);
events.on((_b = targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.document) === null || _b === void 0 ? void 0 : _b.body, 'click', dismissOnLostFocus, true);
}, 0);
return function () { return events.dispose(); };
// eslint-disable-next-line react-hooks/exhaustive-deps -- should only run on mount
}, [dismissOnScroll]);
}
function useHeightOffset(_a, contentHost) {
var finalHeight = _a.finalHeight;
/**
* Tracks the current height offset and updates during
* the height animation when props.finalHeight is specified.
* State stored as object to ensure re-render even if the value does not change.
* See https://github.com/microsoft/fluentui/issues/23545
*/
var _b = React.useState({ value: 0 }), heightOffset = _b[0], setHeightOffset = _b[1];
var async = (0, react_hooks_1.useAsync)();
var setHeightOffsetTimer = React.useRef(0);
/** Animates the height if finalHeight was given. */
var setHeightOffsetEveryFrame = function () {
if (contentHost && finalHeight) {
setHeightOffsetTimer.current = async.requestAnimationFrame(function () {
if (!contentHost.current) {
return;
}
var positioningContainerMainElem = contentHost.current.lastChild;
var cardScrollHeight = positioningContainerMainElem.scrollHeight;
var cardCurrHeight = positioningContainerMainElem.offsetHeight;
var scrollDiff = cardScrollHeight - cardCurrHeight;
setHeightOffset({ value: heightOffset.value + scrollDiff });
if (positioningContainerMainElem.offsetHeight < finalHeight) {
setHeightOffsetEveryFrame();
}
else {
async.cancelAnimationFrame(setHeightOffsetTimer.current);
}
});
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps -- should only re-run if finalHeight changes
React.useEffect(setHeightOffsetEveryFrame, [finalHeight]);
return heightOffset.value;
}
exports.PositioningContainer = React.forwardRef(function (propsWithoutDefaults, forwardedRef) {
var props = (0, Utilities_1.getPropsWithDefaults)(DEFAULT_PROPS, propsWithoutDefaults);
// @TODO rename to reflect the name of this class
var contentHost = React.useRef(null);
/**
* The primary positioned div.
*/
var positionedHost = React.useRef(null);
var rootRef = (0, react_hooks_1.useMergedRefs)(forwardedRef, positionedHost);
var _a = (0, react_hooks_1.useTarget)(props.target, positionedHost), targetRef = _a[0], targetWindow = _a[1];
var getCachedBounds = useBounds(props, targetWindow);
var _b = usePositionState(props, positionedHost, contentHost, targetRef, getCachedBounds), positions = _b[0], updateAsyncPosition = _b[1];
var getCachedMaxHeight = useMaxHeight(props, targetRef, getCachedBounds);
var heightOffset = useHeightOffset(props, contentHost);
useSetInitialFocus(props, contentHost, positions);
useAutoDismissEvents(props, positionedHost, targetWindow, targetRef, positions, updateAsyncPosition);
// eslint-disable-next-line react-hooks/exhaustive-deps -- should only run on initial render
React.useEffect(function () { var _a; return (_a = props.onLayerMounted) === null || _a === void 0 ? void 0 : _a.call(props); }, []);
// If there is no target window then we are likely in server side rendering and we should not render anything.
if (!targetWindow) {
return null;
}
var className = props.className, doNotLayer = props.doNotLayer, positioningContainerWidth = props.positioningContainerWidth, positioningContainerMaxHeight = props.positioningContainerMaxHeight, children = props.children;
var styles = (0, PositioningContainer_styles_1.getClassNames)();
var directionalClassName = positions && positions.targetEdge ? Styling_2.AnimationClassNames[SLIDE_ANIMATIONS[positions.targetEdge]] : '';
var getContentMaxHeight = getCachedMaxHeight() + heightOffset;
var contentMaxHeight = positioningContainerMaxHeight && positioningContainerMaxHeight > getContentMaxHeight
? getContentMaxHeight
: positioningContainerMaxHeight;
var content = (React.createElement("div", { ref: rootRef, className: (0, Utilities_1.css)('ms-PositioningContainer', styles.container) },
React.createElement("div", { className: (0, Styling_2.mergeStyles)('ms-PositioningContainer-layerHost', styles.root, className, directionalClassName, !!positioningContainerWidth && { width: positioningContainerWidth }, doNotLayer && { zIndex: Styling_1.ZIndexes.Layer }), style: positions ? positions.elementPosition : OFF_SCREEN_STYLE,
// Safari and Firefox on Mac OS requires this to back-stop click events so focus remains in the Callout.
// See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
tabIndex: -1, ref: contentHost },
children,
// @TODO apply to the content container
contentMaxHeight)));
return doNotLayer ? content : React.createElement(Layer_1.Layer, tslib_1.__assign({}, props.layerProps), content);
});
exports.PositioningContainer.displayName = 'PositioningContainer';
function arePositionsEqual(positions, newPosition) {
return comparePositions(positions.elementPosition, newPosition.elementPosition);
}
function comparePositions(oldPositions, newPositions) {
for (var key in newPositions) {
if (newPositions.hasOwnProperty(key)) {
var oldPositionEdge = oldPositions[key];
var newPositionEdge = newPositions[key];
if (oldPositionEdge && newPositionEdge) {
if (oldPositionEdge.toFixed(2) !== newPositionEdge.toFixed(2)) {
return false;
}
}
}
}
return true;
}
//# sourceMappingURL=PositioningContainer.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
import type { IStyle } from '../../../Styling';
export interface IPositioningContainerStyles {
/**
* Style for the root element in the default enabled/unchecked state.
*/
root?: IStyle;
}
export interface IPositioningContainerNames {
/**
* Root html container for this component.
*/
root: string;
container: string;
main: string;
overFlowYHidden: string;
beak?: string;
beakCurtain?: string;
}
export declare const getClassNames: () => IPositioningContainerNames;
@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getClassNames = void 0;
var Utilities_1 = require("../../../Utilities");
var Styling_1 = require("../../../Styling");
exports.getClassNames = (0, Utilities_1.memoizeFunction)(function () {
var _a;
return (0, Styling_1.mergeStyleSets)({
root: [
{
position: 'absolute',
boxSizing: 'border-box',
selectors: (_a = {},
_a[Styling_1.HighContrastSelector] = {
border: '1px solid WindowText',
},
_a),
},
(0, Styling_1.focusClear)(),
],
container: {
position: 'relative',
},
main: {
backgroundColor: '#ffffff',
overflowX: 'hidden',
overflowY: 'hidden',
position: 'relative',
},
overFlowYHidden: {
overflowY: 'hidden',
},
});
});
//# sourceMappingURL=PositioningContainer.styles.js.map
@@ -0,0 +1 @@
{"version":3,"file":"PositioningContainer.styles.js","sourceRoot":"../src/","sources":["components/Coachmark/PositioningContainer/PositioningContainer.styles.ts"],"names":[],"mappings":";;;AAAA,gDAAqD;AACrD,4CAAoF;AAsBvE,QAAA,aAAa,GAAG,IAAA,2BAAe,EAAC;;IAC3C,OAAO,IAAA,wBAAc,EAAC;QACpB,IAAI,EAAE;YACJ;gBACE,QAAQ,EAAE,UAAU;gBACpB,SAAS,EAAE,YAAY;gBACvB,SAAS;oBACP,GAAC,8BAAoB,IAAG;wBACtB,MAAM,EAAE,sBAAsB;qBAC/B;uBACF;aACF;YACD,IAAA,oBAAU,GAAE;SACb;QACD,SAAS,EAAE;YACT,QAAQ,EAAE,UAAU;SACrB;QACD,IAAI,EAAE;YACJ,eAAe,EAAE,SAAS;YAC1B,SAAS,EAAE,QAAQ;YACnB,SAAS,EAAE,QAAQ;YACnB,QAAQ,EAAE,UAAU;SACrB;QACD,eAAe,EAAE;YACf,SAAS,EAAE,QAAQ;SACpB;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { memoizeFunction } from '../../../Utilities';\nimport { mergeStyleSets, focusClear, HighContrastSelector } from '../../../Styling';\nimport type { IStyle } from '../../../Styling';\n\nexport interface IPositioningContainerStyles {\n /**\n * Style for the root element in the default enabled/unchecked state.\n */\n root?: IStyle;\n}\n\nexport interface IPositioningContainerNames {\n /**\n * Root html container for this component.\n */\n root: string;\n container: string;\n main: string;\n overFlowYHidden: string;\n beak?: string;\n beakCurtain?: string;\n}\n\nexport const getClassNames = memoizeFunction((): IPositioningContainerNames => {\n return mergeStyleSets({\n root: [\n {\n position: 'absolute',\n boxSizing: 'border-box',\n selectors: {\n [HighContrastSelector]: {\n border: '1px solid WindowText',\n },\n },\n },\n focusClear(),\n ],\n container: {\n position: 'relative',\n },\n main: {\n backgroundColor: '#ffffff',\n overflowX: 'hidden',\n overflowY: 'hidden',\n position: 'relative',\n },\n overFlowYHidden: {\n overflowY: 'hidden',\n },\n });\n});\n"]}
@@ -0,0 +1,159 @@
import * as React from 'react';
import { DirectionalHint } from '../../../common/DirectionalHint';
import type { IRefObject, IBaseProps, Point, IRectangle } from '../../../Utilities';
import type { IPositionedData } from '../../../Positioning';
import type { Target } from '@fluentui/react-hooks';
import type { ILayerProps } from '../../../Layer';
/**
* {@docCategory Coachmark}
*/
export interface IPositioningContainer {
}
/**
* {@docCategory Coachmark}
*/
export interface IPositioningContainerProps extends IBaseProps<IPositioningContainer>, React.RefAttributes<HTMLDivElement> {
/**
* All props for your component are to be defined here.
*/
componentRef?: IRefObject<IPositioningContainer>;
/**
* The target that the positioningContainer should try to position itself based on.
* It can be either an HTMLElement a querySelector string of a valid HTMLElement
* or a MouseEvent. If MouseEvent is given then the origin point of the event will be used.
*/
target?: Target;
/**
* How the element should be positioned
* @defaultvalue DirectionalHint.BottomAutoEdge
*/
directionalHint?: DirectionalHint;
/**
* How the element should be positioned in RTL layouts.
* If not specified, a mirror of `directionalHint` will be used instead
*/
directionalHintForRTL?: DirectionalHint;
/**
* The gap between the positioningContainer and the target
* @defaultvalue 0
*/
offsetFromTarget?: number;
/**
* Custom width for positioningContainer including borders. If value is 0, no width is applied.
* @defaultvalue 0
*/
positioningContainerWidth?: number;
/**
* The background color of the positioningContainer in hex format ie. #ffffff.
* @defaultvalue $ms-color-white
*/
backgroundColor?: string;
/**
* The bounding rectangle for which the contextual menu can appear in.
*/
bounds?: IRectangle;
/**
* The minimum distance the positioningContainer will be away from the edge of the screen.
* @defaultvalue 8
*/
minPagePadding?: number;
/**
* If true use a point rather than rectangle to position the positioningContainer.
* For example it can be used to position based on a click.
* @deprecated Do not use.
*/
useTargetPoint?: boolean;
/**
* Point used to position the positioningContainer.
* Deprecated, use `target` instead.
* @deprecated Use `target` instead.
*/
targetPoint?: Point;
/**
* If true then the onClose will not not dismiss on scroll
* @defaultvalue false
*/
preventDismissOnScroll?: boolean;
/**
* If true the position returned will have the menu element cover the target.
* If false then it will position next to the target;
* @defaultvalue false
*/
coverTarget?: boolean;
/**
* Aria role assigned to the positioningContainer (Eg. dialog, alertdialog).
*/
role?: string;
/**
* Accessible label text for positioningContainer.
*/
ariaLabel?: string;
/**
* Defines the element id referencing the element containing label text for positioningContainer.
*/
ariaLabelledBy?: string;
/**
* Defines the element id referencing the element containing the description for the positioningContainer.
*/
ariaDescribedBy?: string;
/**
* CSS class to apply to the positioningContainer.
* @defaultvalue null
*/
className?: string;
/**
* Defines an optional set of props to be passed through to Layer
*/
layerProps?: ILayerProps;
/**
* Optional callback when the layer content has mounted.
*/
onLayerMounted?: () => void;
/**
* Optional callback that is called once the positioningContainer has been correctly positioned.
* @param positions - gives the user information about how the container is positioned such
* as the element position, the target edge, and the alignment edge of the container.
*/
onPositioned?: (positions?: IPositionedData) => void;
/**
* Callback when the positioningContainer tries to close.
*/
onDismiss?: (ev?: any) => void;
/**
* If true do not render on a new layer. If false render on a new layer.
*/
doNotLayer?: boolean;
/**
* If true the position will not change sides in an attempt to fit the positioningContainer within bounds.
* It will still attempt to align it to whatever bounds are given.
* @defaultvalue false
*/
directionalHintFixed?: boolean;
/**
* Specify the final height of the content.
* To be used when expanding the content dynamically so that positioningContainer can adjust its position.
*/
finalHeight?: number;
/**
* If true then the positioningContainer will attempt to focus the first focusable element that it contains.
* If it doesn't find an element, no focus will be set and the method will return false.
* This means that it's the contents responsibility to either set focus or have
* focusable items.
* @returns True if focus was set, false if it was not.
*/
setInitialFocus?: boolean;
/**
* Set max height of positioningContainer
* When not set the positioningContainer will expand with contents up to the bottom of the screen
*/
positioningContainerMaxHeight?: number;
/**
* Child nodes to render
*/
children?: React.ReactNode;
}
/**
* @deprecated Use `IPositioningContainerProps`
* {@docCategory Coachmark}
*/
export type IPositioningContainerTypes = IPositioningContainerProps;
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=PositioningContainer.types.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
export * from './PositioningContainer';
export * from './PositioningContainer.types';
@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("./PositioningContainer"), exports);
tslib_1.__exportStar(require("./PositioningContainer.types"), exports);
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/Coachmark/PositioningContainer/index.ts"],"names":[],"mappings":";;;AAAA,iEAAuC;AACvC,uEAA6C","sourcesContent":["export * from './PositioningContainer';\nexport * from './PositioningContainer.types';\n"]}
@@ -0,0 +1,3 @@
export * from './Coachmark';
export * from './Coachmark.base';
export * from './Coachmark.types';
@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("./Coachmark"), exports);
tslib_1.__exportStar(require("./Coachmark.base"), exports);
tslib_1.__exportStar(require("./Coachmark.types"), exports);
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/Coachmark/index.ts"],"names":[],"mappings":";;;AAAA,sDAA4B;AAC5B,2DAAiC;AACjC,4DAAkC","sourcesContent":["export * from './Coachmark';\nexport * from './Coachmark.base';\nexport * from './Coachmark.types';\n"]}