Skip to content

Commit 1007e9f

Browse files
Luke BowermanElliot Park
andauthored
Remove ActionListManager & add support for state to DataTable (#1633)
* ActionListManager removed, DataTable supports loading/noResults * Fixed some grammar issues in docs with a/an * Fix states example in datatable docs Co-authored-by: Elliot Park <[email protected]>
1 parent 6b14135 commit 1007e9f

File tree

15 files changed

+139
-272
lines changed

15 files changed

+139
-272
lines changed

packages/components/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- `firstColumnStuck` developer can specify if the first column should "stick" to the viewport edge when scrolling
1818
- NOTE: Column for checkbox selection and actions column are always stuck to their respective edges
1919
- Column selection - the user can select which columns are displayed (if any columns have `hide` specified in their configuration)
20+
- Supports `state="loading|noResults"` and `noResultsDisplay`
2021
- The `autoFocus` prop will now work for inputs in `Popover` and `Dialog`
2122
- `Select`, `SelectMulti`, `InputTimeSelect`, and `InputSearch` now support `autoFocus`
2223
- `Dialog` & `Drawer` now support semantic sizes (`xxsmall - xlarge`)
@@ -47,6 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4748

4849
### Removed
4950

51+
- `ActionListManager` was removed (`DataTable` now supports `state=loading|noResults`)
5052
- `ActionList` (now known as `DataTable`) no longer supports `header` prop (header is always generated by component now)
5153
- `column` no longer supports `width` (see new `size` behavior)
5254
- `groupedPopoversRef` and `groupedMenusRef` (`Popover` and `Menu` no longer cancel the first click outside)
Binary file not shown.
6.73 KB
Loading

packages/components/src/DataTable/DataTable.test.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ const data = [
6767
},
6868
]
6969

70+
const bestCheeseDiv = <div>Pepper Jack</div>
71+
7072
const items = data.map(({ id, name, type }) => {
7173
const availableActions = (
7274
<>
@@ -463,4 +465,31 @@ describe('DataTable', () => {
463465
expect(onTotalClearAll).toHaveBeenCalledTimes(1)
464466
})
465467
})
468+
469+
test('Does not render children if state="loading"', () => {
470+
const { queryByText } = renderWithTheme(
471+
<DataTable columns={[]} state="loading">
472+
{bestCheeseDiv}
473+
</DataTable>
474+
)
475+
expect(queryByText('Pepper Jack')).not.toBeInTheDocument()
476+
})
477+
478+
test('Does not render children if state="noResults"', () => {
479+
const { queryByText } = renderWithTheme(
480+
<DataTable columns={[]} state="noResults">
481+
{bestCheeseDiv}
482+
</DataTable>
483+
)
484+
expect(queryByText('Pepper Jack')).not.toBeInTheDocument()
485+
})
486+
487+
test('Renders custom no results message when noResultsDisplay prop has a value', () => {
488+
const { getByText } = renderWithTheme(
489+
<DataTable columns={[]} state="noResults" noResultsDisplay={'Cheddar'}>
490+
{bestCheeseDiv}
491+
</DataTable>
492+
)
493+
expect(getByText('Cheddar')).toBeInTheDocument()
494+
})
466495
})

packages/components/src/DataTable/DataTable.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,18 @@ export interface DataTableProps {
7272
* Explicit specification of `firstColumnStuck` will always determine outcome
7373
*/
7474
firstColumnStuck?: boolean
75+
76+
/**
77+
* Specify "state" of DataTable to control display of data within the table
78+
* - `loading` will replace content with loading behavior (currently `Spinner`)
79+
* - 'noResults` will display "No Results" rather than DataTable content (customize via `noResultsDisplay`)
80+
* Display loading behavior rather than DataTable content
81+
*/
82+
state?: 'loading' | 'noResults'
83+
/**
84+
* Text to be displayed when no results state displayed
85+
*/
86+
noResultsDisplay?: ReactNode
7587
}
7688

7789
export interface SelectConfig {
@@ -201,6 +213,7 @@ export const DataTableLayout: FC<DataTableProps> = (props) => {
201213
{...filterConfig}
202214
/>
203215
)
216+
204217
return (
205218
<DataTableContext.Provider value={context}>
206219
<div className={className}>

packages/components/src/DataTable/Manager/ActionListManager.test.tsx

Lines changed: 0 additions & 70 deletions
This file was deleted.

packages/components/src/DataTable/Manager/ActionListManager.tsx

Lines changed: 0 additions & 74 deletions
This file was deleted.

packages/components/src/DataTable/Manager/NoResults.tsx

Lines changed: 0 additions & 35 deletions
This file was deleted.

packages/components/src/DataTable/Manager/index.ts

Lines changed: 0 additions & 27 deletions
This file was deleted.

packages/components/src/DataTable/Table.tsx

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
import React, { FC } from 'react'
2828
import styled, { css } from 'styled-components'
29+
import { Spinner } from '../Spinner'
30+
import { Heading } from '../Text'
2931
import { useCallbackRef, useIsTruncated } from '../utils'
3032
import {
3133
getNumericColumnIndices,
@@ -44,19 +46,37 @@ export const TableLayout: FC<TableProps> = ({
4446
className,
4547
columnsVisible,
4648
headerRowId,
49+
noResultsDisplay = 'No Results',
50+
state,
4751
}) => {
4852
const [element, ref] = useCallbackRef()
4953
const overflow = useIsTruncated(element, columnsVisible.length)
5054

55+
const noResultsContent =
56+
typeof noResultsDisplay === 'string' ? (
57+
<Heading variant="subdued">{noResultsDisplay}</Heading>
58+
) : (
59+
noResultsDisplay
60+
)
61+
62+
const interimState = state && (
63+
<InterimState>
64+
{state === 'loading' ? <Spinner /> : noResultsContent}
65+
</InterimState>
66+
)
67+
5168
return (
52-
<TableScroll ref={ref}>
53-
<table className={overflow ? `${className} overflow` : className}>
54-
<thead>
55-
<DataTableHeader id={headerRowId} />
56-
</thead>
57-
<tbody>{children}</tbody>
58-
</table>
59-
</TableScroll>
69+
<>
70+
<TableScroll ref={ref}>
71+
<table className={overflow ? `${className} overflow` : className}>
72+
<thead>
73+
<DataTableHeader id={headerRowId} />
74+
</thead>
75+
{!interimState && <tbody>{children}</tbody>}
76+
</table>
77+
</TableScroll>
78+
{interimState}
79+
</>
6080
)
6181
}
6282

@@ -180,6 +200,13 @@ export const Table = styled(TableLayout)`
180200
)}
181201
`
182202

203+
const InterimState = styled.div`
204+
align-items: center;
205+
display: flex;
206+
justify-content: center;
207+
padding: ${({ theme }) => theme.space.xlarge};
208+
`
209+
183210
export const TableScroll = styled.div`
184211
overflow-x: auto;
185212
scrollbar-width: none; /* Firefox */

0 commit comments

Comments
 (0)