@fluentui/priority-overflow 9.0.0-rc.1 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,208 @@
1
+ define(["require", "exports", "./debounce", "./priorityQueue"], function (require, exports, debounce_1, priorityQueue_1) {
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.createOverflowManager = void 0;
5
+ /**
6
+ * @internal
7
+ * @returns overflow manager instance
8
+ */
9
+ function createOverflowManager() {
10
+ var container;
11
+ var overflowMenu;
12
+ var observing = false;
13
+ var options = {
14
+ padding: 10,
15
+ overflowAxis: 'horizontal',
16
+ overflowDirection: 'end',
17
+ minimumVisible: 0,
18
+ onUpdateItemVisibility: function () { return undefined; },
19
+ onUpdateOverflow: function () { return undefined; },
20
+ };
21
+ var overflowItems = {};
22
+ var overflowGroups = {};
23
+ var resizeObserver = new ResizeObserver(function (entries) {
24
+ if (!entries[0] || !container) {
25
+ return;
26
+ }
27
+ update();
28
+ });
29
+ var invisibleItemQueue = priorityQueue_1.createPriorityQueue(function (a, b) {
30
+ var itemA = overflowItems[a];
31
+ var itemB = overflowItems[b];
32
+ // Higher priority at the top of the queue
33
+ var priority = itemB.priority - itemA.priority;
34
+ if (priority !== 0) {
35
+ return priority;
36
+ }
37
+ var positionStatusBit = options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_FOLLOWING : Node.DOCUMENT_POSITION_PRECEDING;
38
+ // equal priority, use DOM order
39
+ // eslint-disable-next-line no-bitwise
40
+ return itemA.element.compareDocumentPosition(itemB.element) & positionStatusBit ? -1 : 1;
41
+ });
42
+ var visibleItemQueue = priorityQueue_1.createPriorityQueue(function (a, b) {
43
+ var itemA = overflowItems[a];
44
+ var itemB = overflowItems[b];
45
+ // Lower priority at the top of the queue
46
+ var priority = itemA.priority - itemB.priority;
47
+ if (priority !== 0) {
48
+ return priority;
49
+ }
50
+ var positionStatusBit = options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_PRECEDING : Node.DOCUMENT_POSITION_FOLLOWING;
51
+ // equal priority, use DOM order
52
+ // eslint-disable-next-line no-bitwise
53
+ return itemA.element.compareDocumentPosition(itemB.element) & positionStatusBit ? -1 : 1;
54
+ });
55
+ var getOffsetSize = function (el) {
56
+ return options.overflowAxis === 'horizontal' ? el.offsetWidth : el.offsetHeight;
57
+ };
58
+ var makeItemVisible = function () {
59
+ var nextVisible = invisibleItemQueue.dequeue();
60
+ visibleItemQueue.enqueue(nextVisible);
61
+ var item = overflowItems[nextVisible];
62
+ options.onUpdateItemVisibility({ item: item, visible: true });
63
+ if (item.groupId) {
64
+ overflowGroups[item.groupId].invisibleItemIds.delete(item.id);
65
+ overflowGroups[item.groupId].visibleItemIds.add(item.id);
66
+ }
67
+ return getOffsetSize(item.element);
68
+ };
69
+ var makeItemInvisible = function () {
70
+ var nextInvisible = visibleItemQueue.dequeue();
71
+ invisibleItemQueue.enqueue(nextInvisible);
72
+ var item = overflowItems[nextInvisible];
73
+ var width = getOffsetSize(item.element);
74
+ options.onUpdateItemVisibility({ item: item, visible: false });
75
+ if (item.groupId) {
76
+ overflowGroups[item.groupId].visibleItemIds.delete(item.id);
77
+ overflowGroups[item.groupId].invisibleItemIds.add(item.id);
78
+ }
79
+ return width;
80
+ };
81
+ var dispatchOverflowUpdate = function () {
82
+ var visibleItemIds = visibleItemQueue.all();
83
+ var invisibleItemIds = invisibleItemQueue.all();
84
+ var visibleItems = visibleItemIds.map(function (itemId) { return overflowItems[itemId]; });
85
+ var invisibleItems = invisibleItemIds.map(function (itemId) { return overflowItems[itemId]; });
86
+ var groupVisibility = {};
87
+ Object.entries(overflowGroups).forEach(function (_a) {
88
+ var groupId = _a[0], groupState = _a[1];
89
+ if (groupState.invisibleItemIds.size && groupState.visibleItemIds.size) {
90
+ groupVisibility[groupId] = 'overflow';
91
+ }
92
+ else if (groupState.visibleItemIds.size === 0) {
93
+ groupVisibility[groupId] = 'hidden';
94
+ }
95
+ else {
96
+ groupVisibility[groupId] = 'visible';
97
+ }
98
+ });
99
+ options.onUpdateOverflow({ visibleItems: visibleItems, invisibleItems: invisibleItems, groupVisibility: groupVisibility });
100
+ };
101
+ var processOverflowItems = function (availableSize) {
102
+ if (!container) {
103
+ return;
104
+ }
105
+ var overflowMenuOffset = overflowMenu ? getOffsetSize(overflowMenu) : 0;
106
+ // Snapshot of the visible/invisible state to compare for updates
107
+ var visibleTop = visibleItemQueue.peek();
108
+ var invisibleTop = invisibleItemQueue.peek();
109
+ var visibleItemIds = visibleItemQueue.all();
110
+ var currentWidth = visibleItemIds.reduce(function (sum, visibleItemId) {
111
+ var child = overflowItems[visibleItemId].element;
112
+ return sum + getOffsetSize(child);
113
+ }, 0);
114
+ // Add items until available width is filled - can result in overflow
115
+ while (currentWidth < availableSize && invisibleItemQueue.size() > 0) {
116
+ currentWidth += makeItemVisible();
117
+ }
118
+ // Remove items until there's no more overflow
119
+ while (currentWidth > availableSize && visibleItemQueue.size() > 0) {
120
+ if (visibleItemQueue.size() <= options.minimumVisible) {
121
+ break;
122
+ }
123
+ currentWidth -= makeItemInvisible();
124
+ }
125
+ // make sure the overflow menu can fit
126
+ if (visibleItemQueue.size() > options.minimumVisible &&
127
+ invisibleItemQueue.size() > 0 &&
128
+ currentWidth + overflowMenuOffset > availableSize) {
129
+ makeItemInvisible();
130
+ }
131
+ // only update when the state of visible/invisible items has changed
132
+ if (visibleItemQueue.peek() !== visibleTop || invisibleItemQueue.peek() !== invisibleTop) {
133
+ dispatchOverflowUpdate();
134
+ }
135
+ };
136
+ var forceUpdate = function () {
137
+ if (!container) {
138
+ return;
139
+ }
140
+ var availableSize = getOffsetSize(container) - options.padding;
141
+ processOverflowItems(availableSize);
142
+ };
143
+ var update = debounce_1.debounce(forceUpdate);
144
+ var observe = function (observedContainer, userOptions) {
145
+ Object.assign(options, userOptions);
146
+ observing = true;
147
+ Object.values(overflowItems).forEach(function (item) { return visibleItemQueue.enqueue(item.id); });
148
+ container = observedContainer;
149
+ resizeObserver.observe(container);
150
+ };
151
+ var disconnect = function () {
152
+ observing = false;
153
+ resizeObserver.disconnect();
154
+ };
155
+ var addItem = function (item) {
156
+ if (overflowItems[item.id]) {
157
+ return;
158
+ }
159
+ overflowItems[item.id] = item;
160
+ // some options can affect priority which are only set on `observe`
161
+ if (observing) {
162
+ visibleItemQueue.enqueue(item.id);
163
+ }
164
+ if (item.groupId) {
165
+ if (!overflowGroups[item.groupId]) {
166
+ overflowGroups[item.groupId] = {
167
+ visibleItemIds: new Set(),
168
+ invisibleItemIds: new Set(),
169
+ };
170
+ }
171
+ overflowGroups[item.groupId].visibleItemIds.add(item.id);
172
+ }
173
+ update();
174
+ };
175
+ var addOverflowMenu = function (el) {
176
+ overflowMenu = el;
177
+ };
178
+ var removeOverflowMenu = function () {
179
+ overflowMenu = undefined;
180
+ };
181
+ var removeItem = function (itemId) {
182
+ if (!overflowItems[itemId]) {
183
+ return;
184
+ }
185
+ var item = overflowItems[itemId];
186
+ visibleItemQueue.remove(itemId);
187
+ invisibleItemQueue.remove(itemId);
188
+ if (item.groupId) {
189
+ overflowGroups[item.groupId].visibleItemIds.delete(item.id);
190
+ overflowGroups[item.groupId].invisibleItemIds.delete(item.id);
191
+ }
192
+ delete overflowItems[itemId];
193
+ update();
194
+ };
195
+ return {
196
+ addItem: addItem,
197
+ disconnect: disconnect,
198
+ forceUpdate: forceUpdate,
199
+ observe: observe,
200
+ removeItem: removeItem,
201
+ update: update,
202
+ addOverflowMenu: addOverflowMenu,
203
+ removeOverflowMenu: removeOverflowMenu,
204
+ };
205
+ }
206
+ exports.createOverflowManager = createOverflowManager;
207
+ });
208
+ //# sourceMappingURL=overflowManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overflowManager.js","sourceRoot":"","sources":["../../../../../../../packages/react-components/priority-overflow/src/overflowManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { debounce } from './debounce';\nimport { createPriorityQueue } from './priorityQueue';\nimport type { OverflowGroupState, OverflowItemEntry, OverflowManager, ObserveOptions } from './types';\n\n/**\n * @internal\n * @returns overflow manager instance\n */\nexport function createOverflowManager(): OverflowManager {\n let container: HTMLElement | undefined;\n let overflowMenu: HTMLElement | undefined;\n let observing = false;\n const options: Required<ObserveOptions> = {\n padding: 10,\n overflowAxis: 'horizontal',\n overflowDirection: 'end',\n minimumVisible: 0,\n onUpdateItemVisibility: () => undefined,\n onUpdateOverflow: () => undefined,\n };\n\n const overflowItems: Record<string, OverflowItemEntry> = {};\n const overflowGroups: Record<string, { visibleItemIds: Set<string>; invisibleItemIds: Set<string> }> = {};\n const resizeObserver = new ResizeObserver(entries => {\n if (!entries[0] || !container) {\n return;\n }\n\n update();\n });\n\n const invisibleItemQueue = createPriorityQueue<string>((a, b) => {\n const itemA = overflowItems[a];\n const itemB = overflowItems[b];\n // Higher priority at the top of the queue\n const priority = itemB.priority - itemA.priority;\n if (priority !== 0) {\n return priority;\n }\n\n const positionStatusBit =\n options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_FOLLOWING : Node.DOCUMENT_POSITION_PRECEDING;\n\n // equal priority, use DOM order\n // eslint-disable-next-line no-bitwise\n return itemA.element.compareDocumentPosition(itemB.element) & positionStatusBit ? -1 : 1;\n });\n\n const visibleItemQueue = createPriorityQueue<string>((a, b) => {\n const itemA = overflowItems[a];\n const itemB = overflowItems[b];\n // Lower priority at the top of the queue\n const priority = itemA.priority - itemB.priority;\n\n if (priority !== 0) {\n return priority;\n }\n\n const positionStatusBit =\n options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_PRECEDING : Node.DOCUMENT_POSITION_FOLLOWING;\n\n // equal priority, use DOM order\n // eslint-disable-next-line no-bitwise\n return itemA.element.compareDocumentPosition(itemB.element) & positionStatusBit ? -1 : 1;\n });\n\n const getOffsetSize = (el: HTMLElement) => {\n return options.overflowAxis === 'horizontal' ? el.offsetWidth : el.offsetHeight;\n };\n\n const makeItemVisible = () => {\n const nextVisible = invisibleItemQueue.dequeue();\n visibleItemQueue.enqueue(nextVisible);\n\n const item = overflowItems[nextVisible];\n options.onUpdateItemVisibility({ item, visible: true });\n if (item.groupId) {\n overflowGroups[item.groupId].invisibleItemIds.delete(item.id);\n overflowGroups[item.groupId].visibleItemIds.add(item.id);\n }\n\n return getOffsetSize(item.element);\n };\n\n const makeItemInvisible = () => {\n const nextInvisible = visibleItemQueue.dequeue();\n invisibleItemQueue.enqueue(nextInvisible);\n\n const item = overflowItems[nextInvisible];\n const width = getOffsetSize(item.element);\n options.onUpdateItemVisibility({ item, visible: false });\n if (item.groupId) {\n overflowGroups[item.groupId].visibleItemIds.delete(item.id);\n overflowGroups[item.groupId].invisibleItemIds.add(item.id);\n }\n\n return width;\n };\n\n const dispatchOverflowUpdate = () => {\n const visibleItemIds = visibleItemQueue.all();\n const invisibleItemIds = invisibleItemQueue.all();\n\n const visibleItems = visibleItemIds.map(itemId => overflowItems[itemId]);\n const invisibleItems = invisibleItemIds.map(itemId => overflowItems[itemId]);\n\n const groupVisibility: Record<string, OverflowGroupState> = {};\n Object.entries(overflowGroups).forEach(([groupId, groupState]) => {\n if (groupState.invisibleItemIds.size && groupState.visibleItemIds.size) {\n groupVisibility[groupId] = 'overflow';\n } else if (groupState.visibleItemIds.size === 0) {\n groupVisibility[groupId] = 'hidden';\n } else {\n groupVisibility[groupId] = 'visible';\n }\n });\n\n options.onUpdateOverflow({ visibleItems, invisibleItems, groupVisibility });\n };\n\n const processOverflowItems = (availableSize: number) => {\n if (!container) {\n return;\n }\n\n const overflowMenuOffset = overflowMenu ? getOffsetSize(overflowMenu) : 0;\n\n // Snapshot of the visible/invisible state to compare for updates\n const visibleTop = visibleItemQueue.peek();\n const invisibleTop = invisibleItemQueue.peek();\n\n const visibleItemIds = visibleItemQueue.all();\n let currentWidth = visibleItemIds.reduce((sum, visibleItemId) => {\n const child = overflowItems[visibleItemId].element;\n return sum + getOffsetSize(child);\n }, 0);\n\n // Add items until available width is filled - can result in overflow\n while (currentWidth < availableSize && invisibleItemQueue.size() > 0) {\n currentWidth += makeItemVisible();\n }\n\n // Remove items until there's no more overflow\n while (currentWidth > availableSize && visibleItemQueue.size() > 0) {\n if (visibleItemQueue.size() <= options.minimumVisible) {\n break;\n }\n currentWidth -= makeItemInvisible();\n }\n\n // make sure the overflow menu can fit\n if (\n visibleItemQueue.size() > options.minimumVisible &&\n invisibleItemQueue.size() > 0 &&\n currentWidth + overflowMenuOffset > availableSize\n ) {\n makeItemInvisible();\n }\n\n // only update when the state of visible/invisible items has changed\n if (visibleItemQueue.peek() !== visibleTop || invisibleItemQueue.peek() !== invisibleTop) {\n dispatchOverflowUpdate();\n }\n };\n\n const forceUpdate: OverflowManager['forceUpdate'] = () => {\n if (!container) {\n return;\n }\n\n const availableSize = getOffsetSize(container) - options.padding;\n processOverflowItems(availableSize);\n };\n\n const update: OverflowManager['update'] = debounce(forceUpdate);\n\n const observe: OverflowManager['observe'] = (observedContainer, userOptions) => {\n Object.assign(options, userOptions);\n observing = true;\n Object.values(overflowItems).forEach(item => visibleItemQueue.enqueue(item.id));\n\n container = observedContainer;\n resizeObserver.observe(container);\n };\n\n const disconnect: OverflowManager['disconnect'] = () => {\n observing = false;\n resizeObserver.disconnect();\n };\n\n const addItem: OverflowManager['addItem'] = item => {\n if (overflowItems[item.id]) {\n return;\n }\n\n overflowItems[item.id] = item;\n\n // some options can affect priority which are only set on `observe`\n if (observing) {\n visibleItemQueue.enqueue(item.id);\n }\n\n if (item.groupId) {\n if (!overflowGroups[item.groupId]) {\n overflowGroups[item.groupId] = {\n visibleItemIds: new Set<string>(),\n invisibleItemIds: new Set<string>(),\n };\n }\n\n overflowGroups[item.groupId].visibleItemIds.add(item.id);\n }\n\n update();\n };\n\n const addOverflowMenu: OverflowManager['addOverflowMenu'] = el => {\n overflowMenu = el;\n };\n\n const removeOverflowMenu: OverflowManager['removeOverflowMenu'] = () => {\n overflowMenu = undefined;\n };\n\n const removeItem: OverflowManager['removeItem'] = itemId => {\n if (!overflowItems[itemId]) {\n return;\n }\n\n const item = overflowItems[itemId];\n visibleItemQueue.remove(itemId);\n invisibleItemQueue.remove(itemId);\n\n if (item.groupId) {\n overflowGroups[item.groupId].visibleItemIds.delete(item.id);\n overflowGroups[item.groupId].invisibleItemIds.delete(item.id);\n }\n\n delete overflowItems[itemId];\n update();\n };\n\n return {\n addItem,\n disconnect,\n forceUpdate,\n observe,\n removeItem,\n update,\n addOverflowMenu,\n removeOverflowMenu,\n };\n}\n"]}
@@ -0,0 +1,97 @@
1
+ define(["require", "exports"], function (require, exports) {
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.createPriorityQueue = void 0;
5
+ /**
6
+ * @param compare - comparison function for items
7
+ * @returns Priority queue implemented with a min heap
8
+ */
9
+ function createPriorityQueue(compare) {
10
+ var arr = [];
11
+ var size = 0;
12
+ var left = function (i) {
13
+ return 2 * i + 1;
14
+ };
15
+ var right = function (i) {
16
+ return 2 * i + 2;
17
+ };
18
+ var parent = function (i) {
19
+ return Math.floor((i - 1) / 2);
20
+ };
21
+ var swap = function (a, b) {
22
+ var tmp = arr[a];
23
+ arr[a] = arr[b];
24
+ arr[b] = tmp;
25
+ };
26
+ var heapify = function (i) {
27
+ var smallest = i;
28
+ var l = left(i);
29
+ var r = right(i);
30
+ if (l < size && compare(arr[l], arr[smallest]) < 0) {
31
+ smallest = l;
32
+ }
33
+ if (r < size && compare(arr[r], arr[smallest]) < 0) {
34
+ smallest = r;
35
+ }
36
+ if (smallest !== i) {
37
+ swap(smallest, i);
38
+ heapify(smallest);
39
+ }
40
+ };
41
+ var dequeue = function () {
42
+ if (size === 0) {
43
+ throw new Error('Priority queue empty');
44
+ }
45
+ var res = arr[0];
46
+ arr[0] = arr[--size];
47
+ heapify(0);
48
+ return res;
49
+ };
50
+ var peek = function () {
51
+ if (size === 0) {
52
+ return null;
53
+ }
54
+ return arr[0];
55
+ };
56
+ var enqueue = function (item) {
57
+ arr[size++] = item;
58
+ var i = size - 1;
59
+ var p = parent(i);
60
+ while (i > 0 && compare(arr[p], arr[i]) > 0) {
61
+ swap(p, i);
62
+ i = p;
63
+ p = parent(i);
64
+ }
65
+ };
66
+ var contains = function (item) {
67
+ var index = arr.indexOf(item);
68
+ return index >= 0 && index < size;
69
+ };
70
+ var remove = function (item) {
71
+ var i = arr.indexOf(item);
72
+ if (i === -1 || i >= size) {
73
+ return;
74
+ }
75
+ arr[i] = arr[--size];
76
+ heapify(i);
77
+ };
78
+ var clear = function () {
79
+ size = 0;
80
+ };
81
+ var all = function () {
82
+ return arr.slice(0, size);
83
+ };
84
+ return {
85
+ all: all,
86
+ clear: clear,
87
+ contains: contains,
88
+ dequeue: dequeue,
89
+ enqueue: enqueue,
90
+ peek: peek,
91
+ remove: remove,
92
+ size: function () { return size; },
93
+ };
94
+ }
95
+ exports.createPriorityQueue = createPriorityQueue;
96
+ });
97
+ //# sourceMappingURL=priorityQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priorityQueue.js","sourceRoot":"","sources":["../../../../../../../packages/react-components/priority-overflow/src/priorityQueue.ts"],"names":[],"mappings":"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","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"]}
@@ -0,0 +1,5 @@
1
+ define(["require", "exports"], function (require, exports) {
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ });
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../packages/react-components/priority-overflow/src/types.ts"],"names":[],"mappings":"","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\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 * Unsets the overflow menu element\n */\n removeOverflowMenu: () => void;\n}\n"]}
@@ -10,7 +10,6 @@ exports.debounce = void 0;
10
10
  * @param fn - Function to debounce
