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 { useCard_unstable } from './useCard';
import { renderCard_unstable } from './renderCard';
import { useCardStyles_unstable } from './useCardStyles.styles';
import { useCardContextValue } from './useCardContextValue';
import { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';
/**
* A card provides scaffolding for hosting actions and content for a single topic.
*/ export const Card = /*#__PURE__*/ React.forwardRef((props, ref)=>{
const state = useCard_unstable(props, ref);
const cardContextValue = useCardContextValue(state);
useCardStyles_unstable(state);
useCustomStyleHook_unstable('useCardStyles_unstable')(state);
return renderCard_unstable(state, cardContextValue);
});
Card.displayName = 'Card';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Card/Card.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useCard_unstable } from './useCard';\nimport { renderCard_unstable } from './renderCard';\nimport { useCardStyles_unstable } from './useCardStyles.styles';\nimport type { CardProps } from './Card.types';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\nimport { useCardContextValue } from './useCardContextValue';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\n\n/**\n * A card provides scaffolding for hosting actions and content for a single topic.\n */\nexport const Card: ForwardRefComponent<CardProps> = React.forwardRef<HTMLDivElement>((props, ref) => {\n const state = useCard_unstable(props, ref);\n const cardContextValue = useCardContextValue(state);\n\n useCardStyles_unstable(state);\n\n useCustomStyleHook_unstable('useCardStyles_unstable')(state);\n\n return renderCard_unstable(state, cardContextValue);\n});\n\nCard.displayName = 'Card';\n"],"names":["React","useCard_unstable","renderCard_unstable","useCardStyles_unstable","useCardContextValue","useCustomStyleHook_unstable","Card","forwardRef","props","ref","state","cardContextValue","displayName"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,gBAAgB,QAAQ,YAAY;AAC7C,SAASC,mBAAmB,QAAQ,eAAe;AACnD,SAASC,sBAAsB,QAAQ,yBAAyB;AAGhE,SAASC,mBAAmB,QAAQ,wBAAwB;AAC5D,SAASC,2BAA2B,QAAQ,kCAAkC;AAE9E;;CAEC,GACD,OAAO,MAAMC,qBAAuCN,MAAMO,UAAU,CAAiB,CAACC,OAAOC;IAC3F,MAAMC,QAAQT,iBAAiBO,OAAOC;IACtC,MAAME,mBAAmBP,oBAAoBM;IAE7CP,uBAAuBO;IAEvBL,4BAA4B,0BAA0BK;IAEtD,OAAOR,oBAAoBQ,OAAOC;AACpC,GAAG;AAEHL,KAAKM,WAAW,GAAG"}

View File

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

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Card/Card.types.ts"],"sourcesContent":["import * as React from 'react';\nimport type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';\n\n/**\n * Card selected event type\n *\n * This event is fired when a selectable card changes its selection state.\n */\nexport type CardOnSelectionChangeEvent = React.MouseEvent | React.KeyboardEvent | React.ChangeEvent;\n\n/**\n * Data sent from the selection events on a selectable card.\n */\nexport type CardOnSelectData = {\n selected: boolean;\n};\n\n/**\n * Data shared between card components\n */\nexport interface CardContextValue {\n selectableA11yProps: {\n referenceId?: string;\n setReferenceId: (referenceId: string) => void;\n referenceLabel?: string;\n setReferenceLabel: (referenceLabel: string) => void;\n };\n}\n\n/**\n * Slots available in the Card component.\n */\nexport type CardSlots = {\n /**\n * Root element of the component.\n */\n root: Slot<'div'>;\n\n /**\n * Floating action that can be rendered on the top-right of a card. Often used together with\n * `selected`, `defaultSelected`, and `onSelectionChange` props\n */\n floatingAction?: Slot<'div'>;\n\n /**\n * The internal checkbox element that renders when the card is selectable.\n */\n checkbox?: Slot<'input'>;\n};\n\n/**\n * Card component props.\n */\nexport type CardProps = ComponentProps<CardSlots> & {\n /**\n * Sets the appearance of the card.\n *\n * `filled`\n * The card will have a shadow, border and background color.\n *\n * `filled-alternative`\n * This appearance is similar to `filled`, but the background color will be a little darker.\n *\n * `outline`\n * This appearance is similar to `filled`, but the background color will be transparent and no shadow applied.\n *\n * `subtle`\n * This appearance is similar to `filled-alternative`, but no border is applied.\n *\n * @default 'filled'\n */\n appearance?: 'filled' | 'filled-alternative' | 'outline' | 'subtle';\n\n /**\n * Sets the focus behavior for the card.\n *\n * `off`\n * The card will not focusable.\n *\n * `no-tab`\n * This behaviour traps the focus inside of the Card when pressing the Enter key and will only release focus when\n * pressing the Escape key.\n *\n * `tab-exit`\n * This behaviour traps the focus inside of the Card when pressing the Enter key but will release focus when pressing\n * the Tab key on the last inner element.\n *\n * `tab-only`\n * This behaviour will cycle through all elements inside of the Card when pressing the Tab key and then release focus\n * after the last inner element.\n *\n * @default 'off'\n */\n focusMode?: 'off' | 'no-tab' | 'tab-exit' | 'tab-only';\n\n /**\n * Defines the orientation of the card.\n *\n * @default 'vertical'\n */\n orientation?: 'horizontal' | 'vertical';\n\n /**\n * Controls the card's border radius and padding between inner elements.\n *\n * @default 'medium'\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Defines the controlled selected state of the card.\n *\n * @default false\n */\n selected?: boolean;\n\n /**\n * Defines whether the card is initially in a selected state when rendered.\n *\n * @default false\n */\n defaultSelected?: boolean;\n\n /**\n * Callback to be called when the selected state value changes.\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- can't change type of existing callback\n onSelectionChange?: (event: CardOnSelectionChangeEvent, data: CardOnSelectData) => void;\n\n /**\n * Makes the card and card selection disabled (not propagated to children).\n *\n * @default false\n */\n disabled?: boolean;\n};\n\nexport type CardBaseProps = Omit<CardProps, 'appearance' | 'orientation' | 'size'>;\n\n/**\n * State used in rendering Card.\n */\nexport type CardState = ComponentState<CardSlots> &\n CardContextValue &\n Required<\n Pick<CardProps, 'appearance' | 'orientation' | 'size'> & {\n /**\n * Represents a card that contains interactive events (MouseEvents) or is a button/a tag.\n *\n * @default false\n */\n interactive: boolean;\n\n /**\n * Represents a selectable card.\n *\n * @default false\n */\n selectable: boolean;\n\n /**\n * Defines whether the card is currently selected.\n *\n * @default false\n */\n selected: boolean;\n\n /**\n * Defines whether the card internal checkbox is currently focused.\n *\n * @default false\n */\n selectFocused: boolean;\n\n /**\n * Defines whether the card is disabled.\n *\n * @default false\n */\n disabled: boolean;\n }\n >;\n\nexport type CardBaseState = Omit<CardState, 'appearance' | 'orientation' | 'size'>;\n"],"names":["React"],"mappings":"AAAA,YAAYA,WAAW,QAAQ"}

View File

@@ -0,0 +1,24 @@
'use client';
import * as React from 'react';
const cardContext = React.createContext(undefined);
/**
* @internal
*/ export const cardContextDefaultValue = {
selectableA11yProps: {
referenceId: undefined,
setReferenceId () {
/* Noop */ },
referenceLabel: undefined,
setReferenceLabel () {
/* Noop */ }
}
};
/**
* @internal
*/ export const CardProvider = cardContext.Provider;
/**
* @internal
*/ export const useCardContext_unstable = ()=>{
var _React_useContext;
return (_React_useContext = React.useContext(cardContext)) !== null && _React_useContext !== void 0 ? _React_useContext : cardContextDefaultValue;
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Card/CardContext.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { CardContextValue } from './Card.types';\n\nconst cardContext = React.createContext<CardContextValue | undefined>(undefined);\n\n/**\n * @internal\n */\nexport const cardContextDefaultValue: CardContextValue = {\n selectableA11yProps: {\n referenceId: undefined,\n setReferenceId() {\n /* Noop */\n },\n referenceLabel: undefined,\n setReferenceLabel() {\n /* Noop */\n },\n },\n};\n\n/**\n * @internal\n */\nexport const CardProvider = cardContext.Provider;\n\n/**\n * @internal\n */\nexport const useCardContext_unstable = (): CardContextValue => React.useContext(cardContext) ?? cardContextDefaultValue;\n"],"names":["React","cardContext","createContext","undefined","cardContextDefaultValue","selectableA11yProps","referenceId","setReferenceId","referenceLabel","setReferenceLabel","CardProvider","Provider","useCardContext_unstable","useContext"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAG/B,MAAMC,cAAcD,MAAME,aAAa,CAA+BC;AAEtE;;CAEC,GACD,OAAO,MAAMC,0BAA4C;IACvDC,qBAAqB;QACnBC,aAAaH;QACbI;QACE,QAAQ,GACV;QACAC,gBAAgBL;QAChBM;QACE,QAAQ,GACV;IACF;AACF,EAAE;AAEF;;CAEC,GACD,OAAO,MAAMC,eAAeT,YAAYU,QAAQ,CAAC;AAEjD;;CAEC,GACD,OAAO,MAAMC,0BAA0B;QAAwBZ;WAAAA,CAAAA,oBAAAA,MAAMa,UAAU,CAACZ,0BAAjBD,+BAAAA,oBAAiCI;EAAwB"}

