@fluentui/priority-overflow 9.0.2 → 9.1.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.json +75 -1
- package/CHANGELOG.md +21 -2
- package/dist/index.d.ts +16 -0
- package/lib/consts.js +2 -0
- package/lib/consts.js.map +1 -0
- package/lib/debounce.js +13 -14
- package/lib/debounce.js.map +1 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/lib/overflowManager.js +257 -207
- package/lib/overflowManager.js.map +1 -1
- package/lib/priorityQueue.js +85 -86
- package/lib/priorityQueue.js.map +1 -1
- package/lib/types.js +1 -2
- package/lib/types.js.map +1 -1
- package/lib-commonjs/consts.js +16 -0
- package/lib-commonjs/consts.js.map +1 -0
- package/lib-commonjs/debounce.js +1 -3
- package/lib-commonjs/debounce.js.map +1 -1
- package/lib-commonjs/index.js +0 -3
- package/lib-commonjs/index.js.map +1 -1
- package/lib-commonjs/overflowManager.js +111 -61
- package/lib-commonjs/overflowManager.js.map +1 -1
- package/lib-commonjs/priorityQueue.js +1 -3
- package/lib-commonjs/priorityQueue.js.map +1 -1
- package/lib-commonjs/types.js +0 -3
- package/lib-commonjs/types.js.map +1 -1
- package/package.json +3 -2
- package/.swcrc +0 -30
package/lib/priorityQueue.js
CHANGED
@@ -1,90 +1,89 @@
|
|
1
1
|
/**
|
2
2
|
* @param compare - comparison function for items
|
3
3
|
* @returns Priority queue implemented with a min heap
|
4
|
-
*/export function createPriorityQueue(compare) {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
4
|
+
*/ export function createPriorityQueue(compare) {
|
5
|
+
const arr = [];
|
6
|
+
let size = 0;
|
7
|
+
const left = (i)=>{
|
8
|
+
return 2 * i + 1;
|
9
|
+
};
|
10
|
+
const right = (i)=>{
|
11
|
+
return 2 * i + 2;
|
12
|
+
};
|
13
|
+
const parent = (i)=>{
|
14
|
+
return Math.floor((i - 1) / 2);
|
15
|
+
};
|
16
|
+
const swap = (a, b)=>{
|
17
|
+
const tmp = arr[a];
|
18
|
+
arr[a] = arr[b];
|
19
|
+
arr[b] = tmp;
|
20
|
+
};
|
21
|
+
const heapify = (i)=>{
|
22
|
+
let smallest = i;
|
23
|
+
const l = left(i);
|
24
|
+
const r = right(i);
|
25
|
+
if (l < size && compare(arr[l], arr[smallest]) < 0) {
|
26
|
+
smallest = l;
|
27
|
+
}
|
28
|
+
if (r < size && compare(arr[r], arr[smallest]) < 0) {
|
29
|
+
smallest = r;
|
30
|
+
}
|
31
|
+
if (smallest !== i) {
|
32
|
+
swap(smallest, i);
|
33
|
+
heapify(smallest);
|
34
|
+
}
|
35
|
+
};
|
36
|
+
const dequeue = ()=>{
|
37
|
+
if (size === 0) {
|
38
|
+
throw new Error('Priority queue empty');
|
39
|
+
}
|
40
|
+
const res = arr[0];
|
41
|
+
arr[0] = arr[--size];
|
42
|
+
heapify(0);
|
43
|
+
return res;
|
44
|
+
};
|
45
|
+
const peek = ()=>{
|
46
|
+
if (size === 0) {
|
47
|
+
return null;
|
48
|
+
}
|
49
|
+
return arr[0];
|
50
|
+
};
|
51
|
+
const enqueue = (item)=>{
|
52
|
+
arr[size++] = item;
|
53
|
+
let i = size - 1;
|
54
|
+
let p = parent(i);
|
55
|
+
while(i > 0 && compare(arr[p], arr[i]) > 0){
|
56
|
+
swap(p, i);
|
57
|
+
i = p;
|
58
|
+
p = parent(i);
|
59
|
+
}
|
60
|
+
};
|
61
|
+
const contains = (item)=>{
|
62
|
+
const index = arr.indexOf(item);
|
63
|
+
return index >= 0 && index < size;
|
64
|
+
};
|
65
|
+
const remove = (item)=>{
|
66
|
+
const i = arr.indexOf(item);
|
67
|
+
if (i === -1 || i >= size) {
|
68
|
+
return;
|
69
|
+
}
|
70
|
+
arr[i] = arr[--size];
|
71
|
+
heapify(i);
|
72
|
+
};
|
73
|
+
const clear = ()=>{
|
74
|
+
size = 0;
|
75
|
+
};
|
76
|
+
const all = ()=>{
|
77
|
+
return arr.slice(0, size);
|
78
|
+
};
|
79
|
+
return {
|
80
|
+
all,
|
81
|
+
clear,
|
82
|
+
contains,
|
83
|
+
dequeue,
|
84
|
+
enqueue,
|
85
|
+
peek,
|
86
|
+
remove,
|
87
|
+
size: ()=>size
|
88
|
+
};
|
89
89
|
}
|
90
|
-
//# sourceMappingURL=priorityQueue.js.map
|
package/lib/priorityQueue.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"
|
1
|
+
{"version":3,"sources":["priorityQueue.ts"],"sourcesContent":["export type PriorityQueueCompareFn<T> = (a: T, b: T) => number;\n\nexport interface PriorityQueue<T> {\n all: () => T[];\n clear: () => void;\n contains: (item: T) => boolean;\n dequeue: () => T;\n enqueue: (item: T) => void;\n peek: () => T | null;\n remove: (item: T) => void;\n size: () => number;\n}\n\n/**\n * @param compare - comparison function for items\n * @returns Priority queue implemented with a min heap\n */\nexport function createPriorityQueue<T>(compare: PriorityQueueCompareFn<T>): PriorityQueue<T> {\n const arr: T[] = [];\n let size = 0;\n\n const left = (i: number) => {\n return 2 * i + 1;\n };\n\n const right = (i: number) => {\n return 2 * i + 2;\n };\n\n const parent = (i: number) => {\n return Math.floor((i - 1) / 2);\n };\n\n const swap = (a: number, b: number) => {\n const tmp = arr[a];\n arr[a] = arr[b];\n arr[b] = tmp;\n };\n\n const heapify = (i: number) => {\n let smallest = i;\n const l = left(i);\n const r = right(i);\n\n if (l < size && compare(arr[l], arr[smallest]) < 0) {\n smallest = l;\n }\n\n if (r < size && compare(arr[r], arr[smallest]) < 0) {\n smallest = r;\n }\n\n if (smallest !== i) {\n swap(smallest, i);\n heapify(smallest);\n }\n };\n\n const dequeue = () => {\n if (size === 0) {\n throw new Error('Priority queue empty');\n }\n\n const res = arr[0];\n arr[0] = arr[--size];\n heapify(0);\n\n return res;\n };\n\n const peek = () => {\n if (size === 0) {\n return null;\n }\n\n return arr[0];\n };\n\n const enqueue = (item: T) => {\n arr[size++] = item;\n let i = size - 1;\n let p = parent(i);\n while (i > 0 && compare(arr[p], arr[i]) > 0) {\n swap(p, i);\n i = p;\n p = parent(i);\n }\n };\n\n const contains = (item: T) => {\n const index = arr.indexOf(item);\n return index >= 0 && index < size;\n };\n\n const remove = (item: T) => {\n const i = arr.indexOf(item);\n\n if (i === -1 || i >= size) {\n return;\n }\n\n arr[i] = arr[--size];\n heapify(i);\n };\n\n const clear = () => {\n size = 0;\n };\n\n const all = () => {\n return arr.slice(0, size);\n };\n\n return {\n all,\n clear,\n contains,\n dequeue,\n enqueue,\n peek,\n remove,\n size: () => size,\n };\n}\n"],"names":["createPriorityQueue","compare","arr","size","left","i","right","parent","Math","floor","swap","a","b","tmp","heapify","smallest","l","r","dequeue","Error","res","peek","enqueue","item","p","contains","index","indexOf","remove","clear","all","slice"],"mappings":"AAaA;;;CAGC,GACD,OAAO,SAASA,oBAAuBC,OAAkC,EAAoB;IAC3F,MAAMC,MAAW,EAAE;IACnB,IAAIC,OAAO;IAEX,MAAMC,OAAO,CAACC,IAAc;QAC1B,OAAO,IAAIA,IAAI;IACjB;IAEA,MAAMC,QAAQ,CAACD,IAAc;QAC3B,OAAO,IAAIA,IAAI;IACjB;IAEA,MAAME,SAAS,CAACF,IAAc;QAC5B,OAAOG,KAAKC,KAAK,CAAC,AAACJ,CAAAA,IAAI,CAAA,IAAK;IAC9B;IAEA,MAAMK,OAAO,CAACC,GAAWC,IAAc;QACrC,MAAMC,MAAMX,GAAG,CAACS,EAAE;QAClBT,GAAG,CAACS,EAAE,GAAGT,GAAG,CAACU,EAAE;QACfV,GAAG,CAACU,EAAE,GAAGC;IACX;IAEA,MAAMC,UAAU,CAACT,IAAc;QAC7B,IAAIU,WAAWV;QACf,MAAMW,IAAIZ,KAAKC;QACf,MAAMY,IAAIX,MAAMD;QAEhB,IAAIW,IAAIb,QAAQF,QAAQC,GAAG,CAACc,EAAE,EAAEd,GAAG,CAACa,SAAS,IAAI,GAAG;YAClDA,WAAWC;QACb,CAAC;QAED,IAAIC,IAAId,QAAQF,QAAQC,GAAG,CAACe,EAAE,EAAEf,GAAG,CAACa,SAAS,IAAI,GAAG;YAClDA,WAAWE;QACb,CAAC;QAED,IAAIF,aAAaV,GAAG;YAClBK,KAAKK,UAAUV;YACfS,QAAQC;QACV,CAAC;IACH;IAEA,MAAMG,UAAU,IAAM;QACpB,IAAIf,SAAS,GAAG;YACd,MAAM,IAAIgB,MAAM,wBAAwB;QAC1C,CAAC;QAED,MAAMC,MAAMlB,GAAG,CAAC,EAAE;QAClBA,GAAG,CAAC,EAAE,GAAGA,GAAG,CAAC,EAAEC,KAAK;QACpBW,QAAQ;QAER,OAAOM;IACT;IAEA,MAAMC,OAAO,IAAM;QACjB,IAAIlB,SAAS,GAAG;YACd,OAAO,IAAI;QACb,CAAC;QAED,OAAOD,GAAG,CAAC,EAAE;IACf;IAEA,MAAMoB,UAAU,CAACC,OAAY;QAC3BrB,GAAG,CAACC,OAAO,GAAGoB;QACd,IAAIlB,IAAIF,OAAO;QACf,IAAIqB,IAAIjB,OAAOF;QACf,MAAOA,IAAI,KAAKJ,QAAQC,GAAG,CAACsB,EAAE,EAAEtB,GAAG,CAACG,EAAE,IAAI,EAAG;YAC3CK,KAAKc,GAAGnB;YACRA,IAAImB;YACJA,IAAIjB,OAAOF;QACb;IACF;IAEA,MAAMoB,WAAW,CAACF,OAAY;QAC5B,MAAMG,QAAQxB,IAAIyB,OAAO,CAACJ;QAC1B,OAAOG,SAAS,KAAKA,QAAQvB;IAC/B;IAEA,MAAMyB,SAAS,CAACL,OAAY;QAC1B,MAAMlB,IAAIH,IAAIyB,OAAO,CAACJ;QAEtB,IAAIlB,MAAM,CAAC,KAAKA,KAAKF,MAAM;YACzB;QACF,CAAC;QAEDD,GAAG,CAACG,EAAE,GAAGH,GAAG,CAAC,EAAEC,KAAK;QACpBW,QAAQT;IACV;IAEA,MAAMwB,QAAQ,IAAM;QAClB1B,OAAO;IACT;IAEA,MAAM2B,MAAM,IAAM;QAChB,OAAO5B,IAAI6B,KAAK,CAAC,GAAG5B;IACtB;IAEA,OAAO;QACL2B;QACAD;QACAJ;QACAP;QACAI;QACAD;QACAO;QACAzB,MAAM,IAAMA;IACd;AACF,CAAC"}
|
package/lib/types.js
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
export {};
|
2
|
-
//# sourceMappingURL=types.js.map
|
1
|
+
export { };
|
package/lib/types.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"
|
1
|
+
{"version":3,"sources":["types.ts"],"sourcesContent":["export type OverflowDirection = 'start' | 'end';\nexport type OverflowAxis = 'horizontal' | 'vertical';\nexport type OverflowGroupState = 'visible' | 'hidden' | 'overflow';\nexport interface OverflowItemEntry {\n /**\n * HTML element that will be disappear when overflowed\n */\n element: HTMLElement;\n /**\n * Lower priority items are invisible first when the container is overflowed\n * @default 0\n */\n priority: number;\n /**\n * Specific id, used to track visibility and provide updates to consumers\n */\n id: string;\n\n groupId?: string;\n}\n\nexport interface OverflowDividerEntry {\n /**\n * HTML element that will be disappear when overflowed\n */\n element: HTMLElement;\n\n groupId: string;\n}\n\n/**\n * signature similar to standard event listeners, but typed to handle the custom event\n */\nexport type OnUpdateOverflow = (data: OverflowEventPayload) => void;\n\nexport type OnUpdateItemVisibility = (data: OnUpdateItemVisibilityPayload) => void;\n\n/**\n * Payload of the custom DOM event for overflow updates\n */\nexport interface OverflowEventPayload {\n visibleItems: OverflowItemEntry[];\n invisibleItems: OverflowItemEntry[];\n groupVisibility: Record<string, OverflowGroupState>;\n}\n\nexport interface OnUpdateItemVisibilityPayload {\n item: OverflowItemEntry;\n visible: boolean;\n}\n\nexport interface ObserveOptions {\n /**\n * Padding (in px) at the end of the container before overflow occurs\n * Useful to account for extra elements (i.e. dropdown menu)\n * or to account for any kinds of margins between items which are hard to measure with JS\n * @default 10\n */\n padding?: number;\n /**\n * Direction where items are removed when overflow occurs\n * @default end\n */\n overflowDirection?: OverflowDirection;\n\n /**\n * Horizontal or vertical overflow\n * @default horizontal\n */\n overflowAxis?: OverflowAxis;\n\n /**\n * The minimum number of visible items\n */\n minimumVisible?: number;\n\n /**\n * Callback when item visibility is updated\n */\n onUpdateItemVisibility: OnUpdateItemVisibility;\n\n /**\n * Callback when item visibility is updated\n */\n onUpdateOverflow: OnUpdateOverflow;\n}\n\n/**\n * @internal\n */\nexport interface OverflowManager {\n /**\n * Starts observing the container and managing the overflow state\n */\n observe: (container: HTMLElement, options: ObserveOptions) => void;\n /**\n * Stops observing the container\n */\n disconnect: () => void;\n /**\n * Add overflow items\n */\n addItem: (items: OverflowItemEntry) => void;\n /**\n * Remove overflow item\n */\n removeItem: (itemId: string) => void;\n /**\n * Manually update the overflow, updates are batched and async\n */\n update: () => void;\n /**\n * Manually update the overflow sync\n */\n forceUpdate: () => void;\n\n /**\n * Adds an element that opens an overflow menu. This is used to calculate\n * available space and check if additional items need to overflow\n */\n addOverflowMenu: (element: HTMLElement) => void;\n\n /**\n * Add overflow divider\n */\n addDivider: (divider: OverflowDividerEntry) => void;\n\n /**\n * Remove overflow divider\n */\n removeDivider: (groupId: string) => void;\n\n /**\n * Unsets the overflow menu element\n */\n removeOverflowMenu: () => void;\n}\n"],"names":[],"mappings":"AAAA,WAwIC"}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
3
|
+
value: true
|
4
|
+
});
|
5
|
+
function _export(target, all) {
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
7
|
+
enumerable: true,
|
8
|
+
get: all[name]
|
9
|
+
});
|
10
|
+
}
|
11
|
+
_export(exports, {
|
12
|
+
DATA_OVERFLOWING: ()=>DATA_OVERFLOWING,
|
13
|
+
DATA_OVERFLOW_GROUP: ()=>DATA_OVERFLOW_GROUP
|
14
|
+
});
|
15
|
+
const DATA_OVERFLOWING = 'data-overflowing';
|
16
|
+
const DATA_OVERFLOW_GROUP = 'data-overflow-group';
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["consts.js"],"sourcesContent":["export const DATA_OVERFLOWING = 'data-overflowing';\nexport const DATA_OVERFLOW_GROUP = 'data-overflow-group';\n"],"names":["DATA_OVERFLOWING","DATA_OVERFLOW_GROUP"],"mappings":";;;;;;;;;;;IAAaA,gBAAgB,MAAhBA;IACAC,mBAAmB,MAAnBA;;AADN,MAAMD,mBAAmB;AACzB,MAAMC,sBAAsB"}
|
package/lib-commonjs/debounce.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["
|
1
|
+
{"version":3,"sources":["debounce.js"],"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 */ export function debounce(fn) {\n let pending;\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;;;;+BAAmBA;;aAAAA;;AAAT,SAASA,SAASC,EAAE,EAAE;IAC7B,IAAIC;IACJ,OAAO,IAAI;QACP,IAAI,CAACA,SAAS;YACVA,UAAU,IAAI;YACdC,eAAe,IAAI;gBACf,uEAAuE;gBACvE,gEAAgE;gBAChED,UAAU,KAAK;gBACfD;YACJ;QACJ,CAAC;IACL;AACJ"}
|
package/lib-commonjs/index.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["
|
1
|
+
{"version":3,"sources":["index.js"],"sourcesContent":["export { createOverflowManager } from './overflowManager';\n"],"names":["createOverflowManager"],"mappings":";;;;+BAASA;;aAAAA,sCAAqB;;iCAAQ"}
|
@@ -6,15 +6,18 @@ Object.defineProperty(exports, "createOverflowManager", {
|
|
6
6
|
enumerable: true,
|
7
7
|
get: ()=>createOverflowManager
|
8
8
|
});
|
9
|
+
const _consts = require("./consts");
|
9
10
|
const _debounce = require("./debounce");
|
10
11
|
const _priorityQueue = require("./priorityQueue");
|
12
|
+
var _groups, _groupId;
|
11
13
|
function createOverflowManager() {
|
12
14
|
let container;
|
13
15
|
let overflowMenu;
|
14
16
|
// Set as true when resize observer is observing
|
15
17
|
let observing = false;
|
16
18
|
// If true, next update will dispatch to onUpdateOverflow even if queue top states don't change
|
17
|
-
|
19
|
+
// Initially true to force dispatch on first mount
|
20
|
+
let forceDispatch = true;
|
18
21
|
const options = {
|
19
22
|
padding: 10,
|
20
23
|
overflowAxis: 'horizontal',
|
@@ -24,13 +27,66 @@ function createOverflowManager() {
|
|
24
27
|
onUpdateOverflow: ()=>undefined
|
25
28
|
};
|
26
29
|
const overflowItems = {};
|
27
|
-
const
|
30
|
+
const overflowDividers = {};
|
28
31
|
const resizeObserver = new ResizeObserver((entries)=>{
|
29
32
|
if (!entries[0] || !container) {
|
30
33
|
return;
|
31
34
|
}
|
32
35
|
update();
|
33
36
|
});
|
37
|
+
const getNextItem = (queueToDequeue, queueToEnqueue)=>{
|
38
|
+
const nextItem = queueToDequeue.dequeue();
|
39
|
+
queueToEnqueue.enqueue(nextItem);
|
40
|
+
return overflowItems[nextItem];
|
41
|
+
};
|
42
|
+
const createGroupManager = ()=>{
|
43
|
+
const groupVisibility = {};
|
44
|
+
const groups = {};
|
45
|
+
function updateGroupVisibility(groupId) {
|
46
|
+
const group = groups[groupId];
|
47
|
+
if (group.invisibleItemIds.size && group.visibleItemIds.size) {
|
48
|
+
groupVisibility[groupId] = 'overflow';
|
49
|
+
} else if (group.visibleItemIds.size === 0) {
|
50
|
+
groupVisibility[groupId] = 'hidden';
|
51
|
+
} else {
|
52
|
+
groupVisibility[groupId] = 'visible';
|
53
|
+
}
|
54
|
+
}
|
55
|
+
function isGroupVisible(groupId) {
|
56
|
+
return groupVisibility[groupId] === 'visible' || groupVisibility[groupId] === 'overflow';
|
57
|
+
}
|
58
|
+
return {
|
59
|
+
groupVisibility: ()=>groupVisibility,
|
60
|
+
isSingleItemVisible (itemId, groupId) {
|
61
|
+
return isGroupVisible(groupId) && groups[groupId].visibleItemIds.has(itemId) && groups[groupId].visibleItemIds.size === 1;
|
62
|
+
},
|
63
|
+
addItem (itemId, groupId) {
|
64
|
+
var _;
|
65
|
+
(_ = (_groups = groups)[_groupId = groupId]) !== null && _ !== void 0 ? _ : _groups[_groupId] = {
|
66
|
+
visibleItemIds: new Set(),
|
67
|
+
invisibleItemIds: new Set()
|
68
|
+
};
|
69
|
+
groups[groupId].visibleItemIds.add(itemId);
|
70
|
+
updateGroupVisibility(groupId);
|
71
|
+
},
|
72
|
+
removeItem (itemId, groupId) {
|
73
|
+
groups[groupId].invisibleItemIds.delete(itemId);
|
74
|
+
groups[groupId].visibleItemIds.delete(itemId);
|
75
|
+
updateGroupVisibility(groupId);
|
76
|
+
},
|
77
|
+
showItem (itemId, groupId) {
|
78
|
+
groups[groupId].invisibleItemIds.delete(itemId);
|
79
|
+
groups[groupId].visibleItemIds.add(itemId);
|
80
|
+
updateGroupVisibility(groupId);
|
81
|
+
},
|
82
|
+
hideItem (itemId, groupId) {
|
83
|
+
groups[groupId].invisibleItemIds.add(itemId);
|
84
|
+
groups[groupId].visibleItemIds.delete(itemId);
|
85
|
+
updateGroupVisibility(groupId);
|
86
|
+
}
|
87
|
+
};
|
88
|
+
};
|
89
|
+
const groupManager = createGroupManager();
|
34
90
|
const invisibleItemQueue = (0, _priorityQueue.createPriorityQueue)((a, b)=>{
|
35
91
|
const itemA = overflowItems[a];
|
36
92
|
const itemB = overflowItems[b];
|
@@ -60,32 +116,38 @@ function createOverflowManager() {
|
|
60
116
|
const getOffsetSize = (el)=>{
|
61
117
|
return options.overflowAxis === 'horizontal' ? el.offsetWidth : el.offsetHeight;
|
62
118
|
};
|
63
|
-
|
64
|
-
const
|
65
|
-
|
66
|
-
|
119
|
+
function computeSizeChange(entry) {
|
120
|
+
const dividerWidth = entry.groupId && groupManager.isSingleItemVisible(entry.id, entry.groupId) && overflowDividers[entry.groupId] ? getOffsetSize(overflowDividers[entry.groupId].element) : 0;
|
121
|
+
return getOffsetSize(entry.element) + dividerWidth;
|
122
|
+
}
|
123
|
+
const showItem = ()=>{
|
124
|
+
const item = getNextItem(invisibleItemQueue, visibleItemQueue);
|
67
125
|
options.onUpdateItemVisibility({
|
68
126
|
item,
|
69
127
|
visible: true
|
70
128
|
});
|
71
129
|
if (item.groupId) {
|
72
|
-
|
73
|
-
|
130
|
+
groupManager.showItem(item.id, item.groupId);
|
131
|
+
if (groupManager.isSingleItemVisible(item.id, item.groupId)) {
|
132
|
+
var _overflowDividers_item_groupId;
|
133
|
+
(_overflowDividers_item_groupId = overflowDividers[item.groupId]) === null || _overflowDividers_item_groupId === void 0 ? void 0 : _overflowDividers_item_groupId.element.removeAttribute(_consts.DATA_OVERFLOWING);
|
134
|
+
}
|
74
135
|
}
|
75
|
-
return
|
136
|
+
return computeSizeChange(item);
|
76
137
|
};
|
77
|
-
const
|
78
|
-
const
|
79
|
-
|
80
|
-
const item = overflowItems[nextInvisible];
|
81
|
-
const width = getOffsetSize(item.element);
|
138
|
+
const hideItem = ()=>{
|
139
|
+
const item = getNextItem(visibleItemQueue, invisibleItemQueue);
|
140
|
+
const width = computeSizeChange(item);
|
82
141
|
options.onUpdateItemVisibility({
|
83
142
|
item,
|
84
143
|
visible: false
|
85
144
|
});
|
86
145
|
if (item.groupId) {
|
87
|
-
|
88
|
-
|
146
|
+
if (groupManager.isSingleItemVisible(item.id, item.groupId)) {
|
147
|
+
var _overflowDividers_item_groupId;
|
148
|
+
(_overflowDividers_item_groupId = overflowDividers[item.groupId]) === null || _overflowDividers_item_groupId === void 0 ? void 0 : _overflowDividers_item_groupId.element.setAttribute(_consts.DATA_OVERFLOWING, '');
|
149
|
+
}
|
150
|
+
groupManager.hideItem(item.id, item.groupId);
|
89
151
|
}
|
90
152
|
return width;
|
91
153
|
};
|
@@ -94,56 +156,32 @@ function createOverflowManager() {
|
|
94
156
|
const invisibleItemIds = invisibleItemQueue.all();
|
95
157
|
const visibleItems = visibleItemIds.map((itemId)=>overflowItems[itemId]);
|
96
158
|
const invisibleItems = invisibleItemIds.map((itemId)=>overflowItems[itemId]);
|
97
|
-
const groupVisibility = {};
|
98
|
-
Object.entries(overflowGroups).forEach(([groupId, groupState])=>{
|
99
|
-
if (groupState.invisibleItemIds.size && groupState.visibleItemIds.size) {
|
100
|
-
groupVisibility[groupId] = 'overflow';
|
101
|
-
} else if (groupState.visibleItemIds.size === 0) {
|
102
|
-
groupVisibility[groupId] = 'hidden';
|
103
|
-
} else {
|
104
|
-
groupVisibility[groupId] = 'visible';
|
105
|
-
}
|
106
|
-
});
|
107
159
|
options.onUpdateOverflow({
|
108
160
|
visibleItems,
|
109
161
|
invisibleItems,
|
110
|
-
groupVisibility
|
162
|
+
groupVisibility: groupManager.groupVisibility()
|
111
163
|
});
|
112
164
|
};
|
113
165
|
const processOverflowItems = ()=>{
|
114
166
|
if (!container) {
|
115
167
|
return false;
|
116
168
|
}
|
117
|
-
const
|
118
|
-
const
|
169
|
+
const totalDividersWidth = Object.values(overflowDividers).map((dvdr)=>dvdr.groupId ? getOffsetSize(dvdr.element) : 0).reduce((prev, current)=>prev + current, 0);
|
170
|
+
const availableSize = getOffsetSize(container) - options.padding - totalDividersWidth - (overflowMenu ? getOffsetSize(overflowMenu) : 0);
|
119
171
|
// Snapshot of the visible/invisible state to compare for updates
|
120
172
|
const visibleTop = visibleItemQueue.peek();
|
121
173
|
const invisibleTop = invisibleItemQueue.peek();
|
122
|
-
|
123
|
-
let currentWidth = visibleItemIds.reduce((sum, visibleItemId)=>{
|
124
|
-
const child = overflowItems[visibleItemId].element;
|
125
|
-
return sum + getOffsetSize(child);
|
126
|
-
}, 0);
|
174
|
+
let currentWidth = visibleItemQueue.all().map((id)=>overflowItems[id].element).map(getOffsetSize).reduce((prev, current)=>prev + current, 0);
|
127
175
|
// Add items until available width is filled - can result in overflow
|
128
176
|
while(currentWidth < availableSize && invisibleItemQueue.size() > 0){
|
129
|
-
currentWidth +=
|
177
|
+
currentWidth += showItem();
|
130
178
|
}
|
131
179
|
// Remove items until there's no more overflow
|
132
|
-
while(currentWidth > availableSize && visibleItemQueue.size() >
|
133
|
-
|
134
|
-
break;
|
135
|
-
}
|
136
|
-
currentWidth -= makeItemInvisible();
|
137
|
-
}
|
138
|
-
// make sure the overflow menu can fit
|
139
|
-
if (visibleItemQueue.size() > options.minimumVisible && invisibleItemQueue.size() > 0 && currentWidth + overflowMenuOffset > availableSize) {
|
140
|
-
makeItemInvisible();
|
180
|
+
while(currentWidth > availableSize && visibleItemQueue.size() > options.minimumVisible){
|
181
|
+
currentWidth -= hideItem();
|
141
182
|
}
|
142
183
|
// only update when the state of visible/invisible items has changed
|
143
|
-
|
144
|
-
return true;
|
145
|
-
}
|
146
|
-
return false;
|
184
|
+
return visibleItemQueue.peek() !== visibleTop || invisibleItemQueue.peek() !== invisibleTop;
|
147
185
|
};
|
148
186
|
const forceUpdate = ()=>{
|
149
187
|
if (processOverflowItems() || forceDispatch) {
|
@@ -177,22 +215,34 @@ function createOverflowManager() {
|
|
177
215
|
visibleItemQueue.enqueue(item.id);
|
178
216
|
}
|
179
217
|
if (item.groupId) {
|
180
|
-
|
181
|
-
|
182
|
-
visibleItemIds: new Set(),
|
183
|
-
invisibleItemIds: new Set()
|
184
|
-
};
|
185
|
-
}
|
186
|
-
overflowGroups[item.groupId].visibleItemIds.add(item.id);
|
218
|
+
groupManager.addItem(item.id, item.groupId);
|
219
|
+
item.element.setAttribute(_consts.DATA_OVERFLOW_GROUP, item.groupId);
|
187
220
|
}
|
188
221
|
update();
|
189
222
|
};
|
190
223
|
const addOverflowMenu = (el)=>{
|
191
224
|
overflowMenu = el;
|
192
225
|
};
|
226
|
+
const addDivider = (divider)=>{
|
227
|
+
if (!divider.groupId || overflowDividers[divider.groupId]) {
|
228
|
+
return;
|
229
|
+
}
|
230
|
+
divider.element.setAttribute(_consts.DATA_OVERFLOW_GROUP, divider.groupId);
|
231
|
+
overflowDividers[divider.groupId] = divider;
|
232
|
+
};
|
193
233
|
const removeOverflowMenu = ()=>{
|
194
234
|
overflowMenu = undefined;
|
195
235
|
};
|
236
|
+
const removeDivider = (groupId)=>{
|
237
|
+
if (!overflowDividers[groupId]) {
|
238
|
+
return;
|
239
|
+
}
|
240
|
+
const divider = overflowDividers[groupId];
|
241
|
+
if (divider.groupId) {
|
242
|
+
delete overflowDividers[groupId];
|
243
|
+
divider.element.removeAttribute(_consts.DATA_OVERFLOW_GROUP);
|
244
|
+
}
|
245
|
+
};
|
196
246
|
const removeItem = (itemId)=>{
|
197
247
|
if (!overflowItems[itemId]) {
|
198
248
|
return;
|
@@ -201,8 +251,8 @@ function createOverflowManager() {
|
|
201
251
|
visibleItemQueue.remove(itemId);
|
202
252
|
invisibleItemQueue.remove(itemId);
|
203
253
|
if (item.groupId) {
|
204
|
-
|
205
|
-
|
254
|
+
groupManager.removeItem(item.id, item.groupId);
|
255
|
+
item.element.removeAttribute(_consts.DATA_OVERFLOW_GROUP);
|
206
256
|
}
|
207
257
|
delete overflowItems[itemId];
|
208
258
|
update();
|
@@ -215,8 +265,8 @@ function createOverflowManager() {
|
|
215
265
|
removeItem,
|
216
266
|
update,
|
217
267
|
addOverflowMenu,
|
218
|
-
removeOverflowMenu
|
268
|
+
removeOverflowMenu,
|
269
|
+
addDivider,
|
270
|
+
removeDivider
|
219
271
|
};
|
220
|
-
}
|
221
|
-
|
222
|
-
//# sourceMappingURL=overflowManager.js.map
|
272
|
+
}
|