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 { useTableSelectionCell_unstable } from './useTableSelectionCell';
import { renderTableSelectionCell_unstable } from './renderTableSelectionCell';
import { useTableSelectionCellStyles_unstable } from './useTableSelectionCellStyles.styles';
import { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';
/**
* TableSelectionCell component
*/ export const TableSelectionCell = /*#__PURE__*/ React.forwardRef((props, ref)=>{
const state = useTableSelectionCell_unstable(props, ref);
useTableSelectionCellStyles_unstable(state);
useCustomStyleHook_unstable('useTableSelectionCellStyles_unstable')(state);
return renderTableSelectionCell_unstable(state);
});
TableSelectionCell.displayName = 'TableSelectionCell';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/TableSelectionCell/TableSelectionCell.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useTableSelectionCell_unstable } from './useTableSelectionCell';\nimport { renderTableSelectionCell_unstable } from './renderTableSelectionCell';\nimport { useTableSelectionCellStyles_unstable } from './useTableSelectionCellStyles.styles';\nimport type { TableSelectionCellProps } from './TableSelectionCell.types';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\n\n/**\n * TableSelectionCell component\n */\nexport const TableSelectionCell: ForwardRefComponent<TableSelectionCellProps> = React.forwardRef((props, ref) => {\n const state = useTableSelectionCell_unstable(props, ref);\n\n useTableSelectionCellStyles_unstable(state);\n\n useCustomStyleHook_unstable('useTableSelectionCellStyles_unstable')(state);\n\n return renderTableSelectionCell_unstable(state);\n});\n\nTableSelectionCell.displayName = 'TableSelectionCell';\n"],"names":["React","useTableSelectionCell_unstable","renderTableSelectionCell_unstable","useTableSelectionCellStyles_unstable","useCustomStyleHook_unstable","TableSelectionCell","forwardRef","props","ref","state","displayName"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,8BAA8B,QAAQ,0BAA0B;AACzE,SAASC,iCAAiC,QAAQ,6BAA6B;AAC/E,SAASC,oCAAoC,QAAQ,uCAAuC;AAG5F,SAASC,2BAA2B,QAAQ,kCAAkC;AAE9E;;CAEC,GACD,OAAO,MAAMC,mCAAmEL,MAAMM,UAAU,CAAC,CAACC,OAAOC;IACvG,MAAMC,QAAQR,+BAA+BM,OAAOC;IAEpDL,qCAAqCM;IAErCL,4BAA4B,wCAAwCK;IAEpE,OAAOP,kCAAkCO;AAC3C,GAAG;AAEHJ,mBAAmBK,WAAW,GAAG"}

View File

@@ -0,0 +1,3 @@
/**
* State used in rendering TableSelectionCell
*/ export { };

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/TableSelectionCell/TableSelectionCell.types.ts"],"sourcesContent":["import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';\nimport type { Checkbox, CheckboxProps } from '@fluentui/react-checkbox';\nimport type { Radio } from '@fluentui/react-radio';\nimport { TableCellSlots } from '../TableCell/TableCell.types';\nimport { TableContextValue } from '../Table/Table.types';\n\nexport type TableSelectionCellSlots = {\n /**\n * Selection indicator if selection type is checkbox\n */\n checkboxIndicator: Slot<typeof Checkbox>;\n /**\n * Selection indicator if selection type is radio\n */\n radioIndicator: Slot<typeof Radio>;\n} & Pick<TableCellSlots, 'root'>;\n\n/**\n * TableSelectionCell Props\n */\nexport type TableSelectionCellProps = ComponentProps<Partial<TableSelectionCellSlots>> & {\n /**\n * A table can have two kinds of selection modes.\n * @default checkbox\n */\n type?: 'checkbox' | 'radio';\n\n /**\n * @default false\n */\n checked?: CheckboxProps['checked'];\n\n /**\n * Only visible when checked or the parent row is hovered/focused\n * @default false\n */\n subtle?: boolean;\n\n /**\n * Completely hides the selection cell\n * @deprecated cells should never use hidden, since doing so breaks table structure and screen reader navigation. Use `invisible` instead.\n */\n hidden?: boolean;\n\n /**\n * Hides the selection cell visually but takes up the same space\n * @default false\n */\n invisible?: boolean;\n};\n\n/**\n * State used in rendering TableSelectionCell\n */\nexport type TableSelectionCellState = ComponentState<TableSelectionCellSlots> &\n Pick<Required<TableSelectionCellProps>, 'type' | 'checked' | 'subtle'> &\n Pick<TableContextValue, 'noNativeElements'> & {\n /* Visually hides the selection cell; not deprecated on state */\n hidden: boolean;\n };\n"],"names":[],"mappings":"AAmDA;;CAEC,GACD,WAKI"}

