Skip to content

Commit 9c30395

Browse files
authored
feat: Table improvements (#536)
1 parent 247978c commit 9c30395

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

src/components/EmptyState.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { type ReactElement, type Ref, forwardRef } from 'react'
22
import { Div, Flex, type FlexProps, Text } from 'honorable'
33
import PropTypes from 'prop-types'
44

5-
type EmptyStateProps = FlexProps & {
5+
type EmptyStateProps = Omit<FlexProps, 'message' | 'description' | 'icon'> & {
66
message: string
77
description?: string
88
icon?: ReactElement

src/components/Table.tsx

+12-5
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,19 @@ import { rankItem } from '@tanstack/match-sorter-utils'
3232
import type { VirtualItem } from '@tanstack/react-virtual'
3333
import { useVirtualizer } from '@tanstack/react-virtual'
3434
import styled from 'styled-components'
35+
import { isEmpty } from 'lodash-es'
3536

3637
import Button from './Button'
3738
import CaretUpIcon from './icons/CaretUpIcon'
3839
import ArrowRightIcon from './icons/ArrowRightIcon'
3940
import { FillLevelProvider } from './contexts/FillLevelContext'
41+
import EmptyState from './EmptyState'
4042

4143
export type TableProps = Omit<
4244
DivProps,
4345
| 'data'
4446
| 'columns'
4547
| 'getRowCanExpand'
46-
| 'getRowIsSelected'
4748
| 'renderExpanded'
4849
| 'loose'
4950
| 'stickyColumn'
@@ -52,11 +53,11 @@ export type TableProps = Omit<
5253
| 'virtualizerOptions'
5354
| 'reactTableOptions'
5455
| 'onRowClick'
56+
| 'emptyStateProps'
5557
> & {
5658
data: any[]
5759
columns: any[]
5860
getRowCanExpand?: any
59-
getRowIsSelected?: (row: Row<any>) => boolean
6061
renderExpanded?: any
6162
loose?: boolean
6263
stickyColumn?: boolean
@@ -69,6 +70,7 @@ export type TableProps = Omit<
6970
>
7071
reactTableOptions?: Partial<Omit<TableOptions<any>, 'data' | 'columns'>>
7172
onRowClick?: (e: MouseEvent<HTMLTableRowElement>, row: Row<any>) => void
73+
emptyStateProps?: ComponentProps<typeof EmptyState>
7274
}
7375

7476
const propTypes = {}
@@ -445,7 +447,6 @@ function TableRef(
445447
data,
446448
columns,
447449
getRowCanExpand,
448-
getRowIsSelected,
449450
renderExpanded,
450451
loose = false,
451452
stickyColumn = false,
@@ -456,6 +457,7 @@ function TableRef(
456457
reactVirtualOptions: virtualizerOptions,
457458
reactTableOptions,
458459
onRowClick,
460+
emptyStateProps,
459461
...props
460462
}: TableProps,
461463
forwardRef: Ref<any>
@@ -646,8 +648,8 @@ function TableRef(
646648
key={row.id}
647649
onClick={(e) => onRowClick?.(e, row)}
648650
$lighter={i % 2 === 0}
649-
$selectable={!!getRowIsSelected}
650-
$selected={getRowIsSelected?.(row) ?? false}
651+
$selectable={row.getCanSelect()}
652+
$selected={row.getIsSelected() ?? false}
651653
$clickable={!!onRowClick}
652654
// data-index is required for virtual scrolling to work
653655
data-index={row.index}
@@ -693,6 +695,11 @@ function TableRef(
693695
)}
694696
</Tbody>
695697
</T>
698+
{isEmpty(rows) && (
699+
<EmptyState
700+
{...{ message: 'No results match your query', ...emptyStateProps }}
701+
/>
702+
)}
696703
</Div>
697704
{hover && scrollTop > scrollTopMargin && (
698705
<Button

src/stories/Table.stories.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,14 @@ function SelectableTemplate(args: any) {
216216
return (
217217
<Table
218218
{...args}
219-
getRowIsSelected={(row) => row.original.id === selectedId}
220219
onRowClick={(_, row) => {
221220
setSelectedId(row.original.id)
222221
}}
222+
reactTableOptions={{
223+
state: { rowSelection: { [selectedId]: true } },
224+
enableRowSelection: true,
225+
enableMultiRowSelection: false,
226+
}}
223227
/>
224228
)
225229
}
@@ -278,12 +282,12 @@ function FilterableTemplate(args: ComponentProps<typeof Table>) {
278282
const repeatedData = Array(25)
279283
.fill(data)
280284
.flat()
281-
.map((item, i) => ({ ...item, id: i }))
285+
.map((item, i) => ({ ...item, id: `id-${i}` }))
282286

283287
const extremeLengthData = Array(200)
284288
.fill(data)
285289
.flat()
286-
.map((item, i) => ({ ...item, id: i }))
290+
.map((item, i) => ({ ...item, id: `id-${i}` }))
287291

288292
export const Default = Template.bind({})
289293

@@ -349,6 +353,9 @@ Expandable.args = {
349353
export const FilterableAndSortable = FilterableTemplate.bind({})
350354
FilterableAndSortable.args = {
351355
virtualizeRows: true,
356+
emptyStateProps: {
357+
message: 'No results match your query',
358+
},
352359
width: 'auto',
353360
height: '400px',
354361
data: extremeLengthData,

0 commit comments

Comments
 (0)