View File

@@ -0,0 +1,5 @@
export { Card } from './Card';
export { CardProvider, cardContextDefaultValue, useCardContext_unstable } from './CardContext';
export { renderCard_unstable } from './renderCard';
export { useCard_unstable, useCardBase_unstable } from './useCard';
export { cardCSSVars, cardClassNames, useCardStyles_unstable } from './useCardStyles.styles';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Card/index.ts"],"sourcesContent":["export { Card } from './Card';\nexport type {\n CardBaseProps,\n CardBaseState,\n CardContextValue,\n CardOnSelectData,\n CardOnSelectionChangeEvent,\n CardProps,\n CardSlots,\n CardState,\n} from './Card.types';\nexport { CardProvider, cardContextDefaultValue, useCardContext_unstable } from './CardContext';\nexport { renderCard_unstable } from './renderCard';\nexport { useCard_unstable, useCardBase_unstable } from './useCard';\nexport { cardCSSVars, cardClassNames, useCardStyles_unstable } from './useCardStyles.styles';\n"],"names":["Card","CardProvider","cardContextDefaultValue","useCardContext_unstable","renderCard_unstable","useCard_unstable","useCardBase_unstable","cardCSSVars","cardClassNames","useCardStyles_unstable"],"mappings":"AAAA,SAASA,IAAI,QAAQ,SAAS;AAW9B,SAASC,YAAY,EAAEC,uBAAuB,EAAEC,uBAAuB,QAAQ,gBAAgB;AAC/F,SAASC,mBAAmB,QAAQ,eAAe;AACnD,SAASC,gBAAgB,EAAEC,oBAAoB,QAAQ,YAAY;AACnE,SAASC,WAAW,EAAEC,cAAc,EAAEC,sBAAsB,QAAQ,yBAAyB"}

View File

