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

View File

@@ -0,0 +1,60 @@
'use client';
import * as React from 'react';
import { mergeClasses } from '@griffel/react';
import { applyTriggerPropsToChildren, getTriggerChild, getReactElementRef, useMergedRefs } from '@fluentui/react-utilities';
import { OverflowContext } from '../overflowContext';
import { updateVisibilityAttribute, useOverflowContainer } from '../useOverflowContainer';
import { useOverflowStyles } from './useOverflowStyles.styles';
/**
* Provides an OverflowContext for OverflowItem descendants.
*/ export const Overflow = /*#__PURE__*/ React.forwardRef((props, ref)=>{
const styles = useOverflowStyles();
const { children, minimumVisible, overflowAxis = 'horizontal', overflowDirection, padding, onOverflowChange, hasHiddenItems } = props;
const [overflowState, setOverflowState] = React.useState({
hasOverflow: false,
itemVisibility: {},
groupVisibility: {}
});
// useOverflowContainer wraps this method in a useEventCallback.
const update = (data)=>{
const { visibleItems, invisibleItems, groupVisibility } = data;
const itemVisibility = {};
visibleItems.forEach((item)=>{
itemVisibility[item.id] = true;
});
invisibleItems.forEach((x)=>itemVisibility[x.id] = false);
const newState = {
hasOverflow: data.invisibleItems.length > 0,
itemVisibility,
groupVisibility
};
onOverflowChange === null || onOverflowChange === void 0 ? void 0 : onOverflowChange(null, {
...newState
});
setOverflowState(newState);
};
const { containerRef, registerItem, updateOverflow, registerOverflowMenu, registerDivider } = useOverflowContainer(update, {
overflowDirection,
overflowAxis,
padding,
minimumVisible,
hasHiddenItems,
onUpdateItemVisibility: updateVisibilityAttribute
});
const child = getTriggerChild(children);
const clonedChild = applyTriggerPropsToChildren(children, {
ref: useMergedRefs(containerRef, ref, getReactElementRef(child)),
className: mergeClasses('fui-Overflow', styles.overflowMenu, styles.overflowingItems, child === null || child === void 0 ? void 0 : child.props.className)
});
return /*#__PURE__*/ React.createElement(OverflowContext.Provider, {
value: {
itemVisibility: overflowState.itemVisibility,
groupVisibility: overflowState.groupVisibility,
hasOverflow: overflowState.hasOverflow,
registerItem,
updateOverflow,
registerOverflowMenu,
registerDivider
}
}, clonedChild);
});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,14 @@
'use client';
import * as React from 'react';
import { applyTriggerPropsToChildren, useMergedRefs } from '@fluentui/react-utilities';
import { useOverflowDivider } from '../../useOverflowDivider';
/**
* Attaches overflow item behavior to its child registered with the OverflowContext.
* It does not render an element of its own.
*/ export const OverflowDivider = /*#__PURE__*/ React.forwardRef((props, ref)=>{
const { groupId, children } = props;
const containerRef = useOverflowDivider(groupId);
return applyTriggerPropsToChildren(children, {
ref: useMergedRefs(containerRef, ref)
});
});

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/OverflowDivider/OverflowDivider.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { applyTriggerPropsToChildren, useMergedRefs } from '@fluentui/react-utilities';\nimport { useOverflowDivider } from '../../useOverflowDivider';\nimport { OverflowDividerProps } from './OverflowDivider.types';\n\n/**\n * Attaches overflow item behavior to its child registered with the OverflowContext.\n * It does not render an element of its own.\n */\nexport const OverflowDivider = React.forwardRef((props: OverflowDividerProps, ref) => {\n const { groupId, children } = props;\n\n const containerRef = useOverflowDivider(groupId);\n return applyTriggerPropsToChildren(children, {\n ref: useMergedRefs(containerRef, ref),\n });\n});\n"],"names":["React","applyTriggerPropsToChildren","useMergedRefs","useOverflowDivider","OverflowDivider","forwardRef","props","ref","groupId","children","containerRef"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,2BAA2B,EAAEC,aAAa,QAAQ,4BAA4B;AACvF,SAASC,kBAAkB,QAAQ,2BAA2B;AAG9D;;;CAGC,GACD,OAAO,MAAMC,gCAAkBJ,MAAMK,UAAU,CAAC,CAACC,OAA6BC;IAC5E,MAAM,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGH;IAE9B,MAAMI,eAAeP,mBAAmBK;IACxC,OAAOP,4BAA4BQ,UAAU;QAC3CF,KAAKL,cAAcQ,cAAcH;IACnC;AACF,GAAG"}

View File

