Skip to content

Commit

Permalink
[IndexTable] Updates to IndexTable from polaris-next version (#5785)
Browse files Browse the repository at this point in the history
* chore: updates to index table

* chore: update readme

* chore: add ability to clear selection

* chore: add changeset

* chore: export ScrollContainer

* chore: scroll container styling

* chore: cell styling

* chore: add width to first heading for checkbox

* chore: add flush option for TableHeading

* chore: fixes from merge

* chore: update checkbox style
  • Loading branch information
mrcthms committed May 26, 2022
1 parent 54d15c3 commit 56b8ca7
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .changeset/wet-trainers-admire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/polaris': minor
---

Upstream changes from polaris-next IndexTable
16 changes: 10 additions & 6 deletions polaris-react/src/components/IndexTable/IndexTable.scss
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,18 @@ $loading-panel-height: 53px;
border: 0;
}

.TableHeading-flush {
padding: 0;
}

.TableHeading-first {
--pc-index-table-checkbox-offset-left: 14px;
--pc-index-table-checkbox-offset-left: 16px;
--pc-index-table-checkbox-offset-right: 18px;
position: sticky;
left: 0;
padding-left: var(--pc-index-table-checkbox-offset-left);
padding-right: var(--pc-index-table-checkbox-offset-right);
width: var(--p-space-5);
}

.ColumnHeaderCheckboxWrapper {
Expand Down Expand Up @@ -230,7 +235,8 @@ $loading-panel-height: 53px;
position: sticky;
left: 0;
z-index: var(--pc-index-table-sticky-cell);
padding: 0;
padding: var(--p-space-2) 0;
vertical-align: middle;
}

.TableCell-first + .TableCell {
Expand All @@ -240,7 +246,6 @@ $loading-panel-height: 53px;
@include breakpoint-after($breakpoint-small) {
position: sticky;
z-index: var(--pc-index-table-sticky-cell);
padding: 0;
}
}

Expand Down Expand Up @@ -422,10 +427,9 @@ $scroll-bar-size: var(--p-space-2);
z-index: var(--pc-index-table-scroll-bar);
bottom: 0;
padding: var(--p-space-05);
border-top: var(--p-border-divider);
background-color: var(--p-surface);
border-bottom-right-radius: var(--p-border-radius-1);
border-bottom-left-radius: var(--p-border-radius-1);
border-bottom-right-radius: var(--p-border-radius-2);
border-bottom-left-radius: var(--p-border-radius-2);
}

