@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 +25 -2
- package/dist/index.d.ts +142 -39
- package/lib/consts.js +8 -0
- package/lib/consts.js.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/overflowManager.js +130 -40
- package/lib/overflowManager.js.map +1 -1
- package/lib/priorityQueue.js +9 -5
- package/lib/priorityQueue.js.map +1 -1
- package/lib/types.js +4 -0
- package/lib/types.js.map +1 -1
- package/lib-commonjs/consts.js +8 -0
- package/lib-commonjs/consts.js.map +1 -1
- package/lib-commonjs/index.js +12 -3
- package/lib-commonjs/index.js.map +1 -1
- package/lib-commonjs/overflowManager.js +126 -39
- package/lib-commonjs/overflowManager.js.map +1 -1
- package/lib-commonjs/priorityQueue.js +9 -5
- package/lib-commonjs/priorityQueue.js.map +1 -1
- package/lib-commonjs/types.js +3 -1
- package/lib-commonjs/types.js.map +1 -1
- package/package.json +1 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,35 @@
|
|
|
1
1
|
# Change Log - @fluentui/priority-overflow
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
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:
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
|
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
|
|
100
|
+
* HTML element that disappears when the item overflows.
|
|
82
101
|
*/
|
|
83
102
|
element: HTMLElement;
|
|
84
103
|
/**
|
|
85
|
-
* Lower
|
|
104
|
+
* Lower-priority items become invisible first when the container overflows.
|
|
86
105
|
* @default 0
|
|
87
106
|
*/
|
|
88
107
|
priority: number;
|
|
89
108
|
/**
|
|
90
|
-
*
|
|
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
|
|
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":["
|
|
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
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"}
|
package/lib/overflowManager.js
CHANGED
|
@@ -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
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
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
|
|
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
|
|
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
|
-
|
|
149
|
-
|
|
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 = (
|
|
159
|
-
if (overflowItems[
|
|
241
|
+
const addItem = (items)=>{
|
|
242
|
+
if (overflowItems[items.id]) {
|
|
160
243
|
return;
|
|
161
244
|
}
|
|
162
|
-
overflowItems[
|
|
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(
|
|
252
|
+
visibleItemQueue.enqueue(items.id);
|
|
253
|
+
update();
|
|
170
254
|
}
|
|
171
|
-
if (
|
|
172
|
-
groupManager.addItem(
|
|
173
|
-
|
|
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
|
-
|
|
309
|
+
if (observing) {
|
|
310
|
+
update();
|
|
311
|
+
}
|
|
219
312
|
};
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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 = ()=>{
|