@spaethtech/svelte-ui 0.20.0 → 0.20.1-dev.102.3c5719c

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 (46) hide show
  1. package/dist/components/Alert.svelte +11 -5
  2. package/dist/components/Alert.svelte.d.ts +2 -0
  3. package/dist/components/Avatar/Avatar.svelte +4 -2
  4. package/dist/components/Avatar/Avatar.svelte.d.ts +2 -1
  5. package/dist/components/Avatar/AvatarGroup.svelte +4 -1
  6. package/dist/components/Avatar/AvatarGroup.svelte.d.ts +2 -1
  7. package/dist/components/Badge/Badge.svelte +9 -2
  8. package/dist/components/Badge/Badge.svelte.d.ts +2 -1
  9. package/dist/components/Breadcrumbs/Breadcrumbs.svelte +4 -2
  10. package/dist/components/Breadcrumbs/Breadcrumbs.svelte.d.ts +2 -1
  11. package/dist/components/CardFooter.svelte +12 -1
  12. package/dist/components/CardFooter.svelte.d.ts +3 -0
  13. package/dist/components/Divider/Divider.svelte +6 -3
  14. package/dist/components/Divider/Divider.svelte.d.ts +2 -1
  15. package/dist/components/EmailInput.svelte +2 -1
  16. package/dist/components/EmailInput.svelte.d.ts +2 -1
  17. package/dist/components/EmptyState/EmptyState.svelte +4 -2
  18. package/dist/components/EmptyState/EmptyState.svelte.d.ts +2 -1
  19. package/dist/components/Grid.svelte +4 -2
  20. package/dist/components/Grid.svelte.d.ts +2 -1
  21. package/dist/components/Kbd/Kbd.svelte +5 -3
  22. package/dist/components/Kbd/Kbd.svelte.d.ts +2 -1
  23. package/dist/components/List.svelte +4 -2
  24. package/dist/components/List.svelte.d.ts +2 -1
  25. package/dist/components/NumberInput.svelte +2 -1
  26. package/dist/components/NumberInput.svelte.d.ts +2 -1
  27. package/dist/components/PasswordInput.svelte +2 -1
  28. package/dist/components/PasswordInput.svelte.d.ts +2 -1
  29. package/dist/components/Progress/Progress.svelte +4 -2
  30. package/dist/components/Progress/Progress.svelte.d.ts +2 -1
  31. package/dist/components/SearchInput.svelte +2 -1
  32. package/dist/components/SearchInput.svelte.d.ts +2 -1
  33. package/dist/components/Select.svelte +3 -1
  34. package/dist/components/Select.svelte.d.ts +3 -1
  35. package/dist/components/Skeleton/Skeleton.svelte +7 -2
  36. package/dist/components/Skeleton/Skeleton.svelte.d.ts +2 -1
  37. package/dist/components/Stat/Stat.svelte +4 -2
  38. package/dist/components/Stat/Stat.svelte.d.ts +2 -1
  39. package/dist/components/TimeRangeInput.svelte +5 -1
  40. package/dist/components/TimeRangeInput.svelte.d.ts +3 -1
  41. package/dist/components/Timeline/Timeline.svelte +4 -2
  42. package/dist/components/Timeline/Timeline.svelte.d.ts +2 -1
  43. package/dist/components/field-chrome.d.ts +22 -0
  44. package/dist/components/field-chrome.js +1 -0
  45. package/docs/components.md +5 -1
  46. package/package.json +1 -1
@@ -14,6 +14,8 @@
14
14
  variant?: AlertVariant;
15
15
  size?: Responsive<Size>;
16
16
  text?: string;
17
+ /** Optional bold heading rendered above the body (`text`/`children`). Icon top-aligns when set. */
18
+ title?: string;
17
19
  /** Faint tinted background in addition to the bordered + coloured text. */
18
20
  filled?: boolean;
19
21
  /** Drop the visible frame while keeping the 1px box: border colour = the alert's own background
@@ -31,6 +33,7 @@
31
33
  variant = "info",
32
34
  size = "md",
33
35
  text = "",
36
+ title,
34
37
  filled = false,
35
38
  borderless = false,
36
39
  icon,
@@ -86,13 +89,13 @@
86
89
  ` color: ${textColor};` +
87
90
  (filled ? ` background-color: ${bgColor};` : ""),
88
91
  );
89
- const has = $derived(!!children || !!text);
92
+ const has = $derived(!!children || !!text || !!title);
90
93
  </script>
91
94
 
92
95
  {#if has}
93
96
  <div
94
97
  role="alert"
95
- class="flex items-center [border-radius:var(--ui-border-radius)] border {responsiveClasses(
98
+ class="flex {title ? 'items-start' : 'items-center'} [border-radius:var(--ui-border-radius)] border {responsiveClasses(
96
99
  size,
97
100
  sizeClass,
98
101
  )} {cls}"
@@ -104,9 +107,12 @@
104
107
  >{@render icon()}</span
105
108
  >
106
109
  {/if}
107
- <span class="min-w-0"
108
- >{#if children}{@render children()}{:else}{text}{/if}</span
109
- >
110
+ <div class="flex min-w-0 flex-col">
111
+ {#if title}<span class="font-semibold">{title}</span>{/if}
112
+ <span class="min-w-0"
113
+ >{#if children}{@render children()}{:else}{text}{/if}</span
114
+ >
115
+ </div>
110
116
  {#if icon && iconPosition === "right"}
111
117
  <span
112
118
  class="ml-auto inline-flex shrink-0 [&_svg]:fill-current {responsiveClasses(
@@ -11,6 +11,8 @@ interface Props {
11
11
  variant?: AlertVariant;
12
12
  size?: Responsive<Size>;
13
13
  text?: string;
14
+ /** Optional bold heading rendered above the body (`text`/`children`). Icon top-aligns when set. */
15
+ title?: string;
14
16
  /** Faint tinted background in addition to the bordered + coloured text. */
15
17
  filled?: boolean;
