@marianmeres/stuic 3.180.0 → 3.181.0

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 (33) hide show
  1. package/AGENTS.md +2 -2
  2. package/dist/components/ColorPicker/ColorPicker.svelte +457 -0
  3. package/dist/components/ColorPicker/ColorPicker.svelte.d.ts +75 -0
  4. package/dist/components/ColorPicker/README.md +220 -0
  5. package/dist/components/ColorPicker/color-value.d.ts +32 -0
  6. package/dist/components/ColorPicker/color-value.js +55 -0
  7. package/dist/components/ColorPicker/i18n-sk.d.ts +17 -0
  8. package/dist/components/ColorPicker/i18n-sk.js +48 -0
  9. package/dist/components/ColorPicker/i18n.d.ts +64 -0
  10. package/dist/components/ColorPicker/i18n.js +75 -0
  11. package/dist/components/ColorPicker/index.css +275 -0
  12. package/dist/components/ColorPicker/index.d.ts +4 -0
  13. package/dist/components/ColorPicker/index.js +4 -0
  14. package/dist/components/ColorPicker/palettes.d.ts +41 -0
  15. package/dist/components/ColorPicker/palettes.js +49 -0
  16. package/dist/components/FieldsBuilder/README.md +3 -1
  17. package/dist/components/FieldsBuilder/types.d.ts +7 -2
  18. package/dist/components/FieldsBuilder/utils.d.ts +2 -1
  19. package/dist/components/FieldsBuilder/utils.js +4 -15
  20. package/dist/components/Nav/Nav.svelte +7 -2
  21. package/dist/components/Nav/Nav.svelte.d.ts +7 -2
  22. package/dist/components/Nav/README.md +2 -2
  23. package/dist/components/TabbedMenu/README.md +14 -13
  24. package/dist/components/TabbedMenu/TabbedMenu.svelte +7 -2
  25. package/dist/components/TabbedMenu/TabbedMenu.svelte.d.ts +7 -2
  26. package/dist/index.css +1 -0
  27. package/dist/index.d.ts +1 -0
  28. package/dist/index.js +1 -0
  29. package/dist/utils/tr.d.ts +26 -14
  30. package/dist/utils/tr.js +43 -19
  31. package/docs/_archive/maybe-todo.md +9 -2
  32. package/docs/domains/components.md +58 -1
  33. package/package.json +1 -1
package/AGENTS.md CHANGED
@@ -23,7 +23,7 @@
23
23
 