11
11
  * @returns debounced function
12
12
  */
13
-
14
13
  function debounce(fn) {
15
14
  let pending;
16
15
  return () => {
@@ -25,6 +24,5 @@ function debounce(fn) {
25
24
  }
26
25
  };
27
26
  }
28
-
29
27
  exports.debounce = debounce;
30
28
  //# sourceMappingURL=debounce.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["packages/react-components/priority-overflow/src/debounce.ts"],"names":[],"mappings":";;;;;;AAAA;;;;;AAKG;;AACH,SAAgB,QAAhB,CAAyB,EAAzB,EAAqC;EACnC,IAAI,OAAJ;EACA,OAAO,MAAK;IACV,IAAI,CAAC,OAAL,EAAc;MACZ,OAAO,GAAG,IAAV;MACA,cAAc,CAAC,MAAK;QAClB;QACA;QACA,OAAO,GAAG,KAAV;QACA,EAAE;MACH,CALa,CAAd;IAMD;EACF,CAVD;AAWD;;AAbD,OAAA,CAAA,QAAA,GAAA,QAAA","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"],"sourceRoot":"../src/"}
1
+ {"version":3,"mappings":";;;;;;AAAA;;;;;;AAMA,SAAgBA,QAAQ,CAACC,EAAY;EACnC,IAAIC,OAAgB;EACpB,OAAO,MAAK;IACV,IAAI,CAACA,OAAO,EAAE;MACZA,OAAO,GAAG,IAAI;MACdC,cAAc,CAAC,MAAK;QAClB;QACA;QACAD,OAAO,GAAG,KAAK;QACfD,EAAE,EAAE;MACN,CAAC,CAAC;;EAEN,CAAC;AACH;AAbAG","names":["debounce","fn","pending","queueMicrotask","exports"],"sourceRoot":"../src/","sources":["packages/react-components/priority-overflow/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"]}
@@ -4,9 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.createOverflowManager = void 0;
7
-
8
7
  var overflowManager_1 = /*#__PURE__*/require("./overflowManager");
