@fluentui/priority-overflow 9.2.1 → 9.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,35 @@
1
1
  # Change Log - @fluentui/priority-overflow
2
2
 
3
- This log was last generated on Fri, 31 Oct 2025 16:17:34 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 24 Jun 2026 11:03:53 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.4.0](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.4.0)
8
+
9
+ Wed, 24 Jun 2026 11:03:53 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.3.0..@fluentui/priority-overflow_v9.4.0)
11
+
12
+ ### Minor changes
13
+
14
+ - 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)
15
+ - feat: expose getSnapshot and subscribe on OverflowManager ([PR #36263](https://github.com/microsoft/fluentui/pull/36263) by bsunderhus@microsoft.com)
16
+
17
+ ### Patches
18
+
19
+ - fix: recompute overflow eagerly when the overflow menu attaches or detaches ([PR #36264](https://github.com/microsoft/fluentui/pull/36264) by bsunderhus@microsoft.com)
20
+
21
+ ## [9.3.0](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.3.0)
22
+
23
+ Thu, 12 Feb 2026 10:46:12 GMT
24
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.2.1..@fluentui/priority-overflow_v9.3.0)
25
+
26
+ ### Minor changes
27
+
28
+ - feat: add support for pinned items ([PR #35712](https://github.com/microsoft/fluentui/pull/35712) by olfedias@microsoft.com)
29
+
7
30
  ## [9.2.1](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.2.1)
8
31
 
9
- Fri, 31 Oct 2025 16:17:34 GMT
32
+ Fri, 31 Oct 2025 16:22:02 GMT
10
33
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.2.0..@fluentui/priority-overflow_v9.2.1)
11
34
 
12
35
  ### Patches
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 be 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,42 +73,72 @@ 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;
116
+ /**
117
+ * If true, the item will never overflow and will always be visible.
118
+ * Pinned items are excluded from the overflow count.
119
+ * @default false
120
+ */
121
+ pinned?: boolean;
94
122
  }
95
123
 
96
124
  /**
125
+ * Internal manager contract used to observe and compute priority overflow.
126
+ *
97
127
  * @internal
98
128
  */
99
129
  export declare interface OverflowManager {
100
130
  /**
101
131
  * Starts observing the container and managing the overflow state
102
132
  */
103
- observe: (container: HTMLElement, options: ObserveOptions) => void;
133
+ observe: (container: HTMLElement, options?: ObserveOptions) => void;
104
134
  /**
105
135
  * Stops observing the container
106
136
  */
107
137
  disconnect: () => void;
138
+ /**
139
+ * Updates engine options without restarting observation.
140
+ */
141
+ setOptions: (options: Partial<OverflowOptions>) => void;
108
142
  /**
109
143
  * Add overflow items
110
144
  */
@@ -138,6 +172,75 @@ export declare interface OverflowManager {
138
172
  * Unsets the overflow menu element
139
173
  */
140
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;
141
244
  }
142
245
 
143
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);
@@ -45,6 +61,10 @@ import { createPriorityQueue } from './priorityQueue';
45
61
  if (!lte || !rte) {
46
62
  return lte ? 1 : -1;
47
63
  }
64
+ // Pinned items have "infinite" priority - they should never be hidden
65
+ if (lte.pinned !== rte.pinned) {
66
+ return lte.pinned ? 1 : -1;
67
+ }
48
68
  if (lte.priority !== rte.priority) {
49
69
  return lte.priority > rte.priority ? 1 : -1;
50
70
  }
@@ -64,7 +84,10 @@ import { createPriorityQueue } from './priorityQueue';
64
84
  const invisibleItemQueue = createPriorityQueue((a, b)=>-1 * compareItems(a, b));
65
85
  const visibleItemQueue = createPriorityQueue(compareItems);
66
86
  function occupiedSize() {
67
- 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
+ }
68
91
  const totalDividerSize = Object.entries(groupManager.groupVisibility()).reduce((acc, [id, state])=>acc + (state !== 'hidden' && overflowDividers[id] ? getOffsetSize(overflowDividers[id].element) : 0), 0);
69
92
  const overflowMenuSize = (invisibleItemQueue.size() > 0 || options.hasHiddenItems) && overflowMenu ? getOffsetSize(overflowMenu) : 0;
70
93
  return totalItemSize + totalDividerSize + overflowMenuSize;
@@ -98,16 +121,35 @@ import { createPriorityQueue } from './priorityQueue';
98
121
  }
99
122
  };
100
123
  const dispatchOverflowUpdate = ()=>{
101
- const visibleItemIds = visibleItemQueue.all();
102
- const invisibleItemIds = invisibleItemQueue.all();
103
- const visibleItems = visibleItemIds.map((itemId)=>overflowItems[itemId]);
104
- 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.
105
146
  options.onUpdateOverflow({
106
147
  visibleItems,
107
148
  invisibleItems,
108
- groupVisibility: groupManager.groupVisibility()
149
+ groupVisibility
109
150
  });
110
151
  };
152
+ const getSnapshot = ()=>snapshot;
111
153
  const processOverflowItems = ()=>{
112
154
  if (!container) {
113
155
  return false;
@@ -130,6 +172,12 @@ import { createPriorityQueue } from './priorityQueue';
130
172
  }
131
173
  // Remove items until there's no more overflow
132
174
  while(occupiedSize() > availableSize && visibleItemQueue.size() > options.minimumVisible){
175
+ var _overflowItems_nextItemId;
176
+ const nextItemId = visibleItemQueue.peek();
177
+ // Never hide pinned items - they should always remain visible
178
+ if (nextItemId && ((_overflowItems_nextItemId = overflowItems[nextItemId]) === null || _overflowItems_nextItemId === void 0 ? void 0 : _overflowItems_nextItemId.pinned)) {
179
+ break;
180
+ }
133
181
  hideItem();
134
182
  }
135
183
  }
@@ -143,39 +191,78 @@ import { createPriorityQueue } from './priorityQueue';
143
191
  }
