@fluentui/priority-overflow 9.3.0 → 9.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,35 @@
1
1
  # Change Log - @fluentui/priority-overflow
2
2
 
3
- This log was last generated on Thu, 12 Feb 2026 10:42:45 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 15 Jul 2026 14:10:08 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.4.1](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.4.1)
8
+
9
+ Wed, 15 Jul 2026 14:10:08 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.4.0..@fluentui/priority-overflow_v9.4.1)
11
+
12
+ ### Patches
13
+
14
+ - fix: avoid overflow snapshot updates after unmount ([PR #36401](https://github.com/microsoft/fluentui/pull/36401) by bernardo.sunderhus@gmail.com)
15
+
16
+ ## [9.4.0](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.4.0)
17
+
18
+ Wed, 24 Jun 2026 11:10:05 GMT
19
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.3.0..@fluentui/priority-overflow_v9.4.0)
20
+
21
+ ### Minor changes
22
+
23
+ - feat: createOverflowManager accepts initialOptions, new setOptions method, observe now returns its cleanup, and the OverflowManagerOptions type is exported. ([PR #36262](https://github.com/microsoft/fluentui/pull/36262) by bsunderhus@microsoft.com)
24
+ - feat: expose getSnapshot and subscribe on OverflowManager ([PR #36263](https://github.com/microsoft/fluentui/pull/36263) by bsunderhus@microsoft.com)
25
+
26
+ ### Patches
27
+
28
+ - fix: recompute overflow eagerly when the overflow menu attaches or detaches ([PR #36264](https://github.com/microsoft/fluentui/pull/36264) by bsunderhus@microsoft.com)
29
+
7
30
  ## [9.3.0](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.3.0)
8
31
 
9
- Thu, 12 Feb 2026 10:42:45 GMT
32
+ Thu, 12 Feb 2026 10:46:12 GMT
10
33
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.2.1..@fluentui/priority-overflow_v9.3.0)
11
34
 
12
35
  ### Minor changes
package/dist/index.d.ts CHANGED
@@ -1,67 +1,71 @@
1
1
  /**
2
+ * Creates an overflow manager instance for a single container.
3
+ *
2
4
  * @internal
5
+ * @param initialOptions - Initial observe options. Missing values are filled with defaults.
3
6
  * @returns overflow manager instance
4
7
  */
5
- export declare function createOverflowManager(): OverflowManager;
8
+ export declare function createOverflowManager(initialOptions?: Partial<OverflowOptions>): OverflowManager;
6
9
 
7
- export declare interface ObserveOptions {
8
- /**
9
- * Padding (in px) at the end of the container before overflow occurs
10
- * Useful to account for extra elements (i.e. dropdown menu)
11
- * or to account for any kinds of margins between items which are hard to measure with JS
12
- * @default 10
13
- */
14
- padding?: number;
15
- /**
16
- * Direction where items are removed when overflow occurs
17
- * @default end
18
- */
19
- overflowDirection?: OverflowDirection;
20
- /**
21
- * Horizontal or vertical overflow
22
- * @default horizontal
23
- */
24
- overflowAxis?: OverflowAxis;
25
- /**
26
- * The minimum number of visible items
27
- */
28
- minimumVisible?: number;
29
- /**
30
- * Callback when item visibility is updated
31
- */
32
- onUpdateItemVisibility: OnUpdateItemVisibility;
33
- /**
34
- * Callback when item visibility is updated
35
- */
36
- onUpdateOverflow: OnUpdateOverflow;
10
+ /**
11
+ * An empty, frozen overflow snapshot used as the default before anything has been measured.
12
+ * @internal
13
+ */
14
+ export declare const EMPTY_SNAPSHOT: OverflowSnapshot;
15
+
16
+ export declare interface ObserveOptions extends Partial<OverflowOptions> {
37
17
  /**
38
- * When true, the overflow menu has default hidden items
18
+ * forces update when observation begins, ensuring initial overflow state is correct. This is useful when the container starts with items that should be overflowed, or when the container resizes immediately after mounting.
39
19
  * @default false
40
20
  */
41
- hasHiddenItems?: boolean;
21
+ forceUpdate?: boolean;
42
22
  }
43
23
 
24
+ /**
25
+ * Callback invoked when a single item's visibility changes.
26
+ */
44
27
  export declare type OnUpdateItemVisibility = (data: OnUpdateItemVisibilityPayload) => void;
45
28
 
29
+ /**
30
+ * Payload for item-level visibility updates.
31
+ */
46
32
  export declare interface OnUpdateItemVisibilityPayload {
33
+ /**
34
+ * Item whose visibility changed.
35
+ */
47
36
  item: OverflowItemEntry;
37
+ /**
38
+ * Whether the item is now visible.
39
+ */
48
40
  visible: boolean;
49
41
  }
50
42
 
51
43
  /**
52
- * signature similar to standard event listeners, but typed to handle the custom event
44
+ * Signature similar to standard event listeners, typed for overflow updates.
53
45
  */
54
46
  export declare type OnUpdateOverflow = (data: OverflowEventPayload) => void;
55
47
 
48
+ /**
49
+ * Axis used to measure overflow.
50
+ */
56
51
  export declare type OverflowAxis = 'horizontal' | 'vertical';
57
52
 
53
+ /**
54
+ * Direction where items are removed when overflow occurs.
55
+ */
58
56
  export declare type OverflowDirection = 'start' | 'end';
59
57
 
58
+ /**
59
+ * Tracked divider in the overflow manager.
60
+ */
60
61
  export declare interface OverflowDividerEntry {
61
62
  /**
62
- * HTML element that will disappear when overflowed
63
+ * HTML element that disappears when its group overflows.
63
64
  */
64
65
  element: HTMLElement;
66
+ /**
67
+ * Id of the group controlled by this divider.
68
+ */
65
69
  groupId: string;
66
70
  }
67
71
 
@@ -69,27 +73,45 @@ export declare interface OverflowDividerEntry {
69
73
  * Payload of the custom DOM event for overflow updates
70
74
  */
71
75
  export declare interface OverflowEventPayload {
76
+ /**
77
+ * Items currently visible in the container.
78
+ */
72
79
  visibleItems: OverflowItemEntry[];
80
+ /**
81
+ * Items currently moved to overflow.
82
+ */
73
83
  invisibleItems: OverflowItemEntry[];
84
+ /**
85
+ * Current visibility state by group id.
86
+ */
74
87
  groupVisibility: Record<string, OverflowGroupState>;
75
88
  }
76
89
 
90
+ /**
91
+ * Visibility state for an overflow group.
92
+ */
77
93
  export declare type OverflowGroupState = 'visible' | 'hidden' | 'overflow';
78
94
 
95
+ /**
96
+ * Tracked item in the overflow manager.
97
+ */
79
98
  export declare interface OverflowItemEntry {
80
99
  /**
81
- * HTML element that will be disappear when overflowed
100
+ * HTML element that disappears when the item overflows.
82
101
  */
83
102
  element: HTMLElement;
84
103
  /**
85
- * Lower priority items are invisible first when the container is overflowed
104
+ * Lower-priority items become invisible first when the container overflows.
86
105
  * @default 0
87
106
  */
88
107
  priority: number;
89
108
  /**
90
- * Specific id, used to track visibility and provide updates to consumers
109
+ * Stable item id used to track visibility and emit updates.
91
110
  */
92
111
  id: string;
112
+ /**
113
+ * Optional group id used to coordinate divider and grouped visibility states.
114
+ */
93
115
  groupId?: string;
94
116
  /**
95
117
  * If true, the item will never overflow and will always be visible.
@@ -100,17 +122,23 @@ export declare interface OverflowItemEntry {
100
122
  }
101
123
 
102
124
  /**
125
+ * Internal manager contract used to observe and compute priority overflow.
126
+ *
103
127
  * @internal
104
128
  */
105
129
  export declare interface OverflowManager {
106
130
  /**
107
131
  * Starts observing the container and managing the overflow state
108
132
  */
109
- observe: (container: HTMLElement, options: ObserveOptions) => void;
133
+ observe: (container: HTMLElement, options?: ObserveOptions) => void;
110
134
  /**
111
135
  * Stops observing the container
112
136
  */
113
137
  disconnect: () => void;
138
+ /**
139
+ * Updates engine options without restarting observation.
140
+ */
141
+ setOptions: (options: Partial<OverflowOptions>) => void;
114
142
  /**
115
143
  * Add overflow items
116
144
  */
@@ -144,6 +172,75 @@ export declare interface OverflowManager {
144
172
  * Unsets the overflow menu element
145
173
  */
146
174
  removeOverflowMenu: () => void;
175
+ /**
176
+ * Returns the current overflow snapshot.
177
+ */
178
+ getSnapshot: () => OverflowSnapshot;
179
+ /**
180
+ * Subscribes to snapshot changes.
181
+ */
182
+ subscribe: (listener: () => void) => () => void;
183
+ }
184
+
185
+ /**
186
+ * Options used to initialize or reconfigure overflow observation.
187
+ */
188
+ export declare interface OverflowOptions {
189
+ /**
190
+ * Padding in pixels reserved at the end of the container before overflow occurs.
191
+ * Useful for accounting for extra elements (for example an overflow menu button)
192
+ * or margins between items that are difficult to measure in JavaScript.
193
+ * @default 10
194
+ */
195
+ padding?: number;
196
+ /**
197
+ * Direction where items are removed when overflow occurs.
198
+ * @default end
199
+ */
200
+ overflowDirection?: OverflowDirection;
201
+ /**
202
+ * Overflow axis used for size measurement.
203
+ * @default horizontal
204
+ */
205
+ overflowAxis?: OverflowAxis;
206
+ /**
207
+ * Minimum number of items that must remain visible.
208
+ */
209
+ minimumVisible?: number;
210
+ /**
211
+ * Callback invoked when an individual item's visibility changes.
212
+ */
213
+ onUpdateItemVisibility: OnUpdateItemVisibility;
214
+ /**
215
+ * Callback invoked after overflow state is recomputed.
216
+ */
217
+ onUpdateOverflow: OnUpdateOverflow;
218
+ /**
219
+ * When true, reserve space as if the overflow menu were visible even with no overflowing items.
220
+ * @default false
221
+ */
222
+ hasHiddenItems?: boolean;
223
+ }
224
+
225
+ /**
226
+ * Indexed, immutable overflow state returned by `OverflowManager.getSnapshot`.
227
+ *
228
+ * Unlike {@link OverflowEventPayload}, this is shaped for O(1) consumer lookups (item/group
229
+ * visibility by id, item count) rather than ordered item entries.
230
+ */
231
+ export declare interface OverflowSnapshot {
232
+ /**
233
+ * Visibility of each registered item, keyed by item id.
234
+ */
235
+ itemVisibility: Record<string, boolean>;
236
+ /**
237
+ * Current visibility state by group id.
238
+ */
239
+ groupVisibility: Record<string, OverflowGroupState>;
240
+ /**
241
+ * Number of items currently moved to overflow (invisible).
242
+ */
243
+ invisibleItemCount: number;
147
244
  }
148
245
 
149
246
  export { }
package/lib/consts.js CHANGED
@@ -1,2 +1,10 @@
1
1
  export const DATA_OVERFLOWING = 'data-overflowing';
2
2
  export const DATA_OVERFLOW_GROUP = 'data-overflow-group';
3
+ /**
4
+ * An empty, frozen overflow snapshot used as the default before anything has been measured.
5
+ * @internal
6
+ */ export const EMPTY_SNAPSHOT = Object.freeze({
7
+ itemVisibility: {},
8
+ groupVisibility: {},
9
+ invisibleItemCount: 0
10
+ });
package/lib/consts.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/consts.ts"],"sourcesContent":["export const DATA_OVERFLOWING = 'data-overflowing';\nexport const DATA_OVERFLOW_GROUP = 'data-overflow-group';\n"],"names":["DATA_OVERFLOWING","DATA_OVERFLOW_GROUP"],"mappings":"AAAA,OAAO,MAAMA,mBAAmB,mBAAmB;AACnD,OAAO,MAAMC,sBAAsB,sBAAsB"}
1
+ {"version":3,"sources":["../src/consts.ts"],"sourcesContent":["import type { OverflowSnapshot } from './types';\n\nexport const DATA_OVERFLOWING = 'data-overflowing';\nexport const DATA_OVERFLOW_GROUP = 'data-overflow-group';\n\n/**\n * An empty, frozen overflow snapshot used as the default before anything has been measured.\n * @internal\n */\nexport const EMPTY_SNAPSHOT: OverflowSnapshot = Object.freeze({\n itemVisibility: {},\n groupVisibility: {},\n invisibleItemCount: 0,\n});\n"],"names":["DATA_OVERFLOWING","DATA_OVERFLOW_GROUP","EMPTY_SNAPSHOT","Object","freeze","itemVisibility","groupVisibility","invisibleItemCount"],"mappings":"AAEA,OAAO,MAAMA,mBAAmB,mBAAmB;AACnD,OAAO,MAAMC,sBAAsB,sBAAsB;AAEzD;;;CAGC,GACD,OAAO,MAAMC,iBAAmCC,OAAOC,MAAM,CAAC;IAC5DC,gBAAgB,CAAC;IACjBC,iBAAiB,CAAC;IAClBC,oBAAoB;AACtB,GAAG"}
package/lib/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export { createOverflowManager } from './overflowManager';
2
+ export { EMPTY_SNAPSHOT } from './consts';
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { createOverflowManager } from './overflowManager';\nexport type {\n ObserveOptions,\n OnUpdateItemVisibility,\n OnUpdateItemVisibilityPayload,\n OnUpdateOverflow,\n OverflowAxis,\n OverflowDirection,\n OverflowEventPayload,\n OverflowGroupState,\n OverflowItemEntry,\n OverflowDividerEntry,\n OverflowManager,\n} from './types';\n"],"names":["createOverflowManager"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,oBAAoB"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { createOverflowManager } from './overflowManager';\nexport { EMPTY_SNAPSHOT } from './consts';\nexport type {\n ObserveOptions,\n OverflowOptions,\n OnUpdateItemVisibility,\n OnUpdateItemVisibilityPayload,\n OnUpdateOverflow,\n OverflowAxis,\n OverflowDirection,\n OverflowEventPayload,\n OverflowGroupState,\n OverflowItemEntry,\n OverflowDividerEntry,\n OverflowManager,\n OverflowSnapshot,\n} from './types';\n"],"names":["createOverflowManager","EMPTY_SNAPSHOT"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,oBAAoB;AAC1D,SAASC,cAAc,QAAQ,WAAW"}
@@ -1,11 +1,25 @@
1
- import { DATA_OVERFLOWING, DATA_OVERFLOW_GROUP } from './consts';
1
+ import { DATA_OVERFLOWING, DATA_OVERFLOW_GROUP, EMPTY_SNAPSHOT } from './consts';
2
2
  import { observeResize } from './createResizeObserver';
3
3
  import { debounce } from './debounce';
4
4
  import { createPriorityQueue } from './priorityQueue';
5
+ const DEFAULT_OPTIONS = {
6
+ overflowAxis: 'horizontal',
7
+ overflowDirection: 'end',
8
+ padding: 10,
9
+ minimumVisible: 0,
10
+ hasHiddenItems: false,
11
+ onUpdateItemVisibility: ()=>{
12
+ /* noop */ },
13
+ onUpdateOverflow: ()=>{
14
+ /* noop */ }
15
+ };
5
16
  /**
17
+ * Creates an overflow manager instance for a single container.
18
+ *
6
19
  * @internal
20
+ * @param initialOptions - Initial observe options. Missing values are filled with defaults.
7
21
  * @returns overflow manager instance
8
- */ export function createOverflowManager() {
22
+ */ export function createOverflowManager(initialOptions = {}) {
9
23
  // calls to `offsetWidth or offsetHeight` can happen multiple times in an update
10
24
  // Use a cache to avoid causing too many recalcs and avoid scripting time to meausure sizes
11
25
  const sizeCache = new Map();
@@ -17,17 +31,19 @@ import { createPriorityQueue } from './priorityQueue';
17
31
  // Initially true to force dispatch on first mount
18
32
  let forceDispatch = true;
19
33
  const options = {
20
- padding: 10,
21
- overflowAxis: 'horizontal',
22
- overflowDirection: 'end',
23
- minimumVisible: 0,
24
- onUpdateItemVisibility: ()=>undefined,
25
- onUpdateOverflow: ()=>undefined,
26
- hasHiddenItems: false
34
+ ...DEFAULT_OPTIONS,
35
+ ...initialOptions
27
36
  };
28
37
  const overflowItems = {};
29
38
  const overflowDividers = {};
30
- let disposeResizeObserver = ()=>null;
39
+ const listeners = new Set();
40
+ let disposeResizeObserver = ()=>{
41
+ /* noop */ };
42
+ let snapshot = EMPTY_SNAPSHOT;
43
+ const takeSnapshot = (nextSnapshot)=>{
44
+ snapshot = nextSnapshot;
45
+ listeners.forEach((listener)=>listener());
46
+ };
31
47
  const getNextItem = (queueToDequeue, queueToEnqueue)=>{
32
48
  const nextItem = queueToDequeue.dequeue();
33
49
  queueToEnqueue.enqueue(nextItem);
@@ -68,7 +84,10 @@ import { createPriorityQueue } from './priorityQueue';
68
84
  const invisibleItemQueue = createPriorityQueue((a, b)=>-1 * compareItems(a, b));
69
85
  const visibleItemQueue = createPriorityQueue(compareItems);
70
86
  function occupiedSize() {
71
- const totalItemSize = visibleItemQueue.all().map((id)=>overflowItems[id].element).map(getOffsetSize).reduce((prev, current)=>prev + current, 0);
87
+ let totalItemSize = 0;
88
+ for (const id of visibleItemQueue){
89
+ totalItemSize += getOffsetSize(overflowItems[id].element);
90
+ }
72
91
  const totalDividerSize = Object.entries(groupManager.groupVisibility()).reduce((acc, [id, state])=>acc + (state !== 'hidden' && overflowDividers[id] ? getOffsetSize(overflowDividers[id].element) : 0), 0);
73
92
  const overflowMenuSize = (invisibleItemQueue.size() > 0 || options.hasHiddenItems) && overflowMenu ? getOffsetSize(overflowMenu) : 0;
74
93
  return totalItemSize + totalDividerSize + overflowMenuSize;
@@ -102,16 +121,35 @@ import { createPriorityQueue } from './priorityQueue';
102
121
  }
103
122
  };
104
123
  const dispatchOverflowUpdate = ()=>{
105
- const visibleItemIds = visibleItemQueue.all();
106
- const invisibleItemIds = invisibleItemQueue.all();
107
- const visibleItems = visibleItemIds.map((itemId)=>overflowItems[itemId]);
108
- const invisibleItems = invisibleItemIds.map((itemId)=>overflowItems[itemId]);
124
+ const groupVisibility = groupManager.groupVisibility();
125
+ // Build the legacy ordered-entry arrays and the snapshot's id -> visible map in a single pass
126
+ // over each queue.
127
+ const itemVisibility = {};
128
+ const visibleItems = [];
129
+ const invisibleItems = [];
130
+ for (const itemId of visibleItemQueue){
131
+ itemVisibility[itemId] = true;
132
+ visibleItems.push(overflowItems[itemId]);
133
+ }
134
+ for (const itemId of invisibleItemQueue){
135
+ itemVisibility[itemId] = false;
136
+ invisibleItems.push(overflowItems[itemId]);
137
+ }
138
+ // Set the snapshot first so `getSnapshot()` is current for both subscribers and any
139
+ // `onUpdateOverflow` consumer that reads it.
140
+ takeSnapshot({
141
+ itemVisibility,
142
+ groupVisibility,
143
+ invisibleItemCount: invisibleItems.length
144
+ });
145
+ // Legacy event payload: ordered item entries for `onUpdateOverflow` consumers.
109
146
  options.onUpdateOverflow({
110
147
  visibleItems,
111
148
  invisibleItems,
112
- groupVisibility: groupManager.groupVisibility()
149
+ groupVisibility
113
150
  });
114
151
  };
152
+ const getSnapshot = ()=>snapshot;
115
153
  const processOverflowItems = ()=>{
116
154
  if (!container) {
117
155
  return false;
@@ -153,39 +191,80 @@ import { createPriorityQueue } from './priorityQueue';
153
191
  }
154
192
  };
155
193
  const update = debounce(forceUpdate);
156
- const observe = (observedContainer, userOptions)=>{
194
+ const setOptions = (nextOptions)=>{
195
+ if (options === nextOptions) {
196
+ return;
197
+ }
198
+ const shouldTriggerUpdate = nextOptions.overflowAxis && options.overflowAxis !== nextOptions.overflowAxis || nextOptions.overflowDirection && options.overflowDirection !== nextOptions.overflowDirection || nextOptions.padding && options.padding !== nextOptions.padding || nextOptions.minimumVisible && options.minimumVisible !== nextOptions.minimumVisible || nextOptions.hasHiddenItems && options.hasHiddenItems !== nextOptions.hasHiddenItems;
199
+ Object.assign(options, nextOptions);
200
+ if (shouldTriggerUpdate) {
201
+ forceDispatch = true;
202
+ update();
203
+ }
204
+ };
205
+ const observe = (observedContainer, observeOptions)=>{
206
+ const { forceUpdate: shouldForceUpdate, ...userOptions } = observeOptions !== null && observeOptions !== void 0 ? observeOptions : {};
157
207
  Object.assign(options, userOptions);
158
- observing = true;
159
- Object.values(overflowItems).forEach((item)=>visibleItemQueue.enqueue(item.id));
208
+ Object.values(overflowItems).forEach((item)=>{
209
+ if (!visibleItemQueue.contains(item.id) && !invisibleItemQueue.contains(item.id)) {
210
+ visibleItemQueue.enqueue(item.id);
211
+ }
212
+ });
160
213
  container = observedContainer;
214
+ observing = true;
161
215
  disposeResizeObserver = observeResize(container, (entries)=>{
162
216
  if (!entries[0] || !container) {
163
217
  return;
164
218
  }
165
219
  update();
166
220
  });
221
+ if (shouldForceUpdate && getClientSize(observedContainer) > 0) {
222
+ forceUpdate();
223
+ }
167
224
  };
168
- const addItem = (item)=>{
169
- if (overflowItems[item.id]) {
225
+ const disconnect = ()=>{
226
+ disposeResizeObserver();
227
+ disposeResizeObserver = ()=>{
228
+ /* noop */ };
229
+ // reset flags
230
+ container = undefined;
231
+ observing = false;
232
+ forceDispatch = true;
233
+ // clear all entries
234
+ Object.keys(overflowItems).forEach((itemId)=>removeItem(itemId));
235
+ Object.keys(overflowDividers).forEach((dividerId)=>removeDivider(dividerId));
236
+ removeOverflowMenu();
237
+ sizeCache.clear();
238
+ // Reset the snapshot during teardown, but do not broadcast a final update.
239
+ // Consumers unsubscribe as part of unmount, and a disconnect-time notification can race
240
+ // those cleanups and dispatch into already-unmounting React listeners.
241
+ snapshot = EMPTY_SNAPSHOT;
242
+ };
243
+ const addItem = (items)=>{
244
+ if (overflowItems[items.id]) {
170
245
  return;
171
246
  }
172
- overflowItems[item.id] = item;
247
+ overflowItems[items.id] = items;
173
248
  // some options can affect priority which are only set on `observe`
174
249
  if (observing) {
175
250
  // Updates to elements might not change the queue tops
176
251
  // i.e. new element is enqueued but the top of the queue stays the same
177
252
  // force a dispatch on the next batched update
178
253
  forceDispatch = true;
179
- visibleItemQueue.enqueue(item.id);
254
+ visibleItemQueue.enqueue(items.id);
255
+ update();
180
256
  }
181
- if (item.groupId) {
182
- groupManager.addItem(item.id, item.groupId);
183
- item.element.setAttribute(DATA_OVERFLOW_GROUP, item.groupId);
257
+ if (items.groupId) {
258
+ groupManager.addItem(items.id, items.groupId);
259
+ items.element.setAttribute(DATA_OVERFLOW_GROUP, items.groupId);
184
260
  }
185
- update();
186
261
  };
187
262
  const addOverflowMenu = (el)=>{
188
263
  overflowMenu = el;
264
+ if (observing) {
265
+ forceDispatch = true;
266
+ update();
267
+ }
189
268
  };
190
269
  const addDivider = (divider)=>{
191
270
  if (!divider.groupId || overflowDividers[divider.groupId]) {
@@ -196,6 +275,10 @@ import { createPriorityQueue } from './priorityQueue';
196
275
  };
197
276
  const removeOverflowMenu = ()=>{
198
277
  overflowMenu = undefined;
278
+ if (observing) {
279
+ forceDispatch = true;
280
+ update();
281
+ }
199
282
  };
200
283
  const removeDivider = (groupId)=>{
201
284
  if (!overflowDividers[groupId]) {
@@ -225,19 +308,15 @@ import { createPriorityQueue } from './priorityQueue';
225
308
  }
226
309
  sizeCache.delete(item.element);
227
310
  delete overflowItems[itemId];
228
- update();
311
+ if (observing) {
312
+ update();
313
+ }
229
314
  };
230
- const disconnect = ()=>{
231
- disposeResizeObserver();
232
- // reset flags
233
- container = undefined;
234
- observing = false;
235
- forceDispatch = true;
236
- // clear all entries
237
- Object.keys(overflowItems).forEach((itemId)=>removeItem(itemId));
238
- Object.keys(overflowDividers).forEach((dividerId)=>removeDivider(dividerId));
239
- removeOverflowMenu();
240
- sizeCache.clear();
315
+ const subscribe = (listener)=>{
316
+ listeners.add(listener);
317
+ return ()=>{
318
+ listeners.delete(listener);
319
+ };
241
320
  };
242
321
  return {
243
322
  addItem,
@@ -249,7 +328,10 @@ import { createPriorityQueue } from './priorityQueue';
249
328
  addOverflowMenu,
250
329
  removeOverflowMenu,
251
330
  addDivider,
252
- removeDivider
331
+ removeDivider,
332
+ setOptions,
333
+ getSnapshot,
334
+ subscribe
253
335
  };
254
336
  }
255
337
  const createGroupManager = ()=>{