mogh_ui 0.7.4 → 0.7.5
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.
- package/dist/components/data-table.cjs +3 -2
- package/dist/components/data-table.cjs.map +1 -1
- package/dist/components/data-table.d.ts +2 -1
- package/dist/components/data-table.d.ts.map +1 -1
- package/dist/components/data-table.js +3 -2
- package/dist/components/data-table.js.map +1 -1
- package/package.json +1 -1
|
@@ -212,9 +212,10 @@ const SortableHeader = ({
|
|
|
212
212
|
column,
|
|
213
213
|
title,
|
|
214
214
|
description,
|
|
215
|
-
sortDescFirst
|
|
215
|
+
sortDescFirst,
|
|
216
|
+
disabled
|
|
216
217
|
}) => {
|
|
217
|
-
if (!column.getCanSort()) {
|
|
218
|
+
if (disabled || !column.getCanSort()) {
|
|
218
219
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Group, { justify: "start", gap: "xs", wrap: "nowrap", miw: "120", w: "fit-content", children: [
|
|
219
220
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Text, { fw: 600, size: "sm", lineClamp: 1, children: title }),
|
|
220
221
|
description && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.HoverCard, { offset: 10, children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/data-table.tsx"],"sourcesContent":["import {\n Dispatch,\n ReactNode,\n SetStateAction,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport {\n Column,\n ColumnDef,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n Row,\n RowSelectionState,\n SortingState,\n useReactTable,\n} from \"@tanstack/react-table\";\nimport {\n Box,\n BoxProps,\n Center,\n Checkbox,\n DefaultMantineColor,\n Group,\n HoverCard,\n Loader,\n Table,\n TableProps,\n Text,\n UnstyledButton,\n} from \"@mantine/core\";\nimport { ArrowDown, ArrowUp, Info, Minus } from \"lucide-react\";\n\nfunction loadStoredSorting(tableKey: string): SortingState | null {\n try {\n const stored = localStorage.getItem(\"data-table-\" + tableKey);\n return stored ? (JSON.parse(stored) as SortingState) : null;\n } catch {\n return null;\n }\n}\n\nexport interface DataTableProps<TData, TValue = unknown> extends BoxProps {\n /** Unique key given to table so sorting can be remembered on local storage */\n tableKey: string;\n columns: (ColumnDef<TData, TValue> | false | undefined)[];\n data: TData[];\n loading?: boolean;\n onRowClick?: (row: TData) => void;\n noResults?: ReactNode;\n defaultSort?: SortingState;\n sortDescFirst?: boolean;\n /** Sorting is handled externally (eg. server side).\n * The table still manages / persists the sorting state,\n * but does not apply it to the rows. */\n manualSorting?: boolean;\n /** Called with the sorting state whenever it changes.\n * Also called on mount with the initial state\n * (loaded from local storage when available). */\n onSortingStateChange?: (sorting: SortingState) => void;\n selectOptions?: {\n selectKey: (row: TData) => string;\n onSelect?: (selected: string[]) => void;\n state?: [RowSelectionState, Dispatch<SetStateAction<RowSelectionState>>];\n disableRow?: boolean | ((row: Row<TData>) => boolean);\n color?: DefaultMantineColor;\n };\n caption?: string;\n tableProps?: TableProps;\n noBox?: boolean;\n noBorder?: boolean;\n}\n\nexport function DataTable<TData, TValue>({\n tableKey,\n columns,\n data,\n loading,\n onRowClick,\n noResults = <Text c=\"dimmed\">No results</Text>,\n sortDescFirst = false,\n defaultSort = [],\n manualSorting,\n onSortingStateChange,\n selectOptions,\n caption,\n tableProps,\n noBox,\n noBorder,\n mah = \"max(150px, calc(100vh - 320px))\",\n ...boxProps\n}: DataTableProps<TData, TValue>) {\n // Initialized synchronously from local storage so the first render\n // (and any server side sorted query) already uses the persisted sort,\n // instead of flashing through the unsorted state.\n const [sorting, setSorting] = useState<SortingState>(\n () => loadStoredSorting(tableKey) ?? defaultSort,\n );\n const [prevTableKey, setPrevTableKey] = useState(tableKey);\n if (prevTableKey !== tableKey) {\n setPrevTableKey(tableKey);\n setSorting(loadStoredSorting(tableKey) ?? defaultSort);\n }\n\n // intentionally not initialized to clear selected values on table mount\n // could add some prop for adding default selected state to preserve between mounts\n const _internalState = useState<RowSelectionState>({});\n const [rowSelection, setRowSelection] = selectOptions?.state\n ? selectOptions.state\n : _internalState;\n\n const table = useReactTable({\n data,\n columns: columns.filter((c) => c) as any,\n getCoreRowModel: getCoreRowModel(),\n onSortingChange: setSorting,\n getSortedRowModel: getSortedRowModel(),\n manualSorting,\n state: {\n sorting,\n rowSelection,\n },\n sortDescFirst,\n onRowSelectionChange: setRowSelection,\n getRowId: selectOptions?.selectKey,\n enableRowSelection: selectOptions?.disableRow,\n });\n\n useEffect(() => {\n localStorage.setItem(\"data-table-\" + tableKey, JSON.stringify(sorting));\n }, [tableKey, sorting]);\n\n // Layout effect so the parent receives the initial (persisted) sorting\n // before any of its own passive effects run, ie before react-query\n // subscribes a server side sorted query using the pre-sort key.\n useLayoutEffect(() => {\n onSortingStateChange?.(sorting);\n }, [sorting]);\n\n useEffect(() => {\n selectOptions?.onSelect?.(Object.keys(rowSelection));\n }, [rowSelection]);\n\n const rows = table.getPrePaginationRowModel().rows;\n\n const tableNode = (\n <Table\n borderColor=\"accent-border\"\n captionSide=\"top\"\n stickyHeader\n {...tableProps}\n >\n {caption ? <Table.Caption>{caption}</Table.Caption> : null}\n\n <Table.Thead>\n {table.getHeaderGroups().map((hg, i) => (\n <Table.Tr key={hg.id}>\n {i === 0 && selectOptions && (\n <Table.Th\n onClick={() =>\n selectOptions.disableRow !== true &&\n table.toggleAllRowsSelected()\n }\n style={{\n cursor: \"pointer\",\n borderColor: \"var(--mantine-color-accent-border-0)\",\n borderWidth: 0,\n borderRightWidth: 1,\n borderStyle: \"solid\",\n }}\n >\n <Checkbox\n color={selectOptions.color ?? \"Neutral\"}\n disabled={selectOptions.disableRow === true}\n checked={table.getIsAllRowsSelected()}\n indeterminate={table.getIsSomeRowsSelected()}\n />\n </Table.Th>\n )}\n {hg.headers.map((header, i) => {\n // const canSort = header.column.getCanSort();\n // const sortState = header.column.getIsSorted();\n return (\n <Table.Th\n key={header.id}\n px=\"md\"\n style={{\n cursor: \"pointer\",\n borderColor: \"var(--mantine-color-accent-border-0)\",\n borderWidth: 0,\n borderRightWidth: i < hg.headers.length - 1 ? 1 : 0,\n borderStyle: \"solid\",\n }}\n >\n {header.isPlaceholder ? null : (\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </Text>\n )}\n </Table.Th>\n );\n })}\n </Table.Tr>\n ))}\n </Table.Thead>\n\n <Table.Tbody>\n {loading ? (\n <Table.Tr>\n <Table.Td\n colSpan={\n table.getAllLeafColumns().length + (selectOptions ? 1 : 0)\n }\n >\n <Group justify=\"center\" py=\"lg\">\n <Loader size=\"sm\" />\n </Group>\n </Table.Td>\n </Table.Tr>\n ) : rows.length === 0 ? (\n <Table.Tr>\n <Table.Td\n colSpan={\n table.getAllLeafColumns().length + (selectOptions ? 1 : 0)\n }\n >\n <Group justify=\"center\" py=\"lg\">\n {noResults}\n </Group>\n </Table.Td>\n </Table.Tr>\n ) : (\n rows.map((row) => (\n <Table.Tr\n key={row.id}\n style={{\n cursor: onRowClick ? \"pointer\" : undefined,\n contentVisibility: \"auto\",\n containIntrinsicSize: \"auto 2em\",\n }}\n >\n {selectOptions && (\n <Table.Td onClick={() => row.toggleSelected()}>\n <Checkbox\n aria-label=\"Select row\"\n color={selectOptions.color ?? \"Neutral\"}\n disabled={!row.getCanSelect()}\n checked={row.getIsSelected()}\n />\n </Table.Td>\n )}\n {row.getVisibleCells().map((cell) => (\n <Table.Td\n key={cell.id}\n onClick={\n onRowClick ? () => onRowClick(row.original) : undefined\n }\n style={{ flexWrap: \"nowrap\", textWrap: \"nowrap\" }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </Table.Td>\n ))}\n </Table.Tr>\n ))\n )}\n </Table.Tbody>\n </Table>\n );\n\n if (noBox) {\n return tableNode;\n } else {\n return (\n <Box\n p={noBorder ? undefined : \"lg\"}\n pt=\"0\"\n className={noBorder ? undefined : \"bordered-light\"}\n bdrs=\"md\"\n w=\"100%\"\n mah={mah}\n style={{ overflow: \"auto\" }}\n {...boxProps}\n >\n {tableNode}\n </Box>\n );\n }\n}\n\nexport const SortableHeader = <T, V>({\n column,\n title,\n description,\n sortDescFirst,\n}: {\n column: Column<T, V>;\n title: string;\n description?: ReactNode;\n sortDescFirst?: boolean;\n}) => {\n if (!column.getCanSort()) {\n return (\n <Group justify=\"start\" gap=\"xs\" wrap=\"nowrap\" miw=\"120\" w=\"fit-content\">\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {title}\n </Text>\n {description && (\n <HoverCard offset={10}>\n <HoverCard.Target>\n <Info size=\"1rem\" />\n </HoverCard.Target>\n <HoverCard.Dropdown>\n <Text>{description}</Text>\n </HoverCard.Dropdown>\n </HoverCard>\n )}\n </Group>\n );\n }\n return (\n <UnstyledButton\n onClick={column.getToggleSortingHandler()}\n style={{ width: \"100%\" }}\n >\n <Group justify=\"space-between\" gap=\"sm\" wrap=\"nowrap\">\n <Group justify=\"start\" gap=\"xs\" wrap=\"nowrap\" miw=\"120\" w=\"fit-content\">\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {title}\n </Text>\n {description && (\n <HoverCard offset={10}>\n <HoverCard.Target>\n <Info size=\"1rem\" />\n </HoverCard.Target>\n <HoverCard.Dropdown>\n <Text>{description}</Text>\n </HoverCard.Dropdown>\n </HoverCard>\n )}\n </Group>\n <Center>\n <SortIcon\n state={column.getIsSorted()}\n sortDescFirst={sortDescFirst}\n />\n </Center>\n </Group>\n </UnstyledButton>\n );\n};\n\nfunction SortIcon({\n state,\n sortDescFirst,\n}: {\n state: false | \"asc\" | \"desc\";\n sortDescFirst?: boolean;\n}) {\n if (state === \"asc\")\n return sortDescFirst ? <ArrowUp size={14} /> : <ArrowDown size={14} />;\n if (state === \"desc\")\n return sortDescFirst ? <ArrowDown size={14} /> : <ArrowUp size={14} />;\n return <Minus size={14} />;\n}\n"],"mappings":"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","names":["i"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/data-table.tsx"],"sourcesContent":["import {\n Dispatch,\n ReactNode,\n SetStateAction,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport {\n Column,\n ColumnDef,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n Row,\n RowSelectionState,\n SortingState,\n useReactTable,\n} from \"@tanstack/react-table\";\nimport {\n Box,\n BoxProps,\n Center,\n Checkbox,\n DefaultMantineColor,\n Group,\n HoverCard,\n Loader,\n Table,\n TableProps,\n Text,\n UnstyledButton,\n} from \"@mantine/core\";\nimport { ArrowDown, ArrowUp, Info, Minus } from \"lucide-react\";\n\nfunction loadStoredSorting(tableKey: string): SortingState | null {\n try {\n const stored = localStorage.getItem(\"data-table-\" + tableKey);\n return stored ? (JSON.parse(stored) as SortingState) : null;\n } catch {\n return null;\n }\n}\n\nexport interface DataTableProps<TData, TValue = unknown> extends BoxProps {\n /** Unique key given to table so sorting can be remembered on local storage */\n tableKey: string;\n columns: (ColumnDef<TData, TValue> | false | undefined)[];\n data: TData[];\n loading?: boolean;\n onRowClick?: (row: TData) => void;\n noResults?: ReactNode;\n defaultSort?: SortingState;\n sortDescFirst?: boolean;\n /** Sorting is handled externally (eg. server side).\n * The table still manages / persists the sorting state,\n * but does not apply it to the rows. */\n manualSorting?: boolean;\n /** Called with the sorting state whenever it changes.\n * Also called on mount with the initial state\n * (loaded from local storage when available). */\n onSortingStateChange?: (sorting: SortingState) => void;\n selectOptions?: {\n selectKey: (row: TData) => string;\n onSelect?: (selected: string[]) => void;\n state?: [RowSelectionState, Dispatch<SetStateAction<RowSelectionState>>];\n disableRow?: boolean | ((row: Row<TData>) => boolean);\n color?: DefaultMantineColor;\n };\n caption?: string;\n tableProps?: TableProps;\n noBox?: boolean;\n noBorder?: boolean;\n}\n\nexport function DataTable<TData, TValue>({\n tableKey,\n columns,\n data,\n loading,\n onRowClick,\n noResults = <Text c=\"dimmed\">No results</Text>,\n sortDescFirst = false,\n defaultSort = [],\n manualSorting,\n onSortingStateChange,\n selectOptions,\n caption,\n tableProps,\n noBox,\n noBorder,\n mah = \"max(150px, calc(100vh - 320px))\",\n ...boxProps\n}: DataTableProps<TData, TValue>) {\n // Initialized synchronously from local storage so the first render\n // (and any server side sorted query) already uses the persisted sort,\n // instead of flashing through the unsorted state.\n const [sorting, setSorting] = useState<SortingState>(\n () => loadStoredSorting(tableKey) ?? defaultSort,\n );\n const [prevTableKey, setPrevTableKey] = useState(tableKey);\n if (prevTableKey !== tableKey) {\n setPrevTableKey(tableKey);\n setSorting(loadStoredSorting(tableKey) ?? defaultSort);\n }\n\n // intentionally not initialized to clear selected values on table mount\n // could add some prop for adding default selected state to preserve between mounts\n const _internalState = useState<RowSelectionState>({});\n const [rowSelection, setRowSelection] = selectOptions?.state\n ? selectOptions.state\n : _internalState;\n\n const table = useReactTable({\n data,\n columns: columns.filter((c) => c) as any,\n getCoreRowModel: getCoreRowModel(),\n onSortingChange: setSorting,\n getSortedRowModel: getSortedRowModel(),\n manualSorting,\n state: {\n sorting,\n rowSelection,\n },\n sortDescFirst,\n onRowSelectionChange: setRowSelection,\n getRowId: selectOptions?.selectKey,\n enableRowSelection: selectOptions?.disableRow,\n });\n\n useEffect(() => {\n localStorage.setItem(\"data-table-\" + tableKey, JSON.stringify(sorting));\n }, [tableKey, sorting]);\n\n // Layout effect so the parent receives the initial (persisted) sorting\n // before any of its own passive effects run, ie before react-query\n // subscribes a server side sorted query using the pre-sort key.\n useLayoutEffect(() => {\n onSortingStateChange?.(sorting);\n }, [sorting]);\n\n useEffect(() => {\n selectOptions?.onSelect?.(Object.keys(rowSelection));\n }, [rowSelection]);\n\n const rows = table.getPrePaginationRowModel().rows;\n\n const tableNode = (\n <Table\n borderColor=\"accent-border\"\n captionSide=\"top\"\n stickyHeader\n {...tableProps}\n >\n {caption ? <Table.Caption>{caption}</Table.Caption> : null}\n\n <Table.Thead>\n {table.getHeaderGroups().map((hg, i) => (\n <Table.Tr key={hg.id}>\n {i === 0 && selectOptions && (\n <Table.Th\n onClick={() =>\n selectOptions.disableRow !== true &&\n table.toggleAllRowsSelected()\n }\n style={{\n cursor: \"pointer\",\n borderColor: \"var(--mantine-color-accent-border-0)\",\n borderWidth: 0,\n borderRightWidth: 1,\n borderStyle: \"solid\",\n }}\n >\n <Checkbox\n color={selectOptions.color ?? \"Neutral\"}\n disabled={selectOptions.disableRow === true}\n checked={table.getIsAllRowsSelected()}\n indeterminate={table.getIsSomeRowsSelected()}\n />\n </Table.Th>\n )}\n {hg.headers.map((header, i) => {\n // const canSort = header.column.getCanSort();\n // const sortState = header.column.getIsSorted();\n return (\n <Table.Th\n key={header.id}\n px=\"md\"\n style={{\n cursor: \"pointer\",\n borderColor: \"var(--mantine-color-accent-border-0)\",\n borderWidth: 0,\n borderRightWidth: i < hg.headers.length - 1 ? 1 : 0,\n borderStyle: \"solid\",\n }}\n >\n {header.isPlaceholder ? null : (\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </Text>\n )}\n </Table.Th>\n );\n })}\n </Table.Tr>\n ))}\n </Table.Thead>\n\n <Table.Tbody>\n {loading ? (\n <Table.Tr>\n <Table.Td\n colSpan={\n table.getAllLeafColumns().length + (selectOptions ? 1 : 0)\n }\n >\n <Group justify=\"center\" py=\"lg\">\n <Loader size=\"sm\" />\n </Group>\n </Table.Td>\n </Table.Tr>\n ) : rows.length === 0 ? (\n <Table.Tr>\n <Table.Td\n colSpan={\n table.getAllLeafColumns().length + (selectOptions ? 1 : 0)\n }\n >\n <Group justify=\"center\" py=\"lg\">\n {noResults}\n </Group>\n </Table.Td>\n </Table.Tr>\n ) : (\n rows.map((row) => (\n <Table.Tr\n key={row.id}\n style={{\n cursor: onRowClick ? \"pointer\" : undefined,\n contentVisibility: \"auto\",\n containIntrinsicSize: \"auto 2em\",\n }}\n >\n {selectOptions && (\n <Table.Td onClick={() => row.toggleSelected()}>\n <Checkbox\n aria-label=\"Select row\"\n color={selectOptions.color ?? \"Neutral\"}\n disabled={!row.getCanSelect()}\n checked={row.getIsSelected()}\n />\n </Table.Td>\n )}\n {row.getVisibleCells().map((cell) => (\n <Table.Td\n key={cell.id}\n onClick={\n onRowClick ? () => onRowClick(row.original) : undefined\n }\n style={{ flexWrap: \"nowrap\", textWrap: \"nowrap\" }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </Table.Td>\n ))}\n </Table.Tr>\n ))\n )}\n </Table.Tbody>\n </Table>\n );\n\n if (noBox) {\n return tableNode;\n } else {\n return (\n <Box\n p={noBorder ? undefined : \"lg\"}\n pt=\"0\"\n className={noBorder ? undefined : \"bordered-light\"}\n bdrs=\"md\"\n w=\"100%\"\n mah={mah}\n style={{ overflow: \"auto\" }}\n {...boxProps}\n >\n {tableNode}\n </Box>\n );\n }\n}\n\nexport const SortableHeader = <T, V>({\n column,\n title,\n description,\n sortDescFirst,\n disabled,\n}: {\n column: Column<T, V>;\n title: string;\n description?: ReactNode;\n sortDescFirst?: boolean;\n disabled?: boolean;\n}) => {\n if (disabled || !column.getCanSort()) {\n return (\n <Group justify=\"start\" gap=\"xs\" wrap=\"nowrap\" miw=\"120\" w=\"fit-content\">\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {title}\n </Text>\n {description && (\n <HoverCard offset={10}>\n <HoverCard.Target>\n <Info size=\"1rem\" />\n </HoverCard.Target>\n <HoverCard.Dropdown>\n <Text>{description}</Text>\n </HoverCard.Dropdown>\n </HoverCard>\n )}\n </Group>\n );\n }\n return (\n <UnstyledButton\n onClick={column.getToggleSortingHandler()}\n style={{ width: \"100%\" }}\n >\n <Group justify=\"space-between\" gap=\"sm\" wrap=\"nowrap\">\n <Group justify=\"start\" gap=\"xs\" wrap=\"nowrap\" miw=\"120\" w=\"fit-content\">\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {title}\n </Text>\n {description && (\n <HoverCard offset={10}>\n <HoverCard.Target>\n <Info size=\"1rem\" />\n </HoverCard.Target>\n <HoverCard.Dropdown>\n <Text>{description}</Text>\n </HoverCard.Dropdown>\n </HoverCard>\n )}\n </Group>\n <Center>\n <SortIcon\n state={column.getIsSorted()}\n sortDescFirst={sortDescFirst}\n />\n </Center>\n </Group>\n </UnstyledButton>\n );\n};\n\nfunction SortIcon({\n state,\n sortDescFirst,\n}: {\n state: false | \"asc\" | \"desc\";\n sortDescFirst?: boolean;\n}) {\n if (state === \"asc\")\n return sortDescFirst ? <ArrowUp size={14} /> : <ArrowDown size={14} />;\n if (state === \"desc\")\n return sortDescFirst ? <ArrowDown size={14} /> : <ArrowUp size={14} />;\n return <Minus size={14} />;\n}\n"],"mappings":"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","names":["i"]}
|
|
@@ -32,10 +32,11 @@ export interface DataTableProps<TData, TValue = unknown> extends BoxProps {
|
|
|
32
32
|
noBorder?: boolean;
|
|
33
33
|
}
|
|
34
34
|
export declare function DataTable<TData, TValue>({ tableKey, columns, data, loading, onRowClick, noResults, sortDescFirst, defaultSort, manualSorting, onSortingStateChange, selectOptions, caption, tableProps, noBox, noBorder, mah, ...boxProps }: DataTableProps<TData, TValue>): import("react").JSX.Element;
|
|
35
|
-
export declare const SortableHeader: <T, V>({ column, title, description, sortDescFirst, }: {
|
|
35
|
+
export declare const SortableHeader: <T, V>({ column, title, description, sortDescFirst, disabled, }: {
|
|
36
36
|
column: Column<T, V>;
|
|
37
37
|
title: string;
|
|
38
38
|
description?: ReactNode;
|
|
39
39
|
sortDescFirst?: boolean;
|
|
40
|
+
disabled?: boolean;
|
|
40
41
|
}) => import("react").JSX.Element;
|
|
41
42
|
//# sourceMappingURL=data-table.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/components/data-table.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,SAAS,EACT,cAAc,EAIf,MAAM,OAAO,CAAC;AACf,OAAO,EACL,MAAM,EACN,SAAS,EAIT,GAAG,EACH,iBAAiB,EACjB,YAAY,EAEb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,QAAQ,EAGR,mBAAmB,EAKnB,UAAU,EAGX,MAAM,eAAe,CAAC;AAYvB,MAAM,WAAW,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAE,SAAQ,QAAQ;IACvE,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC;IAC1D,IAAI,EAAE,KAAK,EAAE,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;4CAEwC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;qDAEiD;IACjD,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACvD,aAAa,CAAC,EAAE;QACd,SAAS,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,MAAM,CAAC;QAClC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;QACxC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;QACzE,UAAU,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC,CAAC;QACtD,KAAK,CAAC,EAAE,mBAAmB,CAAC;KAC7B,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EACvC,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,OAAO,EACP,UAAU,EACV,SAA8C,EAC9C,aAAqB,EACrB,WAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,OAAO,EACP,UAAU,EACV,KAAK,EACL,QAAQ,EACR,GAAuC,EACvC,GAAG,QAAQ,EACZ,EAAE,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,+BAuM/B;AAED,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/components/data-table.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,SAAS,EACT,cAAc,EAIf,MAAM,OAAO,CAAC;AACf,OAAO,EACL,MAAM,EACN,SAAS,EAIT,GAAG,EACH,iBAAiB,EACjB,YAAY,EAEb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,QAAQ,EAGR,mBAAmB,EAKnB,UAAU,EAGX,MAAM,eAAe,CAAC;AAYvB,MAAM,WAAW,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAE,SAAQ,QAAQ;IACvE,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC;IAC1D,IAAI,EAAE,KAAK,EAAE,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;4CAEwC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;qDAEiD;IACjD,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACvD,aAAa,CAAC,EAAE;QACd,SAAS,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,MAAM,CAAC;QAClC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;QACxC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;QACzE,UAAU,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC,CAAC;QACtD,KAAK,CAAC,EAAE,mBAAmB,CAAC;KAC7B,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EACvC,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,OAAO,EACP,UAAU,EACV,SAA8C,EAC9C,aAAqB,EACrB,WAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,OAAO,EACP,UAAU,EACV,KAAK,EACL,QAAQ,EACR,GAAuC,EACvC,GAAG,QAAQ,EACZ,EAAE,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,+BAuM/B;AAED,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,CAAC,4DAMhC;IACD,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,gCAkDA,CAAC"}
|
|
@@ -207,9 +207,10 @@ const SortableHeader = ({
|
|
|
207
207
|
column,
|
|
208
208
|
title,
|
|
209
209
|
description,
|
|
210
|
-
sortDescFirst
|
|
210
|
+
sortDescFirst,
|
|
211
|
+
disabled
|
|
211
212
|
}) => {
|
|
212
|
-
if (!column.getCanSort()) {
|
|
213
|
+
if (disabled || !column.getCanSort()) {
|
|
213
214
|
return /* @__PURE__ */ jsxs(Group, { justify: "start", gap: "xs", wrap: "nowrap", miw: "120", w: "fit-content", children: [
|
|
214
215
|
/* @__PURE__ */ jsx(Text, { fw: 600, size: "sm", lineClamp: 1, children: title }),
|
|
215
216
|
description && /* @__PURE__ */ jsxs(HoverCard, { offset: 10, children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/data-table.tsx"],"sourcesContent":["import {\n Dispatch,\n ReactNode,\n SetStateAction,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport {\n Column,\n ColumnDef,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n Row,\n RowSelectionState,\n SortingState,\n useReactTable,\n} from \"@tanstack/react-table\";\nimport {\n Box,\n BoxProps,\n Center,\n Checkbox,\n DefaultMantineColor,\n Group,\n HoverCard,\n Loader,\n Table,\n TableProps,\n Text,\n UnstyledButton,\n} from \"@mantine/core\";\nimport { ArrowDown, ArrowUp, Info, Minus } from \"lucide-react\";\n\nfunction loadStoredSorting(tableKey: string): SortingState | null {\n try {\n const stored = localStorage.getItem(\"data-table-\" + tableKey);\n return stored ? (JSON.parse(stored) as SortingState) : null;\n } catch {\n return null;\n }\n}\n\nexport interface DataTableProps<TData, TValue = unknown> extends BoxProps {\n /** Unique key given to table so sorting can be remembered on local storage */\n tableKey: string;\n columns: (ColumnDef<TData, TValue> | false | undefined)[];\n data: TData[];\n loading?: boolean;\n onRowClick?: (row: TData) => void;\n noResults?: ReactNode;\n defaultSort?: SortingState;\n sortDescFirst?: boolean;\n /** Sorting is handled externally (eg. server side).\n * The table still manages / persists the sorting state,\n * but does not apply it to the rows. */\n manualSorting?: boolean;\n /** Called with the sorting state whenever it changes.\n * Also called on mount with the initial state\n * (loaded from local storage when available). */\n onSortingStateChange?: (sorting: SortingState) => void;\n selectOptions?: {\n selectKey: (row: TData) => string;\n onSelect?: (selected: string[]) => void;\n state?: [RowSelectionState, Dispatch<SetStateAction<RowSelectionState>>];\n disableRow?: boolean | ((row: Row<TData>) => boolean);\n color?: DefaultMantineColor;\n };\n caption?: string;\n tableProps?: TableProps;\n noBox?: boolean;\n noBorder?: boolean;\n}\n\nexport function DataTable<TData, TValue>({\n tableKey,\n columns,\n data,\n loading,\n onRowClick,\n noResults = <Text c=\"dimmed\">No results</Text>,\n sortDescFirst = false,\n defaultSort = [],\n manualSorting,\n onSortingStateChange,\n selectOptions,\n caption,\n tableProps,\n noBox,\n noBorder,\n mah = \"max(150px, calc(100vh - 320px))\",\n ...boxProps\n}: DataTableProps<TData, TValue>) {\n // Initialized synchronously from local storage so the first render\n // (and any server side sorted query) already uses the persisted sort,\n // instead of flashing through the unsorted state.\n const [sorting, setSorting] = useState<SortingState>(\n () => loadStoredSorting(tableKey) ?? defaultSort,\n );\n const [prevTableKey, setPrevTableKey] = useState(tableKey);\n if (prevTableKey !== tableKey) {\n setPrevTableKey(tableKey);\n setSorting(loadStoredSorting(tableKey) ?? defaultSort);\n }\n\n // intentionally not initialized to clear selected values on table mount\n // could add some prop for adding default selected state to preserve between mounts\n const _internalState = useState<RowSelectionState>({});\n const [rowSelection, setRowSelection] = selectOptions?.state\n ? selectOptions.state\n : _internalState;\n\n const table = useReactTable({\n data,\n columns: columns.filter((c) => c) as any,\n getCoreRowModel: getCoreRowModel(),\n onSortingChange: setSorting,\n getSortedRowModel: getSortedRowModel(),\n manualSorting,\n state: {\n sorting,\n rowSelection,\n },\n sortDescFirst,\n onRowSelectionChange: setRowSelection,\n getRowId: selectOptions?.selectKey,\n enableRowSelection: selectOptions?.disableRow,\n });\n\n useEffect(() => {\n localStorage.setItem(\"data-table-\" + tableKey, JSON.stringify(sorting));\n }, [tableKey, sorting]);\n\n // Layout effect so the parent receives the initial (persisted) sorting\n // before any of its own passive effects run, ie before react-query\n // subscribes a server side sorted query using the pre-sort key.\n useLayoutEffect(() => {\n onSortingStateChange?.(sorting);\n }, [sorting]);\n\n useEffect(() => {\n selectOptions?.onSelect?.(Object.keys(rowSelection));\n }, [rowSelection]);\n\n const rows = table.getPrePaginationRowModel().rows;\n\n const tableNode = (\n <Table\n borderColor=\"accent-border\"\n captionSide=\"top\"\n stickyHeader\n {...tableProps}\n >\n {caption ? <Table.Caption>{caption}</Table.Caption> : null}\n\n <Table.Thead>\n {table.getHeaderGroups().map((hg, i) => (\n <Table.Tr key={hg.id}>\n {i === 0 && selectOptions && (\n <Table.Th\n onClick={() =>\n selectOptions.disableRow !== true &&\n table.toggleAllRowsSelected()\n }\n style={{\n cursor: \"pointer\",\n borderColor: \"var(--mantine-color-accent-border-0)\",\n borderWidth: 0,\n borderRightWidth: 1,\n borderStyle: \"solid\",\n }}\n >\n <Checkbox\n color={selectOptions.color ?? \"Neutral\"}\n disabled={selectOptions.disableRow === true}\n checked={table.getIsAllRowsSelected()}\n indeterminate={table.getIsSomeRowsSelected()}\n />\n </Table.Th>\n )}\n {hg.headers.map((header, i) => {\n // const canSort = header.column.getCanSort();\n // const sortState = header.column.getIsSorted();\n return (\n <Table.Th\n key={header.id}\n px=\"md\"\n style={{\n cursor: \"pointer\",\n borderColor: \"var(--mantine-color-accent-border-0)\",\n borderWidth: 0,\n borderRightWidth: i < hg.headers.length - 1 ? 1 : 0,\n borderStyle: \"solid\",\n }}\n >\n {header.isPlaceholder ? null : (\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </Text>\n )}\n </Table.Th>\n );\n })}\n </Table.Tr>\n ))}\n </Table.Thead>\n\n <Table.Tbody>\n {loading ? (\n <Table.Tr>\n <Table.Td\n colSpan={\n table.getAllLeafColumns().length + (selectOptions ? 1 : 0)\n }\n >\n <Group justify=\"center\" py=\"lg\">\n <Loader size=\"sm\" />\n </Group>\n </Table.Td>\n </Table.Tr>\n ) : rows.length === 0 ? (\n <Table.Tr>\n <Table.Td\n colSpan={\n table.getAllLeafColumns().length + (selectOptions ? 1 : 0)\n }\n >\n <Group justify=\"center\" py=\"lg\">\n {noResults}\n </Group>\n </Table.Td>\n </Table.Tr>\n ) : (\n rows.map((row) => (\n <Table.Tr\n key={row.id}\n style={{\n cursor: onRowClick ? \"pointer\" : undefined,\n contentVisibility: \"auto\",\n containIntrinsicSize: \"auto 2em\",\n }}\n >\n {selectOptions && (\n <Table.Td onClick={() => row.toggleSelected()}>\n <Checkbox\n aria-label=\"Select row\"\n color={selectOptions.color ?? \"Neutral\"}\n disabled={!row.getCanSelect()}\n checked={row.getIsSelected()}\n />\n </Table.Td>\n )}\n {row.getVisibleCells().map((cell) => (\n <Table.Td\n key={cell.id}\n onClick={\n onRowClick ? () => onRowClick(row.original) : undefined\n }\n style={{ flexWrap: \"nowrap\", textWrap: \"nowrap\" }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </Table.Td>\n ))}\n </Table.Tr>\n ))\n )}\n </Table.Tbody>\n </Table>\n );\n\n if (noBox) {\n return tableNode;\n } else {\n return (\n <Box\n p={noBorder ? undefined : \"lg\"}\n pt=\"0\"\n className={noBorder ? undefined : \"bordered-light\"}\n bdrs=\"md\"\n w=\"100%\"\n mah={mah}\n style={{ overflow: \"auto\" }}\n {...boxProps}\n >\n {tableNode}\n </Box>\n );\n }\n}\n\nexport const SortableHeader = <T, V>({\n column,\n title,\n description,\n sortDescFirst,\n}: {\n column: Column<T, V>;\n title: string;\n description?: ReactNode;\n sortDescFirst?: boolean;\n}) => {\n if (!column.getCanSort()) {\n return (\n <Group justify=\"start\" gap=\"xs\" wrap=\"nowrap\" miw=\"120\" w=\"fit-content\">\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {title}\n </Text>\n {description && (\n <HoverCard offset={10}>\n <HoverCard.Target>\n <Info size=\"1rem\" />\n </HoverCard.Target>\n <HoverCard.Dropdown>\n <Text>{description}</Text>\n </HoverCard.Dropdown>\n </HoverCard>\n )}\n </Group>\n );\n }\n return (\n <UnstyledButton\n onClick={column.getToggleSortingHandler()}\n style={{ width: \"100%\" }}\n >\n <Group justify=\"space-between\" gap=\"sm\" wrap=\"nowrap\">\n <Group justify=\"start\" gap=\"xs\" wrap=\"nowrap\" miw=\"120\" w=\"fit-content\">\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {title}\n </Text>\n {description && (\n <HoverCard offset={10}>\n <HoverCard.Target>\n <Info size=\"1rem\" />\n </HoverCard.Target>\n <HoverCard.Dropdown>\n <Text>{description}</Text>\n </HoverCard.Dropdown>\n </HoverCard>\n )}\n </Group>\n <Center>\n <SortIcon\n state={column.getIsSorted()}\n sortDescFirst={sortDescFirst}\n />\n </Center>\n </Group>\n </UnstyledButton>\n );\n};\n\nfunction SortIcon({\n state,\n sortDescFirst,\n}: {\n state: false | \"asc\" | \"desc\";\n sortDescFirst?: boolean;\n}) {\n if (state === \"asc\")\n return sortDescFirst ? <ArrowUp size={14} /> : <ArrowDown size={14} />;\n if (state === \"desc\")\n return sortDescFirst ? <ArrowDown size={14} /> : <ArrowUp size={14} />;\n return <Minus size={14} />;\n}\n"],"mappings":"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","names":["i"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/data-table.tsx"],"sourcesContent":["import {\n Dispatch,\n ReactNode,\n SetStateAction,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport {\n Column,\n ColumnDef,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n Row,\n RowSelectionState,\n SortingState,\n useReactTable,\n} from \"@tanstack/react-table\";\nimport {\n Box,\n BoxProps,\n Center,\n Checkbox,\n DefaultMantineColor,\n Group,\n HoverCard,\n Loader,\n Table,\n TableProps,\n Text,\n UnstyledButton,\n} from \"@mantine/core\";\nimport { ArrowDown, ArrowUp, Info, Minus } from \"lucide-react\";\n\nfunction loadStoredSorting(tableKey: string): SortingState | null {\n try {\n const stored = localStorage.getItem(\"data-table-\" + tableKey);\n return stored ? (JSON.parse(stored) as SortingState) : null;\n } catch {\n return null;\n }\n}\n\nexport interface DataTableProps<TData, TValue = unknown> extends BoxProps {\n /** Unique key given to table so sorting can be remembered on local storage */\n tableKey: string;\n columns: (ColumnDef<TData, TValue> | false | undefined)[];\n data: TData[];\n loading?: boolean;\n onRowClick?: (row: TData) => void;\n noResults?: ReactNode;\n defaultSort?: SortingState;\n sortDescFirst?: boolean;\n /** Sorting is handled externally (eg. server side).\n * The table still manages / persists the sorting state,\n * but does not apply it to the rows. */\n manualSorting?: boolean;\n /** Called with the sorting state whenever it changes.\n * Also called on mount with the initial state\n * (loaded from local storage when available). */\n onSortingStateChange?: (sorting: SortingState) => void;\n selectOptions?: {\n selectKey: (row: TData) => string;\n onSelect?: (selected: string[]) => void;\n state?: [RowSelectionState, Dispatch<SetStateAction<RowSelectionState>>];\n disableRow?: boolean | ((row: Row<TData>) => boolean);\n color?: DefaultMantineColor;\n };\n caption?: string;\n tableProps?: TableProps;\n noBox?: boolean;\n noBorder?: boolean;\n}\n\nexport function DataTable<TData, TValue>({\n tableKey,\n columns,\n data,\n loading,\n onRowClick,\n noResults = <Text c=\"dimmed\">No results</Text>,\n sortDescFirst = false,\n defaultSort = [],\n manualSorting,\n onSortingStateChange,\n selectOptions,\n caption,\n tableProps,\n noBox,\n noBorder,\n mah = \"max(150px, calc(100vh - 320px))\",\n ...boxProps\n}: DataTableProps<TData, TValue>) {\n // Initialized synchronously from local storage so the first render\n // (and any server side sorted query) already uses the persisted sort,\n // instead of flashing through the unsorted state.\n const [sorting, setSorting] = useState<SortingState>(\n () => loadStoredSorting(tableKey) ?? defaultSort,\n );\n const [prevTableKey, setPrevTableKey] = useState(tableKey);\n if (prevTableKey !== tableKey) {\n setPrevTableKey(tableKey);\n setSorting(loadStoredSorting(tableKey) ?? defaultSort);\n }\n\n // intentionally not initialized to clear selected values on table mount\n // could add some prop for adding default selected state to preserve between mounts\n const _internalState = useState<RowSelectionState>({});\n const [rowSelection, setRowSelection] = selectOptions?.state\n ? selectOptions.state\n : _internalState;\n\n const table = useReactTable({\n data,\n columns: columns.filter((c) => c) as any,\n getCoreRowModel: getCoreRowModel(),\n onSortingChange: setSorting,\n getSortedRowModel: getSortedRowModel(),\n manualSorting,\n state: {\n sorting,\n rowSelection,\n },\n sortDescFirst,\n onRowSelectionChange: setRowSelection,\n getRowId: selectOptions?.selectKey,\n enableRowSelection: selectOptions?.disableRow,\n });\n\n useEffect(() => {\n localStorage.setItem(\"data-table-\" + tableKey, JSON.stringify(sorting));\n }, [tableKey, sorting]);\n\n // Layout effect so the parent receives the initial (persisted) sorting\n // before any of its own passive effects run, ie before react-query\n // subscribes a server side sorted query using the pre-sort key.\n useLayoutEffect(() => {\n onSortingStateChange?.(sorting);\n }, [sorting]);\n\n useEffect(() => {\n selectOptions?.onSelect?.(Object.keys(rowSelection));\n }, [rowSelection]);\n\n const rows = table.getPrePaginationRowModel().rows;\n\n const tableNode = (\n <Table\n borderColor=\"accent-border\"\n captionSide=\"top\"\n stickyHeader\n {...tableProps}\n >\n {caption ? <Table.Caption>{caption}</Table.Caption> : null}\n\n <Table.Thead>\n {table.getHeaderGroups().map((hg, i) => (\n <Table.Tr key={hg.id}>\n {i === 0 && selectOptions && (\n <Table.Th\n onClick={() =>\n selectOptions.disableRow !== true &&\n table.toggleAllRowsSelected()\n }\n style={{\n cursor: \"pointer\",\n borderColor: \"var(--mantine-color-accent-border-0)\",\n borderWidth: 0,\n borderRightWidth: 1,\n borderStyle: \"solid\",\n }}\n >\n <Checkbox\n color={selectOptions.color ?? \"Neutral\"}\n disabled={selectOptions.disableRow === true}\n checked={table.getIsAllRowsSelected()}\n indeterminate={table.getIsSomeRowsSelected()}\n />\n </Table.Th>\n )}\n {hg.headers.map((header, i) => {\n // const canSort = header.column.getCanSort();\n // const sortState = header.column.getIsSorted();\n return (\n <Table.Th\n key={header.id}\n px=\"md\"\n style={{\n cursor: \"pointer\",\n borderColor: \"var(--mantine-color-accent-border-0)\",\n borderWidth: 0,\n borderRightWidth: i < hg.headers.length - 1 ? 1 : 0,\n borderStyle: \"solid\",\n }}\n >\n {header.isPlaceholder ? null : (\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </Text>\n )}\n </Table.Th>\n );\n })}\n </Table.Tr>\n ))}\n </Table.Thead>\n\n <Table.Tbody>\n {loading ? (\n <Table.Tr>\n <Table.Td\n colSpan={\n table.getAllLeafColumns().length + (selectOptions ? 1 : 0)\n }\n >\n <Group justify=\"center\" py=\"lg\">\n <Loader size=\"sm\" />\n </Group>\n </Table.Td>\n </Table.Tr>\n ) : rows.length === 0 ? (\n <Table.Tr>\n <Table.Td\n colSpan={\n table.getAllLeafColumns().length + (selectOptions ? 1 : 0)\n }\n >\n <Group justify=\"center\" py=\"lg\">\n {noResults}\n </Group>\n </Table.Td>\n </Table.Tr>\n ) : (\n rows.map((row) => (\n <Table.Tr\n key={row.id}\n style={{\n cursor: onRowClick ? \"pointer\" : undefined,\n contentVisibility: \"auto\",\n containIntrinsicSize: \"auto 2em\",\n }}\n >\n {selectOptions && (\n <Table.Td onClick={() => row.toggleSelected()}>\n <Checkbox\n aria-label=\"Select row\"\n color={selectOptions.color ?? \"Neutral\"}\n disabled={!row.getCanSelect()}\n checked={row.getIsSelected()}\n />\n </Table.Td>\n )}\n {row.getVisibleCells().map((cell) => (\n <Table.Td\n key={cell.id}\n onClick={\n onRowClick ? () => onRowClick(row.original) : undefined\n }\n style={{ flexWrap: \"nowrap\", textWrap: \"nowrap\" }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </Table.Td>\n ))}\n </Table.Tr>\n ))\n )}\n </Table.Tbody>\n </Table>\n );\n\n if (noBox) {\n return tableNode;\n } else {\n return (\n <Box\n p={noBorder ? undefined : \"lg\"}\n pt=\"0\"\n className={noBorder ? undefined : \"bordered-light\"}\n bdrs=\"md\"\n w=\"100%\"\n mah={mah}\n style={{ overflow: \"auto\" }}\n {...boxProps}\n >\n {tableNode}\n </Box>\n );\n }\n}\n\nexport const SortableHeader = <T, V>({\n column,\n title,\n description,\n sortDescFirst,\n disabled,\n}: {\n column: Column<T, V>;\n title: string;\n description?: ReactNode;\n sortDescFirst?: boolean;\n disabled?: boolean;\n}) => {\n if (disabled || !column.getCanSort()) {\n return (\n <Group justify=\"start\" gap=\"xs\" wrap=\"nowrap\" miw=\"120\" w=\"fit-content\">\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {title}\n </Text>\n {description && (\n <HoverCard offset={10}>\n <HoverCard.Target>\n <Info size=\"1rem\" />\n </HoverCard.Target>\n <HoverCard.Dropdown>\n <Text>{description}</Text>\n </HoverCard.Dropdown>\n </HoverCard>\n )}\n </Group>\n );\n }\n return (\n <UnstyledButton\n onClick={column.getToggleSortingHandler()}\n style={{ width: \"100%\" }}\n >\n <Group justify=\"space-between\" gap=\"sm\" wrap=\"nowrap\">\n <Group justify=\"start\" gap=\"xs\" wrap=\"nowrap\" miw=\"120\" w=\"fit-content\">\n <Text fw={600} size=\"sm\" lineClamp={1}>\n {title}\n </Text>\n {description && (\n <HoverCard offset={10}>\n <HoverCard.Target>\n <Info size=\"1rem\" />\n </HoverCard.Target>\n <HoverCard.Dropdown>\n <Text>{description}</Text>\n </HoverCard.Dropdown>\n </HoverCard>\n )}\n </Group>\n <Center>\n <SortIcon\n state={column.getIsSorted()}\n sortDescFirst={sortDescFirst}\n />\n </Center>\n </Group>\n </UnstyledButton>\n );\n};\n\nfunction SortIcon({\n state,\n sortDescFirst,\n}: {\n state: false | \"asc\" | \"desc\";\n sortDescFirst?: boolean;\n}) {\n if (state === \"asc\")\n return sortDescFirst ? <ArrowUp size={14} /> : <ArrowDown size={14} />;\n if (state === \"desc\")\n return sortDescFirst ? <ArrowDown size={14} /> : <ArrowUp size={14} />;\n return <Minus size={14} />;\n}\n"],"mappings":"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","names":["i"]}
|