@loidolt/theme-svelte 0.2.0 → 0.4.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 (92) hide show
  1. package/README.md +21 -0
  2. package/dist/components/Accordion.svelte +100 -0
  3. package/dist/components/Accordion.svelte.d.ts +50 -0
  4. package/dist/components/Alert.svelte +6 -3
  5. package/dist/components/Alert.svelte.d.ts +3 -2
  6. package/dist/components/AlertDialog.svelte +130 -0
  7. package/dist/components/AlertDialog.svelte.d.ts +35 -0
  8. package/dist/components/AppShell.svelte +2 -1
  9. package/dist/components/AppShell.svelte.d.ts +1 -0
  10. package/dist/components/Badge.svelte +9 -2
  11. package/dist/components/Badge.svelte.d.ts +2 -1
  12. package/dist/components/Brand.svelte +29 -15
  13. package/dist/components/Brand.svelte.d.ts +8 -4
  14. package/dist/components/Breadcrumbs.svelte +53 -0
  15. package/dist/components/Breadcrumbs.svelte.d.ts +18 -0
  16. package/dist/components/Button.svelte +43 -21
  17. package/dist/components/Button.svelte.d.ts +9 -4
  18. package/dist/components/Card.svelte +23 -5
  19. package/dist/components/Card.svelte.d.ts +11 -4
  20. package/dist/components/CodeBlock.svelte +55 -0
  21. package/dist/components/CodeBlock.svelte.d.ts +14 -0
  22. package/dist/components/CommentList.svelte +67 -0
  23. package/dist/components/CommentList.svelte.d.ts +53 -0
  24. package/dist/components/Dialog.svelte +25 -3
  25. package/dist/components/Dialog.svelte.d.ts +4 -1
  26. package/dist/components/Drawer.svelte +105 -0
  27. package/dist/components/Drawer.svelte.d.ts +31 -0
  28. package/dist/components/DropdownMenu.svelte +2 -2
  29. package/dist/components/DropdownMenu.svelte.d.ts +1 -1
  30. package/dist/components/EmptyState.svelte +40 -0
  31. package/dist/components/EmptyState.svelte.d.ts +19 -0
  32. package/dist/components/Fieldset.svelte +60 -0
  33. package/dist/components/Fieldset.svelte.d.ts +19 -0
  34. package/dist/components/FileInput.svelte +47 -0
  35. package/dist/components/FileInput.svelte.d.ts +15 -0
  36. package/dist/components/Filmstrip.svelte +72 -0
  37. package/dist/components/Filmstrip.svelte.d.ts +50 -0
  38. package/dist/components/FloatingBar.svelte +43 -0
  39. package/dist/components/FloatingBar.svelte.d.ts +16 -0
  40. package/dist/components/IconButton.svelte +1 -1
  41. package/dist/components/Input.svelte.d.ts +1 -1
  42. package/dist/components/ListRow.svelte +50 -0
  43. package/dist/components/ListRow.svelte.d.ts +18 -0
  44. package/dist/components/Marker.svelte +38 -0
  45. package/dist/components/Marker.svelte.d.ts +14 -0
  46. package/dist/components/NavMenu.svelte +6 -1
  47. package/dist/components/NavMenu.svelte.d.ts +2 -1
  48. package/dist/components/NumberField.svelte +12 -1
  49. package/dist/components/NumberField.svelte.d.ts +1 -1
  50. package/dist/components/Pagination.svelte +86 -0
  51. package/dist/components/Pagination.svelte.d.ts +22 -0
  52. package/dist/components/Popover.svelte +24 -3
  53. package/dist/components/Popover.svelte.d.ts +4 -1
  54. package/dist/components/RadioGroup.svelte.d.ts +2 -2
  55. package/dist/components/RecordStepper.svelte +58 -0
  56. package/dist/components/RecordStepper.svelte.d.ts +18 -0
  57. package/dist/components/SegmentedNav.svelte +53 -0
  58. package/dist/components/SegmentedNav.svelte.d.ts +22 -0
  59. package/dist/components/Select.svelte.d.ts +2 -2
  60. package/dist/components/Stat.svelte +41 -0
  61. package/dist/components/Stat.svelte.d.ts +17 -0
  62. package/dist/components/StatusDot.svelte +27 -0
  63. package/dist/components/StatusDot.svelte.d.ts +12 -0
  64. package/dist/components/SwatchGroup.svelte +69 -0
  65. package/dist/components/SwatchGroup.svelte.d.ts +44 -0
  66. package/dist/components/Switch.svelte +19 -0
  67. package/dist/components/Table.svelte +30 -3
  68. package/dist/components/Table.svelte.d.ts +13 -0
  69. package/dist/components/TableHeader.svelte +72 -0
  70. package/dist/components/TableHeader.svelte.d.ts +24 -0
  71. package/dist/components/Tabs.svelte +23 -5
  72. package/dist/components/Tabs.svelte.d.ts +4 -3
  73. package/dist/components/Textarea.svelte.d.ts +1 -1
  74. package/dist/components/ThemeToggle.svelte +133 -0
  75. package/dist/components/ThemeToggle.svelte.d.ts +20 -0
  76. package/dist/components/Thumbnail.svelte +51 -0
  77. package/dist/components/Thumbnail.svelte.d.ts +19 -0
  78. package/dist/components/ToggleGroup.svelte +107 -0
  79. package/dist/components/ToggleGroup.svelte.d.ts +46 -0
  80. package/dist/components/TooltipProvider.svelte +1 -0
  81. package/dist/components/Workspace.svelte +27 -6
  82. package/dist/components/Workspace.svelte.d.ts +12 -0
  83. package/dist/index.d.ts +29 -2
  84. package/dist/index.js +26 -1
  85. package/dist/media.svelte.d.ts +48 -0
  86. package/dist/media.svelte.js +69 -0
  87. package/dist/theme.svelte.d.ts +86 -0
  88. package/dist/theme.svelte.js +166 -0
  89. package/dist/toaster.svelte.d.ts +2 -0
  90. package/dist/toaster.svelte.js +51 -9
  91. package/dist/types.d.ts +21 -0
  92. package/package.json +10 -8
