@fluentui/react-overflow 9.7.2 → 9.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -4
- package/dist/index.d.ts +21 -0
- package/lib/components/Overflow.js +2 -1
- package/lib/components/Overflow.js.map +1 -1
- package/lib/components/OverflowReorderObserver/OverflowReorderObserver.js +43 -0
- package/lib/components/OverflowReorderObserver/OverflowReorderObserver.js.map +1 -0
- package/lib/components/OverflowReorderObserver/index.js +1 -0
- package/lib/components/OverflowReorderObserver/index.js.map +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/overflowContext.js.map +1 -1
- package/lib-commonjs/components/Overflow.js +2 -1
- package/lib-commonjs/components/Overflow.js.map +1 -1
- package/lib-commonjs/components/OverflowReorderObserver/OverflowReorderObserver.js +37 -0
- package/lib-commonjs/components/OverflowReorderObserver/OverflowReorderObserver.js.map +1 -0
- package/lib-commonjs/components/OverflowReorderObserver/index.js +11 -0
- package/lib-commonjs/components/OverflowReorderObserver/index.js.map +1 -0
- package/lib-commonjs/index.js +4 -0
- package/lib-commonjs/index.js.map +1 -1
- package/lib-commonjs/overflowContext.js.map +1 -1
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
# Change Log - @fluentui/react-overflow
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Tue, 26 May 2026 09:33:50 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## [9.8.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-overflow_v9.8.0)
|
|
8
|
+
|
|
9
|
+
Tue, 26 May 2026 09:33:50 GMT
|
|
10
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-overflow_v9.7.2..@fluentui/react-overflow_v9.8.0)
|
|
11
|
+
|
|
12
|
+
### Minor changes
|
|
13
|
+
|
|
14
|
+
- feat: add OverflowReorderObserver to recompute overflow when items are reordered via React state without a container resize ([PR #36231](https://github.com/microsoft/fluentui/pull/36231) by olfedias@microsoft.com)
|
|
15
|
+
- Bump @fluentui/react-context-selector to v9.2.17 ([PR #36246](https://github.com/microsoft/fluentui/pull/36246) by beachball)
|
|
16
|
+
- Bump @fluentui/react-utilities to v9.26.4 ([PR #36246](https://github.com/microsoft/fluentui/pull/36246) by beachball)
|
|
17
|
+
|
|
7
18
|
## [9.7.2](https://github.com/microsoft/fluentui/tree/@fluentui/react-overflow_v9.7.2)
|
|
8
19
|
|
|
9
|
-
Thu, 23 Apr 2026
|
|
20
|
+
Thu, 23 Apr 2026 14:21:14 GMT
|
|
10
21
|
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-overflow_v9.7.1..@fluentui/react-overflow_v9.7.2)
|
|
11
22
|
|
|
12
23
|
### Patches
|
|
13
24
|
|
|
14
|
-
- Bump @fluentui/react-context-selector to v9.2.16 ([PR #
|
|
15
|
-
- Bump @fluentui/react-utilities to v9.26.3 ([PR #
|
|
25
|
+
- Bump @fluentui/react-context-selector to v9.2.16 ([PR #36035](https://github.com/microsoft/fluentui/pull/36035) by beachball)
|
|
26
|
+
- Bump @fluentui/react-utilities to v9.26.3 ([PR #36035](https://github.com/microsoft/fluentui/pull/36035) by beachball)
|
|
16
27
|
|
|
17
28
|
## [9.7.1](https://github.com/microsoft/fluentui/tree/@fluentui/react-overflow_v9.7.1)
|
|
18
29
|
|
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ declare interface OverflowContextValue {
|
|
|
36
36
|
registerOverflowMenu: (el: HTMLElement) => () => void;
|
|
37
37
|
registerDivider: (divider: OverflowDividerEntry) => () => void;
|
|
38
38
|
updateOverflow: (padding?: number) => void;
|
|
39
|
+
containerRef?: React_2.RefObject<HTMLElement | null>;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
/**
|
|
@@ -106,6 +107,26 @@ export declare type OverflowProps = Partial<Pick<ObserveOptions, 'overflowAxis'
|
|
|
106
107
|
onOverflowChange?: (ev: null, data: OverflowState) => void;
|
|
107
108
|
};
|
|
108
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Renderless opt-in component that observes the `<Overflow>` container for
|
|
112
|
+
* direct-child DOM mutations and triggers an overflow recompute. Drop it
|
|
113
|
+
* inside `<Overflow>` when items can be reordered, added, or removed via
|
|
114
|
+
* React state without a container resize — Fluent's overflow manager only
|
|
115
|
+
* listens to `ResizeObserver` otherwise, so reorders leave visibility flags
|
|
116
|
+
* stale.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```tsx
|
|
120
|
+
* <Overflow>
|
|
121
|
+
* <div>
|
|
122
|
+
* <OverflowReorderObserver />
|
|
123
|
+
* {items.map(id => <OverflowItem key={id} id={id} priority={1}>{id}</OverflowItem>)}
|
|
124
|
+
* </div>
|
|
125
|
+
* </Overflow>
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export declare const OverflowReorderObserver: React_2.FC;
|
|
129
|
+
|
|
109
130
|
declare interface OverflowState {
|
|
110
131
|
hasOverflow: boolean;
|
|
111
132
|
itemVisibility: Record<string, boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Overflow.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { mergeClasses } from '@griffel/react';\nimport type { OnUpdateOverflow, OverflowGroupState, ObserveOptions } from '@fluentui/priority-overflow';\nimport {\n applyTriggerPropsToChildren,\n getTriggerChild,\n getReactElementRef,\n useMergedRefs,\n} from '@fluentui/react-utilities';\n\nimport { OverflowContext } from '../overflowContext';\nimport { updateVisibilityAttribute, useOverflowContainer } from '../useOverflowContainer';\nimport { useOverflowStyles } from './useOverflowStyles.styles';\n\ninterface OverflowState {\n hasOverflow: boolean;\n itemVisibility: Record<string, boolean>;\n groupVisibility: Record<string, OverflowGroupState>;\n}\n\nexport interface OnOverflowChangeData extends OverflowState {}\n\n/**\n * Overflow Props\n */\nexport type OverflowProps = Partial<\n Pick<ObserveOptions, 'overflowAxis' | 'overflowDirection' | 'padding' | 'minimumVisible' | 'hasHiddenItems'>\n> & {\n children: React.ReactElement;\n\n // overflow is not caused by DOM event\n // eslint-disable-next-line @nx/workspace-consistent-callback-type\n onOverflowChange?: (ev: null, data: OverflowState) => void;\n};\n\n/**\n * Provides an OverflowContext for OverflowItem descendants.\n */\nexport const Overflow = React.forwardRef((props: OverflowProps, ref) => {\n const styles = useOverflowStyles();\n\n const {\n children,\n minimumVisible,\n overflowAxis = 'horizontal',\n overflowDirection,\n padding,\n onOverflowChange,\n hasHiddenItems,\n } = props;\n\n const [overflowState, setOverflowState] = React.useState<OverflowState>({\n hasOverflow: false,\n itemVisibility: {},\n groupVisibility: {},\n });\n\n // useOverflowContainer wraps this method in a useEventCallback.\n const update: OnUpdateOverflow = data => {\n const { visibleItems, invisibleItems, groupVisibility } = data;\n\n const itemVisibility: Record<string, boolean> = {};\n visibleItems.forEach(item => {\n itemVisibility[item.id] = true;\n });\n invisibleItems.forEach(x => (itemVisibility[x.id] = false));\n const newState = {\n hasOverflow: data.invisibleItems.length > 0,\n itemVisibility,\n groupVisibility,\n };\n onOverflowChange?.(null, { ...newState });\n\n setOverflowState(newState);\n };\n\n const { containerRef, registerItem, updateOverflow, registerOverflowMenu, registerDivider } = useOverflowContainer(\n update,\n {\n overflowDirection,\n overflowAxis,\n padding,\n minimumVisible,\n hasHiddenItems,\n onUpdateItemVisibility: updateVisibilityAttribute,\n },\n );\n\n const child = getTriggerChild<HTMLElement>(children);\n const clonedChild = applyTriggerPropsToChildren(children, {\n ref: useMergedRefs(containerRef, ref, getReactElementRef(child)),\n className: mergeClasses('fui-Overflow', styles.overflowMenu, styles.overflowingItems, child?.props.className),\n });\n\n return (\n <OverflowContext.Provider\n value={{\n itemVisibility: overflowState.itemVisibility,\n groupVisibility: overflowState.groupVisibility,\n hasOverflow: overflowState.hasOverflow,\n registerItem,\n updateOverflow,\n registerOverflowMenu,\n registerDivider,\n }}\n >\n {clonedChild}\n </OverflowContext.Provider>\n );\n});\n"],"names":["React","mergeClasses","applyTriggerPropsToChildren","getTriggerChild","getReactElementRef","useMergedRefs","OverflowContext","updateVisibilityAttribute","useOverflowContainer","useOverflowStyles","Overflow","forwardRef","props","ref","styles","children","minimumVisible","overflowAxis","overflowDirection","padding","onOverflowChange","hasHiddenItems","overflowState","setOverflowState","useState","hasOverflow","itemVisibility","groupVisibility","update","data","visibleItems","invisibleItems","forEach","item","id","x","newState","length","containerRef","registerItem","updateOverflow","registerOverflowMenu","registerDivider","onUpdateItemVisibility","child","clonedChild","className","overflowMenu","overflowingItems","Provider","value"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,YAAY,QAAQ,iBAAiB;AAE9C,SACEC,2BAA2B,EAC3BC,eAAe,EACfC,kBAAkB,EAClBC,aAAa,QACR,4BAA4B;AAEnC,SAASC,eAAe,QAAQ,qBAAqB;AACrD,SAASC,yBAAyB,EAAEC,oBAAoB,QAAQ,0BAA0B;AAC1F,SAASC,iBAAiB,QAAQ,6BAA6B;AAuB/D;;CAEC,GACD,OAAO,MAAMC,yBAAWV,MAAMW,UAAU,CAAC,CAACC,OAAsBC;IAC9D,MAAMC,SAASL;IAEf,MAAM,EACJM,QAAQ,EACRC,cAAc,EACdC,eAAe,YAAY,EAC3BC,iBAAiB,EACjBC,OAAO,EACPC,gBAAgB,EAChBC,cAAc,EACf,GAAGT;IAEJ,MAAM,CAACU,eAAeC,iBAAiB,GAAGvB,MAAMwB,QAAQ,CAAgB;QACtEC,aAAa;QACbC,gBAAgB,CAAC;QACjBC,iBAAiB,CAAC;IACpB;IAEA,gEAAgE;IAChE,MAAMC,SAA2BC,CAAAA;QAC/B,MAAM,EAAEC,YAAY,EAAEC,cAAc,EAAEJ,eAAe,EAAE,GAAGE;QAE1D,MAAMH,iBAA0C,CAAC;QACjDI,aAAaE,OAAO,CAACC,CAAAA;YACnBP,cAAc,CAACO,KAAKC,EAAE,CAAC,GAAG;QAC5B;QACAH,eAAeC,OAAO,CAACG,CAAAA,IAAMT,cAAc,CAACS,EAAED,EAAE,CAAC,GAAG;QACpD,MAAME,WAAW;YACfX,aAAaI,KAAKE,cAAc,CAACM,MAAM,GAAG;YAC1CX;YACAC;QACF;QACAP,6BAAAA,uCAAAA,iBAAmB,MAAM;YAAE,GAAGgB,QAAQ;QAAC;QAEvCb,iBAAiBa;IACnB;IAEA,MAAM,EAAEE,YAAY,EAAEC,YAAY,EAAEC,cAAc,EAAEC,oBAAoB,EAAEC,eAAe,EAAE,GAAGlC,qBAC5FoB,QACA;QACEV;QACAD;QACAE;QACAH;QACAK;QACAsB,wBAAwBpC;IAC1B;IAGF,MAAMqC,QAAQzC,gBAA6BY;IAC3C,MAAM8B,cAAc3C,4BAA4Ba,UAAU;QACxDF,KAAKR,cAAciC,cAAczB,KAAKT,mBAAmBwC;QACzDE,WAAW7C,aAAa,gBAAgBa,OAAOiC,YAAY,EAAEjC,OAAOkC,gBAAgB,EAAEJ,kBAAAA,4BAAAA,MAAOhC,KAAK,CAACkC,SAAS;IAC9G;IAEA,qBACE,oBAACxC,gBAAgB2C,QAAQ;QACvBC,OAAO;YACLxB,gBAAgBJ,cAAcI,cAAc;YAC5CC,iBAAiBL,cAAcK,eAAe;YAC9CF,aAAaH,cAAcG,WAAW;YACtCc;YACAC;YACAC;YACAC;QACF;
|
|
1
|
+
{"version":3,"sources":["../src/components/Overflow.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { mergeClasses } from '@griffel/react';\nimport type { OnUpdateOverflow, OverflowGroupState, ObserveOptions } from '@fluentui/priority-overflow';\nimport {\n applyTriggerPropsToChildren,\n getTriggerChild,\n getReactElementRef,\n useMergedRefs,\n} from '@fluentui/react-utilities';\n\nimport { OverflowContext } from '../overflowContext';\nimport { updateVisibilityAttribute, useOverflowContainer } from '../useOverflowContainer';\nimport { useOverflowStyles } from './useOverflowStyles.styles';\n\ninterface OverflowState {\n hasOverflow: boolean;\n itemVisibility: Record<string, boolean>;\n groupVisibility: Record<string, OverflowGroupState>;\n}\n\nexport interface OnOverflowChangeData extends OverflowState {}\n\n/**\n * Overflow Props\n */\nexport type OverflowProps = Partial<\n Pick<ObserveOptions, 'overflowAxis' | 'overflowDirection' | 'padding' | 'minimumVisible' | 'hasHiddenItems'>\n> & {\n children: React.ReactElement;\n\n // overflow is not caused by DOM event\n // eslint-disable-next-line @nx/workspace-consistent-callback-type\n onOverflowChange?: (ev: null, data: OverflowState) => void;\n};\n\n/**\n * Provides an OverflowContext for OverflowItem descendants.\n */\nexport const Overflow = React.forwardRef((props: OverflowProps, ref) => {\n const styles = useOverflowStyles();\n\n const {\n children,\n minimumVisible,\n overflowAxis = 'horizontal',\n overflowDirection,\n padding,\n onOverflowChange,\n hasHiddenItems,\n } = props;\n\n const [overflowState, setOverflowState] = React.useState<OverflowState>({\n hasOverflow: false,\n itemVisibility: {},\n groupVisibility: {},\n });\n\n // useOverflowContainer wraps this method in a useEventCallback.\n const update: OnUpdateOverflow = data => {\n const { visibleItems, invisibleItems, groupVisibility } = data;\n\n const itemVisibility: Record<string, boolean> = {};\n visibleItems.forEach(item => {\n itemVisibility[item.id] = true;\n });\n invisibleItems.forEach(x => (itemVisibility[x.id] = false));\n const newState = {\n hasOverflow: data.invisibleItems.length > 0,\n itemVisibility,\n groupVisibility,\n };\n onOverflowChange?.(null, { ...newState });\n\n setOverflowState(newState);\n };\n\n const { containerRef, registerItem, updateOverflow, registerOverflowMenu, registerDivider } = useOverflowContainer(\n update,\n {\n overflowDirection,\n overflowAxis,\n padding,\n minimumVisible,\n hasHiddenItems,\n onUpdateItemVisibility: updateVisibilityAttribute,\n },\n );\n\n const child = getTriggerChild<HTMLElement>(children);\n const clonedChild = applyTriggerPropsToChildren(children, {\n ref: useMergedRefs(containerRef, ref, getReactElementRef(child)),\n className: mergeClasses('fui-Overflow', styles.overflowMenu, styles.overflowingItems, child?.props.className),\n });\n\n return (\n <OverflowContext.Provider\n value={{\n itemVisibility: overflowState.itemVisibility,\n groupVisibility: overflowState.groupVisibility,\n hasOverflow: overflowState.hasOverflow,\n registerItem,\n updateOverflow,\n registerOverflowMenu,\n registerDivider,\n containerRef,\n }}\n >\n {clonedChild}\n </OverflowContext.Provider>\n );\n});\n"],"names":["React","mergeClasses","applyTriggerPropsToChildren","getTriggerChild","getReactElementRef","useMergedRefs","OverflowContext","updateVisibilityAttribute","useOverflowContainer","useOverflowStyles","Overflow","forwardRef","props","ref","styles","children","minimumVisible","overflowAxis","overflowDirection","padding","onOverflowChange","hasHiddenItems","overflowState","setOverflowState","useState","hasOverflow","itemVisibility","groupVisibility","update","data","visibleItems","invisibleItems","forEach","item","id","x","newState","length","containerRef","registerItem","updateOverflow","registerOverflowMenu","registerDivider","onUpdateItemVisibility","child","clonedChild","className","overflowMenu","overflowingItems","Provider","value"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,YAAY,QAAQ,iBAAiB;AAE9C,SACEC,2BAA2B,EAC3BC,eAAe,EACfC,kBAAkB,EAClBC,aAAa,QACR,4BAA4B;AAEnC,SAASC,eAAe,QAAQ,qBAAqB;AACrD,SAASC,yBAAyB,EAAEC,oBAAoB,QAAQ,0BAA0B;AAC1F,SAASC,iBAAiB,QAAQ,6BAA6B;AAuB/D;;CAEC,GACD,OAAO,MAAMC,yBAAWV,MAAMW,UAAU,CAAC,CAACC,OAAsBC;IAC9D,MAAMC,SAASL;IAEf,MAAM,EACJM,QAAQ,EACRC,cAAc,EACdC,eAAe,YAAY,EAC3BC,iBAAiB,EACjBC,OAAO,EACPC,gBAAgB,EAChBC,cAAc,EACf,GAAGT;IAEJ,MAAM,CAACU,eAAeC,iBAAiB,GAAGvB,MAAMwB,QAAQ,CAAgB;QACtEC,aAAa;QACbC,gBAAgB,CAAC;QACjBC,iBAAiB,CAAC;IACpB;IAEA,gEAAgE;IAChE,MAAMC,SAA2BC,CAAAA;QAC/B,MAAM,EAAEC,YAAY,EAAEC,cAAc,EAAEJ,eAAe,EAAE,GAAGE;QAE1D,MAAMH,iBAA0C,CAAC;QACjDI,aAAaE,OAAO,CAACC,CAAAA;YACnBP,cAAc,CAACO,KAAKC,EAAE,CAAC,GAAG;QAC5B;QACAH,eAAeC,OAAO,CAACG,CAAAA,IAAMT,cAAc,CAACS,EAAED,EAAE,CAAC,GAAG;QACpD,MAAME,WAAW;YACfX,aAAaI,KAAKE,cAAc,CAACM,MAAM,GAAG;YAC1CX;YACAC;QACF;QACAP,6BAAAA,uCAAAA,iBAAmB,MAAM;YAAE,GAAGgB,QAAQ;QAAC;QAEvCb,iBAAiBa;IACnB;IAEA,MAAM,EAAEE,YAAY,EAAEC,YAAY,EAAEC,cAAc,EAAEC,oBAAoB,EAAEC,eAAe,EAAE,GAAGlC,qBAC5FoB,QACA;QACEV;QACAD;QACAE;QACAH;QACAK;QACAsB,wBAAwBpC;IAC1B;IAGF,MAAMqC,QAAQzC,gBAA6BY;IAC3C,MAAM8B,cAAc3C,4BAA4Ba,UAAU;QACxDF,KAAKR,cAAciC,cAAczB,KAAKT,mBAAmBwC;QACzDE,WAAW7C,aAAa,gBAAgBa,OAAOiC,YAAY,EAAEjC,OAAOkC,gBAAgB,EAAEJ,kBAAAA,4BAAAA,MAAOhC,KAAK,CAACkC,SAAS;IAC9G;IAEA,qBACE,oBAACxC,gBAAgB2C,QAAQ;QACvBC,OAAO;YACLxB,gBAAgBJ,cAAcI,cAAc;YAC5CC,iBAAiBL,cAAcK,eAAe;YAC9CF,aAAaH,cAAcG,WAAW;YACtCc;YACAC;YACAC;YACAC;YACAJ;QACF;OAECO;AAGP,GAAG"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
|
|
4
|
+
import { useOverflowContext } from '../../overflowContext';
|
|
5
|
+
/**
|
|
6
|
+
* Renderless opt-in component that observes the `<Overflow>` container for
|
|
7
|
+
* direct-child DOM mutations and triggers an overflow recompute. Drop it
|
|
8
|
+
* inside `<Overflow>` when items can be reordered, added, or removed via
|
|
9
|
+
* React state without a container resize — Fluent's overflow manager only
|
|
10
|
+
* listens to `ResizeObserver` otherwise, so reorders leave visibility flags
|
|
11
|
+
* stale.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <Overflow>
|
|
16
|
+
* <div>
|
|
17
|
+
* <OverflowReorderObserver />
|
|
18
|
+
* {items.map(id => <OverflowItem key={id} id={id} priority={1}>{id}</OverflowItem>)}
|
|
19
|
+
* </div>
|
|
20
|
+
* </Overflow>
|
|
21
|
+
* ```
|
|
22
|
+
*/ export const OverflowReorderObserver = ()=>{
|
|
23
|
+
const containerRef = useOverflowContext((v)=>v.containerRef);
|
|
24
|
+
const updateOverflow = useOverflowContext((v)=>v.updateOverflow);
|
|
25
|
+
const { targetDocument } = useFluent();
|
|
26
|
+
const targetWindow = targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.defaultView;
|
|
27
|
+
React.useEffect(()=>{
|
|
28
|
+
const el = containerRef === null || containerRef === void 0 ? void 0 : containerRef.current;
|
|
29
|
+
if (!el || !(targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.MutationObserver)) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const mutationObserver = new targetWindow.MutationObserver(()=>updateOverflow());
|
|
33
|
+
mutationObserver.observe(el, {
|
|
34
|
+
childList: true
|
|
35
|
+
});
|
|
36
|
+
return ()=>mutationObserver.disconnect();
|
|
37
|
+
}, [
|
|
38
|
+
containerRef,
|
|
39
|
+
updateOverflow,
|
|
40
|
+
targetWindow
|
|
41
|
+
]);
|
|
42
|
+
return null;
|
|
43
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/OverflowReorderObserver/OverflowReorderObserver.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport { useOverflowContext } from '../../overflowContext';\n\n/**\n * Renderless opt-in component that observes the `<Overflow>` container for\n * direct-child DOM mutations and triggers an overflow recompute. Drop it\n * inside `<Overflow>` when items can be reordered, added, or removed via\n * React state without a container resize — Fluent's overflow manager only\n * listens to `ResizeObserver` otherwise, so reorders leave visibility flags\n * stale.\n *\n * @example\n * ```tsx\n * <Overflow>\n * <div>\n * <OverflowReorderObserver />\n * {items.map(id => <OverflowItem key={id} id={id} priority={1}>{id}</OverflowItem>)}\n * </div>\n * </Overflow>\n * ```\n */\nexport const OverflowReorderObserver: React.FC = () => {\n const containerRef = useOverflowContext(v => v.containerRef);\n const updateOverflow = useOverflowContext(v => v.updateOverflow);\n const { targetDocument } = useFluent();\n const targetWindow = targetDocument?.defaultView;\n\n React.useEffect(() => {\n const el = containerRef?.current;\n if (!el || !targetWindow?.MutationObserver) {\n return;\n }\n\n const mutationObserver = new targetWindow.MutationObserver(() => updateOverflow());\n mutationObserver.observe(el, { childList: true });\n\n return () => mutationObserver.disconnect();\n }, [containerRef, updateOverflow, targetWindow]);\n\n return null;\n};\n"],"names":["React","useFluent_unstable","useFluent","useOverflowContext","OverflowReorderObserver","containerRef","v","updateOverflow","targetDocument","targetWindow","defaultView","useEffect","el","current","MutationObserver","mutationObserver","observe","childList","disconnect"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,sBAAsBC,SAAS,QAAQ,kCAAkC;AAClF,SAASC,kBAAkB,QAAQ,wBAAwB;AAE3D;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,MAAMC,0BAAoC;IAC/C,MAAMC,eAAeF,mBAAmBG,CAAAA,IAAKA,EAAED,YAAY;IAC3D,MAAME,iBAAiBJ,mBAAmBG,CAAAA,IAAKA,EAAEC,cAAc;IAC/D,MAAM,EAAEC,cAAc,EAAE,GAAGN;IAC3B,MAAMO,eAAeD,2BAAAA,qCAAAA,eAAgBE,WAAW;IAEhDV,MAAMW,SAAS,CAAC;QACd,MAAMC,KAAKP,yBAAAA,mCAAAA,aAAcQ,OAAO;QAChC,IAAI,CAACD,MAAM,EAACH,yBAAAA,mCAAAA,aAAcK,gBAAgB,GAAE;YAC1C;QACF;QAEA,MAAMC,mBAAmB,IAAIN,aAAaK,gBAAgB,CAAC,IAAMP;QACjEQ,iBAAiBC,OAAO,CAACJ,IAAI;YAAEK,WAAW;QAAK;QAE/C,OAAO,IAAMF,iBAAiBG,UAAU;IAC1C,GAAG;QAACb;QAAcE;QAAgBE;KAAa;IAE/C,OAAO;AACT,EAAE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { OverflowReorderObserver } from './OverflowReorderObserver';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/OverflowReorderObserver/index.ts"],"sourcesContent":["export { OverflowReorderObserver } from './OverflowReorderObserver';\n"],"names":["OverflowReorderObserver"],"mappings":"AAAA,SAASA,uBAAuB,QAAQ,4BAA4B"}
|
package/lib/index.js
CHANGED
|
@@ -11,3 +11,4 @@ export { useOverflowVisibility } from './useOverflowVisibility';
|
|
|
11
11
|
export { useOverflowContext } from './overflowContext';
|
|
12
12
|
export { OverflowItem } from './components/OverflowItem/OverflowItem';
|
|
13
13
|
export { OverflowDivider } from './components/OverflowDivider/OverflowDivider';
|
|
14
|
+
export { OverflowReorderObserver } from './components/OverflowReorderObserver';
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { Overflow } from './components/Overflow';\nexport type { OverflowProps, OnOverflowChangeData } from './components/Overflow';\nexport { DATA_OVERFLOWING, DATA_OVERFLOW_ITEM, DATA_OVERFLOW_MENU, DATA_OVERFLOW_DIVIDER } from './constants';\nexport type { UseOverflowContainerReturn } from './types';\nexport { useIsOverflowGroupVisible } from './useIsOverflowGroupVisible';\nexport { useIsOverflowItemVisible } from './useIsOverflowItemVisible';\nexport { useOverflowContainer } from './useOverflowContainer';\nexport { useOverflowCount } from './useOverflowCount';\nexport { useOverflowItem } from './useOverflowItem';\nexport { useOverflowMenu } from './useOverflowMenu';\nexport { useOverflowDivider } from './useOverflowDivider';\nexport { useOverflowVisibility } from './useOverflowVisibility';\n\nexport { useOverflowContext } from './overflowContext';\n\nexport type { OverflowItemProps } from './components/OverflowItem/OverflowItem.types';\nexport { OverflowItem } from './components/OverflowItem/OverflowItem';\nexport { OverflowDivider } from './components/OverflowDivider/OverflowDivider';\n"],"names":["Overflow","DATA_OVERFLOWING","DATA_OVERFLOW_ITEM","DATA_OVERFLOW_MENU","DATA_OVERFLOW_DIVIDER","useIsOverflowGroupVisible","useIsOverflowItemVisible","useOverflowContainer","useOverflowCount","useOverflowItem","useOverflowMenu","useOverflowDivider","useOverflowVisibility","useOverflowContext","OverflowItem","OverflowDivider"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,wBAAwB;AAEjD,SAASC,gBAAgB,EAAEC,kBAAkB,EAAEC,kBAAkB,EAAEC,qBAAqB,QAAQ,cAAc;AAE9G,SAASC,yBAAyB,QAAQ,8BAA8B;AACxE,SAASC,wBAAwB,QAAQ,6BAA6B;AACtE,SAASC,oBAAoB,QAAQ,yBAAyB;AAC9D,SAASC,gBAAgB,QAAQ,qBAAqB;AACtD,SAASC,eAAe,QAAQ,oBAAoB;AACpD,SAASC,eAAe,QAAQ,oBAAoB;AACpD,SAASC,kBAAkB,QAAQ,uBAAuB;AAC1D,SAASC,qBAAqB,QAAQ,0BAA0B;AAEhE,SAASC,kBAAkB,QAAQ,oBAAoB;AAGvD,SAASC,YAAY,QAAQ,yCAAyC;AACtE,SAASC,eAAe,QAAQ,+CAA+C"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { Overflow } from './components/Overflow';\nexport type { OverflowProps, OnOverflowChangeData } from './components/Overflow';\nexport { DATA_OVERFLOWING, DATA_OVERFLOW_ITEM, DATA_OVERFLOW_MENU, DATA_OVERFLOW_DIVIDER } from './constants';\nexport type { UseOverflowContainerReturn } from './types';\nexport { useIsOverflowGroupVisible } from './useIsOverflowGroupVisible';\nexport { useIsOverflowItemVisible } from './useIsOverflowItemVisible';\nexport { useOverflowContainer } from './useOverflowContainer';\nexport { useOverflowCount } from './useOverflowCount';\nexport { useOverflowItem } from './useOverflowItem';\nexport { useOverflowMenu } from './useOverflowMenu';\nexport { useOverflowDivider } from './useOverflowDivider';\nexport { useOverflowVisibility } from './useOverflowVisibility';\n\nexport { useOverflowContext } from './overflowContext';\n\nexport type { OverflowItemProps } from './components/OverflowItem/OverflowItem.types';\nexport { OverflowItem } from './components/OverflowItem/OverflowItem';\nexport { OverflowDivider } from './components/OverflowDivider/OverflowDivider';\nexport { OverflowReorderObserver } from './components/OverflowReorderObserver';\n"],"names":["Overflow","DATA_OVERFLOWING","DATA_OVERFLOW_ITEM","DATA_OVERFLOW_MENU","DATA_OVERFLOW_DIVIDER","useIsOverflowGroupVisible","useIsOverflowItemVisible","useOverflowContainer","useOverflowCount","useOverflowItem","useOverflowMenu","useOverflowDivider","useOverflowVisibility","useOverflowContext","OverflowItem","OverflowDivider","OverflowReorderObserver"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,wBAAwB;AAEjD,SAASC,gBAAgB,EAAEC,kBAAkB,EAAEC,kBAAkB,EAAEC,qBAAqB,QAAQ,cAAc;AAE9G,SAASC,yBAAyB,QAAQ,8BAA8B;AACxE,SAASC,wBAAwB,QAAQ,6BAA6B;AACtE,SAASC,oBAAoB,QAAQ,yBAAyB;AAC9D,SAASC,gBAAgB,QAAQ,qBAAqB;AACtD,SAASC,eAAe,QAAQ,oBAAoB;AACpD,SAASC,eAAe,QAAQ,oBAAoB;AACpD,SAASC,kBAAkB,QAAQ,uBAAuB;AAC1D,SAASC,qBAAqB,QAAQ,0BAA0B;AAEhE,SAASC,kBAAkB,QAAQ,oBAAoB;AAGvD,SAASC,YAAY,QAAQ,yCAAyC;AACtE,SAASC,eAAe,QAAQ,+CAA+C;AAC/E,SAASC,uBAAuB,QAAQ,uCAAuC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/overflowContext.ts"],"sourcesContent":["'use client';\n\nimport type { OverflowGroupState, OverflowItemEntry, OverflowDividerEntry } from '@fluentui/priority-overflow';\nimport type { ContextSelector, Context } from '@fluentui/react-context-selector';\nimport { createContext, useContextSelector } from '@fluentui/react-context-selector';\n\n/**\n * @internal\n */\nexport interface OverflowContextValue {\n itemVisibility: Record<string, boolean>;\n groupVisibility: Record<string, OverflowGroupState>;\n hasOverflow: boolean;\n registerItem: (item: OverflowItemEntry) => () => void;\n registerOverflowMenu: (el: HTMLElement) => () => void;\n registerDivider: (divider: OverflowDividerEntry) => () => void;\n updateOverflow: (padding?: number) => void;\n}\n\nexport const OverflowContext = createContext<OverflowContextValue | undefined>(\n undefined,\n) as Context<OverflowContextValue>;\n\nconst overflowContextDefaultValue: OverflowContextValue = {\n itemVisibility: {},\n groupVisibility: {},\n hasOverflow: false,\n registerItem: () => () => null,\n updateOverflow: () => null,\n registerOverflowMenu: () => () => null,\n registerDivider: () => () => null,\n};\n\n/**\n * @internal\n */\nexport const useOverflowContext = <SelectedValue>(\n selector: ContextSelector<OverflowContextValue, SelectedValue>,\n): SelectedValue => useContextSelector(OverflowContext, (ctx = overflowContextDefaultValue) => selector(ctx));\n"],"names":["createContext","useContextSelector","OverflowContext","undefined","overflowContextDefaultValue","itemVisibility","groupVisibility","hasOverflow","registerItem","updateOverflow","registerOverflowMenu","registerDivider","useOverflowContext","selector","ctx"],"mappings":"AAAA;
|
|
1
|
+
{"version":3,"sources":["../src/overflowContext.ts"],"sourcesContent":["'use client';\n\nimport type * as React from 'react';\nimport type { OverflowGroupState, OverflowItemEntry, OverflowDividerEntry } from '@fluentui/priority-overflow';\nimport type { ContextSelector, Context } from '@fluentui/react-context-selector';\nimport { createContext, useContextSelector } from '@fluentui/react-context-selector';\n\n/**\n * @internal\n */\nexport interface OverflowContextValue {\n itemVisibility: Record<string, boolean>;\n groupVisibility: Record<string, OverflowGroupState>;\n hasOverflow: boolean;\n registerItem: (item: OverflowItemEntry) => () => void;\n registerOverflowMenu: (el: HTMLElement) => () => void;\n registerDivider: (divider: OverflowDividerEntry) => () => void;\n updateOverflow: (padding?: number) => void;\n containerRef?: React.RefObject<HTMLElement | null>;\n}\n\nexport const OverflowContext = createContext<OverflowContextValue | undefined>(\n undefined,\n) as Context<OverflowContextValue>;\n\nconst overflowContextDefaultValue: OverflowContextValue = {\n itemVisibility: {},\n groupVisibility: {},\n hasOverflow: false,\n registerItem: () => () => null,\n updateOverflow: () => null,\n registerOverflowMenu: () => () => null,\n registerDivider: () => () => null,\n};\n\n/**\n * @internal\n */\nexport const useOverflowContext = <SelectedValue>(\n selector: ContextSelector<OverflowContextValue, SelectedValue>,\n): SelectedValue => useContextSelector(OverflowContext, (ctx = overflowContextDefaultValue) => selector(ctx));\n"],"names":["createContext","useContextSelector","OverflowContext","undefined","overflowContextDefaultValue","itemVisibility","groupVisibility","hasOverflow","registerItem","updateOverflow","registerOverflowMenu","registerDivider","useOverflowContext","selector","ctx"],"mappings":"AAAA;AAKA,SAASA,aAAa,EAAEC,kBAAkB,QAAQ,mCAAmC;AAgBrF,OAAO,MAAMC,kBAAkBF,cAC7BG,WACiC;AAEnC,MAAMC,8BAAoD;IACxDC,gBAAgB,CAAC;IACjBC,iBAAiB,CAAC;IAClBC,aAAa;IACbC,cAAc,IAAM,IAAM;IAC1BC,gBAAgB,IAAM;IACtBC,sBAAsB,IAAM,IAAM;IAClCC,iBAAiB,IAAM,IAAM;AAC/B;AAEA;;CAEC,GACD,OAAO,MAAMC,qBAAqB,CAChCC,WACkBZ,mBAAmBC,iBAAiB,CAACY,MAAMV,2BAA2B,GAAKS,SAASC,MAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Overflow.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { mergeClasses } from '@griffel/react';\nimport type { OnUpdateOverflow, OverflowGroupState, ObserveOptions } from '@fluentui/priority-overflow';\nimport {\n applyTriggerPropsToChildren,\n getTriggerChild,\n getReactElementRef,\n useMergedRefs,\n} from '@fluentui/react-utilities';\n\nimport { OverflowContext } from '../overflowContext';\nimport { updateVisibilityAttribute, useOverflowContainer } from '../useOverflowContainer';\nimport { useOverflowStyles } from './useOverflowStyles.styles';\n\ninterface OverflowState {\n hasOverflow: boolean;\n itemVisibility: Record<string, boolean>;\n groupVisibility: Record<string, OverflowGroupState>;\n}\n\nexport interface OnOverflowChangeData extends OverflowState {}\n\n/**\n * Overflow Props\n */\nexport type OverflowProps = Partial<\n Pick<ObserveOptions, 'overflowAxis' | 'overflowDirection' | 'padding' | 'minimumVisible' | 'hasHiddenItems'>\n> & {\n children: React.ReactElement;\n\n // overflow is not caused by DOM event\n // eslint-disable-next-line @nx/workspace-consistent-callback-type\n onOverflowChange?: (ev: null, data: OverflowState) => void;\n};\n\n/**\n * Provides an OverflowContext for OverflowItem descendants.\n */\nexport const Overflow = React.forwardRef((props: OverflowProps, ref) => {\n const styles = useOverflowStyles();\n\n const {\n children,\n minimumVisible,\n overflowAxis = 'horizontal',\n overflowDirection,\n padding,\n onOverflowChange,\n hasHiddenItems,\n } = props;\n\n const [overflowState, setOverflowState] = React.useState<OverflowState>({\n hasOverflow: false,\n itemVisibility: {},\n groupVisibility: {},\n });\n\n // useOverflowContainer wraps this method in a useEventCallback.\n const update: OnUpdateOverflow = data => {\n const { visibleItems, invisibleItems, groupVisibility } = data;\n\n const itemVisibility: Record<string, boolean> = {};\n visibleItems.forEach(item => {\n itemVisibility[item.id] = true;\n });\n invisibleItems.forEach(x => (itemVisibility[x.id] = false));\n const newState = {\n hasOverflow: data.invisibleItems.length > 0,\n itemVisibility,\n groupVisibility,\n };\n onOverflowChange?.(null, { ...newState });\n\n setOverflowState(newState);\n };\n\n const { containerRef, registerItem, updateOverflow, registerOverflowMenu, registerDivider } = useOverflowContainer(\n update,\n {\n overflowDirection,\n overflowAxis,\n padding,\n minimumVisible,\n hasHiddenItems,\n onUpdateItemVisibility: updateVisibilityAttribute,\n },\n );\n\n const child = getTriggerChild<HTMLElement>(children);\n const clonedChild = applyTriggerPropsToChildren(children, {\n ref: useMergedRefs(containerRef, ref, getReactElementRef(child)),\n className: mergeClasses('fui-Overflow', styles.overflowMenu, styles.overflowingItems, child?.props.className),\n });\n\n return (\n <OverflowContext.Provider\n value={{\n itemVisibility: overflowState.itemVisibility,\n groupVisibility: overflowState.groupVisibility,\n hasOverflow: overflowState.hasOverflow,\n registerItem,\n updateOverflow,\n registerOverflowMenu,\n registerDivider,\n }}\n >\n {clonedChild}\n </OverflowContext.Provider>\n );\n});\n"],"names":["React","mergeClasses","applyTriggerPropsToChildren","getTriggerChild","getReactElementRef","useMergedRefs","OverflowContext","updateVisibilityAttribute","useOverflowContainer","useOverflowStyles","Overflow","forwardRef","props","ref","styles","children","minimumVisible","overflowAxis","overflowDirection","padding","onOverflowChange","hasHiddenItems","overflowState","setOverflowState","useState","hasOverflow","itemVisibility","groupVisibility","update","data","visibleItems","invisibleItems","forEach","item","id","x","newState","length","containerRef","registerItem","updateOverflow","registerOverflowMenu","registerDivider","onUpdateItemVisibility","child","clonedChild","className","overflowMenu","overflowingItems","Provider","value"],"mappings":"AAAA;;;;;+BAwCaU;;;;;;;iEAtCU,QAAQ;wBACF,iBAAiB;gCAOvC,4BAA4B;iCAEH,qBAAqB;sCACW,0BAA0B;yCACxD,6BAA6B;AA0BxD,iBAAMA,WAAAA,GAAWV,OAAMW,UAAU,CAAC,CAACC,OAAsBC;IAC9D,MAAMC,aAASL,0CAAAA;IAEf,MAAM,EACJM,QAAQ,EACRC,cAAc,EACdC,eAAe,YAAY,EAC3BC,iBAAiB,EACjBC,OAAO,EACPC,gBAAgB,EAChBC,cAAc,EACf,GAAGT;IAEJ,MAAM,CAACU,eAAeC,iBAAiB,GAAGvB,OAAMwB,QAAQ,CAAgB;QACtEC,aAAa;QACbC,gBAAgB,CAAC;QACjBC,iBAAiB,CAAC;IACpB;IAEA,gEAAgE;IAChE,MAAMC,SAA2BC,CAAAA;QAC/B,MAAM,EAAEC,YAAY,EAAEC,cAAc,EAAEJ,eAAe,EAAE,GAAGE;QAE1D,MAAMH,iBAA0C,CAAC;QACjDI,aAAaE,OAAO,CAACC,CAAAA;YACnBP,cAAc,CAACO,KAAKC,EAAE,CAAC,GAAG;QAC5B;QACAH,eAAeC,OAAO,CAACG,CAAAA,IAAMT,cAAc,CAACS,EAAED,EAAE,CAAC,GAAG;QACpD,MAAME,WAAW;YACfX,aAAaI,KAAKE,cAAc,CAACM,MAAM,GAAG;YAC1CX;YACAC;QACF;QACAP,qBAAAA,QAAAA,qBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,iBAAmB,MAAM;YAAE,GAAGgB,QAAQ;QAAC;QAEvCb,iBAAiBa;IACnB;IAEA,MAAM,EAAEE,YAAY,EAAEC,YAAY,EAAEC,cAAc,EAAEC,oBAAoB,EAAEC,eAAe,EAAE,OAAGlC,0CAAAA,EAC5FoB,QACA;QACEV;QACAD;QACAE;QACAH;QACAK;QACAsB,wBAAwBpC,+CAAAA;IAC1B;IAGF,MAAMqC,YAAQzC,+BAAAA,EAA6BY;IAC3C,MAAM8B,kBAAc3C,2CAAAA,EAA4Ba,UAAU;QACxDF,SAAKR,6BAAAA,EAAciC,cAAczB,SAAKT,kCAAAA,EAAmBwC;QACzDE,eAAW7C,oBAAAA,EAAa,gBAAgBa,OAAOiC,YAAY,EAAEjC,OAAOkC,gBAAgB,EAAEJ,UAAAA,QAAAA,UAAAA,KAAAA,IAAAA,KAAAA,IAAAA,MAAOhC,KAAK,CAACkC,SAAS;IAC9G;IAEA,OAAA,WAAA,GACE,OAAA,aAAA,CAACxC,gCAAAA,CAAgB2C,QAAQ,EAAA;QACvBC,OAAO;YACLxB,gBAAgBJ,cAAcI,cAAc;YAC5CC,iBAAiBL,cAAcK,eAAe;YAC9CF,aAAaH,cAAcG,WAAW;YACtCc;YACAC;YACAC;YACAC;QACF;
|
|
1
|
+
{"version":3,"sources":["../src/components/Overflow.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { mergeClasses } from '@griffel/react';\nimport type { OnUpdateOverflow, OverflowGroupState, ObserveOptions } from '@fluentui/priority-overflow';\nimport {\n applyTriggerPropsToChildren,\n getTriggerChild,\n getReactElementRef,\n useMergedRefs,\n} from '@fluentui/react-utilities';\n\nimport { OverflowContext } from '../overflowContext';\nimport { updateVisibilityAttribute, useOverflowContainer } from '../useOverflowContainer';\nimport { useOverflowStyles } from './useOverflowStyles.styles';\n\ninterface OverflowState {\n hasOverflow: boolean;\n itemVisibility: Record<string, boolean>;\n groupVisibility: Record<string, OverflowGroupState>;\n}\n\nexport interface OnOverflowChangeData extends OverflowState {}\n\n/**\n * Overflow Props\n */\nexport type OverflowProps = Partial<\n Pick<ObserveOptions, 'overflowAxis' | 'overflowDirection' | 'padding' | 'minimumVisible' | 'hasHiddenItems'>\n> & {\n children: React.ReactElement;\n\n // overflow is not caused by DOM event\n // eslint-disable-next-line @nx/workspace-consistent-callback-type\n onOverflowChange?: (ev: null, data: OverflowState) => void;\n};\n\n/**\n * Provides an OverflowContext for OverflowItem descendants.\n */\nexport const Overflow = React.forwardRef((props: OverflowProps, ref) => {\n const styles = useOverflowStyles();\n\n const {\n children,\n minimumVisible,\n overflowAxis = 'horizontal',\n overflowDirection,\n padding,\n onOverflowChange,\n hasHiddenItems,\n } = props;\n\n const [overflowState, setOverflowState] = React.useState<OverflowState>({\n hasOverflow: false,\n itemVisibility: {},\n groupVisibility: {},\n });\n\n // useOverflowContainer wraps this method in a useEventCallback.\n const update: OnUpdateOverflow = data => {\n const { visibleItems, invisibleItems, groupVisibility } = data;\n\n const itemVisibility: Record<string, boolean> = {};\n visibleItems.forEach(item => {\n itemVisibility[item.id] = true;\n });\n invisibleItems.forEach(x => (itemVisibility[x.id] = false));\n const newState = {\n hasOverflow: data.invisibleItems.length > 0,\n itemVisibility,\n groupVisibility,\n };\n onOverflowChange?.(null, { ...newState });\n\n setOverflowState(newState);\n };\n\n const { containerRef, registerItem, updateOverflow, registerOverflowMenu, registerDivider } = useOverflowContainer(\n update,\n {\n overflowDirection,\n overflowAxis,\n padding,\n minimumVisible,\n hasHiddenItems,\n onUpdateItemVisibility: updateVisibilityAttribute,\n },\n );\n\n const child = getTriggerChild<HTMLElement>(children);\n const clonedChild = applyTriggerPropsToChildren(children, {\n ref: useMergedRefs(containerRef, ref, getReactElementRef(child)),\n className: mergeClasses('fui-Overflow', styles.overflowMenu, styles.overflowingItems, child?.props.className),\n });\n\n return (\n <OverflowContext.Provider\n value={{\n itemVisibility: overflowState.itemVisibility,\n groupVisibility: overflowState.groupVisibility,\n hasOverflow: overflowState.hasOverflow,\n registerItem,\n updateOverflow,\n registerOverflowMenu,\n registerDivider,\n containerRef,\n }}\n >\n {clonedChild}\n </OverflowContext.Provider>\n );\n});\n"],"names":["React","mergeClasses","applyTriggerPropsToChildren","getTriggerChild","getReactElementRef","useMergedRefs","OverflowContext","updateVisibilityAttribute","useOverflowContainer","useOverflowStyles","Overflow","forwardRef","props","ref","styles","children","minimumVisible","overflowAxis","overflowDirection","padding","onOverflowChange","hasHiddenItems","overflowState","setOverflowState","useState","hasOverflow","itemVisibility","groupVisibility","update","data","visibleItems","invisibleItems","forEach","item","id","x","newState","length","containerRef","registerItem","updateOverflow","registerOverflowMenu","registerDivider","onUpdateItemVisibility","child","clonedChild","className","overflowMenu","overflowingItems","Provider","value"],"mappings":"AAAA;;;;;+BAwCaU;;;;;;;iEAtCU,QAAQ;wBACF,iBAAiB;gCAOvC,4BAA4B;iCAEH,qBAAqB;sCACW,0BAA0B;yCACxD,6BAA6B;AA0BxD,iBAAMA,WAAAA,GAAWV,OAAMW,UAAU,CAAC,CAACC,OAAsBC;IAC9D,MAAMC,aAASL,0CAAAA;IAEf,MAAM,EACJM,QAAQ,EACRC,cAAc,EACdC,eAAe,YAAY,EAC3BC,iBAAiB,EACjBC,OAAO,EACPC,gBAAgB,EAChBC,cAAc,EACf,GAAGT;IAEJ,MAAM,CAACU,eAAeC,iBAAiB,GAAGvB,OAAMwB,QAAQ,CAAgB;QACtEC,aAAa;QACbC,gBAAgB,CAAC;QACjBC,iBAAiB,CAAC;IACpB;IAEA,gEAAgE;IAChE,MAAMC,SAA2BC,CAAAA;QAC/B,MAAM,EAAEC,YAAY,EAAEC,cAAc,EAAEJ,eAAe,EAAE,GAAGE;QAE1D,MAAMH,iBAA0C,CAAC;QACjDI,aAAaE,OAAO,CAACC,CAAAA;YACnBP,cAAc,CAACO,KAAKC,EAAE,CAAC,GAAG;QAC5B;QACAH,eAAeC,OAAO,CAACG,CAAAA,IAAMT,cAAc,CAACS,EAAED,EAAE,CAAC,GAAG;QACpD,MAAME,WAAW;YACfX,aAAaI,KAAKE,cAAc,CAACM,MAAM,GAAG;YAC1CX;YACAC;QACF;QACAP,qBAAAA,QAAAA,qBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,iBAAmB,MAAM;YAAE,GAAGgB,QAAQ;QAAC;QAEvCb,iBAAiBa;IACnB;IAEA,MAAM,EAAEE,YAAY,EAAEC,YAAY,EAAEC,cAAc,EAAEC,oBAAoB,EAAEC,eAAe,EAAE,OAAGlC,0CAAAA,EAC5FoB,QACA;QACEV;QACAD;QACAE;QACAH;QACAK;QACAsB,wBAAwBpC,+CAAAA;IAC1B;IAGF,MAAMqC,YAAQzC,+BAAAA,EAA6BY;IAC3C,MAAM8B,kBAAc3C,2CAAAA,EAA4Ba,UAAU;QACxDF,SAAKR,6BAAAA,EAAciC,cAAczB,SAAKT,kCAAAA,EAAmBwC;QACzDE,eAAW7C,oBAAAA,EAAa,gBAAgBa,OAAOiC,YAAY,EAAEjC,OAAOkC,gBAAgB,EAAEJ,UAAAA,QAAAA,UAAAA,KAAAA,IAAAA,KAAAA,IAAAA,MAAOhC,KAAK,CAACkC,SAAS;IAC9G;IAEA,OAAA,WAAA,GACE,OAAA,aAAA,CAACxC,gCAAAA,CAAgB2C,QAAQ,EAAA;QACvBC,OAAO;YACLxB,gBAAgBJ,cAAcI,cAAc;YAC5CC,iBAAiBL,cAAcK,eAAe;YAC9CF,aAAaH,cAAcG,WAAW;YACtCc;YACAC;YACAC;YACAC;YACAJ;QACF;OAECO;AAGP,GAAG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "OverflowReorderObserver", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function() {
|
|
9
|
+
return OverflowReorderObserver;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
|
|
13
|
+
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
|
|
14
|
+
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
|
|
15
|
+
const _overflowContext = require("../../overflowContext");
|
|
16
|
+
const OverflowReorderObserver = ()=>{
|
|
17
|
+
const containerRef = (0, _overflowContext.useOverflowContext)((v)=>v.containerRef);
|
|
18
|
+
const updateOverflow = (0, _overflowContext.useOverflowContext)((v)=>v.updateOverflow);
|
|
19
|
+
const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
|
|
20
|
+
const targetWindow = targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.defaultView;
|
|
21
|
+
_react.useEffect(()=>{
|
|
22
|
+
const el = containerRef === null || containerRef === void 0 ? void 0 : containerRef.current;
|
|
23
|
+
if (!el || !(targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.MutationObserver)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const mutationObserver = new targetWindow.MutationObserver(()=>updateOverflow());
|
|
27
|
+
mutationObserver.observe(el, {
|
|
28
|
+
childList: true
|
|
29
|
+
});
|
|
30
|
+
return ()=>mutationObserver.disconnect();
|
|
31
|
+
}, [
|
|
32
|
+
containerRef,
|
|
33
|
+
updateOverflow,
|
|
34
|
+
targetWindow
|
|
35
|
+
]);
|
|
36
|
+
return null;
|
|
37
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/OverflowReorderObserver/OverflowReorderObserver.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport { useOverflowContext } from '../../overflowContext';\n\n/**\n * Renderless opt-in component that observes the `<Overflow>` container for\n * direct-child DOM mutations and triggers an overflow recompute. Drop it\n * inside `<Overflow>` when items can be reordered, added, or removed via\n * React state without a container resize — Fluent's overflow manager only\n * listens to `ResizeObserver` otherwise, so reorders leave visibility flags\n * stale.\n *\n * @example\n * ```tsx\n * <Overflow>\n * <div>\n * <OverflowReorderObserver />\n * {items.map(id => <OverflowItem key={id} id={id} priority={1}>{id}</OverflowItem>)}\n * </div>\n * </Overflow>\n * ```\n */\nexport const OverflowReorderObserver: React.FC = () => {\n const containerRef = useOverflowContext(v => v.containerRef);\n const updateOverflow = useOverflowContext(v => v.updateOverflow);\n const { targetDocument } = useFluent();\n const targetWindow = targetDocument?.defaultView;\n\n React.useEffect(() => {\n const el = containerRef?.current;\n if (!el || !targetWindow?.MutationObserver) {\n return;\n }\n\n const mutationObserver = new targetWindow.MutationObserver(() => updateOverflow());\n mutationObserver.observe(el, { childList: true });\n\n return () => mutationObserver.disconnect();\n }, [containerRef, updateOverflow, targetWindow]);\n\n return null;\n};\n"],"names":["React","useFluent_unstable","useFluent","useOverflowContext","OverflowReorderObserver","containerRef","v","updateOverflow","targetDocument","targetWindow","defaultView","useEffect","el","current","MutationObserver","mutationObserver","observe","childList","disconnect"],"mappings":"AAAA;;;;;+BAwBaI;;;;;;;iEAtBU,QAAQ;qCACiB,kCAAkC;iCAC/C,wBAAwB;AAoBpD,gCAA0C;IAC/C,MAAMC,mBAAeF,mCAAAA,EAAmBG,CAAAA,IAAKA,EAAED,YAAY;IAC3D,MAAME,qBAAiBJ,mCAAAA,EAAmBG,CAAAA,IAAKA,EAAEC,cAAc;IAC/D,MAAM,EAAEC,cAAc,EAAE,OAAGN,uCAAAA;IAC3B,MAAMO,eAAeD,mBAAAA,QAAAA,mBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,eAAgBE,WAAW;IAEhDV,OAAMW,SAAS,CAAC;QACd,MAAMC,KAAKP,iBAAAA,QAAAA,iBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,aAAcQ,OAAO;QAChC,IAAI,CAACD,MAAM,EAACH,iBAAAA,QAAAA,iBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,aAAcK,gBAAAA,AAAgB,GAAE;YAC1C;QACF;QAEA,MAAMC,mBAAmB,IAAIN,aAAaK,gBAAgB,CAAC,IAAMP;QACjEQ,iBAAiBC,OAAO,CAACJ,IAAI;YAAEK,WAAW;QAAK;QAE/C,OAAO,IAAMF,iBAAiBG,UAAU;IAC1C,GAAG;QAACb;QAAcE;QAAgBE;KAAa;IAE/C,OAAO;AACT,EAAE"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "OverflowReorderObserver", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return _OverflowReorderObserver.OverflowReorderObserver;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _OverflowReorderObserver = require("./OverflowReorderObserver");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/OverflowReorderObserver/index.ts"],"sourcesContent":["export { OverflowReorderObserver } from './OverflowReorderObserver';\n"],"names":["OverflowReorderObserver"],"mappings":";;;;;;;eAASA,gDAAuB;;;yCAAQ,4BAA4B"}
|
package/lib-commonjs/index.js
CHANGED
|
@@ -30,6 +30,9 @@ _export(exports, {
|
|
|
30
30
|
OverflowItem: function() {
|
|
31
31
|
return _OverflowItem.OverflowItem;
|
|
32
32
|
},
|
|
33
|
+
OverflowReorderObserver: function() {
|
|
34
|
+
return _OverflowReorderObserver.OverflowReorderObserver;
|
|
35
|
+
},
|
|
33
36
|
useIsOverflowGroupVisible: function() {
|
|
34
37
|
return _useIsOverflowGroupVisible.useIsOverflowGroupVisible;
|
|
35
38
|
},
|
|
@@ -71,3 +74,4 @@ const _useOverflowVisibility = require("./useOverflowVisibility");
|
|
|
71
74
|
const _overflowContext = require("./overflowContext");
|
|
72
75
|
const _OverflowItem = require("./components/OverflowItem/OverflowItem");
|
|
73
76
|
const _OverflowDivider = require("./components/OverflowDivider/OverflowDivider");
|
|
77
|
+
const _OverflowReorderObserver = require("./components/OverflowReorderObserver");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { Overflow } from './components/Overflow';\nexport type { OverflowProps, OnOverflowChangeData } from './components/Overflow';\nexport { DATA_OVERFLOWING, DATA_OVERFLOW_ITEM, DATA_OVERFLOW_MENU, DATA_OVERFLOW_DIVIDER } from './constants';\nexport type { UseOverflowContainerReturn } from './types';\nexport { useIsOverflowGroupVisible } from './useIsOverflowGroupVisible';\nexport { useIsOverflowItemVisible } from './useIsOverflowItemVisible';\nexport { useOverflowContainer } from './useOverflowContainer';\nexport { useOverflowCount } from './useOverflowCount';\nexport { useOverflowItem } from './useOverflowItem';\nexport { useOverflowMenu } from './useOverflowMenu';\nexport { useOverflowDivider } from './useOverflowDivider';\nexport { useOverflowVisibility } from './useOverflowVisibility';\n\nexport { useOverflowContext } from './overflowContext';\n\nexport type { OverflowItemProps } from './components/OverflowItem/OverflowItem.types';\nexport { OverflowItem } from './components/OverflowItem/OverflowItem';\nexport { OverflowDivider } from './components/OverflowDivider/OverflowDivider';\n"],"names":["Overflow","DATA_OVERFLOWING","DATA_OVERFLOW_ITEM","DATA_OVERFLOW_MENU","DATA_OVERFLOW_DIVIDER","useIsOverflowGroupVisible","useIsOverflowItemVisible","useOverflowContainer","useOverflowCount","useOverflowItem","useOverflowMenu","useOverflowDivider","useOverflowVisibility","useOverflowContext","OverflowItem","OverflowDivider"],"mappings":";;;;;;;;;;;IAESC,gBAAgB;;;;eAA0CG,gCAAqB;;;eAA7DF,6BAAkB;;;eAAEC,6BAAkB;;;eAFxDH,kBAAQ;;;eAiBRe,gCAAe
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { Overflow } from './components/Overflow';\nexport type { OverflowProps, OnOverflowChangeData } from './components/Overflow';\nexport { DATA_OVERFLOWING, DATA_OVERFLOW_ITEM, DATA_OVERFLOW_MENU, DATA_OVERFLOW_DIVIDER } from './constants';\nexport type { UseOverflowContainerReturn } from './types';\nexport { useIsOverflowGroupVisible } from './useIsOverflowGroupVisible';\nexport { useIsOverflowItemVisible } from './useIsOverflowItemVisible';\nexport { useOverflowContainer } from './useOverflowContainer';\nexport { useOverflowCount } from './useOverflowCount';\nexport { useOverflowItem } from './useOverflowItem';\nexport { useOverflowMenu } from './useOverflowMenu';\nexport { useOverflowDivider } from './useOverflowDivider';\nexport { useOverflowVisibility } from './useOverflowVisibility';\n\nexport { useOverflowContext } from './overflowContext';\n\nexport type { OverflowItemProps } from './components/OverflowItem/OverflowItem.types';\nexport { OverflowItem } from './components/OverflowItem/OverflowItem';\nexport { OverflowDivider } from './components/OverflowDivider/OverflowDivider';\nexport { OverflowReorderObserver } from './components/OverflowReorderObserver';\n"],"names":["Overflow","DATA_OVERFLOWING","DATA_OVERFLOW_ITEM","DATA_OVERFLOW_MENU","DATA_OVERFLOW_DIVIDER","useIsOverflowGroupVisible","useIsOverflowItemVisible","useOverflowContainer","useOverflowCount","useOverflowItem","useOverflowMenu","useOverflowDivider","useOverflowVisibility","useOverflowContext","OverflowItem","OverflowDivider","OverflowReorderObserver"],"mappings":";;;;;;;;;;;IAESC,gBAAgB;;;;eAA0CG,gCAAqB;;;eAA7DF,6BAAkB;;;eAAEC,6BAAkB;;;eAFxDH,kBAAQ;;;eAiBRe,gCAAe;;;eADfD,0BAAY;;;eAEZE,gDAAuB;;;eAdvBX,oDAAyB;;IACzBC,wBAAwB;;;;eACxBC,0CAAoB;;;eAOpBM,mCAAkB;;;eANlBL,kCAAgB;;IAGhBG;qDAAkB;;;eAFlBF,gCAAe;;mBACA;eAAfC;;;eAEAE,4CAAqB;;;0BAXL,wBAAwB;2BAE+C,cAAc;2CAEpE,8BAA8B;0CAC/B,6BAA6B;sCACjC,yBAAyB;kCAC7B,qBAAqB;iCACtB,oBAAoB;iCACpB,oBAAoB;oCACjB,uBAAuB;uCACpB,0BAA0B;iCAE7B,oBAAoB;8BAG1B,yCAAyC;iCACtC,+CAA+C;yCACvC,uCAAuC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/overflowContext.ts"],"sourcesContent":["'use client';\n\nimport type { OverflowGroupState, OverflowItemEntry, OverflowDividerEntry } from '@fluentui/priority-overflow';\nimport type { ContextSelector, Context } from '@fluentui/react-context-selector';\nimport { createContext, useContextSelector } from '@fluentui/react-context-selector';\n\n/**\n * @internal\n */\nexport interface OverflowContextValue {\n itemVisibility: Record<string, boolean>;\n groupVisibility: Record<string, OverflowGroupState>;\n hasOverflow: boolean;\n registerItem: (item: OverflowItemEntry) => () => void;\n registerOverflowMenu: (el: HTMLElement) => () => void;\n registerDivider: (divider: OverflowDividerEntry) => () => void;\n updateOverflow: (padding?: number) => void;\n}\n\nexport const OverflowContext = createContext<OverflowContextValue | undefined>(\n undefined,\n) as Context<OverflowContextValue>;\n\nconst overflowContextDefaultValue: OverflowContextValue = {\n itemVisibility: {},\n groupVisibility: {},\n hasOverflow: false,\n registerItem: () => () => null,\n updateOverflow: () => null,\n registerOverflowMenu: () => () => null,\n registerDivider: () => () => null,\n};\n\n/**\n * @internal\n */\nexport const useOverflowContext = <SelectedValue>(\n selector: ContextSelector<OverflowContextValue, SelectedValue>,\n): SelectedValue => useContextSelector(OverflowContext, (ctx = overflowContextDefaultValue) => selector(ctx));\n"],"names":["createContext","useContextSelector","OverflowContext","undefined","overflowContextDefaultValue","itemVisibility","groupVisibility","hasOverflow","registerItem","updateOverflow","registerOverflowMenu","registerDivider","useOverflowContext","selector","ctx"],"mappings":"AAAA;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../src/overflowContext.ts"],"sourcesContent":["'use client';\n\nimport type * as React from 'react';\nimport type { OverflowGroupState, OverflowItemEntry, OverflowDividerEntry } from '@fluentui/priority-overflow';\nimport type { ContextSelector, Context } from '@fluentui/react-context-selector';\nimport { createContext, useContextSelector } from '@fluentui/react-context-selector';\n\n/**\n * @internal\n */\nexport interface OverflowContextValue {\n itemVisibility: Record<string, boolean>;\n groupVisibility: Record<string, OverflowGroupState>;\n hasOverflow: boolean;\n registerItem: (item: OverflowItemEntry) => () => void;\n registerOverflowMenu: (el: HTMLElement) => () => void;\n registerDivider: (divider: OverflowDividerEntry) => () => void;\n updateOverflow: (padding?: number) => void;\n containerRef?: React.RefObject<HTMLElement | null>;\n}\n\nexport const OverflowContext = createContext<OverflowContextValue | undefined>(\n undefined,\n) as Context<OverflowContextValue>;\n\nconst overflowContextDefaultValue: OverflowContextValue = {\n itemVisibility: {},\n groupVisibility: {},\n hasOverflow: false,\n registerItem: () => () => null,\n updateOverflow: () => null,\n registerOverflowMenu: () => () => null,\n registerDivider: () => () => null,\n};\n\n/**\n * @internal\n */\nexport const useOverflowContext = <SelectedValue>(\n selector: ContextSelector<OverflowContextValue, SelectedValue>,\n): SelectedValue => useContextSelector(OverflowContext, (ctx = overflowContextDefaultValue) => selector(ctx));\n"],"names":["createContext","useContextSelector","OverflowContext","undefined","overflowContextDefaultValue","itemVisibility","groupVisibility","hasOverflow","registerItem","updateOverflow","registerOverflowMenu","registerDivider","useOverflowContext","selector","ctx"],"mappings":"AAAA;;;;;;;;;;;;mBAqBaE;;;sBAiBAU;;;;sCAjCqC,mCAAmC;AAgB9E,MAAMV,sBAAkBF,mCAAAA,EAC7BG,WACiC;AAEnC,MAAMC,8BAAoD;IACxDC,gBAAgB,CAAC;IACjBC,iBAAiB,CAAC;IAClBC,aAAa;IACbC,cAAc,IAAM,IAAM;IAC1BC,gBAAgB,IAAM;IACtBC,sBAAsB,IAAM,IAAM;IAClCC,iBAAiB,IAAM,IAAM;AAC/B;AAKO,MAAMC,qBAAqB,CAChCC,eACkBZ,wCAAAA,EAAmBC,iBAAiB,CAACY,MAAMV,2BAA2B,GAAKS,SAASC,MAAM"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluentui/react-overflow",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.8.0",
|
|
4
4
|
"description": "React bindings for @fluentui/priority-overflow",
|
|
5
5
|
"main": "lib-commonjs/index.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@fluentui/priority-overflow": "^9.3.0",
|
|
16
|
-
"@fluentui/react-context-selector": "^9.2.
|
|
16
|
+
"@fluentui/react-context-selector": "^9.2.17",
|
|
17
|
+
"@fluentui/react-shared-contexts": "^9.26.2",
|
|
17
18
|
"@fluentui/react-theme": "^9.2.1",
|
|
18
|
-
"@fluentui/react-utilities": "^9.26.
|
|
19
|
+
"@fluentui/react-utilities": "^9.26.4",
|
|
19
20
|
"@griffel/react": "^1.5.32",
|
|
20
21
|
"@swc/helpers": "^0.5.1"
|
|
21
22
|
},
|