View File

@@ -0,0 +1,4 @@
export { TableSelectionCell } from './TableSelectionCell';
export { renderTableSelectionCell_unstable } from './renderTableSelectionCell';
export { useTableSelectionCell_unstable } from './useTableSelectionCell';
export { CELL_WIDTH, tableSelectionCellClassNames, useTableSelectionCellStyles_unstable } from './useTableSelectionCellStyles.styles';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/TableSelectionCell/index.ts"],"sourcesContent":["export { TableSelectionCell } from './TableSelectionCell';\nexport type {\n TableSelectionCellProps,\n TableSelectionCellSlots,\n TableSelectionCellState,\n} from './TableSelectionCell.types';\nexport { renderTableSelectionCell_unstable } from './renderTableSelectionCell';\nexport { useTableSelectionCell_unstable } from './useTableSelectionCell';\nexport {\n CELL_WIDTH,\n tableSelectionCellClassNames,\n useTableSelectionCellStyles_unstable,\n} from './useTableSelectionCellStyles.styles';\n"],"names":["TableSelectionCell","renderTableSelectionCell_unstable","useTableSelectionCell_unstable","CELL_WIDTH","tableSelectionCellClassNames","useTableSelectionCellStyles_unstable"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ,uBAAuB;AAM1D,SAASC,iCAAiC,QAAQ,6BAA6B;AAC/E,SAASC,8BAA8B,QAAQ,0BAA0B;AACzE,SACEC,UAAU,EACVC,4BAA4B,EAC5BC,oCAAoC,QAC/B,uCAAuC"}

View File

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

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/TableSelectionCell/renderTableSelectionCell.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 { TableSelectionCellState, TableSelectionCellSlots } from './TableSelectionCell.types';\n\n/**\n * Render the final JSX of TableSelectionCell\n */\nexport const renderTableSelectionCell_unstable = (state: TableSelectionCellState): JSXElement => {\n assertSlots<TableSelectionCellSlots>(state);\n\n return (\n <state.root>\n {state.type === 'checkbox' && state.checkboxIndicator && <state.checkboxIndicator />}\n\n {state.type === 'radio' && state.radioIndicator && <state.radioIndicator />}\n </state.root>\n );\n};\n"],"names":["assertSlots","renderTableSelectionCell_unstable","state","root","type","checkboxIndicator","radioIndicator"],"mappings":"AAAA,0BAA0B,GAC1B,iDAAiD;AACjD,SAASA,WAAW,QAAQ,4BAA4B;AAIxD;;CAEC,GACD,OAAO,MAAMC,oCAAoC,CAACC;IAChDF,YAAqCE;IAErC,qBACE,MAACA,MAAMC,IAAI;;YACRD,MAAME,IAAI,KAAK,cAAcF,MAAMG,iBAAiB,kBAAI,KAACH,MAAMG,iBAAiB;YAEhFH,MAAME,IAAI,KAAK,WAAWF,MAAMI,cAAc,kBAAI,KAACJ,MAAMI,cAAc;;;AAG9E,EAAE"}

View File

