From bbfb2fbc0541b4a60b15a7e8ae2653a497da737c Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Thu, 22 Sep 2022 20:48:38 +0200 Subject: [PATCH 1/6] feat: Adds `layoutType` prop to Table with flex option Native `display: table` is great for column alignment and simplifies column sizing. However, native table layout is not very virtualization friendly and does cannot handle any non-compliant element in the markup. For virtualization and other cases that involve non-compliant table elements in markup, there is a `layoutType` prop with the `native`and `flex` layouts. Flex layout is what was used before #24762 with fixes to column alignment for long content. --- .../src/components/Table/Table.types.ts | 19 ++++++- .../src/components/Table/useTable.ts | 1 + .../components/Table/useTableContextValues.ts | 5 +- .../src/components/Table/useTableStyles.ts | 29 ++++++++-- .../components/TableBody/TableBody.types.ts | 3 +- .../src/components/TableBody/useTableBody.ts | 3 +- .../TableBody/useTableBodyStyles.ts | 15 ++++- .../components/TableCell/TableCell.types.ts | 3 +- .../src/components/TableCell/useTableCell.ts | 3 +- .../TableCell/useTableCellStyles.ts | 29 +++++++++- .../TableHeader/TableHeader.types.ts | 3 +- .../components/TableHeader/useTableHeader.ts | 3 +- .../TableHeader/useTableHeaderStyles.ts | 23 +++++++- .../TableHeaderCell/TableHeaderCell.types.ts | 5 +- .../TableHeaderCell/useTableHeaderCell.tsx | 3 +- .../useTableHeaderCellStyles.ts | 28 +++++++++- .../src/components/TableRow/TableRow.types.ts | 4 +- .../src/components/TableRow/useTableRow.ts | 3 +- .../components/TableRow/useTableRowStyles.ts | 55 +++++++++++++++++-- .../TableSelectionCell.types.ts | 4 +- .../useTableSelectionCell.tsx | 3 + .../useTableSelectionCellStyles.ts | 29 +++++++++- .../react-table/src/contexts/tableContext.ts | 1 + 23 files changed, 234 insertions(+), 40 deletions(-) diff --git a/packages/react-components/react-table/src/components/Table/Table.types.ts b/packages/react-components/react-table/src/components/Table/Table.types.ts index eb5cd0b2231e8c..cb66c9daab1175 100644 --- a/packages/react-components/react-table/src/components/Table/Table.types.ts +++ b/packages/react-components/react-table/src/components/Table/Table.types.ts @@ -5,10 +5,27 @@ export type TableSlots = { }; export type TableContextValue = { + /** + * Affects the sizes of all table subcomponents + * @default medium + */ size: 'small' | 'smaller' | 'medium'; + /** + * Render all table elements as divs intead of semantic table elements + */ noNativeElements: boolean; + /** + * Uses native browser `display: table` layout or flexbox layout. + * Recommended to use flx layout for virtualized tables + * @default native + */ + layoutType: 'native' | 'flex'; + + /** + * Whether the table is sortable + */ sortable: boolean; }; @@ -27,5 +44,5 @@ export type TableProps = ComponentProps & Partial * State used in rendering Table */ export type TableState = ComponentState & - Pick, 'size' | 'noNativeElements'> & + Pick, 'size' | 'noNativeElements' | 'layoutType'> & TableContextValue; diff --git a/packages/react-components/react-table/src/components/Table/useTable.ts b/packages/react-components/react-table/src/components/Table/useTable.ts index b520505e5da169..2b612a420f2234 100644 --- a/packages/react-components/react-table/src/components/Table/useTable.ts +++ b/packages/react-components/react-table/src/components/Table/useTable.ts @@ -26,5 +26,6 @@ export const useTable_unstable = (props: TableProps, ref: React.Ref size: props.size ?? 'medium', noNativeElements: props.noNativeElements ?? false, sortable: props.sortable ?? false, + layoutType: props.layoutType ?? 'native', }; }; diff --git a/packages/react-components/react-table/src/components/Table/useTableContextValues.ts b/packages/react-components/react-table/src/components/Table/useTableContextValues.ts index e9a7bb63df310c..f419716eefc910 100644 --- a/packages/react-components/react-table/src/components/Table/useTableContextValues.ts +++ b/packages/react-components/react-table/src/components/Table/useTableContextValues.ts @@ -2,15 +2,16 @@ import * as React from 'react'; import { TableContextValues, TableState } from './Table.types'; export function useTableContextValues_unstable(state: TableState): TableContextValues { - const { size, noNativeElements, sortable } = state; + const { size, noNativeElements, sortable, layoutType } = state; const tableContext = React.useMemo( () => ({ noNativeElements, size, sortable, + layoutType, }), - [noNativeElements, size, sortable], + [noNativeElements, size, sortable, layoutType], ); return { diff --git a/packages/react-components/react-table/src/components/Table/useTableStyles.ts b/packages/react-components/react-table/src/components/Table/useTableStyles.ts index c4606db905114b..df4fada1b59983 100644 --- a/packages/react-components/react-table/src/components/Table/useTableStyles.ts +++ b/packages/react-components/react-table/src/components/Table/useTableStyles.ts @@ -8,15 +8,27 @@ export const tableClassNames: SlotClassNames = { root: 'fui-Table', }; +const useNativeLayoutStyles = makeStyles({ + root: { + display: 'table', + verticalAlign: 'middle', + width: '100%', + tableLayout: 'fixed', + }, +}); + +const useFlexLayoutStyles = makeStyles({ + root: { + display: 'block', + }, +}); + /** * Styles for the root slot */ const useStyles = makeStyles({ root: { - verticalAlign: 'middle', borderCollapse: 'collapse', - width: '100%', - display: 'table', backgroundColor: tokens.colorNeutralBackground1, }, }); @@ -26,7 +38,16 @@ const useStyles = makeStyles({ */ export const useTableStyles_unstable = (state: TableState): TableState => { const styles = useStyles(); - state.root.className = mergeClasses(tableClassName, styles.root, state.root.className); + const layoutStyles = { + native: useNativeLayoutStyles(), + flex: useFlexLayoutStyles(), + }; + state.root.className = mergeClasses( + tableClassName, + styles.root, + layoutStyles[state.layoutType].root, + state.root.className, + ); return state; }; diff --git a/packages/react-components/react-table/src/components/TableBody/TableBody.types.ts b/packages/react-components/react-table/src/components/TableBody/TableBody.types.ts index e2b732cc8225af..32e7cbf8b8eb84 100644 --- a/packages/react-components/react-table/src/components/TableBody/TableBody.types.ts +++ b/packages/react-components/react-table/src/components/TableBody/TableBody.types.ts @@ -1,4 +1,5 @@ import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; +import { TableContextValue } from '../Table/Table.types'; export type TableBodySlots = { root: Slot<'tbody', 'div'>; @@ -12,4 +13,4 @@ export type TableBodyProps = ComponentProps; /** * State used in rendering TableBody */ -export type TableBodyState = ComponentState; +export type TableBodyState = ComponentState & Pick; diff --git a/packages/react-components/react-table/src/components/TableBody/useTableBody.ts b/packages/react-components/react-table/src/components/TableBody/useTableBody.ts index 8729e7f52bb57e..409fe5e42de6ba 100644 --- a/packages/react-components/react-table/src/components/TableBody/useTableBody.ts +++ b/packages/react-components/react-table/src/components/TableBody/useTableBody.ts @@ -13,7 +13,7 @@ import { useTableContext } from '../../contexts/tableContext'; * @param ref - reference to root HTMLElement of TableBody */ export const useTableBody_unstable = (props: TableBodyProps, ref: React.Ref): TableBodyState => { - const { noNativeElements } = useTableContext(); + const { noNativeElements, layoutType } = useTableContext(); const rootComponent = props.as ?? noNativeElements ? 'div' : 'tbody'; return { @@ -25,5 +25,6 @@ export const useTableBody_unstable = (props: TableBodyProps, ref: React.Ref = { root: 'fui-TableBody', @@ -17,8 +23,11 @@ export const tableBodyClassNames: SlotClassNames = { * Apply styling to the TableBody slots based on the state */ export const useTableBodyStyles_unstable = (state: TableBodyState): TableBodyState => { - const styles = useStyles(); - state.root.className = mergeClasses(tableBodyClassName, styles.root, state.root.className); + const layoutStyles = { + native: useNativeLayoutStyles(), + flex: useFlexLayoutStyles(), + }; + state.root.className = mergeClasses(tableBodyClassName, layoutStyles[state.layoutType].root, state.root.className); return state; }; diff --git a/packages/react-components/react-table/src/components/TableCell/TableCell.types.ts b/packages/react-components/react-table/src/components/TableCell/TableCell.types.ts index d3227e64d45e95..3c487ddb9a1eda 100644 --- a/packages/react-components/react-table/src/components/TableCell/TableCell.types.ts +++ b/packages/react-components/react-table/src/components/TableCell/TableCell.types.ts @@ -1,4 +1,5 @@ import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; +import { TableContextValue } from '../Table/Table.types'; export type TableCellSlots = { root: Slot<'td', 'div'>; @@ -12,4 +13,4 @@ export type TableCellProps = ComponentProps & {}; /** * State used in rendering TableCell */ -export type TableCellState = ComponentState; +export type TableCellState = ComponentState & Pick; diff --git a/packages/react-components/react-table/src/components/TableCell/useTableCell.ts b/packages/react-components/react-table/src/components/TableCell/useTableCell.ts index 7bfd1a4284c5b1..fd06e3d6f3b84b 100644 --- a/packages/react-components/react-table/src/components/TableCell/useTableCell.ts +++ b/packages/react-components/react-table/src/components/TableCell/useTableCell.ts @@ -13,7 +13,7 @@ import { useTableContext } from '../../contexts/tableContext'; * @param ref - reference to root HTMLElement of TableCell */ export const useTableCell_unstable = (props: TableCellProps, ref: React.Ref): TableCellState => { - const { noNativeElements } = useTableContext(); + const { noNativeElements, layoutType } = useTableContext(); const rootComponent = props.as ?? noNativeElements ? 'div' : 'td'; @@ -26,5 +26,6 @@ export const useTableCell_unstable = (props: TableCellProps, ref: React.Ref = { root: tableCellClassName, }; +const useNativeLayoutStyles = makeStyles({ + root: { + display: 'table-cell', + verticalAlign: 'middle', + }, +}); + +const useFlexLayoutStyles = makeStyles({ + root: { + display: 'flex', + minWidth: '0px', + alignItems: 'center', + ...shorthands.flex(1, 1, '0px'), + }, +}); + /** * Styles for the root slot */ const useStyles = makeStyles({ root: { position: 'relative', - verticalAlign: 'middle', - display: 'table-cell', ...shorthands.padding('0px', tokens.spacingHorizontalS), }, }); @@ -25,6 +39,15 @@ const useStyles = makeStyles({ */ export const useTableCellStyles_unstable = (state: TableCellState): TableCellState => { const styles = useStyles(); - state.root.className = mergeClasses(tableCellClassNames.root, styles.root, state.root.className); + const layoutStyles = { + native: useNativeLayoutStyles(), + flex: useFlexLayoutStyles(), + }; + state.root.className = mergeClasses( + tableCellClassNames.root, + styles.root, + layoutStyles[state.layoutType].root, + state.root.className, + ); return state; }; diff --git a/packages/react-components/react-table/src/components/TableHeader/TableHeader.types.ts b/packages/react-components/react-table/src/components/TableHeader/TableHeader.types.ts index aa5a066fff418d..8905721ade576d 100644 --- a/packages/react-components/react-table/src/components/TableHeader/TableHeader.types.ts +++ b/packages/react-components/react-table/src/components/TableHeader/TableHeader.types.ts @@ -1,4 +1,5 @@ import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; +import { TableContextValue } from '../Table/Table.types'; export type TableHeaderSlots = { root: Slot<'thead', 'div'>; @@ -12,4 +13,4 @@ export type TableHeaderProps = ComponentProps & {}; /** * State used in rendering TableHeader */ -export type TableHeaderState = ComponentState; +export type TableHeaderState = ComponentState & Pick; diff --git a/packages/react-components/react-table/src/components/TableHeader/useTableHeader.ts b/packages/react-components/react-table/src/components/TableHeader/useTableHeader.ts index 7afbe5f67ac93c..1dc28c2444c2c6 100644 --- a/packages/react-components/react-table/src/components/TableHeader/useTableHeader.ts +++ b/packages/react-components/react-table/src/components/TableHeader/useTableHeader.ts @@ -14,7 +14,7 @@ import { useTableContext } from '../../contexts/tableContext'; * @param ref - reference to root HTMLElement of TableHeader */ export const useTableHeader_unstable = (props: TableHeaderProps, ref: React.Ref): TableHeaderState => { - const { noNativeElements, sortable } = useTableContext(); + const { noNativeElements, sortable, layoutType } = useTableContext(); const keyboardNavAttr = useArrowNavigationGroup({ axis: 'horizontal', circular: true }); const rootComponent = props.as ?? noNativeElements ? 'div' : 'thead'; @@ -28,5 +28,6 @@ export const useTableHeader_unstable = (props: TableHeaderProps, ref: React.Ref< ...(sortable && keyboardNavAttr), ...props, }), + layoutType, }; }; diff --git a/packages/react-components/react-table/src/components/TableHeader/useTableHeaderStyles.ts b/packages/react-components/react-table/src/components/TableHeader/useTableHeaderStyles.ts index 8e58908c1d2319..676f63215d901b 100644 --- a/packages/react-components/react-table/src/components/TableHeader/useTableHeaderStyles.ts +++ b/packages/react-components/react-table/src/components/TableHeader/useTableHeaderStyles.ts @@ -7,7 +7,21 @@ export const tableHeaderClassNames: SlotClassNames = { root: 'fui-TableHeader', }; -const useStyles = makeStyles({ +const useFlexLayoutStyles = makeStyles({ + root: { + display: 'block', + }, + + rootNative: { + display: 'table-row-group', + }, + + rootFlex: { + display: 'block', + }, +}); + +const useNativeLayoutStyles = makeStyles({ root: { display: 'table-row-group', }, @@ -17,8 +31,11 @@ const useStyles = makeStyles({ * Apply styling to the TableHeader slots based on the state */ export const useTableHeaderStyles_unstable = (state: TableHeaderState): TableHeaderState => { - const styles = useStyles(); - state.root.className = mergeClasses(tableHeaderClassName, styles.root, state.root.className); + const layoutStyles = { + native: useNativeLayoutStyles(), + flex: useFlexLayoutStyles(), + }; + state.root.className = mergeClasses(tableHeaderClassName, layoutStyles[state.layoutType].root, state.root.className); return state; }; diff --git a/packages/react-components/react-table/src/components/TableHeaderCell/TableHeaderCell.types.ts b/packages/react-components/react-table/src/components/TableHeaderCell/TableHeaderCell.types.ts index 710aea8da6cd93..40ebecc88aa8dc 100644 --- a/packages/react-components/react-table/src/components/TableHeaderCell/TableHeaderCell.types.ts +++ b/packages/react-components/react-table/src/components/TableHeaderCell/TableHeaderCell.types.ts @@ -1,6 +1,6 @@ import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; import { ARIAButtonSlotProps } from '@fluentui/react-aria'; -import { SortDirection } from '../Table/Table.types'; +import { SortDirection, TableContextValue } from '../Table/Table.types'; export type TableHeaderCellSlots = { root: Slot<'th', 'div'>; @@ -23,4 +23,5 @@ export type TableHeaderCellProps = ComponentProps> /** * State used in rendering TableHeaderCell */ -export type TableHeaderCellState = ComponentState & { sortable: boolean }; +export type TableHeaderCellState = ComponentState & + Pick; diff --git a/packages/react-components/react-table/src/components/TableHeaderCell/useTableHeaderCell.tsx b/packages/react-components/react-table/src/components/TableHeaderCell/useTableHeaderCell.tsx index 8f041ac4a0fbf7..2582248471959d 100644 --- a/packages/react-components/react-table/src/components/TableHeaderCell/useTableHeaderCell.tsx +++ b/packages/react-components/react-table/src/components/TableHeaderCell/useTableHeaderCell.tsx @@ -23,7 +23,7 @@ export const useTableHeaderCell_unstable = ( props: TableHeaderCellProps, ref: React.Ref, ): TableHeaderCellState => { - const { noNativeElements, sortable } = useTableContext(); + const { noNativeElements, sortable, layoutType } = useTableContext(); const rootComponent = props.as ?? noNativeElements ? 'div' : 'th'; return { @@ -55,5 +55,6 @@ export const useTableHeaderCell_unstable = ( }, }), sortable, + layoutType, }; }; diff --git a/packages/react-components/react-table/src/components/TableHeaderCell/useTableHeaderCellStyles.ts b/packages/react-components/react-table/src/components/TableHeaderCell/useTableHeaderCellStyles.ts index fd11a8a146a996..aaf4d4cf50c23e 100644 --- a/packages/react-components/react-table/src/components/TableHeaderCell/useTableHeaderCellStyles.ts +++ b/packages/react-components/react-table/src/components/TableHeaderCell/useTableHeaderCellStyles.ts @@ -10,13 +10,26 @@ export const tableHeaderCellClassNames: SlotClassNames = { sortIcon: 'fui-TableHeaderCell__sortIcon', }; +const useNativeLayoutStyles = makeStyles({ + root: { + display: 'table-cell', + verticalAlign: 'middle', + }, +}); + +const useFlexLayoutStyles = makeStyles({ + root: { + display: 'flex', + ...shorthands.flex(1, 1, '0px'), + minWidth: '0px', + }, +}); + /** * Styles for the root slot */ const useStyles = makeStyles({ root: { - display: 'table-cell', - verticalAlign: 'middle', ...shorthands.padding('0px', tokens.spacingHorizontalS), }, @@ -60,7 +73,16 @@ const useStyles = makeStyles({ */ export const useTableHeaderCellStyles_unstable = (state: TableHeaderCellState): TableHeaderCellState => { const styles = useStyles(); - state.root.className = mergeClasses(tableHeaderCellClassNames.root, styles.root, state.root.className); + const layoutStyles = { + native: useNativeLayoutStyles(), + flex: useFlexLayoutStyles(), + }; + state.root.className = mergeClasses( + tableHeaderCellClassNames.root, + styles.root, + layoutStyles[state.layoutType].root, + state.root.className, + ); state.button.className = mergeClasses( tableHeaderCellClassNames.button, styles.resetButton, diff --git a/packages/react-components/react-table/src/components/TableRow/TableRow.types.ts b/packages/react-components/react-table/src/components/TableRow/TableRow.types.ts index 3b85b2edca47e9..d443bee3c11b3b 100644 --- a/packages/react-components/react-table/src/components/TableRow/TableRow.types.ts +++ b/packages/react-components/react-table/src/components/TableRow/TableRow.types.ts @@ -1,5 +1,5 @@ import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; -import { TableState } from '../Table/Table.types'; +import { TableContextValue } from '../Table/Table.types'; export type TableRowSlots = { root: Slot<'tr', 'div'>; @@ -13,4 +13,4 @@ export type TableRowProps = ComponentProps & {}; /** * State used in rendering TableRow */ -export type TableRowState = ComponentState & { size: TableState['size'] }; +export type TableRowState = ComponentState & Pick; diff --git a/packages/react-components/react-table/src/components/TableRow/useTableRow.ts b/packages/react-components/react-table/src/components/TableRow/useTableRow.ts index 53f5f890aead6f..897c216c6f8cbf 100644 --- a/packages/react-components/react-table/src/components/TableRow/useTableRow.ts +++ b/packages/react-components/react-table/src/components/TableRow/useTableRow.ts @@ -13,7 +13,7 @@ import { useTableContext } from '../../contexts/tableContext'; * @param ref - reference to root HTMLElement of TableRow */ export const useTableRow_unstable = (props: TableRowProps, ref: React.Ref): TableRowState => { - const { noNativeElements, size } = useTableContext(); + const { noNativeElements, size, layoutType } = useTableContext(); const rootComponent = props.as ?? noNativeElements ? 'div' : 'tr'; return { @@ -26,5 +26,6 @@ export const useTableRow_unstable = (props: TableRowProps, ref: React.Ref = { root: tableRowClassName, }; +const useNativeLayoutStyles = makeStyles({ + root: { + display: 'table-row', + }, + + medium: { + height: '44px', + }, + + small: { + height: '34px', + }, + + smaller: { + height: '24px', + }, +}); + +const useFlexLayoutStyles = makeStyles({ + root: { + display: 'flex', + alignItems: 'center', + }, + + medium: { + minHeight: '44px', + }, + + small: { + minHeight: '34px', + }, + + smaller: { + minHeight: '24px', + }, +}); + /** * Styles for the root slot */ const useStyles = makeStyles({ root: { - display: 'table-row', color: tokens.colorNeutralForeground1, ':hover': { backgroundColor: tokens.colorNeutralBackground1Hover, @@ -24,20 +60,18 @@ const useStyles = makeStyles({ opacity: 1, }, }, + boxSizing: 'border-box', }, medium: { - height: '44px', ...shorthands.borderBottom(tokens.strokeWidthThin, 'solid', tokens.colorNeutralStroke2), }, small: { - height: '34px', ...shorthands.borderBottom(tokens.strokeWidthThin, 'solid', tokens.colorNeutralStroke2), }, smaller: { - height: '24px', fontSize: tokens.fontSizeBase200, }, }); @@ -47,7 +81,18 @@ const useStyles = makeStyles({ */ export const useTableRowStyles_unstable = (state: TableRowState): TableRowState => { const styles = useStyles(); - state.root.className = mergeClasses(tableRowClassNames.root, styles.root, styles[state.size], state.root.className); + const layoutStyles = { + native: useNativeLayoutStyles(), + flex: useFlexLayoutStyles(), + }; + state.root.className = mergeClasses( + tableRowClassNames.root, + styles.root, + styles[state.size], + layoutStyles[state.layoutType].root, + layoutStyles[state.layoutType][state.size], + state.root.className, + ); return state; }; diff --git a/packages/react-components/react-table/src/components/TableSelectionCell/TableSelectionCell.types.ts b/packages/react-components/react-table/src/components/TableSelectionCell/TableSelectionCell.types.ts index c8ff497d29eb38..95e2c074d6938c 100644 --- a/packages/react-components/react-table/src/components/TableSelectionCell/TableSelectionCell.types.ts +++ b/packages/react-components/react-table/src/components/TableSelectionCell/TableSelectionCell.types.ts @@ -1,6 +1,7 @@ import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; import type { Checkbox, CheckboxProps } from '@fluentui/react-checkbox'; import { TableCellSlots } from '../TableCell/TableCell.types'; +import { TableContextValue } from '../Table/Table.types'; export type TableSelectionCellSlots = { /** @@ -28,4 +29,5 @@ export type TableSelectionCellProps = ComponentProps & - Pick, 'type' | 'checked'>; + Pick, 'type' | 'checked'> & + Pick; diff --git a/packages/react-components/react-table/src/components/TableSelectionCell/useTableSelectionCell.tsx b/packages/react-components/react-table/src/components/TableSelectionCell/useTableSelectionCell.tsx index c66f08b6e440e5..244eff5acf3517 100644 --- a/packages/react-components/react-table/src/components/TableSelectionCell/useTableSelectionCell.tsx +++ b/packages/react-components/react-table/src/components/TableSelectionCell/useTableSelectionCell.tsx @@ -4,6 +4,7 @@ import { Checkbox } from '@fluentui/react-checkbox'; import { CheckmarkFilled } from '@fluentui/react-icons'; import type { TableSelectionCellProps, TableSelectionCellState } from './TableSelectionCell.types'; import { useTableCell_unstable } from '../TableCell/useTableCell'; +import { useTableContext } from '../../contexts/tableContext'; /** * Create the state required to render TableSelectionCell. @@ -19,6 +20,7 @@ export const useTableSelectionCell_unstable = ( ref: React.Ref, ): TableSelectionCellState => { const tableCellState = useTableCell_unstable(props, ref); + const { layoutType } = useTableContext(); const type = props.type ?? 'checkbox'; return { @@ -38,5 +40,6 @@ export const useTableSelectionCell_unstable = ( }), type, checked: props.checked ?? false, + layoutType, }; }; diff --git a/packages/react-components/react-table/src/components/TableSelectionCell/useTableSelectionCellStyles.ts b/packages/react-components/react-table/src/components/TableSelectionCell/useTableSelectionCellStyles.ts index f0522e8214b1bc..46bbe77ba0cb68 100644 --- a/packages/react-components/react-table/src/components/TableSelectionCell/useTableSelectionCellStyles.ts +++ b/packages/react-components/react-table/src/components/TableSelectionCell/useTableSelectionCellStyles.ts @@ -8,16 +8,30 @@ export const tableSelectionCellClassNames: SlotClassNames { const styles = useStyles(); - state.root.className = mergeClasses(tableSelectionCellClassNames.root, styles.root, state.root.className); + const layoutStyles = { + native: useNativeLayoutStyles(), + flex: useFlexLayoutStyles(), + }; + state.root.className = mergeClasses( + tableSelectionCellClassNames.root, + styles.root, + layoutStyles[state.layoutType].root, + state.root.className, + ); if (state.checkboxIndicator) { state.checkboxIndicator.className = mergeClasses( tableSelectionCellClassNames.checkboxIndicator, diff --git a/packages/react-components/react-table/src/contexts/tableContext.ts b/packages/react-components/react-table/src/contexts/tableContext.ts index f7c87cabd0fb78..1832a2f6047c83 100644 --- a/packages/react-components/react-table/src/contexts/tableContext.ts +++ b/packages/react-components/react-table/src/contexts/tableContext.ts @@ -7,6 +7,7 @@ export const tableContextDefaultValue: TableContextValue = { size: 'medium', noNativeElements: false, sortable: false, + layoutType: 'native', }; export const TableContextProvider = tableContext.Provider; From 9bc33df9d3732a320d98ba0ea70e016406a7b468 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Fri, 23 Sep 2022 09:51:52 +0200 Subject: [PATCH 2/6] update test and md --- .../react-table/etc/react-table.api.md | 19 ++++++++----------- .../Table/useTableContextValues.test.ts | 1 + 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/react-components/react-table/etc/react-table.api.md b/packages/react-components/react-table/etc/react-table.api.md index 32023ee3e96a1b..4dffd4c2e4225a 100644 --- a/packages/react-components/react-table/etc/react-table.api.md +++ b/packages/react-components/react-table/etc/react-table.api.md @@ -87,7 +87,7 @@ export type TableBodySlots = { }; // @public -export type TableBodyState = ComponentState; +export type TableBodyState = ComponentState & Pick; // @public export const TableCell: ForwardRefComponent; @@ -149,7 +149,7 @@ export type TableCellSlots = { }; // @public -export type TableCellState = ComponentState; +export type TableCellState = ComponentState & Pick; // @public (undocumented) export const tableClassName = "fui-Table"; @@ -164,6 +164,7 @@ export const TableContextProvider: React_2.Provider & { - sortable: boolean; -}; +export type TableHeaderCellState = ComponentState & Pick; // @public (undocumented) export const tableHeaderClassName = "fui-TableHeader"; @@ -216,7 +215,7 @@ export type TableHeaderSlots = { }; // @public -export type TableHeaderState = ComponentState; +export type TableHeaderState = ComponentState & Pick; // @public export type TableProps = ComponentProps & Partial; @@ -239,9 +238,7 @@ export type TableRowSlots = { }; // @public -export type TableRowState = ComponentState & { - size: TableState['size']; -}; +export type TableRowState = ComponentState & Pick; // @public export const TableSelectionCell: ForwardRefComponent; @@ -262,7 +259,7 @@ export type TableSelectionCellSlots = { } & Pick; // @public -export type TableSelectionCellState = ComponentState & Pick, 'type' | 'checked'>; +export type TableSelectionCellState = ComponentState & Pick, 'type' | 'checked'> & Pick; // @public (undocumented) export interface TableSelectionState { @@ -292,7 +289,7 @@ export interface TableSortState { } // @public -export type TableState = ComponentState & Pick, 'size' | 'noNativeElements'> & TableContextValue; +export type TableState = ComponentState & Pick, 'size' | 'noNativeElements' | 'layoutType'> & TableContextValue; // @public (undocumented) export function useTable = RowState>(options: UseTableOptions): TableState_2; diff --git a/packages/react-components/react-table/src/components/Table/useTableContextValues.test.ts b/packages/react-components/react-table/src/components/Table/useTableContextValues.test.ts index 3640099f95ae66..1a4566b43e3e94 100644 --- a/packages/react-components/react-table/src/components/Table/useTableContextValues.test.ts +++ b/packages/react-components/react-table/src/components/Table/useTableContextValues.test.ts @@ -13,6 +13,7 @@ describe('useTableContextValues', () => { expect(result.current).toMatchInlineSnapshot(` Object { "table": Object { + "layoutType": "native", "noNativeElements": false, "size": "medium", "sortable": false, From 52ead2399c37011beda72c47128ded0091c667cc Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Fri, 23 Sep 2022 10:18:03 +0200 Subject: [PATCH 3/6] vr tests should test both layout types --- .../src/stories/Table.stories.tsx | 925 +++++++++--------- 1 file changed, 469 insertions(+), 456 deletions(-) diff --git a/apps/vr-tests-react-components/src/stories/Table.stories.tsx b/apps/vr-tests-react-components/src/stories/Table.stories.tsx index 1cdbaef5daf7cd..4f18442262a7c8 100644 --- a/apps/vr-tests-react-components/src/stories/Table.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Table.stories.tsx @@ -21,6 +21,7 @@ import { TableCellLayout, TableSelectionCell, TableCellActions, + TableProps, } from '@fluentui/react-table'; import { Button } from '@fluentui/react-button'; import { storiesOf } from '@storybook/react'; @@ -72,474 +73,486 @@ const columns = [ { columnKey: 'lastUpdate', label: 'Last update' }, ]; -storiesOf('Table - cell actions', module) - .addDecorator(story => ( - {story()} - )) - .addStory( - 'default', - () => ( - - - - {columns.map(column => ( - {column.label} - ))} - - - - {items.map(item => ( - - - - {item.file.label} - -
- ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory( - 'always visible', - () => ( - - - - {columns.map(column => ( - {column.label} - ))} - - - - {items.map(item => ( - - - - {item.file.label} - -
- ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory('in header cell', () => ( - - - - {columns.map(column => ( - {column.label} - ))} +interface SharedVrTestArgs { + layoutType: TableProps['layoutType']; +} + +const CellActionsDefault: React.FC = ({ layoutType }) => ( +
+ + + {columns.map(column => ( + {column.label} + ))} + + + + {items.map(item => ( + + + + {item.file.label} + +
+); + +const CellActionsAlwaysVisible: React.FC = ({ layoutType }) => ( + + + + {columns.map(column => ( + {column.label} ))} - -
- )); + + + + {items.map(item => ( + + + + {item.file.label} + +