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,15 @@
'use client';
import * as React from 'react';
import { useMenuItem_unstable } from './useMenuItem';
import { renderMenuItem_unstable } from './renderMenuItem';
import { useMenuItemStyles_unstable } from './useMenuItemStyles.styles';
import { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';
/**
* Define a styled MenuItem, using the `useMenuItem_unstable` and `useMenuItemStyles_unstable` hook.
*/ export const MenuItem = /*#__PURE__*/ React.forwardRef((props, ref)=>{
const state = useMenuItem_unstable(props, ref);
useMenuItemStyles_unstable(state);
useCustomStyleHook_unstable('useMenuItemStyles_unstable')(state);
return renderMenuItem_unstable(state);
});
MenuItem.displayName = 'MenuItem';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/MenuItem/MenuItem.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useMenuItem_unstable } from './useMenuItem';\nimport { renderMenuItem_unstable } from './renderMenuItem';\nimport { useMenuItemStyles_unstable } from './useMenuItemStyles.styles';\nimport type { MenuItemProps } from './MenuItem.types';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\n\n/**\n * Define a styled MenuItem, using the `useMenuItem_unstable` and `useMenuItemStyles_unstable` hook.\n */\nexport const MenuItem: ForwardRefComponent<MenuItemProps> = React.forwardRef((props, ref) => {\n const state = useMenuItem_unstable(props, ref);\n\n useMenuItemStyles_unstable(state);\n\n useCustomStyleHook_unstable('useMenuItemStyles_unstable')(state);\n\n return renderMenuItem_unstable(state);\n});\n\nMenuItem.displayName = 'MenuItem';\n"],"names":["React","useMenuItem_unstable","renderMenuItem_unstable","useMenuItemStyles_unstable","useCustomStyleHook_unstable","MenuItem","forwardRef","props","ref","state","displayName"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,oBAAoB,QAAQ,gBAAgB;AACrD,SAASC,uBAAuB,QAAQ,mBAAmB;AAC3D,SAASC,0BAA0B,QAAQ,6BAA6B;AAGxE,SAASC,2BAA2B,QAAQ,kCAAkC;AAE9E;;CAEC,GACD,OAAO,MAAMC,yBAA+CL,MAAMM,UAAU,CAAC,CAACC,OAAOC;IACnF,MAAMC,QAAQR,qBAAqBM,OAAOC;IAE1CL,2BAA2BM;IAE3BL,4BAA4B,8BAA8BK;IAE1D,OAAOP,wBAAwBO;AACjC,GAAG;AAEHJ,SAASK,WAAW,GAAG"}

View File

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

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/MenuItem/MenuItem.types.ts"],"sourcesContent":["import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';\n\nexport type MenuItemSlots = {\n root: Slot<'div'>;\n\n /**\n * Icon slot rendered before children content\n */\n icon?: Slot<'span'>;\n\n /**\n * A helper slot for alignment when a menu item is used with selectable menuitems\n * Avoid using this slot as a replacement for MenuItemCheckbox and MenuItemRadio components\n */\n checkmark?: Slot<'span'>;\n\n /**\n * Icon slot that shows the indicator for a submenu\n */\n submenuIndicator?: Slot<'span'>;\n\n /**\n * Component children are placed in this slot\n * Avoid using the `children` property in this slot in favour of Component children whenever possible\n */\n content?: Slot<'span'>;\n\n /**\n * Secondary content rendered opposite the primary content (e.g Shortcut text)\n */\n secondaryContent?: Slot<'span'>;\n\n /**\n * Additional descriptor to main content that creates a multiline layout\n */\n subText?: Slot<'span'>;\n};\n\nexport type MenuItemProps = Omit<ComponentProps<Partial<MenuItemSlots>>, 'content'> &\n Pick<Partial<MenuItemSlots>, 'content'> & {\n /**\n * If the menu item is a trigger for a submenu\n *\n * @default false\n */\n hasSubmenu?: boolean;\n\n /**\n * Clicking on the menu item will not dismiss an open menu\n *\n * @default false\n */\n persistOnClick?: boolean;\n\n disabled?: boolean;\n /**\n * @deprecated this property does nothing.\n * disabled focusable is by default by simply using `disabled` property\n */\n disabledFocusable?: boolean;\n };\n\nexport type MenuItemState = ComponentState<MenuItemSlots> &\n Required<Pick<MenuItemProps, 'disabled' | 'hasSubmenu' | 'persistOnClick'>>;\n"],"names":[],"mappings":"AA8DA,WAC8E"}

View File

@@ -0,0 +1,4 @@
export { MenuItem } from './MenuItem';
export { renderMenuItem_unstable } from './renderMenuItem';
export { useMenuItem_unstable, useMenuItemBase_unstable } from './useMenuItem';
export { menuItemClassNames, useMenuItemStyles_unstable } from './useMenuItemStyles.styles';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/MenuItem/index.ts"],"sourcesContent":["export { MenuItem } from './MenuItem';\nexport type { MenuItemProps, MenuItemSlots, MenuItemState } from './MenuItem.types';\nexport { renderMenuItem_unstable } from './renderMenuItem';\nexport { useMenuItem_unstable, useMenuItemBase_unstable } from './useMenuItem';\nexport { menuItemClassNames, useMenuItemStyles_unstable } from './useMenuItemStyles.styles';\n"],"names":["MenuItem","renderMenuItem_unstable","useMenuItem_unstable","useMenuItemBase_unstable","menuItemClassNames","useMenuItemStyles_unstable"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,aAAa;AAEtC,SAASC,uBAAuB,QAAQ,mBAAmB;AAC3D,SAASC,oBAAoB,EAAEC,wBAAwB,QAAQ,gBAAgB;AAC/E,SAASC,kBAAkB,EAAEC,0BAA0B,QAAQ,6BAA6B"}

