Skip to content
Merged
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
48 changes: 48 additions & 0 deletions apps/vr-tests-react-components/src/stories/Table.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,49 @@ const SubtleSelection: React.FC<SharedVrTestArgs> = ({ noNativeElements }) => (
</Table>
);

const Truncate: React.FC<SharedVrTestArgs & { truncate?: boolean }> = ({ noNativeElements, truncate }) => (
<Table noNativeElements={noNativeElements} style={{ width: '400px' }}>
<TableHeader>
<TableRow>
{columns.map(column => (
<TableHeaderCell key={column.columnKey}>{column.label}</TableHeaderCell>
))}
</TableRow>
</TableHeader>
<TableBody>
{items.map((item, i) => (
<TableRow key={item.file.label} className={`row-${i}`}>
<TableCell>
<TableCellLayout truncate={truncate} media={item.file.icon}>
{item.file.label}
<TableCellActions>
<Button icon={<EditRegular />} appearance="subtle" />
<Button icon={<MoreHorizontalRegular />} appearance="subtle" />
</TableCellActions>
</TableCellLayout>
</TableCell>
<TableCell>
<TableCellLayout
truncate={truncate}
media={<Avatar name={item.author.label} badge={{ status: item.author.status as PresenceBadgeStatus }} />}
>
{item.author.label}
</TableCellLayout>
</TableCell>
<TableCell>
<TableCellLayout truncate={truncate}>{item.lastUpdated.label}</TableCellLayout>
</TableCell>
<TableCell>
<TableCellLayout truncate={truncate} media={item.lastUpdate.icon}>
{item.lastUpdate.label}
</TableCellLayout>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);

([true, false] as const).forEach(noNativeElements => {
const layoutName = noNativeElements ? 'flex' : 'table';
storiesOf(`Table layout ${layoutName} - cell actions`, module)
Expand Down Expand Up @@ -712,4 +755,9 @@ const SubtleSelection: React.FC<SharedVrTestArgs> = ({ noNativeElements }) => (
includeDarkMode: true,
includeHighContrast: true,
});

storiesOf(`Table layout ${layoutName} - truncate`, module)
.addStory('default (disabled)', () => <Truncate noNativeElements={noNativeElements} />)
.addStory('false', () => <Truncate noNativeElements={noNativeElements} truncate={false} />)
.addStory('true', () => <Truncate noNativeElements={noNativeElements} truncate={true} />);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"comment": "feat: TableCellLayout component now supports truncate prop",
"dependentChangeType": "patch",
"email": "[email protected]",
"packageName": "@fluentui/react-table",
"type": "prerelease"
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ export const tableCellLayoutClassNames: SlotClassNames<TableCellLayoutSlots>;
// @public
export type TableCellLayoutProps = ComponentProps<Partial<TableCellLayoutSlots>> & {
appearance?: 'primary';
truncate?: boolean;
};

// @public (undocumented)
Expand All @@ -304,7 +305,7 @@ export type TableCellLayoutSlots = {
};

// @public
export type TableCellLayoutState = ComponentState<TableCellLayoutSlots> & Pick<TableCellLayoutProps, 'appearance'> & {
export type TableCellLayoutState = ComponentState<TableCellLayoutSlots> & Pick<TableCellLayoutProps, 'appearance' | 'truncate'> & {
avatarSize: AvatarSize | undefined;
} & Pick<TableContextValue, 'size'>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,18 @@ export type TableCellLayoutProps = ComponentProps<Partial<TableCellLayoutSlots>>
* @default undefined
*/
appearance?: 'primary';

/**
* Renders content with overflow: hidden and text-overflow: ellipsis
*/
truncate?: boolean;
};

/**
* State used in rendering TableCellLayout
*/
export type TableCellLayoutState = ComponentState<TableCellLayoutSlots> &
Pick<TableCellLayoutProps, 'appearance'> & { avatarSize: AvatarSize | undefined } & Pick<TableContextValue, 'size'>;
Pick<TableCellLayoutProps, 'appearance' | 'truncate'> & { avatarSize: AvatarSize | undefined } & Pick<
TableContextValue,
'size'
>;
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const useTableCellLayout_unstable = (
},
root: getNativeElementProps('div', { ref, ...props }),
appearance: props.appearance,
truncate: props.truncate,
main: resolveShorthand(props.main, { required: true }),
media: resolveShorthand(props.media),
description: resolveShorthand(props.description),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,20 @@ const useStyles = makeStyles({
...shorthands.gap(tokens.spacingHorizontalS),
...shorthands.flex(1, 1, '0px'),
},

rootTruncate: {
overflowX: 'hidden',
},

content: {
display: 'flex',
flexDirection: 'column',
},

contentTruncate: {
overflowX: 'hidden',
},

media: {
display: 'flex',
alignItems: 'center',
Expand All @@ -48,6 +57,12 @@ const useStyles = makeStyles({
fontWeight: tokens.fontWeightSemibold,
},

mainTruncate: {
overflowX: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
},

description: {
color: tokens.colorNeutralForeground2,
...typographyStyles.caption1,
Expand All @@ -59,7 +74,14 @@ const useStyles = makeStyles({
*/
export const useTableCellLayoutStyles_unstable = (state: TableCellLayoutState): TableCellLayoutState => {
const styles = useStyles();
state.root.className = mergeClasses(tableCellLayoutClassNames.root, styles.root, state.root.className);
const { truncate } = state;

state.root.className = mergeClasses(
tableCellLayoutClassNames.root,
styles.root,
truncate && styles.rootTruncate,
state.root.className,
);
const primary = state.appearance === 'primary';

if (state.media) {
Expand All @@ -81,6 +103,7 @@ export const useTableCellLayoutStyles_unstable = (state: TableCellLayoutState):
if (state.main) {
state.main.className = mergeClasses(
tableCellLayoutClassNames.main,
truncate && styles.mainTruncate,
primary && styles.mainPrimary,
state.main.className,
);
Expand All @@ -95,7 +118,12 @@ export const useTableCellLayoutStyles_unstable = (state: TableCellLayoutState):
}

if (state.content) {
state.content.className = mergeClasses(tableCellLayoutClassNames.content, styles.content, state.content.className);
state.content.className = mergeClasses(
tableCellLayoutClassNames.content,
styles.content,
truncate && styles.contentTruncate,
state.content.className,
);
}

return state;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ const columnsDef: TableColumnDefinition<Item>[] = [
createTableColumn<Item>({
columnId: 'file',
renderHeaderCell: () => <>File</>,
renderCell: (item: Item) => <TableCellLayout media={item.file.icon}>{item.file.label}</TableCellLayout>,
renderCell: (item: Item) => (
<TableCellLayout truncate media={item.file.icon}>
{item.file.label}
</TableCellLayout>
),
compare: (a, b) => {
return a.file.label.localeCompare(b.file.label);
},
Expand All @@ -42,6 +46,7 @@ const columnsDef: TableColumnDefinition<Item>[] = [
renderHeaderCell: () => <>Author</>,
renderCell: (item: Item) => (
<TableCellLayout
truncate
media={<Avatar name={item.author.label} badge={{ status: item.author.status as PresenceBadgeStatus }} />}
>
{item.author.label}
Expand All @@ -54,15 +59,19 @@ const columnsDef: TableColumnDefinition<Item>[] = [
createTableColumn<Item>({
columnId: 'lastUpdated',
renderHeaderCell: () => <>Last updated</>,
renderCell: (item: Item) => item.lastUpdated.label,
renderCell: (item: Item) => <TableCellLayout truncate>{item.lastUpdated.label}</TableCellLayout>,
compare: (a, b) => {
return a.lastUpdated.timestamp - b.lastUpdated.timestamp;
},
}),
createTableColumn<Item>({
columnId: 'lastUpdate',
renderHeaderCell: () => <>Last update</>,
renderCell: (item: Item) => <TableCellLayout media={item.lastUpdate.icon}>{item.lastUpdate.label}</TableCellLayout>,
renderCell: (item: Item) => (
<TableCellLayout truncate media={item.lastUpdate.icon}>
{item.lastUpdate.label}
</TableCellLayout>
),
compare: (a, b) => {
return a.lastUpdate.label.localeCompare(b.lastUpdate.label);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,14 @@ export const ResizableColumnsUncontrolled = () => {
const [columnSizingOptions] = useState<TableColumnSizingOptions>({
file: {
idealWidth: 300,
minWidth: 190,
minWidth: 150,
},
author: {
minWidth: 170,
minWidth: 110,
defaultWidth: 250,
},
lastUpdate: {
minWidth: 220,
minWidth: 150,
},
});

Expand Down Expand Up @@ -170,10 +170,13 @@ export const ResizableColumnsUncontrolled = () => {
{rows.map(({ item }) => (
<TableRow key={item.file.label}>
<TableCell {...columnSizing_unstable.getTableCellProps('file')}>
<TableCellLayout media={item.file.icon}>{item.file.label}</TableCellLayout>
<TableCellLayout truncate media={item.file.icon}>
{item.file.label}
</TableCellLayout>
</TableCell>
<TableCell {...columnSizing_unstable.getTableCellProps('author')}>
<TableCellLayout
truncate
media={
<Avatar name={item.author.label} badge={{ status: item.author.status as PresenceBadgeStatus }} />
}
Expand All @@ -182,10 +185,12 @@ export const ResizableColumnsUncontrolled = () => {
</TableCellLayout>
</TableCell>
<TableCell {...columnSizing_unstable.getTableCellProps('lastUpdated')}>
{item.lastUpdated.label}
<TableCellLayout truncate>{item.lastUpdated.label}</TableCellLayout>
</TableCell>
<TableCell {...columnSizing_unstable.getTableCellProps('lastUpdate')}>
<TableCellLayout media={item.lastUpdate.icon}>{item.lastUpdate.label}</TableCellLayout>
<TableCellLayout truncate media={item.lastUpdate.icon}>
{item.lastUpdate.label}
</TableCellLayout>
</TableCell>
</TableRow>
))}
Expand Down