@loidolt/theme-svelte 0.5.0 → 0.6.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 +47 -4
- package/dist/index.js +35 -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/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,94 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
PinInput as PinInputPrimitive,
|
|
4
|
+
REGEXP_ONLY_DIGITS,
|
|
5
|
+
REGEXP_ONLY_DIGITS_AND_CHARS,
|
|
6
|
+
type PinInputRootProps,
|
|
7
|
+
} from 'bits-ui';
|
|
8
|
+
import { cx } from '../utils.js';
|
|
9
|
+
|
|
10
|
+
type Props = Omit<
|
|
11
|
+
PinInputRootProps,
|
|
12
|
+
| 'children'
|
|
13
|
+
| 'maxlength'
|
|
14
|
+
| 'value'
|
|
15
|
+
| 'onValueChange'
|
|
16
|
+
| 'onComplete'
|
|
17
|
+
| 'inputId'
|
|
18
|
+
| 'inputRef'
|
|
19
|
+
| 'pattern'
|
|
20
|
+
| 'inputmode'
|
|
21
|
+
| 'textalign'
|
|
22
|
+
| 'ref'
|
|
23
|
+
| 'class'
|
|
24
|
+
> & {
|
|
25
|
+
value?: string;
|
|
26
|
+
/** Number of characters in the code. */
|
|
27
|
+
length?: number;
|
|
28
|
+
/** `numeric` accepts digits and opens the number pad; `alphanumeric` accepts letters too. */
|
|
29
|
+
type?: 'numeric' | 'alphanumeric';
|
|
30
|
+
/** Accessible name of the input, e.g. "Verification code". */
|
|
31
|
+
label: string;
|
|
32
|
+
/** Draw a gap after every `groupSize` characters — `3` renders a six-digit code as 123 456. */
|
|
33
|
+
groupSize?: number;
|
|
34
|
+
/** Show dots instead of the characters. */
|
|
35
|
+
mask?: boolean;
|
|
36
|
+
/** The id of the underlying input, so a `Field` label can point at it. */
|
|
37
|
+
id?: string;
|
|
38
|
+
onValueChange?: (value: string) => void;
|
|
39
|
+
/** Called with the code once every cell is filled. */
|
|
40
|
+
onComplete?: (value: string) => void;
|
|
41
|
+
class?: string;
|
|
42
|
+
cellClass?: string;
|
|
43
|
+
/** The hidden input that holds the code. */
|
|
44
|
+
ref?: HTMLInputElement | null;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
let {
|
|
48
|
+
value = $bindable(''),
|
|
49
|
+
length = 6,
|
|
50
|
+
type = 'numeric',
|
|
51
|
+
label,
|
|
52
|
+
groupSize,
|
|
53
|
+
mask = false,
|
|
54
|
+
id,
|
|
55
|
+
onValueChange,
|
|
56
|
+
onComplete,
|
|
57
|
+
class: className,
|
|
58
|
+
cellClass,
|
|
59
|
+
ref = $bindable(null),
|
|
60
|
+
...rest
|
|
61
|
+
}: Props = $props();
|
|
62
|
+
|
|
63
|
+
// Codes are often copied as "123-456" or "123 456"; keep only what the field accepts.
|
|
64
|
+
const pasteTransformer = (text: string) => text.replace(/[\s-]/g, '');
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<PinInputPrimitive.Root
|
|
68
|
+
bind:value
|
|
69
|
+
bind:inputRef={ref}
|
|
70
|
+
maxlength={length}
|
|
71
|
+
inputId={id}
|
|
72
|
+
pattern={type === 'numeric' ? REGEXP_ONLY_DIGITS : REGEXP_ONLY_DIGITS_AND_CHARS}
|
|
73
|
+
inputmode={type === 'numeric' ? 'numeric' : 'text'}
|
|
74
|
+
aria-label={label}
|
|
75
|
+
{pasteTransformer}
|
|
76
|
+
{onValueChange}
|
|
77
|
+
onComplete={(code: string) => onComplete?.(code)}
|
|
78
|
+
class={cx('ldt-otp-input', className)}
|
|
79
|
+
{...rest}
|
|
80
|
+
>
|
|
81
|
+
{#snippet children({ cells })}
|
|
82
|
+
{#each cells as cell, index (index)}
|
|
83
|
+
{#if groupSize && index > 0 && index % groupSize === 0}<span
|
|
84
|
+
class="ldt-otp-input__gap"
|
|
85
|
+
aria-hidden="true"
|
|
86
|
+
></span>{/if}
|
|
87
|
+
<PinInputPrimitive.Cell {cell} class={cx('ldt-otp-input__cell', cellClass)}>
|
|
88
|
+
{#if cell.char}{mask ? '•' : cell.char}{/if}{#if cell.hasFakeCaret}<span
|
|
89
|
+
class="ldt-otp-input__caret"
|
|
90
|
+
></span>{/if}
|
|
91
|
+
</PinInputPrimitive.Cell>
|
|
92
|
+
{/each}
|
|
93
|
+
{/snippet}
|
|
94
|
+
</PinInputPrimitive.Root>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type PinInputRootProps } from 'bits-ui';
|
|
2
|
+
type Props = Omit<PinInputRootProps, 'children' | 'maxlength' | 'value' | 'onValueChange' | 'onComplete' | 'inputId' | 'inputRef' | 'pattern' | 'inputmode' | 'textalign' | 'ref' | 'class'> & {
|
|
3
|
+
value?: string;
|
|
4
|
+
/** Number of characters in the code. */
|
|
5
|
+
length?: number;
|
|
6
|
+
/** `numeric` accepts digits and opens the number pad; `alphanumeric` accepts letters too. */
|
|
7
|
+
type?: 'numeric' | 'alphanumeric';
|
|
8
|
+
/** Accessible name of the input, e.g. "Verification code". */
|
|
9
|
+
label: string;
|
|
10
|
+
/** Draw a gap after every `groupSize` characters — `3` renders a six-digit code as 123 456. */
|
|
11
|
+
groupSize?: number;
|
|
12
|
+
/** Show dots instead of the characters. */
|
|
13
|
+
mask?: boolean;
|
|
14
|
+
/** The id of the underlying input, so a `Field` label can point at it. */
|
|
15
|
+
id?: string;
|
|
16
|
+
onValueChange?: (value: string) => void;
|
|
17
|
+
/** Called with the code once every cell is filled. */
|
|
18
|
+
onComplete?: (value: string) => void;
|
|
19
|
+
class?: string;
|
|
20
|
+
cellClass?: string;
|
|
21
|
+
/** The hidden input that holds the code. */
|
|
22
|
+
ref?: HTMLInputElement | null;
|
|
23
|
+
};
|
|
24
|
+
declare const OTPInput: import("svelte").Component<Props, {}, "value" | "ref">;
|
|
25
|
+
type OTPInput = ReturnType<typeof OTPInput>;
|
|
26
|
+
export default OTPInput;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
4
|
+
import { cx } from '../utils.js';
|
|
5
|
+
|
|
6
|
+
interface Props extends Omit<HTMLInputAttributes, 'value' | 'type'> {
|
|
7
|
+
value?: string;
|
|
8
|
+
/** Whether the password is shown as plain text. */
|
|
9
|
+
visible?: boolean;
|
|
10
|
+
onVisibleChange?: (visible: boolean) => void;
|
|
11
|
+
/**
|
|
12
|
+
* Accessible name of the reveal button. It stays the same in both states and `aria-pressed`
|
|
13
|
+
* reports which one is active — changing the name as well would announce the state twice.
|
|
14
|
+
*/
|
|
15
|
+
toggleLabel?: string;
|
|
16
|
+
/** Custom button content; receives whether the password is visible. */
|
|
17
|
+
toggle?: Snippet<[boolean]>;
|
|
18
|
+
/** Draws the full box instead of the default underline. */
|
|
19
|
+
boxed?: boolean;
|
|
20
|
+
/** Lands on the wrapper; the rest props land on the input. */
|
|
21
|
+
class?: string;
|
|
22
|
+
inputClass?: string;
|
|
23
|
+
ref?: HTMLInputElement | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const generatedId = $props.id();
|
|
27
|
+
|
|
28
|
+
let {
|
|
29
|
+
value = $bindable(''),
|
|
30
|
+
visible = $bindable(false),
|
|
31
|
+
onVisibleChange,
|
|
32
|
+
toggleLabel = 'Show password',
|
|
33
|
+
toggle,
|
|
34
|
+
boxed = false,
|
|
35
|
+
autocomplete = 'current-password',
|
|
36
|
+
id = generatedId,
|
|
37
|
+
disabled,
|
|
38
|
+
class: className,
|
|
39
|
+
inputClass,
|
|
40
|
+
ref = $bindable(null),
|
|
41
|
+
...rest
|
|
42
|
+
}: Props = $props();
|
|
43
|
+
|
|
44
|
+
function flip() {
|
|
45
|
+
visible = !visible;
|
|
46
|
+
onVisibleChange?.(visible);
|
|
47
|
+
}
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<div
|
|
51
|
+
class={cx('ldt-password-input', boxed && 'ldt-password-input--boxed', className)}
|
|
52
|
+
data-disabled={disabled ? '' : undefined}
|
|
53
|
+
>
|
|
54
|
+
<input
|
|
55
|
+
bind:this={ref}
|
|
56
|
+
bind:value
|
|
57
|
+
{id}
|
|
58
|
+
{disabled}
|
|
59
|
+
{autocomplete}
|
|
60
|
+
type={visible ? 'text' : 'password'}
|
|
61
|
+
class={cx('ldt-password-input__input', inputClass)}
|
|
62
|
+
autocapitalize="off"
|
|
63
|
+
spellcheck="false"
|
|
64
|
+
{...rest}
|
|
65
|
+
/>
|
|
66
|
+
<button
|
|
67
|
+
type="button"
|
|
68
|
+
class="ldt-password-input__toggle"
|
|
69
|
+
aria-label={toggleLabel}
|
|
70
|
+
aria-pressed={visible}
|
|
71
|
+
aria-controls={id}
|
|
72
|
+
{disabled}
|
|
73
|
+
onclick={flip}
|
|
74
|
+
>
|
|
75
|
+
{#if toggle}{@render toggle(visible)}{:else}
|
|
76
|
+
<svg
|
|
77
|
+
viewBox="0 0 20 20"
|
|
78
|
+
width="18"
|
|
79
|
+
height="18"
|
|
80
|
+
aria-hidden="true"
|
|
81
|
+
focusable="false"
|
|
82
|
+
fill="none"
|
|
83
|
+
stroke="currentColor"
|
|
84
|
+
stroke-width="1.5"
|
|
85
|
+
><path d="M1.5 10S4.6 4 10 4s8.5 6 8.5 6-3.1 6-8.5 6-8.5-6-8.5-6Z" /><circle
|
|
86
|
+
cx="10"
|
|
87
|
+
cy="10"
|
|
88
|
+
r="2.6"
|
|
89
|
+
/>{#if visible}<path d="m3 17 14-14" />{/if}</svg
|
|
90
|
+
>
|
|
91
|
+
{/if}
|
|
92
|
+
</button>
|
|
93
|
+
</div>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props extends Omit<HTMLInputAttributes, 'value' | 'type'> {
|
|
4
|
+
value?: string;
|
|
5
|
+
/** Whether the password is shown as plain text. */
|
|
6
|
+
visible?: boolean;
|
|
7
|
+
onVisibleChange?: (visible: boolean) => void;
|
|
8
|
+
/**
|
|
9
|
+
* Accessible name of the reveal button. It stays the same in both states and `aria-pressed`
|
|
10
|
+
* reports which one is active — changing the name as well would announce the state twice.
|
|
11
|
+
*/
|
|
12
|
+
toggleLabel?: string;
|
|
13
|
+
/** Custom button content; receives whether the password is visible. */
|
|
14
|
+
toggle?: Snippet<[boolean]>;
|
|
15
|
+
/** Draws the full box instead of the default underline. */
|
|
16
|
+
boxed?: boolean;
|
|
17
|
+
/** Lands on the wrapper; the rest props land on the input. */
|
|
18
|
+
class?: string;
|
|
19
|
+
inputClass?: string;
|
|
20
|
+
ref?: HTMLInputElement | null;
|
|
21
|
+
}
|
|
22
|
+
declare const PasswordInput: import("svelte").Component<Props, {}, "value" | "ref" | "visible">;
|
|
23
|
+
type PasswordInput = ReturnType<typeof PasswordInput>;
|
|
24
|
+
export default PasswordInput;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { ControlSize, StatusVariant } from '../types.js';
|
|
3
4
|
import { cx } from '../utils.js';
|
|
4
5
|
|
|
5
6
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
@@ -7,6 +8,18 @@
|
|
|
7
8
|
value?: number;
|
|
8
9
|
max?: number;
|
|
9
10
|
label?: string;
|
|
11
|
+
/** Colours the bar by outcome — `success` when done, `error` when a run failed part-way. */
|
|
12
|
+
variant?: 'default' | StatusVariant;
|
|
13
|
+
/** Bar thickness. */
|
|
14
|
+
size?: ControlSize;
|
|
15
|
+
/** Show the formatted value after the bar. */
|
|
16
|
+
showValue?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Text for the value, shown by `showValue` and spoken as `aria-valuetext` — "3 of 12 sheets"
|
|
19
|
+
* says more than 25%. Defaults to a whole percentage.
|
|
20
|
+
*/
|
|
21
|
+
formatValue?: (value: number, max: number) => string;
|
|
22
|
+
/** Lands on the progressbar element. */
|
|
10
23
|
class?: string;
|
|
11
24
|
ref?: HTMLDivElement | null;
|
|
12
25
|
}
|
|
@@ -15,6 +28,10 @@
|
|
|
15
28
|
value,
|
|
16
29
|
max = 100,
|
|
17
30
|
label = 'Progress',
|
|
31
|
+
variant = 'default',
|
|
32
|
+
size = 'md',
|
|
33
|
+
showValue = false,
|
|
34
|
+
formatValue,
|
|
18
35
|
class: className,
|
|
19
36
|
ref = $bindable(null),
|
|
20
37
|
...rest
|
|
@@ -24,20 +41,46 @@
|
|
|
24
41
|
// A non-positive `max` would make every ratio Infinity or NaN.
|
|
25
42
|
const safeMax = $derived(Number.isFinite(max) && max > 0 ? max : 100);
|
|
26
43
|
const clamped = $derived(Math.max(0, Math.min(safeMax, value ?? 0)));
|
|
44
|
+
const text = $derived(
|
|
45
|
+
indeterminate
|
|
46
|
+
? undefined
|
|
47
|
+
: formatValue
|
|
48
|
+
? formatValue(clamped, safeMax)
|
|
49
|
+
: `${Math.round((clamped / safeMax) * 100)}%`
|
|
50
|
+
);
|
|
27
51
|
</script>
|
|
28
52
|
|
|
29
|
-
|
|
30
|
-
bind:this={ref}
|
|
31
|
-
class={cx('ldt-progress', indeterminate && 'ldt-progress--indeterminate', className)}
|
|
32
|
-
role="progressbar"
|
|
33
|
-
aria-label={label}
|
|
34
|
-
aria-valuenow={indeterminate ? undefined : clamped}
|
|
35
|
-
aria-valuemin="0"
|
|
36
|
-
aria-valuemax={safeMax}
|
|
37
|
-
{...rest}
|
|
38
|
-
>
|
|
53
|
+
{#snippet bar()}
|
|
39
54
|
<div
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
55
|
+
bind:this={ref}
|
|
56
|
+
class={cx(
|
|
57
|
+
'ldt-progress',
|
|
58
|
+
indeterminate && 'ldt-progress--indeterminate',
|
|
59
|
+
variant !== 'default' && `ldt-progress--${variant}`,
|
|
60
|
+
size !== 'md' && `ldt-progress--${size}`,
|
|
61
|
+
className
|
|
62
|
+
)}
|
|
63
|
+
role="progressbar"
|
|
64
|
+
aria-label={label}
|
|
65
|
+
aria-valuenow={indeterminate ? undefined : clamped}
|
|
66
|
+
aria-valuemin="0"
|
|
67
|
+
aria-valuemax={safeMax}
|
|
68
|
+
aria-valuetext={formatValue ? text : undefined}
|
|
69
|
+
{...rest}
|
|
70
|
+
>
|
|
71
|
+
<div
|
|
72
|
+
class="ldt-progress__bar"
|
|
73
|
+
style:--ldt-progress-value={indeterminate ? undefined : clamped / safeMax}
|
|
74
|
+
></div>
|
|
75
|
+
</div>
|
|
76
|
+
{/snippet}
|
|
77
|
+
|
|
78
|
+
{#if showValue}
|
|
79
|
+
<div class="ldt-progress-field">
|
|
80
|
+
{@render bar()}
|
|
81
|
+
<!-- The progressbar already reports its value; this is the sighted copy. -->
|
|
82
|
+
<span class="ldt-progress-field__value" aria-hidden="true">{text ?? ''}</span>
|
|
83
|
+
</div>
|
|
84
|
+
{:else}
|
|
85
|
+
{@render bar()}
|
|
86
|
+
{/if}
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { ControlSize, StatusVariant } from '../types.js';
|
|
2
3
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
3
4
|
/** Omit (or pass `undefined`) for an indeterminate bar. */
|
|
4
5
|
value?: number;
|
|
5
6
|
max?: number;
|
|
6
7
|
label?: string;
|
|
8
|
+
/** Colours the bar by outcome — `success` when done, `error` when a run failed part-way. */
|
|
9
|
+
variant?: 'default' | StatusVariant;
|
|
10
|
+
/** Bar thickness. */
|
|
11
|
+
size?: ControlSize;
|
|
12
|
+
/** Show the formatted value after the bar. */
|
|
13
|
+
showValue?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Text for the value, shown by `showValue` and spoken as `aria-valuetext` — "3 of 12 sheets"
|
|
16
|
+
* says more than 25%. Defaults to a whole percentage.
|
|
17
|
+
*/
|
|
18
|
+
formatValue?: (value: number, max: number) => string;
|
|
19
|
+
/** Lands on the progressbar element. */
|
|
7
20
|
class?: string;
|
|
8
21
|
ref?: HTMLDivElement | null;
|
|
9
22
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends string = string">
|
|
2
2
|
import type { HTMLFieldsetAttributes } from 'svelte/elements';
|
|
3
|
-
import type {
|
|
3
|
+
import type { ChoiceOption, Orientation } from '../types.js';
|
|
4
4
|
import { cx } from '../utils.js';
|
|
5
5
|
|
|
6
6
|
interface Props extends HTMLFieldsetAttributes {
|
|
7
7
|
value?: T;
|
|
8
|
-
|
|
8
|
+
/** Choices. A `description` renders under its label and is read after it. */
|
|
9
|
+
options: ChoiceOption<T>[];
|
|
9
10
|
/** Shared `name` for the inputs. Defaults to an SSR-stable generated id. */
|
|
10
11
|
name?: string;
|
|
11
12
|
/** Visible group label, rendered as a `<legend>`. */
|
|
@@ -35,15 +36,28 @@
|
|
|
35
36
|
<fieldset bind:this={ref} class={cx('ldt-fieldset', className)} {...rest}>
|
|
36
37
|
{#if label}<legend class="ldt-legend">{label}</legend>{/if}
|
|
37
38
|
<div class={cx('ldt-radio-group', orientation === 'vertical' && 'ldt-radio-group--vertical')}>
|
|
38
|
-
{#each options as option (option.value)}
|
|
39
|
+
{#each options as option, index (option.value)}
|
|
40
|
+
{@const labelId = `${generatedName}-${index}-label`}
|
|
41
|
+
{@const descriptionId = option.description
|
|
42
|
+
? `${generatedName}-${index}-description`
|
|
43
|
+
: undefined}
|
|
44
|
+
<label class={cx('ldt-choice', option.description && 'ldt-choice--described')}
|
|
39
45
|
><input
|
|
40
46
|
type="radio"
|
|
41
47
|
{name}
|
|
42
48
|
value={option.value}
|
|
43
49
|
bind:group={value}
|
|
44
50
|
disabled={option.disabled}
|
|
51
|
+
aria-labelledby={option.description ? labelId : undefined}
|
|
52
|
+
aria-describedby={descriptionId}
|
|
45
53
|
onchange={() => onValueChange?.(option.value)}
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
/><span class="ldt-choice__text"
|
|
55
|
+
><span id={labelId}>{option.label}</span>{#if option.description}<span
|
|
56
|
+
class="ldt-choice__description"
|
|
57
|
+
id={descriptionId}>{option.description}</span
|
|
58
|
+
>{/if}</span
|
|
59
|
+
></label
|
|
60
|
+
>
|
|
61
|
+
{/each}
|
|
48
62
|
</div>
|
|
49
63
|
</fieldset>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { HTMLFieldsetAttributes } from 'svelte/elements';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ChoiceOption, Orientation } from '../types.js';
|
|
3
3
|
declare function $$render<T extends string = string>(): {
|
|
4
4
|
props: HTMLFieldsetAttributes & {
|
|
5
5
|
value?: T;
|
|
6
|
-
|
|
6
|
+
/** Choices. A `description` renders under its label and is read after it. */
|
|
7
|
+
options: ChoiceOption<T>[];
|
|
7
8
|
/** Shared `name` for the inputs. Defaults to an SSR-stable generated id. */
|
|
8
9
|
name?: string;
|
|
9
10
|
/** Visible group label, rendered as a `<legend>`. */
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends string = string">
|
|
2
2
|
import type { HTMLSelectAttributes } from 'svelte/elements';
|
|
3
|
-
import type
|
|
3
|
+
import { isOptionGroup, type OptionEntry } from '../internal/options.js';
|
|
4
4
|
import { cx } from '../utils.js';
|
|
5
5
|
|
|
6
6
|
interface Props extends Omit<HTMLSelectAttributes, 'value'> {
|
|
7
7
|
value?: T | '';
|
|
8
|
-
|
|
8
|
+
/** Options, optionally in labelled groups — rendered as native `<optgroup>`s. */
|
|
9
|
+
options: OptionEntry<T>[];
|
|
9
10
|
/**
|
|
10
11
|
* Empty-choice text. Selectable again after a real choice unless the field is `required`,
|
|
11
12
|
* so a user can undo their selection.
|
|
@@ -51,7 +52,16 @@
|
|
|
51
52
|
>
|
|
52
53
|
{#if placeholder}<option value="" disabled={required} hidden={required}>{placeholder}</option
|
|
53
54
|
>{/if}
|
|
54
|
-
{#each options as
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
{#each options as entry (isOptionGroup(entry) ? `group:${entry.label}` : entry.value)}
|
|
56
|
+
{#if isOptionGroup(entry)}
|
|
57
|
+
<optgroup label={entry.label} disabled={entry.disabled}>
|
|
58
|
+
{#each entry.options as option (option.value)}<option
|
|
59
|
+
value={option.value}
|
|
60
|
+
disabled={option.disabled}>{option.label}</option
|
|
61
|
+
>{/each}
|
|
62
|
+
</optgroup>
|
|
63
|
+
{:else}
|
|
64
|
+
<option value={entry.value} disabled={entry.disabled}>{entry.label}</option>
|
|
65
|
+
{/if}
|
|
66
|
+
{/each}
|
|
57
67
|
</select>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { HTMLSelectAttributes } from 'svelte/elements';
|
|
2
|
-
import type
|
|
2
|
+
import { type OptionEntry } from '../internal/options.js';
|
|
3
3
|
declare function $$render<T extends string = string>(): {
|
|
4
4
|
props: Omit<HTMLSelectAttributes, "value"> & {
|
|
5
5
|
value?: T | "";
|
|
6
|
-
|
|
6
|
+
/** Options, optionally in labelled groups — rendered as native `<optgroup>`s. */
|
|
7
|
+
options: OptionEntry<T>[];
|
|
7
8
|
/**
|
|
8
9
|
* Empty-choice text. Selectable again after a real choice unless the field is `required`,
|
|
9
10
|
* so a user can undo their selection.
|