@sveltier/ui 0.0.0-stage → 0.1.0-alpha.1
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/Accordion/Accordion.svelte +74 -0
- package/dist/components/Accordion/Accordion.svelte.d.ts +25 -0
- package/dist/components/Accordion/accordion.css +88 -0
- package/dist/components/Accordion/index.d.ts +2 -0
- package/dist/components/Accordion/index.js +1 -0
- package/dist/components/Accordion/types.d.ts +64 -0
- package/dist/components/Accordion/types.js +1 -0
- 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/Dialog/Dialog.svelte +36 -0
- package/dist/components/Dialog/Dialog.svelte.d.ts +4 -0
- package/dist/components/Dialog/index.d.ts +2 -0
- package/dist/components/Dialog/index.js +1 -0
- package/dist/components/Dialog/types.d.ts +50 -0
- package/dist/components/Dialog/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/Menu/Menu.svelte +195 -0
- package/dist/components/Menu/Menu.svelte.d.ts +4 -0
- package/dist/components/Menu/index.d.ts +2 -0
- package/dist/components/Menu/index.js +1 -0
- package/dist/components/Menu/menu.css +103 -0
- package/dist/components/Menu/types.d.ts +90 -0
- package/dist/components/Menu/types.js +1 -0
- package/dist/components/Modal/Modal.svelte +146 -0
- package/dist/components/Modal/Modal.svelte.d.ts +4 -0
- package/dist/components/Modal/modal.css +150 -0
- package/dist/components/Modal/types.d.ts +54 -0
- package/dist/components/Modal/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/Popover/Popover.svelte +115 -0
- package/dist/components/Popover/Popover.svelte.d.ts +4 -0
- package/dist/components/Popover/index.d.ts +2 -0
- package/dist/components/Popover/index.js +1 -0
- package/dist/components/Popover/popover.css +67 -0
- package/dist/components/Popover/types.d.ts +83 -0
- package/dist/components/Popover/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/Sheet/Sheet.svelte +56 -0
- package/dist/components/Sheet/Sheet.svelte.d.ts +4 -0
- package/dist/components/Sheet/index.d.ts +2 -0
- package/dist/components/Sheet/index.js +2 -0
- package/dist/components/Sheet/sheet.css +61 -0
- package/dist/components/Sheet/types.d.ts +51 -0
- package/dist/components/Sheet/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/components/Tooltip/Tooltip.svelte +161 -0
- package/dist/components/Tooltip/Tooltip.svelte.d.ts +4 -0
- package/dist/components/Tooltip/index.d.ts +2 -0
- package/dist/components/Tooltip/index.js +1 -0
- package/dist/components/Tooltip/tooltip.css +44 -0
- package/dist/components/Tooltip/types.d.ts +55 -0
- package/dist/components/Tooltip/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 +124 -0
- package/dist/core/errors/codes.js +108 -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 +56 -0
- package/dist/core/locale/locale.js +82 -0
- package/dist/core/overlay/types.d.ts +33 -0
- package/dist/core/overlay/types.js +1 -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 +63 -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 +73 -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/core/toast/ToastOutlet.svelte +192 -0
- package/dist/core/toast/ToastOutlet.svelte.d.ts +11 -0
- package/dist/core/toast/ToastProvider.svelte +39 -0
- package/dist/core/toast/ToastProvider.svelte.d.ts +19 -0
- package/dist/core/toast/toast.css +134 -0
- package/dist/core/toast/toast.svelte.d.ts +117 -0
- package/dist/core/toast/toast.svelte.js +133 -0
- package/dist/dev/off.d.ts +5 -0
- package/dist/dev/off.js +4 -0
- package/dist/dev/on.d.ts +20 -0
- package/dist/dev/on.js +49 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.js +83 -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 +32 -0
- package/dist/primitives/layer/dismissable.js +91 -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 +140 -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,118 @@
|
|
|
1
|
+
@layer sv.tokens, sv.base, sv.components, sv.utilities;
|
|
2
|
+
|
|
3
|
+
@layer sv.components {
|
|
4
|
+
/*
|
|
5
|
+
* A track as tall as a line of the label and φ times as wide, with the theme's round radius
|
|
6
|
+
* (square in a square theme). The thumb travels the difference.
|
|
7
|
+
*/
|
|
8
|
+
.sv-switch {
|
|
9
|
+
--sv-switch-block: 1.272em;
|
|
10
|
+
--sv-switch-inline: calc(var(--sv-switch-block) * 1.618);
|
|
11
|
+
--sv-switch-pad: calc(var(--sv-switch-block) * 0.146);
|
|
12
|
+
--sv-switch-travel: calc(var(--sv-switch-inline) - var(--sv-switch-block));
|
|
13
|
+
--sv-choice-control: var(--sv-switch-inline);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/*
|
|
17
|
+
* The native input lies over the drawn track, invisible, so focus, keys and forms stay native.
|
|
18
|
+
* The track sits on the first line of the label.
|
|
19
|
+
*/
|
|
20
|
+
.sv-switch__control {
|
|
21
|
+
position: relative;
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
flex: none;
|
|
24
|
+
margin-block-start: calc((1lh - var(--sv-switch-block)) / 2);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.sv-switch__input {
|
|
28
|
+
position: absolute;
|
|
29
|
+
inset: 0;
|
|
30
|
+
inline-size: 100%;
|
|
31
|
+
block-size: 100%;
|
|
32
|
+
margin: 0;
|
|
33
|
+
opacity: 0;
|
|
34
|
+
cursor: inherit;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* Transparent borders turn visible in forced colours, where backgrounds are dropped. */
|
|
38
|
+
.sv-switch__track {
|
|
39
|
+
position: relative;
|
|
40
|
+
box-sizing: border-box;
|
|
41
|
+
inline-size: var(--sv-switch-inline);
|
|
42
|
+
block-size: var(--sv-switch-block);
|
|
43
|
+
border: var(--sv-hairline) solid transparent;
|
|
44
|
+
border-radius: var(--sv-radius-full);
|
|
45
|
+
background-color: var(--sv-color-border-strong);
|
|
46
|
+
pointer-events: none;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* The fill (before) fades in under the thumb; the state layer (after) sits over both. */
|
|
50
|
+
.sv-switch__track::before,
|
|
51
|
+
.sv-switch__track::after {
|
|
52
|
+
content: '';
|
|
53
|
+
position: absolute;
|
|
54
|
+
inset: calc(var(--sv-hairline) * -1);
|
|
55
|
+
border-radius: inherit;
|
|
56
|
+
opacity: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.sv-switch__track::before {
|
|
60
|
+
background-color: var(--sv-color);
|
|
61
|
+
transition: opacity var(--sv-duration-fast) var(--sv-ease);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.sv-switch__track::after {
|
|
65
|
+
background-color: var(--sv-color-text);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.sv-switch__thumb {
|
|
69
|
+
position: absolute;
|
|
70
|
+
inset-block-start: calc(var(--sv-switch-pad) - var(--sv-hairline));
|
|
71
|
+
inset-inline-start: calc(var(--sv-switch-pad) - var(--sv-hairline));
|
|
72
|
+
box-sizing: border-box;
|
|
73
|
+
inline-size: calc(var(--sv-switch-block) - 2 * var(--sv-switch-pad));
|
|
74
|
+
block-size: calc(var(--sv-switch-block) - 2 * var(--sv-switch-pad));
|
|
75
|
+
border: var(--sv-hairline) solid transparent;
|
|
76
|
+
border-radius: var(--sv-radius-full);
|
|
77
|
+
background-color: var(--sv-color-surface);
|
|
78
|
+
transition: translate var(--sv-duration-fast) var(--sv-ease);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.sv-switch__input:checked + .sv-switch__track::before {
|
|
82
|
+
opacity: 1;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.sv-switch__input:checked + .sv-switch__track::after {
|
|
86
|
+
background-color: var(--sv-on-color);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.sv-switch__input:checked + .sv-switch__track .sv-switch__thumb {
|
|
90
|
+
translate: var(--sv-switch-travel) 0;
|
|
91
|
+
background-color: var(--sv-on-color);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* An attribute selector, as minifiers rewrite :dir() into language guesses. */
|
|
95
|
+
:where([dir='rtl']) .sv-switch__input:checked + .sv-switch__track .sv-switch__thumb {
|
|
96
|
+
translate: calc(var(--sv-switch-travel) * -1) 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Hover and press mix a layer over the track. The disabled guard adds no weight. */
|
|
100
|
+
@media (hover: hover) {
|
|
101
|
+
:where(.sv-switch:not(.sv-choice--disabled)) > .sv-choice__row:hover .sv-switch__track::after {
|
|
102
|
+
opacity: var(--sv-state-hover);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
:where(.sv-switch:not(.sv-choice--disabled)) > .sv-choice__row:active .sv-switch__track::after {
|
|
107
|
+
opacity: var(--sv-state-press);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.sv-switch__input:focus-visible + .sv-switch__track {
|
|
111
|
+
outline: var(--sv-focus-width) solid var(--sv-color);
|
|
112
|
+
outline-offset: var(--sv-focus-offset);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.sv-choice--invalid > .sv-choice__row .sv-switch__track {
|
|
116
|
+
background-color: var(--sv-color-error);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
+
import type { 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
|
+
import type { ChoiceContentProps } from '../Choice/types.js';
|
|
6
|
+
/** The Switch props that `DefaultsProvider` and `UIProvider` can set for a subtree. */
|
|
7
|
+
export interface SwitchDefaults {
|
|
8
|
+
/**
|
|
9
|
+
* The colour of the track while on. An invalid switch uses `error`.
|
|
10
|
+
* @default 'primary'
|
|
11
|
+
*/
|
|
12
|
+
color: Color;
|
|
13
|
+
/**
|
|
14
|
+
* The size of the switch and the label text.
|
|
15
|
+
* @default 'md'
|
|
16
|
+
*/
|
|
17
|
+
size: Size;
|
|
18
|
+
/**
|
|
19
|
+
* Multiplies the height of the row, never the text.
|
|
20
|
+
* @default 'default'
|
|
21
|
+
*/
|
|
22
|
+
density: Density;
|
|
23
|
+
/**
|
|
24
|
+
* Mutes the switch and disables its input.
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
disabled: boolean;
|
|
28
|
+
}
|
|
29
|
+
declare module '../../core/defaults/context.js' {
|
|
30
|
+
interface ComponentDefaults {
|
|
31
|
+
Switch: SwitchDefaults;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
type SwitchOwnProps = Partial<SwitchDefaults> & ChoiceContentProps & {
|
|
35
|
+
/**
|
|
36
|
+
* Whether the switch is on. Bindable.
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
checked?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* What the form submits under `name` while the switch is on.
|
|
42
|
+
* @default 'on'
|
|
43
|
+
*/
|
|
44
|
+
value?: string;
|
|
45
|
+
/** Checks run in order after `required`, with the on state. The first message is shown. */
|
|
46
|
+
rules?: readonly Rule<boolean>[];
|
|
47
|
+
/** When the message shows. Defaults to the form's setting, else `'blur'`. */
|
|
48
|
+
validateOn?: ValidateOn;
|
|
49
|
+
/**
|
|
50
|
+
* The switch must be on. Adds an asterisk to the label.
|
|
51
|
+
* @default false
|
|
52
|
+
*/
|
|
53
|
+
required?: boolean;
|
|
54
|
+
/** Inline style of the switch's root element. */
|
|
55
|
+
style?: string | null;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* A setting that is on or off, with its label beside it: a native checkbox with
|
|
59
|
+
* `role="switch"`, drawn as a track and a thumb. `class` and `style` apply to the root; `id`,
|
|
60
|
+
* `ref`, `name` and every other attribute go to the `<input>`. Use it for a setting that takes
|
|
61
|
+
* effect at once; for a choice submitted with a form, use a Checkbox.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* <Switch label="Sign in with biometrics" bind:checked={biometrics} />
|
|
65
|
+
*/
|
|
66
|
+
export type SwitchProps = ElementProps<HTMLInputElement, Omit<HTMLInputAttributes, 'type' | 'role' | 'children'>, SwitchOwnProps>;
|
|
67
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<script lang="ts" generics="T extends string | number">
|
|
2
|
+
// Tabs and the selected tab's panel. See TabsProps 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 './tabs.css';
|
|
7
|
+
import type { TabsDefaults, TabsItem, TabsProps } from './types.js';
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
color,
|
|
11
|
+
size,
|
|
12
|
+
density,
|
|
13
|
+
grow,
|
|
14
|
+
items,
|
|
15
|
+
value = $bindable(),
|
|
16
|
+
onchange,
|
|
17
|
+
activation = 'automatic',
|
|
18
|
+
panel,
|
|
19
|
+
id,
|
|
20
|
+
'aria-label': ariaLabel,
|
|
21
|
+
'aria-labelledby': ariaLabelledby,
|
|
22
|
+
class: className,
|
|
23
|
+
ref = $bindable(null),
|
|
24
|
+
...rest
|
|
25
|
+
}: TabsProps<T> = $props();
|
|
26
|
+
|
|
27
|
+
const resolve = useDefaults<TabsDefaults>('Tabs', {
|
|
28
|
+
color: 'primary',
|
|
29
|
+
size: 'md',
|
|
30
|
+
density: 'default',
|
|
31
|
+
grow: false
|
|
32
|
+
});
|
|
33
|
+
const p = $derived(resolve({ color, size, density, grow }));
|
|
34
|
+
const base = $props.id();
|
|
35
|
+
const prefix = $derived(id ?? base);
|
|
36
|
+
|
|
37
|
+
// Without a value, the first tab that can be chosen.
|
|
38
|
+
const index = $derived.by(() => {
|
|
39
|
+
const chosen = items.findIndex((item) => item.value === value);
|
|
40
|
+
return chosen >= 0 ? chosen : items.findIndex((item) => !item.disabled);
|
|
41
|
+
});
|
|
42
|
+
const selected = $derived(items[index]);
|
|
43
|
+
|
|
44
|
+
function select(item: TabsItem<T>) {
|
|
45
|
+
if (item.disabled || item.value === selected?.value) return;
|
|
46
|
+
value = item.value;
|
|
47
|
+
onchange?.(item.value);
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<div
|
|
52
|
+
bind:this={ref}
|
|
53
|
+
{...rest}
|
|
54
|
+
id={prefix}
|
|
55
|
+
class={['sv-tabs', sharedClasses(p, 'Tabs'), p.grow && 'sv-tabs--grow', className]}
|
|
56
|
+
>
|
|
57
|
+
<div
|
|
58
|
+
role="tablist"
|
|
59
|
+
aria-label={ariaLabel}
|
|
60
|
+
aria-labelledby={ariaLabelledby}
|
|
61
|
+
class="sv-tabs__list"
|
|
62
|
+
{@attach rovingFocus({ orientation: 'horizontal' })}
|
|
63
|
+
>
|
|
64
|
+
{#each items as item, i (item.value)}
|
|
65
|
+
<button
|
|
66
|
+
type="button"
|
|
67
|
+
role="tab"
|
|
68
|
+
id="{prefix}-tab-{i}"
|
|
69
|
+
class="sv-tabs__tab"
|
|
70
|
+
data-sv-item
|
|
71
|
+
aria-selected={i === index}
|
|
72
|
+
aria-controls={i === index && panel ? `${prefix}-panel` : undefined}
|
|
73
|
+
disabled={item.disabled}
|
|
74
|
+
onclick={() => select(item)}
|
|
75
|
+
onfocus={() => activation === 'automatic' && select(item)}
|
|
76
|
+
>
|
|
77
|
+
{item.label}
|
|
78
|
+
</button>
|
|
79
|
+
{/each}
|
|
80
|
+
</div>
|
|
81
|
+
{#if panel && selected}
|
|
82
|
+
<!-- Focusable, so keyboard users reach a panel with nothing focusable in it (APG). -->
|
|
83
|
+
<div
|
|
84
|
+
role="tabpanel"
|
|
85
|
+
id="{prefix}-panel"
|
|
86
|
+
aria-labelledby="{prefix}-tab-{index}"
|
|
87
|
+
tabindex="0"
|
|
88
|
+
class="sv-tabs__panel"
|
|
89
|
+
>
|
|
90
|
+
{@render panel(selected)}
|
|
91
|
+
</div>
|
|
92
|
+
{/if}
|
|
93
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { TabsProps } from './types.js';
|
|
2
|
+
declare function $$render<T extends string | number>(): {
|
|
3
|
+
props: TabsProps<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 Tabs: $$IsomorphicComponent;
|
|
24
|
+
type Tabs<T extends string | number> = InstanceType<typeof Tabs<T>>;
|
|
25
|
+
export default Tabs;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Tabs } from './Tabs.svelte';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
@layer sv.tokens, sv.base, sv.components, sv.utilities;
|
|
2
|
+
|
|
3
|
+
@layer sv.components {
|
|
4
|
+
.sv-tabs {
|
|
5
|
+
display: grid;
|
|
6
|
+
gap: var(--sv-space-13);
|
|
7
|
+
min-inline-size: 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/* A row that scrolls when the tabs do not fit, over a hairline. */
|
|
11
|
+
.sv-tabs__list {
|
|
12
|
+
display: flex;
|
|
13
|
+
overflow-x: auto;
|
|
14
|
+
box-shadow: inset 0 calc(var(--sv-hairline) * -1) 0 var(--sv-color-border);
|
|
15
|
+
scrollbar-width: thin;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.sv-tabs__tab {
|
|
19
|
+
position: relative;
|
|
20
|
+
flex: none;
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
block-size: calc(var(--sv-size-height) * var(--sv-density));
|
|
23
|
+
margin: 0;
|
|
24
|
+
padding: 0 calc(var(--sv-size-height) * var(--sv-density) * 0.382);
|
|
25
|
+
border: 0;
|
|
26
|
+
background: transparent;
|
|
27
|
+
color: var(--sv-color-text-muted);
|
|
28
|
+
font: var(--sv-weight-medium) var(--sv-size-text) / 1 var(--sv-font-ui);
|
|
29
|
+
white-space: nowrap;
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
-webkit-tap-highlight-color: transparent;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.sv-tabs--grow .sv-tabs__tab {
|
|
35
|
+
flex: 1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@media (hover: hover) {
|
|
39
|
+
.sv-tabs__tab:not(:disabled):hover {
|
|
40
|
+
color: var(--sv-color-text);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.sv-tabs__tab[aria-selected='true'] {
|
|
45
|
+
color: var(--sv-color);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.sv-tabs__tab:disabled {
|
|
49
|
+
opacity: 0.382;
|
|
50
|
+
cursor: not-allowed;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* The selected tab's underline scales in: transform only. */
|
|
54
|
+
.sv-tabs__tab::after {
|
|
55
|
+
content: '';
|
|
56
|
+
position: absolute;
|
|
57
|
+
inset-inline: 0;
|
|
58
|
+
inset-block-end: 0;
|
|
59
|
+
block-size: 2px;
|
|
60
|
+
border-radius: 2px 2px 0 0;
|
|
61
|
+
background-color: var(--sv-color);
|
|
62
|
+
transform: scaleX(0);
|
|
63
|
+
transition: transform var(--sv-duration-normal) var(--sv-ease);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.sv-tabs__tab[aria-selected='true']::after {
|
|
67
|
+
transform: scaleX(1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.sv-tabs__panel {
|
|
71
|
+
min-inline-size: 0;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { ElementProps } from '../../core/props/element.js';
|
|
4
|
+
import type { Color, Density, Size } from '../../core/props/types.js';
|
|
5
|
+
/** The Tabs props that `DefaultsProvider` and `UIProvider` can set for a subtree. */
|
|
6
|
+
export interface TabsDefaults {
|
|
7
|
+
/**
|
|
8
|
+
* The colour of the selected tab and its underline.
|
|
9
|
+
* @default 'primary'
|
|
10
|
+
*/
|
|
11
|
+
color: Color;
|
|
12
|
+
/**
|
|
13
|
+
* Height and text size of the tabs.
|
|
14
|
+
* @default 'md'
|
|
15
|
+
*/
|
|
16
|
+
size: Size;
|
|
17
|
+
/**
|
|
18
|
+
* Multiplies the height and padding of the tabs, never the text.
|
|
19
|
+
* @default 'default'
|
|
20
|
+
*/
|
|
21
|
+
density: Density;
|
|
22
|
+
/**
|
|
23
|
+
* Tabs share the full width equally.
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
grow: boolean;
|
|
27
|
+
}
|
|
28
|
+
declare module '../../core/defaults/context.js' {
|
|
29
|
+
interface ComponentDefaults {
|
|
30
|
+
Tabs: TabsDefaults;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** One tab. */
|
|
34
|
+
export interface TabsItem<T extends string | number = string> {
|
|
35
|
+
value: T;
|
|
36
|
+
/** What the tab says. */
|
|
37
|
+
label: string;
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Tabs and the panel of the selected one. Name the tab list with `aria-label` or
|
|
42
|
+
* `aria-labelledby`, which go to it.
|
|
43
|
+
*/
|
|
44
|
+
export type TabsProps<T extends string | number = string> = ElementProps<HTMLDivElement, HTMLAttributes<HTMLDivElement>, Partial<TabsDefaults> & {
|
|
45
|
+
/** The tabs, in order. */
|
|
46
|
+
items: readonly TabsItem<T>[];
|
|
47
|
+
/** The selected tab. Bindable; the first enabled tab when not set. */
|
|
48
|
+
value?: T;
|
|
49
|
+
/** Called with the value of the tab the user selects. */
|
|
50
|
+
onchange?: (value: T) => void;
|
|
51
|
+
/**
|
|
52
|
+
* `automatic` selects a tab as soon as the arrow keys reach it; `manual` waits for Enter or
|
|
53
|
+
* Space, for panels that are slow to show.
|
|
54
|
+
* @default 'automatic'
|
|
55
|
+
*/
|
|
56
|
+
activation?: 'automatic' | 'manual';
|
|
57
|
+
/** The content of the selected tab's panel. */
|
|
58
|
+
panel?: Snippet<[TabsItem<T>]>;
|
|
59
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// A single line of text in a Field, with validation. See TextFieldProps for the props.
|
|
3
|
+
import { untrack } from 'svelte';
|
|
4
|
+
import { checkValue, DEV, warnUnnamed } from '#dev';
|
|
5
|
+
import { useDefaults } from '../../core/defaults/context.js';
|
|
6
|
+
import { textConstraintMessage } from '../../core/form/constraints.js';
|
|
7
|
+
import { createField } from '../../core/form/field.svelte.js';
|
|
8
|
+
import { useLocale } from '../../core/locale/locale.js';
|
|
9
|
+
import Field from '../Field/Field.svelte';
|
|
10
|
+
import { TEXT_FIELD_TYPES, type TextFieldDefaults, type TextFieldProps } from './types.js';
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
variant,
|
|
14
|
+
color,
|
|
15
|
+
size,
|
|
16
|
+
density,
|
|
17
|
+
rounded,
|
|
18
|
+
disabled,
|
|
19
|
+
value = $bindable(''),
|
|
20
|
+
type = 'text',
|
|
21
|
+
label,
|
|
22
|
+
hint,
|
|
23
|
+
error,
|
|
24
|
+
rules,
|
|
25
|
+
validateOn,
|
|
26
|
+
required = false,
|
|
27
|
+
readonly = false,
|
|
28
|
+
prepend,
|
|
29
|
+
append,
|
|
30
|
+
id,
|
|
31
|
+
'aria-describedby': describedBy,
|
|
32
|
+
class: className,
|
|
33
|
+
style,
|
|
34
|
+
ref = $bindable(null),
|
|
35
|
+
...rest
|
|
36
|
+
}: TextFieldProps = $props();
|
|
37
|
+
|
|
38
|
+
const resolve = useDefaults<TextFieldDefaults>('TextField', {
|
|
39
|
+
variant: 'outlined',
|
|
40
|
+
color: 'primary',
|
|
41
|
+
size: 'md',
|
|
42
|
+
density: 'default',
|
|
43
|
+
rounded: true,
|
|
44
|
+
disabled: false
|
|
45
|
+
});
|
|
46
|
+
const p = $derived(resolve({ variant, color, size, density, rounded, disabled }));
|
|
47
|
+
const locale = useLocale();
|
|
48
|
+
// A form reset goes back to the text the field started with, as it does for a form rendered on
|
|
49
|
+
// the server. A defaultValue of the app's own wins.
|
|
50
|
+
const initial = untrack(() => value ?? '');
|
|
51
|
+
|
|
52
|
+
const field = createField<string>({
|
|
53
|
+
value: () => value ?? '',
|
|
54
|
+
empty: (text) => text === '',
|
|
55
|
+
check: (text) =>
|
|
56
|
+
textConstraintMessage(
|
|
57
|
+
text,
|
|
58
|
+
{
|
|
59
|
+
required,
|
|
60
|
+
type,
|
|
61
|
+
minlength: rest.minlength,
|
|
62
|
+
maxlength: rest.maxlength,
|
|
63
|
+
pattern: rest.pattern
|
|
64
|
+
},
|
|
65
|
+
locale.t
|
|
66
|
+
),
|
|
67
|
+
rules: () => rules,
|
|
68
|
+
error: () => error,
|
|
69
|
+
validateOn: () => validateOn,
|
|
70
|
+
control: () => ref
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// The Field checks the variant; the input's own props are checked here, once it exists.
|
|
74
|
+
if (DEV) {
|
|
75
|
+
$effect(() => {
|
|
76
|
+
checkValue('TextField', 'type', type, TEXT_FIELD_TYPES);
|
|
77
|
+
warnUnnamed('TextField', ref);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Leaving means focus went outside the field, not to a button in it.
|
|
82
|
+
function leave(event: FocusEvent) {
|
|
83
|
+
const root = event.currentTarget as HTMLElement;
|
|
84
|
+
if (!root.contains(event.relatedTarget as Node | null)) field.left();
|
|
85
|
+
}
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
<Field
|
|
89
|
+
{...p}
|
|
90
|
+
{id}
|
|
91
|
+
{label}
|
|
92
|
+
{hint}
|
|
93
|
+
error={field.error}
|
|
94
|
+
{required}
|
|
95
|
+
{readonly}
|
|
96
|
+
{prepend}
|
|
97
|
+
{append}
|
|
98
|
+
class={className}
|
|
99
|
+
{style}
|
|
100
|
+
oninput={field.changed}
|
|
101
|
+
onfocusout={leave}
|
|
102
|
+
>
|
|
103
|
+
{#snippet children(attributes)}
|
|
104
|
+
<input
|
|
105
|
+
bind:this={ref}
|
|
106
|
+
defaultValue={initial}
|
|
107
|
+
{...rest}
|
|
108
|
+
{...attributes}
|
|
109
|
+
aria-describedby={[describedBy, attributes['aria-describedby']].filter(Boolean).join(' ') ||
|
|
110
|
+
undefined}
|
|
111
|
+
{type}
|
|
112
|
+
bind:value
|
|
113
|
+
/>
|
|
114
|
+
{/snippet}
|
|
115
|
+
</Field>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as TextField } from './TextField.svelte';
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
+
import type { Rule, ValidateOn } from '../../core/form/types.js';
|
|
3
|
+
import type { ElementProps } from '../../core/props/element.js';
|
|
4
|
+
import type { FieldContentProps, FieldDefaults } from '../Field/types.js';
|
|
5
|
+
/** The TextField props that `DefaultsProvider` and `UIProvider` can set for a subtree. */
|
|
6
|
+
export type TextFieldDefaults = FieldDefaults;
|
|
7
|
+
declare module '../../core/defaults/context.js' {
|
|
8
|
+
interface ComponentDefaults {
|
|
9
|
+
TextField: TextFieldDefaults;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export declare const TEXT_FIELD_TYPES: readonly ["text", "email", "password", "search", "tel", "url"];
|
|
13
|
+
/** The kinds of single-line text. Numbers and dates have their own fields. */
|
|
14
|
+
export type TextFieldType = (typeof TEXT_FIELD_TYPES)[number];
|
|
15
|
+
type TextFieldOwnProps = Partial<TextFieldDefaults> & FieldContentProps & {
|
|
16
|
+
/** The text. Bindable. */
|
|
17
|
+
value?: string;
|
|
18
|
+
/**
|
|
19
|
+
* The kind of text: it picks the keyboard and autofill, and `email` and `url` are checked.
|
|
20
|
+
* @default 'text'
|
|
21
|
+
*/
|
|
22
|
+
type?: TextFieldType;
|
|
23
|
+
/** Checks run in order after the HTML constraints. The first message is shown. */
|
|
24
|
+
rules?: readonly Rule<string>[];
|
|
25
|
+
/** When the message shows. Defaults to the form's setting, else `'blur'`. */
|
|
26
|
+
validateOn?: ValidateOn;
|
|
27
|
+
/**
|
|
28
|
+
* The field must not be empty. Adds an asterisk to the label.
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
required?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* The text can be read, selected and copied but not changed.
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
readonly?: boolean;
|
|
37
|
+
/** Inline style of the field's root element. */
|
|
38
|
+
style?: string | null;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* A single line of text with a label, a hint and validation. `class` and `style` apply to the
|
|
42
|
+
* field; `id`, `ref` and every other attribute (`name`, `placeholder`, `autocomplete`,
|
|
43
|
+
* `minlength`, `pattern`, events) go to the `<input>`.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* <TextField
|
|
47
|
+
* label="Username"
|
|
48
|
+
* name="username"
|
|
49
|
+
* required
|
|
50
|
+
* minlength={3}
|
|
51
|
+
* rules={[(value) => /^[a-z0-9_]+$/.test(value) || 'Use lowercase letters, digits and _']}
|
|
52
|
+
* error={form?.errors?.username}
|
|
53
|
+
* bind:value={username}
|
|
54
|
+
* />
|
|
55
|
+
*/
|
|
56
|
+
export type TextFieldProps = ElementProps<HTMLInputElement, HTMLInputAttributes, TextFieldOwnProps>;
|
|
57
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const TEXT_FIELD_TYPES = ['text', 'email', 'password', 'search', 'tel', 'url'];
|