9
-
10
8
  Object.defineProperty(exports, "createOverflowManager", {
11
9
  enumerable: true,
12
10
  get: function () {
@@ -1 +1 @@
1
- {"version":3,"sources":["packages/react-components/priority-overflow/src/index.ts"],"names":[],"mappings":";;;;;;;AAAA,IAAA,iBAAA,gBAAA,OAAA,CAAA,mBAAA,CAAA;;AAAS,MAAA,CAAA,cAAA,CAAA,OAAA,EAAA,uBAAA,EAAA;EAAA,UAAA,EAAA,IAAA;EAAA,GAAA,EAAA,YAAA;IAAA,OAAA,iBAAA,CAAA,qBAAA;EAAqB;AAArB,CAAA","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"],"sourceRoot":"../src/"}
1
+ {"version":3,"mappings":";;;;;;AAAA;AAASA;EAAAC;EAAAC;IAAA,8CAAqB;EAAA;AAAA","names":["Object","enumerable","get"],"sourceRoot":"../src/","sources":["packages/react-components/priority-overflow/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"]}
@@ -4,16 +4,12 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.createOverflowManager = void 0;
7
-
8
7
  const debounce_1 = /*#__PURE__*/require("./debounce");
9
-
10
8
  const priorityQueue_1 = /*#__PURE__*/require("./priorityQueue");
11
9
  /**
12
10
  * @internal
13
11
  * @returns overflow manager instance
14
12
  */
15
-
16
-
17
13
  function createOverflowManager() {
18
14
  let container;
19
15
  let overflowMenu;
@@ -32,44 +28,37 @@ function createOverflowManager() {
32
28
  if (!entries[0] || !container) {
33
29
  return;
34
30
  }
35
-
36
31
  update();
37
32
  });
38
33
  const invisibleItemQueue = priorityQueue_1.createPriorityQueue((a, b) => {
39
34
  const itemA = overflowItems[a];
40
- const itemB = overflowItems[b]; // Higher priority at the top of the queue
41
-
35
+ const itemB = overflowItems[b];
36
+ // Higher priority at the top of the queue
42
37
  const priority = itemB.priority - itemA.priority;
43
-
44
38
  if (priority !== 0) {
45
39
  return priority;
46
40
  }
47
-
48
- const positionStatusBit = options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_FOLLOWING : Node.DOCUMENT_POSITION_PRECEDING; // equal priority, use DOM order
41
+ const positionStatusBit = options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_FOLLOWING : Node.DOCUMENT_POSITION_PRECEDING;
42
+ // equal priority, use DOM order
49
43
  // eslint-disable-next-line no-bitwise
50
-
51
44
  return itemA.element.compareDocumentPosition(itemB.element) & positionStatusBit ? -1 : 1;
52
45
  });
53
46
  const visibleItemQueue = priorityQueue_1.createPriorityQueue((a, b) => {
54
47
  const itemA = overflowItems[a];
55
- const itemB = overflowItems[b]; // Lower priority at the top of the queue
56
-
48
+ const itemB = overflowItems[b];
49
+ // Lower priority at the top of the queue
57
50
  const priority = itemA.priority - itemB.priority;
58
-
59
51
  if (priority !== 0) {
60
52
  return priority;
61
53
  }
62
-
63
- const positionStatusBit = options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_PRECEDING : Node.DOCUMENT_POSITION_FOLLOWING; // equal priority, use DOM order
54
+ const positionStatusBit = options.overflowDirection === 'end' ? Node.DOCUMENT_POSITION_PRECEDING : Node.DOCUMENT_POSITION_FOLLOWING;
55
+ // equal priority, use DOM order
64
56
  // eslint-disable-next-line no-bitwise
65
-
66
57
  return itemA.element.compareDocumentPosition(itemB.element) & positionStatusBit ? -1 : 1;
67
58
  });
68
-
69
59
  const getOffsetSize = el => {
70
60
  return options.overflowAxis === 'horizontal' ? el.offsetWidth : el.offsetHeight;
71
61
  };
72
-
73
62
  const makeItemVisible = () => {
74
63
  const nextVisible = invisibleItemQueue.dequeue();
75
64
  visibleItemQueue.enqueue(nextVisible);
@@ -78,15 +67,12 @@ function createOverflowManager() {
78
67
  item,
79
68
  visible: true
80
69
  });
81
-
82
70
  if (item.groupId) {
83
71
  overflowGroups[item.groupId].invisibleItemIds.delete(item.id);
84
72
  overflowGroups[item.groupId].visibleItemIds.add(item.id);
85
73
  }
86
-
87
74
  return getOffsetSize(item.element);
88
75
  };
89
-
90
76
  const makeItemInvisible = () => {
91
77
  const nextInvisible = visibleItemQueue.dequeue();
92
78
  invisibleItemQueue.enqueue(nextInvisible);
@@ -96,15 +82,12 @@ function createOverflowManager() {
96
82
  item,
97
83
  visible: false
98
84
  });
99
-
100
85
  if (item.groupId) {
101
86
  overflowGroups[item.groupId].visibleItemIds.delete(item.id);
102
87
  overflowGroups[item.groupId].invisibleItemIds.add(item.id);
103
88
  }
104
-
105
89
  return width;
106
90
  };
