@salt-ds/lab 1.0.0-alpha.93 → 1.0.0-alpha.94

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.
Files changed (131) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/css/salt-lab.css +163 -122
  3. package/dist-cjs/index.js +6 -8
  4. package/dist-cjs/index.js.map +1 -1
  5. package/dist-cjs/toolbar-next/ToolbarContentNext.css.js +6 -0
  6. package/dist-cjs/toolbar-next/ToolbarContentNext.css.js.map +1 -0
  7. package/dist-cjs/toolbar-next/ToolbarContentNext.js +32 -0
  8. package/dist-cjs/toolbar-next/ToolbarContentNext.js.map +1 -0
  9. package/dist-cjs/toolbar-next/ToolbarNext.css.js +6 -0
  10. package/dist-cjs/toolbar-next/ToolbarNext.css.js.map +1 -0
  11. package/dist-cjs/toolbar-next/ToolbarNext.js +394 -0
  12. package/dist-cjs/toolbar-next/ToolbarNext.js.map +1 -0
  13. package/dist-cjs/toolbar-next/ToolbarNextOverflow.css.js +6 -0
  14. package/dist-cjs/toolbar-next/ToolbarNextOverflow.css.js.map +1 -0
  15. package/dist-cjs/toolbar-next/ToolbarNextOverflow.js +705 -0
  16. package/dist-cjs/toolbar-next/ToolbarNextOverflow.js.map +1 -0
  17. package/dist-cjs/toolbar-next/ToolbarNextOverflowFloatingBoundary.js +165 -0
  18. package/dist-cjs/toolbar-next/ToolbarNextOverflowFloatingBoundary.js.map +1 -0
  19. package/dist-cjs/toolbar-next/TooltrayNext.css.js +6 -0
  20. package/dist-cjs/toolbar-next/TooltrayNext.css.js.map +1 -0
  21. package/dist-cjs/toolbar-next/TooltrayNext.js +55 -0
  22. package/dist-cjs/toolbar-next/TooltrayNext.js.map +1 -0
  23. package/dist-cjs/toolbar-next/toolbarNextKeyboardUtils.js +391 -0
  24. package/dist-cjs/toolbar-next/toolbarNextKeyboardUtils.js.map +1 -0
  25. package/dist-cjs/toolbar-next/toolbarNextUtils.js +215 -0
  26. package/dist-cjs/toolbar-next/toolbarNextUtils.js.map +1 -0
  27. package/dist-cjs/toolbar-next/useToolbarNextKeyboardNavigation.js +334 -0
  28. package/dist-cjs/toolbar-next/useToolbarNextKeyboardNavigation.js.map +1 -0
  29. package/dist-cjs/toolbar-next/useToolbarNextOverflow.js +743 -0
  30. package/dist-cjs/toolbar-next/useToolbarNextOverflow.js.map +1 -0
  31. package/dist-es/index.js +3 -4
  32. package/dist-es/index.js.map +1 -1
  33. package/dist-es/toolbar-next/ToolbarContentNext.css.js +4 -0
  34. package/dist-es/toolbar-next/ToolbarContentNext.css.js.map +1 -0
  35. package/dist-es/toolbar-next/ToolbarContentNext.js +30 -0
  36. package/dist-es/toolbar-next/ToolbarContentNext.js.map +1 -0
  37. package/dist-es/toolbar-next/ToolbarNext.css.js +4 -0
  38. package/dist-es/toolbar-next/ToolbarNext.css.js.map +1 -0
  39. package/dist-es/toolbar-next/ToolbarNext.js +392 -0
  40. package/dist-es/toolbar-next/ToolbarNext.js.map +1 -0
  41. package/dist-es/toolbar-next/ToolbarNextOverflow.css.js +4 -0
  42. package/dist-es/toolbar-next/ToolbarNextOverflow.css.js.map +1 -0
  43. package/dist-es/toolbar-next/ToolbarNextOverflow.js +700 -0
  44. package/dist-es/toolbar-next/ToolbarNextOverflow.js.map +1 -0
  45. package/dist-es/toolbar-next/ToolbarNextOverflowFloatingBoundary.js +159 -0
  46. package/dist-es/toolbar-next/ToolbarNextOverflowFloatingBoundary.js.map +1 -0
  47. package/dist-es/toolbar-next/TooltrayNext.css.js +4 -0
  48. package/dist-es/toolbar-next/TooltrayNext.css.js.map +1 -0
  49. package/dist-es/toolbar-next/TooltrayNext.js +53 -0
  50. package/dist-es/toolbar-next/TooltrayNext.js.map +1 -0
  51. package/dist-es/toolbar-next/toolbarNextKeyboardUtils.js +372 -0
  52. package/dist-es/toolbar-next/toolbarNextKeyboardUtils.js.map +1 -0
  53. package/dist-es/toolbar-next/toolbarNextUtils.js +211 -0
  54. package/dist-es/toolbar-next/toolbarNextUtils.js.map +1 -0
  55. package/dist-es/toolbar-next/useToolbarNextKeyboardNavigation.js +332 -0
  56. package/dist-es/toolbar-next/useToolbarNextKeyboardNavigation.js.map +1 -0
  57. package/dist-es/toolbar-next/useToolbarNextOverflow.js +741 -0
  58. package/dist-es/toolbar-next/useToolbarNextOverflow.js.map +1 -0
  59. package/dist-types/index.d.ts +1 -1
  60. package/dist-types/toolbar-next/ToolbarContentNext.d.ts +11 -0
  61. package/dist-types/toolbar-next/ToolbarNext.d.ts +12 -0
  62. package/dist-types/toolbar-next/ToolbarNextOverflow.d.ts +34 -0
  63. package/dist-types/toolbar-next/ToolbarNextOverflowFloatingBoundary.d.ts +16 -0
  64. package/dist-types/toolbar-next/TooltrayNext.d.ts +37 -0
  65. package/dist-types/toolbar-next/index.d.ts +3 -0
  66. package/dist-types/toolbar-next/toolbarNextKeyboardUtils.d.ts +39 -0
  67. package/dist-types/toolbar-next/toolbarNextUtils.d.ts +42 -0
  68. package/dist-types/toolbar-next/useToolbarNextKeyboardNavigation.d.ts +41 -0
  69. package/dist-types/toolbar-next/useToolbarNextOverflow.d.ts +37 -0
  70. package/package.json +2 -2
  71. package/dist-cjs/tree/Tree.css.js +0 -6
  72. package/dist-cjs/tree/Tree.css.js.map +0 -1
  73. package/dist-cjs/tree/Tree.js +0 -303
  74. package/dist-cjs/tree/Tree.js.map +0 -1
  75. package/dist-cjs/tree/TreeContext.js +0 -31
  76. package/dist-cjs/tree/TreeContext.js.map +0 -1
  77. package/dist-cjs/tree/TreeNode.css.js +0 -6
  78. package/dist-cjs/tree/TreeNode.css.js.map +0 -1
  79. package/dist-cjs/tree/TreeNode.js +0 -103
  80. package/dist-cjs/tree/TreeNode.js.map +0 -1
  81. package/dist-cjs/tree/TreeNodeExpansionIcon.css.js +0 -6
  82. package/dist-cjs/tree/TreeNodeExpansionIcon.css.js.map +0 -1
  83. package/dist-cjs/tree/TreeNodeExpansionIcon.js +0 -62
  84. package/dist-cjs/tree/TreeNodeExpansionIcon.js.map +0 -1
  85. package/dist-cjs/tree/TreeNodeLabel.css.js +0 -6
  86. package/dist-cjs/tree/TreeNodeLabel.css.js.map +0 -1
  87. package/dist-cjs/tree/TreeNodeLabel.js +0 -26
  88. package/dist-cjs/tree/TreeNodeLabel.js.map +0 -1
  89. package/dist-cjs/tree/TreeNodeTrigger.css.js +0 -6
  90. package/dist-cjs/tree/TreeNodeTrigger.css.js.map +0 -1
  91. package/dist-cjs/tree/TreeNodeTrigger.js +0 -153
  92. package/dist-cjs/tree/TreeNodeTrigger.js.map +0 -1
  93. package/dist-cjs/tree/treeModel.js +0 -61
  94. package/dist-cjs/tree/treeModel.js.map +0 -1
  95. package/dist-cjs/tree/useTree.js +0 -337
  96. package/dist-cjs/tree/useTree.js.map +0 -1
  97. package/dist-es/tree/Tree.css.js +0 -4
  98. package/dist-es/tree/Tree.css.js.map +0 -1
  99. package/dist-es/tree/Tree.js +0 -301
  100. package/dist-es/tree/Tree.js.map +0 -1
  101. package/dist-es/tree/TreeContext.js +0 -26
  102. package/dist-es/tree/TreeContext.js.map +0 -1
  103. package/dist-es/tree/TreeNode.css.js +0 -4
  104. package/dist-es/tree/TreeNode.css.js.map +0 -1
  105. package/dist-es/tree/TreeNode.js +0 -101
  106. package/dist-es/tree/TreeNode.js.map +0 -1
  107. package/dist-es/tree/TreeNodeExpansionIcon.css.js +0 -4
  108. package/dist-es/tree/TreeNodeExpansionIcon.css.js.map +0 -1
  109. package/dist-es/tree/TreeNodeExpansionIcon.js +0 -60
  110. package/dist-es/tree/TreeNodeExpansionIcon.js.map +0 -1
  111. package/dist-es/tree/TreeNodeLabel.css.js +0 -4
  112. package/dist-es/tree/TreeNodeLabel.css.js.map +0 -1
  113. package/dist-es/tree/TreeNodeLabel.js +0 -24
  114. package/dist-es/tree/TreeNodeLabel.js.map +0 -1
  115. package/dist-es/tree/TreeNodeTrigger.css.js +0 -4
  116. package/dist-es/tree/TreeNodeTrigger.css.js.map +0 -1
  117. package/dist-es/tree/TreeNodeTrigger.js +0 -151
  118. package/dist-es/tree/TreeNodeTrigger.js.map +0 -1
  119. package/dist-es/tree/treeModel.js +0 -57
  120. package/dist-es/tree/treeModel.js.map +0 -1
  121. package/dist-es/tree/useTree.js +0 -335
  122. package/dist-es/tree/useTree.js.map +0 -1
  123. package/dist-types/tree/Tree.d.ts +0 -36
  124. package/dist-types/tree/TreeContext.d.ts +0 -77
  125. package/dist-types/tree/TreeNode.d.ts +0 -25
  126. package/dist-types/tree/TreeNodeExpansionIcon.d.ts +0 -4
  127. package/dist-types/tree/TreeNodeLabel.d.ts +0 -4
  128. package/dist-types/tree/TreeNodeTrigger.d.ts +0 -8
  129. package/dist-types/tree/index.d.ts +0 -4
  130. package/dist-types/tree/treeModel.d.ts +0 -24
  131. package/dist-types/tree/useTree.d.ts +0 -68
