@spaethtech/svelte-ui 0.5.1-dev.24.9a705e3 → 0.5.1-dev.26.4a7da0b
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 +2 -1
- package/dist/components/FieldGroup.svelte +8 -9
- package/dist/components/FieldGroup.svelte.d.ts +3 -1
- package/dist/components/FieldsetChrome.svelte +9 -7
- package/dist/components/FieldsetChrome.svelte.d.ts +5 -3
- package/dist/components/field-group.d.ts +10 -3
- package/dist/components/field-group.js +20 -0
- package/dist/theme.css +2 -0
- package/docs/components.md +2 -1
- package/docs/usage.md +1 -1
- package/package.json +1 -1
|
@@ -99,7 +99,8 @@ surfaces through the **native validity tooltip** (shown on form submit); the con
|
|
|
99
99
|
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
|
-
(same `label`/`description`/`error`/`required` vocab on a `<fieldset>`, plus `
|
|
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). Inside a
|
|
103
104
|
group, item labels render **inline** (right of the control). For a radio group, `bind:value` on the
|
|
104
105
|
`FieldGroup` (+ optional `name`) and the child `<Radio>`s share it automatically — no `bind:group`:
|
|
105
106
|
|
|
@@ -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 } from "./field-group.js";
|
|
18
|
+
import { setFieldGroup, type Columns } from "./field-group.js";
|
|
19
19
|
|
|
20
20
|
let {
|
|
21
21
|
value = $bindable(),
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
error = null,
|
|
26
26
|
description = null,
|
|
27
27
|
required = false,
|
|
28
|
-
|
|
28
|
+
columns = 1,
|
|
29
29
|
size = "md",
|
|
30
30
|
variant,
|
|
31
31
|
disabled = false,
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
error?: string | Snippet | null;
|
|
42
42
|
description?: string | Snippet | null;
|
|
43
43
|
required?: boolean;
|
|
44
|
-
|
|
44
|
+
/** Grid track count (default 1 = stacked vertical). Set >1 (or a responsive map) for columns. */
|
|
45
|
+
columns?: Columns;
|
|
45
46
|
size?: Responsive<Size>;
|
|
46
47
|
variant?: Variant;
|
|
47
48
|
disabled?: boolean;
|
|
@@ -49,13 +50,11 @@
|
|
|
49
50
|
children: Snippet;
|
|
50
51
|
} = $props();
|
|
51
52
|
|
|
52
|
-
// Reactive context: getters keep size/variant/
|
|
53
|
-
//
|
|
53
|
+
// Reactive context: getters keep size/variant/disabled live; getValue/select share the radio-group
|
|
54
|
+
// value. Set once (context is stable); the getters read current prop values. Layout is the grid's
|
|
55
|
+
// job (columns), so items need no orientation awareness.
|
|
54
56
|
setFieldGroup({
|
|
55
57
|
inGroup: true,
|
|
56
|
-
get orientation() {
|
|
57
|
-
return orientation;
|
|
58
|
-
},
|
|
59
58
|
get size() {
|
|
60
59
|
return size;
|
|
61
60
|
},
|
|
@@ -75,6 +74,6 @@
|
|
|
75
74
|
});
|
|
76
75
|
</script>
|
|
77
76
|
|
|
78
|
-
<FieldsetChrome {label} {aside} {error} {description} {required} {
|
|
77
|
+
<FieldsetChrome {label} {aside} {error} {description} {required} {columns} {size} class={cls}>
|
|
79
78
|
{@render children()}
|
|
80
79
|
</FieldsetChrome>
|
|
@@ -2,6 +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
6
|
type $$ComponentProps = {
|
|
6
7
|
/** Radio groups: the selected value (bindable). Ignored by checkbox/toggle children. */
|
|
7
8
|
value?: string | number;
|
|
@@ -12,7 +13,8 @@ type $$ComponentProps = {
|
|
|
12
13
|
error?: string | Snippet | null;
|
|
13
14
|
description?: string | Snippet | null;
|
|
14
15
|
required?: boolean;
|
|
15
|
-
|
|
16
|
+
/** Grid track count (default 1 = stacked vertical). Set >1 (or a responsive map) for columns. */
|
|
17
|
+
columns?: Columns;
|
|
16
18
|
size?: Responsive<Size>;
|
|
17
19
|
variant?: Variant;
|
|
18
20
|
disabled?: boolean;
|
|
@@ -2,11 +2,12 @@
|
|
|
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
6
|
|
|
6
7
|
/**
|
|
7
8
|
* FieldsetChrome — the group counterpart of FieldChrome: a `<fieldset>` with a `<legend>` (the
|
|
8
|
-
* group label) plus the same error/description rows, and
|
|
9
|
-
*
|
|
9
|
+
* group label) plus the same error/description rows, and a `columns`-driven CSS-grid slot. Child
|
|
10
|
+
* controls are auto-placed into cells (no per-child prop). Used by `FieldGroup`.
|
|
10
11
|
*/
|
|
11
12
|
interface Props {
|
|
12
13
|
label?: string | null;
|
|
@@ -14,7 +15,8 @@
|
|
|
14
15
|
error?: string | Snippet | null;
|
|
15
16
|
description?: string | Snippet | null;
|
|
16
17
|
required?: boolean;
|
|
17
|
-
|
|
18
|
+
/** Grid track count (default 1 = stacked). Items auto-flow into equal cells. */
|
|
19
|
+
columns?: Columns;
|
|
18
20
|
size?: Responsive<Size>;
|
|
19
21
|
class?: string;
|
|
20
22
|
children: Snippet;
|
|
@@ -26,7 +28,7 @@
|
|
|
26
28
|
error = null,
|
|
27
29
|
description = null,
|
|
28
30
|
required = false,
|
|
29
|
-
|
|
31
|
+
columns = 1,
|
|
30
32
|
size = "md",
|
|
31
33
|
class: cls = "",
|
|
32
34
|
children,
|
|
@@ -41,9 +43,9 @@
|
|
|
41
43
|
const hasError = $derived(isSnippet(error) ? true : !!(error && String(error).trim()));
|
|
42
44
|
const hasDesc = $derived(isSnippet(description) ? true : !!(description && String(description).trim()));
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
);
|
|
46
|
+
// 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-x-6 gap-y-1`);
|
|
47
49
|
</script>
|
|
48
50
|
|
|
49
51
|
<fieldset class="m-0 flex min-w-0 flex-col gap-1 border-0 p-0 {cls}">
|
|
@@ -1,10 +1,11 @@
|
|
|
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
5
|
/**
|
|
5
6
|
* FieldsetChrome — the group counterpart of FieldChrome: a `<fieldset>` with a `<legend>` (the
|
|
6
|
-
* group label) plus the same error/description rows, and
|
|
7
|
-
*
|
|
7
|
+
* group label) plus the same error/description rows, and a `columns`-driven CSS-grid slot. Child
|
|
8
|
+
* controls are auto-placed into cells (no per-child prop). Used by `FieldGroup`.
|
|
8
9
|
*/
|
|
9
10
|
interface Props {
|
|
10
11
|
label?: string | null;
|
|
@@ -12,7 +13,8 @@ interface Props {
|
|
|
12
13
|
error?: string | Snippet | null;
|
|
13
14
|
description?: string | Snippet | null;
|
|
14
15
|
required?: boolean;
|
|
15
|
-
|
|
16
|
+
/** Grid track count (default 1 = stacked). Items auto-flow into equal cells. */
|
|
17
|
+
columns?: Columns;
|
|
16
18
|
size?: Responsive<Size>;
|
|
17
19
|
class?: string;
|
|
18
20
|
children: Snippet;
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
+
import type { Breakpoint } from "../types/breakpoints.js";
|
|
1
2
|
import type { Size } from "../types/sizes.js";
|
|
2
3
|
import type { Variant } from "../types/variants.js";
|
|
3
|
-
import type
|
|
4
|
+
import { type Responsive } from "../types/responsive.js";
|
|
4
5
|
export interface FieldGroupContext {
|
|
5
6
|
/** Present ⇒ the item is inside a group and renders its label inline (right of the control). */
|
|
6
7
|
inGroup: true;
|
|
7
|
-
orientation: "vertical" | "horizontal";
|
|
8
8
|
size?: Responsive<Size>;
|
|
9
9
|
variant?: Variant;
|
|
10
10
|
disabled?: boolean;
|
|
11
|
-
/**
|
|
11
|
+
/** Radio groups only — the shared radio-group name + controlled value. */
|
|
12
12
|
name?: string;
|
|
13
13
|
getValue?: () => string | number | undefined;
|
|
14
14
|
select?: (v: string | number) => void;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* FieldGroup `columns`: a track count (1–6) as a scalar or a per-breakpoint map. `1` (default) = a
|
|
18
|
+
* stacked vertical list; anything higher lays the auto-placed items across that many equal columns.
|
|
19
|
+
*/
|
|
20
|
+
export type Columns = number | Partial<Record<Breakpoint, number>>;
|
|
21
|
+
/** Resolve a `Columns` value to `grid-cols-*` classes (responsive-aware). */
|
|
22
|
+
export declare function gridColsClass(columns: Columns | undefined): string;
|
|
16
23
|
export declare function setFieldGroup(ctx: FieldGroupContext): void;
|
|
17
24
|
export declare function getFieldGroup(): FieldGroupContext | undefined;
|
|
@@ -5,6 +5,26 @@
|
|
|
5
5
|
* the radio-group value + `name` so a child `<Radio>` needs no `bind:group`.
|
|
6
6
|
*/
|
|
7
7
|
import { getContext, setContext } from "svelte";
|
|
8
|
+
import { responsiveClasses } from "../types/responsive.js";
|
|
9
|
+
// Static literal map so Tailwind's scanner emits the base classes; the bp:-prefixed variants are
|
|
10
|
+
// safelisted in theme.css (`@source inline(... grid-cols-{1..6})`).
|
|
11
|
+
const COLS_MAP = {
|
|
12
|
+
"1": "grid-cols-1",
|
|
13
|
+
"2": "grid-cols-2",
|
|
14
|
+
"3": "grid-cols-3",
|
|
15
|
+
"4": "grid-cols-4",
|
|
16
|
+
"5": "grid-cols-5",
|
|
17
|
+
"6": "grid-cols-6",
|
|
18
|
+
};
|
|
19
|
+
/** Resolve a `Columns` value to `grid-cols-*` classes (responsive-aware). */
|
|
20
|
+
export function gridColsClass(columns) {
|
|
21
|
+
if (columns == null)
|
|
22
|
+
return COLS_MAP["1"];
|
|
23
|
+
const value = typeof columns === "number"
|
|
24
|
+
? String(columns)
|
|
25
|
+
: Object.fromEntries(Object.entries(columns).map(([bp, n]) => [bp, String(n)]));
|
|
26
|
+
return responsiveClasses(value, COLS_MAP) || COLS_MAP["1"];
|
|
27
|
+
}
|
|
8
28
|
const KEY = Symbol("svelte-ui-field-group");
|
|
9
29
|
export function setFieldGroup(ctx) {
|
|
10
30
|
setContext(KEY, ctx);
|
package/dist/theme.css
CHANGED
|
@@ -203,3 +203,5 @@ body {
|
|
|
203
203
|
@source inline("{,4xs:,3xs:,2xs:,xs:,sm:,md:,lg:,xl:,2xl:,3xl:}gap-{1.5,2,3}");
|
|
204
204
|
@source inline("{,4xs:,3xs:,2xs:,xs:,sm:,md:,lg:,xl:,2xl:,3xl:}text-{xs,sm,base,lg,2xl}");
|
|
205
205
|
@source inline("{,4xs:,3xs:,2xs:,xs:,sm:,md:,lg:,xl:,2xl:,3xl:}[&_svg]:{w,h}-{3.5,4,5,6}");
|
|
206
|
+
/* FieldGroup `columns` → responsive grid tracks (auto-placed cells). */
|
|
207
|
+
@source inline("{,4xs:,3xs:,2xs:,xs:,sm:,md:,lg:,xl:,2xl:,3xl:}grid-cols-{1,2,3,4,5,6}");
|
package/docs/components.md
CHANGED
|
@@ -129,7 +129,8 @@ One wrapper for a set of Radios, Checkboxes, or Toggles under a shared legend (a
|
|
|
129
129
|
|
|
130
130
|
- **Location**: `src/lib/components/FieldGroup.svelte`
|
|
131
131
|
- **Props**: `label` (legend), `aside`, `description`, `error`, `required` (the shared field-chrome
|
|
132
|
-
vocabulary), `
|
|
132
|
+
vocabulary), `columns` (`number | { base, md, … }`, default `1` = stacked; higher = that many
|
|
133
|
+
equal auto-placed columns), `size`, `variant`, `disabled`
|
|
133
134
|
(propagate to children), and for radio groups `value` (bindable) + `name`. Children render their
|
|
134
135
|
label inline; radios auto-share the group value/name via context.
|
|
135
136
|
|
package/docs/usage.md
CHANGED
|
@@ -135,7 +135,7 @@ inline. For radios, bind the group `value` — children need no `bind:group`.
|
|
|
135
135
|
<Radio value="push" label="Push notification" />
|
|
136
136
|
</FieldGroup>
|
|
137
137
|
|
|
138
|
-
<FieldGroup label="Capabilities"
|
|
138
|
+
<FieldGroup label="Capabilities" columns={2}>
|
|
139
139
|
<Checkbox label="Webhook triggers" bind:checked={caps.webhook} />
|
|
140
140
|
<Checkbox label="Script actions" bind:checked={caps.script} />
|
|
141
141
|
</FieldGroup>
|