16
18
  /** Drop the visible frame while keeping the 1px box: border colour = the alert's own background
@@ -12,6 +12,7 @@
12
12
 
13
13
  <script lang="ts">
14
14
  import type { Snippet } from "svelte";
15
+ import type { HTMLAttributes } from "svelte/elements";
15
16
  import type { Variant } from "../../types/variants.js";
16
17
  import { variantToken } from "../../types/variants.js";
17
18
  import type { Size } from "../../types/sizes.js";
@@ -28,6 +29,7 @@
28
29
  shape = "circle",
29
30
  status,
30
31
  class: cls = "",
32
+ ...rest
31
33
  }: {
32
34
  src?: string;
33
35
  name?: string;
@@ -38,7 +40,7 @@
38
40
  shape?: AvatarShape;
39
41
  status?: AvatarStatus;
40
42
  class?: string;
41
- } = $props();
43
+ } & Omit<HTMLAttributes<HTMLSpanElement>, "class"> = $props();
42
44
 
43
45
  let imgFailed = $state(false);
44
46
  // Reset the failed flag whenever the source changes.
@@ -80,7 +82,7 @@
80
82
  const shapeClass = $derived(shape === "circle" ? "rounded-full" : "rounded-[var(--ui-border-radius)]");
81
83
  </script>
82
84
 
83
- <span class="relative inline-flex shrink-0 {cls}">
85
+ <span class="relative inline-flex shrink-0 {cls}" {...rest}>
84
86
  <span
85
87
  class="ui-avatar inline-flex items-center justify-center overflow-hidden font-medium select-none {shapeClass} {responsiveClasses(
86
88
  size,
@@ -1,6 +1,7 @@
1
1
  export type AvatarShape = "circle" | "square";
2
2
  export type AvatarStatus = "online" | "offline" | "busy" | "away";
3
3
  import type { Snippet } from "svelte";
4
+ import type { HTMLAttributes } from "svelte/elements";
4
5
  import type { Variant } from "../../types/variants.js";
5
6
  import type { Size } from "../../types/sizes.js";
6
7
  import { type Responsive } from "../../types/responsive.js";
@@ -14,7 +15,7 @@ type $$ComponentProps = {
14
15
  shape?: AvatarShape;
15
16
  status?: AvatarStatus;
16
17
  class?: string;
17
- };
18
+ } & Omit<HTMLAttributes<HTMLSpanElement>, "class">;
18
19
  declare const Avatar: import("svelte").Component<$$ComponentProps, {}, "">;
19
20
  type Avatar = ReturnType<typeof Avatar>;
20
21
  export default Avatar;
@@ -21,6 +21,7 @@
21
21
 
22
22
  <script lang="ts">
23
23
  import Avatar from "./Avatar.svelte";
24
+ import type { HTMLAttributes } from "svelte/elements";
24
25
  import { variantToken } from "../../types/variants.js";
25
26
  import type { Size } from "../../types/sizes.js";
26
27
  import { responsiveClasses, type Responsive } from "../../types/responsive.js";
@@ -33,6 +34,7 @@
33
34
  variant = "neutral",
34
35
  class: cls = "",
35
36
  children,
37
+ ...rest
36
38
  }: {
37
39
  items?: AvatarItem[];
38
40
  max?: number;
@@ -41,7 +43,7 @@
41
43
  variant?: Variant;
42
44
  class?: string;
43
45
  children?: Snippet;
44
- } = $props();
46
+ } & Omit<HTMLAttributes<HTMLDivElement>, "class"> = $props();
45
47
 
46
48
  const shown = $derived(
47
49
  items ? (max != null && items.length > max ? items.slice(0, max) : items) : [],
@@ -61,6 +63,7 @@
61
63
  avatars stay visually separated. -->
62
64
  <div
63
65
  class="flex items-center [&_.ui-avatar]:border-2 [&_.ui-avatar]:[border-color:var(--ui-color-background)] [&>*:not(:first-child)]:-ml-2 {cls}"
66
+ {...rest}
64
67
  >
65
68
  {#if items}
66
69
  {#each shown as it, i (i)}
@@ -8,6 +8,7 @@ export type AvatarItem = {
8
8
  variant?: Variant;
9
9
  icon?: Snippet;
10
10
  };
11
+ import type { HTMLAttributes } from "svelte/elements";
11
12
  import type { Size } from "../../types/sizes.js";
12
13
  import { type Responsive } from "../../types/responsive.js";
13
14
  type $$ComponentProps = {
@@ -18,7 +19,7 @@ type $$ComponentProps = {
18
19
  variant?: Variant;
19
20
  class?: string;
20
21
  children?: Snippet;
21
- };
22
+ } & Omit<HTMLAttributes<HTMLDivElement>, "class">;
22
23
  declare const AvatarGroup: import("svelte").Component<$$ComponentProps, {}, "">;
23
24
  type AvatarGroup = ReturnType<typeof AvatarGroup>;
24
25
  export default AvatarGroup;
@@ -2,6 +2,7 @@
2
2
  import { uiI18n } from "../../i18n.js";
3
3
  const i18n = uiI18n();
4
4
  import type { Snippet } from "svelte";
5
+ import type { HTMLAttributes } from "svelte/elements";
5
6
  import Close from "~icons/mdi/close";
6
7
  import type { Size } from "../../types/sizes.js";
7
8
  import { responsiveClasses, type Responsive } from "../../types/responsive.js";
@@ -27,7 +28,10 @@
27
28
  | "danger"
28
29
  | "ghost";
29
30
 
30
- interface Props {
31
+ // Spreads leftover HTML attributes (`class`, `data-*`, `aria-*`, `title`, `id`, event handlers, …)
32
+ // onto the chip's root element. `style` is OMITTED — the chip computes its own themed `style`
33
+ // (fill/border/text `color-mix`); a passthrough would clobber it. Use `class` for overrides.
34
+ interface Props extends Omit<HTMLAttributes<HTMLElement>, "style"> {
31
35
  text?: string;
32
36
  variant?: BadgeVariant;
33
37
  size?: Responsive<Size>;
@@ -55,6 +59,8 @@
55
59
  href,
56
60
  ondismiss,
57
61
  children,
62
+ class: cls = "",
63
+ ...rest
58
64
  }: Props = $props();
59
65
 
60
66
  // Every variant maps to a library-wide colour token — no Tailwind
@@ -128,12 +134,13 @@
128
134
  {#if hasContent}
129
135
  <svelte:element
130
136
  this={href ? "a" : "span"}
137
+ {...rest}
131
138
  {href}
132
139
  class="inline-flex items-center gap-1 border no-underline select-none {href
133
140
  ? 'cursor-pointer hover:brightness-95'
134
141
  : 'cursor-default'} {responsiveClasses(size, sizeClass)} {rounded
135
142
  ? 'rounded-full'
136
- : 'rounded'} transition-[filter,background-color,border-color] duration-150"
143
+ : 'rounded'} transition-[filter,background-color,border-color] duration-150 {cls}"
137
144
  {style}
138
145
  >
139
146
  <span class="truncate">
@@ -1,4 +1,5 @@
1
1
  import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
2
3
  import type { Size } from "../../types/sizes.js";
3
4
  import { type Responsive } from "../../types/responsive.js";
4
5
  /**
@@ -12,7 +13,7 @@ import { type Responsive } from "../../types/responsive.js";
12
13
  * text stays high-contrast against the background.
13
14
  */
