@fluentui/priority-overflow 9.0.3 → 9.1.1

Sign up to get free protection for your applications and to get access to all the features.
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