@@ -0,0 +1,53 @@
'use client';
import * as React from 'react';
import { useId, slot, useMergedRefs } from '@fluentui/react-utilities';
import { Checkbox } from '@fluentui/react-checkbox';
import { Radio } from '@fluentui/react-radio';
import { useTableCell_unstable } from '../TableCell/useTableCell';
import { useTableContext } from '../../contexts/tableContext';
import { useFocusWithin } from '@fluentui/react-tabster';
/**
* Create the state required to render TableSelectionCell.
*
* The returned state can be modified with hooks such as useTableSelectionCellStyles_unstable,
* before being passed to renderTableSelectionCell_unstable.
*
* @param props - props from this instance of TableSelectionCell
* @param ref - reference to root HTMLElement of TableSelectionCell
*/ export const useTableSelectionCell_unstable = (props, ref)=>{
const tableCellState = useTableCell_unstable(props, useMergedRefs(ref, useFocusWithin()));
const { noNativeElements } = useTableContext();
const { type = 'checkbox', checked = false, subtle = false, // eslint-disable-next-line @typescript-eslint/no-deprecated
hidden = false, invisible = false } = props;
return {
...tableCellState,
components: {
// eslint-disable-next-line @typescript-eslint/no-deprecated
...tableCellState.components,
checkboxIndicator: Checkbox,
radioIndicator: Radio
},
checkboxIndicator: slot.optional(props.checkboxIndicator, {
renderByDefault: type === 'checkbox',
defaultProps: {
checked: props.checked
},
elementType: Checkbox
}),
radioIndicator: slot.optional(props.radioIndicator, {
renderByDefault: type === 'radio' && !invisible,
defaultProps: {
checked: !!checked,
input: {
name: useId('table-selection-radio')
}
},
elementType: Radio
}),
type,
checked,
noNativeElements,
subtle,
hidden: invisible || hidden
};
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/TableSelectionCell/useTableSelectionCell.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useId, slot, useMergedRefs } from '@fluentui/react-utilities';\nimport { Checkbox } from '@fluentui/react-checkbox';\nimport { Radio } from '@fluentui/react-radio';\nimport type { TableSelectionCellProps, TableSelectionCellState } from './TableSelectionCell.types';\nimport { useTableCell_unstable } from '../TableCell/useTableCell';\nimport { useTableContext } from '../../contexts/tableContext';\nimport { useFocusWithin } from '@fluentui/react-tabster';\n\n/**\n * Create the state required to render TableSelectionCell.\n *\n * The returned state can be modified with hooks such as useTableSelectionCellStyles_unstable,\n * before being passed to renderTableSelectionCell_unstable.\n *\n * @param props - props from this instance of TableSelectionCell\n * @param ref - reference to root HTMLElement of TableSelectionCell\n */\nexport const useTableSelectionCell_unstable = (\n props: TableSelectionCellProps,\n ref: React.Ref<HTMLElement>,\n): TableSelectionCellState => {\n const tableCellState = useTableCell_unstable(props, useMergedRefs(ref, useFocusWithin()));\n const { noNativeElements } = useTableContext();\n const {\n type = 'checkbox',\n checked = false,\n subtle = false,\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n hidden = false,\n invisible = false,\n } = props;\n\n return {\n ...tableCellState,\n components: {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n ...tableCellState.components,\n checkboxIndicator: Checkbox,\n radioIndicator: Radio,\n },\n checkboxIndicator: slot.optional(props.checkboxIndicator, {\n renderByDefault: type === 'checkbox',\n defaultProps: { checked: props.checked },\n elementType: Checkbox,\n }),\n radioIndicator: slot.optional(props.radioIndicator, {\n renderByDefault: type === 'radio' && !invisible,\n defaultProps: { checked: !!checked, input: { name: useId('table-selection-radio') } },\n elementType: Radio,\n }),\n type,\n checked,\n noNativeElements,\n subtle,\n hidden: invisible || hidden,\n };\n};\n"],"names":["React","useId","slot","useMergedRefs","Checkbox","Radio","useTableCell_unstable","useTableContext","useFocusWithin","useTableSelectionCell_unstable","props","ref","tableCellState","noNativeElements","type","checked","subtle","hidden","invisible","components","checkboxIndicator","radioIndicator","optional","renderByDefault","defaultProps","elementType","input","name"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,KAAK,EAAEC,IAAI,EAAEC,aAAa,QAAQ,4BAA4B;AACvE,SAASC,QAAQ,QAAQ,2BAA2B;AACpD,SAASC,KAAK,QAAQ,wBAAwB;AAE9C,SAASC,qBAAqB,QAAQ,4BAA4B;AAClE,SAASC,eAAe,QAAQ,8BAA8B;AAC9D,SAASC,cAAc,QAAQ,0BAA0B;AAEzD;;;;;;;;CAQC,GACD,OAAO,MAAMC,iCAAiC,CAC5CC,OACAC;IAEA,MAAMC,iBAAiBN,sBAAsBI,OAAOP,cAAcQ,KAAKH;IACvE,MAAM,EAAEK,gBAAgB,EAAE,GAAGN;IAC7B,MAAM,EACJO,OAAO,UAAU,EACjBC,UAAU,KAAK,EACfC,SAAS,KAAK,EACd,4DAA4D;IAC5DC,SAAS,KAAK,EACdC,YAAY,KAAK,EAClB,GAAGR;IAEJ,OAAO;QACL,GAAGE,cAAc;QACjBO,YAAY;YACV,4DAA4D;YAC5D,GAAGP,eAAeO,UAAU;YAC5BC,mBAAmBhB;YACnBiB,gBAAgBhB;QAClB;QACAe,mBAAmBlB,KAAKoB,QAAQ,CAACZ,MAAMU,iBAAiB,EAAE;YACxDG,iBAAiBT,SAAS;YAC1BU,cAAc;gBAAET,SAASL,MAAMK,OAAO;YAAC;YACvCU,aAAarB;QACf;QACAiB,gBAAgBnB,KAAKoB,QAAQ,CAACZ,MAAMW,cAAc,EAAE;YAClDE,iBAAiBT,SAAS,WAAW,CAACI;YACtCM,cAAc;gBAAET,SAAS,CAAC,CAACA;gBAASW,OAAO;oBAAEC,MAAM1B,MAAM;gBAAyB;YAAE;YACpFwB,aAAapB;QACf;QACAS;QACAC;QACAF;QACAG;QACAC,QAAQC,aAAaD;IACvB;AACF,EAAE"}