14
15
  type BadgeVariant = "neutral" | "default" | "primary" | "secondary" | "success" | "info" | "warning" | "danger" | "ghost";
15
- interface Props {
16
+ interface Props extends Omit<HTMLAttributes<HTMLElement>, "style"> {
16
17
  text?: string;
17
18
  variant?: BadgeVariant;
18
19
  size?: Responsive<Size>;
@@ -19,6 +19,7 @@
19
19
  <script lang="ts">
20
20
  import { uiI18n } from "../../i18n.js";
21
21
  const i18n = uiI18n();
22
+ import type { HTMLAttributes } from "svelte/elements";
22
23
  import Button from "../Button.svelte";
23
24
  import Menu from "../Menu.svelte";
24
25
  import type { MenuItem } from "../../data/table/types.js";
@@ -33,13 +34,14 @@
33
34
  maxItems,
34
35
  size = "md",
35
36
  class: cls = "",
37
+ ...rest
36
38
  }: {
37
39
  items: BreadcrumbItem[];
38
40
  separator?: Snippet | string;
39
41
  maxItems?: number;
40
42
  size?: Responsive<Size>;
41
43
  class?: string;
42
- } = $props();
44
+ } & Omit<HTMLAttributes<HTMLElement>, "class"> = $props();
43
45
 
44
46
  type Node =
45
47
  | { kind: "crumb"; item: BreadcrumbItem; last: boolean }
@@ -73,7 +75,7 @@
73
75
  }
74
76
  </script>
75
77
 
76
- <nav aria-label={i18n.messages.breadcrumb} class={cls}>
78
+ <nav aria-label={i18n.messages.breadcrumb} class={cls} {...rest}>
77
79
  <ol
78
80
  class="flex flex-wrap items-center gap-1 [color:color-mix(in_srgb,var(--ui-color-text)_60%,transparent)]"
79
81
  >
@@ -5,6 +5,7 @@ export type BreadcrumbItem = {
5
5
  onclick?: () => void;
6
6
  icon?: Snippet;
7
7
  };
8
+ import type { HTMLAttributes } from "svelte/elements";
8
9
  import type { Size } from "../../types/sizes.js";
9
10
  import { type Responsive } from "../../types/responsive.js";
10
11
  type $$ComponentProps = {
@@ -13,7 +14,7 @@ type $$ComponentProps = {
13
14
  maxItems?: number;
14
15
  size?: Responsive<Size>;
15
16
  class?: string;
16
- };
17
+ } & Omit<HTMLAttributes<HTMLElement>, "class">;
17
18
  declare const Breadcrumbs: import("svelte").Component<$$ComponentProps, {}, "">;
18
19
  type Breadcrumbs = ReturnType<typeof Breadcrumbs>;
19
20
  export default Breadcrumbs;
@@ -17,6 +17,7 @@
17
17
  variant = "neutral",
18
18
  size = "md",
19
19
  separator = true,
20
+ align = "right",
20
21
  class: cls = "",
21
22
  children,
22
23
  ...rest
@@ -25,10 +26,20 @@
25
26
  size?: Responsive<Size>;
26
27
  /** Show the top separator (default true). */
27
28
  separator?: boolean;
29
+ /** Horizontal placement of the footer content (action buttons). Default `"right"` — footers
30
+ * right-align actions. Convenience over `class`; a `class` justify-* still overrides (applied last). */
31
+ align?: "left" | "center" | "right" | "between";
28
32
  class?: string;
29
33
  children?: Snippet;
30
34
  } & Omit<HTMLAttributes<HTMLDivElement>, "class"> = $props();
31
35
 
36
+ const justifyClass: Record<NonNullable<typeof align>, string> = {
37
+ left: "justify-start",
38
+ center: "justify-center",
39
+ right: "justify-end",
40
+ between: "justify-between",
41
+ };
42
+
32
43
  // The body→footer gap (`pad`) is ALWAYS applied, so `separator={false}` still leaves breathing room
33
44
  // above the footer (just no line). `separator={true}` adds the line + a matching margin above it
34
45
  // (`sepGap`), giving the margin → line → pad rhythm.
@@ -44,7 +55,7 @@
44
55
  </script>
45
56
 
46
57
  <div
47
- class="flex items-center justify-end gap-3 {responsiveClasses(size, pad)} {separator
58
+ class="flex items-center {justifyClass[align]} gap-3 {responsiveClasses(size, pad)} {separator
48
59
  ? 'border-t ' + responsiveClasses(size, sepGap)
49
60
  : ''} {cls}"
50
61
  style={separator ? `border-color: ${sepColor}` : ""}
@@ -8,6 +8,9 @@ type $$ComponentProps = {
8
8
  size?: Responsive<Size>;
9
9
  /** Show the top separator (default true). */
10
10
  separator?: boolean;
11
+ /** Horizontal placement of the footer content (action buttons). Default `"right"` — footers
12
+ * right-align actions. Convenience over `class`; a `class` justify-* still overrides (applied last). */
13
+ align?: "left" | "center" | "right" | "between";
11
14
  class?: string;
12
15
  children?: Snippet;
13
16
  } & Omit<HTMLAttributes<HTMLDivElement>, "class">;
@@ -7,6 +7,7 @@
7
7
  -->
8
8
  <script lang="ts">
9
9
  import type { Snippet } from "svelte";
10
+ import type { HTMLAttributes } from "svelte/elements";
10
11
 
