Skip to content

Commit 0061baa

Browse files
authored
feat(tables): adds sub-component mapping (#1733)
1 parent 39e7e64 commit 0061baa

File tree

6 files changed

+132
-113
lines changed

6 files changed

+132
-113
lines changed

docs/migration.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ consider additional positioning prop support on a case-by-case basis.
108108
- added `labels` prop
109109
- Renamed `PAGE_TYPE` type export to `PageType`
110110

111+
#### @zendeskgarden/react-tables
112+
113+
- All subcomponent exports have been deprecated and will be removed in a future major version.
114+
Update to subcomponent properties (e.g., `Table.Body`).
115+
111116
#### @zendeskgarden/react-theming
112117

113118
- Utility function `isRtl` has been removed. Use `props.theme.rtl` instead.

packages/tables/README.md

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,36 @@ npm install react react-dom styled-components @zendeskgarden/react-theming
1616

1717
```jsx
1818
import { ThemeProvider } from '@zendeskgarden/react-theming';
19-
import {
20-
Table,
21-
Caption,
22-
Head,
23-
HeaderRow,
24-
HeaderCell,
25-
Body,
26-
Row,
27-
Cell
28-
} from '@zendeskgarden/react-tables';
19+
import { Table } from '@zendeskgarden/react-tables';
2920

3021
/**
3122
* Place a `ThemeProvider` at the root of your React application
3223
*/
3324
<ThemeProvider>
3425
<Table>
35-
<Caption>Your Unsolved Tickets</Caption>
36-
<Head>
37-
<HeaderRow>
38-
<HeaderCell>Subject</HeaderCell>
39-
<HeaderCell>Requester</HeaderCell>
40-
<HeaderCell>Requested</HeaderCell>
41-
<HeaderCell>Type</HeaderCell>
42-
</HeaderRow>
43-
</Head>
44-
<Body>
45-
<Row>
46-
<Cell>Where are my shoes?</Cell>
47-
<Cell>John Smith</Cell>
48-
<Cell>15 minutes ago</Cell>
49-
<Cell>Ticket</Cell>
50-
</Row>
51-
<Row>
52-
<Cell>I was charged twice!</Cell>
53-
<Cell>Jane Doe</Cell>
54-
<Cell>25 minutes ago</Cell>
55-
<Cell>Call</Cell>
56-
</Row>
57-
</Body>
26+
<Table.Caption>Your Unsolved Tickets</Table.Caption>
27+
<Table.Head>
28+
<Table.HeaderRow>
29+
<Table.HeaderCell>Subject</Table.HeaderCell>
30+
<Table.HeaderCell>Requester</Table.HeaderCell>
31+
<Table.HeaderCell>Requested</Table.HeaderCell>
32+
<Table.HeaderCell>Type</Table.HeaderCell>
33+
</Table.HeaderRow>
34+
</Table.Head>
35+
<Table.Body>
36+
<Table.Row>
37+
<Table.Cell>Where are my shoes?</Table.Cell>
38+
<Table.Cell>John Smith</Table.Cell>
39+
<Table.Cell>15 minutes ago</Table.Cell>
40+
<Table.Cell>Ticket</Table.Cell>
41+
</Table.Row>
42+
<Table.Row>
43+
<Table.Cell>I was charged twice!</Table.Cell>
44+
<Table.Cell>Jane Doe</Table.Cell>
45+
<Table.Cell>25 minutes ago</Table.Cell>
46+
<Table.Cell>Call</Table.Cell>
47+
</Table.Row>
48+
</Table.Body>
5849
</Table>
5950
</ThemeProvider>;
6051
```

packages/tables/demo/stories/TableStory.tsx

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,6 @@ import { Story } from '@storybook/react';
1010
import { Checkbox, Field, Label } from '@zendeskgarden/react-forms';
1111
import {
1212
Table,
13-
Body,
14-
Caption,
15-
Cell,
16-
GroupRow,
17-
Head,
18-
HeaderCell,
19-
HeaderRow,
20-
OverflowButton,
21-
Row,
22-
SortableCell,
2313
ITableProps,
2414
IHeadProps,
2515
ISortableCellProps,
@@ -75,21 +65,21 @@ export const TableStory: Story<IArgs> = ({
7565

7666
return (
7767
<Table {...args}>
78-
<Caption>{caption}</Caption>
79-
<Head isSticky={isSticky}>
80-
<HeaderRow>
68+
<Table.Caption>{caption}</Table.Caption>
69+
<Table.Head isSticky={isSticky}>
70+
<Table.HeaderRow>
8171
{hasSelection && (
82-
<HeaderCell isMinimum hidden={isHidden}>
72+
<Table.HeaderCell isMinimum hidden={isHidden}>
8373
<Field>
8474
<Checkbox>
8575
<Label hidden>Select all</Label>
8676
</Checkbox>
8777
</Field>
88-
</HeaderCell>
78+
</Table.HeaderCell>
8979
)}
9080
{headerCells.map((headerCell, index) =>
9181
isSortable ? (
92-
<SortableCell
82+
<Table.SortableCell
9383
key={index}
9484
cellProps={{ isTruncated }}
9585
onClick={() => {
@@ -105,67 +95,67 @@ export const TableStory: Story<IArgs> = ({
10595
width={widths ? widths[index] : undefined}
10696
>
10797
{headerCell}
108-
</SortableCell>
98+
</Table.SortableCell>
10999
) : (
110-
<HeaderCell
100+
<Table.HeaderCell
111101
key={index}
112102
isTruncated={isTruncated}
113103
width={widths ? widths[index] : undefined}
114104
>
115105
{headerCell}
116-
</HeaderCell>
106+
</Table.HeaderCell>
117107
)
118108
)}
119109
{hasOverflow && (
120-
<HeaderCell hasOverflow>
121-
<OverflowButton aria-label="overflow" />
122-
</HeaderCell>
110+
<Table.HeaderCell hasOverflow>
111+
<Table.OverflowButton aria-label="overflow" />
112+
</Table.HeaderCell>
123113
)}
124-
</HeaderRow>
125-
</Head>
126-
<Body>
114+
</Table.HeaderRow>
115+
</Table.Head>
116+
<Table.Body>
127117
{data
128118
.filter(value => (isStriped ? typeof value !== 'string' : true))
129119
.map((row, rowIndex) =>
130120
typeof row === 'string' ? (
131-
<GroupRow key={rowIndex}>
132-
<Cell colSpan={colSpan} isTruncated={isTruncated}>
121+
<Table.GroupRow key={rowIndex}>
122+
<Table.Cell colSpan={colSpan} isTruncated={isTruncated}>
133123
{isBold ? <b>{row}</b> : row}
134-
</Cell>
135-
</GroupRow>
124+
</Table.Cell>
125+
</Table.GroupRow>
136126
) : (
137-
<Row
127+
<Table.Row
138128
key={rowIndex}
139129
isSelected={isSelected}
140130
isStriped={isStriped && rowIndex % 2 === 0}
141131
>
142132
{hasSelection && (
143-
<Cell isMinimum>
133+
<Table.Cell isMinimum>
144134
<Field>
145135
<Checkbox>
146136
<Label hidden>Select all</Label>
147137
</Checkbox>
148138
</Field>
149-
</Cell>
139+
</Table.Cell>
150140
)}
151141
{Object.keys(row).map((column, columnIndex) => (
152-
<Cell
142+
<Table.Cell
153143
key={`${rowIndex}${columnIndex}`}
154144
isTruncated={isTruncated}
155145
hidden={isHidden}
156146
>
157147
{row[column]}
158-
</Cell>
148+
</Table.Cell>
159149
))}
160150
{hasOverflow && (
161-
<Cell hasOverflow>
162-
<OverflowButton aria-label="overflow" />
163-
</Cell>
151+
<Table.Cell hasOverflow>
152+
<Table.OverflowButton aria-label="overflow" />
153+
</Table.Cell>
164154
)}
165-
</Row>
155+
</Table.Row>
166156
)
167157
)}
168-
</Body>
158+
</Table.Body>
169159
</Table>
170160
);
171161
};

packages/tables/demo/table.stories.mdx

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
11
import { Meta, ArgsTable, Canvas, Story, Markdown } from '@storybook/addon-docs';
2-
import {
3-
Table,
4-
Body,
5-
Caption,
6-
Cell,
7-
GroupRow,
8-
Head,
9-
HeaderCell,
10-
HeaderRow,
11-
OverflowButton,
12-
Row,
13-
SortableCell
14-
} from '@zendeskgarden/react-tables';
2+
import { Table } from '@zendeskgarden/react-tables';
153
import { TableStory } from './stories/TableStory';
164
import { TABLE_DATA as DATA } from './stories/data';
175
import README from '../README.md';
@@ -20,16 +8,16 @@ import README from '../README.md';
208
title="Packages/Tables/Table"
219
component={Table}
2210
subcomponents={{
23-
Body,
24-
Caption,
25-
Cell,
26-
GroupRow,
27-
Head,
28-
HeaderCell,
29-
HeaderRow,
30-
OverflowButton,
31-
Row,
32-
SortableCell
11+
'Table.Body': Table.Body,
12+
'Table.Caption': Table.Caption,
13+
'Table.Cell': Table.Cell,
14+
'Table.GroupRow': Table.GroupRow,
15+
'Table.Head': Table.Head,
16+
'Table.HeaderCell': Table.HeaderCell,
17+
'Table.HeaderRow': Table.HeaderRow,
18+
'Table.OverflowButton': Table.OverflowButton,
19+
'Table.Row': Table.Row,
20+
'Table.SortableCell': Table.SortableCell
3321
}}
3422
/>
3523

@@ -45,18 +33,18 @@ import README from '../README.md';
4533
args={{ caption: 'Caption', data: DATA, widths: [], isBold: true }}
4634
argTypes={{
4735
isReadOnly: { control: 'boolean' },
48-
hasOverflow: { control: 'boolean', table: { category: 'Cell' } },
49-
isTruncated: { control: 'boolean', table: { category: 'Cell' } },
50-
isHidden: { name: 'hidden', control: 'boolean', table: { category: 'Cell' } },
51-
caption: { name: 'children', table: { category: 'Caption' } },
52-
isBold: { control: 'boolean', table: { category: 'GroupRow' } },
53-
isSticky: { control: 'boolean', table: { category: 'Head' } },
54-
isStriped: { control: 'boolean', table: { category: 'Row' } },
55-
isSelected: { control: 'boolean', table: { category: 'Row' } },
56-
data: { name: 'Row[]', table: { category: 'Story' } },
57-
widths: { name: 'Cell[] widths', table: { category: 'Story' } },
36+
hasOverflow: { control: 'boolean', table: { category: 'Table.Cell' } },
37+
isTruncated: { control: 'boolean', table: { category: 'Table.Cell' } },
38+
isHidden: { name: 'hidden', control: 'boolean', table: { category: 'Table.Cell' } },
39+
caption: { name: 'children', table: { category: 'Table.Caption' } },
40+
isBold: { control: 'boolean', table: { category: 'Table.GroupRow' } },
41+
isSticky: { control: 'boolean', table: { category: 'Table.Head' } },
42+
isStriped: { control: 'boolean', table: { category: 'Table.Row' } },
43+
isSelected: { control: 'boolean', table: { category: 'Table.Row' } },
44+
data: { name: 'Table.Row[]', table: { category: 'Story' } },
45+
widths: { name: 'Table.Cell[] widths', table: { category: 'Story' } },
5846
hasSelection: { control: 'boolean', table: { category: 'Story' } },
59-
isSortable: { name: 'SortableCell', control: 'boolean', table: { category: 'Story' } }
47+
isSortable: { name: 'Table.SortableCell', control: 'boolean', table: { category: 'Story' } }
6048
}}
6149
parameters={{
6250
design: {

packages/tables/src/elements/Table.tsx

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,18 @@ import PropTypes from 'prop-types';
1010
import { ITableProps, SIZE } from '../types';
1111
import { StyledTable } from '../styled';
1212
import { TableContext } from '../utils/useTableContext';
13+
import { Head } from './Head';
14+
import { Body } from './Body';
15+
import { Caption } from './Caption';
16+
import { Cell } from './Cell';
17+
import { GroupRow } from './GroupRow';
18+
import { HeaderCell } from './HeaderCell';
19+
import { HeaderRow } from './HeaderRow';
20+
import { OverflowButton } from './OverflowButton';
21+
import { Row } from './Row';
22+
import { SortableCell } from './SortableCell';
1323

14-
/**
15-
* @extends TableHTMLAttributes<HTMLTableElement>
16-
*/
17-
export const Table = React.forwardRef<HTMLTableElement, ITableProps>((props, ref) => {
24+
export const TableComponent = React.forwardRef<HTMLTableElement, ITableProps>((props, ref) => {
1825
const tableContextValue = useMemo(
1926
() => ({ size: props.size!, isReadOnly: props.isReadOnly! }),
2027
[props.size, props.isReadOnly]
@@ -27,13 +34,40 @@ export const Table = React.forwardRef<HTMLTableElement, ITableProps>((props, ref
2734
);
2835
});
2936

30-
Table.displayName = 'Table';
37+
TableComponent.displayName = 'Table';
3138

32-
Table.defaultProps = {
39+
TableComponent.defaultProps = {
3340
size: 'medium'
3441
};
3542

36-
Table.propTypes = {
43+
TableComponent.propTypes = {
3744
size: PropTypes.oneOf(SIZE),
3845
isReadOnly: PropTypes.bool
3946
};
47+
48+
/**
49+
* @extends TableHTMLAttributes<HTMLTableElement>
50+
*/
51+
export const Table = TableComponent as typeof TableComponent & {
52+
Body: typeof Body;
53+
Caption: typeof Caption;
54+
Cell: typeof Cell;
55+
GroupRow: typeof GroupRow;
56+
Head: typeof Head;
57+
HeaderCell: typeof HeaderCell;
58+
HeaderRow: typeof HeaderRow;
59+
OverflowButton: typeof OverflowButton;
60+
Row: typeof Row;
61+
SortableCell: typeof SortableCell;
62+
};
63+
64+
Table.Body = Body;
65+
Table.Caption = Caption;
66+
Table.Cell = Cell;
67+
Table.GroupRow = GroupRow;
68+
Table.Head = Head;
69+
Table.HeaderCell = HeaderCell;
70+
Table.HeaderRow = HeaderRow;
71+
Table.OverflowButton = OverflowButton;
72+
Table.Row = Row;
73+
Table.SortableCell = SortableCell;

packages/tables/src/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,27 @@
55
* found at http://www.apache.org/licenses/LICENSE-2.0.
66
*/
77

8+
/** @deprecated use `Table.Body` intead */
89
export { Body } from './elements/Body';
10+
/** @deprecated use `Table.Caption` intead */
911
export { Caption } from './elements/Caption';
12+
/** @deprecated use `Table.Cell` intead */
1013
export { Cell } from './elements/Cell';
14+
/** @deprecated use `Table.GroupRow` intead */
1115
export { GroupRow } from './elements/GroupRow';
16+
/** @deprecated use `Table.Head` intead */
1217
export { Head } from './elements/Head';
18+
/** @deprecated use `Table.HeaderCell` intead */
1319
export { HeaderCell } from './elements/HeaderCell';
20+
/** @deprecated use `Table.HeaderRow` intead */
1421
export { HeaderRow } from './elements/HeaderRow';
22+
/** @deprecated use `Table.OverflowButton` intead */
1523
export { OverflowButton } from './elements/OverflowButton';
24+
/** @deprecated use `Table.Row` intead */
1625
export { Row } from './elements/Row';
26+
/** @deprecated use `Table.SortableCell` intead */
1727
export { SortableCell } from './elements/SortableCell';
28+
1829
export { Table } from './elements/Table';
1930

2031
export type {

0 commit comments

Comments
 (0)