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,17 @@
'use client';
import * as React from 'react';
import { renderSplitButton_unstable } from './renderSplitButton';
import { useSplitButton_unstable } from './useSplitButton';
import { useSplitButtonStyles_unstable } from './useSplitButtonStyles.styles';
import { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';
/**
* SplitButtons are a grouping of two interactive surfaces where interacting with the first one triggers a primary
* action, while interacting with the second one opens a menu with secondary actions.
*/ export const SplitButton = /*#__PURE__*/ React.forwardRef((props, ref)=>{
const state = useSplitButton_unstable(props, ref);
useSplitButtonStyles_unstable(state);
useCustomStyleHook_unstable('useSplitButtonStyles_unstable')(state);
return renderSplitButton_unstable(state);
// Casting is required due to lack of distributive union to support unions on @types/react
});
SplitButton.displayName = 'SplitButton';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/SplitButton/SplitButton.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { renderSplitButton_unstable } from './renderSplitButton';\nimport { useSplitButton_unstable } from './useSplitButton';\nimport { useSplitButtonStyles_unstable } from './useSplitButtonStyles.styles';\nimport type { SplitButtonProps } from './SplitButton.types';\nimport { ForwardRefComponent } from '@fluentui/react-utilities';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\n\n/**\n * SplitButtons are a grouping of two interactive surfaces where interacting with the first one triggers a primary\n * action, while interacting with the second one opens a menu with secondary actions.\n */\nexport const SplitButton: ForwardRefComponent<SplitButtonProps> = React.forwardRef((props, ref) => {\n const state = useSplitButton_unstable(props, ref);\n\n useSplitButtonStyles_unstable(state);\n\n useCustomStyleHook_unstable('useSplitButtonStyles_unstable')(state);\n\n return renderSplitButton_unstable(state);\n // Casting is required due to lack of distributive union to support unions on @types/react\n}) as ForwardRefComponent<SplitButtonProps>;\n\nSplitButton.displayName = 'SplitButton';\n"],"names":["React","renderSplitButton_unstable","useSplitButton_unstable","useSplitButtonStyles_unstable","useCustomStyleHook_unstable","SplitButton","forwardRef","props","ref","state","displayName"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,0BAA0B,QAAQ,sBAAsB;AACjE,SAASC,uBAAuB,QAAQ,mBAAmB;AAC3D,SAASC,6BAA6B,QAAQ,gCAAgC;AAG9E,SAASC,2BAA2B,QAAQ,kCAAkC;AAE9E;;;CAGC,GACD,OAAO,MAAMC,4BAAqDL,MAAMM,UAAU,CAAC,CAACC,OAAOC;IACzF,MAAMC,QAAQP,wBAAwBK,OAAOC;IAE7CL,8BAA8BM;IAE9BL,4BAA4B,iCAAiCK;IAE7D,OAAOR,2BAA2BQ;AAClC,0FAA0F;AAC5F,GAA4C;AAE5CJ,YAAYK,WAAW,GAAG"}

View File

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

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/SplitButton/SplitButton.types.ts"],"sourcesContent":["import { Button } from '../Button/Button';\nimport { MenuButton } from '../MenuButton/MenuButton';\nimport type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';\nimport type { ButtonProps, ButtonState } from '../Button/Button.types';\nimport type { MenuButtonProps, MenuButtonState } from '../MenuButton/MenuButton.types';\n\nexport type SplitButtonSlots = {\n /**\n * Root of the component that wraps the primary action button and menu button.\n */\n root: NonNullable<Slot<'div'>>;\n\n /**\n * Button that opens menu with secondary actions in SplitButton.\n */\n menuButton?: Slot<typeof MenuButton>;\n /**\n * Button to perform primary action in SplitButton.\n */\n primaryActionButton?: Slot<typeof Button>;\n};\n\nexport type SplitButtonProps = ComponentProps<SplitButtonSlots> &\n Omit<ButtonProps, 'root' | 'as'> &\n Omit<MenuButtonProps, 'root' | 'as'>;\n\nexport type SplitButtonState = ComponentState<SplitButtonSlots> &\n Omit<ButtonState, 'components' | 'iconOnly' | 'root'> &\n Omit<MenuButtonState, 'components' | 'iconOnly' | 'root'>;\n"],"names":[],"mappings":"AA0BA,WAE4D"}

View File

@@ -0,0 +1,4 @@
export { SplitButton } from './SplitButton';
export { renderSplitButton_unstable } from './renderSplitButton';
export { useSplitButton_unstable } from './useSplitButton';
export { splitButtonClassNames, useSplitButtonStyles_unstable } from './useSplitButtonStyles.styles';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/SplitButton/index.ts"],"sourcesContent":["export { SplitButton } from './SplitButton';\nexport type { SplitButtonProps, SplitButtonSlots, SplitButtonState } from './SplitButton.types';\nexport { renderSplitButton_unstable } from './renderSplitButton';\nexport { useSplitButton_unstable } from './useSplitButton';\nexport { splitButtonClassNames, useSplitButtonStyles_unstable } from './useSplitButtonStyles.styles';\n"],"names":["SplitButton","renderSplitButton_unstable","useSplitButton_unstable","splitButtonClassNames","useSplitButtonStyles_unstable"],"mappings":"AAAA,SAASA,WAAW,QAAQ,gBAAgB;AAE5C,SAASC,0BAA0B,QAAQ,sBAAsB;AACjE,SAASC,uBAAuB,QAAQ,mBAAmB;AAC3D,SAASC,qBAAqB,EAAEC,6BAA6B,QAAQ,gCAAgC"}

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';
/**
* Renders a SplitButton component by passing the state defined props to the appropriate slots.
*/ export const renderSplitButton_unstable = (state)=>{
assertSlots(state);
return /*#__PURE__*/ _jsxs(state.root, {
children: [
state.primaryActionButton && /*#__PURE__*/ _jsx(state.primaryActionButton, {}),
state.menuButton && /*#__PURE__*/ _jsx(state.menuButton, {})
]
});
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/SplitButton/renderSplitButton.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 { SplitButtonSlots, SplitButtonState } from './SplitButton.types';\n\n/**\n * Renders a SplitButton component by passing the state defined props to the appropriate slots.\n */\nexport const renderSplitButton_unstable = (state: SplitButtonState): JSXElement => {\n assertSlots<SplitButtonSlots>(state);\n\n return (\n <state.root>\n {state.primaryActionButton && <state.primaryActionButton />}\n {state.menuButton && <state.menuButton />}\n </state.root>\n );\n};\n"],"names":["assertSlots","renderSplitButton_unstable","state","root","primaryActionButton","menuButton"],"mappings":"AAAA,0BAA0B,GAC1B,iDAAiD;AAEjD,SAASA,WAAW,QAAQ,4BAA4B;AAKxD;;CAEC,GACD,OAAO,MAAMC,6BAA6B,CAACC;IACzCF,YAA8BE;IAE9B,qBACE,MAACA,MAAMC,IAAI;;YACRD,MAAME,mBAAmB,kBAAI,KAACF,MAAME,mBAAmB;YACvDF,MAAMG,UAAU,kBAAI,KAACH,MAAMG,UAAU;;;AAG5C,EAAE"}

View File

@@ -0,0 +1,66 @@
import * as React from 'react';
import { useId, slot } from '@fluentui/react-utilities';
import { Button } from '../Button/Button';
import { MenuButton } from '../MenuButton/MenuButton';
/**
* Given user props, defines default props for the SplitButton and returns processed state.
* @param props - User provided props to the SplitButton component.
* @param ref - User provided ref to be passed to the SplitButton component.
*/ export const useSplitButton_unstable = (props, ref)=>{
const { appearance = 'secondary', children, disabled = false, disabledFocusable = false, icon, iconPosition = 'before', menuButton, menuIcon, primaryActionButton, shape = 'rounded', size = 'medium', ...rest } = props;
const baseId = useId('splitButton-');
const menuButtonShorthand = slot.optional(menuButton, {
defaultProps: {
appearance,
disabled,
disabledFocusable,
menuIcon,
shape,
size
},
renderByDefault: true,
elementType: MenuButton
});
const primaryActionButtonShorthand = slot.optional(primaryActionButton, {
defaultProps: {
appearance,
children,
disabled,
disabledFocusable,
icon,
iconPosition,
id: baseId + '__primaryActionButton',
shape,
size
},
renderByDefault: true,
elementType: Button
});
// Resolve menu button's aria-labelledby to be labelled by the primary action button if no label was provided by the
// user.
if (menuButtonShorthand && primaryActionButtonShorthand && !menuButtonShorthand['aria-label'] && !menuButtonShorthand['aria-labelledby']) {
menuButtonShorthand['aria-labelledby'] = primaryActionButtonShorthand.id;
}
return {
// Props passed at the top-level
appearance,
disabled,
disabledFocusable,
iconPosition,
shape,
size,
components: {
root: 'div',
menuButton: MenuButton,
primaryActionButton: Button
},
root: slot.always({
ref: ref,
...rest
}, {
elementType: 'div'
}),
menuButton: menuButtonShorthand,
primaryActionButton: primaryActionButtonShorthand
};
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/SplitButton/useSplitButton.ts"],"sourcesContent":["import * as React from 'react';\nimport { useId, slot } from '@fluentui/react-utilities';\nimport { Button } from '../Button/Button';\nimport { MenuButton } from '../MenuButton/MenuButton';\nimport type { SplitButtonProps, SplitButtonState } from './SplitButton.types';\n\n/**\n * Given user props, defines default props for the SplitButton and returns processed state.\n * @param props - User provided props to the SplitButton component.\n * @param ref - User provided ref to be passed to the SplitButton component.\n */\nexport const useSplitButton_unstable = (\n props: SplitButtonProps,\n ref: React.Ref<HTMLButtonElement | HTMLAnchorElement>,\n): SplitButtonState => {\n const {\n appearance = 'secondary',\n children,\n disabled = false,\n disabledFocusable = false,\n icon,\n iconPosition = 'before',\n menuButton,\n menuIcon,\n primaryActionButton,\n shape = 'rounded',\n size = 'medium',\n ...rest\n } = props;\n const baseId = useId('splitButton-');\n\n const menuButtonShorthand = slot.optional(menuButton, {\n defaultProps: {\n appearance,\n disabled,\n disabledFocusable,\n menuIcon,\n shape,\n size,\n },\n renderByDefault: true,\n elementType: MenuButton,\n });\n const primaryActionButtonShorthand = slot.optional(primaryActionButton, {\n defaultProps: {\n appearance,\n children,\n disabled,\n disabledFocusable,\n icon,\n iconPosition,\n id: baseId + '__primaryActionButton',\n shape,\n size,\n },\n renderByDefault: true,\n elementType: Button,\n });\n\n // Resolve menu button's aria-labelledby to be labelled by the primary action button if no label was provided by the\n // user.\n if (\n menuButtonShorthand &&\n primaryActionButtonShorthand &&\n !menuButtonShorthand['aria-label'] &&\n !menuButtonShorthand['aria-labelledby']\n ) {\n menuButtonShorthand['aria-labelledby'] = primaryActionButtonShorthand.id;\n }\n\n return {\n // Props passed at the top-level\n appearance,\n disabled,\n disabledFocusable,\n iconPosition,\n shape,\n size, // Slots definition\n components: { root: 'div', menuButton: MenuButton, primaryActionButton: Button },\n root: slot.always({ ref: ref as React.Ref<HTMLDivElement>, ...rest }, { elementType: 'div' }),\n menuButton: menuButtonShorthand,\n primaryActionButton: primaryActionButtonShorthand,\n };\n};\n"],"names":["React","useId","slot","Button","MenuButton","useSplitButton_unstable","props","ref","appearance","children","disabled","disabledFocusable","icon","iconPosition","menuButton","menuIcon","primaryActionButton","shape","size","rest","baseId","menuButtonShorthand","optional","defaultProps","renderByDefault","elementType","primaryActionButtonShorthand","id","components","root","always"],"mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,KAAK,EAAEC,IAAI,QAAQ,4BAA4B;AACxD,SAASC,MAAM,QAAQ,mBAAmB;AAC1C,SAASC,UAAU,QAAQ,2BAA2B;AAGtD;;;;CAIC,GACD,OAAO,MAAMC,0BAA0B,CACrCC,OACAC;IAEA,MAAM,EACJC,aAAa,WAAW,EACxBC,QAAQ,EACRC,WAAW,KAAK,EAChBC,oBAAoB,KAAK,EACzBC,IAAI,EACJC,eAAe,QAAQ,EACvBC,UAAU,EACVC,QAAQ,EACRC,mBAAmB,EACnBC,QAAQ,SAAS,EACjBC,OAAO,QAAQ,EACf,GAAGC,MACJ,GAAGb;IACJ,MAAMc,SAASnB,MAAM;IAErB,MAAMoB,sBAAsBnB,KAAKoB,QAAQ,CAACR,YAAY;QACpDS,cAAc;YACZf;YACAE;YACAC;YACAI;YACAE;YACAC;QACF;QACAM,iBAAiB;QACjBC,aAAarB;IACf;IACA,MAAMsB,+BAA+BxB,KAAKoB,QAAQ,CAACN,qBAAqB;QACtEO,cAAc;YACZf;YACAC;YACAC;YACAC;YACAC;YACAC;YACAc,IAAIP,SAAS;YACbH;YACAC;QACF;QACAM,iBAAiB;QACjBC,aAAatB;IACf;IAEA,oHAAoH;IACpH,QAAQ;IACR,IACEkB,uBACAK,gCACA,CAACL,mBAAmB,CAAC,aAAa,IAClC,CAACA,mBAAmB,CAAC,kBAAkB,EACvC;QACAA,mBAAmB,CAAC,kBAAkB,GAAGK,6BAA6BC,EAAE;IAC1E;IAEA,OAAO;QACL,gCAAgC;QAChCnB;QACAE;QACAC;QACAE;QACAI;QACAC;QACAU,YAAY;YAAEC,MAAM;YAAOf,YAAYV;YAAYY,qBAAqBb;QAAO;QAC/E0B,MAAM3B,KAAK4B,MAAM,CAAC;YAAEvB,KAAKA;YAAkC,GAAGY,IAAI;QAAC,GAAG;YAAEM,aAAa;QAAM;QAC3FX,YAAYO;QACZL,qBAAqBU;IACvB;AACF,EAAE"}

View File

@@ -0,0 +1,108 @@
'use client';
import { __styles, mergeClasses } from '@griffel/react';
import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster';
import { tokens } from '@fluentui/react-theme';
export const splitButtonClassNames = {
root: 'fui-SplitButton',
menuButton: 'fui-SplitButton__menuButton',
primaryActionButton: 'fui-SplitButton__primaryActionButton'
};
// WCAG minimum target size for pointer targets that are immediately adjacent to other targets:
// https://w3c.github.io/wcag/guidelines/22/#target-size-minimum
const MIN_TARGET_SIZE = '24px';
const useFocusStyles = /*#__PURE__*/__styles({
primaryActionButton: {
B6xbmo0: ["f1x37qnr", "f1um7c6d"],
kdpuga: ["fn4c73s", "f6pwzcr"]
},
menuButton: {
lbo84a: ["frrbwxo", "f1rgcpbv"],
dm238s: ["f1um7c6d", "f1x37qnr"],
Bw81rd7: ["f6pwzcr", "fn4c73s"]
}
}, {
d: [".f1x37qnr[data-fui-focus-visible]{border-top-right-radius:0;}", ".f1um7c6d[data-fui-focus-visible]{border-top-left-radius:0;}", ".fn4c73s[data-fui-focus-visible]{border-bottom-right-radius:0;}", ".f6pwzcr[data-fui-focus-visible]{border-bottom-left-radius:0;}", ".frrbwxo[data-fui-focus-visible]{border-left-width:0;}", ".f1rgcpbv[data-fui-focus-visible]{border-right-width:0;}"]
});
const useRootStyles = /*#__PURE__*/__styles({
base: {
mc9l5x: "ftuwxu6",
Brf1p80: "fsxf2b5",
qhf8xq: "f10pi13n",
ha4doy: "fmrv4ls",
kn2xc0: ["f14uur2j", "fc1btbj"],
Bs76p8a: ["fye5tvs", "fc597qq"],
cuxpm9: ["f1e8brtx", "fr36rk3"],
Biffepf: ["fxp12j1", "f1m6nt2y"],
Defnvf: ["fr7y8no", "f1dn0c6m"],
z0pv9t: "f1b65x5h"
},
outline: {},
primary: {
B1l9wao: ["f4rm5b0", "f1tuwo13"],
lcnrd8: ["fdwdeeo", "f1ezdslh"],
vlshuh: ["f1ju2vgk", "f1r6p88l"],
B3s9tpx: ["f2z0mmn", "f12iqdwp"],
rfylfo: ["f1btorfl", "fxofj4p"],
k5lds2: ["f161sdhp", "f10m3pjc"]
},
secondary: {},
subtle: {
B1l9wao: ["f16kf41h", "fxiafvi"],
lcnrd8: ["ffl6mx9", "f1t5sw6t"],
vlshuh: ["f1mww3cx", "f1wtv0vd"]
},
transparent: {
B1l9wao: ["f16kf41h", "fxiafvi"],
lcnrd8: ["ffl6mx9", "f1t5sw6t"],
vlshuh: ["f1mww3cx", "f1wtv0vd"]
},
circular: {},
rounded: {},
square: {},
disabled: {
B1l9wao: ["f10xrnr8", "f15nylwb"],
lcnrd8: ["f11fwhjz", "f18vtcsx"],
vlshuh: ["f12kx9re", "f1hyxdqk"]
},
disabledHighContrast: {
B3s9tpx: ["fslo9ob", "ftovg2z"],
rfylfo: ["f1fuq5cn", "f168zpha"],
k5lds2: ["f1t6bo0o", "f1dnwhli"]
}
}, {
d: [".ftuwxu6{display:inline-flex;}", ".fsxf2b5{justify-content:stretch;}", ".f10pi13n{position:relative;}", ".fmrv4ls{vertical-align:middle;}", ".f14uur2j .fui-SplitButton__primaryActionButton{border-top-right-radius:0;}", ".fc1btbj .fui-SplitButton__primaryActionButton{border-top-left-radius:0;}", ".fye5tvs .fui-SplitButton__primaryActionButton{border-bottom-right-radius:0;}", ".fc597qq .fui-SplitButton__primaryActionButton{border-bottom-left-radius:0;}", ".f1e8brtx .fui-SplitButton__menuButton{border-left-width:0;}", ".fr36rk3 .fui-SplitButton__menuButton{border-right-width:0;}", ".fxp12j1 .fui-SplitButton__menuButton{border-top-left-radius:0;}", ".f1m6nt2y .fui-SplitButton__menuButton{border-top-right-radius:0;}", ".fr7y8no .fui-SplitButton__menuButton{border-bottom-left-radius:0;}", ".f1dn0c6m .fui-SplitButton__menuButton{border-bottom-right-radius:0;}", ".f1b65x5h .fui-SplitButton__menuButton{min-width:24px;}", ".f4rm5b0 .fui-SplitButton__primaryActionButton{border-right-color:var(--colorNeutralStrokeOnBrand);}", ".f1tuwo13 .fui-SplitButton__primaryActionButton{border-left-color:var(--colorNeutralStrokeOnBrand);}", ".f16kf41h .fui-SplitButton__primaryActionButton{border-right-color:var(--colorTransparentBackground);}", ".fxiafvi .fui-SplitButton__primaryActionButton{border-left-color:var(--colorTransparentBackground);}", ".f10xrnr8 .fui-SplitButton__primaryActionButton{border-right-color:var(--colorNeutralStrokeDisabled);}", ".f15nylwb .fui-SplitButton__primaryActionButton{border-left-color:var(--colorNeutralStrokeDisabled);}"],
h: [".fdwdeeo:hover .fui-SplitButton__primaryActionButton{border-right-color:var(--colorNeutralStrokeOnBrand);}", ".f1ezdslh:hover .fui-SplitButton__primaryActionButton{border-left-color:var(--colorNeutralStrokeOnBrand);}", ".f1ju2vgk:hover:active .fui-SplitButton__primaryActionButton,.f1ju2vgk:active:focus-visible .fui-SplitButton__primaryActionButton{border-right-color:var(--colorNeutralStrokeOnBrand);}", ".f1r6p88l:hover:active .fui-SplitButton__primaryActionButton,.f1r6p88l:active:focus-visible .fui-SplitButton__primaryActionButton{border-left-color:var(--colorNeutralStrokeOnBrand);}", ".ffl6mx9:hover .fui-SplitButton__primaryActionButton{border-right-color:var(--colorTransparentBackgroundHover);}", ".f1t5sw6t:hover .fui-SplitButton__primaryActionButton{border-left-color:var(--colorTransparentBackgroundHover);}", ".f1mww3cx:hover:active .fui-SplitButton__primaryActionButton,.f1mww3cx:active:focus-visible .fui-SplitButton__primaryActionButton{border-right-color:var(--colorTransparentBackgroundPressed);}", ".f1wtv0vd:hover:active .fui-SplitButton__primaryActionButton,.f1wtv0vd:active:focus-visible .fui-SplitButton__primaryActionButton{border-left-color:var(--colorTransparentBackgroundPressed);}", ".f11fwhjz:hover .fui-SplitButton__primaryActionButton{border-right-color:var(--colorNeutralStrokeDisabled);}", ".f18vtcsx:hover .fui-SplitButton__primaryActionButton{border-left-color:var(--colorNeutralStrokeDisabled);}", ".f12kx9re:hover:active .fui-SplitButton__primaryActionButton,.f12kx9re:active:focus-visible .fui-SplitButton__primaryActionButton{border-right-color:var(--colorNeutralStrokeDisabled);}", ".f1hyxdqk:hover:active .fui-SplitButton__primaryActionButton,.f1hyxdqk:active:focus-visible .fui-SplitButton__primaryActionButton{border-left-color:var(--colorNeutralStrokeDisabled);}"],
m: [["@media (forced-colors: active){.f12iqdwp .fui-SplitButton__primaryActionButton{border-left-color:HighlightText;}.f2z0mmn .fui-SplitButton__primaryActionButton{border-right-color:HighlightText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1btorfl:hover .fui-SplitButton__primaryActionButton{border-right-color:Highlight;}.fxofj4p:hover .fui-SplitButton__primaryActionButton{border-left-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f10m3pjc:hover:active .fui-SplitButton__primaryActionButton,.f10m3pjc:active:focus-visible .fui-SplitButton__primaryActionButton{border-left-color:Highlight;}.f161sdhp:hover:active .fui-SplitButton__primaryActionButton,.f161sdhp:active:focus-visible .fui-SplitButton__primaryActionButton{border-right-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.fslo9ob .fui-SplitButton__primaryActionButton{border-right-color:GrayText;}.ftovg2z .fui-SplitButton__primaryActionButton{border-left-color:GrayText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f168zpha:hover .fui-SplitButton__primaryActionButton{border-left-color:GrayText;}.f1fuq5cn:hover .fui-SplitButton__primaryActionButton{border-right-color:GrayText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1dnwhli:hover:active .fui-SplitButton__primaryActionButton,.f1dnwhli:active:focus-visible .fui-SplitButton__primaryActionButton{border-left-color:GrayText;}.f1t6bo0o:hover:active .fui-SplitButton__primaryActionButton,.f1t6bo0o:active:focus-visible .fui-SplitButton__primaryActionButton{border-right-color:GrayText;}}", {
m: "(forced-colors: active)"
}]]
});
export const useSplitButtonStyles_unstable = state => {
'use no memo';
const rootStyles = useRootStyles();
const focusStyles = useFocusStyles();
const {
appearance,
disabled,
disabledFocusable
} = state;
state.root.className = mergeClasses(splitButtonClassNames.root, rootStyles.base, appearance && rootStyles[appearance], (disabled || disabledFocusable) && rootStyles.disabled, (disabled || disabledFocusable) && rootStyles.disabledHighContrast, state.root.className);
if (state.menuButton) {
state.menuButton.className = mergeClasses(splitButtonClassNames.menuButton, focusStyles.menuButton, state.menuButton.className);
}
if (state.primaryActionButton) {
state.primaryActionButton.className = mergeClasses(splitButtonClassNames.primaryActionButton, focusStyles.primaryActionButton, state.primaryActionButton.className);
}
return state;
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,159 @@
'use client';
import { makeStyles, mergeClasses } from '@griffel/react';
import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster';
import { tokens } from '@fluentui/react-theme';
export const splitButtonClassNames = {
root: 'fui-SplitButton',
menuButton: 'fui-SplitButton__menuButton',
primaryActionButton: 'fui-SplitButton__primaryActionButton'
};
// WCAG minimum target size for pointer targets that are immediately adjacent to other targets:
// https://w3c.github.io/wcag/guidelines/22/#target-size-minimum
const MIN_TARGET_SIZE = '24px';
const useFocusStyles = makeStyles({
primaryActionButton: createCustomFocusIndicatorStyle({
borderTopRightRadius: 0,
borderBottomRightRadius: 0
}),
menuButton: createCustomFocusIndicatorStyle({
borderLeftWidth: 0,
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0
})
});
const useRootStyles = makeStyles({
// Base styles
base: {
display: 'inline-flex',
justifyContent: 'stretch',
position: 'relative',
verticalAlign: 'middle',
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderTopRightRadius: 0,
borderBottomRightRadius: 0
},
[`& .${splitButtonClassNames.menuButton}`]: {
borderLeftWidth: 0,
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
minWidth: MIN_TARGET_SIZE
}
},
// Appearance variations
outline: {
},
primary: {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorNeutralStrokeOnBrand
},
':hover': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorNeutralStrokeOnBrand
}
},
':hover:active,:active:focus-visible': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorNeutralStrokeOnBrand
}
},
'@media (forced-colors: active)': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: 'HighlightText'
},
':hover': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: 'Highlight'
}
},
':hover:active,:active:focus-visible': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: 'Highlight'
}
}
}
},
secondary: {
},
subtle: {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorTransparentBackground
},
':hover': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorTransparentBackgroundHover
}
},
':hover:active,:active:focus-visible': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorTransparentBackgroundPressed
}
}
},
transparent: {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorTransparentBackground
},
':hover': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorTransparentBackgroundHover
}
},
':hover:active,:active:focus-visible': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorTransparentBackgroundPressed
}
}
},
// Shape variations
circular: {},
rounded: {},
square: {},
// Disabled styles
disabled: {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorNeutralStrokeDisabled
},
':hover': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorNeutralStrokeDisabled
}
},
':hover:active,:active:focus-visible': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: tokens.colorNeutralStrokeDisabled
}
}
},
// Disabled high contrast styles
disabledHighContrast: {
'@media (forced-colors: active)': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: 'GrayText'
},
':hover': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: 'GrayText'
}
},
':hover:active,:active:focus-visible': {
[`& .${splitButtonClassNames.primaryActionButton}`]: {
borderRightColor: 'GrayText'
}
}
}
}
});
export const useSplitButtonStyles_unstable = (state)=>{
'use no memo';
const rootStyles = useRootStyles();
const focusStyles = useFocusStyles();
const { appearance, disabled, disabledFocusable } = state;
state.root.className = mergeClasses(splitButtonClassNames.root, rootStyles.base, appearance && rootStyles[appearance], (disabled || disabledFocusable) && rootStyles.disabled, (disabled || disabledFocusable) && rootStyles.disabledHighContrast, state.root.className);
if (state.menuButton) {
state.menuButton.className = mergeClasses(splitButtonClassNames.menuButton, focusStyles.menuButton, state.menuButton.className);
}
if (state.primaryActionButton) {
state.primaryActionButton.className = mergeClasses(splitButtonClassNames.primaryActionButton, focusStyles.primaryActionButton, state.primaryActionButton.className);
}
return state;
};

File diff suppressed because one or more lines are too long