Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions change/@fluentui-react-table-base-hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕵🏾‍♀️ visual changes to review in the Visual Change Report

vr-tests-react-components/Charts-DonutChart 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Charts-DonutChart.Dynamic - RTL.default.chromium.png 5570 Changed
vr-tests-react-components/Menu Converged - submenuIndicator slotted content 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Menu Converged - submenuIndicator slotted content.default.submenus open.chromium.png 413 Changed
vr-tests-react-components/Positioning 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Positioning.Positioning end.chromium.png 757 Changed
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 606 Changed
vr-tests-react-components/TagPicker 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled.chromium.png 677 Changed

There were 1 duplicate changes discarded. Check the build logs for more information.

"type": "minor",
"comment": "feat: add base hooks for Table, TableCell, TableRow, TableCellLayout, DataGrid, DataGridRow",
"packageName": "@fluentui/react-table",
"email": "dmytrokirpa@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export type {
DataGridBaseProps,
DataGridBaseState,
DataGridContextValue,
DataGridContextValues,
DataGridFocusMode,
Expand All @@ -12,5 +14,6 @@ export {
renderDataGrid_unstable,
useDataGridContextValues_unstable,
useDataGridStyles_unstable,
useDataGridBase_unstable,
useDataGrid_unstable,
} from './components/DataGrid/index';
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export type {
CellRenderFunction,
DataGridRowBaseProps,
DataGridRowBaseState,
DataGridRowProps,
DataGridRowSlots,
DataGridRowState,
Expand All @@ -9,5 +11,6 @@ export {
dataGridRowClassNames,
renderDataGridRow_unstable,
useDataGridRowStyles_unstable,
useDataGridRowBase_unstable,
useDataGridRow_unstable,
} from './components/DataGridRow/index';
3 changes: 3 additions & 0 deletions packages/react-components/react-table/library/src/Table.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export type {
SortDirection,
TableBaseProps,
TableBaseState,
TableContextValue,
TableContextValues,
TableProps,
Expand All @@ -12,5 +14,6 @@ export {
tableClassName,
tableClassNames,
useTableStyles_unstable,
useTableBase_unstable,
useTable_unstable,
} from './components/Table/index';
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
export type { TableCellProps, TableCellSlots, TableCellState } from './components/TableCell/index';
export type {
TableCellBaseProps,
TableCellBaseState,
TableCellProps,
TableCellSlots,
TableCellState,
} from './components/TableCell/index';
export {
TableCell,
renderTableCell_unstable,
tableCellClassName,
tableCellClassNames,
useTableCellStyles_unstable,
useTableCellBase_unstable,
useTableCell_unstable,
} from './components/TableCell/index';
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export type {
TableCellLayoutBaseProps,
TableCellLayoutBaseState,
TableCellLayoutContextValues,
TableCellLayoutProps,
TableCellLayoutSlots,
Expand All @@ -9,5 +11,6 @@ export {
renderTableCellLayout_unstable,
tableCellLayoutClassNames,
useTableCellLayoutStyles_unstable,
useTableCellLayoutBase_unstable,
useTableCellLayout_unstable,
} from './components/TableCellLayout/index';
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
export type { TableRowProps, TableRowSlots, TableRowState } from './components/TableRow/index';
export type {
TableRowBaseProps,
TableRowBaseState,
TableRowProps,
TableRowSlots,
TableRowState,
} from './components/TableRow/index';
export {
TableRow,
renderTableRow_unstable,
tableRowClassName,
tableRowClassNames,
useTableRowStyles_unstable,
useTableRowBase_unstable,
useTableRow_unstable,
} from './components/TableRow/index';
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { SelectionHookParams, SelectionMode } from '@fluentui/react-utilities';
import { DistributiveOmit, SelectionHookParams, SelectionMode } from '@fluentui/react-utilities';
import { TabsterDOMAttribute } from '@fluentui/react-tabster';
import type { TableContextValues, TableProps, TableSlots, TableState } from '../Table/Table.types';
import type {
Expand Down Expand Up @@ -118,3 +118,13 @@ export type DataGridState = TableState & { tableState: TableFeaturesState<unknow
| 'resizableColumns'
| 'compositeRowTabsterAttribute'
>;

/**
* DataGrid Props without design-only props.
*/
export type DataGridBaseProps = DistributiveOmit<DataGridProps, 'subtleSelection' | 'selectionAppearance' | 'size'>;

/**
* State used in rendering DataGrid, without design-only state.
*/
export type DataGridBaseState = DistributiveOmit<DataGridState, 'subtleSelection' | 'selectionAppearance' | 'size'>;
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export { DataGrid } from './DataGrid';
export type {
DataGridBaseProps,
DataGridBaseState,
DataGridContextValue,
DataGridContextValues,
DataGridFocusMode,
Expand All @@ -8,6 +10,6 @@ export type {
DataGridState,
} from './DataGrid.types';
export { renderDataGrid_unstable } from './renderDataGrid';
export { useDataGrid_unstable } from './useDataGrid';
export { useDataGridBase_unstable, useDataGrid_unstable } from './useDataGrid';
export { dataGridClassNames, useDataGridStyles_unstable } from './useDataGridStyles.styles';
export { useDataGridContextValues_unstable } from './useDataGridContextValues';
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import * as React from 'react';
import { useArrowNavigationGroup, useFocusFinders } from '@fluentui/react-tabster';
import type { DataGridProps, DataGridState } from './DataGrid.types';
import { useTable_unstable } from '../Table/useTable';
import type { DataGridBaseProps, DataGridBaseState, DataGridProps, DataGridState } from './DataGrid.types';
import { useTableBase_unstable } from '../Table/useTable';
import { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';
import { End, Home } from '@fluentui/keyboard-keys';
import {
Expand All @@ -16,15 +16,12 @@ import {
import { CELL_WIDTH } from '../TableSelectionCell';

/**
* Create the state required to render DataGrid.
*
* The returned state can be modified with hooks such as useDataGridStyles_unstable,
* before being passed to renderDataGrid_unstable.
* Create the base state required to render DataGrid, without design-only props.
*
* @param props - props from this instance of DataGrid
* @param props - props from this instance of DataGrid (without subtleSelection, selectionAppearance, size)
* @param ref - reference to root HTMLElement of DataGrid
*/
export const useDataGrid_unstable = (props: DataGridProps, ref: React.Ref<HTMLElement>): DataGridState => {
export const useDataGridBase_unstable = (props: DataGridBaseProps, ref: React.Ref<HTMLElement>): DataGridBaseState => {
const {
items,
columns,
Expand All @@ -36,8 +33,6 @@ export const useDataGrid_unstable = (props: DataGridProps, ref: React.Ref<HTMLEl
sortState,
selectedItems,
defaultSelectedItems,
subtleSelection = false,
selectionAppearance = 'brand',
getRowId,
resizableColumns,
columnSizingOptions,
Expand Down Expand Up @@ -73,11 +68,7 @@ export const useDataGrid_unstable = (props: DataGridProps, ref: React.Ref<HTMLEl
useTableColumnSizing_unstable({
onColumnResize,
columnSizingOptions,
// The selection cell is not part of the columns, therefore its width needs to be subtracted
// from the container to make sure the columns don't overflow the table.
containerWidthOffset: widthOffset,
// Disables automatic resizing of columns when the container overflows.
// This allows the sum of the columns to be larger than the container.
autoFitColumns: resizableColumnsOptions.autoFitColumns ?? true,
}),
]);
Expand All @@ -88,7 +79,6 @@ export const useDataGrid_unstable = (props: DataGridProps, ref: React.Ref<HTMLEl
props.onKeyDown?.(e);
focusMode === 'composite' && onCompositeKeyDown(e);

// handle ctrl+home and ctrl+end
if (!innerRef.current || !e.ctrlKey || e.defaultPrevented) {
return;
}
Expand All @@ -109,7 +99,7 @@ export const useDataGrid_unstable = (props: DataGridProps, ref: React.Ref<HTMLEl
}
});

const baseTableState = useTable_unstable(
const baseTableState = useTableBase_unstable(
{
role: 'grid',
as: 'div',
Expand All @@ -128,9 +118,26 @@ export const useDataGrid_unstable = (props: DataGridProps, ref: React.Ref<HTMLEl
focusMode,
tableState,
selectableRows: !!selectionMode,
subtleSelection,
selectionAppearance,
resizableColumns,
compositeRowTabsterAttribute,
};
};

/**
* Create the state required to render DataGrid.
*
* The returned state can be modified with hooks such as useDataGridStyles_unstable,
* before being passed to renderDataGrid_unstable.
*
* @param props - props from this instance of DataGrid
* @param ref - reference to root HTMLElement of DataGrid
*/
export const useDataGrid_unstable = (props: DataGridProps, ref: React.Ref<HTMLElement>): DataGridState => {
const { subtleSelection = false, selectionAppearance = 'brand' } = props;
return {
...useDataGridBase_unstable(props, ref),
subtleSelection,
selectionAppearance,
size: props.size ?? 'medium',
};
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';
import type { ComponentProps, ComponentState, DistributiveOmit, Slot } from '@fluentui/react-utilities';
import type { TableColumnDefinition } from '../../hooks';
import { DataGridContextValue } from '../DataGrid/DataGrid.types';
import type { TableRowProps, TableRowSlots, TableRowState } from '../TableRow/TableRow.types';
Expand Down Expand Up @@ -36,3 +36,13 @@ export type DataGridRowState = TableRowState &
columnDefs: TableColumnDefinition<any>[];
dataGridContextValue: DataGridContextValue;
};

/**
* DataGridRow Props without design-only props.
*/
export type DataGridRowBaseProps<TItem = unknown> = DistributiveOmit<DataGridRowProps<TItem>, 'appearance'>;

/**
* State used in rendering DataGridRow, without design-only state.
*/
export type DataGridRowBaseState = DistributiveOmit<DataGridRowState, 'appearance' | 'size'>;
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
export { DataGridRow } from './DataGridRow';
export type { CellRenderFunction, DataGridRowProps, DataGridRowSlots, DataGridRowState } from './DataGridRow.types';
export type {
CellRenderFunction,
DataGridRowBaseProps,
DataGridRowBaseState,
DataGridRowProps,
DataGridRowSlots,
DataGridRowState,
} from './DataGridRow.types';
export { renderDataGridRow_unstable } from './renderDataGridRow';
export { useDataGridRow_unstable } from './useDataGridRow';
export { useDataGridRowBase_unstable, useDataGridRow_unstable } from './useDataGridRow';
export { dataGridRowClassNames, useDataGridRowStyles_unstable } from './useDataGridRowStyles.styles';
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,29 @@
import * as React from 'react';
import { isInteractiveHTMLElement, useEventCallback, slot } from '@fluentui/react-utilities';
import { Space } from '@fluentui/keyboard-keys';
import type { DataGridRowProps, DataGridRowState } from './DataGridRow.types';
import { useTableRow_unstable } from '../TableRow/useTableRow';
import type {
DataGridRowBaseProps,
DataGridRowBaseState,
DataGridRowProps,
DataGridRowState,
} from './DataGridRow.types';
import { useTableRowBase_unstable } from '../TableRow/useTableRow';
import { dataGridContextDefaultValue, useDataGridContext_unstable } from '../../contexts/dataGridContext';
import { useTableContext } from '../../contexts/tableContext';
import { DataGridSelectionCell } from '../DataGridSelectionCell/DataGridSelectionCell';
import { useTableRowIdContext } from '../../contexts/rowIdContext';
import { useIsInTableHeader } from '../../contexts/tableHeaderContext';

/**
* Create the state required to render DataGridRow.
* Create the base state required to render DataGridRow, without design-only props.
*
* The returned state can be modified with hooks such as useDataGridRowStyles_unstable,
* before being passed to renderDataGridRow_unstable.
*
* @param props - props from this instance of DataGridRow
* @param props - props from this instance of DataGridRow (without appearance)
* @param ref - reference to root HTMLElement of DataGridRow
*/
export const useDataGridRow_unstable = (props: DataGridRowProps, ref: React.Ref<HTMLElement>): DataGridRowState => {
export const useDataGridRowBase_unstable = (
props: DataGridRowBaseProps,
ref: React.Ref<HTMLElement>,
): DataGridRowBaseState => {
const rowId = useTableRowIdContext();
const isHeader = useIsInTableHeader();
const columnDefs = useDataGridContext_unstable(ctx => ctx.columns);
Expand All @@ -29,13 +35,7 @@ export const useDataGridRow_unstable = (props: DataGridRowProps, ref: React.Ref<
const compositeRowTabsterAttribute = useDataGridContext_unstable(ctx => ctx.compositeRowTabsterAttribute);

const tabbable = focusMode === 'row_unstable' || focusMode === 'composite';
const appearance = useDataGridContext_unstable(ctx => {
if (!isHeader && selectable && ctx.selection.isRowSelected(rowId)) {
return ctx.selectionAppearance;
}

return 'none';
});
const toggleRow = useDataGridContext_unstable(ctx => ctx.selection.toggleRow);

const onClick = useEventCallback((e: React.MouseEvent<HTMLTableRowElement>) => {
Expand All @@ -56,9 +56,8 @@ export const useDataGridRow_unstable = (props: DataGridRowProps, ref: React.Ref<
props.onKeyDown?.(e);
});

const baseState = useTableRow_unstable(
const baseState = useTableRowBase_unstable(
{
appearance,
'aria-selected': selectable ? selected : undefined,
tabIndex: tabbable && !isHeader ? 0 : undefined,
...(focusMode === 'composite' && !isHeader && compositeRowTabsterAttribute),
Expand All @@ -84,12 +83,38 @@ export const useDataGridRow_unstable = (props: DataGridRowProps, ref: React.Ref<
}),
renderCell: props.children,
columnDefs,
// This context value should not be used internally
// It's intended to help power user render functions
dataGridContextValue: useStableDataGridContextValue(),
};
};

/**
* Create the state required to render DataGridRow.
*
* The returned state can be modified with hooks such as useDataGridRowStyles_unstable,
* before being passed to renderDataGridRow_unstable.
*
* @param props - props from this instance of DataGridRow
* @param ref - reference to root HTMLElement of DataGridRow
*/
export const useDataGridRow_unstable = (props: DataGridRowProps, ref: React.Ref<HTMLElement>): DataGridRowState => {
const rowId = useTableRowIdContext();
const isHeader = useIsInTableHeader();
const selectable = useDataGridContext_unstable(ctx => ctx.selectableRows);
const { size } = useTableContext();
const appearance = useDataGridContext_unstable(ctx => {
if (!isHeader && selectable && ctx.selection.isRowSelected(rowId)) {
return ctx.selectionAppearance ?? 'brand';
}

return 'none';
});
return {
...useDataGridRowBase_unstable(props, ref),
appearance,
size,
};
};

function useStableDataGridContextValue() {
const ref = React.useRef(dataGridContextDefaultValue);

Expand Down
Loading
Loading