11
12
  let {
12
13
  orientation = "horizontal",
@@ -14,13 +15,14 @@
14
15
  labelAlign = "center",
15
16
  class: cls = "",
16
17
  children,
18
+ ...rest
17
19
  }: {
18
20
  orientation?: "horizontal" | "vertical";
19
21
  label?: string;
20
22
  labelAlign?: "start" | "center" | "end";
21
23
  class?: string;
22
24
  children?: Snippet;
23
- } = $props();
25
+ } & Omit<HTMLAttributes<HTMLElement>, "class"> = $props();
24
26
 
25
27
  const hasLabel = $derived(orientation === "horizontal" && (!!label || !!children));
26
28
  </script>
@@ -30,9 +32,10 @@
30
32
  role="separator"
31
33
  aria-orientation="vertical"
32
34
  class="inline-block w-px self-stretch [background-color:var(--ui-border-color)] {cls}"
35
+ {...rest}
33
36
  ></div>
34
37
  {:else if hasLabel}
35
- <div role="separator" aria-orientation="horizontal" class="flex items-center gap-3 {cls}">
38
+ <div role="separator" aria-orientation="horizontal" class="flex items-center gap-3 {cls}" {...rest}>
36
39
  {#if labelAlign !== "start"}
37
40
  <div class="h-px flex-1 [background-color:var(--ui-border-color)]"></div>
38
41
  {/if}
@@ -44,5 +47,5 @@
44
47
  {/if}
45
48
  </div>
46
49
  {:else}
47
- <hr class="w-full border-0 h-px [background-color:var(--ui-border-color)] {cls}" />
50
+ <hr class="w-full border-0 h-px [background-color:var(--ui-border-color)] {cls}" {...rest} />
48
51
  {/if}
@@ -1,11 +1,12 @@
1
1
  import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
2
3
  type $$ComponentProps = {
3
4
  orientation?: "horizontal" | "vertical";
4
5
  label?: string;
5
6
  labelAlign?: "start" | "center" | "end";
6
7
  class?: string;
7
8
  children?: Snippet;
8
- };
9
+ } & Omit<HTMLAttributes<HTMLElement>, "class">;
9
10
  declare const Divider: import("svelte").Component<$$ComponentProps, {}, "">;
10
11
  type Divider = ReturnType<typeof Divider>;
11
12
  export default Divider;
@@ -5,8 +5,9 @@
5
5
  import type { Size } from "../types/sizes.js";
6
6
  import type { Responsive } from "../types/responsive.js";
7
7
  import type { Variant } from "../types/variants.js";
8
+ import type { FieldChromeProps } from "./field-chrome.js";
8
9
 
9
- interface Props extends Omit<HTMLInputAttributes, "type" | "size"> {
10
+ interface Props extends Omit<HTMLInputAttributes, "type" | "size">, FieldChromeProps {
10
11
  value: string;
11
12
  class?: string;
12
13
  inputClass?: string;
@@ -2,7 +2,8 @@ import type { HTMLInputAttributes } from "svelte/elements";
2
2
  import type { Size } from "../types/sizes.js";
3
3
  import type { Responsive } from "../types/responsive.js";
4
4
  import type { Variant } from "../types/variants.js";
5
- interface Props extends Omit<HTMLInputAttributes, "type" | "size"> {
5
+ import type { FieldChromeProps } from "./field-chrome.js";
6
+ interface Props extends Omit<HTMLInputAttributes, "type" | "size">, FieldChromeProps {
6
7
  value: string;
7
8
  class?: string;
8
9
  inputClass?: string;
@@ -6,6 +6,7 @@
6
6
  -->
7
7
  <script lang="ts">
8
8
  import type { Snippet } from "svelte";
9
+ import type { HTMLAttributes } from "svelte/elements";
9
10
  import IconInbox from "~icons/mdi/inbox-outline";
10
11
  import type { Variant } from "../../types/variants.js";
11
12
  import { variantToken } from "../../types/variants.js";
@@ -21,6 +22,7 @@
21
22
  size = "md",
22
23
  class: cls = "",
23
24
  children,
25
+ ...rest
24
26
  }: {
25
27
  title?: string;
26
28
  description?: string;
@@ -32,7 +34,7 @@
32
34
  size?: Responsive<Size>;
33
35
  class?: string;
34
36
  children?: Snippet;
35
- } = $props();
37
+ } & Omit<HTMLAttributes<HTMLDivElement>, "class"> = $props();
36
38
 
37
39
  const token = $derived(variantToken[variant]);
38
40
  const iconBox: Record<Size, string> = {
@@ -44,7 +46,7 @@
44
46
  const padSize: Record<Size, string> = { sm: "py-6 gap-2", md: "py-10 gap-3", lg: "py-16 gap-4" };
45
47
  </script>
46
48
 
47
- <div class="flex flex-col items-center text-center {responsiveClasses(size, padSize)} {cls}">
49
+ <div class="flex flex-col items-center text-center {responsiveClasses(size, padSize)} {cls}" {...rest}>
48
50
  <div
49
51
  class="inline-flex items-center justify-center rounded-full {responsiveClasses(size, iconBox)}"
50
52
  style="background-color: color-mix(in srgb, var({token}) 14%, transparent); color: color-mix(in srgb, var({token}) var(--ui-tint-strong), var(--ui-color-text));"
@@ -1,4 +1,5 @@
1
1
  import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
2
3
  import type { Variant } from "../../types/variants.js";
3
4
  import type { Size } from "../../types/sizes.js";
4
5
  import { type Responsive } from "../../types/responsive.js";
@@ -13,7 +14,7 @@ type $$ComponentProps = {
13
14
  size?: Responsive<Size>;
14
15
  class?: string;
15
16
  children?: Snippet;
16
- };
17
+ } & Omit<HTMLAttributes<HTMLDivElement>, "class">;
17
18
  declare const EmptyState: import("svelte").Component<$$ComponentProps, {}, "">;
18
19
  type EmptyState = ReturnType<typeof EmptyState>;
19
20
  export default EmptyState;
@@ -10,6 +10,7 @@
10
10
  -->
11
11
  <script lang="ts">
12
12
  import type { Snippet } from "svelte";
13
+ import type { HTMLAttributes } from "svelte/elements";
13
14
  import { gridColsClass, gapClass, type Columns, type Gap } from "./field-group.js";
14
15
 
15
16
  let {
@@ -17,6 +18,7 @@
17
18
  gap = 4,
18
19
  class: cls = "",
19
20
  children,
21
+ ...rest
20
22
  }: {
21
23
  /** Track count — a number (1–6) or a responsive map like `{ base: 1, md: 3 }`. Default 1. */
22
24
  columns?: Columns;
@@ -24,11 +26,11 @@
24
26
  gap?: Gap;
25
27
  class?: string;
26
28
  children: Snippet;
27
- } = $props();
29
+ } & Omit<HTMLAttributes<HTMLDivElement>, "class"> = $props();
28
30
 
29
31
  const gridClass = $derived(`grid ${gridColsClass(columns)} ${gapClass(gap, 4)}`);
30
32
  </script>
31
33
 
32
- <div class="{gridClass} {cls}">
34
+ <div class="{gridClass} {cls}" {...rest}>
33
35
  {@render children()}
34
36
  </div>
@@ -1,4 +1,5 @@
1
1
  import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
2
3
  import { type Columns, type Gap } from "./field-group.js";
3
4
  type $$ComponentProps = {
4
5
  /** Track count — a number (1–6) or a responsive map like `{ base: 1, md: 3 }`. Default 1. */
@@ -7,7 +8,7 @@ type $$ComponentProps = {
7
8
  gap?: Gap;
8
9
  class?: string;
9
10
  children: Snippet;
10
- };
11
+ } & Omit<HTMLAttributes<HTMLDivElement>, "class">;
11
12
  declare const Grid: import("svelte").Component<$$ComponentProps, {}, "">;
12
13
  type Grid = ReturnType<typeof Grid>;
13
14
  export default Grid;
@@ -6,6 +6,7 @@
6
6
  -->
7
7
  <script lang="ts">
8
8
  import type { Snippet } from "svelte";
9
+ import type { HTMLAttributes } from "svelte/elements";
9
10
  import type { Size } from "../../types/sizes.js";
10
11
  import { responsiveClasses, type Responsive } from "../../types/responsive.js";
11
12
 
@@ -15,6 +16,7 @@
15
16
  size = "md",
16
17
  class: cls = "",
17
18
  children,
19
+ ...rest
18
20
  }: {
19
21
  /** A combo — each string is rendered as its own keycap, joined with "+". */
20
22
  keys?: string[];
@@ -23,7 +25,7 @@
23
25
  size?: Responsive<Size>;
24
26
  class?: string;
25
27
  children?: Snippet;
26
- } = $props();
28
+ } & Omit<HTMLAttributes<HTMLElement>, "class"> = $props();
27
29
 
