Skip to content

Commit c7c2312

Browse files
[IndexTable.Row] Fix tone interaction states; remove subdued and status (#10705)
<!-- ☝️How to write a good PR title: - Prefix it with [ComponentName] (if applicable), for example: [Button] - Start with a verb, for example: Add, Delete, Improve, Fix… - Give as much context as necessary and as little as possible - Prefix it with [WIP] while it’s a work in progress --> ### WHY are these changes introduced? This PR removes the deprecated `status` and `subdued` props. It also fixes the missing and buggy interaction states when `IndexTable.Row` has a `tone`. | Before | After | |--------|--------| |<video src="https://github.com/Shopify/polaris/assets/18447883/2f2e2f76-adbc-4bed-a18b-c09a23b7542e"/>|<video src="https://github.com/Shopify/polaris/assets/18447883/4b097d18-4c0c-4fec-b561-9fc9ba2c55b9"/>| ### 🎩 checklist - [x] Tested on [mobile](https://github.com/Shopify/polaris/blob/main/documentation/Tophatting.md#cross-browser-testing) - [x] Tested on [multiple browsers](https://help.shopify.com/en/manual/shopify-admin/supported-browsers) - [ ] Tested for [accessibility](https://github.com/Shopify/polaris/blob/main/documentation/Accessibility%20testing.md) - [x] Updated the component's `README.md` with documentation changes - [x] [Tophatted documentation](https://github.com/Shopify/polaris/blob/main/documentation/Tophatting%20documentation.md) changes in the style guide --------- Co-authored-by: Jess Telford <jess.telford@shopify.com>
1 parent deba43d commit c7c2312

File tree

8 files changed

+304
-223
lines changed

8 files changed

+304
-223
lines changed

.changeset/dirty-pugs-retire.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/polaris': major
3+
---
4+
5+
- Removed the `subdued` and `status` props from `IndexTable.Row`. Use `tone` instead.

polaris-react/src/components/IndexTable/IndexTable.scss

Lines changed: 146 additions & 167 deletions
Large diffs are not rendered by default.

polaris-react/src/components/IndexTable/IndexTable.stories.tsx

Lines changed: 86 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ export function WithSubduedRows() {
706706
key={id}
707707
selected={selectedResources.includes(id)}
708708
position={index}
709-
subdued={index === 1 || index === 2}
709+
tone={index === 1 || index === 2 ? 'subdued' : undefined}
710710
>
711711
<IndexTable.Cell>
712712
<Text fontWeight="bold" as="span">
@@ -1631,7 +1631,7 @@ export function WithRowStatus() {
16311631
key={id}
16321632
selected={selectedResources.includes(id)}
16331633
position={index}
1634-
status={status as IndexTableRowProps['status']}
1634+
tone={status as IndexTableRowProps['tone']}
16351635
>
16361636
<IndexTable.Cell>
16371637
<Text fontWeight="bold" as="span">
@@ -1667,7 +1667,7 @@ export function WithRowStatus() {
16671667
onSelectionChange={handleSelectionChange}
16681668
headings={[
16691669
{title: 'Name'},
1670-
{title: 'Status'},
1670+
{title: 'Tone'},
16711671
{title: 'Location'},
16721672
{
16731673
alignment: 'end',
@@ -1696,7 +1696,6 @@ export function WithStickyLastColumn() {
16961696
location: 'Decatur, USA',
16971697
orders: 20,
16981698
amountSpent: '$2,400',
1699-
status: 'Created',
17001699
channel: 'Point of Sale',
17011700
paymentStatus: 'Refunded',
17021701
fulfillmentStatus: 'Fulfilled',
@@ -1708,11 +1707,51 @@ export function WithStickyLastColumn() {
17081707
location: 'Los Angeles, USA',
17091708
orders: 30,
17101709
amountSpent: '$140',
1711-
status: 'Created',
17121710
channel: 'Online Store',
17131711
paymentStatus: 'Paid',
17141712
fulfillmentStatus: 'Unfulfilled',
17151713
},
1714+
{
1715+
id: '2562',
1716+
url: '#',
1717+
name: 'Helen Troy',
1718+
location: 'Los Angeles, USA',
1719+
orders: 30,
1720+
amountSpent: '$975',
1721+
lastOrderDate: 'May 31, 2023',
1722+
status: 'success',
1723+
},
1724+
{
1725+
id: '4102',
1726+
url: '#',
1727+
name: 'Colm Dillane',
1728+
location: 'New York, USA',
1729+
orders: 27,
1730+
amountSpent: '$2885',
1731+
lastOrderDate: 'May 31, 2023',
1732+
status: 'critical',
1733+
},
1734+
{
1735+
id: '2564',
1736+
url: '#',
1737+
name: 'Al Chemist',
1738+
location: 'New York, USA',
1739+
orders: 19,
1740+
amountSpent: '$1,209',
1741+
lastOrderDate: 'April 4, 2023',
1742+
disabled: true,
1743+
status: 'warning',
1744+
},
1745+
{
1746+
id: '2563',
1747+
url: '#',
1748+
name: 'Larry June',
1749+
location: 'San Francisco, USA',
1750+
orders: 22,
1751+
amountSpent: '$1,400',
1752+
lastOrderDate: 'March 19, 2023',
1753+
status: 'subdued',
1754+
},
17161755
];
17171756
const resourceName = {
17181757
singular: 'customer',
@@ -1742,6 +1781,7 @@ export function WithStickyLastColumn() {
17421781
key={id}
17431782
selected={selectedResources.includes(id)}
17441783
position={index}
1784+
tone={status as IndexTableRowProps['tone']}
17451785
>
17461786
<IndexTable.Cell>
17471787
<Text fontWeight="bold" as="span">
@@ -1789,7 +1829,7 @@ export function WithStickyLastColumn() {
17891829
id: 'amount-spent',
17901830
title: 'Amount spent',
17911831
},
1792-
{title: 'Status'},
1832+
{title: 'Tone'},
17931833
{title: 'Channel'},
17941834
{title: 'Payment status'},
17951835
{title: 'Fulfillment status'},
@@ -3236,7 +3276,7 @@ export function WithZebraStripingAndRowStatus() {
32363276
key={id}
32373277
selected={selectedResources.includes(id)}
32383278
position={index}
3239-
status={status as IndexTableRowProps['status']}
3279+
tone={status as IndexTableRowProps['tone']}
32403280
>
32413281
<IndexTable.Cell>
32423282
<Text fontWeight="bold" as="span">
@@ -3297,7 +3337,6 @@ export function WithZebraStripingAndStickyLastColumn() {
32973337
location: 'Decatur, USA',
32983338
orders: 20,
32993339
amountSpent: '$2,400',
3300-
status: 'Created',
33013340
channel: 'Point of Sale',
33023341
paymentStatus: 'Refunded',
33033342
fulfillmentStatus: 'Fulfilled',
@@ -3309,12 +3348,49 @@ export function WithZebraStripingAndStickyLastColumn() {
33093348
location: 'Los Angeles, USA',
33103349
orders: 30,
33113350
amountSpent: '$140',
3312-
status: 'Created',
33133351
channel: 'Online Store',
33143352
paymentStatus: 'Paid',
33153353
fulfillmentStatus: 'Unfulfilled',
33163354
},
3355+
{
3356+
id: '2562',
3357+
url: '#',
3358+
name: 'Helen Troy',
3359+
location: 'Los Angeles, USA',
3360+
orders: 30,
3361+
amountSpent: '$975',
3362+
lastOrderDate: 'May 31, 2023',
3363+
},
3364+
{
3365+
id: '4102',
3366+
url: '#',
3367+
name: 'Colm Dillane',
3368+
location: 'New York, USA',
3369+
orders: 27,
3370+
amountSpent: '$2885',
3371+
lastOrderDate: 'May 31, 2023',
3372+
},
3373+
{
3374+
id: '2564',
3375+
url: '#',
3376+
name: 'Al Chemist',
3377+
location: 'New York, USA',
3378+
orders: 19,
3379+
amountSpent: '$1,209',
3380+
lastOrderDate: 'April 4, 2023',
3381+
disabled: true,
3382+
},
3383+
{
3384+
id: '2563',
3385+
url: '#',
3386+
name: 'Larry June',
3387+
location: 'San Francisco, USA',
3388+
orders: 22,
3389+
amountSpent: '$1,400',
3390+
lastOrderDate: 'March 19, 2023',
3391+
},
33173392
];
3393+
33183394
const resourceName = {
33193395
singular: 'customer',
33203396
plural: 'customers',
@@ -3331,7 +3407,6 @@ export function WithZebraStripingAndStickyLastColumn() {
33313407
location,
33323408
orders,
33333409
amountSpent,
3334-
status,
33353410
channel,
33363411
paymentStatus,
33373412
fulfillmentStatus,
@@ -3360,7 +3435,6 @@ export function WithZebraStripingAndStickyLastColumn() {
33603435
{amountSpent}
33613436
</Text>
33623437
</IndexTable.Cell>
3363-
<IndexTable.Cell>{status}</IndexTable.Cell>
33643438
<IndexTable.Cell>{channel}</IndexTable.Cell>
33653439
<IndexTable.Cell>{paymentStatus}</IndexTable.Cell>
33663440
<IndexTable.Cell>{fulfillmentStatus}</IndexTable.Cell>
@@ -3390,7 +3464,6 @@ export function WithZebraStripingAndStickyLastColumn() {
33903464
id: 'amount-spent',
33913465
title: 'Amount spent',
33923466
},
3393-
{title: 'Status'},
33943467
{title: 'Channel'},
33953468
{title: 'Payment status'},
33963469
{title: 'Fulfillment status'},
@@ -3845,7 +3918,7 @@ export function WithSubHeaders() {
38453918
}
38463919

38473920
const selectableRows = rows.filter(({disabled}) => !disabled);
3848-
const rowRange: IndexTableRowProps['subHeaderRange'] = [
3921+
const rowRange: IndexTableRowProps['selectionRange'] = [
38493922
selectableRows.findIndex((row) => row.id === customers[0].id),
38503923
selectableRows.findIndex(
38513924
(row) => row.id === customers[customers.length - 1].id,

polaris-react/src/components/IndexTable/components/Row/Row.tsx

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import type {Range} from '../../../../utilities/index-provider/types';
1313
import styles from '../../IndexTable.scss';
1414

1515
type RowType = 'data' | 'subheader';
16-
type RowStatus = 'success' | 'subdued' | 'critical' | 'warning';
16+
type RowStatus = 'subdued' | 'success' | 'warning' | 'critical';
1717
type TableRowElementType = HTMLTableRowElement & HTMLLIElement;
1818

1919
export interface RowProps {
@@ -25,17 +25,7 @@ export interface RowProps {
2525
selected?: boolean | 'indeterminate';
2626
/** The zero-indexed position of the row. Used for Shift key multi-selection */
2727
position: number;
28-
/**
29-
* @deprecated The subdued prop has been deprecated. Use the `tone` prop instead.
30-
* Whether the row should be subdued */
31-
subdued?: boolean;
32-
/**
33-
* @deprecated The status prop has been deprecated. Use the `tone` prop instead.
34-
* Whether the row should have a status */
35-
status?: RowStatus;
36-
/**
37-
38-
* Whether the row should visually indicate its status with color */
28+
/** Whether the row should visually indicate its status with a background color */
3929
tone?: RowStatus;
4030
/** Whether the row should be disabled */
4131
disabled?: boolean;
@@ -60,8 +50,6 @@ export const Row = memo(function Row({
6050
selected,
6151
id,
6252
position,
63-
subdued,
64-
status,
6553
tone,
6654
disabled,
6755
selectionRange,
@@ -127,12 +115,9 @@ export const Row = memo(function Row({
127115
rowType === 'subheader' && styles['TableRow-subheader'],
128116
selectable && condensed && styles.condensedRow,
129117
selected && styles['TableRow-selected'],
130-
subdued && styles['TableRow-subdued'],
131118
hovered && !condensed && styles['TableRow-hovered'],
132119
disabled && styles['TableRow-disabled'],
133-
status && styles[variationName('status', status)],
134-
tone && styles[variationName('status', tone)],
135-
120+
tone && styles[variationName('tone', tone)],
136121
!selectable &&
137122
!primaryLinkElement.current &&
138123
styles['TableRow-unclickable'],

polaris-react/src/components/IndexTable/components/Row/tests/Row.test.tsx

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -430,37 +430,61 @@ describe('<Row />', () => {
430430
);
431431
});
432432

433-
it('has an undefined status by default', () => {
433+
it('has an undefined tone by default', () => {
434434
const row = mountWithTable(
435435
<Row {...defaultProps}>
436436
<td />
437437
</Row>,
438438
);
439439

440-
expect(row).toHaveReactProps({status: undefined});
440+
expect(row).toHaveReactProps({tone: undefined});
441441
});
442442

443-
it('applies success status styles when status prop is set to "success"', () => {
443+
it('applies subdued tone styles when tone prop is set to "subdued"', () => {
444444
const row = mountWithTable(
445-
<Row {...defaultProps} status="success">
445+
<Row {...defaultProps} tone="subdued">
446446
<td />
447447
</Row>,
448448
);
449449

450450
expect(row).toContainReactComponent('tr', {
451-
className: 'TableRow statusSuccess',
451+
className: 'TableRow toneSubdued',
452452
});
453453
});
454454

455-
it('applies subdued status styles when status prop is set to "subdued"', () => {
455+
it('applies success tone styles when tone prop is set to "success"', () => {
456456
const row = mountWithTable(
457-
<Row {...defaultProps} status="subdued">
457+
<Row {...defaultProps} tone="success">
458458
<td />
459459
</Row>,
460460
);
461461

462462
expect(row).toContainReactComponent('tr', {
463-
className: 'TableRow statusSubdued',
463+
className: 'TableRow toneSuccess',
464+
});
465+
});
466+
467+
it('applies warning tone styles when tone prop is set to "warning"', () => {
468+
const row = mountWithTable(
469+
<Row {...defaultProps} tone="warning">
470+
<td />
471+
</Row>,
472+
);
473+
474+
expect(row).toContainReactComponent('tr', {
475+
className: 'TableRow toneWarning',
476+
});
477+
});
478+
479+
it('applies critical tone styles when tone prop is set to "critical"', () => {
480+
const row = mountWithTable(
481+
<Row {...defaultProps} tone="critical">
482+
<td />
483+
</Row>,
484+
);
485+
486+
expect(row).toContainReactComponent('tr', {
487+
className: 'TableRow toneCritical',
464488
});
465489
});
466490

polaris.shopify.com/content/components/tables/index-table.md

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -195,21 +195,19 @@ An `IndexTable.Row` is used to render a row representing an item within an `Inde
195195

196196
### IndexTable.Row properties
197197

198-
| Prop | Type | Description |
199-
| --------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- |
200-
| children | ReactNode | Table header or data cells |
201-
| id | string | A unique identifier for the row |
202-
| selected? | boolean &#124; "indeterminate" | A boolean property indicating whether the row or it's related rows are selected |
203-
| position | number | The zero-indexed position of the row. Used for Shift key multi-selection as well as selection of a range of rows when a `selectionRange` is set. |
204-
| subdued? (deprecated) | boolean | Whether the row should be subdued. Deprecated in favor of `tone`. |
205-
| status? (deprecated) | "subdued" &#124; "success" &#124; "warning" &#124; "critical" | Whether the row should have a status. Deprecated in favor of `tone`. |
206-
| tone? | "subdued" &#124; "success" &#124; "warning" &#124; "critical" | Whether the row should visually indicate its status with color | |
207-
| disabled? | boolean | Whether the row should be disabled |
208-
| selectionRange? | [number, number] | A tuple array with the first and last index of the range of other rows that the row describes. All non-disabled rows in the range are selected when the row with a selection range set is selected. |
209-
| rowType? | "data" &#124; "subheader" | Indicates the relationship or role of the row's contents. A `rowType` of "subheader" looks and behaves the same as the table header. Defaults to "data". |
210-
| accessibilityLabel? | string | Label set on the row's checkbox. Defaults to "Select \{resourceName\}" |
211-
| onClick? | () => void | Callback fired when the row is clicked. Overrides the default click behaviour. |
212-
| onNavigation? | (id: string) => void | Callback fired when the row is clicked and contains an anchor element with the `data-primary-link` property set |
198+
| Prop | Type | Description |
199+
| ------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
200+
| children | ReactNode | Table header or data cells |
201+
| id | string | A unique identifier for the row |
202+
| selected? | boolean &#124; "indeterminate" | A boolean property indicating whether the row or it's related rows are selected |
203+
| position | number | The zero-indexed position of the row. Used for Shift key multi-selection as well as selection of a range of rows when a `selectionRange` is set. |
204+
| tone? | "subdued" &#124; "success" &#124; "warning" &#124; "critical" | Whether the row should visually indicate its status with a background color |
205+
| disabled? | boolean | Whether the row should be disabled |
206+
| selectionRange? | [number, number] | A tuple array with the first and last index of the range of other rows that the row describes. All non-disabled rows in the range are selected when the row with a selection range set is selected. |
207+
| rowType? | "data" &#124; "subheader" | Indicates the relationship or role of the row's contents. A `rowType` of "subheader" looks and behaves the same as the table header. Defaults to "data". |
208+
| accessibilityLabel? | string | Label set on the row's checkbox. Defaults to "Select \{resourceName\}" |
209+
| onClick? | () => void | Callback fired when the row is clicked. Overrides the default click behaviour. |
210+
| onNavigation? | (id: string) => void | Callback fired when the row is clicked and contains an anchor element with the `data-primary-link` property set |
213211

214212
## IndexTable.Cell
215213

@@ -246,14 +244,14 @@ The `IndexTable` is an actionable, filterable, and sortable table widget that su
246244

247245
Merchants can select a group of rows at once by clicking or <kbd>Space</kbd> keypressing a subheader row's checkbox. To indicate that an `IndexTable.Row` serves as a subheader for 1 or more rows below it, set the:
248246

249-
- Zero-indexed table `position` of the first and last `IndexTable.Row` described by the subheader `IndexTable.Row` as a tuple array on its `subHeaderRange` prop
247+
- Zero-indexed table `position` of the first and last `IndexTable.Row` described by the subheader `IndexTable.Row` as a tuple array on its `selectionRange` prop
250248
- Unique `id` on the `IndexTable.Cell` that contains the subheader content
251249
- Element tag to `"th"` on the `as` prop of the subheader `IndexTable.Cell`
252250
- Subheader `IndexTable.Cell` `scope` prop to `"colgroup"`
253251

254252
To associate the subheader `IndexTable.Row` with each `IndexTable.Cell` that it describes, set the:
255253

256-
- Unique `id` provided to the subheader `IndexTable.Cell` on the `headers` prop of each related `IndexTable.Cell` (contained by an `IndexTable.Row` that's position is within the `subHeaderRange`) as well as the unique `id` of its corresponding column heading that you provided to the `IndexTable` `headings` prop
254+
- Unique `id` provided to the subheader `IndexTable.Cell` on the `headers` prop of each related `IndexTable.Cell` (contained by an `IndexTable.Row` that's position is within the `selectionRange`) as well as the unique `id` of its corresponding column heading that you provided to the `IndexTable` `headings` prop
257255

258256
### Keyboard support
259257

0 commit comments

Comments
 (0)