@@ -0,0 +1,18 @@
import { jsx as _jsx, jsxs as _jsxs } from "@fluentui/react-jsx-runtime/jsx-runtime";
import { assertSlots } from '@fluentui/react-utilities';
import { CardProvider } from './CardContext';
/**
* Render the final JSX of Card.
*/ export const renderCard_unstable = (state, cardContextValue)=>{
assertSlots(state);
return /*#__PURE__*/ _jsx(state.root, {
children: /*#__PURE__*/ _jsxs(CardProvider, {
value: cardContextValue,
children: [
state.checkbox ? /*#__PURE__*/ _jsx(state.checkbox, {}) : null,
state.floatingAction ? /*#__PURE__*/ _jsx(state.floatingAction, {}) : null,
state.root.children
]
})
});
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Card/renderCard.tsx"],"sourcesContent":["/** @jsxRuntime automatic */\n/** @jsxImportSource @fluentui/react-jsx-runtime */\n\nimport { assertSlots } from '@fluentui/react-utilities';\nimport type { JSXElement } from '@fluentui/react-utilities';\nimport type { CardContextValue, CardSlots, CardBaseState } from './Card.types';\nimport { CardProvider } from './CardContext';\n\n/**\n * Render the final JSX of Card.\n */\nexport const renderCard_unstable = (state: CardBaseState, cardContextValue: CardContextValue): JSXElement => {\n assertSlots<CardSlots>(state);\n\n return (\n <state.root>\n <CardProvider value={cardContextValue}>\n {state.checkbox ? <state.checkbox /> : null}\n {state.floatingAction ? <state.floatingAction /> : null}\n {state.root.children}\n </CardProvider>\n </state.root>\n );\n};\n"],"names":["assertSlots","CardProvider","renderCard_unstable","state","cardContextValue","root","value","checkbox","floatingAction","children"],"mappings":"AAAA,0BAA0B,GAC1B,iDAAiD;AAEjD,SAASA,WAAW,QAAQ,4BAA4B;AAGxD,SAASC,YAAY,QAAQ,gBAAgB;AAE7C;;CAEC,GACD,OAAO,MAAMC,sBAAsB,CAACC,OAAsBC;IACxDJ,YAAuBG;IAEvB,qBACE,KAACA,MAAME,IAAI;kBACT,cAAA,MAACJ;YAAaK,OAAOF;;gBAClBD,MAAMI,QAAQ,iBAAG,KAACJ,MAAMI,QAAQ,QAAM;gBACtCJ,MAAMK,cAAc,iBAAG,KAACL,MAAMK,cAAc,QAAM;gBAClDL,MAAME,IAAI,CAACI,QAAQ;;;;AAI5B,EAAE"}

View File

@@ -0,0 +1,132 @@
'use client';
import * as React from 'react';
import { getIntrinsicElementProps, useMergedRefs, slot } from '@fluentui/react-utilities';
import { useFocusableGroup, useFocusWithin } from '@fluentui/react-tabster';
import { useCardSelectable } from './useCardSelectable';
import { cardContextDefaultValue } from './CardContext';
const focusMap = {
off: undefined,
'no-tab': 'limited-trap-focus',
'tab-exit': 'limited',
'tab-only': 'unlimited'
};
/**
* Create the state for interactive cards.
*
* This internal hook defines if the card is interactive
* and control focus properties based on that.
*
* @param props - props from this instance of Card
*/ const useCardInteractive = ({ focusMode: initialFocusMode, disabled = false, ...props })=>{
const interactive = [
'onClick',
'onDoubleClick',
'onMouseUp',
'onMouseDown',
'onPointerUp',
'onPointerDown',
'onTouchStart',
'onTouchEnd',
'onDragStart',
'onDragEnd'
].some((prop)=>props[prop]);
// default focusMode to tab-only when interactive, and off when not
const focusMode = initialFocusMode !== null && initialFocusMode !== void 0 ? initialFocusMode : interactive ? 'no-tab' : 'off';
const groupperAttrs = useFocusableGroup({
tabBehavior: focusMap[focusMode]
});
if (disabled) {
return {
interactive: false,
focusAttributes: null
};
}
if (focusMode === 'off') {
return {
interactive,
focusAttributes: null
};
}
return {
interactive,
focusAttributes: {
...groupperAttrs,
tabIndex: 0
}
};
};
/**
* Create the state required to render Card.
*
* The returned state can be modified with hooks such as useCardStyles_unstable,
* before being passed to renderCard_unstable.
*
* @param props - props from this instance of Card
* @param ref - reference to the root element of Card
*/ export const useCard_unstable = (props, ref)=>{
const { appearance = 'filled', orientation = 'vertical', size = 'medium', ...cardProps } = props;
const state = useCardBase_unstable(cardProps, ref);
return {
...state,
appearance,
orientation,
size
};
};
/**
* Base hook for Card component, which manages state related to interactivity, selection,
* focus management, ARIA attributes, and slot structure without design props.
*
* @param props - props from this instance of Card
* @param ref - reference to the root element of Card
*/ export const useCardBase_unstable = (props, ref)=>{
const { disabled = false, ...restProps } = props;
const [referenceId, setReferenceId] = React.useState(cardContextDefaultValue.selectableA11yProps.referenceId);
const [referenceLabel, setReferenceLabel] = React.useState(cardContextDefaultValue.selectableA11yProps.referenceId);
const cardBaseRef = useFocusWithin();
const { selectable, selected, selectableCardProps, selectFocused, checkboxSlot, floatingActionSlot } = useCardSelectable(props, {
referenceId,
referenceLabel
}, cardBaseRef);
const cardRef = useMergedRefs(cardBaseRef, ref);
const { interactive, focusAttributes } = useCardInteractive(props);
let cardRootProps = {
...!selectable ? focusAttributes : null,
...restProps,
...selectableCardProps
};
if (disabled) {
cardRootProps = {
...restProps,
'aria-disabled': true,
onClick: undefined
};
}
return {
interactive,
selectable,
selectFocused,
selected,
disabled,
selectableA11yProps: {
setReferenceId,
referenceId,
referenceLabel,
setReferenceLabel
},
components: {
root: 'div',
floatingAction: 'div',
checkbox: 'input'
},
root: slot.always(getIntrinsicElementProps('div', {
ref: cardRef,
role: 'group',
...cardRootProps
}), {
elementType: 'div'
}),
floatingAction: floatingActionSlot,
checkbox: checkboxSlot
};
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
export function useCardContextValue({ selectableA11yProps }) {
return {
selectableA11yProps
};
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/Card/useCardContextValue.ts"],"sourcesContent":["import type { CardContextValue, CardState } from './Card.types';\n\nexport function useCardContextValue({ selectableA11yProps }: CardState): CardContextValue {\n return { selectableA11yProps };\n}\n"],"names":["useCardContextValue","selectableA11yProps"],"mappings":"AAEA,OAAO,SAASA,oBAAoB,EAAEC,mBAAmB,EAAa;IACpE,OAAO;QAAEA;IAAoB;AAC/B"}

View File

@@ -0,0 +1,141 @@
'use client';
import * as React from 'react';
import { mergeCallbacks, slot, useControllableState } from '@fluentui/react-utilities';
import { Enter } from '@fluentui/keyboard-keys';
import { useFocusFinders } from '@fluentui/react-tabster';
/**
* Create the state related to selectable cards.
*
* This internal hook controls all the logic for selectable cards and is
* intended to be used alongside with useCard_unstable.
*
* @internal
* @param props - props from this instance of Card
* @param a11yProps - accessibility props shared between elements of the card
* @param cardRef - reference to the root element of Card
*/ export const useCardSelectable = (props, { referenceLabel, referenceId }, cardRef)=>{
const { checkbox = {}, onSelectionChange, floatingAction, onClick, onKeyDown, disabled } = props;
const { findAllFocusable } = useFocusFinders();
const checkboxRef = React.useRef(null);
const [selected, setSelected] = useControllableState({
state: props.selected,
defaultState: props.defaultSelected,
initialState: false
});
const selectable = [
props.selected,
props.defaultSelected,
onSelectionChange
].some((prop)=>typeof prop !== 'undefined');
const [selectFocused, setSelectFocused] = React.useState(false);
const shouldRestrictTriggerAction = React.useCallback((event)=>{
if (!cardRef.current) {
return false;
}
const focusableElements = findAllFocusable(cardRef.current);
const target = event.target;
const isElementInFocusableGroup = focusableElements.some((element)=>element.contains(target));
const isCheckboxSlot = (checkboxRef === null || checkboxRef === void 0 ? void 0 : checkboxRef.current) === target;
return isElementInFocusableGroup && !isCheckboxSlot;
}, [
cardRef,
findAllFocusable
]);
const onChangeHandler = React.useCallback((event)=>{
if (disabled || shouldRestrictTriggerAction(event)) {
return;
}
const newCheckedValue = !selected;
setSelected(newCheckedValue);
if (onSelectionChange) {
onSelectionChange(event, {
selected: newCheckedValue
});
}
}, [
disabled,
onSelectionChange,
selected,
setSelected,
shouldRestrictTriggerAction
]);
const onKeyDownHandler = React.useCallback((event)=>{
if ([
Enter
].includes(event.key)) {
event.preventDefault();
onChangeHandler(event);
}
}, [
onChangeHandler
]);
const checkboxSlot = React.useMemo(()=>{
if (!selectable || floatingAction) {
return;
}
const selectableCheckboxProps = {};
if (referenceId) {
selectableCheckboxProps['aria-labelledby'] = referenceId;
} else if (referenceLabel) {
selectableCheckboxProps['aria-label'] = referenceLabel;
}
return slot.optional(checkbox, {
defaultProps: {
ref: checkboxRef,
type: 'checkbox',
checked: selected,
disabled,
onChange: (event)=>onChangeHandler(event),
onFocus: ()=>setSelectFocused(true),
onBlur: ()=>setSelectFocused(false),
...selectableCheckboxProps
},
elementType: 'input'
});
}, [
checkbox,
disabled,
floatingAction,
selected,
selectable,
onChangeHandler,
referenceId,
referenceLabel
]);
const floatingActionSlot = React.useMemo(()=>{
if (!floatingAction) {
return;
}
return slot.optional(floatingAction, {
defaultProps: {
ref: checkboxRef
},
elementType: 'div'
});
}, [
floatingAction
]);
const selectableCardProps = React.useMemo(()=>{
if (!selectable) {
return null;
}
return {
onClick: mergeCallbacks(onClick, onChangeHandler),
onKeyDown: mergeCallbacks(onKeyDown, onKeyDownHandler)
};
}, [
selectable,
onChangeHandler,
onClick,
onKeyDown,
onKeyDownHandler
]);
return {
selected,
selectable,
selectFocused,
selectableCardProps,
checkboxSlot,
floatingActionSlot
};
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,499 @@
'use client';
import * as React from 'react';
import { shorthands, __styles, mergeClasses, __resetStyles } from '@griffel/react';
import { tokens } from '@fluentui/react-theme';
import { textClassNames } from '@fluentui/react-text';
import { createFocusOutlineStyle } from '@fluentui/react-tabster';
import { cardPreviewClassNames } from '../CardPreview/useCardPreviewStyles.styles';
import { cardHeaderClassNames } from '../CardHeader/useCardHeaderStyles.styles';
import { cardFooterClassNames } from '../CardFooter/useCardFooterStyles.styles';
/**
* Static CSS class names used internally for the component slots.
*/
export const cardClassNames = {
root: 'fui-Card',
floatingAction: 'fui-Card__floatingAction',
checkbox: 'fui-Card__checkbox'
};
/**
* CSS variable names used internally for uniform styling in Card.
*/
export const cardCSSVars = {
cardSizeVar: '--fui-Card--size',
cardBorderRadiusVar: '--fui-Card--border-radius'
};
const focusOutlineStyle = {
outlineRadius: `var(${cardCSSVars.cardBorderRadiusVar})`,
outlineWidth: tokens.strokeWidthThick,
outlineOffset: '-2px'
};
const useCardResetStyles = /*#__PURE__*/__resetStyles("rfxo2k2", "rgle7w9", [".rfxo2k2{overflow:hidden;border-radius:var(--fui-Card--border-radius);padding:var(--fui-Card--size);gap:var(--fui-Card--size);display:flex;position:relative;box-sizing:border-box;color:var(--colorNeutralForeground1);}", ".rfxo2k2::after{position:absolute;top:0;left:0;right:0;bottom:0;content:\"\";pointer-events:none;border-top-style:solid;border-right-style:solid;border-bottom-style:solid;border-left-style:solid;border-top-width:var(--strokeWidthThin);border-right-width:var(--strokeWidthThin);border-bottom-width:var(--strokeWidthThin);border-left-width:var(--strokeWidthThin);border-radius:var(--fui-Card--border-radius);}", ".rfxo2k2>.fui-CardHeader,.rfxo2k2>.fui-CardFooter{flex-shrink:0;}", ".rgle7w9{overflow:hidden;border-radius:var(--fui-Card--border-radius);padding:var(--fui-Card--size);gap:var(--fui-Card--size);display:flex;position:relative;box-sizing:border-box;color:var(--colorNeutralForeground1);}", ".rgle7w9::after{position:absolute;top:0;right:0;left:0;bottom:0;content:\"\";pointer-events:none;border-top-style:solid;border-left-style:solid;border-bottom-style:solid;border-right-style:solid;border-top-width:var(--strokeWidthThin);border-left-width:var(--strokeWidthThin);border-bottom-width:var(--strokeWidthThin);border-right-width:var(--strokeWidthThin);border-radius:var(--fui-Card--border-radius);}", ".rgle7w9>.fui-CardHeader,.rgle7w9>.fui-CardFooter{flex-shrink:0;}"]);
const disabledStyles = {
cursor: 'not-allowed',
userSelect: 'none',
color: tokens.colorNeutralForegroundDisabled,
backgroundColor: tokens.colorNeutralBackgroundDisabled,
boxShadow: tokens.shadow2,
... /*#__PURE__*/shorthands.borderColor(tokens.colorNeutralStrokeDisabled),
'::before': {
content: '""',
position: 'absolute',
inset: 0,
zIndex: `calc(${tokens.zIndexContent} + 1)`
},
'::after': {
... /*#__PURE__*/shorthands.borderColor(tokens.colorNeutralStrokeDisabled)
}
};
const useCardStyles = /*#__PURE__*/__styles({
focused: {
Brovlpu: "ftqa4ok",
B486eqv: "f2hkw1w",
B8q5s1w: "f8hki3x",
Bci5o5g: ["f1d2448m", "ffh67wi"],
n8qw10: "f1bjia2o",
Bdrgwmp: ["ffh67wi", "f1d2448m"],
Bqhya38: "f1j6vpng",
Bwxa6fj: ["f1pniga2", "f1ffjurs"],
Bdhvstf: "f987i1v",
B7zbvrb: ["f1ffjurs", "f1pniga2"],
Bm4h7ae: "f15bsgw9",
B7ys5i9: "f14e48fq",
Busjfv9: "f18yb2kv",
Bhk32uz: "fd6o370",
f6g5ot: 0,
Boxcth7: 0,
Bhdgwq3: 0,
hgwjuy: 0,
Bshpdp8: 0,
Bsom6fd: 0,
Blkhhs4: 0,
Bonggc9: 0,
Ddfuxk: 0,
i03rao: 0,
kclons: 0,
clg4pj: 0,
Bpqj9nj: 0,
B6dhp37: 0,
Bf4ptjt: 0,
Bqtpl0w: 0,
i4rwgc: "fpqizxz",
Dah5zi: 0,
B1tsrr9: 0,
qqdqy8: 0,
Bkh64rk: 0,
e3fwne: "fnd8nzh",
J0r882: "f15fr7a0",
Bule8hv: ["fwsq40z", "fy0y4wt"],
Bjwuhne: "f34ld9f",
Ghsupd: ["fy0y4wt", "fwsq40z"]
},
selectableFocused: {
Brovlpu: "ftqa4ok",
B486eqv: "f2hkw1w",
Bssx7fj: "f1b1k54r",
uh7if5: ["f4ne723", "fqqcjud"],
clntm0: "fh7aioi",
Dlk2r6: ["fqqcjud", "f4ne723"],
h6p2u: "f1ufm4qn",
I6qiy5: ["f1qnwcb4", "fgrk5zm"],
yzno9d: "fi52z01",
By0wis0: ["fgrk5zm", "f1qnwcb4"],
B2j2mmj: "ffht0p2",
wigs8: "f1p0ul1q",
pbfy6t: "f1c901ms",
B0v4ure: "f1alokd7",
Byrf0fs: 0,
Bsiemmq: 0,
Bwckmig: 0,
skfxo0: 0,
Iidy0u: 0,
B98u21t: 0,
Bvwlmkc: 0,
jo1ztg: 0,
Ba1iezr: 0,
Blmvk6g: 0,
B24cy0v: 0,
Bil7v7r: 0,
Br3gin4: 0,
nr063g: 0,
ghq09: 0,
Bbgo44z: 0,
Bseh09z: "f1i978nd",
az1dzo: 0,
Ba3ybja: 0,
B6352mv: 0,
vppk2z: 0,
Biaj6j7: "f1nh8hsq",
B2pnrqr: "f1amxum7",
B29w5g4: ["f1cec8w7", "f554mv0"],
Bhhzhcn: "f1sj6kbr",
Bec0n69: ["f554mv0", "f1cec8w7"]
},
orientationHorizontal: {
Beiy3e4: "f1063pyq",
Bt984gj: "f122n59",
Binpb3b: "ftrw7vg",
qrt8p2: "f18opajm",
k6ws3r: ["f13002it", "fqo182t"],
Btcwela: ["f18yna97", "f1kd6wh7"],
Fer9m8: "f4i4759"
},
orientationVertical: {
Beiy3e4: "f1vx9l62",
B5nvv7i: ["f14k419y", "f1fgo9fz"],
Baxg94k: ["f1fgo9fz", "f14k419y"],
tn21ii: "fvqmfsm",
B0ud6bj: "f3am6yf",
Bgdo4j: "f1r5wgso"
},
sizeSmall: {
B7balbw: "f1pi9uxy",
B1h88n7: "f1h1zgly"
},
sizeMedium: {
B7balbw: "frsmuga",
B1h88n7: "fuldkky"
},
sizeLarge: {
B7balbw: "f1qua4xo",
B1h88n7: "fimkt6v"
},
interactive: {
rhjd8f: "f1epqm3e"
},
filled: {
De3pzq: "fxugw4r",
E5pizo: "f1whvlc6",
B0n5ga8: "f16gxe2i",
s924m2: ["fpgykix", "fzybk4o"],
B1q35kw: "f1osi826",
Gp14am: ["fzybk4o", "fpgykix"]
},
filledInteractive: {
Bceei9c: "f1k6fduh",
De3pzq: "fxugw4r",
E5pizo: "f1whvlc6",
B0n5ga8: "f16gxe2i",
s924m2: ["fpgykix", "fzybk4o"],
B1q35kw: "f1osi826",
Gp14am: ["fzybk4o", "fpgykix"],
Bi91k9c: "feu1g3u",
Jwef8y: "f1knas48",
Bvxd0ez: "f1m145df",
ecr2s2: "fb40n2d"
},
filledInteractiveSelected: {
De3pzq: "f1nfm20t",
B0n5ga8: "f16eln5f",
s924m2: ["fa2okxs", "fg4zq3l"],
B1q35kw: "ff6932p",
Gp14am: ["fg4zq3l", "fa2okxs"],
Bi91k9c: "fx9teim",
Jwef8y: "f1kz6goq"
},
filledAlternative: {
De3pzq: "f1dmdbja",
E5pizo: "f1whvlc6",
B0n5ga8: "f16gxe2i",
s924m2: ["fpgykix", "fzybk4o"],
B1q35kw: "f1osi826",
Gp14am: ["fzybk4o", "fpgykix"]
},
filledAlternativeInteractive: {
Bceei9c: "f1k6fduh",
De3pzq: "f1dmdbja",
E5pizo: "f1whvlc6",
B0n5ga8: "f16gxe2i",
s924m2: ["fpgykix", "fzybk4o"],
B1q35kw: "f1osi826",
Gp14am: ["fzybk4o", "fpgykix"],
Bi91k9c: "fnwyq0v",
Jwef8y: "f1uvynv3",
Bvxd0ez: "f1m145df",
ecr2s2: "f1yhgkbh"
},
filledAlternativeInteractiveSelected: {
De3pzq: "fjxa0vh",
B0n5ga8: "f16eln5f",
s924m2: ["fa2okxs", "fg4zq3l"],
B1q35kw: "ff6932p",
Gp14am: ["fg4zq3l", "fa2okxs"],
Bi91k9c: "f1luvkty",
Jwef8y: "fehi0vp"
},
outline: {
De3pzq: "f1c21dwh",
E5pizo: "f1couhl3",
B0n5ga8: "ft83z1f",
s924m2: ["f1g4150c", "f192dr6e"],
B1q35kw: "f1qnawh6",
Gp14am: ["f192dr6e", "f1g4150c"]
},
outlineInteractive: {
Bceei9c: "f1k6fduh",
De3pzq: "f1c21dwh",
E5pizo: "f1couhl3",
B0n5ga8: "ft83z1f",
s924m2: ["f1g4150c", "f192dr6e"],
B1q35kw: "f1qnawh6",
Gp14am: ["f192dr6e", "f1g4150c"],
Bi91k9c: "feu1g3u",
Jwef8y: "fjxutwb",
Be0v6ae: "f1llr77y",
B5kxglz: ["fzk0khw", "fjj8tog"],
B3pwyw6: "fb1u8ub",
Bymgtzf: ["fjj8tog", "fzk0khw"],
ecr2s2: "fophhak",
dmfk: "f1uohb70",
B4ofi8: ["f1jm7v1n", "f1bus3rq"],
jgq6uv: "f1fbu7rr",
Baxewws: ["f1bus3rq", "f1jm7v1n"]
},
outlineInteractiveSelected: {
De3pzq: "f1q9pm1r",
B0n5ga8: "f16eln5f",
s924m2: ["fa2okxs", "fg4zq3l"],
B1q35kw: "ff6932p",
Gp14am: ["fg4zq3l", "fa2okxs"],
Bi91k9c: "fx9teim",
Jwef8y: "fg59vm4"
},
outlineDisabled: {
De3pzq: "f1c21dwh",
E5pizo: "f1couhl3",
g2u3we: "f1jj8ep1",
h3c5rm: ["f15xbau", "fy0fskl"],
B9xav0g: "f4ikngz",
zhjwy3: ["fy0fskl", "f15xbau"],
ezxybo: "f1ls5moo",
wc7uws: "f1qiza15",
B0n5ga8: "f13dj02",
s924m2: ["f9wngki", "f17v59j0"],
B1q35kw: "f1vxzwsp",
Gp14am: ["f17v59j0", "f9wngki"]
},
subtle: {
De3pzq: "fhovq9v",
E5pizo: "f1couhl3",
B0n5ga8: "f16gxe2i",
s924m2: ["fpgykix", "fzybk4o"],
B1q35kw: "f1osi826",
Gp14am: ["fzybk4o", "fpgykix"]
},
subtleInteractive: {
Bceei9c: "f1k6fduh",
De3pzq: "fhovq9v",
E5pizo: "f1couhl3",
B0n5ga8: "f16gxe2i",
s924m2: ["fpgykix", "fzybk4o"],
B1q35kw: "f1osi826",
Gp14am: ["fzybk4o", "fpgykix"],
Bi91k9c: "feu1g3u",
Jwef8y: "f1t94bn6",
ecr2s2: "f1wfn5kd"
},
subtleInteractiveSelected: {
De3pzq: "fq5gl1p",
B0n5ga8: "f16eln5f",
s924m2: ["fa2okxs", "fg4zq3l"],
B1q35kw: "ff6932p",
Gp14am: ["fg4zq3l", "fa2okxs"],
Bi91k9c: "fx9teim",
Jwef8y: "f1uqaxdt"
},
highContrastSelected: {
B8gzw0y: "f1h3a8gf",
By8wz76: "f1nz3ub2",
B7iucu3: "fqc85l4",
Boo9lyk: "f1ucc5z8",
sga51p: "fyj59f4",
qj1yg9: ["f19v95gn", "f1n69f6i"],
B8acmzm: "f16q7dot",
Gezqo6: ["f1n69f6i", "f19v95gn"]
},
highContrastInteractive: {
waf3gn: "f1quqgnd",
B96h8j5: "f193utb4",
Bpd3jnq: "f1io67iv",
uhbujs: "f3n01jk",
sga51p: "fyj59f4",
qj1yg9: ["f19v95gn", "f1n69f6i"],
B8acmzm: "f16q7dot",
Gezqo6: ["f1n69f6i", "f19v95gn"]
},
select: {
qhf8xq: "f1euv43f",
Bhzewxz: "fqclxi7",
j35jbq: ["fiv86kb", "f36uhnt"],
Bj3rh1h: "fom9my7"
},
hiddenCheckbox: {
B68tc82: 0,
Bmxbyg5: 0,
Bpg54ce: "f1a3p1vp",
a9b677: "frkrog8",
Bqenvij: "f1mpe4l3",
qhf8xq: "f1euv43f",
Bh84pgu: "fmf1zke",
Bgl5zvf: "f1wch0ki",
Huce71: "fz5stix"
},
disabled: {
Bceei9c: "fdrzuqr",
famaaq: "f1xqy1su",
sj55zd: "f1s2aq7o",
De3pzq: "f1bg9a2p",
E5pizo: "fyed02w",
g2u3we: "f1jj8ep1",
h3c5rm: ["f15xbau", "fy0fskl"],
B9xav0g: "f4ikngz",
zhjwy3: ["fy0fskl", "f15xbau"],
Ftih45: "f1wl9k8s",
Brfgrao: "f1j7ml58",
lawp4y: 0,
Fbdkly: 0,
mdwyqc: 0,
Bciustq: 0,
gc50h5: "f13vvzas",
Ehzi8l: "f198lalb",
B0n5ga8: "f13dj02",
s924m2: ["f9wngki", "f17v59j0"],
B1q35kw: "f1vxzwsp",
Gp14am: ["f17v59j0", "f9wngki"],
Bikrtoi: "f11og98d",
G8qf51: "f1rg3h4v",
Brxh4y7: "fbm2y3b",
ezxybo: "f4yodeu",
wc7uws: "fcwfbwp",
gp3uxg: "f1repx37",
Fohawp: ["f1ybi8ct", "f1h4eg6q"],
Bxulg6k: "f18mejnb",
vcjq4m: ["f1h4eg6q", "f1ybi8ct"],
Bsqkqe9: "f1nift3m",
fskg1g: "f1wu3i8x",
iwiei9: 0,
Effecx: 0,
Bkt1b9m: 0,
jfmxvr: 0,
orauir: "f6v4vfa",
B2yd9ot: "folrdqs",
Fn9tzk: "f168z5yf",
Bv0wker: ["fpor7gj", "fzextn6"],
Bp2dl5b: "f1yaw79v",
pzn0iz: ["fzextn6", "fpor7gj"]
}
}, {
f: [".ftqa4ok:focus{outline-style:none;}"],
i: [".f2hkw1w:focus-visible{outline-style:none;}"],
d: [".f8hki3x[data-fui-focus-visible]{border-top-color:transparent;}", ".f1d2448m[data-fui-focus-visible]{border-right-color:transparent;}", ".ffh67wi[data-fui-focus-visible]{border-left-color:transparent;}", ".f1bjia2o[data-fui-focus-visible]{border-bottom-color:transparent;}", ".f15bsgw9[data-fui-focus-visible]::after{content:\"\";}", ".f14e48fq[data-fui-focus-visible]::after{position:absolute;}", ".f18yb2kv[data-fui-focus-visible]::after{pointer-events:none;}", ".fd6o370[data-fui-focus-visible]::after{z-index:1;}", [".fpqizxz[data-fui-focus-visible]::after{border:var(--strokeWidthThick) solid var(--colorStrokeFocus2);}", {
p: -2
}], [".fnd8nzh[data-fui-focus-visible]::after{border-radius:var(--fui-Card--border-radius);}", {
p: -1
}], ".f15fr7a0[data-fui-focus-visible]::after{top:calc(0px - var(--strokeWidthThick) - -2px);}", ".fwsq40z[data-fui-focus-visible]::after{right:calc(0px - var(--strokeWidthThick) - -2px);}", ".fy0y4wt[data-fui-focus-visible]::after{left:calc(0px - var(--strokeWidthThick) - -2px);}", ".f34ld9f[data-fui-focus-visible]::after{bottom:calc(0px - var(--strokeWidthThick) - -2px);}", ".f1b1k54r[data-fui-focus-within]:focus-within{border-top-color:transparent;}", ".f4ne723[data-fui-focus-within]:focus-within{border-right-color:transparent;}", ".fqqcjud[data-fui-focus-within]:focus-within{border-left-color:transparent;}", ".fh7aioi[data-fui-focus-within]:focus-within{border-bottom-color:transparent;}", ".ffht0p2[data-fui-focus-within]:focus-within::after{content:\"\";}", ".f1p0ul1q[data-fui-focus-within]:focus-within::after{position:absolute;}", ".f1c901ms[data-fui-focus-within]:focus-within::after{pointer-events:none;}", ".f1alokd7[data-fui-focus-within]:focus-within::after{z-index:1;}", [".f1i978nd[data-fui-focus-within]:focus-within::after{border:var(--strokeWidthThick) solid var(--colorStrokeFocus2);}", {
p: -2
}], [".f1nh8hsq[data-fui-focus-within]:focus-within::after{border-radius:var(--fui-Card--border-radius);}", {
p: -1
}], ".f1amxum7[data-fui-focus-within]:focus-within::after{top:calc(0px - var(--strokeWidthThick) - -2px);}", ".f1cec8w7[data-fui-focus-within]:focus-within::after{right:calc(0px - var(--strokeWidthThick) - -2px);}", ".f554mv0[data-fui-focus-within]:focus-within::after{left:calc(0px - var(--strokeWidthThick) - -2px);}", ".f1sj6kbr[data-fui-focus-within]:focus-within::after{bottom:calc(0px - var(--strokeWidthThick) - -2px);}", ".f1063pyq{flex-direction:row;}", ".f122n59{align-items:center;}", ".ftrw7vg>.fui-CardPreview{margin-top:calc(var(--fui-Card--size) * -1);}", ".f18opajm>.fui-CardPreview{margin-bottom:calc(var(--fui-Card--size) * -1);}", ".f13002it>:not([aria-hidden=\"true\"]).fui-CardPreview:first-of-type{margin-left:calc(var(--fui-Card--size) * -1);}", ".fqo182t>:not([aria-hidden=\"true\"]).fui-CardPreview:first-of-type{margin-right:calc(var(--fui-Card--size) * -1);}", ".f18yna97>:not([aria-hidden=\"true\"]).fui-CardPreview:last-of-type{margin-right:calc(var(--fui-Card--size) * -1);}", ".f1kd6wh7>:not([aria-hidden=\"true\"]).fui-CardPreview:last-of-type{margin-left:calc(var(--fui-Card--size) * -1);}", ".f4i4759>.fui-CardHeader:last-of-type,.f4i4759>.fui-CardFooter:last-of-type{flex-grow:1;}", ".f1vx9l62{flex-direction:column;}", ".f14k419y>.fui-CardPreview{margin-left:calc(var(--fui-Card--size) * -1);}", ".f1fgo9fz>.fui-CardPreview{margin-right:calc(var(--fui-Card--size) * -1);}", ".fvqmfsm>:not([aria-hidden=\"true\"]).fui-CardPreview:first-of-type{margin-top:calc(var(--fui-Card--size) * -1);}", ".f3am6yf>.fui-Card__floatingAction+.fui-CardPreview{margin-top:calc(var(--fui-Card--size) * -1);}", ".f1r5wgso>:not([aria-hidden=\"true\"]).fui-CardPreview:last-of-type{margin-bottom:calc(var(--fui-Card--size) * -1);}", ".f1pi9uxy{--fui-Card--size:8px;}", ".f1h1zgly{--fui-Card--border-radius:var(--borderRadiusSmall);}", ".frsmuga{--fui-Card--size:12px;}", ".fuldkky{--fui-Card--border-radius:var(--borderRadiusMedium);}", ".f1qua4xo{--fui-Card--size:16px;}", ".fimkt6v{--fui-Card--border-radius:var(--borderRadiusLarge);}", ".f1epqm3e .fui-Text{color:currentColor;}", ".fxugw4r{background-color:var(--colorNeutralBackground1);}", ".f1whvlc6{box-shadow:var(--shadow4);}", ".f16gxe2i::after{border-top-color:var(--colorTransparentStroke);}", ".fpgykix::after{border-right-color:var(--colorTransparentStroke);}", ".fzybk4o::after{border-left-color:var(--colorTransparentStroke);}", ".f1osi826::after{border-bottom-color:var(--colorTransparentStroke);}", ".f1k6fduh{cursor:pointer;}", ".f1nfm20t{background-color:var(--colorNeutralBackground1Selected);}", ".f16eln5f::after{border-top-color:var(--colorNeutralStroke1Selected);}", ".fa2okxs::after{border-right-color:var(--colorNeutralStroke1Selected);}", ".fg4zq3l::after{border-left-color:var(--colorNeutralStroke1Selected);}", ".ff6932p::after{border-bottom-color:var(--colorNeutralStroke1Selected);}", ".f1dmdbja{background-color:var(--colorNeutralBackground2);}", ".fjxa0vh{background-color:var(--colorNeutralBackground2Selected);}", ".f1c21dwh{background-color:var(--colorTransparentBackground);}", ".f1couhl3{box-shadow:none;}", ".ft83z1f::after{border-top-color:var(--colorNeutralStroke1);}", ".f1g4150c::after{border-right-color:var(--colorNeutralStroke1);}", ".f192dr6e::after{border-left-color:var(--colorNeutralStroke1);}", ".f1qnawh6::after{border-bottom-color:var(--colorNeutralStroke1);}", ".f1q9pm1r{background-color:var(--colorTransparentBackgroundSelected);}", ".f1jj8ep1{border-top-color:var(--colorNeutralStrokeDisabled);}", ".f15xbau{border-right-color:var(--colorNeutralStrokeDisabled);}", ".fy0fskl{border-left-color:var(--colorNeutralStrokeDisabled);}", ".f4ikngz{border-bottom-color:var(--colorNeutralStrokeDisabled);}", ".f13dj02::after{border-top-color:var(--colorNeutralStrokeDisabled);}", ".f9wngki::after{border-right-color:var(--colorNeutralStrokeDisabled);}", ".f17v59j0::after{border-left-color:var(--colorNeutralStrokeDisabled);}", ".f1vxzwsp::after{border-bottom-color:var(--colorNeutralStrokeDisabled);}", ".fhovq9v{background-color:var(--colorSubtleBackground);}", ".fq5gl1p{background-color:var(--colorSubtleBackgroundSelected);}", ".f1euv43f{position:absolute;}", ".fqclxi7{top:4px;}", ".fiv86kb{right:4px;}", ".f36uhnt{left:4px;}", ".fom9my7{z-index:var(--zIndexContent, 1);}", [".f1a3p1vp{overflow:hidden;}", {
p: -1
}], ".frkrog8{width:1px;}", ".f1mpe4l3{height:1px;}", ".fmf1zke{clip:rect(0 0 0 0);}", ".f1wch0ki{clip-path:inset(50%);}", ".fz5stix{white-space:nowrap;}", ".fdrzuqr{cursor:not-allowed;}", ".f1xqy1su{-webkit-user-select:none;-moz-user-select:none;user-select:none;}", ".f1s2aq7o{color:var(--colorNeutralForegroundDisabled);}", ".f1bg9a2p{background-color:var(--colorNeutralBackgroundDisabled);}", ".fyed02w{box-shadow:var(--shadow2);}", ".f1wl9k8s::before{content:\"\";}", ".f1j7ml58::before{position:absolute;}", [".f13vvzas::before{inset:0;}", {
p: -1
}], ".f198lalb::before{z-index:calc(var(--zIndexContent, 1) + 1);}"],
m: [["@media (forced-colors: active){.f1j6vpng[data-fui-focus-visible]::after{border-top-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1ffjurs[data-fui-focus-visible]::after{border-left-color:Highlight;}.f1pniga2[data-fui-focus-visible]::after{border-right-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f987i1v[data-fui-focus-visible]::after{border-bottom-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1ufm4qn[data-fui-focus-within]:focus-within::after{border-top-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1qnwcb4[data-fui-focus-within]:focus-within::after{border-right-color:Highlight;}.fgrk5zm[data-fui-focus-within]:focus-within::after{border-left-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.fi52z01[data-fui-focus-within]:focus-within::after{border-bottom-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1h3a8gf{forced-color-adjust:none;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1nz3ub2{background-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.fqc85l4{color:HighlightText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1ucc5z8 .fui-CardPreview,.f1ucc5z8 .fui-CardFooter{forced-color-adjust:auto;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.fyj59f4::after{border-top-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f19v95gn::after{border-right-color:Highlight;}.f1n69f6i::after{border-left-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f16q7dot::after{border-bottom-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1quqgnd:hover,.f1quqgnd :active{forced-color-adjust:none;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f193utb4:hover,.f193utb4 :active{background-color:Highlight;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f1io67iv:hover,.f1io67iv :active{color:HighlightText;}}", {
m: "(forced-colors: active)"
}], ["@media (forced-colors: active){.f3n01jk:hover .fui-CardPreview,.f3n01jk :active .fui-CardPreview,.f3n01jk:hover .fui-CardFooter,.f3n01jk :active .fui-CardFooter{forced-color-adjust:auto;}}", {
m: "(forced-colors: active)"
}]],
h: [".feu1g3u:hover{color:var(--colorNeutralForeground1Hover);}", ".f1knas48:hover{background-color:var(--colorNeutralBackground1Hover);}", ".f1m145df:hover{box-shadow:var(--shadow8);}", ".fx9teim:hover{color:var(--colorNeutralForeground1Selected);}", ".f1kz6goq:hover{background-color:var(--colorNeutralBackground1Selected);}", ".fnwyq0v:hover{color:var(--colorNeutralForeground2Hover);}", ".f1uvynv3:hover{background-color:var(--colorNeutralBackground2Hover);}", ".f1luvkty:hover{color:var(--colorNeutralForeground2Selected);}", ".fehi0vp:hover{background-color:var(--colorNeutralBackground2Selected);}", ".fjxutwb:hover{background-color:var(--colorTransparentBackgroundHover);}", ".f1llr77y:hover::after{border-top-color:var(--colorNeutralStroke1Hover);}", ".fzk0khw:hover::after{border-right-color:var(--colorNeutralStroke1Hover);}", ".fjj8tog:hover::after{border-left-color:var(--colorNeutralStroke1Hover);}", ".fb1u8ub:hover::after{border-bottom-color:var(--colorNeutralStroke1Hover);}", ".fg59vm4:hover{background-color:var(--colorTransparentBackgroundSelected);}", ".f1ls5moo:hover,.f1ls5moo:active{background-color:var(--colorTransparentBackground);}", ".f1qiza15:hover,.f1qiza15:active{box-shadow:none;}", ".f1t94bn6:hover{background-color:var(--colorSubtleBackgroundHover);}", ".f1uqaxdt:hover{background-color:var(--colorSubtleBackgroundSelected);}", ".f11og98d:hover,.f11og98d:active{cursor:not-allowed;}", ".f1rg3h4v:hover,.f1rg3h4v:active{-webkit-user-select:none;-moz-user-select:none;user-select:none;}", ".fbm2y3b:hover,.fbm2y3b:active{color:var(--colorNeutralForegroundDisabled);}", ".f4yodeu:hover,.f4yodeu:active{background-color:var(--colorNeutralBackgroundDisabled);}", ".fcwfbwp:hover,.fcwfbwp:active{box-shadow:var(--shadow2);}", ".f1repx37:hover,.f1repx37:active{border-top-color:var(--colorNeutralStrokeDisabled);}", ".f1ybi8ct:hover,.f1ybi8ct:active{border-right-color:var(--colorNeutralStrokeDisabled);}", ".f1h4eg6q:hover,.f1h4eg6q:active{border-left-color:var(--colorNeutralStrokeDisabled);}", ".f18mejnb:hover,.f18mejnb:active{border-bottom-color:var(--colorNeutralStrokeDisabled);}", ".f1nift3m:hover::before,.f1nift3m:active::before{content:\"\";}", ".f1wu3i8x:hover::before,.f1wu3i8x:active::before{position:absolute;}", [".f6v4vfa:hover::before,.f6v4vfa:active::before{inset:0;}", {
p: -1
}], ".folrdqs:hover::before,.folrdqs:active::before{z-index:calc(var(--zIndexContent, 1) + 1);}", ".f168z5yf:hover::after,.f168z5yf:active::after{border-top-color:var(--colorNeutralStrokeDisabled);}", ".fpor7gj:hover::after,.fpor7gj:active::after{border-right-color:var(--colorNeutralStrokeDisabled);}", ".fzextn6:hover::after,.fzextn6:active::after{border-left-color:var(--colorNeutralStrokeDisabled);}", ".f1yaw79v:hover::after,.f1yaw79v:active::after{border-bottom-color:var(--colorNeutralStrokeDisabled);}"],
a: [".fb40n2d:active{background-color:var(--colorNeutralBackground1Pressed);}", ".f1yhgkbh:active{background-color:var(--colorNeutralBackground2Pressed);}", ".fophhak:active{background-color:var(--colorTransparentBackgroundPressed);}", ".f1uohb70:active::after{border-top-color:var(--colorNeutralStroke1Pressed);}", ".f1jm7v1n:active::after{border-right-color:var(--colorNeutralStroke1Pressed);}", ".f1bus3rq:active::after{border-left-color:var(--colorNeutralStroke1Pressed);}", ".f1fbu7rr:active::after{border-bottom-color:var(--colorNeutralStroke1Pressed);}", ".f1wfn5kd:active{background-color:var(--colorSubtleBackgroundPressed);}"]
});
/**
* Apply styling to the Card slots based on the state.
*/
export const useCardStyles_unstable = state => {
'use no memo';
const resetStyles = useCardResetStyles();
const styles = useCardStyles();
const orientationMap = {
horizontal: styles.orientationHorizontal,
vertical: styles.orientationVertical
};
const sizeMap = {
small: styles.sizeSmall,
medium: styles.sizeMedium,
large: styles.sizeLarge
};
const appearanceMap = {
filled: styles.filled,
'filled-alternative': styles.filledAlternative,
outline: styles.outline,
subtle: styles.subtle
};
const selectedMap = {
filled: styles.filledInteractiveSelected,
'filled-alternative': styles.filledAlternativeInteractiveSelected,
outline: styles.outlineInteractiveSelected,
subtle: styles.subtleInteractiveSelected
};
const interactiveMap = {
filled: styles.filledInteractive,
'filled-alternative': styles.filledAlternativeInteractive,
outline: styles.outlineInteractive,
subtle: styles.subtleInteractive
};
const isSelectableOrInteractive = !state.disabled && (state.interactive || state.selectable);
const focusedClassName = React.useMemo(() => {
if (state.disabled) {
return '';
}
if (state.selectable) {
if (state.selectFocused) {
return styles.selectableFocused;
}
return '';
}
return styles.focused;
}, [state.disabled, state.selectFocused, state.selectable, styles.focused, styles.selectableFocused]);
state.root.className = mergeClasses(cardClassNames.root, resetStyles, orientationMap[state.orientation], sizeMap[state.size], appearanceMap[state.appearance], isSelectableOrInteractive && styles.interactive, isSelectableOrInteractive && interactiveMap[state.appearance], state.selected && selectedMap[state.appearance], focusedClassName, isSelectableOrInteractive && styles.highContrastInteractive, state.selected && styles.highContrastSelected, state.disabled && styles.disabled, state.disabled && state.appearance === 'outline' && styles.outlineDisabled, state.root.className);
if (state.floatingAction) {
state.floatingAction.className = mergeClasses(cardClassNames.floatingAction, styles.select, state.floatingAction.className);
}
if (state.checkbox) {
state.checkbox.className = mergeClasses(cardClassNames.checkbox, styles.hiddenCheckbox, state.checkbox.className);
}
return state;
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,404 @@
'use client';
import * as React from 'react';
import { shorthands, makeStyles, mergeClasses, makeResetStyles } from '@griffel/react';
import { tokens } from '@fluentui/react-theme';
import { textClassNames } from '@fluentui/react-text';
import { createFocusOutlineStyle } from '@fluentui/react-tabster';
import { cardPreviewClassNames } from '../CardPreview/useCardPreviewStyles.styles';
import { cardHeaderClassNames } from '../CardHeader/useCardHeaderStyles.styles';
import { cardFooterClassNames } from '../CardFooter/useCardFooterStyles.styles';
/**
* Static CSS class names used internally for the component slots.
*/ export const cardClassNames = {
root: 'fui-Card',
floatingAction: 'fui-Card__floatingAction',
checkbox: 'fui-Card__checkbox'
};
/**
* CSS variable names used internally for uniform styling in Card.
*/ export const cardCSSVars = {
cardSizeVar: '--fui-Card--size',
cardBorderRadiusVar: '--fui-Card--border-radius'
};
const focusOutlineStyle = {
outlineRadius: `var(${cardCSSVars.cardBorderRadiusVar})`,
outlineWidth: tokens.strokeWidthThick,
outlineOffset: '-2px'
};
const useCardResetStyles = makeResetStyles({
overflow: 'hidden',
borderRadius: `var(${cardCSSVars.cardBorderRadiusVar})`,
padding: `var(${cardCSSVars.cardSizeVar})`,
gap: `var(${cardCSSVars.cardSizeVar})`,
display: 'flex',
position: 'relative',
boxSizing: 'border-box',
color: tokens.colorNeutralForeground1,
// Border setting using after pseudo element to allow CardPreview to render behind it.
'::after': {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
content: '""',
pointerEvents: 'none',
...shorthands.borderStyle('solid'),
...shorthands.borderWidth(tokens.strokeWidthThin),
borderRadius: `var(${cardCSSVars.cardBorderRadiusVar})`
},
// Prevents CardHeader and CardFooter from shrinking.
[`> .${cardHeaderClassNames.root}, > .${cardFooterClassNames.root}`]: {
flexShrink: 0
}
});
const disabledStyles = {
cursor: 'not-allowed',
userSelect: 'none',
color: tokens.colorNeutralForegroundDisabled,
backgroundColor: tokens.colorNeutralBackgroundDisabled,
boxShadow: tokens.shadow2,
...shorthands.borderColor(tokens.colorNeutralStrokeDisabled),
'::before': {
content: '""',
position: 'absolute',
inset: 0,
zIndex: `calc(${tokens.zIndexContent} + 1)`
},
'::after': {
...shorthands.borderColor(tokens.colorNeutralStrokeDisabled)
}
};
const useCardStyles = makeStyles({
focused: {
...createFocusOutlineStyle({
style: focusOutlineStyle,
selector: 'focus'
})
},
selectableFocused: createFocusOutlineStyle({
style: focusOutlineStyle,
selector: 'focus-within'
}),
orientationHorizontal: {
flexDirection: 'row',
alignItems: 'center',
// Remove vertical padding to keep CardPreview content flush with Card's borders.
[`> .${cardPreviewClassNames.root}`]: {
marginTop: `calc(var(${cardCSSVars.cardSizeVar}) * -1)`,
marginBottom: `calc(var(${cardCSSVars.cardSizeVar}) * -1)`
},
// Due to Tabster's "Groupper" focus functionality, hidden elements are injected before and after Card's content.
// As such, the code below targets a CardPreview, when it's the first element.
// Since this is on horizontal cards, the left padding is removed to keep the content flush with the border.
[`> :not([aria-hidden="true"]).${cardPreviewClassNames.root}:first-of-type`]: {
marginLeft: `calc(var(${cardCSSVars.cardSizeVar}) * -1)`
},
// Due to Tabster's "Groupper" focus functionality, hidden elements are injected before and after Card's content.
// As such, the code below targets a CardPreview, when it's the last element.
// Since this is on horizontal cards, the right padding is removed to keep the content flush with the border.
[`> :not([aria-hidden="true"]).${cardPreviewClassNames.root}:last-of-type`]: {
marginRight: `calc(var(${cardCSSVars.cardSizeVar}) * -1)`
},
// If the last child is a CardHeader or CardFooter, allow it to grow to fill the available space.
[`> .${cardHeaderClassNames.root}:last-of-type, > .${cardFooterClassNames.root}:last-of-type`]: {
flexGrow: 1
}
},
orientationVertical: {
flexDirection: 'column',
// Remove lateral padding to keep CardPreview content flush with Card's borders.
[`> .${cardPreviewClassNames.root}`]: {
marginLeft: `calc(var(${cardCSSVars.cardSizeVar}) * -1)`,
marginRight: `calc(var(${cardCSSVars.cardSizeVar}) * -1)`
},
// Due to Tabster's "Groupper" focus functionality, hidden elements are injected before and after Card's content.
// As such, the code below targets a CardPreview, when it's the first element.
// Since this is on vertical cards, the top padding is removed to keep the content flush with the border.
[`> :not([aria-hidden="true"]).${cardPreviewClassNames.root}:first-of-type`]: {
marginTop: `calc(var(${cardCSSVars.cardSizeVar}) * -1)`
},
[`> .${cardClassNames.floatingAction} + .${cardPreviewClassNames.root}`]: {
marginTop: `calc(var(${cardCSSVars.cardSizeVar}) * -1)`
},
// Due to Tabster's "Groupper" focus functionality, hidden elements are injected before and after Card's content.
// As such, the code below targets a CardPreview, when it's the first element.
// Since this is on vertical cards, the bottom padding is removed to keep the content flush with the border.
[`> :not([aria-hidden="true"]).${cardPreviewClassNames.root}:last-of-type`]: {
marginBottom: `calc(var(${cardCSSVars.cardSizeVar}) * -1)`
}
},
sizeSmall: {
[cardCSSVars.cardSizeVar]: '8px',
[cardCSSVars.cardBorderRadiusVar]: tokens.borderRadiusSmall
},
sizeMedium: {
[cardCSSVars.cardSizeVar]: '12px',
[cardCSSVars.cardBorderRadiusVar]: tokens.borderRadiusMedium
},
sizeLarge: {
[cardCSSVars.cardSizeVar]: '16px',
[cardCSSVars.cardBorderRadiusVar]: tokens.borderRadiusLarge
},
interactive: {
[`& .${textClassNames.root}`]: {
color: 'currentColor'
}
},
filled: {
backgroundColor: tokens.colorNeutralBackground1,
boxShadow: tokens.shadow4,
'::after': {
...shorthands.borderColor(tokens.colorTransparentStroke)
}
},
filledInteractive: {
cursor: 'pointer',
backgroundColor: tokens.colorNeutralBackground1,
boxShadow: tokens.shadow4,
'::after': {
...shorthands.borderColor(tokens.colorTransparentStroke)
},
':hover': {
color: tokens.colorNeutralForeground1Hover,
backgroundColor: tokens.colorNeutralBackground1Hover,
boxShadow: tokens.shadow8
},
':active': {
backgroundColor: tokens.colorNeutralBackground1Pressed
}
},
filledInteractiveSelected: {
backgroundColor: tokens.colorNeutralBackground1Selected,
'::after': {
...shorthands.borderColor(tokens.colorNeutralStroke1Selected)
},
':hover': {
color: tokens.colorNeutralForeground1Selected,
backgroundColor: tokens.colorNeutralBackground1Selected
}
},
filledAlternative: {
backgroundColor: tokens.colorNeutralBackground2,
boxShadow: tokens.shadow4,
'::after': {
...shorthands.borderColor(tokens.colorTransparentStroke)
}
},
filledAlternativeInteractive: {
cursor: 'pointer',
backgroundColor: tokens.colorNeutralBackground2,
boxShadow: tokens.shadow4,
'::after': {
...shorthands.borderColor(tokens.colorTransparentStroke)
},
':hover': {
color: tokens.colorNeutralForeground2Hover,
backgroundColor: tokens.colorNeutralBackground2Hover,
boxShadow: tokens.shadow8
},
':active': {
backgroundColor: tokens.colorNeutralBackground2Pressed
}
},
filledAlternativeInteractiveSelected: {
backgroundColor: tokens.colorNeutralBackground2Selected,
'::after': {
...shorthands.borderColor(tokens.colorNeutralStroke1Selected)
},
':hover': {
color: tokens.colorNeutralForeground2Selected,
backgroundColor: tokens.colorNeutralBackground2Selected
}
},
outline: {
backgroundColor: tokens.colorTransparentBackground,
boxShadow: 'none',
'::after': {
...shorthands.borderColor(tokens.colorNeutralStroke1)
}
},
outlineInteractive: {
cursor: 'pointer',
backgroundColor: tokens.colorTransparentBackground,
boxShadow: 'none',
'::after': {
...shorthands.borderColor(tokens.colorNeutralStroke1)
},
':hover': {
color: tokens.colorNeutralForeground1Hover,
backgroundColor: tokens.colorTransparentBackgroundHover,
'::after': {
...shorthands.borderColor(tokens.colorNeutralStroke1Hover)
}
},
':active': {
backgroundColor: tokens.colorTransparentBackgroundPressed,
'::after': {
...shorthands.borderColor(tokens.colorNeutralStroke1Pressed)
}
}
},
outlineInteractiveSelected: {
backgroundColor: tokens.colorTransparentBackgroundSelected,
'::after': {
...shorthands.borderColor(tokens.colorNeutralStroke1Selected)
},
':hover': {
color: tokens.colorNeutralForeground1Selected,
backgroundColor: tokens.colorTransparentBackgroundSelected
}
},
outlineDisabled: {
backgroundColor: tokens.colorTransparentBackground,
boxShadow: 'none',
...shorthands.borderColor(tokens.colorNeutralStrokeDisabled),
'&:hover, &:active': {
backgroundColor: tokens.colorTransparentBackground,
boxShadow: 'none'
},
'::after': {
...shorthands.borderColor(tokens.colorNeutralStrokeDisabled)
}
},
subtle: {
backgroundColor: tokens.colorSubtleBackground,
boxShadow: 'none',
'::after': {
...shorthands.borderColor(tokens.colorTransparentStroke)
}
},
subtleInteractive: {
cursor: 'pointer',
backgroundColor: tokens.colorSubtleBackground,
boxShadow: 'none',
'::after': {
...shorthands.borderColor(tokens.colorTransparentStroke)
},
':hover': {
color: tokens.colorNeutralForeground1Hover,
backgroundColor: tokens.colorSubtleBackgroundHover
},
':active': {
backgroundColor: tokens.colorSubtleBackgroundPressed
}
},
subtleInteractiveSelected: {
backgroundColor: tokens.colorSubtleBackgroundSelected,
'::after': {
...shorthands.borderColor(tokens.colorNeutralStroke1Selected)
},
':hover': {
color: tokens.colorNeutralForeground1Selected,
backgroundColor: tokens.colorSubtleBackgroundSelected
}
},
highContrastSelected: {
'@media (forced-colors: active)': {
forcedColorAdjust: 'none',
backgroundColor: 'Highlight',
color: 'HighlightText',
[`& .${cardPreviewClassNames.root}, & .${cardFooterClassNames.root}`]: {
forcedColorAdjust: 'auto'
},
'::after': {
...shorthands.borderColor('Highlight')
}
}
},
highContrastInteractive: {
'@media (forced-colors: active)': {
':hover, :active': {
forcedColorAdjust: 'none',
backgroundColor: 'Highlight',
color: 'HighlightText',
[`& .${cardPreviewClassNames.root}, & .${cardFooterClassNames.root}`]: {
forcedColorAdjust: 'auto'
}
},
'::after': {
...shorthands.borderColor('Highlight')
}
}
},
select: {
position: 'absolute',
top: '4px',
right: '4px',
zIndex: tokens.zIndexContent
},
hiddenCheckbox: {
overflow: 'hidden',
width: '1px',
height: '1px',
position: 'absolute',
clip: 'rect(0 0 0 0)',
clipPath: 'inset(50%)',
whiteSpace: 'nowrap'
},
disabled: {
...disabledStyles,
'&:hover, &:active': disabledStyles
}
});
/**
* Apply styling to the Card slots based on the state.
*/ export const useCardStyles_unstable = (state)=>{
'use no memo';
const resetStyles = useCardResetStyles();
const styles = useCardStyles();
const orientationMap = {
horizontal: styles.orientationHorizontal,
vertical: styles.orientationVertical
};
const sizeMap = {
small: styles.sizeSmall,
medium: styles.sizeMedium,
large: styles.sizeLarge
};
const appearanceMap = {
filled: styles.filled,
'filled-alternative': styles.filledAlternative,
outline: styles.outline,
subtle: styles.subtle
};
const selectedMap = {
filled: styles.filledInteractiveSelected,
'filled-alternative': styles.filledAlternativeInteractiveSelected,
outline: styles.outlineInteractiveSelected,
subtle: styles.subtleInteractiveSelected
};
const interactiveMap = {
filled: styles.filledInteractive,
'filled-alternative': styles.filledAlternativeInteractive,
outline: styles.outlineInteractive,
subtle: styles.subtleInteractive
};
const isSelectableOrInteractive = !state.disabled && (state.interactive || state.selectable);
const focusedClassName = React.useMemo(()=>{
if (state.disabled) {
return '';
}
if (state.selectable) {
if (state.selectFocused) {
return styles.selectableFocused;
}
return '';
}
return styles.focused;
}, [
state.disabled,
state.selectFocused,
state.selectable,
styles.focused,
styles.selectableFocused
]);
state.root.className = mergeClasses(cardClassNames.root, resetStyles, orientationMap[state.orientation], sizeMap[state.size], appearanceMap[state.appearance], isSelectableOrInteractive && styles.interactive, isSelectableOrInteractive && interactiveMap[state.appearance], state.selected && selectedMap[state.appearance], focusedClassName, isSelectableOrInteractive && styles.highContrastInteractive, state.selected && styles.highContrastSelected, state.disabled && styles.disabled, state.disabled && state.appearance === 'outline' && styles.outlineDisabled, state.root.className);
if (state.floatingAction) {
state.floatingAction.className = mergeClasses(cardClassNames.floatingAction, styles.select, state.floatingAction.className);
}
if (state.checkbox) {
state.checkbox.className = mergeClasses(cardClassNames.checkbox, styles.hiddenCheckbox, state.checkbox.className);
}
return state;
};

File diff suppressed because one or more lines are too long