@spaethtech/svelte-ui 0.5.1-dev.26.4a7da0b → 0.5.1-dev.27.5011e8e
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 +5 -2
- package/dist/components/FieldGroup.svelte +5 -2
- package/dist/components/FieldGroup.svelte.d.ts +3 -1
- package/dist/components/FieldsetChrome.svelte +6 -3
- package/dist/components/FieldsetChrome.svelte.d.ts +3 -1
- package/dist/components/Grid.svelte +34 -0
- package/dist/components/Grid.svelte.d.ts +13 -0
- package/dist/components/field-group.d.ts +7 -0
- package/dist/components/field-group.js +22 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/docs/components.md +13 -3
- package/docs/usage.md +19 -0
- package/package.json +1 -1
|
@@ -100,7 +100,9 @@ prop is the inline row. Both flip the field's error border.
|
|
|
100
100
|
|
|
101
101
|
**Groups:** for a set of radios/checkboxes/toggles under one legend, wrap them in **`FieldGroup`**
|
|
102
102
|
(same `label`/`description`/`error`/`required` vocab on a `<fieldset>`, plus `columns` — a number or
|
|
103
|
-
responsive map; default 1 = stacked, higher lays items across equal auto-placed columns
|
|
103
|
+
responsive map; default 1 = stacked, higher lays items across equal auto-placed columns — and `gap`,
|
|
104
|
+
a number or `{ x, y }`). For non-field content, **`Grid`** is the same auto-placement as a plain
|
|
105
|
+
primitive (`columns` + `gap`, any children). Inside a
|
|
104
106
|
group, item labels render **inline** (right of the control). For a radio group, `bind:value` on the
|
|
105
107
|
`FieldGroup` (+ optional `name`) and the child `<Radio>`s share it automatically — no `bind:group`:
|
|
106
108
|
|
|
@@ -162,7 +164,8 @@ examples):
|
|
|
162
164
|
· `Popup` `Menu` · `tooltip` (a Svelte `use:` action) · `anchored` (positioning engine)
|
|
163
165
|
- **Navigation:** `TabStrip` `SideBarMenu`
|
|
164
166
|
- **Feedback:** `Alert` `Banner` `Badge` `Toaster` + `toast`
|
|
165
|
-
- **Layout:** `Card` `CardHeader` `CardBody` `CardFooter`
|
|
167
|
+
- **Layout:** `Card` `CardHeader` `CardBody` `CardFooter` · **`Grid`** (auto-placed equal-cell grid;
|
|
168
|
+
`columns` + `gap`)
|
|
166
169
|
- **Display / theme:** `NotesEditor` · `ThemeSelector` (Auto/Light/Dark Select) · `ThemeToggle`
|
|
167
170
|
(compact ☀/☾ icon button, same persisted state)
|
|
168
171
|
- **Types / utils:** `Variant` `Size` `TabDefinition` (types), `responsiveClasses` / `resolveScalar`,
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import type { Variant } from "../types/variants.js";
|
|
16
16
|
import type { Responsive } from "../types/responsive.js";
|
|
17
17
|
import FieldsetChrome from "./FieldsetChrome.svelte";
|
|
18
|
-
import { setFieldGroup, type Columns } from "./field-group.js";
|
|
18
|
+
import { setFieldGroup, type Columns, type Gap } from "./field-group.js";
|
|
19
19
|
|
|
20
20
|
let {
|
|
21
21
|
value = $bindable(),
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
description = null,
|
|
27
27
|
required = false,
|
|
28
28
|
columns = 1,
|
|
29
|
+
gap,
|
|
29
30
|
size = "md",
|
|
30
31
|
variant,
|
|
31
32
|
disabled = false,
|
|
@@ -43,6 +44,8 @@
|
|
|
43
44
|
required?: boolean;
|
|
44
45
|
/** Grid track count (default 1 = stacked vertical). Set >1 (or a responsive map) for columns. */
|
|
45
46
|
columns?: Columns;
|
|
47
|
+
/** Cell gap. Default `{ x: 6, y: 1 }` (wide columns, tight rows). Number = symmetric. */
|
|
48
|
+
gap?: Gap;
|
|
46
49
|
size?: Responsive<Size>;
|
|
47
50
|
variant?: Variant;
|
|
48
51
|
disabled?: boolean;
|
|
@@ -74,6 +77,6 @@
|
|
|
74
77
|
});
|
|
75
78
|
</script>
|
|
76
79
|
|
|
77
|
-
<FieldsetChrome {label} {aside} {error} {description} {required} {columns} {size} class={cls}>
|
|
80
|
+
<FieldsetChrome {label} {aside} {error} {description} {required} {columns} {gap} {size} class={cls}>
|
|
78
81
|
{@render children()}
|
|
79
82
|
</FieldsetChrome>
|
|
@@ -2,7 +2,7 @@ import type { Snippet } from "svelte";
|
|
|
2
2
|
import type { Size } from "../types/sizes.js";
|
|
3
3
|
import type { Variant } from "../types/variants.js";
|
|
4
4
|
import type { Responsive } from "../types/responsive.js";
|
|
5
|
-
import { type Columns } from "./field-group.js";
|
|
5
|
+
import { type Columns, type Gap } from "./field-group.js";
|
|
6
6
|
type $$ComponentProps = {
|
|
7
7
|
/** Radio groups: the selected value (bindable). Ignored by checkbox/toggle children. */
|
|
8
8
|
value?: string | number;
|
|
@@ -15,6 +15,8 @@ type $$ComponentProps = {
|
|
|
15
15
|
required?: boolean;
|
|
16
16
|
/** Grid track count (default 1 = stacked vertical). Set >1 (or a responsive map) for columns. */
|
|
17
17
|
columns?: Columns;
|
|
18
|
+
/** Cell gap. Default `{ x: 6, y: 1 }` (wide columns, tight rows). Number = symmetric. */
|
|
19
|
+
gap?: Gap;
|
|
18
20
|
size?: Responsive<Size>;
|
|
19
21
|
variant?: Variant;
|
|
20
22
|
disabled?: boolean;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { Snippet } from "svelte";
|
|
3
3
|
import type { Size } from "../types/sizes.js";
|
|
4
4
|
import { responsiveClasses, type Responsive } from "../types/responsive.js";
|
|
5
|
-
import { gridColsClass, type Columns } from "./field-group.js";
|
|
5
|
+
import { gridColsClass, gapClass, type Columns, type Gap } from "./field-group.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* FieldsetChrome — the group counterpart of FieldChrome: a `<fieldset>` with a `<legend>` (the
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
required?: boolean;
|
|
18
18
|
/** Grid track count (default 1 = stacked). Items auto-flow into equal cells. */
|
|
19
19
|
columns?: Columns;
|
|
20
|
+
/** Cell gap. Default `{ x: 6, y: 1 }` — wide columns, tight rows (the field-list look). */
|
|
21
|
+
gap?: Gap;
|
|
20
22
|
size?: Responsive<Size>;
|
|
21
23
|
class?: string;
|
|
22
24
|
children: Snippet;
|
|
@@ -29,6 +31,7 @@
|
|
|
29
31
|
description = null,
|
|
30
32
|
required = false,
|
|
31
33
|
columns = 1,
|
|
34
|
+
gap,
|
|
32
35
|
size = "md",
|
|
33
36
|
class: cls = "",
|
|
34
37
|
children,
|
|
@@ -44,8 +47,8 @@
|
|
|
44
47
|
const hasDesc = $derived(isSnippet(description) ? true : !!(description && String(description).trim()));
|
|
45
48
|
|
|
46
49
|
// Auto-placed CSS grid: each direct child (a Radio/Checkbox/Toggle label) is one cell — no
|
|
47
|
-
// per-child prop. `columns` sets the equal-width tracks; gap is the single density knob.
|
|
48
|
-
const itemsClass = $derived(`grid ${gridColsClass(columns)} gap
|
|
50
|
+
// per-child prop. `columns` sets the equal-width tracks; `gap` is the single density knob.
|
|
51
|
+
const itemsClass = $derived(`grid ${gridColsClass(columns)} ${gapClass(gap, { x: 6, y: 1 })}`);
|
|
49
52
|
</script>
|
|
50
53
|
|
|
51
54
|
<fieldset class="m-0 flex min-w-0 flex-col gap-1 border-0 p-0 {cls}">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Snippet } from "svelte";
|
|
2
2
|
import type { Size } from "../types/sizes.js";
|
|
3
3
|
import { type Responsive } from "../types/responsive.js";
|
|
4
|
-
import { type Columns } from "./field-group.js";
|
|
4
|
+
import { type Columns, type Gap } from "./field-group.js";
|
|
5
5
|
/**
|
|
6
6
|
* FieldsetChrome — the group counterpart of FieldChrome: a `<fieldset>` with a `<legend>` (the
|
|
7
7
|
* group label) plus the same error/description rows, and a `columns`-driven CSS-grid slot. Child
|
|
@@ -15,6 +15,8 @@ interface Props {
|
|
|
15
15
|
required?: boolean;
|
|
16
16
|
/** Grid track count (default 1 = stacked). Items auto-flow into equal cells. */
|
|
17
17
|
columns?: Columns;
|
|
18
|
+
/** Cell gap. Default `{ x: 6, y: 1 }` — wide columns, tight rows (the field-list look). */
|
|
19
|
+
gap?: Gap;
|
|
18
20
|
size?: Responsive<Size>;
|
|
19
21
|
class?: string;
|
|
20
22
|
children: Snippet;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
/**
|
|
3
|
+
* Grid — a minimal auto-placed CSS-grid layout primitive. Sets `grid grid-cols-{columns}` and lets
|
|
4
|
+
* every direct child flow into an equal cell (no per-child prop). Works with any content — Cards,
|
|
5
|
+
* Buttons, arbitrary markup. `columns` is responsive; `gap` is a single symmetric step or `{ x, y }`.
|
|
6
|
+
*
|
|
7
|
+
* Uniform cells only (by design). For variable-width layouts, use a bespoke grid + `col-span-*` on
|
|
8
|
+
* the cells yourself. `FieldGroup` is the field-specific sibling (adds legend/error chrome).
|
|
9
|
+
*/
|
|
10
|
+
-->
|
|
11
|
+
<script lang="ts">
|
|
12
|
+
import type { Snippet } from "svelte";
|
|
13
|
+
import { gridColsClass, gapClass, type Columns, type Gap } from "./field-group.js";
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
columns = 1,
|
|
17
|
+
gap = 4,
|
|
18
|
+
class: cls = "",
|
|
19
|
+
children,
|
|
20
|
+
}: {
|
|
21
|
+
/** Track count — a number (1–6) or a responsive map like `{ base: 1, md: 3 }`. Default 1. */
|
|
22
|
+
columns?: Columns;
|
|
23
|
+
/** Cell gap — a Tailwind step (symmetric) or `{ x, y }` per-axis. Default 4. */
|
|
24
|
+
gap?: Gap;
|
|
25
|
+
class?: string;
|
|
26
|
+
children: Snippet;
|
|
27
|
+
} = $props();
|
|
28
|
+
|
|
29
|
+
const gridClass = $derived(`grid ${gridColsClass(columns)} ${gapClass(gap, 4)}`);
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<div class="{gridClass} {cls}">
|
|
33
|
+
{@render children()}
|
|
34
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import { type Columns, type Gap } from "./field-group.js";
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
/** Track count — a number (1–6) or a responsive map like `{ base: 1, md: 3 }`. Default 1. */
|
|
5
|
+
columns?: Columns;
|
|
6
|
+
/** Cell gap — a Tailwind step (symmetric) or `{ x, y }` per-axis. Default 4. */
|
|
7
|
+
gap?: Gap;
|
|
8
|
+
class?: string;
|
|
9
|
+
children: Snippet;
|
|
10
|
+
};
|
|
11
|
+
declare const Grid: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
12
|
+
type Grid = ReturnType<typeof Grid>;
|
|
13
|
+
export default Grid;
|
|
@@ -20,5 +20,12 @@ export interface FieldGroupContext {
|
|
|
20
20
|
export type Columns = number | Partial<Record<Breakpoint, number>>;
|
|
21
21
|
/** Resolve a `Columns` value to `grid-cols-*` classes (responsive-aware). */
|
|
22
22
|
export declare function gridColsClass(columns: Columns | undefined): string;
|
|
23
|
+
/** Grid gap: a single Tailwind gap step (symmetric) or `{ x, y }` for per-axis (column/row) gaps. */
|
|
24
|
+
export type Gap = number | {
|
|
25
|
+
x?: number;
|
|
26
|
+
y?: number;
|
|
27
|
+
};
|
|
28
|
+
/** Resolve a `Gap` (or the fallback when unset) to `gap-*` / `gap-x-* gap-y-*` classes. */
|
|
29
|
+
export declare function gapClass(gap: Gap | undefined, fallback: Gap): string;
|
|
23
30
|
export declare function setFieldGroup(ctx: FieldGroupContext): void;
|
|
24
31
|
export declare function getFieldGroup(): FieldGroupContext | undefined;
|
|
@@ -25,6 +25,28 @@ export function gridColsClass(columns) {
|
|
|
25
25
|
: Object.fromEntries(Object.entries(columns).map(([bp, n]) => [bp, String(n)]));
|
|
26
26
|
return responsiveClasses(value, COLS_MAP) || COLS_MAP["1"];
|
|
27
27
|
}
|
|
28
|
+
// Static literal maps (Tailwind-scannable via the shipped dist). Non-responsive — one gap per grid.
|
|
29
|
+
const GAP = {
|
|
30
|
+
"0": "gap-0", "1": "gap-1", "1.5": "gap-1.5", "2": "gap-2", "3": "gap-3",
|
|
31
|
+
"4": "gap-4", "5": "gap-5", "6": "gap-6", "8": "gap-8",
|
|
32
|
+
};
|
|
33
|
+
const GAP_X = {
|
|
34
|
+
"0": "gap-x-0", "1": "gap-x-1", "1.5": "gap-x-1.5", "2": "gap-x-2", "3": "gap-x-3",
|
|
35
|
+
"4": "gap-x-4", "5": "gap-x-5", "6": "gap-x-6", "8": "gap-x-8",
|
|
36
|
+
};
|
|
37
|
+
const GAP_Y = {
|
|
38
|
+
"0": "gap-y-0", "1": "gap-y-1", "1.5": "gap-y-1.5", "2": "gap-y-2", "3": "gap-y-3",
|
|
39
|
+
"4": "gap-y-4", "5": "gap-y-5", "6": "gap-y-6", "8": "gap-y-8",
|
|
40
|
+
};
|
|
41
|
+
/** Resolve a `Gap` (or the fallback when unset) to `gap-*` / `gap-x-* gap-y-*` classes. */
|
|
42
|
+
export function gapClass(gap, fallback) {
|
|
43
|
+
const g = gap ?? fallback;
|
|
44
|
+
if (typeof g === "number")
|
|
45
|
+
return GAP[String(g)] ?? "";
|
|
46
|
+
return [g.x != null ? GAP_X[String(g.x)] : "", g.y != null ? GAP_Y[String(g.y)] : ""]
|
|
47
|
+
.filter(Boolean)
|
|
48
|
+
.join(" ");
|
|
49
|
+
}
|
|
28
50
|
const KEY = Symbol("svelte-ui-field-group");
|
|
29
51
|
export function setFieldGroup(ctx) {
|
|
30
52
|
setContext(KEY, ctx);
|
package/dist/index.d.ts
CHANGED
|
@@ -35,6 +35,8 @@ export { default as Checkbox } from "./components/Checkbox.svelte";
|
|
|
35
35
|
export { default as Toggle } from "./components/Toggle.svelte";
|
|
36
36
|
export { default as Radio } from "./components/Radio.svelte";
|
|
37
37
|
export { default as FieldGroup } from "./components/FieldGroup.svelte";
|
|
38
|
+
export { default as Grid } from "./components/Grid.svelte";
|
|
39
|
+
export type { Columns, Gap } from "./components/field-group.js";
|
|
38
40
|
export { default as SideBarMenu } from "./components/SideBarMenu/SideBarMenu.svelte";
|
|
39
41
|
export type { SideBarMenuItem, SideBarMenuBadge, SideBarMenuBadgeVariant, } from "./components/SideBarMenu/SideBarMenu.svelte";
|
|
40
42
|
export { default as TabStrip } from "./components/TabStrip/TabStrip.svelte";
|
package/dist/index.js
CHANGED
|
@@ -40,6 +40,7 @@ export { default as Checkbox } from "./components/Checkbox.svelte";
|
|
|
40
40
|
export { default as Toggle } from "./components/Toggle.svelte";
|
|
41
41
|
export { default as Radio } from "./components/Radio.svelte";
|
|
42
42
|
export { default as FieldGroup } from "./components/FieldGroup.svelte";
|
|
43
|
+
export { default as Grid } from "./components/Grid.svelte";
|
|
43
44
|
// Navigation Components
|
|
44
45
|
export { default as SideBarMenu } from "./components/SideBarMenu/SideBarMenu.svelte";
|
|
45
46
|
export { default as TabStrip } from "./components/TabStrip/TabStrip.svelte";
|
package/docs/components.md
CHANGED
|
@@ -130,9 +130,19 @@ One wrapper for a set of Radios, Checkboxes, or Toggles under a shared legend (a
|
|
|
130
130
|
- **Location**: `src/lib/components/FieldGroup.svelte`
|
|
131
131
|
- **Props**: `label` (legend), `aside`, `description`, `error`, `required` (the shared field-chrome
|
|
132
132
|
vocabulary), `columns` (`number | { base, md, … }`, default `1` = stacked; higher = that many
|
|
133
|
-
equal auto-placed columns), `
|
|
134
|
-
(propagate to children), and for radio groups `value` (bindable) + `name`.
|
|
135
|
-
label inline; radios auto-share the group value/name via context.
|
|
133
|
+
equal auto-placed columns), `gap` (`number | { x, y }`, default `{ x: 6, y: 1 }`), `size`,
|
|
134
|
+
`variant`, `disabled` (propagate to children), and for radio groups `value` (bindable) + `name`.
|
|
135
|
+
Children render their label inline; radios auto-share the group value/name via context.
|
|
136
|
+
|
|
137
|
+
### Grid
|
|
138
|
+
|
|
139
|
+
Minimal auto-placed CSS-grid layout primitive — every direct child flows into an equal cell (no
|
|
140
|
+
per-child prop). Works with any content. Uniform cells only (for variable widths, use your own grid +
|
|
141
|
+
`col-span-*`).
|
|
142
|
+
|
|
143
|
+
- **Location**: `src/lib/components/Grid.svelte`
|
|
144
|
+
- **Props**: `columns` (`number | { base, md, … }`, 1–6, default `1`), `gap` (`number | { x, y }`,
|
|
145
|
+
default `4`), `class`, `children`. Shares `gridColsClass`/`gapClass` with `FieldGroup`.
|
|
136
146
|
|
|
137
147
|
### Rating
|
|
138
148
|
|
package/docs/usage.md
CHANGED
|
@@ -141,6 +141,25 @@ inline. For radios, bind the group `value` — children need no `bind:group`.
|
|
|
141
141
|
</FieldGroup>
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
+
### Grid
|
|
145
|
+
|
|
146
|
+
Auto-placed layout — direct children flow into equal cells, no per-child prop. `columns` is
|
|
147
|
+
responsive; `gap` is symmetric (a number) or per-axis (`{ x, y }`).
|
|
148
|
+
|
|
149
|
+
```svelte
|
|
150
|
+
<script>
|
|
151
|
+
import { Grid, Card } from "@spaethtech/svelte-ui";
|
|
152
|
+
</script>
|
|
153
|
+
|
|
154
|
+
<Grid columns={{ base: 1, sm: 2, lg: 3 }} gap={4}>
|
|
155
|
+
<Card>One</Card>
|
|
156
|
+
<Card>Two</Card>
|
|
157
|
+
<Card>Three</Card>
|
|
158
|
+
</Grid>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
For variable-width cells, use your own grid + `col-span-*`; `Grid` is uniform cells by design.
|
|
162
|
+
|
|
144
163
|
### Button
|
|
145
164
|
|
|
146
165
|
```svelte
|