Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6baf51f

Browse files
authoredOct 23, 2024
fix: subtle selection should apply correctly to header rows (microsoft#33104)
1 parent d0e28c6 commit 6baf51f

File tree

5 files changed

+79
-18
lines changed

5 files changed

+79
-18
lines changed
 
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
import * as React from 'react';
22
import type { Meta } from '@storybook/react';
3-
import { Table } from '@fluentui/react-table';
3+
import { Table, tableHeaderClassNames } from '@fluentui/react-table';
44
import { Steps } from 'storywright';
55
import { withStoryWrightSteps } from '../../utilities';
6-
import { SubtleSelection } from './utils';
6+
import { SubtleSelection, SubtleSelectionEmpty } from './utils';
77

88
export default {
99
title: 'Table table - subtle selection',
1010
decorators: [
1111
story =>
12-
withStoryWrightSteps({ story, steps: new Steps().hover('.not-selected').snapshot('hover unselected row').end() }),
12+
withStoryWrightSteps({
13+
story,
14+
steps: new Steps()
15+
.hover('.not-selected')
16+
.snapshot('hover unselected row')
17+
.hover(`.${tableHeaderClassNames.root}`)
18+
.snapshot('hover header row')
19+
.end(),
20+
}),
1321
],
1422
} satisfies Meta<typeof Table>;
1523

1624
export const Rest = () => <SubtleSelection noNativeElements={false} />;
1725
Rest.storyName = 'rest';
26+
27+
export const NoSelection = () => <SubtleSelectionEmpty noNativeElements={false} />;

‎apps/vr-tests-react-components/src/stories/Table/utils.tsx‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,41 @@ export const SubtleSelection: React.FC<SharedVrTestArgs> = ({ noNativeElements }
639639
</Table>
640640
);
641641

642+
export const SubtleSelectionEmpty: React.FC<SharedVrTestArgs> = ({ noNativeElements }) => (
643+
<Table noNativeElements={noNativeElements}>
644+
<TableHeader>
645+
<TableRow>
646+
<TableSelectionCell type="checkbox" hidden />
647+
{columns.map(column => (
648+
<TableHeaderCell key={column.columnKey}>{column.label}</TableHeaderCell>
649+
))}
650+
</TableRow>
651+
</TableHeader>
652+
<TableBody>
653+
{items.map((item, i) => (
654+
<TableRow key={item.file.label}>
655+
<TableSelectionCell subtle type="checkbox" className="not-selected" />
656+
<TableCell>
657+
<TableCellLayout media={item.file.icon}>{item.file.label}</TableCellLayout>
658+
</TableCell>
659+
660+
<TableCell>
661+
<TableCellLayout
662+
media={<Avatar name={item.author.label} badge={{ status: item.author.status as PresenceBadgeStatus }} />}
663+
>
664+
{item.author.label}
665+
</TableCellLayout>
666+
</TableCell>
667+
<TableCell>{item.lastUpdated.label}</TableCell>
668+
<TableCell>
669+
<TableCellLayout media={item.lastUpdate.icon}>{item.lastUpdate.label}</TableCellLayout>
670+
</TableCell>
671+
</TableRow>
672+
))}
673+
</TableBody>
674+
</Table>
675+
);
676+
642677
export const Truncate: React.FC<SharedVrTestArgs & { truncate?: boolean }> = ({ noNativeElements, truncate }) => (
643678
<Table noNativeElements={noNativeElements} style={{ width: '400px' }}>
644679
<TableHeader>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "fix: subtle selection should apply correctly to header rows",
4+
"packageName": "@fluentui/react-table",
5+
"email": "lingfangao@hotmail.com",
6+
"dependentChangeType": "patch"
7+
}

‎packages/react-components/react-table/library/src/components/TableRow/useTableRowStyles.styles.ts‎

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,43 +31,50 @@ const useStyles = makeStyles({
3131
root: {
3232
color: tokens.colorNeutralForeground1,
3333
boxSizing: 'border-box',
34+
...createCustomFocusIndicatorStyle(
35+
{ outline: `2px solid ${tokens.colorStrokeFocus2}`, borderRadius: tokens.borderRadiusMedium },
36+
{ selector: 'focus' },
37+
),
38+
},
39+
40+
rootSubtleSelection: {
3441
...createCustomFocusIndicatorStyle(
3542
{
3643
[`& .${tableSelectionCellClassNames.root}`]: {
3744
opacity: 1,
3845
},
39-
[`& .${tableCellActionsClassNames.root}`]: {
40-
opacity: 1,
41-
},
4246
},
4347
{ selector: 'focus-within' },
4448
),
45-
...createCustomFocusIndicatorStyle(
46-
{ outline: `2px solid ${tokens.colorStrokeFocus2}`, borderRadius: tokens.borderRadiusMedium },
47-
{ selector: 'focus' },
48-
),
49+
':hover': {
50+
[`& .${tableSelectionCellClassNames.root}`]: {
51+
opacity: 1,
52+
},
53+
},
4954
},
5055

5156
rootInteractive: {
57+
...createCustomFocusIndicatorStyle(
58+
{
59+
[`& .${tableCellActionsClassNames.root}`]: {
60+
opacity: 1,
61+
},
62+
},
63+
{ selector: 'focus-within' },
64+
),
5265
':active': {
5366
backgroundColor: tokens.colorSubtleBackgroundPressed,
5467
color: tokens.colorNeutralForeground1Pressed,
5568
[`& .${tableCellActionsClassNames.root}`]: {
5669
opacity: 1,
5770
},
58-
[`& .${tableSelectionCellClassNames.root}`]: {
59-
opacity: 1,
60-
},
6171
},
6272
':hover': {
6373
backgroundColor: tokens.colorSubtleBackgroundHover,
6474
color: tokens.colorNeutralForeground1Hover,
6575
[`& .${tableCellActionsClassNames.root}`]: {
6676
opacity: 1,
6777
},
68-
[`& .${tableSelectionCellClassNames.root}`]: {
69-
opacity: 1,
70-
},
7178
},
7279
// High contrast styles
7380
'@media (forced-colors: active)': {
@@ -142,6 +149,7 @@ export const useTableRowStyles_unstable = (state: TableRowState): TableRowState
142149
state.root.className = mergeClasses(
143150
tableRowClassNames.root,
144151
styles.root,
152+
styles.rootSubtleSelection,
145153
!state.isHeaderRow && styles.rootInteractive,
146154
styles[state.size],
147155
state.noNativeElements ? layoutStyles.flex.root : layoutStyles.table.root,

‎packages/react-components/react-table/library/src/components/TableSelectionCell/useTableSelectionCell.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import * as React from 'react';
2-
import { useId, slot } from '@fluentui/react-utilities';
2+
import { useId, slot, useMergedRefs } from '@fluentui/react-utilities';
33
import { Checkbox } from '@fluentui/react-checkbox';
44
import { Radio } from '@fluentui/react-radio';
55
import type { TableSelectionCellProps, TableSelectionCellState } from './TableSelectionCell.types';
66
import { useTableCell_unstable } from '../TableCell/useTableCell';
77
import { useTableContext } from '../../contexts/tableContext';
8+
import { useFocusWithin } from '@fluentui/react-tabster';
89

910
/**
1011
* Create the state required to render TableSelectionCell.
@@ -19,7 +20,7 @@ export const useTableSelectionCell_unstable = (
1920
props: TableSelectionCellProps,
2021
ref: React.Ref<HTMLElement>,
2122
): TableSelectionCellState => {
22-
const tableCellState = useTableCell_unstable(props, ref);
23+
const tableCellState = useTableCell_unstable(props, useMergedRefs(ref, useFocusWithin()));
2324
const { noNativeElements } = useTableContext();
2425
const {
2526
type = 'checkbox',

0 commit comments

Comments
 (0)
Please sign in to comment.