@spaethtech/svelte-ui 0.1.10 → 0.3.1-dev.10.ff03a8d
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/.claude/skills/svelte-ui/SKILL.md +118 -0
- package/.claude/skills/themes/SKILL.md +303 -0
- package/CLAUDE.md +248 -0
- package/README.md +180 -42
- package/dist/components/Alert.svelte +119 -0
- package/dist/components/Alert.svelte.d.ts +29 -0
- package/dist/components/Badge/Badge.svelte +142 -69
- package/dist/components/Badge/Badge.svelte.d.ts +26 -6
- package/dist/components/Badge/index.d.ts +1 -1
- package/dist/components/Badge/index.js +1 -1
- package/dist/components/Banner.svelte +133 -0
- package/dist/components/Banner.svelte.d.ts +31 -0
- package/dist/components/Button.svelte +240 -0
- package/dist/components/Button.svelte.d.ts +33 -0
- package/dist/components/ButtonDropdown.svelte +145 -0
- package/dist/components/ButtonDropdown.svelte.d.ts +31 -0
- package/dist/components/Calendar.svelte +259 -0
- package/dist/components/Calendar.svelte.d.ts +27 -0
- package/dist/components/Card.svelte +79 -0
- package/dist/components/Card.svelte.d.ts +17 -0
- package/dist/components/CardBody.svelte +41 -0
- package/dist/components/CardBody.svelte.d.ts +17 -0
- package/dist/components/CardFooter.svelte +51 -0
- package/dist/components/CardFooter.svelte.d.ts +16 -0
- package/dist/components/CardHeader.svelte +51 -0
- package/dist/components/CardHeader.svelte.d.ts +16 -0
- package/dist/components/Checkbox.svelte +131 -0
- package/dist/components/Checkbox.svelte.d.ts +16 -0
- package/dist/components/ConfirmDialog.svelte +103 -0
- package/dist/components/ConfirmDialog.svelte.d.ts +33 -0
- package/dist/components/DataTable.svelte +518 -0
- package/dist/components/DataTable.svelte.d.ts +74 -0
- package/dist/components/DatePicker.svelte +312 -0
- package/dist/components/DatePicker.svelte.d.ts +32 -0
- package/dist/components/DateTimeInput.svelte +93 -0
- package/dist/components/DateTimeInput.svelte.d.ts +20 -0
- package/dist/components/Dialog.svelte +151 -0
- package/dist/components/Dialog.svelte.d.ts +30 -0
- package/dist/components/{EmailInput/EmailInput.svelte → EmailInput.svelte} +17 -8
- package/dist/components/EmailInput.svelte.d.ts +21 -0
- package/dist/components/Input.svelte +369 -0
- package/dist/components/Input.svelte.d.ts +35 -0
- package/dist/components/{List/List.svelte → List.svelte} +194 -133
- package/dist/components/{List/List.svelte.d.ts → List.svelte.d.ts} +9 -1
- package/dist/components/Menu.svelte +117 -0
- package/dist/components/Menu.svelte.d.ts +20 -0
- package/dist/components/NotesEditor.svelte +127 -0
- package/dist/components/NotesEditor.svelte.d.ts +17 -0
- package/dist/components/{NumberInput/NumberInput.svelte → NumberInput.svelte} +146 -105
- package/dist/components/{NumberInput/NumberInput.svelte.d.ts → NumberInput.svelte.d.ts} +11 -4
- package/dist/components/PasswordInput.svelte +52 -0
- package/dist/components/PasswordInput.svelte.d.ts +20 -0
- package/dist/components/Popup.svelte +140 -0
- package/dist/components/Popup.svelte.d.ts +31 -0
- package/dist/components/Query.svelte +284 -0
- package/dist/components/Query.svelte.d.ts +15 -0
- package/dist/components/{Rating/Rating.svelte → Rating.svelte} +19 -10
- package/dist/components/Rating.svelte.d.ts +13 -0
- package/dist/components/{SearchInput/SearchInput.svelte → SearchInput.svelte} +19 -8
- package/dist/components/{SearchInput/SearchInput.svelte.d.ts → SearchInput.svelte.d.ts} +9 -2
- package/dist/components/{Select/Select.svelte → Select.svelte} +48 -76
- package/dist/components/{Select/Select.svelte.d.ts → Select.svelte.d.ts} +11 -1
- package/dist/components/SideBarMenu/SideBarMenu.svelte +724 -0
- package/dist/components/SideBarMenu/SideBarMenu.svelte.d.ts +109 -0
- package/dist/components/SideBarMenu/index.d.ts +2 -0
- package/dist/components/SideBarMenu/index.js +1 -0
- package/dist/components/TabStrip/TabStrip.svelte +384 -0
- package/dist/components/TabStrip/TabStrip.svelte.d.ts +50 -0
- package/dist/components/TabStrip/index.d.ts +3 -0
- package/dist/components/TabStrip/index.js +2 -0
- package/dist/components/{TextArea/TextArea.svelte → TextArea.svelte} +143 -112
- package/dist/components/TextArea.svelte.d.ts +38 -0
- package/dist/components/ThemeSelector.svelte +81 -0
- package/dist/components/ThemeSelector.svelte.d.ts +10 -0
- package/dist/components/TimePicker.svelte +148 -0
- package/dist/components/TimePicker.svelte.d.ts +28 -0
- package/dist/components/TimeRangeInput.svelte +203 -0
- package/dist/components/TimeRangeInput.svelte.d.ts +29 -0
- package/dist/components/TimeSpinner.svelte +202 -0
- package/dist/components/TimeSpinner.svelte.d.ts +26 -0
- package/dist/components/Toast/Toaster.svelte +51 -0
- package/dist/components/Toast/Toaster.svelte.d.ts +12 -0
- package/dist/components/Toast/toast.svelte.d.ts +29 -0
- package/dist/components/Toast/toast.svelte.js +27 -0
- package/dist/components/Toggle.svelte +93 -0
- package/dist/components/Toggle.svelte.d.ts +15 -0
- package/dist/data/dataset.d.ts +42 -0
- package/dist/data/dataset.js +3 -0
- package/dist/data/index.d.ts +3 -0
- package/dist/data/index.js +3 -0
- package/dist/data/query/ast.d.ts +62 -0
- package/dist/data/query/ast.js +12 -0
- package/dist/data/query/index.d.ts +3 -0
- package/dist/data/query/index.js +3 -0
- package/dist/data/query/lexer.d.ts +33 -0
- package/dist/data/query/lexer.js +225 -0
- package/dist/data/query/parser.d.ts +11 -0
- package/dist/data/query/parser.js +252 -0
- package/dist/data/table/grid.svelte.d.ts +57 -0
- package/dist/data/table/grid.svelte.js +139 -0
- package/dist/data/table/index.d.ts +2 -0
- package/dist/data/table/index.js +2 -0
- package/dist/data/table/types.d.ts +79 -0
- package/dist/index.d.ts +49 -22
- package/dist/index.js +46 -21
- package/dist/positioning/anchored.d.ts +61 -0
- package/dist/positioning/anchored.js +122 -0
- package/dist/positioning/tooltip.d.ts +41 -0
- package/dist/positioning/tooltip.js +147 -0
- package/dist/theme.css +205 -0
- package/dist/types/breakpoints.d.ts +24 -0
- package/dist/types/breakpoints.js +13 -0
- package/dist/types/responsive.d.ts +32 -0
- package/dist/types/responsive.js +54 -0
- package/dist/types/sizes.d.ts +10 -3
- package/dist/types/time.d.ts +19 -0
- package/dist/types/time.js +10 -0
- package/dist/types/variants.d.ts +8 -1
- package/dist/types/variants.js +16 -1
- package/docs/components.md +255 -0
- package/docs/examples.md +323 -0
- package/docs/paradigm.md +240 -0
- package/docs/themes.md +170 -0
- package/docs/usage.md +450 -0
- package/package.json +97 -63
- package/dist/components/Button/Button.svelte +0 -172
- package/dist/components/Button/Button.svelte.d.ts +0 -32
- package/dist/components/Button/index.d.ts +0 -1
- package/dist/components/Button/index.js +0 -1
- package/dist/components/Dialog/Dialog.svelte +0 -101
- package/dist/components/Dialog/Dialog.svelte.d.ts +0 -18
- package/dist/components/Dialog/index.d.ts +0 -1
- package/dist/components/Dialog/index.js +0 -1
- package/dist/components/ElementManager/ElementManager.svelte +0 -397
- package/dist/components/ElementManager/ElementManager.svelte.d.ts +0 -43
- package/dist/components/ElementManager/index.d.ts +0 -1
- package/dist/components/ElementManager/index.js +0 -1
- package/dist/components/EmailInput/EmailInput.svelte.d.ts +0 -14
- package/dist/components/EmailInput/index.d.ts +0 -1
- package/dist/components/EmailInput/index.js +0 -1
- package/dist/components/Icon/Icon.svelte +0 -74
- package/dist/components/Icon/Icon.svelte.d.ts +0 -13
- package/dist/components/Icon/index.d.ts +0 -1
- package/dist/components/Icon/index.js +0 -1
- package/dist/components/Input/Input.svelte +0 -268
- package/dist/components/Input/Input.svelte.d.ts +0 -18
- package/dist/components/Input/index.d.ts +0 -1
- package/dist/components/Input/index.js +0 -1
- package/dist/components/List/index.d.ts +0 -1
- package/dist/components/List/index.js +0 -1
- package/dist/components/ListItem/ListItem.svelte +0 -175
- package/dist/components/ListItem/ListItem.svelte.d.ts +0 -24
- package/dist/components/ListItem/index.d.ts +0 -2
- package/dist/components/ListItem/index.js +0 -2
- package/dist/components/ListView/ListView.svelte +0 -463
- package/dist/components/ListView/ListView.svelte.d.ts +0 -37
- package/dist/components/ListView/index.d.ts +0 -2
- package/dist/components/ListView/index.js +0 -2
- package/dist/components/NodeGraph/BaseNode.d.ts +0 -57
- package/dist/components/NodeGraph/BaseNode.js +0 -30
- package/dist/components/NodeGraph/Edge.svelte +0 -60
- package/dist/components/NodeGraph/Edge.svelte.d.ts +0 -16
- package/dist/components/NodeGraph/ExpressionEvaluator.d.ts +0 -82
- package/dist/components/NodeGraph/ExpressionEvaluator.js +0 -152
- package/dist/components/NodeGraph/Node.svelte +0 -100
- package/dist/components/NodeGraph/Node.svelte.d.ts +0 -10
- package/dist/components/NodeGraph/NodeGraph.svelte +0 -52
- package/dist/components/NodeGraph/NodeGraph.svelte.d.ts +0 -14
- package/dist/components/NodeGraph/NodeInstance.svelte.d.ts +0 -80
- package/dist/components/NodeGraph/NodeInstance.svelte.js +0 -241
- package/dist/components/NodeGraph/NodePort.svelte +0 -75
- package/dist/components/NodeGraph/NodePort.svelte.d.ts +0 -11
- package/dist/components/NodeGraph/decorators.d.ts +0 -81
- package/dist/components/NodeGraph/decorators.js +0 -148
- package/dist/components/NodeGraph/index.d.ts +0 -9
- package/dist/components/NodeGraph/index.js +0 -9
- package/dist/components/NodeGraph/types.d.ts +0 -94
- package/dist/components/NodeGraph/types.js +0 -33
- package/dist/components/NotesEditor/NotesEditor.svelte +0 -203
- package/dist/components/NotesEditor/NotesEditor.svelte.d.ts +0 -9
- package/dist/components/NotesEditor/index.d.ts +0 -1
- package/dist/components/NotesEditor/index.js +0 -1
- package/dist/components/NumberInput/index.d.ts +0 -1
- package/dist/components/NumberInput/index.js +0 -1
- package/dist/components/PasswordInput/PasswordInput.svelte +0 -41
- package/dist/components/PasswordInput/PasswordInput.svelte.d.ts +0 -13
- package/dist/components/PasswordInput/index.d.ts +0 -1
- package/dist/components/PasswordInput/index.js +0 -1
- package/dist/components/Popup/index.d.ts +0 -1
- package/dist/components/Popup/index.js +0 -1
- package/dist/components/Rating/Rating.svelte.d.ts +0 -7
- package/dist/components/Rating/index.d.ts +0 -1
- package/dist/components/Rating/index.js +0 -1
- package/dist/components/ScrollView/ScrollView.svelte +0 -285
- package/dist/components/ScrollView/ScrollView.svelte.d.ts +0 -19
- package/dist/components/ScrollView/index.d.ts +0 -1
- package/dist/components/ScrollView/index.js +0 -1
- package/dist/components/SearchInput/index.d.ts +0 -1
- package/dist/components/SearchInput/index.js +0 -1
- package/dist/components/Select/index.d.ts +0 -1
- package/dist/components/Select/index.js +0 -1
- package/dist/components/TextArea/TextArea.svelte.d.ts +0 -19
- package/dist/components/TextArea/index.d.ts +0 -1
- package/dist/components/TextArea/index.js +0 -1
- package/dist/components/ThemeSelector/ThemeSelector.svelte +0 -64
- package/dist/components/ThemeSelector/ThemeSelector.svelte.d.ts +0 -3
- package/dist/components/ThemeSelector/index.d.ts +0 -1
- package/dist/components/ThemeSelector/index.js +0 -1
- package/dist/components/TooltipHandler/TooltipHandler.svelte +0 -593
- package/dist/components/TooltipHandler/TooltipHandler.svelte.d.ts +0 -10
- package/dist/components/TooltipHandler/index.d.ts +0 -1
- package/dist/components/TooltipHandler/index.js +0 -1
- package/dist/styles/sizes.d.ts +0 -78
- package/dist/styles/sizes.js +0 -120
- package/dist/styles/variants.d.ts +0 -106
- package/dist/styles/variants.js +0 -194
- package/dist/types/ManagerTypes.d.ts +0 -42
- /package/dist/{types/ManagerTypes.js → data/table/types.js} +0 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
/**
|
|
3
|
+
* DataTable — config-driven, responsive 12-col data table over a DataGrid (svelte-ui/data).
|
|
4
|
+
* Selectable rows, expandable rows, per-row + bulk action menus, sortable headers, paginated footer.
|
|
5
|
+
* Styled on the svelte-ui theme; menus use the Popup/Menu primitives (top layer, flip vs viewport).
|
|
6
|
+
*
|
|
7
|
+
* Compound component: every control is built from our own core components — icon controls and
|
|
8
|
+
* pagination use <Button variant="ghost" size="sm">, per-page uses <Select size="sm">. No raw
|
|
9
|
+
* <button>/<select> (see CLAUDE.md "compound components").
|
|
10
|
+
*/
|
|
11
|
+
-->
|
|
12
|
+
<script lang="ts" generics="T">
|
|
13
|
+
import type { Snippet } from "svelte";
|
|
14
|
+
import IconDots from "~icons/mdi/dots-vertical";
|
|
15
|
+
import IconBulk from "~icons/mdi/format-list-checks";
|
|
16
|
+
import IconSortAsc from "~icons/mdi/sort-ascending";
|
|
17
|
+
import IconSortDesc from "~icons/mdi/sort-descending";
|
|
18
|
+
import IconSortNone from "~icons/mdi/sort";
|
|
19
|
+
import IconChevronRight from "~icons/mdi/chevron-right";
|
|
20
|
+
import IconChevronDown from "~icons/mdi/chevron-down";
|
|
21
|
+
import IconChevronUp from "~icons/mdi/chevron-up";
|
|
22
|
+
import IconExpandAll from "~icons/mdi/chevron-double-right";
|
|
23
|
+
import IconCollapseAll from "~icons/mdi/chevron-double-down";
|
|
24
|
+
import IconLoading from "~icons/mdi/loading";
|
|
25
|
+
import IconFirst from "~icons/mdi/page-first";
|
|
26
|
+
import IconPrev from "~icons/mdi/chevron-left";
|
|
27
|
+
import IconNext from "~icons/mdi/chevron-right";
|
|
28
|
+
import IconLast from "~icons/mdi/page-last";
|
|
29
|
+
import Button from "./Button.svelte";
|
|
30
|
+
import Select from "./Select.svelte";
|
|
31
|
+
import Checkbox from "./Checkbox.svelte";
|
|
32
|
+
import Menu from "./Menu.svelte";
|
|
33
|
+
import type { Column, GridPlacement, MenuItem, DataGrid } from "../data/table/index.js";
|
|
34
|
+
import type { Size } from "../types/sizes.js";
|
|
35
|
+
import { resolveScalar, type Responsive } from "../types/responsive.js";
|
|
36
|
+
import { variantToken, type Variant } from "../types/variants.js";
|
|
37
|
+
|
|
38
|
+
let {
|
|
39
|
+
grid,
|
|
40
|
+
selectable = false,
|
|
41
|
+
expandable = false,
|
|
42
|
+
reorderable = false,
|
|
43
|
+
expanded,
|
|
44
|
+
rowActions,
|
|
45
|
+
bulkActions,
|
|
46
|
+
onReorder,
|
|
47
|
+
size = "md",
|
|
48
|
+
truncate = true,
|
|
49
|
+
borderless = false,
|
|
50
|
+
variant,
|
|
51
|
+
}: {
|
|
52
|
+
grid: DataGrid<T>;
|
|
53
|
+
selectable?: boolean;
|
|
54
|
+
expandable?: boolean;
|
|
55
|
+
/** When true, each row gets up/down chevron buttons in the lead
|
|
56
|
+
* column and fires `onReorder(row, 'up'|'down')` when clicked.
|
|
57
|
+
* The consumer owns the actual swap (typically updating the
|
|
58
|
+
* `sortOrder` field of two rows). Buttons auto-disable at the
|
|
59
|
+
* ends of the visible page — with server pagination, this
|
|
60
|
+
* reorders WITHIN the visible page only. */
|
|
61
|
+
reorderable?: boolean;
|
|
62
|
+
expanded?: Snippet<[T]>;
|
|
63
|
+
rowActions?: (row: T) => MenuItem[];
|
|
64
|
+
bulkActions?: (selected: ReadonlySet<string>) => MenuItem[];
|
|
65
|
+
onReorder?: (row: T, direction: "up" | "down") => void;
|
|
66
|
+
/** Overall density tier. Scales the whole table uniformly:
|
|
67
|
+
* font-size (--ui-text-*), row/footer padding, inter-column
|
|
68
|
+
* gap, lead/tail control squares (--ui-height-*), and
|
|
69
|
+
* propagates to every inner Button / Checkbox / Select.
|
|
70
|
+
* Header text inherits the outer font-size — no separate
|
|
71
|
+
* axis. Default `'md'` matches the rest of svelte-ui. */
|
|
72
|
+
size?: Responsive<Size>;
|
|
73
|
+
/** Every header + body cell wrapper gets Tailwind's `truncate`
|
|
74
|
+
* (white-space:nowrap, overflow:hidden, text-overflow:ellipsis).
|
|
75
|
+
* Simple text cells render with ellipsis automatically. Compound
|
|
76
|
+
* cells (inline-flex wrappers, badges, buttons) clip at the
|
|
77
|
+
* right edge — to also get ellipsis on the inner text, the
|
|
78
|
+
* snippet's text span needs its own `truncate` class.
|
|
79
|
+
*
|
|
80
|
+
* Defaults to `true` — the "wrong" default is columns visually
|
|
81
|
+
* bleeding into their neighbours when a value doesn't fit its
|
|
82
|
+
* configured span. Pass `truncate={false}` if the consumer
|
|
83
|
+
* wants wrap-on-overflow (rare — usually you'd fix the span
|
|
84
|
+
* allocation instead). */
|
|
85
|
+
truncate?: boolean;
|
|
86
|
+
/** Drop the visible frame while keeping each section's 1px box: every section's border colour
|
|
87
|
+
* becomes its own background, so it vanishes per-section on a matching surface. Defaults `false`. */
|
|
88
|
+
borderless?: boolean;
|
|
89
|
+
/** Tints the whole table's interactive/section surfaces (row hover,
|
|
90
|
+
* header/footer bands) with a semantic colour instead of the neutral
|
|
91
|
+
* default. Points --ui-accent at the variant's token and re-mixes the
|
|
92
|
+
* --ui-color-hover/surface/active tints via the `.ui-accent` class.
|
|
93
|
+
* `ghost` additionally drops ALL section fills (bands + body) for a bare,
|
|
94
|
+
* see-through table. Omit for the default grey tint. */
|
|
95
|
+
variant?: Variant;
|
|
96
|
+
} = $props();
|
|
97
|
+
|
|
98
|
+
/** When a variant is set, override --ui-accent so the shared interactive
|
|
99
|
+
* tints re-mix from that colour (the `.ui-accent` class on the root does
|
|
100
|
+
* the actual re-mix). Neutral (text) default when unset. */
|
|
101
|
+
const accentVar = $derived(variant ? `--ui-accent: var(${variantToken[variant]});` : "");
|
|
102
|
+
|
|
103
|
+
/** Font size for the WHOLE table. Applied as `font-size` on the
|
|
104
|
+
* outer container; every descendant inherits via standard CSS
|
|
105
|
+
* cascade — headers, cells, footer text all follow. */
|
|
106
|
+
// DataTable's own density is set via inline-style CSS vars + cell padding that already bakes in its
|
|
107
|
+
// own `md:` responsive step — neither can be re-prefixed per size tier. So the TABLE'S density keys
|
|
108
|
+
// off the base tier of a responsive `size` (via resolveScalar); the responsive `size` is still passed
|
|
109
|
+
// through to child controls (Button/Select/Checkbox), which DO resize at every breakpoint.
|
|
110
|
+
const sSize = $derived(resolveScalar(size, "md"));
|
|
111
|
+
const textVar = $derived(
|
|
112
|
+
sSize === "lg" ? "var(--ui-text-lg)" : sSize === "md" ? "var(--ui-text)" : "var(--ui-text-sm)",
|
|
113
|
+
);
|
|
114
|
+
/** Control height for the icon-only Button squares in lead/tail
|
|
115
|
+
* columns AND the row minimum height. Matches Button/Checkbox
|
|
116
|
+
* defaults at each size (sm=24px, md=32px, lg=40px). */
|
|
117
|
+
const heightVar = $derived(
|
|
118
|
+
sSize === "lg"
|
|
119
|
+
? "var(--ui-height-lg)"
|
|
120
|
+
: sSize === "md"
|
|
121
|
+
? "var(--ui-height)"
|
|
122
|
+
: "var(--ui-height-sm)",
|
|
123
|
+
);
|
|
124
|
+
/** Cell padding scales with size. Mobile-first: base padding is
|
|
125
|
+
* tight; the md: variant applies at ≥ 768px so tables feel
|
|
126
|
+
* chunkier on desktop but stay dense on phones. */
|
|
127
|
+
const cellPad = $derived(
|
|
128
|
+
sSize === "lg"
|
|
129
|
+
? "py-3 px-4 md:py-4 md:px-5"
|
|
130
|
+
: sSize === "md"
|
|
131
|
+
? "py-2 px-3 md:py-3 md:px-4"
|
|
132
|
+
: "py-1 px-2 md:py-2 md:px-3",
|
|
133
|
+
);
|
|
134
|
+
/** Inter-column gap. Tracks the same size axis so lead/cell/tail
|
|
135
|
+
* spacing stays proportional to cell padding. */
|
|
136
|
+
const cellGap = $derived(sSize === "lg" ? "gap-3" : sSize === "md" ? "gap-2" : "gap-1");
|
|
137
|
+
|
|
138
|
+
const columns = $derived(grid.columns);
|
|
139
|
+
const hasLead = $derived(selectable || expandable || reorderable);
|
|
140
|
+
const hasTail = $derived(!!rowActions || !!bulkActions);
|
|
141
|
+
|
|
142
|
+
// Server-controlled fetch (a reactive query); mirror into the grid for selection/expansion logic.
|
|
143
|
+
const result = $derived(grid.fetch(grid.request));
|
|
144
|
+
const rows = $derived(result.current?.rows ?? grid.rows);
|
|
145
|
+
const total = $derived(result.current?.total ?? grid.total);
|
|
146
|
+
const pageCount = $derived(Math.max(1, Math.ceil(total / grid.perPage)));
|
|
147
|
+
// "Settled" = a result came back AND we're not fetching — only then is empty genuinely "No results".
|
|
148
|
+
const settled = $derived(!!result.current && !result.loading);
|
|
149
|
+
$effect(() => {
|
|
150
|
+
grid.loading = result.loading;
|
|
151
|
+
if (result.current) {
|
|
152
|
+
grid.rows = result.current.rows;
|
|
153
|
+
grid.total = result.current.total;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const sortKeyOf = (c: Column<T>) => c.sortKey ?? c.id;
|
|
158
|
+
|
|
159
|
+
function placement(bp: string, p: GridPlacement): string {
|
|
160
|
+
const prefix = bp === "base" ? "" : `${bp}:`;
|
|
161
|
+
const out: string[] = [];
|
|
162
|
+
if (p.hidden) out.push(`${prefix}hidden`);
|
|
163
|
+
else if (bp !== "base") out.push(`${prefix}block`);
|
|
164
|
+
if (p.span) out.push(`${prefix}col-span-${p.span}`);
|
|
165
|
+
if (p.start) out.push(`${prefix}col-start-${p.start}`);
|
|
166
|
+
if (p.row) out.push(`${prefix}row-start-${p.row}`);
|
|
167
|
+
return out.join(" ");
|
|
168
|
+
}
|
|
169
|
+
function cellClasses(col: Column<T>): string {
|
|
170
|
+
const bps = col.breakpoints ?? { base: { span: 12 } };
|
|
171
|
+
return Object.entries(bps)
|
|
172
|
+
.map(([bp, p]) => placement(bp, p))
|
|
173
|
+
.join(" ");
|
|
174
|
+
}
|
|
175
|
+
const alignClass = (col: Column<T>) =>
|
|
176
|
+
col.align === "end"
|
|
177
|
+
? "justify-end text-end"
|
|
178
|
+
: col.align === "center"
|
|
179
|
+
? "justify-center text-center"
|
|
180
|
+
: "justify-start text-start";
|
|
181
|
+
|
|
182
|
+
function rowClick(e: MouseEvent, id: string) {
|
|
183
|
+
if (!expandable) return;
|
|
184
|
+
const el = e.target as HTMLElement;
|
|
185
|
+
if (el.closest('a, button, input, select, textarea, label, [role="button"]')) return;
|
|
186
|
+
grid.toggleExpand(id);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// One shared Menu instance, anchored to whichever kebab/bulk button opened it.
|
|
190
|
+
let menuAnchor = $state<HTMLElement>();
|
|
191
|
+
let menuItems = $state<MenuItem[]>([]);
|
|
192
|
+
let menuOpen = $state(false);
|
|
193
|
+
function openMenu(e: MouseEvent, items: MenuItem[]) {
|
|
194
|
+
menuAnchor = e.currentTarget as HTMLElement;
|
|
195
|
+
menuItems = items;
|
|
196
|
+
menuOpen = true;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const rangeText = $derived(
|
|
200
|
+
total === 0
|
|
201
|
+
? "0 of 0"
|
|
202
|
+
: `${(grid.page - 1) * grid.perPage + 1}–${Math.min(grid.page * grid.perPage, total)} of ${total}`,
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
// Invisible icon-slot sizing for the empty-state spacer. Sized to
|
|
206
|
+
// heightVar via inline style at each use site (kept as a snippet
|
|
207
|
+
// of class + style below).
|
|
208
|
+
const spacerClass =
|
|
209
|
+
"inline-flex shrink-0 items-center justify-center [&_svg]:w-[1em] [&_svg]:h-[1em]";
|
|
210
|
+
const subtle = "[color:color-mix(in_srgb,var(--ui-color-text)_60%,transparent)]";
|
|
211
|
+
// Per-section borders: header, body, and footer each keep a FULL 1px border box, so the table height
|
|
212
|
+
// is fixed no matter the variant/borderless (nothing is ever added or removed — only colours change).
|
|
213
|
+
// Non-borderless → the standard tint calc (secondary @ --ui-tint-border); borderless → the section's
|
|
214
|
+
// own background, so it vanishes per-section on a matching surface (fixes the white-frame-on-a-coloured-
|
|
215
|
+
// surface bug). To avoid DOUBLING the horizontal separators, the body's top/bottom borders match its
|
|
216
|
+
// own background whenever the neighbouring header/footer is present (always, today) — so the header's
|
|
217
|
+
// bottom border and the footer's top border are the only horizontal lines; the body owns left/right.
|
|
218
|
+
// (If a header-less / footer-less mode is ever added, flip that edge to `bodyBorder` + round the corner.)
|
|
219
|
+
// `ghost` makes every section transparent (bands AND body) for a bare, see-through table.
|
|
220
|
+
const sectionBorder =
|
|
221
|
+
"color-mix(in srgb, var(--ui-color-secondary) var(--ui-tint-border), transparent)";
|
|
222
|
+
const bandBg = $derived(variant === "ghost" ? "transparent" : "var(--ui-color-surface)");
|
|
223
|
+
const bodyBg = $derived(variant === "ghost" ? "transparent" : "var(--ui-color-background)");
|
|
224
|
+
const bandBorder = $derived(borderless ? bandBg : sectionBorder); // header + footer, all 4 sides
|
|
225
|
+
const bodyBorder = $derived(borderless ? bodyBg : sectionBorder); // body left/right (top/bottom = bodyBg)
|
|
226
|
+
</script>
|
|
227
|
+
|
|
228
|
+
<div
|
|
229
|
+
role="table"
|
|
230
|
+
class="ui-accent relative [color:var(--ui-color-text)]"
|
|
231
|
+
style="font-size: {textVar}; {accentVar}"
|
|
232
|
+
>
|
|
233
|
+
<!-- Header. Font size inherits from the outer container; weight,
|
|
234
|
+
transform, and colour are library defaults (semibold, uppercase,
|
|
235
|
+
text token). Background is --ui-color-surface — the shared section
|
|
236
|
+
tint (a notch darker than the row-hover token), so header + footer
|
|
237
|
+
read as bands framing the interactive rows. -->
|
|
238
|
+
<div
|
|
239
|
+
role="row"
|
|
240
|
+
class="flex items-center font-semibold uppercase border
|
|
241
|
+
{cellGap} {cellPad}
|
|
242
|
+
[border-top-left-radius:var(--ui-border-radius)] [border-top-right-radius:var(--ui-border-radius)]
|
|
243
|
+
[color:var(--ui-color-text)]"
|
|
244
|
+
style="border-color: {bandBorder}; background-color: {bandBg}"
|
|
245
|
+
>
|
|
246
|
+
{#if hasLead}
|
|
247
|
+
<div class="flex shrink-0 items-center gap-1">
|
|
248
|
+
{#if selectable}
|
|
249
|
+
<Checkbox
|
|
250
|
+
{size}
|
|
251
|
+
aria-label="Select all"
|
|
252
|
+
checked={grid.allSelected}
|
|
253
|
+
indeterminate={grid.someSelected}
|
|
254
|
+
onchange={() => grid.toggleAll()}
|
|
255
|
+
/>
|
|
256
|
+
{/if}
|
|
257
|
+
{#if expandable}
|
|
258
|
+
<Button
|
|
259
|
+
variant="ghost"
|
|
260
|
+
{size}
|
|
261
|
+
aria-label={grid.allExpanded ? "Collapse all" : "Expand all"}
|
|
262
|
+
title={grid.allExpanded ? "Collapse all" : "Expand all"}
|
|
263
|
+
onclick={() => grid.toggleExpandAll()}
|
|
264
|
+
>
|
|
265
|
+
{#snippet icon()}{#if grid.allExpanded}<IconCollapseAll />{:else}<IconExpandAll
|
|
266
|
+
/>{/if}{/snippet}
|
|
267
|
+
</Button>
|
|
268
|
+
{/if}
|
|
269
|
+
{#if reorderable}
|
|
270
|
+
<!-- Placeholder pair to match the body-row column so header + body align. -->
|
|
271
|
+
<span
|
|
272
|
+
class={spacerClass}
|
|
273
|
+
style="width: {heightVar}; height: {heightVar}"
|
|
274
|
+
aria-hidden="true"
|
|
275
|
+
></span>
|
|
276
|
+
<span
|
|
277
|
+
class={spacerClass}
|
|
278
|
+
style="width: {heightVar}; height: {heightVar}"
|
|
279
|
+
aria-hidden="true"
|
|
280
|
+
></span>
|
|
281
|
+
{/if}
|
|
282
|
+
</div>
|
|
283
|
+
{/if}
|
|
284
|
+
|
|
285
|
+
<div class="grid grow grid-cols-12 items-center {cellGap}">
|
|
286
|
+
{#each columns as col (col.id)}
|
|
287
|
+
<div
|
|
288
|
+
role="columnheader"
|
|
289
|
+
class="{cellClasses(col)} flex min-w-0 items-center {alignClass(col)} {truncate
|
|
290
|
+
? 'truncate'
|
|
291
|
+
: ''}"
|
|
292
|
+
>
|
|
293
|
+
{#if col.sortable}
|
|
294
|
+
<Button
|
|
295
|
+
variant="ghost"
|
|
296
|
+
{size}
|
|
297
|
+
class="!px-0 [font-size:inherit]"
|
|
298
|
+
onclick={() => grid.toggleSort(sortKeyOf(col))}
|
|
299
|
+
>
|
|
300
|
+
<span>{col.header ?? col.id}</span>
|
|
301
|
+
{#if grid.sort?.col === sortKeyOf(col)}
|
|
302
|
+
{#if grid.sort.dir === "asc"}<IconSortAsc
|
|
303
|
+
class="w-[1em] h-[1em]"
|
|
304
|
+
/>{:else}<IconSortDesc class="w-[1em] h-[1em]" />{/if}
|
|
305
|
+
{:else}
|
|
306
|
+
<IconSortNone class="w-[1em] h-[1em] opacity-40" />
|
|
307
|
+
{/if}
|
|
308
|
+
</Button>
|
|
309
|
+
{:else}
|
|
310
|
+
<span>{col.header ?? col.id}</span>
|
|
311
|
+
{/if}
|
|
312
|
+
</div>
|
|
313
|
+
{/each}
|
|
314
|
+
</div>
|
|
315
|
+
|
|
316
|
+
{#if hasTail}
|
|
317
|
+
<div class="flex shrink-0 items-center justify-end" style="width: {heightVar}">
|
|
318
|
+
{#if bulkActions && selectable}
|
|
319
|
+
<Button
|
|
320
|
+
variant="ghost"
|
|
321
|
+
{size}
|
|
322
|
+
aria-label="Bulk actions"
|
|
323
|
+
title="Bulk actions"
|
|
324
|
+
disabled={grid.selected.size === 0}
|
|
325
|
+
onclick={(e) => openMenu(e, bulkActions(grid.selected))}
|
|
326
|
+
>
|
|
327
|
+
{#snippet icon()}<IconBulk />{/snippet}
|
|
328
|
+
</Button>
|
|
329
|
+
{/if}
|
|
330
|
+
</div>
|
|
331
|
+
{/if}
|
|
332
|
+
</div>
|
|
333
|
+
|
|
334
|
+
<!-- Body — its own full 1px border box (fixed height). Top/bottom match the body bg so they don't
|
|
335
|
+
double the header's bottom / footer's top border; left/right carry the real border colour. -->
|
|
336
|
+
<div
|
|
337
|
+
class="border"
|
|
338
|
+
style="border-color: {bodyBg}; border-left-color: {bodyBorder}; border-right-color: {bodyBorder}; background-color: {bodyBg}"
|
|
339
|
+
>
|
|
340
|
+
{#if rows.length === 0}
|
|
341
|
+
<div class="flex items-center {cellGap} {cellPad}" style="min-height: {heightVar}">
|
|
342
|
+
{#if hasLead}
|
|
343
|
+
<div class="invisible flex shrink-0 items-center gap-1" aria-hidden="true">
|
|
344
|
+
{#if selectable}<Checkbox {size} tabindex={-1} />{/if}
|
|
345
|
+
{#if expandable}<span
|
|
346
|
+
class={spacerClass}
|
|
347
|
+
style="width: {heightVar}; height: {heightVar}"><IconChevronRight /></span
|
|
348
|
+
>{/if}
|
|
349
|
+
{#if reorderable}
|
|
350
|
+
<span class={spacerClass} style="width: {heightVar}; height: {heightVar}"></span>
|
|
351
|
+
<span class={spacerClass} style="width: {heightVar}; height: {heightVar}"></span>
|
|
352
|
+
{/if}
|
|
353
|
+
</div>
|
|
354
|
+
{/if}
|
|
355
|
+
<div class="grow self-center text-center {subtle}">
|
|
356
|
+
{#if settled}
|
|
357
|
+
No results.
|
|
358
|
+
{:else}
|
|
359
|
+
<span class="inline-flex items-center gap-2"
|
|
360
|
+
><IconLoading class="w-[1em] h-[1em] animate-spin" /> Loading…</span
|
|
361
|
+
>
|
|
362
|
+
{/if}
|
|
363
|
+
</div>
|
|
364
|
+
{#if hasTail}<div
|
|
365
|
+
class="invisible flex shrink-0 items-center"
|
|
366
|
+
style="width: {heightVar}"
|
|
367
|
+
aria-hidden="true"
|
|
368
|
+
></div>{/if}
|
|
369
|
+
</div>
|
|
370
|
+
{:else}
|
|
371
|
+
{#each rows as row, rowIndex (grid.getRowId(row))}
|
|
372
|
+
{@const id = grid.getRowId(row)}
|
|
373
|
+
<!-- Row + its expand panel form one hover group, so they always share the SAME background
|
|
374
|
+
(transparent by default; both take the hover tint together). -->
|
|
375
|
+
<div class="group">
|
|
376
|
+
<div
|
|
377
|
+
role="row"
|
|
378
|
+
class="flex items-center {cellGap} {cellPad} group-hover:[background-color:var(--ui-color-hover)]"
|
|
379
|
+
style="min-height: {heightVar}"
|
|
380
|
+
>
|
|
381
|
+
{#if hasLead}
|
|
382
|
+
<div class="flex shrink-0 items-center gap-1">
|
|
383
|
+
{#if selectable}
|
|
384
|
+
<Checkbox
|
|
385
|
+
{size}
|
|
386
|
+
aria-label="Select row"
|
|
387
|
+
checked={grid.isSelected(id)}
|
|
388
|
+
onchange={() => grid.toggleRow(id)}
|
|
389
|
+
/>
|
|
390
|
+
{/if}
|
|
391
|
+
{#if expandable}
|
|
392
|
+
<Button
|
|
393
|
+
variant="ghost"
|
|
394
|
+
{size}
|
|
395
|
+
aria-label={grid.isExpanded(id) ? "Collapse" : "Expand"}
|
|
396
|
+
title={grid.isExpanded(id) ? "Collapse" : "Expand"}
|
|
397
|
+
onclick={() => grid.toggleExpand(id)}
|
|
398
|
+
>
|
|
399
|
+
{#snippet icon()}{#if grid.isExpanded(id)}<IconChevronDown
|
|
400
|
+
/>{:else}<IconChevronRight />{/if}{/snippet}
|
|
401
|
+
</Button>
|
|
402
|
+
{/if}
|
|
403
|
+
{#if reorderable}
|
|
404
|
+
<Button
|
|
405
|
+
variant="ghost"
|
|
406
|
+
{size}
|
|
407
|
+
aria-label="Move up"
|
|
408
|
+
title="Move up"
|
|
409
|
+
disabled={rowIndex === 0}
|
|
410
|
+
onclick={() => onReorder?.(row, "up")}
|
|
411
|
+
>
|
|
412
|
+
{#snippet icon()}<IconChevronUp />{/snippet}
|
|
413
|
+
</Button>
|
|
414
|
+
<Button
|
|
415
|
+
variant="ghost"
|
|
416
|
+
{size}
|
|
417
|
+
aria-label="Move down"
|
|
418
|
+
title="Move down"
|
|
419
|
+
disabled={rowIndex === rows.length - 1}
|
|
420
|
+
onclick={() => onReorder?.(row, "down")}
|
|
421
|
+
>
|
|
422
|
+
{#snippet icon()}<IconChevronDown />{/snippet}
|
|
423
|
+
</Button>
|
|
424
|
+
{/if}
|
|
425
|
+
</div>
|
|
426
|
+
{/if}
|
|
427
|
+
|
|
428
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
429
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
430
|
+
<div
|
|
431
|
+
class="grid grow grid-cols-12 items-center {cellGap} {expandable
|
|
432
|
+
? 'cursor-pointer'
|
|
433
|
+
: ''}"
|
|
434
|
+
onclick={(e) => rowClick(e, id)}
|
|
435
|
+
>
|
|
436
|
+
{#each columns as col (col.id)}
|
|
437
|
+
<div
|
|
438
|
+
role="cell"
|
|
439
|
+
class="{cellClasses(col)} flex min-w-0 items-center {alignClass(col)} {truncate
|
|
440
|
+
? 'truncate'
|
|
441
|
+
: ''}"
|
|
442
|
+
>
|
|
443
|
+
{@render col.cell(row)}
|
|
444
|
+
</div>
|
|
445
|
+
{/each}
|
|
446
|
+
</div>
|
|
447
|
+
|
|
448
|
+
{#if hasTail}
|
|
449
|
+
<div class="flex shrink-0 items-center justify-end" style="width: {heightVar}">
|
|
450
|
+
{#if rowActions}
|
|
451
|
+
<Button
|
|
452
|
+
variant="ghost"
|
|
453
|
+
{size}
|
|
454
|
+
aria-label="Row actions"
|
|
455
|
+
title="Row actions"
|
|
456
|
+
onclick={(e) => openMenu(e, rowActions(row))}
|
|
457
|
+
>
|
|
458
|
+
{#snippet icon()}<IconDots />{/snippet}
|
|
459
|
+
</Button>
|
|
460
|
+
{/if}
|
|
461
|
+
</div>
|
|
462
|
+
{/if}
|
|
463
|
+
</div>
|
|
464
|
+
|
|
465
|
+
{#if expandable && expanded && grid.isExpanded(id)}
|
|
466
|
+
<div class="{cellPad} group-hover:[background-color:var(--ui-color-hover)]">
|
|
467
|
+
{@render expanded(row)}
|
|
468
|
+
</div>
|
|
469
|
+
{/if}
|
|
470
|
+
</div>
|
|
471
|
+
{/each}
|
|
472
|
+
{/if}
|
|
473
|
+
</div>
|
|
474
|
+
|
|
475
|
+
<!-- Footer — its own full 1px border box (matches the header); rounds the bottom corners. Its top
|
|
476
|
+
border is the separator above it. Inherits font-size from the outer container. -->
|
|
477
|
+
<div
|
|
478
|
+
class="flex flex-wrap items-center justify-between border {cellGap} {cellPad}
|
|
479
|
+
[border-bottom-left-radius:var(--ui-border-radius)] [border-bottom-right-radius:var(--ui-border-radius)]"
|
|
480
|
+
style="border-color: {bandBorder}; background-color: {bandBg}"
|
|
481
|
+
>
|
|
482
|
+
<div class="flex items-center gap-2">
|
|
483
|
+
<Select
|
|
484
|
+
class="w-20"
|
|
485
|
+
{size}
|
|
486
|
+
value={String(grid.perPage)}
|
|
487
|
+
options={grid.perPageOptions.map((n) => ({ value: String(n), label: String(n) }))}
|
|
488
|
+
onSelection={(o) => grid.setPerPage(Number(o.value))}
|
|
489
|
+
/>
|
|
490
|
+
<span class={subtle}>per page</span>
|
|
491
|
+
</div>
|
|
492
|
+
|
|
493
|
+
<div class="flex items-center gap-3">
|
|
494
|
+
<span class={subtle}>{rangeText}</span>
|
|
495
|
+
<div class="inline-flex items-center gap-0.5">
|
|
496
|
+
{#snippet pageBtn(Icon: typeof IconFirst, to: number, disabled: boolean, aria: string)}
|
|
497
|
+
<Button
|
|
498
|
+
variant="ghost"
|
|
499
|
+
{size}
|
|
500
|
+
{disabled}
|
|
501
|
+
aria-label={aria}
|
|
502
|
+
title={aria}
|
|
503
|
+
onclick={() => grid.setPage(to)}
|
|
504
|
+
>
|
|
505
|
+
{#snippet icon()}<Icon />{/snippet}
|
|
506
|
+
</Button>
|
|
507
|
+
{/snippet}
|
|
508
|
+
{@render pageBtn(IconFirst, 1, grid.page <= 1, "First")}
|
|
509
|
+
{@render pageBtn(IconPrev, grid.page - 1, grid.page <= 1, "Previous")}
|
|
510
|
+
<span class="px-2 {subtle}">{grid.page} / {pageCount}</span>
|
|
511
|
+
{@render pageBtn(IconNext, grid.page + 1, grid.page >= pageCount, "Next")}
|
|
512
|
+
{@render pageBtn(IconLast, pageCount, grid.page >= pageCount, "Last")}
|
|
513
|
+
</div>
|
|
514
|
+
</div>
|
|
515
|
+
</div>
|
|
516
|
+
</div>
|
|
517
|
+
|
|
518
|
+
<Menu bind:open={menuOpen} anchor={menuAnchor} items={menuItems} side="bottom" align="end" />
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import type { MenuItem, DataGrid } from "../data/table/index.js";
|
|
3
|
+
import type { Size } from "../types/sizes.js";
|
|
4
|
+
import { type Responsive } from "../types/responsive.js";
|
|
5
|
+
import { type Variant } from "../types/variants.js";
|
|
6
|
+
declare function $$render<T>(): {
|
|
7
|
+
props: {
|
|
8
|
+
grid: DataGrid<T>;
|
|
9
|
+
selectable?: boolean;
|
|
10
|
+
expandable?: boolean;
|
|
11
|
+
/** When true, each row gets up/down chevron buttons in the lead
|
|
12
|
+
* column and fires `onReorder(row, 'up'|'down')` when clicked.
|
|
13
|
+
* The consumer owns the actual swap (typically updating the
|
|
14
|
+
* `sortOrder` field of two rows). Buttons auto-disable at the
|
|
15
|
+
* ends of the visible page — with server pagination, this
|
|
16
|
+
* reorders WITHIN the visible page only. */
|
|
17
|
+
reorderable?: boolean;
|
|
18
|
+
expanded?: Snippet<[T]>;
|
|
19
|
+
rowActions?: (row: T) => MenuItem[];
|
|
20
|
+
bulkActions?: (selected: ReadonlySet<string>) => MenuItem[];
|
|
21
|
+
onReorder?: (row: T, direction: "up" | "down") => void;
|
|
22
|
+
/** Overall density tier. Scales the whole table uniformly:
|
|
23
|
+
* font-size (--ui-text-*), row/footer padding, inter-column
|
|
24
|
+
* gap, lead/tail control squares (--ui-height-*), and
|
|
25
|
+
* propagates to every inner Button / Checkbox / Select.
|
|
26
|
+
* Header text inherits the outer font-size — no separate
|
|
27
|
+
* axis. Default `'md'` matches the rest of svelte-ui. */
|
|
28
|
+
size?: Responsive<Size>;
|
|
29
|
+
/** Every header + body cell wrapper gets Tailwind's `truncate`
|
|
30
|
+
* (white-space:nowrap, overflow:hidden, text-overflow:ellipsis).
|
|
31
|
+
* Simple text cells render with ellipsis automatically. Compound
|
|
32
|
+
* cells (inline-flex wrappers, badges, buttons) clip at the
|
|
33
|
+
* right edge — to also get ellipsis on the inner text, the
|
|
34
|
+
* snippet's text span needs its own `truncate` class.
|
|
35
|
+
*
|
|
36
|
+
* Defaults to `true` — the "wrong" default is columns visually
|
|
37
|
+
* bleeding into their neighbours when a value doesn't fit its
|
|
38
|
+
* configured span. Pass `truncate={false}` if the consumer
|
|
39
|
+
* wants wrap-on-overflow (rare — usually you'd fix the span
|
|
40
|
+
* allocation instead). */
|
|
41
|
+
truncate?: boolean;
|
|
42
|
+
/** Drop the visible frame while keeping each section's 1px box: every section's border colour
|
|
43
|
+
* becomes its own background, so it vanishes per-section on a matching surface. Defaults `false`. */
|
|
44
|
+
borderless?: boolean;
|
|
45
|
+
/** Tints the whole table's interactive/section surfaces (row hover,
|
|
46
|
+
* header/footer bands) with a semantic colour instead of the neutral
|
|
47
|
+
* default. Points --ui-accent at the variant's token and re-mixes the
|
|
48
|
+
* --ui-color-hover/surface/active tints via the `.ui-accent` class.
|
|
49
|
+
* `ghost` additionally drops ALL section fills (bands + body) for a bare,
|
|
50
|
+
* see-through table. Omit for the default grey tint. */
|
|
51
|
+
variant?: Variant;
|
|
52
|
+
};
|
|
53
|
+
exports: {};
|
|
54
|
+
bindings: "";
|
|
55
|
+
slots: {};
|
|
56
|
+
events: {};
|
|
57
|
+
};
|
|
58
|
+
declare class __sveltets_Render<T> {
|
|
59
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
60
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
61
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
62
|
+
bindings(): "";
|
|
63
|
+
exports(): {};
|
|
64
|
+
}
|
|
65
|
+
interface $$IsomorphicComponent {
|
|
66
|
+
new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
67
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
68
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
69
|
+
<T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
70
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
71
|
+
}
|
|
72
|
+
declare const DataTable: $$IsomorphicComponent;
|
|
73
|
+
type DataTable<T> = InstanceType<typeof DataTable<T>>;
|
|
74
|
+
export default DataTable;
|