diff --git a/src/components/table/EnhancedTable.tsx b/src/components/table/EnhancedTable.tsx index 38639c2..a4746b0 100644 --- a/src/components/table/EnhancedTable.tsx +++ b/src/components/table/EnhancedTable.tsx @@ -1,25 +1,29 @@ import { createMemo, For, + Show, splitProps, - type JSX, - type Component, type Accessor, + type JSX, } from "solid-js"; import { createSolidTable, flexRender, getCoreRowModel, getSortedRowModel, + getFilteredRowModel, + getPaginationRowModel, type ColumnDef, type SortingState, type ColumnFiltersState, type PaginationState, - getFilteredRowModel, - getPaginationRowModel, type OnChangeFn, } from "@tanstack/solid-table"; import Table, { type TableProps } from "./Table"; +import Button from "../button/Button"; +import Input from "../input/Input"; +import Select from "../select/Select"; +import Loading from "../loading/Loading"; export type EnhancedTableProps = Omit & { data: TData[]; @@ -30,11 +34,15 @@ export type EnhancedTableProps = Omit & { setColumnFilters?: OnChangeFn; pagination?: Accessor; setPagination?: OnChangeFn; + globalFilter?: Accessor; + setGlobalFilter?: OnChangeFn; enableSorting?: boolean; enableFilters?: boolean; enablePagination?: boolean; renderRowSubComponent?: (props: { row: any }) => JSX.Element; renderEmpty?: () => JSX.Element; + loading?: boolean; + renderLoading?: () => JSX.Element; }; function EnhancedTable(props: EnhancedTableProps): JSX.Element { @@ -47,11 +55,15 @@ function EnhancedTable(props: EnhancedTableProps): JSX.Element { "setColumnFilters", "pagination", "setPagination", + "globalFilter", + "setGlobalFilter", "enableSorting", "enableFilters", "enablePagination", "renderRowSubComponent", "renderEmpty", + "loading", + "renderLoading", ]); const table = createSolidTable({ @@ -71,10 +83,14 @@ function EnhancedTable(props: EnhancedTableProps): JSX.Element { get pagination() { return local.pagination?.() || { pageIndex: 0, pageSize: 10 }; }, + get globalFilter() { + return local.globalFilter?.() || ""; + }, }, onSortingChange: local.setSorting, onColumnFiltersChange: local.setColumnFilters, onPaginationChange: local.setPagination, + onGlobalFilterChange: local.setGlobalFilter, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getFilteredRowModel: getFilteredRowModel(), @@ -85,48 +101,113 @@ function EnhancedTable(props: EnhancedTableProps): JSX.Element { }); const tableRows = createMemo(() => { + if (local.loading) return []; const rows = table.getRowModel().rows; - if (rows.length === 0 && local.renderEmpty) { - return []; - } + if (rows.length === 0 && local.renderEmpty) return []; return rows; }); + const headerGroups = () => table.getHeaderGroups(); + const leafHeaders = () => + headerGroups().length > 0 + ? headerGroups()[headerGroups().length - 1].headers + : []; + return ( - - - {(headerGroup) => ( - + {/* Toolbar */} + + + + {/* Fila de headers */} + + {(hg) => ( + + + {(header) => ( + +
+ {flexRender( + header.column.columnDef.header, + header.getContext() + )} + {header.column.getIsSorted() === "asc" && } + {header.column.getIsSorted() === "desc" && } +
+
+ )} +
+ + )} + + + + + {(header) => ( - -
- {flexRender( - header.column.columnDef.header, - header.getContext() - )} - {header.column.getIsSorted() === "asc" && } - {header.column.getIsSorted() === "desc" && } -
+ + {header.isPlaceholder || + !header.column.getCanFilter() ? null : ( + + )} )}
- )} - + + + - {tableRows().length === 0 && local.renderEmpty ? ( + {local.loading ? ( + + + {local.renderLoading ? ( + local.renderLoading() + ) : ( + + )} + + + ) : tableRows().length === 0 && local.renderEmpty ? ( (props: EnhancedTableProps): JSX.Element { ) : ( {(row) => ( - <> - - - {(cell) => ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext() - )} - - )} - - - {row.getIsExpanded() && local.renderRowSubComponent && ( - - - {local.renderRowSubComponent({ row })} + + + {(cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} - - )} - + )} + + )} )} + + +
+
+ Rows per page + +
+
+ + Page {table.getState().pagination.pageIndex + 1} of{" "} + {table.getPageCount() || 1} + +
+ + + + +
+
+
+
+
+
+ { + const val = (e.currentTarget as HTMLInputElement).value; + clearTimeout((window as any).__t); + (window as any).__t = setTimeout( + () => table.setGlobalFilter(val), + 300 + ); + }} + /> + +
+
+
); } +function ColumnFilter(props: { column: any }) { + const col = props.column; + const value = () => col.getFilterValue() as any; + const type = col.columnDef.meta?.filterType ?? "text"; + + if (type === "text") { + return ( + + col.setFilterValue( + (e.currentTarget as HTMLInputElement).value || undefined + ) + } + /> + ); + } + + if (type === "numberRange") { + const v: [string?, string?] = value() ?? [undefined, undefined]; + const setRange = (min?: string, max?: string) => { + if (!min && !max) return col.setFilterValue(undefined); + col.setFilterValue([min || undefined, max || undefined]); + }; + return ( +
+ + setRange((e.currentTarget as HTMLInputElement).value, v[1]) + } + /> + + setRange(v[0], (e.currentTarget as HTMLInputElement).value) + } + /> +
+ ); + } + + if (type === "select") { + const options: Array<{ label: string; value: string }> = + col.columnDef.meta?.options ?? []; + return ( + + ); + } + + return null; +} + export default EnhancedTable; diff --git a/src/components/table/Table.tsx b/src/components/table/Table.tsx index 827d754..feb9155 100644 --- a/src/components/table/Table.tsx +++ b/src/components/table/Table.tsx @@ -9,7 +9,6 @@ import TableRow from "./TableRow"; import TableFooter from "./TableFooter"; import TableCell from "./TableCell"; import TableHeadCell from "./TableHeadCell"; -import EnhancedTable from "./EnhancedTable"; export type TableProps = JSX.HTMLAttributes & IComponentBaseProps & { @@ -63,5 +62,4 @@ export default Object.assign(Table, { Footer: TableFooter, Cell: TableCell, HeadCell: TableHeadCell, - Enhanced: EnhancedTable, }); diff --git a/src/components/table/TableHead.tsx b/src/components/table/TableHead.tsx index 89d7676..ab30732 100644 --- a/src/components/table/TableHead.tsx +++ b/src/components/table/TableHead.tsx @@ -4,6 +4,7 @@ import { JSX, createMemo, children as resolveChildren, + Show, } from "solid-js"; import clsx from "clsx"; import { twMerge } from "tailwind-merge"; @@ -28,7 +29,9 @@ const TableHead: Component = (props) => { return ( - {resolved()} + {resolved()}}> + {resolved()} + ); }; diff --git a/src/components/table/index.ts b/src/components/table/index.ts index b1dd4ce..49d74e3 100644 --- a/src/components/table/index.ts +++ b/src/components/table/index.ts @@ -1,3 +1,5 @@ export { default } from "./Table"; export type { TableProps } from "./Table"; + +export { default as EnhancedTable } from "./EnhancedTable"; export type { EnhancedTableProps } from "./EnhancedTable"; diff --git a/src/index.ts b/src/index.ts index be29ce6..8df0a58 100644 --- a/src/index.ts +++ b/src/index.ts @@ -109,7 +109,7 @@ export { type SvgBackgroundProps, } from "./components/svgbackground"; export { default as Swap } from "./components/swap"; -export { default as Table } from "./components/table"; +export { default as Table, EnhancedTable } from "./components/table"; export type { TableProps } from "./components/table"; export type { EnhancedTableProps } from "./components/table/EnhancedTable"; export { default as Tabs } from "./components/tabs";