107
-
108
91
  const dispatchOverflowUpdate = () => {
109
92
  const visibleItemIds = visibleItemQueue.all();
110
93
  const invisibleItemIds = invisibleItemQueue.all();
@@ -126,56 +109,47 @@ function createOverflowManager() {
126
109
  groupVisibility
127
110
  });
128
111
  };
129
-
130
112
  const processOverflowItems = availableSize => {
131
113
  if (!container) {
132
114
  return;
133
115
  }
134
-
135
- const overflowMenuOffset = overflowMenu ? getOffsetSize(overflowMenu) : 0; // Snapshot of the visible/invisible state to compare for updates
136
-
116
+ const overflowMenuOffset = overflowMenu ? getOffsetSize(overflowMenu) : 0;
117
+ // Snapshot of the visible/invisible state to compare for updates
137
118
  const visibleTop = visibleItemQueue.peek();
138
119
  const invisibleTop = invisibleItemQueue.peek();
139
120
  const visibleItemIds = visibleItemQueue.all();
140
121
  let currentWidth = visibleItemIds.reduce((sum, visibleItemId) => {
141
122
  const child = overflowItems[visibleItemId].element;
142
123
  return sum + getOffsetSize(child);
143
- }, 0); // Add items until available width is filled
144
-
124
+ }, 0);
125
+ // Add items until available width is filled - can result in overflow
145
126
  while (currentWidth < availableSize && invisibleItemQueue.size() > 0) {
146
127
  currentWidth += makeItemVisible();
147
- } // Remove items until there's no more overlap
148
-
149
-
128
+ }
129
+ // Remove items until there's no more overflow
150
130
  while (currentWidth > availableSize && visibleItemQueue.size() > 0) {
151
- if (visibleItemQueue.size() === options.minimumVisible) {
131
+ if (visibleItemQueue.size() <= options.minimumVisible) {
152
132
  break;
153
133
  }
154
-
155
134
  currentWidth -= makeItemInvisible();
156
135
  }
157
-
158
- if (invisibleItemQueue.size() > 0 && currentWidth + overflowMenuOffset > availableSize) {
136
+ // make sure the overflow menu can fit
137
+ if (visibleItemQueue.size() > options.minimumVisible && invisibleItemQueue.size() > 0 && currentWidth + overflowMenuOffset > availableSize) {
159
138
  makeItemInvisible();
160
- } // only update when the state of visible/invisible items has changed
161
-
162
-
139
+ }
140
+ // only update when the state of visible/invisible items has changed
163
141
  if (visibleItemQueue.peek() !== visibleTop || invisibleItemQueue.peek() !== invisibleTop) {
164
142
  dispatchOverflowUpdate();
165
143
  }
166
144
  };
