@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
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
//#region src/lib/flatTree.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
let t = [], n = /* @__PURE__ */ new Map();
|
|
4
|
+
e.forEach((e, r) => {
|
|
5
|
+
if (n.has(e.value)) {
|
|
6
|
+
t.push({
|
|
7
|
+
kind: "duplicate-value",
|
|
8
|
+
value: e.value,
|
|
9
|
+
index: r
|
|
10
|
+
});
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
n.set(e.value, {
|
|
14
|
+
item: e,
|
|
15
|
+
index: r,
|
|
16
|
+
parent: e.parentValue
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
for (let [e, r] of n) r.parent !== void 0 && !n.has(r.parent) && (t.push({
|
|
20
|
+
kind: "unknown-parent",
|
|
21
|
+
value: e,
|
|
22
|
+
parentValue: r.parent
|
|
23
|
+
}), r.parent = void 0);
|
|
24
|
+
let r = /* @__PURE__ */ new Map();
|
|
25
|
+
for (let e of n.keys()) {
|
|
26
|
+
if (r.has(e)) continue;
|
|
27
|
+
let i = [], a = e;
|
|
28
|
+
for (; a !== void 0 && !r.has(a);) r.set(a, 1), i.push(a), a = n.get(a)?.parent;
|
|
29
|
+
if (a !== void 0 && r.get(a) === 1) {
|
|
30
|
+
t.push({
|
|
31
|
+
kind: "cycle",
|
|
32
|
+
value: a
|
|
33
|
+
});
|
|
34
|
+
let e = n.get(a);
|
|
35
|
+
e && (e.parent = void 0);
|
|
36
|
+
}
|
|
37
|
+
for (let e of i) r.set(e, 2);
|
|
38
|
+
}
|
|
39
|
+
let i = [], a = /* @__PURE__ */ new Map();
|
|
40
|
+
for (let [e, t] of n) {
|
|
41
|
+
if (t.parent === void 0) {
|
|
42
|
+
i.push(e);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
let n = a.get(t.parent);
|
|
46
|
+
n ? n.push(e) : a.set(t.parent, [e]);
|
|
47
|
+
}
|
|
48
|
+
let o = /* @__PURE__ */ new Map(), s = [];
|
|
49
|
+
i.forEach((e, t) => s.push({
|
|
50
|
+
value: e,
|
|
51
|
+
level: 1,
|
|
52
|
+
position: t + 1,
|
|
53
|
+
setSize: i.length
|
|
54
|
+
}));
|
|
55
|
+
for (let e = 0; e < s.length; e += 1) {
|
|
56
|
+
let { value: t, level: r, position: i, setSize: c } = s[e], l = n.get(t), u = a.get(t) ?? [];
|
|
57
|
+
o.set(t, {
|
|
58
|
+
item: l.item,
|
|
59
|
+
index: l.index,
|
|
60
|
+
parentValue: l.parent,
|
|
61
|
+
level: r,
|
|
62
|
+
position: i,
|
|
63
|
+
setSize: c,
|
|
64
|
+
children: u,
|
|
65
|
+
hasChildren: u.length > 0,
|
|
66
|
+
isBranch: u.length > 0 || l.item.itemType === "branch"
|
|
67
|
+
}), u.forEach((e, t) => s.push({
|
|
68
|
+
value: e,
|
|
69
|
+
level: r + 1,
|
|
70
|
+
position: t + 1,
|
|
71
|
+
setSize: u.length
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
let c = /* @__PURE__ */ new Map();
|
|
75
|
+
for (let e of n.keys()) c.set(e, o.get(e));
|
|
76
|
+
return {
|
|
77
|
+
byValue: c,
|
|
78
|
+
roots: i,
|
|
79
|
+
issues: t
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function t(e, t) {
|
|
83
|
+
let n = [], r = [];
|
|
84
|
+
for (let t = e.roots.length - 1; t >= 0; --t) r.push(e.roots[t]);
|
|
85
|
+
for (; r.length > 0;) {
|
|
86
|
+
let i = e.byValue.get(r.pop());
|
|
87
|
+
if (!i) continue;
|
|
88
|
+
let a = i.isBranch && t.has(i.item.value);
|
|
89
|
+
if (n.push({
|
|
90
|
+
item: i.item,
|
|
91
|
+
level: i.level,
|
|
92
|
+
position: i.position,
|
|
93
|
+
setSize: i.setSize,
|
|
94
|
+
parentValue: i.parentValue,
|
|
95
|
+
hasChildren: i.hasChildren,
|
|
96
|
+
isBranch: i.isBranch,
|
|
97
|
+
expanded: a,
|
|
98
|
+
index: n.length
|
|
99
|
+
}), a) for (let e = i.children.length - 1; e >= 0; --e) r.push(i.children[e]);
|
|
100
|
+
}
|
|
101
|
+
return n;
|
|
102
|
+
}
|
|
103
|
+
function n(e) {
|
|
104
|
+
let t = /* @__PURE__ */ new Map();
|
|
105
|
+
for (let n of e.byValue.keys()) t.set(n, {
|
|
106
|
+
value: n,
|
|
107
|
+
children: []
|
|
108
|
+
});
|
|
109
|
+
for (let [n, r] of e.byValue) {
|
|
110
|
+
let e = t.get(n);
|
|
111
|
+
for (let n of r.children) e.children.push(t.get(n));
|
|
112
|
+
}
|
|
113
|
+
return e.roots.map((e) => t.get(e));
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { e as buildFlatTreeIndex, n as flatTreeForest, t as visibleFlatItems };
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=flatTree.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flatTree.mjs","names":["buildFlatTreeIndex","issues","drafts","item","value","draft","state","start","path","current","repeated","roots","childValues","siblings","byValue","queue","at","children","child","level","childAt","ordered","visibleFlatItems","visible","stack","index","record","open","expanded","flatTreeForest","nodes","node"],"sources":["../../src/lib/flatTree.ts"],"sourcesContent":["// The pure model behind `useFlatTree` and `FlatTree`: server-safe, no React import. A flat list of\n// items with `parentValue` links becomes an index (one pass, no recursion), the visible rows for an\n// expanded set (a walk that enters only expanded branches) and a `TreeNode` forest for the check\n// cascade of `treeCascade.ts`. Every walk is iterative, so a chain thousands of levels deep cannot\n// overflow the stack.\nimport type { TreeNode } from './treeCascade';\n\n/** One item of a flat tree: `parentValue` places it, items are listed in any order. */\nexport interface FlatTreeItemData {\n /** The item's identity; it must be unique among the items (a later duplicate is ignored). */\n value: string;\n /** The `value` of the item this one is nested in; absent for a root. */\n parentValue?: string;\n /**\n * `'branch'` marks an item that can expand even while it has no child items (children loaded\n * on demand). An item with child items is a branch whatever its type says.\n */\n itemType?: 'leaf' | 'branch';\n /** The text the item shows. */\n label?: string;\n /**\n * Whether the item is disabled. `FlatTree` reads it (the keys and typeahead skip the item, it is\n * not the tab stop, and the user cannot activate, expand or check it); the model ignores it:\n * `expand`, `collapse`, `toggle` and `setChecked` change a disabled item too, and a check of its\n * parent includes it.\n */\n disabled?: boolean;\n}\n\n/**\n * One row of the visible list: an item under expanded branches only, with the facts a row needs\n * for its tree semantics. A row is a branch when `hasChildren` is true or when\n * `item.itemType === 'branch'`; `expanded` is true only for a branch whose value is in the\n * expanded set (so a childless `'branch'` item can be expanded).\n */\nexport interface VisibleFlatItem {\n /** The item data, as passed in. */\n item: FlatTreeItemData;\n /** The depth, 1 for a root (`aria-level`). */\n level: number;\n /** The 1-based place among its siblings, in the order of `items` (`aria-posinset`). */\n position: number;\n /** The number of siblings, itself included (`aria-setsize`). */\n setSize: number;\n /** The value of the parent as indexed (`undefined` for a root, an unknown parent included). */\n parentValue: string | undefined;\n /** Whether other items are nested in it. */\n hasChildren: boolean;\n /** Whether it can expand: `hasChildren`, or `item.itemType === 'branch'` (`aria-expanded` is set for these). */\n isBranch: boolean;\n /** Whether it is a branch in the expanded set. */\n expanded: boolean;\n /** The place in the visible list, 0-based. */\n index: number;\n}\n\n/** What the index knows about one item. */\nexport interface FlatTreeNodeRecord {\n /** The item data, as passed in. */\n item: FlatTreeItemData;\n /** The place of the item in `items`, 0-based. */\n index: number;\n /** The value of the parent as indexed: `undefined` for a root, also when the parent was unknown or the link was cut as a cycle. */\n parentValue: string | undefined;\n /** The depth, 1 for a root. */\n level: number;\n /** The 1-based place among its siblings. */\n position: number;\n /** The number of siblings, itself included. */\n setSize: number;\n /** The values of the items nested in it, in the order of `items`. */\n children: readonly string[];\n /** Whether other items are nested in it (`children` is not empty). */\n hasChildren: boolean;\n /** Whether it can expand: `hasChildren`, or `item.itemType === 'branch'`. */\n isBranch: boolean;\n}\n\n/** A problem the index found in the items and repaired. Stable: `useFlatTree` reports these in development. */\nexport type FlatTreeIssue =\n | {\n /** A later item with a value an earlier one has: it is ignored (the first is kept). */\n kind: 'duplicate-value';\n value: string;\n /** The place of the ignored item in `items`. */\n index: number;\n }\n | {\n /** An item whose `parentValue` matches no item: it is indexed as a root. */\n kind: 'unknown-parent';\n value: string;\n parentValue: string;\n }\n | {\n /** A loop of parents: the link of this value to its parent is cut, so it is a root. */\n kind: 'cycle';\n value: string;\n };\n\n/** The indexed items of a flat tree, from `buildFlatTreeIndex`. */\nexport interface FlatTreeIndex {\n /** Every item by value (one record per value). */\n byValue: Map<string, FlatTreeNodeRecord>;\n /** The values of the roots, in the order of `items`. */\n roots: readonly string[];\n /** What was repaired, in the order it was found: duplicates first, then unknown parents, then cycles. */\n issues: readonly FlatTreeIssue[];\n}\n\ninterface Draft {\n item: FlatTreeItemData;\n index: number;\n parent: string | undefined;\n}\n\n/**\n * Indexes `items` in one pass over them (linear time, no recursion). Repairs, each reported as an\n * issue: a repeated value keeps its first item; an item whose parent is unknown becomes a root;\n * a loop of parents is cut at the first of its values met by the walk up from the first item, in\n * `items` order, whose parent chain reaches the loop (an item outside the loop that leads into it\n * can start that walk: `[x→b, a→b, b→a]` cuts at `b`), and that value becomes a root. Siblings\n * keep the order of `items`.\n */\nexport function buildFlatTreeIndex(items: readonly FlatTreeItemData[]): FlatTreeIndex {\n const issues: FlatTreeIssue[] = [];\n const drafts = new Map<string, Draft>();\n items.forEach((item, index) => {\n if (drafts.has(item.value)) {\n issues.push({ kind: 'duplicate-value', value: item.value, index });\n return;\n }\n drafts.set(item.value, { item, index, parent: item.parentValue });\n });\n\n for (const [value, draft] of drafts) {\n if (draft.parent !== undefined && !drafts.has(draft.parent)) {\n issues.push({ kind: 'unknown-parent', value, parentValue: draft.parent });\n draft.parent = undefined;\n }\n }\n\n // Colour walk: 1 while on the current path, 2 once settled. A walk that reaches a value of its\n // own path has found a loop; cutting that value's parent link ends it.\n const state = new Map<string, 1 | 2>();\n for (const start of drafts.keys()) {\n if (state.has(start)) continue;\n const path: string[] = [];\n let current: string | undefined = start;\n while (current !== undefined && !state.has(current)) {\n state.set(current, 1);\n path.push(current);\n current = drafts.get(current)?.parent;\n }\n if (current !== undefined && state.get(current) === 1) {\n issues.push({ kind: 'cycle', value: current });\n const repeated = drafts.get(current);\n if (repeated) repeated.parent = undefined;\n }\n for (const value of path) state.set(value, 2);\n }\n\n const roots: string[] = [];\n const childValues = new Map<string, string[]>();\n for (const [value, draft] of drafts) {\n if (draft.parent === undefined) {\n roots.push(value);\n continue;\n }\n const siblings = childValues.get(draft.parent);\n if (siblings) siblings.push(value);\n else childValues.set(draft.parent, [value]);\n }\n\n const byValue = new Map<string, FlatTreeNodeRecord>();\n const queue: Array<{ value: string; level: number; position: number; setSize: number }> = [];\n roots.forEach((value, at) =>\n queue.push({ value, level: 1, position: at + 1, setSize: roots.length }),\n );\n // Every item is reachable from a root now: the loops are cut and the unknown parents are roots.\n for (let at = 0; at < queue.length; at += 1) {\n const { value, level, position, setSize } = queue[at];\n const draft = drafts.get(value) as Draft;\n const children = childValues.get(value) ?? [];\n byValue.set(value, {\n item: draft.item,\n index: draft.index,\n parentValue: draft.parent,\n level,\n position,\n setSize,\n children,\n hasChildren: children.length > 0,\n isBranch: children.length > 0 || draft.item.itemType === 'branch',\n });\n children.forEach((child, childAt) =>\n queue.push({\n value: child,\n level: level + 1,\n position: childAt + 1,\n setSize: children.length,\n }),\n );\n }\n // `byValue` is filled in breadth-first order; present it in the order of `items`.\n const ordered = new Map<string, FlatTreeNodeRecord>();\n for (const value of drafts.keys()) ordered.set(value, byValue.get(value) as FlatTreeNodeRecord);\n\n return { byValue: ordered, roots, issues };\n}\n\n/**\n * The rows visible with `expanded`: the roots, and the children of every branch in the set, in\n * tree order. Only expanded branches are entered, so the cost is the number of rows returned plus\n * the depth of the stack, never the number of items. A value in `expanded` that is no branch (a\n * leaf, or no item at all) has no effect.\n */\nexport function visibleFlatItems(\n index: FlatTreeIndex,\n expanded: ReadonlySet<string>,\n): readonly VisibleFlatItem[] {\n const visible: VisibleFlatItem[] = [];\n const stack: string[] = [];\n for (let at = index.roots.length - 1; at >= 0; at -= 1) stack.push(index.roots[at]);\n while (stack.length > 0) {\n const record = index.byValue.get(stack.pop() as string);\n if (!record) continue;\n const open = record.isBranch && expanded.has(record.item.value);\n visible.push({\n item: record.item,\n level: record.level,\n position: record.position,\n setSize: record.setSize,\n parentValue: record.parentValue,\n hasChildren: record.hasChildren,\n isBranch: record.isBranch,\n expanded: open,\n index: visible.length,\n });\n if (open) {\n for (let at = record.children.length - 1; at >= 0; at -= 1) stack.push(record.children[at]);\n }\n }\n return visible;\n}\n\n/**\n * The items as a `TreeNode` forest (one node per indexed item, children in the order of `items`),\n * the input of `computeCheckStates` and `toggleCheck`. Built without recursion; walking the result\n * with those recursive functions is as deep as the tree is.\n */\nexport function flatTreeForest(index: FlatTreeIndex): TreeNode[] {\n const nodes = new Map<string, TreeNode>();\n for (const value of index.byValue.keys()) nodes.set(value, { value, children: [] });\n for (const [value, record] of index.byValue) {\n const node = nodes.get(value) as TreeNode;\n for (const child of record.children) node.children.push(nodes.get(child) as TreeNode);\n }\n return index.roots.map((value) => nodes.get(value) as TreeNode);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=`transition-[opacity,scale] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:scale-85 data-[presence=exiting]:opacity-0 data-[presence=exiting]:scale-85`,t=`transition-opacity duration-wave-gentle ease-wave-easy-ease data-[presence=exiting]:duration-wave-normal motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0`,n={start:`transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:-translate-x-full data-[presence=exiting]:-translate-x-full wave-rtl:data-[presence=entering]:starting:translate-x-full wave-rtl:data-[presence=exiting]:translate-x-full`,end:`transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-x-full data-[presence=exiting]:translate-x-full wave-rtl:data-[presence=entering]:starting:-translate-x-full wave-rtl:data-[presence=exiting]:-translate-x-full`,left:`transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:-translate-x-full data-[presence=exiting]:-translate-x-full`,right:`transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-x-full data-[presence=exiting]:translate-x-full`,bottom:`transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-y-full data-[presence=exiting]:translate-y-full`},r={small:`duration-wave-gentle`,medium:`duration-wave-slow`,large:`duration-wave-slower`,full:`duration-wave-ultra-slow`},i={small:`transition-opacity duration-wave-gentle ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0`,medium:`transition-opacity duration-wave-slow ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0`,large:`transition-opacity duration-wave-slower ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0`,full:`transition-opacity duration-wave-ultra-slow ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0`},a={start:`grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] justify-items-end justify-end overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none`,end:`grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] justify-items-start overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none`,left:`grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] [justify-items:right] [justify-content:right] overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none`,right:`grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] [justify-items:left] [justify-content:left] overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none`,bottom:`grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-start overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-h-none`},o={width:`transition-[grid-template-columns,opacity] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:grid-cols-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-cols-[minmax(0,0fr)] data-[presence=exiting]:opacity-0`,height:`transition-[grid-template-rows,opacity] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:opacity-0`},s=`transition-[opacity,translate] duration-wave-normal ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-faster data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[side=top]:data-[presence=entering]:starting:translate-y-1 data-[side=top]:data-[presence=exiting]:translate-y-1 data-[side=bottom]:data-[presence=entering]:starting:-translate-y-1 data-[side=bottom]:data-[presence=exiting]:-translate-y-1 data-[side=left]:data-[presence=entering]:starting:translate-x-1 data-[side=left]:data-[presence=exiting]:translate-x-1 data-[side=right]:data-[presence=entering]:starting:-translate-x-1 data-[side=right]:data-[presence=exiting]:-translate-x-1`,c=`transition-opacity duration-wave-faster ease-wave-easy-ease motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0`,l=`grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-start overflow-hidden data-[presence=entered]:contents`,u=`transition-[grid-template-rows,opacity] duration-wave-normal ease-wave-easy-ease-max motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:opacity-0`,d=`transition-transform duration-wave-fast ease-wave-easy-ease motion-reduce:transition-none`,f=`*:transition *:duration-wave-fast *:ease-wave-easy-ease motion-reduce:*:transition-none`,p=`grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] not-data-[presence=entered]:overflow-hidden`,m={top:`transition-[grid-template-rows,margin-bottom,opacity,translate] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-easy-ease data-[presence=exiting]:[transition-delay:var(--wave-duration-normal),var(--wave-duration-normal),0s,0s] motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:-translate-y-2 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0`,bottom:`transition-[grid-template-rows,margin-bottom,opacity,translate] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-easy-ease data-[presence=exiting]:[transition-delay:var(--wave-duration-normal),var(--wave-duration-normal),0s,0s] motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:translate-y-2 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0`},h=`grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-end content-end overflow-hidden data-[presence=entered]:contents`,g=`transition-[grid-template-rows,margin-bottom,opacity] duration-wave-gentle ease-wave-linear motion-reduce:transition-none data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0`,_=`data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0`,v=`transition-transform duration-wave-slow ease-wave-easy-ease motion-reduce:transition-none`,y=`transition-opacity duration-wave-slow ease-wave-easy-ease motion-reduce:transition-none`,b=`after:transition-[translate,scale] after:duration-wave-slow after:ease-wave-decelerate-max motion-reduce:after:transition-none`,x=`w-2/5 animate-wave-indeterminate wave-rtl:animate-wave-indeterminate-rtl motion-reduce:w-full motion-reduce:translate-x-0 motion-reduce:animate-wave-pulse wave-rtl:motion-reduce:animate-wave-pulse`,S=`[presence=`;function C(e){return typeof e==`string`?e:e.className}function w(e,t){return e===void 0&&(t?.includes(S)??!1)}function T(e,t,n,r){return e===null?``:e===void 0?n===`none`||w(e,r)?``:t:C(e)}exports.carouselFadeMotion=y,exports.carouselSlideMotion=v,exports.collapseMotion=u,exports.collapseStructure=l,exports.dialogBackdropMotion=t,exports.dialogMotion=e,exports.drawerBackdropMotion=i,exports.drawerDurations=r,exports.drawerMotion=n,exports.expandIconMotion=d,exports.inlineDrawerMotion=o,exports.inlineDrawerStructure=a,exports.messageBarGroupEnterMotion=_,exports.messageBarGroupExitMotion=g,exports.messageBarGroupItemStructure=h,exports.navActionsRevealMotion=f,exports.popupMotion=s,exports.progressIndeterminateMotion=x,exports.resolveMotion=T,exports.tabIndicatorMotion=b,exports.toastMotion=m,exports.toastStructure=p,exports.tooltipMotion=c,exports.usesLegacyMotion=w;
|
|
2
|
+
//# sourceMappingURL=motion.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motion.cjs","names":["dialogMotion","dialogBackdropMotion","drawerMotion","drawerDurations","drawerBackdropMotion","inlineDrawerStructure","inlineDrawerMotion","popupMotion","tooltipMotion","collapseStructure","collapseMotion","expandIconMotion","navActionsRevealMotion","toastStructure","toastMotion","messageBarGroupItemStructure","messageBarGroupExitMotion","messageBarGroupEnterMotion","carouselSlideMotion","carouselFadeMotion","tabIndicatorMotion","progressIndeterminateMotion","PRESENCE_VARIANT","slotClassName","slot","usesLegacyMotion","legacyClassName","resolveMotion","preference","recipe"],"sources":["../../src/lib/motion.ts"],"sourcesContent":["import type { MotionPreference, MotionSlot, SurfaceSize } from './types';\n\n/**\n * The motion of Wave's animated parts, in one server-safe module that imports nothing at run\n * time (types only), so a Server Component and the build's Node checks can reach it.\n *\n * Every recipe is one plain string literal per value, never a concatenation, a template or a call:\n * components compose the strings at run time, and the build reads each literal whole. A recipe\n * keys its classes on the presence core's phases (the enter's start gated on the entering phase,\n * the exit on the exiting phase), times them with Wave's duration and curve tokens, lists the\n * properties it moves and switches its transition off under reduced motion. This comment\n * describes each recipe in words and never writes a class: the CSS build reads every word of this\n * file.\n *\n * - `dialogMotion`, the Dialog surface: opacity and scale. It enters from transparent at 85% of its\n * size over the gentle duration (250 ms) with the mid decelerating curve, and exits back to the\n * same over the normal duration (200 ms) with the min accelerating curve.\n * - `dialogBackdropMotion`, the Dialog backdrop: opacity only, with the easy-ease curve. It fades in\n * over the gentle duration and out over the normal duration, the surface's exit, so the backdrop\n * never outlasts the surface (the presence core waits only for the surface).\n * - `drawerMotion`, the overlay panel of Drawer and NavDrawer, per edge: opacity and translate. It\n * enters from transparent and moved out by its whole width (its whole height at the bottom)\n * beyond its edge, with the mid decelerating curve, and exits back there with the min\n * accelerating curve. The start and end edges follow the text direction (a right-to-left\n * counterpart on the same value), the left and right edges do not mirror. It holds no duration:\n * the panel adds its size's from `drawerDurations`.\n * - `drawerDurations`, the duration of an overlay panel per size, the same both ways: the gentle\n * duration (250 ms) when small, the slow one (300 ms) when medium, the slower one (400 ms) when\n * large and the ultra-slow one (500 ms) when full.\n * - `drawerBackdropMotion`, the overlay drawer's backdrop per size: opacity only, with the linear\n * curve and its size's duration both ways, so it ends with the panel.\n * - `inlineDrawerStructure`, the element around an inline drawer's panel, per edge (not motion: it\n * is on the element whatever its motion slot holds). While the drawer is open the element\n * renders no box of its own, so the panel lays out in the page as it did before the element\n * existed; while it enters or exits, the element is a clipping grid of one track on the panel's\n * axis (columns at a side, rows at the bottom) whose minimum is zero, so the track can get\n * smaller than the panel, padding and borders included, and it keeps its size in a flex row. The\n * panel sits against the inner edge of that track (the end at the start edge, the start at the\n * end edge, the physical right and left at the left and right edges, the top at the bottom\n * edge), so it reads as sliding out to its own edge, and the track sits on that same side of the\n * element: while the collapse is partly open, the grid gives its track only that fraction of\n * the element, and a track left at the element's start would leave an empty strip between the\n * visible panel and the page wherever the panel aligns to the end. While the element is not\n * entered it also lifts the panel's own maximum on that axis (its width at a side, its height at\n * the bottom): that maximum is a percentage, which inside the grid would follow the track and\n * squeeze the panel's content as the track narrows, where the track should only clip the panel.\n * Entered, the maximum applies again against the page, as before. Its track on the other axis\n * (the row at a side, the column at the bottom) has a minimum of zero too and stays whole, so\n * the panel fills the element on that axis as it fills its place once entered, rather than\n * growing there to its content's own size.\n * - `inlineDrawerMotion`, the motion of that element per axis: its track and its opacity. It\n * enters from an empty, transparent track with the mid decelerating curve and exits back to one\n * with the min accelerating curve, so the space the panel takes in the layout opens and closes\n * while the panel keeps its size. It holds no duration: the element adds its size's from\n * `drawerDurations`.\n * - `popupMotion`, a positioned popup (Popover.Content, Menu.Popover and its submenus, the\n * InfoButton note and the TeachingPopover surface): opacity and translate. It enters from\n * transparent and moved 4px toward its anchor, on the axis of the side it opened on (the\n * resolved physical side the surface renders as `data-side`: a popup below its anchor starts\n * 4px higher, one to its right 4px further left), over the normal duration (200 ms) with the mid\n * decelerating curve, and exits back there over the faster duration (100 ms) with the min\n * accelerating curve. It lists the properties it moves and never the one floating-ui places the\n * popup with, so the popup never glides from its last position; a popup that renders no side (a\n * TeachingPopover rendered in place, without a target) only fades.\n * - `tooltipMotion`, the Tooltip surface: opacity only. It fades in from transparent and back out\n * over the faster duration (100 ms) with the easy-ease curve, both ways, and does not slide. Like\n * the popups, it never lists the property floating-ui places the surface with.\n * - `collapseStructure`, the element around the part a disclosure opens and closes (Accordion's\n * region, a Tree group, a Nav category's list; not motion: it is on the element whatever its\n * motion slot holds). While the part is open the element renders no box of its own, so the part\n * lays out in its parent as it did before the element existed; while it enters or exits, the\n * element is a clipping grid of one row track whose minimum is zero, so the track can get\n * smaller than the part, padding and borders included. The part sits at the top of that track\n * at its own height rather than stretched to it: the track only clips the part, so a part that\n * scrolls shows no scroll bar and keeps its line breaks, and its background and border cover\n * all of its visible part (while the collapse is partly open, the grid gives its track only that\n * fraction of the element, so a stretched part would be shorter than what the element shows).\n * Its one column has a minimum of zero too and fills the element, so the part keeps the width it\n * has once entered: a column sized by its content would grow to the part's longest unbreakable\n * line (a long link, a label that does not wrap), and the part would be wider, its end side\n * clipped and its lines broken anew, for as long as it moves.\n * - `collapseMotion`, the motion of that element: its row track and its opacity. It enters from\n * an empty, transparent track and exits back to one over the normal duration (200 ms) with the\n * max easy-ease curve, both ways, so the space the part takes opens and closes while the content\n * keeps its width.\n * - `expandIconMotion`, the expand icon of a Nav category (its default chevron, or the span of a\n * custom glyph): the transition of its transform over the fast duration (150 ms) with the\n * easy-ease curve, both ways, so the chevron's half turn as the category opens and closes is\n * animated. The turn itself is state, not motion: without this recipe the chevron still turns,\n * at once.\n * - `navActionsRevealMotion`, the group of a Nav item's actions: the default transition on each\n * of its direct children (so a button child keeps its colour transition, and its opacity fades)\n * over the fast duration (150 ms) with the easy-ease curve, so an action fades in as its row is\n * hovered or takes focus, and out again. It replaces any transition list of the children's own.\n * - `toastStructure`, the container of each toast of a Toaster (not motion: it is on the element\n * whatever its motion slot holds): a grid of one cell around the one element that holds the\n * toast's content, both of whose tracks have a minimum of zero. The row track can so get\n * smaller than that content, and the column keeps the content to the container's width (a\n * column sized by its content would grow to the content's longest unbreakable line, such as a\n * long link, past the region's width). Unlike the elements of the disclosures it always has a\n * box of its own (it takes focus); it clips what it holds while it enters or exits, and no\n * longer once it is shown.\n * - `toastMotion`, the motion of that container per edge of the stack (the top or bottom edge its\n * position names): its row track, its bottom margin, its opacity and translate. It enters over\n * the gentle duration (250 ms) with the mid decelerating curve, all together: the track opens\n * from empty, the margin returns from minus the region's 8px gap, and the toast fades in from\n * transparent while it slides 8px in from beyond the stack's edge (from below at the bottom,\n * from above at the top). It exits over the normal duration (200 ms) with the easy-ease curve:\n * the toast fades out in place first, then the track and the margin close after a delay of the\n * same normal duration, so the toasts around it glide together once it has faded. The margin\n * makes up for the gap the region keeps after each toast, so nothing moves when the exited\n * container unmounts. Under reduced motion nothing is transitioned, so the delay goes too.\n * - `messageBarGroupItemStructure`, the element around each bar of a MessageBarGroup (not motion:\n * it is on the element whatever its motion slot holds). While the bar is shown the element\n * renders no box of its own, so the bar is an item of the group's stack as it would be without\n * the element; while it enters or exits, the element is a clipping grid of one row track whose\n * minimum is zero. The bar sits at the bottom of that track at its own height, and the track at\n * the bottom of the element: while the collapse is partly open the grid gives its track only\n * that fraction of the element, so a track left at the top would leave an empty strip under\n * the visible part of the bar. So the element always shows the bottom of the bar, which reads\n * as sliding down into the space as it opens. Its one column has a minimum of zero too and fills\n * the element, so the bar keeps the width it has once shown.\n * - `messageBarGroupExitMotion`, the default motion of that element: its row track, its bottom\n * margin and its opacity, over the gentle duration (250 ms) with the linear curve. It exits by\n * closing the track to empty while the margin goes to minus the group's 8px gap and the bar\n * fades out, so the bars after it glide up together and nothing moves when the exited element\n * unmounts.\n * - `messageBarGroupEnterMotion`, the enter a MessageBarGroup adds after the exit with its `both`\n * animation: an added bar starts from an empty track, minus the gap and transparent, and opens\n * on the exit's transition (250 ms, linear). It holds no transition of its own.\n * - `carouselSlideMotion`, the track of a Carousel that slides: the transition of its transform\n * (the inline translation that shows the current page) over the slow duration (300 ms) with the\n * easy-ease curve, so the track glides to the new page. It keys on no phase: the carousel drops\n * it while the track follows a drag, so the track stays under the pointer, and a carousel's\n * `motionDuration` other than 300 ms replaces the duration with an inline one.\n * - `carouselFadeMotion`, each slide of a Carousel that fades: the transition of its opacity over\n * the slow duration (300 ms) with the easy-ease curve, so the slide that leaves fades out while\n * the one that comes fades in, in the same place. It keys on no phase either (the carousel hides\n * the inactive slides by their opacity), and `motionDuration` replaces its duration the same way.\n * - `tabIndicatorMotion`, the line of the selected tab of a TabList with the underline look (drawn\n * by the tab's after pseudo-element, not by the tab itself): the transition of its translate\n * and scale over the slow duration (300 ms) with the max decelerating curve, so the line slides\n * and stretches from the tab selected before to the new one. It keys on no phase: for one frame\n * after the selection moves, the TabList gives the new tab the line's start (the offset and the\n * size ratio of the previous tab, measured in physical pixels) as two custom properties without\n * this recipe, then clears them and adds it, so the line glides back to its own tab. Under\n * reduced motion the line's transition is off, and the TabList writes no start either.\n * - `progressIndeterminateMotion`, the fill of an indeterminate ProgressBar (0.14's own list,\n * unchanged): a fill two fifths of the track wide that sweeps across it with Wave's indeterminate\n * keyframes, mirrored by the right-to-left counterpart on the same value. Under reduced motion\n * it becomes a full-width fill that pulses in place instead, in either direction.\n *\n * The resolver below picks the classes of a part: its motion slot, the provider's preference and\n * the className rule of the parts that keep 0.14's own motion.\n */\n\n/** The Dialog surface's default motion: scale and fade, 250 ms in and 200 ms out. */\nexport const dialogMotion =\n 'transition-[opacity,scale] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:scale-85 data-[presence=exiting]:opacity-0 data-[presence=exiting]:scale-85';\n\n/** The Dialog backdrop's default motion: a fade, 250 ms in and 200 ms out (the surface's exit). */\nexport const dialogBackdropMotion =\n 'transition-opacity duration-wave-gentle ease-wave-easy-ease data-[presence=exiting]:duration-wave-normal motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0';\n\n/**\n * An edge a drawer is attached to (Drawer's `DrawerPosition`, which lives in a client component\n * module that this module does not import).\n */\ntype DrawerEdge = 'start' | 'end' | 'left' | 'right' | 'bottom';\n\n/**\n * The overlay drawer panel's default motion per edge: a slide from beyond its edge and a fade,\n * timed by `drawerDurations` (composed at run time).\n */\nexport const drawerMotion: Readonly<Record<DrawerEdge, string>> = {\n start:\n 'transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:-translate-x-full data-[presence=exiting]:-translate-x-full wave-rtl:data-[presence=entering]:starting:translate-x-full wave-rtl:data-[presence=exiting]:translate-x-full',\n end: 'transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-x-full data-[presence=exiting]:translate-x-full wave-rtl:data-[presence=entering]:starting:-translate-x-full wave-rtl:data-[presence=exiting]:-translate-x-full',\n left: 'transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:-translate-x-full data-[presence=exiting]:-translate-x-full', // wave-allow-physical: left and right drawers do not mirror\n right:\n 'transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-x-full data-[presence=exiting]:translate-x-full', // wave-allow-physical: left and right drawers do not mirror\n bottom:\n 'transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-y-full data-[presence=exiting]:translate-y-full',\n};\n\n/** The overlay drawer panel's duration per size: 250, 300, 400 and 500 ms, both ways. */\nexport const drawerDurations: Readonly<Record<SurfaceSize, string>> = {\n small: 'duration-wave-gentle',\n medium: 'duration-wave-slow',\n large: 'duration-wave-slower',\n full: 'duration-wave-ultra-slow',\n};\n\n/** The overlay drawer backdrop's default motion per size: a linear fade over its size's duration. */\nexport const drawerBackdropMotion: Readonly<Record<SurfaceSize, string>> = {\n small:\n 'transition-opacity duration-wave-gentle ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0',\n medium:\n 'transition-opacity duration-wave-slow ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0',\n large:\n 'transition-opacity duration-wave-slower ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0',\n full: 'transition-opacity duration-wave-ultra-slow ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0',\n};\n\n/**\n * The structure of the element around an inline drawer's panel, per edge: no box while open, a\n * clipping one-track grid on the panel's axis while it enters or exits, the panel and the track\n * against its inner edge (so no empty strip opens next to the page), the panel without its\n * percentage maximum on that axis (so it is clipped, not squeezed), and a whole track with a zero\n * minimum on the other axis (so the panel fills the element there, as once entered).\n */\nexport const inlineDrawerStructure: Readonly<Record<DrawerEdge, string>> = {\n start:\n 'grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] justify-items-end justify-end overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none',\n end: 'grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] justify-items-start overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none',\n left: 'grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] [justify-items:right] [justify-content:right] overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none', // wave-allow-physical: the consumer asked for the physical left edge\n right:\n 'grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] [justify-items:left] [justify-content:left] overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none', // wave-allow-physical: the consumer asked for the physical right edge\n bottom:\n 'grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-start overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-h-none',\n};\n\n/**\n * The inline drawer's default motion per axis, on the element around its panel: the track opens\n * from zero and closes back with a fade, timed by `drawerDurations` (composed at run time).\n */\nexport const inlineDrawerMotion: Readonly<Record<'width' | 'height', string>> = {\n width:\n 'transition-[grid-template-columns,opacity] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:grid-cols-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-cols-[minmax(0,0fr)] data-[presence=exiting]:opacity-0',\n height:\n 'transition-[grid-template-rows,opacity] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:opacity-0',\n};\n\n/**\n * The default motion of a positioned popup (Popover.Content, Menu.Popover and its submenus, the\n * InfoButton note and the TeachingPopover surface): a fade and a 4px slide away from its anchor,\n * by the side it opened on, 200 ms in and 100 ms out; only the fade without a side.\n */\nexport const popupMotion =\n 'transition-[opacity,translate] duration-wave-normal ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-faster data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[side=top]:data-[presence=entering]:starting:translate-y-1 data-[side=top]:data-[presence=exiting]:translate-y-1 data-[side=bottom]:data-[presence=entering]:starting:-translate-y-1 data-[side=bottom]:data-[presence=exiting]:-translate-y-1 data-[side=left]:data-[presence=entering]:starting:translate-x-1 data-[side=left]:data-[presence=exiting]:translate-x-1 data-[side=right]:data-[presence=entering]:starting:-translate-x-1 data-[side=right]:data-[presence=exiting]:-translate-x-1'; // wave-allow-physical: data-side is the resolved physical side\n\n/** The Tooltip surface's default motion: a fade, 100 ms both ways, without a slide. */\nexport const tooltipMotion =\n 'transition-opacity duration-wave-faster ease-wave-easy-ease motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0';\n\n/**\n * The structure of the element around a disclosure's collapsing part (Accordion's region, a Tree\n * group, a Nav category's list): no box while open, a clipping one-track grid of rows while it\n * enters or exits, with the part at the top of the track at its own height (clipped, not\n * squeezed) and in a whole column with a zero minimum (the width it has once entered).\n */\nexport const collapseStructure =\n 'grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-start overflow-hidden data-[presence=entered]:contents';\n\n/**\n * A disclosure's default collapse, on the element around its part: the row track opens from zero\n * and closes back with a fade, 200 ms both ways.\n */\nexport const collapseMotion =\n 'transition-[grid-template-rows,opacity] duration-wave-normal ease-wave-easy-ease-max motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:opacity-0';\n\n/** The default motion of a Nav category's expand icon: its turn is animated, 150 ms both ways. */\nexport const expandIconMotion =\n 'transition-transform duration-wave-fast ease-wave-easy-ease motion-reduce:transition-none';\n\n/**\n * The default reveal of a Nav item's actions, on their group: each action fades in and out as\n * its row is hovered or takes focus, 150 ms both ways.\n */\nexport const navActionsRevealMotion =\n '*:transition *:duration-wave-fast *:ease-wave-easy-ease motion-reduce:*:transition-none';\n\n/**\n * The structure of a toast's container: a one-cell grid around the toast's content element, its\n * tracks with a zero minimum (the content keeps the container's width), clipping it while the\n * container enters or exits.\n */\nexport const toastStructure =\n 'grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] not-data-[presence=entered]:overflow-hidden';\n\n/**\n * A toast container's default motion per edge of its stack: it opens, fades in and slides from\n * that edge together, 250 ms; it fades out over 200 ms, then closes over 200 ms more.\n */\nexport const toastMotion: Readonly<Record<'top' | 'bottom', string>> = {\n top: 'transition-[grid-template-rows,margin-bottom,opacity,translate] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-easy-ease data-[presence=exiting]:[transition-delay:var(--wave-duration-normal),var(--wave-duration-normal),0s,0s] motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:-translate-y-2 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0',\n bottom:\n 'transition-[grid-template-rows,margin-bottom,opacity,translate] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-easy-ease data-[presence=exiting]:[transition-delay:var(--wave-duration-normal),var(--wave-duration-normal),0s,0s] motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:translate-y-2 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0',\n};\n\n/**\n * The structure of the element around each bar of a MessageBarGroup: no box while the bar is\n * shown, a clipping one-track grid of rows while it enters or exits, with the bar at the bottom\n * of the track at its own height and the track at the bottom of the element (so no empty strip\n * opens under the bar), in a whole column with a zero minimum (the width it has once shown).\n */\nexport const messageBarGroupItemStructure =\n 'grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-end content-end overflow-hidden data-[presence=entered]:contents';\n\n/**\n * A MessageBarGroup bar's default exit, on the element around it: its row track and its bottom\n * margin close while it fades out, 250 ms.\n */\nexport const messageBarGroupExitMotion =\n 'transition-[grid-template-rows,margin-bottom,opacity] duration-wave-gentle ease-wave-linear motion-reduce:transition-none data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0';\n\n/**\n * The enter a MessageBarGroup adds to the exit with `animate=\"both\"`: an added bar's row track and\n * bottom margin open from closed while it fades in, on the exit's transition.\n */\nexport const messageBarGroupEnterMotion =\n 'data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0';\n\n/** A sliding Carousel track's motion: its transform glides to the new page, 300 ms. */\nexport const carouselSlideMotion =\n 'transition-transform duration-wave-slow ease-wave-easy-ease motion-reduce:transition-none';\n\n/** A fading Carousel slide's motion: it fades in or out in place, 300 ms. */\nexport const carouselFadeMotion =\n 'transition-opacity duration-wave-slow ease-wave-easy-ease motion-reduce:transition-none';\n\n/**\n * The default slide of a TabList's selection line, on the selected tab's after pseudo-element: it\n * moves and stretches from the tab selected before, 300 ms.\n */\nexport const tabIndicatorMotion =\n 'after:transition-[translate,scale] after:duration-wave-slow after:ease-wave-decelerate-max motion-reduce:after:transition-none';\n\n/**\n * An indeterminate ProgressBar fill's default motion: it sweeps across the track, mirrored in\n * right-to-left, and pulses at full width under reduced motion.\n */\nexport const progressIndeterminateMotion =\n 'w-2/5 animate-wave-indeterminate wave-rtl:animate-wave-indeterminate-rtl motion-reduce:w-full motion-reduce:translate-x-0 motion-reduce:animate-wave-pulse wave-rtl:motion-reduce:animate-wave-pulse';\n\n/** The text of a class list that marks a presence variant written for 0.14's own motion. */\nconst PRESENCE_VARIANT = '[presence=';\n\nfunction slotClassName(slot: MotionSlot): string {\n return typeof slot === 'string' ? slot : slot.className;\n}\n\n/**\n * Whether a part keeps 0.14's own motion: no slot, and a `className` that holds a presence\n * variant, which the consumer wrote to animate the surface themselves. That `className` then\n * turns the default motion off, as it did before the default existed.\n *\n * @param slot - The part's `motion` prop.\n * @param legacyClassName - The part's `className`; omit it for a part without that rule.\n */\nexport function usesLegacyMotion(\n slot: MotionSlot | null | undefined,\n legacyClassName?: string,\n): boolean {\n return slot === undefined && (legacyClassName?.includes(PRESENCE_VARIANT) ?? false);\n}\n\n/**\n * The motion classes of an animated part: `null` none; a string or `{ className }` the\n * consumer's classes; `undefined` none under the provider's `'none'`, else `recipe`.\n * `legacyClassName` (the parts that keep 0.14's behaviour): a value containing a presence variant\n * gives no default motion.\n *\n * @param slot - The part's `motion` prop: `undefined` the default, `null` none, a value replaces it.\n * @param recipe - The part's default motion classes.\n * @param preference - The `motion` of the nearest `WaveProvider`.\n * @param legacyClassName - The part's `className`, for the parts that keep 0.14's behaviour.\n */\nexport function resolveMotion(\n slot: MotionSlot | null | undefined,\n recipe: string,\n preference: MotionPreference,\n legacyClassName?: string,\n): string {\n if (slot === null) return '';\n if (slot !== undefined) return slotClassName(slot);\n if (preference === 'none') return '';\n if (usesLegacyMotion(slot, legacyClassName)) return '';\n return recipe;\n}\n"],"mappings":"AA6JA,IAAaA,EACX,iWAGWC,EACX,uNAYWC,EAAqD,CAChE,MACE,maACF,IAAK,maACL,KAAM,qTACN,MACE,mTACF,OACE,kTACJ,EAGaC,EAAyD,CACpE,MAAO,uBACP,OAAQ,qBACR,MAAO,uBACP,KAAM,0BACR,EAGaC,EAA8D,CACzE,MACE,uKACF,OACE,qKACF,MACE,uKACF,KAAM,0KACR,EASaC,EAA8D,CACzE,MACE,4LACF,IAAK,kLACL,KAAM,4MACN,MACE,0MACF,OACE,yKACJ,EAMaC,EAAmE,CAC9E,MACE,iVACF,OACE,6UACJ,EAOaC,EACX,iwBAGWC,EACX,0KAQWC,EACX,wHAMWC,EACX,iTAGWC,EACX,4FAMWC,EACX,0FAOWC,EACX,uGAMWC,EAA0D,CACrE,IAAK,moBACL,OACE,ioBACJ,EAQaC,EACX,kIAMWC,EACX,8OAMWC,EACX,kJAGWC,EACX,4FAGWC,EACX,0FAMWC,EACX,iIAMWC,EACX,uMAGIC,EAAmB,aAEzB,SAASC,EAAc,EAA0B,CAC/C,OAAO,OAAOC,GAAS,SAAWA,EAAOA,EAAK,SAChD,CAUA,SAAgBC,EACd,EACA,EACS,CACT,OAAOD,IAAS,IAAA,KAAcE,GAAiB,SAASJ,CAAgB,GAAK,GAC/E,CAaA,SAAgBK,EACd,EACA,EACA,EACA,EACQ,CAKR,OAJIH,IAAS,KAAa,GACtBA,IAAS,IAAA,GACTI,IAAe,QACfH,EAAiBD,EAAME,CAAe,EAAU,GAC7CG,EAHwBN,EAAcC,CAAI,CAInD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//#region src/lib/motion.ts
|
|
2
|
+
var e = "transition-[opacity,scale] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:scale-85 data-[presence=exiting]:opacity-0 data-[presence=exiting]:scale-85", t = "transition-opacity duration-wave-gentle ease-wave-easy-ease data-[presence=exiting]:duration-wave-normal motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0", n = {
|
|
3
|
+
start: "transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:-translate-x-full data-[presence=exiting]:-translate-x-full wave-rtl:data-[presence=entering]:starting:translate-x-full wave-rtl:data-[presence=exiting]:translate-x-full",
|
|
4
|
+
end: "transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-x-full data-[presence=exiting]:translate-x-full wave-rtl:data-[presence=entering]:starting:-translate-x-full wave-rtl:data-[presence=exiting]:-translate-x-full",
|
|
5
|
+
left: "transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:-translate-x-full data-[presence=exiting]:-translate-x-full",
|
|
6
|
+
right: "transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-x-full data-[presence=exiting]:translate-x-full",
|
|
7
|
+
bottom: "transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-y-full data-[presence=exiting]:translate-y-full"
|
|
8
|
+
}, r = {
|
|
9
|
+
small: "duration-wave-gentle",
|
|
10
|
+
medium: "duration-wave-slow",
|
|
11
|
+
large: "duration-wave-slower",
|
|
12
|
+
full: "duration-wave-ultra-slow"
|
|
13
|
+
}, i = {
|
|
14
|
+
small: "transition-opacity duration-wave-gentle ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0",
|
|
15
|
+
medium: "transition-opacity duration-wave-slow ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0",
|
|
16
|
+
large: "transition-opacity duration-wave-slower ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0",
|
|
17
|
+
full: "transition-opacity duration-wave-ultra-slow ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0"
|
|
18
|
+
}, a = {
|
|
19
|
+
start: "grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] justify-items-end justify-end overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none",
|
|
20
|
+
end: "grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] justify-items-start overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none",
|
|
21
|
+
left: "grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] [justify-items:right] [justify-content:right] overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none",
|
|
22
|
+
right: "grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] [justify-items:left] [justify-content:left] overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none",
|
|
23
|
+
bottom: "grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-start overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-h-none"
|
|
24
|
+
}, o = {
|
|
25
|
+
width: "transition-[grid-template-columns,opacity] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:grid-cols-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-cols-[minmax(0,0fr)] data-[presence=exiting]:opacity-0",
|
|
26
|
+
height: "transition-[grid-template-rows,opacity] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:opacity-0"
|
|
27
|
+
}, s = "transition-[opacity,translate] duration-wave-normal ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-faster data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[side=top]:data-[presence=entering]:starting:translate-y-1 data-[side=top]:data-[presence=exiting]:translate-y-1 data-[side=bottom]:data-[presence=entering]:starting:-translate-y-1 data-[side=bottom]:data-[presence=exiting]:-translate-y-1 data-[side=left]:data-[presence=entering]:starting:translate-x-1 data-[side=left]:data-[presence=exiting]:translate-x-1 data-[side=right]:data-[presence=entering]:starting:-translate-x-1 data-[side=right]:data-[presence=exiting]:-translate-x-1", c = "transition-opacity duration-wave-faster ease-wave-easy-ease motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0", l = "grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-start overflow-hidden data-[presence=entered]:contents", u = "transition-[grid-template-rows,opacity] duration-wave-normal ease-wave-easy-ease-max motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:opacity-0", d = "transition-transform duration-wave-fast ease-wave-easy-ease motion-reduce:transition-none", f = "*:transition *:duration-wave-fast *:ease-wave-easy-ease motion-reduce:*:transition-none", p = "grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] not-data-[presence=entered]:overflow-hidden", m = {
|
|
28
|
+
top: "transition-[grid-template-rows,margin-bottom,opacity,translate] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-easy-ease data-[presence=exiting]:[transition-delay:var(--wave-duration-normal),var(--wave-duration-normal),0s,0s] motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:-translate-y-2 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0",
|
|
29
|
+
bottom: "transition-[grid-template-rows,margin-bottom,opacity,translate] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-easy-ease data-[presence=exiting]:[transition-delay:var(--wave-duration-normal),var(--wave-duration-normal),0s,0s] motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:translate-y-2 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0"
|
|
30
|
+
}, h = "grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-end content-end overflow-hidden data-[presence=entered]:contents", g = "transition-[grid-template-rows,margin-bottom,opacity] duration-wave-gentle ease-wave-linear motion-reduce:transition-none data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0", _ = "data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0", v = "transition-transform duration-wave-slow ease-wave-easy-ease motion-reduce:transition-none", y = "transition-opacity duration-wave-slow ease-wave-easy-ease motion-reduce:transition-none", b = "after:transition-[translate,scale] after:duration-wave-slow after:ease-wave-decelerate-max motion-reduce:after:transition-none", x = "w-2/5 animate-wave-indeterminate wave-rtl:animate-wave-indeterminate-rtl motion-reduce:w-full motion-reduce:translate-x-0 motion-reduce:animate-wave-pulse wave-rtl:motion-reduce:animate-wave-pulse", S = "[presence=";
|
|
31
|
+
function C(e) {
|
|
32
|
+
return typeof e == "string" ? e : e.className;
|
|
33
|
+
}
|
|
34
|
+
function w(e, t) {
|
|
35
|
+
return e === void 0 && (t?.includes(S) ?? !1);
|
|
36
|
+
}
|
|
37
|
+
function T(e, t, n, r) {
|
|
38
|
+
return e === null ? "" : e === void 0 ? n === "none" || w(e, r) ? "" : t : C(e);
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { y as carouselFadeMotion, v as carouselSlideMotion, u as collapseMotion, l as collapseStructure, t as dialogBackdropMotion, e as dialogMotion, i as drawerBackdropMotion, r as drawerDurations, n as drawerMotion, d as expandIconMotion, o as inlineDrawerMotion, a as inlineDrawerStructure, _ as messageBarGroupEnterMotion, g as messageBarGroupExitMotion, h as messageBarGroupItemStructure, f as navActionsRevealMotion, s as popupMotion, x as progressIndeterminateMotion, T as resolveMotion, b as tabIndicatorMotion, m as toastMotion, p as toastStructure, c as tooltipMotion, w as usesLegacyMotion };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=motion.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motion.mjs","names":["dialogMotion","dialogBackdropMotion","drawerMotion","drawerDurations","drawerBackdropMotion","inlineDrawerStructure","inlineDrawerMotion","popupMotion","tooltipMotion","collapseStructure","collapseMotion","expandIconMotion","navActionsRevealMotion","toastStructure","toastMotion","messageBarGroupItemStructure","messageBarGroupExitMotion","messageBarGroupEnterMotion","carouselSlideMotion","carouselFadeMotion","tabIndicatorMotion","progressIndeterminateMotion","PRESENCE_VARIANT","slotClassName","slot","usesLegacyMotion","legacyClassName","resolveMotion","preference","recipe"],"sources":["../../src/lib/motion.ts"],"sourcesContent":["import type { MotionPreference, MotionSlot, SurfaceSize } from './types';\n\n/**\n * The motion of Wave's animated parts, in one server-safe module that imports nothing at run\n * time (types only), so a Server Component and the build's Node checks can reach it.\n *\n * Every recipe is one plain string literal per value, never a concatenation, a template or a call:\n * components compose the strings at run time, and the build reads each literal whole. A recipe\n * keys its classes on the presence core's phases (the enter's start gated on the entering phase,\n * the exit on the exiting phase), times them with Wave's duration and curve tokens, lists the\n * properties it moves and switches its transition off under reduced motion. This comment\n * describes each recipe in words and never writes a class: the CSS build reads every word of this\n * file.\n *\n * - `dialogMotion`, the Dialog surface: opacity and scale. It enters from transparent at 85% of its\n * size over the gentle duration (250 ms) with the mid decelerating curve, and exits back to the\n * same over the normal duration (200 ms) with the min accelerating curve.\n * - `dialogBackdropMotion`, the Dialog backdrop: opacity only, with the easy-ease curve. It fades in\n * over the gentle duration and out over the normal duration, the surface's exit, so the backdrop\n * never outlasts the surface (the presence core waits only for the surface).\n * - `drawerMotion`, the overlay panel of Drawer and NavDrawer, per edge: opacity and translate. It\n * enters from transparent and moved out by its whole width (its whole height at the bottom)\n * beyond its edge, with the mid decelerating curve, and exits back there with the min\n * accelerating curve. The start and end edges follow the text direction (a right-to-left\n * counterpart on the same value), the left and right edges do not mirror. It holds no duration:\n * the panel adds its size's from `drawerDurations`.\n * - `drawerDurations`, the duration of an overlay panel per size, the same both ways: the gentle\n * duration (250 ms) when small, the slow one (300 ms) when medium, the slower one (400 ms) when\n * large and the ultra-slow one (500 ms) when full.\n * - `drawerBackdropMotion`, the overlay drawer's backdrop per size: opacity only, with the linear\n * curve and its size's duration both ways, so it ends with the panel.\n * - `inlineDrawerStructure`, the element around an inline drawer's panel, per edge (not motion: it\n * is on the element whatever its motion slot holds). While the drawer is open the element\n * renders no box of its own, so the panel lays out in the page as it did before the element\n * existed; while it enters or exits, the element is a clipping grid of one track on the panel's\n * axis (columns at a side, rows at the bottom) whose minimum is zero, so the track can get\n * smaller than the panel, padding and borders included, and it keeps its size in a flex row. The\n * panel sits against the inner edge of that track (the end at the start edge, the start at the\n * end edge, the physical right and left at the left and right edges, the top at the bottom\n * edge), so it reads as sliding out to its own edge, and the track sits on that same side of the\n * element: while the collapse is partly open, the grid gives its track only that fraction of\n * the element, and a track left at the element's start would leave an empty strip between the\n * visible panel and the page wherever the panel aligns to the end. While the element is not\n * entered it also lifts the panel's own maximum on that axis (its width at a side, its height at\n * the bottom): that maximum is a percentage, which inside the grid would follow the track and\n * squeeze the panel's content as the track narrows, where the track should only clip the panel.\n * Entered, the maximum applies again against the page, as before. Its track on the other axis\n * (the row at a side, the column at the bottom) has a minimum of zero too and stays whole, so\n * the panel fills the element on that axis as it fills its place once entered, rather than\n * growing there to its content's own size.\n * - `inlineDrawerMotion`, the motion of that element per axis: its track and its opacity. It\n * enters from an empty, transparent track with the mid decelerating curve and exits back to one\n * with the min accelerating curve, so the space the panel takes in the layout opens and closes\n * while the panel keeps its size. It holds no duration: the element adds its size's from\n * `drawerDurations`.\n * - `popupMotion`, a positioned popup (Popover.Content, Menu.Popover and its submenus, the\n * InfoButton note and the TeachingPopover surface): opacity and translate. It enters from\n * transparent and moved 4px toward its anchor, on the axis of the side it opened on (the\n * resolved physical side the surface renders as `data-side`: a popup below its anchor starts\n * 4px higher, one to its right 4px further left), over the normal duration (200 ms) with the mid\n * decelerating curve, and exits back there over the faster duration (100 ms) with the min\n * accelerating curve. It lists the properties it moves and never the one floating-ui places the\n * popup with, so the popup never glides from its last position; a popup that renders no side (a\n * TeachingPopover rendered in place, without a target) only fades.\n * - `tooltipMotion`, the Tooltip surface: opacity only. It fades in from transparent and back out\n * over the faster duration (100 ms) with the easy-ease curve, both ways, and does not slide. Like\n * the popups, it never lists the property floating-ui places the surface with.\n * - `collapseStructure`, the element around the part a disclosure opens and closes (Accordion's\n * region, a Tree group, a Nav category's list; not motion: it is on the element whatever its\n * motion slot holds). While the part is open the element renders no box of its own, so the part\n * lays out in its parent as it did before the element existed; while it enters or exits, the\n * element is a clipping grid of one row track whose minimum is zero, so the track can get\n * smaller than the part, padding and borders included. The part sits at the top of that track\n * at its own height rather than stretched to it: the track only clips the part, so a part that\n * scrolls shows no scroll bar and keeps its line breaks, and its background and border cover\n * all of its visible part (while the collapse is partly open, the grid gives its track only that\n * fraction of the element, so a stretched part would be shorter than what the element shows).\n * Its one column has a minimum of zero too and fills the element, so the part keeps the width it\n * has once entered: a column sized by its content would grow to the part's longest unbreakable\n * line (a long link, a label that does not wrap), and the part would be wider, its end side\n * clipped and its lines broken anew, for as long as it moves.\n * - `collapseMotion`, the motion of that element: its row track and its opacity. It enters from\n * an empty, transparent track and exits back to one over the normal duration (200 ms) with the\n * max easy-ease curve, both ways, so the space the part takes opens and closes while the content\n * keeps its width.\n * - `expandIconMotion`, the expand icon of a Nav category (its default chevron, or the span of a\n * custom glyph): the transition of its transform over the fast duration (150 ms) with the\n * easy-ease curve, both ways, so the chevron's half turn as the category opens and closes is\n * animated. The turn itself is state, not motion: without this recipe the chevron still turns,\n * at once.\n * - `navActionsRevealMotion`, the group of a Nav item's actions: the default transition on each\n * of its direct children (so a button child keeps its colour transition, and its opacity fades)\n * over the fast duration (150 ms) with the easy-ease curve, so an action fades in as its row is\n * hovered or takes focus, and out again. It replaces any transition list of the children's own.\n * - `toastStructure`, the container of each toast of a Toaster (not motion: it is on the element\n * whatever its motion slot holds): a grid of one cell around the one element that holds the\n * toast's content, both of whose tracks have a minimum of zero. The row track can so get\n * smaller than that content, and the column keeps the content to the container's width (a\n * column sized by its content would grow to the content's longest unbreakable line, such as a\n * long link, past the region's width). Unlike the elements of the disclosures it always has a\n * box of its own (it takes focus); it clips what it holds while it enters or exits, and no\n * longer once it is shown.\n * - `toastMotion`, the motion of that container per edge of the stack (the top or bottom edge its\n * position names): its row track, its bottom margin, its opacity and translate. It enters over\n * the gentle duration (250 ms) with the mid decelerating curve, all together: the track opens\n * from empty, the margin returns from minus the region's 8px gap, and the toast fades in from\n * transparent while it slides 8px in from beyond the stack's edge (from below at the bottom,\n * from above at the top). It exits over the normal duration (200 ms) with the easy-ease curve:\n * the toast fades out in place first, then the track and the margin close after a delay of the\n * same normal duration, so the toasts around it glide together once it has faded. The margin\n * makes up for the gap the region keeps after each toast, so nothing moves when the exited\n * container unmounts. Under reduced motion nothing is transitioned, so the delay goes too.\n * - `messageBarGroupItemStructure`, the element around each bar of a MessageBarGroup (not motion:\n * it is on the element whatever its motion slot holds). While the bar is shown the element\n * renders no box of its own, so the bar is an item of the group's stack as it would be without\n * the element; while it enters or exits, the element is a clipping grid of one row track whose\n * minimum is zero. The bar sits at the bottom of that track at its own height, and the track at\n * the bottom of the element: while the collapse is partly open the grid gives its track only\n * that fraction of the element, so a track left at the top would leave an empty strip under\n * the visible part of the bar. So the element always shows the bottom of the bar, which reads\n * as sliding down into the space as it opens. Its one column has a minimum of zero too and fills\n * the element, so the bar keeps the width it has once shown.\n * - `messageBarGroupExitMotion`, the default motion of that element: its row track, its bottom\n * margin and its opacity, over the gentle duration (250 ms) with the linear curve. It exits by\n * closing the track to empty while the margin goes to minus the group's 8px gap and the bar\n * fades out, so the bars after it glide up together and nothing moves when the exited element\n * unmounts.\n * - `messageBarGroupEnterMotion`, the enter a MessageBarGroup adds after the exit with its `both`\n * animation: an added bar starts from an empty track, minus the gap and transparent, and opens\n * on the exit's transition (250 ms, linear). It holds no transition of its own.\n * - `carouselSlideMotion`, the track of a Carousel that slides: the transition of its transform\n * (the inline translation that shows the current page) over the slow duration (300 ms) with the\n * easy-ease curve, so the track glides to the new page. It keys on no phase: the carousel drops\n * it while the track follows a drag, so the track stays under the pointer, and a carousel's\n * `motionDuration` other than 300 ms replaces the duration with an inline one.\n * - `carouselFadeMotion`, each slide of a Carousel that fades: the transition of its opacity over\n * the slow duration (300 ms) with the easy-ease curve, so the slide that leaves fades out while\n * the one that comes fades in, in the same place. It keys on no phase either (the carousel hides\n * the inactive slides by their opacity), and `motionDuration` replaces its duration the same way.\n * - `tabIndicatorMotion`, the line of the selected tab of a TabList with the underline look (drawn\n * by the tab's after pseudo-element, not by the tab itself): the transition of its translate\n * and scale over the slow duration (300 ms) with the max decelerating curve, so the line slides\n * and stretches from the tab selected before to the new one. It keys on no phase: for one frame\n * after the selection moves, the TabList gives the new tab the line's start (the offset and the\n * size ratio of the previous tab, measured in physical pixels) as two custom properties without\n * this recipe, then clears them and adds it, so the line glides back to its own tab. Under\n * reduced motion the line's transition is off, and the TabList writes no start either.\n * - `progressIndeterminateMotion`, the fill of an indeterminate ProgressBar (0.14's own list,\n * unchanged): a fill two fifths of the track wide that sweeps across it with Wave's indeterminate\n * keyframes, mirrored by the right-to-left counterpart on the same value. Under reduced motion\n * it becomes a full-width fill that pulses in place instead, in either direction.\n *\n * The resolver below picks the classes of a part: its motion slot, the provider's preference and\n * the className rule of the parts that keep 0.14's own motion.\n */\n\n/** The Dialog surface's default motion: scale and fade, 250 ms in and 200 ms out. */\nexport const dialogMotion =\n 'transition-[opacity,scale] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:scale-85 data-[presence=exiting]:opacity-0 data-[presence=exiting]:scale-85';\n\n/** The Dialog backdrop's default motion: a fade, 250 ms in and 200 ms out (the surface's exit). */\nexport const dialogBackdropMotion =\n 'transition-opacity duration-wave-gentle ease-wave-easy-ease data-[presence=exiting]:duration-wave-normal motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0';\n\n/**\n * An edge a drawer is attached to (Drawer's `DrawerPosition`, which lives in a client component\n * module that this module does not import).\n */\ntype DrawerEdge = 'start' | 'end' | 'left' | 'right' | 'bottom';\n\n/**\n * The overlay drawer panel's default motion per edge: a slide from beyond its edge and a fade,\n * timed by `drawerDurations` (composed at run time).\n */\nexport const drawerMotion: Readonly<Record<DrawerEdge, string>> = {\n start:\n 'transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:-translate-x-full data-[presence=exiting]:-translate-x-full wave-rtl:data-[presence=entering]:starting:translate-x-full wave-rtl:data-[presence=exiting]:translate-x-full',\n end: 'transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-x-full data-[presence=exiting]:translate-x-full wave-rtl:data-[presence=entering]:starting:-translate-x-full wave-rtl:data-[presence=exiting]:-translate-x-full',\n left: 'transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:-translate-x-full data-[presence=exiting]:-translate-x-full', // wave-allow-physical: left and right drawers do not mirror\n right:\n 'transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-x-full data-[presence=exiting]:translate-x-full', // wave-allow-physical: left and right drawers do not mirror\n bottom:\n 'transition-[opacity,translate] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[presence=entering]:starting:translate-y-full data-[presence=exiting]:translate-y-full',\n};\n\n/** The overlay drawer panel's duration per size: 250, 300, 400 and 500 ms, both ways. */\nexport const drawerDurations: Readonly<Record<SurfaceSize, string>> = {\n small: 'duration-wave-gentle',\n medium: 'duration-wave-slow',\n large: 'duration-wave-slower',\n full: 'duration-wave-ultra-slow',\n};\n\n/** The overlay drawer backdrop's default motion per size: a linear fade over its size's duration. */\nexport const drawerBackdropMotion: Readonly<Record<SurfaceSize, string>> = {\n small:\n 'transition-opacity duration-wave-gentle ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0',\n medium:\n 'transition-opacity duration-wave-slow ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0',\n large:\n 'transition-opacity duration-wave-slower ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0',\n full: 'transition-opacity duration-wave-ultra-slow ease-wave-linear motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0',\n};\n\n/**\n * The structure of the element around an inline drawer's panel, per edge: no box while open, a\n * clipping one-track grid on the panel's axis while it enters or exits, the panel and the track\n * against its inner edge (so no empty strip opens next to the page), the panel without its\n * percentage maximum on that axis (so it is clipped, not squeezed), and a whole track with a zero\n * minimum on the other axis (so the panel fills the element there, as once entered).\n */\nexport const inlineDrawerStructure: Readonly<Record<DrawerEdge, string>> = {\n start:\n 'grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] justify-items-end justify-end overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none',\n end: 'grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] justify-items-start overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none',\n left: 'grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] [justify-items:right] [justify-content:right] overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none', // wave-allow-physical: the consumer asked for the physical left edge\n right:\n 'grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] [justify-items:left] [justify-content:left] overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-w-none', // wave-allow-physical: the consumer asked for the physical right edge\n bottom:\n 'grid shrink-0 grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-start overflow-hidden data-[presence=entered]:contents not-data-[presence=entered]:*:max-h-none',\n};\n\n/**\n * The inline drawer's default motion per axis, on the element around its panel: the track opens\n * from zero and closes back with a fade, timed by `drawerDurations` (composed at run time).\n */\nexport const inlineDrawerMotion: Readonly<Record<'width' | 'height', string>> = {\n width:\n 'transition-[grid-template-columns,opacity] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:grid-cols-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-cols-[minmax(0,0fr)] data-[presence=exiting]:opacity-0',\n height:\n 'transition-[grid-template-rows,opacity] ease-wave-decelerate-mid data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:opacity-0',\n};\n\n/**\n * The default motion of a positioned popup (Popover.Content, Menu.Popover and its submenus, the\n * InfoButton note and the TeachingPopover surface): a fade and a 4px slide away from its anchor,\n * by the side it opened on, 200 ms in and 100 ms out; only the fade without a side.\n */\nexport const popupMotion =\n 'transition-[opacity,translate] duration-wave-normal ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-faster data-[presence=exiting]:ease-wave-accelerate-min motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0 data-[side=top]:data-[presence=entering]:starting:translate-y-1 data-[side=top]:data-[presence=exiting]:translate-y-1 data-[side=bottom]:data-[presence=entering]:starting:-translate-y-1 data-[side=bottom]:data-[presence=exiting]:-translate-y-1 data-[side=left]:data-[presence=entering]:starting:translate-x-1 data-[side=left]:data-[presence=exiting]:translate-x-1 data-[side=right]:data-[presence=entering]:starting:-translate-x-1 data-[side=right]:data-[presence=exiting]:-translate-x-1'; // wave-allow-physical: data-side is the resolved physical side\n\n/** The Tooltip surface's default motion: a fade, 100 ms both ways, without a slide. */\nexport const tooltipMotion =\n 'transition-opacity duration-wave-faster ease-wave-easy-ease motion-reduce:transition-none data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:opacity-0';\n\n/**\n * The structure of the element around a disclosure's collapsing part (Accordion's region, a Tree\n * group, a Nav category's list): no box while open, a clipping one-track grid of rows while it\n * enters or exits, with the part at the top of the track at its own height (clipped, not\n * squeezed) and in a whole column with a zero minimum (the width it has once entered).\n */\nexport const collapseStructure =\n 'grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-start overflow-hidden data-[presence=entered]:contents';\n\n/**\n * A disclosure's default collapse, on the element around its part: the row track opens from zero\n * and closes back with a fade, 200 ms both ways.\n */\nexport const collapseMotion =\n 'transition-[grid-template-rows,opacity] duration-wave-normal ease-wave-easy-ease-max motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:opacity-0 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:opacity-0';\n\n/** The default motion of a Nav category's expand icon: its turn is animated, 150 ms both ways. */\nexport const expandIconMotion =\n 'transition-transform duration-wave-fast ease-wave-easy-ease motion-reduce:transition-none';\n\n/**\n * The default reveal of a Nav item's actions, on their group: each action fades in and out as\n * its row is hovered or takes focus, 150 ms both ways.\n */\nexport const navActionsRevealMotion =\n '*:transition *:duration-wave-fast *:ease-wave-easy-ease motion-reduce:*:transition-none';\n\n/**\n * The structure of a toast's container: a one-cell grid around the toast's content element, its\n * tracks with a zero minimum (the content keeps the container's width), clipping it while the\n * container enters or exits.\n */\nexport const toastStructure =\n 'grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] not-data-[presence=entered]:overflow-hidden';\n\n/**\n * A toast container's default motion per edge of its stack: it opens, fades in and slides from\n * that edge together, 250 ms; it fades out over 200 ms, then closes over 200 ms more.\n */\nexport const toastMotion: Readonly<Record<'top' | 'bottom', string>> = {\n top: 'transition-[grid-template-rows,margin-bottom,opacity,translate] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-easy-ease data-[presence=exiting]:[transition-delay:var(--wave-duration-normal),var(--wave-duration-normal),0s,0s] motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:-translate-y-2 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0',\n bottom:\n 'transition-[grid-template-rows,margin-bottom,opacity,translate] duration-wave-gentle ease-wave-decelerate-mid data-[presence=exiting]:duration-wave-normal data-[presence=exiting]:ease-wave-easy-ease data-[presence=exiting]:[transition-delay:var(--wave-duration-normal),var(--wave-duration-normal),0s,0s] motion-reduce:transition-none data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0 data-[presence=entering]:starting:translate-y-2 data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0',\n};\n\n/**\n * The structure of the element around each bar of a MessageBarGroup: no box while the bar is\n * shown, a clipping one-track grid of rows while it enters or exits, with the bar at the bottom\n * of the track at its own height and the track at the bottom of the element (so no empty strip\n * opens under the bar), in a whole column with a zero minimum (the width it has once shown).\n */\nexport const messageBarGroupItemStructure =\n 'grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] items-end content-end overflow-hidden data-[presence=entered]:contents';\n\n/**\n * A MessageBarGroup bar's default exit, on the element around it: its row track and its bottom\n * margin close while it fades out, 250 ms.\n */\nexport const messageBarGroupExitMotion =\n 'transition-[grid-template-rows,margin-bottom,opacity] duration-wave-gentle ease-wave-linear motion-reduce:transition-none data-[presence=exiting]:grid-rows-[minmax(0,0fr)] data-[presence=exiting]:-mb-2 data-[presence=exiting]:opacity-0';\n\n/**\n * The enter a MessageBarGroup adds to the exit with `animate=\"both\"`: an added bar's row track and\n * bottom margin open from closed while it fades in, on the exit's transition.\n */\nexport const messageBarGroupEnterMotion =\n 'data-[presence=entering]:starting:grid-rows-[minmax(0,0fr)] data-[presence=entering]:starting:-mb-2 data-[presence=entering]:starting:opacity-0';\n\n/** A sliding Carousel track's motion: its transform glides to the new page, 300 ms. */\nexport const carouselSlideMotion =\n 'transition-transform duration-wave-slow ease-wave-easy-ease motion-reduce:transition-none';\n\n/** A fading Carousel slide's motion: it fades in or out in place, 300 ms. */\nexport const carouselFadeMotion =\n 'transition-opacity duration-wave-slow ease-wave-easy-ease motion-reduce:transition-none';\n\n/**\n * The default slide of a TabList's selection line, on the selected tab's after pseudo-element: it\n * moves and stretches from the tab selected before, 300 ms.\n */\nexport const tabIndicatorMotion =\n 'after:transition-[translate,scale] after:duration-wave-slow after:ease-wave-decelerate-max motion-reduce:after:transition-none';\n\n/**\n * An indeterminate ProgressBar fill's default motion: it sweeps across the track, mirrored in\n * right-to-left, and pulses at full width under reduced motion.\n */\nexport const progressIndeterminateMotion =\n 'w-2/5 animate-wave-indeterminate wave-rtl:animate-wave-indeterminate-rtl motion-reduce:w-full motion-reduce:translate-x-0 motion-reduce:animate-wave-pulse wave-rtl:motion-reduce:animate-wave-pulse';\n\n/** The text of a class list that marks a presence variant written for 0.14's own motion. */\nconst PRESENCE_VARIANT = '[presence=';\n\nfunction slotClassName(slot: MotionSlot): string {\n return typeof slot === 'string' ? slot : slot.className;\n}\n\n/**\n * Whether a part keeps 0.14's own motion: no slot, and a `className` that holds a presence\n * variant, which the consumer wrote to animate the surface themselves. That `className` then\n * turns the default motion off, as it did before the default existed.\n *\n * @param slot - The part's `motion` prop.\n * @param legacyClassName - The part's `className`; omit it for a part without that rule.\n */\nexport function usesLegacyMotion(\n slot: MotionSlot | null | undefined,\n legacyClassName?: string,\n): boolean {\n return slot === undefined && (legacyClassName?.includes(PRESENCE_VARIANT) ?? false);\n}\n\n/**\n * The motion classes of an animated part: `null` none; a string or `{ className }` the\n * consumer's classes; `undefined` none under the provider's `'none'`, else `recipe`.\n * `legacyClassName` (the parts that keep 0.14's behaviour): a value containing a presence variant\n * gives no default motion.\n *\n * @param slot - The part's `motion` prop: `undefined` the default, `null` none, a value replaces it.\n * @param recipe - The part's default motion classes.\n * @param preference - The `motion` of the nearest `WaveProvider`.\n * @param legacyClassName - The part's `className`, for the parts that keep 0.14's behaviour.\n */\nexport function resolveMotion(\n slot: MotionSlot | null | undefined,\n recipe: string,\n preference: MotionPreference,\n legacyClassName?: string,\n): string {\n if (slot === null) return '';\n if (slot !== undefined) return slotClassName(slot);\n if (preference === 'none') return '';\n if (usesLegacyMotion(slot, legacyClassName)) return '';\n return recipe;\n}\n"],"mappings":";AA6JA,IAAaA,IACX,kWAGWC,IACX,wNAYWC,IAAqD;CAChE,OACE;CACF,KAAK;CACL,MAAM;CACN,OACE;CACF,QACE;AACJ,GAGaC,IAAyD;CACpE,OAAO;CACP,QAAQ;CACR,OAAO;CACP,MAAM;AACR,GAGaC,IAA8D;CACzE,OACE;CACF,QACE;CACF,OACE;CACF,MAAM;AACR,GASaC,IAA8D;CACzE,OACE;CACF,KAAK;CACL,MAAM;CACN,OACE;CACF,QACE;AACJ,GAMaC,IAAmE;CAC9E,OACE;CACF,QACE;AACJ,GAOaC,IACX,kwBAGWC,IACX,2KAQWC,IACX,yHAMWC,IACX,kTAGWC,IACX,6FAMWC,IACX,2FAOWC,IACX,wGAMWC,IAA0D;CACrE,KAAK;CACL,QACE;AACJ,GAQaC,IACX,mIAMWC,IACX,+OAMWC,IACX,mJAGWC,IACX,6FAGWC,IACX,2FAMWC,IACX,kIAMWC,IACX,wMAGIC,IAAmB;AAEzB,SAASC,EAAc,GAA0B;CAC/C,OAAO,OAAOC,KAAS,WAAWA,IAAOA,EAAK;AAChD;AAUA,SAAgBC,EACd,GACA,GACS;CACT,OAAOD,MAAS,KAAA,MAAcE,GAAiB,SAASJ,CAAgB,KAAK;AAC/E;AAaA,SAAgBK,EACd,GACA,GACA,GACA,GACQ;CAKR,OAJIH,MAAS,OAAa,KACtBA,MAAS,KAAA,IACTI,MAAe,UACfH,EAAiBD,GAAME,CAAe,IAAU,KAC7CG,IAHwBN,EAAcC,CAAI;AAInD"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function e(e,t,n,r){if(n===`single`)return e.has(t)&&r?.allowEmpty?new Set:new Set([t]);let i=new Set(e);return i.delete(t)||i.add(t),i}function t(e,t){let n=new Set(e);for(let e of t)n.add(e);return n}function n(e,t){let n=new Set(e);for(let e of t)n.delete(e);return n}function r(e,t,n=t){let r=n.length>0&&n.every(t=>e.has(t)),i=!r&&t.some(t=>e.has(t));return{all:r,some:i,none:!r&&!i}}exports.clearIds=n,exports.selectAllIds=t,exports.summarizeSelection=r,exports.toggleId=e;
|
|
2
|
+
//# sourceMappingURL=selection.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection.cjs","names":["toggleId","mode","selected","id","options","next","selectAllIds","selectableIds","clearIds","universe","summarizeSelection","all","some"],"sources":["../../src/lib/selection.ts"],"sourcesContent":["import type { SelectionMode } from './types';\n\n/**\n * Toggles `id` in a selection and returns a new set; the argument is never mutated.\n *\n * `multiple` adds or removes the id. `single` replaces the selection with the id; when that id\n * is the selection already it stays selected, unless `options.allowEmpty` clears it.\n */\nexport function toggleId(\n selected: ReadonlySet<string>,\n id: string,\n mode: SelectionMode,\n options?: { allowEmpty?: boolean },\n): Set<string> {\n if (mode === 'single') {\n return selected.has(id) && options?.allowEmpty ? new Set() : new Set([id]);\n }\n const next = new Set(selected);\n if (!next.delete(id)) next.add(id);\n return next;\n}\n\n/** Adds `selectableIds` to a selection, keeping every id already in it (foreign ones too). */\nexport function selectAllIds(\n selected: ReadonlySet<string>,\n selectableIds: readonly string[],\n): Set<string> {\n const next = new Set(selected);\n for (const id of selectableIds) next.add(id);\n return next;\n}\n\n/** Removes the ids of `universe` from a selection; ids outside the universe stay selected. */\nexport function clearIds(selected: ReadonlySet<string>, universe: readonly string[]): Set<string> {\n const next = new Set(selected);\n for (const id of universe) next.delete(id);\n return next;\n}\n\n/**\n * Summarises a selection over `universe`. `all`: `selectableIds` (default `universe`) is\n * non-empty and every id in it is selected. `some`: an id of `universe` is selected and not\n * `all`, so a selected disabled id counts. `none`: neither. Ids outside `universe` count toward\n * nothing.\n */\nexport function summarizeSelection(\n selected: ReadonlySet<string>,\n universe: readonly string[],\n selectableIds: readonly string[] = universe,\n): { all: boolean; some: boolean; none: boolean } {\n const all = selectableIds.length > 0 && selectableIds.every((id) => selected.has(id));\n const some = !all && universe.some((id) => selected.has(id));\n return { all, some, none: !all && !some };\n}\n"],"mappings":"AAQA,SAAgBA,EACd,EACA,EACA,EACA,EACa,CACb,GAAIC,IAAS,SACX,OAAOC,EAAS,IAAIC,CAAE,GAAKC,GAAS,WAAa,IAAI,IAAQ,IAAI,IAAI,CAACD,CAAE,CAAC,EAE3E,IAAME,EAAO,IAAI,IAAIH,CAAQ,EAE7B,OADKG,EAAK,OAAOF,CAAE,GAAGE,EAAK,IAAIF,CAAE,EAC1BE,CACT,CAGA,SAAgBC,EACd,EACA,EACa,CACb,IAAMD,EAAO,IAAI,IAAIH,CAAQ,EAC7B,IAAK,IAAMC,KAAMI,EAAeF,EAAK,IAAIF,CAAE,EAC3C,OAAOE,CACT,CAGA,SAAgBG,EAAS,EAA+B,EAA0C,CAChG,IAAMH,EAAO,IAAI,IAAIH,CAAQ,EAC7B,IAAK,IAAMC,KAAMM,EAAUJ,EAAK,OAAOF,CAAE,EACzC,OAAOE,CACT,CAQA,SAAgBK,EACd,EACA,EACA,EAAmCD,EACa,CAChD,IAAME,EAAMJ,EAAc,OAAS,GAAKA,EAAc,MAAO,GAAOL,EAAS,IAAIC,CAAE,CAAC,EAC9ES,EAAO,CAACD,GAAOF,EAAS,KAAM,GAAOP,EAAS,IAAIC,CAAE,CAAC,EAC3D,MAAO,CAAE,MAAK,OAAM,KAAM,CAACQ,GAAO,CAACC,CAAK,CAC1C"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/lib/selection.ts
|
|
2
|
+
function e(e, t, n, r) {
|
|
3
|
+
if (n === "single") return e.has(t) && r?.allowEmpty ? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set([t]);
|
|
4
|
+
let i = new Set(e);
|
|
5
|
+
return i.delete(t) || i.add(t), i;
|
|
6
|
+
}
|
|
7
|
+
function t(e, t) {
|
|
8
|
+
let n = new Set(e);
|
|
9
|
+
for (let e of t) n.add(e);
|
|
10
|
+
return n;
|
|
11
|
+
}
|
|
12
|
+
function n(e, t) {
|
|
13
|
+
let n = new Set(e);
|
|
14
|
+
for (let e of t) n.delete(e);
|
|
15
|
+
return n;
|
|
16
|
+
}
|
|
17
|
+
function r(e, t, n = t) {
|
|
18
|
+
let r = n.length > 0 && n.every((t) => e.has(t)), i = !r && t.some((t) => e.has(t));
|
|
19
|
+
return {
|
|
20
|
+
all: r,
|
|
21
|
+
some: i,
|
|
22
|
+
none: !r && !i
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { n as clearIds, t as selectAllIds, r as summarizeSelection, e as toggleId };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=selection.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection.mjs","names":["toggleId","mode","selected","id","options","next","selectAllIds","selectableIds","clearIds","universe","summarizeSelection","all","some"],"sources":["../../src/lib/selection.ts"],"sourcesContent":["import type { SelectionMode } from './types';\n\n/**\n * Toggles `id` in a selection and returns a new set; the argument is never mutated.\n *\n * `multiple` adds or removes the id. `single` replaces the selection with the id; when that id\n * is the selection already it stays selected, unless `options.allowEmpty` clears it.\n */\nexport function toggleId(\n selected: ReadonlySet<string>,\n id: string,\n mode: SelectionMode,\n options?: { allowEmpty?: boolean },\n): Set<string> {\n if (mode === 'single') {\n return selected.has(id) && options?.allowEmpty ? new Set() : new Set([id]);\n }\n const next = new Set(selected);\n if (!next.delete(id)) next.add(id);\n return next;\n}\n\n/** Adds `selectableIds` to a selection, keeping every id already in it (foreign ones too). */\nexport function selectAllIds(\n selected: ReadonlySet<string>,\n selectableIds: readonly string[],\n): Set<string> {\n const next = new Set(selected);\n for (const id of selectableIds) next.add(id);\n return next;\n}\n\n/** Removes the ids of `universe` from a selection; ids outside the universe stay selected. */\nexport function clearIds(selected: ReadonlySet<string>, universe: readonly string[]): Set<string> {\n const next = new Set(selected);\n for (const id of universe) next.delete(id);\n return next;\n}\n\n/**\n * Summarises a selection over `universe`. `all`: `selectableIds` (default `universe`) is\n * non-empty and every id in it is selected. `some`: an id of `universe` is selected and not\n * `all`, so a selected disabled id counts. `none`: neither. Ids outside `universe` count toward\n * nothing.\n */\nexport function summarizeSelection(\n selected: ReadonlySet<string>,\n universe: readonly string[],\n selectableIds: readonly string[] = universe,\n): { all: boolean; some: boolean; none: boolean } {\n const all = selectableIds.length > 0 && selectableIds.every((id) => selected.has(id));\n const some = !all && universe.some((id) => selected.has(id));\n return { all, some, none: !all && !some };\n}\n"],"mappings":";AAQA,SAAgBA,EACd,GACA,GACA,GACA,GACa;CACb,IAAIC,MAAS,UACX,OAAOC,EAAS,IAAIC,CAAE,KAAKC,GAAS,6BAAa,IAAI,IAAI,oBAAI,IAAI,IAAI,CAACD,CAAE,CAAC;CAE3E,IAAME,IAAO,IAAI,IAAIH,CAAQ;CAE7B,OADKG,EAAK,OAAOF,CAAE,KAAGE,EAAK,IAAIF,CAAE,GAC1BE;AACT;AAGA,SAAgBC,EACd,GACA,GACa;CACb,IAAMD,IAAO,IAAI,IAAIH,CAAQ;CAC7B,KAAK,IAAMC,KAAMI,GAAe,EAAK,IAAIJ,CAAE;CAC3C,OAAOE;AACT;AAGA,SAAgBG,EAAS,GAA+B,GAA0C;CAChG,IAAMH,IAAO,IAAI,IAAIH,CAAQ;CAC7B,KAAK,IAAMC,KAAMM,GAAU,EAAK,OAAON,CAAE;CACzC,OAAOE;AACT;AAQA,SAAgBK,EACd,GACA,GACA,IAAmCD,GACa;CAChD,IAAME,IAAMJ,EAAc,SAAS,KAAKA,EAAc,OAAO,MAAOL,EAAS,IAAIC,CAAE,CAAC,GAC9ES,IAAO,CAACD,KAAOF,EAAS,MAAM,MAAOP,EAAS,IAAIC,CAAE,CAAC;CAC3D,OAAO;EAAE;EAAK;EAAM,MAAM,CAACQ,KAAO,CAACC;CAAK;AAC1C"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function e(t,n){for(let r of t)n(r),e(r.children,n)}function t(e,n){for(let r of e){if(r.value===n)return[r];let e=t(r.children,n);if(e)return[r,...e]}return null}function n(t,n,r=!1){let i=new Map;e(t,e=>{i.has(e.value)||i.set(e.value,e)});let a=new Map,o=(e,t)=>{let r=t||n.has(e.value),s=e.children.map(e=>o(e,r)),c;return c=r?`checked`:s.length===0?`unchecked`:s.every(e=>e===`checked`)?`checked`:s.some(e=>e!==`unchecked`)?`mixed`:`unchecked`,i.get(e.value)===e&&a.set(e.value,c),c};for(let e of t)o(e,r);return a}function r(r,i,a){let o=n(r,new Set(i)),s=new Set;for(let[e,t]of o)t===`checked`&&s.add(e);let c=new Set;e(r,e=>c.add(e.value));let l=Array.from(new Set(i.filter(e=>!c.has(e)))),u=t(r,a);if(u){let t=u[u.length-1],n=o.get(a)!==`checked`;e([t],e=>{n?s.add(e.value):s.delete(e.value)});for(let e=u.length-2;e>=0;--e){let t=u[e];t.children.every(e=>s.has(e.value))?s.add(t.value):s.delete(t.value)}}else{let e=l.indexOf(a);e===-1?l.push(a):l.splice(e,1)}let d=[],f=new Set;return e(r,e=>{s.has(e.value)&&!f.has(e.value)&&(f.add(e.value),d.push(e.value))}),[...d,...l]}exports.computeCheckStates=n,exports.toggleCheck=r;
|
|
2
|
+
//# sourceMappingURL=treeCascade.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treeCascade.cjs","names":["forEachNode","node","nodes","visit","findPath","value","below","computeCheckStates","first","candidate","states","forced","forcedAbove","listed","current","childStates","child","state","childState","top","ancestorListed","toggleCheck","checked","itemValue","known","unmatched","listedValue","path","target","turnOn","index","ancestor","at","ordered","seen"],"sources":["../../src/lib/treeCascade.ts"],"sourcesContent":["// The pure check-state cascade of the trees: server-safe, no React import. The nested Tree feeds it\n// a forest read from its elements (`Tree.selection.ts`), the flat tree a forest built from flat data\n// (`flatTree.ts`).\n\n/** One Tree.Item of the cascade model: its value and the items nested in it. */\nexport interface TreeNode {\n value: string;\n children: TreeNode[];\n}\n\n/** The check state of an item in a `selectionMode=\"multiple\"` tree. */\nexport type CheckState = 'checked' | 'mixed' | 'unchecked';\n\nfunction forEachNode(nodes: readonly TreeNode[], visit: (node: TreeNode) => void): void {\n for (const node of nodes) {\n visit(node);\n forEachNode(node.children, visit);\n }\n}\n\n/** The first item with `value` in tree order and its ancestors, from the top down; `null` if none. */\nfunction findPath(nodes: readonly TreeNode[], value: string): TreeNode[] | null {\n for (const node of nodes) {\n if (node.value === value) return [node];\n const below = findPath(node.children, value);\n if (below) return [node, ...below];\n }\n return null;\n}\n\n/**\n * The check state of every item: checked when its value is listed, when an ancestor's value is\n * listed (or `ancestorListed`), or when it has nested items and all of them are checked; mixed\n * when some of them are checked or mixed; else unchecked. For a value that several items share,\n * the first item in tree order decides the entry.\n */\nexport function computeCheckStates(\n nodes: readonly TreeNode[],\n listed: ReadonlySet<string>,\n ancestorListed = false,\n): Map<string, CheckState> {\n const first = new Map<string, TreeNode>();\n forEachNode(nodes, (candidate) => {\n if (!first.has(candidate.value)) first.set(candidate.value, candidate);\n });\n const states = new Map<string, CheckState>();\n const visit = (current: TreeNode, forcedAbove: boolean): CheckState => {\n const forced = forcedAbove || listed.has(current.value);\n const childStates = current.children.map((child) => visit(child, forced));\n let state: CheckState;\n if (forced) state = 'checked';\n else if (childStates.length === 0) state = 'unchecked';\n else if (childStates.every((childState) => childState === 'checked')) state = 'checked';\n else if (childStates.some((childState) => childState !== 'unchecked')) state = 'mixed';\n else state = 'unchecked';\n if (first.get(current.value) === current) states.set(current.value, state);\n return state;\n };\n for (const top of nodes) visit(top, ancestorListed);\n return states;\n}\n\n/**\n * The checked items after toggling `value`. A checked item and every item nested in it become\n * unchecked; an unchecked or mixed one and every item nested in it become checked; its ancestors\n * then follow their nested items. Returns every checked item in tree order (fully checked parents\n * included, mixed ones not), each value once, followed by the listed values that match no item,\n * in their order; a value that no item has is added to, or removed from, those.\n */\nexport function toggleCheck(\n nodes: readonly TreeNode[],\n listed: readonly string[],\n value: string,\n): string[] {\n const states = computeCheckStates(nodes, new Set(listed));\n const checked = new Set<string>();\n for (const [itemValue, state] of states) {\n if (state === 'checked') checked.add(itemValue);\n }\n const known = new Set<string>();\n forEachNode(nodes, (candidate) => known.add(candidate.value));\n const unmatched = Array.from(new Set(listed.filter((listedValue) => !known.has(listedValue))));\n\n const path = findPath(nodes, value);\n if (path) {\n const target = path[path.length - 1];\n const turnOn = states.get(value) !== 'checked';\n forEachNode([target], (candidate) => {\n if (turnOn) checked.add(candidate.value);\n else checked.delete(candidate.value);\n });\n for (let index = path.length - 2; index >= 0; index -= 1) {\n const ancestor = path[index];\n if (ancestor.children.every((child) => checked.has(child.value))) checked.add(ancestor.value);\n else checked.delete(ancestor.value);\n }\n } else {\n const at = unmatched.indexOf(value);\n if (at === -1) unmatched.push(value);\n else unmatched.splice(at, 1);\n }\n\n const ordered: string[] = [];\n const seen = new Set<string>();\n forEachNode(nodes, (candidate) => {\n if (checked.has(candidate.value) && !seen.has(candidate.value)) {\n seen.add(candidate.value);\n ordered.push(candidate.value);\n }\n });\n return [...ordered, ...unmatched];\n}\n"],"mappings":"AAaA,SAASA,EAAY,EAA4B,EAAuC,CACtF,IAAK,IAAMC,KAAQC,EACjBC,EAAMF,CAAI,EACVD,EAAYC,EAAK,SAAUE,CAAK,CAEpC,CAGA,SAASC,EAAS,EAA4B,EAAkC,CAC9E,IAAK,IAAMH,KAAQC,EAAO,CACxB,GAAID,EAAK,QAAUI,EAAO,MAAO,CAACJ,CAAI,EACtC,IAAMK,EAAQF,EAASH,EAAK,SAAUI,CAAK,EAC3C,GAAIC,EAAO,MAAO,CAACL,EAAM,GAAGK,CAAK,CACnC,CACA,OAAO,IACT,CAQA,SAAgBC,EACd,EACA,EACA,EAAiB,GACQ,CACzB,IAAMC,EAAQ,IAAI,IAClBR,EAAYE,EAAQ,GAAc,CAC3BM,EAAM,IAAIC,EAAU,KAAK,GAAGD,EAAM,IAAIC,EAAU,MAAOA,CAAS,CACvE,CAAC,EACD,IAAMC,EAAS,IAAI,IACbP,GAAS,EAAmB,IAAqC,CACrE,IAAMQ,EAASC,GAAeC,EAAO,IAAIC,EAAQ,KAAK,EAChDC,EAAcD,EAAQ,SAAS,IAAK,GAAUX,EAAMa,EAAOL,CAAM,CAAC,EACpEM,EAOJ,MANA,CAIKA,EAJDN,EAAgB,UACXI,EAAY,SAAW,EAAW,YAClCA,EAAY,MAAO,GAAeG,IAAe,SAAS,EAAW,UACrEH,EAAY,KAAM,GAAeG,IAAe,WAAW,EAAW,QAClE,YACTV,EAAM,IAAIM,EAAQ,KAAK,IAAMA,GAASJ,EAAO,IAAII,EAAQ,MAAOG,CAAK,EAClEA,CACT,EACA,IAAK,IAAME,KAAOjB,EAAOC,EAAMgB,EAAKC,CAAc,EAClD,OAAOV,CACT,CASA,SAAgBW,EACd,EACA,EACA,EACU,CACV,IAAMX,EAASH,EAAmBL,EAAO,IAAI,IAAIW,CAAM,CAAC,EAClDS,EAAU,IAAI,IACpB,IAAK,GAAM,CAACC,EAAWN,KAAUP,EAC3BO,IAAU,WAAWK,EAAQ,IAAIC,CAAS,EAEhD,IAAMC,EAAQ,IAAI,IAClBxB,EAAYE,EAAQ,GAAcsB,EAAM,IAAIf,EAAU,KAAK,CAAC,EAC5D,IAAMgB,EAAY,MAAM,KAAK,IAAI,IAAIZ,EAAO,OAAQ,GAAgB,CAACW,EAAM,IAAIE,CAAW,CAAC,CAAC,CAAC,EAEvFC,EAAOvB,EAASF,EAAOG,CAAK,EAClC,GAAIsB,EAAM,CACR,IAAMC,EAASD,EAAKA,EAAK,OAAS,GAC5BE,EAASnB,EAAO,IAAIL,CAAK,IAAM,UACrCL,EAAY,CAAC4B,CAAM,EAAI,GAAc,CAC/BC,EAAQP,EAAQ,IAAIb,EAAU,KAAK,EAClCa,EAAQ,OAAOb,EAAU,KAAK,CACrC,CAAC,EACD,IAAK,IAAIqB,EAAQH,EAAK,OAAS,EAAGG,GAAS,EAAG,IAAY,CACxD,IAAMC,EAAWJ,EAAKG,GAClBC,EAAS,SAAS,MAAO,GAAUT,EAAQ,IAAIN,EAAM,KAAK,CAAC,EAAGM,EAAQ,IAAIS,EAAS,KAAK,EACvFT,EAAQ,OAAOS,EAAS,KAAK,CACpC,CACF,KAAO,CACL,IAAMC,EAAKP,EAAU,QAAQpB,CAAK,EAC9B2B,IAAO,GAAIP,EAAU,KAAKpB,CAAK,EAC9BoB,EAAU,OAAOO,EAAI,CAAC,CAC7B,CAEA,IAAMC,EAAoB,CAAC,EACrBC,EAAO,IAAI,IAOjB,OANAlC,EAAYE,EAAQ,GAAc,CAC5BoB,EAAQ,IAAIb,EAAU,KAAK,GAAK,CAACyB,EAAK,IAAIzB,EAAU,KAAK,IAC3DyB,EAAK,IAAIzB,EAAU,KAAK,EACxBwB,EAAQ,KAAKxB,EAAU,KAAK,EAEhC,CAAC,EACM,CAAC,GAAGwB,EAAS,GAAGR,CAAS,CAClC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//#region src/lib/treeCascade.ts
|
|
2
|
+
function e(t, n) {
|
|
3
|
+
for (let r of t) n(r), e(r.children, n);
|
|
4
|
+
}
|
|
5
|
+
function t(e, n) {
|
|
6
|
+
for (let r of e) {
|
|
7
|
+
if (r.value === n) return [r];
|
|
8
|
+
let e = t(r.children, n);
|
|
9
|
+
if (e) return [r, ...e];
|
|
10
|
+
}
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
function n(t, n, r = !1) {
|
|
14
|
+
let i = /* @__PURE__ */ new Map();
|
|
15
|
+
e(t, (e) => {
|
|
16
|
+
i.has(e.value) || i.set(e.value, e);
|
|
17
|
+
});
|
|
18
|
+
let a = /* @__PURE__ */ new Map(), o = (e, t) => {
|
|
19
|
+
let r = t || n.has(e.value), s = e.children.map((e) => o(e, r)), c;
|
|
20
|
+
return c = r ? "checked" : s.length === 0 ? "unchecked" : s.every((e) => e === "checked") ? "checked" : s.some((e) => e !== "unchecked") ? "mixed" : "unchecked", i.get(e.value) === e && a.set(e.value, c), c;
|
|
21
|
+
};
|
|
22
|
+
for (let e of t) o(e, r);
|
|
23
|
+
return a;
|
|
24
|
+
}
|
|
25
|
+
function r(r, i, a) {
|
|
26
|
+
let o = n(r, new Set(i)), s = /* @__PURE__ */ new Set();
|
|
27
|
+
for (let [e, t] of o) t === "checked" && s.add(e);
|
|
28
|
+
let c = /* @__PURE__ */ new Set();
|
|
29
|
+
e(r, (e) => c.add(e.value));
|
|
30
|
+
let l = Array.from(new Set(i.filter((e) => !c.has(e)))), u = t(r, a);
|
|
31
|
+
if (u) {
|
|
32
|
+
let t = u[u.length - 1], n = o.get(a) !== "checked";
|
|
33
|
+
e([t], (e) => {
|
|
34
|
+
n ? s.add(e.value) : s.delete(e.value);
|
|
35
|
+
});
|
|
36
|
+
for (let e = u.length - 2; e >= 0; --e) {
|
|
37
|
+
let t = u[e];
|
|
38
|
+
t.children.every((e) => s.has(e.value)) ? s.add(t.value) : s.delete(t.value);
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
let e = l.indexOf(a);
|
|
42
|
+
e === -1 ? l.push(a) : l.splice(e, 1);
|
|
43
|
+
}
|
|
44
|
+
let d = [], f = /* @__PURE__ */ new Set();
|
|
45
|
+
return e(r, (e) => {
|
|
46
|
+
s.has(e.value) && !f.has(e.value) && (f.add(e.value), d.push(e.value));
|
|
47
|
+
}), [...d, ...l];
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { n as computeCheckStates, r as toggleCheck };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=treeCascade.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treeCascade.mjs","names":["forEachNode","node","nodes","visit","findPath","value","below","computeCheckStates","first","candidate","states","forced","forcedAbove","listed","current","childStates","child","state","childState","top","ancestorListed","toggleCheck","checked","itemValue","known","unmatched","listedValue","path","target","turnOn","index","ancestor","at","ordered","seen"],"sources":["../../src/lib/treeCascade.ts"],"sourcesContent":["// The pure check-state cascade of the trees: server-safe, no React import. The nested Tree feeds it\n// a forest read from its elements (`Tree.selection.ts`), the flat tree a forest built from flat data\n// (`flatTree.ts`).\n\n/** One Tree.Item of the cascade model: its value and the items nested in it. */\nexport interface TreeNode {\n value: string;\n children: TreeNode[];\n}\n\n/** The check state of an item in a `selectionMode=\"multiple\"` tree. */\nexport type CheckState = 'checked' | 'mixed' | 'unchecked';\n\nfunction forEachNode(nodes: readonly TreeNode[], visit: (node: TreeNode) => void): void {\n for (const node of nodes) {\n visit(node);\n forEachNode(node.children, visit);\n }\n}\n\n/** The first item with `value` in tree order and its ancestors, from the top down; `null` if none. */\nfunction findPath(nodes: readonly TreeNode[], value: string): TreeNode[] | null {\n for (const node of nodes) {\n if (node.value === value) return [node];\n const below = findPath(node.children, value);\n if (below) return [node, ...below];\n }\n return null;\n}\n\n/**\n * The check state of every item: checked when its value is listed, when an ancestor's value is\n * listed (or `ancestorListed`), or when it has nested items and all of them are checked; mixed\n * when some of them are checked or mixed; else unchecked. For a value that several items share,\n * the first item in tree order decides the entry.\n */\nexport function computeCheckStates(\n nodes: readonly TreeNode[],\n listed: ReadonlySet<string>,\n ancestorListed = false,\n): Map<string, CheckState> {\n const first = new Map<string, TreeNode>();\n forEachNode(nodes, (candidate) => {\n if (!first.has(candidate.value)) first.set(candidate.value, candidate);\n });\n const states = new Map<string, CheckState>();\n const visit = (current: TreeNode, forcedAbove: boolean): CheckState => {\n const forced = forcedAbove || listed.has(current.value);\n const childStates = current.children.map((child) => visit(child, forced));\n let state: CheckState;\n if (forced) state = 'checked';\n else if (childStates.length === 0) state = 'unchecked';\n else if (childStates.every((childState) => childState === 'checked')) state = 'checked';\n else if (childStates.some((childState) => childState !== 'unchecked')) state = 'mixed';\n else state = 'unchecked';\n if (first.get(current.value) === current) states.set(current.value, state);\n return state;\n };\n for (const top of nodes) visit(top, ancestorListed);\n return states;\n}\n\n/**\n * The checked items after toggling `value`. A checked item and every item nested in it become\n * unchecked; an unchecked or mixed one and every item nested in it become checked; its ancestors\n * then follow their nested items. Returns every checked item in tree order (fully checked parents\n * included, mixed ones not), each value once, followed by the listed values that match no item,\n * in their order; a value that no item has is added to, or removed from, those.\n */\nexport function toggleCheck(\n nodes: readonly TreeNode[],\n listed: readonly string[],\n value: string,\n): string[] {\n const states = computeCheckStates(nodes, new Set(listed));\n const checked = new Set<string>();\n for (const [itemValue, state] of states) {\n if (state === 'checked') checked.add(itemValue);\n }\n const known = new Set<string>();\n forEachNode(nodes, (candidate) => known.add(candidate.value));\n const unmatched = Array.from(new Set(listed.filter((listedValue) => !known.has(listedValue))));\n\n const path = findPath(nodes, value);\n if (path) {\n const target = path[path.length - 1];\n const turnOn = states.get(value) !== 'checked';\n forEachNode([target], (candidate) => {\n if (turnOn) checked.add(candidate.value);\n else checked.delete(candidate.value);\n });\n for (let index = path.length - 2; index >= 0; index -= 1) {\n const ancestor = path[index];\n if (ancestor.children.every((child) => checked.has(child.value))) checked.add(ancestor.value);\n else checked.delete(ancestor.value);\n }\n } else {\n const at = unmatched.indexOf(value);\n if (at === -1) unmatched.push(value);\n else unmatched.splice(at, 1);\n }\n\n const ordered: string[] = [];\n const seen = new Set<string>();\n forEachNode(nodes, (candidate) => {\n if (checked.has(candidate.value) && !seen.has(candidate.value)) {\n seen.add(candidate.value);\n ordered.push(candidate.value);\n }\n });\n return [...ordered, ...unmatched];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function e(e,t){return Number.isFinite(e)?Math.max(0,Math.floor(e)):t}function t(t){let{itemSize:n,keep:r}=t,i=e(t.count,0);if(i===0)return[];let a=Number.isFinite(n)&&n>0?n:1,o=Math.max(1,Number.isFinite(t.viewportSize)?Math.ceil(t.viewportSize/a):1),s=e(t.overscan,0),c=Math.min(e(t.firstVisible,0),Math.max(0,i-o)),l=Math.max(0,c-s),u=Math.min(i,c+o+s),d=[...new Set(r??[])].filter(e=>Number.isInteger(e)&&e>=0&&e<i).filter(e=>e<l||e>=u).sort((e,t)=>e-t),f=[],p=(e,t)=>{let n=f[f.length-1];n&&e<=n[1]?n[1]=Math.max(n[1],t):f.push([e,t])},m=!1;for(let e of d)!m&&e>l&&(p(l,u),m=!0),p(e,e+1);m||p(l,u);let h=[],g=0;for(let[e,t]of f){e>g&&h.push({kind:`spacer`,size:(e-g)*a,key:`spacer-${e}`});for(let n=e;n<t;n++)h.push({kind:`item`,index:n});g=t}return g<i&&h.push({kind:`spacer`,size:(i-g)*a,key:`spacer-end`}),h}function n(t){let{align:n,scrollTop:r,viewportSize:i}=t,a=e(t.count,0),o=Number.isFinite(t.itemSize)&&t.itemSize>0?t.itemSize:0,s=Number.isFinite(i)?Math.max(0,i):0,c=Math.max(0,a*o-s);if(a===0||c===0)return 0;let l=Math.min(Math.max(0,Number.isFinite(t.index)?Math.floor(t.index):0),a-1)*o,u=l+o,d=Number.isFinite(r)?r:0,f;switch(n){case`start`:f=l;break;case`end`:f=u-s;break;case`center`:f=l+o/2-s/2;break;default:f=l<d?l:u>d+s?u-s:d}return Math.min(Math.max(0,f),c)}exports.computeVirtualLayout=t,exports.scrollOffsetForIndex=n;
|
|
2
|
+
//# sourceMappingURL=virtual.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual.cjs","names":["toCount","value","fallback","computeVirtualLayout","input","count","rowSize","itemSize","visibleCount","overscan","first","start","end","extra","keep","index","a","b","runs","push","last","from","to","windowPushed","entries","next","scrollOffsetForIndex","viewport","viewportSize","maxOffset","top","bottom","current","scrollTop","target","align"],"sources":["../../src/lib/virtual.ts"],"sourcesContent":["/**\n * One entry of a windowed list: a row to render, or the empty space that stands in for the rows\n * that are not rendered. A spacer's `key` is stable for React: `spacer-<index of the next item>`,\n * or `spacer-end` for the one after the last item.\n */\nexport type VirtualEntry =\n { kind: 'item'; index: number } | { kind: 'spacer'; size: number; key: string };\n\n/** Input of {@link computeVirtualLayout}. */\nexport interface VirtualLayoutInput {\n /** Number of rows in the whole list. */\n count: number;\n /** Height (or width) of one row, in pixels. */\n itemSize: number;\n /** Index of the first row in view. Clamped to `[0, max(0, count - rows in view)]`. */\n firstVisible: number;\n /** Height (or width) of the scroll viewport, in pixels. */\n viewportSize: number;\n /** Rows rendered beyond each edge of the view. */\n overscan: number;\n /**\n * Indexes that stay rendered outside the window (the focused row, the row a drag holds).\n * Entries that are not integers inside the list are ignored.\n */\n keep?: readonly number[];\n}\n\n/** An index run, `[from, to)`. */\ntype Run = readonly [from: number, to: number];\n\nfunction toCount(value: number, fallback: number): number {\n return Number.isFinite(value) ? Math.max(0, Math.floor(value)) : fallback;\n}\n\n/**\n * The rows to render for a scrolled list and the spacers that keep its scroll height: the rows in\n * view with `overscan` rows on both sides, plus every `keep` index as a run of its own. The sizes\n * of the items and the spacers add up to `count * itemSize`; a spacer is never empty.\n */\nexport function computeVirtualLayout(input: VirtualLayoutInput): readonly VirtualEntry[] {\n const { itemSize, keep } = input;\n const count = toCount(input.count, 0);\n if (count === 0) return [];\n\n const rowSize = Number.isFinite(itemSize) && itemSize > 0 ? itemSize : 1;\n const visibleCount = Math.max(\n 1,\n Number.isFinite(input.viewportSize) ? Math.ceil(input.viewportSize / rowSize) : 1,\n );\n const overscan = toCount(input.overscan, 0);\n // A scroller never shows a first row past the last full page: a list that shrank under a\n // scrolled window is clamped the way the browser clamps `scrollTop`.\n const first = Math.min(toCount(input.firstVisible, 0), Math.max(0, count - visibleCount));\n const start = Math.max(0, first - overscan);\n const end = Math.min(count, first + visibleCount + overscan);\n\n // The window and the kept rows outside it, sorted; touching runs merge into one.\n const extra = [...new Set(keep ?? [])]\n .filter((index) => Number.isInteger(index) && index >= 0 && index < count)\n .filter((index) => index < start || index >= end)\n .sort((a, b) => a - b);\n const runs: [number, number][] = [];\n const push = (from: number, to: number) => {\n const last = runs[runs.length - 1];\n if (last && from <= last[1]) last[1] = Math.max(last[1], to);\n else runs.push([from, to]);\n };\n let windowPushed = false;\n for (const index of extra) {\n if (!windowPushed && index > start) {\n push(start, end);\n windowPushed = true;\n }\n push(index, index + 1);\n }\n if (!windowPushed) push(start, end);\n\n const entries: VirtualEntry[] = [];\n let next = 0;\n for (const [from, to] of runs as readonly Run[]) {\n if (from > next)\n entries.push({ kind: 'spacer', size: (from - next) * rowSize, key: `spacer-${from}` });\n for (let index = from; index < to; index++) entries.push({ kind: 'item', index });\n next = to;\n }\n if (next < count)\n entries.push({ kind: 'spacer', size: (count - next) * rowSize, key: 'spacer-end' });\n return entries;\n}\n\n/** Input of {@link scrollOffsetForIndex}. */\nexport interface ScrollOffsetInput {\n index: number;\n /**\n * Where the row ends up: `'start'`, `'center'` or `'end'` of the viewport, or `'auto'`, the\n * smallest move that shows it whole (the current offset when it already is).\n */\n align: 'auto' | 'start' | 'center' | 'end';\n itemSize: number;\n count: number;\n scrollTop: number;\n viewportSize: number;\n}\n\n/** The scroll offset, clamped to the content, that brings row `index` to the requested place. */\nexport function scrollOffsetForIndex(input: ScrollOffsetInput): number {\n const { align, scrollTop, viewportSize } = input;\n const count = toCount(input.count, 0);\n const rowSize = Number.isFinite(input.itemSize) && input.itemSize > 0 ? input.itemSize : 0;\n const viewport = Number.isFinite(viewportSize) ? Math.max(0, viewportSize) : 0;\n const maxOffset = Math.max(0, count * rowSize - viewport);\n if (count === 0 || maxOffset === 0) return 0;\n\n const index = Math.min(\n Math.max(0, Number.isFinite(input.index) ? Math.floor(input.index) : 0),\n count - 1,\n );\n const top = index * rowSize;\n const bottom = top + rowSize;\n const current = Number.isFinite(scrollTop) ? scrollTop : 0;\n\n let target: number;\n switch (align) {\n case 'start':\n target = top;\n break;\n case 'end':\n target = bottom - viewport;\n break;\n case 'center':\n target = top + rowSize / 2 - viewport / 2;\n break;\n default:\n target = top < current ? top : bottom > current + viewport ? bottom - viewport : current;\n }\n return Math.min(Math.max(0, target), maxOffset);\n}\n"],"mappings":"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"}
|