@rsc-kit/press 0.30.50 → 0.30.52
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/README.md +3 -2
- package/dist/admin/actions.js +6 -3
- package/dist/admin/actions.js.map +1 -1
- package/dist/admin/panel.js +28 -9
- package/dist/admin/panel.js.map +1 -1
- package/dist/admin/theme.d.ts +10 -1
- package/dist/admin/theme.js.map +1 -1
- package/dist/admin/url.d.ts +12 -0
- package/dist/admin/url.js +18 -0
- package/dist/admin/url.js.map +1 -1
- package/dist/conditions.d.ts +32 -0
- package/dist/conditions.js +25 -0
- package/dist/conditions.js.map +1 -0
- package/dist/forms/actions.d.ts +6 -5
- package/dist/forms/actions.js +13 -8
- package/dist/forms/actions.js.map +1 -1
- package/dist/forms/blueprint.d.ts +99 -0
- package/dist/forms/blueprint.js +141 -0
- package/dist/forms/blueprint.js.map +1 -0
- package/dist/forms/brand.d.ts +26 -0
- package/dist/forms/brand.js +9 -0
- package/dist/forms/brand.js.map +1 -0
- package/dist/forms/host.d.ts +12 -2
- package/dist/forms/host.js +16 -6
- package/dist/forms/host.js.map +1 -1
- package/dist/forms/index.d.ts +3 -3
- package/dist/forms/index.js +1 -1
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/registry.d.ts +6 -1
- package/dist/forms/registry.js +1 -1
- package/dist/forms/registry.js.map +1 -1
- package/dist/forms/theme.d.ts +10 -7
- package/dist/forms/theme.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/installable.js +8 -3
- package/dist/installable.js.map +1 -1
- package/dist/resource.d.ts +77 -6
- package/dist/resource.js +137 -18
- package/dist/resource.js.map +1 -1
- package/dist/shadcn/blueprint-form.d.ts +8 -0
- package/dist/shadcn/{public-form.js → blueprint-form.js} +7 -6
- package/dist/shadcn/blueprint-form.js.map +1 -0
- package/dist/shadcn/data-table.d.ts +1 -1
- package/dist/shadcn/data-table.js +5 -4
- package/dist/shadcn/data-table.js.map +1 -1
- package/dist/shadcn/fields.d.ts +11 -1
- package/dist/shadcn/fields.js +72 -10
- package/dist/shadcn/fields.js.map +1 -1
- package/dist/shadcn/index.d.ts +1 -1
- package/dist/shadcn/index.js +3 -3
- package/dist/shadcn/index.js.map +1 -1
- package/dist/shadcn/resource-form.js +3 -2
- package/dist/shadcn/resource-form.js.map +1 -1
- package/package.json +2 -2
- package/dist/forms/form.d.ts +0 -61
- package/dist/forms/form.js +0 -66
- package/dist/forms/form.js.map +0 -1
- package/dist/shadcn/public-form.d.ts +0 -8
- package/dist/shadcn/public-form.js.map +0 -1
|
@@ -30,7 +30,7 @@ const ALL = '__all__';
|
|
|
30
30
|
* client every row arrived at once; search, filters, sort and the pager
|
|
31
31
|
* happen here, with no request.
|
|
32
32
|
*/
|
|
33
|
-
export function DataTable({ mode, href, columns, rows, total, perPage, query, filters, noun, bulk, }) {
|
|
33
|
+
export function DataTable({ mode, href, columns, rows, total, cursors, perPage, query, filters, noun, bulk, }) {
|
|
34
34
|
const server = mode === 'server';
|
|
35
35
|
const [q, setQ] = useState(query.q);
|
|
36
36
|
const [chosen, setChosen] = useState(query.filters);
|
|
@@ -98,7 +98,7 @@ export function DataTable({ mode, href, columns, rows, total, perPage, query, fi
|
|
|
98
98
|
getRowId: (row) => row.id,
|
|
99
99
|
manualSorting: server,
|
|
100
100
|
manualPagination: server,
|
|
101
|
-
...(server ? { pageCount: Math.max(1, Math.ceil(total / perPage)) } : {}),
|
|
101
|
+
...(server ? { pageCount: Math.max(1, Math.ceil((total ?? 0) / perPage)) } : {}),
|
|
102
102
|
onSortingChange: setSorting,
|
|
103
103
|
onPaginationChange: setPagination,
|
|
104
104
|
onColumnVisibilityChange: setColumnVisibility,
|
|
@@ -120,8 +120,9 @@ export function DataTable({ mode, href, columns, rows, total, perPage, query, fi
|
|
|
120
120
|
});
|
|
121
121
|
const searchable = columns.some((column) => column.searchable);
|
|
122
122
|
const hasActions = rows.some((row) => row.edit || row.remove);
|
|
123
|
-
const pageCount = server ? Math.max(1, Math.ceil(total / perPage)) : Math.max(1, table.getPageCount());
|
|
123
|
+
const pageCount = server ? Math.max(1, Math.ceil((total ?? 0) / perPage)) : Math.max(1, table.getPageCount());
|
|
124
124
|
const page = server ? query.page : pagination.pageIndex + 1;
|
|
125
|
+
// A list paged by cursor may not be counted: then it says nothing of how many.
|
|
125
126
|
const count = server ? total : visible.length;
|
|
126
127
|
return (_jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [searchable && (_jsxs("form", { action: href, method: "get", className: "relative w-full sm:max-w-xs", onSubmit: (event) => {
|
|
127
128
|
event.preventDefault();
|
|
@@ -148,7 +149,7 @@ export function DataTable({ mode, href, columns, rows, total, perPage, query, fi
|
|
|
148
149
|
const sorted = server ? (query.sort === column.id ? query.dir : false) : column.getIsSorted();
|
|
149
150
|
const Arrow = sorted === 'asc' ? ArrowUp : sorted === 'desc' ? ArrowDown : ArrowUpDown;
|
|
150
151
|
return (_jsx(TableHead, { "aria-sort": sorted === 'asc' ? 'ascending' : sorted === 'desc' ? 'descending' : undefined, children: !column.getCanSort() ? (label) : server ? (_jsxs(Button, { variant: "ghost", size: "sm", className: "-ml-2.5 h-8", nativeButton: false, render: _jsx(Link, { href: urlFor({ sort: column.id, dir: sorted === 'asc' ? 'desc' : 'asc', page: 1 }), replace: true }), children: [label, _jsx(Arrow, { className: sorted ? undefined : 'text-muted-foreground/60' })] })) : (_jsxs(Button, { variant: "ghost", size: "sm", className: "-ml-2.5 h-8", onClick: () => column.toggleSorting(sorted === 'asc'), children: [label, _jsx(Arrow, { className: sorted ? undefined : 'text-muted-foreground/60' })] })) }, header.id));
|
|
151
|
-
}), hasActions && (_jsx(TableHead, { className: "w-12", children: _jsx("span", { className: "sr-only", children: "Actions" }) }))] }, group.id))) }), _jsx(TableBody, { children: table.getRowModel().rows.length ? (table.getRowModel().rows.map((row) => (_jsxs(TableRow, { "data-state": selected.has(row.id) ? 'selected' : undefined, children: [bulk && (_jsx(TableCell, { children: _jsx(Checkbox, { "aria-label": "Select row", checked: selected.has(row.id), onCheckedChange: (on) => tick([row.id], on) }) })), row.getVisibleCells().map((cell) => (_jsx(TableCell, { children: _jsx(table.FlexRender, { cell: cell }) }, cell.id))), hasActions && (_jsx(TableCell, { className: "text-right", children: _jsx(RowActions, { row: row.original, onDelete: () => setConfirming({ row: row.original }) }) }))] }, row.id)))) : (_jsx(TableRow, { children: _jsxs(TableCell, { colSpan: columns.length + (hasActions ? 1 : 0) + (bulk ? 1 : 0), className: "h-24 text-center text-muted-foreground", children: ["No ", noun.many.toLowerCase(), " found."] }) })) })] }) }), _jsxs("div", { className: "flex items-center justify-between gap-2", children: [bulk && ticked.length > 0 ? (_jsxs("div", { role: "toolbar", "aria-label": "Selected rows", className: "flex flex-wrap items-center gap-2", children: [_jsxs("span", { className: "text-sm font-medium", children: [ticked.length, " selected"] }), bulk.actions.map((action) => (_jsxs(Button, { size: "sm", variant: action.destructive ? 'destructive' : 'outline', disabled: running, onClick: () => (action.destructive ? setConfirming({ action, ids: ticked }) : runBulk(action, ticked)), children: [action.name === 'delete' && _jsx(Trash2, {}), action.label] }, action.name))), _jsx(Button, { size: "icon-sm", variant: "ghost", "aria-label": "Clear selection", disabled: running, onClick: () => setSelected(new Set()), children: _jsx(X, {}) })] })) : (_jsxs("p", { className: "text-sm text-muted-foreground", children: [count, " ", count === 1 ? noun.one.toLowerCase() : noun.many.toLowerCase()] })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "text-sm text-muted-foreground", children: ["Page ", page, " of ", pageCount] }), server ? (_jsxs(_Fragment, { children: [_jsx(Pager, { to: page > 1 ? urlFor({ page: page - 1 }) : null, label: "Previous page", children: _jsx(ChevronLeft, {}) }), _jsx(Pager, { to: page < pageCount ? urlFor({ page: page + 1 }) : null, label: "Next page", children: _jsx(ChevronRight, {}) })] })) : (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "outline", size: "icon-sm", "aria-label": "Previous page", disabled: !table.getCanPreviousPage(), onClick: () => table.previousPage(), children: _jsx(ChevronLeft, {}) }), _jsx(Button, { variant: "outline", size: "icon-sm", "aria-label": "Next page", disabled: !table.getCanNextPage(), onClick: () => table.nextPage(), children: _jsx(ChevronRight, {}) })] }))] })] }), _jsx(AlertDialog, { open: confirming !== null, onOpenChange: (open) => !open && !deleting && !running && setConfirming(null), children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: confirmTitle(confirming, noun) }), _jsx(AlertDialogDescription, { children: confirmDescription(confirming) })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: deleting || running, children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", disabled: deleting || running, onClick: () => {
|
|
152
|
+
}), hasActions && (_jsx(TableHead, { className: "w-12", children: _jsx("span", { className: "sr-only", children: "Actions" }) }))] }, group.id))) }), _jsx(TableBody, { children: table.getRowModel().rows.length ? (table.getRowModel().rows.map((row) => (_jsxs(TableRow, { "data-state": selected.has(row.id) ? 'selected' : undefined, children: [bulk && (_jsx(TableCell, { children: _jsx(Checkbox, { "aria-label": "Select row", checked: selected.has(row.id), onCheckedChange: (on) => tick([row.id], on) }) })), row.getVisibleCells().map((cell) => (_jsx(TableCell, { children: _jsx(table.FlexRender, { cell: cell }) }, cell.id))), hasActions && (_jsx(TableCell, { className: "text-right", children: _jsx(RowActions, { row: row.original, onDelete: () => setConfirming({ row: row.original }) }) }))] }, row.id)))) : (_jsx(TableRow, { children: _jsxs(TableCell, { colSpan: columns.length + (hasActions ? 1 : 0) + (bulk ? 1 : 0), className: "h-24 text-center text-muted-foreground", children: ["No ", noun.many.toLowerCase(), " found."] }) })) })] }) }), _jsxs("div", { className: "flex items-center justify-between gap-2", children: [bulk && ticked.length > 0 ? (_jsxs("div", { role: "toolbar", "aria-label": "Selected rows", className: "flex flex-wrap items-center gap-2", children: [_jsxs("span", { className: "text-sm font-medium", children: [ticked.length, " selected"] }), bulk.actions.map((action) => (_jsxs(Button, { size: "sm", variant: action.destructive ? 'destructive' : 'outline', disabled: running, onClick: () => (action.destructive ? setConfirming({ action, ids: ticked }) : runBulk(action, ticked)), children: [action.name === 'delete' && _jsx(Trash2, {}), action.label] }, action.name))), _jsx(Button, { size: "icon-sm", variant: "ghost", "aria-label": "Clear selection", disabled: running, onClick: () => setSelected(new Set()), children: _jsx(X, {}) })] })) : count === null ? (_jsx("span", {})) : (_jsxs("p", { className: "text-sm text-muted-foreground", children: [count, " ", count === 1 ? noun.one.toLowerCase() : noun.many.toLowerCase()] })), _jsxs("div", { className: "flex items-center gap-2", children: [!cursors && (_jsxs("span", { className: "text-sm text-muted-foreground", children: ["Page ", page, " of ", pageCount] })), server && cursors ? (_jsxs(_Fragment, { children: [_jsx(Pager, { to: cursors.prev, label: "Previous page", children: _jsx(ChevronLeft, {}) }), _jsx(Pager, { to: cursors.next, label: "Next page", children: _jsx(ChevronRight, {}) })] })) : server ? (_jsxs(_Fragment, { children: [_jsx(Pager, { to: page > 1 ? urlFor({ page: page - 1 }) : null, label: "Previous page", children: _jsx(ChevronLeft, {}) }), _jsx(Pager, { to: page < pageCount ? urlFor({ page: page + 1 }) : null, label: "Next page", children: _jsx(ChevronRight, {}) })] })) : (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "outline", size: "icon-sm", "aria-label": "Previous page", disabled: !table.getCanPreviousPage(), onClick: () => table.previousPage(), children: _jsx(ChevronLeft, {}) }), _jsx(Button, { variant: "outline", size: "icon-sm", "aria-label": "Next page", disabled: !table.getCanNextPage(), onClick: () => table.nextPage(), children: _jsx(ChevronRight, {}) })] }))] })] }), _jsx(AlertDialog, { open: confirming !== null, onOpenChange: (open) => !open && !deleting && !running && setConfirming(null), children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: confirmTitle(confirming, noun) }), _jsx(AlertDialogDescription, { children: confirmDescription(confirming) })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: deleting || running, children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", disabled: deleting || running, onClick: () => {
|
|
152
153
|
if (confirming && 'ids' in confirming)
|
|
153
154
|
return runBulk(confirming.action, confirming.ids);
|
|
154
155
|
startDelete(async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table.js","sourceRoot":"","sources":["../../src/shadcn/data-table.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { useEffect, useMemo, useRef, useState, useTransition } from 'react'\nimport type { ReactNode } from 'react'\nimport {\n type ColumnDef,\n type ColumnVisibilityState,\n type PaginationState,\n type SortingState,\n columnVisibilityFeature,\n createPaginatedRowModel,\n createSortedRowModel,\n rowPaginationFeature,\n rowSortingFeature,\n tableFeatures,\n useTable,\n} from '@tanstack/react-table'\nimport Link from '@rsc-kit/core/Link'\nimport { visit } from '@rsc-kit/core/router'\nimport { ArrowDown, ArrowUp, ArrowUpDown, ChevronLeft, ChevronRight, Columns3, MoreHorizontal, Pencil, Search, Trash2, X } from 'lucide-react'\nimport type { TableBulkAction, TableProps, TableQuery, TableRowData } from '../admin/theme.js'\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from './components/ui/alert-dialog.js'\nimport { Button } from './components/ui/button.js'\nimport { Checkbox } from './components/ui/checkbox.js'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from './components/ui/dropdown-menu.js'\nimport { Input } from './components/ui/input.js'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './components/ui/select.js'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './components/ui/table.js'\n\n/** What is asked before it happens: one row's delete, or an action over the ticked rows. */\ntype Confirming = { row: TableRowData } | { action: TableBulkAction; ids: string[] }\n\nconst features = tableFeatures({\n rowSortingFeature,\n rowPaginationFeature,\n columnVisibilityFeature,\n sortedRowModel: createSortedRowModel(),\n paginatedRowModel: createPaginatedRowModel(),\n})\n\ntype Features = typeof features\n\nconst ALL = '__all__'\n\n/**\n * Every resource's table. One component for both modes, so a table looks and\n * behaves the same wherever its rows are searched:\n *\n * server the url is the state. Typing, a filter, a header and the pager\n * each visit a url, the page asks the source for one page, and a\n * link works with no javascript and can be shared.\n * client every row arrived at once; search, filters, sort and the pager\n * happen here, with no request.\n */\nexport function DataTable({\n mode,\n href,\n columns,\n rows,\n total,\n perPage,\n query,\n filters,\n noun,\n bulk,\n}: TableProps) {\n const server = mode === 'server'\n const [q, setQ] = useState(query.q)\n const [chosen, setChosen] = useState<Record<string, string>>(query.filters)\n const [sorting, setSorting] = useState<SortingState>(query.sort ? [{ id: query.sort, desc: query.dir === 'desc' }] : [])\n const [columnVisibility, setColumnVisibility] = useState<ColumnVisibilityState>(() =>\n Object.fromEntries(columns.filter((column) => !column.visible).map((column) => [column.key, false])),\n )\n const [pagination, setPagination] = useState<PaginationState>({ pageIndex: server ? query.page - 1 : 0, pageSize: perPage })\n const [confirming, setConfirming] = useState<Confirming | null>(null)\n const [deleting, startDelete] = useTransition()\n const [selected, setSelected] = useState<ReadonlySet<string>>(() => new Set())\n const [running, startRun] = useTransition()\n\n // New rows - another page, a search, the table after an action - start\n // with nothing ticked: a selection is of rows the visitor can see.\n useEffect(() => setSelected(new Set()), [rows])\n const [, startVisit] = useTransition()\n\n // Server mode: the url this state names. Empty values are left out, so a\n // cleared search is the plain list url and not ?q=.\n const urlFor = (changes: Partial<Omit<TableQuery, 'filters'>> & { filters?: Record<string, string> }) => {\n const next = { ...query, q, filters: chosen, ...changes }\n const search = new URLSearchParams()\n\n if (next.q) search.set('q', next.q)\n if (next.sort) search.set('sort', next.sort)\n if (next.sort && next.dir === 'desc') search.set('dir', 'desc')\n if (next.page > 1) search.set('page', String(next.page))\n for (const [key, value] of Object.entries(next.filters)) if (value) search.set(key, value)\n\n const qs = search.toString()\n\n return qs ? `${href}?${qs}` : href\n }\n\n const go = (url: string) => startVisit(() => void visit(url as never, { replace: true }))\n\n // Typing searches after a pause, not per keystroke; the page resets to the first.\n const typed = useRef(false)\n\n useEffect(() => {\n if (!server || !typed.current) return\n\n const timer = setTimeout(() => go(urlFor({ q, page: 1 })), 300)\n\n return () => clearTimeout(timer)\n }, [q])\n\n // Client mode: search and filters here, before the table sorts and pages.\n const visible = useMemo(() => {\n if (server) return rows\n\n const needle = q.trim().toLowerCase()\n const searchable = columns.filter((column) => column.searchable).map((column) => column.key)\n\n return rows.filter(\n (row) =>\n Object.entries(chosen).every(([key, value]) => !value || String(row.values[key]) === value) &&\n (!needle || searchable.some((key) => String(row.values[key] ?? '').toLowerCase().includes(needle))),\n )\n }, [server, rows, q, chosen, columns])\n\n const columnDefs = useMemo<ColumnDef<Features, TableRowData>[]>(\n () =>\n columns.map((column) => ({\n id: column.key,\n accessorFn: (row: TableRowData) => row.values[column.key],\n header: column.label,\n cell: ({ row }: { row: { original: TableRowData } }) => row.original.cells[column.key],\n enableSorting: column.sortable,\n enableHiding: true,\n sortFn: (a, b, id) => compare(a.getValue(id), b.getValue(id)),\n })) as ColumnDef<Features, TableRowData>[],\n [columns],\n )\n\n const table = useTable({\n features,\n data: visible,\n columns: columnDefs,\n getRowId: (row: TableRowData) => row.id,\n manualSorting: server,\n manualPagination: server,\n ...(server ? { pageCount: Math.max(1, Math.ceil(total / perPage)) } : {}),\n onSortingChange: setSorting,\n onPaginationChange: setPagination,\n onColumnVisibilityChange: setColumnVisibility,\n state: { sorting, pagination, columnVisibility },\n })\n\n const onPage = table.getRowModel().rows.map((row) => row.id)\n const ticked = onPage.filter((id) => selected.has(id))\n const allTicked = onPage.length > 0 && ticked.length === onPage.length\n\n const tick = (ids: string[], on: boolean) =>\n setSelected((current) => {\n const next = new Set(current)\n\n for (const id of ids) on ? next.add(id) : next.delete(id)\n\n return next\n })\n\n const runBulk = (action: TableBulkAction, ids: string[]) =>\n startRun(async () => {\n await bulk?.run(action.name, ids)\n setSelected(new Set())\n setConfirming(null)\n })\n\n const searchable = columns.some((column) => column.searchable)\n const hasActions = rows.some((row) => row.edit || row.remove)\n const pageCount = server ? Math.max(1, Math.ceil(total / perPage)) : Math.max(1, table.getPageCount())\n const page = server ? query.page : pagination.pageIndex + 1\n const count = server ? total : visible.length\n\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex flex-wrap items-center gap-2\">\n {searchable && (\n // A form, so Enter searches and a server-mode search works before\n // the page has javascript: it is a GET of the list url.\n <form\n action={href}\n method=\"get\"\n className=\"relative w-full sm:max-w-xs\"\n onSubmit={(event) => {\n event.preventDefault()\n if (server) go(urlFor({ q, page: 1 }))\n }}\n >\n <Search className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n name=\"q\"\n type=\"search\"\n placeholder={`Search ${noun.many.toLowerCase()}…`}\n aria-label={`Search ${noun.many.toLowerCase()}`}\n className=\"pl-8\"\n value={q}\n onChange={(event) => {\n typed.current = true\n setQ(event.target.value)\n if (!server) table.setPageIndex(0)\n }}\n />\n </form>\n )}\n {filters.map((filter) => (\n <Select\n key={filter.key}\n items={[{ value: ALL, label: `All ${filter.label.toLowerCase()}` }, ...filter.options]}\n value={chosen[filter.key] || ALL}\n onValueChange={(value) => {\n const next = { ...chosen, [filter.key]: value === ALL || value === null ? '' : String(value) }\n\n setChosen(next)\n if (server) go(urlFor({ filters: next, page: 1 }))\n else table.setPageIndex(0)\n }}\n >\n <SelectTrigger aria-label={filter.label} className=\"w-full sm:w-44\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All {filter.label.toLowerCase()}</SelectItem>\n {filter.options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ))}\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"outline\" className=\"ml-auto\" />}>\n <Columns3 />\n <span className=\"hidden sm:inline\">Columns</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-44\">\n <DropdownMenuGroup>\n <DropdownMenuLabel>Show columns</DropdownMenuLabel>\n {table\n .getAllColumns()\n .filter((column) => column.getCanHide())\n .map((column) => (\n <DropdownMenuCheckboxItem\n key={column.id}\n checked={column.getIsVisible()}\n onCheckedChange={(value) => column.toggleVisibility(!!value)}\n >\n {columns.find((candidate) => candidate.key === column.id)?.label}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n <div className=\"overflow-hidden rounded-lg border\">\n <Table>\n <TableHeader className=\"bg-muted/50\">\n {table.getHeaderGroups().map((group) => (\n <TableRow key={group.id}>\n {bulk && (\n <TableHead className=\"w-10\">\n <Checkbox\n aria-label={`Select every ${noun.one.toLowerCase()} on this page`}\n checked={allTicked}\n indeterminate={ticked.length > 0 && !allTicked}\n disabled={onPage.length === 0}\n onCheckedChange={() => tick(onPage, !allTicked)}\n />\n </TableHead>\n )}\n {group.headers.map((header) => {\n const column = header.column\n const label = columns.find((candidate) => candidate.key === column.id)?.label\n const sorted = server ? (query.sort === column.id ? query.dir : false) : column.getIsSorted()\n const Arrow = sorted === 'asc' ? ArrowUp : sorted === 'desc' ? ArrowDown : ArrowUpDown\n\n return (\n <TableHead key={header.id} aria-sort={sorted === 'asc' ? 'ascending' : sorted === 'desc' ? 'descending' : undefined}>\n {!column.getCanSort() ? (\n label\n ) : server ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"-ml-2.5 h-8\"\n nativeButton={false}\n render={<Link href={urlFor({ sort: column.id, dir: sorted === 'asc' ? 'desc' : 'asc', page: 1 }) as never} replace />}\n >\n {label}\n <Arrow className={sorted ? undefined : 'text-muted-foreground/60'} />\n </Button>\n ) : (\n <Button variant=\"ghost\" size=\"sm\" className=\"-ml-2.5 h-8\" onClick={() => column.toggleSorting(sorted === 'asc')}>\n {label}\n <Arrow className={sorted ? undefined : 'text-muted-foreground/60'} />\n </Button>\n )}\n </TableHead>\n )\n })}\n {hasActions && (\n <TableHead className=\"w-12\">\n <span className=\"sr-only\">Actions</span>\n </TableHead>\n )}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {table.getRowModel().rows.length ? (\n table.getRowModel().rows.map((row) => (\n <TableRow key={row.id} data-state={selected.has(row.id) ? 'selected' : undefined}>\n {bulk && (\n <TableCell>\n <Checkbox aria-label=\"Select row\" checked={selected.has(row.id)} onCheckedChange={(on) => tick([row.id], on)} />\n </TableCell>\n )}\n {row.getVisibleCells().map((cell) => (\n <TableCell key={cell.id}>\n <table.FlexRender cell={cell} />\n </TableCell>\n ))}\n {hasActions && (\n <TableCell className=\"text-right\">\n <RowActions row={row.original} onDelete={() => setConfirming({ row: row.original })} />\n </TableCell>\n )}\n </TableRow>\n ))\n ) : (\n <TableRow>\n <TableCell colSpan={columns.length + (hasActions ? 1 : 0) + (bulk ? 1 : 0)} className=\"h-24 text-center text-muted-foreground\">\n No {noun.many.toLowerCase()} found.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n\n <div className=\"flex items-center justify-between gap-2\">\n {/* The ticked rows' actions take the count's place, below the table:\n above it they would push the rows down under the next click. */}\n {bulk && ticked.length > 0 ? (\n <div role=\"toolbar\" aria-label=\"Selected rows\" className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-medium\">{ticked.length} selected</span>\n {bulk.actions.map((action) => (\n <Button\n key={action.name}\n size=\"sm\"\n variant={action.destructive ? 'destructive' : 'outline'}\n disabled={running}\n onClick={() => (action.destructive ? setConfirming({ action, ids: ticked }) : runBulk(action, ticked))}\n >\n {action.name === 'delete' && <Trash2 />}\n {action.label}\n </Button>\n ))}\n <Button size=\"icon-sm\" variant=\"ghost\" aria-label=\"Clear selection\" disabled={running} onClick={() => setSelected(new Set())}>\n <X />\n </Button>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {count} {count === 1 ? noun.one.toLowerCase() : noun.many.toLowerCase()}\n </p>\n )}\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">\n Page {page} of {pageCount}\n </span>\n {server ? (\n <>\n <Pager to={page > 1 ? urlFor({ page: page - 1 }) : null} label=\"Previous page\">\n <ChevronLeft />\n </Pager>\n <Pager to={page < pageCount ? urlFor({ page: page + 1 }) : null} label=\"Next page\">\n <ChevronRight />\n </Pager>\n </>\n ) : (\n <>\n <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"Previous page\" disabled={!table.getCanPreviousPage()} onClick={() => table.previousPage()}>\n <ChevronLeft />\n </Button>\n <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"Next page\" disabled={!table.getCanNextPage()} onClick={() => table.nextPage()}>\n <ChevronRight />\n </Button>\n </>\n )}\n </div>\n </div>\n\n <AlertDialog open={confirming !== null} onOpenChange={(open) => !open && !deleting && !running && setConfirming(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{confirmTitle(confirming, noun)}</AlertDialogTitle>\n <AlertDialogDescription>\n {confirmDescription(confirming)}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={deleting || running}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n disabled={deleting || running}\n onClick={() => {\n if (confirming && 'ids' in confirming) return runBulk(confirming.action, confirming.ids)\n\n startDelete(async () => {\n await confirming?.row.remove?.()\n setConfirming(null)\n })\n }}\n >\n {confirming && 'ids' in confirming ? (running ? 'Working…' : confirming.action.label) : deleting ? 'Deleting…' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n )\n}\n\nfunction confirmTitle(confirming: Confirming | null, noun: { one: string; many: string }): string {\n if (!confirming || 'row' in confirming) return `Delete this ${noun.one.toLowerCase()}?`\n\n const { action, ids } = confirming\n const counted = `${ids.length} ${(ids.length === 1 ? noun.one : noun.many).toLowerCase()}`\n\n return action.name === 'delete' ? `Delete ${counted}?` : `${action.label}: ${counted}?`\n}\n\nfunction confirmDescription(confirming: Confirming | null): string {\n if (confirming && 'ids' in confirming && confirming.action.name !== 'delete') return 'This cannot be undone.'\n\n const many = confirming !== null && 'ids' in confirming && confirming.ids.length > 1\n\n return `${many ? 'They are' : 'It is'} removed for good. This cannot be undone.`\n}\n\nfunction Pager({ to, label, children }: { to: string | null; label: string; children: ReactNode }) {\n if (!to) {\n return (\n <Button variant=\"outline\" size=\"icon-sm\" aria-label={label} disabled>\n {children}\n </Button>\n )\n }\n\n return <Button variant=\"outline\" size=\"icon-sm\" aria-label={label} nativeButton={false} render={<Link href={to as never} replace />}>{children}</Button>\n}\n\nfunction RowActions({ row, onDelete }: { row: TableRowData; onDelete: () => void }) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"ghost\" size=\"icon-sm\" aria-label=\"Actions\" />}>\n <MoreHorizontal />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-36\">\n {row.edit && (\n <DropdownMenuItem render={<Link href={row.edit as never} />}>\n <Pencil />\n Edit\n </DropdownMenuItem>\n )}\n {row.edit && row.remove && <DropdownMenuSeparator />}\n {row.remove && (\n <DropdownMenuItem variant=\"destructive\" onClick={onDelete}>\n <Trash2 />\n Delete\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\nfunction compare(a: unknown, b: unknown): number {\n if (a === b) return 0\n if (a === null || a === undefined) return 1\n if (b === null || b === undefined) return -1\n if (typeof a === 'number' && typeof b === 'number') return a - b\n if (typeof a === 'boolean' && typeof b === 'boolean') return Number(a) - Number(b)\n\n return String(a).localeCompare(String(b), undefined, { numeric: true })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"data-table.js","sourceRoot":"","sources":["../../src/shadcn/data-table.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE3E,OAAO,EAKL,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,QAAQ,GACT,MAAM,uBAAuB,CAAA;AAC9B,OAAO,IAAI,MAAM,oBAAoB,CAAA;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAE9I,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,iCAAiC,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AACtD,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACzG,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAKxG,MAAM,QAAQ,GAAG,aAAa,CAAC;IAC7B,iBAAiB;IACjB,oBAAoB;IACpB,uBAAuB;IACvB,cAAc,EAAE,oBAAoB,EAAE;IACtC,iBAAiB,EAAE,uBAAuB,EAAE;CAC7C,CAAC,CAAA;AAIF,MAAM,GAAG,GAAG,SAAS,CAAA;AAErB;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EACP,KAAK,EACL,OAAO,EACP,IAAI,EACJ,IAAI,GACO;IACX,MAAM,MAAM,GAAG,IAAI,KAAK,QAAQ,CAAA;IAChC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACnC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAyB,KAAK,CAAC,OAAO,CAAC,CAAA;IAC3E,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAe,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IACxH,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAwB,GAAG,EAAE,CACnF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CACrG,CAAA;IACD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAkB,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;IAC5H,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAoB,IAAI,CAAC,CAAA;IACrE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,aAAa,EAAE,CAAA;IAC/C,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAsB,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,CAAA;IAC9E,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,aAAa,EAAE,CAAA;IAE3C,uEAAuE;IACvE,mEAAmE;IACnE,SAAS,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAC/C,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG,aAAa,EAAE,CAAA;IAEtC,yEAAyE;IACzE,oDAAoD;IACpD,MAAM,MAAM,GAAG,CAAC,OAAoF,EAAE,EAAE;QACtG,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAAA;QACzD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAA;QAEpC,IAAI,IAAI,CAAC,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;QACnC,IAAI,IAAI,CAAC,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5C,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,KAAK,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAC/D,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACxD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,IAAI,KAAK;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAE1F,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;QAE5B,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IACpC,CAAC,CAAA;IAED,MAAM,EAAE,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,KAAK,CAAC,GAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAEzF,kFAAkF;IAClF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAE3B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,OAAM;QAErC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAE/D,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;IAClC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAEP,0EAA0E;IAC1E,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE;QAC3B,IAAI,MAAM;YAAE,OAAO,IAAI,CAAA;QAEvB,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACrC,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAE5F,OAAO,IAAI,CAAC,MAAM,CAChB,CAAC,GAAG,EAAE,EAAE,CACN,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC;YAC3F,CAAC,CAAC,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CACtG,CAAA;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAEtC,MAAM,UAAU,GAAG,OAAO,CACxB,GAAG,EAAE,CACH,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvB,EAAE,EAAE,MAAM,CAAC,GAAG;QACd,UAAU,EAAE,CAAC,GAAiB,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;QACzD,MAAM,EAAE,MAAM,CAAC,KAAK;QACpB,IAAI,EAAE,CAAC,EAAE,GAAG,EAAuC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;QACtF,aAAa,EAAE,MAAM,CAAC,QAAQ;QAC9B,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;KAC9D,CAAC,CAAwC,EAC5C,CAAC,OAAO,CAAC,CACV,CAAA;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC;QACrB,QAAQ;QACR,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,UAAU;QACnB,QAAQ,EAAE,CAAC,GAAiB,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE;QACvC,aAAa,EAAE,MAAM;QACrB,gBAAgB,EAAE,MAAM;QACxB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChF,eAAe,EAAE,UAAU;QAC3B,kBAAkB,EAAE,aAAa;QACjC,wBAAwB,EAAE,mBAAmB;QAC7C,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE;KACjD,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;IACtD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAA;IAEtE,MAAM,IAAI,GAAG,CAAC,GAAa,EAAE,EAAW,EAAE,EAAE,CAC1C,WAAW,CAAC,CAAC,OAAO,EAAE,EAAE;QACtB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAA;QAE7B,KAAK,MAAM,EAAE,IAAI,GAAG;YAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAEzD,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;IAEJ,MAAM,OAAO,GAAG,CAAC,MAAuB,EAAE,GAAa,EAAE,EAAE,CACzD,QAAQ,CAAC,KAAK,IAAI,EAAE;QAClB,MAAM,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACjC,WAAW,CAAC,IAAI,GAAG,EAAE,CAAC,CAAA;QACtB,aAAa,CAAC,IAAI,CAAC,CAAA;IACrB,CAAC,CAAC,CAAA;IAEJ,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;IAC7D,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAA;IAC7G,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,GAAG,CAAC,CAAA;IAC3D,+EAA+E;IAC/E,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAA;IAE7C,OAAO,CACL,eAAK,SAAS,EAAC,qBAAqB,aAClC,eAAK,SAAS,EAAC,mCAAmC,aAC/C,UAAU,IAAI,CAGb,gBACE,MAAM,EAAE,IAAI,EACZ,MAAM,EAAC,KAAK,EACZ,SAAS,EAAC,6BAA6B,EACvC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;4BAClB,KAAK,CAAC,cAAc,EAAE,CAAA;4BACtB,IAAI,MAAM;gCAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;wBACxC,CAAC,aAED,KAAC,MAAM,IAAC,SAAS,EAAC,6FAA6F,GAAG,EAClH,KAAC,KAAK,IACJ,IAAI,EAAC,GAAG,EACR,IAAI,EAAC,QAAQ,EACb,WAAW,EAAE,UAAU,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,gBACrC,UAAU,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,EAC/C,SAAS,EAAC,MAAM,EAChB,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;oCAClB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAA;oCACpB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;oCACxB,IAAI,CAAC,MAAM;wCAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;gCACpC,CAAC,GACD,IACG,CACR,EACA,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACvB,MAAC,MAAM,IAEL,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,EACtF,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,EAChC,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;4BACvB,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;4BAE9F,SAAS,CAAC,IAAI,CAAC,CAAA;4BACf,IAAI,MAAM;gCAAE,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;;gCAC7C,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;wBAC5B,CAAC,aAED,KAAC,aAAa,kBAAa,MAAM,CAAC,KAAK,EAAE,SAAS,EAAC,gBAAgB,YACjE,KAAC,WAAW,KAAG,GACD,EAChB,MAAC,aAAa,eACZ,MAAC,UAAU,IAAC,KAAK,EAAE,GAAG,qBAAO,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,IAAc,EACpE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC9B,KAAC,UAAU,IAAoB,KAAK,EAAE,MAAM,CAAC,KAAK,YAC/C,MAAM,CAAC,KAAK,IADE,MAAM,CAAC,KAAK,CAEhB,CACd,CAAC,IACY,KArBX,MAAM,CAAC,GAAG,CAsBR,CACV,CAAC,EACF,MAAC,YAAY,eACX,MAAC,mBAAmB,IAAC,MAAM,EAAE,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAC,SAAS,GAAG,aAC3E,KAAC,QAAQ,KAAG,EACZ,eAAM,SAAS,EAAC,kBAAkB,wBAAe,IAC7B,EACtB,KAAC,mBAAmB,IAAC,KAAK,EAAC,KAAK,EAAC,SAAS,EAAC,MAAM,YAC/C,MAAC,iBAAiB,eAChB,KAAC,iBAAiB,+BAAiC,EAClD,KAAK;6CACH,aAAa,EAAE;6CACf,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;6CACvC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACf,KAAC,wBAAwB,IAEvB,OAAO,EAAE,MAAM,CAAC,YAAY,EAAE,EAC9B,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,YAE3D,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,KAAK,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,IAJ3D,MAAM,CAAC,EAAE,CAKW,CAC5B,CAAC,IACc,GACA,IACT,IACX,EAEN,cAAK,SAAS,EAAC,mCAAmC,YAChD,MAAC,KAAK,eACJ,KAAC,WAAW,IAAC,SAAS,EAAC,aAAa,YACjC,KAAK,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACtC,MAAC,QAAQ,eACN,IAAI,IAAI,CACP,KAAC,SAAS,IAAC,SAAS,EAAC,MAAM,YACzB,KAAC,QAAQ,kBACK,gBAAgB,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,eAAe,EACjE,OAAO,EAAE,SAAS,EAClB,aAAa,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,EAC9C,QAAQ,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAC7B,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,GAC/C,GACQ,CACb,EACA,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;wCAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;wCAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,KAAK,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,CAAA;wCAC7E,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAA;wCAC7F,MAAM,KAAK,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAA;wCAEtF,OAAO,CACL,KAAC,SAAS,iBAA4B,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,YAChH,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CACtB,KAAK,CACN,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CACX,MAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,aAAa,EACvB,YAAY,EAAE,KAAK,EACnB,MAAM,EAAE,KAAC,IAAI,IAAC,IAAI,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAU,EAAE,OAAO,SAAG,aAEpH,KAAK,EACN,KAAC,KAAK,IAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,0BAA0B,GAAI,IAC9D,CACV,CAAC,CAAC,CAAC,CACF,MAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,IAAI,EAAC,SAAS,EAAC,aAAa,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,KAAK,KAAK,CAAC,aAC5G,KAAK,EACN,KAAC,KAAK,IAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,0BAA0B,GAAI,IAC9D,CACV,IAnBa,MAAM,CAAC,EAAE,CAoBb,CACb,CAAA;oCACH,CAAC,CAAC,EACD,UAAU,IAAI,CACb,KAAC,SAAS,IAAC,SAAS,EAAC,MAAM,YACzB,eAAM,SAAS,EAAC,SAAS,wBAAe,GAC9B,CACb,KA9CY,KAAK,CAAC,EAAE,CA+CZ,CACZ,CAAC,GACU,EACd,KAAC,SAAS,cACP,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CACjC,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACpC,MAAC,QAAQ,kBAA0B,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,aAC7E,IAAI,IAAI,CACP,KAAC,SAAS,cACR,KAAC,QAAQ,kBAAY,YAAY,EAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAI,GACtG,CACb,EACA,GAAG,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACnC,KAAC,SAAS,cACR,KAAC,KAAK,CAAC,UAAU,IAAC,IAAI,EAAE,IAAI,GAAI,IADlB,IAAI,CAAC,EAAE,CAEX,CACb,CAAC,EACD,UAAU,IAAI,CACb,KAAC,SAAS,IAAC,SAAS,EAAC,YAAY,YAC/B,KAAC,UAAU,IAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAI,GAC7E,CACb,KAfY,GAAG,CAAC,EAAE,CAgBV,CACZ,CAAC,CACH,CAAC,CAAC,CAAC,CACF,KAAC,QAAQ,cACP,MAAC,SAAS,IAAC,OAAO,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAC,wCAAwC,oBACxH,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eACjB,GACH,CACZ,GACS,IACN,GACJ,EAEN,eAAK,SAAS,EAAC,yCAAyC,aAGrD,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC3B,eAAK,IAAI,EAAC,SAAS,gBAAY,eAAe,EAAC,SAAS,EAAC,mCAAmC,aAC1F,gBAAM,SAAS,EAAC,qBAAqB,aAAE,MAAM,CAAC,MAAM,iBAAiB,EACpE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC5B,MAAC,MAAM,IAEL,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EACvD,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,aAErG,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAC,MAAM,KAAG,EACtC,MAAM,CAAC,KAAK,KAPR,MAAM,CAAC,IAAI,CAQT,CACV,CAAC,EACF,KAAC,MAAM,IAAC,IAAI,EAAC,SAAS,EAAC,OAAO,EAAC,OAAO,gBAAY,iBAAiB,EAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,GAAG,EAAE,CAAC,YAC1H,KAAC,CAAC,KAAG,GACE,IACL,CACP,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,CACnB,gBAAQ,CACT,CAAC,CAAC,CAAC,CACF,aAAG,SAAS,EAAC,+BAA+B,aACzC,KAAK,OAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IACrE,CACL,EACD,eAAK,SAAS,EAAC,yBAAyB,aACrC,CAAC,OAAO,IAAI,CACX,gBAAM,SAAS,EAAC,+BAA+B,sBACvC,IAAI,UAAM,SAAS,IACpB,CACR,EACA,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CACnB,8BACE,KAAC,KAAK,IAAC,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAC,eAAe,YAC5C,KAAC,WAAW,KAAG,GACT,EACR,KAAC,KAAK,IAAC,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAC,WAAW,YACxC,KAAC,YAAY,KAAG,GACV,IACP,CACJ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CACX,8BACE,KAAC,KAAK,IAAC,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAC,eAAe,YAC5E,KAAC,WAAW,KAAG,GACT,EACR,KAAC,KAAK,IAAC,EAAE,EAAE,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAC,WAAW,YAChF,KAAC,YAAY,KAAG,GACV,IACP,CACJ,CAAC,CAAC,CAAC,CACF,8BACE,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,SAAS,gBAAY,eAAe,EAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,YAC5I,KAAC,WAAW,KAAG,GACR,EACT,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,SAAS,gBAAY,WAAW,EAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,YAChI,KAAC,YAAY,KAAG,GACT,IACR,CACJ,IACG,IACF,EAEN,KAAC,WAAW,IAAC,IAAI,EAAE,UAAU,KAAK,IAAI,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,YACnH,MAAC,kBAAkB,eACjB,MAAC,iBAAiB,eAChB,KAAC,gBAAgB,cAAE,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,GAAoB,EACrE,KAAC,sBAAsB,cACpB,kBAAkB,CAAC,UAAU,CAAC,GACR,IACP,EACpB,MAAC,iBAAiB,eAChB,KAAC,iBAAiB,IAAC,QAAQ,EAAE,QAAQ,IAAI,OAAO,uBAA4B,EAC5E,KAAC,iBAAiB,IAChB,OAAO,EAAC,aAAa,EACrB,QAAQ,EAAE,QAAQ,IAAI,OAAO,EAC7B,OAAO,EAAE,GAAG,EAAE;wCACZ,IAAI,UAAU,IAAI,KAAK,IAAI,UAAU;4CAAE,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAA;wCAExF,WAAW,CAAC,KAAK,IAAI,EAAE;4CACrB,MAAM,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,CAAA;4CAChC,aAAa,CAAC,IAAI,CAAC,CAAA;wCACrB,CAAC,CAAC,CAAA;oCACJ,CAAC,YAEA,UAAU,IAAI,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,GACvG,IACF,IACD,GACT,IACV,CACP,CAAA;AACH,CAAC;AAED,SAAS,YAAY,CAAC,UAA6B,EAAE,IAAmC;IACtF,IAAI,CAAC,UAAU,IAAI,KAAK,IAAI,UAAU;QAAE,OAAO,eAAe,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAA;IAEvF,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,UAAU,CAAA;IAClC,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAA;IAE1F,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,KAAK,OAAO,GAAG,CAAA;AACzF,CAAC;AAED,SAAS,kBAAkB,CAAC,UAA6B;IACvD,IAAI,UAAU,IAAI,KAAK,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,wBAAwB,CAAA;IAE7G,MAAM,IAAI,GAAG,UAAU,KAAK,IAAI,IAAI,KAAK,IAAI,UAAU,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAA;IAEpF,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,2CAA2C,CAAA;AAClF,CAAC;AAED,SAAS,KAAK,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAA6D;IAC/F,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,CACL,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,SAAS,gBAAa,KAAK,EAAE,QAAQ,kBACjE,QAAQ,GACF,CACV,CAAA;IACH,CAAC;IAED,OAAO,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,SAAS,gBAAa,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,KAAC,IAAI,IAAC,IAAI,EAAE,EAAW,EAAE,OAAO,SAAG,YAAG,QAAQ,GAAU,CAAA;AAC1J,CAAC;AAED,SAAS,UAAU,CAAC,EAAE,GAAG,EAAE,QAAQ,EAA+C;IAChF,OAAO,CACL,MAAC,YAAY,eACX,KAAC,mBAAmB,IAAC,MAAM,EAAE,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,SAAS,gBAAY,SAAS,GAAG,YACzF,KAAC,cAAc,KAAG,GACE,EACtB,MAAC,mBAAmB,IAAC,KAAK,EAAC,KAAK,EAAC,SAAS,EAAC,MAAM,aAC9C,GAAG,CAAC,IAAI,IAAI,CACX,MAAC,gBAAgB,IAAC,MAAM,EAAE,KAAC,IAAI,IAAC,IAAI,EAAE,GAAG,CAAC,IAAa,GAAI,aACzD,KAAC,MAAM,KAAG,YAEO,CACpB,EACA,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM,IAAI,KAAC,qBAAqB,KAAG,EACnD,GAAG,CAAC,MAAM,IAAI,CACb,MAAC,gBAAgB,IAAC,OAAO,EAAC,aAAa,EAAC,OAAO,EAAE,QAAQ,aACvD,KAAC,MAAM,KAAG,cAEO,CACpB,IACmB,IACT,CAChB,CAAA;AACH,CAAC;AAED,SAAS,OAAO,CAAC,CAAU,EAAE,CAAU;IACrC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAA;IACrB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,CAAC,CAAA;IAC3C,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC,CAAA;IAC5C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAChE,IAAI,OAAO,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;IAElF,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;AACzE,CAAC","sourcesContent":["'use client'\n\nimport { useEffect, useMemo, useRef, useState, useTransition } from 'react'\nimport type { ReactNode } from 'react'\nimport {\n type ColumnDef,\n type ColumnVisibilityState,\n type PaginationState,\n type SortingState,\n columnVisibilityFeature,\n createPaginatedRowModel,\n createSortedRowModel,\n rowPaginationFeature,\n rowSortingFeature,\n tableFeatures,\n useTable,\n} from '@tanstack/react-table'\nimport Link from '@rsc-kit/core/Link'\nimport { visit } from '@rsc-kit/core/router'\nimport { ArrowDown, ArrowUp, ArrowUpDown, ChevronLeft, ChevronRight, Columns3, MoreHorizontal, Pencil, Search, Trash2, X } from 'lucide-react'\nimport type { TableBulkAction, TableProps, TableQuery, TableRowData } from '../admin/theme.js'\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from './components/ui/alert-dialog.js'\nimport { Button } from './components/ui/button.js'\nimport { Checkbox } from './components/ui/checkbox.js'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from './components/ui/dropdown-menu.js'\nimport { Input } from './components/ui/input.js'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './components/ui/select.js'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './components/ui/table.js'\n\n/** What is asked before it happens: one row's delete, or an action over the ticked rows. */\ntype Confirming = { row: TableRowData } | { action: TableBulkAction; ids: string[] }\n\nconst features = tableFeatures({\n rowSortingFeature,\n rowPaginationFeature,\n columnVisibilityFeature,\n sortedRowModel: createSortedRowModel(),\n paginatedRowModel: createPaginatedRowModel(),\n})\n\ntype Features = typeof features\n\nconst ALL = '__all__'\n\n/**\n * Every resource's table. One component for both modes, so a table looks and\n * behaves the same wherever its rows are searched:\n *\n * server the url is the state. Typing, a filter, a header and the pager\n * each visit a url, the page asks the source for one page, and a\n * link works with no javascript and can be shared.\n * client every row arrived at once; search, filters, sort and the pager\n * happen here, with no request.\n */\nexport function DataTable({\n mode,\n href,\n columns,\n rows,\n total,\n cursors,\n perPage,\n query,\n filters,\n noun,\n bulk,\n}: TableProps) {\n const server = mode === 'server'\n const [q, setQ] = useState(query.q)\n const [chosen, setChosen] = useState<Record<string, string>>(query.filters)\n const [sorting, setSorting] = useState<SortingState>(query.sort ? [{ id: query.sort, desc: query.dir === 'desc' }] : [])\n const [columnVisibility, setColumnVisibility] = useState<ColumnVisibilityState>(() =>\n Object.fromEntries(columns.filter((column) => !column.visible).map((column) => [column.key, false])),\n )\n const [pagination, setPagination] = useState<PaginationState>({ pageIndex: server ? query.page - 1 : 0, pageSize: perPage })\n const [confirming, setConfirming] = useState<Confirming | null>(null)\n const [deleting, startDelete] = useTransition()\n const [selected, setSelected] = useState<ReadonlySet<string>>(() => new Set())\n const [running, startRun] = useTransition()\n\n // New rows - another page, a search, the table after an action - start\n // with nothing ticked: a selection is of rows the visitor can see.\n useEffect(() => setSelected(new Set()), [rows])\n const [, startVisit] = useTransition()\n\n // Server mode: the url this state names. Empty values are left out, so a\n // cleared search is the plain list url and not ?q=.\n const urlFor = (changes: Partial<Omit<TableQuery, 'filters'>> & { filters?: Record<string, string> }) => {\n const next = { ...query, q, filters: chosen, ...changes }\n const search = new URLSearchParams()\n\n if (next.q) search.set('q', next.q)\n if (next.sort) search.set('sort', next.sort)\n if (next.sort && next.dir === 'desc') search.set('dir', 'desc')\n if (next.page > 1) search.set('page', String(next.page))\n for (const [key, value] of Object.entries(next.filters)) if (value) search.set(key, value)\n\n const qs = search.toString()\n\n return qs ? `${href}?${qs}` : href\n }\n\n const go = (url: string) => startVisit(() => void visit(url as never, { replace: true }))\n\n // Typing searches after a pause, not per keystroke; the page resets to the first.\n const typed = useRef(false)\n\n useEffect(() => {\n if (!server || !typed.current) return\n\n const timer = setTimeout(() => go(urlFor({ q, page: 1 })), 300)\n\n return () => clearTimeout(timer)\n }, [q])\n\n // Client mode: search and filters here, before the table sorts and pages.\n const visible = useMemo(() => {\n if (server) return rows\n\n const needle = q.trim().toLowerCase()\n const searchable = columns.filter((column) => column.searchable).map((column) => column.key)\n\n return rows.filter(\n (row) =>\n Object.entries(chosen).every(([key, value]) => !value || String(row.values[key]) === value) &&\n (!needle || searchable.some((key) => String(row.values[key] ?? '').toLowerCase().includes(needle))),\n )\n }, [server, rows, q, chosen, columns])\n\n const columnDefs = useMemo<ColumnDef<Features, TableRowData>[]>(\n () =>\n columns.map((column) => ({\n id: column.key,\n accessorFn: (row: TableRowData) => row.values[column.key],\n header: column.label,\n cell: ({ row }: { row: { original: TableRowData } }) => row.original.cells[column.key],\n enableSorting: column.sortable,\n enableHiding: true,\n sortFn: (a, b, id) => compare(a.getValue(id), b.getValue(id)),\n })) as ColumnDef<Features, TableRowData>[],\n [columns],\n )\n\n const table = useTable({\n features,\n data: visible,\n columns: columnDefs,\n getRowId: (row: TableRowData) => row.id,\n manualSorting: server,\n manualPagination: server,\n ...(server ? { pageCount: Math.max(1, Math.ceil((total ?? 0) / perPage)) } : {}),\n onSortingChange: setSorting,\n onPaginationChange: setPagination,\n onColumnVisibilityChange: setColumnVisibility,\n state: { sorting, pagination, columnVisibility },\n })\n\n const onPage = table.getRowModel().rows.map((row) => row.id)\n const ticked = onPage.filter((id) => selected.has(id))\n const allTicked = onPage.length > 0 && ticked.length === onPage.length\n\n const tick = (ids: string[], on: boolean) =>\n setSelected((current) => {\n const next = new Set(current)\n\n for (const id of ids) on ? next.add(id) : next.delete(id)\n\n return next\n })\n\n const runBulk = (action: TableBulkAction, ids: string[]) =>\n startRun(async () => {\n await bulk?.run(action.name, ids)\n setSelected(new Set())\n setConfirming(null)\n })\n\n const searchable = columns.some((column) => column.searchable)\n const hasActions = rows.some((row) => row.edit || row.remove)\n const pageCount = server ? Math.max(1, Math.ceil((total ?? 0) / perPage)) : Math.max(1, table.getPageCount())\n const page = server ? query.page : pagination.pageIndex + 1\n // A list paged by cursor may not be counted: then it says nothing of how many.\n const count = server ? total : visible.length\n\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex flex-wrap items-center gap-2\">\n {searchable && (\n // A form, so Enter searches and a server-mode search works before\n // the page has javascript: it is a GET of the list url.\n <form\n action={href}\n method=\"get\"\n className=\"relative w-full sm:max-w-xs\"\n onSubmit={(event) => {\n event.preventDefault()\n if (server) go(urlFor({ q, page: 1 }))\n }}\n >\n <Search className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n name=\"q\"\n type=\"search\"\n placeholder={`Search ${noun.many.toLowerCase()}…`}\n aria-label={`Search ${noun.many.toLowerCase()}`}\n className=\"pl-8\"\n value={q}\n onChange={(event) => {\n typed.current = true\n setQ(event.target.value)\n if (!server) table.setPageIndex(0)\n }}\n />\n </form>\n )}\n {filters.map((filter) => (\n <Select\n key={filter.key}\n items={[{ value: ALL, label: `All ${filter.label.toLowerCase()}` }, ...filter.options]}\n value={chosen[filter.key] || ALL}\n onValueChange={(value) => {\n const next = { ...chosen, [filter.key]: value === ALL || value === null ? '' : String(value) }\n\n setChosen(next)\n if (server) go(urlFor({ filters: next, page: 1 }))\n else table.setPageIndex(0)\n }}\n >\n <SelectTrigger aria-label={filter.label} className=\"w-full sm:w-44\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All {filter.label.toLowerCase()}</SelectItem>\n {filter.options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ))}\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"outline\" className=\"ml-auto\" />}>\n <Columns3 />\n <span className=\"hidden sm:inline\">Columns</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-44\">\n <DropdownMenuGroup>\n <DropdownMenuLabel>Show columns</DropdownMenuLabel>\n {table\n .getAllColumns()\n .filter((column) => column.getCanHide())\n .map((column) => (\n <DropdownMenuCheckboxItem\n key={column.id}\n checked={column.getIsVisible()}\n onCheckedChange={(value) => column.toggleVisibility(!!value)}\n >\n {columns.find((candidate) => candidate.key === column.id)?.label}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n <div className=\"overflow-hidden rounded-lg border\">\n <Table>\n <TableHeader className=\"bg-muted/50\">\n {table.getHeaderGroups().map((group) => (\n <TableRow key={group.id}>\n {bulk && (\n <TableHead className=\"w-10\">\n <Checkbox\n aria-label={`Select every ${noun.one.toLowerCase()} on this page`}\n checked={allTicked}\n indeterminate={ticked.length > 0 && !allTicked}\n disabled={onPage.length === 0}\n onCheckedChange={() => tick(onPage, !allTicked)}\n />\n </TableHead>\n )}\n {group.headers.map((header) => {\n const column = header.column\n const label = columns.find((candidate) => candidate.key === column.id)?.label\n const sorted = server ? (query.sort === column.id ? query.dir : false) : column.getIsSorted()\n const Arrow = sorted === 'asc' ? ArrowUp : sorted === 'desc' ? ArrowDown : ArrowUpDown\n\n return (\n <TableHead key={header.id} aria-sort={sorted === 'asc' ? 'ascending' : sorted === 'desc' ? 'descending' : undefined}>\n {!column.getCanSort() ? (\n label\n ) : server ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"-ml-2.5 h-8\"\n nativeButton={false}\n render={<Link href={urlFor({ sort: column.id, dir: sorted === 'asc' ? 'desc' : 'asc', page: 1 }) as never} replace />}\n >\n {label}\n <Arrow className={sorted ? undefined : 'text-muted-foreground/60'} />\n </Button>\n ) : (\n <Button variant=\"ghost\" size=\"sm\" className=\"-ml-2.5 h-8\" onClick={() => column.toggleSorting(sorted === 'asc')}>\n {label}\n <Arrow className={sorted ? undefined : 'text-muted-foreground/60'} />\n </Button>\n )}\n </TableHead>\n )\n })}\n {hasActions && (\n <TableHead className=\"w-12\">\n <span className=\"sr-only\">Actions</span>\n </TableHead>\n )}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {table.getRowModel().rows.length ? (\n table.getRowModel().rows.map((row) => (\n <TableRow key={row.id} data-state={selected.has(row.id) ? 'selected' : undefined}>\n {bulk && (\n <TableCell>\n <Checkbox aria-label=\"Select row\" checked={selected.has(row.id)} onCheckedChange={(on) => tick([row.id], on)} />\n </TableCell>\n )}\n {row.getVisibleCells().map((cell) => (\n <TableCell key={cell.id}>\n <table.FlexRender cell={cell} />\n </TableCell>\n ))}\n {hasActions && (\n <TableCell className=\"text-right\">\n <RowActions row={row.original} onDelete={() => setConfirming({ row: row.original })} />\n </TableCell>\n )}\n </TableRow>\n ))\n ) : (\n <TableRow>\n <TableCell colSpan={columns.length + (hasActions ? 1 : 0) + (bulk ? 1 : 0)} className=\"h-24 text-center text-muted-foreground\">\n No {noun.many.toLowerCase()} found.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n\n <div className=\"flex items-center justify-between gap-2\">\n {/* The ticked rows' actions take the count's place, below the table:\n above it they would push the rows down under the next click. */}\n {bulk && ticked.length > 0 ? (\n <div role=\"toolbar\" aria-label=\"Selected rows\" className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-medium\">{ticked.length} selected</span>\n {bulk.actions.map((action) => (\n <Button\n key={action.name}\n size=\"sm\"\n variant={action.destructive ? 'destructive' : 'outline'}\n disabled={running}\n onClick={() => (action.destructive ? setConfirming({ action, ids: ticked }) : runBulk(action, ticked))}\n >\n {action.name === 'delete' && <Trash2 />}\n {action.label}\n </Button>\n ))}\n <Button size=\"icon-sm\" variant=\"ghost\" aria-label=\"Clear selection\" disabled={running} onClick={() => setSelected(new Set())}>\n <X />\n </Button>\n </div>\n ) : count === null ? (\n <span />\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {count} {count === 1 ? noun.one.toLowerCase() : noun.many.toLowerCase()}\n </p>\n )}\n <div className=\"flex items-center gap-2\">\n {!cursors && (\n <span className=\"text-sm text-muted-foreground\">\n Page {page} of {pageCount}\n </span>\n )}\n {server && cursors ? (\n <>\n <Pager to={cursors.prev} label=\"Previous page\">\n <ChevronLeft />\n </Pager>\n <Pager to={cursors.next} label=\"Next page\">\n <ChevronRight />\n </Pager>\n </>\n ) : server ? (\n <>\n <Pager to={page > 1 ? urlFor({ page: page - 1 }) : null} label=\"Previous page\">\n <ChevronLeft />\n </Pager>\n <Pager to={page < pageCount ? urlFor({ page: page + 1 }) : null} label=\"Next page\">\n <ChevronRight />\n </Pager>\n </>\n ) : (\n <>\n <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"Previous page\" disabled={!table.getCanPreviousPage()} onClick={() => table.previousPage()}>\n <ChevronLeft />\n </Button>\n <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"Next page\" disabled={!table.getCanNextPage()} onClick={() => table.nextPage()}>\n <ChevronRight />\n </Button>\n </>\n )}\n </div>\n </div>\n\n <AlertDialog open={confirming !== null} onOpenChange={(open) => !open && !deleting && !running && setConfirming(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{confirmTitle(confirming, noun)}</AlertDialogTitle>\n <AlertDialogDescription>\n {confirmDescription(confirming)}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={deleting || running}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n disabled={deleting || running}\n onClick={() => {\n if (confirming && 'ids' in confirming) return runBulk(confirming.action, confirming.ids)\n\n startDelete(async () => {\n await confirming?.row.remove?.()\n setConfirming(null)\n })\n }}\n >\n {confirming && 'ids' in confirming ? (running ? 'Working…' : confirming.action.label) : deleting ? 'Deleting…' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n )\n}\n\nfunction confirmTitle(confirming: Confirming | null, noun: { one: string; many: string }): string {\n if (!confirming || 'row' in confirming) return `Delete this ${noun.one.toLowerCase()}?`\n\n const { action, ids } = confirming\n const counted = `${ids.length} ${(ids.length === 1 ? noun.one : noun.many).toLowerCase()}`\n\n return action.name === 'delete' ? `Delete ${counted}?` : `${action.label}: ${counted}?`\n}\n\nfunction confirmDescription(confirming: Confirming | null): string {\n if (confirming && 'ids' in confirming && confirming.action.name !== 'delete') return 'This cannot be undone.'\n\n const many = confirming !== null && 'ids' in confirming && confirming.ids.length > 1\n\n return `${many ? 'They are' : 'It is'} removed for good. This cannot be undone.`\n}\n\nfunction Pager({ to, label, children }: { to: string | null; label: string; children: ReactNode }) {\n if (!to) {\n return (\n <Button variant=\"outline\" size=\"icon-sm\" aria-label={label} disabled>\n {children}\n </Button>\n )\n }\n\n return <Button variant=\"outline\" size=\"icon-sm\" aria-label={label} nativeButton={false} render={<Link href={to as never} replace />}>{children}</Button>\n}\n\nfunction RowActions({ row, onDelete }: { row: TableRowData; onDelete: () => void }) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"ghost\" size=\"icon-sm\" aria-label=\"Actions\" />}>\n <MoreHorizontal />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-36\">\n {row.edit && (\n <DropdownMenuItem render={<Link href={row.edit as never} />}>\n <Pencil />\n Edit\n </DropdownMenuItem>\n )}\n {row.edit && row.remove && <DropdownMenuSeparator />}\n {row.remove && (\n <DropdownMenuItem variant=\"destructive\" onClick={onDelete}>\n <Trash2 />\n Delete\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\nfunction compare(a: unknown, b: unknown): number {\n if (a === b) return 0\n if (a === null || a === undefined) return 1\n if (b === null || b === undefined) return -1\n if (typeof a === 'number' && typeof b === 'number') return a - b\n if (typeof a === 'boolean' && typeof b === 'boolean') return Number(a) - Number(b)\n\n return String(a).localeCompare(String(b), undefined, { numeric: true })\n}\n"]}
|
package/dist/shadcn/fields.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
1
2
|
import type { Field as FieldSpec } from '../resource.js';
|
|
2
3
|
/**
|
|
3
4
|
* Each field as its shadcn control, labelled, with its message under it: the
|
|
@@ -5,11 +6,20 @@ import type { Field as FieldSpec } from '../resource.js';
|
|
|
5
6
|
* panel's forms and the public ones, so a field looks and checks the same in
|
|
6
7
|
* both.
|
|
7
8
|
*/
|
|
8
|
-
export declare function FieldList({ fields, values, error }: {
|
|
9
|
+
export declare function FieldList({ fields, values, error, hidden, }: {
|
|
9
10
|
fields: FieldSpec[];
|
|
10
11
|
values: Record<string, unknown>;
|
|
11
12
|
error: (name: string) => string | undefined;
|
|
13
|
+
/** The fields whose condition hides them now, from useConditions. */
|
|
14
|
+
hidden?: ReadonlySet<string>;
|
|
12
15
|
}): import("react").JSX.Element[];
|
|
16
|
+
/**
|
|
17
|
+
* The fields' conditions and slugs, applied while the visitor types: which
|
|
18
|
+
* fields are hidden now, read from the form's own controls - the form stays
|
|
19
|
+
* uncontrolled, so nothing typed is lost to a render. A slug follows its
|
|
20
|
+
* source until it is edited by hand. The server applies both again.
|
|
21
|
+
*/
|
|
22
|
+
export declare function useConditions(form: RefObject<HTMLFormElement | null>, fields: FieldSpec[], values: Record<string, unknown>): ReadonlySet<string>;
|
|
13
23
|
/**
|
|
14
24
|
* The browser's own validation, shown the shadcn way. A submit fires
|
|
15
25
|
* 'invalid' at each control that fails its constraints; that is cancelled -
|
package/dist/shadcn/fields.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useId, useState } from 'react';
|
|
4
|
+
import { shown, slugify } from '../conditions.js';
|
|
4
5
|
import { ArrowDown, ArrowUp, FileIcon, Plus, Trash2 } from 'lucide-react';
|
|
5
6
|
import { sizeOf } from '../uploads.js';
|
|
6
7
|
import { Button } from './components/ui/button.js';
|
|
@@ -16,19 +17,80 @@ import { Textarea } from './components/ui/textarea.js';
|
|
|
16
17
|
* panel's forms and the public ones, so a field looks and checks the same in
|
|
17
18
|
* both.
|
|
18
19
|
*/
|
|
19
|
-
export function FieldList({ fields, values, error }) {
|
|
20
|
+
export function FieldList({ fields, values, error, hidden, }) {
|
|
20
21
|
return fields.map((field) => {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return (_jsxs(Field, { orientation: "horizontal", "data-invalid": invalid || undefined, children: [_jsxs(FieldContent, { children: [_jsx(FieldLabel, { htmlFor: id, children: field.label }), field.description && _jsx(FieldDescription, { children: field.description }), invalid && _jsx(FieldError, { children: error(field.name) })] }), _jsx(Switch, { id: id, name: field.name, defaultChecked: Boolean(values[field.name]), "aria-invalid": invalid || undefined })] }, field.name));
|
|
28
|
-
}
|
|
29
|
-
return (_jsxs(Field, { "data-invalid": invalid || undefined, children: [_jsxs(FieldLabel, { htmlFor: id, children: [field.label, field.required && _jsx("span", { className: "text-destructive", children: "*" })] }), field.type === 'file' || field.type === 'image' ? (_jsx(FileControl, { id: id, field: field, value: values[field.name], invalid: invalid }, String(values[field.name] ?? ''))) : (_jsx(Control, { id: id, field: field, value: values[field.name], invalid: invalid })), (field.description ?? limitOf(field)) && _jsx(FieldDescription, { children: field.description ?? limitOf(field) }), invalid && _jsx(FieldError, { children: error(field.name) })] }, field.name));
|
|
22
|
+
const control = fieldOf(field, values, error);
|
|
23
|
+
if (!field.visible)
|
|
24
|
+
return control;
|
|
25
|
+
// Disabled, a hidden field's controls are neither sent nor checked by the browser.
|
|
26
|
+
const off = hidden?.has(field.name) ?? false;
|
|
27
|
+
return (_jsx("fieldset", { disabled: off, hidden: off, className: off ? 'hidden' : 'contents', children: control }, field.name));
|
|
30
28
|
});
|
|
31
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* The fields' conditions and slugs, applied while the visitor types: which
|
|
32
|
+
* fields are hidden now, read from the form's own controls - the form stays
|
|
33
|
+
* uncontrolled, so nothing typed is lost to a render. A slug follows its
|
|
34
|
+
* source until it is edited by hand. The server applies both again.
|
|
35
|
+
*/
|
|
36
|
+
export function useConditions(form, fields, values) {
|
|
37
|
+
const initial = (name) => {
|
|
38
|
+
const value = values[name];
|
|
39
|
+
return typeof value === 'boolean' ? value : value === undefined || value === null ? '' : String(value);
|
|
40
|
+
};
|
|
41
|
+
const [hidden, setHidden] = useState(() => new Set(fields.filter((field) => field.visible && !shown(field.visible, initial)).map((field) => field.name)));
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
const element = form.current;
|
|
44
|
+
const conditional = fields.filter((field) => field.visible);
|
|
45
|
+
const derived = fields.filter((field) => field.from);
|
|
46
|
+
if (!element || (conditional.length === 0 && derived.length === 0))
|
|
47
|
+
return;
|
|
48
|
+
const types = new Map(fields.map((field) => [field.name, field.type]));
|
|
49
|
+
// What each slug was last made as: it follows while it still says that.
|
|
50
|
+
const last = new Map(derived.map((field) => [field.name, slugify(String(initial(field.from.field)))]));
|
|
51
|
+
const update = () => {
|
|
52
|
+
const data = new FormData(element);
|
|
53
|
+
const read = (name) => (types.get(name) === 'toggle' ? data.has(name) : String(data.get(name) ?? ''));
|
|
54
|
+
for (const field of derived) {
|
|
55
|
+
const target = element.elements.namedItem(field.name);
|
|
56
|
+
const made = slugify(String(read(field.from.field)));
|
|
57
|
+
if (target instanceof HTMLInputElement && (target.value === '' || target.value === last.get(field.name)))
|
|
58
|
+
target.value = made;
|
|
59
|
+
last.set(field.name, made);
|
|
60
|
+
}
|
|
61
|
+
const now = new Set(conditional.filter((field) => !shown(field.visible, read)).map((field) => field.name));
|
|
62
|
+
setHidden((before) => (before.size === now.size && [...now].every((name) => before.has(name)) ? before : now));
|
|
63
|
+
};
|
|
64
|
+
// A select sets its hidden input after the click or key that chose it,
|
|
65
|
+
// with no event of its own, from a list drawn outside the form - so
|
|
66
|
+
// clicks and keys anywhere are read a frame later.
|
|
67
|
+
const soon = () => requestAnimationFrame(update);
|
|
68
|
+
const typed = [['input', update], ['change', update]];
|
|
69
|
+
const chosen = [['click', soon], ['keyup', soon]];
|
|
70
|
+
for (const [name, listener] of typed)
|
|
71
|
+
element.addEventListener(name, listener);
|
|
72
|
+
for (const [name, listener] of chosen)
|
|
73
|
+
document.addEventListener(name, listener);
|
|
74
|
+
return () => {
|
|
75
|
+
for (const [name, listener] of typed)
|
|
76
|
+
element.removeEventListener(name, listener);
|
|
77
|
+
for (const [name, listener] of chosen)
|
|
78
|
+
document.removeEventListener(name, listener);
|
|
79
|
+
};
|
|
80
|
+
}, [form, fields]);
|
|
81
|
+
return hidden;
|
|
82
|
+
}
|
|
83
|
+
function fieldOf(field, values, error) {
|
|
84
|
+
const id = `field-${field.name}`;
|
|
85
|
+
const invalid = !!error(field.name);
|
|
86
|
+
if (field.type === 'blocks') {
|
|
87
|
+
return _jsx(BlocksField, { field: field, value: values[field.name], error: error }, field.name);
|
|
88
|
+
}
|
|
89
|
+
if (field.type === 'toggle') {
|
|
90
|
+
return (_jsxs(Field, { orientation: "horizontal", "data-invalid": invalid || undefined, children: [_jsxs(FieldContent, { children: [_jsx(FieldLabel, { htmlFor: id, children: field.label }), field.description && _jsx(FieldDescription, { children: field.description }), invalid && _jsx(FieldError, { children: error(field.name) })] }), _jsx(Switch, { id: id, name: field.name, defaultChecked: Boolean(values[field.name]), "aria-invalid": invalid || undefined })] }, field.name));
|
|
91
|
+
}
|
|
92
|
+
return (_jsxs(Field, { "data-invalid": invalid || undefined, children: [_jsxs(FieldLabel, { htmlFor: id, children: [field.label, field.required && _jsx("span", { className: "text-destructive", children: "*" })] }), field.type === 'file' || field.type === 'image' ? (_jsx(FileControl, { id: id, field: field, value: values[field.name], invalid: invalid }, String(values[field.name] ?? ''))) : (_jsx(Control, { id: id, field: field, value: values[field.name], invalid: invalid })), (field.description ?? limitOf(field)) && _jsx(FieldDescription, { children: field.description ?? limitOf(field) }), invalid && _jsx(FieldError, { children: error(field.name) })] }, field.name));
|
|
93
|
+
}
|
|
32
94
|
/**
|
|
33
95
|
* A list of blocks an editor adds, orders and removes, each with its own
|
|
34
96
|
* fields. Every control stays an ordinary named input - block i's heading is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../../src/shadcn/fields.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { useEffect, useId, useState } from 'react'\nimport { ArrowDown, ArrowUp, FileIcon, Plus, Trash2 } from 'lucide-react'\nimport type { BlockSpec, Field as FieldSpec } from '../resource.js'\nimport { sizeOf } from '../uploads.js'\nimport { Button } from './components/ui/button.js'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from './components/ui/dropdown-menu.js'\nimport { Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSet } from './components/ui/field.js'\nimport { Input } from './components/ui/input.js'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './components/ui/select.js'\nimport { Switch } from './components/ui/switch.js'\nimport { Textarea } from './components/ui/textarea.js'\n\n/**\n * Each field as its shadcn control, labelled, with its message under it: the\n * browser's while the value is still wrong, else the server's. Shared by the\n * panel's forms and the public ones, so a field looks and checks the same in\n * both.\n */\nexport function FieldList({ fields, values, error }: { fields: FieldSpec[]; values: Record<string, unknown>; error: (name: string) => string | undefined }) {\n return fields.map((field) => {\n const id = `field-${field.name}`\n const invalid = !!error(field.name)\n\n if (field.type === 'blocks') {\n return <BlocksField key={field.name} field={field} value={values[field.name]} error={error} />\n }\n\n if (field.type === 'toggle') {\n return (\n <Field key={field.name} orientation=\"horizontal\" data-invalid={invalid || undefined}>\n <FieldContent>\n <FieldLabel htmlFor={id}>{field.label}</FieldLabel>\n {field.description && <FieldDescription>{field.description}</FieldDescription>}\n {invalid && <FieldError>{error(field.name)}</FieldError>}\n </FieldContent>\n <Switch id={id} name={field.name} defaultChecked={Boolean(values[field.name])} aria-invalid={invalid || undefined} />\n </Field>\n )\n }\n\n return (\n <Field key={field.name} data-invalid={invalid || undefined}>\n <FieldLabel htmlFor={id}>\n {field.label}\n {field.required && <span className=\"text-destructive\">*</span>}\n </FieldLabel>\n {field.type === 'file' || field.type === 'image' ? (\n <FileControl key={String(values[field.name] ?? '')} id={id} field={field} value={values[field.name]} invalid={invalid} />\n ) : (\n <Control id={id} field={field} value={values[field.name]} invalid={invalid} />\n )}\n {(field.description ?? limitOf(field)) && <FieldDescription>{field.description ?? limitOf(field)}</FieldDescription>}\n {invalid && <FieldError>{error(field.name)}</FieldError>}\n </Field>\n )\n })\n}\n\ninterface Item {\n key: string\n type: string\n data: Record<string, unknown>\n}\n\n/**\n * A list of blocks an editor adds, orders and removes, each with its own\n * fields. Every control stays an ordinary named input - block i's heading is\n * `content.i.heading` - so it submits with the form, is checked by the\n * browser like any other, and shows the server's refusal under itself. Each\n * block keeps a key of its own, so moving one moves what was typed into it.\n */\nfunction BlocksField({ field, value, error }: { field: FieldSpec; value: unknown; error: (name: string) => string | undefined }) {\n const kinds = field.blocks ?? []\n const prefix = useId()\n const saved = Array.isArray(value) ? (value as { type: string; data?: Record<string, unknown> }[]) : []\n // A kind the app no longer offers has no fields to draw; it is left out,\n // and saving drops it.\n const retired = saved.filter((item) => !kinds.some((kind) => kind.name === item.type)).length\n const [items, setItems] = useState<Item[]>(() =>\n saved\n .filter((item) => kinds.some((kind) => kind.name === item.type))\n .map((item, index) => ({ key: `${prefix}-${index}`, type: item.type, data: item.data ?? {} })),\n )\n const [made, setMade] = useState(0)\n\n const add = (kind: BlockSpec) => {\n setItems((current) => [...current, { key: `${prefix}-new-${made}`, type: kind.name, data: {} }])\n setMade((count) => count + 1)\n }\n\n const move = (from: number, to: number) =>\n setItems((current) => {\n const next = [...current]\n const [item] = next.splice(from, 1)\n\n next.splice(to, 0, item!)\n\n return next\n })\n\n const remove = (at: number) => setItems((current) => current.filter((_, index) => index !== at))\n\n return (\n <FieldSet>\n <FieldLegend variant=\"label\">{field.label}</FieldLegend>\n {field.description && <FieldDescription>{field.description}</FieldDescription>}\n {items.length === 0 && <p className=\"text-sm text-muted-foreground\">No blocks yet.</p>}\n {retired > 0 && (\n <p className=\"text-sm text-muted-foreground\">\n {retired === 1 ? 'One block is' : `${retired} blocks are`} of a kind no longer offered, and saving removes {retired === 1 ? 'it' : 'them'}.\n </p>\n )}\n {items.map((item, index) => {\n const kind = kinds.find((candidate) => candidate.name === item.type)!\n const base = `${field.name}.${index}.`\n\n return (\n <div key={item.key} className=\"rounded-lg border\">\n <div className=\"flex items-center gap-1 border-b px-3 py-2\">\n <span className=\"text-sm font-medium\">{kind.label}</span>\n <input type=\"hidden\" name={`${base}type`} value={item.type} />\n <div className=\"ml-auto flex gap-1\">\n <Button type=\"button\" variant=\"ghost\" size=\"icon-sm\" aria-label=\"Move up\" disabled={index === 0} onClick={() => move(index, index - 1)}>\n <ArrowUp />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label=\"Move down\"\n disabled={index === items.length - 1}\n onClick={() => move(index, index + 1)}\n >\n <ArrowDown />\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"icon-sm\" aria-label=\"Remove\" onClick={() => remove(index)}>\n <Trash2 />\n </Button>\n </div>\n </div>\n <div className=\"p-3\">\n <FieldGroup>\n <FieldList\n fields={kind.fields.map((inner) => ({ ...inner, name: base + inner.name }))}\n values={Object.fromEntries(Object.entries(item.data).map(([name, data]) => [base + name, data]))}\n error={error}\n />\n </FieldGroup>\n </div>\n {error(`${field.name}.${index}`) && <FieldError className=\"px-3 pb-3\">{error(`${field.name}.${index}`)}</FieldError>}\n </div>\n )\n })}\n <div>\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button type=\"button\" variant=\"outline\" />}>\n <Plus />\n Add block\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n {kinds.map((kind) => (\n <DropdownMenuItem key={kind.name} onClick={() => add(kind)}>\n {kind.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </FieldSet>\n )\n}\n\ntype Control = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement\n\nconst isControl = (target: EventTarget | null): target is Control =>\n target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement\n\n/**\n * The browser's own validation, shown the shadcn way. A submit fires\n * 'invalid' at each control that fails its constraints; that is cancelled -\n * no bubble - and its validationMessage, in the visitor's language, is kept\n * under its name. Fixing the value clears it. 'invalid' does not bubble, so\n * the form listens in the capture phase.\n */\nexport function useBrowserErrors(form: React.RefObject<HTMLFormElement | null>): Record<string, string> {\n const [errors, setErrors] = useState<Record<string, string>>({})\n\n useEffect(() => {\n const element = form.current\n\n if (!element) return\n\n let focusing = false\n\n const onInvalid = (event: Event) => {\n if (!isControl(event.target) || !event.target.name) return\n\n const { name, validationMessage } = event.target\n\n event.preventDefault()\n setErrors((current) => (current[name] === validationMessage ? current : { ...current, [name]: validationMessage }))\n\n // Cancelling the bubble also cancels the browser's focus on the first\n // wrong field. Every control's 'invalid' fires before the next task, so\n // give focus back once, to the first one, after they all have.\n if (!focusing) {\n focusing = true\n setTimeout(() => {\n focusing = false\n element.querySelector<Control>(':invalid')?.focus()\n })\n }\n }\n\n const onEdit = (event: Event) => {\n if (!isControl(event.target) || !event.target.name) return\n\n const { name, validity, validationMessage } = event.target\n\n setErrors((current) => {\n if (!(name in current)) return current\n if (!validity.valid) return { ...current, [name]: validationMessage }\n\n const { [name]: _, ...rest } = current\n\n return rest\n })\n }\n\n element.addEventListener('invalid', onInvalid, true)\n element.addEventListener('input', onEdit)\n element.addEventListener('change', onEdit)\n\n return () => {\n element.removeEventListener('invalid', onInvalid, true)\n element.removeEventListener('input', onEdit)\n element.removeEventListener('change', onEdit)\n }\n }, [form])\n\n return errors\n}\n\nfunction Control({ id, field, value, invalid }: { id: string; field: FieldSpec; value: unknown; invalid: boolean }) {\n const shared = {\n id,\n name: field.name,\n required: field.required,\n 'aria-invalid': invalid || undefined,\n }\n const lengths = { minLength: field.minLength, maxLength: field.maxLength }\n\n switch (field.type) {\n case 'textarea':\n return <Textarea {...shared} {...lengths} rows={4} defaultValue={String(value ?? '')} />\n case 'select': {\n // An optional select can be left empty: its first choice is \"None\",\n // which arrives as \"\" and is left out of the values, as any empty\n // optional field is. A required one starts on its first real choice.\n const options = field.required ? (field.options ?? []) : [{ value: '', label: 'None' }, ...(field.options ?? [])]\n\n return (\n <Select name={field.name} items={options} defaultValue={value === null || value === undefined ? (options[0]?.value ?? '') : String(value)}>\n <SelectTrigger id={id} aria-invalid={invalid || undefined} className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n }\n case 'number':\n return (\n <Input\n {...shared}\n type=\"number\"\n min={field.min}\n max={field.max}\n step={field.step ?? 'any'}\n defaultValue={value === undefined || value === null ? '' : String(value)}\n />\n )\n case 'email':\n return <Input {...shared} {...lengths} type=\"email\" defaultValue={String(value ?? '')} />\n case 'date':\n return <Input {...shared} type=\"date\" defaultValue={String(value ?? '').slice(0, 10)} />\n default:\n return <Input {...shared} {...lengths} pattern={field.pattern} defaultValue={String(value ?? '')} />\n }\n}\n\n/** A file field's size limit, said under it when the app said nothing else. */\nfunction limitOf(field: FieldSpec): string | undefined {\n return (field.type === 'file' || field.type === 'image') && field.maxSize !== undefined ? `Up to ${sizeOf(field.maxSize)}.` : undefined\n}\n\n/**\n * A file or image field: what it holds now, and a file input to replace it.\n * The value it holds goes back with the form in a hidden input under the\n * same name, so a save that chooses nothing keeps it; the server keeps it\n * only if the record already had it. A file over the size limit is refused\n * as it is chosen, through the input's own validity, so it shows as any\n * other field's message and never makes the trip.\n */\nfunction FileControl({ id, field, value, invalid }: { id: string; field: FieldSpec; value: unknown; invalid: boolean }) {\n const [kept, setKept] = useState(typeof value === 'string' ? value : '')\n const [preview, setPreview] = useState<string | null>(null)\n\n useEffect(() => () => {\n if (preview) URL.revokeObjectURL(preview)\n }, [preview])\n\n const choose = (event: React.ChangeEvent<HTMLInputElement>) => {\n const input = event.currentTarget\n const file = input.files?.[0]\n\n input.setCustomValidity(file && field.maxSize !== undefined && file.size > field.maxSize ? `Choose a file of ${sizeOf(field.maxSize)} or less.` : '')\n setPreview(file && field.type === 'image' && input.validity.valid ? URL.createObjectURL(file) : null)\n }\n\n const shown = preview ?? (kept || null)\n\n return (\n <div className=\"flex flex-col gap-3\">\n {shown && field.type === 'image' && <img src={shown} alt=\"\" className=\"h-32 w-fit max-w-full rounded-md border object-cover\" />}\n {kept && !preview && field.type === 'file' && (\n <a href={kept} target=\"_blank\" rel=\"noreferrer\" className=\"flex w-fit items-center gap-2 text-sm underline-offset-4 hover:underline\">\n <FileIcon className=\"size-4\" />\n {decodeURIComponent(kept.split(/[/?#]/).filter(Boolean).pop() ?? kept)}\n </a>\n )}\n <div className=\"flex items-center gap-2\">\n <Input\n id={id}\n name={field.name}\n type=\"file\"\n accept={field.accept}\n required={field.required && !kept}\n aria-invalid={invalid || undefined}\n onChange={choose}\n />\n {kept && field.nullable && (\n <Button type=\"button\" variant=\"outline\" onClick={() => setKept('')}>\n Remove\n </Button>\n )}\n </div>\n <input type=\"hidden\" name={field.name} value={kept} />\n </div>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../../src/shadcn/fields.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { useEffect, useId, useState } from 'react'\nimport type { RefObject } from 'react'\nimport { shown, slugify } from '../conditions.js'\nimport type { Read } from '../conditions.js'\nimport { ArrowDown, ArrowUp, FileIcon, Plus, Trash2 } from 'lucide-react'\nimport type { BlockSpec, Field as FieldSpec } from '../resource.js'\nimport { sizeOf } from '../uploads.js'\nimport { Button } from './components/ui/button.js'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from './components/ui/dropdown-menu.js'\nimport { Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSet } from './components/ui/field.js'\nimport { Input } from './components/ui/input.js'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './components/ui/select.js'\nimport { Switch } from './components/ui/switch.js'\nimport { Textarea } from './components/ui/textarea.js'\n\n/**\n * Each field as its shadcn control, labelled, with its message under it: the\n * browser's while the value is still wrong, else the server's. Shared by the\n * panel's forms and the public ones, so a field looks and checks the same in\n * both.\n */\nexport function FieldList({\n fields,\n values,\n error,\n hidden,\n}: {\n fields: FieldSpec[]\n values: Record<string, unknown>\n error: (name: string) => string | undefined\n /** The fields whose condition hides them now, from useConditions. */\n hidden?: ReadonlySet<string>\n}) {\n return fields.map((field) => {\n const control = fieldOf(field, values, error)\n\n if (!field.visible) return control\n\n // Disabled, a hidden field's controls are neither sent nor checked by the browser.\n const off = hidden?.has(field.name) ?? false\n\n return (\n <fieldset key={field.name} disabled={off} hidden={off} className={off ? 'hidden' : 'contents'}>\n {control}\n </fieldset>\n )\n })\n}\n\n/**\n * The fields' conditions and slugs, applied while the visitor types: which\n * fields are hidden now, read from the form's own controls - the form stays\n * uncontrolled, so nothing typed is lost to a render. A slug follows its\n * source until it is edited by hand. The server applies both again.\n */\nexport function useConditions(form: RefObject<HTMLFormElement | null>, fields: FieldSpec[], values: Record<string, unknown>): ReadonlySet<string> {\n const initial: Read = (name) => {\n const value = values[name]\n\n return typeof value === 'boolean' ? value : value === undefined || value === null ? '' : String(value)\n }\n const [hidden, setHidden] = useState<ReadonlySet<string>>(() => new Set(fields.filter((field) => field.visible && !shown(field.visible, initial)).map((field) => field.name)))\n\n useEffect(() => {\n const element = form.current\n const conditional = fields.filter((field) => field.visible)\n const derived = fields.filter((field) => field.from)\n\n if (!element || (conditional.length === 0 && derived.length === 0)) return\n\n const types = new Map(fields.map((field) => [field.name, field.type]))\n // What each slug was last made as: it follows while it still says that.\n const last = new Map(derived.map((field) => [field.name, slugify(String(initial(field.from!.field)))]))\n\n const update = () => {\n const data = new FormData(element)\n const read: Read = (name) => (types.get(name) === 'toggle' ? data.has(name) : String(data.get(name) ?? ''))\n\n for (const field of derived) {\n const target = element.elements.namedItem(field.name)\n const made = slugify(String(read(field.from!.field)))\n\n if (target instanceof HTMLInputElement && (target.value === '' || target.value === last.get(field.name))) target.value = made\n\n last.set(field.name, made)\n }\n\n const now = new Set(conditional.filter((field) => !shown(field.visible!, read)).map((field) => field.name))\n\n setHidden((before) => (before.size === now.size && [...now].every((name) => before.has(name)) ? before : now))\n }\n // A select sets its hidden input after the click or key that chose it,\n // with no event of its own, from a list drawn outside the form - so\n // clicks and keys anywhere are read a frame later.\n const soon = () => requestAnimationFrame(update)\n const typed = [['input', update], ['change', update]] as const\n const chosen = [['click', soon], ['keyup', soon]] as const\n\n for (const [name, listener] of typed) element.addEventListener(name, listener)\n for (const [name, listener] of chosen) document.addEventListener(name, listener)\n\n return () => {\n for (const [name, listener] of typed) element.removeEventListener(name, listener)\n for (const [name, listener] of chosen) document.removeEventListener(name, listener)\n }\n }, [form, fields])\n\n return hidden\n}\n\nfunction fieldOf(field: FieldSpec, values: Record<string, unknown>, error: (name: string) => string | undefined) {\n const id = `field-${field.name}`\n const invalid = !!error(field.name)\n\n if (field.type === 'blocks') {\n return <BlocksField key={field.name} field={field} value={values[field.name]} error={error} />\n }\n\n if (field.type === 'toggle') {\n return (\n <Field key={field.name} orientation=\"horizontal\" data-invalid={invalid || undefined}>\n <FieldContent>\n <FieldLabel htmlFor={id}>{field.label}</FieldLabel>\n {field.description && <FieldDescription>{field.description}</FieldDescription>}\n {invalid && <FieldError>{error(field.name)}</FieldError>}\n </FieldContent>\n <Switch id={id} name={field.name} defaultChecked={Boolean(values[field.name])} aria-invalid={invalid || undefined} />\n </Field>\n )\n }\n\n return (\n <Field key={field.name} data-invalid={invalid || undefined}>\n <FieldLabel htmlFor={id}>\n {field.label}\n {field.required && <span className=\"text-destructive\">*</span>}\n </FieldLabel>\n {field.type === 'file' || field.type === 'image' ? (\n <FileControl key={String(values[field.name] ?? '')} id={id} field={field} value={values[field.name]} invalid={invalid} />\n ) : (\n <Control id={id} field={field} value={values[field.name]} invalid={invalid} />\n )}\n {(field.description ?? limitOf(field)) && <FieldDescription>{field.description ?? limitOf(field)}</FieldDescription>}\n {invalid && <FieldError>{error(field.name)}</FieldError>}\n </Field>\n )\n}\n\ninterface Item {\n key: string\n type: string\n data: Record<string, unknown>\n}\n\n/**\n * A list of blocks an editor adds, orders and removes, each with its own\n * fields. Every control stays an ordinary named input - block i's heading is\n * `content.i.heading` - so it submits with the form, is checked by the\n * browser like any other, and shows the server's refusal under itself. Each\n * block keeps a key of its own, so moving one moves what was typed into it.\n */\nfunction BlocksField({ field, value, error }: { field: FieldSpec; value: unknown; error: (name: string) => string | undefined }) {\n const kinds = field.blocks ?? []\n const prefix = useId()\n const saved = Array.isArray(value) ? (value as { type: string; data?: Record<string, unknown> }[]) : []\n // A kind the app no longer offers has no fields to draw; it is left out,\n // and saving drops it.\n const retired = saved.filter((item) => !kinds.some((kind) => kind.name === item.type)).length\n const [items, setItems] = useState<Item[]>(() =>\n saved\n .filter((item) => kinds.some((kind) => kind.name === item.type))\n .map((item, index) => ({ key: `${prefix}-${index}`, type: item.type, data: item.data ?? {} })),\n )\n const [made, setMade] = useState(0)\n\n const add = (kind: BlockSpec) => {\n setItems((current) => [...current, { key: `${prefix}-new-${made}`, type: kind.name, data: {} }])\n setMade((count) => count + 1)\n }\n\n const move = (from: number, to: number) =>\n setItems((current) => {\n const next = [...current]\n const [item] = next.splice(from, 1)\n\n next.splice(to, 0, item!)\n\n return next\n })\n\n const remove = (at: number) => setItems((current) => current.filter((_, index) => index !== at))\n\n return (\n <FieldSet>\n <FieldLegend variant=\"label\">{field.label}</FieldLegend>\n {field.description && <FieldDescription>{field.description}</FieldDescription>}\n {items.length === 0 && <p className=\"text-sm text-muted-foreground\">No blocks yet.</p>}\n {retired > 0 && (\n <p className=\"text-sm text-muted-foreground\">\n {retired === 1 ? 'One block is' : `${retired} blocks are`} of a kind no longer offered, and saving removes {retired === 1 ? 'it' : 'them'}.\n </p>\n )}\n {items.map((item, index) => {\n const kind = kinds.find((candidate) => candidate.name === item.type)!\n const base = `${field.name}.${index}.`\n\n return (\n <div key={item.key} className=\"rounded-lg border\">\n <div className=\"flex items-center gap-1 border-b px-3 py-2\">\n <span className=\"text-sm font-medium\">{kind.label}</span>\n <input type=\"hidden\" name={`${base}type`} value={item.type} />\n <div className=\"ml-auto flex gap-1\">\n <Button type=\"button\" variant=\"ghost\" size=\"icon-sm\" aria-label=\"Move up\" disabled={index === 0} onClick={() => move(index, index - 1)}>\n <ArrowUp />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label=\"Move down\"\n disabled={index === items.length - 1}\n onClick={() => move(index, index + 1)}\n >\n <ArrowDown />\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"icon-sm\" aria-label=\"Remove\" onClick={() => remove(index)}>\n <Trash2 />\n </Button>\n </div>\n </div>\n <div className=\"p-3\">\n <FieldGroup>\n <FieldList\n fields={kind.fields.map((inner) => ({ ...inner, name: base + inner.name }))}\n values={Object.fromEntries(Object.entries(item.data).map(([name, data]) => [base + name, data]))}\n error={error}\n />\n </FieldGroup>\n </div>\n {error(`${field.name}.${index}`) && <FieldError className=\"px-3 pb-3\">{error(`${field.name}.${index}`)}</FieldError>}\n </div>\n )\n })}\n <div>\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button type=\"button\" variant=\"outline\" />}>\n <Plus />\n Add block\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n {kinds.map((kind) => (\n <DropdownMenuItem key={kind.name} onClick={() => add(kind)}>\n {kind.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </FieldSet>\n )\n}\n\ntype Control = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement\n\nconst isControl = (target: EventTarget | null): target is Control =>\n target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement\n\n/**\n * The browser's own validation, shown the shadcn way. A submit fires\n * 'invalid' at each control that fails its constraints; that is cancelled -\n * no bubble - and its validationMessage, in the visitor's language, is kept\n * under its name. Fixing the value clears it. 'invalid' does not bubble, so\n * the form listens in the capture phase.\n */\nexport function useBrowserErrors(form: React.RefObject<HTMLFormElement | null>): Record<string, string> {\n const [errors, setErrors] = useState<Record<string, string>>({})\n\n useEffect(() => {\n const element = form.current\n\n if (!element) return\n\n let focusing = false\n\n const onInvalid = (event: Event) => {\n if (!isControl(event.target) || !event.target.name) return\n\n const { name, validationMessage } = event.target\n\n event.preventDefault()\n setErrors((current) => (current[name] === validationMessage ? current : { ...current, [name]: validationMessage }))\n\n // Cancelling the bubble also cancels the browser's focus on the first\n // wrong field. Every control's 'invalid' fires before the next task, so\n // give focus back once, to the first one, after they all have.\n if (!focusing) {\n focusing = true\n setTimeout(() => {\n focusing = false\n element.querySelector<Control>(':invalid')?.focus()\n })\n }\n }\n\n const onEdit = (event: Event) => {\n if (!isControl(event.target) || !event.target.name) return\n\n const { name, validity, validationMessage } = event.target\n\n setErrors((current) => {\n if (!(name in current)) return current\n if (!validity.valid) return { ...current, [name]: validationMessage }\n\n const { [name]: _, ...rest } = current\n\n return rest\n })\n }\n\n element.addEventListener('invalid', onInvalid, true)\n element.addEventListener('input', onEdit)\n element.addEventListener('change', onEdit)\n\n return () => {\n element.removeEventListener('invalid', onInvalid, true)\n element.removeEventListener('input', onEdit)\n element.removeEventListener('change', onEdit)\n }\n }, [form])\n\n return errors\n}\n\nfunction Control({ id, field, value, invalid }: { id: string; field: FieldSpec; value: unknown; invalid: boolean }) {\n const shared = {\n id,\n name: field.name,\n required: field.required,\n 'aria-invalid': invalid || undefined,\n }\n const lengths = { minLength: field.minLength, maxLength: field.maxLength }\n\n switch (field.type) {\n case 'textarea':\n return <Textarea {...shared} {...lengths} rows={4} defaultValue={String(value ?? '')} />\n case 'select': {\n // An optional select can be left empty: its first choice is \"None\",\n // which arrives as \"\" and is left out of the values, as any empty\n // optional field is. A required one starts on its first real choice.\n const options = field.required ? (field.options ?? []) : [{ value: '', label: 'None' }, ...(field.options ?? [])]\n\n return (\n <Select name={field.name} items={options} defaultValue={value === null || value === undefined ? (options[0]?.value ?? '') : String(value)}>\n <SelectTrigger id={id} aria-invalid={invalid || undefined} className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n }\n case 'number':\n return (\n <Input\n {...shared}\n type=\"number\"\n min={field.min}\n max={field.max}\n step={field.step ?? 'any'}\n defaultValue={value === undefined || value === null ? '' : String(value)}\n />\n )\n case 'email':\n return <Input {...shared} {...lengths} type=\"email\" defaultValue={String(value ?? '')} />\n case 'date':\n return <Input {...shared} type=\"date\" defaultValue={String(value ?? '').slice(0, 10)} />\n default:\n return <Input {...shared} {...lengths} pattern={field.pattern} defaultValue={String(value ?? '')} />\n }\n}\n\n/** A file field's size limit, said under it when the app said nothing else. */\nfunction limitOf(field: FieldSpec): string | undefined {\n return (field.type === 'file' || field.type === 'image') && field.maxSize !== undefined ? `Up to ${sizeOf(field.maxSize)}.` : undefined\n}\n\n/**\n * A file or image field: what it holds now, and a file input to replace it.\n * The value it holds goes back with the form in a hidden input under the\n * same name, so a save that chooses nothing keeps it; the server keeps it\n * only if the record already had it. A file over the size limit is refused\n * as it is chosen, through the input's own validity, so it shows as any\n * other field's message and never makes the trip.\n */\nfunction FileControl({ id, field, value, invalid }: { id: string; field: FieldSpec; value: unknown; invalid: boolean }) {\n const [kept, setKept] = useState(typeof value === 'string' ? value : '')\n const [preview, setPreview] = useState<string | null>(null)\n\n useEffect(() => () => {\n if (preview) URL.revokeObjectURL(preview)\n }, [preview])\n\n const choose = (event: React.ChangeEvent<HTMLInputElement>) => {\n const input = event.currentTarget\n const file = input.files?.[0]\n\n input.setCustomValidity(file && field.maxSize !== undefined && file.size > field.maxSize ? `Choose a file of ${sizeOf(field.maxSize)} or less.` : '')\n setPreview(file && field.type === 'image' && input.validity.valid ? URL.createObjectURL(file) : null)\n }\n\n const shown = preview ?? (kept || null)\n\n return (\n <div className=\"flex flex-col gap-3\">\n {shown && field.type === 'image' && <img src={shown} alt=\"\" className=\"h-32 w-fit max-w-full rounded-md border object-cover\" />}\n {kept && !preview && field.type === 'file' && (\n <a href={kept} target=\"_blank\" rel=\"noreferrer\" className=\"flex w-fit items-center gap-2 text-sm underline-offset-4 hover:underline\">\n <FileIcon className=\"size-4\" />\n {decodeURIComponent(kept.split(/[/?#]/).filter(Boolean).pop() ?? kept)}\n </a>\n )}\n <div className=\"flex items-center gap-2\">\n <Input\n id={id}\n name={field.name}\n type=\"file\"\n accept={field.accept}\n required={field.required && !kept}\n aria-invalid={invalid || undefined}\n onChange={choose}\n />\n {kept && field.nullable && (\n <Button type=\"button\" variant=\"outline\" onClick={() => setKept('')}>\n Remove\n </Button>\n )}\n </div>\n <input type=\"hidden\" name={field.name} value={kept} />\n </div>\n )\n}\n"]}
|
package/dist/shadcn/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AdminTheme } from '../admin/theme.js';
|
|
2
2
|
import type { FormsTheme } from '../forms/theme.js';
|
|
3
3
|
/**
|
|
4
|
-
* Panels and
|
|
4
|
+
* Panels and blueprints' forms drawn with shadcn/ui: its sidebar layout, data table, fields and
|
|
5
5
|
* cards, in the app's own theme variables, so it follows the app's colours,
|
|
6
6
|
* radius, fonts and dark mode. Its classes reach the app's stylesheet through
|
|
7
7
|
*
|
package/dist/shadcn/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { PanelBreadcrumbs } from './breadcrumbs.js';
|
|
2
2
|
import { DataTable } from './data-table.js';
|
|
3
3
|
import { PanelNav } from './nav.js';
|
|
4
|
-
import {
|
|
4
|
+
import { BlueprintForm } from './blueprint-form.js';
|
|
5
5
|
import { Brand, Cell, Dashboard, Form, Index, Loading, Plugins, Shell } from './pages.js';
|
|
6
6
|
import { TenantSwitcher } from './tenant-switcher.js';
|
|
7
7
|
import { UserMenu } from './user-menu.js';
|
|
8
8
|
/**
|
|
9
|
-
* Panels and
|
|
9
|
+
* Panels and blueprints' forms drawn with shadcn/ui: its sidebar layout, data table, fields and
|
|
10
10
|
* cards, in the app's own theme variables, so it follows the app's colours,
|
|
11
11
|
* radius, fonts and dark mode. Its classes reach the app's stylesheet through
|
|
12
12
|
*
|
|
@@ -26,6 +26,6 @@ export const shadcn = {
|
|
|
26
26
|
Plugins,
|
|
27
27
|
Cell,
|
|
28
28
|
Loading,
|
|
29
|
-
|
|
29
|
+
BlueprintForm,
|
|
30
30
|
};
|
|
31
31
|
//# sourceMappingURL=index.js.map
|
package/dist/shadcn/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/shadcn/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/shadcn/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACzF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,MAAM,GAA4B;IAC7C,KAAK;IACL,KAAK;IACL,cAAc;IACd,GAAG,EAAE,QAAQ;IACb,WAAW,EAAE,gBAAgB;IAC7B,QAAQ;IACR,SAAS;IACT,KAAK;IACL,KAAK,EAAE,SAAS;IAChB,IAAI;IACJ,OAAO;IACP,IAAI;IACJ,OAAO;IACP,aAAa;CACd,CAAA","sourcesContent":["import type { AdminTheme } from '../admin/theme.js'\nimport type { FormsTheme } from '../forms/theme.js'\nimport { PanelBreadcrumbs } from './breadcrumbs.js'\nimport { DataTable } from './data-table.js'\nimport { PanelNav } from './nav.js'\nimport { BlueprintForm } from './blueprint-form.js'\nimport { Brand, Cell, Dashboard, Form, Index, Loading, Plugins, Shell } from './pages.js'\nimport { TenantSwitcher } from './tenant-switcher.js'\nimport { UserMenu } from './user-menu.js'\n\n/**\n * Panels and blueprints' forms drawn with shadcn/ui: its sidebar layout, data table, fields and\n * cards, in the app's own theme variables, so it follows the app's colours,\n * radius, fonts and dark mode. Its classes reach the app's stylesheet through\n *\n * @import \"@rsc-kit/press/shadcn.css\";\n */\nexport const shadcn: AdminTheme & FormsTheme = {\n Shell,\n Brand,\n TenantSwitcher,\n Nav: PanelNav,\n Breadcrumbs: PanelBreadcrumbs,\n UserMenu,\n Dashboard,\n Index,\n Table: DataTable,\n Form,\n Plugins,\n Cell,\n Loading,\n BlueprintForm,\n}\n"]}
|