View File

@@ -0,0 +1,21 @@
import { jsx as _jsx, jsxs as _jsxs } from "@fluentui/react-jsx-runtime/jsx-runtime";
import { assertSlots } from '@fluentui/react-utilities';
/**
* Function that renders the final JSX of the component
*/ export const renderMenuItem_unstable = (state)=>{
assertSlots(state);
return /*#__PURE__*/ _jsxs(state.root, {
children: [
state.checkmark && /*#__PURE__*/ _jsx(state.checkmark, {}),
state.icon && /*#__PURE__*/ _jsx(state.icon, {}),
state.content && /*#__PURE__*/ _jsxs(state.content, {
children: [
state.content.children,
state.subText && /*#__PURE__*/ _jsx(state.subText, {})
]
}),
state.secondaryContent && /*#__PURE__*/ _jsx(state.secondaryContent, {}),
state.submenuIndicator && /*#__PURE__*/ _jsx(state.submenuIndicator, {})
]
});
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/MenuItem/renderMenuItem.tsx"],"sourcesContent":["/** @jsxRuntime automatic */\n/** @jsxImportSource @fluentui/react-jsx-runtime */\nimport { assertSlots } from '@fluentui/react-utilities';\nimport type { JSXElement } from '@fluentui/react-utilities';\nimport type { MenuItemSlots, MenuItemState } from './MenuItem.types';\n\n/**\n * Function that renders the final JSX of the component\n */\nexport const renderMenuItem_unstable = (state: MenuItemState): JSXElement => {\n assertSlots<MenuItemSlots>(state);\n\n return (\n <state.root>\n {state.checkmark && <state.checkmark />}\n {state.icon && <state.icon />}\n {state.content && (\n <state.content>\n {state.content.children}\n {state.subText && <state.subText />}\n </state.content>\n )}\n {state.secondaryContent && <state.secondaryContent />}\n {state.submenuIndicator && <state.submenuIndicator />}\n </state.root>\n );\n};\n"],"names":["assertSlots","renderMenuItem_unstable","state","root","checkmark","icon","content","children","subText","secondaryContent","submenuIndicator"],"mappings":"AAAA,0BAA0B,GAC1B,iDAAiD;AACjD,SAASA,WAAW,QAAQ,4BAA4B;AAIxD;;CAEC,GACD,OAAO,MAAMC,0BAA0B,CAACC;IACtCF,YAA2BE;IAE3B,qBACE,MAACA,MAAMC,IAAI;;YACRD,MAAME,SAAS,kBAAI,KAACF,MAAME,SAAS;YACnCF,MAAMG,IAAI,kBAAI,KAACH,MAAMG,IAAI;YACzBH,MAAMI,OAAO,kBACZ,MAACJ,MAAMI,OAAO;;oBACXJ,MAAMI,OAAO,CAACC,QAAQ;oBACtBL,MAAMM,OAAO,kBAAI,KAACN,MAAMM,OAAO;;;YAGnCN,MAAMO,gBAAgB,kBAAI,KAACP,MAAMO,gBAAgB;YACjDP,MAAMQ,gBAAgB,kBAAI,KAACR,MAAMQ,gBAAgB;;;AAGxD,EAAE"}

View File

@@ -0,0 +1,19 @@
'use client';
import * as React from 'react';
import { useMenuListContext_unstable } from '../../contexts/menuListContext';
export const useCharacterSearch = (state, ref)=>{
'use no memo';
const setFocusByFirstCharacter = useMenuListContext_unstable((context)=>context.setFocusByFirstCharacter);
const { onKeyDown: originalOnKeyDown } = state.root;
state.root.onKeyDown = (e)=>{
var _e_key;
originalOnKeyDown === null || originalOnKeyDown === void 0 ? void 0 : originalOnKeyDown(e);
if (((_e_key = e.key) === null || _e_key === void 0 ? void 0 : _e_key.length) > 1) {
return;
}
if (ref.current) {
setFocusByFirstCharacter === null || setFocusByFirstCharacter === void 0 ? void 0 : setFocusByFirstCharacter(e, ref.current);
}
};
return state;
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/MenuItem/useCharacterSearch.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useMenuListContext_unstable } from '../../contexts/menuListContext';\nimport type { MenuItemState } from '../../components/index';\nimport type { ARIAButtonElementIntersection } from '@fluentui/react-aria';\n\nexport const useCharacterSearch = (state: MenuItemState, ref: React.RefObject<HTMLElement | null>): MenuItemState => {\n 'use no memo';\n\n const setFocusByFirstCharacter = useMenuListContext_unstable(context => context.setFocusByFirstCharacter);\n\n const { onKeyDown: originalOnKeyDown } = state.root;\n\n state.root.onKeyDown = (e: React.KeyboardEvent<ARIAButtonElementIntersection>) => {\n originalOnKeyDown?.(e);\n\n if (e.key?.length > 1) {\n return;\n }\n\n if (ref.current) {\n setFocusByFirstCharacter?.(e, ref.current);\n }\n };\n\n return state;\n};\n"],"names":["React","useMenuListContext_unstable","useCharacterSearch","state","ref","setFocusByFirstCharacter","context","onKeyDown","originalOnKeyDown","root","e","key","length","current"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,2BAA2B,QAAQ,iCAAiC;AAI7E,OAAO,MAAMC,qBAAqB,CAACC,OAAsBC;IACvD;IAEA,MAAMC,2BAA2BJ,4BAA4BK,CAAAA,UAAWA,QAAQD,wBAAwB;IAExG,MAAM,EAAEE,WAAWC,iBAAiB,EAAE,GAAGL,MAAMM,IAAI;IAEnDN,MAAMM,IAAI,CAACF,SAAS,GAAG,CAACG;YAGlBA;QAFJF,8BAAAA,wCAAAA,kBAAoBE;QAEpB,IAAIA,EAAAA,SAAAA,EAAEC,GAAG,cAALD,6BAAAA,OAAOE,MAAM,IAAG,GAAG;YACrB;QACF;QAEA,IAAIR,IAAIS,OAAO,EAAE;YACfR,qCAAAA,+CAAAA,yBAA2BK,GAAGN,IAAIS,OAAO;QAC3C;IACF;IAEA,OAAOV;AACT,EAAE"}