.scrollBarContainerCondensed {
Expand Down
16 changes: 12 additions & 4 deletions polaris-react/src/components/IndexTable/IndexTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import styles from './IndexTable.scss';

export interface IndexTableHeading {
title: string;
flush?: boolean;
new?: boolean;
hidden?: boolean;
}
Expand All @@ -46,6 +47,7 @@ export interface IndexTableBaseProps {
children?: React.ReactNode;
emptyState?: React.ReactNode;
sort?: React.ReactNode;
paginatedSelectAllActionText?: string;
lastColumnSticky?: boolean;
selectable?: boolean;
}
Expand All @@ -67,6 +69,7 @@ function IndexTableBase({
children,
emptyState,
sort,
paginatedSelectAllActionText,
lastColumnSticky = false,
...restProps
}: IndexTableBaseProps) {
Expand Down Expand Up @@ -633,6 +636,7 @@ function IndexTableBase({
isSecond && styles['TableHeading-second'],
isLast && !heading.hidden && styles['TableHeading-last'],
!selectable && styles['TableHeading-unselectable'],
heading.flush && styles['TableHeading-flush'],
);

const stickyPositioningStyle =
Expand Down Expand Up @@ -746,13 +750,17 @@ function IndexTableBase({
return;
}

const customActionText =
paginatedSelectAllActionText ??
i18n.translate('Polaris.IndexTable.selectAllItems', {
itemsLength: itemCount,
resourceNamePlural: resourceName.plural.toLocaleLowerCase(),
});

const actionText =
selectedItemsCount === SELECT_ALL_ITEMS
? i18n.translate('Polaris.IndexTable.undo')
: i18n.translate('Polaris.IndexTable.selectAllItems', {
itemsLength: itemCount,
resourceNamePlural: resourceName.plural.toLocaleLowerCase(),
});
: customActionText;

return {
content: actionText,
Expand Down
95 changes: 85 additions & 10 deletions polaris-react/src/components/IndexTable/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,79 @@ function SimpleIndexTableExample() {
}
```

### Simple flush index table

A index table with simple items and no bulk actions, sorting, or filtering.

```jsx
function SimpleFlushIndexTableExample() {
const customers = [
{
id: '3411',
url: 'customers/341',
name: 'Mae Jemison',
location: 'Decatur, USA',
orders: 20,
amountSpent: '$2,400',
},
{
id: '2561',
url: 'customers/256',
name: 'Ellen Ochoa',
location: 'Los Angeles, USA',
orders: 30,
amountSpent: '$140',
},
];
const resourceName = {
singular: 'customer',
plural: 'customers',
};

const {selectedResources, allResourcesSelected, handleSelectionChange} =
useIndexResourceState(customers);

const rowMarkup = customers.map(
({id, name, location, orders, amountSpent}, index) => (
<IndexTable.Row
id={id}
key={id}
selected={selectedResources.includes(id)}
position={index}
>
<IndexTable.Cell flush>
<TextStyle variation="strong">{name}</TextStyle>
</IndexTable.Cell>
<IndexTable.Cell flush>{location}</IndexTable.Cell>
<IndexTable.Cell flush>{orders}</IndexTable.Cell>
<IndexTable.Cell flush>{amountSpent}</IndexTable.Cell>
</IndexTable.Row>
),
);

return (
<Card>
<IndexTable
resourceName={resourceName}
itemCount={customers.length}
selectedItemsCount={
allResourcesSelected ? 'All' : selectedResources.length
}
onSelectionChange={handleSelectionChange}
headings={[
{title: 'Name', flush: true},
{title: 'Location', flush: true},
{title: 'Order count', flush: true},
{title: 'Amount spent', flush: true},
]}
>
{rowMarkup}
</IndexTable>
</Card>
);
}
```

### Simple small screen index table

A small screen index table with simple items and no bulk actions, sorting, or filtering.
Expand Down Expand Up @@ -1495,13 +1568,14 @@ An `IndexTableRow` is used to render a row representing an item within an `Index

### IndexTableRow properties

| Prop | Type | Description |
| -------- | --------- | --------------------------------------------------------------- |
| id | string | A unique identifier for the row |
| selected | boolean | A boolean property indicating whether the row is selected |
| position | number | The index position of the row |
| subdued | boolean | A boolean property indicating whether the row should be subdued |
| status | RowStatus | A property indicating whether the row should have a status |
| Prop | Type | Description |
| -------- | ---------- | --------------------------------------------------------------- |
| id | string | A unique identifier for the row |
| selected | boolean | A boolean property indicating whether the row is selected |
| position | number | The index position of the row |
| subdued | boolean | A boolean property indicating whether the row should be subdued |
| status | RowStatus | A property indicating whether the row should have a status |
| onClick | () => void | A function which overrides the default click behaviour |

<a name="index-table-cell"></a>

Expand All @@ -1511,9 +1585,10 @@ An `IndexTableCell` is used to render a single cell within an `IndexTableRow`

### IndexTableCell properties

| Prop | Type | Description |
| ----- | ------- | -------------------------------------------------------------------------------- |
| flush | boolean | A boolean property indicating whether the cell should remove the default padding |
| Prop | Type | Description |
| --------- | ------- | -------------------------------------------------------------------------------- |
| flush | boolean | A boolean property indicating whether the cell should remove the default padding |
| className | string | Adds a class to the cell, used for setting widths of a cell |

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ import styles from '../../IndexTable.scss';

export interface CellProps {
children?: ReactNode;
className?: string;
flush?: boolean;
}

export const Cell = memo(function Cell({children, flush}: CellProps) {
export const Cell = memo(function Cell({
children,
className,
flush,
}: CellProps) {
const cellClassName = classNames(
className,
styles.TableCell,
flush && styles['TableCell-flush'],
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ describe('<Cell />', () => {
className: 'TableCell TableCell-flush',
});
});

it('applies className if present', () => {
const className = 'foo-bar-baz';
const cell = mountWithTable(<Cell className={className} />);
expect(cell).toContainReactComponent('td', {
className: `${className} TableCell`,
});
});
});

function mountWithTable(children: ReactElement) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import '../../../../styles/common';

$expanded-height: 32px;
$expanded-width: 32px;
$expanded-height: 20px;
$expanded-width: 36px;
$condensed-height: 44px;
$condensed-width: 50px;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface RowProps {
subdued?: boolean;
status?: RowStatus;
onNavigation?(id: string): void;
onClick?(): void;
}

export const Row = memo(function Row({
Expand All @@ -31,6 +32,7 @@ export const Row = memo(function Row({
subdued,
status,
onNavigation,
onClick,
}: RowProps) {
const {selectable, selectMode, condensed} = useIndexRow();
const onSelectionChange = useIndexSelectionChange();
Expand Down Expand Up @@ -101,6 +103,11 @@ export const Row = memo(function Row({
event.stopPropagation();
event.preventDefault();

if (onClick) {
onClick();
return;
}

if (primaryLinkElement.current && !selectMode) {
isNavigating.current = true;
const {ctrlKey, metaKey} = event.nativeEvent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,48 @@ describe('<Row />', () => {
expect(onNavigationSpy).toHaveBeenCalledTimes(1);
});

it('calls onClick when clicked', () => {
const onClickSpy = jest.fn();
const row = mountWithTable(
<Row {...defaultProps} onClick={onClickSpy}>
<th>
<a href="/" data-primary-link>
Child
</a>
</th>
</Row>,
);

triggerOnClick(row, 1, defaultEvent);

expect(onClickSpy).toHaveBeenCalledTimes(1);
});

it('does not execute further functionality when onClick is present', () => {
const onClickSpy = jest.fn();
const onSelectionChangeSpy = jest.fn();

const row = mountWithTable(
<Row {...defaultProps} onClick={onClickSpy}>
<th>
<a href="/" data-primary-link>
Child
</a>
</th>
</Row>,
{
indexTableProps: {
itemCount: 50,
selectedItemsCount: 0,
onSelectionChange: onSelectionChangeSpy,
},
},
);

triggerOnClick(row, 1, defaultEvent);
expect(onSelectionChangeSpy).toHaveBeenCalledTimes(0);
});

it('calls handleInteraction when clicked and no primary link child present', () => {
const onSelectionChangeSpy = jest.fn();
const row = mountWithTable(
Expand Down
20 changes: 20 additions & 0 deletions polaris-react/src/components/IndexTable/tests/IndexTable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,26 @@ describe('<IndexTable>', () => {
);
});

it('renders a custom select all string if present', () => {
const onSelectionChangeSpy = jest.fn();
const customString = 'Foo bar baz';
const index = mountWithApp(
<IndexTable
{...defaultProps}
selectable
hasMoreItems
selectedItemsCount={1}
itemCount={2}
promotedBulkActions={[{content: 'promoted action'}]}
onSelectionChange={onSelectionChangeSpy}
paginatedSelectAllActionText={customString}
>
{mockTableItems.map(mockRenderRow)}
</IndexTable>,
);
expect(index.find(BulkActions)).toContainReactText(customString);
});

it('toggles all page resources when onToggleAll is triggered', () => {
const onSelectionChangeSpy = jest.fn();
const index = mountWithApp(
Expand Down

0 comments on commit 56b8ca7

Please sign in to comment.