@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.
- package/README.md +21 -0
- package/dist/components/Accordion.svelte +100 -0
- package/dist/components/Accordion.svelte.d.ts +50 -0
- package/dist/components/Alert.svelte +6 -3
- package/dist/components/Alert.svelte.d.ts +3 -2
- package/dist/components/AlertDialog.svelte +130 -0
- package/dist/components/AlertDialog.svelte.d.ts +35 -0
- package/dist/components/AppShell.svelte +2 -1
- package/dist/components/AppShell.svelte.d.ts +1 -0
- package/dist/components/Badge.svelte +9 -2
- package/dist/components/Badge.svelte.d.ts +2 -1
- package/dist/components/Brand.svelte +29 -15
- package/dist/components/Brand.svelte.d.ts +8 -4
- package/dist/components/Breadcrumbs.svelte +53 -0
- package/dist/components/Breadcrumbs.svelte.d.ts +18 -0
- package/dist/components/Button.svelte +43 -21
- package/dist/components/Button.svelte.d.ts +9 -4
- package/dist/components/Card.svelte +23 -5
- package/dist/components/Card.svelte.d.ts +11 -4
- package/dist/components/CodeBlock.svelte +55 -0
- package/dist/components/CodeBlock.svelte.d.ts +14 -0
- package/dist/components/CommentList.svelte +67 -0
- package/dist/components/CommentList.svelte.d.ts +53 -0
- package/dist/components/Dialog.svelte +25 -3
- package/dist/components/Dialog.svelte.d.ts +4 -1
- package/dist/components/Drawer.svelte +105 -0
- package/dist/components/Drawer.svelte.d.ts +31 -0
- package/dist/components/DropdownMenu.svelte +2 -2
- package/dist/components/DropdownMenu.svelte.d.ts +1 -1
- package/dist/components/EmptyState.svelte +40 -0
- package/dist/components/EmptyState.svelte.d.ts +19 -0
- package/dist/components/Fieldset.svelte +60 -0
- package/dist/components/Fieldset.svelte.d.ts +19 -0
- package/dist/components/FileInput.svelte +47 -0
- package/dist/components/FileInput.svelte.d.ts +15 -0
- package/dist/components/Filmstrip.svelte +72 -0
- package/dist/components/Filmstrip.svelte.d.ts +50 -0
- package/dist/components/FloatingBar.svelte +43 -0
- package/dist/components/FloatingBar.svelte.d.ts +16 -0
- package/dist/components/IconButton.svelte +1 -1
- package/dist/components/Input.svelte.d.ts +1 -1
- package/dist/components/ListRow.svelte +50 -0
- package/dist/components/ListRow.svelte.d.ts +18 -0
- package/dist/components/Marker.svelte +38 -0
- package/dist/components/Marker.svelte.d.ts +14 -0
- package/dist/components/NavMenu.svelte +6 -1
- package/dist/components/NavMenu.svelte.d.ts +2 -1
- package/dist/components/NumberField.svelte +12 -1
- package/dist/components/NumberField.svelte.d.ts +1 -1
- package/dist/components/Pagination.svelte +86 -0
- package/dist/components/Pagination.svelte.d.ts +22 -0
- package/dist/components/Popover.svelte +24 -3
- package/dist/components/Popover.svelte.d.ts +4 -1
- package/dist/components/RadioGroup.svelte.d.ts +2 -2
- package/dist/components/RecordStepper.svelte +58 -0
- package/dist/components/RecordStepper.svelte.d.ts +18 -0
- package/dist/components/SegmentedNav.svelte +53 -0
- package/dist/components/SegmentedNav.svelte.d.ts +22 -0
- package/dist/components/Select.svelte.d.ts +2 -2
- package/dist/components/Stat.svelte +41 -0
- package/dist/components/Stat.svelte.d.ts +17 -0
- package/dist/components/StatusDot.svelte +27 -0
- package/dist/components/StatusDot.svelte.d.ts +12 -0
- package/dist/components/SwatchGroup.svelte +69 -0
- package/dist/components/SwatchGroup.svelte.d.ts +44 -0
- package/dist/components/Switch.svelte +19 -0
- package/dist/components/Table.svelte +30 -3
- package/dist/components/Table.svelte.d.ts +13 -0
- package/dist/components/TableHeader.svelte +72 -0
- package/dist/components/TableHeader.svelte.d.ts +24 -0
- package/dist/components/Tabs.svelte +23 -5
- package/dist/components/Tabs.svelte.d.ts +4 -3
- package/dist/components/Textarea.svelte.d.ts +1 -1
- package/dist/components/ThemeToggle.svelte +133 -0
- package/dist/components/ThemeToggle.svelte.d.ts +20 -0
- package/dist/components/Thumbnail.svelte +51 -0
- package/dist/components/Thumbnail.svelte.d.ts +19 -0
- package/dist/components/ToggleGroup.svelte +107 -0
- package/dist/components/ToggleGroup.svelte.d.ts +46 -0
- package/dist/components/TooltipProvider.svelte +1 -0
- package/dist/components/Workspace.svelte +27 -6
- package/dist/components/Workspace.svelte.d.ts +12 -0
- package/dist/index.d.ts +29 -2
- package/dist/index.js +26 -1
- package/dist/media.svelte.d.ts +48 -0
- package/dist/media.svelte.js +69 -0
- package/dist/theme.svelte.d.ts +86 -0
- package/dist/theme.svelte.js +166 -0
- package/dist/toaster.svelte.d.ts +2 -0
- package/dist/toaster.svelte.js +51 -9
- package/dist/types.d.ts +21 -0
- 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;
|
|
@@ -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, {}, "
|
|
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) =>
|
|
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, {}, "
|
|
19
|
+
declare const NumberField: import("svelte").Component<Props, {}, "value" | "ref">;
|
|
20
20
|
type NumberField = ReturnType<typeof NumberField>;
|
|
21
21
|
export default NumberField;
|