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,16 @@
'use client';
import * as React from 'react';
import { renderAvatarGroupItem_unstable } from './renderAvatarGroupItem';
import { useAvatarGroupItem_unstable } from './useAvatarGroupItem';
import { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';
import { useAvatarGroupItemStyles_unstable } from './useAvatarGroupItemStyles.styles';
/**
* The AvatarGroupItem component represents a single person or entity.
* AvatarGroupItem should only be used in an AvatarGroup component.
*/ export const AvatarGroupItem = /*#__PURE__*/ React.forwardRef((props, ref)=>{
const state = useAvatarGroupItem_unstable(props, ref);
useAvatarGroupItemStyles_unstable(state);
useCustomStyleHook_unstable('useAvatarGroupItemStyles_unstable')(state);
return renderAvatarGroupItem_unstable(state);
});
AvatarGroupItem.displayName = 'AvatarGroupItem';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/AvatarGroupItem/AvatarGroupItem.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { renderAvatarGroupItem_unstable } from './renderAvatarGroupItem';\nimport { useAvatarGroupItem_unstable } from './useAvatarGroupItem';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\nimport { useAvatarGroupItemStyles_unstable } from './useAvatarGroupItemStyles.styles';\nimport type { AvatarGroupItemProps } from './AvatarGroupItem.types';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\n\n/**\n * The AvatarGroupItem component represents a single person or entity.\n * AvatarGroupItem should only be used in an AvatarGroup component.\n */\nexport const AvatarGroupItem: ForwardRefComponent<AvatarGroupItemProps> = React.forwardRef((props, ref) => {\n const state = useAvatarGroupItem_unstable(props, ref);\n\n useAvatarGroupItemStyles_unstable(state);\n\n useCustomStyleHook_unstable('useAvatarGroupItemStyles_unstable')(state);\n\n return renderAvatarGroupItem_unstable(state);\n});\n\nAvatarGroupItem.displayName = 'AvatarGroupItem';\n"],"names":["React","renderAvatarGroupItem_unstable","useAvatarGroupItem_unstable","useCustomStyleHook_unstable","useAvatarGroupItemStyles_unstable","AvatarGroupItem","forwardRef","props","ref","state","displayName"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,8BAA8B,QAAQ,0BAA0B;AACzE,SAASC,2BAA2B,QAAQ,uBAAuB;AACnE,SAASC,2BAA2B,QAAQ,kCAAkC;AAC9E,SAASC,iCAAiC,QAAQ,oCAAoC;AAItF;;;CAGC,GACD,OAAO,MAAMC,gCAA6DL,MAAMM,UAAU,CAAC,CAACC,OAAOC;IACjG,MAAMC,QAAQP,4BAA4BK,OAAOC;IAEjDJ,kCAAkCK;IAElCN,4BAA4B,qCAAqCM;IAEjE,OAAOR,+BAA+BQ;AACxC,GAAG;AAEHJ,gBAAgBK,WAAW,GAAG"}

View File

@@ -0,0 +1 @@
export { };

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/AvatarGroupItem/AvatarGroupItem.types.ts"],"sourcesContent":["import { AvatarGroupProps } from '../AvatarGroup/AvatarGroup.types';\nimport type { Avatar, AvatarSize } from '../../Avatar';\nimport type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';\n\nexport type AvatarGroupItemSlots = {\n root: NonNullable<Slot<'div', 'li'>>;\n\n /**\n * Avatar that represents a person or entity.\n */\n avatar: NonNullable<Slot<typeof Avatar>>;\n\n /**\n * Label used for the name of the AvatarGroupItem when rendered as an overflow item.\n * The content of the label, by default, is the `name` prop from the `avatar` slot.\n */\n overflowLabel: NonNullable<Slot<'span'>>;\n};\n\n/**\n * AvatarGroupItem Props\n */\nexport type AvatarGroupItemProps = Omit<ComponentProps<Partial<AvatarGroupItemSlots>, 'avatar'>, 'size' | 'shape'>;\n\nexport type AvatarGroupItemBaseProps = AvatarGroupItemProps;\n\n/**\n * State used in rendering AvatarGroupItem\n */\nexport type AvatarGroupItemState = ComponentState<AvatarGroupItemSlots> & {\n /**\n * Whether the Avatar is an overflow item.\n *\n * @default false\n */\n isOverflowItem?: boolean;\n\n layout: AvatarGroupProps['layout'];\n size: AvatarSize;\n};\n\nexport type AvatarGroupItemBaseState = Omit<AvatarGroupItemState, 'size'>;\n"],"names":[],"mappings":"AAyCA,WAA0E"}

