mogh_ui 0.7.1 → 0.7.3
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 +19 -9
- package/dist/components/data-table.cjs.map +1 -1
- package/dist/components/data-table.d.cts +3 -2
- package/dist/components/data-table.d.ts +3 -2
- package/dist/components/data-table.js +20 -9
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/page-guard.d.cts +1 -1
- package/dist/components/page-guard.d.ts +1 -1
- package/package.json +2 -2
|
@@ -27,6 +27,14 @@ var import_react = require("react");
|
|
|
27
27
|
var import_react_table = require("@tanstack/react-table");
|
|
28
28
|
var import_core = require("@mantine/core");
|
|
29
29
|
var import_lucide_react = require("lucide-react");
|
|
30
|
+
function loadStoredSorting(tableKey) {
|
|
31
|
+
try {
|
|
32
|
+
const stored = localStorage.getItem("data-table-" + tableKey);
|
|
33
|
+
return stored ? JSON.parse(stored) : null;
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
30
38
|
function DataTable({
|
|
31
39
|
tableKey,
|
|
32
40
|
columns,
|
|
@@ -46,7 +54,14 @@ function DataTable({
|
|
|
46
54
|
mah = "max(150px, calc(100vh - 320px))",
|
|
47
55
|
...boxProps
|
|
48
56
|
}) {
|
|
49
|
-
const [sorting, setSorting] = (0, import_react.useState)(
|
|
57
|
+
const [sorting, setSorting] = (0, import_react.useState)(
|
|
58
|
+
() => loadStoredSorting(tableKey) ?? defaultSort
|
|
59
|
+
);
|
|
60
|
+
const [prevTableKey, setPrevTableKey] = (0, import_react.useState)(tableKey);
|
|
61
|
+
if (prevTableKey !== tableKey) {
|
|
62
|
+
setPrevTableKey(tableKey);
|
|
63
|
+
setSorting(loadStoredSorting(tableKey) ?? defaultSort);
|
|
64
|
+
}
|
|
50
65
|
const _internalState = (0, import_react.useState)({});
|
|
51
66
|
const [rowSelection, setRowSelection] = selectOptions?.state ? selectOptions.state : _internalState;
|
|
52
67
|
const table = (0, import_react_table.useReactTable)({
|
|
@@ -65,15 +80,10 @@ function DataTable({
|
|
|
65
80
|
getRowId: selectOptions?.selectKey,
|
|
66
81
|
enableRowSelection: selectOptions?.disableRow
|
|
67
82
|
});
|
|
68
|
-
(0, import_react.useEffect)(() => {
|
|
69
|
-
const stored = localStorage.getItem("data-table-" + tableKey);
|
|
70
|
-
const sorting2 = stored ? JSON.parse(stored) : null;
|
|
71
|
-
if (sorting2) setSorting(sorting2);
|
|
72
|
-
}, [tableKey]);
|
|
73
83
|
(0, import_react.useEffect)(() => {
|
|
74
84
|
localStorage.setItem("data-table-" + tableKey, JSON.stringify(sorting));
|
|
75
85
|
}, [tableKey, sorting]);
|
|
76
|
-
(0, import_react.
|
|
86
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
77
87
|
onSortingStateChange?.(sorting);
|
|
78
88
|
}, [sorting]);
|
|
79
89
|
(0, import_react.useEffect)(() => {
|
|
@@ -242,9 +252,9 @@ function SortIcon({
|
|
|
242
252
|
sortDescFirst
|
|
243
253
|
}) {
|
|
244
254
|
if (state === "asc")
|
|
245
|
-
return sortDescFirst ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowDown, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowUp, { size: 14 });
|
|
246
|
-
if (state === "desc")
|
|
247
255
|
return sortDescFirst ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowUp, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowDown, { size: 14 });
|
|
256
|
+
if (state === "desc")
|
|
257
|
+
return sortDescFirst ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowDown, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowUp, { size: 14 });
|
|
248
258
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Minus, { size: 14 });
|
|
249
259
|
}
|
|
250
260
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/data-table.tsx"],"sourcesContent":["import {\n Dispatch,\n ReactNode,\n SetStateAction,\n useEffect,\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\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 * including on load from local storage. */\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 const [sorting, setSorting] = useState<SortingState>(defaultSort);\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 const stored = localStorage.getItem(\"data-table-\" + tableKey);\n const sorting = stored ? (JSON.parse(stored) as SortingState) : null;\n if (sorting) setSorting(sorting);\n }, [tableKey]);\n\n useEffect(() => {\n localStorage.setItem(\"data-table-\" + tableKey, JSON.stringify(sorting));\n }, [tableKey, sorting]);\n\n useEffect(() => {\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 ? <ArrowDown size={14} /> : <ArrowUp size={14} />;\n if (state === \"desc\")\n return sortDescFirst ? <ArrowUp size={14} /> : <ArrowDown size={14} />;\n return <Minus size={14} />;\n}\n"],"mappings":"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","names":["sorting","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}: {\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"]}
|
|
@@ -17,8 +17,9 @@ interface DataTableProps<TData, TValue = unknown> extends BoxProps {
|
|
|
17
17
|
* The table still manages / persists the sorting state,
|
|
18
18
|
* but does not apply it to the rows. */
|
|
19
19
|
manualSorting?: boolean;
|
|
20
|
-
/** Called with the sorting state whenever it changes
|
|
21
|
-
*
|
|
20
|
+
/** Called with the sorting state whenever it changes.
|
|
21
|
+
* Also called on mount with the initial state
|
|
22
|
+
* (loaded from local storage when available). */
|
|
22
23
|
onSortingStateChange?: (sorting: SortingState) => void;
|
|
23
24
|
selectOptions?: {
|
|
24
25
|
selectKey: (row: TData) => string;
|
|
@@ -17,8 +17,9 @@ interface DataTableProps<TData, TValue = unknown> extends BoxProps {
|
|
|
17
17
|
* The table still manages / persists the sorting state,
|
|
18
18
|
* but does not apply it to the rows. */
|
|
19
19
|
manualSorting?: boolean;
|
|
20
|
-
/** Called with the sorting state whenever it changes
|
|
21
|
-
*
|
|
20
|
+
/** Called with the sorting state whenever it changes.
|
|
21
|
+
* Also called on mount with the initial state
|
|
22
|
+
* (loaded from local storage when available). */
|
|
22
23
|
onSortingStateChange?: (sorting: SortingState) => void;
|
|
23
24
|
selectOptions?: {
|
|
24
25
|
selectKey: (row: TData) => string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import {
|
|
3
3
|
useEffect,
|
|
4
|
+
useLayoutEffect,
|
|
4
5
|
useState
|
|
5
6
|
} from "react";
|
|
6
7
|
import {
|
|
@@ -21,6 +22,14 @@ import {
|
|
|
21
22
|
UnstyledButton
|
|
22
23
|
} from "@mantine/core";
|
|
23
24
|
import { ArrowDown, ArrowUp, Info, Minus } from "lucide-react";
|
|
25
|
+
function loadStoredSorting(tableKey) {
|
|
26
|
+
try {
|
|
27
|
+
const stored = localStorage.getItem("data-table-" + tableKey);
|
|
28
|
+
return stored ? JSON.parse(stored) : null;
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
24
33
|
function DataTable({
|
|
25
34
|
tableKey,
|
|
26
35
|
columns,
|
|
@@ -40,7 +49,14 @@ function DataTable({
|
|
|
40
49
|
mah = "max(150px, calc(100vh - 320px))",
|
|
41
50
|
...boxProps
|
|
42
51
|
}) {
|
|
43
|
-
const [sorting, setSorting] = useState(
|
|
52
|
+
const [sorting, setSorting] = useState(
|
|
53
|
+
() => loadStoredSorting(tableKey) ?? defaultSort
|
|
54
|
+
);
|
|
55
|
+
const [prevTableKey, setPrevTableKey] = useState(tableKey);
|
|
56
|
+
if (prevTableKey !== tableKey) {
|
|
57
|
+
setPrevTableKey(tableKey);
|
|
58
|
+
setSorting(loadStoredSorting(tableKey) ?? defaultSort);
|
|
59
|
+
}
|
|
44
60
|
const _internalState = useState({});
|
|
45
61
|
const [rowSelection, setRowSelection] = selectOptions?.state ? selectOptions.state : _internalState;
|
|
46
62
|
const table = useReactTable({
|
|
@@ -59,15 +75,10 @@ function DataTable({
|
|
|
59
75
|
getRowId: selectOptions?.selectKey,
|
|
60
76
|
enableRowSelection: selectOptions?.disableRow
|
|
61
77
|
});
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
const stored = localStorage.getItem("data-table-" + tableKey);
|
|
64
|
-
const sorting2 = stored ? JSON.parse(stored) : null;
|
|
65
|
-
if (sorting2) setSorting(sorting2);
|
|
66
|
-
}, [tableKey]);
|
|
67
78
|
useEffect(() => {
|
|
68
79
|
localStorage.setItem("data-table-" + tableKey, JSON.stringify(sorting));
|
|
69
80
|
}, [tableKey, sorting]);
|
|
70
|
-
|
|
81
|
+
useLayoutEffect(() => {
|
|
71
82
|
onSortingStateChange?.(sorting);
|
|
72
83
|
}, [sorting]);
|
|
73
84
|
useEffect(() => {
|
|
@@ -236,9 +247,9 @@ function SortIcon({
|
|
|
236
247
|
sortDescFirst
|
|
237
248
|
}) {
|
|
238
249
|
if (state === "asc")
|
|
239
|
-
return sortDescFirst ? /* @__PURE__ */ jsx(ArrowDown, { size: 14 }) : /* @__PURE__ */ jsx(ArrowUp, { size: 14 });
|
|
240
|
-
if (state === "desc")
|
|
241
250
|
return sortDescFirst ? /* @__PURE__ */ jsx(ArrowUp, { size: 14 }) : /* @__PURE__ */ jsx(ArrowDown, { size: 14 });
|
|
251
|
+
if (state === "desc")
|
|
252
|
+
return sortDescFirst ? /* @__PURE__ */ jsx(ArrowDown, { size: 14 }) : /* @__PURE__ */ jsx(ArrowUp, { size: 14 });
|
|
242
253
|
return /* @__PURE__ */ jsx(Minus, { size: 14 });
|
|
243
254
|
}
|
|
244
255
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/data-table.tsx"],"sourcesContent":["import {\n Dispatch,\n ReactNode,\n SetStateAction,\n useEffect,\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\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 * including on load from local storage. */\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 const [sorting, setSorting] = useState<SortingState>(defaultSort);\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 const stored = localStorage.getItem(\"data-table-\" + tableKey);\n const sorting = stored ? (JSON.parse(stored) as SortingState) : null;\n if (sorting) setSorting(sorting);\n }, [tableKey]);\n\n useEffect(() => {\n localStorage.setItem(\"data-table-\" + tableKey, JSON.stringify(sorting));\n }, [tableKey, sorting]);\n\n useEffect(() => {\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 ? <ArrowDown size={14} /> : <ArrowUp size={14} />;\n if (state === \"desc\")\n return sortDescFirst ? <ArrowUp size={14} /> : <ArrowDown size={14} />;\n return <Minus size={14} />;\n}\n"],"mappings":"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","names":["sorting","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}: {\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"]}
|
|
@@ -7,6 +7,6 @@ interface PageGuardProps extends CenterProps {
|
|
|
7
7
|
error?: false | string;
|
|
8
8
|
children?: ReactNode;
|
|
9
9
|
}
|
|
10
|
-
declare function PageGuard({ isPending, error, children, ...centerProps }: PageGuardProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> |
|
|
10
|
+
declare function PageGuard({ isPending, error, children, ...centerProps }: PageGuardProps): string | number | bigint | boolean | react.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
11
11
|
|
|
12
12
|
export { PageGuard, type PageGuardProps };
|
|
@@ -7,6 +7,6 @@ interface PageGuardProps extends CenterProps {
|
|
|
7
7
|
error?: false | string;
|
|
8
8
|
children?: ReactNode;
|
|
9
9
|
}
|
|
10
|
-
declare function PageGuard({ isPending, error, children, ...centerProps }: PageGuardProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> |
|
|
10
|
+
declare function PageGuard({ isPending, error, children, ...centerProps }: PageGuardProps): string | number | bigint | boolean | react.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
11
11
|
|
|
12
12
|
export { PageGuard, type PageGuardProps };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mogh_ui",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "Common UI components and styling used across Mogh apps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -62,6 +62,6 @@
|
|
|
62
62
|
"react-dom": "^19.2.7",
|
|
63
63
|
"react-router-dom": "^7.18.1",
|
|
64
64
|
"tsup": "^8.5.1",
|
|
65
|
-
"typescript": "^
|
|
65
|
+
"typescript": "^7.0.2"
|
|
66
66
|
}
|
|
67
67
|
}
|