@mortenbrudvik/waveui 0.14.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +413 -53
- package/dist/components/data-display/InfoButton.cjs +1 -1
- package/dist/components/data-display/InfoButton.cjs.map +1 -1
- package/dist/components/data-display/InfoButton.mjs +90 -82
- package/dist/components/data-display/InfoButton.mjs.map +1 -1
- package/dist/components/data-display/InfoLabel.cjs +1 -1
- package/dist/components/data-display/InfoLabel.cjs.map +1 -1
- package/dist/components/data-display/InfoLabel.mjs +19 -18
- package/dist/components/data-display/InfoLabel.mjs.map +1 -1
- package/dist/components/data-display/List.cjs +1 -1
- package/dist/components/data-display/List.cjs.map +1 -1
- package/dist/components/data-display/List.mjs +405 -219
- package/dist/components/data-display/List.mjs.map +1 -1
- package/dist/components/data-display/List.registry.cjs +1 -1
- package/dist/components/data-display/List.registry.cjs.map +1 -1
- package/dist/components/data-display/List.registry.mjs +12 -6
- package/dist/components/data-display/List.registry.mjs.map +1 -1
- package/dist/components/feedback/MessageBarGroup.cjs +2 -0
- package/dist/components/feedback/MessageBarGroup.cjs.map +1 -0
- package/dist/components/feedback/MessageBarGroup.mjs +63 -0
- package/dist/components/feedback/MessageBarGroup.mjs.map +1 -0
- package/dist/components/feedback/ProgressBar.cjs +1 -1
- package/dist/components/feedback/ProgressBar.cjs.map +1 -1
- package/dist/components/feedback/ProgressBar.mjs +41 -39
- package/dist/components/feedback/ProgressBar.mjs.map +1 -1
- package/dist/components/feedback/Toaster.cjs +1 -1
- package/dist/components/feedback/Toaster.cjs.map +1 -1
- package/dist/components/feedback/Toaster.mjs +222 -216
- package/dist/components/feedback/Toaster.mjs.map +1 -1
- package/dist/components/input/Combobox.cjs +1 -1
- package/dist/components/input/Combobox.cjs.map +1 -1
- package/dist/components/input/Combobox.mjs +163 -148
- package/dist/components/input/Combobox.mjs.map +1 -1
- package/dist/components/input/Dropdown.cjs +1 -1
- package/dist/components/input/Dropdown.cjs.map +1 -1
- package/dist/components/input/Dropdown.mjs +132 -117
- package/dist/components/input/Dropdown.mjs.map +1 -1
- package/dist/components/input/Listbox.cjs +1 -1
- package/dist/components/input/Listbox.cjs.map +1 -1
- package/dist/components/input/Listbox.mjs +90 -78
- package/dist/components/input/Listbox.mjs.map +1 -1
- package/dist/components/input/Option.cjs +1 -1
- package/dist/components/input/Option.cjs.map +1 -1
- package/dist/components/input/Option.data.cjs +2 -0
- package/dist/components/input/Option.data.cjs.map +1 -0
- package/dist/components/input/Option.data.mjs +114 -0
- package/dist/components/input/Option.data.mjs.map +1 -0
- package/dist/components/input/Option.mjs +21 -17
- package/dist/components/input/Option.mjs.map +1 -1
- package/dist/components/layout/Accordion.cjs +1 -1
- package/dist/components/layout/Accordion.cjs.map +1 -1
- package/dist/components/layout/Accordion.mjs +124 -109
- package/dist/components/layout/Accordion.mjs.map +1 -1
- package/dist/components/layout/Carousel.cjs +1 -1
- package/dist/components/layout/Carousel.cjs.map +1 -1
- package/dist/components/layout/Carousel.mjs +207 -193
- package/dist/components/layout/Carousel.mjs.map +1 -1
- package/dist/components/layout/FlatTree.cjs +2 -0
- package/dist/components/layout/FlatTree.cjs.map +1 -0
- package/dist/components/layout/FlatTree.context.cjs +2 -0
- package/dist/components/layout/FlatTree.context.cjs.map +1 -0
- package/dist/components/layout/FlatTree.context.mjs +20 -0
- package/dist/components/layout/FlatTree.context.mjs.map +1 -0
- package/dist/components/layout/FlatTree.item.cjs +2 -0
- package/dist/components/layout/FlatTree.item.cjs.map +1 -0
- package/dist/components/layout/FlatTree.item.mjs +90 -0
- package/dist/components/layout/FlatTree.item.mjs.map +1 -0
- package/dist/components/layout/FlatTree.mjs +276 -0
- package/dist/components/layout/FlatTree.mjs.map +1 -0
- package/dist/components/layout/TabList.cjs +1 -1
- package/dist/components/layout/TabList.cjs.map +1 -1
- package/dist/components/layout/TabList.mjs +149 -108
- package/dist/components/layout/TabList.mjs.map +1 -1
- package/dist/components/layout/Tree.cjs.map +1 -1
- package/dist/components/layout/Tree.context.cjs +1 -1
- package/dist/components/layout/Tree.context.cjs.map +1 -1
- package/dist/components/layout/Tree.context.mjs +2 -1
- package/dist/components/layout/Tree.context.mjs.map +1 -1
- package/dist/components/layout/Tree.core.cjs +1 -1
- package/dist/components/layout/Tree.core.cjs.map +1 -1
- package/dist/components/layout/Tree.core.mjs +162 -148
- package/dist/components/layout/Tree.core.mjs.map +1 -1
- package/dist/components/layout/Tree.mjs.map +1 -1
- package/dist/components/layout/Tree.selection.cjs +1 -1
- package/dist/components/layout/Tree.selection.cjs.map +1 -1
- package/dist/components/layout/Tree.selection.mjs +11 -57
- package/dist/components/layout/Tree.selection.mjs.map +1 -1
- package/dist/components/layout/useFlatTree.cjs +2 -0
- package/dist/components/layout/useFlatTree.cjs.map +1 -0
- package/dist/components/layout/useFlatTree.mjs +83 -0
- package/dist/components/layout/useFlatTree.mjs.map +1 -0
- package/dist/components/navigation/Menu.popover.cjs +1 -1
- package/dist/components/navigation/Menu.popover.cjs.map +1 -1
- package/dist/components/navigation/Menu.popover.mjs +154 -168
- package/dist/components/navigation/Menu.popover.mjs.map +1 -1
- package/dist/components/navigation/Nav.cjs +1 -1
- package/dist/components/navigation/Nav.cjs.map +1 -1
- package/dist/components/navigation/Nav.mjs +156 -136
- package/dist/components/navigation/Nav.mjs.map +1 -1
- package/dist/components/navigation/NavDrawer.cjs +1 -1
- package/dist/components/navigation/NavDrawer.cjs.map +1 -1
- package/dist/components/navigation/NavDrawer.mjs +48 -45
- package/dist/components/navigation/NavDrawer.mjs.map +1 -1
- package/dist/components/overlays/Dialog.cjs +1 -1
- package/dist/components/overlays/Dialog.cjs.map +1 -1
- package/dist/components/overlays/Dialog.mjs +128 -122
- package/dist/components/overlays/Dialog.mjs.map +1 -1
- package/dist/components/overlays/Dialog.slots.cjs +1 -1
- package/dist/components/overlays/Dialog.slots.cjs.map +1 -1
- package/dist/components/overlays/Dialog.slots.mjs +12 -12
- package/dist/components/overlays/Dialog.slots.mjs.map +1 -1
- package/dist/components/overlays/Drawer.cjs.map +1 -1
- package/dist/components/overlays/Drawer.mjs.map +1 -1
- package/dist/components/overlays/Drawer.panel.cjs +1 -1
- package/dist/components/overlays/Drawer.panel.cjs.map +1 -1
- package/dist/components/overlays/Drawer.panel.mjs +97 -81
- package/dist/components/overlays/Drawer.panel.mjs.map +1 -1
- package/dist/components/overlays/Drawer.root.cjs +1 -1
- package/dist/components/overlays/Drawer.root.cjs.map +1 -1
- package/dist/components/overlays/Drawer.root.mjs +34 -31
- package/dist/components/overlays/Drawer.root.mjs.map +1 -1
- package/dist/components/overlays/Popover.cjs +1 -1
- package/dist/components/overlays/Popover.cjs.map +1 -1
- package/dist/components/overlays/Popover.mjs +231 -216
- package/dist/components/overlays/Popover.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.parts.cjs +1 -1
- package/dist/components/overlays/TeachingPopover.parts.cjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.parts.mjs +199 -177
- package/dist/components/overlays/TeachingPopover.parts.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.root.cjs +1 -1
- package/dist/components/overlays/TeachingPopover.root.cjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.root.mjs +93 -92
- package/dist/components/overlays/TeachingPopover.root.mjs.map +1 -1
- package/dist/components/overlays/Tooltip.cjs +1 -1
- package/dist/components/overlays/Tooltip.cjs.map +1 -1
- package/dist/components/overlays/Tooltip.mjs +66 -61
- package/dist/components/overlays/Tooltip.mjs.map +1 -1
- package/dist/components/provider/WaveProvider.cjs +1 -1
- package/dist/components/provider/WaveProvider.cjs.map +1 -1
- package/dist/components/provider/WaveProvider.mjs +26 -23
- package/dist/components/provider/WaveProvider.mjs.map +1 -1
- package/dist/components/table/DataGrid.cjs +1 -1
- package/dist/components/table/DataGrid.cjs.map +1 -1
- package/dist/components/table/DataGrid.context.cjs +2 -0
- package/dist/components/table/DataGrid.context.cjs.map +1 -0
- package/dist/components/table/DataGrid.context.mjs +74 -0
- package/dist/components/table/DataGrid.context.mjs.map +1 -0
- package/dist/components/table/DataGrid.header.cjs +2 -0
- package/dist/components/table/DataGrid.header.cjs.map +1 -0
- package/dist/components/table/DataGrid.header.mjs +168 -0
- package/dist/components/table/DataGrid.header.mjs.map +1 -0
- package/dist/components/table/DataGrid.mjs +488 -591
- package/dist/components/table/DataGrid.mjs.map +1 -1
- package/dist/components/table/DataGrid.sizing.cjs +2 -0
- package/dist/components/table/DataGrid.sizing.cjs.map +1 -0
- package/dist/components/table/DataGrid.sizing.mjs +187 -0
- package/dist/components/table/DataGrid.sizing.mjs.map +1 -0
- package/dist/components/table/DataGrid.store.cjs +2 -0
- package/dist/components/table/DataGrid.store.cjs.map +1 -0
- package/dist/components/table/DataGrid.store.mjs +108 -0
- package/dist/components/table/DataGrid.store.mjs.map +1 -0
- package/dist/components/table/DataGrid.window.cjs +2 -0
- package/dist/components/table/DataGrid.window.cjs.map +1 -0
- package/dist/components/table/DataGrid.window.mjs +165 -0
- package/dist/components/table/DataGrid.window.mjs.map +1 -0
- package/dist/components/table/Table.cjs +1 -1
- package/dist/components/table/Table.cjs.map +1 -1
- package/dist/components/table/Table.mjs +74 -72
- package/dist/components/table/Table.mjs.map +1 -1
- package/dist/components/table/Table.resize.cjs +2 -0
- package/dist/components/table/Table.resize.cjs.map +1 -0
- package/dist/components/table/Table.resize.mjs +98 -0
- package/dist/components/table/Table.resize.mjs.map +1 -0
- package/dist/components/table/useGridNavigation.cjs +1 -1
- package/dist/components/table/useGridNavigation.cjs.map +1 -1
- package/dist/components/table/useGridNavigation.mjs +343 -140
- package/dist/components/table/useGridNavigation.mjs.map +1 -1
- package/dist/components/table/useTableColumnSizing.cjs +2 -0
- package/dist/components/table/useTableColumnSizing.cjs.map +1 -0
- package/dist/components/table/useTableColumnSizing.mjs +76 -0
- package/dist/components/table/useTableColumnSizing.mjs.map +1 -0
- package/dist/components/table/useTableFeatures.cjs +2 -0
- package/dist/components/table/useTableFeatures.cjs.map +1 -0
- package/dist/components/table/useTableFeatures.mjs +110 -0
- package/dist/components/table/useTableFeatures.mjs.map +1 -0
- package/dist/components/table/useTableSelection.cjs +2 -0
- package/dist/components/table/useTableSelection.cjs.map +1 -0
- package/dist/components/table/useTableSelection.mjs +39 -0
- package/dist/components/table/useTableSelection.mjs.map +1 -0
- package/dist/components/table/useTableSort.cjs +2 -0
- package/dist/components/table/useTableSort.cjs.map +1 -0
- package/dist/components/table/useTableSort.mjs +58 -0
- package/dist/components/table/useTableSort.mjs.map +1 -0
- package/dist/hooks/useActiveDescendant.cjs +1 -1
- package/dist/hooks/useActiveDescendant.cjs.map +1 -1
- package/dist/hooks/useActiveDescendant.mjs +33 -25
- package/dist/hooks/useActiveDescendant.mjs.map +1 -1
- package/dist/hooks/useCollapsePresence.cjs +2 -0
- package/dist/hooks/useCollapsePresence.cjs.map +1 -0
- package/dist/hooks/useCollapsePresence.mjs +21 -0
- package/dist/hooks/useCollapsePresence.mjs.map +1 -0
- package/dist/hooks/useFocusBeforeClose.cjs +2 -0
- package/dist/hooks/useFocusBeforeClose.cjs.map +1 -0
- package/dist/hooks/useFocusBeforeClose.mjs +33 -0
- package/dist/hooks/useFocusBeforeClose.mjs.map +1 -0
- package/dist/hooks/useListbox.cjs +1 -1
- package/dist/hooks/useListbox.cjs.map +1 -1
- package/dist/hooks/useListbox.mjs +140 -130
- package/dist/hooks/useListbox.mjs.map +1 -1
- package/dist/hooks/useMotion.cjs +2 -0
- package/dist/hooks/useMotion.cjs.map +1 -0
- package/dist/hooks/useMotion.mjs +14 -0
- package/dist/hooks/useMotion.mjs.map +1 -0
- package/dist/hooks/usePresenceGroup.cjs +2 -0
- package/dist/hooks/usePresenceGroup.cjs.map +1 -0
- package/dist/hooks/usePresenceGroup.mjs +68 -0
- package/dist/hooks/usePresenceGroup.mjs.map +1 -0
- package/dist/hooks/useRovingTabIndex.cjs +1 -1
- package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
- package/dist/hooks/useRovingTabIndex.mjs +1 -1
- package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
- package/dist/hooks/useSelection.cjs +2 -0
- package/dist/hooks/useSelection.cjs.map +1 -0
- package/dist/hooks/useSelection.mjs +57 -0
- package/dist/hooks/useSelection.mjs.map +1 -0
- package/dist/hooks/useVirtualWindow.cjs +2 -0
- package/dist/hooks/useVirtualWindow.cjs.map +1 -0
- package/dist/hooks/useVirtualWindow.mjs +102 -0
- package/dist/hooks/useVirtualWindow.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2249 -179
- package/dist/index.d.ts +2249 -179
- package/dist/index.mjs +147 -135
- package/dist/lib/classNames.cjs +1 -1
- package/dist/lib/classNames.cjs.map +1 -1
- package/dist/lib/classNames.mjs +125 -95
- package/dist/lib/classNames.mjs.map +1 -1
- package/dist/lib/columnSizing.cjs +2 -0
- package/dist/lib/columnSizing.cjs.map +1 -0
- package/dist/lib/columnSizing.mjs +27 -0
- package/dist/lib/columnSizing.mjs.map +1 -0
- package/dist/lib/flatTree.cjs +2 -0
- package/dist/lib/flatTree.cjs.map +1 -0
- package/dist/lib/flatTree.mjs +118 -0
- package/dist/lib/flatTree.mjs.map +1 -0
- package/dist/lib/motion.cjs +2 -0
- package/dist/lib/motion.cjs.map +1 -0
- package/dist/lib/motion.mjs +43 -0
- package/dist/lib/motion.mjs.map +1 -0
- package/dist/lib/selection.cjs +2 -0
- package/dist/lib/selection.cjs.map +1 -0
- package/dist/lib/selection.mjs +28 -0
- package/dist/lib/selection.mjs.map +1 -0
- package/dist/lib/treeCascade.cjs +2 -0
- package/dist/lib/treeCascade.cjs.map +1 -0
- package/dist/lib/treeCascade.mjs +52 -0
- package/dist/lib/treeCascade.mjs.map +1 -0
- package/dist/lib/virtual.cjs +2 -0
- package/dist/lib/virtual.cjs.map +1 -0
- package/dist/lib/virtual.mjs +54 -0
- package/dist/lib/virtual.mjs.map +1 -0
- package/dist/styles.css +1 -1
- package/package.json +2 -1
|
@@ -5,154 +5,155 @@ import { slotRendersContent as i } from "../../lib/slot.mjs";
|
|
|
5
5
|
import { teachingPopoverClassNames as ee } from "../../lib/classNames.mjs";
|
|
6
6
|
import { useEventCallback as a } from "../../hooks/useEventCallback.mjs";
|
|
7
7
|
import { useControllable as o } from "../../hooks/useControllable.mjs";
|
|
8
|
-
import { useId as
|
|
9
|
-
import { useMergedRefs as
|
|
10
|
-
import { useTargetConflictWarning as
|
|
11
|
-
import { TeachingPopoverContext as
|
|
12
|
-
import { TeachingPopoverSurface as
|
|
13
|
-
import * as
|
|
14
|
-
import { jsx as
|
|
8
|
+
import { useId as s } from "../../hooks/useId.mjs";
|
|
9
|
+
import { useMergedRefs as te } from "../../hooks/useMergedRefs.mjs";
|
|
10
|
+
import { useTargetConflictWarning as ne } from "../../hooks/useResolvedTarget.mjs";
|
|
11
|
+
import { TeachingPopoverContext as re } from "./TeachingPopover.context.mjs";
|
|
12
|
+
import { TeachingPopoverSurface as c, TeachingPopoverTrigger as l, TeachingSurface as ie } from "./TeachingPopover.parts.mjs";
|
|
13
|
+
import * as u from "react";
|
|
14
|
+
import { jsx as ae, jsxs as oe } from "react/jsx-runtime";
|
|
15
15
|
//#region src/components/overlays/TeachingPopover.root.tsx
|
|
16
|
-
var
|
|
17
|
-
function
|
|
16
|
+
var se = "Back", ce = "Next", le = "Done", ue = "Choose step", de = (e, t) => `step ${e + 1} of ${t}`, fe = (e, t) => `Step ${e + 1} of ${t}`;
|
|
17
|
+
function d(e, t) {
|
|
18
18
|
return i(e) ? e : i(t) ? t : void 0;
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function f(e, t) {
|
|
21
21
|
return Number.isFinite(e) ? Math.min(Math.max(Math.trunc(e), 0), t - 1) : 0;
|
|
22
22
|
}
|
|
23
|
-
function
|
|
23
|
+
function pe(n) {
|
|
24
24
|
let r = {
|
|
25
25
|
trigger: !1,
|
|
26
26
|
surface: !1
|
|
27
27
|
};
|
|
28
28
|
if (n == null) return r;
|
|
29
|
-
for (let { node: i } of e(n)) t(i,
|
|
29
|
+
for (let { node: i } of e(n)) t(i, l) ? r.trigger = !0 : t(i, c) && (r.surface = !0);
|
|
30
30
|
return r;
|
|
31
31
|
}
|
|
32
|
-
var
|
|
33
|
-
|
|
34
|
-
let
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
var me = "TeachingPopover.Surface:placement", he = "TeachingPopover.Surface: render one TeachingPopover.Surface in a TeachingPopover; a second Surface renders a second popover.", ge = "TeachingPopover:surface-props", _e = "TeachingPopover: the props of the surface element on TeachingPopover (`className`, `style`, `ref`, `onKeyDown`, `motion` and the other element props) are ignored next to a TeachingPopover.Surface: pass them to the Surface.", p = ({ steps: e, activeStep: t, defaultActiveStep: i, currentStep: c, defaultCurrentStep: l, onStepChange: p, onDismiss: m, onFinish: ve, primaryAction: ye, secondaryAction: be, footerLayout: h = "horizontal", open: xe, defaultOpen: Se, onOpenChange: Ce, closeLabel: g = "Close", labels: _, target: v, positioning: y, side: b = "bottom", align: x = "center", children: S, id: C, className: w, style: T, onKeyDown: E, motion: D, ref: O, ...k }) => {
|
|
33
|
+
ne("TeachingPopover", v, y?.target);
|
|
34
|
+
let A = v === void 0 ? y?.target : v, we = n("TeachingPopover", t, c, "currentStep", "activeStep"), j = n("TeachingPopover", i, l, "defaultCurrentStep", "defaultActiveStep") ?? 0, [M, N, P] = o(we, j, p), F = pe(S), [I, L] = o(xe, Se ?? !F.trigger, Ce), R = s("teaching-popover-title"), [Te, Ee] = u.useState(I), [z, B] = u.useState(!1);
|
|
35
|
+
I !== Te && (Ee(I), I && !P && !Object.is(M, j) && B(!0)), z && (P || Object.is(M, j)) && B(!1), u.useLayoutEffect(() => {
|
|
36
|
+
z && N(j);
|
|
37
37
|
}, [
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
z,
|
|
39
|
+
j,
|
|
40
|
+
N
|
|
41
41
|
]);
|
|
42
|
-
let
|
|
43
|
-
--
|
|
44
|
-
}), []),
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
let V = z ? j : M, H = e.length, U = I && H > 0, W = H > 0 ? f(V, H) : 0, De = H > 0 && W !== V, G = H > 0 ? e[W] : void 0, K = W === 0, q = W === H - 1, J = H > 0 ? (_?.step ?? de)(W, H) : "", Y = G ? d(G.primaryAction, ye) : void 0, Oe = G ? d(G.secondaryAction, be) : void 0, ke = _?.back ?? se, Ae = _?.next ?? ce, je = _?.done ?? le, Me = _?.nav ?? ue, Ne = _?.navButton ?? fe, [Pe, Fe] = u.useState(null), X = F.trigger || Pe !== null, Ie = A === void 0 ? X ? Pe : void 0 : A, Le = u.useRef(null), Re = te(Le, Fe), Z = u.useRef(0), [ze, Be] = u.useState(!1), Ve = u.useCallback(() => (Z.current += 1, Be(!0), () => {
|
|
43
|
+
--Z.current, Z.current === 0 && Be(!1);
|
|
44
|
+
}), []), Q = F.surface || ze;
|
|
45
|
+
u.useEffect(() => {
|
|
46
|
+
Z.current > 1 && r(me, he);
|
|
47
47
|
});
|
|
48
|
-
let He =
|
|
49
|
-
|
|
50
|
-
}),
|
|
51
|
-
|
|
48
|
+
let He = s("teaching-popover"), [Ue, We] = u.useState(void 0), Ge = (Q ? Ue : C || void 0) ?? He, Ke = a(() => L(!0)), qe = a(() => {
|
|
49
|
+
L(!1), m?.();
|
|
50
|
+
}), $ = a(() => {
|
|
51
|
+
L(!1), ve?.(), m?.();
|
|
52
52
|
}), Je = a(() => {
|
|
53
|
-
|
|
53
|
+
K || N(W - 1);
|
|
54
54
|
}), Ye = a(() => {
|
|
55
|
-
|
|
55
|
+
q ? $() : N(W + 1);
|
|
56
56
|
}), Xe = a((e) => {
|
|
57
|
-
if (
|
|
58
|
-
let t =
|
|
59
|
-
t !==
|
|
60
|
-
}), Ze =
|
|
61
|
-
|
|
62
|
-
Ze && r(
|
|
63
|
-
}, [Ze]),
|
|
64
|
-
|
|
57
|
+
if (H === 0) return;
|
|
58
|
+
let t = f(e, H);
|
|
59
|
+
t !== W && N(t);
|
|
60
|
+
}), Ze = Q && (C !== void 0 || w !== void 0 || T !== void 0 || E !== void 0 || D !== void 0 || O !== void 0 || Object.keys(k).length > 0);
|
|
61
|
+
u.useEffect(() => {
|
|
62
|
+
Ze && r(ge, _e);
|
|
63
|
+
}, [Ze]), u.useEffect(() => {
|
|
64
|
+
De && r("TeachingPopover:activeStep-range", `TeachingPopover: activeStep ${V} is out of range for ${H} steps; showing step ${W + 1}.`);
|
|
65
65
|
}, [
|
|
66
|
+
De,
|
|
66
67
|
V,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
B
|
|
68
|
+
H,
|
|
69
|
+
W
|
|
70
70
|
]);
|
|
71
|
-
let
|
|
72
|
-
open:
|
|
73
|
-
shown:
|
|
71
|
+
let Qe = u.useMemo(() => ({
|
|
72
|
+
open: I,
|
|
73
|
+
shown: U,
|
|
74
74
|
requestOpen: Ke,
|
|
75
75
|
dismiss: qe,
|
|
76
|
-
finish:
|
|
77
|
-
count:
|
|
78
|
-
index:
|
|
79
|
-
step:
|
|
80
|
-
isFirst:
|
|
81
|
-
isLast:
|
|
82
|
-
stepPosition:
|
|
76
|
+
finish: $,
|
|
77
|
+
count: H,
|
|
78
|
+
index: W,
|
|
79
|
+
step: G,
|
|
80
|
+
isFirst: K,
|
|
81
|
+
isLast: q,
|
|
82
|
+
stepPosition: J,
|
|
83
83
|
goBack: Je,
|
|
84
84
|
goNext: Ye,
|
|
85
85
|
goToStep: Xe,
|
|
86
|
-
primaryAction:
|
|
87
|
-
secondaryAction:
|
|
88
|
-
footerLayout:
|
|
89
|
-
backLabel:
|
|
90
|
-
nextLabel:
|
|
86
|
+
primaryAction: Y,
|
|
87
|
+
secondaryAction: Oe,
|
|
88
|
+
footerLayout: h,
|
|
89
|
+
backLabel: ke,
|
|
90
|
+
nextLabel: Ae,
|
|
91
91
|
doneLabel: je,
|
|
92
|
-
closeLabel:
|
|
92
|
+
closeLabel: g,
|
|
93
93
|
navLabel: Me,
|
|
94
94
|
navButtonLabel: Ne,
|
|
95
|
-
titleId:
|
|
95
|
+
titleId: R,
|
|
96
96
|
target: Ie,
|
|
97
|
-
side:
|
|
98
|
-
align:
|
|
99
|
-
positioning:
|
|
100
|
-
hasTrigger:
|
|
97
|
+
side: b,
|
|
98
|
+
align: x,
|
|
99
|
+
positioning: y,
|
|
100
|
+
hasTrigger: X,
|
|
101
101
|
triggerElementRef: Re,
|
|
102
102
|
triggerRef: Le,
|
|
103
103
|
surfaceId: Ge,
|
|
104
104
|
setCustomSurfaceId: We,
|
|
105
105
|
registerSurface: Ve
|
|
106
106
|
}), [
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
I,
|
|
108
|
+
U,
|
|
109
109
|
Ke,
|
|
110
110
|
qe,
|
|
111
|
-
|
|
112
|
-
R,
|
|
113
|
-
B,
|
|
111
|
+
$,
|
|
114
112
|
H,
|
|
115
|
-
U,
|
|
116
113
|
W,
|
|
117
|
-
Ae,
|
|
118
|
-
Je,
|
|
119
|
-
Ye,
|
|
120
|
-
Xe,
|
|
121
114
|
G,
|
|
122
115
|
K,
|
|
123
|
-
m,
|
|
124
116
|
q,
|
|
125
117
|
J,
|
|
126
|
-
|
|
118
|
+
Je,
|
|
119
|
+
Ye,
|
|
120
|
+
Xe,
|
|
121
|
+
Y,
|
|
122
|
+
Oe,
|
|
127
123
|
h,
|
|
124
|
+
ke,
|
|
125
|
+
Ae,
|
|
126
|
+
je,
|
|
127
|
+
g,
|
|
128
128
|
Me,
|
|
129
129
|
Ne,
|
|
130
|
-
|
|
130
|
+
R,
|
|
131
131
|
Ie,
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
b,
|
|
133
|
+
x,
|
|
134
|
+
y,
|
|
135
|
+
X,
|
|
136
136
|
Re,
|
|
137
137
|
Ge,
|
|
138
138
|
Ve
|
|
139
139
|
]);
|
|
140
|
-
return /* @__PURE__ */
|
|
141
|
-
value:
|
|
142
|
-
children: [
|
|
143
|
-
context:
|
|
140
|
+
return /* @__PURE__ */ oe(re.Provider, {
|
|
141
|
+
value: Qe,
|
|
142
|
+
children: [S, Q ? null : /* @__PURE__ */ ae(ie, {
|
|
143
|
+
context: Qe,
|
|
144
144
|
rootClassName: ee.root,
|
|
145
|
-
id:
|
|
146
|
-
className:
|
|
147
|
-
style:
|
|
148
|
-
onKeyDown:
|
|
149
|
-
|
|
150
|
-
|
|
145
|
+
id: C,
|
|
146
|
+
className: w,
|
|
147
|
+
style: T,
|
|
148
|
+
onKeyDown: E,
|
|
149
|
+
motion: D,
|
|
150
|
+
...k,
|
|
151
|
+
ref: O
|
|
151
152
|
})]
|
|
152
153
|
});
|
|
153
154
|
};
|
|
154
|
-
|
|
155
|
+
p.displayName = "TeachingPopover";
|
|
155
156
|
//#endregion
|
|
156
|
-
export {
|
|
157
|
+
export { p as TeachingPopoverRoot };
|
|
157
158
|
|
|
158
159
|
//# sourceMappingURL=TeachingPopover.root.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeachingPopover.root.mjs","names":["useId","useId$1","React","DEFAULT_BACK_LABEL","DEFAULT_NEXT_LABEL","DEFAULT_DONE_LABEL","DEFAULT_NAV_LABEL","defaultStepLabel","index","count","defaultNavButtonLabel","pickAction","slotRendersContent","own","fallback","clampStep","step","findParts","found","children","flattenChildren","isElementOfType","node","TeachingPopoverTrigger","TeachingPopoverSurface","SURFACE_PLACEMENT_WARNING_KEY","SURFACE_PLACEMENT_WARNING","SURFACE_PROPS_WARNING_KEY","SURFACE_PROPS_WARNING","TeachingPopoverRoot","activeStepProp","primaryActionProp","secondaryActionProp","openProp","targetProp","rest","positioning","explicitTarget","controlledStep","resolveDeprecatedProp","currentStep","initialStep","defaultActiveStep","defaultCurrentStep","storedStep","setStep","stepControlled","useControllable","onStepChange","parts","open","setOpen","defaultOpen","onOpenChange","titleId","openSeen","setOpenSeen","stepResetPending","setStepResetPending","rawStep","steps","shown","outOfRange","isFirst","isLast","stepPosition","labels","primaryAction","secondaryAction","backLabel","nextLabel","doneLabel","navLabel","navButtonLabel","triggerElement","setTriggerElement","hasTrigger","target","triggerRef","triggerElementRef","useMergedRefs","surfaceCountRef","hasRegisteredSurface","setHasRegisteredSurface","registerSurface","hasSurfacePart","warnOnce","generatedSurfaceId","customSurfaceId","setCustomSurfaceId","surfaceId","id","requestOpen","useEventCallback","dismiss","onDismiss","finish","onFinish","goBack","goNext","goToStep","next","ignoresSurfaceProps","className","style","onKeyDown","ref","context","footerLayout","closeLabel","side","align","TeachingPopoverContext","TeachingSurface","teachingPopoverClassNames"],"sources":["../../../src/components/overlays/TeachingPopover.root.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { teachingPopoverClassNames } from '../../lib/classNames';\nimport { resolveDeprecatedProp, warnOnce } from '../../lib/dev';\nimport { slotRendersContent } from '../../lib/slot';\nimport type { PopupAlign, PopupPositioning, PopupSide, VirtualElement } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useTargetConflictWarning } from '../../hooks/useResolvedTarget';\nimport {\n TeachingPopoverContext,\n type TeachingPopoverAction,\n type TeachingPopoverContextValue,\n type TeachingPopoverLabels,\n type TeachingPopoverStep,\n} from './TeachingPopover.context';\nimport {\n TeachingPopoverSurface,\n TeachingPopoverTrigger,\n TeachingSurface,\n} from './TeachingPopover.parts';\n\n/*\n * The TeachingPopover root: its props, the state of both forms (the open state, the step and the\n * step's resolved content), the child scan for the Trigger and the Surface, and the surface it\n * renders when no Surface is among its children. Imports the context and parts modules (never\n * `TeachingPopover.tsx`, which holds the compound).\n */\n\nconst DEFAULT_BACK_LABEL = 'Back';\nconst DEFAULT_NEXT_LABEL = 'Next';\nconst DEFAULT_DONE_LABEL = 'Done';\nconst DEFAULT_NAV_LABEL = 'Choose step';\nconst defaultStepLabel = (index: number, count: number) => `step ${index + 1} of ${count}`;\nconst defaultNavButtonLabel = (index: number, count: number) => `Step ${index + 1} of ${count}`;\n\n/** Properties for the TeachingPopover component. */\nexport interface TeachingPopoverProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Steps to display in the teaching popover (a readonly array is accepted). */\n steps: readonly TeachingPopoverStep[];\n /**\n * Controlled index of the displayed step. Out-of-range values are clamped to the first or last\n * step (with a development warning). Opening the popover leaves it as it is.\n */\n activeStep?: number;\n /**\n * Initial step index for uncontrolled usage, and the step the popover starts on again each time\n * it opens (after Done, Close, Escape or the Trigger closed it, or a controlled `open` turned it\n * off), so a tour opened again starts over; `onStepChange` is called with it when the step was\n * elsewhere.\n * @default 0\n */\n defaultActiveStep?: number;\n /** @deprecated Use `activeStep`. */\n currentStep?: number;\n /** @deprecated Use `defaultActiveStep`. */\n defaultCurrentStep?: number;\n /**\n * Called with the requested step index when Next, Back or a step button of\n * `TeachingPopover.CarouselNav` is activated (the button of the current step requests nothing),\n * and, while the step is uncontrolled, with the initial step when an opening moves the step back\n * to it (see `defaultActiveStep`).\n */\n onStepChange?: (step: number) => void;\n /**\n * Called when the popover is dismissed with Close, Done, Escape or a `TeachingPopover.Trigger`\n * that closes it.\n *\n * Done also calls it in 0.x, after `onFinish`, so that code written before `onFinish` keeps\n * working; from 1.0 only Close, Escape and the Trigger will.\n */\n onDismiss?: () => void;\n /**\n * Called when the tour is finished: Done, the button that replaces Next on the last step, or a\n * `primaryAction` on the last step whose click was not prevented. The popover closes first.\n * Close, Escape and the Trigger call only `onDismiss`. Fires on every activation, like\n * `onStepChange`.\n */\n onFinish?: () => void;\n /**\n * Replaces the Next (or Done) button on every step that sets no `primaryAction` of its own.\n */\n primaryAction?: TeachingPopoverAction;\n /**\n * Replaces the Back button on every step that sets no `secondaryAction` of its own.\n */\n secondaryAction?: TeachingPopoverAction;\n /**\n * How the footer lays out the step dots and the buttons: side by side, or the dots above\n * buttons that fill the width. Rendered as `data-layout` on the popover and on its footer.\n * `TeachingPopover.CarouselFooter` has its own `layout` instead.\n * @default 'horizontal'\n */\n footerLayout?: 'horizontal' | 'vertical';\n /** Controlled visibility of the teaching popover. */\n open?: boolean;\n /**\n * Initial visibility for uncontrolled usage: `true` (a tour that shows on page load), or\n * `false` when a `TeachingPopover.Trigger` is a direct child (a Fragment is fine), which then\n * opens it.\n * @default true (false with a direct TeachingPopover.Trigger)\n */\n defaultOpen?: boolean;\n /**\n * Called with `false` when Close, Done or Escape dismisses the popover, and with the new state\n * when a `TeachingPopover.Trigger` opens or closes it.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Accessible name of the built-in Close button (an icon-only button). Localize it with the\n * page's language.\n * @default 'Close'\n */\n closeLabel?: string;\n /**\n * Text of the Back, Next and Done buttons, the wording of the step position (“step 2 of 3”) and\n * the names of `TeachingPopover.CarouselNav`'s step buttons, for localization. Unset members keep\n * their English defaults.\n */\n labels?: TeachingPopoverLabels;\n /**\n * The element the popover points at (a ref, the element, or a `VirtualElement`: a rectangle such as a\n * point; an inline object is fine). When given, the popover is\n * rendered in a portal, positioned next to it with a beak, and flips or shifts to stay in view;\n * without it (`undefined`) the popover renders inline where it is placed (0.4 behaviour), or,\n * with a `TeachingPopover.Trigger`, points at the trigger.\n * While the target is `null` or has not been positioned against yet (an element held in state\n * that is not set yet, a ref that is not attached), the popover stays hidden: it is not\n * shown, takes no focus, announces no step change and does not handle Escape until it can\n * point at the target. It hides the same way when the target goes away later and shows again\n * when a target returns.\n *\n * An element (for example one held in state through a callback ref) is followed as soon as the\n * prop changes. A ref cannot be observed, so it is read after each render of the popover is\n * committed, wherever the target is in the tree: an element attaching to or detaching from the\n * ref is noticed the next time the popover renders (for example when the parent that mounts or\n * unmounts the target re-renders it), not in a commit that does not render the popover. A\n * memoized popover whose target mounts or unmounts in another subtree therefore stays hidden,\n * or keeps pointing at the removed element, until it renders again. A newly passed ref keeps\n * the previous visibility until it has been read, so a tour can move between attached refs\n * (`target={step === 0 ? aRef : bRef}`) without hiding, and a switch to a ref that is not\n * attached hides the popover right after that commit. Pass the element held in state when the\n * target can mount or unmount without the popover re-rendering.\n */\n target?: React.RefObject<HTMLElement | null> | HTMLElement | VirtualElement | null;\n /** Side of the `target` to open on; `start`/`end` follow the writing direction.\n * @default 'bottom'\n */\n side?: PopupSide;\n /** Alignment along the `target`'s edge.\n * @default 'center'\n */\n align?: PopupAlign;\n /**\n * Advanced positioning (Fluent's `positioning`): `offset`, `fitViewport`, `matchReferenceWidth`,\n * `fallbackPlacements` and `target` (used when the `target` prop is not set). `side` and `align`\n * stay separate props.\n * @default `{ offset: 12 }`\n */\n positioning?: PopupPositioning;\n /**\n * `TeachingPopover.Trigger` and `TeachingPopover.Surface` (Fluent's composition), rendered where\n * they are written. Without a `TeachingPopover.Surface` among them, the popover renders its\n * surface itself, after the children, with the element props given here (`className`, `style`,\n * `ref`, …); with one (best written directly inside, a Fragment is fine: see\n * `TeachingPopover.Surface`), the Surface takes them instead.\n */\n children?: React.ReactNode;\n /**\n * Ref to the popover surface (`role=\"dialog\"`). Ignored next to a `TeachingPopover.Surface`\n * (pass it to the Surface).\n */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** The action a step shows: its own when it renders anything, else the popover's. */\nfunction pickAction(\n own: TeachingPopoverAction | undefined,\n fallback: TeachingPopoverAction | undefined,\n): TeachingPopoverAction | undefined {\n if (slotRendersContent(own)) return own;\n return slotRendersContent(fallback) ? fallback : undefined;\n}\n\nfunction clampStep(step: number, count: number): number {\n if (!Number.isFinite(step)) return 0;\n return Math.min(Math.max(Math.trunc(step), 0), count - 1);\n}\n\n/**\n * Which parts are direct children (Fragments flattened, lazy types of a Server Component\n * unwrapped): a Trigger closes `defaultOpen`, a Surface replaces the root's own surface. Runs\n * during render, so the server HTML agrees (a Surface deeper down registers once mounted).\n */\nfunction findParts(children: React.ReactNode): { trigger: boolean; surface: boolean } {\n const found = { trigger: false, surface: false };\n if (children === null || children === undefined) return found;\n for (const { node } of flattenChildren(children)) {\n if (isElementOfType(node, TeachingPopoverTrigger)) found.trigger = true;\n else if (isElementOfType(node, TeachingPopoverSurface)) found.surface = true;\n }\n return found;\n}\n\nconst SURFACE_PLACEMENT_WARNING_KEY = 'TeachingPopover.Surface:placement';\nconst SURFACE_PLACEMENT_WARNING =\n 'TeachingPopover.Surface: render one TeachingPopover.Surface in a TeachingPopover; a second Surface renders a second popover.';\n\nconst SURFACE_PROPS_WARNING_KEY = 'TeachingPopover:surface-props';\nconst SURFACE_PROPS_WARNING =\n 'TeachingPopover: the props of the surface element on TeachingPopover (`className`, `style`, `ref`, `onKeyDown` and the other element props) are ignored next to a TeachingPopover.Surface: pass them to the Surface.';\n\n// The root of `TeachingPopover` (documented on the export in TeachingPopover.tsx).\nexport const TeachingPopoverRoot = ({\n steps,\n activeStep: activeStepProp,\n defaultActiveStep,\n currentStep,\n defaultCurrentStep,\n onStepChange,\n onDismiss,\n onFinish,\n primaryAction: primaryActionProp,\n secondaryAction: secondaryActionProp,\n footerLayout = 'horizontal',\n open: openProp,\n defaultOpen,\n onOpenChange,\n closeLabel = 'Close',\n labels,\n target: targetProp,\n positioning,\n side = 'bottom',\n align = 'center',\n children,\n id,\n className,\n style,\n onKeyDown,\n ref,\n ...rest\n}: TeachingPopoverProps) => {\n useTargetConflictWarning('TeachingPopover', targetProp, positioning?.target);\n const explicitTarget = (\n targetProp !== undefined ? targetProp : positioning?.target\n ) as TeachingPopoverProps['target'];\n const controlledStep = resolveDeprecatedProp(\n 'TeachingPopover',\n activeStepProp,\n currentStep,\n 'currentStep',\n 'activeStep',\n );\n const initialStep =\n resolveDeprecatedProp(\n 'TeachingPopover',\n defaultActiveStep,\n defaultCurrentStep,\n 'defaultCurrentStep',\n 'defaultActiveStep',\n ) ?? 0;\n const [storedStep, setStep, stepControlled] = useControllable(\n controlledStep,\n initialStep,\n onStepChange,\n );\n const parts = findParts(children);\n const [open, setOpen] = useControllable(openProp, defaultOpen ?? !parts.trigger, onOpenChange);\n const titleId = useId('teaching-popover-title');\n\n // An uncontrolled step starts again at the initial step each time the popover opens (not on\n // mount), whatever closed it and whatever opens it. The opening is noticed during render (C-HOOKS:\n // a previous-value state), so the opened popover shows the initial step from its first render;\n // the layout effect stores it through the setter (which calls `onStepChange` once, from the\n // commit), and the render that reads it back ends the reset.\n const [openSeen, setOpenSeen] = React.useState(open);\n const [stepResetPending, setStepResetPending] = React.useState(false);\n if (open !== openSeen) {\n setOpenSeen(open);\n if (open && !stepControlled && !Object.is(storedStep, initialStep)) {\n setStepResetPending(true);\n }\n }\n if (stepResetPending && (stepControlled || Object.is(storedStep, initialStep))) {\n setStepResetPending(false);\n }\n React.useLayoutEffect(() => {\n if (stepResetPending) setStep(initialStep);\n }, [stepResetPending, initialStep, setStep]);\n const rawStep = stepResetPending ? initialStep : storedStep;\n\n const count = steps.length;\n const shown = open && count > 0;\n const index = count > 0 ? clampStep(rawStep, count) : 0;\n const outOfRange = count > 0 && index !== rawStep;\n const step = count > 0 ? steps[index] : undefined;\n const isFirst = index === 0;\n const isLast = index === count - 1;\n const stepPosition = count > 0 ? (labels?.step ?? defaultStepLabel)(index, count) : '';\n const primaryAction = step ? pickAction(step.primaryAction, primaryActionProp) : undefined;\n const secondaryAction = step ? pickAction(step.secondaryAction, secondaryActionProp) : undefined;\n const backLabel = labels?.back ?? DEFAULT_BACK_LABEL;\n const nextLabel = labels?.next ?? DEFAULT_NEXT_LABEL;\n const doneLabel = labels?.done ?? DEFAULT_DONE_LABEL;\n const navLabel = labels?.nav ?? DEFAULT_NAV_LABEL;\n const navButtonLabel = labels?.navButton ?? defaultNavButtonLabel;\n\n // A Trigger is the target when neither `target` nor `positioning.target` is set: a direct one\n // from the first render (the surface stays hidden until its element attaches), a nested one\n // once its element has attached.\n const [triggerElement, setTriggerElement] = React.useState<HTMLElement | null>(null);\n const hasTrigger = parts.trigger || triggerElement !== null;\n const target =\n explicitTarget !== undefined ? explicitTarget : hasTrigger ? triggerElement : undefined;\n // The Trigger's element also as a ref, where the surface returns focus.\n const triggerRef = React.useRef<HTMLElement | null>(null);\n const triggerElementRef = useMergedRefs<HTMLElement>(triggerRef, setTriggerElement);\n\n // Surfaces (TeachingPopover.Surface) register while mounted, wherever they are among the\n // children: once one has, the root renders no surface of its own. A direct one is also found by\n // the scan above, so it never renders next to the root's own; one inside a component of yours\n // does in its first commit, until its registration re-renders the root. After every commit\n // (every surface's layout effect has run) more than one warns.\n const surfaceCountRef = React.useRef(0);\n const [hasRegisteredSurface, setHasRegisteredSurface] = React.useState(false);\n const registerSurface = React.useCallback(() => {\n surfaceCountRef.current += 1;\n setHasRegisteredSurface(true);\n return () => {\n surfaceCountRef.current -= 1;\n if (surfaceCountRef.current === 0) setHasRegisteredSurface(false);\n };\n }, []);\n const hasSurfacePart = parts.surface || hasRegisteredSurface;\n React.useEffect(() => {\n if (surfaceCountRef.current > 1) {\n warnOnce(SURFACE_PLACEMENT_WARNING_KEY, SURFACE_PLACEMENT_WARNING);\n }\n });\n\n // The Trigger's `aria-controls`: the surface's id (the root's own `id` on its own surface, or\n // the id a Surface reports), else a generated one.\n const generatedSurfaceId = useId('teaching-popover');\n const [customSurfaceId, setCustomSurfaceId] = React.useState<string | undefined>(undefined);\n const surfaceId = (hasSurfacePart ? customSurfaceId : id || undefined) ?? generatedSurfaceId;\n\n const requestOpen = useEventCallback(() => setOpen(true));\n const dismiss = useEventCallback(() => {\n setOpen(false);\n onDismiss?.();\n });\n // Done: close, then `onFinish`. `onDismiss` still follows in 0.x (see its JSDoc).\n const finish = useEventCallback(() => {\n setOpen(false);\n onFinish?.();\n onDismiss?.();\n });\n const goBack = useEventCallback(() => {\n if (!isFirst) setStep(index - 1);\n });\n const goNext = useEventCallback(() => {\n if (isLast) finish();\n else setStep(index + 1);\n });\n // A step button of TeachingPopover.CarouselNav: the shown (clamped) step requests nothing.\n const goToStep = useEventCallback((target: number) => {\n if (count === 0) return;\n const next = clampStep(target, count);\n if (next !== index) setStep(next);\n });\n\n // Next to a Surface the root renders no surface element, so its element props go nowhere.\n const ignoresSurfaceProps =\n hasSurfacePart &&\n (id !== undefined ||\n className !== undefined ||\n style !== undefined ||\n onKeyDown !== undefined ||\n ref !== undefined ||\n Object.keys(rest).length > 0);\n React.useEffect(() => {\n if (ignoresSurfaceProps) warnOnce(SURFACE_PROPS_WARNING_KEY, SURFACE_PROPS_WARNING);\n }, [ignoresSurfaceProps]);\n\n React.useEffect(() => {\n if (!outOfRange) return;\n warnOnce(\n 'TeachingPopover:activeStep-range',\n `TeachingPopover: activeStep ${rawStep} is out of range for ${count} steps; showing step ${index + 1}.`,\n );\n }, [outOfRange, rawStep, count, index]);\n\n const context = React.useMemo<TeachingPopoverContextValue>(\n () => ({\n open,\n shown,\n requestOpen,\n dismiss,\n finish,\n count,\n index,\n step,\n isFirst,\n isLast,\n stepPosition,\n goBack,\n goNext,\n goToStep,\n primaryAction,\n secondaryAction,\n footerLayout,\n backLabel,\n nextLabel,\n doneLabel,\n closeLabel,\n navLabel,\n navButtonLabel,\n titleId,\n target,\n side,\n align,\n positioning,\n hasTrigger,\n triggerElementRef,\n triggerRef,\n surfaceId,\n setCustomSurfaceId,\n registerSurface,\n }),\n [\n open,\n shown,\n requestOpen,\n dismiss,\n finish,\n count,\n index,\n step,\n isFirst,\n isLast,\n stepPosition,\n goBack,\n goNext,\n goToStep,\n primaryAction,\n secondaryAction,\n footerLayout,\n backLabel,\n nextLabel,\n doneLabel,\n closeLabel,\n navLabel,\n navButtonLabel,\n titleId,\n target,\n side,\n align,\n positioning,\n hasTrigger,\n triggerElementRef,\n surfaceId,\n registerSurface,\n ],\n );\n\n return (\n <TeachingPopoverContext.Provider value={context}>\n {children}\n {hasSurfacePart ? null : (\n <TeachingSurface\n context={context}\n rootClassName={teachingPopoverClassNames.root}\n id={id}\n className={className}\n style={style}\n onKeyDown={onKeyDown}\n {...rest}\n ref={ref}\n />\n )}\n </TeachingPopoverContext.Provider>\n );\n};\nTeachingPopoverRoot.displayName = 'TeachingPopover';\n"],"mappings":"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AACsD;EAAYH;EAASlD;EAAOD;CAAK,CAAC;CAEtC,IAAMmG,IAAUzG,EAAM,eACb;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,IACA;EACEgD;EACAW;EACA+B;EACAE;EACAE;EACAvF;EACAD;EACAQ;EACA+C;EACAC;EACAC;EACAiC;EACAC;EACAC;EACAjC;EACAC;EACAwC;EACAvC;EACAC;EACAC;EACAsC;EACArC;EACAC;EACAnB;EACAuB;EACAiC;EACAC;EACA3E;EACAwC;EACAG;EACAW;EACAN;CACF,CACF;CAEA,OACE,mBAAC4B,GAAuB,UAAxB;EAAiC,OAAOL;EAAxC,UAAA,CACGxF,GACAkE,IAAiB,OAChB,mBAAC4B,IAAD;GACW;GACT,eAAeC,GAA0B;GACrC;GACO;GACJ;GACI;GACX,GAAI/E;GACC;EACN,CAAA,CAE4B;;AAErC;AACA,EAAoB,cAAc"}
|
|
1
|
+
{"version":3,"file":"TeachingPopover.root.mjs","names":["useId","useId$1","React","DEFAULT_BACK_LABEL","DEFAULT_NEXT_LABEL","DEFAULT_DONE_LABEL","DEFAULT_NAV_LABEL","defaultStepLabel","index","count","defaultNavButtonLabel","pickAction","slotRendersContent","own","fallback","clampStep","step","findParts","found","children","flattenChildren","isElementOfType","node","TeachingPopoverTrigger","TeachingPopoverSurface","SURFACE_PLACEMENT_WARNING_KEY","SURFACE_PLACEMENT_WARNING","SURFACE_PROPS_WARNING_KEY","SURFACE_PROPS_WARNING","TeachingPopoverRoot","activeStepProp","primaryActionProp","secondaryActionProp","openProp","targetProp","rest","positioning","explicitTarget","controlledStep","resolveDeprecatedProp","currentStep","initialStep","defaultActiveStep","defaultCurrentStep","storedStep","setStep","stepControlled","useControllable","onStepChange","parts","open","setOpen","defaultOpen","onOpenChange","titleId","openSeen","setOpenSeen","stepResetPending","setStepResetPending","rawStep","steps","shown","outOfRange","isFirst","isLast","stepPosition","labels","primaryAction","secondaryAction","backLabel","nextLabel","doneLabel","navLabel","navButtonLabel","triggerElement","setTriggerElement","hasTrigger","target","triggerRef","triggerElementRef","useMergedRefs","surfaceCountRef","hasRegisteredSurface","setHasRegisteredSurface","registerSurface","hasSurfacePart","warnOnce","generatedSurfaceId","customSurfaceId","setCustomSurfaceId","surfaceId","id","requestOpen","useEventCallback","dismiss","onDismiss","finish","onFinish","goBack","goNext","goToStep","next","ignoresSurfaceProps","className","style","onKeyDown","motion","ref","context","footerLayout","closeLabel","side","align","TeachingPopoverContext","TeachingSurface","teachingPopoverClassNames"],"sources":["../../../src/components/overlays/TeachingPopover.root.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { teachingPopoverClassNames } from '../../lib/classNames';\nimport { resolveDeprecatedProp, warnOnce } from '../../lib/dev';\nimport { slotRendersContent } from '../../lib/slot';\nimport type {\n MotionSlot,\n PopupAlign,\n PopupPositioning,\n PopupSide,\n VirtualElement,\n} from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useTargetConflictWarning } from '../../hooks/useResolvedTarget';\nimport {\n TeachingPopoverContext,\n type TeachingPopoverAction,\n type TeachingPopoverContextValue,\n type TeachingPopoverLabels,\n type TeachingPopoverStep,\n} from './TeachingPopover.context';\nimport {\n TeachingPopoverSurface,\n TeachingPopoverTrigger,\n TeachingSurface,\n} from './TeachingPopover.parts';\n\n/*\n * The TeachingPopover root: its props, the state of both forms (the open state, the step and the\n * step's resolved content), the child scan for the Trigger and the Surface, and the surface it\n * renders when no Surface is among its children. Imports the context and parts modules (never\n * `TeachingPopover.tsx`, which holds the compound).\n */\n\nconst DEFAULT_BACK_LABEL = 'Back';\nconst DEFAULT_NEXT_LABEL = 'Next';\nconst DEFAULT_DONE_LABEL = 'Done';\nconst DEFAULT_NAV_LABEL = 'Choose step';\nconst defaultStepLabel = (index: number, count: number) => `step ${index + 1} of ${count}`;\nconst defaultNavButtonLabel = (index: number, count: number) => `Step ${index + 1} of ${count}`;\n\n/** Properties for the TeachingPopover component. */\nexport interface TeachingPopoverProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Steps to display in the teaching popover (a readonly array is accepted). */\n steps: readonly TeachingPopoverStep[];\n /**\n * Controlled index of the displayed step. Out-of-range values are clamped to the first or last\n * step (with a development warning). Opening the popover leaves it as it is.\n */\n activeStep?: number;\n /**\n * Initial step index for uncontrolled usage, and the step the popover starts on again each time\n * it opens (after Done, Close, Escape or the Trigger closed it, or a controlled `open` turned it\n * off), so a tour opened again starts over; `onStepChange` is called with it when the step was\n * elsewhere.\n * @default 0\n */\n defaultActiveStep?: number;\n /** @deprecated Use `activeStep`. */\n currentStep?: number;\n /** @deprecated Use `defaultActiveStep`. */\n defaultCurrentStep?: number;\n /**\n * Called with the requested step index when Next, Back or a step button of\n * `TeachingPopover.CarouselNav` is activated (the button of the current step requests nothing),\n * and, while the step is uncontrolled, with the initial step when an opening moves the step back\n * to it (see `defaultActiveStep`).\n */\n onStepChange?: (step: number) => void;\n /**\n * Called when the popover is dismissed with Close, Done, Escape or a `TeachingPopover.Trigger`\n * that closes it.\n *\n * Done also calls it in 0.x, after `onFinish`, so that code written before `onFinish` keeps\n * working; from 1.0 only Close, Escape and the Trigger will.\n */\n onDismiss?: () => void;\n /**\n * Called when the tour is finished: Done, the button that replaces Next on the last step, or a\n * `primaryAction` on the last step whose click was not prevented. The popover closes first.\n * Close, Escape and the Trigger call only `onDismiss`. Fires on every activation, like\n * `onStepChange`.\n */\n onFinish?: () => void;\n /**\n * Replaces the Next (or Done) button on every step that sets no `primaryAction` of its own.\n */\n primaryAction?: TeachingPopoverAction;\n /**\n * Replaces the Back button on every step that sets no `secondaryAction` of its own.\n */\n secondaryAction?: TeachingPopoverAction;\n /**\n * How the footer lays out the step dots and the buttons: side by side, or the dots above\n * buttons that fill the width. Rendered as `data-layout` on the popover and on its footer.\n * `TeachingPopover.CarouselFooter` has its own `layout` instead.\n * @default 'horizontal'\n */\n footerLayout?: 'horizontal' | 'vertical';\n /** Controlled visibility of the teaching popover. */\n open?: boolean;\n /**\n * Initial visibility for uncontrolled usage: `true` (a tour that shows on page load), or\n * `false` when a `TeachingPopover.Trigger` is a direct child (a Fragment is fine), which then\n * opens it.\n * @default true (false with a direct TeachingPopover.Trigger)\n */\n defaultOpen?: boolean;\n /**\n * Called with `false` when Close, Done or Escape dismisses the popover, and with the new state\n * when a `TeachingPopover.Trigger` opens or closes it.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Accessible name of the built-in Close button (an icon-only button). Localize it with the\n * page's language.\n * @default 'Close'\n */\n closeLabel?: string;\n /**\n * Text of the Back, Next and Done buttons, the wording of the step position (“step 2 of 3”) and\n * the names of `TeachingPopover.CarouselNav`'s step buttons, for localization. Unset members keep\n * their English defaults.\n */\n labels?: TeachingPopoverLabels;\n /**\n * The element the popover points at (a ref, the element, or a `VirtualElement`: a rectangle such as a\n * point; an inline object is fine). When given, the popover is\n * rendered in a portal, positioned next to it with a beak, and flips or shifts to stay in view;\n * without it (`undefined`) the popover renders inline where it is placed (0.4 behaviour), or,\n * with a `TeachingPopover.Trigger`, points at the trigger.\n * While the target is `null` or has not been positioned against yet (an element held in state\n * that is not set yet, a ref that is not attached), the popover stays hidden: it is not\n * shown, takes no focus, announces no step change and does not handle Escape until it can\n * point at the target. It hides the same way when the target goes away later and shows again\n * when a target returns.\n *\n * An element (for example one held in state through a callback ref) is followed as soon as the\n * prop changes. A ref cannot be observed, so it is read after each render of the popover is\n * committed, wherever the target is in the tree: an element attaching to or detaching from the\n * ref is noticed the next time the popover renders (for example when the parent that mounts or\n * unmounts the target re-renders it), not in a commit that does not render the popover. A\n * memoized popover whose target mounts or unmounts in another subtree therefore stays hidden,\n * or keeps pointing at the removed element, until it renders again. A newly passed ref keeps\n * the previous visibility until it has been read, so a tour can move between attached refs\n * (`target={step === 0 ? aRef : bRef}`) without hiding, and a switch to a ref that is not\n * attached hides the popover right after that commit. Pass the element held in state when the\n * target can mount or unmount without the popover re-rendering.\n */\n target?: React.RefObject<HTMLElement | null> | HTMLElement | VirtualElement | null;\n /** Side of the `target` to open on; `start`/`end` follow the writing direction.\n * @default 'bottom'\n */\n side?: PopupSide;\n /** Alignment along the `target`'s edge.\n * @default 'center'\n */\n align?: PopupAlign;\n /**\n * Advanced positioning (Fluent's `positioning`): `offset`, `fitViewport`, `matchReferenceWidth`,\n * `fallbackPlacements` and `target` (used when the `target` prop is not set). `side` and `align`\n * stay separate props.\n * @default `{ offset: 12 }`\n */\n positioning?: PopupPositioning;\n /**\n * The motion of the surface TeachingPopover renders (next to a `TeachingPopover.Surface` it is\n * ignored, with a development warning: give it to the Surface). By default the surface fades in\n * over 200 ms with a decelerating curve and out over 100 ms with an accelerating curve, and,\n * pointed at a target (or the Trigger), also slides 4px away from it on the side it opened on,\n * and back as it closes; under reduced motion it appears and disappears at once. `null` turns\n * the motion off (the surface still renders its `data-presence` phases, which then end at\n * once); a class string or `{ className }` replaces the default classes with yours (see\n * `MotionSlot`), also under a `WaveProvider` with `motion=\"none\"`, which otherwise turns the\n * default off. Fluent's `TeachingPopover` `surfaceMotion` (a TeachingPopover is a Popover\n * there).\n * @default the fade and slide above\n */\n motion?: MotionSlot | null;\n /**\n * `TeachingPopover.Trigger` and `TeachingPopover.Surface` (Fluent's composition), rendered where\n * they are written. Without a `TeachingPopover.Surface` among them, the popover renders its\n * surface itself, after the children, with the element props given here (`className`, `style`,\n * `ref`, `motion`, …); with one (best written directly inside, a Fragment is fine: see\n * `TeachingPopover.Surface`), the Surface takes them instead.\n */\n children?: React.ReactNode;\n /**\n * Ref to the popover surface (`role=\"dialog\"`). Ignored next to a `TeachingPopover.Surface`\n * (pass it to the Surface).\n */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** The action a step shows: its own when it renders anything, else the popover's. */\nfunction pickAction(\n own: TeachingPopoverAction | undefined,\n fallback: TeachingPopoverAction | undefined,\n): TeachingPopoverAction | undefined {\n if (slotRendersContent(own)) return own;\n return slotRendersContent(fallback) ? fallback : undefined;\n}\n\nfunction clampStep(step: number, count: number): number {\n if (!Number.isFinite(step)) return 0;\n return Math.min(Math.max(Math.trunc(step), 0), count - 1);\n}\n\n/**\n * Which parts are direct children (Fragments flattened, lazy types of a Server Component\n * unwrapped): a Trigger closes `defaultOpen`, a Surface replaces the root's own surface. Runs\n * during render, so the server HTML agrees (a Surface deeper down registers once mounted).\n */\nfunction findParts(children: React.ReactNode): { trigger: boolean; surface: boolean } {\n const found = { trigger: false, surface: false };\n if (children === null || children === undefined) return found;\n for (const { node } of flattenChildren(children)) {\n if (isElementOfType(node, TeachingPopoverTrigger)) found.trigger = true;\n else if (isElementOfType(node, TeachingPopoverSurface)) found.surface = true;\n }\n return found;\n}\n\nconst SURFACE_PLACEMENT_WARNING_KEY = 'TeachingPopover.Surface:placement';\nconst SURFACE_PLACEMENT_WARNING =\n 'TeachingPopover.Surface: render one TeachingPopover.Surface in a TeachingPopover; a second Surface renders a second popover.';\n\nconst SURFACE_PROPS_WARNING_KEY = 'TeachingPopover:surface-props';\nconst SURFACE_PROPS_WARNING =\n 'TeachingPopover: the props of the surface element on TeachingPopover (`className`, `style`, `ref`, `onKeyDown`, `motion` and the other element props) are ignored next to a TeachingPopover.Surface: pass them to the Surface.';\n\n// The root of `TeachingPopover` (documented on the export in TeachingPopover.tsx).\nexport const TeachingPopoverRoot = ({\n steps,\n activeStep: activeStepProp,\n defaultActiveStep,\n currentStep,\n defaultCurrentStep,\n onStepChange,\n onDismiss,\n onFinish,\n primaryAction: primaryActionProp,\n secondaryAction: secondaryActionProp,\n footerLayout = 'horizontal',\n open: openProp,\n defaultOpen,\n onOpenChange,\n closeLabel = 'Close',\n labels,\n target: targetProp,\n positioning,\n side = 'bottom',\n align = 'center',\n children,\n id,\n className,\n style,\n onKeyDown,\n motion,\n ref,\n ...rest\n}: TeachingPopoverProps) => {\n useTargetConflictWarning('TeachingPopover', targetProp, positioning?.target);\n const explicitTarget = (\n targetProp !== undefined ? targetProp : positioning?.target\n ) as TeachingPopoverProps['target'];\n const controlledStep = resolveDeprecatedProp(\n 'TeachingPopover',\n activeStepProp,\n currentStep,\n 'currentStep',\n 'activeStep',\n );\n const initialStep =\n resolveDeprecatedProp(\n 'TeachingPopover',\n defaultActiveStep,\n defaultCurrentStep,\n 'defaultCurrentStep',\n 'defaultActiveStep',\n ) ?? 0;\n const [storedStep, setStep, stepControlled] = useControllable(\n controlledStep,\n initialStep,\n onStepChange,\n );\n const parts = findParts(children);\n const [open, setOpen] = useControllable(openProp, defaultOpen ?? !parts.trigger, onOpenChange);\n const titleId = useId('teaching-popover-title');\n\n // An uncontrolled step starts again at the initial step each time the popover opens (not on\n // mount), whatever closed it and whatever opens it. The opening is noticed during render (C-HOOKS:\n // a previous-value state), so the opened popover shows the initial step from its first render;\n // the layout effect stores it through the setter (which calls `onStepChange` once, from the\n // commit), and the render that reads it back ends the reset.\n const [openSeen, setOpenSeen] = React.useState(open);\n const [stepResetPending, setStepResetPending] = React.useState(false);\n if (open !== openSeen) {\n setOpenSeen(open);\n if (open && !stepControlled && !Object.is(storedStep, initialStep)) {\n setStepResetPending(true);\n }\n }\n if (stepResetPending && (stepControlled || Object.is(storedStep, initialStep))) {\n setStepResetPending(false);\n }\n React.useLayoutEffect(() => {\n if (stepResetPending) setStep(initialStep);\n }, [stepResetPending, initialStep, setStep]);\n const rawStep = stepResetPending ? initialStep : storedStep;\n\n const count = steps.length;\n const shown = open && count > 0;\n const index = count > 0 ? clampStep(rawStep, count) : 0;\n const outOfRange = count > 0 && index !== rawStep;\n const step = count > 0 ? steps[index] : undefined;\n const isFirst = index === 0;\n const isLast = index === count - 1;\n const stepPosition = count > 0 ? (labels?.step ?? defaultStepLabel)(index, count) : '';\n const primaryAction = step ? pickAction(step.primaryAction, primaryActionProp) : undefined;\n const secondaryAction = step ? pickAction(step.secondaryAction, secondaryActionProp) : undefined;\n const backLabel = labels?.back ?? DEFAULT_BACK_LABEL;\n const nextLabel = labels?.next ?? DEFAULT_NEXT_LABEL;\n const doneLabel = labels?.done ?? DEFAULT_DONE_LABEL;\n const navLabel = labels?.nav ?? DEFAULT_NAV_LABEL;\n const navButtonLabel = labels?.navButton ?? defaultNavButtonLabel;\n\n // A Trigger is the target when neither `target` nor `positioning.target` is set: a direct one\n // from the first render (the surface stays hidden until its element attaches), a nested one\n // once its element has attached.\n const [triggerElement, setTriggerElement] = React.useState<HTMLElement | null>(null);\n const hasTrigger = parts.trigger || triggerElement !== null;\n const target =\n explicitTarget !== undefined ? explicitTarget : hasTrigger ? triggerElement : undefined;\n // The Trigger's element also as a ref, where the surface returns focus.\n const triggerRef = React.useRef<HTMLElement | null>(null);\n const triggerElementRef = useMergedRefs<HTMLElement>(triggerRef, setTriggerElement);\n\n // Surfaces (TeachingPopover.Surface) register while mounted, wherever they are among the\n // children: once one has, the root renders no surface of its own. A direct one is also found by\n // the scan above, so it never renders next to the root's own; one inside a component of yours\n // does in its first commit, until its registration re-renders the root. After every commit\n // (every surface's layout effect has run) more than one warns.\n const surfaceCountRef = React.useRef(0);\n const [hasRegisteredSurface, setHasRegisteredSurface] = React.useState(false);\n const registerSurface = React.useCallback(() => {\n surfaceCountRef.current += 1;\n setHasRegisteredSurface(true);\n return () => {\n surfaceCountRef.current -= 1;\n if (surfaceCountRef.current === 0) setHasRegisteredSurface(false);\n };\n }, []);\n const hasSurfacePart = parts.surface || hasRegisteredSurface;\n React.useEffect(() => {\n if (surfaceCountRef.current > 1) {\n warnOnce(SURFACE_PLACEMENT_WARNING_KEY, SURFACE_PLACEMENT_WARNING);\n }\n });\n\n // The Trigger's `aria-controls`: the surface's id (the root's own `id` on its own surface, or\n // the id a Surface reports), else a generated one.\n const generatedSurfaceId = useId('teaching-popover');\n const [customSurfaceId, setCustomSurfaceId] = React.useState<string | undefined>(undefined);\n const surfaceId = (hasSurfacePart ? customSurfaceId : id || undefined) ?? generatedSurfaceId;\n\n const requestOpen = useEventCallback(() => setOpen(true));\n const dismiss = useEventCallback(() => {\n setOpen(false);\n onDismiss?.();\n });\n // Done: close, then `onFinish`. `onDismiss` still follows in 0.x (see its JSDoc).\n const finish = useEventCallback(() => {\n setOpen(false);\n onFinish?.();\n onDismiss?.();\n });\n const goBack = useEventCallback(() => {\n if (!isFirst) setStep(index - 1);\n });\n const goNext = useEventCallback(() => {\n if (isLast) finish();\n else setStep(index + 1);\n });\n // A step button of TeachingPopover.CarouselNav: the shown (clamped) step requests nothing.\n const goToStep = useEventCallback((target: number) => {\n if (count === 0) return;\n const next = clampStep(target, count);\n if (next !== index) setStep(next);\n });\n\n // Next to a Surface the root renders no surface element, so its element props and its `motion`\n // (`null` included: it asks for no motion) go nowhere.\n const ignoresSurfaceProps =\n hasSurfacePart &&\n (id !== undefined ||\n className !== undefined ||\n style !== undefined ||\n onKeyDown !== undefined ||\n motion !== undefined ||\n ref !== undefined ||\n Object.keys(rest).length > 0);\n React.useEffect(() => {\n if (ignoresSurfaceProps) warnOnce(SURFACE_PROPS_WARNING_KEY, SURFACE_PROPS_WARNING);\n }, [ignoresSurfaceProps]);\n\n React.useEffect(() => {\n if (!outOfRange) return;\n warnOnce(\n 'TeachingPopover:activeStep-range',\n `TeachingPopover: activeStep ${rawStep} is out of range for ${count} steps; showing step ${index + 1}.`,\n );\n }, [outOfRange, rawStep, count, index]);\n\n const context = React.useMemo<TeachingPopoverContextValue>(\n () => ({\n open,\n shown,\n requestOpen,\n dismiss,\n finish,\n count,\n index,\n step,\n isFirst,\n isLast,\n stepPosition,\n goBack,\n goNext,\n goToStep,\n primaryAction,\n secondaryAction,\n footerLayout,\n backLabel,\n nextLabel,\n doneLabel,\n closeLabel,\n navLabel,\n navButtonLabel,\n titleId,\n target,\n side,\n align,\n positioning,\n hasTrigger,\n triggerElementRef,\n triggerRef,\n surfaceId,\n setCustomSurfaceId,\n registerSurface,\n }),\n [\n open,\n shown,\n requestOpen,\n dismiss,\n finish,\n count,\n index,\n step,\n isFirst,\n isLast,\n stepPosition,\n goBack,\n goNext,\n goToStep,\n primaryAction,\n secondaryAction,\n footerLayout,\n backLabel,\n nextLabel,\n doneLabel,\n closeLabel,\n navLabel,\n navButtonLabel,\n titleId,\n target,\n side,\n align,\n positioning,\n hasTrigger,\n triggerElementRef,\n surfaceId,\n registerSurface,\n ],\n );\n\n return (\n <TeachingPopoverContext.Provider value={context}>\n {children}\n {hasSurfacePart ? null : (\n <TeachingSurface\n context={context}\n rootClassName={teachingPopoverClassNames.root}\n id={id}\n className={className}\n style={style}\n onKeyDown={onKeyDown}\n motion={motion}\n {...rest}\n ref={ref}\n />\n )}\n </TeachingPopoverContext.Provider>\n );\n};\nTeachingPopoverRoot.displayName = 'TeachingPopover';\n"],"mappings":"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AAE,EACvG;CACF,GAAG;EAACsD;EAAYH;EAASlD;EAAOD;CAAK,CAAC;CAEtC,IAAMoG,KAAU1G,EAAM,eACb;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,IACA;EACEgD;EACAW;EACA+B;EACAE;EACAE;EACAvF;EACAD;EACAQ;EACA+C;EACAC;EACAC;EACAiC;EACAC;EACAC;EACAjC;EACAC;EACAyC;EACAxC;EACAC;EACAC;EACAuC;EACAtC;EACAC;EACAnB;EACAuB;EACAkC;EACAC;EACA5E;EACAwC;EACAG;EACAW;EACAN;CACF,CACF;CAEA,OACE,mBAAC6B,GAAuB,UAAxB;EAAiC,OAAOL;EAAxC,UAAA,CACGzF,GACAkE,IAAiB,OAChB,mBAAC6B,IAAD;GACW;GACT,eAAeC,GAA0B;GACrC;GACO;GACJ;GACI;GACH;GACR,GAAIhF;GACC;EACN,CAAA,CAE4B;;AAErC;AACA,EAAoB,cAAc"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/composeEventHandlers.cjs"),i=require("../../lib/classNames.cjs"),a=require("../../hooks/useEventCallback.cjs"),o=require("../../hooks/useControllable.cjs"),s=require("../../hooks/useId.cjs"),c=require("../../lib/focus.cjs"),l=require("../../hooks/useMergedRefs.cjs"),
|
|
1
|
+
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/composeEventHandlers.cjs"),i=require("../../lib/classNames.cjs"),a=require("../../hooks/useEventCallback.cjs"),o=require("../../hooks/useControllable.cjs"),s=require("../../hooks/useId.cjs"),c=require("../../lib/focus.cjs"),l=require("../../hooks/useMergedRefs.cjs"),ee=require("../../hooks/useIsClient.cjs"),u=require("../../lib/aria.cjs"),te=require("../../hooks/usePresence.cjs"),d=require("../../hooks/usePopupPosition.cjs"),ne=require("../../hooks/useDismiss.cjs"),re=require("../portal/Portal.cjs"),f=require("../../lib/motion.cjs"),p=require("../../hooks/useMotion.cjs"),m=require("../../lib/renderTrigger.cjs");let h=require("react");h=e.__toESM(h,1);let g=require("react/jsx-runtime");var ie={dark:`inverted`,light:`normal`},ae={inverted:`border border-inverted-border bg-inverted text-inverted-foreground`,normal:`border border-border bg-background text-foreground`},oe=`max-w-60 whitespace-normal break-words rounded px-3 py-1.5 text-caption-1 font-normal normal-case tracking-normal text-start shadow-8 ${[`before:absolute`,`data-[side=top]:before:inset-x-0 data-[side=top]:before:top-full data-[side=top]:before:h-2`,`data-[side=bottom]:before:inset-x-0 data-[side=bottom]:before:bottom-full data-[side=bottom]:before:h-2`,`data-[side=left]:before:inset-y-0 data-[side=left]:before:left-full data-[side=left]:before:w-2`,`data-[side=right]:before:inset-y-0 data-[side=right]:before:right-full data-[side=right]:before:w-2`].join(` `)}`,_=/^on[A-Z]/,se=[`aria-label`,`aria-labelledby`];function v(e){return e.currentTarget.contains(e.target)}function y(e){return t=>{v(t)&&e(t)}}function ce(e){let t={},n={};for(let[r,i]of Object.entries(e))r===`id`||r.startsWith(`aria-`)?t[r]=i:n[r]=_.test(r)&&typeof i==`function`?y(i):i;return{childProps:t,wrapperProps:n}}function le(e,t){let n={...e};for(let e of t)delete n[e];return n}function b(e,t,n){return(e.getAttribute(t)??``).split(/\s+/).includes(n)}function x(e,t,n){let r=(e.getAttribute(t)??``).split(/\s+/).filter(e=>e&&e!==n);r.length>0?e.setAttribute(t,r.join(` `)):e.removeAttribute(t)}function S(e,t,r,i){let a=h.useRef(null),o=r===`label`?`aria-labelledby`:`aria-describedby`;h.useLayoutEffect(()=>{let r=e.current;if(!r)return;let s=()=>{let e=a.current,s=Array.from(r.querySelectorAll(`[${o}]`)).filter(n=>!(e&&e.element===n&&e.attribute===o)&&b(n,o,t)).some(e=>e.matches(c.FOCUSABLE_SELECTOR))?null:c.getFirstTabbable(r);e&&(e.element!==s||e.attribute!==o)&&(x(e.element,e.attribute,t),a.current=null),s&&(b(s,o,t)||s.setAttribute(o,u.joinIds(s.getAttribute(o),t)??``),a.current={element:s,attribute:o},i||n.warnOnce(`Tooltip:focus-target`,`Tooltip: the element that takes focus inside it did not get \`${o}\` (the child is not focusable, or is a component, such as a Popover or Dialog root, that does not pass the prop on), so it was added to the first focusable element inside. Put the Tooltip directly around the focusable element, e.g. <Popover.Trigger><Tooltip content="…"><Button /></Tooltip></Popover.Trigger>.`))};if(s(),!a.current||typeof MutationObserver>`u`)return;let l=new MutationObserver(s);return l.observe(r,{subtree:!0,childList:!0,attributes:!0,attributeFilter:[o]}),()=>l.disconnect()})}var C=({content:e,appearance:c,variant:_,openDelay:b,closeDelay:x=100,delay:C,open:ue,defaultOpen:de,onOpenChange:fe,relationship:w=`description`,side:pe=`top`,align:me=`center`,positioning:T,motion:E,children:D,className:O,onMouseEnter:k,onMouseLeave:A,onFocus:j,onBlur:M,ref:N,...P})=>{let F=n.resolveDeprecatedProp(`Tooltip`,c,_===void 0?void 0:ie[_],`variant`,`appearance`)??`inverted`,I=n.resolveDeprecatedProp(`Tooltip`,b,C,`delay`,`openDelay`)??200,[L,R]=o.useControllable(ue,de??!1,fe),z=ee.useIsClient(),B=L&&z,V=h.useRef(void 0),H=h.useRef(null),U=h.useRef(null),W=s.useId(`tooltip`),{isMounted:he,ref:ge,presenceProps:_e}=te.usePresence(B,{appear:!0}),ve=p.useMotionClasses(E,f.tooltipMotion),{setReference:ye,setFloating:be,floatingProps:xe}=d.usePopupPosition({open:B,side:pe,align:me,...d.resolvePositioning(T,{offset:8})}),Se=l.useMergedRefs(N,H,ye),Ce=l.useMergedRefs(U,be,ge),G=a.useEventCallback(()=>{V.current!==void 0&&(clearTimeout(V.current),V.current=void 0)}),K=a.useEventCallback(()=>{if(G(),!B){if(I<=0){R(!0);return}V.current=setTimeout(()=>{V.current=void 0,R(!0)},I)}}),q=a.useEventCallback(()=>{G(),R(!1)}),we=a.useEventCallback(()=>{G(),B&&(V.current=setTimeout(()=>{V.current=void 0,R(!1)},x))});ne.useDismiss({open:B,onDismiss:q,refs:[H,U],anchorRef:H,kind:`tooltip`,outsidePress:!1}),h.useEffect(()=>{let e=V;return()=>clearTimeout(e.current)},[]);let Te=a.useEventCallback(e=>{(v(e)||U.current?.contains(e.target))&&K()}),Ee=a.useEventCallback(e=>{!v(e)&&!U.current?.contains(e.target)&&q()}),{childProps:J,wrapperProps:Y}=ce(P),X=m.unwrapFragment(D),Z=!m.isCloneableElement(X),Q=w===`label`?`aria-labelledby`:`aria-describedby`,$=Z?le(J,[...m.STATE_ARIA,...se]):{...J};(!Z||w===`description`)&&($[Q]=u.joinIds(J[Q],W));let De=m.renderTrigger(X,$,{componentName:`Tooltip`});return S(H,W,w,Z),(0,g.jsxs)(`span`,{ref:Se,...Y,className:t.cn(i.tooltipClassNames.root,`inline-block`,O),onMouseEnter:r.composeEventHandlers(k,Te),onMouseLeave:r.composeEventHandlers(A,we),onMouseOver:r.composeEventHandlers(Y.onMouseOver,Ee),onFocus:y(r.composeEventHandlers(j,K)),onBlur:y(r.composeEventHandlers(M,q)),children:[De,(0,g.jsx)(`span`,{id:W,role:`tooltip`,hidden:!0,children:e}),he&&(0,g.jsx)(re.Portal,{layer:`tooltip`,children:(0,g.jsx)(`span`,{ref:Ce,"aria-hidden":`true`,"data-wave-tooltip-surface":``,"data-state":B?`open`:`closed`,..._e,...xe,className:t.cn(i.tooltipClassNames.content,oe,ae[F],ve),children:e})})]})};C.displayName=`Tooltip`,exports.Tooltip=C;
|
|
2
2
|
//# sourceMappingURL=Tooltip.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.cjs","names":["React","FOCUSABLE_SELECTOR","getFirstTabbable","joinIds","resolveDeprecatedProp","useControllable","useIsClient","useId","usePopupPosition","resolvePositioning","useMergedRefs","useEventCallback","unwrapFragment","isCloneableElement","STATE_ARIA","renderTrigger","cn","tooltipClassNames","composeEventHandlers","Portal","require_runtime","require_cn","require_dev","require_composeEventHandlers","require_classNames","require_useEventCallback","require_useControllable","require_useId","require_focus","require_useMergedRefs","require_useIsClient","require_aria","require_usePopupPosition","require_useDismiss","require_Portal","require_renderTrigger","react","react_jsx_runtime","VARIANT_APPEARANCE","appearanceClasses","surfaceClasses","HANDLER_KEY","NAMING_ARIA","isOwnEvent","event","ownEventsOnly","handler","splitProps","childProps","wrapperProps","key","value","props","omit","result","keys","hasIdRef","el","attribute","id","removeIdRef","rest","useRelationshipTarget","appliedRef","relationship","wrapper","wrapperRef","update","applied","target","tooltipId","childIsFallback","observer","Tooltip","appearanceProp","openDelayProp","openProp","appearance","variant","openDelay","delay","open","setOpen","defaultOpen","onOpenChange","isClient","visible","timerRef","surfaceRef","positioning","wrapperElementRef","ref","setReference","surfaceElementRef","setFloating","clearTimer","show","hide","scheduleHide","closeDelay","timer","showOnEnter","hideOverPortaledPopup","children","triggerProps","child","className","onMouseEnter","onMouseLeave","onFocus","onBlur","content","floatingProps"],"sources":["../../../src/components/overlays/Tooltip.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { joinIds } from '../../lib/aria';\nimport { tooltipClassNames } from '../../lib/classNames';\nimport { resolveDeprecatedProp, warnOnce } from '../../lib/dev';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { FOCUSABLE_SELECTOR, getFirstTabbable } from '../../lib/focus';\nimport {\n isCloneableElement,\n renderTrigger,\n STATE_ARIA,\n unwrapFragment,\n} from '../../lib/renderTrigger';\nimport type { PopupAlign, PopupPositioningOptions, PopupSide } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useId } from '../../hooks/useId';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useDismiss } from '../../hooks/useDismiss';\nimport { resolvePositioning, usePopupPosition } from '../../hooks/usePopupPosition';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { Portal } from '../portal/Portal';\n\n/** Color treatment of a tooltip (`TooltipProps.appearance`). */\nexport type TooltipAppearance = 'inverted' | 'normal';\n\n/** Properties for the Tooltip component. */\nexport interface TooltipProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'content'> {\n /** Content to display inside the tooltip (short, non-interactive text). */\n content: React.ReactNode;\n /**\n * Color treatment: `inverted` (dark surface in the light theme) or `normal` (the page\n * background with a border).\n * @default 'inverted'\n */\n appearance?: TooltipAppearance;\n /**\n * @deprecated Use `appearance` (`'dark'` → `'inverted'`, `'light'` → `'normal'`).\n */\n variant?: 'dark' | 'light';\n /**\n * Milliseconds before the tooltip appears when the pointer rests on the child or the child\n * receives keyboard focus (Fluent's `showDelay`; unlike Menu's and Popover's `openDelay`, it\n * applies to focus too).\n * @default 200\n */\n openDelay?: number;\n /**\n * Milliseconds before it hides once the pointer has left the child and the tooltip (Fluent's\n * `hideDelay`); blur and Escape hide it at once.\n * @default 100\n */\n closeDelay?: number;\n /** @deprecated Use `openDelay`. */\n delay?: number;\n /**\n * Controlled open state (Fluent's `visible`). The tooltip still asks to open on hover and focus\n * (after `openDelay`) and to close on leave, blur and Escape through `onOpenChange`. The surface\n * renders only in the browser: an open tooltip is closed in the server HTML and opens once it\n * has hydrated.\n */\n open?: boolean;\n /**\n * Initial open state for uncontrolled usage.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Called with the new open state when it changes (Fluent's `onVisibleChange`). It has no\n * `details` argument yet.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * How the tooltip relates to its child: `description` adds it to the child's\n * `aria-describedby`; `label` adds it to the child's `aria-labelledby`, naming an icon-only\n * button.\n * @default 'description'\n */\n relationship?: 'description' | 'label';\n /**\n * Side of the target the tooltip opens on. `start`/`end` follow the writing direction; the\n * tooltip flips to the opposite side when there is not enough room.\n * @default 'top'\n */\n side?: PopupSide;\n /** Alignment along the target's edge.\n * @default 'center'\n */\n align?: PopupAlign;\n /**\n * Advanced positioning (Fluent's `positioning`): `offset`, `fitViewport`, `matchReferenceWidth`\n * and `fallbackPlacements`. `side` and `align` stay separate props. The hover bridge across the\n * gap covers the default 8px, so a larger `offset` leaves a gap the pointer cannot cross.\n * @default `{ offset: 8 }`\n */\n positioning?: PopupPositioningOptions;\n /**\n * A single element that triggers the tooltip on hover and focus: it receives the\n * `aria-describedby`/`aria-labelledby`, plus any `id` and `aria-*` props given to the Tooltip\n * (a Fragment around one element counts as that element). Other children are wrapped in a\n * described `<span>` with a development warning, and their first focusable element gets the\n * relationship.\n */\n children: React.ReactElement;\n /** Ref to the wrapper `<span>` (the positioning anchor). */\n ref?: React.Ref<HTMLSpanElement>;\n}\n\nconst VARIANT_APPEARANCE: Record<'dark' | 'light', TooltipAppearance> = {\n dark: 'inverted',\n light: 'normal',\n};\n\nconst appearanceClasses: Record<TooltipAppearance, string> = {\n inverted: 'border border-inverted-border bg-inverted text-inverted-foreground',\n normal: 'border border-border bg-background text-foreground',\n};\n\n/**\n * Transparent `::before` hover bridge across the 8px gap (the positioning offset) on the side that\n * faces the trigger only, so the pointer can move onto the tooltip; the other sides get no bridge,\n * which would otherwise catch hovers and clicks meant for neighbouring controls.\n */\nconst bridgeClasses = [\n 'before:absolute',\n // Tooltip above the trigger: a strip below it.\n 'data-[side=top]:before:inset-x-0 data-[side=top]:before:top-full data-[side=top]:before:h-2',\n // Tooltip below the trigger: a strip above it.\n 'data-[side=bottom]:before:inset-x-0 data-[side=bottom]:before:bottom-full data-[side=bottom]:before:h-2',\n // wave-allow-physical: data-side is the physical side resolved by the positioning\n 'data-[side=left]:before:inset-y-0 data-[side=left]:before:left-full data-[side=left]:before:w-2',\n // wave-allow-physical: data-side is the physical side resolved by the positioning\n 'data-[side=right]:before:inset-y-0 data-[side=right]:before:right-full data-[side=right]:before:w-2',\n].join(' ');\n\n/**\n * The visual surface: wrapping text, typography reset against the host (header cells, muted\n * panels), and the hover bridge towards the trigger.\n */\nconst surfaceClasses = `max-w-60 whitespace-normal break-words rounded px-3 py-1.5 text-caption-1 font-normal normal-case tracking-normal text-start shadow-8 ${bridgeClasses}`;\n\ntype UnknownProps = Record<string, unknown>;\ntype Relationship = NonNullable<TooltipProps['relationship']>;\n\nconst HANDLER_KEY = /^on[A-Z]/;\n\n/** Naming attributes a generic element such as the fallback `<span>` must not carry. */\nconst NAMING_ARIA = ['aria-label', 'aria-labelledby'] as const;\n\n/**\n * Whether an event reached the wrapper from its own DOM subtree — the child — rather than through\n * a portal: React bubbles events from portaled content (the tooltip surface, a popup the child\n * renders in a portal) through the component tree.\n */\nfunction isOwnEvent(event: React.SyntheticEvent): boolean {\n return (event.currentTarget as Node).contains(event.target as Node);\n}\n\n/** `handler`, called only for the wrapper's own events (see {@link isOwnEvent}). */\nfunction ownEventsOnly<E extends React.SyntheticEvent>(\n handler: (event: E) => void,\n): (event: E) => void {\n return (event) => {\n if (isOwnEvent(event)) handler(event);\n };\n}\n\n/**\n * Splits the props the Tooltip receives, from its consumer or from a parent that clones its child\n * (Menu.Trigger, Popover.Trigger, Dialog.Trigger, Field): `id` and `aria-*` describe the element\n * the Tooltip is attached to, so they go to the child; the rest stays on the wrapper `<span>`.\n */\nfunction splitProps(props: UnknownProps): { childProps: UnknownProps; wrapperProps: UnknownProps } {\n const childProps: UnknownProps = {};\n const wrapperProps: UnknownProps = {};\n for (const [key, value] of Object.entries(props)) {\n if (key === 'id' || key.startsWith('aria-')) childProps[key] = value;\n else if (HANDLER_KEY.test(key) && typeof value === 'function') {\n // The wrapper sees the child's events as they bubble, but not those that reach it through\n // a portal, such as a click on the tooltip surface (it would toggle a parent trigger).\n wrapperProps[key] = ownEventsOnly(value as (event: React.SyntheticEvent) => void);\n } else wrapperProps[key] = value;\n }\n return { childProps, wrapperProps };\n}\n\nfunction omit(props: UnknownProps, keys: readonly string[]): UnknownProps {\n const result = { ...props };\n for (const key of keys) delete result[key];\n return result;\n}\n\nfunction hasIdRef(el: Element, attribute: string, id: string): boolean {\n return (el.getAttribute(attribute) ?? '').split(/\\s+/).includes(id);\n}\n\nfunction removeIdRef(el: Element, attribute: string, id: string): void {\n const rest = (el.getAttribute(attribute) ?? '')\n .split(/\\s+/)\n .filter((value) => value && value !== id);\n if (rest.length > 0) el.setAttribute(attribute, rest.join(' '));\n else el.removeAttribute(attribute);\n}\n\n/**\n * Makes sure the element people focus carries the tooltip relationship. After each commit, when no\n * focusable element inside the wrapper references `tooltipId` through `attribute` — children in the\n * fallback span, a non-focusable child element, or a child component that drops the prop (a\n * Popover or Dialog root) — the id is added to the first tabbable element inside the wrapper and\n * kept there while the subtree changes; a development warning explains the nesting, except for\n * the fallback span, whose children shape `renderTrigger` already warned about.\n */\nfunction useRelationshipTarget(\n wrapperRef: React.RefObject<HTMLSpanElement | null>,\n tooltipId: string,\n relationship: Relationship,\n childIsFallback: boolean,\n): void {\n const appliedRef = React.useRef<{ element: Element; attribute: string } | null>(null);\n const attribute = relationship === 'label' ? 'aria-labelledby' : 'aria-describedby';\n\n React.useLayoutEffect(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return;\n\n const update = () => {\n const applied = appliedRef.current;\n const carriers = Array.from(wrapper.querySelectorAll(`[${attribute}]`)).filter(\n (el) =>\n !(applied && applied.element === el && applied.attribute === attribute) &&\n hasIdRef(el, attribute, tooltipId),\n );\n const reached = carriers.some((el) => el.matches(FOCUSABLE_SELECTOR));\n const target = reached ? null : getFirstTabbable(wrapper);\n if (applied && (applied.element !== target || applied.attribute !== attribute)) {\n removeIdRef(applied.element, applied.attribute, tooltipId);\n appliedRef.current = null;\n }\n if (!target) return;\n if (!hasIdRef(target, attribute, tooltipId)) {\n target.setAttribute(attribute, joinIds(target.getAttribute(attribute), tooltipId) ?? '');\n }\n appliedRef.current = { element: target, attribute };\n if (!childIsFallback) {\n warnOnce(\n 'Tooltip:focus-target',\n `Tooltip: the element that takes focus inside it did not get \\`${attribute}\\` (the child is not focusable, or is a component, such as a Popover or Dialog root, that does not pass the prop on), so it was added to the first focusable element inside. Put the Tooltip directly around the focusable element, e.g. <Popover.Trigger><Tooltip content=\"…\"><Button /></Tooltip></Popover.Trigger>.`,\n );\n }\n };\n\n update();\n if (!appliedRef.current || typeof MutationObserver === 'undefined') return;\n // Keep it on the focusable element when the child replaces it or rewrites the attribute\n // without the Tooltip re-rendering.\n const observer = new MutationObserver(update);\n observer.observe(wrapper, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeFilter: [attribute],\n });\n return () => observer.disconnect();\n });\n}\n\n/**\n * Shows a short text label or description for its child on hover and keyboard focus.\n *\n * - The text is always present as a hidden `role=\"tooltip\"` element referenced by the child's\n * `aria-describedby` (or `aria-labelledby` with `relationship=\"label\"`), so screen readers get\n * it on focus without waiting for the delay; the child's own ids are kept.\n * - The visual surface is rendered in a portal only while visible (it is `aria-hidden`, a copy of\n * the description), positioned on `side`/`align` with flipping and shifting to stay in view.\n * - It appears `openDelay` after the pointer rests on the child or the child takes keyboard focus,\n * stays visible while the pointer moves onto it, hides `closeDelay` after the pointer leaves or\n * immediately on blur, and Escape hides it without closing an enclosing dialog or popover. Focus\n * and hover inside a popup the child renders in a portal (a DatePicker calendar, a listbox) do\n * not show it, and the pointer moving onto such a popup hides it.\n * - The open state is uncontrolled by default (`defaultOpen`). With `open` and `onOpenChange`\n * (Fluent's `visible` and `onVisibleChange`) the parent owns it: hover, focus, leave, blur and\n * Escape then only ask for a change, and `open` alone shows the surface.\n * - `id` and `aria-*` props given to the Tooltip go to its child, merged with the child's own (the\n * child's `id` wins, id lists are joined, `aria-expanded`/`aria-controls`/`aria-haspopup` from\n * the Tooltip win). `className`, `style`, `ref`, `data-*` and event handlers stay on the wrapper\n * `<span>`; the handlers see the child's events as they bubble, not events from portaled\n * content such as the tooltip surface or a popup the child renders in a portal (a DatePicker\n * calendar, a listbox). `onMouseEnter` and `onMouseLeave` are the exception: React fires them\n * along the component tree, so they also fire when the pointer moves onto or off the tooltip\n * surface or such a popup. So the Tooltip can sit inside a trigger, and the trigger's\n * id and state reach the button: `<Menu.Trigger><Tooltip content=\"…\"><Button /></Tooltip>\n * </Menu.Trigger>` (also `Popover.Trigger`, `Dialog.Trigger`, `Drawer.Trigger`). Around a\n * trigger works too, since triggers pass `aria-describedby` on to their child.\n * - Wrap the focusable element itself. When the element that takes focus does not get the\n * relationship (a Popover or Dialog root, a component that drops props, a non-focusable\n * wrapper element), it is added to the first focusable element inside, with a development\n * warning.\n *\n * @example\n * <Menu>\n * <Menu.Trigger>\n * <Tooltip content=\"Edit, duplicate or delete the item\">\n * <Button>Actions</Button>\n * </Tooltip>\n * </Menu.Trigger>\n * <Menu.Popover>…</Menu.Popover>\n * </Menu>\n */\nexport const Tooltip = ({\n content,\n appearance: appearanceProp,\n variant,\n openDelay: openDelayProp,\n closeDelay = 100,\n delay,\n open: openProp,\n defaultOpen,\n onOpenChange,\n relationship = 'description',\n side = 'top',\n align = 'center',\n positioning,\n children,\n className,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: TooltipProps) => {\n const appearance =\n resolveDeprecatedProp(\n 'Tooltip',\n appearanceProp,\n variant === undefined ? undefined : VARIANT_APPEARANCE[variant],\n 'variant',\n 'appearance',\n ) ?? 'inverted';\n const openDelay =\n resolveDeprecatedProp('Tooltip', openDelayProp, delay, 'delay', 'openDelay') ?? 200;\n const [open, setOpen] = useControllable(openProp, defaultOpen ?? false, onOpenChange);\n // The surface lives in a portal, which renders only in the browser: until then (the server HTML,\n // hydration) the tooltip is closed; the hidden description is rendered either way.\n const isClient = useIsClient();\n const visible = open && isClient;\n const timerRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const wrapperRef = React.useRef<HTMLSpanElement | null>(null);\n const surfaceRef = React.useRef<HTMLSpanElement | null>(null);\n const tooltipId = useId('tooltip');\n\n // Destructured: react-hooks/refs treats an object whose member is passed to `ref` as a ref.\n const { setReference, setFloating, floatingProps } = usePopupPosition({\n open: visible,\n side,\n align,\n ...resolvePositioning(positioning, { offset: 8 }),\n });\n const wrapperElementRef = useMergedRefs<HTMLSpanElement>(ref, wrapperRef, setReference);\n const surfaceElementRef = useMergedRefs<HTMLSpanElement>(surfaceRef, setFloating);\n\n // Timer handlers are event callbacks (stable, latest state): they are composed with the\n // consumer's handlers during render but only run from events and timers.\n const clearTimer = useEventCallback(() => {\n if (timerRef.current !== undefined) {\n clearTimeout(timerRef.current);\n timerRef.current = undefined;\n }\n });\n\n // show, hide and scheduleHide ask for the new state; a controlled tooltip changes only when the\n // parent updates `open`.\n const show = useEventCallback(() => {\n clearTimer();\n if (visible) return;\n if (openDelay <= 0) {\n setOpen(true);\n return;\n }\n timerRef.current = setTimeout(() => {\n timerRef.current = undefined;\n setOpen(true);\n }, openDelay);\n });\n\n const hide = useEventCallback(() => {\n clearTimer();\n setOpen(false);\n });\n\n // The grace period after the pointer leaves lets it move onto the tooltip.\n const scheduleHide = useEventCallback(() => {\n clearTimer();\n if (!visible) return;\n timerRef.current = setTimeout(() => {\n timerRef.current = undefined;\n setOpen(false);\n }, closeDelay);\n });\n\n // An Escape-only layer while visible: Escape hides the tooltip before any enclosing overlay. The\n // wrapper is its anchor (its trigger, not its surface): Tab from the child inside a focus trap\n // moves on from the popover, portal or dialog around the wrapper.\n useDismiss({\n open: visible,\n onDismiss: hide,\n refs: [wrapperRef, surfaceRef],\n anchorRef: wrapperRef,\n kind: 'tooltip',\n outsidePress: false,\n });\n\n React.useEffect(() => {\n const timer = timerRef;\n return () => clearTimeout(timer.current);\n }, []);\n\n // The tooltip's own reactions ignore a popup the child renders in a portal: its focus and blur\n // are not the child's, entering it does not show the tooltip, and the pointer moving onto it\n // (no mouseleave reaches the wrapper then) hides the tooltip, which would cover it. The tooltip\n // surface itself is portaled too but belongs to the tooltip: it stays hoverable.\n const showOnEnter = useEventCallback((event: React.MouseEvent<HTMLSpanElement>) => {\n if (isOwnEvent(event) || surfaceRef.current?.contains(event.target as Node)) show();\n });\n const hideOverPortaledPopup = useEventCallback((event: React.MouseEvent<HTMLSpanElement>) => {\n if (!isOwnEvent(event) && !surfaceRef.current?.contains(event.target as Node)) hide();\n });\n\n const { childProps, wrapperProps } = splitProps(rest);\n const target = unwrapFragment(children);\n const childIsFallback = !isCloneableElement(target);\n const attribute = relationship === 'label' ? 'aria-labelledby' : 'aria-describedby';\n // Props given to the Tooltip come first, as if the child had them; then the tooltip's own id.\n // The fallback span is a generic element: no state ARIA and no naming on it (the relationship\n // then reaches its first focusable element through useRelationshipTarget).\n const triggerProps: UnknownProps = childIsFallback\n ? omit(childProps, [...STATE_ARIA, ...NAMING_ARIA])\n : { ...childProps };\n if (!childIsFallback || relationship === 'description') {\n triggerProps[attribute] = joinIds(childProps[attribute] as string | undefined, tooltipId);\n }\n const child = renderTrigger(target, triggerProps, { componentName: 'Tooltip' });\n useRelationshipTarget(wrapperRef, tooltipId, relationship, childIsFallback);\n\n return (\n <span\n ref={wrapperElementRef}\n {...wrapperProps}\n className={cn(tooltipClassNames.root, 'inline-block', className)}\n onMouseEnter={composeEventHandlers(onMouseEnter, showOnEnter)}\n onMouseLeave={composeEventHandlers(onMouseLeave, scheduleHide)}\n onMouseOver={composeEventHandlers(\n wrapperProps.onMouseOver as React.MouseEventHandler<HTMLSpanElement> | undefined,\n hideOverPortaledPopup,\n )}\n onFocus={ownEventsOnly(composeEventHandlers(onFocus, show))}\n onBlur={ownEventsOnly(composeEventHandlers(onBlur, hide))}\n >\n {child}\n <span id={tooltipId} role=\"tooltip\" hidden>\n {content}\n </span>\n {visible && (\n <Portal layer=\"tooltip\">\n <span\n ref={surfaceElementRef}\n aria-hidden=\"true\"\n data-wave-tooltip-surface=\"\"\n {...floatingProps}\n className={cn(tooltipClassNames.content, surfaceClasses, appearanceClasses[appearance])}\n >\n {content}\n </span>\n </Portal>\n )}\n </span>\n );\n};\n\nTooltip.displayName = 'Tooltip';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Tooltip.cjs","names":["React","FOCUSABLE_SELECTOR","getFirstTabbable","joinIds","resolveDeprecatedProp","useControllable","useIsClient","useId","usePresence","useMotionClasses","tooltipMotion","usePopupPosition","resolvePositioning","useMergedRefs","useEventCallback","unwrapFragment","isCloneableElement","STATE_ARIA","renderTrigger","cn","tooltipClassNames","composeEventHandlers","Portal","require_runtime","require_cn","require_dev","require_composeEventHandlers","require_classNames","require_useEventCallback","require_useControllable","require_useId","require_focus","require_useMergedRefs","require_useIsClient","require_aria","require_usePresence","require_usePopupPosition","require_useDismiss","require_Portal","require_motion","require_useMotion","require_renderTrigger","react","react_jsx_runtime","VARIANT_APPEARANCE","appearanceClasses","surfaceClasses","HANDLER_KEY","NAMING_ARIA","isOwnEvent","event","ownEventsOnly","handler","splitProps","childProps","wrapperProps","key","value","props","omit","result","keys","hasIdRef","el","attribute","id","removeIdRef","rest","useRelationshipTarget","appliedRef","relationship","wrapper","wrapperRef","update","applied","target","tooltipId","childIsFallback","observer","Tooltip","appearanceProp","openDelayProp","openProp","appearance","variant","openDelay","delay","open","setOpen","defaultOpen","onOpenChange","isClient","visible","timerRef","surfaceRef","presenceRef","motionClassName","motion","positioning","wrapperElementRef","ref","setReference","surfaceElementRef","setFloating","clearTimer","show","hide","scheduleHide","closeDelay","timer","showOnEnter","hideOverPortaledPopup","children","triggerProps","child","className","onMouseEnter","onMouseLeave","onFocus","onBlur","content","isMounted","presenceProps","floatingProps"],"sources":["../../../src/components/overlays/Tooltip.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { joinIds } from '../../lib/aria';\nimport { tooltipClassNames } from '../../lib/classNames';\nimport { resolveDeprecatedProp, warnOnce } from '../../lib/dev';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { FOCUSABLE_SELECTOR, getFirstTabbable } from '../../lib/focus';\nimport { tooltipMotion } from '../../lib/motion';\nimport {\n isCloneableElement,\n renderTrigger,\n STATE_ARIA,\n unwrapFragment,\n} from '../../lib/renderTrigger';\nimport type { MotionSlot, PopupAlign, PopupPositioningOptions, PopupSide } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useId } from '../../hooks/useId';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useDismiss } from '../../hooks/useDismiss';\nimport { resolvePositioning, usePopupPosition } from '../../hooks/usePopupPosition';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useMotionClasses } from '../../hooks/useMotion';\nimport { usePresence } from '../../hooks/usePresence';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { Portal } from '../portal/Portal';\n\n/** Color treatment of a tooltip (`TooltipProps.appearance`). */\nexport type TooltipAppearance = 'inverted' | 'normal';\n\n/** Properties for the Tooltip component. */\nexport interface TooltipProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'content'> {\n /** Content to display inside the tooltip (short, non-interactive text). */\n content: React.ReactNode;\n /**\n * Color treatment: `inverted` (dark surface in the light theme) or `normal` (the page\n * background with a border).\n * @default 'inverted'\n */\n appearance?: TooltipAppearance;\n /**\n * @deprecated Use `appearance` (`'dark'` → `'inverted'`, `'light'` → `'normal'`).\n */\n variant?: 'dark' | 'light';\n /**\n * Milliseconds before the tooltip appears when the pointer rests on the child or the child\n * receives keyboard focus (Fluent's `showDelay`; unlike Menu's and Popover's `openDelay`, it\n * applies to focus too).\n * @default 200\n */\n openDelay?: number;\n /**\n * Milliseconds before it hides once the pointer has left the child and the tooltip (Fluent's\n * `hideDelay`); blur and Escape hide it at once.\n * @default 100\n */\n closeDelay?: number;\n /** @deprecated Use `openDelay`. */\n delay?: number;\n /**\n * Controlled open state (Fluent's `visible`). The tooltip still asks to open on hover and focus\n * (after `openDelay`) and to close on leave, blur and Escape through `onOpenChange`. The surface\n * renders only in the browser: an open tooltip is closed in the server HTML and opens once it\n * has hydrated.\n */\n open?: boolean;\n /**\n * Initial open state for uncontrolled usage.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Called with the new open state when it changes (Fluent's `onVisibleChange`). It has no\n * `details` argument yet.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * How the tooltip relates to its child: `description` adds it to the child's\n * `aria-describedby`; `label` adds it to the child's `aria-labelledby`, naming an icon-only\n * button.\n * @default 'description'\n */\n relationship?: 'description' | 'label';\n /**\n * Side of the target the tooltip opens on. `start`/`end` follow the writing direction; the\n * tooltip flips to the opposite side when there is not enough room.\n * @default 'top'\n */\n side?: PopupSide;\n /** Alignment along the target's edge.\n * @default 'center'\n */\n align?: PopupAlign;\n /**\n * Advanced positioning (Fluent's `positioning`): `offset`, `fitViewport`, `matchReferenceWidth`\n * and `fallbackPlacements`. `side` and `align` stay separate props. The hover bridge across the\n * gap covers the default 8px, so a larger `offset` leaves a gap the pointer cannot cross.\n * @default `{ offset: 8 }`\n */\n positioning?: PopupPositioningOptions;\n /**\n * The motion of the tooltip's surface (the portaled box; `className` stays on the wrapper\n * `<span>`). By default it fades in over 100 ms and out over 100 ms with the easy-ease curve,\n * without a slide; under reduced motion it appears and disappears at once. `null` turns the\n * motion off (the surface still renders its `data-presence` phases, which then end at once); a\n * class string or `{ className }` replaces the default classes with yours (see `MotionSlot`),\n * also under a `WaveProvider` with `motion=\"none\"`, which otherwise turns the default off. A\n * WaveUI addition: Fluent's Tooltip has no motion.\n * @default the fade above\n */\n motion?: MotionSlot | null;\n /**\n * A single element that triggers the tooltip on hover and focus: it receives the\n * `aria-describedby`/`aria-labelledby`, plus any `id` and `aria-*` props given to the Tooltip\n * (a Fragment around one element counts as that element). Other children are wrapped in a\n * described `<span>` with a development warning, and their first focusable element gets the\n * relationship.\n */\n children: React.ReactElement;\n /** Ref to the wrapper `<span>` (the positioning anchor). */\n ref?: React.Ref<HTMLSpanElement>;\n}\n\nconst VARIANT_APPEARANCE: Record<'dark' | 'light', TooltipAppearance> = {\n dark: 'inverted',\n light: 'normal',\n};\n\nconst appearanceClasses: Record<TooltipAppearance, string> = {\n inverted: 'border border-inverted-border bg-inverted text-inverted-foreground',\n normal: 'border border-border bg-background text-foreground',\n};\n\n/**\n * Transparent `::before` hover bridge across the 8px gap (the positioning offset) on the side that\n * faces the trigger only, so the pointer can move onto the tooltip; the other sides get no bridge,\n * which would otherwise catch hovers and clicks meant for neighbouring controls.\n */\nconst bridgeClasses = [\n 'before:absolute',\n // Tooltip above the trigger: a strip below it.\n 'data-[side=top]:before:inset-x-0 data-[side=top]:before:top-full data-[side=top]:before:h-2',\n // Tooltip below the trigger: a strip above it.\n 'data-[side=bottom]:before:inset-x-0 data-[side=bottom]:before:bottom-full data-[side=bottom]:before:h-2',\n // wave-allow-physical: data-side is the physical side resolved by the positioning\n 'data-[side=left]:before:inset-y-0 data-[side=left]:before:left-full data-[side=left]:before:w-2',\n // wave-allow-physical: data-side is the physical side resolved by the positioning\n 'data-[side=right]:before:inset-y-0 data-[side=right]:before:right-full data-[side=right]:before:w-2',\n].join(' ');\n\n/**\n * The visual surface: wrapping text, typography reset against the host (header cells, muted\n * panels), and the hover bridge towards the trigger.\n */\nconst surfaceClasses = `max-w-60 whitespace-normal break-words rounded px-3 py-1.5 text-caption-1 font-normal normal-case tracking-normal text-start shadow-8 ${bridgeClasses}`;\n\ntype UnknownProps = Record<string, unknown>;\ntype Relationship = NonNullable<TooltipProps['relationship']>;\n\nconst HANDLER_KEY = /^on[A-Z]/;\n\n/** Naming attributes a generic element such as the fallback `<span>` must not carry. */\nconst NAMING_ARIA = ['aria-label', 'aria-labelledby'] as const;\n\n/**\n * Whether an event reached the wrapper from its own DOM subtree — the child — rather than through\n * a portal: React bubbles events from portaled content (the tooltip surface, a popup the child\n * renders in a portal) through the component tree.\n */\nfunction isOwnEvent(event: React.SyntheticEvent): boolean {\n return (event.currentTarget as Node).contains(event.target as Node);\n}\n\n/** `handler`, called only for the wrapper's own events (see {@link isOwnEvent}). */\nfunction ownEventsOnly<E extends React.SyntheticEvent>(\n handler: (event: E) => void,\n): (event: E) => void {\n return (event) => {\n if (isOwnEvent(event)) handler(event);\n };\n}\n\n/**\n * Splits the props the Tooltip receives, from its consumer or from a parent that clones its child\n * (Menu.Trigger, Popover.Trigger, Dialog.Trigger, Field): `id` and `aria-*` describe the element\n * the Tooltip is attached to, so they go to the child; the rest stays on the wrapper `<span>`.\n */\nfunction splitProps(props: UnknownProps): { childProps: UnknownProps; wrapperProps: UnknownProps } {\n const childProps: UnknownProps = {};\n const wrapperProps: UnknownProps = {};\n for (const [key, value] of Object.entries(props)) {\n if (key === 'id' || key.startsWith('aria-')) childProps[key] = value;\n else if (HANDLER_KEY.test(key) && typeof value === 'function') {\n // The wrapper sees the child's events as they bubble, but not those that reach it through\n // a portal, such as a click on the tooltip surface (it would toggle a parent trigger).\n wrapperProps[key] = ownEventsOnly(value as (event: React.SyntheticEvent) => void);\n } else wrapperProps[key] = value;\n }\n return { childProps, wrapperProps };\n}\n\nfunction omit(props: UnknownProps, keys: readonly string[]): UnknownProps {\n const result = { ...props };\n for (const key of keys) delete result[key];\n return result;\n}\n\nfunction hasIdRef(el: Element, attribute: string, id: string): boolean {\n return (el.getAttribute(attribute) ?? '').split(/\\s+/).includes(id);\n}\n\nfunction removeIdRef(el: Element, attribute: string, id: string): void {\n const rest = (el.getAttribute(attribute) ?? '')\n .split(/\\s+/)\n .filter((value) => value && value !== id);\n if (rest.length > 0) el.setAttribute(attribute, rest.join(' '));\n else el.removeAttribute(attribute);\n}\n\n/**\n * Makes sure the element people focus carries the tooltip relationship. After each commit, when no\n * focusable element inside the wrapper references `tooltipId` through `attribute` — children in the\n * fallback span, a non-focusable child element, or a child component that drops the prop (a\n * Popover or Dialog root) — the id is added to the first tabbable element inside the wrapper and\n * kept there while the subtree changes; a development warning explains the nesting, except for\n * the fallback span, whose children shape `renderTrigger` already warned about.\n */\nfunction useRelationshipTarget(\n wrapperRef: React.RefObject<HTMLSpanElement | null>,\n tooltipId: string,\n relationship: Relationship,\n childIsFallback: boolean,\n): void {\n const appliedRef = React.useRef<{ element: Element; attribute: string } | null>(null);\n const attribute = relationship === 'label' ? 'aria-labelledby' : 'aria-describedby';\n\n React.useLayoutEffect(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return;\n\n const update = () => {\n const applied = appliedRef.current;\n const carriers = Array.from(wrapper.querySelectorAll(`[${attribute}]`)).filter(\n (el) =>\n !(applied && applied.element === el && applied.attribute === attribute) &&\n hasIdRef(el, attribute, tooltipId),\n );\n const reached = carriers.some((el) => el.matches(FOCUSABLE_SELECTOR));\n const target = reached ? null : getFirstTabbable(wrapper);\n if (applied && (applied.element !== target || applied.attribute !== attribute)) {\n removeIdRef(applied.element, applied.attribute, tooltipId);\n appliedRef.current = null;\n }\n if (!target) return;\n if (!hasIdRef(target, attribute, tooltipId)) {\n target.setAttribute(attribute, joinIds(target.getAttribute(attribute), tooltipId) ?? '');\n }\n appliedRef.current = { element: target, attribute };\n if (!childIsFallback) {\n warnOnce(\n 'Tooltip:focus-target',\n `Tooltip: the element that takes focus inside it did not get \\`${attribute}\\` (the child is not focusable, or is a component, such as a Popover or Dialog root, that does not pass the prop on), so it was added to the first focusable element inside. Put the Tooltip directly around the focusable element, e.g. <Popover.Trigger><Tooltip content=\"…\"><Button /></Tooltip></Popover.Trigger>.`,\n );\n }\n };\n\n update();\n if (!appliedRef.current || typeof MutationObserver === 'undefined') return;\n // Keep it on the focusable element when the child replaces it or rewrites the attribute\n // without the Tooltip re-rendering.\n const observer = new MutationObserver(update);\n observer.observe(wrapper, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeFilter: [attribute],\n });\n return () => observer.disconnect();\n });\n}\n\n/**\n * Shows a short text label or description for its child on hover and keyboard focus.\n *\n * - The text is always present as a hidden `role=\"tooltip\"` element referenced by the child's\n * `aria-describedby` (or `aria-labelledby` with `relationship=\"label\"`), so screen readers get\n * it on focus without waiting for the delay; the child's own ids are kept.\n * - The visual surface is rendered in a portal while visible (it is `aria-hidden`, a copy of the\n * description), positioned on `side`/`align` with flipping and shifting to stay in view.\n * - It fades in and out over 100 ms (see `motion`; at once under reduced motion). The surface\n * mounts through the presence core: it carries `data-presence` and `data-state=\"open\"`, and\n * while it fades out `data-state=\"closed\"` and `inert`, staying where it was until its exit\n * ends; the Escape layer goes as it hides, not after the fade. Shown again during its exit, the\n * same surface fades back in. The hidden description is unchanged in every phase.\n * - It appears `openDelay` after the pointer rests on the child or the child takes keyboard focus,\n * stays visible while the pointer moves onto it, hides `closeDelay` after the pointer leaves or\n * immediately on blur, and Escape hides it without closing an enclosing dialog or popover. Focus\n * and hover inside a popup the child renders in a portal (a DatePicker calendar, a listbox) do\n * not show it, and the pointer moving onto such a popup hides it.\n * - The open state is uncontrolled by default (`defaultOpen`). With `open` and `onOpenChange`\n * (Fluent's `visible` and `onVisibleChange`) the parent owns it: hover, focus, leave, blur and\n * Escape then only ask for a change, and `open` alone shows the surface.\n * - `id` and `aria-*` props given to the Tooltip go to its child, merged with the child's own (the\n * child's `id` wins, id lists are joined, `aria-expanded`/`aria-controls`/`aria-haspopup` from\n * the Tooltip win). `className`, `style`, `ref`, `data-*` and event handlers stay on the wrapper\n * `<span>`; the handlers see the child's events as they bubble, not events from portaled\n * content such as the tooltip surface or a popup the child renders in a portal (a DatePicker\n * calendar, a listbox). `onMouseEnter` and `onMouseLeave` are the exception: React fires them\n * along the component tree, so they also fire when the pointer moves onto or off the tooltip\n * surface or such a popup. So the Tooltip can sit inside a trigger, and the trigger's\n * id and state reach the button: `<Menu.Trigger><Tooltip content=\"…\"><Button /></Tooltip>\n * </Menu.Trigger>` (also `Popover.Trigger`, `Dialog.Trigger`, `Drawer.Trigger`). Around a\n * trigger works too, since triggers pass `aria-describedby` on to their child.\n * - Wrap the focusable element itself. When the element that takes focus does not get the\n * relationship (a Popover or Dialog root, a component that drops props, a non-focusable\n * wrapper element), it is added to the first focusable element inside, with a development\n * warning.\n *\n * @example\n * <Menu>\n * <Menu.Trigger>\n * <Tooltip content=\"Edit, duplicate or delete the item\">\n * <Button>Actions</Button>\n * </Tooltip>\n * </Menu.Trigger>\n * <Menu.Popover>…</Menu.Popover>\n * </Menu>\n */\nexport const Tooltip = ({\n content,\n appearance: appearanceProp,\n variant,\n openDelay: openDelayProp,\n closeDelay = 100,\n delay,\n open: openProp,\n defaultOpen,\n onOpenChange,\n relationship = 'description',\n side = 'top',\n align = 'center',\n positioning,\n motion,\n children,\n className,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: TooltipProps) => {\n const appearance =\n resolveDeprecatedProp(\n 'Tooltip',\n appearanceProp,\n variant === undefined ? undefined : VARIANT_APPEARANCE[variant],\n 'variant',\n 'appearance',\n ) ?? 'inverted';\n const openDelay =\n resolveDeprecatedProp('Tooltip', openDelayProp, delay, 'delay', 'openDelay') ?? 200;\n const [open, setOpen] = useControllable(openProp, defaultOpen ?? false, onOpenChange);\n // The surface lives in a portal, which renders only in the browser: until then (the server HTML,\n // hydration) the tooltip is closed; the hidden description is rendered either way.\n const isClient = useIsClient();\n const visible = open && isClient;\n const timerRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const wrapperRef = React.useRef<HTMLSpanElement | null>(null);\n const surfaceRef = React.useRef<HTMLSpanElement | null>(null);\n const tooltipId = useId('tooltip');\n\n // The surface mounts and unmounts through the presence core, and enters also when it mounts\n // visible (a tooltip open by default fades in on a client render as after hydration); the\n // positioning and the Escape layer key on `visible`, so they go as it hides, not after its exit.\n // Destructured: react-hooks/refs treats an object whose member is passed to `ref` as a ref.\n const { isMounted, ref: presenceRef, presenceProps } = usePresence(visible, { appear: true });\n const motionClassName = useMotionClasses(motion, tooltipMotion);\n const { setReference, setFloating, floatingProps } = usePopupPosition({\n open: visible,\n side,\n align,\n ...resolvePositioning(positioning, { offset: 8 }),\n });\n const wrapperElementRef = useMergedRefs<HTMLSpanElement>(ref, wrapperRef, setReference);\n const surfaceElementRef = useMergedRefs<HTMLSpanElement>(surfaceRef, setFloating, presenceRef);\n\n // Timer handlers are event callbacks (stable, latest state): they are composed with the\n // consumer's handlers during render but only run from events and timers.\n const clearTimer = useEventCallback(() => {\n if (timerRef.current !== undefined) {\n clearTimeout(timerRef.current);\n timerRef.current = undefined;\n }\n });\n\n // show, hide and scheduleHide ask for the new state; a controlled tooltip changes only when the\n // parent updates `open`.\n const show = useEventCallback(() => {\n clearTimer();\n if (visible) return;\n if (openDelay <= 0) {\n setOpen(true);\n return;\n }\n timerRef.current = setTimeout(() => {\n timerRef.current = undefined;\n setOpen(true);\n }, openDelay);\n });\n\n const hide = useEventCallback(() => {\n clearTimer();\n setOpen(false);\n });\n\n // The grace period after the pointer leaves lets it move onto the tooltip.\n const scheduleHide = useEventCallback(() => {\n clearTimer();\n if (!visible) return;\n timerRef.current = setTimeout(() => {\n timerRef.current = undefined;\n setOpen(false);\n }, closeDelay);\n });\n\n // An Escape-only layer while visible: Escape hides the tooltip before any enclosing overlay. The\n // wrapper is its anchor (its trigger, not its surface): Tab from the child inside a focus trap\n // moves on from the popover, portal or dialog around the wrapper.\n useDismiss({\n open: visible,\n onDismiss: hide,\n refs: [wrapperRef, surfaceRef],\n anchorRef: wrapperRef,\n kind: 'tooltip',\n outsidePress: false,\n });\n\n React.useEffect(() => {\n const timer = timerRef;\n return () => clearTimeout(timer.current);\n }, []);\n\n // The tooltip's own reactions ignore a popup the child renders in a portal: its focus and blur\n // are not the child's, entering it does not show the tooltip, and the pointer moving onto it\n // (no mouseleave reaches the wrapper then) hides the tooltip, which would cover it. The tooltip\n // surface itself is portaled too but belongs to the tooltip: it stays hoverable.\n const showOnEnter = useEventCallback((event: React.MouseEvent<HTMLSpanElement>) => {\n if (isOwnEvent(event) || surfaceRef.current?.contains(event.target as Node)) show();\n });\n const hideOverPortaledPopup = useEventCallback((event: React.MouseEvent<HTMLSpanElement>) => {\n if (!isOwnEvent(event) && !surfaceRef.current?.contains(event.target as Node)) hide();\n });\n\n const { childProps, wrapperProps } = splitProps(rest);\n const target = unwrapFragment(children);\n const childIsFallback = !isCloneableElement(target);\n const attribute = relationship === 'label' ? 'aria-labelledby' : 'aria-describedby';\n // Props given to the Tooltip come first, as if the child had them; then the tooltip's own id.\n // The fallback span is a generic element: no state ARIA and no naming on it (the relationship\n // then reaches its first focusable element through useRelationshipTarget).\n const triggerProps: UnknownProps = childIsFallback\n ? omit(childProps, [...STATE_ARIA, ...NAMING_ARIA])\n : { ...childProps };\n if (!childIsFallback || relationship === 'description') {\n triggerProps[attribute] = joinIds(childProps[attribute] as string | undefined, tooltipId);\n }\n const child = renderTrigger(target, triggerProps, { componentName: 'Tooltip' });\n useRelationshipTarget(wrapperRef, tooltipId, relationship, childIsFallback);\n\n return (\n <span\n ref={wrapperElementRef}\n {...wrapperProps}\n className={cn(tooltipClassNames.root, 'inline-block', className)}\n onMouseEnter={composeEventHandlers(onMouseEnter, showOnEnter)}\n onMouseLeave={composeEventHandlers(onMouseLeave, scheduleHide)}\n onMouseOver={composeEventHandlers(\n wrapperProps.onMouseOver as React.MouseEventHandler<HTMLSpanElement> | undefined,\n hideOverPortaledPopup,\n )}\n onFocus={ownEventsOnly(composeEventHandlers(onFocus, show))}\n onBlur={ownEventsOnly(composeEventHandlers(onBlur, hide))}\n >\n {child}\n <span id={tooltipId} role=\"tooltip\" hidden>\n {content}\n </span>\n {isMounted && (\n <Portal layer=\"tooltip\">\n <span\n ref={surfaceElementRef}\n aria-hidden=\"true\"\n data-wave-tooltip-surface=\"\"\n data-state={visible ? 'open' : 'closed'}\n {...presenceProps}\n {...floatingProps}\n className={cn(\n tooltipClassNames.content,\n surfaceClasses,\n appearanceClasses[appearance],\n motionClassName,\n )}\n >\n {content}\n </span>\n </Portal>\n )}\n </span>\n );\n};\n\nTooltip.displayName = 'Tooltip';\n"],"mappings":"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"}
|