@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,743 @@
1
+ 'use strict';
2
+
3
+ var core = require('@salt-ds/core');
4
+ var window = require('@salt-ds/window');
5
+ var react = require('react');
6
+ var toolbarNextUtils = require('./toolbarNextUtils.js');
7
+
8
+ const emptyOverflowState = {
9
+ overflowGroups: [],
10
+ overflowedIds: /* @__PURE__ */ new Set()
11
+ };
12
+ const bandPositions = ["start", "center", "end"];
13
+ function measureWidth(element) {
14
+ if (!element) {
15
+ return 0;
16
+ }
17
+ const { width } = element.getBoundingClientRect();
18
+ return Math.ceil(width);
19
+ }
20
+ function isVisibleMeasurementElement(element) {
21
+ if (!(element instanceof HTMLElement)) {
22
+ return false;
23
+ }
24
+ const { width, height } = element.getBoundingClientRect();
25
+ const styles = core.ownerWindow(element).getComputedStyle(element);
26
+ return width > 0 && height > 0 && styles.display !== "none" && styles.visibility !== "hidden";
27
+ }
28
+ function measureOverflowItemWidth(element) {
29
+ if (!element) {
30
+ return 0;
31
+ }
32
+ const rect = element.getBoundingClientRect();
33
+ let left = rect.left;
34
+ let right = rect.right;
35
+ for (const descendant of element.querySelectorAll("*")) {
36
+ if (!isVisibleMeasurementElement(descendant)) {
37
+ continue;
38
+ }
39
+ const descendantRect = descendant.getBoundingClientRect();
40
+ left = Math.min(left, descendantRect.left);
41
+ right = Math.max(right, descendantRect.right);
42
+ }
43
+ return Math.ceil(Math.max(rect.width, right - left));
44
+ }
45
+ function readGap(gapValue) {
46
+ return Number.parseFloat(gapValue || "0") || 0;
47
+ }
48
+ function sumFlexWidths(widths, gap) {
49
+ if (widths.length === 0) {
50
+ return 0;
51
+ }
52
+ return widths.reduce((total, width) => total + width, 0) + gap * (widths.length - 1);
53
+ }
54
+ function buildGroupDefinitions(items) {
55
+ const groupMap = /* @__PURE__ */ new Map();
56
+ for (const [sequence, item] of items.entries()) {
57
+ if (item.overflowMode === "none") {
58
+ continue;
59
+ }
60
+ const existing = groupMap.get(item.overflowGroupKey);
61
+ if (existing) {
62
+ if (!existing.named && item.overflowGroup === "shared") {
63
+ continue;
64
+ }
65
+ if (existing.label === item.overflowGroup && item.overflowLabel) {
66
+ existing.label = item.overflowLabel;
67
+ }
68
+ continue;
69
+ }
70
+ groupMap.set(item.overflowGroupKey, {
71
+ id: `${item.overflowGroupKey}-${sequence}`,
72
+ key: item.overflowGroupKey,
73
+ label: item.overflowGroup === "shared" ? "More" : item.overflowLabel ?? item.overflowGroup,
74
+ named: item.overflowGroup !== "shared",
75
+ order: sequence,
76
+ overflowGroup: item.overflowGroup,
77
+ contentKey: item.overflowGroup === "shared" ? void 0 : item.contentKey
78
+ });
79
+ }
80
+ return Array.from(groupMap.values()).sort(
81
+ (left, right) => left.order - right.order
82
+ );
83
+ }
84
+ function buildCollapseUnits(items) {
85
+ const groupedUnits = /* @__PURE__ */ new Map();
86
+ const units = [];
87
+ for (const [sequence, item] of items.entries()) {
88
+ if (item.overflowMode === "none") {
89
+ continue;
90
+ }
91
+ if (item.overflowMode === "grouped" && item.overflowGroup !== "shared") {
92
+ const existing = groupedUnits.get(item.overflowGroupKey);
93
+ if (existing) {
94
+ existing.itemIds.push(item.id);
95
+ existing.order = Math.max(existing.order, sequence);
96
+ existing.priority = Math.max(existing.priority, item.overflowPriority);
97
+ continue;
98
+ }
99
+ const unit = {
100
+ groupKey: item.overflowGroupKey,
101
+ itemIds: [item.id],
102
+ order: sequence,
103
+ priority: item.overflowPriority
104
+ };
105
+ groupedUnits.set(item.overflowGroupKey, unit);
106
+ units.push(unit);
107
+ continue;
108
+ }
109
+ units.push({
110
+ groupKey: item.overflowGroupKey,
111
+ itemIds: [item.id],
112
+ order: sequence,
113
+ priority: item.overflowPriority
114
+ });
115
+ }
116
+ return units.sort((left, right) => {
117
+ if (left.priority !== right.priority) {
118
+ return right.priority - left.priority;
119
+ }
120
+ return right.order - left.order;
121
+ });
122
+ }
123
+ function areOverflowStatesEqual(previous, next) {
124
+ if (previous.overflowedIds.size !== next.overflowedIds.size) {
125
+ return false;
126
+ }
127
+ for (const itemId of previous.overflowedIds) {
128
+ if (!next.overflowedIds.has(itemId)) {
129
+ return false;
130
+ }
131
+ }
132
+ if (previous.overflowGroups.length !== next.overflowGroups.length) {
133
+ return false;
134
+ }
135
+ return previous.overflowGroups.every((group, index) => {
136
+ const nextGroup = next.overflowGroups[index];
137
+ if (nextGroup == null || group.id !== nextGroup.id || group.label !== nextGroup.label || group.items.length !== nextGroup.items.length) {
138
+ return false;
139
+ }
140
+ return group.items.every((item, itemIndex) => {
141
+ var _a;
142
+ return item.id === ((_a = nextGroup.items[itemIndex]) == null ? void 0 : _a.id);
143
+ });
144
+ });
145
+ }
146
+ function computeToolbarNextOverflowState({
147
+ bandGaps,
148
+ collapseUnits,
149
+ containerWidth,
150
+ groupDefinitions,
151
+ itemWidths,
152
+ items,
153
+ namedTriggerWidths,
154
+ content,
155
+ contentGaps,
156
+ rootGap,
157
+ triggerWidths
158
+ }) {
159
+ const hasCenteredLayout = content.some(
160
+ (contentArea) => contentArea.position === "center"
161
+ );
162
+ const contentByPosition = bandPositions.reduce(
163
+ (bands, position) => {
164
+ bands[position] = content.filter(
165
+ (contentArea) => contentArea.position === position
166
+ );
167
+ return bands;
168
+ },
169
+ {
170
+ start: [],
171
+ center: [],
172
+ end: []
173
+ }
174
+ );
175
+ const overflowedIds = /* @__PURE__ */ new Set();
176
+ const activeGroups = /* @__PURE__ */ new Set();
177
+ const getContentWidth = (contentArea) => {
178
+ const renderSlots = toolbarNextUtils.buildContentOverflowRenderSlots(
179
+ contentArea.items,
180
+ overflowedIds,
181
+ new Set(
182
+ groupDefinitions.filter((group) => {
183
+ return group.named && group.contentKey === contentArea.key && activeGroups.has(group.key);
184
+ }).map((group) => group.key)
185
+ )
186
+ );
187
+ const slotWidths = [];
188
+ for (const slot of renderSlots) {
189
+ const width = slot.triggerGroupKey != null ? namedTriggerWidths.get(slot.item.id) : itemWidths.get(slot.item.id);
190
+ if (width == null || width <= 0) {
191
+ return null;
192
+ }
193
+ slotWidths.push(width);
194
+ }
195
+ return sumFlexWidths(slotWidths, contentGaps.get(contentArea.key) ?? 0);
196
+ };
197
+ const getBandWidth = (position) => {
198
+ const bandChildWidths = [];
199
+ for (const contentArea of contentByPosition[position]) {
200
+ const contentWidth = getContentWidth(contentArea);
201
+ if (contentWidth == null) {
202
+ return null;
203
+ }
204
+ if (contentWidth > 0) {
205
+ bandChildWidths.push(contentWidth);
206
+ }
207
+ }
208
+ if (position === "end") {
209
+ for (const group of groupDefinitions) {
210
+ if (!group.named && activeGroups.has(group.key)) {
211
+ const width = triggerWidths.get(group.key);
212
+ if (width == null || width <= 0) {
213
+ return null;
214
+ }
215
+ bandChildWidths.push(width);
216
+ }
217
+ }
218
+ }
219
+ return sumFlexWidths(bandChildWidths, bandGaps.get(position) ?? 0);
220
+ };
221
+ const getTotalWidth = () => {
222
+ if (hasCenteredLayout) {
223
+ const startBandWidth = getBandWidth("start");
224
+ const centerBandWidth = getBandWidth("center");
225
+ const endBandWidth = getBandWidth("end");
226
+ if (startBandWidth == null || centerBandWidth == null || endBandWidth == null) {
227
+ return null;
228
+ }
229
+ return centerBandWidth + Math.max(startBandWidth, endBandWidth) * 2;
230
+ }
231
+ const visibleBandWidths = [];
232
+ for (const position of bandPositions) {
233
+ const bandWidth = getBandWidth(position);
234
+ if (bandWidth == null) {
235
+ return null;
236
+ }
237
+ if (bandWidth > 0) {
238
+ visibleBandWidths.push(bandWidth);
239
+ }
240
+ }
241
+ return sumFlexWidths(visibleBandWidths, rootGap);
242
+ };
243
+ const initialWidth = getTotalWidth();
244
+ if (initialWidth == null) {
245
+ return emptyOverflowState;
246
+ }
247
+ if (initialWidth > containerWidth) {
248
+ for (const unit of collapseUnits) {
249
+ for (const itemId of unit.itemIds) {
250
+ overflowedIds.add(itemId);
251
+ }
252
+ activeGroups.add(unit.groupKey);
253
+ const nextWidth = getTotalWidth();
254
+ if (nextWidth == null) {
255
+ return emptyOverflowState;
256
+ }
257
+ if (nextWidth <= containerWidth) {
258
+ break;
259
+ }
260
+ }
261
+ }
262
+ const overflowGroups = groupDefinitions.reduce(
263
+ (groups, group) => {
264
+ const hiddenItems = items.filter(
265
+ (item) => item.overflowGroupKey === group.key && overflowedIds.has(item.id)
266
+ );
267
+ if (hiddenItems.length > 0) {
268
+ groups.push({
269
+ id: group.id,
270
+ items: hiddenItems,
271
+ key: group.key,
272
+ label: group.label,
273
+ named: group.named,
274
+ overflowGroup: group.overflowGroup,
275
+ contentKey: group.contentKey
276
+ });
277
+ }
278
+ return groups;
279
+ },
280
+ []
281
+ );
282
+ return {
283
+ overflowGroups,
284
+ overflowedIds
285
+ };
286
+ }
287
+ function useToolbarNextOverflow({
288
+ content
289
+ }) {
290
+ const targetWindow = window.useWindow();
291
+ const items = react.useMemo(
292
+ () => content.flatMap((contentArea) => contentArea.items),
293
+ [content]
294
+ );
295
+ const containerRef = react.useRef(null);
296
+ const bandRefs = react.useRef({
297
+ start: null,
298
+ center: null,
299
+ end: null
300
+ });
301
+ const bandRefCallbacks = react.useRef(
302
+ /* @__PURE__ */ new Map()
303
+ );
304
+ const contentRefs = react.useRef({});
305
+ const contentRefCallbacks = react.useRef(
306
+ /* @__PURE__ */ new Map()
307
+ );
308
+ const itemRefs = react.useRef({});
309
+ const itemRefCallbacks = react.useRef(
310
+ /* @__PURE__ */ new Map()
311
+ );
312
+ const namedTriggerRefs = react.useRef({});
313
+ const namedTriggerRefCallbacks = react.useRef(
314
+ /* @__PURE__ */ new Map()
315
+ );
316
+ const namedTriggerMeasureRefs = react.useRef(
317
+ {}
318
+ );
319
+ const namedTriggerMeasureCallbacks = react.useRef(
320
+ /* @__PURE__ */ new Map()
321
+ );
322
+ const triggerMeasureRefs = react.useRef(
323
+ {}
324
+ );
325
+ const triggerMeasureCallbacks = react.useRef(
326
+ /* @__PURE__ */ new Map()
327
+ );
328
+ const rafRef = react.useRef(null);
329
+ const clearComputingRafRef = react.useRef(null);
330
+ const isComputingRef = react.useRef(false);
331
+ const pendingMeasureRef = react.useRef(false);
332
+ const resizeObserverRef = react.useRef(null);
333
+ const observedWidthTargetsRef = react.useRef(
334
+ /* @__PURE__ */ new Map()
335
+ );
336
+ const cachedItemWidths = react.useRef({});
337
+ const cachedNamedTriggerWidths = react.useRef({});
338
+ const cachedSharedTriggerWidths = react.useRef({});
339
+ const [overflowState, setOverflowState] = react.useState(emptyOverflowState);
340
+ const namedTriggerItems = react.useMemo(
341
+ () => items.filter((item) => {
342
+ return item.overflowMode !== "none" && item.overflowGroup !== "shared";
343
+ }),
344
+ [items]
345
+ );
346
+ const groupDefinitions = react.useMemo(() => buildGroupDefinitions(items), [items]);
347
+ const collapseUnits = react.useMemo(() => buildCollapseUnits(items), [items]);
348
+ const computeOverflow = react.useCallback(() => {
349
+ const container = containerRef.current;
350
+ if (!container) {
351
+ return emptyOverflowState;
352
+ }
353
+ const containerStyles = core.ownerWindow(container).getComputedStyle(container);
354
+ const paddingLeft = Number.parseFloat(containerStyles.paddingLeft || "0") || 0;
355
+ const paddingRight = Number.parseFloat(containerStyles.paddingRight || "0") || 0;
356
+ const borderLeft = Number.parseFloat(containerStyles.borderLeftWidth || "0") || 0;
357
+ const borderRight = Number.parseFloat(containerStyles.borderRightWidth || "0") || 0;
358
+ const containerWidth = Math.floor(
359
+ container.getBoundingClientRect().width - paddingLeft - paddingRight - borderLeft - borderRight
360
+ );
361
+ if (containerWidth <= 0) {
362
+ return emptyOverflowState;
363
+ }
364
+ const rootGap = readGap(
365
+ containerStyles.columnGap || containerStyles.gap || "0"
366
+ );
367
+ const bandGaps = /* @__PURE__ */ new Map();
368
+ const contentGaps = /* @__PURE__ */ new Map();
369
+ const itemWidths = /* @__PURE__ */ new Map();
370
+ const namedTriggerWidths = /* @__PURE__ */ new Map();
371
+ const triggerWidths = /* @__PURE__ */ new Map();
372
+ for (const position of bandPositions) {
373
+ const bandElement = bandRefs.current[position];
374
+ if (!bandElement) {
375
+ bandGaps.set(position, 0);
376
+ continue;
377
+ }
378
+ const bandStyles = core.ownerWindow(bandElement).getComputedStyle(bandElement);
379
+ bandGaps.set(
380
+ position,
381
+ readGap(bandStyles.columnGap || bandStyles.gap || "0")
382
+ );
383
+ }
384
+ for (const contentArea of content) {
385
+ const contentElement = contentRefs.current[contentArea.key];
386
+ if (!contentElement) {
387
+ return emptyOverflowState;
388
+ }
389
+ const contentStyles = core.ownerWindow(contentElement).getComputedStyle(contentElement);
390
+ contentGaps.set(
391
+ contentArea.key,
392
+ readGap(contentStyles.columnGap || contentStyles.gap || "0")
393
+ );
394
+ }
395
+ for (const item of items) {
396
+ const element = itemRefs.current[item.id];
397
+ if (element) {
398
+ const width = measureOverflowItemWidth(element);
399
+ if (width > 0) {
400
+ itemWidths.set(item.id, width);
401
+ cachedItemWidths.current[item.id] = width;
402
+ continue;
403
+ }
404
+ }
405
+ const cached = cachedItemWidths.current[item.id];
406
+ if (cached != null && cached > 0) {
407
+ itemWidths.set(item.id, cached);
408
+ continue;
409
+ }
410
+ return emptyOverflowState;
411
+ }
412
+ for (const item of namedTriggerItems) {
413
+ const liveWidth = measureWidth(namedTriggerRefs.current[item.id]);
414
+ if (liveWidth > 0) {
415
+ namedTriggerWidths.set(item.id, liveWidth);
416
+ cachedNamedTriggerWidths.current[item.id] = liveWidth;
417
+ continue;
418
+ }
419
+ const measureWidthForItem = measureWidth(
420
+ namedTriggerMeasureRefs.current[item.id]
421
+ );
422
+ if (measureWidthForItem > 0) {
423
+ namedTriggerWidths.set(item.id, measureWidthForItem);
424
+ cachedNamedTriggerWidths.current[item.id] = measureWidthForItem;
425
+ continue;
426
+ }
427
+ const cached = cachedNamedTriggerWidths.current[item.id];
428
+ if (cached != null && cached > 0) {
429
+ namedTriggerWidths.set(item.id, cached);
430
+ continue;
431
+ }
432
+ return emptyOverflowState;
433
+ }
434
+ for (const group of groupDefinitions.filter((entry) => !entry.named)) {
435
+ const width = measureWidth(triggerMeasureRefs.current[group.key]);
436
+ if (width <= 0) {
437
+ const cached = cachedSharedTriggerWidths.current[group.key];
438
+ if (cached != null && cached > 0) {
439
+ triggerWidths.set(group.key, cached);
440
+ continue;
441
+ }
442
+ return emptyOverflowState;
443
+ }
444
+ triggerWidths.set(group.key, width);
445
+ cachedSharedTriggerWidths.current[group.key] = width;
446
+ }
447
+ const nextOverflowState = computeToolbarNextOverflowState({
448
+ bandGaps,
449
+ collapseUnits,
450
+ containerWidth,
451
+ groupDefinitions,
452
+ itemWidths,
453
+ items,
454
+ namedTriggerWidths,
455
+ content,
456
+ contentGaps,
457
+ rootGap,
458
+ triggerWidths
459
+ });
460
+ return nextOverflowState;
461
+ }, [collapseUnits, groupDefinitions, items, namedTriggerItems, content]);
462
+ const scheduleMeasureRef = react.useRef(() => {
463
+ });
464
+ const scheduleMeasure = react.useCallback(() => {
465
+ if (!targetWindow) {
466
+ return;
467
+ }
468
+ if (isComputingRef.current) {
469
+ pendingMeasureRef.current = true;
470
+ return;
471
+ }
472
+ if (rafRef.current != null) {
473
+ targetWindow.cancelAnimationFrame(rafRef.current);
474
+ }
475
+ rafRef.current = targetWindow.requestAnimationFrame(() => {
476
+ rafRef.current = null;
477
+ isComputingRef.current = true;
478
+ try {
479
+ const nextState = computeOverflow();
480
+ setOverflowState((previous) => {
481
+ return areOverflowStatesEqual(previous, nextState) ? previous : nextState;
482
+ });
483
+ } finally {
484
+ clearComputingRafRef.current = targetWindow.requestAnimationFrame(
485
+ () => {
486
+ clearComputingRafRef.current = null;
487
+ isComputingRef.current = false;
488
+ if (pendingMeasureRef.current) {
489
+ pendingMeasureRef.current = false;
490
+ scheduleMeasureRef.current();
491
+ }
492
+ }
493
+ );
494
+ }
495
+ });
496
+ }, [computeOverflow, targetWindow]);
497
+ core.useIsomorphicLayoutEffect(() => {
498
+ scheduleMeasureRef.current = scheduleMeasure;
499
+ return () => {
500
+ scheduleMeasureRef.current = () => {
501
+ };
502
+ };
503
+ }, [scheduleMeasure]);
504
+ const getCachedWidthForObservedTarget = react.useCallback(
505
+ (target) => {
506
+ switch (target.kind) {
507
+ case "item":
508
+ return cachedItemWidths.current[target.id];
509
+ case "named-trigger":
510
+ case "named-trigger-measure":
511
+ return cachedNamedTriggerWidths.current[target.id];
512
+ case "shared-trigger-measure":
513
+ return cachedSharedTriggerWidths.current[target.groupKey];
514
+ }
515
+ },
516
+ []
517
+ );
518
+ const setCachedWidthForObservedTarget = react.useCallback(
519
+ (target, width) => {
520
+ switch (target.kind) {
521
+ case "item":
522
+ cachedItemWidths.current[target.id] = width;
523
+ return;
524
+ case "named-trigger":
525
+ case "named-trigger-measure":
526
+ cachedNamedTriggerWidths.current[target.id] = width;
527
+ return;
528
+ case "shared-trigger-measure":
529
+ cachedSharedTriggerWidths.current[target.groupKey] = width;
530
+ return;
531
+ }
532
+ },
533
+ []
534
+ );
535
+ const observeWidthTarget = react.useCallback(
536
+ (node, target) => {
537
+ var _a;
538
+ if (!node) {
539
+ return;
540
+ }
541
+ observedWidthTargetsRef.current.set(node, target);
542
+ (_a = resizeObserverRef.current) == null ? void 0 : _a.observe(node);
543
+ },
544
+ []
545
+ );
546
+ const unobserveWidthTarget = react.useCallback((node) => {
547
+ var _a;
548
+ if (!node) {
549
+ return;
550
+ }
551
+ observedWidthTargetsRef.current.delete(node);
552
+ (_a = resizeObserverRef.current) == null ? void 0 : _a.unobserve(node);
553
+ }, []);
554
+ const updateObservedNode = react.useCallback(
555
+ (nodes, key, node, target) => {
556
+ const previous = nodes[key];
557
+ if (previous === node) {
558
+ return;
559
+ }
560
+ if (previous) {
561
+ unobserveWidthTarget(previous);
562
+ }
563
+ nodes[key] = node;
564
+ if (node) {
565
+ observeWidthTarget(node, target);
566
+ }
567
+ },
568
+ [observeWidthTarget, unobserveWidthTarget]
569
+ );
570
+ core.useIsomorphicLayoutEffect(() => {
571
+ scheduleMeasure();
572
+ }, [scheduleMeasure]);
573
+ react.useEffect(() => {
574
+ const container = containerRef.current;
575
+ if (!container) {
576
+ return;
577
+ }
578
+ let cancelled = false;
579
+ const win = core.ownerWindow(container);
580
+ const resizeObserver = new win.ResizeObserver((entries) => {
581
+ let shouldMeasure = false;
582
+ for (const entry of entries) {
583
+ const target = observedWidthTargetsRef.current.get(entry.target);
584
+ if (!target) {
585
+ continue;
586
+ }
587
+ if (target.kind === "container") {
588
+ shouldMeasure = true;
589
+ continue;
590
+ }
591
+ const nextWidth = target.kind === "item" ? measureOverflowItemWidth(entry.target) : measureWidth(entry.target);
592
+ if (nextWidth <= 0) {
593
+ continue;
594
+ }
595
+ const previousWidth = getCachedWidthForObservedTarget(target);
596
+ if (previousWidth !== nextWidth) {
597
+ setCachedWidthForObservedTarget(target, nextWidth);
598
+ shouldMeasure = true;
599
+ }
600
+ }
601
+ if (shouldMeasure) {
602
+ scheduleMeasureRef.current();
603
+ }
604
+ });
605
+ resizeObserverRef.current = resizeObserver;
606
+ observeWidthTarget(container, { kind: "container" });
607
+ for (const node of observedWidthTargetsRef.current.keys()) {
608
+ resizeObserver.observe(node);
609
+ }
610
+ if (win.document.fonts) {
611
+ void win.document.fonts.ready.then(() => {
612
+ if (!cancelled) {
613
+ scheduleMeasureRef.current();
614
+ }
615
+ });
616
+ }
617
+ return () => {
618
+ cancelled = true;
619
+ resizeObserverRef.current = null;
620
+ resizeObserver.disconnect();
621
+ if (rafRef.current != null) {
622
+ win.cancelAnimationFrame(rafRef.current);
623
+ rafRef.current = null;
624
+ }
625
+ if (clearComputingRafRef.current != null) {
626
+ win.cancelAnimationFrame(clearComputingRafRef.current);
627
+ clearComputingRafRef.current = null;
628
+ }
629
+ isComputingRef.current = false;
630
+ pendingMeasureRef.current = false;
631
+ };
632
+ }, [
633
+ getCachedWidthForObservedTarget,
634
+ observeWidthTarget,
635
+ setCachedWidthForObservedTarget
636
+ ]);
637
+ const getItemRef = react.useCallback(
638
+ (id) => {
639
+ const existing = itemRefCallbacks.current.get(id);
640
+ if (existing) {
641
+ return existing;
642
+ }
643
+ const callback = (node) => {
644
+ updateObservedNode(itemRefs.current, id, node, {
645
+ id,
646
+ kind: "item"
647
+ });
648
+ };
649
+ itemRefCallbacks.current.set(id, callback);
650
+ return callback;
651
+ },
652
+ [updateObservedNode]
653
+ );
654
+ const getNamedTriggerRef = react.useCallback(
655
+ (id) => {
656
+ const existing = namedTriggerRefCallbacks.current.get(id);
657
+ if (existing) {
658
+ return existing;
659
+ }
660
+ const callback = (node) => {
661
+ updateObservedNode(namedTriggerRefs.current, id, node, {
662
+ id,
663
+ kind: "named-trigger"
664
+ });
665
+ };
666
+ namedTriggerRefCallbacks.current.set(id, callback);
667
+ return callback;
668
+ },
669
+ [updateObservedNode]
670
+ );
671
+ const getNamedTriggerMeasureRef = react.useCallback(
672
+ (id) => {
673
+ const existing = namedTriggerMeasureCallbacks.current.get(id);
674
+ if (existing) {
675
+ return existing;
676
+ }
677
+ const callback = (node) => {
678
+ updateObservedNode(namedTriggerMeasureRefs.current, id, node, {
679
+ id,
680
+ kind: "named-trigger-measure"
681
+ });
682
+ };
683
+ namedTriggerMeasureCallbacks.current.set(id, callback);
684
+ return callback;
685
+ },
686
+ [updateObservedNode]
687
+ );
688
+ const getContentRef = react.useCallback((contentKey) => {
689
+ const existing = contentRefCallbacks.current.get(contentKey);
690
+ if (existing) {
691
+ return existing;
692
+ }
693
+ const callback = (node) => {
694
+ contentRefs.current[contentKey] = node;
695
+ };
696
+ contentRefCallbacks.current.set(contentKey, callback);
697
+ return callback;
698
+ }, []);
699
+ const getBandRef = react.useCallback((position) => {
700
+ const existing = bandRefCallbacks.current.get(position);
701
+ if (existing) {
702
+ return existing;
703
+ }
704
+ const callback = (node) => {
705
+ bandRefs.current[position] = node;
706
+ };
707
+ bandRefCallbacks.current.set(position, callback);
708
+ return callback;
709
+ }, []);
710
+ const getTriggerMeasureRef = react.useCallback(
711
+ (groupKey) => {
712
+ const existing = triggerMeasureCallbacks.current.get(groupKey);
713
+ if (existing) {
714
+ return existing;
715
+ }
716
+ const callback = (node) => {
717
+ updateObservedNode(triggerMeasureRefs.current, groupKey, node, {
718
+ groupKey,
719
+ kind: "shared-trigger-measure"
720
+ });
721
+ };
722
+ triggerMeasureCallbacks.current.set(groupKey, callback);
723
+ return callback;
724
+ },
725
+ [updateObservedNode]
726
+ );
727
+ return {
728
+ containerRef,
729
+ getBandRef,
730
+ getItemRef,
731
+ getNamedTriggerMeasureRef,
732
+ getNamedTriggerRef,
733
+ getContentRef,
734
+ getTriggerMeasureRef,
735
+ isOverflowing: overflowState.overflowGroups.length > 0,
736
+ overflowGroups: overflowState.overflowGroups,
737
+ overflowedIds: overflowState.overflowedIds,
738
+ overflowTriggerGroups: groupDefinitions
739
+ };
740
+ }
741
+
742
+ exports.useToolbarNextOverflow = useToolbarNextOverflow;
743
+ //# sourceMappingURL=useToolbarNextOverflow.js.map