@@ -0,0 +1 @@
import * as React from 'react';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/OverflowDivider/OverflowDivider.types.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * OverflowDividerProps\n */\nexport type OverflowDividerProps = {\n /**\n * Assigns the item to a group, group visibility can be watched.\n */\n groupId: string;\n /**\n * The single child that has overflow item behavior attached.\n */\n children: React.ReactElement;\n};\n"],"names":["React"],"mappings":"AAAA,YAAYA,WAAW,QAAQ"}

View File

@@ -0,0 +1,19 @@
'use client';
import * as React from 'react';
import { applyTriggerPropsToChildren, getReactElementRef, getTriggerChild, useMergedRefs } from '@fluentui/react-utilities';
import { useOverflowItem } from '../../useOverflowItem';
/**
* Attaches overflow item behavior to its child registered with the OverflowContext.
* It does not render an element of its own.
*
* Behaves similarly to other `*Trigger` components in Fluent UI React.
*/ export const OverflowItem = /*#__PURE__*/ React.forwardRef((props, ref)=>{
const { id, groupId, priority, pinned, children } = props;
const containerRef = useOverflowItem(id, priority, groupId, pinned);
const child = getTriggerChild(children);
return applyTriggerPropsToChildren(children, {
ref: useMergedRefs(containerRef, ref, getReactElementRef(child))
});
});
// type casting here is required to ensure internal type FluentTriggerComponent is not leaked
OverflowItem.isFluentTriggerComponent = true;

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/OverflowItem/OverflowItem.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n applyTriggerPropsToChildren,\n getReactElementRef,\n type FluentTriggerComponent,\n getTriggerChild,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport { useOverflowItem } from '../../useOverflowItem';\nimport { OverflowItemProps } from './OverflowItem.types';\n\n/**\n * Attaches overflow item behavior to its child registered with the OverflowContext.\n * It does not render an element of its own.\n *\n * Behaves similarly to other `*Trigger` components in Fluent UI React.\n */\nexport const OverflowItem = React.forwardRef((props: OverflowItemProps, ref) => {\n const { id, groupId, priority, pinned, children } = props;\n\n const containerRef = useOverflowItem(id, priority, groupId, pinned);\n const child = getTriggerChild(children);\n\n return applyTriggerPropsToChildren(children, {\n ref: useMergedRefs(containerRef, ref, getReactElementRef(child)),\n });\n});\n\n// type casting here is required to ensure internal type FluentTriggerComponent is not leaked\n(OverflowItem as FluentTriggerComponent).isFluentTriggerComponent = true;\n"],"names":["React","applyTriggerPropsToChildren","getReactElementRef","getTriggerChild","useMergedRefs","useOverflowItem","OverflowItem","forwardRef","props","ref","id","groupId","priority","pinned","children","containerRef","child","isFluentTriggerComponent"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SACEC,2BAA2B,EAC3BC,kBAAkB,EAElBC,eAAe,EACfC,aAAa,QACR,4BAA4B;AACnC,SAASC,eAAe,QAAQ,wBAAwB;AAGxD;;;;;CAKC,GACD,OAAO,MAAMC,6BAAeN,MAAMO,UAAU,CAAC,CAACC,OAA0BC;IACtE,MAAM,EAAEC,EAAE,EAAEC,OAAO,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,QAAQ,EAAE,GAAGN;IAEpD,MAAMO,eAAeV,gBAAgBK,IAAIE,UAAUD,SAASE;IAC5D,MAAMG,QAAQb,gBAAgBW;IAE9B,OAAOb,4BAA4Ba,UAAU;QAC3CL,KAAKL,cAAcW,cAAcN,KAAKP,mBAAmBc;IAC3D;AACF,GAAG;AAEH,6FAA6F;AAC5FV,aAAwCW,wBAAwB,GAAG"}

View File

@@ -0,0 +1 @@
import * as React from 'react';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/OverflowItem/OverflowItem.types.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * OverflowItemProps\n */\nexport type OverflowItemProps = {\n /**\n * The unique identifier for the item used by the overflow manager.\n */\n id: string;\n /**\n * Assigns the item to a group, group visibility can be watched.\n */\n groupId?: string;\n /**\n * The single child that has overflow item behavior attached.\n */\n children: React.ReactElement;\n} & (\n | {\n /**\n * If true, the item will never overflow and will always be visible.\n * Mutually exclusive with `priority`.\n */\n pinned?: boolean;\n priority?: never;\n }\n | {\n pinned?: never;\n /**\n * A higher priority means the item overflows later.\n * Mutually exclusive with `pinned`.\n */\n priority?: number;\n }\n);\n"],"names":["React"],"mappings":"AAAA,YAAYA,WAAW,QAAQ"}

View File

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

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/OverflowItem/index.ts"],"sourcesContent":["export type { OverflowItemProps } from './OverflowItem.types';\nexport { OverflowItem } from './OverflowItem';\n"],"names":["OverflowItem"],"mappings":"AACA,SAASA,YAAY,QAAQ,iBAAiB"}

View File

