@salt-ds/lab 1.0.0-alpha.92 → 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 (204) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/css/salt-lab.css +166 -249
  3. package/dist-cjs/index.js +6 -24
  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 -12
  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 -2
  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/side-panel/SidePanel.css.js +0 -6
  72. package/dist-cjs/side-panel/SidePanel.css.js.map +0 -1
  73. package/dist-cjs/side-panel/SidePanel.js +0 -197
  74. package/dist-cjs/side-panel/SidePanel.js.map +0 -1
  75. package/dist-cjs/side-panel/SidePanelCloseButton.js +0 -38
  76. package/dist-cjs/side-panel/SidePanelCloseButton.js.map +0 -1
  77. package/dist-cjs/side-panel/SidePanelContent.css.js +0 -6
  78. package/dist-cjs/side-panel/SidePanelContent.css.js.map +0 -1
  79. package/dist-cjs/side-panel/SidePanelContent.js +0 -66
  80. package/dist-cjs/side-panel/SidePanelContent.js.map +0 -1
  81. package/dist-cjs/side-panel/SidePanelHeader.css.js +0 -6
  82. package/dist-cjs/side-panel/SidePanelHeader.css.js.map +0 -1
  83. package/dist-cjs/side-panel/SidePanelHeader.js +0 -26
  84. package/dist-cjs/side-panel/SidePanelHeader.js.map +0 -1
  85. package/dist-cjs/side-panel/SidePanelProvider.js +0 -78
  86. package/dist-cjs/side-panel/SidePanelProvider.js.map +0 -1
  87. package/dist-cjs/side-panel/SidePanelTitle.css.js +0 -6
  88. package/dist-cjs/side-panel/SidePanelTitle.css.js.map +0 -1
  89. package/dist-cjs/side-panel/SidePanelTitle.js +0 -48
  90. package/dist-cjs/side-panel/SidePanelTitle.js.map +0 -1
  91. package/dist-cjs/side-panel/SidePanelTrigger.js +0 -37
  92. package/dist-cjs/side-panel/SidePanelTrigger.js.map +0 -1
  93. package/dist-cjs/side-panel/internal/SidePanelContext.js +0 -32
  94. package/dist-cjs/side-panel/internal/SidePanelContext.js.map +0 -1
  95. package/dist-cjs/side-panel/internal/useIsScrollable.js +0 -50
  96. package/dist-cjs/side-panel/internal/useIsScrollable.js.map +0 -1
  97. package/dist-cjs/side-panel/internal/useSidePanelTabOrder.js +0 -214
  98. package/dist-cjs/side-panel/internal/useSidePanelTabOrder.js.map +0 -1
  99. package/dist-cjs/side-panel/useSidePanel.js +0 -43
  100. package/dist-cjs/side-panel/useSidePanel.js.map +0 -1
  101. package/dist-cjs/tree/Tree.css.js +0 -6
  102. package/dist-cjs/tree/Tree.css.js.map +0 -1
  103. package/dist-cjs/tree/Tree.js +0 -300
  104. package/dist-cjs/tree/Tree.js.map +0 -1
  105. package/dist-cjs/tree/TreeContext.js +0 -31
  106. package/dist-cjs/tree/TreeContext.js.map +0 -1
  107. package/dist-cjs/tree/TreeNode.css.js +0 -6
  108. package/dist-cjs/tree/TreeNode.css.js.map +0 -1
  109. package/dist-cjs/tree/TreeNode.js +0 -103
  110. package/dist-cjs/tree/TreeNode.js.map +0 -1
  111. package/dist-cjs/tree/TreeNodeExpansionIcon.css.js +0 -6
  112. package/dist-cjs/tree/TreeNodeExpansionIcon.css.js.map +0 -1
  113. package/dist-cjs/tree/TreeNodeExpansionIcon.js +0 -62
  114. package/dist-cjs/tree/TreeNodeExpansionIcon.js.map +0 -1
  115. package/dist-cjs/tree/TreeNodeLabel.css.js +0 -6
  116. package/dist-cjs/tree/TreeNodeLabel.css.js.map +0 -1
  117. package/dist-cjs/tree/TreeNodeLabel.js +0 -26
  118. package/dist-cjs/tree/TreeNodeLabel.js.map +0 -1
  119. package/dist-cjs/tree/TreeNodeTrigger.css.js +0 -6
  120. package/dist-cjs/tree/TreeNodeTrigger.css.js.map +0 -1
  121. package/dist-cjs/tree/TreeNodeTrigger.js +0 -153
  122. package/dist-cjs/tree/TreeNodeTrigger.js.map +0 -1
  123. package/dist-cjs/tree/treeModel.js +0 -61
  124. package/dist-cjs/tree/treeModel.js.map +0 -1
  125. package/dist-cjs/tree/useTree.js +0 -337
  126. package/dist-cjs/tree/useTree.js.map +0 -1
  127. package/dist-es/side-panel/SidePanel.css.js +0 -4
  128. package/dist-es/side-panel/SidePanel.css.js.map +0 -1
  129. package/dist-es/side-panel/SidePanel.js +0 -195
  130. package/dist-es/side-panel/SidePanel.js.map +0 -1
  131. package/dist-es/side-panel/SidePanelCloseButton.js +0 -36
  132. package/dist-es/side-panel/SidePanelCloseButton.js.map +0 -1
  133. package/dist-es/side-panel/SidePanelContent.css.js +0 -4
  134. package/dist-es/side-panel/SidePanelContent.css.js.map +0 -1
  135. package/dist-es/side-panel/SidePanelContent.js +0 -64
  136. package/dist-es/side-panel/SidePanelContent.js.map +0 -1
  137. package/dist-es/side-panel/SidePanelHeader.css.js +0 -4
  138. package/dist-es/side-panel/SidePanelHeader.css.js.map +0 -1
  139. package/dist-es/side-panel/SidePanelHeader.js +0 -24
  140. package/dist-es/side-panel/SidePanelHeader.js.map +0 -1
  141. package/dist-es/side-panel/SidePanelProvider.js +0 -76
  142. package/dist-es/side-panel/SidePanelProvider.js.map +0 -1
  143. package/dist-es/side-panel/SidePanelTitle.css.js +0 -4
  144. package/dist-es/side-panel/SidePanelTitle.css.js.map +0 -1
  145. package/dist-es/side-panel/SidePanelTitle.js +0 -46
  146. package/dist-es/side-panel/SidePanelTitle.js.map +0 -1
  147. package/dist-es/side-panel/SidePanelTrigger.js +0 -35
  148. package/dist-es/side-panel/SidePanelTrigger.js.map +0 -1
  149. package/dist-es/side-panel/internal/SidePanelContext.js +0 -29
  150. package/dist-es/side-panel/internal/SidePanelContext.js.map +0 -1
  151. package/dist-es/side-panel/internal/useIsScrollable.js +0 -48
  152. package/dist-es/side-panel/internal/useIsScrollable.js.map +0 -1
  153. package/dist-es/side-panel/internal/useSidePanelTabOrder.js +0 -212
  154. package/dist-es/side-panel/internal/useSidePanelTabOrder.js.map +0 -1
  155. package/dist-es/side-panel/useSidePanel.js +0 -41
  156. package/dist-es/side-panel/useSidePanel.js.map +0 -1
  157. package/dist-es/tree/Tree.css.js +0 -4
  158. package/dist-es/tree/Tree.css.js.map +0 -1
  159. package/dist-es/tree/Tree.js +0 -298
  160. package/dist-es/tree/Tree.js.map +0 -1
  161. package/dist-es/tree/TreeContext.js +0 -26
  162. package/dist-es/tree/TreeContext.js.map +0 -1
  163. package/dist-es/tree/TreeNode.css.js +0 -4
  164. package/dist-es/tree/TreeNode.css.js.map +0 -1
  165. package/dist-es/tree/TreeNode.js +0 -101
  166. package/dist-es/tree/TreeNode.js.map +0 -1
  167. package/dist-es/tree/TreeNodeExpansionIcon.css.js +0 -4
  168. package/dist-es/tree/TreeNodeExpansionIcon.css.js.map +0 -1
  169. package/dist-es/tree/TreeNodeExpansionIcon.js +0 -60
  170. package/dist-es/tree/TreeNodeExpansionIcon.js.map +0 -1
  171. package/dist-es/tree/TreeNodeLabel.css.js +0 -4
  172. package/dist-es/tree/TreeNodeLabel.css.js.map +0 -1
  173. package/dist-es/tree/TreeNodeLabel.js +0 -24
  174. package/dist-es/tree/TreeNodeLabel.js.map +0 -1
  175. package/dist-es/tree/TreeNodeTrigger.css.js +0 -4
  176. package/dist-es/tree/TreeNodeTrigger.css.js.map +0 -1
  177. package/dist-es/tree/TreeNodeTrigger.js +0 -151
  178. package/dist-es/tree/TreeNodeTrigger.js.map +0 -1
  179. package/dist-es/tree/treeModel.js +0 -57
  180. package/dist-es/tree/treeModel.js.map +0 -1
  181. package/dist-es/tree/useTree.js +0 -335
  182. package/dist-es/tree/useTree.js.map +0 -1
  183. package/dist-types/side-panel/SidePanel.d.ts +0 -26
  184. package/dist-types/side-panel/SidePanelCloseButton.d.ts +0 -2
  185. package/dist-types/side-panel/SidePanelContent.d.ts +0 -5
  186. package/dist-types/side-panel/SidePanelHeader.d.ts +0 -5
  187. package/dist-types/side-panel/SidePanelProvider.d.ts +0 -20
  188. package/dist-types/side-panel/SidePanelTitle.d.ts +0 -3
  189. package/dist-types/side-panel/SidePanelTrigger.d.ts +0 -3
  190. package/dist-types/side-panel/index.d.ts +0 -8
  191. package/dist-types/side-panel/internal/SidePanelContext.d.ts +0 -52
  192. package/dist-types/side-panel/internal/index.d.ts +0 -3
  193. package/dist-types/side-panel/internal/useIsScrollable.d.ts +0 -2
  194. package/dist-types/side-panel/internal/useSidePanelTabOrder.d.ts +0 -7
  195. package/dist-types/side-panel/useSidePanel.d.ts +0 -58
  196. package/dist-types/tree/Tree.d.ts +0 -36
  197. package/dist-types/tree/TreeContext.d.ts +0 -77
  198. package/dist-types/tree/TreeNode.d.ts +0 -25
  199. package/dist-types/tree/TreeNodeExpansionIcon.d.ts +0 -4
  200. package/dist-types/tree/TreeNodeLabel.d.ts +0 -4
  201. package/dist-types/tree/TreeNodeTrigger.d.ts +0 -8
  202. package/dist-types/tree/index.d.ts +0 -4
  203. package/dist-types/tree/treeModel.d.ts +0 -24
  204. package/dist-types/tree/useTree.d.ts +0 -68
