lutra 0.1.69 → 0.1.73

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.
Files changed (40) hide show
  1. package/dist/components/Callout.svelte +85 -0
  2. package/dist/components/Callout.svelte.d.ts +14 -0
  3. package/dist/components/DataList.svelte +111 -0
  4. package/dist/components/DataList.svelte.d.ts +10 -0
  5. package/dist/components/DataListTypes.d.ts +14 -0
  6. package/dist/components/DataListTypes.js +1 -0
  7. package/dist/components/IconButton.svelte +12 -4
  8. package/dist/components/IconButton.svelte.d.ts +2 -0
  9. package/dist/components/Layout.svelte +1 -1
  10. package/dist/components/Popover.svelte +4 -1
  11. package/dist/components/Tabs.svelte +13 -1
  12. package/dist/components/Tabs.svelte.d.ts +2 -0
  13. package/dist/components/Tag.svelte +11 -3
  14. package/dist/components/Tag.svelte.d.ts +2 -0
  15. package/dist/components/index.d.ts +3 -0
  16. package/dist/components/index.js +3 -0
  17. package/dist/css/1-props.css +157 -136
  18. package/dist/css/2-init.css +39 -23
  19. package/dist/css/themes/DefaultTheme.css +10 -0
  20. package/dist/form/Button.svelte +4 -4
  21. package/dist/form/Button.svelte.d.ts +1 -1
  22. package/dist/form/FieldContent.svelte +11 -3
  23. package/dist/form/FieldContent.svelte.d.ts +2 -0
  24. package/dist/form/FieldGroup.svelte +84 -0
  25. package/dist/form/FieldGroup.svelte.d.ts +20 -0
  26. package/dist/form/Input.svelte +4 -0
  27. package/dist/form/Input.svelte.d.ts +2 -0
  28. package/dist/form/SegmentedControl.svelte +273 -0
  29. package/dist/form/SegmentedControl.svelte.d.ts +33 -0
  30. package/dist/form/SegmentedControlTypes.d.ts +8 -0
  31. package/dist/form/SegmentedControlTypes.js +1 -0
  32. package/dist/form/Select.svelte +4 -0
  33. package/dist/form/Select.svelte.d.ts +2 -0
  34. package/dist/form/Textarea.svelte +4 -0
  35. package/dist/form/Textarea.svelte.d.ts +2 -0
  36. package/dist/form/Toggle.svelte +166 -0
  37. package/dist/form/Toggle.svelte.d.ts +33 -17
  38. package/dist/form/index.d.ts +3 -0
  39. package/dist/form/index.js +3 -0
  40. package/package.json +1 -1
