@fluentui/react-tooltip 9.1.5 → 9.1.7
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.json +81 -1
- package/CHANGELOG.md +26 -2
- package/lib/components/Tooltip/Tooltip.js +2 -3
- package/lib/components/Tooltip/Tooltip.js.map +1 -1
- package/lib/components/Tooltip/private/constants.js +0 -1
- package/lib/components/Tooltip/private/constants.js.map +1 -1
- package/lib/components/Tooltip/renderTooltip.js +2 -2
- package/lib/components/Tooltip/renderTooltip.js.map +1 -1
- package/lib/components/Tooltip/useTooltip.js +24 -38
- package/lib/components/Tooltip/useTooltip.js.map +1 -1
- package/lib/components/Tooltip/useTooltipStyles.js +67 -70
- package/lib/components/Tooltip/useTooltipStyles.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib-commonjs/Tooltip.js +0 -2
- package/lib-commonjs/Tooltip.js.map +1 -1
- package/lib-commonjs/components/Tooltip/Tooltip.js +2 -8
- package/lib-commonjs/components/Tooltip/Tooltip.js.map +1 -1
- package/lib-commonjs/components/Tooltip/Tooltip.types.js.map +1 -1
- package/lib-commonjs/components/Tooltip/index.js +0 -6
- package/lib-commonjs/components/Tooltip/index.js.map +1 -1
- package/lib-commonjs/components/Tooltip/private/constants.js +0 -2
- package/lib-commonjs/components/Tooltip/private/constants.js.map +1 -1
- package/lib-commonjs/components/Tooltip/renderTooltip.js +2 -7
- package/lib-commonjs/components/Tooltip/renderTooltip.js.map +1 -1
- package/lib-commonjs/components/Tooltip/useTooltip.js +24 -46
- package/lib-commonjs/components/Tooltip/useTooltip.js.map +1 -1
- package/lib-commonjs/components/Tooltip/useTooltipStyles.js +67 -76
- package/lib-commonjs/components/Tooltip/useTooltipStyles.js.map +1 -1
- package/lib-commonjs/index.js +0 -2
- package/lib-commonjs/index.js.map +1 -1
- package/package.json +7 -7
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"
|
1
|
+
{"version":3,"mappings":"AAAA,SAASA,UAAU,YAAcC,YAAY,QAAQ,gBAAgB;AACrE,SAASC,iBAAiB,QAAQ,6BAA6B;AAC/D,SAASC,MAAM,QAAQ,uBAAuB;AAC9C,SAASC,WAAW,QAAQ,qBAAqB;AAIjD,OAAO,MAAMC,iBAAiB,GAAiC;EAC7DC,OAAO,EAAE;CACV;AAED;;;AAGA,MAAMC,SAAS,gBAAG;EAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;EAAA;EAAA;IAAA;EAAA;EAAA;IAAA;IAAA;EAAA;EAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;EAAA;AAAA;EAAA;AAAA,EAgChB;AAEF;;;AAGA,OAAO,MAAMC,yBAAyB,GAAIC,KAAmB,IAAkB;EAC7E,MAAMC,MAAM,GAAGH,SAAS,EAAE;EAE1BE,KAAK,CAACH,OAAO,CAACK,SAAS,GAAGV,YAAY,CACpCI,iBAAiB,CAACC,OAAO,EACzBI,MAAM,CAACE,IAAI,EACXH,KAAK,CAACI,UAAU,KAAK,UAAU,IAAIH,MAAM,CAACI,QAAQ,EAClDL,KAAK,CAACM,OAAO,IAAIL,MAAM,CAACK,OAAO,EAC/BN,KAAK,CAACH,OAAO,CAACK,SAAS,CACxB;EAEDF,KAAK,CAACO,cAAc,GAAGN,MAAM,CAACO,KAAK;EAEnC,OAAOR,KAAK;AACd,CAAC","names":["shorthands","mergeClasses","createArrowStyles","tokens","arrowHeight","tooltipClassNames","content","useStyles","useTooltipStyles_unstable","state","styles","className","root","appearance","inverted","visible","arrowClassName","arrow"],"sourceRoot":"../src/","sources":["packages/react-components/react-tooltip/src/components/Tooltip/useTooltipStyles.ts"],"sourcesContent":["import { shorthands, makeStyles, mergeClasses } from '@griffel/react';\nimport { createArrowStyles } from '@fluentui/react-positioning';\nimport { tokens } from '@fluentui/react-theme';\nimport { arrowHeight } from './private/constants';\nimport type { TooltipSlots, TooltipState } from './Tooltip.types';\nimport type { SlotClassNames } from '@fluentui/react-utilities';\n\nexport const tooltipClassNames: SlotClassNames<TooltipSlots> = {\n content: 'fui-Tooltip__content',\n};\n\n/**\n * Styles for the tooltip\n */\nconst useStyles = makeStyles({\n root: {\n display: 'none',\n boxSizing: 'border-box',\n maxWidth: '240px',\n cursor: 'default',\n fontFamily: tokens.fontFamilyBase,\n fontSize: tokens.fontSizeBase200,\n lineHeight: tokens.lineHeightBase200,\n\n ...shorthands.borderRadius(tokens.borderRadiusMedium),\n ...shorthands.border('1px', 'solid', tokens.colorTransparentStroke),\n ...shorthands.padding('4px', '11px', '6px', '11px'), // '5px 12px 7px 12px' minus the border width '1px'\n backgroundColor: tokens.colorNeutralBackground1,\n color: tokens.colorNeutralForeground1,\n\n // TODO need to add versions of tokens.alias.shadow.shadow8, etc. that work with filter\n filter:\n `drop-shadow(0 0 2px ${tokens.colorNeutralShadowAmbient}) ` +\n `drop-shadow(0 4px 8px ${tokens.colorNeutralShadowKey})`,\n },\n\n visible: {\n display: 'block',\n },\n\n inverted: {\n backgroundColor: tokens.colorNeutralBackgroundStatic,\n color: tokens.colorNeutralForegroundStaticInverted,\n },\n\n arrow: createArrowStyles({ arrowHeight }),\n});\n\n/**\n * Apply styling to the Tooltip slots based on the state\n */\nexport const useTooltipStyles_unstable = (state: TooltipState): TooltipState => {\n const styles = useStyles();\n\n state.content.className = mergeClasses(\n tooltipClassNames.content,\n styles.root,\n state.appearance === 'inverted' && styles.inverted,\n state.visible && styles.visible,\n state.content.className,\n );\n\n state.arrowClassName = styles.arrow;\n\n return state;\n};\n"]}
|
package/lib/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["packages/react-components/react-tooltip/src/index.ts"],"
|
1
|
+
{"version":3,"mappings":"AAAA,SACEA,OAAO,EACPC,sBAAsB,EACtBC,iBAAiB,EACjBC,yBAAyB,EACzBC,mBAAmB,QACd,WAAW","names":["Tooltip","renderTooltip_unstable","tooltipClassNames","useTooltipStyles_unstable","useTooltip_unstable"],"sourceRoot":"../src/","sources":["packages/react-components/react-tooltip/src/index.ts"],"sourcesContent":["export {\n Tooltip,\n renderTooltip_unstable,\n tooltipClassNames,\n useTooltipStyles_unstable,\n useTooltip_unstable,\n} from './Tooltip';\nexport type {\n OnVisibleChangeData,\n TooltipProps,\n TooltipSlots,\n TooltipState,\n TooltipChildProps as TooltipTriggerProps,\n} from './Tooltip';\n"]}
|
package/lib-commonjs/Tooltip.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["packages/react-components/react-tooltip/src/Tooltip.ts"],"
|
1
|
+
{"version":3,"mappings":";;;;;;AAAAA","names":["tslib_1"],"sourceRoot":"../src/","sources":["packages/react-components/react-tooltip/src/Tooltip.ts"],"sourcesContent":["export * from './components/Tooltip/index';\n"]}
|
@@ -4,25 +4,19 @@ Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
5
5
|
});
|
6
6
|
exports.Tooltip = void 0;
|
7
|
-
|
8
7
|
const useTooltip_1 = /*#__PURE__*/require("./useTooltip");
|
9
|
-
|
10
8
|
const renderTooltip_1 = /*#__PURE__*/require("./renderTooltip");
|
11
|
-
|
12
9
|
const useTooltipStyles_1 = /*#__PURE__*/require("./useTooltipStyles");
|
13
10
|
/**
|
14
11
|
* A tooltip provides light weight contextual information on top of its target element.
|
15
12
|
*/
|
16
|
-
|
17
|
-
|
18
13
|
const Tooltip = props => {
|
19
14
|
const state = useTooltip_1.useTooltip_unstable(props);
|
20
15
|
useTooltipStyles_1.useTooltipStyles_unstable(state);
|
21
16
|
return renderTooltip_1.renderTooltip_unstable(state);
|
22
17
|
};
|
23
|
-
|
24
18
|
exports.Tooltip = Tooltip;
|
25
|
-
exports.Tooltip.displayName = 'Tooltip';
|
26
|
-
|
19
|
+
exports.Tooltip.displayName = 'Tooltip';
|
20
|
+
// type casting here is required to ensure internal type FluentTriggerComponent is not leaked
|
27
21
|
exports.Tooltip.isFluentTriggerComponent = true;
|
28
22
|
//# sourceMappingURL=Tooltip.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"
|
1
|
+
{"version":3,"mappings":";;;;;;AACA;AACA;AACA;AAIA;;;AAGO,MAAMA,OAAO,GAA2BC,KAAK,IAAG;EACrD,MAAMC,KAAK,GAAGC,gCAAmB,CAACF,KAAK,CAAC;EAExCG,4CAAyB,CAACF,KAAK,CAAC;EAChC,OAAOG,sCAAsB,CAACH,KAAK,CAAC;AACtC,CAAC;AALYI,eAAO;AAOpBA,eAAO,CAACC,WAAW,GAAG,SAAS;AAC/B;AACCD,eAAkC,CAACE,wBAAwB,GAAG,IAAI","names":["Tooltip","props","state","useTooltip_1","useTooltipStyles_1","renderTooltip_1","exports","displayName","isFluentTriggerComponent"],"sourceRoot":"../src/","sources":["packages/react-components/react-tooltip/src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useTooltip_unstable } from './useTooltip';\nimport { renderTooltip_unstable } from './renderTooltip';\nimport { useTooltipStyles_unstable } from './useTooltipStyles';\nimport type { TooltipProps } from './Tooltip.types';\nimport type { FluentTriggerComponent } from '@fluentui/react-utilities';\n\n/**\n * A tooltip provides light weight contextual information on top of its target element.\n */\nexport const Tooltip: React.FC<TooltipProps> = props => {\n const state = useTooltip_unstable(props);\n\n useTooltipStyles_unstable(state);\n return renderTooltip_unstable(state);\n};\n\nTooltip.displayName = 'Tooltip';\n// type casting here is required to ensure internal type FluentTriggerComponent is not leaked\n(Tooltip as FluentTriggerComponent).isFluentTriggerComponent = true;\n"]}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"
|
1
|
+
{"version":3,"mappings":"","names":[],"sourceRoot":"../src/","sources":[],"sourcesContent":[]}
|
@@ -3,16 +3,10 @@
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
4
4
|
value: true
|
5
5
|
});
|
6
|
-
|
7
6
|
const tslib_1 = /*#__PURE__*/require("tslib");
|
8
|
-
|
9
7
|
tslib_1.__exportStar(require("./Tooltip"), exports);
|
10
|
-
|
11
8
|
tslib_1.__exportStar(require("./Tooltip.types"), exports);
|
12
|
-
|
13
9
|
tslib_1.__exportStar(require("./renderTooltip"), exports);
|
14
|
-
|
15
10
|
tslib_1.__exportStar(require("./useTooltip"), exports);
|
16
|
-
|
17
11
|
tslib_1.__exportStar(require("./useTooltipStyles"), exports);
|
18
12
|
//# sourceMappingURL=index.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["packages/react-components/react-tooltip/src/components/Tooltip/index.ts"],"
|
1
|
+
{"version":3,"mappings":";;;;;;AAAAA;AACAA;AACAA;AACAA;AACAA","names":["tslib_1"],"sourceRoot":"../src/","sources":["packages/react-components/react-tooltip/src/components/Tooltip/index.ts"],"sourcesContent":["export * from './Tooltip';\nexport * from './Tooltip.types';\nexport * from './renderTooltip';\nexport * from './useTooltip';\nexport * from './useTooltipStyles';\n"]}
|
@@ -7,7 +7,6 @@ exports.tooltipBorderRadius = exports.arrowHeight = void 0;
|
|
7
7
|
/**
|
8
8
|
* The height of the tooltip's arrow in pixels.
|
9
9
|
*/
|
10
|
-
|
11
10
|
exports.arrowHeight = 6;
|
12
11
|
/**
|
13
12
|
* The default value of the tooltip's border radius (borderRadiusMedium).
|
@@ -16,6 +15,5 @@ exports.arrowHeight = 6;
|
|
16
15
|
* While we could use getComputedStyle, that adds a performance penalty for something that
|
17
16
|
* will likely never change.
|
18
17
|
*/
|
19
|
-
|
20
18
|
exports.tooltipBorderRadius = 4;
|
21
19
|
//# sourceMappingURL=constants.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["packages/react-components/react-tooltip/src/components/Tooltip/private/constants.ts"],"
|
1
|
+
{"version":3,"mappings":";;;;;;AAAA;;;AAGaA,mBAAW,GAAG,CAAC;AAE5B;;;;;;;AAOaA,2BAAmB,GAAG,CAAC","names":["exports"],"sourceRoot":"../src/","sources":["packages/react-components/react-tooltip/src/components/Tooltip/private/constants.ts"],"sourcesContent":["/**\n * The height of the tooltip's arrow in pixels.\n */\nexport const arrowHeight = 6;\n\n/**\n * The default value of the tooltip's border radius (borderRadiusMedium).\n *\n * Unfortunately, Popper requires it to be specified as a variable instead of using CSS.\n * While we could use getComputedStyle, that adds a performance penalty for something that\n * will likely never change.\n */\nexport const tooltipBorderRadius = 4;\n"]}
|
@@ -4,17 +4,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
5
5
|
});
|
6
6
|
exports.renderTooltip_unstable = void 0;
|
7
|
-
|
8
7
|
const React = /*#__PURE__*/require("react");
|
9
|
-
|
10
8
|
const react_portal_1 = /*#__PURE__*/require("@fluentui/react-portal");
|
11
|
-
|
12
9
|
const react_utilities_1 = /*#__PURE__*/require("@fluentui/react-utilities");
|
13
10
|
/**
|
14
11
|
* Render the final JSX of Tooltip
|
15
12
|
*/
|
16
|
-
|
17
|
-
|
18
13
|
const renderTooltip_unstable = state => {
|
19
14
|
const {
|
20
15
|
slots,
|
@@ -22,12 +17,12 @@ const renderTooltip_unstable = state => {
|
|
22
17
|
} = react_utilities_1.getSlots(state);
|
23
18
|
return React.createElement(React.Fragment, null, state.children, state.shouldRenderTooltip && React.createElement(react_portal_1.Portal, {
|
24
19
|
mountNode: state.mountNode
|
25
|
-
}, React.createElement(slots.content, {
|
20
|
+
}, React.createElement(slots.content, {
|
21
|
+
...slotProps.content
|
26
22
|
}, state.withArrow && React.createElement("div", {
|
27
23
|
ref: state.arrowRef,
|
28
24
|
className: state.arrowClassName
|
29
25
|
}), state.content.children)));
|
30
26
|
};
|
31
|
-
|
32
27
|
exports.renderTooltip_unstable = renderTooltip_unstable;
|
33
28
|
//# sourceMappingURL=renderTooltip.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"
|
1
|
+
{"version":3,"mappings":";;;;;;AAAA;AACA;AACA;AAGA;;;AAGO,MAAMA,sBAAsB,GAAIC,KAAmB,IAAI;EAC5D,MAAM;IAAEC,KAAK;IAAEC;EAAS,CAAE,GAAGC,0BAAQ,CAAeH,KAAK,CAAC;EAE1D,OACEI,0CACGJ,KAAK,CAACK,QAAQ,EACdL,KAAK,CAACM,mBAAmB,IACxBF,oBAACG,qBAAM;IAACC,SAAS,EAAER,KAAK,CAACQ;EAAS,GAChCJ,oBAACH,KAAK,CAACQ,OAAO;IAAA,GAAKP,SAAS,CAACO;EAAO,GACjCT,KAAK,CAACU,SAAS,IAAIN;IAAKO,GAAG,EAAEX,KAAK,CAACY,QAAQ;IAAEC,SAAS,EAAEb,KAAK,CAACc;EAAc,EAAI,EAChFd,KAAK,CAACS,OAAO,CAACJ,QAAQ,CACT,CAEnB,CACA;AAEP,CAAC;AAhBYU,8BAAsB","names":["renderTooltip_unstable","state","slots","slotProps","react_utilities_1","React","children","shouldRenderTooltip","react_portal_1","mountNode","content","withArrow","ref","arrowRef","className","arrowClassName","exports"],"sourceRoot":"../src/","sources":["packages/react-components/react-tooltip/src/components/Tooltip/renderTooltip.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Portal } from '@fluentui/react-portal';\nimport { getSlots } from '@fluentui/react-utilities';\nimport type { TooltipSlots, TooltipState } from './Tooltip.types';\n\n/**\n * Render the final JSX of Tooltip\n */\nexport const renderTooltip_unstable = (state: TooltipState) => {\n const { slots, slotProps } = getSlots<TooltipSlots>(state);\n\n return (\n <>\n {state.children}\n {state.shouldRenderTooltip && (\n <Portal mountNode={state.mountNode}>\n <slots.content {...slotProps.content}>\n {state.withArrow && <div ref={state.arrowRef} className={state.arrowClassName} />}\n {state.content.children}\n </slots.content>\n </Portal>\n )}\n </>\n );\n};\n"]}
|
@@ -4,17 +4,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
5
5
|
});
|
6
6
|
exports.useTooltip_unstable = void 0;
|
7
|
-
|
8
7
|
const React = /*#__PURE__*/require("react");
|
9
|
-
|
10
8
|
const react_positioning_1 = /*#__PURE__*/require("@fluentui/react-positioning");
|
11
|
-
|
12
9
|
const react_shared_contexts_1 = /*#__PURE__*/require("@fluentui/react-shared-contexts");
|
13
|
-
|
14
10
|
const react_utilities_1 = /*#__PURE__*/require("@fluentui/react-utilities");
|
15
|
-
|
16
11
|
const constants_1 = /*#__PURE__*/require("./private/constants");
|
17
|
-
|
18
12
|
const keyboard_keys_1 = /*#__PURE__*/require("@fluentui/keyboard-keys");
|
19
13
|
/**
|
20
14
|
* Create the state required to render Tooltip.
|
@@ -24,11 +18,8 @@ const keyboard_keys_1 = /*#__PURE__*/require("@fluentui/keyboard-keys");
|
|
24
18
|
*
|
25
19
|
* @param props - props from this instance of Tooltip
|
26
20
|
*/
|
27
|
-
|
28
|
-
|
29
21
|
const useTooltip_unstable = props => {
|
30
22
|
var _a, _b, _c, _d;
|
31
|
-
|
32
23
|
const context = react_shared_contexts_1.useTooltipVisibility_unstable();
|
33
24
|
const isServerSideRender = react_utilities_1.useIsSSR();
|
34
25
|
const {
|
@@ -59,7 +50,6 @@ const useTooltip_unstable = props => {
|
|
59
50
|
visible: newVisible
|
60
51
|
});
|
61
52
|
}
|
62
|
-
|
63
53
|
return newVisible;
|
64
54
|
});
|
65
55
|
}, [clearDelayTimeout, setVisibleInternal, onVisibleChange]);
|
@@ -93,40 +83,35 @@ const useTooltip_unstable = props => {
|
|
93
83
|
offset: 4,
|
94
84
|
...react_positioning_1.resolvePositioningShorthand(state.positioning)
|
95
85
|
};
|
96
|
-
|
97
86
|
if (state.withArrow) {
|
98
87
|
positioningOptions.offset = react_positioning_1.mergeArrowOffset(positioningOptions.offset, constants_1.arrowHeight);
|
99
88
|
}
|
100
|
-
|
101
89
|
const {
|
102
90
|
targetRef,
|
103
91
|
containerRef,
|
104
92
|
arrowRef
|
105
93
|
} = react_positioning_1.usePositioning(positioningOptions);
|
106
94
|
state.content.ref = react_utilities_1.useMergedRefs(state.content.ref, containerRef);
|
107
|
-
state.arrowRef = arrowRef;
|
95
|
+
state.arrowRef = arrowRef;
|
96
|
+
// When this tooltip is visible, hide any other tooltips, and register it
|
108
97
|
// as the visibleTooltip with the TooltipContext.
|
109
98
|
// Also add a listener on document to hide the tooltip if Escape is pressed
|
110
|
-
|
111
99
|
react_utilities_1.useIsomorphicLayoutEffect(() => {
|
112
100
|
var _a;
|
113
|
-
|
114
101
|
if (visible) {
|
115
102
|
const thisTooltip = {
|
116
103
|
hide: () => setVisible(false)
|
117
104
|
};
|
118
105
|
(_a = context.visibleTooltip) === null || _a === void 0 ? void 0 : _a.hide();
|
119
106
|
context.visibleTooltip = thisTooltip;
|
120
|
-
|
121
107
|
const onDocumentKeyDown = ev => {
|
122
108
|
if (ev.key === keyboard_keys_1.Escape) {
|
123
|
-
thisTooltip.hide();
|
109
|
+
thisTooltip.hide();
|
110
|
+
// stop propagation to avoid conflicting with other elements that listen for `Escape`
|
124
111
|
// e,g: Dialog, Popover, Menu
|
125
|
-
|
126
112
|
ev.stopPropagation();
|
127
113
|
}
|
128
114
|
};
|
129
|
-
|
130
115
|
targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.addEventListener('keydown', onDocumentKeyDown, {
|
131
116
|
// As this event is added at targeted document,
|
132
117
|
// we need to capture the event to be sure keydown handling from tooltip happens first
|
@@ -136,80 +121,74 @@ const useTooltip_unstable = props => {
|
|
136
121
|
if (context.visibleTooltip === thisTooltip) {
|
137
122
|
context.visibleTooltip = undefined;
|
138
123
|
}
|
139
|
-
|
140
124
|
targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.removeEventListener('keydown', onDocumentKeyDown, {
|
141
125
|
capture: true
|
142
126
|
});
|
143
127
|
};
|
144
128
|
}
|
145
|
-
}, [context, targetDocument, visible, setVisible]);
|
129
|
+
}, [context, targetDocument, visible, setVisible]);
|
130
|
+
// The focused element gets a blur event when the document loses focus
|
146
131
|
// (e.g. switching tabs in the browser), but we don't want to show the
|
147
132
|
// tooltip again when the document gets focus back. Handle this case by
|
148
133
|
// checking if the blurred element is still the document's activeElement.
|
149
134
|
// See https://github.com/microsoft/fluentui/issues/13541
|
150
|
-
|
151
|
-
|
152
|
-
|
135
|
+
const ignoreNextFocusEventRef = React.useRef(false);
|
136
|
+
// Listener for onPointerEnter and onFocus on the trigger element
|
153
137
|
const onEnterTrigger = React.useCallback(ev => {
|
154
138
|
if (ev.type === 'focus' && ignoreNextFocusEventRef.current) {
|
155
139
|
ignoreNextFocusEventRef.current = false;
|
156
140
|
return;
|
157
|
-
}
|
158
|
-
|
159
|
-
|
141
|
+
}
|
142
|
+
// Show immediately if another tooltip is already visible
|
160
143
|
const delay = context.visibleTooltip ? 0 : state.showDelay;
|
161
144
|
setDelayTimeout(() => {
|
162
145
|
setVisible(true, ev);
|
163
146
|
}, delay);
|
164
147
|
ev.persist(); // Persist the event since the setVisible call will happen asynchronously
|
165
|
-
}, [setDelayTimeout, setVisible, state.showDelay, context]);
|
166
|
-
|
148
|
+
}, [setDelayTimeout, setVisible, state.showDelay, context]);
|
149
|
+
// Listener for onPointerLeave and onBlur on the trigger element
|
167
150
|
const onLeaveTrigger = React.useCallback(ev => {
|
168
151
|
let delay = state.hideDelay;
|
169
|
-
|
170
152
|
if (ev.type === 'blur') {
|
171
153
|
// Hide immediately when losing focus
|
172
154
|
delay = 0;
|
173
155
|
ignoreNextFocusEventRef.current = (targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.activeElement) === ev.target;
|
174
156
|
}
|
175
|
-
|
176
157
|
setDelayTimeout(() => {
|
177
158
|
setVisible(false, ev);
|
178
159
|
}, delay);
|
179
160
|
ev.persist(); // Persist the event since the setVisible call will happen asynchronously
|
180
|
-
}, [setDelayTimeout, setVisible, state.hideDelay, targetDocument]);
|
161
|
+
}, [setDelayTimeout, setVisible, state.hideDelay, targetDocument]);
|
162
|
+
// Cancel the hide timer when the mouse or focus enters the tooltip, and restart it when the mouse or focus leaves.
|
181
163
|
// This keeps the tooltip visible when the mouse is moved over it, or it has focus within.
|
182
|
-
|
183
164
|
state.content.onPointerEnter = react_utilities_1.mergeCallbacks(state.content.onPointerEnter, clearDelayTimeout);
|
184
165
|
state.content.onPointerLeave = react_utilities_1.mergeCallbacks(state.content.onPointerLeave, onLeaveTrigger);
|
185
166
|
state.content.onFocus = react_utilities_1.mergeCallbacks(state.content.onFocus, clearDelayTimeout);
|
186
167
|
state.content.onBlur = react_utilities_1.mergeCallbacks(state.content.onBlur, onLeaveTrigger);
|
187
168
|
const child = react_utilities_1.getTriggerChild(children);
|
188
169
|
const triggerAriaProps = {};
|
189
|
-
|
190
170
|
if (relationship === 'label') {
|
191
171
|
// aria-label only works if the content is a string. Otherwise, need to use aria-labelledby.
|
192
172
|
if (typeof state.content.children === 'string') {
|
193
173
|
triggerAriaProps['aria-label'] = state.content.children;
|
194
174
|
} else {
|
195
|
-
triggerAriaProps['aria-labelledby'] = state.content.id;
|
196
|
-
|
175
|
+
triggerAriaProps['aria-labelledby'] = state.content.id;
|
176
|
+
// Always render the tooltip even if hidden, so that aria-labelledby refers to a valid element
|
197
177
|
state.shouldRenderTooltip = true;
|
198
178
|
}
|
199
179
|
} else if (relationship === 'description') {
|
200
|
-
triggerAriaProps['aria-describedby'] = state.content.id;
|
201
|
-
|
180
|
+
triggerAriaProps['aria-describedby'] = state.content.id;
|
181
|
+
// Always render the tooltip even if hidden, so that aria-describedby refers to a valid element
|
202
182
|
state.shouldRenderTooltip = true;
|
203
|
-
}
|
204
|
-
|
205
|
-
|
183
|
+
}
|
184
|
+
// Don't render the Tooltip in SSR to avoid hydration errors
|
206
185
|
if (isServerSideRender) {
|
207
186
|
state.shouldRenderTooltip = false;
|
208
187
|
}
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
188
|
+
const childTargetRef = react_utilities_1.useMergedRefs(child === null || child === void 0 ? void 0 : child.ref, targetRef);
|
189
|
+
// Apply the trigger props to the child, either by calling the render function, or cloning with the new props
|
190
|
+
state.children = react_utilities_1.applyTriggerPropsToChildren(children, {
|
191
|
+
...triggerAriaProps,
|
213
192
|
...(child === null || child === void 0 ? void 0 : child.props),
|
214
193
|
// If the target prop is not provided, attach targetRef to the trigger element's ref prop
|
215
194
|
ref: positioningOptions.target === undefined ? childTargetRef : child === null || child === void 0 ? void 0 : child.ref,
|
@@ -220,6 +199,5 @@ const useTooltip_unstable = props => {
|
|
220
199
|
});
|
221
200
|
return state;
|
222
201
|
};
|
223
|
-
|
224
202
|
exports.useTooltip_unstable = useTooltip_unstable;
|
225
203
|
//# sourceMappingURL=useTooltip.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["packages/react-components/react-tooltip/src/components/Tooltip/useTooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { mergeArrowOffset, resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';\nimport {\n useTooltipVisibility_unstable as useTooltipVisibility,\n useFluent_unstable as useFluent,\n} from '@fluentui/react-shared-contexts';\nimport {\n applyTriggerPropsToChildren,\n resolveShorthand,\n useControllableState,\n useId,\n useIsomorphicLayoutEffect,\n useIsSSR,\n useMergedRefs,\n useTimeout,\n getTriggerChild,\n mergeCallbacks,\n useEventCallback,\n} from '@fluentui/react-utilities';\nimport type { TooltipProps, TooltipState, TooltipChildProps } from './Tooltip.types';\nimport { arrowHeight, tooltipBorderRadius } from './private/constants';\nimport { Escape } from '@fluentui/keyboard-keys';\n\n/**\n * Create the state required to render Tooltip.\n *\n * The returned state can be modified with hooks such as useTooltipStyles_unstable,\n * before being passed to renderTooltip_unstable.\n *\n * @param props - props from this instance of Tooltip\n */\nexport const useTooltip_unstable = (props: TooltipProps): TooltipState => {\n const context = useTooltipVisibility();\n const isServerSideRender = useIsSSR();\n const { targetDocument } = useFluent();\n const [setDelayTimeout, clearDelayTimeout] = useTimeout();\n\n const {\n appearance = 'normal',\n children,\n content,\n withArrow = false,\n positioning = 'above',\n onVisibleChange,\n relationship,\n showDelay = 250,\n hideDelay = 250,\n mountNode,\n } = props;\n\n const [visible, setVisibleInternal] = useControllableState({ state: props.visible, initialState: false });\n const setVisible = React.useCallback(\n (newVisible: boolean, ev?: React.PointerEvent<HTMLElement> | React.FocusEvent<HTMLElement>) => {\n clearDelayTimeout();\n setVisibleInternal(oldVisible => {\n if (newVisible !== oldVisible) {\n onVisibleChange?.(ev, { visible: newVisible });\n }\n return newVisible;\n });\n },\n [clearDelayTimeout, setVisibleInternal, onVisibleChange],\n );\n\n const state: TooltipState = {\n withArrow,\n positioning,\n showDelay,\n hideDelay,\n relationship,\n visible,\n shouldRenderTooltip: visible,\n appearance,\n mountNode,\n // Slots\n components: {\n content: 'div',\n },\n content: resolveShorthand(content, {\n defaultProps: {\n role: 'tooltip',\n },\n required: true,\n }),\n };\n\n state.content.id = useId('tooltip-', state.content.id);\n\n const positioningOptions = {\n enabled: state.visible,\n arrowPadding: 2 * tooltipBorderRadius,\n position: 'above' as const,\n align: 'center' as const,\n offset: 4,\n ...resolvePositioningShorthand(state.positioning),\n };\n\n if (state.withArrow) {\n positioningOptions.offset = mergeArrowOffset(positioningOptions.offset, arrowHeight);\n }\n\n const {\n targetRef,\n containerRef,\n arrowRef,\n }: {\n targetRef: React.MutableRefObject<unknown>;\n containerRef: React.MutableRefObject<HTMLDivElement>;\n arrowRef: React.MutableRefObject<HTMLDivElement>;\n } = usePositioning(positioningOptions);\n\n state.content.ref = useMergedRefs(state.content.ref, containerRef);\n state.arrowRef = arrowRef;\n\n // When this tooltip is visible, hide any other tooltips, and register it\n // as the visibleTooltip with the TooltipContext.\n // Also add a listener on document to hide the tooltip if Escape is pressed\n useIsomorphicLayoutEffect(() => {\n if (visible) {\n const thisTooltip = { hide: () => setVisible(false) };\n\n context.visibleTooltip?.hide();\n context.visibleTooltip = thisTooltip;\n\n const onDocumentKeyDown = (ev: KeyboardEvent) => {\n if (ev.key === Escape) {\n thisTooltip.hide();\n // stop propagation to avoid conflicting with other elements that listen for `Escape`\n // e,g: Dialog, Popover, Menu\n ev.stopPropagation();\n }\n };\n\n targetDocument?.addEventListener('keydown', onDocumentKeyDown, {\n // As this event is added at targeted document,\n // we need to capture the event to be sure keydown handling from tooltip happens first\n capture: true,\n });\n\n return () => {\n if (context.visibleTooltip === thisTooltip) {\n context.visibleTooltip = undefined;\n }\n\n targetDocument?.removeEventListener('keydown', onDocumentKeyDown, { capture: true });\n };\n }\n }, [context, targetDocument, visible, setVisible]);\n\n // The focused element gets a blur event when the document loses focus\n // (e.g. switching tabs in the browser), but we don't want to show the\n // tooltip again when the document gets focus back. Handle this case by\n // checking if the blurred element is still the document's activeElement.\n // See https://github.com/microsoft/fluentui/issues/13541\n const ignoreNextFocusEventRef = React.useRef(false);\n\n // Listener for onPointerEnter and onFocus on the trigger element\n const onEnterTrigger = React.useCallback(\n (ev: React.PointerEvent<HTMLElement> | React.FocusEvent<HTMLElement>) => {\n if (ev.type === 'focus' && ignoreNextFocusEventRef.current) {\n ignoreNextFocusEventRef.current = false;\n return;\n }\n\n // Show immediately if another tooltip is already visible\n const delay = context.visibleTooltip ? 0 : state.showDelay;\n\n setDelayTimeout(() => {\n setVisible(true, ev);\n }, delay);\n\n ev.persist(); // Persist the event since the setVisible call will happen asynchronously\n },\n [setDelayTimeout, setVisible, state.showDelay, context],\n );\n\n // Listener for onPointerLeave and onBlur on the trigger element\n const onLeaveTrigger = React.useCallback(\n (ev: React.PointerEvent<HTMLElement> | React.FocusEvent<HTMLElement>) => {\n let delay = state.hideDelay;\n\n if (ev.type === 'blur') {\n // Hide immediately when losing focus\n delay = 0;\n\n ignoreNextFocusEventRef.current = targetDocument?.activeElement === ev.target;\n }\n\n setDelayTimeout(() => {\n setVisible(false, ev);\n }, delay);\n\n ev.persist(); // Persist the event since the setVisible call will happen asynchronously\n },\n [setDelayTimeout, setVisible, state.hideDelay, targetDocument],\n );\n\n // Cancel the hide timer when the mouse or focus enters the tooltip, and restart it when the mouse or focus leaves.\n // This keeps the tooltip visible when the mouse is moved over it, or it has focus within.\n state.content.onPointerEnter = mergeCallbacks(state.content.onPointerEnter, clearDelayTimeout);\n state.content.onPointerLeave = mergeCallbacks(state.content.onPointerLeave, onLeaveTrigger);\n state.content.onFocus = mergeCallbacks(state.content.onFocus, clearDelayTimeout);\n state.content.onBlur = mergeCallbacks(state.content.onBlur, onLeaveTrigger);\n\n const child = getTriggerChild(children);\n\n const triggerAriaProps: Pick<TooltipChildProps, 'aria-label' | 'aria-labelledby' | 'aria-describedby'> = {};\n\n if (relationship === 'label') {\n // aria-label only works if the content is a string. Otherwise, need to use aria-labelledby.\n if (typeof state.content.children === 'string') {\n triggerAriaProps['aria-label'] = state.content.children;\n } else {\n triggerAriaProps['aria-labelledby'] = state.content.id;\n // Always render the tooltip even if hidden, so that aria-labelledby refers to a valid element\n state.shouldRenderTooltip = true;\n }\n } else if (relationship === 'description') {\n triggerAriaProps['aria-describedby'] = state.content.id;\n // Always render the tooltip even if hidden, so that aria-describedby refers to a valid element\n state.shouldRenderTooltip = true;\n }\n\n // Don't render the Tooltip in SSR to avoid hydration errors\n if (isServerSideRender) {\n state.shouldRenderTooltip = false;\n }\n\n const childTargetRef = useMergedRefs(child?.ref, targetRef);\n\n // Apply the trigger props to the child, either by calling the render function, or cloning with the new props\n state.children = applyTriggerPropsToChildren(children, {\n ...triggerAriaProps,\n ...child?.props,\n // If the target prop is not provided, attach targetRef to the trigger element's ref prop\n ref: positioningOptions.target === undefined ? childTargetRef : child?.ref,\n onPointerEnter: useEventCallback(mergeCallbacks(child?.props?.onPointerEnter, onEnterTrigger)),\n onPointerLeave: useEventCallback(mergeCallbacks(child?.props?.onPointerLeave, onLeaveTrigger)),\n onFocus: useEventCallback(mergeCallbacks(child?.props?.onFocus, onEnterTrigger)),\n onBlur: useEventCallback(mergeCallbacks(child?.props?.onBlur, onLeaveTrigger)),\n });\n\n return state;\n};\n"],"sourceRoot":"../src/"}
|
1
|
+
{"version":3,"mappings":"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","names":["useTooltip_unstable","props","context","react_shared_contexts_1","isServerSideRender","react_utilities_1","targetDocument","setDelayTimeout","clearDelayTimeout","appearance","children","content","withArrow","positioning","onVisibleChange","relationship","showDelay","hideDelay","mountNode","visible","setVisibleInternal","state","initialState","setVisible","React","useCallback","newVisible","ev","oldVisible","shouldRenderTooltip","components","defaultProps","role","required","id","positioningOptions","enabled","arrowPadding","constants_1","position","align","offset","react_positioning_1","targetRef","containerRef","arrowRef","ref","thisTooltip","hide","visibleTooltip","onDocumentKeyDown","key","keyboard_keys_1","stopPropagation","addEventListener","capture","undefined","removeEventListener","ignoreNextFocusEventRef","useRef","onEnterTrigger","type","current","delay","persist","onLeaveTrigger","activeElement","target","onPointerEnter","onPointerLeave","onFocus","onBlur","child","triggerAriaProps","childTargetRef","exports"],"sourceRoot":"../src/","sources":["packages/react-components/react-tooltip/src/components/Tooltip/useTooltip.tsx"],"sourcesContent":["import * as React from 'react';\nimport { mergeArrowOffset, resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';\nimport {\n useTooltipVisibility_unstable as useTooltipVisibility,\n useFluent_unstable as useFluent,\n} from '@fluentui/react-shared-contexts';\nimport {\n applyTriggerPropsToChildren,\n resolveShorthand,\n useControllableState,\n useId,\n useIsomorphicLayoutEffect,\n useIsSSR,\n useMergedRefs,\n useTimeout,\n getTriggerChild,\n mergeCallbacks,\n useEventCallback,\n} from '@fluentui/react-utilities';\nimport type { TooltipProps, TooltipState, TooltipChildProps } from './Tooltip.types';\nimport { arrowHeight, tooltipBorderRadius } from './private/constants';\nimport { Escape } from '@fluentui/keyboard-keys';\n\n/**\n * Create the state required to render Tooltip.\n *\n * The returned state can be modified with hooks such as useTooltipStyles_unstable,\n * before being passed to renderTooltip_unstable.\n *\n * @param props - props from this instance of Tooltip\n */\nexport const useTooltip_unstable = (props: TooltipProps): TooltipState => {\n const context = useTooltipVisibility();\n const isServerSideRender = useIsSSR();\n const { targetDocument } = useFluent();\n const [setDelayTimeout, clearDelayTimeout] = useTimeout();\n\n const {\n appearance = 'normal',\n children,\n content,\n withArrow = false,\n positioning = 'above',\n onVisibleChange,\n relationship,\n showDelay = 250,\n hideDelay = 250,\n mountNode,\n } = props;\n\n const [visible, setVisibleInternal] = useControllableState({ state: props.visible, initialState: false });\n const setVisible = React.useCallback(\n (newVisible: boolean, ev?: React.PointerEvent<HTMLElement> | React.FocusEvent<HTMLElement>) => {\n clearDelayTimeout();\n setVisibleInternal(oldVisible => {\n if (newVisible !== oldVisible) {\n onVisibleChange?.(ev, { visible: newVisible });\n }\n return newVisible;\n });\n },\n [clearDelayTimeout, setVisibleInternal, onVisibleChange],\n );\n\n const state: TooltipState = {\n withArrow,\n positioning,\n showDelay,\n hideDelay,\n relationship,\n visible,\n shouldRenderTooltip: visible,\n appearance,\n mountNode,\n // Slots\n components: {\n content: 'div',\n },\n content: resolveShorthand(content, {\n defaultProps: {\n role: 'tooltip',\n },\n required: true,\n }),\n };\n\n state.content.id = useId('tooltip-', state.content.id);\n\n const positioningOptions = {\n enabled: state.visible,\n arrowPadding: 2 * tooltipBorderRadius,\n position: 'above' as const,\n align: 'center' as const,\n offset: 4,\n ...resolvePositioningShorthand(state.positioning),\n };\n\n if (state.withArrow) {\n positioningOptions.offset = mergeArrowOffset(positioningOptions.offset, arrowHeight);\n }\n\n const {\n targetRef,\n containerRef,\n arrowRef,\n }: {\n targetRef: React.MutableRefObject<unknown>;\n containerRef: React.MutableRefObject<HTMLDivElement>;\n arrowRef: React.MutableRefObject<HTMLDivElement>;\n } = usePositioning(positioningOptions);\n\n state.content.ref = useMergedRefs(state.content.ref, containerRef);\n state.arrowRef = arrowRef;\n\n // When this tooltip is visible, hide any other tooltips, and register it\n // as the visibleTooltip with the TooltipContext.\n // Also add a listener on document to hide the tooltip if Escape is pressed\n useIsomorphicLayoutEffect(() => {\n if (visible) {\n const thisTooltip = { hide: () => setVisible(false) };\n\n context.visibleTooltip?.hide();\n context.visibleTooltip = thisTooltip;\n\n const onDocumentKeyDown = (ev: KeyboardEvent) => {\n if (ev.key === Escape) {\n thisTooltip.hide();\n // stop propagation to avoid conflicting with other elements that listen for `Escape`\n // e,g: Dialog, Popover, Menu\n ev.stopPropagation();\n }\n };\n\n targetDocument?.addEventListener('keydown', onDocumentKeyDown, {\n // As this event is added at targeted document,\n // we need to capture the event to be sure keydown handling from tooltip happens first\n capture: true,\n });\n\n return () => {\n if (context.visibleTooltip === thisTooltip) {\n context.visibleTooltip = undefined;\n }\n\n targetDocument?.removeEventListener('keydown', onDocumentKeyDown, { capture: true });\n };\n }\n }, [context, targetDocument, visible, setVisible]);\n\n // The focused element gets a blur event when the document loses focus\n // (e.g. switching tabs in the browser), but we don't want to show the\n // tooltip again when the document gets focus back. Handle this case by\n // checking if the blurred element is still the document's activeElement.\n // See https://github.com/microsoft/fluentui/issues/13541\n const ignoreNextFocusEventRef = React.useRef(false);\n\n // Listener for onPointerEnter and onFocus on the trigger element\n const onEnterTrigger = React.useCallback(\n (ev: React.PointerEvent<HTMLElement> | React.FocusEvent<HTMLElement>) => {\n if (ev.type === 'focus' && ignoreNextFocusEventRef.current) {\n ignoreNextFocusEventRef.current = false;\n return;\n }\n\n // Show immediately if another tooltip is already visible\n const delay = context.visibleTooltip ? 0 : state.showDelay;\n\n setDelayTimeout(() => {\n setVisible(true, ev);\n }, delay);\n\n ev.persist(); // Persist the event since the setVisible call will happen asynchronously\n },\n [setDelayTimeout, setVisible, state.showDelay, context],\n );\n\n // Listener for onPointerLeave and onBlur on the trigger element\n const onLeaveTrigger = React.useCallback(\n (ev: React.PointerEvent<HTMLElement> | React.FocusEvent<HTMLElement>) => {\n let delay = state.hideDelay;\n\n if (ev.type === 'blur') {\n // Hide immediately when losing focus\n delay = 0;\n\n ignoreNextFocusEventRef.current = targetDocument?.activeElement === ev.target;\n }\n\n setDelayTimeout(() => {\n setVisible(false, ev);\n }, delay);\n\n ev.persist(); // Persist the event since the setVisible call will happen asynchronously\n },\n [setDelayTimeout, setVisible, state.hideDelay, targetDocument],\n );\n\n // Cancel the hide timer when the mouse or focus enters the tooltip, and restart it when the mouse or focus leaves.\n // This keeps the tooltip visible when the mouse is moved over it, or it has focus within.\n state.content.onPointerEnter = mergeCallbacks(state.content.onPointerEnter, clearDelayTimeout);\n state.content.onPointerLeave = mergeCallbacks(state.content.onPointerLeave, onLeaveTrigger);\n state.content.onFocus = mergeCallbacks(state.content.onFocus, clearDelayTimeout);\n state.content.onBlur = mergeCallbacks(state.content.onBlur, onLeaveTrigger);\n\n const child = getTriggerChild(children);\n\n const triggerAriaProps: Pick<TooltipChildProps, 'aria-label' | 'aria-labelledby' | 'aria-describedby'> = {};\n\n if (relationship === 'label') {\n // aria-label only works if the content is a string. Otherwise, need to use aria-labelledby.\n if (typeof state.content.children === 'string') {\n triggerAriaProps['aria-label'] = state.content.children;\n } else {\n triggerAriaProps['aria-labelledby'] = state.content.id;\n // Always render the tooltip even if hidden, so that aria-labelledby refers to a valid element\n state.shouldRenderTooltip = true;\n }\n } else if (relationship === 'description') {\n triggerAriaProps['aria-describedby'] = state.content.id;\n // Always render the tooltip even if hidden, so that aria-describedby refers to a valid element\n state.shouldRenderTooltip = true;\n }\n\n // Don't render the Tooltip in SSR to avoid hydration errors\n if (isServerSideRender) {\n state.shouldRenderTooltip = false;\n }\n\n const childTargetRef = useMergedRefs(child?.ref, targetRef);\n\n // Apply the trigger props to the child, either by calling the render function, or cloning with the new props\n state.children = applyTriggerPropsToChildren(children, {\n ...triggerAriaProps,\n ...child?.props,\n // If the target prop is not provided, attach targetRef to the trigger element's ref prop\n ref: positioningOptions.target === undefined ? childTargetRef : child?.ref,\n onPointerEnter: useEventCallback(mergeCallbacks(child?.props?.onPointerEnter, onEnterTrigger)),\n onPointerLeave: useEventCallback(mergeCallbacks(child?.props?.onPointerLeave, onLeaveTrigger)),\n onFocus: useEventCallback(mergeCallbacks(child?.props?.onFocus, onEnterTrigger)),\n onBlur: useEventCallback(mergeCallbacks(child?.props?.onBlur, onLeaveTrigger)),\n });\n\n return state;\n};\n"]}
|