167
-
168
145
  const forceUpdate = () => {
169
146
  if (!container) {
170
147
  return;
171
148
  }
172
-
173
149
  const availableSize = getOffsetSize(container) - options.padding;
174
150
  processOverflowItems(availableSize);
175
151
  };
176
-
177
152
  const update = debounce_1.debounce(forceUpdate);
178
-
179
153
  const observe = (observedContainer, userOptions) => {
180
154
  Object.assign(options, userOptions);
181
155
  observing = true;
@@ -183,23 +157,19 @@ function createOverflowManager() {
183
157
  container = observedContainer;
184
158
  resizeObserver.observe(container);
185
159
  };
186
-
187
160
  const disconnect = () => {
188
161
  observing = false;
189
162
  resizeObserver.disconnect();
190
163
  };
191
-
192
164
  const addItem = item => {
193
165
  if (overflowItems[item.id]) {
194
166
  return;
195
167
  }
196
-
197
- overflowItems[item.id] = item; // some options can affect priority which are only set on `observe`
198
-
168
+ overflowItems[item.id] = item;
169
+ // some options can affect priority which are only set on `observe`
199
170
  if (observing) {
200
171
  visibleItemQueue.enqueue(item.id);
201
172
  }
202
-
203
173
  if (item.groupId) {
204
174
  if (!overflowGroups[item.groupId]) {
205
175
  overflowGroups[item.groupId] = {
@@ -207,39 +177,30 @@ function createOverflowManager() {
207
177
  invisibleItemIds: new Set()
208
178
  };
209
179
  }
210
-
211
180
  overflowGroups[item.groupId].visibleItemIds.add(item.id);
212
181
  }
213
-
214
182
  update();
215
183
  };
216
-
217
184
  const addOverflowMenu = el => {
218
185
  overflowMenu = el;
219
186
  };
220
-
221
187
  const removeOverflowMenu = () => {
222
188
  overflowMenu = undefined;
223
189
  };
224
-
225
190
  const removeItem = itemId => {
226
191
  if (!overflowItems[itemId]) {
227
192
  return;
228
193
  }
229
-
230
194
  const item = overflowItems[itemId];
231
195
  visibleItemQueue.remove(itemId);
232
196
  invisibleItemQueue.remove(itemId);
233
-
234
197
  if (item.groupId) {
235
198
  overflowGroups[item.groupId].visibleItemIds.delete(item.id);
236
199
  overflowGroups[item.groupId].invisibleItemIds.delete(item.id);
237
200
  }
238
-
239
201
  delete overflowItems[itemId];
240
202
  update();
241
203
  };
242
-
243
204
  return {
244
205
  addItem,
245
206
  disconnect,
@@ -251,6 +212,5 @@ function createOverflowManager() {
251
212
  removeOverflowMenu
252
213
  };
253
214
  }
254
-
255
215
  exports.createOverflowManager = createOverflowManager;
256
216
  //# sourceMappingURL=overflowManager.js.map