View File

@@ -0,0 +1,4 @@
export { AvatarGroupItem } from './AvatarGroupItem';
export { renderAvatarGroupItem_unstable } from './renderAvatarGroupItem';
export { useAvatarGroupItem_unstable, useAvatarGroupItemBase_unstable } from './useAvatarGroupItem';
export { avatarGroupItemClassNames, useAvatarGroupItemStyles_unstable, useGroupChildClassName } from './useAvatarGroupItemStyles.styles';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/AvatarGroupItem/index.ts"],"sourcesContent":["export { AvatarGroupItem } from './AvatarGroupItem';\nexport type {\n AvatarGroupItemProps,\n AvatarGroupItemSlots,\n AvatarGroupItemState,\n AvatarGroupItemBaseProps,\n AvatarGroupItemBaseState,\n} from './AvatarGroupItem.types';\nexport { renderAvatarGroupItem_unstable } from './renderAvatarGroupItem';\nexport { useAvatarGroupItem_unstable, useAvatarGroupItemBase_unstable } from './useAvatarGroupItem';\nexport {\n avatarGroupItemClassNames,\n useAvatarGroupItemStyles_unstable,\n useGroupChildClassName,\n} from './useAvatarGroupItemStyles.styles';\n"],"names":["AvatarGroupItem","renderAvatarGroupItem_unstable","useAvatarGroupItem_unstable","useAvatarGroupItemBase_unstable","avatarGroupItemClassNames","useAvatarGroupItemStyles_unstable","useGroupChildClassName"],"mappings":"AAAA,SAASA,eAAe,QAAQ,oBAAoB;AAQpD,SAASC,8BAA8B,QAAQ,0BAA0B;AACzE,SAASC,2BAA2B,EAAEC,+BAA+B,QAAQ,uBAAuB;AACpG,SACEC,yBAAyB,EACzBC,iCAAiC,EACjCC,sBAAsB,QACjB,oCAAoC"}

View File

