Private
Public Access
1
0

feat: Fluent UI Outlook Lite + connections mockup

This commit is contained in:
2026-04-14 18:52:25 +00:00
parent 1199eff6c3
commit dfa4010406
34820 changed files with 1003813 additions and 205 deletions

277
node_modules/@fluentui/priority-overflow/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,277 @@
# Change Log - @fluentui/priority-overflow
This log was last generated on Thu, 12 Feb 2026 10:42:45 GMT and should not be manually modified.
<!-- Start content -->
## [9.3.0](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.3.0)
Thu, 12 Feb 2026 10:42:45 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.2.1..@fluentui/priority-overflow_v9.3.0)
### Minor changes
- feat: add support for pinned items ([PR #35712](https://github.com/microsoft/fluentui/pull/35712) by olfedias@microsoft.com)
## [9.2.1](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.2.1)
Fri, 31 Oct 2025 16:22:02 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.2.0..@fluentui/priority-overflow_v9.2.1)
### Patches
- fix: use numeric literals for Node constants to make SSR work ([PR #35357](https://github.com/microsoft/fluentui/pull/35357) by 198982749+Copilot@users.noreply.github.com)
## [9.2.0](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.2.0)
Thu, 02 Oct 2025 15:12:11 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.16..@fluentui/priority-overflow_v9.2.0)
### Minor changes
- fix: overflowMenuSize is included in occupiedSize ([PR #35090](https://github.com/microsoft/fluentui/pull/35090) by vkozlova@microsoft.com)
## [9.1.16](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.16)
Mon, 08 Sep 2025 12:51:42 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.15..@fluentui/priority-overflow_v9.1.16)
### Patches
- chore: enforce explicit module boundary types ([PR #35080](https://github.com/microsoft/fluentui/pull/35080) by dmytrokirpa@microsoft.com)
## [9.1.15](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.15)
Fri, 21 Feb 2025 14:34:03 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.14..@fluentui/priority-overflow_v9.1.15)
### Patches
- fix: Add a defensive check when getting overflow item records ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by lingfangao@hotmail.com)
## [9.1.14](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.14)
Mon, 11 Nov 2024 10:01:03 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.13..@fluentui/priority-overflow_v9.1.14)
### Patches
- chore: replace npm-scripts and just-scrtips with nx inferred tasks ([PR #33074](https://github.com/microsoft/fluentui/pull/33074) by martinhochel@microsoft.com)
## [9.1.13](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.13)
Thu, 06 Jun 2024 15:26:28 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.12..@fluentui/priority-overflow_v9.1.13)
### Patches
- chore: disable eslint rule ([PR #30967](https://github.com/microsoft/fluentui/pull/30967) by seanmonahan@microsoft.com)
## [9.1.12](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.12)
Thu, 16 May 2024 09:25:11 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.11..@fluentui/priority-overflow_v9.1.12)
### Patches
- force update the overflow when item is removed ([PR #31340](https://github.com/microsoft/fluentui/pull/31340) by miroslav.stastny@microsoft.com)
## [9.1.11](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.11)
Thu, 14 Dec 2023 09:58:42 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.10..@fluentui/priority-overflow_v9.1.11)
### Patches
- fix: updates should be synchronous in unit tests ([PR #30014](https://github.com/microsoft/fluentui/pull/30014) by lingfangao@hotmail.com)
## [9.1.10](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.10)
Mon, 20 Nov 2023 09:55:08 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.9..@fluentui/priority-overflow_v9.1.10)
### Patches
- fix: disconnect should dispose all state correctly ([PR #29375](https://github.com/microsoft/fluentui/pull/29375) by lingfan.gao@microsoft.com)
## [9.1.9](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.9)
Thu, 09 Nov 2023 17:29:49 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.8..@fluentui/priority-overflow_v9.1.9)
### Patches
- chore: use package.json#files setup instead of npmignore for all v9 libraries ([PR #29734](https://github.com/microsoft/fluentui/pull/29734) by martinhochel@microsoft.com)
## [9.1.8](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.8)
Mon, 23 Oct 2023 09:51:55 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.7..@fluentui/priority-overflow_v9.1.8)
### Patches
- fix: Use container window's resize observer ([PR #29551](https://github.com/microsoft/fluentui/pull/29551) by lingfangao@hotmail.com)
## [9.1.7](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.7)
Tue, 26 Sep 2023 17:49:01 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.6..@fluentui/priority-overflow_v9.1.7)
### Patches
- chore: trigger manual version bump after broken release ([PR #29303](https://github.com/microsoft/fluentui/pull/29303) by yuanboxue@microsoft.com)
## [9.1.6](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.6)
Tue, 26 Sep 2023 15:32:06 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.5..@fluentui/priority-overflow_v9.1.6)
### Patches
- fix: bump swc core to mitigate transpilation memory leaks ([PR #29253](https://github.com/microsoft/fluentui/pull/29253) by martinhochel@microsoft.com)
## [9.1.5](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.5)
Tue, 05 Sep 2023 13:29:14 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.4..@fluentui/priority-overflow_v9.1.5)
### Patches
- bumps @swc/helpers version to 0.5.1 ([PR #28989](https://github.com/microsoft/fluentui/pull/28989) by bernardo.sunderhus@gmail.com)
## [9.1.4](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.4)
Fri, 11 Aug 2023 12:14:24 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.3..@fluentui/priority-overflow_v9.1.4)
### Patches
- fix: flickering in Overflow ([PR #28767](https://github.com/microsoft/fluentui/pull/28767) by vkozlova@microsoft.com)
## [9.1.3](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.3)
Wed, 09 Aug 2023 13:16:48 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.2..@fluentui/priority-overflow_v9.1.3)
### Patches
- fix: inaccurate calculation of size ([PR #28728](https://github.com/microsoft/fluentui/pull/28728) by vkozlova@microsoft.com)
## [9.1.2](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.2)
Tue, 25 Jul 2023 13:29:15 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.1..@fluentui/priority-overflow_v9.1.2)
### Patches
- fix: Overflow update should run show/hide steps twice ([PR #28628](https://github.com/microsoft/fluentui/pull/28628) by lingfan.gao@microsoft.com)
## [9.1.1](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.1)
Mon, 26 Jun 2023 09:53:53 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.0..@fluentui/priority-overflow_v9.1.1)
### Patches
- 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)
## [9.1.0](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.0)
Tue, 20 Jun 2023 12:38:54 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.3..@fluentui/priority-overflow_v9.1.0)
### Minor changes
- feat: Added support for custom divider ([PR #28011](https://github.com/microsoft/fluentui/pull/28011) by vkozlova@microsoft.com)
## [9.0.3](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.0.3)
Fri, 12 May 2023 20:28:09 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.2..@fluentui/priority-overflow_v9.0.3)
### Patches
- fix: overflowManager should always dispatch initial state ([PR #27756](https://github.com/microsoft/fluentui/pull/27756) by lingfangao@hotmail.com)
- chore: exclude .swcrc from being published ([PR #27740](https://github.com/microsoft/fluentui/pull/27740) by olfedias@microsoft.com)
## [9.0.2](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.0.2)
Tue, 21 Mar 2023 21:23:19 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.1..@fluentui/priority-overflow_v9.0.2)
### Patches
- fix: add node field to package.json exports map. ([PR #27154](https://github.com/microsoft/fluentui/pull/27154) by tristan.watanabe@gmail.com)
- chore: migrate to swc transpilation approach. ([PR #27250](https://github.com/microsoft/fluentui/pull/27250) by tristan.watanabe@gmail.com)
## [9.0.1](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.0.1)
Tue, 07 Feb 2023 14:13:08 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.0..@fluentui/priority-overflow_v9.0.1)
### Patches
- fix: New overflow items all always dispatch updates to subscriber ([PR #26565](https://github.com/microsoft/fluentui/pull/26565) by lingfangao@hotmail.com)
## [9.0.0](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.0.0)
Wed, 18 Jan 2023 16:32:53 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.0-rc.2..@fluentui/priority-overflow_v9.0.0)
### Patches
- Release as stable ([PR #26380](https://github.com/microsoft/fluentui/pull/26380) by lingfangao@hotmail.com)
## [9.0.0-rc.2](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.0.0-rc.2)
Mon, 09 Jan 2023 14:34:54 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.0-rc.1..@fluentui/priority-overflow_v9.0.0-rc.2)
### Changes
- fix: Minimum visible overflow items should be respected ([PR #26194](https://github.com/microsoft/fluentui/pull/26194) by lingfangao@hotmail.com)
## [9.0.0-rc.1](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.0.0-rc.1)
Thu, 17 Nov 2022 23:05:32 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.0-beta.4..@fluentui/priority-overflow_v9.0.0-rc.1)
### Changes
- feat: Bump to RC ([PR #25659](https://github.com/microsoft/fluentui/pull/25659) by lingfangao@hotmail.com)
## [9.0.0-beta.4](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.0.0-beta.4)
Fri, 11 Nov 2022 14:57:50 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.0-beta.3..@fluentui/priority-overflow_v9.0.0-beta.4)
### Changes
- fix: create valid export maps ([PR #25558](https://github.com/microsoft/fluentui/pull/25558) by martinhochel@microsoft.com)
## [9.0.0-beta.3](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.0.0-beta.3)
Thu, 13 Oct 2022 11:02:41 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.0-beta.2..@fluentui/priority-overflow_v9.0.0-beta.3)
### Changes
- feat: Adds API to register overflow menus for better available space calculation ([PR #25091](https://github.com/microsoft/fluentui/pull/25091) by lingfangao@hotmail.com)
- new overflow items should only be enqueued while observing ([PR #25122](https://github.com/microsoft/fluentui/pull/25122) by lingfangao@hotmail.com)
## [9.0.0-beta.2](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.0.0-beta.2)
Tue, 28 Jun 2022 15:14:10 GMT
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.0.0-beta.1..@fluentui/priority-overflow_v9.0.0-beta.2)
### Changes
- chore: Mark internal APIs with @internal ([PR #23689](https://github.com/microsoft/fluentui/pull/23689) by lingfangao@hotmail.com)
## [9.0.0-beta.1](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.0.0-beta.1)
Mon, 23 May 2022 12:13:58 GMT
### Changes
- feat: Initial beta release ([PR #22913](https://github.com/microsoft/fluentui/pull/22913) by lingfangao@hotmail.com)

15
node_modules/@fluentui/priority-overflow/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,15 @@
@fluentui/priority-overflow
Copyright (c) Microsoft Corporation
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Note: Usage of the fonts and icons referenced in Fluent UI React is subject to the terms listed at https://aka.ms/fluentui-assets-license

5
node_modules/@fluentui/priority-overflow/README.md generated vendored Normal file
View File

@@ -0,0 +1,5 @@
# @fluentui/priority-overflow
**Priority Overflow components for [Fluent UI React](https://react.fluentui.dev)**
These are not production-ready components and **should never be used in product**. This space is useful for testing new components whose APIs might change before final release.

View File

@@ -0,0 +1,149 @@
/**
* @internal
* @returns overflow manager instance
*/
export declare function createOverflowManager(): OverflowManager;
export declare interface ObserveOptions {
/**
* Padding (in px) at the end of the container before overflow occurs
* Useful to account for extra elements (i.e. dropdown menu)
* or to account for any kinds of margins between items which are hard to measure with JS
* @default 10
*/
padding?: number;
/**
* Direction where items are removed when overflow occurs
* @default end
*/
overflowDirection?: OverflowDirection;
/**
* Horizontal or vertical overflow
* @default horizontal
*/
overflowAxis?: OverflowAxis;
/**
* The minimum number of visible items
*/
minimumVisible?: number;
/**
* Callback when item visibility is updated
*/
onUpdateItemVisibility: OnUpdateItemVisibility;
/**
* Callback when item visibility is updated
*/
onUpdateOverflow: OnUpdateOverflow;
/**
* When true, the overflow menu has default hidden items
* @default false
*/
hasHiddenItems?: boolean;
}
export declare type OnUpdateItemVisibility = (data: OnUpdateItemVisibilityPayload) => void;
export declare interface OnUpdateItemVisibilityPayload {
item: OverflowItemEntry;
visible: boolean;
}
/**
* signature similar to standard event listeners, but typed to handle the custom event
*/
export declare type OnUpdateOverflow = (data: OverflowEventPayload) => void;
export declare type OverflowAxis = 'horizontal' | 'vertical';
export declare type OverflowDirection = 'start' | 'end';
export declare interface OverflowDividerEntry {
/**
* HTML element that will disappear when overflowed
*/
element: HTMLElement;
groupId: string;
}
/**
* Payload of the custom DOM event for overflow updates
*/
export declare interface OverflowEventPayload {
visibleItems: OverflowItemEntry[];
invisibleItems: OverflowItemEntry[];
groupVisibility: Record<string, OverflowGroupState>;
}
export declare type OverflowGroupState = 'visible' | 'hidden' | 'overflow';
export declare interface OverflowItemEntry {
/**
* HTML element that will be disappear when overflowed
*/
element: HTMLElement;
/**
* Lower priority items are invisible first when the container is overflowed
* @default 0
*/
priority: number;
/**
* Specific id, used to track visibility and provide updates to consumers
*/
id: string;
groupId?: string;
/**
* If true, the item will never overflow and will always be visible.
* Pinned items are excluded from the overflow count.
* @default false
*/
pinned?: boolean;
}
/**
* @internal
*/
export declare interface OverflowManager {
/**
* Starts observing the container and managing the overflow state
*/
observe: (container: HTMLElement, options: ObserveOptions) => void;
/**
* Stops observing the container
*/
disconnect: () => void;
/**
* Add overflow items
*/
addItem: (items: OverflowItemEntry) => void;
/**
* Remove overflow item
*/
removeItem: (itemId: string) => void;
/**
* Manually update the overflow, updates are batched and async
*/
update: () => void;
/**
* Manually update the overflow sync
*/
forceUpdate: () => void;
/**
* Adds an element that opens an overflow menu. This is used to calculate
* available space and check if additional items need to overflow
*/
addOverflowMenu: (element: HTMLElement) => void;
/**
* Add overflow divider
*/
addDivider: (divider: OverflowDividerEntry) => void;
/**
* Remove overflow divider
*/
removeDivider: (groupId: string) => void;
/**
* Unsets the overflow menu element
*/
removeOverflowMenu: () => void;
}
export { }

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
DATA_OVERFLOWING: function() {
return DATA_OVERFLOWING;
},
DATA_OVERFLOW_GROUP: function() {
return DATA_OVERFLOW_GROUP;
}
});
const DATA_OVERFLOWING = 'data-overflowing';
const DATA_OVERFLOW_GROUP = 'data-overflow-group';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/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":";;;;;;;;;;;IAAaA,gBAAgB;eAAhBA;;IACAC,mBAAmB;eAAnBA;;;AADN,MAAMD,mBAAmB;AACzB,MAAMC,sBAAsB"}

View File

@@ -0,0 +1,32 @@
/**
* Helper function that creates a resize observer in the element's own window global
* @param elementToObserve - Uses the element's window global to create the resize observer
* @param callback
* @returns function to cleanup the resize observer
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "observeResize", {
enumerable: true,
get: function() {
return observeResize;
}
});
function observeResize(elementToObserve, callback) {
var _elementToObserve_ownerDocument_defaultView;
const GlobalResizeObserver = (_elementToObserve_ownerDocument_defaultView = elementToObserve.ownerDocument.defaultView) === null || _elementToObserve_ownerDocument_defaultView === void 0 ? void 0 : _elementToObserve_ownerDocument_defaultView.ResizeObserver;
if (!GlobalResizeObserver) {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.error('@fluentui/priority-overflow', 'ResizeObserver does not exist on container window');
}
return ()=>null;
}
let resizeObserver = new GlobalResizeObserver(callback);
resizeObserver.observe(elementToObserve);
return ()=>{
resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect();
resizeObserver = undefined;
};
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/createResizeObserver.ts"],"sourcesContent":["/**\n * Helper function that creates a resize observer in the element's own window global\n * @param elementToObserve - Uses the element's window global to create the resize observer\n * @param callback\n * @returns function to cleanup the resize observer\n */\nexport function observeResize(elementToObserve: HTMLElement, callback: ResizeObserverCallback): () => void {\n const GlobalResizeObserver = elementToObserve.ownerDocument.defaultView?.ResizeObserver;\n\n if (!GlobalResizeObserver) {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error('@fluentui/priority-overflow', 'ResizeObserver does not exist on container window');\n }\n return () => null;\n }\n\n let resizeObserver: InstanceType<typeof GlobalResizeObserver> | undefined = new GlobalResizeObserver(callback);\n resizeObserver.observe(elementToObserve);\n\n return () => {\n resizeObserver?.disconnect();\n resizeObserver = undefined;\n };\n}\n"],"names":["observeResize","elementToObserve","callback","GlobalResizeObserver","ownerDocument","defaultView","ResizeObserver","process","env","NODE_ENV","console","error","resizeObserver","observe","disconnect","undefined"],"mappings":"AAAA;;;;;CAKC;;;;+BACeA;;;eAAAA;;;AAAT,SAASA,cAAcC,gBAA6B,EAAEC,QAAgC;QAC9DD;IAA7B,MAAME,wBAAuBF,8CAAAA,iBAAiBG,aAAa,CAACC,WAAW,cAA1CJ,kEAAAA,4CAA4CK,cAAc;IAEvF,IAAI,CAACH,sBAAsB;QACzB,IAAII,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,sCAAsC;YACtCC,QAAQC,KAAK,CAAC,+BAA+B;QAC/C;QACA,OAAO,IAAM;IACf;IAEA,IAAIC,iBAAwE,IAAIT,qBAAqBD;IACrGU,eAAeC,OAAO,CAACZ;IAEvB,OAAO;QACLW,2BAAAA,qCAAAA,eAAgBE,UAAU;QAC1BF,iBAAiBG;IACnB;AACF"}

View File

@@ -0,0 +1,34 @@
/**
* Microtask debouncer
* https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide
* @param fn - Function to debounce
* @returns debounced function
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "debounce", {
enumerable: true,
get: function() {
return debounce;
}
});
function debounce(fn) {
let pending;
// React testing platforms will often output errors when state updates happen outside `act`
// Since there is nothing obvious to wait for we just avoid debouncing in unit test environments
if (process.env.NODE_ENV === 'test') {
return fn;
}
return ()=>{
if (!pending) {
pending = true;
queueMicrotask(()=>{
// Need to set pending to `false` before the debounced function is run.
// React can actually interrupt the function while it's running!
pending = false;
fn();
});
}
};
}

View File

@@ -0,0 +1 @@
{"version":3,"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): () => void {\n let pending: boolean;\n\n // React testing platforms will often output errors when state updates happen outside `act`\n // Since there is nothing obvious to wait for we just avoid debouncing in unit test environments\n if (process.env.NODE_ENV === 'test') {\n return fn as () => void;\n }\n\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","process","env","NODE_ENV","queueMicrotask"],"mappings":"AAAA;;;;;CAKC;;;;+BACeA;;;eAAAA;;;AAAT,SAASA,SAASC,EAAY;IACnC,IAAIC;IAEJ,2FAA2F;IAC3F,gGAAgG;IAChG,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,QAAQ;QACnC,OAAOJ;IACT;IAEA,OAAO;QACL,IAAI,CAACC,SAAS;YACZA,UAAU;YACVI,eAAe;gBACb,uEAAuE;gBACvE,gEAAgE;gBAChEJ,UAAU;gBACVD;YACF;QACF;IACF;AACF"}

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "createOverflowManager", {
enumerable: true,
get: function() {
return _overflowManager.createOverflowManager;
}
});
const _overflowManager = require("./overflowManager");

View File

@@ -0,0 +1 @@
{"version":3,"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 OverflowDividerEntry,\n OverflowManager,\n} from './types';\n"],"names":["createOverflowManager"],"mappings":";;;;+BAASA;;;eAAAA,sCAAqB;;;iCAAQ"}

View File

@@ -0,0 +1,309 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "createOverflowManager", {
enumerable: true,
get: function() {
return createOverflowManager;
}
});
const _consts = require("./consts");
const _createResizeObserver = require("./createResizeObserver");
const _debounce = require("./debounce");
const _priorityQueue = require("./priorityQueue");
function createOverflowManager() {
// calls to `offsetWidth or offsetHeight` can happen multiple times in an update
// Use a cache to avoid causing too many recalcs and avoid scripting time to meausure sizes
const sizeCache = new Map();
let container;
let overflowMenu;
// Set as true when resize observer is observing
let observing = false;
// If true, next update will dispatch to onUpdateOverflow even if queue top states don't change
// Initially true to force dispatch on first mount
let forceDispatch = true;
const options = {
padding: 10,
overflowAxis: 'horizontal',
overflowDirection: 'end',
minimumVisible: 0,
onUpdateItemVisibility: ()=>undefined,
onUpdateOverflow: ()=>undefined,
hasHiddenItems: false
};
const overflowItems = {};
const overflowDividers = {};
let disposeResizeObserver = ()=>null;
const getNextItem = (queueToDequeue, queueToEnqueue)=>{
const nextItem = queueToDequeue.dequeue();
queueToEnqueue.enqueue(nextItem);
return overflowItems[nextItem];
};
const groupManager = createGroupManager();
function compareItems(lt, rt) {
if (!lt || !rt) {
return 0;
}
const lte = overflowItems[lt];
const rte = overflowItems[rt];
// TODO this should not happen but there have been reports of one of these items being undefined
// Try to find a consistent repro for this
if (!lte || !rte) {
return lte ? 1 : -1;
}
// Pinned items have "infinite" priority - they should never be hidden
if (lte.pinned !== rte.pinned) {
return lte.pinned ? 1 : -1;
}
if (lte.priority !== rte.priority) {
return lte.priority > rte.priority ? 1 : -1;
}
// Node.DOCUMENT_POSITION_FOLLOWING = 4, Node.DOCUMENT_POSITION_PRECEDING = 2
const positionStatusBit = options.overflowDirection === 'end' ? 4 : 2;
// eslint-disable-next-line no-bitwise
return lte.element.compareDocumentPosition(rte.element) & positionStatusBit ? 1 : -1;
}
function getElementAxisSize(horizontal, vertical, el) {
if (!sizeCache.has(el)) {
sizeCache.set(el, options.overflowAxis === 'horizontal' ? el[horizontal] : el[vertical]);
}
return sizeCache.get(el);
}
const getOffsetSize = getElementAxisSize.bind(null, 'offsetWidth', 'offsetHeight');
const getClientSize = getElementAxisSize.bind(null, 'clientWidth', 'clientHeight');
const invisibleItemQueue = (0, _priorityQueue.createPriorityQueue)((a, b)=>-1 * compareItems(a, b));
const visibleItemQueue = (0, _priorityQueue.createPriorityQueue)(compareItems);
function occupiedSize() {
const totalItemSize = visibleItemQueue.all().map((id)=>overflowItems[id].element).map(getOffsetSize).reduce((prev, current)=>prev + current, 0);
const totalDividerSize = Object.entries(groupManager.groupVisibility()).reduce((acc, [id, state])=>acc + (state !== 'hidden' && overflowDividers[id] ? getOffsetSize(overflowDividers[id].element) : 0), 0);
const overflowMenuSize = (invisibleItemQueue.size() > 0 || options.hasHiddenItems) && overflowMenu ? getOffsetSize(overflowMenu) : 0;
return totalItemSize + totalDividerSize + overflowMenuSize;
}
const showItem = ()=>{
const item = getNextItem(invisibleItemQueue, visibleItemQueue);
options.onUpdateItemVisibility({
item,
visible: true
});
if (item.groupId) {
groupManager.showItem(item.id, item.groupId);
if (groupManager.isSingleItemVisible(item.id, item.groupId)) {
var _overflowDividers_item_groupId;
(_overflowDividers_item_groupId = overflowDividers[item.groupId]) === null || _overflowDividers_item_groupId === void 0 ? void 0 : _overflowDividers_item_groupId.element.removeAttribute(_consts.DATA_OVERFLOWING);
}
}
};
const hideItem = ()=>{
const item = getNextItem(visibleItemQueue, invisibleItemQueue);
options.onUpdateItemVisibility({
item,
visible: false
});
if (item.groupId) {
if (groupManager.isSingleItemVisible(item.id, item.groupId)) {
var _overflowDividers_item_groupId;
(_overflowDividers_item_groupId = overflowDividers[item.groupId]) === null || _overflowDividers_item_groupId === void 0 ? void 0 : _overflowDividers_item_groupId.element.setAttribute(_consts.DATA_OVERFLOWING, '');
}
groupManager.hideItem(item.id, item.groupId);
}
};
const dispatchOverflowUpdate = ()=>{
const visibleItemIds = visibleItemQueue.all();
const invisibleItemIds = invisibleItemQueue.all();
const visibleItems = visibleItemIds.map((itemId)=>overflowItems[itemId]);
const invisibleItems = invisibleItemIds.map((itemId)=>overflowItems[itemId]);
options.onUpdateOverflow({
visibleItems,
invisibleItems,
groupVisibility: groupManager.groupVisibility()
});
};
const processOverflowItems = ()=>{
if (!container) {
return false;
}
sizeCache.clear();
const availableSize = getClientSize(container) - options.padding;
// Snapshot of the visible/invisible state to compare for updates
const visibleTop = visibleItemQueue.peek();
const invisibleTop = invisibleItemQueue.peek();
while(compareItems(invisibleItemQueue.peek(), visibleItemQueue.peek()) > 0){
hideItem(); // hide elements whose priority become smaller than the highest priority of the hidden one
}
// Run the show/hide step twice - the first step might not be correct if
// it was triggered by a new item being added - new items are always visible by default.
for(let i = 0; i < 2; i++){
// Add items until available width is filled - can result in overflow
while(occupiedSize() < availableSize && invisibleItemQueue.size() > 0 || invisibleItemQueue.size() === 1 // attempt to show the last invisible item hoping it's size does not exceed overflow menu size
){
showItem();
}
// Remove items until there's no more overflow
while(occupiedSize() > availableSize && visibleItemQueue.size() > options.minimumVisible){
var _overflowItems_nextItemId;
const nextItemId = visibleItemQueue.peek();
// Never hide pinned items - they should always remain visible
if (nextItemId && ((_overflowItems_nextItemId = overflowItems[nextItemId]) === null || _overflowItems_nextItemId === void 0 ? void 0 : _overflowItems_nextItemId.pinned)) {
break;
}
hideItem();
}
}
// only update when the state of visible/invisible items has changed
return visibleItemQueue.peek() !== visibleTop || invisibleItemQueue.peek() !== invisibleTop;
};
const forceUpdate = ()=>{
if (processOverflowItems() || forceDispatch) {
forceDispatch = false;
dispatchOverflowUpdate();
}
};
const update = (0, _debounce.debounce)(forceUpdate);
const observe = (observedContainer, userOptions)=>{
Object.assign(options, userOptions);
observing = true;
Object.values(overflowItems).forEach((item)=>visibleItemQueue.enqueue(item.id));
container = observedContainer;
disposeResizeObserver = (0, _createResizeObserver.observeResize)(container, (entries)=>{
if (!entries[0] || !container) {
return;
}
update();
});
};
const addItem = (item)=>{
if (overflowItems[item.id]) {
return;
}
overflowItems[item.id] = item;
// some options can affect priority which are only set on `observe`
if (observing) {
// Updates to elements might not change the queue tops
// i.e. new element is enqueued but the top of the queue stays the same
// force a dispatch on the next batched update
forceDispatch = true;
visibleItemQueue.enqueue(item.id);
}
if (item.groupId) {
groupManager.addItem(item.id, item.groupId);
item.element.setAttribute(_consts.DATA_OVERFLOW_GROUP, item.groupId);
}
update();
};
const addOverflowMenu = (el)=>{
overflowMenu = el;
};
const addDivider = (divider)=>{
if (!divider.groupId || overflowDividers[divider.groupId]) {
return;
}
divider.element.setAttribute(_consts.DATA_OVERFLOW_GROUP, divider.groupId);
overflowDividers[divider.groupId] = divider;
};
const removeOverflowMenu = ()=>{
overflowMenu = undefined;
};
const removeDivider = (groupId)=>{
if (!overflowDividers[groupId]) {
return;
}
const divider = overflowDividers[groupId];
if (divider.groupId) {
delete overflowDividers[groupId];
divider.element.removeAttribute(_consts.DATA_OVERFLOW_GROUP);
}
};
const removeItem = (itemId)=>{
if (!overflowItems[itemId]) {
return;
}
if (observing) {
// We might be removing an item in an overflow which would not affect the tops,
// but we need to update anyway to update the overflow menu state
forceDispatch = true;
}
const item = overflowItems[itemId];
visibleItemQueue.remove(itemId);
invisibleItemQueue.remove(itemId);
if (item.groupId) {
groupManager.removeItem(item.id, item.groupId);
item.element.removeAttribute(_consts.DATA_OVERFLOW_GROUP);
}
sizeCache.delete(item.element);
delete overflowItems[itemId];
update();
};
const disconnect = ()=>{
disposeResizeObserver();
// reset flags
container = undefined;
observing = false;
forceDispatch = true;
// clear all entries
Object.keys(overflowItems).forEach((itemId)=>removeItem(itemId));
Object.keys(overflowDividers).forEach((dividerId)=>removeDivider(dividerId));
removeOverflowMenu();
sizeCache.clear();
};
return {
addItem,
disconnect,
forceUpdate,
observe,
removeItem,
update,
addOverflowMenu,
removeOverflowMenu,
addDivider,
removeDivider
};
}
const createGroupManager = ()=>{
const groupVisibility = {};
const groups = {};
function updateGroupVisibility(groupId) {
const group = groups[groupId];
if (group.invisibleItemIds.size && group.visibleItemIds.size) {
groupVisibility[groupId] = 'overflow';
} else if (group.visibleItemIds.size === 0) {
groupVisibility[groupId] = 'hidden';
} else {
groupVisibility[groupId] = 'visible';
}
}
function isGroupVisible(groupId) {
return groupVisibility[groupId] === 'visible' || groupVisibility[groupId] === 'overflow';
}
return {
groupVisibility: ()=>groupVisibility,
isSingleItemVisible (itemId, groupId) {
return isGroupVisible(groupId) && groups[groupId].visibleItemIds.has(itemId) && groups[groupId].visibleItemIds.size === 1;
},
addItem (itemId, groupId) {
var _groups, _groupId;
var _;
(_ = (_groups = groups)[_groupId = groupId]) !== null && _ !== void 0 ? _ : _groups[_groupId] = {
visibleItemIds: new Set(),
invisibleItemIds: new Set()
};
groups[groupId].visibleItemIds.add(itemId);
updateGroupVisibility(groupId);
},
removeItem (itemId, groupId) {
groups[groupId].invisibleItemIds.delete(itemId);
groups[groupId].visibleItemIds.delete(itemId);
updateGroupVisibility(groupId);
},
showItem (itemId, groupId) {
groups[groupId].invisibleItemIds.delete(itemId);
groups[groupId].visibleItemIds.add(itemId);
updateGroupVisibility(groupId);
},
hideItem (itemId, groupId) {
groups[groupId].invisibleItemIds.add(itemId);
groups[groupId].visibleItemIds.delete(itemId);
updateGroupVisibility(groupId);
}
};
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,96 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "createPriorityQueue", {
enumerable: true,
get: function() {
return createPriorityQueue;
}
});
function createPriorityQueue(compare) {
const arr = [];
let size = 0;
const left = (i)=>{
return 2 * i + 1;
};
const right = (i)=>{
return 2 * i + 2;
};
const parent = (i)=>{
return Math.floor((i - 1) / 2);
};
const swap = (a, b)=>{
const tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
};
const heapify = (i)=>{
let smallest = i;
const l = left(i);
const r = right(i);
if (l < size && compare(arr[l], arr[smallest]) < 0) {
smallest = l;
}
if (r < size && compare(arr[r], arr[smallest]) < 0) {
smallest = r;
}
if (smallest !== i) {
swap(smallest, i);
heapify(smallest);
}
};
const dequeue = ()=>{
if (size === 0) {
throw new Error('Priority queue empty');
}
const res = arr[0];
arr[0] = arr[--size];
heapify(0);
return res;
};
const peek = ()=>{
if (size === 0) {
return null;
}
return arr[0];
};
const enqueue = (item)=>{
arr[size++] = item;
let i = size - 1;
let p = parent(i);
while(i > 0 && compare(arr[p], arr[i]) > 0){
swap(p, i);
i = p;
p = parent(i);
}
};
const contains = (item)=>{
const index = arr.indexOf(item);
return index >= 0 && index < size;
};
const remove = (item)=>{
const i = arr.indexOf(item);
if (i === -1 || i >= size) {
return;
}
arr[i] = arr[--size];
heapify(i);
};
const clear = ()=>{
size = 0;
};
const all = ()=>{
return arr.slice(0, size);
};
return {
all,
clear,
contains,
dequeue,
enqueue,
peek,
remove,
size: ()=>size
};
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/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":";;;;+BAiBgBA;;;eAAAA;;;AAAT,SAASA,oBAAuBC,OAAkC;IACvE,MAAMC,MAAW,EAAE;IACnB,IAAIC,OAAO;IAEX,MAAMC,OAAO,CAACC;QACZ,OAAO,IAAIA,IAAI;IACjB;IAEA,MAAMC,QAAQ,CAACD;QACb,OAAO,IAAIA,IAAI;IACjB;IAEA,MAAME,SAAS,CAACF;QACd,OAAOG,KAAKC,KAAK,CAAC,AAACJ,CAAAA,IAAI,CAAA,IAAK;IAC9B;IAEA,MAAMK,OAAO,CAACC,GAAWC;QACvB,MAAMC,MAAMX,GAAG,CAACS,EAAE;QAClBT,GAAG,CAACS,EAAE,GAAGT,GAAG,CAACU,EAAE;QACfV,GAAG,CAACU,EAAE,GAAGC;IACX;IAEA,MAAMC,UAAU,CAACT;QACf,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;QAEA,IAAIC,IAAId,QAAQF,QAAQC,GAAG,CAACe,EAAE,EAAEf,GAAG,CAACa,SAAS,IAAI,GAAG;YAClDA,WAAWE;QACb;QAEA,IAAIF,aAAaV,GAAG;YAClBK,KAAKK,UAAUV;YACfS,QAAQC;QACV;IACF;IAEA,MAAMG,UAAU;QACd,IAAIf,SAAS,GAAG;YACd,MAAM,IAAIgB,MAAM;QAClB;QAEA,MAAMC,MAAMlB,GAAG,CAAC,EAAE;QAClBA,GAAG,CAAC,EAAE,GAAGA,GAAG,CAAC,EAAEC,KAAK;QACpBW,QAAQ;QAER,OAAOM;IACT;IAEA,MAAMC,OAAO;QACX,IAAIlB,SAAS,GAAG;YACd,OAAO;QACT;QAEA,OAAOD,GAAG,CAAC,EAAE;IACf;IAEA,MAAMoB,UAAU,CAACC;QACfrB,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;QAChB,MAAMG,QAAQxB,IAAIyB,OAAO,CAACJ;QAC1B,OAAOG,SAAS,KAAKA,QAAQvB;IAC/B;IAEA,MAAMyB,SAAS,CAACL;QACd,MAAMlB,IAAIH,IAAIyB,OAAO,CAACJ;QAEtB,IAAIlB,MAAM,CAAC,KAAKA,KAAKF,MAAM;YACzB;QACF;QAEAD,GAAG,CAACG,EAAE,GAAGH,GAAG,CAAC,EAAEC,KAAK;QACpBW,QAAQT;IACV;IAEA,MAAMwB,QAAQ;QACZ1B,OAAO;IACT;IAEA,MAAM2B,MAAM;QACV,OAAO5B,IAAI6B,KAAK,CAAC,GAAG5B;IACtB;IAEA,OAAO;QACL2B;QACAD;QACAJ;QACAP;QACAI;QACAD;QACAO;QACAzB,MAAM,IAAMA;IACd;AACF"}

View File

@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});

View File

@@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":""}

View File

@@ -0,0 +1,2 @@
export const DATA_OVERFLOWING = 'data-overflowing';
export const DATA_OVERFLOW_GROUP = 'data-overflow-group';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/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"}

View File

@@ -0,0 +1,22 @@
/**
* Helper function that creates a resize observer in the element's own window global
* @param elementToObserve - Uses the element's window global to create the resize observer
* @param callback
* @returns function to cleanup the resize observer
*/ export function observeResize(elementToObserve, callback) {
var _elementToObserve_ownerDocument_defaultView;
const GlobalResizeObserver = (_elementToObserve_ownerDocument_defaultView = elementToObserve.ownerDocument.defaultView) === null || _elementToObserve_ownerDocument_defaultView === void 0 ? void 0 : _elementToObserve_ownerDocument_defaultView.ResizeObserver;
if (!GlobalResizeObserver) {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.error('@fluentui/priority-overflow', 'ResizeObserver does not exist on container window');
}
return ()=>null;
}
let resizeObserver = new GlobalResizeObserver(callback);
resizeObserver.observe(elementToObserve);
return ()=>{
resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect();
resizeObserver = undefined;
};
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/createResizeObserver.ts"],"sourcesContent":["/**\n * Helper function that creates a resize observer in the element's own window global\n * @param elementToObserve - Uses the element's window global to create the resize observer\n * @param callback\n * @returns function to cleanup the resize observer\n */\nexport function observeResize(elementToObserve: HTMLElement, callback: ResizeObserverCallback): () => void {\n const GlobalResizeObserver = elementToObserve.ownerDocument.defaultView?.ResizeObserver;\n\n if (!GlobalResizeObserver) {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error('@fluentui/priority-overflow', 'ResizeObserver does not exist on container window');\n }\n return () => null;\n }\n\n let resizeObserver: InstanceType<typeof GlobalResizeObserver> | undefined = new GlobalResizeObserver(callback);\n resizeObserver.observe(elementToObserve);\n\n return () => {\n resizeObserver?.disconnect();\n resizeObserver = undefined;\n };\n}\n"],"names":["observeResize","elementToObserve","callback","GlobalResizeObserver","ownerDocument","defaultView","ResizeObserver","process","env","NODE_ENV","console","error","resizeObserver","observe","disconnect","undefined"],"mappings":"AAAA;;;;;CAKC,GACD,OAAO,SAASA,cAAcC,gBAA6B,EAAEC,QAAgC;QAC9DD;IAA7B,MAAME,wBAAuBF,8CAAAA,iBAAiBG,aAAa,CAACC,WAAW,cAA1CJ,kEAAAA,4CAA4CK,cAAc;IAEvF,IAAI,CAACH,sBAAsB;QACzB,IAAII,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,sCAAsC;YACtCC,QAAQC,KAAK,CAAC,+BAA+B;QAC/C;QACA,OAAO,IAAM;IACf;IAEA,IAAIC,iBAAwE,IAAIT,qBAAqBD;IACrGU,eAAeC,OAAO,CAACZ;IAEvB,OAAO;QACLW,2BAAAA,qCAAAA,eAAgBE,UAAU;QAC1BF,iBAAiBG;IACnB;AACF"}

View File

@@ -0,0 +1,24 @@
/**
* Microtask debouncer
* https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide
* @param fn - Function to debounce
* @returns debounced function
*/ export function debounce(fn) {
let pending;
// React testing platforms will often output errors when state updates happen outside `act`
// Since there is nothing obvious to wait for we just avoid debouncing in unit test environments
if (process.env.NODE_ENV === 'test') {
return fn;
}
return ()=>{
if (!pending) {
pending = true;
queueMicrotask(()=>{
// Need to set pending to `false` before the debounced function is run.
// React can actually interrupt the function while it's running!
pending = false;
fn();
});
}
};
}

View File

@@ -0,0 +1 @@
{"version":3,"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): () => void {\n let pending: boolean;\n\n // React testing platforms will often output errors when state updates happen outside `act`\n // Since there is nothing obvious to wait for we just avoid debouncing in unit test environments\n if (process.env.NODE_ENV === 'test') {\n return fn as () => void;\n }\n\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","process","env","NODE_ENV","queueMicrotask"],"mappings":"AAAA;;;;;CAKC,GACD,OAAO,SAASA,SAASC,EAAY;IACnC,IAAIC;IAEJ,2FAA2F;IAC3F,gGAAgG;IAChG,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,QAAQ;QACnC,OAAOJ;IACT;IAEA,OAAO;QACL,IAAI,CAACC,SAAS;YACZA,UAAU;YACVI,eAAe;gBACb,uEAAuE;gBACvE,gEAAgE;gBAChEJ,UAAU;gBACVD;YACF;QACF;IACF;AACF"}

View File

@@ -0,0 +1 @@
export { createOverflowManager } from './overflowManager';

View File

@@ -0,0 +1 @@
{"version":3,"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 OverflowDividerEntry,\n OverflowManager,\n} from './types';\n"],"names":["createOverflowManager"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,oBAAoB"}

View File

@@ -0,0 +1,302 @@
import { DATA_OVERFLOWING, DATA_OVERFLOW_GROUP } from './consts';
import { observeResize } from './createResizeObserver';
import { debounce } from './debounce';
import { createPriorityQueue } from './priorityQueue';
/**
* @internal
* @returns overflow manager instance
*/ export function createOverflowManager() {
// calls to `offsetWidth or offsetHeight` can happen multiple times in an update
// Use a cache to avoid causing too many recalcs and avoid scripting time to meausure sizes
const sizeCache = new Map();
let container;
let overflowMenu;
// Set as true when resize observer is observing
let observing = false;
// If true, next update will dispatch to onUpdateOverflow even if queue top states don't change
// Initially true to force dispatch on first mount
let forceDispatch = true;
const options = {
padding: 10,
overflowAxis: 'horizontal',
overflowDirection: 'end',
minimumVisible: 0,
onUpdateItemVisibility: ()=>undefined,
onUpdateOverflow: ()=>undefined,
hasHiddenItems: false
};
const overflowItems = {};
const overflowDividers = {};
let disposeResizeObserver = ()=>null;
const getNextItem = (queueToDequeue, queueToEnqueue)=>{
const nextItem = queueToDequeue.dequeue();
queueToEnqueue.enqueue(nextItem);
return overflowItems[nextItem];
};
const groupManager = createGroupManager();
function compareItems(lt, rt) {
if (!lt || !rt) {
return 0;
}
const lte = overflowItems[lt];
const rte = overflowItems[rt];
// TODO this should not happen but there have been reports of one of these items being undefined
// Try to find a consistent repro for this
if (!lte || !rte) {
return lte ? 1 : -1;
}
// Pinned items have "infinite" priority - they should never be hidden
if (lte.pinned !== rte.pinned) {
return lte.pinned ? 1 : -1;
}
if (lte.priority !== rte.priority) {
return lte.priority > rte.priority ? 1 : -1;
}
// Node.DOCUMENT_POSITION_FOLLOWING = 4, Node.DOCUMENT_POSITION_PRECEDING = 2
const positionStatusBit = options.overflowDirection === 'end' ? 4 : 2;
// eslint-disable-next-line no-bitwise
return lte.element.compareDocumentPosition(rte.element) & positionStatusBit ? 1 : -1;
}
function getElementAxisSize(horizontal, vertical, el) {
if (!sizeCache.has(el)) {
sizeCache.set(el, options.overflowAxis === 'horizontal' ? el[horizontal] : el[vertical]);
}
return sizeCache.get(el);
}
const getOffsetSize = getElementAxisSize.bind(null, 'offsetWidth', 'offsetHeight');
const getClientSize = getElementAxisSize.bind(null, 'clientWidth', 'clientHeight');
const invisibleItemQueue = createPriorityQueue((a, b)=>-1 * compareItems(a, b));
const visibleItemQueue = createPriorityQueue(compareItems);
function occupiedSize() {
const totalItemSize = visibleItemQueue.all().map((id)=>overflowItems[id].element).map(getOffsetSize).reduce((prev, current)=>prev + current, 0);
const totalDividerSize = Object.entries(groupManager.groupVisibility()).reduce((acc, [id, state])=>acc + (state !== 'hidden' && overflowDividers[id] ? getOffsetSize(overflowDividers[id].element) : 0), 0);
const overflowMenuSize = (invisibleItemQueue.size() > 0 || options.hasHiddenItems) && overflowMenu ? getOffsetSize(overflowMenu) : 0;
return totalItemSize + totalDividerSize + overflowMenuSize;
}
const showItem = ()=>{
const item = getNextItem(invisibleItemQueue, visibleItemQueue);
options.onUpdateItemVisibility({
item,
visible: true
});
if (item.groupId) {
groupManager.showItem(item.id, item.groupId);
if (groupManager.isSingleItemVisible(item.id, item.groupId)) {
var _overflowDividers_item_groupId;
(_overflowDividers_item_groupId = overflowDividers[item.groupId]) === null || _overflowDividers_item_groupId === void 0 ? void 0 : _overflowDividers_item_groupId.element.removeAttribute(DATA_OVERFLOWING);
}
}
};
const hideItem = ()=>{
const item = getNextItem(visibleItemQueue, invisibleItemQueue);
options.onUpdateItemVisibility({
item,
visible: false
});
if (item.groupId) {
if (groupManager.isSingleItemVisible(item.id, item.groupId)) {
var _overflowDividers_item_groupId;
(_overflowDividers_item_groupId = overflowDividers[item.groupId]) === null || _overflowDividers_item_groupId === void 0 ? void 0 : _overflowDividers_item_groupId.element.setAttribute(DATA_OVERFLOWING, '');
}
groupManager.hideItem(item.id, item.groupId);
}
};
const dispatchOverflowUpdate = ()=>{
const visibleItemIds = visibleItemQueue.all();
const invisibleItemIds = invisibleItemQueue.all();
const visibleItems = visibleItemIds.map((itemId)=>overflowItems[itemId]);
const invisibleItems = invisibleItemIds.map((itemId)=>overflowItems[itemId]);
options.onUpdateOverflow({
visibleItems,
invisibleItems,
groupVisibility: groupManager.groupVisibility()
});
};
const processOverflowItems = ()=>{
if (!container) {
return false;
}
sizeCache.clear();
const availableSize = getClientSize(container) - options.padding;
// Snapshot of the visible/invisible state to compare for updates
const visibleTop = visibleItemQueue.peek();
const invisibleTop = invisibleItemQueue.peek();
while(compareItems(invisibleItemQueue.peek(), visibleItemQueue.peek()) > 0){
hideItem(); // hide elements whose priority become smaller than the highest priority of the hidden one
}
// Run the show/hide step twice - the first step might not be correct if
// it was triggered by a new item being added - new items are always visible by default.
for(let i = 0; i < 2; i++){
// Add items until available width is filled - can result in overflow
while(occupiedSize() < availableSize && invisibleItemQueue.size() > 0 || invisibleItemQueue.size() === 1 // attempt to show the last invisible item hoping it's size does not exceed overflow menu size
){
showItem();
}
// Remove items until there's no more overflow
while(occupiedSize() > availableSize && visibleItemQueue.size() > options.minimumVisible){
var _overflowItems_nextItemId;
const nextItemId = visibleItemQueue.peek();
// Never hide pinned items - they should always remain visible
if (nextItemId && ((_overflowItems_nextItemId = overflowItems[nextItemId]) === null || _overflowItems_nextItemId === void 0 ? void 0 : _overflowItems_nextItemId.pinned)) {
break;
}
hideItem();
}
}
// only update when the state of visible/invisible items has changed
return visibleItemQueue.peek() !== visibleTop || invisibleItemQueue.peek() !== invisibleTop;
};
const forceUpdate = ()=>{
if (processOverflowItems() || forceDispatch) {
forceDispatch = false;
dispatchOverflowUpdate();
}
};
const update = debounce(forceUpdate);
const observe = (observedContainer, userOptions)=>{
Object.assign(options, userOptions);
observing = true;
Object.values(overflowItems).forEach((item)=>visibleItemQueue.enqueue(item.id));
container = observedContainer;
disposeResizeObserver = observeResize(container, (entries)=>{
if (!entries[0] || !container) {
return;
}
update();
});
};
const addItem = (item)=>{
if (overflowItems[item.id]) {
return;
}
overflowItems[item.id] = item;
// some options can affect priority which are only set on `observe`
if (observing) {
// Updates to elements might not change the queue tops
// i.e. new element is enqueued but the top of the queue stays the same
// force a dispatch on the next batched update
forceDispatch = true;
visibleItemQueue.enqueue(item.id);
}
if (item.groupId) {
groupManager.addItem(item.id, item.groupId);
item.element.setAttribute(DATA_OVERFLOW_GROUP, item.groupId);
}
update();
};
const addOverflowMenu = (el)=>{
overflowMenu = el;
};
const addDivider = (divider)=>{
if (!divider.groupId || overflowDividers[divider.groupId]) {
return;
}
divider.element.setAttribute(DATA_OVERFLOW_GROUP, divider.groupId);
overflowDividers[divider.groupId] = divider;
};
const removeOverflowMenu = ()=>{
overflowMenu = undefined;
};
const removeDivider = (groupId)=>{
if (!overflowDividers[groupId]) {
return;
}
const divider = overflowDividers[groupId];
if (divider.groupId) {
delete overflowDividers[groupId];
divider.element.removeAttribute(DATA_OVERFLOW_GROUP);
}
};
const removeItem = (itemId)=>{
if (!overflowItems[itemId]) {
return;
}
if (observing) {
// We might be removing an item in an overflow which would not affect the tops,
// but we need to update anyway to update the overflow menu state
forceDispatch = true;
}
const item = overflowItems[itemId];
visibleItemQueue.remove(itemId);
invisibleItemQueue.remove(itemId);
if (item.groupId) {
groupManager.removeItem(item.id, item.groupId);
item.element.removeAttribute(DATA_OVERFLOW_GROUP);
}
sizeCache.delete(item.element);
delete overflowItems[itemId];
update();
};
const disconnect = ()=>{
disposeResizeObserver();
// reset flags
container = undefined;
observing = false;
forceDispatch = true;
// clear all entries
Object.keys(overflowItems).forEach((itemId)=>removeItem(itemId));
Object.keys(overflowDividers).forEach((dividerId)=>removeDivider(dividerId));
removeOverflowMenu();
sizeCache.clear();
};
return {
addItem,
disconnect,
forceUpdate,
observe,
removeItem,
update,
addOverflowMenu,
removeOverflowMenu,
addDivider,
removeDivider
};
}
const createGroupManager = ()=>{
const groupVisibility = {};
const groups = {};
function updateGroupVisibility(groupId) {
const group = groups[groupId];
if (group.invisibleItemIds.size && group.visibleItemIds.size) {
groupVisibility[groupId] = 'overflow';
} else if (group.visibleItemIds.size === 0) {
groupVisibility[groupId] = 'hidden';
} else {
groupVisibility[groupId] = 'visible';
}
}
function isGroupVisible(groupId) {
return groupVisibility[groupId] === 'visible' || groupVisibility[groupId] === 'overflow';
}
return {
groupVisibility: ()=>groupVisibility,
isSingleItemVisible (itemId, groupId) {
return isGroupVisible(groupId) && groups[groupId].visibleItemIds.has(itemId) && groups[groupId].visibleItemIds.size === 1;
},
addItem (itemId, groupId) {
var _groups, _groupId;
var _;
(_ = (_groups = groups)[_groupId = groupId]) !== null && _ !== void 0 ? _ : _groups[_groupId] = {
visibleItemIds: new Set(),
invisibleItemIds: new Set()
};
groups[groupId].visibleItemIds.add(itemId);
updateGroupVisibility(groupId);
},
removeItem (itemId, groupId) {
groups[groupId].invisibleItemIds.delete(itemId);
groups[groupId].visibleItemIds.delete(itemId);
updateGroupVisibility(groupId);
},
showItem (itemId, groupId) {
groups[groupId].invisibleItemIds.delete(itemId);
groups[groupId].visibleItemIds.add(itemId);
updateGroupVisibility(groupId);
},
hideItem (itemId, groupId) {
groups[groupId].invisibleItemIds.add(itemId);
groups[groupId].visibleItemIds.delete(itemId);
updateGroupVisibility(groupId);
}
};
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,89 @@
/**
* @param compare - comparison function for items
* @returns Priority queue implemented with a min heap
*/ export function createPriorityQueue(compare) {
const arr = [];
let size = 0;
const left = (i)=>{
return 2 * i + 1;
};
const right = (i)=>{
return 2 * i + 2;
};
const parent = (i)=>{
return Math.floor((i - 1) / 2);
};
const swap = (a, b)=>{
const tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
};
const heapify = (i)=>{
let smallest = i;
const l = left(i);
const r = right(i);
if (l < size && compare(arr[l], arr[smallest]) < 0) {
smallest = l;
}
if (r < size && compare(arr[r], arr[smallest]) < 0) {
smallest = r;
}
if (smallest !== i) {
swap(smallest, i);
heapify(smallest);
}
};
const dequeue = ()=>{
if (size === 0) {
throw new Error('Priority queue empty');
}
const res = arr[0];
arr[0] = arr[--size];
heapify(0);
return res;
};
const peek = ()=>{
if (size === 0) {
return null;
}
return arr[0];
};
const enqueue = (item)=>{
arr[size++] = item;
let i = size - 1;
let p = parent(i);
while(i > 0 && compare(arr[p], arr[i]) > 0){
swap(p, i);
i = p;
p = parent(i);
}
};
const contains = (item)=>{
const index = arr.indexOf(item);
return index >= 0 && index < size;
};
const remove = (item)=>{
const i = arr.indexOf(item);
if (i === -1 || i >= size) {
return;
}
arr[i] = arr[--size];
heapify(i);
};
const clear = ()=>{
size = 0;
};
const all = ()=>{
return arr.slice(0, size);
};
return {
all,
clear,
contains,
dequeue,
enqueue,
peek,
remove,
size: ()=>size
};
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/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;IACvE,MAAMC,MAAW,EAAE;IACnB,IAAIC,OAAO;IAEX,MAAMC,OAAO,CAACC;QACZ,OAAO,IAAIA,IAAI;IACjB;IAEA,MAAMC,QAAQ,CAACD;QACb,OAAO,IAAIA,IAAI;IACjB;IAEA,MAAME,SAAS,CAACF;QACd,OAAOG,KAAKC,KAAK,CAAC,AAACJ,CAAAA,IAAI,CAAA,IAAK;IAC9B;IAEA,MAAMK,OAAO,CAACC,GAAWC;QACvB,MAAMC,MAAMX,GAAG,CAACS,EAAE;QAClBT,GAAG,CAACS,EAAE,GAAGT,GAAG,CAACU,EAAE;QACfV,GAAG,CAACU,EAAE,GAAGC;IACX;IAEA,MAAMC,UAAU,CAACT;QACf,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;QAEA,IAAIC,IAAId,QAAQF,QAAQC,GAAG,CAACe,EAAE,EAAEf,GAAG,CAACa,SAAS,IAAI,GAAG;YAClDA,WAAWE;QACb;QAEA,IAAIF,aAAaV,GAAG;YAClBK,KAAKK,UAAUV;YACfS,QAAQC;QACV;IACF;IAEA,MAAMG,UAAU;QACd,IAAIf,SAAS,GAAG;YACd,MAAM,IAAIgB,MAAM;QAClB;QAEA,MAAMC,MAAMlB,GAAG,CAAC,EAAE;QAClBA,GAAG,CAAC,EAAE,GAAGA,GAAG,CAAC,EAAEC,KAAK;QACpBW,QAAQ;QAER,OAAOM;IACT;IAEA,MAAMC,OAAO;QACX,IAAIlB,SAAS,GAAG;YACd,OAAO;QACT;QAEA,OAAOD,GAAG,CAAC,EAAE;IACf;IAEA,MAAMoB,UAAU,CAACC;QACfrB,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;QAChB,MAAMG,QAAQxB,IAAIyB,OAAO,CAACJ;QAC1B,OAAOG,SAAS,KAAKA,QAAQvB;IAC/B;IAEA,MAAMyB,SAAS,CAACL;QACd,MAAMlB,IAAIH,IAAIyB,OAAO,CAACJ;QAEtB,IAAIlB,MAAM,CAAC,KAAKA,KAAKF,MAAM;YACzB;QACF;QAEAD,GAAG,CAACG,EAAE,GAAGH,GAAG,CAAC,EAAEC,KAAK;QACpBW,QAAQT;IACV;IAEA,MAAMwB,QAAQ;QACZ1B,OAAO;IACT;IAEA,MAAM2B,MAAM;QACV,OAAO5B,IAAI6B,KAAK,CAAC,GAAG5B;IACtB;IAEA,OAAO;QACL2B;QACAD;QACAJ;QACAP;QACAI;QACAD;QACAO;QACAzB,MAAM,IAAMA;IACd;AACF"}

View File

@@ -0,0 +1,3 @@
/**
* @internal
*/ export { };

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/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 /**\n * If true, the item will never overflow and will always be visible.\n * Pinned items are excluded from the overflow count.\n * @default false\n */\n pinned?: boolean;\n}\n\nexport interface OverflowDividerEntry {\n /**\n * HTML element that will 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 * When true, the overflow menu has default hidden items\n * @default false\n */\n hasHiddenItems?: boolean;\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":"AAoGA;;CAEC,GACD,WA8CC"}

38
node_modules/@fluentui/priority-overflow/package.json generated vendored Normal file
View File

@@ -0,0 +1,38 @@
{
"name": "@fluentui/priority-overflow",
"version": "9.3.0",
"description": "Vanilla JS utilities to implement overflow menus",
"main": "lib-commonjs/index.js",
"module": "lib/index.js",
"typings": "./dist/index.d.ts",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/microsoft/fluentui"
},
"license": "MIT",
"dependencies": {
"@swc/helpers": "^0.5.1"
},
"beachball": {
"disallowedChangeTypes": [
"prerelease",
"major"
]
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"node": "./lib-commonjs/index.js",
"import": "./lib/index.js",
"require": "./lib-commonjs/index.js"
},
"./package.json": "./package.json"
},
"files": [
"*.md",
"dist/*.d.ts",
"lib",
"lib-commonjs"
]
}