28
30
  const list = $derived(keys ?? null);
29
31
 
@@ -38,7 +40,7 @@
38
40
  </script>
39
41
 
40
42
  {#if list}
41
- <span class="inline-flex items-center gap-1 {cls}">
43
+ <span class="inline-flex items-center gap-1 {cls}" {...rest}>
42
44
  {#each list as k, i (i)}
43
45
  {#if i > 0}<span class="text-xs [color:color-mix(in_srgb,var(--ui-color-text)_50%,transparent)]"
44
46
  >+</span
@@ -47,7 +49,7 @@
47
49
  {/each}
48
50
  </span>
49
51
  {:else}
50
- <kbd class="{cap} {responsiveClasses(size, capSize)} {cls}"
52
+ <kbd class="{cap} {responsiveClasses(size, capSize)} {cls}" {...rest}
51
53
  >{#if children}{@render children()}{:else}{text}{/if}</kbd
52
54
  >
53
55
  {/if}
@@ -1,4 +1,5 @@
1
1
  import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
2
3
  import type { Size } from "../../types/sizes.js";
3
4
  import { type Responsive } from "../../types/responsive.js";
4
5
  type $$ComponentProps = {
@@ -9,7 +10,7 @@ type $$ComponentProps = {
9
10
  size?: Responsive<Size>;
10
11
  class?: string;
11
12
  children?: Snippet;
12
- };
13
+ } & Omit<HTMLAttributes<HTMLElement>, "class">;
13
14
  declare const Kbd: import("svelte").Component<$$ComponentProps, {}, "">;
14
15
  type Kbd = ReturnType<typeof Kbd>;
15
16
  export default Kbd;
@@ -3,6 +3,7 @@
3
3
  const i18n = uiI18n();
4
4
  import { untrack } from "svelte";
5
5
  import type { Snippet } from "svelte";
6
+ import type { HTMLAttributes } from "svelte/elements";
6
7
  import type { Size } from "../types/sizes.js";
7
8
  import { responsiveClasses, type Responsive } from "../types/responsive.js";
8
9
  import { variantToken, type Variant } from "../types/variants.js";
@@ -12,7 +13,7 @@
12
13
  label: string;
13
14
  };
14
15
 
15
- interface Props {
16
+ interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "class"> {
16
17
  options: Option[];
17
18
  value?: string | string[]; // Bindable selected value - string[] when multiSelect is true
18
19
  multiSelect?: boolean; // Enable multi-select mode
@@ -81,6 +82,7 @@
81
82
  onLoadStart,
82
83
  onLoadEnd,
83
84
  onSelection,
85
+ ...rest
84
86
  }: Props = $props();
85
87
 
86
88
  // Size axis (see types/sizes.ts): option text scales with the trigger (forwarded by Select).
@@ -499,7 +501,7 @@
499
501
  });
500
502
  </script>
501
503
 
502
- <div class="relative {className}">
504
+ <div class="relative {className}" {...rest}>
503
505
  <div class="relative">
504
506
  <div
505
507
  bind:this={listElement}
@@ -1,4 +1,5 @@
1
1
  import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
2
3
  import type { Size } from "../types/sizes.js";
3
4
  import { type Responsive } from "../types/responsive.js";
4
5
  import { type Variant } from "../types/variants.js";
@@ -6,7 +7,7 @@ type Option = Record<string, any> & {
6
7
  value: string;
7
8
  label: string;
8
9
  };
9
- interface Props {
10
+ interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "class"> {
10
11
  options: Option[];
11
12
  value?: string | string[];
12
13
  multiSelect?: boolean;
@@ -11,8 +11,9 @@
11
11
  import type { Size } from "../types/sizes.js";
12
12
  import type { Responsive } from "../types/responsive.js";
13
13
  import type { Variant } from "../types/variants.js";
14
+ import type { FieldChromeProps } from "./field-chrome.js";
14
15
 
15
- interface Props extends Omit<HTMLInputAttributes, "type" | "value" | "size"> {
16
+ interface Props extends Omit<HTMLInputAttributes, "type" | "value" | "size">, FieldChromeProps {
16
17
  value: number | null;
17
18
  class?: string;
18
19
  inputClass?: string;
@@ -2,7 +2,8 @@ import type { HTMLInputAttributes } from "svelte/elements";
2
2
  import type { Size } from "../types/sizes.js";
3
3
  import type { Responsive } from "../types/responsive.js";
4
4
  import type { Variant } from "../types/variants.js";
5
- interface Props extends Omit<HTMLInputAttributes, "type" | "value" | "size"> {
5
+ import type { FieldChromeProps } from "./field-chrome.js";
6
+ interface Props extends Omit<HTMLInputAttributes, "type" | "value" | "size">, FieldChromeProps {
6
7
  value: number | null;
7
8
  class?: string;
8
9
  inputClass?: string;
@@ -6,8 +6,9 @@
6
6
  import type { Size } from "../types/sizes.js";
7
7
  import type { Responsive } from "../types/responsive.js";
8
8
  import type { Variant } from "../types/variants.js";
9
+ import type { FieldChromeProps } from "./field-chrome.js";
9
10
 
10
- interface Props extends Omit<HTMLInputAttributes, "type" | "size"> {
11
+ interface Props extends Omit<HTMLInputAttributes, "type" | "size">, FieldChromeProps {
11
12
  value: string;
12
13
  class?: string;
13
14
  inputClass?: string;
@@ -2,7 +2,8 @@ import type { HTMLInputAttributes } from "svelte/elements";
2
2
  import type { Size } from "../types/sizes.js";
3
3
  import type { Responsive } from "../types/responsive.js";
4
4
  import type { Variant } from "../types/variants.js";
5
- interface Props extends Omit<HTMLInputAttributes, "type" | "size"> {
5
+ import type { FieldChromeProps } from "./field-chrome.js";
6
+ interface Props extends Omit<HTMLInputAttributes, "type" | "size">, FieldChromeProps {
6
7
  value: string;
7
8
  class?: string;
8
9
  inputClass?: string;
@@ -6,6 +6,7 @@
6
6
  */
7
7
  -->
8
8
  <script lang="ts">
9
+ import type { HTMLAttributes } from "svelte/elements";
9
10
  import type { Variant } from "../../types/variants.js";
10
11
  import { variantToken } from "../../types/variants.js";
11
12
  import type { Size } from "../../types/sizes.js";
@@ -20,6 +21,7 @@
20
21
  label,
21
22
  showValue = false,
22
23
  class: cls = "",
24
+ ...rest
23
25
  }: {
24
26
  value?: number;
25
27
  max?: number;
@@ -29,7 +31,7 @@
29
31
  label?: string;
30
32
  showValue?: boolean;
31
33
  class?: string;
32
- } = $props();
34
+ } & Omit<HTMLAttributes<HTMLDivElement>, "class"> = $props();
33
35
 
34
36
  const token = $derived(variantToken[variant]);
35
37
  const pct = $derived(
@@ -41,7 +43,7 @@
41
43
  const textClass: Record<Size, string> = { sm: "text-xs", md: "text-sm", lg: "text-sm" };
42
44
  </script>
43
45
 
44
- <div class="w-full {cls}">
46
+ <div class="w-full {cls}" {...rest}>
45
47
  {#if label || (showValue && !indeterminate)}
46
48
  <div
47
49
  class="mb-1 flex items-center justify-between {responsiveClasses(
@@ -1,3 +1,4 @@
1
+ import type { HTMLAttributes } from "svelte/elements";
1
2
  import type { Variant } from "../../types/variants.js";
2
3
  import type { Size } from "../../types/sizes.js";
3
4
  import { type Responsive } from "../../types/responsive.js";
@@ -10,7 +11,7 @@ type $$ComponentProps = {
10
11
  label?: string;
11
12
  showValue?: boolean;
12
13
  class?: string;
13
- };
14
+ } & Omit<HTMLAttributes<HTMLDivElement>, "class">;
14
15
  declare const Progress: import("svelte").Component<$$ComponentProps, {}, "">;
15
16
  type Progress = ReturnType<typeof Progress>;
16
17
  export default Progress;
@@ -6,8 +6,9 @@
6
6
  import type { Size } from "../types/sizes.js";
7
7
  import type { Responsive } from "../types/responsive.js";
8
8
  import type { Variant } from "../types/variants.js";
9
+ import type { FieldChromeProps } from "./field-chrome.js";
9
10
 
10
- interface Props extends Omit<HTMLInputAttributes, "type" | "size"> {
11
+ interface Props extends Omit<HTMLInputAttributes, "type" | "size">, FieldChromeProps {
11
12
  value: string;
12
13
  class?: string;
13
14
  inputClass?: string;
@@ -2,7 +2,8 @@ import type { HTMLInputAttributes } from "svelte/elements";
2
2
  import type { Size } from "../types/sizes.js";
3
3
  import type { Responsive } from "../types/responsive.js";
4
4
  import type { Variant } from "../types/variants.js";
5
- interface Props extends Omit<HTMLInputAttributes, "type" | "size"> {
5
+ import type { FieldChromeProps } from "./field-chrome.js";
6
+ interface Props extends Omit<HTMLInputAttributes, "type" | "size">, FieldChromeProps {
6
7
  value: string;
7
8
  class?: string;
8
9
  inputClass?: string;
@@ -1,5 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from "svelte";
3
+ import type { HTMLInputAttributes } from "svelte/elements";
4
+ import type { FieldChromeProps } from "./field-chrome.js";
3
5
  import ChevronDown from "~icons/mdi/chevron-down";
4
6
  import Input from "./Input.svelte";
5
7
  import List from "./List.svelte";
@@ -77,7 +79,7 @@
77
79
  borderless?: boolean;
78
80
  /** When set, render a hidden <input name> carrying the value so the Select submits in a form. */
79
81
  name?: string;
80
- } & Record<string, any> = $props();
82
+ } & Omit<HTMLInputAttributes, "type" | "value" | "size" | "class"> & FieldChromeProps = $props();
81
83
 
82
84
  let isOpen = $state(false);
83
85
  let containerElement = $state<HTMLElement>();
@@ -1,4 +1,6 @@
1
1
  import type { Snippet } from "svelte";
2
+ import type { HTMLInputAttributes } from "svelte/elements";
3
+ import type { FieldChromeProps } from "./field-chrome.js";
2
4
  import type { Size } from "../types/sizes.js";
3
5
  import type { Responsive } from "../types/responsive.js";
4
6
  import type { Variant } from "../types/variants.js";
@@ -39,7 +41,7 @@ type $$ComponentProps = {
39
41
  borderless?: boolean;
40
42
  /** When set, render a hidden <input name> carrying the value so the Select submits in a form. */
41
43
  name?: string;
42
- } & Record<string, any>;
44
+ } & Omit<HTMLInputAttributes, "type" | "value" | "size" | "class"> & FieldChromeProps;
43
45
  declare const Select: import("svelte").Component<$$ComponentProps, {}, "value" | "searchTerm" | "methods">;
44
46
  type Select = ReturnType<typeof Select>;
45
47
  export default Select;
@@ -6,6 +6,8 @@
6
6
  */
7
7
  -->
8
8
  <script lang="ts">
9
+ import type { HTMLAttributes } from "svelte/elements";
10
+
9
11
  let {
10
12
  shape = "text",
11
13
  width,
@@ -14,6 +16,7 @@
14
16
  radius,
15
17
  animate = true,
16
18
  class: cls = "",
19
+ ...rest
17
20
  }: {
18
21
  shape?: "text" | "rect" | "circle";
19
22
  width?: string | number;
@@ -22,7 +25,8 @@
22
25
  radius?: string;
23
26
  animate?: boolean;
24
27
  class?: string;
25
- } = $props();
28
+ // `style` omitted — dimensions come from `width`/`height`/`radius`, applied as the element's style.
29
+ } & Omit<HTMLAttributes<HTMLElement>, "class" | "style"> = $props();
26
30
 
27
31
  const css = (v: string | number | undefined): string | undefined =>
28
32
  typeof v === "number" ? `${v}px` : v;
@@ -39,7 +43,7 @@
39
43
  </script>
40
44
 
41
45
  {#if shape === "text" && lines > 1}
42
- <div class="flex flex-col gap-2 {cls}" aria-hidden="true">
46
+ <div class="flex flex-col gap-2 {cls}" aria-hidden="true" {...rest}>
43
47
  {#each Array(lines) as _, i (i)}
44
48
  <span
45
49
  class={blockClass}
@@ -52,6 +56,7 @@
52
56
  class="{blockClass} {cls}"
53
57
  style="width: {w}; height: {h}; border-radius: {rad};"
54
58
  aria-hidden="true"
59
+ {...rest}
55
60
  ></span>
56
61
  {/if}
57
62
 
@@ -1,3 +1,4 @@
1
+ import type { HTMLAttributes } from "svelte/elements";
1
2
  type $$ComponentProps = {
2
3
  shape?: "text" | "rect" | "circle";
3
4
  width?: string | number;
@@ -6,7 +7,7 @@ type $$ComponentProps = {
6
7
  radius?: string;
7
8
  animate?: boolean;
8
9
  class?: string;
9
- };
10
+ } & Omit<HTMLAttributes<HTMLElement>, "class" | "style">;
10
11
  declare const Skeleton: import("svelte").Component<$$ComponentProps, {}, "">;
11
12
  type Skeleton = ReturnType<typeof Skeleton>;
12
13
  export default Skeleton;
@@ -6,6 +6,7 @@
6
6
  -->
7
7
  <script lang="ts">
8
8
  import type { Snippet } from "svelte";
9
+ import type { HTMLAttributes } from "svelte/elements";
9
10
  import Card from "../Card.svelte";
10
11
  import IconUp from "~icons/mdi/trending-up";
11
12
  import IconDown from "~icons/mdi/trending-down";
@@ -24,6 +25,7 @@
24
25
  variant = "neutral",
25
26
  size = "md",
26
27
  class: cls = "",
28
+ ...rest
27
29
  }: {
28
30
  label: string;
29
31
  value: string | number;
@@ -37,7 +39,7 @@
37
39
  variant?: Variant;
38
40
  size?: Responsive<Size>;
39
41
  class?: string;
40
- } = $props();
42
+ } & Omit<HTMLAttributes<HTMLDivElement>, "class"> = $props();
41
43
 
42
44
  const token = $derived(variantToken[variant]);
43
45
  const deltaNum = $derived(typeof delta === "number" ? delta : null);
@@ -60,7 +62,7 @@
60
62
  };
61
63
  </script>
62
64
 
63
- <Card class="p-4 {cls}">
65
+ <Card class="p-4 {cls}" {...rest}>
64
66
  <div class="flex items-start justify-between gap-3">
65
67
  <div class="min-w-0">
66
68
  <div class="truncate text-sm [color:color-mix(in_srgb,var(--ui-color-text)_60%,transparent)]">
@@ -1,4 +1,5 @@
1
1
  import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
2
3
  import type { Variant } from "../../types/variants.js";
3
4
  import type { Size } from "../../types/sizes.js";
4
5
  import { type Responsive } from "../../types/responsive.js";
@@ -15,7 +16,7 @@ type $$ComponentProps = {
15
16
  variant?: Variant;
16
17
  size?: Responsive<Size>;
17
18
  class?: string;
18
- };
19
+ } & Omit<HTMLAttributes<HTMLDivElement>, "class">;
19
20
  declare const Stat: import("svelte").Component<$$ComponentProps, {}, "">;
20
21
  type Stat = ReturnType<typeof Stat>;
21
22
  export default Stat;
@@ -11,6 +11,8 @@
11
11
  <script lang="ts">
12
12
  import { uiI18n } from "../i18n.js";
13
13
  const i18n = uiI18n();
14
+ import type { HTMLInputAttributes } from "svelte/elements";
15
+ import type { FieldChromeProps } from "./field-chrome.js";
14
16
  import type { Size } from "../types/sizes.js";
15
17
  import { responsiveClasses, type Responsive } from "../types/responsive.js";
16
18
  import { resolveStep, type StepSpec } from "../types/time.js";
@@ -21,7 +23,9 @@
21
23
  import IconClock from "~icons/mdi/clock-outline";
22
24
 
23
25
  type RangeValue = { start: string | null; end: string | null };
24
- interface Props {
26
+ interface Props
27
+ extends Omit<HTMLInputAttributes, "type" | "value" | "size" | "step" | "class">,
28
+ FieldChromeProps {
25
29
  /** `{ start, end }` with 24h `HH:MM` (or `HH:MM:SS` when `seconds`), or null. Bindable. */
26
30
  value?: RangeValue | null;
27
31
  /** Column interval: a number = minute step, or `{ hour, minute, second }`. Default 1 (minute). */
@@ -1,3 +1,5 @@
1
+ import type { HTMLInputAttributes } from "svelte/elements";
2
+ import type { FieldChromeProps } from "./field-chrome.js";
1
3
  import type { Size } from "../types/sizes.js";
2
4
  import { type Responsive } from "../types/responsive.js";
3
5
  import { type StepSpec } from "../types/time.js";
@@ -6,7 +8,7 @@ type RangeValue = {
6
8
  start: string | null;
7
9
  end: string | null;
8
10
  };
9
- interface Props {
11
+ interface Props extends Omit<HTMLInputAttributes, "type" | "value" | "size" | "step" | "class">, FieldChromeProps {
10
12
  /** `{ start, end }` with 24h `HH:MM` (or `HH:MM:SS` when `seconds`), or null. Bindable. */
11
13
  value?: RangeValue | null;
12
14
  /** Column interval: a number = minute step, or `{ hour, minute, second }`. Default 1 (minute). */
@@ -19,6 +19,7 @@
19
19
  </script>
20
20
 
21
21
  <script lang="ts">
22
+ import type { HTMLAttributes } from "svelte/elements";
22
23
  import { variantToken } from "../../types/variants.js";
23
24
  import type { Size } from "../../types/sizes.js";
24
25
  import { responsiveClasses, type Responsive } from "../../types/responsive.js";
@@ -28,12 +29,13 @@
28
29
  variant = "primary",
29
30
  size = "md",
30
31
  class: cls = "",
32
+ ...rest
31
33
  }: {
32
34
  items: TimelineItem[];
33
35
  variant?: Variant;
34
36
  size?: Responsive<Size>;
35
37
  class?: string;
36
- } = $props();
38
+ } & Omit<HTMLAttributes<HTMLOListElement>, "class"> = $props();
37
39
 
38
40
  const dotSize: Record<Size, string> = { sm: "w-2.5 h-2.5", md: "w-3 h-3", lg: "w-3.5 h-3.5" };
39
41
  const iconBox: Record<Size, string> = {
@@ -45,7 +47,7 @@
45
47
  const tokenFor = (item: TimelineItem) => variantToken[item.variant ?? variant];
46
48
  </script>
47
49
 
48
- <ol class="flex flex-col {cls}">
50
+ <ol class="flex flex-col {cls}" {...rest}>
49
51
  {#each items as item, i (i)}
50
52
  {@const last = i === items.length - 1}
51
53
  <li class="flex gap-3">
@@ -8,6 +8,7 @@ export type TimelineItem = {
8
8
  variant?: Variant;
9
9
  content?: Snippet;
10
10
  };
11
+ import type { HTMLAttributes } from "svelte/elements";
11
12
  import type { Size } from "../../types/sizes.js";
12
13
  import { type Responsive } from "../../types/responsive.js";
13
14
  type $$ComponentProps = {
@@ -15,7 +16,7 @@ type $$ComponentProps = {
15
16
  variant?: Variant;
16
17
  size?: Responsive<Size>;
17
18
  class?: string;
18
- };
19
+ } & Omit<HTMLAttributes<HTMLOListElement>, "class">;
19
20
  declare const Timeline: import("svelte").Component<$$ComponentProps, {}, "">;
20
21
  type Timeline = ReturnType<typeof Timeline>;
21
22
  export default Timeline;
@@ -0,0 +1,22 @@
1
+ import type { Snippet } from "svelte";
2
+ /**
3
+ * The shared **FieldChrome** vocabulary (`label` / `aside` / `error` / `description`) that `Input`,
4
+ * `TextArea`, and the specialized inputs (`PasswordInput` / `EmailInput` / `NumberInput` /
5
+ * `SearchInput`) all render through `FieldChrome`. See `FieldChrome.spec.md`.
6
+ *
7
+ * The specialized inputs forward `{...restProps}` into `<Input>` at runtime, so these props already
8
+ * WORK on them — they just weren't TYPED (their `Props` derived from `HTMLInputAttributes` alone,
9
+ * which has no `label`/`aside`/`error`/`description`). Extending this interface types them without any
10
+ * runtime change. `required`/`id` are NOT here — they are genuine `HTMLInputAttributes` and come from
11
+ * the base. Keep in sync with the chrome props declared on `Input`/`TextArea`.
12
+ */
13
+ export interface FieldChromeProps {
14
+ /** Renders above the control; `null`/omitted → no label row. */
15
+ label?: string | null;
16
+ /** Right-aligned snippet in the label row. */
17
+ aside?: Snippet;
18
+ /** Inline error row (string → `{@html}`); also drives the shared error state (border + aria-invalid). */
19
+ error?: string | Snippet | null;
20
+ /** Muted help row below the control (string → `{@html}`). */
21
+ description?: string | Snippet | null;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -590,7 +590,11 @@ Status indicator / label.
590
590
  - **Location**: `src/lib/components/Badge/Badge.svelte`
591
591
  - **Axes**: `size`
592
592
  - **Variants**: `default`, `primary`, `success`, `warning`, `danger`, `info`
593
- - **Props**: `text`, `variant`, `size`, `dismissible`, `rounded`, `children`; dispatches `dismiss`
593
+ - **Props**: `text`, `variant`, `size`, `dismissible`, `rounded`, `href`, `children`; dispatches `dismiss`
594
+ - **Attribute passthrough**: leftover HTML attributes — `class` (merged, appended last), `data-*`
595
+ (e.g. a `data-testid` e2e hook), `aria-*`, `id`, `title`, event handlers — spread onto the chip's
596
+ root element. **`style` is not** passed through (the chip computes its own themed `style`); use
597
+ `class` for style overrides.
594
598
 
595
599
  ### NotesEditor
596
600
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaethtech/svelte-ui",
3
- "version": "0.20.0",
3
+ "version": "0.20.1-dev.102.3c5719c",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/spaethtech/svelte-ui.git"