@@ -0,0 +1,372 @@
1
+ const TOOLBAR_NEXT_SCOPE_ROOT_ATTR = "data-salt-toolbar-next-scope-root";
2
+ const TOOLBAR_NEXT_ITEM_ATTR = "data-salt-toolbar-next-item-id";
3
+ const TOOLBAR_NEXT_GROUP_KEY_ATTR = "data-salt-toolbar-next-overflow-group-key";
4
+ const TOOLBAR_NEXT_OVERFLOW_TRIGGER_ATTR = "data-salt-toolbar-next-overflow-trigger";
5
+ const toolbarNextFocusableSelector = [
6
+ "button",
7
+ "[href]",
8
+ "input",
9
+ "select",
10
+ "textarea",
11
+ "[tabindex]"
12
+ ].join(", ");
13
+ const textEntryInputTypes = /* @__PURE__ */ new Set([
14
+ "",
15
+ "date",
16
+ "datetime-local",
17
+ "email",
18
+ "month",
19
+ "number",
20
+ "password",
21
+ "search",
22
+ "tel",
23
+ "text",
24
+ "time",
25
+ "url",
26
+ "week"
27
+ ]);
28
+ function getClosestToolbarNextScopeRoot(target) {
29
+ if (!(target instanceof Element)) {
30
+ return null;
31
+ }
32
+ return target.closest(`[${TOOLBAR_NEXT_SCOPE_ROOT_ATTR}]`);
33
+ }
34
+ function getToolbarNextItemId(target) {
35
+ var _a;
36
+ return ((_a = target == null ? void 0 : target.closest(`[${TOOLBAR_NEXT_ITEM_ATTR}]`)) == null ? void 0 : _a.getAttribute(TOOLBAR_NEXT_ITEM_ATTR)) ?? null;
37
+ }
38
+ function isToolbarNextFocusFromPointerTarget(focusTarget, pointerTarget) {
39
+ if (!(pointerTarget instanceof Node)) {
40
+ return false;
41
+ }
42
+ if (focusTarget === pointerTarget || focusTarget.contains(pointerTarget)) {
43
+ return true;
44
+ }
45
+ if (!(pointerTarget instanceof Element)) {
46
+ return false;
47
+ }
48
+ const focusItemId = getToolbarNextItemId(focusTarget);
49
+ const pointerItemId = getToolbarNextItemId(pointerTarget);
50
+ return focusItemId != null && focusItemId === pointerItemId;
51
+ }
52
+ function getToolbarNextScopeFocusableElements(scopeRoot, options = {}) {
53
+ return Array.from(
54
+ scopeRoot.querySelectorAll(toolbarNextFocusableSelector)
55
+ ).filter((element) => {
56
+ return getClosestToolbarNextScopeRoot(element) === scopeRoot && (isToolbarNextFocusable(element, options) || isToolbarNextToggleGroupButton(element));
57
+ });
58
+ }
59
+ function getToolbarNextFocusMemory(scopeRoot, target, options = {}) {
60
+ const scopeElements = getToolbarNextScopeFocusableElements(
61
+ scopeRoot,
62
+ options
63
+ );
64
+ const scopeIndex = scopeElements.indexOf(target);
65
+ if (scopeIndex === -1) {
66
+ return null;
67
+ }
68
+ const groupTrigger = target.closest(
69
+ `[${TOOLBAR_NEXT_OVERFLOW_TRIGGER_ATTR}]`
70
+ );
71
+ const groupKey = groupTrigger == null ? void 0 : groupTrigger.getAttribute(TOOLBAR_NEXT_GROUP_KEY_ATTR);
72
+ if (groupKey) {
73
+ return {
74
+ groupKey,
75
+ scopeIndex,
76
+ type: "overflow-trigger"
77
+ };
78
+ }
79
+ const itemRoot = target.closest(`[${TOOLBAR_NEXT_ITEM_ATTR}]`);
80
+ const itemId = itemRoot == null ? void 0 : itemRoot.getAttribute(TOOLBAR_NEXT_ITEM_ATTR);
81
+ if (itemRoot && itemId) {
82
+ const itemElements = getToolbarNextItemFocusableElements(
83
+ itemRoot,
84
+ scopeRoot,
85
+ options
86
+ );
87
+ const controlIndex = itemElements.indexOf(target);
88
+ return {
89
+ controlIndex: Math.max(controlIndex, 0),
90
+ itemId,
91
+ scopeIndex,
92
+ type: "item"
93
+ };
94
+ }
95
+ return {
96
+ scopeIndex,
97
+ type: "scope"
98
+ };
99
+ }
100
+ function resolveToolbarNextFocusTarget(scopeRoot, focusMemory, {
101
+ includeTabIndexMinusOne,
102
+ items = [],
103
+ overflowedIds
104
+ } = {}) {
105
+ const focusableOptions = {
106
+ includeTabIndexMinusOne
107
+ };
108
+ if (!focusMemory) {
109
+ return getToolbarNextScopeFocusableElements(scopeRoot, focusableOptions)[0] ?? null;
110
+ }
111
+ const fallback = getToolbarNextFocusFallback(
112
+ scopeRoot,
113
+ focusMemory.scopeIndex,
114
+ focusableOptions
115
+ );
116
+ if (focusMemory.type === "overflow-trigger") {
117
+ const trigger = getToolbarNextOverflowTriggerElement(
118
+ scopeRoot,
119
+ focusMemory.groupKey
120
+ );
121
+ if (trigger) {
122
+ return trigger;
123
+ }
124
+ const firstVisibleItem = items.find((item) => {
125
+ return item.overflowGroupKey === focusMemory.groupKey;
126
+ });
127
+ if (firstVisibleItem) {
128
+ return getToolbarNextFocusableElementForItem(
129
+ scopeRoot,
130
+ firstVisibleItem.id,
131
+ 0,
132
+ focusableOptions
133
+ ) ?? fallback;
134
+ }
135
+ return fallback;
136
+ }
137
+ if (focusMemory.type === "item") {
138
+ const visibleItemTarget = getToolbarNextFocusableElementForItem(
139
+ scopeRoot,
140
+ focusMemory.itemId,
141
+ focusMemory.controlIndex,
142
+ focusableOptions
143
+ );
144
+ if (visibleItemTarget) {
145
+ return visibleItemTarget;
146
+ }
147
+ const item = items.find((entry) => entry.id === focusMemory.itemId);
148
+ if (item && (overflowedIds == null ? void 0 : overflowedIds.has(item.id))) {
149
+ return getToolbarNextOverflowTriggerElement(
150
+ scopeRoot,
151
+ item.overflowGroupKey
152
+ ) ?? fallback;
153
+ }
154
+ return fallback;
155
+ }
156
+ return fallback;
157
+ }
158
+ function getToolbarNextDirectionalMoveTarget(scopeRoot, target, key, options = {}) {
159
+ if (key !== "ArrowLeft" && key !== "ArrowRight") {
160
+ return null;
161
+ }
162
+ if (getToolbarNextKeyboardPolicy(target).preserveHorizontalArrows) {
163
+ return null;
164
+ }
165
+ const toggleGroupButtons = getToggleGroupButtons(target);
166
+ if (toggleGroupButtons.length > 0) {
167
+ const visualDelta = getVisualDelta(scopeRoot, key);
168
+ const currentIndex2 = toggleGroupButtons.indexOf(target);
169
+ if (currentIndex2 === -1 || !isToggleGroupBoundary(
170
+ currentIndex2,
171
+ toggleGroupButtons.length,
172
+ visualDelta
173
+ )) {
174
+ return null;
175
+ }
176
+ }
177
+ const scopeElements = getToolbarNextScopeFocusableElements(
178
+ scopeRoot,
179
+ options
180
+ );
181
+ const currentIndex = scopeElements.indexOf(target);
182
+ if (currentIndex === -1 || scopeElements.length <= 1) {
183
+ return null;
184
+ }
185
+ const nextIndex = (currentIndex + getVisualDelta(scopeRoot, key) + scopeElements.length) % scopeElements.length;
186
+ return scopeElements[nextIndex] ?? null;
187
+ }
188
+ function getToolbarNextTabMoveTarget(scopeRoot, shiftKey) {
189
+ const focusableElements = getDocumentFocusableElements(
190
+ scopeRoot.ownerDocument
191
+ );
192
+ if (shiftKey) {
193
+ for (let index = focusableElements.length - 1; index >= 0; index -= 1) {
194
+ const element = focusableElements[index];
195
+ if (!element || scopeRoot.contains(element)) {
196
+ continue;
197
+ }
198
+ if (element.compareDocumentPosition(scopeRoot) & Node.DOCUMENT_POSITION_FOLLOWING) {
199
+ return element;
200
+ }
201
+ }
202
+ return null;
203
+ }
204
+ return focusableElements.find((element) => {
205
+ return !scopeRoot.contains(element) && !!(scopeRoot.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_FOLLOWING);
206
+ }) ?? null;
207
+ }
208
+ function shouldToolbarNextPreserveNativeTab(target) {
209
+ return getToolbarNextKeyboardPolicy(target).preserveNativeTab;
210
+ }
211
+ function getToolbarNextItemFocusableElements(itemRoot, scopeRoot, options = {}) {
212
+ return Array.from(
213
+ itemRoot.querySelectorAll(toolbarNextFocusableSelector)
214
+ ).filter((element) => {
215
+ return getClosestToolbarNextScopeRoot(element) === scopeRoot && (isToolbarNextFocusable(element, options) || isToolbarNextToggleGroupButton(element));
216
+ });
217
+ }
218
+ function getToolbarNextFocusableElementForItem(scopeRoot, itemId, controlIndex, options = {}) {
219
+ const itemRoot = scopeRoot.querySelector(
220
+ `[${TOOLBAR_NEXT_ITEM_ATTR}="${itemId}"]`
221
+ );
222
+ if (!itemRoot) {
223
+ return null;
224
+ }
225
+ const itemElements = getToolbarNextItemFocusableElements(
226
+ itemRoot,
227
+ scopeRoot,
228
+ options
229
+ );
230
+ return itemElements[Math.min(controlIndex, itemElements.length - 1)] ?? itemElements[0] ?? null;
231
+ }
232
+ function getToolbarNextOverflowTriggerElement(scopeRoot, groupKey) {
233
+ return scopeRoot.querySelector(
234
+ `[${TOOLBAR_NEXT_OVERFLOW_TRIGGER_ATTR}][${TOOLBAR_NEXT_GROUP_KEY_ATTR}="${groupKey}"]`
235
+ );
236
+ }
237
+ function getToolbarNextFocusFallback(scopeRoot, rememberedIndex, options = {}) {
238
+ const focusableElements = getToolbarNextScopeFocusableElements(
239
+ scopeRoot,
240
+ options
241
+ );
242
+ if (focusableElements.length === 0) {
243
+ return null;
244
+ }
245
+ return focusableElements[Math.max(0, Math.min(rememberedIndex, focusableElements.length - 1))] ?? focusableElements[0];
246
+ }
247
+ function getVisualDelta(scopeRoot, key) {
248
+ var _a;
249
+ const direction = (_a = scopeRoot.ownerDocument.defaultView) == null ? void 0 : _a.getComputedStyle(scopeRoot).direction;
250
+ if (key === "ArrowRight") {
251
+ return direction === "rtl" ? -1 : 1;
252
+ }
253
+ return direction === "rtl" ? 1 : -1;
254
+ }
255
+ function isToggleGroupBoundary(currentIndex, length, visualDelta) {
256
+ if (visualDelta > 0) {
257
+ return currentIndex === length - 1;
258
+ }
259
+ return currentIndex === 0;
260
+ }
261
+ function getToggleGroupButtons(target) {
262
+ const toggleGroup = target.closest(".saltToggleButtonGroup");
263
+ if (!toggleGroup || target.tagName !== "BUTTON") {
264
+ return [];
265
+ }
266
+ return Array.from(toggleGroup.querySelectorAll("button")).filter(
267
+ (button) => isToolbarNextFocusable(button, { includeTabIndexMinusOne: true })
268
+ );
269
+ }
270
+ function isToolbarNextToggleGroupButton(target) {
271
+ return target.tagName === "BUTTON" && target.closest(".saltToggleButtonGroup") != null && isToolbarNextFocusable(target, { includeTabIndexMinusOne: true });
272
+ }
273
+ function getToolbarNextKeyboardPolicy(target) {
274
+ if (target.isContentEditable || isPlainTextInput(target) || isComboBoxInput(target)) {
275
+ return {
276
+ preserveHorizontalArrows: true,
277
+ preserveNativeTab: true
278
+ };
279
+ }
280
+ if (isDropdownControl(target)) {
281
+ return {
282
+ preserveHorizontalArrows: false,
283
+ preserveNativeTab: false
284
+ };
285
+ }
286
+ if (isSelectLikeControl(target) || target.closest(".saltDatePickerTrigger") != null) {
287
+ return {
288
+ preserveHorizontalArrows: false,
289
+ preserveNativeTab: true
290
+ };
291
+ }
292
+ return {
293
+ preserveHorizontalArrows: false,
294
+ preserveNativeTab: false
295
+ };
296
+ }
297
+ function isComboBoxInput(target) {
298
+ return target.tagName === "INPUT" && target.closest('[role="combobox"], .saltComboBox') != null;
299
+ }
300
+ function isDropdownControl(target) {
301
+ return target.closest(".saltDropdown") != null;
302
+ }
303
+ function isSelectLikeControl(target) {
304
+ return target.tagName === "SELECT" || target.closest('[role="combobox"], .saltComboBox, .saltDropdown') != null;
305
+ }
306
+ function isPlainTextInput(target) {
307
+ if (target.tagName === "TEXTAREA") {
308
+ return true;
309
+ }
310
+ if (target.tagName !== "INPUT") {
311
+ return false;
312
+ }
313
+ return textEntryInputTypes.has(
314
+ target.type.toLowerCase()
315
+ );
316
+ }
317
+ function isNativeDisabledFormControl(target) {
318
+ return "disabled" in target && target.disabled;
319
+ }
320
+ function isToolbarNextFocusable(target, { includeTabIndexMinusOne = false } = {}) {
321
+ if (isNativeDisabledFormControl(target)) {
322
+ return false;
323
+ }
324
+ if (target.getAttribute("aria-hidden") === "true") {
325
+ return false;
326
+ }
327
+ if (!includeTabIndexMinusOne && target.getAttribute("tabindex") === "-1") {
328
+ return false;
329
+ }
330
+ if (target.hidden) {
331
+ return false;
332
+ }
333
+ const win = target.ownerDocument.defaultView;
334
+ if (!win) {
335
+ return false;
336
+ }
337
+ const styles = win.getComputedStyle(target);
338
+ if (styles.display === "none" || styles.visibility === "hidden") {
339
+ return false;
340
+ }
341
+ return target.getClientRects().length > 0;
342
+ }
343
+ function focusToolbarNextElement(target) {
344
+ if (target == null ? void 0 : target.isConnected) {
345
+ target.focus({ preventScroll: true });
346
+ }
347
+ }
348
+ function scheduleToolbarNextFocus(target, targetWindow = target == null ? void 0 : target.ownerDocument.defaultView) {
349
+ if (!target) {
350
+ return () => void 0;
351
+ }
352
+ if (targetWindow == null ? void 0 : targetWindow.requestAnimationFrame) {
353
+ const frame = targetWindow.requestAnimationFrame(() => {
354
+ focusToolbarNextElement(target);
355
+ });
356
+ return () => {
357
+ targetWindow.cancelAnimationFrame(frame);
358
+ };
359
+ }
360
+ queueMicrotask(() => {
361
+ focusToolbarNextElement(target);
362
+ });
363
+ return () => void 0;
364
+ }
365
+ function getDocumentFocusableElements(ownerDocument) {
366
+ return Array.from(
367
+ ownerDocument.querySelectorAll(toolbarNextFocusableSelector)
368
+ ).filter((element) => isToolbarNextFocusable(element));
369
+ }
370
+
371
+ export { TOOLBAR_NEXT_GROUP_KEY_ATTR, TOOLBAR_NEXT_ITEM_ATTR, TOOLBAR_NEXT_OVERFLOW_TRIGGER_ATTR, TOOLBAR_NEXT_SCOPE_ROOT_ATTR, focusToolbarNextElement, getClosestToolbarNextScopeRoot, getDocumentFocusableElements, getToolbarNextDirectionalMoveTarget, getToolbarNextFocusMemory, getToolbarNextItemId, getToolbarNextScopeFocusableElements, getToolbarNextTabMoveTarget, isToolbarNextFocusFromPointerTarget, isToolbarNextFocusable, resolveToolbarNextFocusTarget, scheduleToolbarNextFocus, shouldToolbarNextPreserveNativeTab, toolbarNextFocusableSelector };
372
+ //# sourceMappingURL=toolbarNextKeyboardUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolbarNextKeyboardUtils.js","sources":["../src/toolbar-next/toolbarNextKeyboardUtils.ts"],"sourcesContent":["import type { ToolbarNextOverflowItem } from \"./toolbarNextUtils\";\n\nexport const TOOLBAR_NEXT_SCOPE_ROOT_ATTR = \"data-salt-toolbar-next-scope-root\";\nexport const TOOLBAR_NEXT_ITEM_ATTR = \"data-salt-toolbar-next-item-id\";\nexport const TOOLBAR_NEXT_GROUP_KEY_ATTR =\n \"data-salt-toolbar-next-overflow-group-key\";\nexport const TOOLBAR_NEXT_OVERFLOW_TRIGGER_ATTR =\n \"data-salt-toolbar-next-overflow-trigger\";\n\nexport const toolbarNextFocusableSelector = [\n \"button\",\n \"[href]\",\n \"input\",\n \"select\",\n \"textarea\",\n \"[tabindex]\",\n].join(\", \");\n\nconst textEntryInputTypes = new Set([\n \"\",\n \"date\",\n \"datetime-local\",\n \"email\",\n \"month\",\n \"number\",\n \"password\",\n \"search\",\n \"tel\",\n \"text\",\n \"time\",\n \"url\",\n \"week\",\n]);\n\nexport type ToolbarNextFocusMemory =\n | {\n controlIndex: number;\n itemId: string;\n scopeIndex: number;\n type: \"item\";\n }\n | {\n groupKey: string;\n scopeIndex: number;\n type: \"overflow-trigger\";\n }\n | {\n scopeIndex: number;\n type: \"scope\";\n };\n\nexport interface ToolbarNextFocusableOptions {\n includeTabIndexMinusOne?: boolean;\n}\n\ninterface ToolbarNextKeyboardPolicy {\n preserveHorizontalArrows: boolean;\n preserveNativeTab: boolean;\n}\n\nexport function getClosestToolbarNextScopeRoot(target: EventTarget | null) {\n if (!(target instanceof Element)) {\n return null;\n }\n\n return target.closest<HTMLElement>(`[${TOOLBAR_NEXT_SCOPE_ROOT_ATTR}]`);\n}\n\nexport function getToolbarNextItemId(target: Element | null) {\n return (\n target\n ?.closest<HTMLElement>(`[${TOOLBAR_NEXT_ITEM_ATTR}]`)\n ?.getAttribute(TOOLBAR_NEXT_ITEM_ATTR) ?? null\n );\n}\n\nexport function isToolbarNextFocusFromPointerTarget(\n focusTarget: HTMLElement,\n pointerTarget: EventTarget | null,\n) {\n if (!(pointerTarget instanceof Node)) {\n return false;\n }\n\n if (focusTarget === pointerTarget || focusTarget.contains(pointerTarget)) {\n return true;\n }\n\n if (!(pointerTarget instanceof Element)) {\n return false;\n }\n\n const focusItemId = getToolbarNextItemId(focusTarget);\n const pointerItemId = getToolbarNextItemId(pointerTarget);\n\n return focusItemId != null && focusItemId === pointerItemId;\n}\n\nexport function getToolbarNextScopeFocusableElements(\n scopeRoot: HTMLElement,\n options: ToolbarNextFocusableOptions = {},\n) {\n return Array.from(\n scopeRoot.querySelectorAll<HTMLElement>(toolbarNextFocusableSelector),\n ).filter((element) => {\n return (\n getClosestToolbarNextScopeRoot(element) === scopeRoot &&\n (isToolbarNextFocusable(element, options) ||\n isToolbarNextToggleGroupButton(element))\n );\n });\n}\n\nexport function getToolbarNextFocusMemory(\n scopeRoot: HTMLElement,\n target: HTMLElement,\n options: ToolbarNextFocusableOptions = {},\n): ToolbarNextFocusMemory | null {\n const scopeElements = getToolbarNextScopeFocusableElements(\n scopeRoot,\n options,\n );\n const scopeIndex = scopeElements.indexOf(target);\n if (scopeIndex === -1) {\n return null;\n }\n\n const groupTrigger = target.closest<HTMLElement>(\n `[${TOOLBAR_NEXT_OVERFLOW_TRIGGER_ATTR}]`,\n );\n const groupKey = groupTrigger?.getAttribute(TOOLBAR_NEXT_GROUP_KEY_ATTR);\n\n if (groupKey) {\n return {\n groupKey,\n scopeIndex,\n type: \"overflow-trigger\",\n };\n }\n\n const itemRoot = target.closest<HTMLElement>(`[${TOOLBAR_NEXT_ITEM_ATTR}]`);\n const itemId = itemRoot?.getAttribute(TOOLBAR_NEXT_ITEM_ATTR);\n\n if (itemRoot && itemId) {\n const itemElements = getToolbarNextItemFocusableElements(\n itemRoot,\n scopeRoot,\n options,\n );\n const controlIndex = itemElements.indexOf(target);\n\n return {\n controlIndex: Math.max(controlIndex, 0),\n itemId,\n scopeIndex,\n type: \"item\",\n };\n }\n\n return {\n scopeIndex,\n type: \"scope\",\n };\n}\n\nexport function resolveToolbarNextFocusTarget(\n scopeRoot: HTMLElement,\n focusMemory: ToolbarNextFocusMemory | null,\n {\n includeTabIndexMinusOne,\n items = [],\n overflowedIds,\n }: {\n items?: ToolbarNextOverflowItem[];\n includeTabIndexMinusOne?: boolean;\n overflowedIds?: Set<string>;\n } = {},\n) {\n const focusableOptions = {\n includeTabIndexMinusOne,\n };\n\n if (!focusMemory) {\n return (\n getToolbarNextScopeFocusableElements(scopeRoot, focusableOptions)[0] ??\n null\n );\n }\n\n const fallback = getToolbarNextFocusFallback(\n scopeRoot,\n focusMemory.scopeIndex,\n focusableOptions,\n );\n\n if (focusMemory.type === \"overflow-trigger\") {\n const trigger = getToolbarNextOverflowTriggerElement(\n scopeRoot,\n focusMemory.groupKey,\n );\n\n if (trigger) {\n return trigger;\n }\n\n const firstVisibleItem = items.find((item) => {\n return item.overflowGroupKey === focusMemory.groupKey;\n });\n\n if (firstVisibleItem) {\n return (\n getToolbarNextFocusableElementForItem(\n scopeRoot,\n firstVisibleItem.id,\n 0,\n focusableOptions,\n ) ?? fallback\n );\n }\n\n return fallback;\n }\n\n if (focusMemory.type === \"item\") {\n const visibleItemTarget = getToolbarNextFocusableElementForItem(\n scopeRoot,\n focusMemory.itemId,\n focusMemory.controlIndex,\n focusableOptions,\n );\n\n if (visibleItemTarget) {\n return visibleItemTarget;\n }\n\n const item = items.find((entry) => entry.id === focusMemory.itemId);\n\n if (item && overflowedIds?.has(item.id)) {\n return (\n getToolbarNextOverflowTriggerElement(\n scopeRoot,\n item.overflowGroupKey,\n ) ?? fallback\n );\n }\n\n return fallback;\n }\n\n return fallback;\n}\n\nexport function getToolbarNextDirectionalMoveTarget(\n scopeRoot: HTMLElement,\n target: HTMLElement,\n key: string,\n options: ToolbarNextFocusableOptions = {},\n) {\n if (key !== \"ArrowLeft\" && key !== \"ArrowRight\") {\n return null;\n }\n\n if (getToolbarNextKeyboardPolicy(target).preserveHorizontalArrows) {\n return null;\n }\n\n const toggleGroupButtons = getToggleGroupButtons(target);\n\n if (toggleGroupButtons.length > 0) {\n const visualDelta = getVisualDelta(scopeRoot, key);\n const currentIndex = toggleGroupButtons.indexOf(target);\n\n if (\n currentIndex === -1 ||\n !isToggleGroupBoundary(\n currentIndex,\n toggleGroupButtons.length,\n visualDelta,\n )\n ) {\n return null;\n }\n }\n\n const scopeElements = getToolbarNextScopeFocusableElements(\n scopeRoot,\n options,\n );\n const currentIndex = scopeElements.indexOf(target);\n\n if (currentIndex === -1 || scopeElements.length <= 1) {\n return null;\n }\n\n const nextIndex =\n (currentIndex + getVisualDelta(scopeRoot, key) + scopeElements.length) %\n scopeElements.length;\n\n return scopeElements[nextIndex] ?? null;\n}\n\nexport function getToolbarNextTabMoveTarget(\n scopeRoot: HTMLElement,\n shiftKey: boolean,\n) {\n const focusableElements = getDocumentFocusableElements(\n scopeRoot.ownerDocument,\n );\n\n if (shiftKey) {\n for (let index = focusableElements.length - 1; index >= 0; index -= 1) {\n const element = focusableElements[index];\n\n if (!element || scopeRoot.contains(element)) {\n continue;\n }\n\n if (\n element.compareDocumentPosition(scopeRoot) &\n Node.DOCUMENT_POSITION_FOLLOWING\n ) {\n return element;\n }\n }\n\n return null;\n }\n\n return (\n focusableElements.find((element) => {\n return (\n !scopeRoot.contains(element) &&\n !!(\n scopeRoot.compareDocumentPosition(element) &\n Node.DOCUMENT_POSITION_FOLLOWING\n )\n );\n }) ?? null\n );\n}\n\nexport function shouldToolbarNextPreserveNativeTab(target: HTMLElement) {\n return getToolbarNextKeyboardPolicy(target).preserveNativeTab;\n}\n\nfunction getToolbarNextItemFocusableElements(\n itemRoot: HTMLElement,\n scopeRoot: HTMLElement,\n options: ToolbarNextFocusableOptions = {},\n) {\n return Array.from(\n itemRoot.querySelectorAll<HTMLElement>(toolbarNextFocusableSelector),\n ).filter((element) => {\n return (\n getClosestToolbarNextScopeRoot(element) === scopeRoot &&\n (isToolbarNextFocusable(element, options) ||\n isToolbarNextToggleGroupButton(element))\n );\n });\n}\n\nfunction getToolbarNextFocusableElementForItem(\n scopeRoot: HTMLElement,\n itemId: string,\n controlIndex: number,\n options: ToolbarNextFocusableOptions = {},\n) {\n const itemRoot = scopeRoot.querySelector<HTMLElement>(\n `[${TOOLBAR_NEXT_ITEM_ATTR}=\"${itemId}\"]`,\n );\n\n if (!itemRoot) {\n return null;\n }\n\n const itemElements = getToolbarNextItemFocusableElements(\n itemRoot,\n scopeRoot,\n options,\n );\n\n return (\n itemElements[Math.min(controlIndex, itemElements.length - 1)] ??\n itemElements[0] ??\n null\n );\n}\n\nfunction getToolbarNextOverflowTriggerElement(\n scopeRoot: HTMLElement,\n groupKey: string,\n) {\n return scopeRoot.querySelector<HTMLElement>(\n `[${TOOLBAR_NEXT_OVERFLOW_TRIGGER_ATTR}][${TOOLBAR_NEXT_GROUP_KEY_ATTR}=\"${groupKey}\"]`,\n );\n}\n\nfunction getToolbarNextFocusFallback(\n scopeRoot: HTMLElement,\n rememberedIndex: number,\n options: ToolbarNextFocusableOptions = {},\n) {\n const focusableElements = getToolbarNextScopeFocusableElements(\n scopeRoot,\n options,\n );\n\n if (focusableElements.length === 0) {\n return null;\n }\n\n return (\n focusableElements[\n Math.max(0, Math.min(rememberedIndex, focusableElements.length - 1))\n ] ?? focusableElements[0]\n );\n}\n\nfunction getVisualDelta(scopeRoot: HTMLElement, key: string) {\n const direction =\n scopeRoot.ownerDocument.defaultView?.getComputedStyle(scopeRoot).direction;\n\n if (key === \"ArrowRight\") {\n return direction === \"rtl\" ? -1 : 1;\n }\n\n return direction === \"rtl\" ? 1 : -1;\n}\n\nfunction isToggleGroupBoundary(\n currentIndex: number,\n length: number,\n visualDelta: number,\n) {\n if (visualDelta > 0) {\n return currentIndex === length - 1;\n }\n\n return currentIndex === 0;\n}\n\nfunction getToggleGroupButtons(target: HTMLElement) {\n const toggleGroup = target.closest<HTMLElement>(\".saltToggleButtonGroup\");\n\n if (!toggleGroup || target.tagName !== \"BUTTON\") {\n return [];\n }\n\n return Array.from(toggleGroup.querySelectorAll<HTMLElement>(\"button\")).filter(\n (button) =>\n isToolbarNextFocusable(button, { includeTabIndexMinusOne: true }),\n );\n}\n\nfunction isToolbarNextToggleGroupButton(target: HTMLElement) {\n return (\n target.tagName === \"BUTTON\" &&\n target.closest(\".saltToggleButtonGroup\") != null &&\n isToolbarNextFocusable(target, { includeTabIndexMinusOne: true })\n );\n}\n\nfunction getToolbarNextKeyboardPolicy(\n target: HTMLElement,\n): ToolbarNextKeyboardPolicy {\n if (\n target.isContentEditable ||\n isPlainTextInput(target) ||\n isComboBoxInput(target)\n ) {\n return {\n preserveHorizontalArrows: true,\n preserveNativeTab: true,\n };\n }\n\n if (isDropdownControl(target)) {\n return {\n preserveHorizontalArrows: false,\n preserveNativeTab: false,\n };\n }\n\n if (\n isSelectLikeControl(target) ||\n target.closest(\".saltDatePickerTrigger\") != null\n ) {\n return {\n preserveHorizontalArrows: false,\n preserveNativeTab: true,\n };\n }\n\n return {\n preserveHorizontalArrows: false,\n preserveNativeTab: false,\n };\n}\n\nfunction isComboBoxInput(target: HTMLElement) {\n return (\n target.tagName === \"INPUT\" &&\n target.closest('[role=\"combobox\"], .saltComboBox') != null\n );\n}\n\nfunction isDropdownControl(target: HTMLElement) {\n return target.closest(\".saltDropdown\") != null;\n}\n\nfunction isSelectLikeControl(target: HTMLElement) {\n return (\n target.tagName === \"SELECT\" ||\n target.closest('[role=\"combobox\"], .saltComboBox, .saltDropdown') != null\n );\n}\n\nfunction isPlainTextInput(target: HTMLElement) {\n if (target.tagName === \"TEXTAREA\") {\n return true;\n }\n\n if (target.tagName !== \"INPUT\") {\n return false;\n }\n\n return textEntryInputTypes.has(\n (target as HTMLInputElement).type.toLowerCase(),\n );\n}\n\nfunction isNativeDisabledFormControl(target: HTMLElement) {\n return (\n \"disabled\" in target &&\n (target as HTMLButtonElement | HTMLInputElement).disabled\n );\n}\n\nexport function isToolbarNextFocusable(\n target: HTMLElement,\n { includeTabIndexMinusOne = false }: ToolbarNextFocusableOptions = {},\n) {\n if (isNativeDisabledFormControl(target)) {\n return false;\n }\n\n if (target.getAttribute(\"aria-hidden\") === \"true\") {\n return false;\n }\n\n if (!includeTabIndexMinusOne && target.getAttribute(\"tabindex\") === \"-1\") {\n return false;\n }\n\n if (target.hidden) {\n return false;\n }\n\n const win = target.ownerDocument.defaultView;\n\n if (!win) {\n return false;\n }\n\n const styles = win.getComputedStyle(target);\n\n if (styles.display === \"none\" || styles.visibility === \"hidden\") {\n return false;\n }\n\n return target.getClientRects().length > 0;\n}\n\nexport function focusToolbarNextElement(\n target: HTMLElement | null | undefined,\n) {\n if (target?.isConnected) {\n target.focus({ preventScroll: true });\n }\n}\n\nexport function scheduleToolbarNextFocus(\n target: HTMLElement | null | undefined,\n targetWindow = target?.ownerDocument.defaultView,\n) {\n if (!target) {\n return () => undefined;\n }\n\n if (targetWindow?.requestAnimationFrame) {\n const frame = targetWindow.requestAnimationFrame(() => {\n focusToolbarNextElement(target);\n });\n\n return () => {\n targetWindow.cancelAnimationFrame(frame);\n };\n }\n\n queueMicrotask(() => {\n focusToolbarNextElement(target);\n });\n\n return () => undefined;\n}\n\nexport function getDocumentFocusableElements(ownerDocument: Document) {\n return Array.from(\n ownerDocument.querySelectorAll<HTMLElement>(toolbarNextFocusableSelector),\n ).filter((element) => isToolbarNextFocusable(element));\n}\n"],"names":["currentIndex"],"mappings":"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"}
@@ -0,0 +1,211 @@
1
+ import { Divider, getRefFromChildren } from '@salt-ds/core';
2
+ import { Children, isValidElement, Fragment } from 'react';
3
+ import { ToolbarContentNext } from './ToolbarContentNext.js';
4
+ import { TooltrayNext } from './TooltrayNext.js';
5
+
6
+ function buildContentOverflowRenderSlots(items, overflowedIds, activeNamedGroupKeys) {
7
+ const triggerGroupByItemId = /* @__PURE__ */ new Map();
8
+ for (const groupKey of activeNamedGroupKeys) {
9
+ const anchorItem = items.find((item) => {
10
+ return overflowedIds.has(item.id) && item.overflowGroupKey === groupKey;
11
+ });
12
+ if (anchorItem) {
13
+ triggerGroupByItemId.set(anchorItem.id, groupKey);
14
+ }
15
+ }
16
+ const slots = [];
17
+ let hasSurvivingPredecessor = false;
18
+ for (const item of items) {
19
+ const overflowed = overflowedIds.has(item.id);
20
+ const triggerGroupKey = triggerGroupByItemId.get(item.id);
21
+ const survives = !overflowed || triggerGroupKey != null;
22
+ if (overflowed && !triggerGroupKey) {
23
+ continue;
24
+ }
25
+ slots.push({
26
+ item,
27
+ overflowed,
28
+ showLeadingDecorations: item.leadingDecorations.length > 0 && hasSurvivingPredecessor && survives,
29
+ showTrailingDecorations: !overflowed && item.trailingDecorations.length > 0,
30
+ triggerGroupKey
31
+ });
32
+ if (survives) {
33
+ hasSurvivingPredecessor = true;
34
+ }
35
+ }
36
+ return slots;
37
+ }
38
+ function flattenToolbarChildren(children) {
39
+ const flattened = [];
40
+ Children.forEach(children, (child) => {
41
+ if (child == null || typeof child === "boolean") {
42
+ return;
43
+ }
44
+ if (isValidElement(child) && child.type === Fragment) {
45
+ flattened.push(...flattenToolbarChildren(child.props.children));
46
+ return;
47
+ }
48
+ flattened.push(child);
49
+ });
50
+ return flattened;
51
+ }
52
+ function isToolbarContentNextElement(child) {
53
+ return isValidElement(child) && child.type === ToolbarContentNext;
54
+ }
55
+ function isTooltrayElement(child) {
56
+ return isValidElement(child) && child.type === TooltrayNext;
57
+ }
58
+ function isDividerElement(child) {
59
+ return isValidElement(child) && child.type === Divider;
60
+ }
61
+ function buildItemId(contentKey, element, order) {
62
+ const elementKey = element.key != null ? String(element.key) : `tray-${order}`;
63
+ return `${contentKey}-${elementKey}-${order}`;
64
+ }
65
+ function buildOverflowGroupKey(contentKey, overflowGroup) {
66
+ return overflowGroup === "shared" ? "shared" : `${contentKey}:${overflowGroup}`;
67
+ }
68
+ function normalizeContentItems(children, contentKey) {
69
+ var _a;
70
+ const flattenedChildren = flattenToolbarChildren(children);
71
+ const items = [];
72
+ let pendingLeadingDecorations = [];
73
+ for (const child of flattenedChildren) {
74
+ if (isDividerElement(child)) {
75
+ pendingLeadingDecorations.push(child);
76
+ continue;
77
+ }
78
+ if (!isTooltrayElement(child)) {
79
+ return null;
80
+ }
81
+ const {
82
+ align = "start",
83
+ overflowGroup = "shared",
84
+ overflowLabel,
85
+ overflowMode = "independent",
86
+ overflowPriority = 0
87
+ } = child.props;
88
+ const order = items.length;
89
+ items.push({
90
+ align,
91
+ element: child,
92
+ id: buildItemId(contentKey, child, order),
93
+ leadingDecorations: pendingLeadingDecorations,
94
+ order,
95
+ overflowGroup,
96
+ overflowGroupKey: buildOverflowGroupKey(contentKey, overflowGroup),
97
+ overflowLabel,
98
+ overflowMode,
99
+ overflowPriority,
100
+ contentKey,
101
+ trailingDecorations: []
102
+ });
103
+ pendingLeadingDecorations = [];
104
+ }
105
+ if (pendingLeadingDecorations.length > 0 && items.length > 0) {
106
+ (_a = items[items.length - 1]) == null ? void 0 : _a.trailingDecorations.push(
107
+ ...pendingLeadingDecorations
108
+ );
109
+ }
110
+ return items;
111
+ }
112
+ function normalizeExplicitContent(children) {
113
+ const content = [];
114
+ for (const [index, child] of children.entries()) {
115
+ if (!isToolbarContentNextElement(child)) {
116
+ continue;
117
+ }
118
+ const {
119
+ children: contentChildren,
120
+ position,
121
+ ...contentProps
122
+ } = child.props;
123
+ const contentKey = child.key != null ? String(child.key) : `${position}-content-${index}`;
124
+ const items = normalizeContentItems(contentChildren, contentKey);
125
+ if (items == null) {
126
+ return null;
127
+ }
128
+ content.push({
129
+ implicit: false,
130
+ items,
131
+ key: contentKey,
132
+ position,
133
+ props: contentProps,
134
+ ref: getRefFromChildren(child)
135
+ });
136
+ }
137
+ return content;
138
+ }
139
+ function normalizeFlatChildren(children) {
140
+ const buckets = {
141
+ start: [],
142
+ center: [],
143
+ end: []
144
+ };
145
+ let currentPosition = "start";
146
+ for (const child of children) {
147
+ if (isTooltrayElement(child)) {
148
+ currentPosition = child.props.align ?? "start";
149
+ buckets[currentPosition].push(child);
150
+ continue;
151
+ }
152
+ if (isDividerElement(child)) {
153
+ buckets[currentPosition].push(child);
154
+ continue;
155
+ }
156
+ return null;
157
+ }
158
+ return Object.keys(buckets).reduce((content, position) => {
159
+ const contentKey = `${position}-implicit`;
160
+ const contentItems = normalizeContentItems(buckets[position], contentKey);
161
+ if (contentItems == null || contentItems.length === 0) {
162
+ return content;
163
+ }
164
+ content.push({
165
+ implicit: true,
166
+ items: contentItems,
167
+ key: contentKey,
168
+ position,
169
+ props: {},
170
+ ref: null
171
+ });
172
+ return content;
173
+ }, []);
174
+ }
175
+ function normalizeToolbarChildren(children) {
176
+ const flattenedChildren = flattenToolbarChildren(children);
177
+ const hasContentChildren = flattenedChildren.some(
178
+ isToolbarContentNextElement
179
+ );
180
+ const hasOnlyContent = hasContentChildren && flattenedChildren.every(isToolbarContentNextElement);
181
+ const hasOnlyFlatChildren = flattenedChildren.every(
182
+ (child) => isTooltrayElement(child) || isDividerElement(child)
183
+ );
184
+ if (hasOnlyContent) {
185
+ const content = normalizeExplicitContent(flattenedChildren);
186
+ if (content == null) {
187
+ return { mode: "invalid", content: [] };
188
+ }
189
+ return {
190
+ mode: "explicit",
191
+ content
192
+ };
193
+ }
194
+ if (hasOnlyFlatChildren) {
195
+ const content = normalizeFlatChildren(flattenedChildren);
196
+ if (content == null) {
197
+ return { mode: "invalid", content: [] };
198
+ }
199
+ return {
200
+ mode: "flat",
201
+ content
202
+ };
203
+ }
204
+ return {
205
+ mode: "invalid",
206
+ content: []
207
+ };
208
+ }
209
+
210
+ export { buildContentOverflowRenderSlots, flattenToolbarChildren, normalizeToolbarChildren };
211
+ //# sourceMappingURL=toolbarNextUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolbarNextUtils.js","sources":["../src/toolbar-next/toolbarNextUtils.ts"],"sourcesContent":["import { Divider, getRefFromChildren } from \"@salt-ds/core\";\nimport {\n Children,\n Fragment,\n isValidElement,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\n\nimport {\n ToolbarContentNext,\n type ToolbarContentNextPosition,\n type ToolbarContentNextProps,\n} from \"./ToolbarContentNext\";\nimport {\n TooltrayNext,\n type TooltrayNextOverflowMode,\n type TooltrayNextProps,\n} from \"./TooltrayNext\";\n\nexport type ToolbarNextMode = \"explicit\" | \"flat\" | \"invalid\";\n\ntype ToolbarNextChild = Exclude<ReactNode, boolean | null | undefined>;\n\nexport interface ToolbarNextOverflowItem {\n align: NonNullable<TooltrayNextProps[\"align\"]>;\n element: ReactElement<TooltrayNextProps>;\n id: string;\n leadingDecorations: ReactElement[];\n order: number;\n overflowGroup: string;\n overflowGroupKey: string;\n overflowLabel?: string;\n overflowMode: TooltrayNextOverflowMode;\n overflowPriority: number;\n contentKey: string;\n trailingDecorations: ReactElement[];\n}\n\nexport interface ToolbarNextOverflowRenderSlot {\n item: ToolbarNextOverflowItem;\n overflowed: boolean;\n showLeadingDecorations: boolean;\n showTrailingDecorations: boolean;\n triggerGroupKey?: string;\n}\n\nexport interface ToolbarNextContentModel {\n implicit: boolean;\n items: ToolbarNextOverflowItem[];\n key: string;\n position: ToolbarContentNextPosition;\n props: Omit<ToolbarContentNextProps, \"children\" | \"position\">;\n ref: Ref<HTMLDivElement> | null;\n}\n\nexport interface ToolbarNextModel {\n mode: ToolbarNextMode;\n content: ToolbarNextContentModel[];\n}\n\nexport function buildContentOverflowRenderSlots(\n items: ToolbarNextOverflowItem[],\n overflowedIds: Set<string>,\n activeNamedGroupKeys: Set<string>,\n) {\n const triggerGroupByItemId = new Map<string, string>();\n\n for (const groupKey of activeNamedGroupKeys) {\n const anchorItem = items.find((item) => {\n return overflowedIds.has(item.id) && item.overflowGroupKey === groupKey;\n });\n\n if (anchorItem) {\n triggerGroupByItemId.set(anchorItem.id, groupKey);\n }\n }\n\n const slots: ToolbarNextOverflowRenderSlot[] = [];\n let hasSurvivingPredecessor = false;\n\n for (const item of items) {\n const overflowed = overflowedIds.has(item.id);\n const triggerGroupKey = triggerGroupByItemId.get(item.id);\n const survives = !overflowed || triggerGroupKey != null;\n\n if (overflowed && !triggerGroupKey) {\n continue;\n }\n\n slots.push({\n item,\n overflowed,\n showLeadingDecorations:\n item.leadingDecorations.length > 0 &&\n hasSurvivingPredecessor &&\n survives,\n showTrailingDecorations:\n !overflowed && item.trailingDecorations.length > 0,\n triggerGroupKey,\n });\n\n if (survives) {\n hasSurvivingPredecessor = true;\n }\n }\n\n return slots;\n}\n\nexport function flattenToolbarChildren(\n children: ReactNode,\n): ToolbarNextChild[] {\n const flattened: ToolbarNextChild[] = [];\n\n Children.forEach(children, (child) => {\n if (child == null || typeof child === \"boolean\") {\n return;\n }\n\n if (isValidElement(child) && child.type === Fragment) {\n flattened.push(...flattenToolbarChildren(child.props.children));\n return;\n }\n\n flattened.push(child);\n });\n\n return flattened;\n}\n\nfunction isToolbarContentNextElement(\n child: ToolbarNextChild,\n): child is ReactElement<ToolbarContentNextProps> {\n return isValidElement(child) && child.type === ToolbarContentNext;\n}\n\nfunction isTooltrayElement(\n child: ToolbarNextChild,\n): child is ReactElement<TooltrayNextProps> {\n return isValidElement(child) && child.type === TooltrayNext;\n}\n\nfunction isDividerElement(child: ToolbarNextChild): child is ReactElement {\n return isValidElement(child) && child.type === Divider;\n}\n\nfunction buildItemId(\n contentKey: string,\n element: ReactElement<TooltrayNextProps>,\n order: number,\n) {\n const elementKey =\n element.key != null ? String(element.key) : `tray-${order}`;\n return `${contentKey}-${elementKey}-${order}`;\n}\n\nfunction buildOverflowGroupKey(contentKey: string, overflowGroup: string) {\n return overflowGroup === \"shared\"\n ? \"shared\"\n : `${contentKey}:${overflowGroup}`;\n}\n\nfunction normalizeContentItems(\n children: ReactNode,\n contentKey: string,\n): ToolbarNextOverflowItem[] | null {\n const flattenedChildren = flattenToolbarChildren(children);\n const items: ToolbarNextOverflowItem[] = [];\n let pendingLeadingDecorations: ReactElement[] = [];\n\n for (const child of flattenedChildren) {\n if (isDividerElement(child)) {\n pendingLeadingDecorations.push(child);\n continue;\n }\n\n if (!isTooltrayElement(child)) {\n return null;\n }\n\n const {\n align = \"start\",\n overflowGroup = \"shared\",\n overflowLabel,\n overflowMode = \"independent\",\n overflowPriority = 0,\n } = child.props;\n const order = items.length;\n\n items.push({\n align,\n element: child,\n id: buildItemId(contentKey, child, order),\n leadingDecorations: pendingLeadingDecorations,\n order,\n overflowGroup,\n overflowGroupKey: buildOverflowGroupKey(contentKey, overflowGroup),\n overflowLabel,\n overflowMode,\n overflowPriority,\n contentKey,\n trailingDecorations: [],\n });\n\n pendingLeadingDecorations = [];\n }\n\n if (pendingLeadingDecorations.length > 0 && items.length > 0) {\n items[items.length - 1]?.trailingDecorations.push(\n ...pendingLeadingDecorations,\n );\n }\n\n return items;\n}\n\nfunction normalizeExplicitContent(\n children: ToolbarNextChild[],\n): ToolbarNextContentModel[] | null {\n const content: ToolbarNextContentModel[] = [];\n\n for (const [index, child] of children.entries()) {\n if (!isToolbarContentNextElement(child)) {\n continue;\n }\n\n const {\n children: contentChildren,\n position,\n ...contentProps\n } = child.props;\n const contentKey =\n child.key != null ? String(child.key) : `${position}-content-${index}`;\n const items = normalizeContentItems(contentChildren, contentKey);\n\n if (items == null) {\n return null;\n }\n\n content.push({\n implicit: false,\n items,\n key: contentKey,\n position,\n props: contentProps,\n ref: getRefFromChildren(child),\n });\n }\n\n return content;\n}\n\nfunction normalizeFlatChildren(children: ToolbarNextChild[]) {\n const buckets: Record<ToolbarContentNextPosition, ToolbarNextChild[]> = {\n start: [],\n center: [],\n end: [],\n };\n let currentPosition: ToolbarContentNextPosition = \"start\";\n\n for (const child of children) {\n if (isTooltrayElement(child)) {\n currentPosition = child.props.align ?? \"start\";\n buckets[currentPosition].push(child);\n continue;\n }\n\n if (isDividerElement(child)) {\n buckets[currentPosition].push(child);\n continue;\n }\n\n return null;\n }\n\n return (Object.keys(buckets) as ToolbarContentNextPosition[]).reduce<\n ToolbarNextContentModel[]\n >((content, position) => {\n const contentKey = `${position}-implicit`;\n const contentItems = normalizeContentItems(buckets[position], contentKey);\n\n if (contentItems == null || contentItems.length === 0) {\n return content;\n }\n\n content.push({\n implicit: true,\n items: contentItems,\n key: contentKey,\n position,\n props: {},\n ref: null,\n });\n\n return content;\n }, []);\n}\n\nexport function normalizeToolbarChildren(\n children: ReactNode,\n): ToolbarNextModel {\n const flattenedChildren = flattenToolbarChildren(children);\n const hasContentChildren = flattenedChildren.some(\n isToolbarContentNextElement,\n );\n const hasOnlyContent =\n hasContentChildren && flattenedChildren.every(isToolbarContentNextElement);\n const hasOnlyFlatChildren = flattenedChildren.every(\n (child) => isTooltrayElement(child) || isDividerElement(child),\n );\n\n if (hasOnlyContent) {\n const content = normalizeExplicitContent(flattenedChildren);\n\n if (content == null) {\n return { mode: \"invalid\", content: [] };\n }\n\n return {\n mode: \"explicit\",\n content,\n };\n }\n\n if (hasOnlyFlatChildren) {\n const content = normalizeFlatChildren(flattenedChildren);\n\n if (content == null) {\n return { mode: \"invalid\", content: [] };\n }\n\n return {\n mode: \"flat\",\n content,\n };\n }\n\n return {\n mode: \"invalid\",\n content: [],\n };\n}\n"],"names":[],"mappings":"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"}