144
192
  };
145
193
  const update = debounce(forceUpdate);
146
- 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 : {};
147
207
  Object.assign(options, userOptions);
148
- observing = true;
149
- 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
+ });
150
213
  container = observedContainer;
214
+ observing = true;
151
215
  disposeResizeObserver = observeResize(container, (entries)=>{
152
216
  if (!entries[0] || !container) {
153
217
  return;
154
218
  }
155
219
  update();
156
220
  });
221
+ if (shouldForceUpdate && getClientSize(observedContainer) > 0) {
222
+ forceUpdate();
223
+ }
224
+ };
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
+ // notify subscribers that the manager is no longer tracking anything
239
+ takeSnapshot(EMPTY_SNAPSHOT);
157
240
  };
158
- const addItem = (item)=>{
159
- if (overflowItems[item.id]) {
241
+ const addItem = (items)=>{
242
+ if (overflowItems[items.id]) {
160
243
  return;
161
244
  }
162
- overflowItems[item.id] = item;
245
+ overflowItems[items.id] = items;
163
246
  // some options can affect priority which are only set on `observe`
164
247
  if (observing) {
165
248
  // Updates to elements might not change the queue tops
166
249
  // i.e. new element is enqueued but the top of the queue stays the same
167
250
  // force a dispatch on the next batched update
168
251
  forceDispatch = true;
169
- visibleItemQueue.enqueue(item.id);
252
+ visibleItemQueue.enqueue(items.id);
253
+ update();
170
254
  }
171
- if (item.groupId) {
172
- groupManager.addItem(item.id, item.groupId);
173
- item.element.setAttribute(DATA_OVERFLOW_GROUP, item.groupId);
255
+ if (items.groupId) {
256
+ groupManager.addItem(items.id, items.groupId);
257
+ items.element.setAttribute(DATA_OVERFLOW_GROUP, items.groupId);
174
258
  }
175
- update();
176
259
  };
177
260
  const addOverflowMenu = (el)=>{
178
261
  overflowMenu = el;
262
+ if (observing) {
263
+ forceDispatch = true;
264
+ update();
265
+ }
179
266
  };
180
267
  const addDivider = (divider)=>{
181
268
  if (!divider.groupId || overflowDividers[divider.groupId]) {
@@ -186,6 +273,10 @@ import { createPriorityQueue } from './priorityQueue';
186
273
  };
187
274
  const removeOverflowMenu = ()=>{
188
275
  overflowMenu = undefined;
276
+ if (observing) {
277
+ forceDispatch = true;
278
+ update();
279
+ }
189
280
  };
190
281
  const removeDivider = (groupId)=>{
191
282
  if (!overflowDividers[groupId]) {
@@ -215,19 +306,15 @@ import { createPriorityQueue } from './priorityQueue';
215
306
  }
216
307
  sizeCache.delete(item.element);
217
308
  delete overflowItems[itemId];
218
- update();
309
+ if (observing) {
310
+ update();
311
+ }
219
312
  };
220
- const disconnect = ()=>{
221
- disposeResizeObserver();
222
- // reset flags
223
- container = undefined;
224
- observing = false;
225
- forceDispatch = true;
226
- // clear all entries
227
- Object.keys(overflowItems).forEach((itemId)=>removeItem(itemId));
228
- Object.keys(overflowDividers).forEach((dividerId)=>removeDivider(dividerId));
229
- removeOverflowMenu();
230
- sizeCache.clear();
313
+ const subscribe = (listener)=>{
314
+ listeners.add(listener);
315
+ return ()=>{
316
+ listeners.delete(listener);
317
+ };
231
318
  };
232
319
  return {
233
320
  addItem,
@@ -239,7 +326,10 @@ import { createPriorityQueue } from './priorityQueue';
239
326
  addOverflowMenu,
240
327
  removeOverflowMenu,
241
328
  addDivider,
242
- removeDivider
329
+ removeDivider,
330
+ setOptions,
331
+ getSnapshot,
332
+ subscribe
243
333
  };
244
334
  }
245
335
  const createGroupManager = ()=>{