@@ -0,0 +1,40 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import type { HeadingLevel } from '../types.js';
5
+ import { cx } from '../utils.js';
6
+
7
+ interface Props extends HTMLAttributes<HTMLDivElement> {
8
+ title: string;
9
+ /** What to do about it. An empty state without a next step is just a blank screen. */
10
+ description?: string;
11
+ /** Leading visual, sized by the consumer. */
12
+ icon?: Snippet;
13
+ /** Buttons or links offering the next step. */
14
+ actions?: Snippet;
15
+ headingLevel?: HeadingLevel;
16
+ class?: string;
17
+ children?: Snippet;
18
+ ref?: HTMLDivElement | null;
19
+ }
20
+
21
+ let {
22
+ title,
23
+ description,
24
+ icon,
25
+ actions,
26
+ headingLevel = 3,
27
+ class: className,
28
+ children,
29
+ ref = $bindable(null),
30
+ ...rest
31
+ }: Props = $props();
32
+ </script>
33
+
34
+ <div bind:this={ref} class={cx('ldt-empty-state', className)} {...rest}>
35
+ {#if icon}<div class="ldt-empty-state__icon" aria-hidden="true">{@render icon()}</div>{/if}
36
+ <svelte:element this={`h${headingLevel}`} class="ldt-empty-state__title">{title}</svelte:element>
37
+ {#if description}<p class="ldt-empty-state__description">{description}</p>{/if}
38
+ {#if children}{@render children()}{/if}
39
+ {#if actions}<div class="ldt-empty-state__actions">{@render actions()}</div>{/if}
40
+ </div>
@@ -0,0 +1,19 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { HeadingLevel } from '../types.js';
4
+ interface Props extends HTMLAttributes<HTMLDivElement> {
5
+ title: string;
6
+ /** What to do about it. An empty state without a next step is just a blank screen. */
7
+ description?: string;
8
+ /** Leading visual, sized by the consumer. */
9
+ icon?: Snippet;
10
+ /** Buttons or links offering the next step. */
11
+ actions?: Snippet;
12
+ headingLevel?: HeadingLevel;
13
+ class?: string;
14
+ children?: Snippet;
15
+ ref?: HTMLDivElement | null;
16
+ }
17
+ declare const EmptyState: import("svelte").Component<Props, {}, "ref">;
18
+ type EmptyState = ReturnType<typeof EmptyState>;
19
+ export default EmptyState;
@@ -0,0 +1,60 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLFieldsetAttributes } from 'svelte/elements';
4
+ import { cx } from '../utils.js';
5
+
6
+ interface Props extends HTMLFieldsetAttributes {
7
+ /** Defaults to an SSR-stable generated id, used to wire the description and error. */
8
+ id?: string;
9
+ /** Visible group label, rendered as a `<legend>`. */
10
+ legend: string;
11
+ description?: string;
12
+ error?: string;
13
+ optional?: boolean;
14
+ /** Text of the "optional" marker, for localisation. */
15
+ optionalText?: string;
16
+ class?: string;
17
+ children: Snippet;
18
+ ref?: HTMLFieldSetElement | null;
19
+ }
20
+
21
+ const generatedId = $props.id();
22
+
23
+ let {
24
+ id = generatedId,
25
+ legend,
26
+ description,
27
+ error,
28
+ optional = false,
29
+ optionalText = 'Optional',
30
+ class: className,
31
+ children,
32
+ ref = $bindable(null),
33
+ ...rest
34
+ }: Props = $props();
35
+
36
+ const describedBy = $derived(
37
+ [description && `${id}-description`, error && `${id}-error`].filter(Boolean).join(' ') ||
38
+ undefined
39
+ );
40
+ </script>
41
+
42
+ <!--
43
+ `Field` wires one control; `Fieldset` wires a group of them. The description and error hang off
44
+ the `<fieldset>` rather than off each control: grouping context is announced once on entry, so
45
+ a shared message stays shared instead of repeating on every checkbox in the set.
46
+ -->
47
+ <fieldset
48
+ bind:this={ref}
49
+ {id}
50
+ class={cx('ldt-fieldset', className)}
51
+ aria-describedby={describedBy}
52
+ {...rest}
53
+ >
54
+ <legend class="ldt-legend"
55
+ ><span>{legend}</span>{#if optional}<small>{optionalText}</small>{/if}</legend
56
+ >
57
+ <div class="ldt-fieldset__body">{@render children()}</div>
58
+ {#if description}<p class="ldt-field__description" id={`${id}-description`}>{description}</p>{/if}
59
+ {#if error}<p class="ldt-field__error" id={`${id}-error`} role="alert">{error}</p>{/if}
60
+ </fieldset>
@@ -0,0 +1,19 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLFieldsetAttributes } from 'svelte/elements';
3
+ interface Props extends HTMLFieldsetAttributes {
4
+ /** Defaults to an SSR-stable generated id, used to wire the description and error. */
5
+ id?: string;
6
+ /** Visible group label, rendered as a `<legend>`. */
7
+ legend: string;
8
+ description?: string;
9
+ error?: string;
10
+ optional?: boolean;
11
+ /** Text of the "optional" marker, for localisation. */
12
+ optionalText?: string;
13
+ class?: string;
14
+ children: Snippet;
15
+ ref?: HTMLFieldSetElement | null;
16
+ }
17
+ declare const Fieldset: import("svelte").Component<Props, {}, "ref">;
18
+ type Fieldset = ReturnType<typeof Fieldset>;
19
+ export default Fieldset;
@@ -0,0 +1,47 @@
1
+ <script lang="ts">
2
+ import type { HTMLInputAttributes } from 'svelte/elements';
3
+ import { cx } from '../utils.js';
4
+
5
+ // Input cannot render type="file" — its string `value` binding does not apply — so the
6
+ // file picker gets its own component in the same clothes.
7
+ interface Props extends Omit<HTMLInputAttributes, 'type' | 'value' | 'files' | 'class'> {
8
+ accept?: string;
9
+ multiple?: boolean;
10
+ /** Fired when the user picks at least one file. */
11
+ onFiles?: (files: FileList) => void;
12
+ disabled?: boolean;
13
+ /** Draws the full box instead of the default underline, like Input. */
14
+ boxed?: boolean;
15
+ class?: string;
16
+ ref?: HTMLInputElement | null;
17
+ }
18
+
19
+ let {
20
+ accept,
21
+ multiple = false,
22
+ onFiles,
23
+ disabled = false,
24
+ boxed = false,
25
+ class: className,
26
+ onchange,
27
+ ref = $bindable(null),
28
+ ...rest
29
+ }: Props = $props();
30
+
31
+ function handleChange(event: Event & { currentTarget: HTMLInputElement }) {
32
+ onchange?.(event);
33
+ const files = event.currentTarget.files;
34
+ if (files && files.length > 0) onFiles?.(files);
35
+ }
36
+ </script>
37
+
38
+ <input
39
+ bind:this={ref}
40
+ type="file"
41
+ class={cx('ldt-input', 'ldt-file-input', boxed && 'ldt-input--boxed', className)}
42
+ {accept}
43
+ {multiple}
44
+ {disabled}
45
+ {...rest}
46
+ onchange={handleChange}
47
+ />
@@ -0,0 +1,15 @@
1
+ import type { HTMLInputAttributes } from 'svelte/elements';
2
+ interface Props extends Omit<HTMLInputAttributes, 'type' | 'value' | 'files' | 'class'> {
3
+ accept?: string;
4
+ multiple?: boolean;
5
+ /** Fired when the user picks at least one file. */
6
+ onFiles?: (files: FileList) => void;
7
+ disabled?: boolean;
8
+ /** Draws the full box instead of the default underline, like Input. */
9
+ boxed?: boolean;
10
+ class?: string;
11
+ ref?: HTMLInputElement | null;
12
+ }
13
+ declare const FileInput: import("svelte").Component<Props, {}, "ref">;
14
+ type FileInput = ReturnType<typeof FileInput>;
15
+ export default FileInput;
@@ -0,0 +1,72 @@
1
+ <script lang="ts" generics="T extends { id: string }">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import type { Orientation } from '../types.js';
5
+ import { cx } from '../utils.js';
6
+
7
+ interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
8
+ items: T[];
9
+ selectedId?: string | null;
10
+ onSelect?: (id: string) => void;
11
+ /** Vertical rails flip horizontal on their own when the workspace container goes compact. */
12
+ orientation?: Orientation;
13
+ /** Accessible name of the listbox. */
14
+ label: string;
15
+ /** Thumbnail contents for one item; second argument is whether it is selected. */
16
+ item: Snippet<[T, boolean]>;
17
+ class?: string;
18
+ itemClass?: string;
19
+ ref?: HTMLDivElement | null;
20
+ }
21
+
22
+ let {
23
+ items,
24
+ selectedId = $bindable(null),
25
+ onSelect,
26
+ orientation = 'vertical',
27
+ label,
28
+ item,
29
+ class: className,
30
+ itemClass,
31
+ ref = $bindable(null),
32
+ ...rest
33
+ }: Props = $props();
34
+
35
+ let buttons = $state<Record<string, HTMLButtonElement | null>>({});
36
+
37
+ $effect(() => {
38
+ if (selectedId) {
39
+ buttons[selectedId]?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
40
+ }
41
+ });
42
+
43
+ function select(id: string) {
44
+ selectedId = id;
45
+ onSelect?.(id);
46
+ }
47
+ </script>
48
+
49
+ <div
50
+ bind:this={ref}
51
+ class={cx(
52
+ 'ldt-filmstrip',
53
+ orientation === 'horizontal' && 'ldt-filmstrip--horizontal',
54
+ className
55
+ )}
56
+ role="listbox"
57
+ aria-label={label}
58
+ {...rest}
59
+ >
60
+ {#each items as entry (entry.id)}
61
+ <button
62
+ type="button"
63
+ class={cx('ldt-filmstrip__item', itemClass)}
64
+ role="option"
65
+ aria-selected={selectedId === entry.id}
66
+ bind:this={buttons[entry.id]}
67
+ onclick={() => select(entry.id)}
68
+ >
69
+ {@render item(entry, selectedId === entry.id)}
70
+ </button>
71
+ {/each}
72
+ </div>
@@ -0,0 +1,50 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { Orientation } from '../types.js';
4
+ declare function $$render<T extends {
5
+ id: string;
6
+ }>(): {
7
+ props: Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
8
+ items: T[];
9
+ selectedId?: string | null;
10
+ onSelect?: (id: string) => void;
11
+ /** Vertical rails flip horizontal on their own when the workspace container goes compact. */
12
+ orientation?: Orientation;
13
+ /** Accessible name of the listbox. */
14
+ label: string;
15
+ /** Thumbnail contents for one item; second argument is whether it is selected. */
16
+ item: Snippet<[T, boolean]>;
17
+ class?: string;
18
+ itemClass?: string;
19
+ ref?: HTMLDivElement | null;
20
+ };
21
+ exports: {};
22
+ bindings: "ref" | "selectedId";
23
+ slots: {};
24
+ events: {};
25
+ };
26
+ declare class __sveltets_Render<T extends {
27
+ id: string;
28
+ }> {
29
+ props(): ReturnType<typeof $$render<T>>['props'];
30
+ events(): ReturnType<typeof $$render<T>>['events'];
31
+ slots(): ReturnType<typeof $$render<T>>['slots'];
32
+ bindings(): "ref" | "selectedId";
33
+ exports(): {};
34
+ }
35
+ interface $$IsomorphicComponent {
36
+ new <T extends {
37
+ id: string;
38
+ }>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
39
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
40
+ } & ReturnType<__sveltets_Render<T>['exports']>;
41
+ <T extends {
42
+ id: string;
43
+ }>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
44
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
45
+ }
46
+ declare const Filmstrip: $$IsomorphicComponent;
47
+ type Filmstrip<T extends {
48
+ id: string;
49
+ }> = InstanceType<typeof Filmstrip<T>>;
50
+ export default Filmstrip;
@@ -0,0 +1,43 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import type { Orientation } from '../types.js';
5
+ import { cx } from '../utils.js';
6
+
7
+ interface Props extends HTMLAttributes<HTMLDivElement> {
8
+ /** Corner of the nearest positioned ancestor to pin to. */
9
+ placement?: 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end';
10
+ orientation?: Orientation;
11
+ /** Accessible name; renders `role="group"` when set. */
12
+ label?: string;
13
+ children: Snippet;
14
+ class?: string;
15
+ ref?: HTMLDivElement | null;
16
+ }
17
+
18
+ let {
19
+ placement = 'bottom-end',
20
+ orientation = 'horizontal',
21
+ label,
22
+ children,
23
+ class: className,
24
+ ref = $bindable(null),
25
+ ...rest
26
+ }: Props = $props();
27
+ </script>
28
+
29
+ <!-- The parent supplies position: relative — the bar is a pointer-events island over a stage. -->
30
+ <div
31
+ bind:this={ref}
32
+ class={cx(
33
+ 'ldt-floating-bar',
34
+ `ldt-floating-bar--${placement}`,
35
+ orientation === 'vertical' && 'ldt-floating-bar--vertical',
36
+ className
37
+ )}
38
+ role={label ? 'group' : undefined}
39
+ aria-label={label}
40
+ {...rest}
41
+ >
42
+ {@render children()}
43
+ </div>
@@ -0,0 +1,16 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { Orientation } from '../types.js';
4
+ interface Props extends HTMLAttributes<HTMLDivElement> {
5
+ /** Corner of the nearest positioned ancestor to pin to. */
6
+ placement?: 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end';
7
+ orientation?: Orientation;
8
+ /** Accessible name; renders `role="group"` when set. */
9
+ label?: string;
10
+ children: Snippet;
11
+ class?: string;
12
+ ref?: HTMLDivElement | null;
13
+ }
14
+ declare const FloatingBar: import("svelte").Component<Props, {}, "ref">;
15
+ type FloatingBar = ReturnType<typeof FloatingBar>;
16
+ export default FloatingBar;
@@ -34,7 +34,7 @@
34
34
  {disabled}
35
35
  class={cx(
36
36
  'ldt-button ldt-icon-button',
37
- `ldt-button--${variant}`,
37
+ variant !== 'default' && `ldt-button--${variant}`,
38
38
  size !== 'md' && `ldt-button--${size}`,
39
39
  className
40
40
  )}
@@ -6,6 +6,6 @@ interface Props extends Omit<HTMLInputAttributes, 'value'> {
6
6
  class?: string;
7
7
  ref?: HTMLInputElement | null;
8
8
  }
9
- declare const Input: import("svelte").Component<Props, {}, "ref" | "value">;
9
+ declare const Input: import("svelte").Component<Props, {}, "value" | "ref">;
10
10
  type Input = ReturnType<typeof Input>;
11
11
  export default Input;
@@ -0,0 +1,50 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
4
+ import { cx } from '../utils.js';
5
+
6
+ interface CommonProps {
7
+ /** Highlighted as the current item: `aria-current` on links, `aria-pressed` on buttons. */
8
+ selected?: boolean;
9
+ class?: string;
10
+ children: Snippet;
11
+ ref?: HTMLAnchorElement | HTMLButtonElement | null;
12
+ }
13
+
14
+ // Same href rule as Button: with it an <a>, without it a <button>.
15
+ type Props = CommonProps &
16
+ (
17
+ | (Omit<HTMLAnchorAttributes, 'class' | 'type'> & { href: string; type?: never })
18
+ | (Omit<HTMLButtonAttributes, 'class'> & { href?: never })
19
+ );
20
+
21
+ let {
22
+ selected = false,
23
+ href,
24
+ type = 'button',
25
+ class: className,
26
+ children,
27
+ ref = $bindable(null),
28
+ ...rest
29
+ }: Props = $props();
30
+
31
+ const classes = $derived(cx('ldt-list-row', selected && 'ldt-list-row--selected', className));
32
+ </script>
33
+
34
+ {#if href}
35
+ <a
36
+ bind:this={ref}
37
+ {href}
38
+ class={classes}
39
+ aria-current={selected || undefined}
40
+ {...rest as HTMLAnchorAttributes}>{@render children()}</a
41
+ >
42
+ {:else}
43
+ <button
44
+ bind:this={ref}
45
+ {type}
46
+ class={classes}
47
+ aria-pressed={selected || undefined}
48
+ {...rest as HTMLButtonAttributes}>{@render children()}</button
49
+ >
50
+ {/if}
@@ -0,0 +1,18 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
3
+ interface CommonProps {
4
+ /** Highlighted as the current item: `aria-current` on links, `aria-pressed` on buttons. */
5
+ selected?: boolean;
6
+ class?: string;
7
+ children: Snippet;
8
+ ref?: HTMLAnchorElement | HTMLButtonElement | null;
9
+ }
10
+ type Props = CommonProps & ((Omit<HTMLAnchorAttributes, 'class' | 'type'> & {
11
+ href: string;
12
+ type?: never;
13
+ }) | (Omit<HTMLButtonAttributes, 'class'> & {
14
+ href?: never;
15
+ }));
16
+ declare const ListRow: import("svelte").Component<Props, {}, "ref">;
17
+ type ListRow = ReturnType<typeof ListRow>;
18
+ export default ListRow;
@@ -0,0 +1,38 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import { cx } from '../utils.js';
4
+
5
+ interface Props extends HTMLAttributes<HTMLSpanElement> {
6
+ number?: number;
7
+ /** `dot` sits in lists; `pin` is the teardrop that points at a spot on a canvas. */
8
+ shape?: 'dot' | 'pin';
9
+ active?: boolean;
10
+ /** Accessible name, e.g. "Comment 3". Omit when adjacent text already names it. */
11
+ label?: string;
12
+ class?: string;
13
+ ref?: HTMLSpanElement | null;
14
+ }
15
+
16
+ let {
17
+ number,
18
+ shape = 'dot',
19
+ active = false,
20
+ label,
21
+ class: className,
22
+ ref = $bindable(null),
23
+ ...rest
24
+ }: Props = $props();
25
+ </script>
26
+
27
+ <span
28
+ bind:this={ref}
29
+ class={cx(
30
+ 'ldt-marker',
31
+ shape === 'pin' && 'ldt-marker--pin',
32
+ active && 'ldt-marker--active',
33
+ className
34
+ )}
35
+ {...rest}
36
+ >{#if number !== undefined}{number}{/if}{#if label}<span class="ldt-sr-only">{label}</span
37
+ >{/if}</span
38
+ >
@@ -0,0 +1,14 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ interface Props extends HTMLAttributes<HTMLSpanElement> {
3
+ number?: number;
4
+ /** `dot` sits in lists; `pin` is the teardrop that points at a spot on a canvas. */
5
+ shape?: 'dot' | 'pin';
6
+ active?: boolean;
7
+ /** Accessible name, e.g. "Comment 3". Omit when adjacent text already names it. */
8
+ label?: string;
9
+ class?: string;
10
+ ref?: HTMLSpanElement | null;
11
+ }
12
+ declare const Marker: import("svelte").Component<Props, {}, "ref">;
13
+ type Marker = ReturnType<typeof Marker>;
14
+ export default Marker;
@@ -1,10 +1,11 @@
1
1
  <script lang="ts" generics="T extends string = string">
2
2
  import type { Snippet } from 'svelte';
3
+ import type { HTMLButtonAttributes } from 'svelte/elements';
3
4
  import DropdownMenu from './DropdownMenu.svelte';
4
5
  import type { Alignment, MenuItem, Placement } from '../types.js';
5
6
  import { cx } from '../utils.js';
6
7
 
7
- interface Props {
8
+ interface Props extends Omit<HTMLButtonAttributes, 'children' | 'class' | 'type'> {
8
9
  open?: boolean;
9
10
  /** Trigger text. */
10
11
  label: string;
@@ -36,11 +37,15 @@
36
37
  menuClass,
37
38
  onSelect,
38
39
  onOpenChange,
40
+ ...rest
39
41
  }: Props = $props();
40
42
  </script>
41
43
 
42
44
  {#snippet navTrigger({ props }: { props: Record<string, unknown> })}
45
+ <!-- `rest` first: the menu's trigger wiring (from `props`) and this component's own
46
+ attributes are policy and must win over forwarded attributes. -->
43
47
  <button
48
+ {...rest}
44
49
  {...props}
45
50
  type="button"
46
51
  class={cx('ldt-nav-menu', active && 'ldt-nav-menu--active', className)}
@@ -1,7 +1,8 @@
1
1
  import type { Snippet } from 'svelte';
2
+ import type { HTMLButtonAttributes } from 'svelte/elements';
2
3
  import type { Alignment, MenuItem, Placement } from '../types.js';
3
4
  declare function $$render<T extends string = string>(): {
4
- props: {
5
+ props: Omit<HTMLButtonAttributes, "children" | "class" | "type"> & {
5
6
  open?: boolean;
6
7
  /** Trigger text. */
7
8
  label: string;
@@ -29,7 +29,9 @@
29
29
  decrementLabel = (name) => `Decrease ${name}`,
30
30
  incrementLabel = (name) => `Increase ${name}`,
31
31
  boxed = false,
32
+ disabled = false,
32
33
  onValueChange,
34
+ onchange,
33
35
  class: className,
34
36
  inputClass,
35
37
  ref = $bindable(null),
@@ -52,6 +54,7 @@
52
54
  <button
53
55
  class="ldt-number-field__button"
54
56
  type="button"
57
+ {disabled}
55
58
  aria-label={decrementLabel(label)}
56
59
  aria-disabled={atMin || undefined}
57
60
  onclick={() => !atMin && set(value - step)}>−</button
@@ -64,13 +67,21 @@
64
67
  min={Number.isFinite(min) ? min : undefined}
65
68
  max={Number.isFinite(max) ? max : undefined}
66
69
  {step}
70
+ {disabled}
67
71
  aria-label={label}
68
72
  {...rest}
69
- onchange={(event) => set(Number(event.currentTarget.value))}
73
+ onchange={(event) => {
74
+ // `Number('')` is 0, not NaN — a cleared field must hit the documented fallback,
75
+ // not silently clamp to zero.
76
+ const raw = event.currentTarget.value;
77
+ set(raw === '' ? NaN : Number(raw));
78
+ onchange?.(event);
79
+ }}
70
80
  />
71
81
  <button
72
82
  class="ldt-number-field__button"
73
83
  type="button"
84
+ {disabled}
74
85
  aria-label={incrementLabel(label)}
75
86
  aria-disabled={atMax || undefined}
76
87
  onclick={() => !atMax && set(value + step)}>+</button
@@ -16,6 +16,6 @@ interface Props extends Omit<HTMLInputAttributes, 'type' | 'value' | 'min' | 'ma
16
16
  inputClass?: string;
17
17
  ref?: HTMLInputElement | null;
18
18
  }
19
- declare const NumberField: import("svelte").Component<Props, {}, "ref" | "value">;
19
+ declare const NumberField: import("svelte").Component<Props, {}, "value" | "ref">;
20
20
  type NumberField = ReturnType<typeof NumberField>;
21
21
  export default NumberField;