@sveltier/ui 0.0.0-stage → 0.1.0-alpha.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/LICENSE +21 -0
- package/README.md +82 -2
- package/dist/components/Alert/Alert.svelte +88 -0
- package/dist/components/Alert/Alert.svelte.d.ts +4 -0
- package/dist/components/Alert/alert.css +78 -0
- package/dist/components/Alert/index.d.ts +2 -0
- package/dist/components/Alert/index.js +1 -0
- package/dist/components/Alert/types.d.ts +67 -0
- package/dist/components/Alert/types.js +1 -0
- package/dist/components/Avatar/Avatar.svelte +47 -0
- package/dist/components/Avatar/Avatar.svelte.d.ts +4 -0
- package/dist/components/Avatar/avatar.css +34 -0
- package/dist/components/Avatar/index.d.ts +2 -0
- package/dist/components/Avatar/index.js +1 -0
- package/dist/components/Avatar/types.d.ts +47 -0
- package/dist/components/Avatar/types.js +1 -0
- package/dist/components/Badge/Badge.svelte +53 -0
- package/dist/components/Badge/Badge.svelte.d.ts +4 -0
- package/dist/components/Badge/badge.css +57 -0
- package/dist/components/Badge/index.d.ts +2 -0
- package/dist/components/Badge/index.js +1 -0
- package/dist/components/Badge/types.d.ts +43 -0
- package/dist/components/Badge/types.js +1 -0
- package/dist/components/Button/Button.svelte +85 -0
- package/dist/components/Button/Button.svelte.d.ts +4 -0
- package/dist/components/Button/button.css +132 -0
- package/dist/components/Button/index.d.ts +2 -0
- package/dist/components/Button/index.js +1 -0
- package/dist/components/Button/types.d.ts +76 -0
- package/dist/components/Button/types.js +1 -0
- package/dist/components/ButtonGroup/ButtonGroup.svelte +61 -0
- package/dist/components/ButtonGroup/ButtonGroup.svelte.d.ts +4 -0
- package/dist/components/ButtonGroup/button-group.css +39 -0
- package/dist/components/ButtonGroup/index.d.ts +2 -0
- package/dist/components/ButtonGroup/index.js +1 -0
- package/dist/components/ButtonGroup/types.d.ts +48 -0
- package/dist/components/ButtonGroup/types.js +1 -0
- package/dist/components/Card/Card.svelte +53 -0
- package/dist/components/Card/Card.svelte.d.ts +4 -0
- package/dist/components/Card/card.css +62 -0
- package/dist/components/Card/index.d.ts +2 -0
- package/dist/components/Card/index.js +1 -0
- package/dist/components/Card/types.d.ts +56 -0
- package/dist/components/Card/types.js +1 -0
- package/dist/components/Checkbox/Checkbox.svelte +105 -0
- package/dist/components/Checkbox/Checkbox.svelte.d.ts +4 -0
- package/dist/components/Checkbox/checkbox.css +138 -0
- package/dist/components/Checkbox/index.d.ts +2 -0
- package/dist/components/Checkbox/index.js +1 -0
- package/dist/components/Checkbox/types.d.ts +76 -0
- package/dist/components/Checkbox/types.js +1 -0
- package/dist/components/Chip/Chip.svelte +109 -0
- package/dist/components/Chip/Chip.svelte.d.ts +4 -0
- package/dist/components/Chip/chip.css +101 -0
- package/dist/components/Chip/index.d.ts +2 -0
- package/dist/components/Chip/index.js +1 -0
- package/dist/components/Chip/types.d.ts +69 -0
- package/dist/components/Chip/types.js +1 -0
- package/dist/components/Choice/Choice.svelte +60 -0
- package/dist/components/Choice/Choice.svelte.d.ts +4 -0
- package/dist/components/Choice/choice.css +75 -0
- package/dist/components/Choice/types.d.ts +43 -0
- package/dist/components/Choice/types.js +1 -0
- package/dist/components/Divider/Divider.svelte +19 -0
- package/dist/components/Divider/Divider.svelte.d.ts +4 -0
- package/dist/components/Divider/divider.css +23 -0
- package/dist/components/Divider/index.d.ts +2 -0
- package/dist/components/Divider/index.js +1 -0
- package/dist/components/Divider/types.d.ts +10 -0
- package/dist/components/Divider/types.js +1 -0
- package/dist/components/Field/Field.svelte +95 -0
- package/dist/components/Field/Field.svelte.d.ts +4 -0
- package/dist/components/Field/field.css +210 -0
- package/dist/components/Field/index.d.ts +3 -0
- package/dist/components/Field/index.js +2 -0
- package/dist/components/Field/types.d.ts +109 -0
- package/dist/components/Field/types.js +2 -0
- package/dist/components/Form/Form.svelte +93 -0
- package/dist/components/Form/Form.svelte.d.ts +8 -0
- package/dist/components/Form/form.css +16 -0
- package/dist/components/Form/index.d.ts +2 -0
- package/dist/components/Form/index.js +1 -0
- package/dist/components/Form/types.d.ts +38 -0
- package/dist/components/Form/types.js +1 -0
- package/dist/components/Icon/Icon.svelte +38 -0
- package/dist/components/Icon/Icon.svelte.d.ts +4 -0
- package/dist/components/Icon/icon.css +33 -0
- package/dist/components/Icon/index.d.ts +2 -0
- package/dist/components/Icon/index.js +1 -0
- package/dist/components/Icon/types.d.ts +34 -0
- package/dist/components/Icon/types.js +1 -0
- package/dist/components/List/List.svelte +39 -0
- package/dist/components/List/List.svelte.d.ts +4 -0
- package/dist/components/List/ListItem.svelte +57 -0
- package/dist/components/List/ListItem.svelte.d.ts +4 -0
- package/dist/components/List/index.d.ts +3 -0
- package/dist/components/List/index.js +2 -0
- package/dist/components/List/list.css +127 -0
- package/dist/components/List/types.d.ts +67 -0
- package/dist/components/List/types.js +1 -0
- package/dist/components/NativeSelect/NativeSelect.svelte +110 -0
- package/dist/components/NativeSelect/NativeSelect.svelte.d.ts +25 -0
- package/dist/components/NativeSelect/index.d.ts +2 -0
- package/dist/components/NativeSelect/index.js +1 -0
- package/dist/components/NativeSelect/native-select.css +45 -0
- package/dist/components/NativeSelect/types.d.ts +58 -0
- package/dist/components/NativeSelect/types.js +1 -0
- package/dist/components/NumberField/NumberField.svelte +246 -0
- package/dist/components/NumberField/NumberField.svelte.d.ts +4 -0
- package/dist/components/NumberField/index.d.ts +2 -0
- package/dist/components/NumberField/index.js +1 -0
- package/dist/components/NumberField/number-field.css +74 -0
- package/dist/components/NumberField/types.d.ts +73 -0
- package/dist/components/NumberField/types.js +1 -0
- package/dist/components/Progress/ProgressCircular.svelte +61 -0
- package/dist/components/Progress/ProgressCircular.svelte.d.ts +4 -0
- package/dist/components/Progress/ProgressLinear.svelte +44 -0
- package/dist/components/Progress/ProgressLinear.svelte.d.ts +4 -0
- package/dist/components/Progress/index.d.ts +3 -0
- package/dist/components/Progress/index.js +2 -0
- package/dist/components/Progress/progress-circular.css +61 -0
- package/dist/components/Progress/progress-linear.css +67 -0
- package/dist/components/Progress/types.d.ts +53 -0
- package/dist/components/Progress/types.js +1 -0
- package/dist/components/RadioGroup/RadioGroup.svelte +149 -0
- package/dist/components/RadioGroup/RadioGroup.svelte.d.ts +25 -0
- package/dist/components/RadioGroup/index.d.ts +2 -0
- package/dist/components/RadioGroup/index.js +1 -0
- package/dist/components/RadioGroup/radio-group.css +139 -0
- package/dist/components/RadioGroup/types.d.ts +93 -0
- package/dist/components/RadioGroup/types.js +1 -0
- package/dist/components/SegmentedControl/SegmentedControl.svelte +70 -0
- package/dist/components/SegmentedControl/SegmentedControl.svelte.d.ts +25 -0
- package/dist/components/SegmentedControl/index.d.ts +2 -0
- package/dist/components/SegmentedControl/index.js +1 -0
- package/dist/components/SegmentedControl/segmented-control.css +68 -0
- package/dist/components/SegmentedControl/types.d.ts +60 -0
- package/dist/components/SegmentedControl/types.js +1 -0
- package/dist/components/Skeleton/Skeleton.svelte +33 -0
- package/dist/components/Skeleton/Skeleton.svelte.d.ts +4 -0
- package/dist/components/Skeleton/index.d.ts +2 -0
- package/dist/components/Skeleton/index.js +1 -0
- package/dist/components/Skeleton/skeleton.css +70 -0
- package/dist/components/Skeleton/types.d.ts +25 -0
- package/dist/components/Skeleton/types.js +1 -0
- package/dist/components/Slider/Slider.svelte +153 -0
- package/dist/components/Slider/Slider.svelte.d.ts +4 -0
- package/dist/components/Slider/index.d.ts +2 -0
- package/dist/components/Slider/index.js +1 -0
- package/dist/components/Slider/slider.css +206 -0
- package/dist/components/Slider/types.d.ts +102 -0
- package/dist/components/Slider/types.js +1 -0
- package/dist/components/Switch/Switch.svelte +94 -0
- package/dist/components/Switch/Switch.svelte.d.ts +4 -0
- package/dist/components/Switch/index.d.ts +2 -0
- package/dist/components/Switch/index.js +1 -0
- package/dist/components/Switch/switch.css +118 -0
- package/dist/components/Switch/types.d.ts +67 -0
- package/dist/components/Switch/types.js +1 -0
- package/dist/components/Tabs/Tabs.svelte +93 -0
- package/dist/components/Tabs/Tabs.svelte.d.ts +25 -0
- package/dist/components/Tabs/index.d.ts +2 -0
- package/dist/components/Tabs/index.js +1 -0
- package/dist/components/Tabs/tabs.css +73 -0
- package/dist/components/Tabs/types.d.ts +59 -0
- package/dist/components/Tabs/types.js +1 -0
- package/dist/components/TextField/TextField.svelte +115 -0
- package/dist/components/TextField/TextField.svelte.d.ts +4 -0
- package/dist/components/TextField/index.d.ts +2 -0
- package/dist/components/TextField/index.js +1 -0
- package/dist/components/TextField/types.d.ts +57 -0
- package/dist/components/TextField/types.js +1 -0
- package/dist/components/Textarea/Textarea.svelte +116 -0
- package/dist/components/Textarea/Textarea.svelte.d.ts +4 -0
- package/dist/components/Textarea/index.d.ts +2 -0
- package/dist/components/Textarea/index.js +1 -0
- package/dist/components/Textarea/textarea.css +35 -0
- package/dist/components/Textarea/types.d.ts +60 -0
- package/dist/components/Textarea/types.js +1 -0
- package/dist/core/defaults/DefaultsProvider.svelte +30 -0
- package/dist/core/defaults/DefaultsProvider.svelte.d.ts +13 -0
- package/dist/core/defaults/context.d.ts +45 -0
- package/dist/core/defaults/context.js +38 -0
- package/dist/core/display/display.d.ts +39 -0
- package/dist/core/display/display.js +53 -0
- package/dist/core/errors/codes.d.ts +112 -0
- package/dist/core/errors/codes.js +96 -0
- package/dist/core/errors/errors.d.ts +8 -0
- package/dist/core/errors/errors.js +7 -0
- package/dist/core/form/constraints.d.ts +15 -0
- package/dist/core/form/constraints.js +42 -0
- package/dist/core/form/context.d.ts +19 -0
- package/dist/core/form/context.js +4 -0
- package/dist/core/form/field.svelte.d.ts +34 -0
- package/dist/core/form/field.svelte.js +66 -0
- package/dist/core/form/number.d.ts +24 -0
- package/dist/core/form/number.js +71 -0
- package/dist/core/form/types.d.ts +22 -0
- package/dist/core/form/types.js +1 -0
- package/dist/core/locale/locale.d.ts +55 -0
- package/dist/core/locale/locale.js +80 -0
- package/dist/core/props/classes.d.ts +21 -0
- package/dist/core/props/classes.js +44 -0
- package/dist/core/props/element.d.ts +18 -0
- package/dist/core/props/element.js +1 -0
- package/dist/core/props/types.d.ts +47 -0
- package/dist/core/props/types.js +16 -0
- package/dist/core/provider/UIProvider.svelte +60 -0
- package/dist/core/provider/UIProvider.svelte.d.ts +29 -0
- package/dist/core/theme/ThemeProvider.svelte +178 -0
- package/dist/core/theme/ThemeProvider.svelte.d.ts +25 -0
- package/dist/core/theme/color.d.ts +23 -0
- package/dist/core/theme/color.js +54 -0
- package/dist/core/theme/context.d.ts +25 -0
- package/dist/core/theme/context.js +14 -0
- package/dist/core/theme/css.d.ts +25 -0
- package/dist/core/theme/css.js +69 -0
- package/dist/core/theme/define.d.ts +11 -0
- package/dist/core/theme/define.js +21 -0
- package/dist/core/theme/resolve.d.ts +6 -0
- package/dist/core/theme/resolve.js +18 -0
- package/dist/core/theme/theme-provider.css +13 -0
- package/dist/core/theme/types.d.ts +35 -0
- package/dist/core/theme/types.js +61 -0
- package/dist/dev/off.d.ts +4 -0
- package/dist/dev/off.js +3 -0
- package/dist/dev/on.d.ts +8 -0
- package/dist/dev/on.js +33 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.js +72 -0
- package/dist/primitives/anchored/anchored.d.ts +39 -0
- package/dist/primitives/anchored/anchored.js +104 -0
- package/dist/primitives/anchored/fallback.d.ts +31 -0
- package/dist/primitives/anchored/fallback.js +73 -0
- package/dist/primitives/focus/focus-trap.d.ts +25 -0
- package/dist/primitives/focus/focus-trap.js +86 -0
- package/dist/primitives/focus/roving-focus.d.ts +22 -0
- package/dist/primitives/focus/roving-focus.js +86 -0
- package/dist/primitives/focus/tabbable.d.ts +9 -0
- package/dist/primitives/focus/tabbable.js +75 -0
- package/dist/primitives/inert/inert-others.d.ts +12 -0
- package/dist/primitives/inert/inert-others.js +44 -0
- package/dist/primitives/keyboard/keymap.d.ts +17 -0
- package/dist/primitives/keyboard/keymap.js +39 -0
- package/dist/primitives/keyboard/typeahead.d.ts +18 -0
- package/dist/primitives/keyboard/typeahead.js +50 -0
- package/dist/primitives/layer/dismissable.d.ts +26 -0
- package/dist/primitives/layer/dismissable.js +84 -0
- package/dist/primitives/motion/easing.d.ts +9 -0
- package/dist/primitives/motion/easing.js +46 -0
- package/dist/primitives/motion/motion.d.ts +59 -0
- package/dist/primitives/motion/motion.js +80 -0
- package/dist/primitives/portal/Portal.svelte +37 -0
- package/dist/primitives/portal/Portal.svelte.d.ts +9 -0
- package/dist/primitives/portal/PortalContent.svelte +15 -0
- package/dist/primitives/portal/PortalContent.svelte.d.ts +9 -0
- package/dist/primitives/portal/portal.css +8 -0
- package/dist/primitives/scroll-lock/scroll-lock.d.ts +10 -0
- package/dist/primitives/scroll-lock/scroll-lock.js +33 -0
- package/dist/primitives/virtual/virtual-list.svelte.d.ts +65 -0
- package/dist/primitives/virtual/virtual-list.svelte.js +291 -0
- package/dist/styles/base.css +44 -0
- package/dist/styles/props.css +137 -0
- package/dist/styles/tokens.css +84 -0
- package/dist/styles/visually-hidden.css +16 -0
- package/dist/themes/aurora.d.ts +13 -0
- package/dist/themes/aurora.js +103 -0
- package/dist/themes/heritage.d.ts +13 -0
- package/dist/themes/heritage.js +102 -0
- package/dist/themes/maison.d.ts +13 -0
- package/dist/themes/maison.js +99 -0
- package/dist/themes/milano.d.ts +13 -0
- package/dist/themes/milano.js +101 -0
- package/dist/themes/monolith.d.ts +13 -0
- package/dist/themes/monolith.js +101 -0
- package/package.json +87 -5
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { HTMLFieldsetAttributes } from 'svelte/elements';
|
|
2
|
+
import type { FieldError, Rule, ValidateOn } from '../../core/form/types.js';
|
|
3
|
+
import type { ElementProps } from '../../core/props/element.js';
|
|
4
|
+
import type { Color, Density, Size } from '../../core/props/types.js';
|
|
5
|
+
/** The RadioGroup props that `DefaultsProvider` and `UIProvider` can set for a subtree. */
|
|
6
|
+
export interface RadioGroupDefaults {
|
|
7
|
+
/**
|
|
8
|
+
* The colour of the chosen radio. An invalid group uses `error`.
|
|
9
|
+
* @default 'primary'
|
|
10
|
+
*/
|
|
11
|
+
color: Color;
|
|
12
|
+
/**
|
|
13
|
+
* The size of the radios and their labels.
|
|
14
|
+
* @default 'md'
|
|
15
|
+
*/
|
|
16
|
+
size: Size;
|
|
17
|
+
/**
|
|
18
|
+
* Multiplies the height of each row, never the text.
|
|
19
|
+
* @default 'default'
|
|
20
|
+
*/
|
|
21
|
+
density: Density;
|
|
22
|
+
/**
|
|
23
|
+
* Mutes the group and disables every radio in it.
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
disabled: boolean;
|
|
27
|
+
}
|
|
28
|
+
declare module '../../core/defaults/context.js' {
|
|
29
|
+
interface ComponentDefaults {
|
|
30
|
+
RadioGroup: RadioGroupDefaults;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** One choice of a RadioGroup. */
|
|
34
|
+
export interface RadioGroupOption<T extends string | number = string> {
|
|
35
|
+
/** The value the group binds to when this radio is chosen. */
|
|
36
|
+
value: T;
|
|
37
|
+
/** What the radio says. */
|
|
38
|
+
label: string;
|
|
39
|
+
/** Help under the label, read out with the radio. */
|
|
40
|
+
hint?: string;
|
|
41
|
+
disabled?: boolean;
|
|
42
|
+
}
|
|
43
|
+
type RadioGroupOwnProps<T extends string | number> = Partial<RadioGroupDefaults> & {
|
|
44
|
+
/** The choices, in order. */
|
|
45
|
+
options: readonly RadioGroupOption<T>[];
|
|
46
|
+
/** The chosen value, or `null` for none. Bindable. */
|
|
47
|
+
value?: T | null;
|
|
48
|
+
/** The question the radios answer, as the group's legend. Without it, use `aria-label`. */
|
|
49
|
+
label?: string;
|
|
50
|
+
/** Help under the radios. An error replaces it. */
|
|
51
|
+
hint?: string;
|
|
52
|
+
/**
|
|
53
|
+
* An error from outside the group, such as the server's answer: a message, a list of which
|
|
54
|
+
* the first is shown, or `true` for an invalid state described elsewhere.
|
|
55
|
+
*/
|
|
56
|
+
error?: FieldError;
|
|
57
|
+
/** Checks run in order after `required`, with the chosen value. The first message is shown. */
|
|
58
|
+
rules?: readonly Rule<T>[];
|
|
59
|
+
/** When the message shows. Defaults to the form's setting, else `'blur'`. */
|
|
60
|
+
validateOn?: ValidateOn;
|
|
61
|
+
/**
|
|
62
|
+
* A choice must be made. Adds an asterisk to the legend.
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
required?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Lays the radios side by side, wrapping when they run out of room.
|
|
68
|
+
* @default false
|
|
69
|
+
*/
|
|
70
|
+
inline?: boolean;
|
|
71
|
+
/** The name the radios submit their value under. Generated when not given. */
|
|
72
|
+
name?: string;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* One choice among a few options, all shown: native radios sharing a name in a `<fieldset>`,
|
|
76
|
+
* whose `<legend>` is the label. The arrow keys move the choice, as the platform does. `class`,
|
|
77
|
+
* `style`, `ref` and other attributes go to the `<fieldset>`. For many options, use a
|
|
78
|
+
* NativeSelect.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* <RadioGroup
|
|
82
|
+
* label="Pay out"
|
|
83
|
+
* name="payout"
|
|
84
|
+
* required
|
|
85
|
+
* options={[
|
|
86
|
+
* { value: 'daily', label: 'Every day' },
|
|
87
|
+
* { value: 'weekly', label: 'Every Monday', hint: 'Fewer, larger transfers' }
|
|
88
|
+
* ]}
|
|
89
|
+
* bind:value={payout}
|
|
90
|
+
* />
|
|
91
|
+
*/
|
|
92
|
+
export type RadioGroupProps<T extends string | number = string> = ElementProps<HTMLFieldSetElement, Omit<HTMLFieldsetAttributes, 'children'>, RadioGroupOwnProps<T>>;
|
|
93
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script lang="ts" generics="T extends string | number">
|
|
2
|
+
// One choice among a few, as a radio group. See SegmentedControlProps for the props.
|
|
3
|
+
import { useDefaults } from '../../core/defaults/context.js';
|
|
4
|
+
import { sharedClasses } from '../../core/props/classes.js';
|
|
5
|
+
import { rovingFocus } from '../../primitives/focus/roving-focus.js';
|
|
6
|
+
import './segmented-control.css';
|
|
7
|
+
import type {
|
|
8
|
+
SegmentedControlDefaults,
|
|
9
|
+
SegmentedControlOption,
|
|
10
|
+
SegmentedControlProps
|
|
11
|
+
} from './types.js';
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
variant,
|
|
15
|
+
color,
|
|
16
|
+
size,
|
|
17
|
+
density,
|
|
18
|
+
rounded,
|
|
19
|
+
options,
|
|
20
|
+
value = $bindable(),
|
|
21
|
+
onchange,
|
|
22
|
+
disabled = false,
|
|
23
|
+
class: className,
|
|
24
|
+
ref = $bindable(null),
|
|
25
|
+
...rest
|
|
26
|
+
}: SegmentedControlProps<T> = $props();
|
|
27
|
+
|
|
28
|
+
const resolve = useDefaults<SegmentedControlDefaults>('SegmentedControl', {
|
|
29
|
+
variant: 'elevated',
|
|
30
|
+
color: 'neutral',
|
|
31
|
+
size: 'md',
|
|
32
|
+
density: 'default',
|
|
33
|
+
rounded: true
|
|
34
|
+
});
|
|
35
|
+
const p = $derived(resolve({ variant, color, size, density, rounded }));
|
|
36
|
+
const index = $derived(options.findIndex((option) => option.value === value));
|
|
37
|
+
|
|
38
|
+
// Selection follows focus, as in a radio group: arrows move and pick.
|
|
39
|
+
function pick(option: SegmentedControlOption<T>) {
|
|
40
|
+
if (disabled || option.disabled || option.value === value) return;
|
|
41
|
+
value = option.value;
|
|
42
|
+
onchange?.(option.value);
|
|
43
|
+
}
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<div
|
|
47
|
+
bind:this={ref}
|
|
48
|
+
{...rest}
|
|
49
|
+
role="radiogroup"
|
|
50
|
+
class={['sv-segmented', sharedClasses(p, 'SegmentedControl'), className]}
|
|
51
|
+
style:--sv-segments={options.length}
|
|
52
|
+
style:--sv-segment={index}
|
|
53
|
+
{@attach rovingFocus({ orientation: 'horizontal' })}
|
|
54
|
+
>
|
|
55
|
+
{#if index >= 0}<span class="sv-segmented__thumb" aria-hidden="true"></span>{/if}
|
|
56
|
+
{#each options as option (option.value)}
|
|
57
|
+
<button
|
|
58
|
+
type="button"
|
|
59
|
+
role="radio"
|
|
60
|
+
class="sv-segmented__option"
|
|
61
|
+
data-sv-item
|
|
62
|
+
aria-checked={option.value === value}
|
|
63
|
+
disabled={disabled || option.disabled}
|
|
64
|
+
onclick={() => pick(option)}
|
|
65
|
+
onfocus={() => pick(option)}
|
|
66
|
+
>
|
|
67
|
+
{option.label}
|
|
68
|
+
</button>
|
|
69
|
+
{/each}
|
|
70
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SegmentedControlProps } from './types.js';
|
|
2
|
+
declare function $$render<T extends string | number>(): {
|
|
3
|
+
props: SegmentedControlProps<T>;
|
|
4
|
+
exports: {};
|
|
5
|
+
bindings: "ref" | "value";
|
|
6
|
+
slots: {};
|
|
7
|
+
events: {};
|
|
8
|
+
};
|
|
9
|
+
declare class __sveltets_Render<T extends string | number> {
|
|
10
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
11
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
12
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
13
|
+
bindings(): "ref" | "value";
|
|
14
|
+
exports(): {};
|
|
15
|
+
}
|
|
16
|
+
interface $$IsomorphicComponent {
|
|
17
|
+
new <T extends string | number>(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']>> & {
|
|
18
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
19
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
20
|
+
<T extends string | number>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
21
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
22
|
+
}
|
|
23
|
+
declare const SegmentedControl: $$IsomorphicComponent;
|
|
24
|
+
type SegmentedControl<T extends string | number> = InstanceType<typeof SegmentedControl<T>>;
|
|
25
|
+
export default SegmentedControl;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as SegmentedControl } from './SegmentedControl.svelte';
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
@layer sv.tokens, sv.base, sv.components, sv.utilities;
|
|
2
|
+
|
|
3
|
+
@layer sv.components {
|
|
4
|
+
/*
|
|
5
|
+
* Segments share the width of the widest, so the thumb moves one segment per step with
|
|
6
|
+
* translate alone. The selected segment is painted by the variant classes.
|
|
7
|
+
*/
|
|
8
|
+
.sv-segmented {
|
|
9
|
+
--sv-segmented-pad: var(--sv-space-3);
|
|
10
|
+
position: relative;
|
|
11
|
+
isolation: isolate;
|
|
12
|
+
display: inline-grid;
|
|
13
|
+
grid-auto-columns: 1fr;
|
|
14
|
+
grid-auto-flow: column;
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
max-inline-size: 100%;
|
|
17
|
+
block-size: calc(var(--sv-size-height) * var(--sv-density));
|
|
18
|
+
padding: var(--sv-segmented-pad);
|
|
19
|
+
border-radius: var(--sv-rounded, var(--sv-radius-md));
|
|
20
|
+
background-color: var(--sv-color-surface-raised);
|
|
21
|
+
vertical-align: middle;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.sv-segmented__thumb {
|
|
25
|
+
position: absolute;
|
|
26
|
+
inset-block: var(--sv-segmented-pad);
|
|
27
|
+
inset-inline-start: var(--sv-segmented-pad);
|
|
28
|
+
z-index: -1;
|
|
29
|
+
inline-size: calc((100% - 2 * var(--sv-segmented-pad)) / var(--sv-segments));
|
|
30
|
+
border: var(--sv-hairline) solid var(--sv-variant-border);
|
|
31
|
+
border-radius: calc(var(--sv-rounded, var(--sv-radius-md)) - var(--sv-segmented-pad));
|
|
32
|
+
box-sizing: border-box;
|
|
33
|
+
background-color: var(--sv-variant-bg);
|
|
34
|
+
box-shadow: var(--sv-variant-shadow);
|
|
35
|
+
translate: calc(var(--sv-segment) * 100%) 0;
|
|
36
|
+
transition: translate var(--sv-duration-normal) var(--sv-ease);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* An attribute selector, as minifiers rewrite :dir() into language guesses. */
|
|
40
|
+
:where([dir='rtl']) .sv-segmented__thumb {
|
|
41
|
+
translate: calc(var(--sv-segment) * -100%) 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.sv-segmented__option {
|
|
45
|
+
min-inline-size: 0;
|
|
46
|
+
margin: 0;
|
|
47
|
+
padding: 0 calc(var(--sv-size-height) * var(--sv-density) * 0.382);
|
|
48
|
+
overflow: hidden;
|
|
49
|
+
border: 0;
|
|
50
|
+
border-radius: calc(var(--sv-rounded, var(--sv-radius-md)) - var(--sv-segmented-pad));
|
|
51
|
+
background: transparent;
|
|
52
|
+
color: var(--sv-color-text-muted);
|
|
53
|
+
font: var(--sv-weight-medium) var(--sv-size-text) / 1 var(--sv-font-ui);
|
|
54
|
+
text-overflow: ellipsis;
|
|
55
|
+
white-space: nowrap;
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
-webkit-tap-highlight-color: transparent;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.sv-segmented__option[aria-checked='true'] {
|
|
61
|
+
color: var(--sv-variant-fg);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.sv-segmented__option:disabled {
|
|
65
|
+
opacity: 0.382;
|
|
66
|
+
cursor: not-allowed;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { ElementProps } from '../../core/props/element.js';
|
|
3
|
+
import type { Color, Density, Rounded, Size, Variant } from '../../core/props/types.js';
|
|
4
|
+
/** The SegmentedControl props that `DefaultsProvider` and `UIProvider` can set for a subtree. */
|
|
5
|
+
export interface SegmentedControlDefaults {
|
|
6
|
+
/**
|
|
7
|
+
* How the selected segment is painted: a raised surface by default.
|
|
8
|
+
* @default 'elevated'
|
|
9
|
+
*/
|
|
10
|
+
variant: Variant;
|
|
11
|
+
/**
|
|
12
|
+
* The colour of the selected segment.
|
|
13
|
+
* @default 'neutral'
|
|
14
|
+
*/
|
|
15
|
+
color: Color;
|
|
16
|
+
/**
|
|
17
|
+
* Height and text size.
|
|
18
|
+
* @default 'md'
|
|
19
|
+
*/
|
|
20
|
+
size: Size;
|
|
21
|
+
/**
|
|
22
|
+
* Multiplies the height and padding, never the text.
|
|
23
|
+
* @default 'default'
|
|
24
|
+
*/
|
|
25
|
+
density: Density;
|
|
26
|
+
/**
|
|
27
|
+
* Corner rounding. `true` keeps the theme's radius.
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
rounded: Rounded;
|
|
31
|
+
}
|
|
32
|
+
declare module '../../core/defaults/context.js' {
|
|
33
|
+
interface ComponentDefaults {
|
|
34
|
+
SegmentedControl: SegmentedControlDefaults;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** One choice of a SegmentedControl. */
|
|
38
|
+
export interface SegmentedControlOption<T extends string | number = string> {
|
|
39
|
+
value: T;
|
|
40
|
+
/** What the segment says. */
|
|
41
|
+
label: string;
|
|
42
|
+
disabled?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* One choice among a few options, side by side, as a radio group with one tab stop. Name it
|
|
46
|
+
* with `aria-label`.
|
|
47
|
+
*/
|
|
48
|
+
export type SegmentedControlProps<T extends string | number = string> = ElementProps<HTMLDivElement, HTMLAttributes<HTMLDivElement>, Partial<SegmentedControlDefaults> & {
|
|
49
|
+
/** The choices, in order. */
|
|
50
|
+
options: readonly SegmentedControlOption<T>[];
|
|
51
|
+
/** The chosen value. Bindable. */
|
|
52
|
+
value?: T;
|
|
53
|
+
/** Called with the value the user picks. */
|
|
54
|
+
onchange?: (value: T) => void;
|
|
55
|
+
/**
|
|
56
|
+
* Disables every option.
|
|
57
|
+
* @default false
|
|
58
|
+
*/
|
|
59
|
+
disabled?: boolean;
|
|
60
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// A loading placeholder. See SkeletonProps for the props.
|
|
3
|
+
import { sharedClasses } from '../../core/props/classes.js';
|
|
4
|
+
import './skeleton.css';
|
|
5
|
+
import type { SkeletonProps } from './types.js';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
type = 'text',
|
|
9
|
+
lines = 1,
|
|
10
|
+
size = 'md',
|
|
11
|
+
class: className,
|
|
12
|
+
ref = $bindable(null),
|
|
13
|
+
...rest
|
|
14
|
+
}: SkeletonProps = $props();
|
|
15
|
+
|
|
16
|
+
const count = $derived(Math.max(1, Math.trunc(lines) || 1));
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<span
|
|
20
|
+
bind:this={ref}
|
|
21
|
+
{...rest}
|
|
22
|
+
aria-hidden="true"
|
|
23
|
+
class={[
|
|
24
|
+
'sv-skeleton',
|
|
25
|
+
`sv-skeleton--${type}`,
|
|
26
|
+
type === 'circle' && sharedClasses({ size }, 'Skeleton'),
|
|
27
|
+
className
|
|
28
|
+
]}
|
|
29
|
+
>
|
|
30
|
+
{#if type === 'text'}
|
|
31
|
+
{#each { length: count }, line (line)}<span class="sv-skeleton__line"></span>{/each}
|
|
32
|
+
{/if}
|
|
33
|
+
</span>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Skeleton } from './Skeleton.svelte';
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
@layer sv.tokens, sv.base, sv.components, sv.utilities;
|
|
2
|
+
|
|
3
|
+
@layer sv.components {
|
|
4
|
+
.sv-skeleton,
|
|
5
|
+
.sv-skeleton__line {
|
|
6
|
+
position: relative;
|
|
7
|
+
display: block;
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
border-radius: var(--sv-radius-sm);
|
|
10
|
+
background-color: var(--sv-color-surface-raised);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* Lines as tall as the text around them, a φ⁻¹ gap apart. */
|
|
14
|
+
.sv-skeleton--text {
|
|
15
|
+
display: grid;
|
|
16
|
+
gap: 0.618em;
|
|
17
|
+
overflow: visible;
|
|
18
|
+
background-color: transparent;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.sv-skeleton__line {
|
|
22
|
+
block-size: 1em;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.sv-skeleton__line:last-child:not(:first-child) {
|
|
26
|
+
inline-size: 61.8%;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.sv-skeleton--rect {
|
|
30
|
+
inline-size: 100%;
|
|
31
|
+
aspect-ratio: 1.618;
|
|
32
|
+
/* The control radius, never rounder than a card, even where controls are pills. */
|
|
33
|
+
border-radius: min(var(--sv-radius-md), var(--sv-radius-lg));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.sv-skeleton--circle {
|
|
37
|
+
inline-size: var(--sv-size-height);
|
|
38
|
+
block-size: var(--sv-size-height);
|
|
39
|
+
border-radius: 50%;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* A highlight sweeps across: transform only, and none under reduced motion. */
|
|
43
|
+
.sv-skeleton:not(.sv-skeleton--text)::after,
|
|
44
|
+
.sv-skeleton__line::after {
|
|
45
|
+
content: '';
|
|
46
|
+
position: absolute;
|
|
47
|
+
inset: 0;
|
|
48
|
+
background: linear-gradient(
|
|
49
|
+
90deg,
|
|
50
|
+
transparent,
|
|
51
|
+
color-mix(in oklch, var(--sv-color-surface) 61.8%, transparent),
|
|
52
|
+
transparent
|
|
53
|
+
);
|
|
54
|
+
transform: translateX(-100%);
|
|
55
|
+
animation: sv-skeleton-sweep 1618ms var(--sv-ease) infinite;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@media (prefers-reduced-motion: reduce) {
|
|
59
|
+
.sv-skeleton::after,
|
|
60
|
+
.sv-skeleton__line::after {
|
|
61
|
+
display: none;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@keyframes sv-skeleton-sweep {
|
|
66
|
+
to {
|
|
67
|
+
transform: translateX(100%);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { ElementProps } from '../../core/props/element.js';
|
|
3
|
+
import type { Size } from '../../core/props/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* A placeholder in the shape of content that is still loading. Hidden from assistive
|
|
6
|
+
* technology: mark the region that is loading with `aria-busy="true"` instead.
|
|
7
|
+
*/
|
|
8
|
+
export type SkeletonProps = ElementProps<HTMLSpanElement, HTMLAttributes<HTMLSpanElement>, {
|
|
9
|
+
/**
|
|
10
|
+
* Lines of text, a golden rectangle that fills the width (an image, a chart), or a circle
|
|
11
|
+
* (an avatar).
|
|
12
|
+
* @default 'text'
|
|
13
|
+
*/
|
|
14
|
+
type?: 'text' | 'rect' | 'circle';
|
|
15
|
+
/**
|
|
16
|
+
* Lines of text; the last of several is φ⁻¹ as wide.
|
|
17
|
+
* @default 1
|
|
18
|
+
*/
|
|
19
|
+
lines?: number;
|
|
20
|
+
/**
|
|
21
|
+
* The diameter of a circle: the control height of the size.
|
|
22
|
+
* @default 'md'
|
|
23
|
+
*/
|
|
24
|
+
size?: Size;
|
|
25
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// A number picked along a track, with its label, its value and validation. See SliderProps.
|
|
3
|
+
import { untrack } from 'svelte';
|
|
4
|
+
import { DEV, warnUnnamed } from '#dev';
|
|
5
|
+
import { useDefaults } from '../../core/defaults/context.js';
|
|
6
|
+
import { createField } from '../../core/form/field.svelte.js';
|
|
7
|
+
import { useLocale } from '../../core/locale/locale.js';
|
|
8
|
+
import { sharedClasses } from '../../core/props/classes.js';
|
|
9
|
+
import './slider.css';
|
|
10
|
+
import type { SliderDefaults, SliderProps } from './types.js';
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
color,
|
|
14
|
+
size,
|
|
15
|
+
density,
|
|
16
|
+
disabled,
|
|
17
|
+
value = $bindable(),
|
|
18
|
+
min = 0,
|
|
19
|
+
max = 100,
|
|
20
|
+
step = 1,
|
|
21
|
+
ticks,
|
|
22
|
+
format,
|
|
23
|
+
label,
|
|
24
|
+
hint,
|
|
25
|
+
error,
|
|
26
|
+
rules,
|
|
27
|
+
validateOn,
|
|
28
|
+
id: idProp,
|
|
29
|
+
'aria-describedby': describedBy,
|
|
30
|
+
class: className,
|
|
31
|
+
style,
|
|
32
|
+
ref = $bindable(null),
|
|
33
|
+
...rest
|
|
34
|
+
}: SliderProps = $props();
|
|
35
|
+
|
|
36
|
+
const uid = $props.id();
|
|
37
|
+
const id = $derived(idProp ?? uid);
|
|
38
|
+
const resolve = useDefaults<SliderDefaults>('Slider', {
|
|
39
|
+
color: 'primary',
|
|
40
|
+
size: 'md',
|
|
41
|
+
density: 'default',
|
|
42
|
+
disabled: false
|
|
43
|
+
});
|
|
44
|
+
const p = $derived(resolve({ color, size, density, disabled }));
|
|
45
|
+
const locale = useLocale();
|
|
46
|
+
|
|
47
|
+
const current = $derived(value ?? min);
|
|
48
|
+
// A form reset goes back to the value the slider started at.
|
|
49
|
+
const initial = untrack(() => value ?? min);
|
|
50
|
+
// Where a value sits along the track, from 0 to 1.
|
|
51
|
+
const along = (at: number) =>
|
|
52
|
+
max > min ? Math.min(1, Math.max(0, (at - min) / (max - min))) : 0;
|
|
53
|
+
|
|
54
|
+
// Steps in decimals add up with float errors (0.1 + 0.2), so tick values are rounded to the
|
|
55
|
+
// decimals of min and step, the same values the input stops at.
|
|
56
|
+
const decimals = (at: number) => `${at}`.split('.')[1]?.length ?? 0;
|
|
57
|
+
const marks = $derived.by((): Array<{ value: number; label?: string }> => {
|
|
58
|
+
if (!ticks) return [];
|
|
59
|
+
if (ticks !== true) {
|
|
60
|
+
return ticks.map((tick) => (typeof tick === 'number' ? { value: tick } : tick));
|
|
61
|
+
}
|
|
62
|
+
if (!(step > 0) || max <= min) return [];
|
|
63
|
+
const places = Math.max(decimals(min), decimals(step));
|
|
64
|
+
const count = Math.floor((max - min) / step + 1e-9);
|
|
65
|
+
return Array.from({ length: count + 1 }, (_, index) => ({
|
|
66
|
+
value: Number((min + index * step).toFixed(places))
|
|
67
|
+
}));
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const tickLabel = $derived(marks.find((mark) => mark.value === current && mark.label)?.label);
|
|
71
|
+
const text = $derived(format?.(current) ?? tickLabel ?? locale.formatNumber(current));
|
|
72
|
+
|
|
73
|
+
const field = createField<number>({
|
|
74
|
+
value: () => current,
|
|
75
|
+
// A range always holds a value; the browser keeps it between min and max, on a step.
|
|
76
|
+
empty: () => false,
|
|
77
|
+
check: () => undefined,
|
|
78
|
+
rules: () => rules,
|
|
79
|
+
error: () => error,
|
|
80
|
+
validateOn: () => validateOn,
|
|
81
|
+
control: () => ref
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const message = $derived(typeof field.error === 'string' ? field.error : undefined);
|
|
85
|
+
|
|
86
|
+
if (DEV) $effect(() => warnUnnamed('Slider', ref));
|
|
87
|
+
|
|
88
|
+
// Letting go of the thumb, or a key step, finishes an edit, so it also counts as leaving.
|
|
89
|
+
function committed() {
|
|
90
|
+
field.changed();
|
|
91
|
+
field.left();
|
|
92
|
+
}
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
<div
|
|
96
|
+
class={[
|
|
97
|
+
'sv-slider',
|
|
98
|
+
sharedClasses(p, 'Slider'),
|
|
99
|
+
field.error !== false && 'sv-slider--invalid',
|
|
100
|
+
p.disabled && 'sv-slider--disabled',
|
|
101
|
+
className
|
|
102
|
+
]}
|
|
103
|
+
{style}
|
|
104
|
+
style:--sv-slider-fraction={along(current)}
|
|
105
|
+
oninput={field.changed}
|
|
106
|
+
onchange={committed}
|
|
107
|
+
>
|
|
108
|
+
{#if label}
|
|
109
|
+
<div class="sv-slider__header">
|
|
110
|
+
<label class="sv-slider__label" for={id}>{label}</label>
|
|
111
|
+
<!-- Shown for sight; screen readers hear the slider's own value. -->
|
|
112
|
+
<span class="sv-slider__value" aria-hidden="true">{text}</span>
|
|
113
|
+
</div>
|
|
114
|
+
{/if}
|
|
115
|
+
<input
|
|
116
|
+
bind:this={ref}
|
|
117
|
+
defaultValue={initial}
|
|
118
|
+
{...rest}
|
|
119
|
+
{id}
|
|
120
|
+
type="range"
|
|
121
|
+
class="sv-slider__input"
|
|
122
|
+
{min}
|
|
123
|
+
{max}
|
|
124
|
+
{step}
|
|
125
|
+
disabled={p.disabled}
|
|
126
|
+
aria-describedby={[describedBy, message ? `${id}-error` : hint ? `${id}-hint` : undefined]
|
|
127
|
+
.filter(Boolean)
|
|
128
|
+
.join(' ') || undefined}
|
|
129
|
+
aria-invalid={field.error !== false || undefined}
|
|
130
|
+
aria-valuetext={format || tickLabel ? text : undefined}
|
|
131
|
+
bind:value={() => current, (next: number) => (value = next)}
|
|
132
|
+
/>
|
|
133
|
+
{#if marks.length}
|
|
134
|
+
<div class="sv-slider__ticks" aria-hidden="true">
|
|
135
|
+
{#each marks as mark (mark.value)}
|
|
136
|
+
<span
|
|
137
|
+
class={[
|
|
138
|
+
'sv-slider__tick',
|
|
139
|
+
mark.value <= min && 'sv-slider__tick--start',
|
|
140
|
+
mark.value >= max && 'sv-slider__tick--end'
|
|
141
|
+
]}
|
|
142
|
+
style:--sv-slider-at={along(mark.value)}
|
|
143
|
+
>{#if mark.label}<span class="sv-slider__tick-label">{mark.label}</span>{/if}</span
|
|
144
|
+
>
|
|
145
|
+
{/each}
|
|
146
|
+
</div>
|
|
147
|
+
{/if}
|
|
148
|
+
{#if hint && !message}<p class="sv-slider__hint" id="{id}-hint">{hint}</p>{/if}
|
|
149
|
+
<!-- Announces an error that appears after the user has moved on. -->
|
|
150
|
+
<div aria-live="polite">
|
|
151
|
+
{#if message}<p class="sv-slider__error" id="{id}-error">{message}</p>{/if}
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Slider } from './Slider.svelte';
|