@loidolt/theme-svelte 0.5.0 → 0.7.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 +11 -0
- package/dist/announcer.svelte.d.ts +36 -0
- package/dist/announcer.svelte.js +73 -0
- package/dist/attachments.d.ts +83 -0
- package/dist/attachments.js +211 -0
- package/dist/components/ActiveFilterChips.svelte +80 -0
- package/dist/components/ActiveFilterChips.svelte.d.ts +41 -0
- package/dist/components/AspectRatio.svelte +32 -0
- package/dist/components/AspectRatio.svelte.d.ts +13 -0
- package/dist/components/AudioPlayer.svelte +94 -0
- package/dist/components/AudioPlayer.svelte.d.ts +24 -0
- package/dist/components/Avatar.svelte +85 -0
- package/dist/components/Avatar.svelte.d.ts +31 -0
- package/dist/components/Badge.svelte +28 -2
- package/dist/components/Badge.svelte.d.ts +13 -1
- package/dist/components/Combobox.svelte +180 -0
- package/dist/components/Combobox.svelte.d.ts +77 -0
- package/dist/components/DataTable.svelte +228 -0
- package/dist/components/DataTable.svelte.d.ts +62 -0
- package/dist/components/DataTableColumnVisibility.svelte +46 -0
- package/dist/components/DataTableColumnVisibility.svelte.d.ts +31 -0
- package/dist/components/DataTableFacetedFilter.svelte +87 -0
- package/dist/components/DataTableFacetedFilter.svelte.d.ts +40 -0
- package/dist/components/DataTablePagination.svelte +68 -0
- package/dist/components/DataTablePagination.svelte.d.ts +42 -0
- package/dist/components/DataTableSearch.svelte +67 -0
- package/dist/components/DataTableSearch.svelte.d.ts +37 -0
- package/dist/components/Dialog.svelte +32 -11
- package/dist/components/Dialog.svelte.d.ts +7 -0
- package/dist/components/DropdownMenu.svelte +95 -28
- package/dist/components/DropdownMenu.svelte.d.ts +12 -3
- package/dist/components/Field.svelte +2 -3
- package/dist/components/Fieldset.svelte +2 -3
- package/dist/components/Filmstrip.svelte +10 -3
- package/dist/components/FilterPanel.svelte +62 -0
- package/dist/components/FilterPanel.svelte.d.ts +22 -0
- package/dist/components/Lightbox.svelte +239 -0
- package/dist/components/Lightbox.svelte.d.ts +40 -0
- package/dist/components/LiveRegion.svelte +48 -0
- package/dist/components/LiveRegion.svelte.d.ts +20 -0
- package/dist/components/MediaCarousel.svelte +177 -0
- package/dist/components/MediaCarousel.svelte.d.ts +32 -0
- package/dist/components/MediaEmbed.svelte +116 -0
- package/dist/components/MediaEmbed.svelte.d.ts +34 -0
- package/dist/components/MediaGrid.svelte +91 -0
- package/dist/components/MediaGrid.svelte.d.ts +24 -0
- package/dist/components/MultiSelect.svelte +232 -0
- package/dist/components/MultiSelect.svelte.d.ts +67 -0
- package/dist/components/NumberField.svelte +53 -25
- package/dist/components/NumberField.svelte.d.ts +47 -18
- package/dist/components/OTPInput.svelte +94 -0
- package/dist/components/OTPInput.svelte.d.ts +26 -0
- package/dist/components/PasswordInput.svelte +93 -0
- package/dist/components/PasswordInput.svelte.d.ts +24 -0
- package/dist/components/Progress.svelte +57 -14
- package/dist/components/Progress.svelte.d.ts +13 -0
- package/dist/components/RadioGroup.svelte +19 -5
- package/dist/components/RadioGroup.svelte.d.ts +3 -2
- package/dist/components/Select.svelte +15 -5
- package/dist/components/Select.svelte.d.ts +3 -2
- package/dist/components/SignaturePad.svelte +317 -0
- package/dist/components/SignaturePad.svelte.d.ts +48 -0
- package/dist/components/Skeleton.svelte +40 -9
- package/dist/components/Skeleton.svelte.d.ts +8 -0
- package/dist/components/SkipLink.svelte +48 -0
- package/dist/components/SkipLink.svelte.d.ts +14 -0
- package/dist/components/Slider.svelte +148 -0
- package/dist/components/Slider.svelte.d.ts +55 -0
- package/dist/components/Spinner.svelte +11 -2
- package/dist/components/Spinner.svelte.d.ts +3 -0
- package/dist/components/Tabs.svelte.d.ts +1 -1
- package/dist/components/Thumbnail.svelte +52 -6
- package/dist/components/Thumbnail.svelte.d.ts +14 -2
- package/dist/components/Toast.svelte +24 -0
- package/dist/components/Toast.svelte.d.ts +10 -0
- package/dist/components/ToastViewport.svelte +9 -1
- package/dist/components/ToastViewport.svelte.d.ts +2 -0
- package/dist/components/Toolbar.svelte +49 -0
- package/dist/components/Toolbar.svelte.d.ts +23 -0
- package/dist/components/Tooltip.svelte +9 -1
- package/dist/components/Tooltip.svelte.d.ts +2 -0
- package/dist/components/VideoPlayer.svelte +136 -0
- package/dist/components/VideoPlayer.svelte.d.ts +38 -0
- package/dist/data-table-utils.d.ts +62 -0
- package/dist/data-table-utils.js +91 -0
- package/dist/data-table.svelte.d.ts +132 -0
- package/dist/data-table.svelte.js +292 -0
- package/dist/hls.d.ts +35 -0
- package/dist/hls.js +37 -0
- package/dist/hls.svelte.d.ts +22 -0
- package/dist/hls.svelte.js +66 -0
- package/dist/index.d.ts +49 -4
- package/dist/index.js +36 -2
- package/dist/internal/EditableCell.svelte +58 -0
- package/dist/internal/EditableCell.svelte.d.ts +8 -0
- package/dist/internal/ListboxEntries.svelte +49 -0
- package/dist/internal/ListboxEntries.svelte.d.ts +35 -0
- package/dist/internal/media/MediaControls.svelte +163 -0
- package/dist/internal/media/MediaControls.svelte.d.ts +12 -0
- package/dist/internal/media/MediaStage.svelte +49 -0
- package/dist/internal/media/MediaStage.svelte.d.ts +11 -0
- package/dist/internal/media/MediaTile.svelte +36 -0
- package/dist/internal/media/MediaTile.svelte.d.ts +11 -0
- package/dist/internal/media/keys.d.ts +7 -0
- package/dist/internal/media/keys.js +51 -0
- package/dist/internal/media/labels.d.ts +19 -0
- package/dist/internal/media/labels.js +15 -0
- package/dist/internal/options.d.ts +9 -0
- package/dist/internal/options.js +20 -0
- package/dist/media-player.svelte.d.ts +61 -0
- package/dist/media-player.svelte.js +246 -0
- package/dist/media-utils.d.ts +112 -0
- package/dist/media-utils.js +205 -0
- package/dist/media-zoom.svelte.d.ts +33 -0
- package/dist/media-zoom.svelte.js +126 -0
- package/dist/signature.d.ts +55 -0
- package/dist/signature.js +52 -0
- package/dist/toaster.svelte.d.ts +24 -0
- package/dist/toaster.svelte.js +23 -0
- package/dist/token-colors.svelte.d.ts +49 -0
- package/dist/token-colors.svelte.js +165 -0
- package/dist/types.d.ts +62 -3
- package/dist/utils.d.ts +9 -0
- package/dist/utils.js +11 -0
- package/package.json +10 -4
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { Orientation } from '../types.js';
|
|
4
|
+
declare function $$render<V extends number | number[] = number>(): {
|
|
5
|
+
props: Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
|
|
6
|
+
/** A number for one thumb, an array for a range — one thumb per entry. */
|
|
7
|
+
value?: V;
|
|
8
|
+
min?: number;
|
|
9
|
+
max?: number;
|
|
10
|
+
/** The increment, or an explicit list of the only values allowed. */
|
|
11
|
+
step?: number | number[];
|
|
12
|
+
orientation?: Orientation;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
/** Accessible name. With two or more thumbs each is named from it by `thumbLabel`. */
|
|
15
|
+
label: string;
|
|
16
|
+
thumbLabel?: (index: number, count: number) => string;
|
|
17
|
+
/** Spoken (`aria-valuetext`) and shown for each value — add units here: `(v) => \`${v} mm\``. */
|
|
18
|
+
formatValue?: (value: number) => string;
|
|
19
|
+
/** Show the formatted value beside the track. */
|
|
20
|
+
showValue?: boolean;
|
|
21
|
+
/** Mark every step along the track. Sensible only for a coarse `step`. */
|
|
22
|
+
ticks?: boolean;
|
|
23
|
+
/** Submits each value as a hidden input under this name. */
|
|
24
|
+
name?: string;
|
|
25
|
+
/** Every change, while dragging too. */
|
|
26
|
+
onValueChange?: (value: V) => void;
|
|
27
|
+
/** Only when the user lets go or finishes a key press — the moment to save. */
|
|
28
|
+
onValueCommit?: (value: V) => void;
|
|
29
|
+
/** Rendered after the track, e.g. min/max captions. */
|
|
30
|
+
children?: Snippet;
|
|
31
|
+
class?: string;
|
|
32
|
+
ref?: HTMLDivElement | null;
|
|
33
|
+
};
|
|
34
|
+
exports: {};
|
|
35
|
+
bindings: "value" | "ref";
|
|
36
|
+
slots: {};
|
|
37
|
+
events: {};
|
|
38
|
+
};
|
|
39
|
+
declare class __sveltets_Render<V extends number | number[] = number> {
|
|
40
|
+
props(): ReturnType<typeof $$render<V>>['props'];
|
|
41
|
+
events(): ReturnType<typeof $$render<V>>['events'];
|
|
42
|
+
slots(): ReturnType<typeof $$render<V>>['slots'];
|
|
43
|
+
bindings(): "value" | "ref";
|
|
44
|
+
exports(): {};
|
|
45
|
+
}
|
|
46
|
+
interface $$IsomorphicComponent {
|
|
47
|
+
new <V extends number | number[] = number>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<V>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<V>['props']>, ReturnType<__sveltets_Render<V>['events']>, ReturnType<__sveltets_Render<V>['slots']>> & {
|
|
48
|
+
$$bindings?: ReturnType<__sveltets_Render<V>['bindings']>;
|
|
49
|
+
} & ReturnType<__sveltets_Render<V>['exports']>;
|
|
50
|
+
<V extends number | number[] = number>(internal: unknown, props: ReturnType<__sveltets_Render<V>['props']> & {}): ReturnType<__sveltets_Render<V>['exports']>;
|
|
51
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
52
|
+
}
|
|
53
|
+
declare const Slider: $$IsomorphicComponent;
|
|
54
|
+
type Slider<V extends number | number[] = number> = InstanceType<typeof Slider<V>>;
|
|
55
|
+
export default Slider;
|
|
@@ -1,20 +1,29 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { ControlSize } from '../types.js';
|
|
3
4
|
import { cx } from '../utils.js';
|
|
4
5
|
|
|
5
6
|
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
6
7
|
/** Accessible name. Pass `undefined` when an adjacent label already announces the wait. */
|
|
7
8
|
label?: string;
|
|
9
|
+
/** Omit to follow the surrounding font size, which suits a spinner inside a button. */
|
|
10
|
+
size?: ControlSize;
|
|
8
11
|
class?: string;
|
|
9
12
|
ref?: HTMLSpanElement | null;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
|
-
let {
|
|
15
|
+
let {
|
|
16
|
+
label = 'Loading',
|
|
17
|
+
size,
|
|
18
|
+
class: className,
|
|
19
|
+
ref = $bindable(null),
|
|
20
|
+
...rest
|
|
21
|
+
}: Props = $props();
|
|
13
22
|
</script>
|
|
14
23
|
|
|
15
24
|
<span
|
|
16
25
|
bind:this={ref}
|
|
17
|
-
class={cx('ldt-spinner', className)}
|
|
26
|
+
class={cx('ldt-spinner', size && `ldt-spinner--${size}`, className)}
|
|
18
27
|
role={label ? 'status' : undefined}
|
|
19
28
|
aria-label={label}
|
|
20
29
|
aria-hidden={label ? undefined : 'true'}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { ControlSize } from '../types.js';
|
|
2
3
|
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
3
4
|
/** Accessible name. Pass `undefined` when an adjacent label already announces the wait. */
|
|
4
5
|
label?: string;
|
|
6
|
+
/** Omit to follow the surrounding font size, which suits a spinner inside a button. */
|
|
7
|
+
size?: ControlSize;
|
|
5
8
|
class?: string;
|
|
6
9
|
ref?: HTMLSpanElement | null;
|
|
7
10
|
}
|
|
@@ -2,7 +2,7 @@ import { Tabs as TabsPrimitive } from 'bits-ui';
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { NavItem, Orientation } from '../types.js';
|
|
4
4
|
declare function $$render<T extends string = string>(): {
|
|
5
|
-
props: Omit<TabsPrimitive.RootProps, "
|
|
5
|
+
props: Omit<TabsPrimitive.RootProps, "orientation" | "value" | "children" | "class" | "onValueChange" | "ref" | "child"> & {
|
|
6
6
|
/** Defaults to the first tab, so a panel is always rendered. */
|
|
7
7
|
value?: T;
|
|
8
8
|
tabs: NavItem<T>[];
|
|
@@ -1,19 +1,32 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import { aspectRatio } from '@loidolt/theme-tokens';
|
|
5
|
+
import type { AspectRatioName } from '../media-utils.js';
|
|
4
6
|
import { cx } from '../utils.js';
|
|
5
7
|
|
|
6
8
|
interface Props extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
|
|
7
9
|
src?: string;
|
|
8
10
|
/** Required whenever `src` is set — decorative images should say so with `alt=""`. */
|
|
9
11
|
alt?: string;
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
+
/** Candidate sources for responsive images, with `sizes`. */
|
|
13
|
+
srcset?: string;
|
|
14
|
+
sizes?: string;
|
|
15
|
+
/** A named frame (`photo`, `video`, `square`…), a CSS aspect-ratio value, or a number. */
|
|
16
|
+
ratio?: AspectRatioName | string | number;
|
|
12
17
|
fit?: 'contain' | 'cover';
|
|
13
18
|
/** `sunken` recesses into the page; `paper` stays white in every theme for artwork. */
|
|
14
19
|
surface?: 'sunken' | 'paper';
|
|
20
|
+
/** `lazy` (the default) waits until the image nears the viewport. */
|
|
21
|
+
loading?: 'lazy' | 'eager';
|
|
22
|
+
/** Shown if the image fails to load. Defaults to an empty frame. */
|
|
23
|
+
fallback?: Snippet;
|
|
24
|
+
/** Content over the image — a badge, a duration, a selection mark. */
|
|
25
|
+
overlay?: Snippet;
|
|
15
26
|
/** Alternative to `src` — inline SVG, canvas, anything that fills the frame. */
|
|
16
27
|
children?: Snippet;
|
|
28
|
+
onload?: (event: Event) => void;
|
|
29
|
+
onerror?: (event: Event) => void;
|
|
17
30
|
class?: string;
|
|
18
31
|
ref?: HTMLElement | null;
|
|
19
32
|
}
|
|
@@ -21,14 +34,33 @@
|
|
|
21
34
|
let {
|
|
22
35
|
src,
|
|
23
36
|
alt = '',
|
|
37
|
+
srcset,
|
|
38
|
+
sizes,
|
|
24
39
|
ratio = '4/3',
|
|
25
40
|
fit = 'contain',
|
|
26
41
|
surface = 'sunken',
|
|
42
|
+
loading = 'lazy',
|
|
43
|
+
fallback,
|
|
44
|
+
overlay,
|
|
27
45
|
children,
|
|
46
|
+
onload,
|
|
47
|
+
onerror,
|
|
28
48
|
class: className,
|
|
29
49
|
ref = $bindable(null),
|
|
30
50
|
...rest
|
|
31
51
|
}: Props = $props();
|
|
52
|
+
|
|
53
|
+
const frame = $derived(
|
|
54
|
+
typeof ratio === 'string' && ratio in aspectRatio
|
|
55
|
+
? aspectRatio[ratio as AspectRatioName]
|
|
56
|
+
: ratio
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// Resets to `loading` whenever `src` changes; the image's own events move it on.
|
|
60
|
+
let status = $derived.by<'loading' | 'loaded' | 'error'>(() => {
|
|
61
|
+
void src;
|
|
62
|
+
return 'loading';
|
|
63
|
+
});
|
|
32
64
|
</script>
|
|
33
65
|
|
|
34
66
|
<figure
|
|
@@ -39,13 +71,27 @@
|
|
|
39
71
|
fit === 'cover' && 'ldt-thumbnail--cover',
|
|
40
72
|
className
|
|
41
73
|
)}
|
|
42
|
-
style={`--ldt-thumbnail-ratio: ${
|
|
74
|
+
style={`--ldt-thumbnail-ratio: ${frame};`}
|
|
75
|
+
data-status={src && !children ? status : undefined}
|
|
43
76
|
{...rest}
|
|
44
77
|
>
|
|
45
|
-
{#if children}{@render children()}{:else if src}<
|
|
78
|
+
{#if children}{@render children()}{:else if src && status === 'error'}{#if fallback}{@render fallback()}{:else}<span
|
|
79
|
+
class="ldt-sr-only">{alt}</span
|
|
80
|
+
>{/if}{:else if src}<img
|
|
46
81
|
class="ldt-thumbnail__image"
|
|
47
82
|
{src}
|
|
48
83
|
{alt}
|
|
49
|
-
|
|
50
|
-
|
|
84
|
+
{srcset}
|
|
85
|
+
{sizes}
|
|
86
|
+
{loading}
|
|
87
|
+
decoding="async"
|
|
88
|
+
onload={(event) => {
|
|
89
|
+
status = 'loaded';
|
|
90
|
+
onload?.(event);
|
|
91
|
+
}}
|
|
92
|
+
onerror={(event) => {
|
|
93
|
+
status = 'error';
|
|
94
|
+
onerror?.(event);
|
|
95
|
+
}}
|
|
96
|
+
/>{/if}{#if overlay}<div class="ldt-thumbnail__overlay">{@render overlay()}</div>{/if}
|
|
51
97
|
</figure>
|
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { AspectRatioName } from '../media-utils.js';
|
|
3
4
|
interface Props extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
|
|
4
5
|
src?: string;
|
|
5
6
|
/** Required whenever `src` is set — decorative images should say so with `alt=""`. */
|
|
6
7
|
alt?: string;
|
|
7
|
-
/**
|
|
8
|
-
|
|
8
|
+
/** Candidate sources for responsive images, with `sizes`. */
|
|
9
|
+
srcset?: string;
|
|
10
|
+
sizes?: string;
|
|
11
|
+
/** A named frame (`photo`, `video`, `square`…), a CSS aspect-ratio value, or a number. */
|
|
12
|
+
ratio?: AspectRatioName | string | number;
|
|
9
13
|
fit?: 'contain' | 'cover';
|
|
10
14
|
/** `sunken` recesses into the page; `paper` stays white in every theme for artwork. */
|
|
11
15
|
surface?: 'sunken' | 'paper';
|
|
16
|
+
/** `lazy` (the default) waits until the image nears the viewport. */
|
|
17
|
+
loading?: 'lazy' | 'eager';
|
|
18
|
+
/** Shown if the image fails to load. Defaults to an empty frame. */
|
|
19
|
+
fallback?: Snippet;
|
|
20
|
+
/** Content over the image — a badge, a duration, a selection mark. */
|
|
21
|
+
overlay?: Snippet;
|
|
12
22
|
/** Alternative to `src` — inline SVG, canvas, anything that fills the frame. */
|
|
13
23
|
children?: Snippet;
|
|
24
|
+
onload?: (event: Event) => void;
|
|
25
|
+
onerror?: (event: Event) => void;
|
|
14
26
|
class?: string;
|
|
15
27
|
ref?: HTMLElement | null;
|
|
16
28
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import Button from './Button.svelte';
|
|
4
5
|
import IconButton from './IconButton.svelte';
|
|
6
|
+
import type { ToastAction } from '../toaster.svelte.js';
|
|
5
7
|
import type { StatusVariant } from '../types.js';
|
|
6
8
|
import { cx } from '../utils.js';
|
|
7
9
|
|
|
@@ -11,6 +13,15 @@
|
|
|
11
13
|
variant?: StatusVariant;
|
|
12
14
|
dismissLabel?: string;
|
|
13
15
|
onDismiss?: () => void;
|
|
16
|
+
/** One follow-up button, e.g. Undo. Runs `onAction`, then dismisses unless told not to. */
|
|
17
|
+
action?: ToastAction;
|
|
18
|
+
/** Custom action area, in place of `action`. */
|
|
19
|
+
actions?: Snippet;
|
|
20
|
+
/**
|
|
21
|
+
* Read by `createToaster`, not the component. Declared so `{...toast}` from a toaster's queue
|
|
22
|
+
* does not leak it onto the element as an attribute.
|
|
23
|
+
*/
|
|
24
|
+
duration?: number;
|
|
14
25
|
class?: string;
|
|
15
26
|
children?: Snippet;
|
|
16
27
|
ref?: HTMLDivElement | null;
|
|
@@ -22,6 +33,10 @@
|
|
|
22
33
|
variant,
|
|
23
34
|
dismissLabel = 'Dismiss notification',
|
|
24
35
|
onDismiss,
|
|
36
|
+
action,
|
|
37
|
+
actions,
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- read by the toaster, never rendered
|
|
39
|
+
duration: _duration,
|
|
25
40
|
class: className,
|
|
26
41
|
children,
|
|
27
42
|
ref = $bindable(null),
|
|
@@ -44,6 +59,15 @@
|
|
|
44
59
|
{description}
|
|
45
60
|
</p>{/if}{#if children}<div class="ldt-toast__description">
|
|
46
61
|
{@render children()}
|
|
62
|
+
</div>{/if}{#if actions || action}<div class="ldt-toast__actions">
|
|
63
|
+
{#if actions}{@render actions()}{:else if action}<Button
|
|
64
|
+
size="sm"
|
|
65
|
+
variant="quiet"
|
|
66
|
+
onclick={() => {
|
|
67
|
+
action.onAction();
|
|
68
|
+
if (action.dismiss !== false) onDismiss?.();
|
|
69
|
+
}}>{action.label}</Button
|
|
70
|
+
>{/if}
|
|
47
71
|
</div>{/if}{#if onDismiss}<IconButton
|
|
48
72
|
class="ldt-toast__dismiss"
|
|
49
73
|
size="sm"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { ToastAction } from '../toaster.svelte.js';
|
|
3
4
|
import type { StatusVariant } from '../types.js';
|
|
4
5
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
6
|
title: string;
|
|
@@ -7,6 +8,15 @@ interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
|
7
8
|
variant?: StatusVariant;
|
|
8
9
|
dismissLabel?: string;
|
|
9
10
|
onDismiss?: () => void;
|
|
11
|
+
/** One follow-up button, e.g. Undo. Runs `onAction`, then dismisses unless told not to. */
|
|
12
|
+
action?: ToastAction;
|
|
13
|
+
/** Custom action area, in place of `action`. */
|
|
14
|
+
actions?: Snippet;
|
|
15
|
+
/**
|
|
16
|
+
* Read by `createToaster`, not the component. Declared so `{...toast}` from a toaster's queue
|
|
17
|
+
* does not leak it onto the element as an attribute.
|
|
18
|
+
*/
|
|
19
|
+
duration?: number;
|
|
10
20
|
class?: string;
|
|
11
21
|
children?: Snippet;
|
|
12
22
|
ref?: HTMLDivElement | null;
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
label?: string;
|
|
8
8
|
/** `polite` for routine updates; `assertive` interrupts and should be rare. */
|
|
9
9
|
politeness?: 'polite' | 'assertive';
|
|
10
|
+
/** Which corner or edge the stack sits against. Top positions stack newest-last as well. */
|
|
11
|
+
position?:
|
|
12
|
+
'bottom-end' | 'bottom-start' | 'bottom-center' | 'top-end' | 'top-start' | 'top-center';
|
|
10
13
|
class?: string;
|
|
11
14
|
children: Snippet;
|
|
12
15
|
ref?: HTMLDivElement | null;
|
|
@@ -15,6 +18,7 @@
|
|
|
15
18
|
let {
|
|
16
19
|
label = 'Notifications',
|
|
17
20
|
politeness = 'polite',
|
|
21
|
+
position = 'bottom-end',
|
|
18
22
|
class: className,
|
|
19
23
|
children,
|
|
20
24
|
ref = $bindable(null),
|
|
@@ -28,7 +32,11 @@
|
|
|
28
32
|
-->
|
|
29
33
|
<div
|
|
30
34
|
bind:this={ref}
|
|
31
|
-
class={cx(
|
|
35
|
+
class={cx(
|
|
36
|
+
'ldt-toast-viewport',
|
|
37
|
+
position !== 'bottom-end' && `ldt-toast-viewport--${position}`,
|
|
38
|
+
className
|
|
39
|
+
)}
|
|
32
40
|
aria-label={label}
|
|
33
41
|
aria-live={politeness}
|
|
34
42
|
aria-relevant="additions text"
|
|
@@ -4,6 +4,8 @@ interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
|
4
4
|
label?: string;
|
|
5
5
|
/** `polite` for routine updates; `assertive` interrupts and should be rare. */
|
|
6
6
|
politeness?: 'polite' | 'assertive';
|
|
7
|
+
/** Which corner or edge the stack sits against. Top positions stack newest-last as well. */
|
|
8
|
+
position?: 'bottom-end' | 'bottom-start' | 'bottom-center' | 'top-end' | 'top-start' | 'top-center';
|
|
7
9
|
class?: string;
|
|
8
10
|
children: Snippet;
|
|
9
11
|
ref?: HTMLDivElement | null;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import { rovingFocus } from '../attachments.js';
|
|
5
|
+
import type { Orientation } from '../types.js';
|
|
6
|
+
import { cx } from '../utils.js';
|
|
7
|
+
|
|
8
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
9
|
+
/** Accessible name, e.g. "Sheet list tools". */
|
|
10
|
+
label: string;
|
|
11
|
+
/** Leading controls — search, filters, a result count. */
|
|
12
|
+
children?: Snippet;
|
|
13
|
+
/** Controls pushed to the far end — view toggles, a sort menu. */
|
|
14
|
+
end?: Snippet;
|
|
15
|
+
orientation?: Orientation;
|
|
16
|
+
/**
|
|
17
|
+
* Make it an ARIA `toolbar`: one tab stop, arrow keys between the controls marked
|
|
18
|
+
* `data-roving-item`. Leave it off (a labelled `group`, Tab between controls) when the bar
|
|
19
|
+
* holds a text field or a control that owns its own arrow keys, like a `ToggleGroup`.
|
|
20
|
+
*/
|
|
21
|
+
roving?: boolean;
|
|
22
|
+
class?: string;
|
|
23
|
+
ref?: HTMLDivElement | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let {
|
|
27
|
+
label,
|
|
28
|
+
children,
|
|
29
|
+
end,
|
|
30
|
+
orientation = 'horizontal',
|
|
31
|
+
roving = false,
|
|
32
|
+
class: className,
|
|
33
|
+
ref = $bindable(null),
|
|
34
|
+
...rest
|
|
35
|
+
}: Props = $props();
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<div
|
|
39
|
+
bind:this={ref}
|
|
40
|
+
class={cx('ldt-toolbar', orientation === 'vertical' && 'ldt-toolbar--vertical', className)}
|
|
41
|
+
role={roving ? 'toolbar' : 'group'}
|
|
42
|
+
aria-label={label}
|
|
43
|
+
aria-orientation={roving ? orientation : undefined}
|
|
44
|
+
{@attach roving ? rovingFocus({ orientation }) : undefined}
|
|
45
|
+
{...rest}
|
|
46
|
+
>
|
|
47
|
+
{#if children}{@render children()}{/if}
|
|
48
|
+
{#if end}<div class="ldt-toolbar__end">{@render end()}</div>{/if}
|
|
49
|
+
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
/** Accessible name, e.g. "Sheet list tools". */
|
|
6
|
+
label: string;
|
|
7
|
+
/** Leading controls — search, filters, a result count. */
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
/** Controls pushed to the far end — view toggles, a sort menu. */
|
|
10
|
+
end?: Snippet;
|
|
11
|
+
orientation?: Orientation;
|
|
12
|
+
/**
|
|
13
|
+
* Make it an ARIA `toolbar`: one tab stop, arrow keys between the controls marked
|
|
14
|
+
* `data-roving-item`. Leave it off (a labelled `group`, Tab between controls) when the bar
|
|
15
|
+
* holds a text field or a control that owns its own arrow keys, like a `ToggleGroup`.
|
|
16
|
+
*/
|
|
17
|
+
roving?: boolean;
|
|
18
|
+
class?: string;
|
|
19
|
+
ref?: HTMLDivElement | null;
|
|
20
|
+
}
|
|
21
|
+
declare const Toolbar: import("svelte").Component<Props, {}, "ref">;
|
|
22
|
+
type Toolbar = ReturnType<typeof Toolbar>;
|
|
23
|
+
export default Toolbar;
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
side?: Placement;
|
|
22
22
|
align?: Alignment;
|
|
23
23
|
sideOffset?: number;
|
|
24
|
+
/** Point the tooltip at its trigger — worth it when the trigger is small or crowded. */
|
|
25
|
+
arrow?: boolean;
|
|
24
26
|
/** Ignored when an ancestor `TooltipProvider` is present. */
|
|
25
27
|
delayDuration?: number;
|
|
26
28
|
/** `class` lands on the portaled Content element. */
|
|
@@ -39,6 +41,7 @@
|
|
|
39
41
|
side = 'top',
|
|
40
42
|
align = 'center',
|
|
41
43
|
sideOffset = 6,
|
|
44
|
+
arrow = false,
|
|
42
45
|
delayDuration = 350,
|
|
43
46
|
class: className,
|
|
44
47
|
onOpenChange,
|
|
@@ -65,7 +68,12 @@
|
|
|
65
68
|
{align}
|
|
66
69
|
{sideOffset}
|
|
67
70
|
class={cx('ldt-tooltip', className)}
|
|
68
|
-
{...rest}
|
|
71
|
+
{...rest}
|
|
72
|
+
>{content}{#if arrow}<TooltipPrimitive.Arrow
|
|
73
|
+
class="ldt-tooltip__arrow"
|
|
74
|
+
width={10}
|
|
75
|
+
height={5}
|
|
76
|
+
/>{/if}</TooltipPrimitive.Content
|
|
69
77
|
></TooltipPrimitive.Portal
|
|
70
78
|
>
|
|
71
79
|
</TooltipPrimitive.Root>
|
|
@@ -16,6 +16,8 @@ type Props = Omit<TooltipContentProps, 'children' | 'class' | 'child'> & {
|
|
|
16
16
|
side?: Placement;
|
|
17
17
|
align?: Alignment;
|
|
18
18
|
sideOffset?: number;
|
|
19
|
+
/** Point the tooltip at its trigger — worth it when the trigger is small or crowded. */
|
|
20
|
+
arrow?: boolean;
|
|
19
21
|
/** Ignored when an ancestor `TooltipProvider` is present. */
|
|
20
22
|
delayDuration?: number;
|
|
21
23
|
/** `class` lands on the portaled Content element. */
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import type { HlsLoader } from '../hls.js';
|
|
5
|
+
import { createHlsSource } from '../hls.svelte.js';
|
|
6
|
+
import { defaultMediaLabels, type MediaPlayerLabels } from '../internal/media/labels.js';
|
|
7
|
+
import { mediaKeydown } from '../internal/media/keys.js';
|
|
8
|
+
import MediaControls from '../internal/media/MediaControls.svelte';
|
|
9
|
+
import { createMediaPlayer } from '../media-player.svelte.js';
|
|
10
|
+
import {
|
|
11
|
+
isHlsSource,
|
|
12
|
+
resolveAspectRatio,
|
|
13
|
+
toMediaSources,
|
|
14
|
+
type AspectRatioName,
|
|
15
|
+
type MediaSourceEntry,
|
|
16
|
+
type MediaTextTrack,
|
|
17
|
+
} from '../media-utils.js';
|
|
18
|
+
import { cx } from '../utils.js';
|
|
19
|
+
|
|
20
|
+
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
21
|
+
/** A URL, or several sources for the browser to choose from. `.m3u8` plays as HLS. */
|
|
22
|
+
src: string | MediaSourceEntry[];
|
|
23
|
+
/** Names the player for assistive tech. */
|
|
24
|
+
label: string;
|
|
25
|
+
poster?: string;
|
|
26
|
+
/** Captions and subtitles. Provide captions for any video with speech (WCAG 1.2.2). */
|
|
27
|
+
tracks?: MediaTextTrack[];
|
|
28
|
+
ratio?: AspectRatioName | number | string;
|
|
29
|
+
fit?: 'contain' | 'cover';
|
|
30
|
+
/** Browsers only autoplay muted media; `autoplay` implies `muted`. */
|
|
31
|
+
autoplay?: boolean;
|
|
32
|
+
muted?: boolean;
|
|
33
|
+
loop?: boolean;
|
|
34
|
+
preload?: 'none' | 'metadata' | 'auto';
|
|
35
|
+
/** `custom` draws this library's controls; `native` uses the browser's; `none` hides both. */
|
|
36
|
+
controls?: 'custom' | 'native' | 'none';
|
|
37
|
+
/** hls.js loader for this player, in place of the one given to `setHlsLoader()`. */
|
|
38
|
+
hlsLoader?: HlsLoader;
|
|
39
|
+
hlsConfig?: Record<string, unknown>;
|
|
40
|
+
/** Content layered over the video, e.g. a title card. */
|
|
41
|
+
overlay?: Snippet;
|
|
42
|
+
labels?: Partial<MediaPlayerLabels>;
|
|
43
|
+
onEnded?: () => void;
|
|
44
|
+
onTimeUpdate?: (seconds: number) => void;
|
|
45
|
+
class?: string;
|
|
46
|
+
ref?: HTMLDivElement | null;
|
|
47
|
+
/** The `<video>` element. */
|
|
48
|
+
mediaRef?: HTMLVideoElement | null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let {
|
|
52
|
+
src,
|
|
53
|
+
label,
|
|
54
|
+
poster,
|
|
55
|
+
tracks = [],
|
|
56
|
+
ratio = 'video',
|
|
57
|
+
fit = 'contain',
|
|
58
|
+
autoplay = false,
|
|
59
|
+
muted = false,
|
|
60
|
+
loop = false,
|
|
61
|
+
preload = 'metadata',
|
|
62
|
+
controls = 'custom',
|
|
63
|
+
hlsLoader,
|
|
64
|
+
hlsConfig,
|
|
65
|
+
overlay,
|
|
66
|
+
labels,
|
|
67
|
+
onEnded,
|
|
68
|
+
onTimeUpdate,
|
|
69
|
+
class: className,
|
|
70
|
+
ref = $bindable(null),
|
|
71
|
+
mediaRef = $bindable(null),
|
|
72
|
+
...rest
|
|
73
|
+
}: Props = $props();
|
|
74
|
+
|
|
75
|
+
const text = $derived({ ...defaultMediaLabels, ...labels });
|
|
76
|
+
const sources = $derived(toMediaSources(src));
|
|
77
|
+
const stream = $derived(sources.find((source) => isHlsSource(source)));
|
|
78
|
+
const player = createMediaPlayer({
|
|
79
|
+
onEnded: () => onEnded?.(),
|
|
80
|
+
onTimeUpdate: (seconds) => onTimeUpdate?.(seconds),
|
|
81
|
+
});
|
|
82
|
+
const hls = createHlsSource({
|
|
83
|
+
get loader() {
|
|
84
|
+
return hlsLoader;
|
|
85
|
+
},
|
|
86
|
+
get config() {
|
|
87
|
+
return hlsConfig;
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
const failed = $derived(
|
|
91
|
+
Boolean(player.error) || hls.status === 'unsupported' || hls.status === 'error'
|
|
92
|
+
);
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
<div
|
|
96
|
+
bind:this={ref}
|
|
97
|
+
class={cx('ldt-media-player', 'ldt-media-player--video', className)}
|
|
98
|
+
style:--ldt-aspect-ratio={resolveAspectRatio(ratio)}
|
|
99
|
+
data-playing={player.playing ? '' : undefined}
|
|
100
|
+
role="group"
|
|
101
|
+
aria-label={label}
|
|
102
|
+
onkeydown={controls === 'custom' ? mediaKeydown(player, () => ref) : undefined}
|
|
103
|
+
{...rest}
|
|
104
|
+
>
|
|
105
|
+
<video
|
|
106
|
+
bind:this={mediaRef}
|
|
107
|
+
class="ldt-media-player__media"
|
|
108
|
+
style:object-fit={fit}
|
|
109
|
+
{poster}
|
|
110
|
+
{preload}
|
|
111
|
+
{autoplay}
|
|
112
|
+
muted={muted || autoplay}
|
|
113
|
+
{loop}
|
|
114
|
+
playsinline
|
|
115
|
+
controls={controls === 'native'}
|
|
116
|
+
crossorigin={tracks.length ? 'anonymous' : undefined}
|
|
117
|
+
{@attach player.attach}
|
|
118
|
+
{@attach stream ? hls.source(stream.src) : undefined}
|
|
119
|
+
onclick={controls === 'custom' ? () => player.toggle() : undefined}
|
|
120
|
+
>
|
|
121
|
+
{#if !stream}{#each sources as source (source.src)}<source
|
|
122
|
+
src={source.src}
|
|
123
|
+
type={source.type}
|
|
124
|
+
/>{/each}{/if}
|
|
125
|
+
{#each tracks as track (track.src)}<track
|
|
126
|
+
src={track.src}
|
|
127
|
+
kind={track.kind ?? 'captions'}
|
|
128
|
+
srclang={track.srclang}
|
|
129
|
+
label={track.label}
|
|
130
|
+
default={track.default}
|
|
131
|
+
/>{/each}
|
|
132
|
+
</video>
|
|
133
|
+
{#if overlay}<div class="ldt-media-player__overlay">{@render overlay()}</div>{/if}
|
|
134
|
+
{#if failed}<p class="ldt-media-player__error" role="alert">{text.error}</p>{/if}
|
|
135
|
+
{#if controls === 'custom'}<MediaControls {player} labels={text} video container={ref} />{/if}
|
|
136
|
+
</div>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { HlsLoader } from '../hls.js';
|
|
4
|
+
import { type MediaPlayerLabels } from '../internal/media/labels.js';
|
|
5
|
+
import { type AspectRatioName, type MediaSourceEntry, type MediaTextTrack } from '../media-utils.js';
|
|
6
|
+
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
7
|
+
/** A URL, or several sources for the browser to choose from. `.m3u8` plays as HLS. */
|
|
8
|
+
src: string | MediaSourceEntry[];
|
|
9
|
+
/** Names the player for assistive tech. */
|
|
10
|
+
label: string;
|
|
11
|
+
poster?: string;
|
|
12
|
+
/** Captions and subtitles. Provide captions for any video with speech (WCAG 1.2.2). */
|
|
13
|
+
tracks?: MediaTextTrack[];
|
|
14
|
+
ratio?: AspectRatioName | number | string;
|
|
15
|
+
fit?: 'contain' | 'cover';
|
|
16
|
+
/** Browsers only autoplay muted media; `autoplay` implies `muted`. */
|
|
17
|
+
autoplay?: boolean;
|
|
18
|
+
muted?: boolean;
|
|
19
|
+
loop?: boolean;
|
|
20
|
+
preload?: 'none' | 'metadata' | 'auto';
|
|
21
|
+
/** `custom` draws this library's controls; `native` uses the browser's; `none` hides both. */
|
|
22
|
+
controls?: 'custom' | 'native' | 'none';
|
|
23
|
+
/** hls.js loader for this player, in place of the one given to `setHlsLoader()`. */
|
|
24
|
+
hlsLoader?: HlsLoader;
|
|
25
|
+
hlsConfig?: Record<string, unknown>;
|
|
26
|
+
/** Content layered over the video, e.g. a title card. */
|
|
27
|
+
overlay?: Snippet;
|
|
28
|
+
labels?: Partial<MediaPlayerLabels>;
|
|
29
|
+
onEnded?: () => void;
|
|
30
|
+
onTimeUpdate?: (seconds: number) => void;
|
|
31
|
+
class?: string;
|
|
32
|
+
ref?: HTMLDivElement | null;
|
|
33
|
+
/** The `<video>` element. */
|
|
34
|
+
mediaRef?: HTMLVideoElement | null;
|
|
35
|
+
}
|
|
36
|
+
declare const VideoPlayer: import("svelte").Component<Props, {}, "ref" | "mediaRef">;
|
|
37
|
+
type VideoPlayer = ReturnType<typeof VideoPlayer>;
|
|
38
|
+
export default VideoPlayer;
|