24
24
  ```
25
25
  src/lib/
26
- ├── components/ # 79 component directories
26
+ ├── components/ # 80 component directories
27
27
  ├── actions/ # 16 Svelte actions (use: directives)
28
28
  ├── attachments/ # Svelte attachments ({@attach} — preferred for new DOM helpers)
29
29
  ├── utils/ # 55 utility modules (48 on the barrel)
@@ -146,7 +146,7 @@ so it is the only confusable pair — do not "fix" one into the other.
146
146
 
147
147
  ### Domain Docs
148
148
 
149
- - [Components](./docs/domains/components.md) — 79 component directories, Props pattern, snippets
149
+ - [Components](./docs/domains/components.md) — 80 component directories, Props pattern, snippets
150
150
  - [Theming](./docs/domains/theming.md) — CSS tokens, dark mode, themes
151
151
  - [CSS presets](./docs/domains/css-presets.md) — ratio-locked frame (letterbox), safe-area, scrollbar
152
152
  - [Actions](./docs/domains/actions.md) — 16 Svelte directives
@@ -0,0 +1,457 @@
1
+ <script lang="ts" module>
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import type { TranslateFn } from "../../types.js";
4
+ import type {
5
+ ValidateOptions,
6
+ ValidationResult,
7
+ } from "../../actions/validate.svelte.js";
8
+ import type { ColorPickerSwatch } from "./palettes.js";
9
+
10
+ /**
11
+ * Which custom-color controls are rendered under the palette:
12
+ * - `"both"` (default) — the native picker button and the hex text field
13
+ * - `"native"` — only the native `<input type="color">` button
14
+ * - `"text"` — only the hex text field
15
+ * - `false` — none; the palette is the only source of values
16
+ */
17
+ export type ColorPickerCustom = "both" | "native" | "text" | false;
18
+
19
+ export interface Props extends Omit<
20
+ HTMLAttributes<HTMLDivElement>,
21
+ "children" | "onchange"
22
+ > {
23
+ /**
24
+ * Current color (bindable). Any CSS color string; `""` = no color. Stored
25
+ * verbatim — the component never converts between color spaces, so what a
26
+ * swatch holds is what you get back.
27
+ */
28
+ value?: string;
29
+ /**
30
+ * The swatches. Either bare CSS color strings or `{ value, label }` objects.
31
+ * Defaults to `COLOR_PICKER_PALETTE` (12 hues + white/grey/black); pass
32
+ * `COLOR_PICKER_PALETTE_THEME` for design-token colors, or `[]` for none.
33
+ */
34
+ palette?: ColorPickerSwatch[];
35
+ /**
36
+ * Cap the palette at this many swatches per row (a narrower container
37
+ * wraps to fewer rather than overflowing). Unset = as many as fit.
38
+ * ArrowUp / ArrowDown always step by the *rendered* row, whatever this is.
39
+ */
40
+ columns?: number;
41
+ /** Which custom-color controls to show (default `"both"`) */
42
+ custom?: ColorPickerCustom;
43
+ /**
44
+ * Offer clearing: a crossed-out swatch after the palette, plus Delete /
45
+ * Backspace, plus emptying the hex field — all setting `value` to `""`.
46
+ */
47
+ allowClear?: boolean;
48
+ /** Disable interaction (the hidden input is disabled too, so nothing submits) */
49
+ disabled?: boolean;
50
+ /** Accessible name of the swatch group (default `t("color")`, "Color") */
51
+ label?: string;
52
+ /** Form field name (hidden input) */
53
+ name?: string;
54
+ /** Require a non-empty value (enforced by the built-in validator) */
55
+ required?: boolean;
56
+ /** i18n translate function (see `createColorPickerT`) */
57
+ t?: TranslateFn;
58
+ /**
59
+ * Fires when the user commits a color: a swatch click / arrow key, the
60
+ * native picker's `change`, or the hex field on Enter or blur. NOT while
61
+ * the native picker is being dragged — `value` does update live there, so
62
+ * `bind:value` previews, but only the commit is an `onchange`.
63
+ */
64
+ onchange?: (value: string) => void;
65
+ validate?: boolean | Omit<ValidateOptions, "setValidationResult">;
66
+ setValidationResult?: (res: ValidationResult) => void;
67
+ /** Skip all default styling */
68
+ unstyled?: boolean;
69
+ /** Additional CSS classes */
70
+ class?: string;
71
+ /** Class for every swatch button */
72
+ classSwatch?: string;
73
+ /** Bindable root element reference */
74
+ el?: HTMLDivElement;
75
+ /** Bindable hidden input reference */
76
+ inputEl?: HTMLInputElement;
77
+ }
78
+ </script>
79
+
80
+ <script lang="ts">
81
+ import { twMerge } from "../../utils/tw-merge.js";
82
+ import { validate as validateAction } from "../../actions/validate.svelte.js";
83
+ import { isCssColor, isSameColor, normalizeHex } from "./color-value.js";
84
+ import { COLOR_PICKER_PALETTE } from "./palettes.js";
85
+ import { t_default } from "./i18n.js";
86
+
87
+ let {
88
+ value = $bindable(""),
89
+ palette = COLOR_PICKER_PALETTE,
90
+ columns,
91
+ custom = "both",
92
+ allowClear = true,
93
+ disabled = false,
94
+ label,
95
+ name,
96
+ required = false,
97
+ t = t_default,
98
+ onchange,
99
+ validate: validateProp,
100
+ setValidationResult,
101
+ unstyled = false,
102
+ class: classProp,
103
+ classSwatch: classSwatchProp,
104
+ el = $bindable(),
105
+ inputEl = $bindable(),
106
+ ...rest
107
+ }: Props = $props();
108
+
109
+ let _value = $derived(typeof value === "string" ? value : "");
110
+
111
+ // Normalized entries; empty/invalid ones are dropped so a swatch always has
112
+ // something to paint.
113
+ let _entries = $derived(
114
+ (Array.isArray(palette) ? palette : [])
115
+ .map((s) => (typeof s === "string" ? { value: s } : s))
116
+ .filter((s) => !!s && typeof s.value === "string" && !!s.value.trim())
117
+ );
118
+
119
+ let _showNative = $derived(custom === "both" || custom === "native");
120
+ let _showText = $derived(custom === "both" || custom === "text");
121
+
122
+ let _cols = $derived(
123
+ Number.isFinite(columns) && (columns as number) >= 1 ? Math.floor(columns!) : 0
124
+ );
125
+
126
+ // The clear swatch is the last member of the radio group (when enabled).
127
+ let _navCount = $derived(_entries.length + (allowClear ? 1 : 0));
128
+ let _selected = $derived.by(() => {
129
+ if (allowClear && _value === "") return _entries.length;
130
+ return _entries.findIndex((e) => isSameColor(e.value, _value));
131
+ });
132
+
133
+ /**
134
+ * Roving tabindex: the checked swatch is the single tab stop; with a custom
135
+ * (off-palette) color checked, nothing is — so fall back to the first one.
136
+ */
137
+ function tabindexOf(i: number): 0 | -1 {
138
+ if (_selected >= 0) return _selected === i ? 0 : -1;
139
+ return i === 0 ? 0 : -1;
140
+ }
141
+
142
+ function labelOf(e: { value: string; label?: string }): string {
143
+ return e.label ? t(e.label, null, e.label) : e.value;
144
+ }
145
+
146
+ // `<input type="color">` only accepts `#rrggbb`; anything else (a token
147
+ // reference, `transparent`, an empty value) shows as black until picked.
148
+ let _nativeValue = $derived(normalizeHex(_value) ?? "#000000");
149
+
150
+ /**
151
+ * The hex field owns its own DOM value while it is focused — a half-typed
152
+ * "#3b" must survive the keystroke, and the value round-trip must not fight
153
+ * the caret. So it is written explicitly (`syncText`) rather than driven by a
154
+ * reactive `value=`: Svelte skips a write whenever the expression matches
155
+ * what it last wrote, which is exactly the snap-back-after-typing case.
156
+ */
157
+ let textEl: HTMLInputElement | undefined = $state();
158
+
159
+ /** Push the current value into the hex field, dropping whatever was typed. */
160
+ function syncText(input?: HTMLInputElement | null) {
161
+ const target = input ?? textEl;
162
+ if (target && target.value !== _value) target.value = _value;
163
+ }
164
+
165
+ // ...which leaves the field to follow value changes made anywhere else (a
166
+ // swatch, the native picker, the consumer) — but never under the caret.
167
+ $effect(() => {
168
+ void _value;
169
+ if (textEl && document.activeElement !== textEl) syncText();
170
+ });
171
+
172
+ /** Accepts hex in any spelling, then any color the browser understands. */
173
+ function parseColor(raw: string): string | null {
174
+ const v = (raw ?? "").trim();
175
+ if (!v) return allowClear ? "" : null;
176
+ return normalizeHex(v) ?? (isCssColor(v) ? v : null);
177
+ }
178
+
179
+ /** Enter / blur in the hex field: commit it, or snap back if it is garbage. */
180
+ function commitText(input: HTMLInputElement) {
181
+ const parsed = parseColor(input.value);
182
+ if (parsed === null) return syncText(input);
183
+ commit(parsed);
184
+ // show the normalized spelling ("#0f0" -> "#00ff00")
185
+ input.value = parsed;
186
+ }
187
+
188
+ /**
189
+ * Live update, no event — the native picker's drag stream, and a valid color
190
+ * being typed into the hex field.
191
+ */
192
+ function preview(v: string) {
193
+ if (disabled) return;
194
+ value = v;
195
+ }
196
+
197
+ /** A user commit: syncs the hidden input (revalidation) and fires `onchange`. */
198
+ function commit(v: string) {
199
+ if (disabled) return;
200
+ value = v;
201
+ // The hidden input's DOM value is only synced on the next flush, but the
202
+ // validate action reads it synchronously in its "change" listener — so
203
+ // write it by hand before dispatching. Svelte re-applies the same string
204
+ // later (a no-op).
205
+ if (inputEl) {
206
+ inputEl.value = v;
207
+ inputEl.dispatchEvent(new Event("change", { bubbles: true }));
208
+ }
209
+ onchange?.(v);
210
+ }
211
+
212
+ function valueAt(i: number): string {
213
+ return i === _entries.length ? "" : (_entries[i]?.value ?? "");
214
+ }
215
+
216
+ /** Every group member, in DOM order (the clear swatch last). */
217
+ function members(): HTMLElement[] {
218
+ return [
219
+ ...(el?.querySelectorAll<HTMLElement>(`[role="radiogroup"] [data-index]`) ?? []),
220
+ ];
221
+ }
222
+
223
+ /**
224
+ * How many swatches actually share the top row right now. The palette wraps,
225
+ * so this — not the `columns` prop — is what ArrowUp / ArrowDown must step by:
226
+ * it stays true when a narrow screen wraps to fewer per row, and it gives the
227
+ * default (uncapped) palette working vertical arrows for free.
228
+ */
229
+ function rowLength(): number {
230
+ const nodes = members();
231
+ if (nodes.length < 2) return 1;
232
+ const top = nodes[0].offsetTop;
233
+ let n = 0;
234
+ while (n < nodes.length && nodes[n].offsetTop === top) n++;
235
+ return n || 1;
236
+ }
237
+
238
+ function focusAt(i: number) {
239
+ // keyed off the role, not the class — `unstyled` removes the classes
240
+ el?.querySelector<HTMLButtonElement>(
241
+ `[role="radiogroup"] [data-index="${i}"]`
242
+ )?.focus();
243
+ }
244
+
245
+ /**
246
+ * Select the i-th group member. Re-picking the checked one is a no-op event-wise
247
+ * (a radio does not fire `change` when it is already the checked one), but it
248
+ * still moves focus — which is what arrow navigation needs.
249
+ */
250
+ function pick(i: number) {
251
+ if (i < 0 || i >= _navCount) return;
252
+ if (i !== _selected) commit(valueAt(i));
253
+ focusAt(i);
254
+ }
255
+
256
+ function onkeydown(e: KeyboardEvent) {
257
+ if (disabled || !_navCount) return;
258
+ const from = Number((e.target as HTMLElement)?.dataset?.index);
259
+ const cur = Number.isFinite(from) ? from : Math.max(_selected, 0);
260
+ const step = rowLength();
261
+ let next: number;
262
+ switch (e.key) {
263
+ // Horizontal wraps (radiogroup convention), vertical does not — a
264
+ // wrapped row has no meaningful cell above the first one.
265
+ case "ArrowRight":
266
+ next = (cur + 1) % _navCount;
267
+ break;
268
+ case "ArrowLeft":
269
+ next = (cur - 1 + _navCount) % _navCount;
270
+ break;
271
+ case "ArrowDown":
272
+ next = cur + step;
273
+ if (next >= _navCount) return;
274
+ break;
275
+ case "ArrowUp":
276
+ next = cur - step;
277
+ if (next < 0) return;
278
+ break;
279
+ case "Home":
280
+ next = 0;
281
+ break;
282
+ case "End":
283
+ next = _navCount - 1;
284
+ break;
285
+ case "Delete":
286
+ case "Backspace":
287
+ if (!allowClear) return;
288
+ e.preventDefault();
289
+ // already cleared -> handled, but nothing changed (no event)
290
+ if (_value !== "") commit("");
291
+ return;
292
+ default:
293
+ return;
294
+ }
295
+ e.preventDefault();
296
+ pick(next);
297
+ }
298
+
299
+ let _class = $derived(unstyled ? classProp : twMerge("stuic-color-picker", classProp));
300
+ let _classSwatch = $derived(
301
+ unstyled ? classSwatchProp : twMerge("stuic-color-picker-swatch", classSwatchProp)
302
+ );
303
+
304
+ //
305
+ let _doValidate: (() => void) | undefined = $state();
306
+ // Local copy of the last validation result so getValidation() works even
307
+ // when no external setValidationResult was provided.
308
+ let _validation: ValidationResult | undefined = $state();
309
+
310
+ /** Trigger validation now. Reaches the parent via `setValidationResult`. */
311
+ export function validate(): ValidationResult | undefined {
312
+ _doValidate?.();
313
+ return _validation;
314
+ }
315
+
316
+ /** Clear the inline validation message and reset `setCustomValidity`. */
317
+ export function clearValidation(): void {
318
+ _validation = undefined;
319
+ inputEl?.setCustomValidity?.("");
320
+ }
321
+
322
+ /** Current validation state. */
323
+ export function getValidation(): ValidationResult | undefined {
324
+ return _validation;
325
+ }
326
+ </script>
327
+
328
+ <div
329
+ bind:this={el}
330
+ class={_class}
331
+ data-disabled={!unstyled && disabled ? "" : undefined}
332
+ {...rest}
333
+ >
334
+ {#if _navCount}
335
+ <!-- The group is a composite widget with a roving tabindex: the checked
336
+ swatch is the tab stop, never the container. Making the container
337
+ focusable would add a second stop and let a click on the gap between
338
+ swatches pull focus off them. -->
339
+ <!-- svelte-ignore a11y_interactive_supports_focus -->
340
+ <div
341
+ class={unstyled ? undefined : "stuic-color-picker-swatches"}
342
+ role="radiogroup"
343
+ aria-label={label || t("color", null, "Color")}
344
+ aria-required={required ? "true" : undefined}
345
+ aria-disabled={disabled ? "true" : undefined}
346
+ aria-invalid={_validation && !_validation.valid ? "true" : undefined}
347
+ data-columns={!unstyled && _cols ? _cols : undefined}
348
+ style={_cols ? `--stuic-color-picker-columns: ${_cols};` : undefined}
349
+ {onkeydown}
350
+ >
351
+ {#each _entries as entry, i (entry.value + "-" + i)}
352
+ <button
353
+ type="button"
354
+ role="radio"
355
+ class={_classSwatch}
356
+ style="--stuic-color-picker-swatch-color: {entry.value};"
357
+ data-index={i}
358
+ data-selected={!unstyled && _selected === i ? "" : undefined}
359
+ aria-checked={_selected === i}
360
+ aria-label={labelOf(entry)}
361
+ title={labelOf(entry)}
362
+ tabindex={tabindexOf(i)}
363
+ {disabled}
364
+ onclick={() => pick(i)}
365
+ ></button>
366
+ {/each}
367
+ {#if allowClear}
368
+ {@const i = _entries.length}
369
+ <button
370
+ type="button"
371
+ role="radio"
372
+ class={_classSwatch}
373
+ data-index={i}
374
+ data-clear={!unstyled ? "" : undefined}
375
+ data-selected={!unstyled && _selected === i ? "" : undefined}
376
+ aria-checked={_selected === i}
377
+ aria-label={t("no_color", null, "No color")}
378
+ title={t("no_color", null, "No color")}
379
+ tabindex={tabindexOf(i)}
380
+ {disabled}
381
+ onclick={() => pick(i)}
382
+ ></button>
383
+ {/if}
384
+ </div>
385
+ {/if}
386
+
387
+ {#if _showNative || _showText}
388
+ <div class={unstyled ? undefined : "stuic-color-picker-custom"}>
389
+ {#if _showNative}
390
+ <input
391
+ type="color"
392
+ class={unstyled ? undefined : "stuic-color-picker-native"}
393
+ value={_nativeValue}
394
+ {disabled}
395
+ aria-label={t("custom_color", null, "Custom color")}
396
+ title={t("custom_color", null, "Custom color")}
397
+ oninput={(e) => preview(e.currentTarget.value)}
398
+ onchange={(e) => commit(e.currentTarget.value)}
399
+ />
400
+ {/if}
401
+ {#if _showText}
402
+ <input
403
+ bind:this={textEl}
404
+ type="text"
405
+ class={unstyled ? undefined : "stuic-color-picker-text"}
406
+ value={_value}
407
+ {disabled}
408
+ autocomplete="off"
409
+ autocapitalize="none"
410
+ autocorrect="off"
411
+ spellcheck="false"
412
+ inputmode="text"
413
+ placeholder={t("hex_placeholder", null, "#rrggbb")}
414
+ aria-label={t("hex_value", null, "Hex value")}
415
+ oninput={(e) => {
416
+ const parsed = parseColor(e.currentTarget.value);
417
+ // preview only — the commit (and `onchange`) waits for
418
+ // Enter / blur, so a partial value never fires an event
419
+ if (parsed !== null) preview(parsed);
420
+ }}
421
+ onchange={(e) => commitText(e.currentTarget)}
422
+ onblur={(e) => syncText(e.currentTarget)}
423
+ />
424
+ {/if}
425
+ </div>
426
+ {/if}
427
+
428
+ <input
429
+ bind:this={inputEl}
430
+ type="hidden"
431
+ {name}
432
+ value={_value}
433
+ {disabled}
434
+ use:validateAction={() => {
435
+ const customOpts =
436
+ typeof validateProp === "object" && validateProp ? validateProp : {};
437
+ const userValidator = customOpts.customValidator;
438
+ return {
439
+ enabled: validateProp !== false,
440
+ ...customOpts,
441
+ // Hidden inputs are barred from native constraint validation, so
442
+ // `required` is enforced here, then the consumer's validator runs.
443
+ customValidator(val, ctx, input) {
444
+ if (required && !String(val ?? "").trim()) {
445
+ return t("required", null, "Please select a color");
446
+ }
447
+ return userValidator?.(val, ctx, input) || "";
448
+ },
449
+ setValidationResult: (res) => {
450
+ _validation = res;
451
+ setValidationResult?.(res);
452
+ },
453
+ setDoValidate: (fn) => (_doValidate = fn),
454
+ };
455
+ }}
456
+ />
457
+ </div>
@@ -0,0 +1,75 @@
1
+ import type { HTMLAttributes } from "svelte/elements";
2
+ import type { TranslateFn } from "../../types.js";
3
+ import type { ValidateOptions, ValidationResult } from "../../actions/validate.svelte.js";
4
+ import type { ColorPickerSwatch } from "./palettes.js";
5
+ /**
6
+ * Which custom-color controls are rendered under the palette:
7
+ * - `"both"` (default) — the native picker button and the hex text field
8
+ * - `"native"` — only the native `<input type="color">` button
9
+ * - `"text"` — only the hex text field
10
+ * - `false` — none; the palette is the only source of values
11
+ */
12
+ export type ColorPickerCustom = "both" | "native" | "text" | false;
13
+ export interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "children" | "onchange"> {
14
+ /**
15
+ * Current color (bindable). Any CSS color string; `""` = no color. Stored
16
+ * verbatim — the component never converts between color spaces, so what a
17
+ * swatch holds is what you get back.
18
+ */
19
+ value?: string;
20
+ /**
21
+ * The swatches. Either bare CSS color strings or `{ value, label }` objects.
22
+ * Defaults to `COLOR_PICKER_PALETTE` (12 hues + white/grey/black); pass
23
+ * `COLOR_PICKER_PALETTE_THEME` for design-token colors, or `[]` for none.
24
+ */
25
+ palette?: ColorPickerSwatch[];
26
+ /**
27
+ * Cap the palette at this many swatches per row (a narrower container
28
+ * wraps to fewer rather than overflowing). Unset = as many as fit.
29
+ * ArrowUp / ArrowDown always step by the *rendered* row, whatever this is.
30
+ */
31
+ columns?: number;
32
+ /** Which custom-color controls to show (default `"both"`) */
33
+ custom?: ColorPickerCustom;
34
+ /**
35
+ * Offer clearing: a crossed-out swatch after the palette, plus Delete /
36
+ * Backspace, plus emptying the hex field — all setting `value` to `""`.
37
+ */
38
+ allowClear?: boolean;
39
+ /** Disable interaction (the hidden input is disabled too, so nothing submits) */
40
+ disabled?: boolean;
41
+ /** Accessible name of the swatch group (default `t("color")`, "Color") */
42
+ label?: string;
43
+ /** Form field name (hidden input) */
44
+ name?: string;
45
+ /** Require a non-empty value (enforced by the built-in validator) */
46
+ required?: boolean;
47
+ /** i18n translate function (see `createColorPickerT`) */
48
+ t?: TranslateFn;
49
+ /**
50
+ * Fires when the user commits a color: a swatch click / arrow key, the
51
+ * native picker's `change`, or the hex field on Enter or blur. NOT while
52
+ * the native picker is being dragged — `value` does update live there, so
53
+ * `bind:value` previews, but only the commit is an `onchange`.
54
+ */
55
+ onchange?: (value: string) => void;
56
+ validate?: boolean | Omit<ValidateOptions, "setValidationResult">;
57
+ setValidationResult?: (res: ValidationResult) => void;
58
+ /** Skip all default styling */
59
+ unstyled?: boolean;
60
+ /** Additional CSS classes */
61
+ class?: string;
62
+ /** Class for every swatch button */
63
+ classSwatch?: string;
64
+ /** Bindable root element reference */
65
+ el?: HTMLDivElement;
66
+ /** Bindable hidden input reference */
67
+ inputEl?: HTMLInputElement;
68
+ }
69
+ declare const ColorPicker: import("svelte").Component<Props, {
70
+ validate: () => ValidationResult | undefined;
71
+ clearValidation: () => void;
72
+ getValidation: () => ValidationResult | undefined;
73
+ }, "el" | "value" | "inputEl">;
74
+ type ColorPicker = ReturnType<typeof ColorPicker>;
75
+ export default ColorPicker;