@chumsinc/sortable-tables 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/LICENSE +21 -0
  3. package/README.md +82 -0
  4. package/babel.config.mjs +13 -0
  5. package/changelog-template.hbs +45 -0
  6. package/dist/DataTable.d.ts +6 -0
  7. package/dist/DataTable.js +15 -0
  8. package/dist/DataTable.js.map +1 -0
  9. package/dist/DataTableCell.d.ts +293 -0
  10. package/dist/DataTableCell.js +17 -0
  11. package/dist/DataTableCell.js.map +1 -0
  12. package/dist/DataTableHead.d.ts +6 -0
  13. package/dist/DataTableHead.js +11 -0
  14. package/dist/DataTableHead.js.map +1 -0
  15. package/dist/DataTableRow.d.ts +6 -0
  16. package/dist/DataTableRow.js +17 -0
  17. package/dist/DataTableRow.js.map +1 -0
  18. package/dist/DataTableTBody.d.ts +6 -0
  19. package/dist/DataTableTBody.js +16 -0
  20. package/dist/DataTableTBody.js.map +1 -0
  21. package/dist/DataTableTH.d.ts +6 -0
  22. package/dist/DataTableTH.js +9 -0
  23. package/dist/DataTableTH.js.map +1 -0
  24. package/dist/RowsPerPage.d.ts +7 -0
  25. package/dist/RowsPerPage.js +16 -0
  26. package/dist/RowsPerPage.js.map +1 -0
  27. package/dist/SortableTable.d.ts +6 -0
  28. package/dist/SortableTable.js +15 -0
  29. package/dist/SortableTable.js.map +1 -0
  30. package/dist/SortableTableHead.d.ts +6 -0
  31. package/dist/SortableTableHead.js +12 -0
  32. package/dist/SortableTableHead.js.map +1 -0
  33. package/dist/SortableTableTH.d.ts +6 -0
  34. package/dist/SortableTableTH.js +48 -0
  35. package/dist/SortableTableTH.js.map +1 -0
  36. package/dist/Table.d.ts +5 -0
  37. package/dist/Table.js +28 -0
  38. package/dist/Table.js.map +1 -0
  39. package/dist/TablePagination.d.ts +6 -0
  40. package/dist/TablePagination.js +13 -0
  41. package/dist/TablePagination.js.map +1 -0
  42. package/dist/index.d.ts +10 -0
  43. package/dist/index.js +10 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/types.d.ts +104 -0
  46. package/dist/types.js +2 -0
  47. package/dist/types.js.map +1 -0
  48. package/dist/utils.d.ts +1 -0
  49. package/dist/utils.js +2 -0
  50. package/dist/utils.js.map +1 -0
  51. package/eslint.config.mjs +14 -0
  52. package/package.json +91 -0
  53. package/public/index.html +28 -0
  54. package/src/DataTable.tsx +47 -0
  55. package/src/DataTableCell.tsx +28 -0
  56. package/src/DataTableHead.tsx +27 -0
  57. package/src/DataTableRow.tsx +38 -0
  58. package/src/DataTableTBody.tsx +40 -0
  59. package/src/DataTableTH.tsx +20 -0
  60. package/src/RowsPerPage.tsx +38 -0
  61. package/src/SortableTable.tsx +46 -0
  62. package/src/SortableTableHead.tsx +31 -0
  63. package/src/SortableTableTH.tsx +77 -0
  64. package/src/Table.tsx +43 -0
  65. package/src/TablePagination.tsx +72 -0
  66. package/src/index.tsx +14 -0
  67. package/src/types.ts +127 -0
  68. package/src/utils.ts +1 -0
  69. package/test/TestTable.tsx +67 -0
  70. package/test/data.ts +232 -0
  71. package/test/index.tsx +11 -0
  72. package/tsconfig.json +29 -0
  73. package/webpack.common.mjs +72 -0
  74. package/webpack.dev.mjs +35 -0
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import classNames from "classnames";
3
+ import DataTableHead from "./DataTableHead";
4
+ import DataTableTBody from "./DataTableTBody";
5
+ import {DataTableProps} from "./types";
6
+ import {noop} from "./utils";
7
+ import Table from "./Table";
8
+
9
+
10
+ function DataTable<T = unknown>({
11
+ fields,
12
+ data,
13
+ keyField,
14
+ size = '',
15
+ sticky,
16
+ responsive,
17
+ rowClassName,
18
+ renderRow,
19
+ onSelectRow = noop,
20
+ selected = '',
21
+ className = '',
22
+ tfoot,
23
+ children,
24
+ tableHeadProps,
25
+ ...rest
26
+ }: DataTableProps<T>) {
27
+
28
+ const tableClassName = classNames('table', className, {
29
+ [`table-${size}`]: !!size,
30
+ })
31
+
32
+ return (
33
+ <Table sticky={sticky} responsive={responsive} className={tableClassName} {...rest}>
34
+ <DataTableHead {...tableHeadProps} fields={fields}/>
35
+ {!!data.length && (
36
+ <DataTableTBody fields={fields} data={data} keyField={keyField} rowClassName={rowClassName}
37
+ renderRow={renderRow}
38
+ onSelectRow={onSelectRow} selected={selected}/>
39
+ )}
40
+ {children}
41
+ {tfoot}
42
+ </Table>
43
+ )
44
+ }
45
+
46
+ DataTable.displayName = 'DataTable';
47
+ export default DataTable;
@@ -0,0 +1,28 @@
1
+ import React, {ReactNode} from 'react';
2
+ import {DataTableCellProps} from "./types";
3
+ import classNames from "classnames";
4
+
5
+ export default function DataTableCell<T = unknown>({field, row, className, as, ...rest}:DataTableCellProps<T>) {
6
+ const cellClassName = classNames(
7
+ {[`text-${field.align}`]: !!field.align},
8
+ className,
9
+ typeof field.className === 'function' ? field.className(row) : field.className
10
+ );
11
+ return React.createElement(
12
+ (as ?? field.as) ?? 'td',
13
+ {
14
+ className: cellClassName,
15
+ scope: (as ?? field.as) === 'th' ? 'row' : undefined,
16
+ colSpan: field.colSpan,
17
+ ...field.cellProps,
18
+ ...rest
19
+ },
20
+ row[field.field] === undefined
21
+ ? null
22
+ : (
23
+ typeof field.render === 'function'
24
+ ? field.render(row)
25
+ : row[field.field] as ReactNode
26
+ )
27
+ )
28
+ }
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+ import DataTableTH from "./DataTableTH";
3
+ import classNames from "classnames";
4
+ import {DataTableHeadProps} from "./types";
5
+
6
+
7
+ function DataTableHead<T = unknown>({fields, ...rest}: DataTableHeadProps<T>) {
8
+ return (
9
+ <thead {...rest}>
10
+ <tr>
11
+ {fields.map((field, index) => (
12
+ <DataTableTH key={field.id ?? index}
13
+ {...field.thProps}
14
+ field={field}
15
+ className={classNames(
16
+ typeof field.className === 'function'
17
+ ? {[`text-${field.align}`]: !!field.align}
18
+ : field.className
19
+ )}/>
20
+ ))}
21
+ </tr>
22
+ </thead>
23
+ )
24
+ }
25
+
26
+ DataTableHead.displayName = 'DataTableHead';
27
+ export default DataTableHead;
@@ -0,0 +1,38 @@
1
+ import React, {ReactNode} from 'react';
2
+ import classNames from "classnames";
3
+ import {noop} from "./utils";
4
+ import {DataTableRowProps} from "./types";
5
+ import DataTableCell from "./DataTableCell";
6
+
7
+
8
+ function DataTableRow<T = unknown>({
9
+ className,
10
+ rowClassName,
11
+ selected,
12
+ fields,
13
+ row,
14
+ trRef,
15
+ onClick = noop,
16
+ ...rest
17
+ }: DataTableRowProps<T>) {
18
+ const clickHandler = () => {
19
+ return onClick ? onClick() : noop();
20
+ }
21
+
22
+ const _className = typeof rowClassName === 'function' ? rowClassName(row) : rowClassName;
23
+ if (!row) {
24
+ return null;
25
+ }
26
+
27
+ return (
28
+ <tr ref={trRef}
29
+ className={classNames({'table-active': selected}, className, _className)}
30
+ onClick={clickHandler}
31
+ {...rest}>
32
+ {fields.map((field, index) => (<DataTableCell key={index} field={field} row={row} />))}
33
+ </tr>
34
+ )
35
+ }
36
+
37
+ DataTableRow.displayName = 'DataTableRow';
38
+ export default DataTableRow;
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import DataTableRow from "./DataTableRow";
3
+ import {noop} from "./utils";
4
+ import {DataTableTBodyProps} from "./types";
5
+
6
+
7
+
8
+ function DataTableTBody<T = unknown>({
9
+ fields,
10
+ data,
11
+ keyField,
12
+ rowClassName,
13
+ renderRow,
14
+ onSelectRow = noop,
15
+ selected = '',
16
+ children,
17
+ ...rest
18
+ }: DataTableTBodyProps<T>) {
19
+
20
+ return (
21
+ <tbody {...rest}>
22
+ {data.map(row => {
23
+ const keyValue = String(typeof keyField === "function" ? keyField(row) : row[keyField]);
24
+ const isSelected = typeof selected === 'function' ? selected(row) : keyValue === selected;
25
+ if (renderRow) {
26
+ return renderRow(row);
27
+ }
28
+ return (
29
+ <DataTableRow key={keyValue} onClick={() => onSelectRow(row)}
30
+ rowClassName={rowClassName}
31
+ fields={fields}
32
+ row={row} selected={isSelected}/>
33
+ )
34
+ })}
35
+ {children}
36
+ </tbody>
37
+ )
38
+ }
39
+ DataTableTBody.displayName = 'DataTableTBody';
40
+ export default DataTableTBody
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import classNames from "classnames";
3
+ import {DataTableTHProps} from "./types";
4
+
5
+
6
+ function DataTableTH<T = unknown>({
7
+ field,
8
+ className,
9
+ children,
10
+ ...rest
11
+ }: DataTableTHProps<T>) {
12
+ const thClassName = classNames({[`text-${field.align}`]: !!field.align}, className);
13
+ return (
14
+ <th className={thClassName} scope="col" {...rest}>
15
+ {children ?? field.title}
16
+ </th>
17
+ )
18
+ }
19
+ DataTableTH.displayName = 'DataTableTH';
20
+ export default DataTableTH;
@@ -0,0 +1,38 @@
1
+ import React, {ChangeEvent, useId} from 'react';
2
+ import classNames from "classnames";
3
+ import {RowsPerPageProps} from "./types";
4
+
5
+ export const defaultRowsPerPageValues: number[] = [10, 25, 50, 100, 250, 500, 1000];
6
+
7
+
8
+ function RowsPerPage({
9
+ value,
10
+ pageValues = defaultRowsPerPageValues,
11
+ size,
12
+ label,
13
+ className,
14
+ onChange,
15
+ ...rest
16
+ }: RowsPerPageProps) {
17
+ const id = useId();
18
+ const changeHandler = (ev: ChangeEvent<HTMLSelectElement>) => onChange(Number(ev.target.value));
19
+ const selectClassName = className ?? classNames('form-select', {[`form-select-${size}`]: !!size});
20
+ const inputGroupClassName = classNames('input-group', {
21
+ [`input-group-${size}`]: !!size,
22
+ })
23
+
24
+ return (
25
+ <div className={inputGroupClassName} key={value}>
26
+ <label className="input-group-text" htmlFor={id}>{label ?? 'Rows'}</label>
27
+ <select className={selectClassName} id={id}
28
+ value={value} onChange={changeHandler} {...rest}>
29
+ {pageValues.map(value => (
30
+ <option key={value} value={value}>{value}</option>
31
+ ))}
32
+ </select>
33
+ </div>
34
+ )
35
+ }
36
+
37
+ RowsPerPage.displayName = 'RowsPerPage';
38
+ export default RowsPerPage;
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import classNames from "classnames";
3
+ import SortableTableHead from "./SortableTableHead";
4
+ import DataTableTBody from "./DataTableTBody";
5
+ import {SortableTableProps} from "./types";
6
+ import {noop} from "./utils";
7
+ import Table from "./Table";
8
+
9
+
10
+ function SortableTable<T = unknown>({
11
+ fields,
12
+ data,
13
+ currentSort,
14
+ onChangeSort,
15
+ keyField,
16
+ size = '',
17
+ sticky,
18
+ rowClassName,
19
+ renderRow,
20
+ onSelectRow = noop,
21
+ selected = '',
22
+ className = '',
23
+ tfoot,
24
+ children,
25
+ ...rest
26
+ }: SortableTableProps<T>) {
27
+ const tableClassName = classNames('table', className, {
28
+ [`table-${size}`]: !!size,
29
+ })
30
+
31
+ return (
32
+ <Table className={tableClassName} sticky={sticky} {...rest}>
33
+ <SortableTableHead currentSort={currentSort} fields={fields} onChangeSort={onChangeSort}/>
34
+ {!!data.length && (
35
+ <DataTableTBody fields={fields} data={data} keyField={keyField} rowClassName={rowClassName}
36
+ renderRow={renderRow}
37
+ onSelectRow={onSelectRow} selected={selected}/>
38
+ )}
39
+ {children}
40
+ {tfoot}
41
+ </Table>
42
+ )
43
+ }
44
+
45
+ SortableTable.displayName = 'SortableTable';
46
+ export default SortableTable;
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import SortableTableTH from "./SortableTableTH";
3
+ import classNames from "classnames";
4
+ import {SortableTableHeadProps} from "./types";
5
+
6
+
7
+ function SortableTableHead<T = unknown>({
8
+ currentSort,
9
+ fields,
10
+ onChangeSort,
11
+ }: SortableTableHeadProps<T>) {
12
+ const {field, ascending} = currentSort;
13
+ return (
14
+ <thead>
15
+ <tr>
16
+ {fields.map((tableField, index) => (
17
+ <SortableTableTH<T> key={index} field={tableField}
18
+ sorted={field === tableField.field} ascending={ascending}
19
+ className={classNames(
20
+ typeof tableField.className === 'function'
21
+ ? {[`text-${tableField.align}`]: !!tableField.align}
22
+ : tableField.className
23
+ )} onClick={onChangeSort}/>
24
+ ))}
25
+ </tr>
26
+ </thead>
27
+ )
28
+ }
29
+
30
+ SortableTableHead.displayName = 'SortableTableHead';
31
+ export default SortableTableHead;
@@ -0,0 +1,77 @@
1
+ import React from "react";
2
+ import classNames from "classnames";
3
+ import DataTableTH from "./DataTableTH";
4
+ import {SortableTableTHProps, UIFlexAlign} from "./types";
5
+ import styled from '@emotion/styled';
6
+
7
+ const flexJustifyContent = (align?: UIFlexAlign) => {
8
+ if (!align) {
9
+ return 'flex-start';
10
+ }
11
+ switch (align) {
12
+ case 'end':
13
+ return 'flex-end';
14
+ default:
15
+ return 'center';
16
+ }
17
+ }
18
+
19
+ type FieldTitleProps = {
20
+ sorted?: boolean;
21
+ align?: UIFlexAlign;
22
+ };
23
+ const FieldTitle = styled.div<FieldTitleProps>`
24
+ display: flex;
25
+ width: 100%;
26
+ flex-direction: ${props => props.align === 'end' ? 'row-reverse' : 'row'};
27
+ justify-content: ${props => flexJustifyContent(props.align)};
28
+ .sort-icon {
29
+ flex-grow: ${props => props.align === 'end' ? '1' : '0'};
30
+ opacity: ${props => props.sorted ? 1 : 0};
31
+ }
32
+ &:hover .sort-icon {
33
+ color: ${props => props.sorted ? 'unset' : 'var(--bs-primary)'} ;
34
+ opacity: 0.75;
35
+ transition: opacity 0.2s;
36
+ }
37
+ `
38
+
39
+ function SortableTableTH<T = unknown>({
40
+ field,
41
+ sorted,
42
+ ascending,
43
+ className,
44
+ onClick
45
+ }: SortableTableTHProps<T>) {
46
+ if (!field.sortable) {
47
+ return (<DataTableTH field={field} className={className}/>)
48
+ }
49
+
50
+ const {className: _thClassName, ...thProps} = field.thProps ?? {};
51
+ const thClassName = classNames(
52
+ className,
53
+ _thClassName,
54
+ {[`text-${field.align}`]: !!field.align}
55
+ );
56
+
57
+ const clickHandler = () => {
58
+ onClick({field: field.field, ascending: !sorted ? true : !ascending});
59
+ }
60
+
61
+ const iconClassName = {
62
+ 'bi-arrow-down': ascending,
63
+ 'bi-arrow-up': !ascending,
64
+ }
65
+
66
+ return (
67
+ <th {...thProps} className={classNames("sortable", thClassName)} scope="col" onClick={clickHandler}>
68
+ <FieldTitle sorted={sorted} align={field.align}>
69
+ <div className="field-title">{field.title}</div>
70
+ <div className={classNames('me-1 sort-icon', iconClassName)}/>
71
+ </FieldTitle>
72
+ </th>
73
+ )
74
+ }
75
+
76
+ SortableTableTH.displayName = 'SortableTableTH';
77
+ export default SortableTableTH;
package/src/Table.tsx ADDED
@@ -0,0 +1,43 @@
1
+ import React, {TableHTMLAttributes} from 'react';
2
+ import styled from "@emotion/styled";
3
+ import {DataTableProps} from "./types";
4
+ import classNames from "classnames";
5
+
6
+ export type StyledTableProps = TableHTMLAttributes<HTMLTableElement> & Pick<DataTableProps, 'sticky'|'responsive'>
7
+
8
+ const StyledTable = styled.table<StyledTableProps>`
9
+ --table-sticky-top: ${props => props.sticky ? '0' : undefined};
10
+
11
+ thead {
12
+ tr:nth-of-type(1) td,
13
+ tr:nth-of-type(1) th {
14
+ top: var(--table-sticky-top, unset);
15
+ position: ${props => props.sticky ? "sticky" : "unset"};
16
+ z-index: ${props => props.sticky ? 10 : "unset"};
17
+ background: ${props => props.sticky ? "linear-gradient(var(--bs-table-bg) 75%, rgba(var(--bs-secondary-bg-rgb), 0.9))" : "unset"};
18
+ }
19
+ }
20
+ `
21
+
22
+ export default React.forwardRef<HTMLTableElement, StyledTableProps>(
23
+ function Table({
24
+ sticky,
25
+ responsive,
26
+ children,
27
+ ...rest
28
+ }, ref) {
29
+ if (responsive) {
30
+ const className = classNames({
31
+ 'table-responsive': responsive === true,
32
+ [`table-responsive-${responsive}`]: responsive !== true,
33
+ })
34
+ return (
35
+ <div className={className}>
36
+ <StyledTable ref={ref} {...rest}>{children}</StyledTable>
37
+ </div>
38
+ )
39
+ }
40
+ return (
41
+ <StyledTable sticky={sticky} ref={ref} {...rest}>{children}</StyledTable>
42
+ )
43
+ })
@@ -0,0 +1,72 @@
1
+ import React from 'react';
2
+ import RowsPerPage from "./RowsPerPage";
3
+ import classNames from "classnames";
4
+ import {TablePaginationProps} from "./types";
5
+
6
+ function TablePagination({
7
+ page,
8
+ rowsPerPage,
9
+ onChangePage,
10
+ count,
11
+ size,
12
+ showFirst,
13
+ showLast,
14
+ className,
15
+ rowsPerPageProps,
16
+ ...rest
17
+ }: TablePaginationProps) {
18
+
19
+ const first = count === 0 ? 0 : (page * rowsPerPage) + 1;
20
+ const last = Math.min(page * rowsPerPage + rowsPerPage, count);
21
+ const lastPage = rowsPerPage === 0 ? 0 : Math.floor((count - 1) / rowsPerPage);
22
+
23
+ const buttonClassName = classNames("btn btn-link", {[`btn-${size}`]: !!size});
24
+
25
+ return (
26
+ <div className={classNames("row g-3 justify-content-end", className)} {...rest}>
27
+ {!!rowsPerPageProps && (
28
+ <div className="col-auto">
29
+ <RowsPerPage {...rowsPerPageProps} value={rowsPerPage} size={size}/>
30
+ </div>
31
+ )}
32
+ <div className="col-auto">
33
+ <div className="row g-3 flex-nowrap align-items-baseline">
34
+ <div className="col-auto">
35
+ {first}-{last} of {count}
36
+ </div>
37
+ {showFirst && (
38
+ <div className="col-auto">
39
+ <button className={buttonClassName} disabled={page === 0}
40
+ onClick={() => onChangePage(0)} aria-label="First page">
41
+ <span className="bi-chevron-bar-left" aria-hidden="true"/>
42
+ </button>
43
+ </div>
44
+ )}
45
+ <div className="col-auto">
46
+ <button className={buttonClassName} disabled={page === 0}
47
+ onClick={() => onChangePage(page - 1)} aria-label="Previous page">
48
+ <span className="bi-chevron-left" aria-hidden="true"/>
49
+ </button>
50
+ </div>
51
+ <div className="col-auto">
52
+ <button className={buttonClassName} disabled={page >= lastPage}
53
+ onClick={() => onChangePage(page + 1)} aria-label="Next page">
54
+ <span className="bi-chevron-right" aria-hidden="true"/>
55
+ </button>
56
+ </div>
57
+ {showLast && (
58
+ <div className="col-auto">
59
+ <button className={buttonClassName} disabled={page >= lastPage}
60
+ onClick={() => onChangePage(lastPage)} aria-label="Last page">
61
+ <span className="bi-chevron-bar-right" aria-hidden="true"/>
62
+ </button>
63
+ </div>
64
+ )}
65
+ </div>
66
+ </div>
67
+ </div>
68
+ )
69
+ }
70
+
71
+ TablePagination.displayname = 'TablePagination';
72
+ export default TablePagination
package/src/index.tsx ADDED
@@ -0,0 +1,14 @@
1
+ export {default as DataTable} from './DataTable';
2
+ export {default as DataTableRow} from './DataTableRow';
3
+ export {default as DataTableTBody} from './DataTableTBody';
4
+ export {default as DataTableTH} from './DataTableTH';
5
+ export {default as SortableTable} from './SortableTable';
6
+ export {default as SortableTableHead} from './SortableTableHead';
7
+ export {default as SortableTableTH} from './SortableTableTH';
8
+ export {default as RowsPerPage, defaultRowsPerPageValues} from './RowsPerPage';
9
+ export {default as TablePagination} from './TablePagination';
10
+ export type {
11
+ DataTableHeadProps, DataTableField, DataTableTHProps, DataTableClassNames, DataTableProps,
12
+ SortableTableField, DataTableRowProps, DataTableTBodyProps, SortableTableTHProps, SortableTableHeadProps,
13
+ SortProps, SortableTableProps, UISize, UIFlexAlign, TablePaginationProps, RowsPerPageProps
14
+ } from './types';
package/src/types.ts ADDED
@@ -0,0 +1,127 @@
1
+ import React, {HTMLAttributes, ReactNode, TableHTMLAttributes} from 'react'
2
+ import classNames from "classnames";
3
+
4
+
5
+ export interface SortProps<T = unknown> {
6
+ field: keyof T;
7
+ ascending: boolean;
8
+ }
9
+
10
+ export type UISize = 'sm'|'lg'|'';
11
+ export type UITableSize = UISize|'xs';
12
+
13
+ export type DataTableClassNames<T = unknown> =
14
+ string
15
+ | classNames.Argument
16
+ | ((row: T) => (string | classNames.Argument));
17
+
18
+
19
+ export type UIFlexAlign = 'start' | 'end' | 'center' | 'baseline' | 'stretch';
20
+
21
+ export interface DataTableField<T = unknown> {
22
+ id?: number | string;
23
+ field: keyof T;
24
+ title: ReactNode;
25
+ as?: 'td'|'th';
26
+ align?: 'start' | 'center' | 'end';
27
+ render?: (row: T) => ReactNode;
28
+ className?: DataTableClassNames<T>;
29
+ colSpan?: number;
30
+ thProps?: Omit<DataTableTHProps<T>, 'field'>;
31
+ cellProps?: TableHTMLAttributes<HTMLTableCellElement>
32
+ }
33
+
34
+ export interface SortableTableField<T = unknown> extends DataTableField<T> {
35
+ sortable?: boolean;
36
+ }
37
+
38
+ export interface DataTableProps<T = unknown> extends TableHTMLAttributes<HTMLTableElement> {
39
+ fields: DataTableField<T>[];
40
+ data: T[];
41
+ keyField: keyof T | ((row: T) => string|number);
42
+ size?: UITableSize;
43
+ sticky?: boolean;
44
+ responsive?: boolean|"sm" | "md" | "lg" | "xl" | 'xxl';
45
+ rowClassName?: DataTableClassNames<T>;
46
+ renderRow?: (row: T) => React.ReactNode;
47
+ onSelectRow?: (row: T) => T | void;
48
+ selected?: string | number | ((row: T) => boolean);
49
+ tfoot?: React.ReactElement<HTMLTableSectionElement>;
50
+ tableHeadProps?: DataTableHeadProps<T>;
51
+ children?: ReactNode;
52
+ }
53
+
54
+ export interface DataTableCellProps<T = unknown> extends Omit<TableHTMLAttributes<HTMLTableCellElement>, 'className'> {
55
+ field: DataTableField<T>;
56
+ row: T;
57
+ as?: 'td'|'th',
58
+ className?: string | classNames.Argument;
59
+ children?: React.ReactNode;
60
+ }
61
+
62
+ export interface DataTableTHProps<T = unknown> extends Omit<DataTableCellProps<T>, 'row'> {
63
+ as?: 'th',
64
+ }
65
+
66
+ export interface DataTableHeadProps<T = unknown> extends TableHTMLAttributes<HTMLTableSectionElement> {
67
+ fields: DataTableField<T>[];
68
+ }
69
+
70
+ export interface DataTableTBodyProps<T = unknown> extends TableHTMLAttributes<HTMLTableSectionElement> {
71
+ fields: DataTableField<T>[];
72
+ data: T[];
73
+ keyField: keyof T | ((row: T) => string|number);
74
+ rowClassName?: DataTableClassNames<T>;
75
+ renderRow?: (row: T) => React.ReactNode;
76
+ onSelectRow?: (row: T) => T | void;
77
+ selected?: string | number | ((row: T) => boolean);
78
+ children?: ReactNode;
79
+ }
80
+
81
+ export interface DataTableRowProps<T = unknown> extends Omit <TableHTMLAttributes<HTMLTableRowElement>, 'onClick'> {
82
+ rowClassName?: string | classNames.Argument | ((row: T) => string | classNames.Argument);
83
+ selected?: boolean;
84
+ fields: DataTableField<T>[];
85
+ row: T;
86
+ trRef?: React.Ref<HTMLTableRowElement>;
87
+ onClick?: (row?: T) => T | void;
88
+ }
89
+
90
+ export interface SortableTableProps<T = unknown> extends DataTableProps<T> {
91
+ currentSort: SortProps<T>;
92
+ onChangeSort: (sort: SortProps<T>) => void;
93
+ }
94
+
95
+ export interface SortableTableHeadProps<T = unknown> extends DataTableHeadProps<T> {
96
+ currentSort: SortProps<T>;
97
+ fields: SortableTableField<T>[];
98
+ onChangeSort: (sort: SortProps<T>) => void;
99
+ }
100
+
101
+ export interface SortableTableTHProps<T = unknown> extends Omit<DataTableTHProps<T>, 'onClick'> {
102
+ field: SortableTableField<T>;
103
+ sorted?: boolean;
104
+ ascending?: boolean;
105
+ onClick: (sort: SortProps<T>) => void;
106
+ }
107
+
108
+ export interface RowsPerPageProps extends Omit<HTMLAttributes<HTMLSelectElement>, 'onChange'> {
109
+ value: number;
110
+ pageValues?: number[];
111
+ label?: string;
112
+ size?: UISize;
113
+ className?: string;
114
+ onChange: (value: number) => void;
115
+ }
116
+
117
+ export interface TablePaginationProps extends HTMLAttributes<HTMLDivElement> {
118
+ page: number;
119
+ rowsPerPage: number;
120
+ onChangePage: (page: number) => void;
121
+ count: number;
122
+ size?: UISize;
123
+ showFirst?: boolean;
124
+ showLast?: boolean;
125
+ rowsPerPageProps?: Omit<RowsPerPageProps, 'value'>;
126
+ }
127
+
package/src/utils.ts ADDED
@@ -0,0 +1 @@
1
+ export function noop(){}