@fluentui/priority-overflow 9.0.3 → 9.1.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.json CHANGED
@@ -2,7 +2,67 @@
2
2
  "name": "@fluentui/priority-overflow",
3
3
  "entries": [
4
4
  {
5
- "date": "Fri, 12 May 2023 20:22:38 GMT",
5
+ "date": "Mon, 26 Jun 2023 09:51:04 GMT",
6
+ "tag": "@fluentui/priority-overflow_v9.1.1",
7
+ "version": "9.1.1",
8
+ "comments": {
9
+ "patch": [
10
+ {
11
+ "author": "vkozlova@microsoft.com",
12
+ "package": "@fluentui/priority-overflow",
13
+ "commit": "d93cb0b8cb80f56e753ad18c645eeb84a9c10256",
14
+ "comment": "fix: remove overflow menu if the last overflowed item can take its place"
15
+ }
16
+ ]
17
+ }
18
+ },
19
+ {
20
+ "date": "Tue, 20 Jun 2023 12:38:54 GMT",
21
+ "tag": "@fluentui/priority-overflow_v9.1.0",
22
+ "version": "9.1.0",
23
+ "comments": {
24
+ "minor": [
25
+ {
26
+ "author": "vkozlova@microsoft.com",
27
+ "package": "@fluentui/priority-overflow",
28
+ "commit": "4dedf40597f3b5cfa63d8f2e28a79276eb816bda",
29
+ "comment": "feat: Added support for custom divider"
30
+ }
31
+ ]
32
+ }
33
+ },
34
+ {
35
+ "date": "Wed, 24 May 2023 20:45:22 GMT",
36
+ "tag": "@fluentui/priority-overflow_v9.0.3",
37
+ "version": "9.0.3",
38
+ "comments": {
39
+ "none": [
40
+ {
41
+ "author": "olfedias@microsoft.com",
42
+ "package": "@fluentui/priority-overflow",
43
+ "commit": "69e0617a93cb44ef42f3bd19284b7dc5fe27fed3",
44
+ "comment": "chore: update test-ssr script"
45
+ }
46
+ ]
47
+ }
48
+ },
49
+ {
50
+ "date": "Thu, 18 May 2023 00:39:01 GMT",
51
+ "tag": "@fluentui/priority-overflow_v9.0.3",
52
+ "version": "9.0.3",
53
+ "comments": {
54
+ "none": [
55
+ {
56
+ "author": "olfedias@microsoft.com",
57
+ "package": "@fluentui/priority-overflow",
58
+ "commit": "06cd515eda59a3078bfe32f9cc7c1f281cd20208",
59
+ "comment": "chore: add test-ssr script to v9 packages"
60
+ }
61
+ ]
62
+ }
63
+ },
64
+ {
65
+ "date": "Fri, 12 May 2023 20:28:09 GMT",
6
66
  "tag": "@fluentui/priority-overflow_v9.0.3",
7
67
  "version": "9.0.3",
8
68
  "comments": {
package/CHANGELOG.md CHANGED
@@ -1,12 +1,30 @@
1
1
  # Change Log - @fluentui/priority-overflow
2
2
 
3
- This log was last generated on Fri, 12 May 2023 20:22:38 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 26 Jun 2023 09:51:04 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.1.1](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.1)
8
+
9
+ Mon, 26 Jun 2023 09:51:04 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.0..@fluentui/priority-overflow_v9.1.1)
11
+
12
+ ### Patches
13
+
14
+ - fix: remove overflow menu if the last overflowed item can take its place ([PR #28285](https://github.com/microsoft/fluentui/pull/28285) by vkozlova@microsoft.com)
15
+
16
+ ## [9.1.0](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.0)
17
+
18
+ Tue, 20 Jun 2023 12:38:54 GMT
19
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.3..@fluentui/priority-overflow_v9.1.0)
20
+
21
+ ### Minor changes
22
+
23
+ - feat: Added support for custom divider ([PR #28011](https://github.com/microsoft/fluentui/pull/28011) by vkozlova@microsoft.com)
24
+
7
25
  ## [9.0.3](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.0.3)
8
26
 
9
- Fri, 12 May 2023 20:22:38 GMT
27
+ Fri, 12 May 2023 20:28:09 GMT
10
28
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.2..@fluentui/priority-overflow_v9.0.3)
11
29
 
12
30
  ### Patches
package/dist/index.d.ts CHANGED
@@ -52,6 +52,14 @@ export declare type OverflowAxis = 'horizontal' | 'vertical';
52
52
 
53
53
  export declare type OverflowDirection = 'start' | 'end';
54
54
 
55
+ export declare interface OverflowDividerEntry {
56
+ /**
57
+ * HTML element that will be disappear when overflowed
58
+ */
59
+ element: HTMLElement;
60
+ groupId: string;
61
+ }
62
+
55
63
  /**
56
64
  * Payload of the custom DOM event for overflow updates
57
65
  */
@@ -113,6 +121,14 @@ export declare interface OverflowManager {
113
121
  * available space and check if additional items need to overflow
114
122
  */
115
123
  addOverflowMenu: (element: HTMLElement) => void;
124
+ /**
125
+ * Add overflow divider
126
+ */
127
+ addDivider: (divider: OverflowDividerEntry) => void;
128
+ /**
129
+ * Remove overflow divider
130
+ */
131
+ removeDivider: (groupId: string) => void;
116
132
  /**
117
133
  * Unsets the overflow menu element
118
134
  */
package/lib/consts.js ADDED
@@ -0,0 +1,2 @@
1
+ export const DATA_OVERFLOWING = 'data-overflowing';
2
+ export const DATA_OVERFLOW_GROUP = 'data-overflow-group';
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["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"}
package/lib/debounce.js CHANGED
@@ -3,18 +3,17 @@
3
3
  * https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide
4
4
  * @param fn - Function to debounce
5
5
  * @returns debounced function
6
- */export function debounce(fn) {
7
- let pending;
8
- return () => {
9
- if (!pending) {
10
- pending = true;
11
- queueMicrotask(() => {
12
- // Need to set pending to `false` before the debounced function is run.
13
- // React can actually interrupt the function while it's running!
14
- pending = false;
15
- fn();
16
- });
17
- }
18
- };
6
+ */ export function debounce(fn) {
7
+ let pending;
8
+ return ()=>{
9
+ if (!pending) {
10
+ pending = true;
11
+ queueMicrotask(()=>{
12
+ // Need to set pending to `false` before the debounced function is run.
13
+ // React can actually interrupt the function while it's running!
14
+ pending = false;
15
+ fn();
16
+ });
17
+ }
18
+ };
19
19
  }
20
- //# sourceMappingURL=debounce.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["debounce","fn","pending","queueMicrotask"],"sources":["../src/debounce.ts"],"sourcesContent":["/**\n * Microtask debouncer\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide\n * @param fn - Function to debounce\n * @returns debounced function\n */\nexport function debounce(fn: Function) {\n let pending: boolean;\n return () => {\n if (!pending) {\n pending = true;\n queueMicrotask(() => {\n // Need to set pending to `false` before the debounced function is run.\n // React can actually interrupt the function while it's running!\n pending = false;\n fn();\n });\n }\n };\n}\n"],"mappings":"AAAA;;;;;GAMA,OAAO,SAASA,SAASC,EAAY,EAAE;EACrC,IAAIC,OAAA;EACJ,OAAO,MAAM;IACX,IAAI,CAACA,OAAA,EAAS;MACZA,OAAA,GAAU,IAAI;MACdC,cAAA,CAAe,MAAM;QACnB;QACA;QACAD,OAAA,GAAU,KAAK;QACfD,EAAA;MACF;IACF;EACF;AACF"}
1
+ {"version":3,"sources":["debounce.ts"],"sourcesContent":["/**\n * Microtask debouncer\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide\n * @param fn - Function to debounce\n * @returns debounced function\n */\nexport function debounce(fn: Function) {\n let pending: boolean;\n return () => {\n if (!pending) {\n pending = true;\n queueMicrotask(() => {\n // Need to set pending to `false` before the debounced function is run.\n // React can actually interrupt the function while it's running!\n pending = false;\n fn();\n });\n }\n };\n}\n"],"names":["debounce","fn","pending","queueMicrotask"],"mappings":"AAAA;;;;;CAKC,GACD,OAAO,SAASA,SAASC,EAAY,EAAE;IACrC,IAAIC;IACJ,OAAO,IAAM;QACX,IAAI,CAACA,SAAS;YACZA,UAAU,IAAI;YACdC,eAAe,IAAM;gBACnB,uEAAuE;gBACvE,gEAAgE;gBAChED,UAAU,KAAK;gBACfD;YACF;QACF,CAAC;IACH;AACF,CAAC"}
package/lib/index.js CHANGED
@@ -1,2 +1 @@
1
1
  export { createOverflowManager } from './overflowManager';
2
- //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"names":["createOverflowManager"],"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 OverflowManager,\n} from './types';\n"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ"}
1
+ {"version":3,"sources":["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,218 +1,270 @@
1
+ var _groups, _groupId;
2
+ import { DATA_OVERFLOWING, DATA_OVERFLOW_GROUP } from './consts';
1
3
  import { debounce } from './debounce';
2
4
  import { createPriorityQueue } from './priorityQueue';
3
5
  /**
4
6
  * @internal
5
7
  * @returns overflow manager instance
6
- */
7
- export function createOverflowManager() {
8
- let container;
9
- let overflowMenu;
10
- // Set as true when resize observer is observing
11
- let observing = false;
12
- // If true, next update will dispatch to onUpdateOverflow even if queue top states don't change
13
- // Initially true to force dispatch on first mount
14
- let forceDispatch = true;
15
- const options = {
16
- padding: 10,
17
- overflowAxis: 'horizontal',
18
- overflowDirection: 'end',
19
- minimumVisible: 0,
20
- onUpdateItemVisibility: () => undefined,
21
- onUpdateOverflow: () => undefined
22
- };
23
- const overflowItems = {};
24
- const overflowGroups = {};
25
- const resizeObserver = new ResizeObserver(entries => {
26
- if (!entries[0] || !container) {
27
- return;
28
- }
29
- update();
30
- });
31
- const invisibleItemQueue = createPriorityQueue((a, b) => {
32
- const itemA = overflowItems[a];
33
- const itemB = overflowItems[b];
34
- // Higher priority at the top of the queue
35
- const priority = itemB.priority - itemA.priority;
36
- if (priority !== 0) {
37
- return priority;
38
- }
39
- const positionStatusBit = options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_FOLLOWING : Node.DOCUMENT_POSITION_PRECEDING;
40
- // equal priority, use DOM order
41
- // eslint-disable-next-line no-bitwise
42
- return itemA.element.compareDocumentPosition(itemB.element) & positionStatusBit ? -1 : 1;
43
- });
44
- const visibleItemQueue = createPriorityQueue((a, b) => {
45
- const itemA = overflowItems[a];
46
- const itemB = overflowItems[b];
47
- // Lower priority at the top of the queue
48
- const priority = itemA.priority - itemB.priority;
49
- if (priority !== 0) {
50
- return priority;
51
- }
52
- const positionStatusBit = options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_PRECEDING : Node.DOCUMENT_POSITION_FOLLOWING;
53
- // equal priority, use DOM order
54
- // eslint-disable-next-line no-bitwise
55
- return itemA.element.compareDocumentPosition(itemB.element) & positionStatusBit ? -1 : 1;
56
- });
57
- const getOffsetSize = el => {
58
- return options.overflowAxis === 'horizontal' ? el.offsetWidth : el.offsetHeight;
59
- };
60
- const makeItemVisible = () => {
61
- const nextVisible = invisibleItemQueue.dequeue();
62
- visibleItemQueue.enqueue(nextVisible);
63
- const item = overflowItems[nextVisible];
64
- options.onUpdateItemVisibility({
65
- item,
66
- visible: true
67
- });
68
- if (item.groupId) {
69
- overflowGroups[item.groupId].invisibleItemIds.delete(item.id);
70
- overflowGroups[item.groupId].visibleItemIds.add(item.id);
71
- }
72
- return getOffsetSize(item.element);
73
- };
74
- const makeItemInvisible = () => {
75
- const nextInvisible = visibleItemQueue.dequeue();
76
- invisibleItemQueue.enqueue(nextInvisible);
77
- const item = overflowItems[nextInvisible];
78
- const width = getOffsetSize(item.element);
79
- options.onUpdateItemVisibility({
80
- item,
81
- visible: false
8
+ */ export function createOverflowManager() {
9
+ let container;
10
+ let overflowMenu;
11
+ // Set as true when resize observer is observing
12
+ let observing = false;
13
+ // If true, next update will dispatch to onUpdateOverflow even if queue top states don't change
14
+ // Initially true to force dispatch on first mount
15
+ let forceDispatch = true;
16
+ const options = {
17
+ padding: 10,
18
+ overflowAxis: 'horizontal',
19
+ overflowDirection: 'end',
20
+ minimumVisible: 0,
21
+ onUpdateItemVisibility: ()=>undefined,
22
+ onUpdateOverflow: ()=>undefined
23
+ };
24
+ const overflowItems = {};
25
+ const overflowDividers = {};
26
+ const resizeObserver = new ResizeObserver((entries)=>{
27
+ if (!entries[0] || !container) {
28
+ return;
29
+ }
30
+ update();
82
31
  });
83
- if (item.groupId) {
84
- overflowGroups[item.groupId].visibleItemIds.delete(item.id);
85
- overflowGroups[item.groupId].invisibleItemIds.add(item.id);
86
- }
87
- return width;
88
- };
89
- const dispatchOverflowUpdate = () => {
90
- const visibleItemIds = visibleItemQueue.all();
91
- const invisibleItemIds = invisibleItemQueue.all();
92
- const visibleItems = visibleItemIds.map(itemId => overflowItems[itemId]);
93
- const invisibleItems = invisibleItemIds.map(itemId => overflowItems[itemId]);
94
- const groupVisibility = {};
95
- Object.entries(overflowGroups).forEach(([groupId, groupState]) => {
96
- if (groupState.invisibleItemIds.size && groupState.visibleItemIds.size) {
97
- groupVisibility[groupId] = 'overflow';
98
- } else if (groupState.visibleItemIds.size === 0) {
99
- groupVisibility[groupId] = 'hidden';
100
- } else {
101
- groupVisibility[groupId] = 'visible';
102
- }
32
+ const getNextItem = (queueToDequeue, queueToEnqueue)=>{
33
+ const nextItem = queueToDequeue.dequeue();
34
+ queueToEnqueue.enqueue(nextItem);
35
+ return overflowItems[nextItem];
36
+ };
37
+ const createGroupManager = ()=>{
38
+ const groupVisibility = {};
39
+ const groups = {};
40
+ function updateGroupVisibility(groupId) {
41
+ const group = groups[groupId];
42
+ if (group.invisibleItemIds.size && group.visibleItemIds.size) {
43
+ groupVisibility[groupId] = 'overflow';
44
+ } else if (group.visibleItemIds.size === 0) {
45
+ groupVisibility[groupId] = 'hidden';
46
+ } else {
47
+ groupVisibility[groupId] = 'visible';
48
+ }
49
+ }
50
+ function isGroupVisible(groupId) {
51
+ return groupVisibility[groupId] === 'visible' || groupVisibility[groupId] === 'overflow';
52
+ }
53
+ return {
54
+ groupVisibility: ()=>groupVisibility,
55
+ isSingleItemVisible (itemId, groupId) {
56
+ return isGroupVisible(groupId) && groups[groupId].visibleItemIds.has(itemId) && groups[groupId].visibleItemIds.size === 1;
57
+ },
58
+ addItem (itemId, groupId) {
59
+ var _;
60
+ (_ = (_groups = groups)[_groupId = groupId]) !== null && _ !== void 0 ? _ : _groups[_groupId] = {
61
+ visibleItemIds: new Set(),
62
+ invisibleItemIds: new Set()
63
+ };
64
+ groups[groupId].visibleItemIds.add(itemId);
65
+ updateGroupVisibility(groupId);
66
+ },
67
+ removeItem (itemId, groupId) {
68
+ groups[groupId].invisibleItemIds.delete(itemId);
69
+ groups[groupId].visibleItemIds.delete(itemId);
70
+ updateGroupVisibility(groupId);
71
+ },
72
+ showItem (itemId, groupId) {
73
+ groups[groupId].invisibleItemIds.delete(itemId);
74
+ groups[groupId].visibleItemIds.add(itemId);
75
+ updateGroupVisibility(groupId);
76
+ },
77
+ hideItem (itemId, groupId) {
78
+ groups[groupId].invisibleItemIds.add(itemId);
79
+ groups[groupId].visibleItemIds.delete(itemId);
80
+ updateGroupVisibility(groupId);
81
+ }
82
+ };
83
+ };
84
+ const groupManager = createGroupManager();
85
+ const invisibleItemQueue = createPriorityQueue((a, b)=>{
86
+ const itemA = overflowItems[a];
87
+ const itemB = overflowItems[b];
88
+ // Higher priority at the top of the queue
89
+ const priority = itemB.priority - itemA.priority;
90
+ if (priority !== 0) {
91
+ return priority;
92
+ }
93
+ const positionStatusBit = options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_FOLLOWING : Node.DOCUMENT_POSITION_PRECEDING;
94
+ // equal priority, use DOM order
95
+ // eslint-disable-next-line no-bitwise
96
+ return itemA.element.compareDocumentPosition(itemB.element) & positionStatusBit ? -1 : 1;
103
97
  });
104
- options.onUpdateOverflow({
105
- visibleItems,
106
- invisibleItems,
107
- groupVisibility
98
+ const visibleItemQueue = createPriorityQueue((a, b)=>{
99
+ const itemA = overflowItems[a];
100
+ const itemB = overflowItems[b];
101
+ // Lower priority at the top of the queue
102
+ const priority = itemA.priority - itemB.priority;
103
+ if (priority !== 0) {
104
+ return priority;
105
+ }
106
+ const positionStatusBit = options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_PRECEDING : Node.DOCUMENT_POSITION_FOLLOWING;
107
+ // equal priority, use DOM order
108
+ // eslint-disable-next-line no-bitwise
109
+ return itemA.element.compareDocumentPosition(itemB.element) & positionStatusBit ? -1 : 1;
108
110
  });
109
- };
110
- const processOverflowItems = () => {
111
- if (!container) {
112
- return false;
113
- }
114
- const availableSize = getOffsetSize(container) - options.padding;
115
- const overflowMenuOffset = overflowMenu ? getOffsetSize(overflowMenu) : 0;
116
- // Snapshot of the visible/invisible state to compare for updates
117
- const visibleTop = visibleItemQueue.peek();
118
- const invisibleTop = invisibleItemQueue.peek();
119
- const visibleItemIds = visibleItemQueue.all();
120
- let currentWidth = visibleItemIds.reduce((sum, visibleItemId) => {
121
- const child = overflowItems[visibleItemId].element;
122
- return sum + getOffsetSize(child);
123
- }, 0);
124
- // Add items until available width is filled - can result in overflow
125
- while (currentWidth < availableSize && invisibleItemQueue.size() > 0) {
126
- currentWidth += makeItemVisible();
127
- }
128
- // Remove items until there's no more overflow
129
- while (currentWidth > availableSize && visibleItemQueue.size() > 0) {
130
- if (visibleItemQueue.size() <= options.minimumVisible) {
131
- break;
132
- }
133
- currentWidth -= makeItemInvisible();
134
- }
135
- // make sure the overflow menu can fit
136
- if (visibleItemQueue.size() > options.minimumVisible && invisibleItemQueue.size() > 0 && currentWidth + overflowMenuOffset > availableSize) {
137
- makeItemInvisible();
138
- }
139
- // only update when the state of visible/invisible items has changed
140
- if (visibleItemQueue.peek() !== visibleTop || invisibleItemQueue.peek() !== invisibleTop) {
141
- return true;
142
- }
143
- return false;
144
- };
145
- const forceUpdate = () => {
146
- if (processOverflowItems() || forceDispatch) {
147
- forceDispatch = false;
148
- dispatchOverflowUpdate();
149
- }
150
- };
151
- const update = debounce(forceUpdate);
152
- const observe = (observedContainer, userOptions) => {
153
- Object.assign(options, userOptions);
154
- observing = true;
155
- Object.values(overflowItems).forEach(item => visibleItemQueue.enqueue(item.id));
156
- container = observedContainer;
157
- resizeObserver.observe(container);
158
- };
159
- const disconnect = () => {
160
- observing = false;
161
- resizeObserver.disconnect();
162
- };
163
- const addItem = item => {
164
- if (overflowItems[item.id]) {
165
- return;
166
- }
167
- overflowItems[item.id] = item;
168
- // some options can affect priority which are only set on `observe`
169
- if (observing) {
170
- // Updates to elements might not change the queue tops
171
- // i.e. new element is enqueued but the top of the queue stays the same
172
- // force a dispatch on the next batched update
173
- forceDispatch = true;
174
- visibleItemQueue.enqueue(item.id);
175
- }
176
- if (item.groupId) {
177
- if (!overflowGroups[item.groupId]) {
178
- overflowGroups[item.groupId] = {
179
- visibleItemIds: new Set(),
180
- invisibleItemIds: new Set()
181
- };
182
- }
183
- overflowGroups[item.groupId].visibleItemIds.add(item.id);
184
- }
185
- update();
186
- };
187
- const addOverflowMenu = el => {
188
- overflowMenu = el;
189
- };
190
- const removeOverflowMenu = () => {
191
- overflowMenu = undefined;
192
- };
193
- const removeItem = itemId => {
194
- if (!overflowItems[itemId]) {
195
- return;
196
- }
197
- const item = overflowItems[itemId];
198
- visibleItemQueue.remove(itemId);
199
- invisibleItemQueue.remove(itemId);
200
- if (item.groupId) {
201
- overflowGroups[item.groupId].visibleItemIds.delete(item.id);
202
- overflowGroups[item.groupId].invisibleItemIds.delete(item.id);
111
+ const getOffsetSize = (el)=>{
112
+ return options.overflowAxis === 'horizontal' ? el.offsetWidth : el.offsetHeight;
113
+ };
114
+ function computeSizeChange(entry) {
115
+ const dividerWidth = entry.groupId && groupManager.isSingleItemVisible(entry.id, entry.groupId) && overflowDividers[entry.groupId] ? getOffsetSize(overflowDividers[entry.groupId].element) : 0;
116
+ return getOffsetSize(entry.element) + dividerWidth;
203
117
  }
204
- delete overflowItems[itemId];
205
- update();
206
- };
207
- return {
208
- addItem,
209
- disconnect,
210
- forceUpdate,
211
- observe,
212
- removeItem,
213
- update,
214
- addOverflowMenu,
215
- removeOverflowMenu
216
- };
118
+ const showItem = ()=>{
119
+ const item = getNextItem(invisibleItemQueue, visibleItemQueue);
120
+ options.onUpdateItemVisibility({
121
+ item,
122
+ visible: true
123
+ });
124
+ if (item.groupId) {
125
+ groupManager.showItem(item.id, item.groupId);
126
+ if (groupManager.isSingleItemVisible(item.id, item.groupId)) {
127
+ var _overflowDividers_item_groupId;
128
+ (_overflowDividers_item_groupId = overflowDividers[item.groupId]) === null || _overflowDividers_item_groupId === void 0 ? void 0 : _overflowDividers_item_groupId.element.removeAttribute(DATA_OVERFLOWING);
129
+ }
130
+ }
131
+ return computeSizeChange(item);
132
+ };
133
+ const hideItem = ()=>{
134
+ const item = getNextItem(visibleItemQueue, invisibleItemQueue);
135
+ const width = computeSizeChange(item);
136
+ options.onUpdateItemVisibility({
137
+ item,
138
+ visible: false
139
+ });
140
+ if (item.groupId) {
141
+ if (groupManager.isSingleItemVisible(item.id, item.groupId)) {
142
+ var _overflowDividers_item_groupId;
143
+ (_overflowDividers_item_groupId = overflowDividers[item.groupId]) === null || _overflowDividers_item_groupId === void 0 ? void 0 : _overflowDividers_item_groupId.element.setAttribute(DATA_OVERFLOWING, '');
144
+ }
145
+ groupManager.hideItem(item.id, item.groupId);
146
+ }
147
+ return width;
148
+ };
149
+ const dispatchOverflowUpdate = ()=>{
150
+ const visibleItemIds = visibleItemQueue.all();
151
+ const invisibleItemIds = invisibleItemQueue.all();
152
+ const visibleItems = visibleItemIds.map((itemId)=>overflowItems[itemId]);
153
+ const invisibleItems = invisibleItemIds.map((itemId)=>overflowItems[itemId]);
154
+ options.onUpdateOverflow({
155
+ visibleItems,
156
+ invisibleItems,
157
+ groupVisibility: groupManager.groupVisibility()
158
+ });
159
+ };
160
+ const processOverflowItems = ()=>{
161
+ if (!container) {
162
+ return false;
163
+ }
164
+ const totalDividersWidth = Object.values(overflowDividers).map((dvdr)=>dvdr.groupId ? getOffsetSize(dvdr.element) : 0).reduce((prev, current)=>prev + current, 0);
165
+ function overflowMenuSize() {
166
+ return invisibleItemQueue.size() > 0 && overflowMenu ? getOffsetSize(overflowMenu) : 0;
167
+ }
168
+ const availableSize = getOffsetSize(container) - totalDividersWidth - options.padding;
169
+ // Snapshot of the visible/invisible state to compare for updates
170
+ const visibleTop = visibleItemQueue.peek();
171
+ const invisibleTop = invisibleItemQueue.peek();
172
+ let currentWidth = visibleItemQueue.all().map((id)=>overflowItems[id].element).map(getOffsetSize).reduce((prev, current)=>prev + current, 0);
173
+ // Add items until available width is filled - can result in overflow
174
+ while(currentWidth + overflowMenuSize() < availableSize && invisibleItemQueue.size() > 0){
175
+ currentWidth += showItem();
176
+ }
177
+ // Remove items until there's no more overflow
178
+ while(currentWidth + overflowMenuSize() > availableSize && visibleItemQueue.size() > options.minimumVisible){
179
+ currentWidth -= hideItem();
180
+ }
181
+ // only update when the state of visible/invisible items has changed
182
+ return visibleItemQueue.peek() !== visibleTop || invisibleItemQueue.peek() !== invisibleTop;
183
+ };
184
+ const forceUpdate = ()=>{
185
+ if (processOverflowItems() || forceDispatch) {
186
+ forceDispatch = false;
187
+ dispatchOverflowUpdate();
188
+ }
189
+ };
190
+ const update = debounce(forceUpdate);
191
+ const observe = (observedContainer, userOptions)=>{
192
+ Object.assign(options, userOptions);
193
+ observing = true;
194
+ Object.values(overflowItems).forEach((item)=>visibleItemQueue.enqueue(item.id));
195
+ container = observedContainer;
196
+ resizeObserver.observe(container);
197
+ };
198
+ const disconnect = ()=>{
199
+ observing = false;
200
+ resizeObserver.disconnect();
201
+ };
202
+ const addItem = (item)=>{
203
+ if (overflowItems[item.id]) {
204
+ return;
205
+ }
206
+ overflowItems[item.id] = item;
207
+ // some options can affect priority which are only set on `observe`
208
+ if (observing) {
209
+ // Updates to elements might not change the queue tops
210
+ // i.e. new element is enqueued but the top of the queue stays the same
211
+ // force a dispatch on the next batched update
212
+ forceDispatch = true;
213
+ visibleItemQueue.enqueue(item.id);
214
+ }
215
+ if (item.groupId) {
216
+ groupManager.addItem(item.id, item.groupId);
217
+ item.element.setAttribute(DATA_OVERFLOW_GROUP, item.groupId);
218
+ }
219
+ update();
220
+ };
221
+ const addOverflowMenu = (el)=>{
222
+ overflowMenu = el;
223
+ };
224
+ const addDivider = (divider)=>{
225
+ if (!divider.groupId || overflowDividers[divider.groupId]) {
226
+ return;
227
+ }
228
+ divider.element.setAttribute(DATA_OVERFLOW_GROUP, divider.groupId);
229
+ overflowDividers[divider.groupId] = divider;
230
+ };
231
+ const removeOverflowMenu = ()=>{
232
+ overflowMenu = undefined;
233
+ };
234
+ const removeDivider = (groupId)=>{
235
+ if (!overflowDividers[groupId]) {
236
+ return;
237
+ }
238
+ const divider = overflowDividers[groupId];
239
+ if (divider.groupId) {
240
+ delete overflowDividers[groupId];
241
+ divider.element.removeAttribute(DATA_OVERFLOW_GROUP);
242
+ }
243
+ };
244
+ const removeItem = (itemId)=>{
245
+ if (!overflowItems[itemId]) {
246
+ return;
247
+ }
248
+ const item = overflowItems[itemId];
249
+ visibleItemQueue.remove(itemId);
250
+ invisibleItemQueue.remove(itemId);
251
+ if (item.groupId) {
252
+ groupManager.removeItem(item.id, item.groupId);
253
+ item.element.removeAttribute(DATA_OVERFLOW_GROUP);
254
+ }
255
+ delete overflowItems[itemId];
256
+ update();
257
+ };
258
+ return {
259
+ addItem,
260
+ disconnect,
261
+ forceUpdate,
262
+ observe,
263
+ removeItem,
264
+ update,
265
+ addOverflowMenu,
266
+ removeOverflowMenu,
267
+ addDivider,
268
+ removeDivider
269
+ };
217
270
  }
218
- //# sourceMappingURL=overflowManager.js.map