View File

@@ -0,0 +1,99 @@
'use client';
import { __styles, mergeClasses } from '@griffel/react';
import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster';
import { tokens } from '@fluentui/react-theme';
export const CELL_WIDTH = 44;
export const tableSelectionCellClassNames = {
root: 'fui-TableSelectionCell',
checkboxIndicator: 'fui-TableSelectionCell__checkboxIndicator',
radioIndicator: 'fui-TableSelectionCell__radioIndicator'
};
const useTableLayoutStyles = /*#__PURE__*/__styles({
root: {
mc9l5x: "f15pt5es",
a9b677: "fksc0bp"
}
}, {
d: [".f15pt5es{display:table-cell;}", ".fksc0bp{width:44px;}"]
});
const useFlexLayoutStyles = /*#__PURE__*/__styles({
root: {
mc9l5x: "f22iagw",
xawz: 0,
Bh6795r: 0,
Bnnss6s: 0,
fkmc3a: "f1izfyrr",
Bf4jedk: "fvrlu0f",
B2u0y6b: "f1c71y05",
Brf1p80: "f4d9j23"
}
}, {
d: [".f22iagw{display:flex;}", [".f1izfyrr{flex:1 1 0px;}", {
p: -1
}], ".fvrlu0f{min-width:44px;}", ".f1c71y05{max-width:44px;}", ".f4d9j23{justify-content:center;}"]
});
/**
* Styles for the root slot
*/
const useStyles = /*#__PURE__*/__styles({
root: {
fsow6f: "f17mccla",
Huce71: "fz5stix",
Byoj8tv: 0,
uwmqm3: 0,
z189sj: 0,
z8tnut: 0,
B0ocmuz: "f1mk8lai",
Bfpq7zp: 0,
g9k6zt: 0,
Bn4voq9: 0,
giviqs: "f1dxfoyt",
Bw81rd7: 0,
kdpuga: 0,
dm238s: 0,
B6xbmo0: 0,
B3whbx2: "f2krc9w"
},
radioIndicator: {
mc9l5x: "f22iagw",
Bh6795r: "fqerorx",
Bt984gj: "f122n59",
Brf1p80: "f4d9j23"
},
subtle: {
abs64n: "fk73vx1",
B8a84jv: "f1y7ij6c"
},
hidden: {
abs64n: "fk73vx1"
}
}, {
d: [".f17mccla{text-align:center;}", ".fz5stix{white-space:nowrap;}", [".f1mk8lai{padding:0;}", {
p: -1
}], [".f1dxfoyt[data-fui-focus-visible]{outline:2px solid var(--colorStrokeFocus2);}", {
p: -1
}], [".f2krc9w[data-fui-focus-visible]{border-radius:var(--borderRadiusMedium);}", {
p: -1
}], ".f22iagw{display:flex;}", ".fqerorx{flex-grow:1;}", ".f122n59{align-items:center;}", ".f4d9j23{justify-content:center;}", ".fk73vx1{opacity:0;}", ".f1y7ij6c[data-fui-focus-within]:focus-within{opacity:1;}"]
});
/**
* Apply styling to the TableSelectionCell slots based on the state
*/
export const useTableSelectionCellStyles_unstable = state => {
'use no memo';
const styles = useStyles();
const layoutStyles = {
table: useTableLayoutStyles(),
flex: useFlexLayoutStyles()
};
state.root.className = mergeClasses(tableSelectionCellClassNames.root, styles.root, state.noNativeElements ? layoutStyles.flex.root : layoutStyles.table.root, state.subtle && state.checked === false && styles.subtle, state.hidden && styles.hidden, state.root.className);
if (state.checkboxIndicator) {
state.checkboxIndicator.className = mergeClasses(tableSelectionCellClassNames.checkboxIndicator, state.checkboxIndicator.className);
}
if (state.radioIndicator) {
state.radioIndicator.className = mergeClasses(tableSelectionCellClassNames.radioIndicator, styles.radioIndicator, state.radioIndicator.className);
}
return state;
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,75 @@
'use client';
import { makeStyles, mergeClasses } from '@griffel/react';
import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster';
import { tokens } from '@fluentui/react-theme';
export const CELL_WIDTH = 44;
export const tableSelectionCellClassNames = {
root: 'fui-TableSelectionCell',
checkboxIndicator: 'fui-TableSelectionCell__checkboxIndicator',
radioIndicator: 'fui-TableSelectionCell__radioIndicator'
};
const useTableLayoutStyles = makeStyles({
root: {
display: 'table-cell',
width: `${CELL_WIDTH}px`
}
});
const useFlexLayoutStyles = makeStyles({
root: {
display: 'flex',
flex: '1 1 0px',
minWidth: `${CELL_WIDTH}px`,
maxWidth: `${CELL_WIDTH}px`,
justifyContent: 'center'
}
});
/**
* Styles for the root slot
*/ const useStyles = makeStyles({
root: {
textAlign: 'center',
whiteSpace: 'nowrap',
padding: '0',
...createCustomFocusIndicatorStyle({
outline: `2px solid ${tokens.colorStrokeFocus2}`,
borderRadius: tokens.borderRadiusMedium
}, {
selector: 'focus'
})
},
radioIndicator: {
display: 'flex',
flexGrow: 1,
alignItems: 'center',
justifyContent: 'center'
},
subtle: {
opacity: 0,
...createCustomFocusIndicatorStyle({
opacity: 1
}, {
selector: 'focus-within'
})
},
hidden: {
opacity: 0
}
});
/**
* Apply styling to the TableSelectionCell slots based on the state
*/ export const useTableSelectionCellStyles_unstable = (state)=>{
'use no memo';
const styles = useStyles();
const layoutStyles = {
table: useTableLayoutStyles(),
flex: useFlexLayoutStyles()
};
state.root.className = mergeClasses(tableSelectionCellClassNames.root, styles.root, state.noNativeElements ? layoutStyles.flex.root : layoutStyles.table.root, state.subtle && state.checked === false && styles.subtle, state.hidden && styles.hidden, state.root.className);
if (state.checkboxIndicator) {
state.checkboxIndicator.className = mergeClasses(tableSelectionCellClassNames.checkboxIndicator, state.checkboxIndicator.className);
}
if (state.radioIndicator) {
state.radioIndicator.className = mergeClasses(tableSelectionCellClassNames.radioIndicator, styles.radioIndicator, state.radioIndicator.className);
}
return state;
};

File diff suppressed because one or more lines are too long