@fluentui/priority-overflow 9.0.2 → 9.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|