View File

@@ -0,0 +1,164 @@
'use client';
import * as React from 'react';
import { useEventCallback, useMergedRefs, getIntrinsicElementProps, slot, useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
import { useCharacterSearch } from './useCharacterSearch';
import { useMenuTriggerContext_unstable } from '../../contexts/menuTriggerContext';
import { ChevronRightFilled, ChevronRightRegular, ChevronLeftFilled, ChevronLeftRegular, bundleIcon } from '@fluentui/react-icons';
import { useMenuListContext_unstable } from '../../contexts/menuListContext';
import { useMenuContext_unstable } from '../../contexts/menuContext';
import { useARIAButtonProps } from '@fluentui/react-aria';
import { Enter, Space } from '@fluentui/keyboard-keys';
import { useIsInMenuSplitGroup, useMenuSplitGroupContext_unstable } from '../../contexts/menuSplitGroupContext';
import { useValidateNesting } from '../../utils/useValidateNesting';
const ChevronRightIcon = bundleIcon(ChevronRightFilled, ChevronRightRegular);
const ChevronLeftIcon = bundleIcon(ChevronLeftFilled, ChevronLeftRegular);
/**
* Returns the props and state required to render the component
*/ export const useMenuItem_unstable = (props, ref)=>{
const { dir } = useFluent();
const state = useMenuItemBase_unstable(props, ref);
// Set default chevron icon
if (state.submenuIndicator) {
var _state_submenuIndicator;
var _children;
(_children = (_state_submenuIndicator = state.submenuIndicator).children) !== null && _children !== void 0 ? _children : _state_submenuIndicator.children = dir === 'rtl' ? /*#__PURE__*/ React.createElement(ChevronLeftIcon, null) : /*#__PURE__*/ React.createElement(ChevronRightIcon, null);
}
return state;
};
/**
* Base hook for MenuItem component, produces state required to render the component.
* It doesn't set any design-related props specific to MenuItem such as submenu indicator icon.
*
* @internal
*/ export const useMenuItemBase_unstable = (props, ref)=>{
const isSubmenuTrigger = useMenuTriggerContext_unstable();
const persistOnClickContext = useMenuContext_unstable((context)=>context.persistOnItemClick);
const { as = 'div', disabled = false, hasSubmenu = isSubmenuTrigger, persistOnClick = persistOnClickContext, content: _content, ...rest } = props;
const { hasIcons, hasCheckmarks } = useIconAndCheckmarkAlignment({
hasSubmenu
});
const setOpen = useMenuContext_unstable((context)=>context.setOpen);
useNotifySplitItemMultiline({
multiline: !!props.subText,
hasSubmenu
});
const innerRef = React.useRef(null);
const dismissedWithKeyboardRef = React.useRef(false);
const validateNestingRef = useValidateNesting(getValidateNestingComponentName(props.role));
const state = {
hasSubmenu,
disabled,
persistOnClick,
components: {
root: 'div',
icon: 'span',
checkmark: 'span',
submenuIndicator: 'span',
content: 'span',
secondaryContent: 'span',
subText: 'span'
},
root: slot.always(getIntrinsicElementProps(as, useARIAButtonProps(as, {
role: 'menuitem',
...rest,
disabled: false,
disabledFocusable: disabled,
ref: useMergedRefs(ref, innerRef, validateNestingRef),
onKeyDown: useEventCallback((event)=>{
var _props_onKeyDown;
(_props_onKeyDown = props.onKeyDown) === null || _props_onKeyDown === void 0 ? void 0 : _props_onKeyDown.call(props, event);
if (!event.isDefaultPrevented() && (event.key === Space || event.key === Enter)) {
dismissedWithKeyboardRef.current = true;
}
}),
onMouseMove: useEventCallback((event)=>{
var _props_onMouseMove;
if (event.currentTarget.ownerDocument.activeElement !== event.currentTarget) {
var _innerRef_current;
(_innerRef_current = innerRef.current) === null || _innerRef_current === void 0 ? void 0 : _innerRef_current.focus();
}
(_props_onMouseMove = props.onMouseMove) === null || _props_onMouseMove === void 0 ? void 0 : _props_onMouseMove.call(props, event);
}),
onClick: useEventCallback((event)=>{
var _props_onClick;
if (!hasSubmenu && !persistOnClick) {
setOpen(event, {
open: false,
keyboard: dismissedWithKeyboardRef.current,
bubble: true,
type: 'menuItemClick',
event
});
dismissedWithKeyboardRef.current = false;
}
(_props_onClick = props.onClick) === null || _props_onClick === void 0 ? void 0 : _props_onClick.call(props, event);
})
})), {
elementType: 'div'
}),
icon: slot.optional(props.icon, {
renderByDefault: hasIcons,
elementType: 'span'
}),
checkmark: slot.optional(props.checkmark, {
renderByDefault: hasCheckmarks,
elementType: 'span'
}),
submenuIndicator: slot.optional(props.submenuIndicator, {
renderByDefault: hasSubmenu,
elementType: 'span'
}),
content: slot.optional(props.content, {
renderByDefault: !!props.children,
defaultProps: {
children: props.children
},
elementType: 'span'
}),
secondaryContent: slot.optional(props.secondaryContent, {
elementType: 'span'
}),
subText: slot.optional(props.subText, {
elementType: 'span'
})
};
useCharacterSearch(state, innerRef);
return state;
};
/**
* MenuSplitGroup needs to apply extra styles when its main item is in multiline layout mode
* Notify the parent MenuSplitGroup so that it can handle this case
*/ const useNotifySplitItemMultiline = (options)=>{
const { hasSubmenu, multiline } = options;
const isSplitItemTrigger = useIsInMenuSplitGroup() && hasSubmenu;
const { setMultiline } = useMenuSplitGroupContext_unstable();
useIsomorphicLayoutEffect(()=>{
if (!isSplitItemTrigger) {
setMultiline(multiline);
}
}, [
setMultiline,
multiline,
isSplitItemTrigger
]);
};
const useIconAndCheckmarkAlignment = (options)=>{
const { hasSubmenu } = options;
const hasIcons = useMenuListContext_unstable((context)=>context.hasIcons);
const hasCheckmarks = useMenuListContext_unstable((context)=>context.hasCheckmarks);
const isSplitItemTrigger = useIsInMenuSplitGroup() && hasSubmenu;
return {
hasIcons: hasIcons && !isSplitItemTrigger,
hasCheckmarks: hasCheckmarks && !isSplitItemTrigger
};
};
const getValidateNestingComponentName = (role)=>{
switch(role){
case 'menuitemcheckbox':
return 'MenuItemCheckbox';
case 'menuitemradio':
return 'MenuItemRadio';
}
return 'MenuItem';
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,155 @@
'use client';
import { mergeClasses, __styles, __resetStyles } from '@griffel/react';
import { iconFilledClassName, iconRegularClassName } from '@fluentui/react-icons';
import { createFocusOutlineStyle } from '@fluentui/react-tabster';
import { tokens, typographyStyles } from '@fluentui/react-theme';
import { useCheckmarkStyles_unstable } from '../../selectable/index';
export const menuItemClassNames = {
root: 'fui-MenuItem',
icon: 'fui-MenuItem__icon',
checkmark: 'fui-MenuItem__checkmark',
submenuIndicator: 'fui-MenuItem__submenuIndicator',
content: 'fui-MenuItem__content',
secondaryContent: 'fui-MenuItem__secondaryContent',
subText: 'fui-MenuItem__subText'
};
const useRootBaseStyles = /*#__PURE__*/__resetStyles("rfoezjv", "r8lt3v0", {
r: [".rfoezjv{border-radius:var(--borderRadiusMedium);position:relative;color:var(--colorNeutralForeground2);background-color:var(--colorNeutralBackground1);padding-right:var(--spacingVerticalSNudge);padding-left:var(--spacingVerticalSNudge);padding-top:var(--spacingVerticalSNudge);padding-bottom:var(--spacingVerticalSNudge);box-sizing:border-box;max-width:290px;min-height:32px;flex-shrink:0;display:flex;align-items:start;font-size:var(--fontSizeBase300);cursor:pointer;gap:4px;-webkit-user-select:none;-moz-user-select:none;user-select:none;}", ".rfoezjv:hover{background-color:var(--colorNeutralBackground1Hover);color:var(--colorNeutralForeground2Hover);}", ".rfoezjv:hover .fui-Icon-filled{display:inline;}", ".rfoezjv:hover .fui-Icon-regular{display:none;}", ".rfoezjv:hover .fui-MenuItem__icon{color:var(--colorNeutralForeground2BrandSelected);}", ".rfoezjv:hover .fui-MenuItem__subText{color:var(--colorNeutralForeground3Hover);}", ".rfoezjv:hover:active{background-color:var(--colorNeutralBackground1Pressed);color:var(--colorNeutralForeground2Pressed);}", ".rfoezjv:hover:active .fui-MenuItem__subText{color:var(--colorNeutralForeground3Pressed);}", ".rfoezjv:focus{outline-style:none;}", ".rfoezjv:focus-visible{outline-style:none;}", ".rfoezjv[data-fui-focus-visible]{border-top-color:transparent;border-right-color:transparent;border-bottom-color:transparent;border-left-color:transparent;}", ".rfoezjv[data-fui-focus-visible]::after{content:\"\";position:absolute;pointer-events:none;z-index:1;border:2px solid var(--colorStrokeFocus2);border-radius:var(--borderRadiusMedium);top:calc(2px * -1);right:calc(2px * -1);bottom:calc(2px * -1);left:calc(2px * -1);}", ".r8lt3v0{border-radius:var(--borderRadiusMedium);position:relative;color:var(--colorNeutralForeground2);background-color:var(--colorNeutralBackground1);padding-left:var(--spacingVerticalSNudge);padding-right:var(--spacingVerticalSNudge);padding-top:var(--spacingVerticalSNudge);padding-bottom:var(--spacingVerticalSNudge);box-sizing:border-box;max-width:290px;min-height:32px;flex-shrink:0;display:flex;align-items:start;font-size:var(--fontSizeBase300);cursor:pointer;gap:4px;-webkit-user-select:none;-moz-user-select:none;user-select:none;}", ".r8lt3v0:hover{background-color:var(--colorNeutralBackground1Hover);color:var(--colorNeutralForeground2Hover);}", ".r8lt3v0:hover .fui-Icon-filled{display:inline;}", ".r8lt3v0:hover .fui-Icon-regular{display:none;}", ".r8lt3v0:hover .fui-MenuItem__icon{color:var(--colorNeutralForeground2BrandSelected);}", ".r8lt3v0:hover .fui-MenuItem__subText{color:var(--colorNeutralForeground3Hover);}", ".r8lt3v0:hover:active{background-color:var(--colorNeutralBackground1Pressed);color:var(--colorNeutralForeground2Pressed);}", ".r8lt3v0:hover:active .fui-MenuItem__subText{color:var(--colorNeutralForeground3Pressed);}", ".r8lt3v0:focus{outline-style:none;}", ".r8lt3v0:focus-visible{outline-style:none;}", ".r8lt3v0[data-fui-focus-visible]{border-top-color:transparent;border-left-color:transparent;border-bottom-color:transparent;border-right-color:transparent;}", ".r8lt3v0[data-fui-focus-visible]::after{content:\"\";position:absolute;pointer-events:none;z-index:1;border:2px solid var(--colorStrokeFocus2);border-radius:var(--borderRadiusMedium);top:calc(2px * -1);left:calc(2px * -1);bottom:calc(2px * -1);right:calc(2px * -1);}"],
s: ["@media (forced-colors: active){.rfoezjv:hover{background-color:Canvas;border-color:Highlight;color:Highlight;}.rfoezjv:focus{outline-style:none;}.rfoezjv:focus-visible{outline-style:none;}.rfoezjv[data-fui-focus-visible]{border-top-color:transparent;border-right-color:transparent;border-bottom-color:transparent;border-left-color:transparent;}@media (forced-colors: active){.rfoezjv[data-fui-focus-visible]::after{border-top-color:Highlight;border-right-color:Highlight;border-bottom-color:Highlight;border-left-color:Highlight;}}.rfoezjv[data-fui-focus-visible]::after{content:\"\";position:absolute;pointer-events:none;z-index:1;border:2px solid Highlight;border-radius:var(--borderRadiusMedium);top:calc(2px * -1);right:calc(2px * -1);bottom:calc(2px * -1);left:calc(2px * -1);}}", "@media (forced-colors: active){.rfoezjv[data-fui-focus-visible]::after{border-top-color:Highlight;border-right-color:Highlight;border-bottom-color:Highlight;border-left-color:Highlight;}}", "@media (forced-colors: active){.r8lt3v0:hover{background-color:Canvas;border-color:Highlight;color:Highlight;}.r8lt3v0:focus{outline-style:none;}.r8lt3v0:focus-visible{outline-style:none;}.r8lt3v0[data-fui-focus-visible]{border-top-color:transparent;border-left-color:transparent;border-bottom-color:transparent;border-right-color:transparent;}@media (forced-colors: active){.r8lt3v0[data-fui-focus-visible]::after{border-top-color:Highlight;border-left-color:Highlight;border-bottom-color:Highlight;border-right-color:Highlight;}}.r8lt3v0[data-fui-focus-visible]::after{content:\"\";position:absolute;pointer-events:none;z-index:1;border:2px solid Highlight;border-radius:var(--borderRadiusMedium);top:calc(2px * -1);left:calc(2px * -1);bottom:calc(2px * -1);right:calc(2px * -1);}}", "@media (forced-colors: active){.r8lt3v0[data-fui-focus-visible]::after{border-top-color:Highlight;border-left-color:Highlight;border-bottom-color:Highlight;border-right-color:Highlight;}}"]
});
const useContentBaseStyles = /*#__PURE__*/__resetStyles("r1ls86vo", "rpbc5dr", [".r1ls86vo{padding-left:2px;padding-right:2px;background-color:transparent;flex-grow:1;}", ".rpbc5dr{padding-right:2px;padding-left:2px;background-color:transparent;flex-grow:1;}"]);
const useSecondaryContentBaseStyles = /*#__PURE__*/__resetStyles("r12mwwux", "r1ewgu5j", [".r12mwwux{padding-left:2px;padding-right:2px;font-family:var(--fontFamilyBase);font-size:var(--fontSizeBase200);font-weight:var(--fontWeightRegular);line-height:var(--lineHeightBase300);color:var(--colorNeutralForeground3);}", ".r12mwwux:hover{color:var(--colorNeutralForeground3Hover);}", ".r12mwwux:focus{color:var(--colorNeutralForeground3Hover);}", ".r1ewgu5j{padding-right:2px;padding-left:2px;font-family:var(--fontFamilyBase);font-size:var(--fontSizeBase200);font-weight:var(--fontWeightRegular);line-height:var(--lineHeightBase300);color:var(--colorNeutralForeground3);}", ".r1ewgu5j:hover{color:var(--colorNeutralForeground3Hover);}", ".r1ewgu5j:focus{color:var(--colorNeutralForeground3Hover);}"]);
const useIconBaseStyles = /*#__PURE__*/__resetStyles("ro9koqv", null, [".ro9koqv{width:20px;height:20px;font-size:20px;line-height:0;align-items:center;display:inline-flex;justify-content:center;flex-shrink:0;}"]);
const useSubmenuIndicatorBaseStyles = /*#__PURE__*/__resetStyles("r9c34qo", null, [".r9c34qo{width:20px;height:20px;font-size:20px;line-height:0;align-items:center;display:inline-flex;justify-content:center;}"]);
const useSubtextBaseStyles = /*#__PURE__*/__resetStyles("rk2ppru", null, [".rk2ppru{font-family:var(--fontFamilyBase);font-size:var(--fontSizeBase100);font-weight:var(--fontWeightRegular);line-height:var(--lineHeightBase100);color:var(--colorNeutralForeground3);}"]);
const useStyles = /*#__PURE__*/__styles({
checkmark: {
B6of3ja: "fmnzpld"
},
splitItemMain: {
Bh6795r: "fqerorx"
},
splitItemTrigger: {
Btl43ni: ["f1ozlkrg", "f10ostut"],
Beyfa6y: ["f1deotkl", "f1krrbdw"],
uwmqm3: ["f1cnd47f", "fhxju0i"],
Ftih45: "f1wl9k8s",
Ccq8qp: "f1yn80uh",
Baz25je: "f68mna0",
cmx5o7: "f1p5zmk"
},
disabled: {
sj55zd: "f1s2aq7o",
Bi91k9c: "fvgxktp",
Jwef8y: "f1ijtazh",
eoavqd: "fphbwmw",
Bk3fhr4: "f19vpps7",
Bmfj8id: "fv5swzo",
Bg7n49j: "f1q1x1ba",
c7f7en: "ff3wrqt",
B2d53fq: "fcvwxyo",
iro3zm: "f1to34ca",
Bumww26: "fszh5vc",
t0hwav: "ft33916",
B7iucu3: "f1cyfu5x",
Bahaeuw: "fa9u7a5",
Bbkh6qg: "f1wzezsb",
B3ejlan: "f1egomlm",
B41git9: "f1wf2001",
Boq1n10: "fied5gk",
Dcq74g: "f1efp33f",
rxnm8d: "f1m2zpi7",
wxluhh: "fei14nx",
idgcvv: "f12hmwa5",
j9xr24: "f1hzwxd0"
}
}, {
d: [".fmnzpld{margin-top:2px;}", ".fqerorx{flex-grow:1;}", ".f1ozlkrg{border-top-left-radius:0;}", ".f10ostut{border-top-right-radius:0;}", ".f1deotkl{border-bottom-left-radius:0;}", ".f1krrbdw{border-bottom-right-radius:0;}", ".f1cnd47f{padding-left:0;}", ".fhxju0i{padding-right:0;}", ".f1wl9k8s::before{content:\"\";}", ".f1yn80uh::before{width:var(--strokeWidthThin);}", ".f68mna0::before{height:24px;}", ".f1p5zmk::before{background-color:var(--colorNeutralStroke1);}", ".f1s2aq7o{color:var(--colorNeutralForegroundDisabled);}"],
h: [".fvgxktp:hover{color:var(--colorNeutralForegroundDisabled);}", ".f1ijtazh:hover{background-color:var(--colorNeutralBackground1);}", ".fphbwmw:hover{cursor:not-allowed;}", ".f19vpps7:hover .fui-Icon-filled{display:none;}", ".fv5swzo:hover .fui-Icon-regular{display:inline;}", ".f1q1x1ba:hover .fui-MenuItem__icon{color:var(--colorNeutralForegroundDisabled);}", ".ff3wrqt:hover .fui-MenuItem__subText{color:var(--colorNeutralForegroundDisabled);}", ".fcvwxyo:hover:active{color:var(--colorNeutralForegroundDisabled);}", ".f1to34ca:hover:active{background-color:var(--colorNeutralBackground1);}", ".fszh5vc:hover:active .fui-MenuItem__subText{color:var(--colorNeutralForegroundDisabled);}"],
f: [".ft33916:focus{color:var(--colorNeutralForegroundDisabled);}"],
m: [["@media (forced-colors: active){.f1cyfu5x{color:GrayText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.fa9u7a5:hover{color:GrayText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1wzezsb:hover{background-color:Canvas;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1egomlm:hover .fui-MenuItem__icon{color:GrayText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1wf2001:hover .fui-MenuItem__icon{background-color:Canvas;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.fied5gk:hover .fui-MenuItem__subText{color:GrayText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1efp33f:hover:active{color:GrayText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1m2zpi7:hover:active{background-color:Canvas;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.fei14nx:hover:active .fui-MenuItem__subText{color:GrayText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f12hmwa5:focus{color:GrayText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1hzwxd0:focus{background-color:Canvas;}}", {
m: "(forced-colors: active)"
}]]
});
const useSubTextStyles = /*#__PURE__*/__styles({
disabled: {
sj55zd: "f1s2aq7o",
B7iucu3: "f1cyfu5x"
}
}, {
d: [".f1s2aq7o{color:var(--colorNeutralForegroundDisabled);}"],
m: [["@media (forced-colors: active){.f1cyfu5x{color:GrayText;}}", {
m: "(forced-colors: active)"
}]]
});
const useMultilineStyles = /*#__PURE__*/__styles({
content: {
mc9l5x: "f22iagw",
Beiy3e4: "f1vx9l62"
},
secondaryContent: {
qb2dma: "f7nlbp4"
},
submenuIndicator: {
qb2dma: "f7nlbp4"
}
}, {
d: [".f22iagw{display:flex;}", ".f1vx9l62{flex-direction:column;}", ".f7nlbp4{align-self:center;}"]
});
/** Applies style classnames to slots */
export const useMenuItemStyles_unstable = state => {
'use no memo';
const styles = useStyles();
const rootBaseStyles = useRootBaseStyles();
const contentBaseStyles = useContentBaseStyles();
const secondaryContentBaseStyles = useSecondaryContentBaseStyles();
const iconBaseStyles = useIconBaseStyles();
const submenuIndicatorBaseStyles = useSubmenuIndicatorBaseStyles();
const multilineStyles = useMultilineStyles();
const subtextBaseStyles = useSubtextBaseStyles();
const subTextStyles = useSubTextStyles();
const multiline = !!state.subText;
state.root.className = mergeClasses(menuItemClassNames.root, rootBaseStyles, state.disabled && styles.disabled, state.root.className);
if (state.content) {
state.content.className = mergeClasses(menuItemClassNames.content, contentBaseStyles, state.content.className, multiline && multilineStyles.content);
}
if (state.checkmark) {
state.checkmark.className = mergeClasses(menuItemClassNames.checkmark, styles.checkmark, state.checkmark.className);
}
if (state.secondaryContent) {
state.secondaryContent.className = mergeClasses(menuItemClassNames.secondaryContent, secondaryContentBaseStyles, state.disabled && styles.disabled, state.secondaryContent.className, multiline && multilineStyles.secondaryContent);
}
if (state.icon) {
state.icon.className = mergeClasses(menuItemClassNames.icon, iconBaseStyles, state.icon.className);
}
if (state.submenuIndicator) {
state.submenuIndicator.className = mergeClasses(menuItemClassNames.submenuIndicator, submenuIndicatorBaseStyles, state.submenuIndicator.className, multiline && multilineStyles.submenuIndicator);
}
if (state.subText) {
state.subText.className = mergeClasses(menuItemClassNames.subText, state.disabled && subTextStyles.disabled, state.subText.className, subtextBaseStyles);
}
useCheckmarkStyles_unstable(state);
return state;
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,242 @@
'use client';
import { mergeClasses, makeStyles, makeResetStyles } from '@griffel/react';
import { iconFilledClassName, iconRegularClassName } from '@fluentui/react-icons';
import { createFocusOutlineStyle } from '@fluentui/react-tabster';
import { tokens, typographyStyles } from '@fluentui/react-theme';
import { useCheckmarkStyles_unstable } from '../../selectable/index';
export const menuItemClassNames = {
root: 'fui-MenuItem',
icon: 'fui-MenuItem__icon',
checkmark: 'fui-MenuItem__checkmark',
submenuIndicator: 'fui-MenuItem__submenuIndicator',
content: 'fui-MenuItem__content',
secondaryContent: 'fui-MenuItem__secondaryContent',
subText: 'fui-MenuItem__subText'
};
const useRootBaseStyles = makeResetStyles({
borderRadius: tokens.borderRadiusMedium,
position: 'relative',
color: tokens.colorNeutralForeground2,
backgroundColor: tokens.colorNeutralBackground1,
paddingRight: tokens.spacingVerticalSNudge,
paddingLeft: tokens.spacingVerticalSNudge,
paddingTop: tokens.spacingVerticalSNudge,
paddingBottom: tokens.spacingVerticalSNudge,
boxSizing: 'border-box',
maxWidth: '290px',
minHeight: '32px',
flexShrink: 0,
display: 'flex',
alignItems: 'start',
fontSize: tokens.fontSizeBase300,
cursor: 'pointer',
gap: '4px',
':hover': {
backgroundColor: tokens.colorNeutralBackground1Hover,
color: tokens.colorNeutralForeground2Hover,
[`& .${iconFilledClassName}`]: {
display: 'inline'
},
[`& .${iconRegularClassName}`]: {
display: 'none'
},
[`& .${menuItemClassNames.icon}`]: {
color: tokens.colorNeutralForeground2BrandSelected
},
[`& .${menuItemClassNames.subText}`]: {
color: tokens.colorNeutralForeground3Hover
}
},
':hover:active': {
backgroundColor: tokens.colorNeutralBackground1Pressed,
color: tokens.colorNeutralForeground2Pressed,
[`& .${menuItemClassNames.subText}`]: {
color: tokens.colorNeutralForeground3Pressed
}
},
// High contrast styles
'@media (forced-colors: active)': {
':hover': {
backgroundColor: 'Canvas',
borderColor: 'Highlight',
color: 'Highlight'
},
...createFocusOutlineStyle({
style: {
outlineColor: 'Highlight'
}
})
},
userSelect: 'none',
...createFocusOutlineStyle()
});
const useContentBaseStyles = makeResetStyles({
paddingLeft: '2px',
paddingRight: '2px',
backgroundColor: 'transparent',
flexGrow: 1
});
const useSecondaryContentBaseStyles = makeResetStyles({
paddingLeft: '2px',
paddingRight: '2px',
...typographyStyles.caption1,
lineHeight: tokens.lineHeightBase300,
color: tokens.colorNeutralForeground3,
':hover': {
color: tokens.colorNeutralForeground3Hover
},
':focus': {
color: tokens.colorNeutralForeground3Hover
}
});
const useIconBaseStyles = makeResetStyles({
width: '20px',
height: '20px',
fontSize: '20px',
lineHeight: 0,
alignItems: 'center',
display: 'inline-flex',
justifyContent: 'center',
flexShrink: 0
});
const useSubmenuIndicatorBaseStyles = makeResetStyles({
width: '20px',
height: '20px',
fontSize: '20px',
lineHeight: 0,
alignItems: 'center',
display: 'inline-flex',
justifyContent: 'center'
});
const useSubtextBaseStyles = makeResetStyles({
...typographyStyles.caption2,
color: tokens.colorNeutralForeground3
});
const useStyles = makeStyles({
checkmark: {
marginTop: '2px'
},
splitItemMain: {
flexGrow: 1
},
splitItemTrigger: {
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
paddingLeft: 0,
'::before': {
content: '""',
width: tokens.strokeWidthThin,
height: '24px',
backgroundColor: tokens.colorNeutralStroke1
}
},
disabled: {
color: tokens.colorNeutralForegroundDisabled,
':hover': {
color: tokens.colorNeutralForegroundDisabled,
backgroundColor: tokens.colorNeutralBackground1,
cursor: 'not-allowed',
[`& .${iconFilledClassName}`]: {
display: 'none'
},
[`& .${iconRegularClassName}`]: {
display: 'inline'
},
[`& .${menuItemClassNames.icon}`]: {
color: tokens.colorNeutralForegroundDisabled
},
[`& .${menuItemClassNames.subText}`]: {
color: tokens.colorNeutralForegroundDisabled
}
},
':hover:active': {
color: tokens.colorNeutralForegroundDisabled,
backgroundColor: tokens.colorNeutralBackground1,
[`& .${menuItemClassNames.subText}`]: {
color: tokens.colorNeutralForegroundDisabled
}
},
':focus': {
color: tokens.colorNeutralForegroundDisabled
},
'@media (forced-colors: active)': {
color: 'GrayText',
':hover': {
color: 'GrayText',
backgroundColor: 'Canvas',
[`& .${menuItemClassNames.icon}`]: {
color: 'GrayText',
backgroundColor: 'Canvas'
},
[`& .${menuItemClassNames.subText}`]: {
color: 'GrayText'
}
},
':hover:active': {
color: 'GrayText',
backgroundColor: 'Canvas',
[`& .${menuItemClassNames.subText}`]: {
color: 'GrayText'
}
},
':focus': {
color: 'GrayText',
backgroundColor: 'Canvas'
}
}
}
});
const useSubTextStyles = makeStyles({
disabled: {
color: tokens.colorNeutralForegroundDisabled,
'@media (forced-colors: active)': {
color: 'GrayText'
}
}
});
const useMultilineStyles = makeStyles({
content: {
display: 'flex',
flexDirection: 'column'
},
secondaryContent: {
alignSelf: 'center'
},
submenuIndicator: {
alignSelf: 'center'
}
});
/** Applies style classnames to slots */ export const useMenuItemStyles_unstable = (state)=>{
'use no memo';
const styles = useStyles();
const rootBaseStyles = useRootBaseStyles();
const contentBaseStyles = useContentBaseStyles();
const secondaryContentBaseStyles = useSecondaryContentBaseStyles();
const iconBaseStyles = useIconBaseStyles();
const submenuIndicatorBaseStyles = useSubmenuIndicatorBaseStyles();
const multilineStyles = useMultilineStyles();
const subtextBaseStyles = useSubtextBaseStyles();
const subTextStyles = useSubTextStyles();
const multiline = !!state.subText;
state.root.className = mergeClasses(menuItemClassNames.root, rootBaseStyles, state.disabled && styles.disabled, state.root.className);
if (state.content) {
state.content.className = mergeClasses(menuItemClassNames.content, contentBaseStyles, state.content.className, multiline && multilineStyles.content);
}
if (state.checkmark) {
state.checkmark.className = mergeClasses(menuItemClassNames.checkmark, styles.checkmark, state.checkmark.className);
}
if (state.secondaryContent) {
state.secondaryContent.className = mergeClasses(menuItemClassNames.secondaryContent, secondaryContentBaseStyles, state.disabled && styles.disabled, state.secondaryContent.className, multiline && multilineStyles.secondaryContent);
}
if (state.icon) {
state.icon.className = mergeClasses(menuItemClassNames.icon, iconBaseStyles, state.icon.className);
}
if (state.submenuIndicator) {
state.submenuIndicator.className = mergeClasses(menuItemClassNames.submenuIndicator, submenuIndicatorBaseStyles, state.submenuIndicator.className, multiline && multilineStyles.submenuIndicator);
}
if (state.subText) {
state.subText.className = mergeClasses(menuItemClassNames.subText, state.disabled && subTextStyles.disabled, state.subText.className, subtextBaseStyles);
}
useCheckmarkStyles_unstable(state);
return state;
};

File diff suppressed because one or more lines are too long