@@ -7,7 +7,7 @@ type $$ComponentProps = {
7
7
  /** Visual style variant. */
8
8
  kind?: 'default' | 'outlined' | 'secondary' | 'warn';
9
9
  /** Size variant. */
10
- size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
10
+ scale?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
11
11
  /** Additional CSS class names. */
12
12
  class?: string;
13
13
  /** Whether the button is disabled. Also disabled automatically when the parent form is loading. */
@@ -27,6 +27,7 @@
27
27
  help,
28
28
  type = "text",
29
29
  direction = 'column', // 'row' | 'column'
30
+ scale = 'md',
30
31
  required,
31
32
  children,
32
33
  field,
@@ -42,6 +43,8 @@
42
43
  labelTip?: string | Snippet;
43
44
  labelHelp?: string | Snippet;
44
45
  direction?: 'row' | 'column';
46
+ /** Size variant controlling font-size. Em-based tokens cascade automatically. */
47
+ scale?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
45
48
  required?: boolean;
46
49
  children: Snippet;
47
50
  field?: FormField;
@@ -63,7 +66,7 @@
63
66
  </div>
64
67
  {/snippet}
65
68
 
66
- <div class="FieldContentContainer">
69
+ <div class="FieldContentContainer {scale}">
67
70
  <div class="FieldContent {type} {direction}" class:contained>
68
71
  <Label {label} tip={labelTip} help={labelHelp} {id} {required} />
69
72
  {#if contained}
@@ -179,9 +182,14 @@
179
182
  border-radius: calc(var(--field-border-radius) - 2px);
180
183
  }
181
184
  .Help {
182
- font-size: min(11px, var(--font-size-075));
185
+ font-size: var(--font-size-sm);
183
186
  line-height: var(--font-line-height-tight);
184
187
  color: var(--text-color-p-subtle);
185
- font-weight: var(--font-weight-normal);
188
+ font-weight: var(--font-weight-light);
186
189
  }
190
+
191
+ .FieldContentContainer.xs { font-size: var(--font-size-xs); }
192
+ .FieldContentContainer.sm { font-size: var(--font-size-sm); }
193
+ .FieldContentContainer.lg { font-size: var(--font-size-h5); }
194
+ .FieldContentContainer.xl { font-size: var(--font-size-h4); }
187
195
  </style>
@@ -11,6 +11,8 @@ type $$ComponentProps = {
11
11
  labelTip?: string | Snippet;
12
12
  labelHelp?: string | Snippet;
13
13
  direction?: 'row' | 'column';
14
+ /** Size variant controlling font-size. Em-based tokens cascade automatically. */
15
+ scale?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
14
16
  required?: boolean;
15
17
  children: Snippet;
16
18
  field?: FormField;
@@ -0,0 +1,84 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+ import Label from "./Label.svelte";
4
+ import StringOrSnippet from "../util/StringOrSnippet.svelte";
5
+
6
+ /**
7
+ * @description
8
+ * Groups related form fields (checkboxes, radios, toggles) under a shared label
9
+ * with a tighter gap than the default form field spacing.
10
+ *
11
+ * @cssprop --field-group-gap -- Gap between items within the group.
12
+ * @cssprop --form-label-gap -- Gap between the group label and the items.
13
+ *
14
+ * @example
15
+ * <FieldGroup label="Permissions">
16
+ * <Input name="read" type="checkbox" label="Read" />
17
+ * <Input name="write" type="checkbox" label="Write" />
18
+ * <Input name="admin" type="checkbox" label="Admin" />
19
+ * </FieldGroup>
20
+ */
21
+ let {
22
+ id = crypto.randomUUID(),
23
+ label,
24
+ labelHelp,
25
+ labelTip,
26
+ help,
27
+ required,
28
+ children,
29
+ }: {
30
+ /** A unique id for the group. Auto-generated if not provided. */
31
+ id?: string;
32
+ /** The group label. */
33
+ label?: string | Snippet;
34
+ /** Help text to display alongside the label. */
35
+ labelHelp?: string | Snippet;
36
+ /** Context tooltip for the label. */
37
+ labelTip?: string | Snippet;
38
+ /** Help text to display below the group. */
39
+ help?: string | Snippet;
40
+ /** Whether the group is required. */
41
+ required?: boolean;
42
+ /** The grouped fields to render. */
43
+ children: Snippet;
44
+ } = $props();
45
+ </script>
46
+
47
+ <div
48
+ class="FieldGroup"
49
+ role="group"
50
+ aria-labelledby={label ? `fg-${id}` : undefined}
51
+ >
52
+ {#if label}
53
+ <div id="fg-{id}">
54
+ <Label {label} tip={labelTip} help={labelHelp} {required} />
55
+ </div>
56
+ {/if}
57
+ <div class="FieldGroupContent">
58
+ {@render children()}
59
+ </div>
60
+ {#if help}
61
+ <div class="Help">
62
+ <StringOrSnippet content={help} />
63
+ </div>
64
+ {/if}
65
+ </div>
66
+
67
+ <style>
68
+ .FieldGroup {
69
+ display: flex;
70
+ flex-direction: column;
71
+ gap: var(--form-label-gap, var(--space-xs));
72
+ }
73
+ .FieldGroupContent {
74
+ display: flex;
75
+ flex-direction: column;
76
+ gap: var(--field-group-gap);
77
+ }
78
+ .Help {
79
+ font-size: var(--font-size-sm);
80
+ line-height: var(--font-line-height-tight);
81
+ color: var(--text-color-p-subtle);
82
+ font-weight: var(--font-weight-light);
83
+ }
84
+ </style>
@@ -0,0 +1,20 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ /** A unique id for the group. Auto-generated if not provided. */
4
+ id?: string;
5
+ /** The group label. */
6
+ label?: string | Snippet;
7
+ /** Help text to display alongside the label. */
8
+ labelHelp?: string | Snippet;
9
+ /** Context tooltip for the label. */
10
+ labelTip?: string | Snippet;
11
+ /** Help text to display below the group. */
12
+ help?: string | Snippet;
13
+ /** Whether the group is required. */
14
+ required?: boolean;
15
+ /** The grouped fields to render. */
16
+ children: Snippet;
17
+ };
18
+ declare const FieldGroup: import("svelte").Component<$$ComponentProps, {}, "">;
19
+ type FieldGroup = ReturnType<typeof FieldGroup>;
20
+ export default FieldGroup;
@@ -69,6 +69,7 @@
69
69
  readonly,
70
70
  required,
71
71
  shape = 'rounded',
72
+ scale = 'md',
72
73
  size,
73
74
  src,
74
75
  step,
@@ -162,6 +163,8 @@
162
163
  required?: boolean;
163
164
  /** The shape of the input element. */
164
165
  shape?: 'default' | 'rounded' | 'pill' | 'circle';
166
+ /** Size variant controlling font-size. Em-based tokens cascade automatically. */
167
+ scale?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
165
168
  /** The size of the input element. */
166
169
  size?: number;
167
170
  /** Source URL for the image type. */
@@ -350,6 +353,7 @@
350
353
  {prefix}
351
354
  {suffix}
352
355
  {required}
356
+ {scale}
353
357
  >
354
358
 
355
359
  {#if type === "checkbox" || type === "radio"}
@@ -83,6 +83,8 @@ type $$ComponentProps = {
83
83
  required?: boolean;
84
84
  /** The shape of the input element. */
85
85
  shape?: 'default' | 'rounded' | 'pill' | 'circle';
86
+ /** Size variant controlling font-size. Em-based tokens cascade automatically. */
87
+ scale?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
86
88
  /** The size of the input element. */
87
89
  size?: number;
88
90
  /** Source URL for the image type. */
@@ -0,0 +1,273 @@
1
+ <script lang="ts">
2
+ import { getContext, onMount, type Snippet } from "svelte";
3
+ import { BROWSER } from "esm-env";
4
+ import type { LutraForm } from "./types.js";
5
+ import { fieldChange } from "./client.svelte.js";
6
+ import FieldContent from "./FieldContent.svelte";
7
+ import { getFromObjWithStringPath } from "./form.js";
8
+ import { ZodType } from "zod";
9
+ import type { SegmentedControlOption } from "./SegmentedControlTypes.js";
10
+
11
+ /**
12
+ * @description
13
+ * A segmented control that functions as a styled radio group. Works both as a
14
+ * standalone control (with `onchange` callback and bindable `value`) and as a
15
+ * form-integrated field via the Lutra form system.
16
+ *
17
+ * Options can be passed as `string[]` (each string used as both label and value)
18
+ * or as `SegmentedControlOption[]` for more control.
19
+ *
20
+ * @cssprop --segmented-background - Track background. (Default: var(--tab-background-color, var(--menu-background-color)))
21
+ * @cssprop --segmented-background-active - Selected segment background. (Default: var(--tab-background-color-active, var(--background-selected)))
22
+ * @cssprop --segmented-text-color - Text color. (Default: var(--tab-text-color, var(--menu-text-color)))
23
+ * @cssprop --segmented-text-color-active - Selected text color. (Default: var(--tab-text-color-active, var(--text-color-heading)))
24
+ * @cssprop --segmented-border-size - Border width. (Default: var(--tab-border-size, var(--menu-border-size)))
25
+ * @cssprop --segmented-border-style - Border style. (Default: var(--tab-border-style, var(--menu-border-style)))
26
+ * @cssprop --segmented-border-color - Border color. (Default: var(--tab-border-color, var(--menu-border-color)))
27
+ * @cssprop --segmented-border-radius - Border radius. (Default: var(--tab-border-radius, var(--menu-border-radius)))
28
+ *
29
+ * @example
30
+ * <SegmentedControl name="view" options={['List', 'Grid', 'Board']} />
31
+ * <SegmentedControl name="tab" options={[{ label: 'Inbox', value: 'inbox' }, { label: 'Sent', value: 'sent' }]} />
32
+ */
33
+ let {
34
+ disabled,
35
+ help,
36
+ id = $bindable(crypto.randomUUID()),
37
+ label,
38
+ labelHelp,
39
+ labelTip,
40
+ name,
41
+ onchange,
42
+ options,
43
+ required,
44
+ shape = "rounded",
45
+ scale = "md",
46
+ value = $bindable(""),
47
+ }: {
48
+ /** Whether the entire control is disabled. */
49
+ disabled?: boolean;
50
+ /** Help text to display below the control. */
51
+ help?: string | Snippet;
52
+ /** A random id is generated if not provided. */
53
+ id?: string;
54
+ /** The label for the control. */
55
+ label?: string | Snippet;
56
+ /** Help text to display below the label. */
57
+ labelHelp?: string | Snippet;
58
+ /** Context tooltip for the label. Renders with a questionmark using ContextTip. */
59
+ labelTip?: string | Snippet;
60
+ /** The name of the field (used as the radio group name). */
61
+ name: string;
62
+ /** Change event handler. */
63
+ onchange?: (e: Event) => void;
64
+ /** Segment options. Accepts `string[]` or `SegmentedControlOption[]`. */
65
+ options: string[] | SegmentedControlOption[];
66
+ /** Whether the field is required. */
67
+ required?: boolean;
68
+ /** The shape of the control. */
69
+ shape?: "rounded" | "pill" | "rectangle";
70
+ /** Size variant controlling padding and font-size. */
71
+ scale?: "xs" | "sm" | "md" | "lg" | "xl";
72
+ /** The currently selected value (bindable). */
73
+ value?: string;
74
+ } = $props();
75
+
76
+ /** Normalise string[] options into SegmentedControlOption[]. */
77
+ const normalised = $derived(
78
+ options.map((o): SegmentedControlOption =>
79
+ typeof o === "string" ? { label: o, value: o } : o
80
+ )
81
+ );
82
+
83
+ let els: HTMLInputElement[] = $state([]);
84
+ let segmentEls: HTMLLabelElement[] = $state([]);
85
+ let loaded = $state(false);
86
+
87
+ const form = getContext<LutraForm<any>>("form");
88
+ const field = $derived(form?.fields[name]);
89
+ const issue = $derived(form?.issues?.find((issue) => issue.name === name));
90
+ const validator = getContext<Record<string, ZodType>>("form.validators")?.[name];
91
+ const data = form?.data;
92
+ const originalData = form?.originalData;
93
+
94
+ if (!value) {
95
+ const formValue = form
96
+ ? (getFromObjWithStringPath(Object.assign(originalData ?? {}, data ?? {}), name) as string)
97
+ : undefined;
98
+ if (formValue) value = formValue;
99
+ else if (normalised.length) value = normalised[0].value;
100
+ }
101
+
102
+ const selectedIndex = $derived(
103
+ normalised.findIndex((o) => o.value === value)
104
+ );
105
+
106
+ const indicatorStyle = $derived.by(() => {
107
+ if (!BROWSER || !loaded || selectedIndex < 0) return "opacity: 0;";
108
+ const el = segmentEls[selectedIndex];
109
+ if (!el) return "opacity: 0;";
110
+ return `opacity: 1; width: ${el.offsetWidth}px; translate: ${el.offsetLeft}px 0;`;
111
+ });
112
+
113
+ onMount(async () => {
114
+ if (value) {
115
+ const checkedEl = els.find((el) => el?.value === value);
116
+ if (checkedEl) fieldChange(form, name, () => checkedEl)({} as any);
117
+ }
118
+ await new Promise((resolve) => setTimeout(resolve, 50));
119
+ loaded = true;
120
+ });
121
+
122
+ function handleChange(e: Event, index: number) {
123
+ fieldChange(form, name, () => els[index], validator, onchange)(e);
124
+ }
125
+ </script>
126
+
127
+ <FieldContent
128
+ {id}
129
+ {label}
130
+ {labelHelp}
131
+ {labelTip}
132
+ contained={false}
133
+ {field}
134
+ {issue}
135
+ type="segmented"
136
+ {help}
137
+ {required}
138
+ >
139
+ <div class="SegmentedControl {shape} {scale}" role="radiogroup">
140
+ {#each normalised as option, i}
141
+ <label
142
+ bind:this={segmentEls[i]}
143
+ class="Segment"
144
+ class:selected={value === option.value}
145
+ class:disabled={disabled || option.disabled}
146
+ >
147
+ <input
148
+ type="radio"
149
+ bind:this={els[i]}
150
+ {name}
151
+ value={option.value}
152
+ disabled={disabled || option.disabled}
153
+ required={i === 0 ? (required || field?.required) : undefined}
154
+ bind:group={value}
155
+ onchange={(e) => handleChange(e, i)}
156
+ />
157
+ {option.label}
158
+ </label>
159
+ {/each}
160
+ <div class="Indicator" style={indicatorStyle}></div>
161
+ </div>
162
+ </FieldContent>
163
+
164
+ <svelte:window onresize={() => { loaded = false; loaded = true; }} />
165
+
166
+ <style>
167
+ .SegmentedControl {
168
+ position: relative;
169
+ display: inline-flex;
170
+ background: var(--segmented-background, var(--tab-background-color, var(--menu-background-color)));
171
+ border: var(--segmented-border-size, var(--tab-border-size, var(--menu-border-size)))
172
+ var(--segmented-border-style, var(--tab-border-style, var(--menu-border-style)))
173
+ var(--segmented-border-color, var(--tab-border-color, var(--menu-border-color)));
174
+ border-radius: var(--segmented-border-radius, var(--tab-border-radius, var(--menu-border-radius)));
175
+ overflow: clip;
176
+ }
177
+
178
+ .SegmentedControl.pill {
179
+ border-radius: calc(infinity * 1px);
180
+ }
181
+
182
+ .SegmentedControl.rectangle {
183
+ border-radius: 0;
184
+ }
185
+
186
+ .Segment {
187
+ position: relative;
188
+ z-index: 1;
189
+ display: flex;
190
+ align-items: center;
191
+ justify-content: center;
192
+ border-radius: inherit;
193
+ cursor: pointer;
194
+ color: var(--segmented-text-color, var(--tab-text-color, var(--menu-text-color)));
195
+ font-weight: var(--font-weight-medium);
196
+ letter-spacing: var(--tab-letter-spacing, -0.05ch);
197
+ user-select: none;
198
+ transition: color var(--transition-duration-fast) var(--transition-timing-function);
199
+ }
200
+
201
+ .Segment:hover:not(.disabled):not(.selected) {
202
+ background: var(--tab-background-color-hover, var(--menu-background-color-hover));
203
+ }
204
+
205
+ .Segment.selected {
206
+ color: var(--segmented-text-color-active, var(--tab-text-color-active, var(--text-color-heading)));
207
+ }
208
+
209
+ .Segment.disabled {
210
+ opacity: 0.5;
211
+ cursor: not-allowed;
212
+ }
213
+
214
+ .Segment:has(input:focus-visible) {
215
+ outline: var(--focus-ring-size) solid var(--focus-ring-color);
216
+ outline-offset: calc(-1 * var(--focus-ring-size));
217
+ z-index: 2;
218
+ }
219
+
220
+ .Segment input {
221
+ position: absolute;
222
+ opacity: 0;
223
+ pointer-events: none;
224
+ }
225
+
226
+ .Indicator {
227
+ position: absolute;
228
+ inset-block: 0;
229
+ inset-inline-start: 0;
230
+ background: var(--segmented-background-active, var(--tab-background-color-active, var(--background-selected)));
231
+ border-radius: inherit;
232
+ transition:
233
+ translate var(--transition-duration-fast) ease-out,
234
+ width var(--transition-duration-fast) ease-out;
235
+ opacity: 0;
236
+ }
237
+
238
+ @media (prefers-reduced-motion: reduce) {
239
+ .Indicator {
240
+ transition: none;
241
+ }
242
+ }
243
+
244
+ /* Size: xs */
245
+ .SegmentedControl.xs .Segment {
246
+ padding: 0.125em 0.375em;
247
+ font-size: var(--font-size-xs);
248
+ }
249
+
250
+ /* Size: sm */
251
+ .SegmentedControl.sm .Segment {
252
+ padding: var(--space-xxs) var(--space-sm);
253
+ font-size: var(--font-size-sm);
254
+ }
255
+
256
+ /* Size: md */
257
+ .SegmentedControl.md .Segment {
258
+ padding: var(--space-xs) var(--space-md);
259
+ font-size: var(--font-size-sm);
260
+ }
261
+
262
+ /* Size: lg */
263
+ .SegmentedControl.lg .Segment {
264
+ padding: var(--space-sm) var(--space-lg);
265
+ font-size: 1em;
266
+ }
267
+
268
+ /* Size: xl */
269
+ .SegmentedControl.xl .Segment {
270
+ padding: var(--space-md) var(--space-xl);
271
+ font-size: var(--font-size-h5);
272
+ }
273
+ </style>
@@ -0,0 +1,33 @@
1
+ import { type Snippet } from "svelte";
2
+ import type { SegmentedControlOption } from "./SegmentedControlTypes.js";
3
+ type $$ComponentProps = {
4
+ /** Whether the entire control is disabled. */
5
+ disabled?: boolean;
6
+ /** Help text to display below the control. */
7
+ help?: string | Snippet;
8
+ /** A random id is generated if not provided. */
9
+ id?: string;
10
+ /** The label for the control. */
11
+ label?: string | Snippet;
12
+ /** Help text to display below the label. */
13
+ labelHelp?: string | Snippet;
14
+ /** Context tooltip for the label. Renders with a questionmark using ContextTip. */
15
+ labelTip?: string | Snippet;
16
+ /** The name of the field (used as the radio group name). */
17
+ name: string;
18
+ /** Change event handler. */
19
+ onchange?: (e: Event) => void;
20
+ /** Segment options. Accepts `string[]` or `SegmentedControlOption[]`. */
21
+ options: string[] | SegmentedControlOption[];
22
+ /** Whether the field is required. */
23
+ required?: boolean;
24
+ /** The shape of the control. */
25
+ shape?: "rounded" | "pill" | "rectangle";
26
+ /** Size variant controlling padding and font-size. */
27
+ scale?: "xs" | "sm" | "md" | "lg" | "xl";
28
+ /** The currently selected value (bindable). */
29
+ value?: string;
30
+ };
31
+ declare const SegmentedControl: import("svelte").Component<$$ComponentProps, {}, "id" | "value">;
32
+ type SegmentedControl = ReturnType<typeof SegmentedControl>;
33
+ export default SegmentedControl;
@@ -0,0 +1,8 @@
1
+ export type SegmentedControlOption = {
2
+ /** Display label for the segment. */
3
+ label: string;
4
+ /** Value submitted when this segment is selected. */
5
+ value: string;
6
+ /** Whether this individual segment is disabled. */
7
+ disabled?: boolean;
8
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -40,6 +40,7 @@
40
40
  required,
41
41
  results,
42
42
  shape = 'default',
43
+ scale = 'md',
43
44
  tabindex,
44
45
  value = $bindable(),
45
46
  }: {
@@ -87,6 +88,8 @@
87
88
  results?: number;
88
89
  /** The shape of the input element. */
89
90
  shape?: 'default' | 'rounded' | 'pill' | 'circle';
91
+ /** Size variant controlling font-size. Em-based tokens cascade automatically. */
92
+ scale?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
90
93
  /** Source URL for the image type. */
91
94
  src?: string;
92
95
  /** An integer attribute indicating if the element can take input focus (is focusable), if it should participate to sequential keyboard navigation. */
@@ -120,6 +123,7 @@
120
123
  {field}
121
124
  {issue}
122
125
  {required}
126
+ {scale}
123
127
  contained
124
128
  >
125
129
  <div class="SelectContainer">
@@ -47,6 +47,8 @@ type $$ComponentProps = {
47
47
  results?: number;
48
48
  /** The shape of the input element. */
49
49
  shape?: 'default' | 'rounded' | 'pill' | 'circle';
50
+ /** Size variant controlling font-size. Em-based tokens cascade automatically. */
51
+ scale?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
50
52
  /** Source URL for the image type. */
51
53
  src?: string;
52
54
  /** An integer attribute indicating if the element can take input focus (is focusable), if it should participate to sequential keyboard navigation. */
@@ -55,6 +55,7 @@
55
55
  required,
56
56
  resize,
57
57
  shape = 'rounded',
58
+ scale = 'md',
58
59
  step,
59
60
  style,
60
61
  tabindex,
@@ -138,6 +139,8 @@
138
139
  resize?: boolean | 'both' | 'horizontal' | 'vertical' | 'none';
139
140
  /** The shape of the input element. */
140
141
  shape?: 'default' | 'rounded' | 'pill' | 'circle';
142
+ /** Size variant controlling font-size. Em-based tokens cascade automatically. */
143
+ scale?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
141
144
  /** Spellcheck the input. */
142
145
  spellcheck?: boolean;
143
146
  /** A number that specifies the granularity that the value must adhere to. Valid for date, month, week, time, datetime-local, number, and range. */
@@ -221,6 +224,7 @@
221
224
  {help}
222
225
  {suffix}
223
226
  {required}
227
+ {scale}
224
228
  >
225
229
  <textarea
226
230
  class="{resizeClass}"
@@ -77,6 +77,8 @@ type $$ComponentProps = {
77
77
  resize?: boolean | 'both' | 'horizontal' | 'vertical' | 'none';
78
78
  /** The shape of the input element. */
79
79
  shape?: 'default' | 'rounded' | 'pill' | 'circle';
80
+ /** Size variant controlling font-size. Em-based tokens cascade automatically. */
81
+ scale?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
80
82
  /** Spellcheck the input. */
81
83
  spellcheck?: boolean;
82
84
  /** A number that specifies the granularity that the value must adhere to. Valid for date, month, week, time, datetime-local, number, and range. */