@@ -0,0 +1,700 @@
1
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
+ import { offset, size, flip, shift, useInteractions, useClick, useDismiss } from '@floating-ui/react';
3
+ import { makePrefixer, useIcon, useForkRef, useId, useFloatingUI, useFloatingComponent, useIsomorphicLayoutEffect, Button } from '@salt-ds/core';
4
+ import { useComponentCssInjection } from '@salt-ds/styles';
5
+ import { useWindow } from '@salt-ds/window';
6
+ import { clsx } from 'clsx';
7
+ import { compute } from 'compute-scroll-into-view';
8
+ import { useState, useRef, useCallback, useEffect, cloneElement, Children, isValidElement } from 'react';
9
+ import { createPortal } from 'react-dom';
10
+ import { ToolbarContentNext } from './ToolbarContentNext.js';
11
+ import css_248z from './ToolbarNextOverflow.css.js';
12
+ import { useToolbarNextOverflowFloatingBoundary, isTargetInsideOverflowBoundary, getToolbarNextOverflowBoundaryKey, ToolbarNextOverflowFloatingComponentProvider } from './ToolbarNextOverflowFloatingBoundary.js';
13
+ import { scheduleToolbarNextFocus, shouldToolbarNextPreserveNativeTab, getDocumentFocusableElements, TOOLBAR_NEXT_SCOPE_ROOT_ATTR, getToolbarNextTabMoveTarget, getToolbarNextFocusMemory, TOOLBAR_NEXT_OVERFLOW_TRIGGER_ATTR, TOOLBAR_NEXT_GROUP_KEY_ATTR, toolbarNextFocusableSelector, TOOLBAR_NEXT_ITEM_ATTR, getToolbarNextScopeFocusableElements } from './toolbarNextKeyboardUtils.js';
14
+ import { buildContentOverflowRenderSlots } from './toolbarNextUtils.js';
15
+ import { useToolbarNextKeyboardNavigation } from './useToolbarNextKeyboardNavigation.js';
16
+
17
+ const withBaseName = makePrefixer("saltToolbarNextOverflow");
18
+ const toolbarNextStatefulFocusRootSelector = [
19
+ ".saltDateInput-focused",
20
+ ".saltInput-focused"
21
+ ].join(", ");
22
+ const toolbarNextOverflowFocusScrollRootSelector = [
23
+ ".saltComboBox",
24
+ ".saltDateInput",
25
+ ".saltDropdown",
26
+ ".saltInput",
27
+ ".saltSwitch"
28
+ ].join(", ");
29
+ function createToolbarNextFocusEvent(eventName, target, relatedTarget) {
30
+ var _a;
31
+ const FocusEventCtor = (_a = target.ownerDocument.defaultView) == null ? void 0 : _a.FocusEvent;
32
+ const eventInit = {
33
+ bubbles: eventName === "focusout",
34
+ relatedTarget
35
+ };
36
+ return FocusEventCtor ? new FocusEventCtor(eventName, eventInit) : new Event(eventName, eventInit);
37
+ }
38
+ function notifyToolbarNextReparentedFocusLoss(mountNode) {
39
+ const activeElement = mountNode.ownerDocument.activeElement;
40
+ if (mountNode.contains(activeElement)) {
41
+ return;
42
+ }
43
+ const staleFocusTargets = Array.from(
44
+ mountNode.querySelectorAll(
45
+ toolbarNextStatefulFocusRootSelector
46
+ )
47
+ ).map(
48
+ (root) => root.querySelector(toolbarNextFocusableSelector)
49
+ ).filter((target) => target != null);
50
+ for (const target of staleFocusTargets) {
51
+ const relatedTarget = activeElement instanceof Element ? activeElement : null;
52
+ target.dispatchEvent(
53
+ createToolbarNextFocusEvent("blur", target, relatedTarget)
54
+ );
55
+ target.dispatchEvent(
56
+ createToolbarNextFocusEvent("focusout", target, relatedTarget)
57
+ );
58
+ }
59
+ }
60
+ function getToolbarNextOverflowFocusScrollTarget(target) {
61
+ const itemRoot = target.closest(`[${TOOLBAR_NEXT_ITEM_ATTR}]`);
62
+ const controlRoot = target.closest(
63
+ toolbarNextOverflowFocusScrollRootSelector
64
+ );
65
+ return controlRoot && (itemRoot == null ? void 0 : itemRoot.contains(controlRoot)) ? controlRoot : target;
66
+ }
67
+ function getToolbarNextOverflowPanelInlinePadding(target) {
68
+ var _a;
69
+ const panelContent = target.closest(
70
+ `[${TOOLBAR_NEXT_SCOPE_ROOT_ATTR}]`
71
+ );
72
+ const styles = (_a = panelContent == null ? void 0 : panelContent.ownerDocument.defaultView) == null ? void 0 : _a.getComputedStyle(panelContent);
73
+ return {
74
+ left: Number.parseFloat((styles == null ? void 0 : styles.paddingLeft) ?? "0") || 0,
75
+ right: Number.parseFloat((styles == null ? void 0 : styles.paddingRight) ?? "0") || 0
76
+ };
77
+ }
78
+ function scrollToolbarNextOverflowTargetIntoView(panel, target) {
79
+ if (!panel || !panel.contains(target)) {
80
+ return;
81
+ }
82
+ const scrollTarget = getToolbarNextOverflowFocusScrollTarget(target);
83
+ const actions = compute(scrollTarget, {
84
+ block: "nearest",
85
+ boundary: panel,
86
+ inline: "nearest",
87
+ scrollMode: "if-needed"
88
+ });
89
+ for (const { el, left, top } of actions) {
90
+ if (el === panel) {
91
+ const targetRect = scrollTarget.getBoundingClientRect();
92
+ const panelRect = panel.getBoundingClientRect();
93
+ const viewportLeft = panelRect.left + panel.clientLeft;
94
+ const viewportRight = viewportLeft + panel.clientWidth;
95
+ const padding = getToolbarNextOverflowPanelInlinePadding(scrollTarget);
96
+ const nextLeft = targetRect.left < viewportLeft + padding.left ? left - padding.left : targetRect.right > viewportRight - padding.right ? left + padding.right : left;
97
+ el.scrollLeft = Math.max(0, nextLeft);
98
+ } else {
99
+ el.scrollLeft = left;
100
+ }
101
+ el.scrollTop = top;
102
+ }
103
+ }
104
+ function canSeedOverflowFocusMemory(focusMemory, group) {
105
+ return (focusMemory == null ? void 0 : focusMemory.type) === "item" && group.items.some((item) => item.id === focusMemory.itemId);
106
+ }
107
+ function ToolbarNextOverflowItemOwner({
108
+ host,
109
+ item
110
+ }) {
111
+ const targetWindow = useWindow();
112
+ const [mountNode, setMountNode] = useState(null);
113
+ const mainToolbarTabIndexMemoryRef = useRef(
114
+ /* @__PURE__ */ new WeakMap()
115
+ );
116
+ const lastOverflowBoundaryKeyRef = useRef(null);
117
+ const currentOverflowBoundaryKey = getToolbarNextOverflowBoundaryKey(host);
118
+ if (host) {
119
+ lastOverflowBoundaryKeyRef.current = currentOverflowBoundaryKey;
120
+ }
121
+ const boundaryKey = host ? currentOverflowBoundaryKey : lastOverflowBoundaryKeyRef.current;
122
+ useIsomorphicLayoutEffect(() => {
123
+ const nextMountNode = targetWindow == null ? void 0 : targetWindow.document.createElement("div");
124
+ if (!nextMountNode) {
125
+ return;
126
+ }
127
+ nextMountNode.className = withBaseName("contentHost");
128
+ setMountNode(nextMountNode);
129
+ return () => {
130
+ var _a;
131
+ (_a = nextMountNode.parentElement) == null ? void 0 : _a.removeChild(nextMountNode);
132
+ };
133
+ }, [targetWindow]);
134
+ useIsomorphicLayoutEffect(() => {
135
+ var _a, _b;
136
+ if (!mountNode) {
137
+ return;
138
+ }
139
+ if (host) {
140
+ if (mountNode.parentElement !== host) {
141
+ host.appendChild(mountNode);
142
+ notifyToolbarNextReparentedFocusLoss(mountNode);
143
+ }
144
+ const isMainToolbarHost = ((_a = host.closest(`[${TOOLBAR_NEXT_SCOPE_ROOT_ATTR}]`)) == null ? void 0 : _a.getAttribute(TOOLBAR_NEXT_SCOPE_ROOT_ATTR)) === "main";
145
+ if (isMainToolbarHost) {
146
+ const focusableElements = Array.from(
147
+ mountNode.querySelectorAll(toolbarNextFocusableSelector)
148
+ );
149
+ for (const element of focusableElements) {
150
+ const rememberedTabIndex = mainToolbarTabIndexMemoryRef.current.get(element);
151
+ if (rememberedTabIndex !== void 0) {
152
+ if (rememberedTabIndex == null) {
153
+ element.removeAttribute("tabindex");
154
+ } else {
155
+ element.setAttribute("tabindex", rememberedTabIndex);
156
+ }
157
+ }
158
+ }
159
+ for (const element of focusableElements) {
160
+ mainToolbarTabIndexMemoryRef.current.set(
161
+ element,
162
+ element.getAttribute("tabindex")
163
+ );
164
+ }
165
+ }
166
+ return;
167
+ }
168
+ notifyToolbarNextReparentedFocusLoss(mountNode);
169
+ (_b = mountNode.parentElement) == null ? void 0 : _b.removeChild(mountNode);
170
+ }, [host, mountNode]);
171
+ if (!mountNode) {
172
+ return null;
173
+ }
174
+ const clonedItem = cloneElement(
175
+ item.element,
176
+ {
177
+ [TOOLBAR_NEXT_GROUP_KEY_ATTR]: item.overflowGroupKey,
178
+ [TOOLBAR_NEXT_ITEM_ATTR]: item.id
179
+ }
180
+ );
181
+ const itemContent = /* @__PURE__ */ jsx(ToolbarNextOverflowFloatingComponentProvider, { boundaryKey, children: clonedItem });
182
+ return createPortal(itemContent, mountNode);
183
+ }
184
+ function ToolbarNextOverflowOwners({
185
+ hostNodes,
186
+ items
187
+ }) {
188
+ return /* @__PURE__ */ jsx(Fragment, { children: items.map((item) => /* @__PURE__ */ jsx(
189
+ ToolbarNextOverflowItemOwner,
190
+ {
191
+ host: hostNodes[item.id] ?? null,
192
+ item
193
+ },
194
+ item.id
195
+ )) });
196
+ }
197
+ function cloneDecorations(itemId, decorations, slot) {
198
+ return Children.toArray(decorations).flatMap((decoration) => {
199
+ if (!isValidElement(decoration)) {
200
+ return [];
201
+ }
202
+ return [
203
+ cloneElement(decoration, {
204
+ key: `${itemId}-${slot}-${String(
205
+ decoration.key ?? (typeof decoration.type === "string" ? decoration.type : "decoration")
206
+ )}`
207
+ })
208
+ ];
209
+ });
210
+ }
211
+ function ToolbarNextOverflowTriggerContent({
212
+ label,
213
+ named
214
+ }) {
215
+ const { OverflowIcon } = useIcon();
216
+ if (named) {
217
+ return /* @__PURE__ */ jsx(Fragment, { children: label });
218
+ }
219
+ return /* @__PURE__ */ jsx(OverflowIcon, { "aria-hidden": true });
220
+ }
221
+ function getOverflowTriggerLabel(group) {
222
+ return group.named ? `${group.label} overflow. Hidden controls.` : "Overflow. Hidden controls.";
223
+ }
224
+ function ToolbarNextOverflowMenu({
225
+ focusMemoryRef,
226
+ getItemHostRef,
227
+ group,
228
+ onItemFocus
229
+ }) {
230
+ var _a, _b;
231
+ const panelId = useId();
232
+ const [open, setOpen] = useState(false);
233
+ const triggerRef = useRef(null);
234
+ const panelRef = useRef(null);
235
+ const panelContentRef = useRef(null);
236
+ const [panelContentNode, setPanelContentNode] = useState(null);
237
+ const wasOpenRef = useRef(false);
238
+ const focusedOpenPanelRef = useRef(false);
239
+ const openModalityRef = useRef(null);
240
+ const floatingBoundary = useToolbarNextOverflowFloatingBoundary();
241
+ const {
242
+ focusEntryTarget,
243
+ handleScopeBlur,
244
+ handleScopeFocus,
245
+ handleScopeKeyDown,
246
+ handleScopePointerDown,
247
+ rememberedFocusRef
248
+ } = useToolbarNextKeyboardNavigation({
249
+ includeTabIndexMinusOne: true,
250
+ items: group.items,
251
+ scopeRef: panelContentRef
252
+ });
253
+ const { refs, x, y, strategy, context, elements } = useFloatingUI({
254
+ open,
255
+ onOpenChange(nextOpen, _, reason) {
256
+ setOpen(nextOpen);
257
+ if (!nextOpen) {
258
+ openModalityRef.current = null;
259
+ }
260
+ if (!nextOpen && reason === "escape-key") {
261
+ scheduleToolbarNextFocus(triggerRef.current);
262
+ }
263
+ },
264
+ placement: "bottom-end",
265
+ middleware: [
266
+ offset(1),
267
+ size({
268
+ apply({ elements: elements2, availableHeight }) {
269
+ Object.assign(elements2.floating.style, {
270
+ maxHeight: `${availableHeight}px`
271
+ });
272
+ }
273
+ }),
274
+ flip(),
275
+ shift({
276
+ padding: 8
277
+ })
278
+ ]
279
+ });
280
+ const { getFloatingProps, getReferenceProps } = useInteractions([
281
+ useClick(context),
282
+ useDismiss(context, {
283
+ escapeKey: false,
284
+ outsidePress(event) {
285
+ return !isTargetInsideOverflowBoundary(
286
+ panelContentRef.current,
287
+ floatingBoundary,
288
+ group.key,
289
+ event.target
290
+ );
291
+ }
292
+ })
293
+ ]);
294
+ const handleTriggerKeyDown = useCallback(
295
+ (event) => {
296
+ if (!open && ["Enter", " "].includes(event.key)) {
297
+ event.preventDefault();
298
+ openModalityRef.current = "keyboard";
299
+ setOpen(true);
300
+ return;
301
+ }
302
+ if (open && event.key === "Escape") {
303
+ event.preventDefault();
304
+ setOpen(false);
305
+ scheduleToolbarNextFocus(triggerRef.current);
306
+ }
307
+ },
308
+ [open]
309
+ );
310
+ const handleTriggerPointerDown = useCallback(
311
+ (event) => {
312
+ if (!open && event.button === 0) {
313
+ openModalityRef.current = "pointer";
314
+ }
315
+ },
316
+ [open]
317
+ );
318
+ const handleTriggerMouseDown = useCallback(
319
+ (event) => {
320
+ if (!open && event.button === 0) {
321
+ openModalityRef.current = "pointer";
322
+ }
323
+ },
324
+ [open]
325
+ );
326
+ const handlePanelKeyDown = useCallback((event) => {
327
+ var _a2;
328
+ if (event.key === "Tab") {
329
+ const panelContent = panelContentRef.current;
330
+ const target = event.target;
331
+ if (panelContent && target instanceof HTMLElement && shouldToolbarNextPreserveNativeTab(target)) {
332
+ const focusableElements = getDocumentFocusableElements(
333
+ panelContent.ownerDocument
334
+ );
335
+ const currentIndex = focusableElements.indexOf(target);
336
+ const nextFocusTarget = focusableElements[currentIndex + (event.shiftKey ? -1 : 1)];
337
+ if (currentIndex !== -1 && nextFocusTarget && panelContent.contains(nextFocusTarget)) {
338
+ return;
339
+ }
340
+ }
341
+ }
342
+ if (event.key === "Tab" && !event.shiftKey) {
343
+ const toolbarRoot = (_a2 = triggerRef.current) == null ? void 0 : _a2.closest(
344
+ `[${TOOLBAR_NEXT_SCOPE_ROOT_ATTR}]`
345
+ );
346
+ const nextFocusTarget = toolbarRoot ? getToolbarNextTabMoveTarget(toolbarRoot, false) : null;
347
+ if (nextFocusTarget) {
348
+ event.preventDefault();
349
+ event.stopPropagation();
350
+ setOpen(false);
351
+ scheduleToolbarNextFocus(nextFocusTarget);
352
+ }
353
+ return;
354
+ }
355
+ if (event.key === "Tab" && event.shiftKey) {
356
+ event.preventDefault();
357
+ event.stopPropagation();
358
+ setOpen(false);
359
+ scheduleToolbarNextFocus(triggerRef.current);
360
+ return;
361
+ }
362
+ if (event.key === "Escape") {
363
+ event.preventDefault();
364
+ event.stopPropagation();
365
+ setOpen(false);
366
+ scheduleToolbarNextFocus(triggerRef.current);
367
+ }
368
+ }, []);
369
+ const handleTriggerRef = useForkRef(
370
+ triggerRef,
371
+ refs.setReference
372
+ );
373
+ const handlePanelRef = useForkRef(panelRef, refs.setFloating);
374
+ const handlePanelContentRef = useForkRef(
375
+ panelContentRef,
376
+ setPanelContentNode
377
+ );
378
+ const handlePanelFocus = useCallback(
379
+ (event) => {
380
+ handleScopeFocus(event);
381
+ const panelContent = panelContentRef.current;
382
+ const target = event.target;
383
+ if (!panelContent || !(target instanceof HTMLElement)) {
384
+ return;
385
+ }
386
+ const focusMemory = getToolbarNextFocusMemory(panelContent, target, {
387
+ includeTabIndexMinusOne: true
388
+ });
389
+ if ((focusMemory == null ? void 0 : focusMemory.type) !== "item") {
390
+ return;
391
+ }
392
+ scrollToolbarNextOverflowTargetIntoView(panelRef.current, target);
393
+ onItemFocus == null ? void 0 : onItemFocus(focusMemory.itemId, focusMemory.controlIndex);
394
+ },
395
+ [handleScopeFocus, onItemFocus]
396
+ );
397
+ const { Component: FloatingComponent } = useFloatingComponent();
398
+ useEffect(() => {
399
+ if (open && !wasOpenRef.current) {
400
+ const externalFocusMemory = focusMemoryRef == null ? void 0 : focusMemoryRef.current;
401
+ if (canSeedOverflowFocusMemory(externalFocusMemory, group)) {
402
+ rememberedFocusRef.current = externalFocusMemory;
403
+ }
404
+ if (openModalityRef.current !== "pointer") {
405
+ focusEntryTarget();
406
+ }
407
+ }
408
+ wasOpenRef.current = open;
409
+ }, [focusEntryTarget, focusMemoryRef, group, open, rememberedFocusRef]);
410
+ useEffect(() => {
411
+ if (!open || !panelContentNode) {
412
+ return;
413
+ }
414
+ const handleFocusIn = (event) => {
415
+ handlePanelFocus(event);
416
+ };
417
+ const handleFocusOut = (event) => {
418
+ if (isTargetInsideOverflowBoundary(
419
+ panelContentRef.current,
420
+ floatingBoundary,
421
+ group.key,
422
+ event.relatedTarget
423
+ )) {
424
+ return;
425
+ }
426
+ handleScopeBlur(event);
427
+ };
428
+ const handleKeyDownCapture = (event) => {
429
+ handleScopeKeyDown(event);
430
+ };
431
+ const handlePointerDownCapture = (event) => {
432
+ handleScopePointerDown(event);
433
+ };
434
+ const handleKeyDown = (event) => {
435
+ if (!event.defaultPrevented) {
436
+ handlePanelKeyDown(event);
437
+ }
438
+ };
439
+ panelContentNode.addEventListener("focusin", handleFocusIn);
440
+ panelContentNode.addEventListener("focusout", handleFocusOut);
441
+ panelContentNode.addEventListener("keydown", handleKeyDownCapture, true);
442
+ panelContentNode.addEventListener(
443
+ "pointerdown",
444
+ handlePointerDownCapture,
445
+ true
446
+ );
447
+ panelContentNode.addEventListener("keydown", handleKeyDown);
448
+ return () => {
449
+ panelContentNode.removeEventListener("focusin", handleFocusIn);
450
+ panelContentNode.removeEventListener("focusout", handleFocusOut);
451
+ panelContentNode.removeEventListener(
452
+ "keydown",
453
+ handleKeyDownCapture,
454
+ true
455
+ );
456
+ panelContentNode.removeEventListener(
457
+ "pointerdown",
458
+ handlePointerDownCapture,
459
+ true
460
+ );
461
+ panelContentNode.removeEventListener("keydown", handleKeyDown);
462
+ };
463
+ }, [
464
+ handlePanelFocus,
465
+ handlePanelKeyDown,
466
+ handleScopeBlur,
467
+ handleScopeKeyDown,
468
+ handleScopePointerDown,
469
+ floatingBoundary,
470
+ group.key,
471
+ open,
472
+ panelContentNode
473
+ ]);
474
+ useIsomorphicLayoutEffect(() => {
475
+ if (!open) {
476
+ focusedOpenPanelRef.current = false;
477
+ return;
478
+ }
479
+ if (!panelContentNode || focusedOpenPanelRef.current || openModalityRef.current === "pointer") {
480
+ return;
481
+ }
482
+ const getPanelFocusables = () => getToolbarNextScopeFocusableElements(panelContentNode, {
483
+ includeTabIndexMinusOne: true
484
+ });
485
+ const focusEntryWhenReady = () => {
486
+ const panelFocusables = getPanelFocusables();
487
+ if (panelFocusables.length === 0) {
488
+ return false;
489
+ }
490
+ focusedOpenPanelRef.current = true;
491
+ focusEntryTarget();
492
+ return true;
493
+ };
494
+ if (focusEntryWhenReady()) {
495
+ return;
496
+ }
497
+ const panelWindow = panelContentNode.ownerDocument.defaultView;
498
+ const mutationObserverCtor = panelWindow == null ? void 0 : panelWindow.MutationObserver;
499
+ const resizeObserverCtor = panelWindow == null ? void 0 : panelWindow.ResizeObserver;
500
+ let mutationObserver = null;
501
+ let resizeObserver = null;
502
+ mutationObserver = mutationObserverCtor != null ? new mutationObserverCtor(() => {
503
+ if (focusEntryWhenReady()) {
504
+ mutationObserver == null ? void 0 : mutationObserver.disconnect();
505
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
506
+ }
507
+ }) : null;
508
+ resizeObserver = resizeObserverCtor != null ? new resizeObserverCtor(() => {
509
+ if (focusEntryWhenReady()) {
510
+ mutationObserver == null ? void 0 : mutationObserver.disconnect();
511
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
512
+ }
513
+ }) : null;
514
+ mutationObserver == null ? void 0 : mutationObserver.observe(panelContentNode, {
515
+ childList: true,
516
+ subtree: true
517
+ });
518
+ resizeObserver == null ? void 0 : resizeObserver.observe(panelContentNode);
519
+ return () => {
520
+ mutationObserver == null ? void 0 : mutationObserver.disconnect();
521
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
522
+ };
523
+ }, [focusEntryTarget, open, panelContentNode]);
524
+ return /* @__PURE__ */ jsxs(
525
+ "div",
526
+ {
527
+ className: withBaseName("menu"),
528
+ "data-overflowgroup": group.overflowGroup,
529
+ children: [
530
+ /* @__PURE__ */ jsx(
531
+ Button,
532
+ {
533
+ appearance: "transparent",
534
+ "aria-controls": panelId,
535
+ "aria-expanded": open,
536
+ "aria-label": getOverflowTriggerLabel(group),
537
+ className: withBaseName("trigger"),
538
+ ...{
539
+ [TOOLBAR_NEXT_GROUP_KEY_ATTR]: group.key,
540
+ [TOOLBAR_NEXT_OVERFLOW_TRIGGER_ATTR]: ""
541
+ },
542
+ ...getReferenceProps({
543
+ onKeyDown: handleTriggerKeyDown,
544
+ onMouseDown: handleTriggerMouseDown,
545
+ onPointerDown: handleTriggerPointerDown
546
+ }),
547
+ ref: handleTriggerRef,
548
+ sentiment: "neutral",
549
+ children: /* @__PURE__ */ jsx(
550
+ ToolbarNextOverflowTriggerContent,
551
+ {
552
+ label: group.label,
553
+ named: group.named
554
+ }
555
+ )
556
+ }
557
+ ),
558
+ /* @__PURE__ */ jsx(
559
+ FloatingComponent,
560
+ {
561
+ ...getFloatingProps({
562
+ role: "presentation"
563
+ }),
564
+ className: withBaseName("panel"),
565
+ focusManagerProps: context ? {
566
+ context,
567
+ initialFocus: -1,
568
+ returnFocus: false,
569
+ modal: false,
570
+ closeOnFocusOut: false
571
+ } : void 0,
572
+ id: panelId,
573
+ left: x ?? 0,
574
+ open,
575
+ position: strategy,
576
+ ref: handlePanelRef,
577
+ top: y ?? 0,
578
+ width: (_a = elements.floating) == null ? void 0 : _a.offsetWidth,
579
+ height: (_b = elements.floating) == null ? void 0 : _b.offsetHeight,
580
+ children: /* @__PURE__ */ jsx(
581
+ "div",
582
+ {
583
+ "aria-label": `${group.label} overflow`,
584
+ "aria-orientation": "horizontal",
585
+ className: withBaseName("panelContent"),
586
+ ...{ [TOOLBAR_NEXT_SCOPE_ROOT_ATTR]: group.key },
587
+ role: "toolbar",
588
+ ref: handlePanelContentRef,
589
+ children: group.items.map((item, index) => /* @__PURE__ */ jsxs(
590
+ "div",
591
+ {
592
+ className: withBaseName("panelItem"),
593
+ children: [
594
+ index > 0 && item.leadingDecorations.length > 0 && cloneDecorations(item.id, item.leadingDecorations, "leading"),
595
+ /* @__PURE__ */ jsx(
596
+ "div",
597
+ {
598
+ className: withBaseName("itemHost"),
599
+ ref: open ? getItemHostRef(item.id, "overflow") : null
600
+ }
601
+ ),
602
+ cloneDecorations(item.id, item.trailingDecorations, "trailing")
603
+ ]
604
+ },
605
+ `${group.id}-${item.id}`
606
+ ))
607
+ }
608
+ )
609
+ }
610
+ )
611
+ ]
612
+ }
613
+ );
614
+ }
615
+ function ToolbarNextOverflowContent({
616
+ content,
617
+ focusMemoryRef,
618
+ getItemHostRef,
619
+ getItemRef,
620
+ getNamedTriggerRef,
621
+ getContentRef,
622
+ onItemFocus,
623
+ overflowGroups,
624
+ overflowedIds
625
+ }) {
626
+ const targetWindow = useWindow();
627
+ useComponentCssInjection({
628
+ testId: "salt-toolbar-next-overflow",
629
+ css: css_248z,
630
+ window: targetWindow
631
+ });
632
+ const { className, ...contentProps } = content.props;
633
+ const handleContentRef = useForkRef(content.ref, getContentRef(content.key));
634
+ const overflowGroupByKey = new Map(
635
+ overflowGroups.map((group) => [group.key, group])
636
+ );
637
+ const renderSlots = buildContentOverflowRenderSlots(
638
+ content.items,
639
+ overflowedIds,
640
+ new Set(overflowGroups.map((group) => group.key))
641
+ );
642
+ return /* @__PURE__ */ jsx(
643
+ ToolbarContentNext,
644
+ {
645
+ ...contentProps,
646
+ "data-implicit": content.implicit || void 0,
647
+ className: clsx(className, withBaseName("content")),
648
+ position: content.position,
649
+ ref: handleContentRef,
650
+ children: renderSlots.map(
651
+ ({
652
+ item,
653
+ overflowed,
654
+ showLeadingDecorations,
655
+ showTrailingDecorations,
656
+ triggerGroupKey
657
+ }) => {
658
+ const triggerGroup = triggerGroupKey != null ? overflowGroupByKey.get(triggerGroupKey) : void 0;
659
+ return /* @__PURE__ */ jsxs(
660
+ "div",
661
+ {
662
+ className: withBaseName("slot"),
663
+ "data-align": item.align,
664
+ "data-priority": item.overflowPriority,
665
+ ref: triggerGroup ? getNamedTriggerRef(item.id) : getItemRef(item.id),
666
+ children: [
667
+ showLeadingDecorations ? cloneDecorations(item.id, item.leadingDecorations, "leading") : null,
668
+ !overflowed ? /* @__PURE__ */ jsx("div", { className: withBaseName("item"), children: /* @__PURE__ */ jsx(
669
+ "div",
670
+ {
671
+ className: withBaseName("itemHost"),
672
+ ref: getItemHostRef(item.id, "main")
673
+ }
674
+ ) }) : null,
675
+ triggerGroup ? /* @__PURE__ */ jsx("div", { className: withBaseName("item"), children: /* @__PURE__ */ jsx(
676
+ ToolbarNextOverflowMenu,
677
+ {
678
+ focusMemoryRef,
679
+ getItemHostRef,
680
+ group: triggerGroup,
681
+ onItemFocus
682
+ }
683
+ ) }) : null,
684
+ showTrailingDecorations ? cloneDecorations(
685
+ item.id,
686
+ item.trailingDecorations,
687
+ "trailing"
688
+ ) : null
689
+ ]
690
+ },
691
+ triggerGroup ? `${content.key}-${triggerGroup.id}-anchor-${item.id}` : item.id
692
+ );
693
+ }
694
+ )
695
+ }
696
+ );
697
+ }
698
+
699
+ export { ToolbarNextOverflowContent, ToolbarNextOverflowMenu, ToolbarNextOverflowOwners, ToolbarNextOverflowTriggerContent };
700
+ //# sourceMappingURL=ToolbarNextOverflow.js.map