@@ -0,0 +1,13 @@
import { jsx as _jsx, jsxs as _jsxs } from "@fluentui/react-jsx-runtime/jsx-runtime";
import { assertSlots } from '@fluentui/react-utilities';
/**
* Render the final JSX of AvatarGroupItem
*/ export const renderAvatarGroupItem_unstable = (state)=>{
assertSlots(state);
return /*#__PURE__*/ _jsxs(state.root, {
children: [
/*#__PURE__*/ _jsx(state.avatar, {}),
state.isOverflowItem && /*#__PURE__*/ _jsx(state.overflowLabel, {})
]
});
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/AvatarGroupItem/renderAvatarGroupItem.tsx"],"sourcesContent":["/** @jsxRuntime automatic */\n/** @jsxImportSource @fluentui/react-jsx-runtime */\n\nimport { assertSlots } from '@fluentui/react-utilities';\nimport type { JSXElement } from '@fluentui/react-utilities';\n\nimport type { AvatarGroupItemBaseState, AvatarGroupItemSlots } from './AvatarGroupItem.types';\n\n/**\n * Render the final JSX of AvatarGroupItem\n */\nexport const renderAvatarGroupItem_unstable = (state: AvatarGroupItemBaseState): JSXElement => {\n assertSlots<AvatarGroupItemSlots>(state);\n\n return (\n <state.root>\n <state.avatar />\n {state.isOverflowItem && <state.overflowLabel />}\n </state.root>\n );\n};\n"],"names":["assertSlots","renderAvatarGroupItem_unstable","state","root","avatar","isOverflowItem","overflowLabel"],"mappings":"AAAA,0BAA0B,GAC1B,iDAAiD;AAEjD,SAASA,WAAW,QAAQ,4BAA4B;AAKxD;;CAEC,GACD,OAAO,MAAMC,iCAAiC,CAACC;IAC7CF,YAAkCE;IAElC,qBACE,MAACA,MAAMC,IAAI;;0BACT,KAACD,MAAME,MAAM;YACZF,MAAMG,cAAc,kBAAI,KAACH,MAAMI,aAAa;;;AAGnD,EAAE"}

View File

@@ -0,0 +1,88 @@
'use client';
import * as React from 'react';
import { Avatar } from '../Avatar/Avatar';
import { AvatarGroupContext, useAvatarGroupContext_unstable } from '../../contexts/AvatarGroupContext';
import { defaultAvatarGroupSize } from '../AvatarGroup/useAvatarGroup';
import { slot } from '@fluentui/react-utilities';
import { useHasParentContext } from '@fluentui/react-context-selector';
/**
* Create the state required to render AvatarGroupItem.
*
* The returned state can be modified with hooks such as useAvatarGroupItemStyles_unstable,
* before being passed to renderAvatarGroupItem_unstable.
*
* @param props - props from this instance of AvatarGroupItem
* @param ref - reference to root HTMLElement of AvatarGroupItem
*/ export const useAvatarGroupItem_unstable = (props, ref)=>{
const state = useAvatarGroupItemBase_unstable(props, ref);
const groupSize = useAvatarGroupContext_unstable((ctx)=>ctx.size);
const size = groupSize !== null && groupSize !== void 0 ? groupSize : defaultAvatarGroupSize;
return {
size,
...state,
components: {
// eslint-disable-next-line @typescript-eslint/no-deprecated
...state.components,
avatar: Avatar
},
avatar: slot.always(props.avatar, {
defaultProps: {
size,
color: 'colorful',
...state.avatar
},
elementType: Avatar
})
};
};
/**
* Create the base state required to render AvatarGroupItem, without default slot props or component types.
*
* The returned state can be modified with hooks such as useAvatarGroupItemStyles_unstable,
* before being passed to renderAvatarGroupItem_unstable.
*
* @param props - props from this instance of AvatarGroupItem
* @param ref - reference to root HTMLElement of AvatarGroupItem
* @returns AvatarGroupItem state without default slot props or component types
*/ export const useAvatarGroupItemBase_unstable = (props, ref)=>{
const groupIsOverflow = useAvatarGroupContext_unstable((ctx)=>ctx.isOverflow);
const layout = useAvatarGroupContext_unstable((ctx)=>ctx.layout);
// Since the primary slot is not an intrinsic element, getPartitionedNativeProps cannot be used here.
const { style, className, overflowLabel, ...avatarSlotProps } = props;
const hasAvatarGroupContext = useHasParentContext(AvatarGroupContext);
if (process.env.NODE_ENV !== 'production' && !hasAvatarGroupContext) {
// eslint-disable-next-line no-console
console.warn('AvatarGroupItem must only be used inside an AvatarGroup component.');
}
return {
isOverflowItem: groupIsOverflow,
layout,
components: {
root: groupIsOverflow ? 'li' : 'div',
avatar: 'span',
overflowLabel: 'span'
},
root: slot.always(props.root, {
defaultProps: {
style,
className
},
elementType: groupIsOverflow ? 'li' : 'div'
}),
avatar: slot.always(props.avatar, {
defaultProps: {
ref,
...avatarSlotProps
},
elementType: 'span'
}),
overflowLabel: slot.always(overflowLabel, {
defaultProps: {
// Avatar already has its aria-label set to the name, this will prevent the name to be read twice.
'aria-hidden': true,
children: props.name
},
elementType: 'span'
})
};
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,261 @@
'use client';
import { __styles, mergeClasses } from '@griffel/react';
import { tokens, typographyStyles } from '@fluentui/react-theme';
import { useSizeStyles } from '../../Avatar';
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
export const avatarGroupItemClassNames = {
root: 'fui-AvatarGroupItem',
avatar: 'fui-AvatarGroupItem__avatar',
overflowLabel: 'fui-AvatarGroupItem__overflowLabel'
};
const avatarGroupItemDividerWidthVar = '--fuiAvatarGroupItem__divider--width';
/**
* Styles for the root slot
*/
const useRootStyles = /*#__PURE__*/__styles({
base: {
Bt984gj: "f122n59",
mc9l5x: "ftuwxu6",
Bnnss6s: "fi64zpg",
qhf8xq: "f10pi13n"
},
overflowItem: {
Byoj8tv: 0,
uwmqm3: 0,
z189sj: 0,
z8tnut: 0,
B0ocmuz: "f16d74zd"
},
nonOverflowItem: {
Beyfa6y: 0,
Bbmb7ep: 0,
Btl43ni: 0,
B7oj6ja: 0,
Dimara: "f44lkw9"
}
}, {
d: [".f122n59{align-items:center;}", ".ftuwxu6{display:inline-flex;}", ".fi64zpg{flex-shrink:0;}", ".f10pi13n{position:relative;}", [".f16d74zd{padding:var(--spacingVerticalXS) var(--spacingHorizontalXS);}", {
p: -1
}], [".f44lkw9{border-radius:var(--borderRadiusCircular);}", {
p: -1
}]]
});
/**
* Styles for the avatar slot
*/
const useAvatarStyles = /*#__PURE__*/__styles({
nonOverflowItem: {
qhf8xq: "f1euv43f"
},
pie: {
Beyfa6y: 0,
Bbmb7ep: 0,
Btl43ni: 0,
B7oj6ja: 0,
Dimara: "fokr779"
}
}, {
d: [".f1euv43f{position:absolute;}", [".fokr779{border-radius:0;}", {
p: -1
}]]
});
/**
* Styles for the label slot
*/
const useOverflowLabelStyles = /*#__PURE__*/__styles({
base: {
Frg6f3: ["foyynoy", "f1vcna3q"],
sj55zd: "f19n0e5",
Bahqtrf: "fk6fouc",
Be2twd7: "fkhj508",
Bhrd7zp: "figsok6",
Bg96gwp: "f1i3iumi"
}
}, {
d: [".foyynoy{margin-left:var(--spacingHorizontalS);}", ".f1vcna3q{margin-right:var(--spacingHorizontalS);}", ".f19n0e5{color:var(--colorNeutralForeground1);}", ".fk6fouc{font-family:var(--fontFamilyBase);}", ".fkhj508{font-size:var(--fontSizeBase300);}", ".figsok6{font-weight:var(--fontWeightRegular);}", ".f1i3iumi{line-height:var(--lineHeightBase300);}"]
});
/**
* Styles for the stack layout
*/
const useStackStyles = /*#__PURE__*/__styles({
thick: {
E5pizo: "foiuzp5"
},
thicker: {
E5pizo: "f1x6o7w7"
},
thickest: {
E5pizo: "f2aml1u"
},
xxs: {
jhia2w: ["f1cjco14", "f13dxjc9"]
},
xs: {
jhia2w: ["f15p6bln", "f1bab3ru"]
},
s: {
jhia2w: ["f1v53ncc", "f17pu8r8"]
},
l: {
jhia2w: ["flv48ch", "fnh1ydj"]
}
}, {
d: [".foiuzp5{box-shadow:0 0 0 var(--strokeWidthThick) var(--colorNeutralBackground2);}", ".f1x6o7w7{box-shadow:0 0 0 var(--strokeWidthThicker) var(--colorNeutralBackground2);}", ".f2aml1u{box-shadow:0 0 0 var(--strokeWidthThickest) var(--colorNeutralBackground2);}", ".f1cjco14:not(:first-child){margin-left:calc(-1 * var(--spacingHorizontalXXS));}", ".f13dxjc9:not(:first-child){margin-right:calc(-1 * var(--spacingHorizontalXXS));}", ".f15p6bln:not(:first-child){margin-left:calc(-1 * var(--spacingHorizontalXS));}", ".f1bab3ru:not(:first-child){margin-right:calc(-1 * var(--spacingHorizontalXS));}", ".f1v53ncc:not(:first-child){margin-left:calc(-1 * var(--spacingHorizontalS));}", ".f17pu8r8:not(:first-child){margin-right:calc(-1 * var(--spacingHorizontalS));}", ".flv48ch:not(:first-child){margin-left:calc(-1 * var(--spacingHorizontalL));}", ".fnh1ydj:not(:first-child){margin-right:calc(-1 * var(--spacingHorizontalL));}"]
});
/**
* Styles for the spread layout
*/
const useSpreadStyles = /*#__PURE__*/__styles({
s: {
jhia2w: ["f7lhxv7", "f6ou2b0"]
},
mNudge: {
jhia2w: ["f1h0okno", "fnnqava"]
},
m: {
jhia2w: ["f1wkt588", "f1maio5g"]
},
l: {
jhia2w: ["f1l333zn", "f1r41m4c"]
},
xl: {
jhia2w: ["fahr13a", "f2n7rbo"]
}
}, {
d: [".f7lhxv7:not(:first-child){margin-left:var(--spacingHorizontalS);}", ".f6ou2b0:not(:first-child){margin-right:var(--spacingHorizontalS);}", ".f1h0okno:not(:first-child){margin-left:var(--spacingHorizontalMNudge);}", ".fnnqava:not(:first-child){margin-right:var(--spacingHorizontalMNudge);}", ".f1wkt588:not(:first-child){margin-left:var(--spacingHorizontalM);}", ".f1maio5g:not(:first-child){margin-right:var(--spacingHorizontalM);}", ".f1l333zn:not(:first-child){margin-left:var(--spacingHorizontalL);}", ".f1r41m4c:not(:first-child){margin-right:var(--spacingHorizontalL);}", ".fahr13a:not(:first-child){margin-left:var(--spacingHorizontalXL);}", ".f2n7rbo:not(:first-child){margin-right:var(--spacingHorizontalXL);}"]
});
/**
* Styles for the pie layout
*/
const usePieStyles = /*#__PURE__*/__styles({
base: {
qhf8xq: "f1euv43f"
},
slices: {
B3gf25r: "f16m7w7k",
Be2twx7: ["f1o4hhgz", "fb4gjrz"],
Bvaow4n: "f1pgb5nx",
Gpecfs: ["fugirid", "f4sk99m"],
bhabj1: "fjreaf3",
B7rc6i7: ["f1k4vw81", "f1w1xcy7"],
Bwrfys5: "f1ef8vxk",
Bwuzm9m: ["f1x2qbfv", "f1xwf4nz"],
fflka: "ff6xuso",
do7bja: "fzpvk6c",
Be8zqhl: "f4onu7f",
Bij0kh0: ["f1ydfez1", "fjensob"],
Bwexnyt: "f1yv732j",
Bhe5x6o: "fchq2fj",
B3kv7bh: "ff5binh"
},
rtlSlices: {
B3gf25r: "f5vdl61",
Bvaow4n: "f1bnra92",
bhabj1: "f4ibo7t",
Bwrfys5: "f17heuis",
Bwuzm9m: ["f64f2ud", "f1yjglu3"],
Be8zqhl: "fa6l61x",
Bij0kh0: ["f1w2396a", "f14ab3yo"]
},
thick: {
uiicq7: "fnyfzln"
},
thicker: {
uiicq7: "f1xdzzot"
},
thickest: {
uiicq7: "f1auhru5"
}
}, {
d: [".f1euv43f{position:absolute;}", ".f16m7w7k:nth-of-type(1):nth-last-of-type(2){clip-path:inset(0 calc(25% + (var(--fuiAvatarGroupItem__divider--width) / 2)) 0 25%);}", ".f1o4hhgz:nth-of-type(1):nth-last-of-type(2){left:-25%;}", ".fb4gjrz:nth-of-type(1):nth-last-of-type(2){right:-25%;}", ".f1pgb5nx:nth-of-type(2):nth-last-of-type(1){clip-path:inset(0 25% 0 calc(25% + (var(--fuiAvatarGroupItem__divider--width) / 2)));}", ".fugirid:nth-of-type(2):nth-last-of-type(1){left:25%;}", ".f4sk99m:nth-of-type(2):nth-last-of-type(1){right:25%;}", ".fjreaf3:nth-of-type(1):nth-last-of-type(3){clip-path:inset(0 calc(25% + (var(--fuiAvatarGroupItem__divider--width) / 2)) 0 25%);}", ".f1k4vw81:nth-of-type(1):nth-last-of-type(3){left:-25%;}", ".f1w1xcy7:nth-of-type(1):nth-last-of-type(3){right:-25%;}", ".f1ef8vxk:nth-of-type(2):nth-last-of-type(2){clip-path:inset(0 0 var(--fuiAvatarGroupItem__divider--width) var(--fuiAvatarGroupItem__divider--width));}", ".f1x2qbfv:nth-of-type(2):nth-last-of-type(2){left:50%;}", ".f1xwf4nz:nth-of-type(2):nth-last-of-type(2){right:50%;}", ".ff6xuso:nth-of-type(2):nth-last-of-type(2){transform:scale(0.5);}", ".fzpvk6c:nth-of-type(2):nth-last-of-type(2){transform-origin:0 0;}", ".f4onu7f:nth-of-type(3):nth-last-of-type(1){clip-path:inset(var(--fuiAvatarGroupItem__divider--width) 0 0 var(--fuiAvatarGroupItem__divider--width));}", ".f1ydfez1:nth-of-type(3):nth-last-of-type(1){left:50%;}", ".fjensob:nth-of-type(3):nth-last-of-type(1){right:50%;}", ".f1yv732j:nth-of-type(3):nth-last-of-type(1){top:50%;}", ".fchq2fj:nth-of-type(3):nth-last-of-type(1){transform:scale(0.5);}", ".ff5binh:nth-of-type(3):nth-last-of-type(1){transform-origin:0 0;}", ".f5vdl61:nth-of-type(1):nth-last-of-type(2){clip-path:inset(0 25% 0 calc(25% + (var(--fuiAvatarGroupItem__divider--width) / 2)));}", ".f1bnra92:nth-of-type(2):nth-last-of-type(1){clip-path:inset(0 calc(25% + (var(--fuiAvatarGroupItem__divider--width) / 2)) 0 25%);}", ".f4ibo7t:nth-of-type(1):nth-last-of-type(3){clip-path:inset(0 25% 0 calc(25% + (var(--fuiAvatarGroupItem__divider--width) / 2)));}", ".f17heuis:nth-of-type(2):nth-last-of-type(2){clip-path:inset(0 var(--fuiAvatarGroupItem__divider--width) var(--fuiAvatarGroupItem__divider--width) 0);}", ".f64f2ud:nth-of-type(2):nth-last-of-type(2){left:0;}", ".f1yjglu3:nth-of-type(2):nth-last-of-type(2){right:0;}", ".fa6l61x:nth-of-type(3):nth-last-of-type(1){clip-path:inset(var(--fuiAvatarGroupItem__divider--width) var(--fuiAvatarGroupItem__divider--width) 0 0);}", ".f1w2396a:nth-of-type(3):nth-last-of-type(1){left:0;}", ".f14ab3yo:nth-of-type(3):nth-last-of-type(1){right:0;}", ".fnyfzln{--fuiAvatarGroupItem__divider--width:var(--strokeWidthThick);}", ".f1xdzzot{--fuiAvatarGroupItem__divider--width:var(--strokeWidthThicker);}", ".f1auhru5{--fuiAvatarGroupItem__divider--width:var(--strokeWidthThickest);}"]
});
/**
* Apply styling to the AvatarGroupItem slots based on the state
*/
export const useAvatarGroupItemStyles_unstable = state => {
'use no memo';
const {
isOverflowItem,
layout,
size
} = state;
const {
dir
} = useFluent();
const avatarStyles = useAvatarStyles();
const overflowLabelStyles = useOverflowLabelStyles();
const pieStyles = usePieStyles();
const rootStyles = useRootStyles();
const sizeStyles = useSizeStyles();
const groupChildClassName = useGroupChildClassName(layout, size);
const rootClasses = [rootStyles.base];
if (!isOverflowItem) {
rootClasses.push(rootStyles.nonOverflowItem);
rootClasses.push(groupChildClassName);
rootClasses.push(sizeStyles[size]);
if (layout === 'pie') {
rootClasses.push(pieStyles.base);
if (size < 56) {
rootClasses.push(pieStyles.thick);
} else if (size < 72) {
rootClasses.push(pieStyles.thicker);
} else {
rootClasses.push(pieStyles.thickest);
}
rootClasses.push(pieStyles.slices);
if (dir === 'rtl') {
rootClasses.push(pieStyles.rtlSlices);
}
}
} else {
rootClasses.push(rootStyles.overflowItem);
}
state.root.className = mergeClasses(avatarGroupItemClassNames.root, ...rootClasses, state.root.className);
state.avatar.className = mergeClasses(avatarGroupItemClassNames.avatar, !isOverflowItem && avatarStyles.nonOverflowItem, layout === 'pie' && avatarStyles.pie, state.avatar.className);
if (state.overflowLabel) {
state.overflowLabel.className = mergeClasses(avatarGroupItemClassNames.overflowLabel, overflowLabelStyles.base, state.overflowLabel.className);
}
return state;
};
/**
* Hook for getting the className for the children of AvatarGroup. This hook will provide the spacing and outlines
* needed for each layout.
*/
export const useGroupChildClassName = (layout, size) => {
const stackStyles = useStackStyles();
const spreadStyles = useSpreadStyles();
const layoutClasses = [];
if (size) {
if (layout === 'stack') {
if (size < 56) {
layoutClasses.push(stackStyles.thick);
} else if (size < 72) {
layoutClasses.push(stackStyles.thicker);
} else {
layoutClasses.push(stackStyles.thickest);
}
if (size < 24) {
layoutClasses.push(stackStyles.xxs);
} else if (size < 48) {
layoutClasses.push(stackStyles.xs);
} else if (size < 96) {
layoutClasses.push(stackStyles.s);
} else {
layoutClasses.push(stackStyles.l);
}
} else if (layout === 'spread') {
if (size < 20) {
layoutClasses.push(spreadStyles.s);
} else if (size < 32) {
layoutClasses.push(spreadStyles.mNudge);
} else if (size < 64) {
layoutClasses.push(spreadStyles.l);
} else {
layoutClasses.push(spreadStyles.xl);
}
}
}
return mergeClasses(...layoutClasses);
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,267 @@
'use client';
import { makeStyles, mergeClasses } from '@griffel/react';
import { tokens, typographyStyles } from '@fluentui/react-theme';
import { useSizeStyles } from '../../Avatar';
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
export const avatarGroupItemClassNames = {
root: 'fui-AvatarGroupItem',
avatar: 'fui-AvatarGroupItem__avatar',
overflowLabel: 'fui-AvatarGroupItem__overflowLabel'
};
const avatarGroupItemDividerWidthVar = '--fuiAvatarGroupItem__divider--width';
/**
* Styles for the root slot
*/ const useRootStyles = makeStyles({
base: {
alignItems: 'center',
display: 'inline-flex',
flexShrink: 0,
position: 'relative'
},
overflowItem: {
padding: `${tokens.spacingVerticalXS} ${tokens.spacingHorizontalXS}`
},
nonOverflowItem: {
borderRadius: tokens.borderRadiusCircular
}
});
/**
* Styles for the avatar slot
*/ const useAvatarStyles = makeStyles({
nonOverflowItem: {
position: 'absolute'
},
pie: {
borderRadius: '0'
}
});
/**
* Styles for the label slot
*/ const useOverflowLabelStyles = makeStyles({
base: {
marginLeft: tokens.spacingHorizontalS,
color: tokens.colorNeutralForeground1,
...typographyStyles.body1
}
});
/**
* Styles for the stack layout
*/ const useStackStyles = makeStyles({
thick: {
boxShadow: `0 0 0 ${tokens.strokeWidthThick} ${tokens.colorNeutralBackground2}`
},
thicker: {
boxShadow: `0 0 0 ${tokens.strokeWidthThicker} ${tokens.colorNeutralBackground2}`
},
thickest: {
boxShadow: `0 0 0 ${tokens.strokeWidthThickest} ${tokens.colorNeutralBackground2}`
},
xxs: {
'&:not(:first-child)': {
marginLeft: `calc(-1 * ${tokens.spacingHorizontalXXS})`
}
},
xs: {
'&:not(:first-child)': {
marginLeft: `calc(-1 * ${tokens.spacingHorizontalXS})`
}
},
s: {
'&:not(:first-child)': {
marginLeft: `calc(-1 * ${tokens.spacingHorizontalS})`
}
},
l: {
'&:not(:first-child)': {
marginLeft: `calc(-1 * ${tokens.spacingHorizontalL})`
}
}
});
/**
* Styles for the spread layout
*/ const useSpreadStyles = makeStyles({
s: {
'&:not(:first-child)': {
marginLeft: tokens.spacingHorizontalS
}
},
mNudge: {
'&:not(:first-child)': {
marginLeft: tokens.spacingHorizontalMNudge
}
},
m: {
'&:not(:first-child)': {
marginLeft: tokens.spacingHorizontalM
}
},
l: {
'&:not(:first-child)': {
marginLeft: tokens.spacingHorizontalL
}
},
xl: {
'&:not(:first-child)': {
marginLeft: tokens.spacingHorizontalXL
}
}
});
/**
* Styles for the pie layout
*/ const usePieStyles = makeStyles({
base: {
position: 'absolute'
},
slices: {
// Two slices
// 1st of 2 items
'&:nth-of-type(1):nth-last-of-type(2)': {
clipPath: `inset(0 calc(25% + (var(${avatarGroupItemDividerWidthVar}) / 2)) 0 25%)`,
left: '-25%'
},
// 2nd of 2 items
'&:nth-of-type(2):nth-last-of-type(1)': {
clipPath: `inset(0 25% 0 calc(25% + (var(${avatarGroupItemDividerWidthVar}) / 2)))`,
left: '25%'
},
// Three slices
// 1st of 3 items
'&:nth-of-type(1):nth-last-of-type(3)': {
clipPath: `inset(0 calc(25% + (var(${avatarGroupItemDividerWidthVar}) / 2)) 0 25%)`,
left: '-25%'
},
// 2nd of 3 items
'&:nth-of-type(2):nth-last-of-type(2)': {
// Since the two AvatarGroupItems on the right are scaled by 0.5, the divider width should not be halved.
clipPath: `inset(0 0 var(${avatarGroupItemDividerWidthVar}) var(${avatarGroupItemDividerWidthVar}))`,
left: '50%',
transform: 'scale(0.5)',
transformOrigin: '0 0'
},
// 3rd of 3 items
'&:nth-of-type(3):nth-last-of-type(1)': {
clipPath: `inset(var(${avatarGroupItemDividerWidthVar}) 0 0 var(${avatarGroupItemDividerWidthVar}))`,
left: '50%',
top: '50%',
transform: 'scale(0.5)',
transformOrigin: '0 0'
}
},
rtlSlices: {
// Two slices
// 1st of 2 items
'&:nth-of-type(1):nth-last-of-type(2)': {
clipPath: `inset(0 25% 0 calc(25% + (var(${avatarGroupItemDividerWidthVar}) / 2)))`
},
// 2nd of 2 items
'&:nth-of-type(2):nth-last-of-type(1)': {
clipPath: `inset(0 calc(25% + (var(${avatarGroupItemDividerWidthVar}) / 2)) 0 25%)`
},
// Three slices
// 1st of 3 items
'&:nth-of-type(1):nth-last-of-type(3)': {
clipPath: `inset(0 25% 0 calc(25% + (var(${avatarGroupItemDividerWidthVar}) / 2)))`
},
// 2nd of 3 items
'&:nth-of-type(2):nth-last-of-type(2)': {
clipPath: `inset(0 var(${avatarGroupItemDividerWidthVar}) var(${avatarGroupItemDividerWidthVar}) 0)`,
left: '0'
},
// 3rd of 3 items
'&:nth-of-type(3):nth-last-of-type(1)': {
clipPath: `inset(var(${avatarGroupItemDividerWidthVar}) var(${avatarGroupItemDividerWidthVar}) 0 0)`,
left: '0'
}
},
thick: {
[avatarGroupItemDividerWidthVar]: tokens.strokeWidthThick
},
thicker: {
[avatarGroupItemDividerWidthVar]: tokens.strokeWidthThicker
},
thickest: {
[avatarGroupItemDividerWidthVar]: tokens.strokeWidthThickest
}
});
/**
* Apply styling to the AvatarGroupItem slots based on the state
*/ export const useAvatarGroupItemStyles_unstable = (state)=>{
'use no memo';
const { isOverflowItem, layout, size } = state;
const { dir } = useFluent();
const avatarStyles = useAvatarStyles();
const overflowLabelStyles = useOverflowLabelStyles();
const pieStyles = usePieStyles();
const rootStyles = useRootStyles();
const sizeStyles = useSizeStyles();
const groupChildClassName = useGroupChildClassName(layout, size);
const rootClasses = [
rootStyles.base
];
if (!isOverflowItem) {
rootClasses.push(rootStyles.nonOverflowItem);
rootClasses.push(groupChildClassName);
rootClasses.push(sizeStyles[size]);
if (layout === 'pie') {
rootClasses.push(pieStyles.base);
if (size < 56) {
rootClasses.push(pieStyles.thick);
} else if (size < 72) {
rootClasses.push(pieStyles.thicker);
} else {
rootClasses.push(pieStyles.thickest);
}
rootClasses.push(pieStyles.slices);
if (dir === 'rtl') {
rootClasses.push(pieStyles.rtlSlices);
}
}
} else {
rootClasses.push(rootStyles.overflowItem);
}
state.root.className = mergeClasses(avatarGroupItemClassNames.root, ...rootClasses, state.root.className);
state.avatar.className = mergeClasses(avatarGroupItemClassNames.avatar, !isOverflowItem && avatarStyles.nonOverflowItem, layout === 'pie' && avatarStyles.pie, state.avatar.className);
if (state.overflowLabel) {
state.overflowLabel.className = mergeClasses(avatarGroupItemClassNames.overflowLabel, overflowLabelStyles.base, state.overflowLabel.className);
}
return state;
};
/**
* Hook for getting the className for the children of AvatarGroup. This hook will provide the spacing and outlines
* needed for each layout.
*/ export const useGroupChildClassName = (layout, size)=>{
const stackStyles = useStackStyles();
const spreadStyles = useSpreadStyles();
const layoutClasses = [];
if (size) {
if (layout === 'stack') {
if (size < 56) {
layoutClasses.push(stackStyles.thick);
} else if (size < 72) {
layoutClasses.push(stackStyles.thicker);
} else {
layoutClasses.push(stackStyles.thickest);
}
if (size < 24) {
layoutClasses.push(stackStyles.xxs);
} else if (size < 48) {
layoutClasses.push(stackStyles.xs);
} else if (size < 96) {
layoutClasses.push(stackStyles.s);
} else {
layoutClasses.push(stackStyles.l);
}
} else if (layout === 'spread') {
if (size < 20) {
layoutClasses.push(spreadStyles.s);
} else if (size < 32) {
layoutClasses.push(spreadStyles.mNudge);
} else if (size < 64) {
layoutClasses.push(spreadStyles.l);
} else {
layoutClasses.push(spreadStyles.xl);
}
}
}
return mergeClasses(...layoutClasses);
};

File diff suppressed because one or more lines are too long