UNPKG

@saas-ui/data-table

Version:

Data-table Component

1 lines 12.6 kB
{"version":3,"sources":["../src/data-table.tsx"],"sourcesContent":["import * as React from 'react'\nimport {\n useReactTable,\n getCoreRowModel,\n getSortedRowModel,\n Table as TableInstance,\n flexRender,\n ColumnDef,\n ColumnSort,\n TableOptions,\n Header,\n Cell,\n} from '@tanstack/react-table'\nimport {\n chakra,\n forwardRef,\n Table,\n Thead,\n Tbody,\n Tr,\n Th,\n Td,\n Checkbox,\n ThemingProps,\n SystemStyleObject,\n} from '@chakra-ui/react'\n\nimport { cx } from '@chakra-ui/utils'\n\nimport { ChevronDownIcon, ChevronUpIcon, Link } from '@saas-ui/core'\n\nexport type { TableInstance, ColumnDef }\n\nexport interface DataTableProps<Data extends object>\n extends Omit<TableOptions<Data>, 'getCoreRowModel'>,\n ThemingProps<'Table'> {\n /**\n * The TableInstance reference\n */\n instanceRef?: React.Ref<TableInstance<Data>>\n /**\n * Enable sorting on all columns\n */\n isSortable?: boolean\n /**\n * Enable row selection\n */\n isSelectable?: boolean\n /**\n * Triggers whenever the row selection changes.\n * @params rows The selected row id's\n */\n onSelectedRowsChange?: (rows: Array<string>) => void\n /**\n * Triggers when sort changed.\n * Use incombination with `manualSortBy` to enable remote sorting.\n */\n onSortChange?: (columns: ColumnSort[]) => void\n /**\n * The table class name attribute\n */\n className?: string\n /**\n * Table styles\n */\n sx?: SystemStyleObject\n}\n\nexport const DataTable = React.forwardRef(\n <Data extends object>(\n props: DataTableProps<Data>,\n ref: React.ForwardedRef<HTMLTableElement>\n ) => {\n const {\n instanceRef,\n columns,\n isSortable,\n isSelectable,\n onSelectedRowsChange,\n onSortChange,\n colorScheme,\n size,\n variant,\n className,\n sx,\n ...rest\n } = props\n\n const instance = useReactTable<Data>({\n columns: React.useMemo(() => {\n return getSelectionColumn<Data>(isSelectable).concat(\n columns?.map((column: any) => {\n if (!column.accessorKey) {\n column.accessorKey = column.accessor || column.id\n }\n if (!column.header && column.Header) {\n column.header = column.Header\n }\n if (!column.cell && column.Cell) {\n column.cell = column.Cell\n } else if (!column.cell) {\n column.cell = DataTableCell\n }\n return column\n })\n )\n }, []),\n enableRowSelection: isSelectable,\n getSortedRowModel: isSortable ? getSortedRowModel() : undefined,\n ...rest,\n getCoreRowModel: getCoreRowModel(),\n })\n\n // This exposes the useTable api through the instanceRef\n React.useImperativeHandle(instanceRef, () => instance, [instanceRef])\n\n const state = instance.getState()\n\n React.useEffect(() => {\n onSelectedRowsChange?.(Object.keys(state.rowSelection))\n }, [onSelectedRowsChange, state.rowSelection, instance])\n\n React.useEffect(() => {\n onSortChange?.(state.sorting)\n }, [onSortChange, state.sorting])\n\n return (\n <Table\n ref={ref}\n sx={{ 'tr:last-child td': { border: 0 }, ...sx }}\n className={cx('sui-data-table', className)}\n colorScheme={colorScheme}\n size={size}\n variant={variant}\n >\n <Thead>\n {instance.getHeaderGroups().map((headerGroup) => (\n <Tr key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <DataTableHeader\n key={header.id}\n header={header}\n isSortable={isSortable}\n />\n ))}\n </Tr>\n ))}\n </Thead>\n <Tbody>\n {instance.getRowModel().rows.map((row) => {\n return (\n <Tr key={row.id}>\n {row.getVisibleCells().map((cell) => {\n const meta = (cell.column.columnDef.meta || {}) as any\n return (\n <Td\n key={cell.id}\n overflow=\"hidden\"\n whiteSpace=\"nowrap\"\n textOverflow=\"ellipsis\"\n isNumeric={meta.isNumeric}\n >\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext()\n )}\n </Td>\n )\n })}\n </Tr>\n )\n })}\n </Tbody>\n </Table>\n )\n }\n) as (<Data extends object>(\n props: DataTableProps<Data> & {\n ref?: React.ForwardedRef<HTMLTableElement>\n }\n) => React.ReactElement) & { displayName?: string }\n\nDataTable.displayName = 'DataTable'\n\nexport interface DataTableSortProps<Data extends object, TValue> {\n header: Header<Data, TValue>\n}\nexport const DataTableSort = <Data extends object, TValue>(\n props: DataTableSortProps<Data, TValue>\n) => {\n const { header, ...rest } = props\n\n const sorterStyles = {\n ms: 2,\n }\n\n if (header.id === 'selection') {\n return null\n }\n\n const sorted = header.column.getIsSorted()\n\n return (\n <chakra.span __css={sorterStyles} {...rest}>\n {sorted ? (\n sorted === 'desc' ? (\n <ChevronDownIcon aria-label=\"sorted descending\" />\n ) : (\n <ChevronUpIcon aria-label=\"sorted ascending\" />\n )\n ) : (\n ''\n )}\n </chakra.span>\n )\n}\n\nDataTableSort.displayName = 'DataTableSort'\n\nexport interface DataTableHeaderProps<Data extends object, TValue> {\n header: Header<Data, TValue>\n isSortable?: boolean\n}\nexport const DataTableHeader = <Data extends object, TValue>(\n props: DataTableHeaderProps<Data, TValue>\n) => {\n const { header, isSortable, ...rest } = props\n\n let headerProps = {}\n\n const enabled = !header.column.getCanSort() ? false : isSortable\n\n if (enabled) {\n headerProps = {\n className: 'saas-data-table__sortable',\n userSelect: 'none',\n cursor: 'pointer',\n onClick: header.column.getToggleSortingHandler(),\n }\n }\n\n const meta = (header.column.columnDef.meta || {}) as any\n const size = header.column.columnDef.size\n return (\n <Th\n colSpan={header.colSpan}\n textTransform=\"none\"\n width={size && `${size}px`}\n isNumeric={meta.isNumeric}\n {...headerProps}\n {...rest}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {enabled && <DataTableSort header={header} />}\n </Th>\n )\n}\n\nDataTableHeader.displayName = 'DataTableHeader'\n\nconst getResult = <Data extends object>(\n fn: (row: Data) => string,\n params: Data\n): string => {\n if (typeof fn === 'function') {\n return fn(params)\n }\n return fn\n}\n\nexport const DataTableCell = <Data extends object, TValue>(\n props: Cell<Data, TValue>\n) => {\n const { column, row, getValue } = props\n\n const meta = (column.columnDef.meta || {}) as any\n\n if (meta.href) {\n const href = getResult(meta.href, row.original)\n return <Link href={href}>{getValue<string>()}</Link>\n }\n return getValue() || null\n}\n\nDataTableCell.displayName = 'DataTableCell'\n\nconst DataTableCheckbox = forwardRef((props, ref) => {\n return (\n <chakra.div>\n <Checkbox ref={ref} {...props} />\n </chakra.div>\n )\n})\n\nDataTableCheckbox.displayName = 'DataTableCheckbox'\n\nconst getSelectionColumn = <Data extends object>(enabled?: boolean) => {\n return enabled\n ? [\n {\n id: 'selection',\n size: 1,\n header: ({ table }) => (\n <DataTableCheckbox\n isChecked={table.getIsAllRowsSelected()}\n isIndeterminate={table.getIsSomeRowsSelected()}\n onChange={table.getToggleAllRowsSelectedHandler()}\n aria-label={\n table.getIsAllRowsSelected()\n ? 'Deselect all rows'\n : 'Select all rows'\n }\n />\n ),\n cell: ({ row }) => (\n <DataTableCheckbox\n isChecked={row.getIsSelected()}\n isIndeterminate={row.getIsSomeSelected()}\n onChange={row.getToggleSelectedHandler()}\n aria-label={row.getIsSelected() ? 'Deselect row' : 'Select row'}\n />\n ),\n } as ColumnDef<Data>,\n ]\n : []\n}\n"],"mappings":"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","names":["forwardRef"]}