@@ -0,0 +1,14 @@
'use client';
import { __styles } from '@griffel/react';
import { DATA_OVERFLOWING, DATA_OVERFLOW_MENU } from '../constants';
export const useOverflowStyles = /*#__PURE__*/__styles({
overflowMenu: {
Brvla84: "fyfkpbf"
},
overflowingItems: {
zb22lx: "f10570jf"
}
}, {
d: [".fyfkpbf [data-overflow-menu]{flex-shrink:0;}", ".f10570jf [data-overflowing]{display:none;}"]
});

View File

@@ -0,0 +1 @@
{"version":3,"names":["__styles","DATA_OVERFLOWING","DATA_OVERFLOW_MENU","useOverflowStyles","overflowMenu","Brvla84","overflowingItems","zb22lx","d"],"sources":["useOverflowStyles.styles.js"],"sourcesContent":["'use client';\nimport { makeStyles } from '@griffel/react';\nimport { DATA_OVERFLOWING, DATA_OVERFLOW_MENU } from '../constants';\nexport const useOverflowStyles = makeStyles({\n overflowMenu: {\n [`& [${DATA_OVERFLOW_MENU}]`]: {\n flexShrink: 0\n }\n },\n overflowingItems: {\n [`& [${DATA_OVERFLOWING}]`]: {\n display: 'none'\n }\n }\n});\n"],"mappings":"AAAA,YAAY;;AACZ,SAAAA,QAAA,QAA2B,gBAAgB;AAC3C,SAASC,gBAAgB,EAAEC,kBAAkB,QAAQ,cAAc;AACnE,OAAO,MAAMC,iBAAiB,gBAAGH,QAAA;EAAAI,YAAA;IAAAC,OAAA;EAAA;EAAAC,gBAAA;IAAAC,MAAA;EAAA;AAAA;EAAAC,CAAA;AAAA,CAWhC,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,15 @@
'use client';
import { makeStyles } from '@griffel/react';
import { DATA_OVERFLOWING, DATA_OVERFLOW_MENU } from '../constants';
export const useOverflowStyles = makeStyles({
overflowMenu: {
[`& [${DATA_OVERFLOW_MENU}]`]: {
flexShrink: 0
}
},
overflowingItems: {
[`& [${DATA_OVERFLOWING}]`]: {
display: 'none'
}
}
});

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/useOverflowStyles.styles.ts"],"sourcesContent":["'use client';\n\nimport { makeStyles } from '@griffel/react';\nimport { DATA_OVERFLOWING, DATA_OVERFLOW_MENU } from '../constants';\n\nexport const useOverflowStyles = makeStyles({\n overflowMenu: {\n [`& [${DATA_OVERFLOW_MENU}]`]: {\n flexShrink: 0,\n },\n },\n\n overflowingItems: {\n [`& [${DATA_OVERFLOWING}]`]: {\n display: 'none',\n },\n },\n});\n"],"names":["makeStyles","DATA_OVERFLOWING","DATA_OVERFLOW_MENU","useOverflowStyles","overflowMenu","flexShrink","overflowingItems","display"],"mappings":"AAAA;AAEA,SAASA,UAAU,QAAQ,iBAAiB;AAC5C,SAASC,gBAAgB,EAAEC,kBAAkB,QAAQ,eAAe;AAEpE,OAAO,MAAMC,oBAAoBH,WAAW;IAC1CI,cAAc;QACZ,CAAC,CAAC,GAAG,EAAEF,mBAAmB,CAAC,CAAC,CAAC,EAAE;YAC7BG,YAAY;QACd;IACF;IAEAC,kBAAkB;QAChB,CAAC,CAAC,GAAG,EAAEL,iBAAiB,CAAC,CAAC,CAAC,EAAE;YAC3BM,SAAS;QACX;IACF;AACF,GAAG"}

View File

@@ -0,0 +1,4 @@
export const DATA_OVERFLOWING = 'data-overflowing';
export const DATA_OVERFLOW_ITEM = 'data-overflow-item';
export const DATA_OVERFLOW_MENU = 'data-overflow-menu';
export const DATA_OVERFLOW_DIVIDER = 'data-overflow-divider';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/constants.ts"],"sourcesContent":["export const DATA_OVERFLOWING = 'data-overflowing';\nexport const DATA_OVERFLOW_ITEM = 'data-overflow-item';\nexport const DATA_OVERFLOW_MENU = 'data-overflow-menu';\nexport const DATA_OVERFLOW_DIVIDER = 'data-overflow-divider';\n"],"names":["DATA_OVERFLOWING","DATA_OVERFLOW_ITEM","DATA_OVERFLOW_MENU","DATA_OVERFLOW_DIVIDER"],"mappings":"AAAA,OAAO,MAAMA,mBAAmB,mBAAmB;AACnD,OAAO,MAAMC,qBAAqB,qBAAqB;AACvD,OAAO,MAAMC,qBAAqB,qBAAqB;AACvD,OAAO,MAAMC,wBAAwB,wBAAwB"}

13
node_modules/@fluentui/react-overflow/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
export { Overflow } from './components/Overflow';
export { DATA_OVERFLOWING, DATA_OVERFLOW_ITEM, DATA_OVERFLOW_MENU, DATA_OVERFLOW_DIVIDER } from './constants';
export { useIsOverflowGroupVisible } from './useIsOverflowGroupVisible';
export { useIsOverflowItemVisible } from './useIsOverflowItemVisible';
export { useOverflowContainer } from './useOverflowContainer';
export { useOverflowCount } from './useOverflowCount';
export { useOverflowItem } from './useOverflowItem';
export { useOverflowMenu } from './useOverflowMenu';
export { useOverflowDivider } from './useOverflowDivider';
export { useOverflowVisibility } from './useOverflowVisibility';
export { useOverflowContext } from './overflowContext';
export { OverflowItem } from './components/OverflowItem/OverflowItem';
export { OverflowDivider } from './components/OverflowDivider/OverflowDivider';

View File

@@ -0,0 +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"}

View File

@@ -0,0 +1,15 @@
'use client';
import { createContext, useContextSelector } from '@fluentui/react-context-selector';
export const OverflowContext = createContext(undefined);
const overflowContextDefaultValue = {
itemVisibility: {},
groupVisibility: {},
hasOverflow: false,
registerItem: ()=>()=>null,
updateOverflow: ()=>null,
registerOverflowMenu: ()=>()=>null,
registerDivider: ()=>()=>null
};
/**
* @internal
*/ export const useOverflowContext = (selector)=>useContextSelector(OverflowContext, (ctx = overflowContextDefaultValue)=>selector(ctx));

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/overflowContext.ts"],"sourcesContent":["'use client';\n\nimport type { OverflowGroupState, OverflowItemEntry, OverflowDividerEntry } from '@fluentui/priority-overflow';\nimport { ContextSelector, createContext, useContextSelector, Context } 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;AAGA,SAA0BA,aAAa,EAAEC,kBAAkB,QAAiB,mCAAmC;AAe/G,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
node_modules/@fluentui/react-overflow/lib/types.js generated vendored Normal file
View File

@@ -0,0 +1 @@
import * as React from 'react';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import * as React from 'react';\nimport { OverflowContextValue } from './overflowContext';\n\n/**\n * @internal\n */\nexport interface UseOverflowContainerReturn<TElement extends HTMLElement>\n extends Pick<OverflowContextValue, 'registerItem' | 'updateOverflow' | 'registerOverflowMenu' | 'registerDivider'> {\n /**\n * Ref to apply to the container that will overflow\n */\n containerRef: React.RefObject<TElement | null>;\n}\n"],"names":["React"],"mappings":"AAAA,YAAYA,WAAW,QAAQ"}

View File

@@ -0,0 +1,8 @@
'use client';
import { useOverflowContext } from './overflowContext';
/**
* @param id - unique identifier for a group of overflow items
* @returns visibility state of the group
*/ export function useIsOverflowGroupVisible(id) {
return useOverflowContext((ctx)=>ctx.groupVisibility[id]);
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/useIsOverflowGroupVisible.ts"],"sourcesContent":["'use client';\n\nimport { OverflowGroupState } from '@fluentui/priority-overflow';\nimport { useOverflowContext } from './overflowContext';\n\n/**\n * @param id - unique identifier for a group of overflow items\n * @returns visibility state of the group\n */\nexport function useIsOverflowGroupVisible(id: string): OverflowGroupState {\n return useOverflowContext(ctx => ctx.groupVisibility[id]);\n}\n"],"names":["useOverflowContext","useIsOverflowGroupVisible","id","ctx","groupVisibility"],"mappings":"AAAA;AAGA,SAASA,kBAAkB,QAAQ,oBAAoB;AAEvD;;;CAGC,GACD,OAAO,SAASC,0BAA0BC,EAAU;IAClD,OAAOF,mBAAmBG,CAAAA,MAAOA,IAAIC,eAAe,CAACF,GAAG;AAC1D"}

View File

@@ -0,0 +1,8 @@
'use client';
import { useOverflowContext } from './overflowContext';
/**
* @param id - unique identifier for the item used by the overflow manager
* @returns visibility state of an overflow item
*/ export function useIsOverflowItemVisible(id) {
return !!useOverflowContext((ctx)=>ctx.itemVisibility[id]);
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/useIsOverflowItemVisible.ts"],"sourcesContent":["'use client';\n\nimport { useOverflowContext } from './overflowContext';\n\n/**\n * @param id - unique identifier for the item used by the overflow manager\n * @returns visibility state of an overflow item\n */\nexport function useIsOverflowItemVisible(id: string): boolean {\n return !!useOverflowContext(ctx => ctx.itemVisibility[id]);\n}\n"],"names":["useOverflowContext","useIsOverflowItemVisible","id","ctx","itemVisibility"],"mappings":"AAAA;AAEA,SAASA,kBAAkB,QAAQ,oBAAoB;AAEvD;;;CAGC,GACD,OAAO,SAASC,yBAAyBC,EAAU;IACjD,OAAO,CAAC,CAACF,mBAAmBG,CAAAA,MAAOA,IAAIC,cAAc,CAACF,GAAG;AAC3D"}

View File

@@ -0,0 +1,115 @@
'use client';
import * as React from 'react';
import { createOverflowManager } from '@fluentui/priority-overflow';
import { canUseDOM, useEventCallback, useFirstMount, useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
import { DATA_OVERFLOWING, DATA_OVERFLOW_DIVIDER, DATA_OVERFLOW_ITEM, DATA_OVERFLOW_MENU } from './constants';
const noop = ()=>null;
/**
* @internal
* @param update - Callback when overflow state changes
* @param options - Options to configure the overflow container
* @returns - ref to attach to an intrinsic HTML element and imperative functions
*/ export const useOverflowContainer = (update, options)=>{
'use no memo';
const { overflowAxis = 'horizontal', overflowDirection = 'end', padding = 10, minimumVisible = 0, onUpdateItemVisibility = noop, hasHiddenItems = false } = options;
const onUpdateOverflow = useEventCallback(update);
const overflowOptions = React.useMemo(()=>({
overflowAxis,
overflowDirection,
padding,
minimumVisible,
onUpdateItemVisibility,
onUpdateOverflow,
hasHiddenItems
}), [
minimumVisible,
onUpdateItemVisibility,
overflowAxis,
overflowDirection,
padding,
onUpdateOverflow,
hasHiddenItems
]);
const firstMount = useFirstMount();
// DOM ref to the overflow container element
const containerRef = React.useRef(null);
const [overflowManager, setOverflowManager] = React.useState(()=>canUseDOM() ? createOverflowManager() : null);
// On first mount there is no need to create an overflow manager and re-render
useIsomorphicLayoutEffect(()=>{
if (firstMount && containerRef.current) {
overflowManager === null || overflowManager === void 0 ? void 0 : overflowManager.observe(containerRef.current, overflowOptions);
}
}, [
firstMount,
overflowManager,
overflowOptions
]);
useIsomorphicLayoutEffect(()=>{
if (!containerRef.current || !canUseDOM() || firstMount) {
return;
}
const newOverflowManager = createOverflowManager();
newOverflowManager.observe(containerRef.current, overflowOptions);
setOverflowManager(newOverflowManager);
// We don't want to re-create the overflow manager when the first mount flag changes from true to false
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
overflowOptions
]);
/* Clean up overflow manager on unmount */ React.useEffect(()=>()=>{
overflowManager === null || overflowManager === void 0 ? void 0 : overflowManager.disconnect();
}, [
overflowManager
]);
const registerItem = React.useCallback((item)=>{
overflowManager === null || overflowManager === void 0 ? void 0 : overflowManager.addItem(item);
item.element.setAttribute(DATA_OVERFLOW_ITEM, '');
return ()=>{
item.element.removeAttribute(DATA_OVERFLOWING);
item.element.removeAttribute(DATA_OVERFLOW_ITEM);
overflowManager === null || overflowManager === void 0 ? void 0 : overflowManager.removeItem(item.id);
};
}, [
overflowManager
]);
const registerDivider = React.useCallback((divider)=>{
const el = divider.element;
overflowManager === null || overflowManager === void 0 ? void 0 : overflowManager.addDivider(divider);
el.setAttribute(DATA_OVERFLOW_DIVIDER, '');
return ()=>{
divider.groupId && (overflowManager === null || overflowManager === void 0 ? void 0 : overflowManager.removeDivider(divider.groupId));
el.removeAttribute(DATA_OVERFLOW_DIVIDER);
};
}, [
overflowManager
]);
const registerOverflowMenu = React.useCallback((el)=>{
overflowManager === null || overflowManager === void 0 ? void 0 : overflowManager.addOverflowMenu(el);
el.setAttribute(DATA_OVERFLOW_MENU, '');
return ()=>{
overflowManager === null || overflowManager === void 0 ? void 0 : overflowManager.removeOverflowMenu();
el.removeAttribute(DATA_OVERFLOW_MENU);
};
}, [
overflowManager
]);
const updateOverflow = React.useCallback(()=>{
overflowManager === null || overflowManager === void 0 ? void 0 : overflowManager.update();
}, [
overflowManager
]);
return {
registerItem,
registerDivider,
registerOverflowMenu,
updateOverflow,
containerRef
};
};
export const updateVisibilityAttribute = ({ item, visible })=>{
if (visible) {
item.element.removeAttribute(DATA_OVERFLOWING);
} else {
item.element.setAttribute(DATA_OVERFLOWING, '');
}
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
'use client';
import { useOverflowContext } from './overflowContext';
/**
* @returns Number of items that are overflowing
*/ export const useOverflowCount = ()=>useOverflowContext((v)=>{
return Object.entries(v.itemVisibility).reduce((acc, [id, visible])=>{
if (!visible) {
acc++;
}
return acc;
}, 0);
});

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/useOverflowCount.ts"],"sourcesContent":["'use client';\n\nimport { useOverflowContext } from './overflowContext';\n\n/**\n * @returns Number of items that are overflowing\n */\nexport const useOverflowCount = (): number =>\n useOverflowContext(v => {\n return Object.entries(v.itemVisibility).reduce((acc, [id, visible]) => {\n if (!visible) {\n acc++;\n }\n\n return acc;\n }, 0);\n });\n"],"names":["useOverflowContext","useOverflowCount","v","Object","entries","itemVisibility","reduce","acc","id","visible"],"mappings":"AAAA;AAEA,SAASA,kBAAkB,QAAQ,oBAAoB;AAEvD;;CAEC,GACD,OAAO,MAAMC,mBAAmB,IAC9BD,mBAAmBE,CAAAA;QACjB,OAAOC,OAAOC,OAAO,CAACF,EAAEG,cAAc,EAAEC,MAAM,CAAC,CAACC,KAAK,CAACC,IAAIC,QAAQ;YAChE,IAAI,CAACA,SAAS;gBACZF;YACF;YAEA,OAAOA;QACT,GAAG;IACL,GAAG"}

View File

@@ -0,0 +1,25 @@
'use client';
import * as React from 'react';
import { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
import { useOverflowContext } from './overflowContext';
/**
* @internal
* Registers an overflow item
* @param groupId - assigns the item to a group, group visibility can be watched
* @returns ref to assign to an intrinsic HTML element
*/ export function useOverflowDivider(groupId) {
const ref = React.useRef(null);
const registerDivider = useOverflowContext((v)=>v.registerDivider);
useIsomorphicLayoutEffect(()=>{
if (ref.current && groupId) {
return registerDivider({
element: ref.current,
groupId
});
}
}, [
registerDivider,
groupId
]);
return ref;
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/useOverflowDivider.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';\nimport { useOverflowContext } from './overflowContext';\n\n/**\n * @internal\n * Registers an overflow item\n * @param groupId - assigns the item to a group, group visibility can be watched\n * @returns ref to assign to an intrinsic HTML element\n */\nexport function useOverflowDivider<TElement extends HTMLElement>(groupId?: string): React.RefObject<TElement | null> {\n const ref = React.useRef<TElement | null>(null);\n const registerDivider = useOverflowContext(v => v.registerDivider);\n\n useIsomorphicLayoutEffect(() => {\n if (ref.current && groupId) {\n return registerDivider({\n element: ref.current,\n groupId,\n });\n }\n }, [registerDivider, groupId]);\n\n return ref;\n}\n"],"names":["React","useIsomorphicLayoutEffect","useOverflowContext","useOverflowDivider","groupId","ref","useRef","registerDivider","v","current","element"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,yBAAyB,QAAQ,4BAA4B;AACtE,SAASC,kBAAkB,QAAQ,oBAAoB;AAEvD;;;;;CAKC,GACD,OAAO,SAASC,mBAAiDC,OAAgB;IAC/E,MAAMC,MAAML,MAAMM,MAAM,CAAkB;IAC1C,MAAMC,kBAAkBL,mBAAmBM,CAAAA,IAAKA,EAAED,eAAe;IAEjEN,0BAA0B;QACxB,IAAII,IAAII,OAAO,IAAIL,SAAS;YAC1B,OAAOG,gBAAgB;gBACrBG,SAASL,IAAII,OAAO;gBACpBL;YACF;QACF;IACF,GAAG;QAACG;QAAiBH;KAAQ;IAE7B,OAAOC;AACT"}

View File

@@ -0,0 +1,40 @@
'use client';
import * as React from 'react';
import { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
import { useOverflowContext } from './overflowContext';
/**
* @internal
* Registers an overflow item
* @param id - unique identifier for the item used by the overflow manager
* @param priority - higher priority means the item overflows later
* @param groupId - assigns the item to a group, group visibility can be watched
* @param pinned - if true, the item will never overflow and will always be visible
* @returns ref to assign to an intrinsic HTML element
*/ export function useOverflowItem(id, priority, groupId, pinned) {
const ref = React.useRef(null);
const registerItem = useOverflowContext((v)=>v.registerItem);
useIsomorphicLayoutEffect(()=>{
if (process.env.NODE_ENV !== 'production') {
if (typeof pinned !== 'undefined' && typeof priority !== 'undefined' && pinned) {
// eslint-disable-next-line no-console
console.error(`useOverflowItem: Overflow item with id "${id}" has pinned=true and priority<0. ` + `Pinned items are always visible and should not have defined priority.`);
}
}
if (ref.current) {
return registerItem({
element: ref.current,
id,
priority: priority !== null && priority !== void 0 ? priority : 0,
groupId,
pinned
});
}
}, [
id,
priority,
registerItem,
groupId,
pinned
]);
return ref;
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/useOverflowItem.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';\nimport { useOverflowContext } from './overflowContext';\n\n/**\n * @internal\n * Registers an overflow item\n * @param id - unique identifier for the item used by the overflow manager\n * @param priority - higher priority means the item overflows later\n * @param groupId - assigns the item to a group, group visibility can be watched\n * @param pinned - if true, the item will never overflow and will always be visible\n * @returns ref to assign to an intrinsic HTML element\n */\nexport function useOverflowItem<TElement extends HTMLElement>(\n id: string,\n priority?: number,\n groupId?: string,\n pinned?: boolean,\n): React.RefObject<TElement | null> {\n const ref = React.useRef<TElement | null>(null);\n const registerItem = useOverflowContext(v => v.registerItem);\n\n useIsomorphicLayoutEffect(() => {\n if (process.env.NODE_ENV !== 'production') {\n if (typeof pinned !== 'undefined' && typeof priority !== 'undefined' && pinned) {\n // eslint-disable-next-line no-console\n console.error(\n `useOverflowItem: Overflow item with id \"${id}\" has pinned=true and priority<0. ` +\n `Pinned items are always visible and should not have defined priority.`,\n );\n }\n }\n\n if (ref.current) {\n return registerItem({\n element: ref.current,\n id,\n priority: priority ?? 0,\n groupId,\n pinned,\n });\n }\n }, [id, priority, registerItem, groupId, pinned]);\n\n return ref;\n}\n"],"names":["React","useIsomorphicLayoutEffect","useOverflowContext","useOverflowItem","id","priority","groupId","pinned","ref","useRef","registerItem","v","process","env","NODE_ENV","console","error","current","element"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,yBAAyB,QAAQ,4BAA4B;AACtE,SAASC,kBAAkB,QAAQ,oBAAoB;AAEvD;;;;;;;;CAQC,GACD,OAAO,SAASC,gBACdC,EAAU,EACVC,QAAiB,EACjBC,OAAgB,EAChBC,MAAgB;IAEhB,MAAMC,MAAMR,MAAMS,MAAM,CAAkB;IAC1C,MAAMC,eAAeR,mBAAmBS,CAAAA,IAAKA,EAAED,YAAY;IAE3DT,0BAA0B;QACxB,IAAIW,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,IAAI,OAAOP,WAAW,eAAe,OAAOF,aAAa,eAAeE,QAAQ;gBAC9E,sCAAsC;gBACtCQ,QAAQC,KAAK,CACX,CAAC,wCAAwC,EAAEZ,GAAG,kCAAkC,CAAC,GAC/E,CAAC,qEAAqE,CAAC;YAE7E;QACF;QAEA,IAAII,IAAIS,OAAO,EAAE;YACf,OAAOP,aAAa;gBAClBQ,SAASV,IAAIS,OAAO;gBACpBb;gBACAC,UAAUA,qBAAAA,sBAAAA,WAAY;gBACtBC;gBACAC;YACF;QACF;IACF,GAAG;QAACH;QAAIC;QAAUK;QAAcJ;QAASC;KAAO;IAEhD,OAAOC;AACT"}

View File

@@ -0,0 +1,36 @@
'use client';
import * as React from 'react';
import { useId, useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
import { useOverflowContext } from './overflowContext';
import { useOverflowCount } from './useOverflowCount';
export function useOverflowMenu(id) {
const elementId = useId('overflow-menu', id);
const overflowCount = useOverflowCount();
const registerOverflowMenu = useOverflowContext((v)=>v.registerOverflowMenu);
const updateOverflow = useOverflowContext((v)=>v.updateOverflow);
const ref = React.useRef(null);
const isOverflowing = overflowCount > 0;
useIsomorphicLayoutEffect(()=>{
if (ref.current) {
return registerOverflowMenu(ref.current);
}
}, [
registerOverflowMenu,
isOverflowing,
elementId
]);
useIsomorphicLayoutEffect(()=>{
if (isOverflowing) {
updateOverflow();
}
}, [
isOverflowing,
updateOverflow,
ref
]);
return {
ref,
overflowCount,
isOverflowing
};
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/useOverflowMenu.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useId, useIsomorphicLayoutEffect } from '@fluentui/react-utilities';\nimport { useOverflowContext } from './overflowContext';\nimport { useOverflowCount } from './useOverflowCount';\n\nexport function useOverflowMenu<TElement extends HTMLElement>(\n id?: string,\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n): { ref: React.MutableRefObject<TElement | null>; overflowCount: number; isOverflowing: boolean } {\n const elementId = useId('overflow-menu', id);\n const overflowCount = useOverflowCount();\n const registerOverflowMenu = useOverflowContext(v => v.registerOverflowMenu);\n const updateOverflow = useOverflowContext(v => v.updateOverflow);\n const ref = React.useRef<TElement | null>(null);\n const isOverflowing = overflowCount > 0;\n\n useIsomorphicLayoutEffect(() => {\n if (ref.current) {\n return registerOverflowMenu(ref.current);\n }\n }, [registerOverflowMenu, isOverflowing, elementId]);\n\n useIsomorphicLayoutEffect(() => {\n if (isOverflowing) {\n updateOverflow();\n }\n }, [isOverflowing, updateOverflow, ref]);\n\n return { ref, overflowCount, isOverflowing };\n}\n"],"names":["React","useId","useIsomorphicLayoutEffect","useOverflowContext","useOverflowCount","useOverflowMenu","id","elementId","overflowCount","registerOverflowMenu","v","updateOverflow","ref","useRef","isOverflowing","current"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,KAAK,EAAEC,yBAAyB,QAAQ,4BAA4B;AAC7E,SAASC,kBAAkB,QAAQ,oBAAoB;AACvD,SAASC,gBAAgB,QAAQ,qBAAqB;AAEtD,OAAO,SAASC,gBACdC,EAAW;IAGX,MAAMC,YAAYN,MAAM,iBAAiBK;IACzC,MAAME,gBAAgBJ;IACtB,MAAMK,uBAAuBN,mBAAmBO,CAAAA,IAAKA,EAAED,oBAAoB;IAC3E,MAAME,iBAAiBR,mBAAmBO,CAAAA,IAAKA,EAAEC,cAAc;IAC/D,MAAMC,MAAMZ,MAAMa,MAAM,CAAkB;IAC1C,MAAMC,gBAAgBN,gBAAgB;IAEtCN,0BAA0B;QACxB,IAAIU,IAAIG,OAAO,EAAE;YACf,OAAON,qBAAqBG,IAAIG,OAAO;QACzC;IACF,GAAG;QAACN;QAAsBK;QAAeP;KAAU;IAEnDL,0BAA0B;QACxB,IAAIY,eAAe;YACjBH;QACF;IACF,GAAG;QAACG;QAAeH;QAAgBC;KAAI;IAEvC,OAAO;QAAEA;QAAKJ;QAAeM;IAAc;AAC7C"}

View File

@@ -0,0 +1,22 @@
'use client';
import * as React from 'react';
import { useOverflowContext } from './overflowContext';
/**
* A hook that returns the visibility status of all items and groups.
*
* ⚠️ Heads up!
*
* This hook will cause the component it is in to re-render for every single time an item overflows or becomes
* visible - use with caution
* @returns visibility status of all items and groups
*/ export function useOverflowVisibility() {
const itemVisibility = useOverflowContext((ctx)=>ctx.itemVisibility);
const groupVisibility = useOverflowContext((ctx)=>ctx.groupVisibility);
return React.useMemo(()=>({
itemVisibility,
groupVisibility
}), [
itemVisibility,
groupVisibility
]);
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/useOverflowVisibility.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useOverflowContext } from './overflowContext';\n\n/**\n * A hook that returns the visibility status of all items and groups.\n *\n * ⚠️ Heads up!\n *\n * This hook will cause the component it is in to re-render for every single time an item overflows or becomes\n * visible - use with caution\n * @returns visibility status of all items and groups\n */\nexport function useOverflowVisibility(): {\n itemVisibility: Record<string, boolean>;\n groupVisibility: Record<string, import('@fluentui/priority-overflow').OverflowGroupState>;\n} {\n const itemVisibility = useOverflowContext(ctx => ctx.itemVisibility);\n const groupVisibility = useOverflowContext(ctx => ctx.groupVisibility);\n\n return React.useMemo(() => ({ itemVisibility, groupVisibility }), [itemVisibility, groupVisibility]);\n}\n"],"names":["React","useOverflowContext","useOverflowVisibility","itemVisibility","ctx","groupVisibility","useMemo"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,kBAAkB,QAAQ,oBAAoB;AAEvD;;;;;;;;CAQC,GACD,OAAO,SAASC;IAId,MAAMC,iBAAiBF,mBAAmBG,CAAAA,MAAOA,IAAID,cAAc;IACnE,MAAME,kBAAkBJ,mBAAmBG,CAAAA,MAAOA,IAAIC,eAAe;IAErE,OAAOL,MAAMM,OAAO,CAAC,IAAO,CAAA;YAAEH;YAAgBE;QAAgB,CAAA,GAAI;QAACF;QAAgBE;KAAgB;AACrG"}