@nqmcreative/ui 0.1.0 → 0.2.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 +151 -439
- package/cli/index.mjs +67 -30
- package/dist/core/calendar.d.ts +3 -0
- package/dist/core/calendar.js +36 -0
- package/dist/core/dialog.svelte.d.ts +14 -0
- package/dist/core/dialog.svelte.js +23 -0
- package/dist/core/files.d.ts +35 -0
- package/dist/core/files.js +62 -0
- package/dist/core/index.d.ts +37 -0
- package/dist/core/index.js +35 -0
- package/dist/core/list.svelte.d.ts +41 -0
- package/dist/core/list.svelte.js +77 -0
- package/dist/core/number.d.ts +7 -0
- package/dist/core/number.js +17 -0
- package/dist/core/pagination.d.ts +6 -0
- package/dist/core/pagination.js +21 -0
- package/dist/core/password.d.ts +8 -0
- package/dist/core/password.js +23 -0
- package/dist/core/table.d.ts +22 -0
- package/dist/core/table.js +41 -0
- package/dist/core/theme.svelte.d.ts +16 -0
- package/dist/core/theme.svelte.js +34 -0
- package/dist/core/trigger.d.ts +35 -0
- package/dist/core/trigger.js +77 -0
- package/dist/index.d.ts +11 -103
- package/dist/index.js +11 -75
- package/dist/{components → styles/matte}/AccordionItem.svelte +1 -1
- package/dist/{components → styles/matte}/AccordionItem.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Alert.svelte +8 -2
- package/dist/{components → styles/matte}/Alert.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Avatar.svelte +1 -1
- package/dist/{components → styles/matte}/Avatar.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Badge.svelte +8 -3
- package/dist/{components → styles/matte}/Badge.svelte.d.ts +1 -3
- package/dist/{components → styles/matte}/Breadcrumb.svelte +2 -2
- package/dist/{components → styles/matte}/Breadcrumb.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Button.svelte +1 -1
- package/dist/{components → styles/matte}/Button.svelte.d.ts +1 -1
- package/dist/styles/matte/CTASection.svelte +76 -0
- package/dist/styles/matte/CTASection.svelte.d.ts +18 -0
- package/dist/{components → styles/matte}/Calendar.svelte +7 -17
- package/dist/{components → styles/matte}/Calendar.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Card.svelte +1 -1
- package/dist/{components → styles/matte}/Card.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Checkbox.svelte +1 -1
- package/dist/{components → styles/matte}/Checkbox.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/CheckboxGroup.svelte +1 -1
- package/dist/{components → styles/matte}/CheckboxGroup.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Combobox.svelte +31 -42
- package/dist/{components → styles/matte}/Combobox.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/CommandPalette.svelte +26 -41
- package/dist/{components → styles/matte}/CommandPalette.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/ConfirmDialog.svelte +2 -2
- package/dist/{components → styles/matte}/ConfirmDialog.svelte.d.ts +2 -2
- package/dist/{components → styles/matte}/ContextMenu.svelte +5 -7
- package/dist/{components → styles/matte}/DatePicker.svelte +7 -11
- package/dist/{components → styles/matte}/DatePicker.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Drawer.svelte +4 -7
- package/dist/{components → styles/matte}/Dropdown.svelte +18 -36
- package/dist/{components → styles/matte}/Dropdown.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Dropzone.svelte +11 -43
- package/dist/{components → styles/matte}/Dropzone.svelte.d.ts +2 -5
- package/dist/{components → styles/matte}/EmptyState.svelte +1 -1
- package/dist/{components → styles/matte}/EmptyState.svelte.d.ts +1 -1
- package/dist/styles/matte/FeatureCard.svelte +58 -0
- package/dist/styles/matte/FeatureCard.svelte.d.ts +16 -0
- package/dist/styles/matte/FeatureGrid.svelte +62 -0
- package/dist/styles/matte/FeatureGrid.svelte.d.ts +16 -0
- package/dist/{components → styles/matte}/Footer.svelte +1 -1
- package/dist/{components → styles/matte}/Footer.svelte.d.ts +1 -1
- package/dist/styles/matte/HeroSection.svelte +80 -0
- package/dist/styles/matte/HeroSection.svelte.d.ts +21 -0
- package/dist/{components → styles/matte}/Input.svelte +1 -1
- package/dist/{components → styles/matte}/Input.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Link.svelte +1 -1
- package/dist/{components → styles/matte}/Link.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/LocaleProvider.svelte +1 -1
- package/dist/{components → styles/matte}/LocaleProvider.svelte.d.ts +1 -1
- package/dist/styles/matte/LogoCloud.svelte +61 -0
- package/dist/styles/matte/LogoCloud.svelte.d.ts +19 -0
- package/dist/{components → styles/matte}/MenuItem.svelte +1 -1
- package/dist/{components → styles/matte}/MenuItem.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Modal.svelte +4 -7
- package/dist/{components → styles/matte}/MultiSelect.svelte +18 -37
- package/dist/{components → styles/matte}/MultiSelect.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Navbar.svelte +2 -2
- package/dist/{components → styles/matte}/Navbar.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/NumberInput.svelte +4 -8
- package/dist/{components → styles/matte}/NumberInput.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Pagination.svelte +4 -15
- package/dist/{components → styles/matte}/Pagination.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/PasswordInput.svelte +4 -13
- package/dist/{components → styles/matte}/PasswordInput.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Popover.svelte +16 -41
- package/dist/{components → styles/matte}/Popover.svelte.d.ts +1 -1
- package/dist/styles/matte/PricingCard.svelte +107 -0
- package/dist/styles/matte/PricingCard.svelte.d.ts +25 -0
- package/dist/{components → styles/matte}/Progress.svelte +3 -2
- package/dist/{components → styles/matte}/Progress.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Radio.svelte +1 -1
- package/dist/{components → styles/matte}/Radio.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/RadioGroup.svelte +1 -1
- package/dist/{components → styles/matte}/RadioGroup.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/SegmentedControl.svelte +1 -1
- package/dist/{components → styles/matte}/SegmentedControl.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Select.svelte +1 -1
- package/dist/{components → styles/matte}/Select.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Sidebar.svelte +2 -2
- package/dist/{components → styles/matte}/Sidebar.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Slider.svelte +3 -2
- package/dist/{components → styles/matte}/Slider.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Spinner.svelte +2 -2
- package/dist/{components → styles/matte}/Spinner.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Stat.svelte +1 -1
- package/dist/{components → styles/matte}/Stat.svelte.d.ts +1 -1
- package/dist/styles/matte/StatsBand.svelte +57 -0
- package/dist/styles/matte/StatsBand.svelte.d.ts +20 -0
- package/dist/{components → styles/matte}/Steps.svelte +1 -1
- package/dist/{components → styles/matte}/Steps.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Switch.svelte +1 -1
- package/dist/{components → styles/matte}/Switch.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/Table.svelte +6 -28
- package/dist/{components → styles/matte}/Table.svelte.d.ts +2 -6
- package/dist/{components → styles/matte}/Tabs.svelte +8 -1
- package/dist/{components → styles/matte}/Tabs.svelte.d.ts +1 -1
- package/dist/styles/matte/Testimonial.svelte +67 -0
- package/dist/styles/matte/Testimonial.svelte.d.ts +19 -0
- package/dist/{components → styles/matte}/Textarea.svelte +1 -1
- package/dist/{components → styles/matte}/Textarea.svelte.d.ts +1 -1
- package/dist/{components → styles/matte}/ThemeToggle.svelte +14 -27
- package/dist/{components → styles/matte}/ThemeToggle.svelte.d.ts +2 -6
- package/dist/{components → styles/matte}/Toaster.svelte +4 -4
- package/dist/{fonts.css → styles/matte/fonts.css} +4 -3
- package/dist/styles/matte/index.d.ts +109 -0
- package/dist/styles/matte/index.js +83 -0
- package/dist/{theme.css → styles/matte/theme.css} +0 -1
- package/dist/styles/paper/Accordion.svelte +17 -0
- package/dist/styles/paper/Accordion.svelte.d.ts +8 -0
- package/dist/styles/paper/AccordionItem.svelte +46 -0
- package/dist/styles/paper/AccordionItem.svelte.d.ts +14 -0
- package/dist/styles/paper/Alert.svelte +99 -0
- package/dist/styles/paper/Alert.svelte.d.ts +18 -0
- package/dist/styles/paper/Avatar.svelte +60 -0
- package/dist/styles/paper/Avatar.svelte.d.ts +16 -0
- package/dist/styles/paper/AvatarGroup.svelte +17 -0
- package/dist/styles/paper/AvatarGroup.svelte.d.ts +8 -0
- package/dist/styles/paper/Badge.svelte +58 -0
- package/dist/styles/paper/Badge.svelte.d.ts +16 -0
- package/dist/styles/paper/Breadcrumb.svelte +49 -0
- package/dist/styles/paper/Breadcrumb.svelte.d.ts +14 -0
- package/dist/styles/paper/Button.svelte +96 -0
- package/dist/styles/paper/Button.svelte.d.ts +21 -0
- package/dist/styles/paper/CTASection.svelte +76 -0
- package/dist/styles/paper/CTASection.svelte.d.ts +18 -0
- package/dist/styles/paper/Calendar.svelte +202 -0
- package/dist/styles/paper/Calendar.svelte.d.ts +22 -0
- package/dist/styles/paper/Card.svelte +78 -0
- package/dist/styles/paper/Card.svelte.d.ts +21 -0
- package/dist/styles/paper/Checkbox.svelte +75 -0
- package/dist/styles/paper/Checkbox.svelte.d.ts +15 -0
- package/dist/styles/paper/CheckboxGroup.svelte +111 -0
- package/dist/styles/paper/CheckboxGroup.svelte.d.ts +30 -0
- package/dist/styles/paper/Combobox.svelte +266 -0
- package/dist/styles/paper/Combobox.svelte.d.ts +29 -0
- package/dist/styles/paper/CommandPalette.svelte +209 -0
- package/dist/styles/paper/CommandPalette.svelte.d.ts +32 -0
- package/dist/styles/paper/ConfirmDialog.svelte +97 -0
- package/dist/styles/paper/ConfirmDialog.svelte.d.ts +22 -0
- package/dist/styles/paper/ContextMenu.svelte +88 -0
- package/dist/styles/paper/ContextMenu.svelte.d.ts +15 -0
- package/dist/styles/paper/DatePicker.svelte +192 -0
- package/dist/styles/paper/DatePicker.svelte.d.ts +23 -0
- package/dist/styles/paper/Divider.svelte +30 -0
- package/dist/styles/paper/Divider.svelte.d.ts +10 -0
- package/dist/styles/paper/Drawer.svelte +165 -0
- package/dist/styles/paper/Drawer.svelte.d.ts +20 -0
- package/dist/styles/paper/Dropdown.svelte +94 -0
- package/dist/styles/paper/Dropdown.svelte.d.ts +23 -0
- package/dist/styles/paper/Dropzone.svelte +210 -0
- package/dist/styles/paper/Dropzone.svelte.d.ts +29 -0
- package/dist/styles/paper/EmptyState.svelte +71 -0
- package/dist/styles/paper/EmptyState.svelte.d.ts +18 -0
- package/dist/styles/paper/FeatureCard.svelte +58 -0
- package/dist/styles/paper/FeatureCard.svelte.d.ts +16 -0
- package/dist/styles/paper/FeatureGrid.svelte +62 -0
- package/dist/styles/paper/FeatureGrid.svelte.d.ts +16 -0
- package/dist/styles/paper/Field.svelte +42 -0
- package/dist/styles/paper/Field.svelte.d.ts +16 -0
- package/dist/styles/paper/Footer.svelte +91 -0
- package/dist/styles/paper/Footer.svelte.d.ts +25 -0
- package/dist/styles/paper/HeroSection.svelte +86 -0
- package/dist/styles/paper/HeroSection.svelte.d.ts +21 -0
- package/dist/styles/paper/Input.svelte +60 -0
- package/dist/styles/paper/Input.svelte.d.ts +18 -0
- package/dist/styles/paper/InputGroup.svelte +20 -0
- package/dist/styles/paper/InputGroup.svelte.d.ts +11 -0
- package/dist/styles/paper/Kbd.svelte +17 -0
- package/dist/styles/paper/Kbd.svelte.d.ts +8 -0
- package/dist/styles/paper/Label.svelte +16 -0
- package/dist/styles/paper/Label.svelte.d.ts +9 -0
- package/dist/styles/paper/Link.svelte +44 -0
- package/dist/styles/paper/Link.svelte.d.ts +16 -0
- package/dist/styles/paper/LocaleProvider.svelte +24 -0
- package/dist/styles/paper/LocaleProvider.svelte.d.ts +10 -0
- package/dist/styles/paper/LogoCloud.svelte +61 -0
- package/dist/styles/paper/LogoCloud.svelte.d.ts +19 -0
- package/dist/styles/paper/MenuItem.svelte +64 -0
- package/dist/styles/paper/MenuItem.svelte.d.ts +18 -0
- package/dist/styles/paper/MenuSeparator.svelte +22 -0
- package/dist/styles/paper/MenuSeparator.svelte.d.ts +8 -0
- package/dist/styles/paper/Modal.svelte +118 -0
- package/dist/styles/paper/Modal.svelte.d.ts +21 -0
- package/dist/styles/paper/MultiSelect.svelte +287 -0
- package/dist/styles/paper/MultiSelect.svelte.d.ts +31 -0
- package/dist/styles/paper/Navbar.svelte +201 -0
- package/dist/styles/paper/Navbar.svelte.d.ts +33 -0
- package/dist/styles/paper/NumberInput.svelte +96 -0
- package/dist/styles/paper/NumberInput.svelte.d.ts +15 -0
- package/dist/styles/paper/Pagination.svelte +83 -0
- package/dist/styles/paper/Pagination.svelte.d.ts +15 -0
- package/dist/styles/paper/PasswordInput.svelte +100 -0
- package/dist/styles/paper/PasswordInput.svelte.d.ts +12 -0
- package/dist/styles/paper/Popover.svelte +89 -0
- package/dist/styles/paper/Popover.svelte.d.ts +19 -0
- package/dist/styles/paper/PricingCard.svelte +108 -0
- package/dist/styles/paper/PricingCard.svelte.d.ts +25 -0
- package/dist/styles/paper/Progress.svelte +59 -0
- package/dist/styles/paper/Progress.svelte.d.ts +17 -0
- package/dist/styles/paper/Radio.svelte +55 -0
- package/dist/styles/paper/Radio.svelte.d.ts +15 -0
- package/dist/styles/paper/RadioGroup.svelte +95 -0
- package/dist/styles/paper/RadioGroup.svelte.d.ts +27 -0
- package/dist/styles/paper/SegmentedControl.svelte +88 -0
- package/dist/styles/paper/SegmentedControl.svelte.d.ts +25 -0
- package/dist/styles/paper/Select.svelte +61 -0
- package/dist/styles/paper/Select.svelte.d.ts +20 -0
- package/dist/styles/paper/Sidebar.svelte +206 -0
- package/dist/styles/paper/Sidebar.svelte.d.ts +36 -0
- package/dist/styles/paper/Skeleton.svelte +46 -0
- package/dist/styles/paper/Skeleton.svelte.d.ts +13 -0
- package/dist/styles/paper/Slider.svelte +80 -0
- package/dist/styles/paper/Slider.svelte.d.ts +19 -0
- package/dist/styles/paper/Spinner.svelte +34 -0
- package/dist/styles/paper/Spinner.svelte.d.ts +13 -0
- package/dist/styles/paper/Stat.svelte +51 -0
- package/dist/styles/paper/Stat.svelte.d.ts +16 -0
- package/dist/styles/paper/StatsBand.svelte +63 -0
- package/dist/styles/paper/StatsBand.svelte.d.ts +20 -0
- package/dist/styles/paper/Steps.svelte +141 -0
- package/dist/styles/paper/Steps.svelte.d.ts +24 -0
- package/dist/styles/paper/Switch.svelte +64 -0
- package/dist/styles/paper/Switch.svelte.d.ts +14 -0
- package/dist/styles/paper/Table.svelte +217 -0
- package/dist/styles/paper/Table.svelte.d.ts +66 -0
- package/dist/styles/paper/Tabs.svelte +102 -0
- package/dist/styles/paper/Tabs.svelte.d.ts +23 -0
- package/dist/styles/paper/Testimonial.svelte +64 -0
- package/dist/styles/paper/Testimonial.svelte.d.ts +19 -0
- package/dist/styles/paper/Textarea.svelte +54 -0
- package/dist/styles/paper/Textarea.svelte.d.ts +12 -0
- package/dist/styles/paper/ThemeToggle.svelte +130 -0
- package/dist/styles/paper/ThemeToggle.svelte.d.ts +16 -0
- package/dist/styles/paper/Toaster.svelte +132 -0
- package/dist/styles/paper/Toaster.svelte.d.ts +8 -0
- package/dist/styles/paper/Tooltip.svelte +33 -0
- package/dist/styles/paper/Tooltip.svelte.d.ts +12 -0
- package/dist/styles/paper/fonts.css +46 -0
- package/dist/styles/paper/index.d.ts +109 -0
- package/dist/styles/paper/index.js +83 -0
- package/dist/styles/paper/theme.css +222 -0
- package/package.json +531 -201
- package/registry.json +658 -339
- /package/dist/{actions → core/actions}/anchor.d.ts +0 -0
- /package/dist/{actions → core/actions}/anchor.js +0 -0
- /package/dist/{actions → core/actions}/dismissable.d.ts +0 -0
- /package/dist/{actions → core/actions}/dismissable.js +0 -0
- /package/dist/{date.d.ts → core/date.d.ts} +0 -0
- /package/dist/{date.js → core/date.js} +0 -0
- /package/dist/{locale.svelte.d.ts → core/locale.svelte.d.ts} +0 -0
- /package/dist/{locale.svelte.js → core/locale.svelte.js} +0 -0
- /package/dist/{toast.svelte.d.ts → core/toast.svelte.d.ts} +0 -0
- /package/dist/{toast.svelte.js → core/toast.svelte.js} +0 -0
- /package/dist/{tones.d.ts → core/tones.d.ts} +0 -0
- /package/dist/{tones.js → core/tones.js} +0 -0
- /package/dist/{components → styles/matte}/Accordion.svelte +0 -0
- /package/dist/{components → styles/matte}/Accordion.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/AvatarGroup.svelte +0 -0
- /package/dist/{components → styles/matte}/AvatarGroup.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/ContextMenu.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/Divider.svelte +0 -0
- /package/dist/{components → styles/matte}/Divider.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/Drawer.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/Field.svelte +0 -0
- /package/dist/{components → styles/matte}/Field.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/InputGroup.svelte +0 -0
- /package/dist/{components → styles/matte}/InputGroup.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/Kbd.svelte +0 -0
- /package/dist/{components → styles/matte}/Kbd.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/Label.svelte +0 -0
- /package/dist/{components → styles/matte}/Label.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/MenuSeparator.svelte +0 -0
- /package/dist/{components → styles/matte}/MenuSeparator.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/Modal.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/Skeleton.svelte +0 -0
- /package/dist/{components → styles/matte}/Skeleton.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/Toaster.svelte.d.ts +0 -0
- /package/dist/{components → styles/matte}/Tooltip.svelte +0 -0
- /package/dist/{components → styles/matte}/Tooltip.svelte.d.ts +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
export type SkeletonVariant = 'text' | 'block' | 'circle';
|
|
3
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
variant?: SkeletonVariant;
|
|
5
|
+
/** `text` only — number of stacked lines, the last one runs short. */
|
|
6
|
+
lines?: number;
|
|
7
|
+
/** Any CSS length, e.g. `'12rem'` or `'60%'`. */
|
|
8
|
+
width?: string;
|
|
9
|
+
height?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const Skeleton: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type Skeleton = ReturnType<typeof Skeleton>;
|
|
13
|
+
export default Skeleton;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
+
import { toneText, type Tone } from '../../core/tones.js';
|
|
4
|
+
import { percentOf } from '../../core/number.js';
|
|
5
|
+
|
|
6
|
+
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
|
|
7
|
+
value?: number;
|
|
8
|
+
min?: number;
|
|
9
|
+
max?: number;
|
|
10
|
+
step?: number;
|
|
11
|
+
tone?: Tone;
|
|
12
|
+
label?: string;
|
|
13
|
+
/** Prints the current value on the right of the label row. */
|
|
14
|
+
showValue?: boolean;
|
|
15
|
+
/** Appended to the printed value, e.g. `'%'`. */
|
|
16
|
+
unit?: string;
|
|
17
|
+
/** Tick labels under the track — usually just `[min, max]`. */
|
|
18
|
+
marks?: (number | string)[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let {
|
|
22
|
+
value = $bindable(50),
|
|
23
|
+
min = 0,
|
|
24
|
+
max = 100,
|
|
25
|
+
step = 1,
|
|
26
|
+
tone = 'brand',
|
|
27
|
+
label,
|
|
28
|
+
showValue = false,
|
|
29
|
+
unit = '',
|
|
30
|
+
marks,
|
|
31
|
+
disabled = false,
|
|
32
|
+
class: className = '',
|
|
33
|
+
...rest
|
|
34
|
+
}: Props = $props();
|
|
35
|
+
|
|
36
|
+
const pct = $derived(percentOf(value, min, max));
|
|
37
|
+
|
|
38
|
+
// The filled part of the track and the thumb both paint with `currentColor`,
|
|
39
|
+
// so a single tone class on the input drives every vendor pseudo-element.
|
|
40
|
+
// The gradient classes below are spelled out twice on purpose: Tailwind only
|
|
41
|
+
// sees literal class strings, so a shared JS constant would produce nothing.
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<div class="flex w-full flex-col gap-2 {disabled ? 'opacity-50' : ''} {className}">
|
|
45
|
+
{#if label || showValue}
|
|
46
|
+
<div class="flex items-baseline justify-between gap-4 font-sans text-sm">
|
|
47
|
+
{#if label}<span class="text-text-secondary">{label}</span>{/if}
|
|
48
|
+
{#if showValue}
|
|
49
|
+
<span class="text-sm font-medium tabular-nums {toneText[tone]}">{value}{unit}</span>
|
|
50
|
+
{/if}
|
|
51
|
+
</div>
|
|
52
|
+
{/if}
|
|
53
|
+
|
|
54
|
+
<input
|
|
55
|
+
type="range"
|
|
56
|
+
bind:value
|
|
57
|
+
{min}
|
|
58
|
+
{max}
|
|
59
|
+
{step}
|
|
60
|
+
{disabled}
|
|
61
|
+
aria-label={label}
|
|
62
|
+
style="--pct:{pct}%"
|
|
63
|
+
class="h-5 w-full cursor-pointer appearance-none bg-transparent focus:outline-none disabled:cursor-not-allowed
|
|
64
|
+
{toneText[tone]}
|
|
65
|
+
focus-visible:outline-2 focus-visible:outline-offset-4
|
|
66
|
+
[&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:rounded-full
|
|
67
|
+
[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-bg [&::-moz-range-thumb]:bg-current [&::-moz-range-thumb]:shadow-sm [&::-moz-range-track]:h-1.5 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-[linear-gradient(to_right,currentColor_var(--pct),var(--color-bg-inset)_var(--pct))] [&::-webkit-slider-runnable-track]:h-1.5 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,currentColor_var(--pct),var(--color-bg-inset)_var(--pct))]
|
|
68
|
+
[&::-webkit-slider-thumb]:-mt-[5px] [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2
|
|
69
|
+
[&::-webkit-slider-thumb]:border-bg [&::-webkit-slider-thumb]:bg-current [&::-webkit-slider-thumb]:shadow-sm"
|
|
70
|
+
{...rest}
|
|
71
|
+
/>
|
|
72
|
+
|
|
73
|
+
{#if marks?.length}
|
|
74
|
+
<div class="flex justify-between text-[11px] text-text-muted tabular-nums">
|
|
75
|
+
{#each marks as mark (mark)}
|
|
76
|
+
<span>{mark}</span>
|
|
77
|
+
{/each}
|
|
78
|
+
</div>
|
|
79
|
+
{/if}
|
|
80
|
+
</div>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
+
import { type Tone } from '../../core/tones.js';
|
|
3
|
+
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
|
|
4
|
+
value?: number;
|
|
5
|
+
min?: number;
|
|
6
|
+
max?: number;
|
|
7
|
+
step?: number;
|
|
8
|
+
tone?: Tone;
|
|
9
|
+
label?: string;
|
|
10
|
+
/** Prints the current value on the right of the label row. */
|
|
11
|
+
showValue?: boolean;
|
|
12
|
+
/** Appended to the printed value, e.g. `'%'`. */
|
|
13
|
+
unit?: string;
|
|
14
|
+
/** Tick labels under the track — usually just `[min, max]`. */
|
|
15
|
+
marks?: (number | string)[];
|
|
16
|
+
}
|
|
17
|
+
declare const Slider: import("svelte").Component<Props, {}, "value">;
|
|
18
|
+
type Slider = ReturnType<typeof Slider>;
|
|
19
|
+
export default Slider;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { toneText, type Tone } from '../../core/tones.js';
|
|
4
|
+
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
|
+
|
|
6
|
+
export type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
7
|
+
|
|
8
|
+
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
9
|
+
size?: SpinnerSize;
|
|
10
|
+
/** Omit to inherit the parent's `currentColor` (e.g. inside a Button). */
|
|
11
|
+
tone?: Tone;
|
|
12
|
+
/** Defaults to the locale's loading string; pass `''` to hide it. */
|
|
13
|
+
label?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const t = useLocale();
|
|
17
|
+
|
|
18
|
+
let { size = 'md', tone, label, class: className = '', ...rest }: Props = $props();
|
|
19
|
+
|
|
20
|
+
const sizes: Record<SpinnerSize, string> = {
|
|
21
|
+
xs: 'size-3 border-[1.5px]',
|
|
22
|
+
sm: 'size-4 border-2',
|
|
23
|
+
md: 'size-5 border-2',
|
|
24
|
+
lg: 'size-8 border-[3px]'
|
|
25
|
+
};
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<span
|
|
29
|
+
role="status"
|
|
30
|
+
aria-label={label ?? t.current.loading}
|
|
31
|
+
class="inline-block shrink-0 animate-spin rounded-full border-current/25 border-t-current
|
|
32
|
+
{sizes[size]} {tone ? toneText[tone] : ''} {className}"
|
|
33
|
+
{...rest}
|
|
34
|
+
></span>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import { type Tone } from '../../core/tones.js';
|
|
3
|
+
export type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
4
|
+
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
5
|
+
size?: SpinnerSize;
|
|
6
|
+
/** Omit to inherit the parent's `currentColor` (e.g. inside a Button). */
|
|
7
|
+
tone?: Tone;
|
|
8
|
+
/** Defaults to the locale's loading string; pass `''` to hide it. */
|
|
9
|
+
label?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const Spinner: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type Spinner = ReturnType<typeof Spinner>;
|
|
13
|
+
export default Spinner;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { toneText, type Tone } from '../../core/tones.js';
|
|
4
|
+
|
|
5
|
+
export type StatTrend = 'up' | 'down' | 'flat';
|
|
6
|
+
|
|
7
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
8
|
+
label: string;
|
|
9
|
+
value: string | number;
|
|
10
|
+
/** Secondary figure, e.g. `'+12.4%'`. */
|
|
11
|
+
delta?: string;
|
|
12
|
+
trend?: StatTrend;
|
|
13
|
+
hint?: string;
|
|
14
|
+
/** Colour of the value itself. Leave unset for plain `text`. */
|
|
15
|
+
tone?: Tone;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
label,
|
|
20
|
+
value,
|
|
21
|
+
delta,
|
|
22
|
+
trend = 'flat',
|
|
23
|
+
hint,
|
|
24
|
+
tone,
|
|
25
|
+
class: className = '',
|
|
26
|
+
...rest
|
|
27
|
+
}: Props = $props();
|
|
28
|
+
|
|
29
|
+
const trendTone: Record<StatTrend, Tone> = { up: 'success', down: 'danger', flat: 'neutral' };
|
|
30
|
+
const trendGlyph: Record<StatTrend, string> = { up: '↑', down: '↓', flat: '→' };
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<div class="flex flex-col gap-1 font-sans {className}" {...rest}>
|
|
34
|
+
<span class="text-sm font-medium text-text-muted">{label}</span>
|
|
35
|
+
<div class="flex items-baseline gap-2">
|
|
36
|
+
<span
|
|
37
|
+
class="font-heading text-3xl font-semibold tracking-tight tabular-nums {tone
|
|
38
|
+
? toneText[tone]
|
|
39
|
+
: 'text-text'}"
|
|
40
|
+
>
|
|
41
|
+
{value}
|
|
42
|
+
</span>
|
|
43
|
+
{#if delta}
|
|
44
|
+
<span class="text-sm font-medium {toneText[trendTone[trend]]}">
|
|
45
|
+
{trendGlyph[trend]}
|
|
46
|
+
{delta}
|
|
47
|
+
</span>
|
|
48
|
+
{/if}
|
|
49
|
+
</div>
|
|
50
|
+
{#if hint}<span class="text-sm text-text-muted">{hint}</span>{/if}
|
|
51
|
+
</div>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import { type Tone } from '../../core/tones.js';
|
|
3
|
+
export type StatTrend = 'up' | 'down' | 'flat';
|
|
4
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
label: string;
|
|
6
|
+
value: string | number;
|
|
7
|
+
/** Secondary figure, e.g. `'+12.4%'`. */
|
|
8
|
+
delta?: string;
|
|
9
|
+
trend?: StatTrend;
|
|
10
|
+
hint?: string;
|
|
11
|
+
/** Colour of the value itself. Leave unset for plain `text`. */
|
|
12
|
+
tone?: Tone;
|
|
13
|
+
}
|
|
14
|
+
declare const Stat: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type Stat = ReturnType<typeof Stat>;
|
|
16
|
+
export default Stat;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import Stat from './Stat.svelte';
|
|
4
|
+
import type { StatTrend } from './Stat.svelte';
|
|
5
|
+
import type { Tone } from '../../core/tones.js';
|
|
6
|
+
|
|
7
|
+
export interface BandStat {
|
|
8
|
+
label: string;
|
|
9
|
+
value: string | number;
|
|
10
|
+
delta?: string;
|
|
11
|
+
trend?: StatTrend;
|
|
12
|
+
hint?: string;
|
|
13
|
+
tone?: Tone;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface Props extends HTMLAttributes<HTMLElement> {
|
|
17
|
+
stats: BandStat[];
|
|
18
|
+
title?: string;
|
|
19
|
+
/** Figures in one bordered card rather than free-standing. */
|
|
20
|
+
bordered?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let { stats, title, bordered = true, class: className = '', ...rest }: Props = $props();
|
|
24
|
+
|
|
25
|
+
const cols = $derived(
|
|
26
|
+
stats.length === 2
|
|
27
|
+
? 'sm:grid-cols-2'
|
|
28
|
+
: stats.length === 4
|
|
29
|
+
? 'sm:grid-cols-2 lg:grid-cols-4'
|
|
30
|
+
: 'sm:grid-cols-3'
|
|
31
|
+
);
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<section class="w-full px-6 py-16 {className}" {...rest}>
|
|
35
|
+
<div class="mx-auto flex w-full max-w-6xl flex-col gap-8">
|
|
36
|
+
{#if title}
|
|
37
|
+
<h2
|
|
38
|
+
class="max-w-xl font-heading text-3xl font-semibold tracking-tight text-balance text-text"
|
|
39
|
+
>
|
|
40
|
+
{title}
|
|
41
|
+
</h2>
|
|
42
|
+
{/if}
|
|
43
|
+
|
|
44
|
+
<div
|
|
45
|
+
class="grid {cols} {bordered
|
|
46
|
+
? 'gap-px overflow-hidden rounded-lg border border-hairline bg-hairline shadow-xs'
|
|
47
|
+
: 'gap-8'}"
|
|
48
|
+
>
|
|
49
|
+
{#each stats as stat (stat.label)}
|
|
50
|
+
<div class={bordered ? 'bg-bg p-6' : ''}>
|
|
51
|
+
<Stat
|
|
52
|
+
label={stat.label}
|
|
53
|
+
value={stat.value}
|
|
54
|
+
delta={stat.delta}
|
|
55
|
+
trend={stat.trend}
|
|
56
|
+
hint={stat.hint}
|
|
57
|
+
tone={stat.tone}
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
{/each}
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</section>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { StatTrend } from './Stat.svelte';
|
|
3
|
+
import type { Tone } from '../../core/tones.js';
|
|
4
|
+
export interface BandStat {
|
|
5
|
+
label: string;
|
|
6
|
+
value: string | number;
|
|
7
|
+
delta?: string;
|
|
8
|
+
trend?: StatTrend;
|
|
9
|
+
hint?: string;
|
|
10
|
+
tone?: Tone;
|
|
11
|
+
}
|
|
12
|
+
interface Props extends HTMLAttributes<HTMLElement> {
|
|
13
|
+
stats: BandStat[];
|
|
14
|
+
title?: string;
|
|
15
|
+
/** Figures in one bordered card rather than free-standing. */
|
|
16
|
+
bordered?: boolean;
|
|
17
|
+
}
|
|
18
|
+
declare const StatsBand: import("svelte").Component<Props, {}, "">;
|
|
19
|
+
type StatsBand = ReturnType<typeof StatsBand>;
|
|
20
|
+
export default StatsBand;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
export interface StepItem {
|
|
3
|
+
label: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
/** Marks the step as failed — shown in `danger` regardless of position. */
|
|
6
|
+
error?: boolean;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<script lang="ts">
|
|
12
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
13
|
+
import { focusRing, toneFill, toneRing, toneText, type Tone } from '../../core/tones.js';
|
|
14
|
+
|
|
15
|
+
interface Props extends Omit<HTMLAttributes<HTMLElement>, 'onchange'> {
|
|
16
|
+
items: StepItem[];
|
|
17
|
+
/** Bindable, zero-based. Steps before it count as done. */
|
|
18
|
+
current?: number;
|
|
19
|
+
orientation?: 'horizontal' | 'vertical';
|
|
20
|
+
tone?: Tone;
|
|
21
|
+
/** Let the user jump to a completed step by clicking it. */
|
|
22
|
+
clickable?: boolean;
|
|
23
|
+
/** Hide the connecting rule between steps. */
|
|
24
|
+
bare?: boolean;
|
|
25
|
+
onchange?: (index: number) => void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let {
|
|
29
|
+
items,
|
|
30
|
+
current = $bindable(0),
|
|
31
|
+
orientation = 'horizontal',
|
|
32
|
+
tone = 'brand',
|
|
33
|
+
clickable = false,
|
|
34
|
+
bare = false,
|
|
35
|
+
class: className = '',
|
|
36
|
+
onchange,
|
|
37
|
+
...rest
|
|
38
|
+
}: Props = $props();
|
|
39
|
+
|
|
40
|
+
function status(index: number): 'done' | 'current' | 'todo' {
|
|
41
|
+
if (index < current) return 'done';
|
|
42
|
+
if (index === current) return 'current';
|
|
43
|
+
return 'todo';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const marker =
|
|
47
|
+
'flex size-8 shrink-0 items-center justify-center rounded-full border font-sans text-xs font-semibold transition-colors duration-150 ease-brand-out';
|
|
48
|
+
|
|
49
|
+
function markerTone(state: 'done' | 'current' | 'todo', item: StepItem) {
|
|
50
|
+
if (item.error) return 'border-danger bg-danger-light text-danger';
|
|
51
|
+
if (state === 'done') return `${toneFill[tone]} border-transparent text-text-inverse shadow-xs`;
|
|
52
|
+
if (state === 'current') return `border-2 border-current bg-bg ${toneText[tone]}`;
|
|
53
|
+
return 'border-hairline-strong bg-bg text-text-muted';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function go(index: number, item: StepItem) {
|
|
57
|
+
if (!clickable || item.disabled || index > current) return;
|
|
58
|
+
current = index;
|
|
59
|
+
onchange?.(index);
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
{#snippet glyph(index: number, state: 'done' | 'current' | 'todo', item: StepItem)}
|
|
64
|
+
{#if item.error}
|
|
65
|
+
!
|
|
66
|
+
{:else if state === 'done'}
|
|
67
|
+
<svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
|
|
68
|
+
<path
|
|
69
|
+
d="m2 7 3.2 3.2L12 3.6"
|
|
70
|
+
stroke="currentColor"
|
|
71
|
+
stroke-width="2"
|
|
72
|
+
stroke-linecap="round"
|
|
73
|
+
stroke-linejoin="round"
|
|
74
|
+
/>
|
|
75
|
+
</svg>
|
|
76
|
+
{:else}
|
|
77
|
+
{index + 1}
|
|
78
|
+
{/if}
|
|
79
|
+
{/snippet}
|
|
80
|
+
|
|
81
|
+
<nav
|
|
82
|
+
aria-label="Progress"
|
|
83
|
+
class="flex w-full {orientation === 'vertical' ? 'flex-col gap-0' : 'flex-row'} {className}"
|
|
84
|
+
{...rest}
|
|
85
|
+
>
|
|
86
|
+
{#each items as item, i (item.label)}
|
|
87
|
+
{@const state = status(i)}
|
|
88
|
+
<div
|
|
89
|
+
class="flex min-w-0 {orientation === 'vertical' ? 'flex-row gap-3' : 'flex-1 flex-col gap-2'}"
|
|
90
|
+
>
|
|
91
|
+
<!-- marker + rule -->
|
|
92
|
+
<div
|
|
93
|
+
class="flex shrink-0 items-center {orientation === 'vertical'
|
|
94
|
+
? 'flex-col self-stretch'
|
|
95
|
+
: 'w-full flex-row'}"
|
|
96
|
+
>
|
|
97
|
+
{#if clickable && state !== 'todo' && !item.disabled}
|
|
98
|
+
<button
|
|
99
|
+
type="button"
|
|
100
|
+
onclick={() => go(i, item)}
|
|
101
|
+
aria-current={state === 'current' ? 'step' : undefined}
|
|
102
|
+
class="{marker} cursor-pointer {markerTone(state, item)} {focusRing} {toneRing[tone]}"
|
|
103
|
+
>
|
|
104
|
+
{@render glyph(i, state, item)}
|
|
105
|
+
</button>
|
|
106
|
+
{:else}
|
|
107
|
+
<div
|
|
108
|
+
aria-current={state === 'current' ? 'step' : undefined}
|
|
109
|
+
class="{marker} {markerTone(state, item)}"
|
|
110
|
+
>
|
|
111
|
+
{@render glyph(i, state, item)}
|
|
112
|
+
</div>
|
|
113
|
+
{/if}
|
|
114
|
+
|
|
115
|
+
{#if !bare && i < items.length - 1}
|
|
116
|
+
<span
|
|
117
|
+
class="rounded-full {orientation === 'vertical'
|
|
118
|
+
? 'my-1 w-0.5 flex-1'
|
|
119
|
+
: 'mx-3 h-0.5 flex-1'} {i < current ? toneFill[tone] : 'bg-hairline'}"
|
|
120
|
+
></span>
|
|
121
|
+
{/if}
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<!-- copy -->
|
|
125
|
+
<div class="flex min-w-0 flex-col gap-0.5 {orientation === 'vertical' ? 'pb-6' : 'pr-3'}">
|
|
126
|
+
<span
|
|
127
|
+
class="font-sans text-sm leading-snug break-words {state === 'todo'
|
|
128
|
+
? 'text-text-muted'
|
|
129
|
+
: 'font-medium text-text'}"
|
|
130
|
+
>
|
|
131
|
+
{item.label}
|
|
132
|
+
</span>
|
|
133
|
+
{#if item.description}
|
|
134
|
+
<span class="font-sans text-[13px] leading-snug break-words text-text-muted">
|
|
135
|
+
{item.description}
|
|
136
|
+
</span>
|
|
137
|
+
{/if}
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
{/each}
|
|
141
|
+
</nav>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface StepItem {
|
|
2
|
+
label: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
/** Marks the step as failed — shown in `danger` regardless of position. */
|
|
5
|
+
error?: boolean;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
9
|
+
import { type Tone } from '../../core/tones.js';
|
|
10
|
+
interface Props extends Omit<HTMLAttributes<HTMLElement>, 'onchange'> {
|
|
11
|
+
items: StepItem[];
|
|
12
|
+
/** Bindable, zero-based. Steps before it count as done. */
|
|
13
|
+
current?: number;
|
|
14
|
+
orientation?: 'horizontal' | 'vertical';
|
|
15
|
+
tone?: Tone;
|
|
16
|
+
/** Let the user jump to a completed step by clicking it. */
|
|
17
|
+
clickable?: boolean;
|
|
18
|
+
/** Hide the connecting rule between steps. */
|
|
19
|
+
bare?: boolean;
|
|
20
|
+
onchange?: (index: number) => void;
|
|
21
|
+
}
|
|
22
|
+
declare const Steps: import("svelte").Component<Props, {}, "current">;
|
|
23
|
+
type Steps = ReturnType<typeof Steps>;
|
|
24
|
+
export default Steps;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
+
import { focusRing, toneFill, toneRing, type Tone } from '../../core/tones.js';
|
|
4
|
+
|
|
5
|
+
export type SwitchSize = 'sm' | 'md';
|
|
6
|
+
|
|
7
|
+
interface Props extends Omit<HTMLButtonAttributes, 'onclick' | 'onchange'> {
|
|
8
|
+
checked?: boolean;
|
|
9
|
+
label?: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
tone?: Tone;
|
|
12
|
+
size?: SwitchSize;
|
|
13
|
+
onchange?: (checked: boolean) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
checked = $bindable(false),
|
|
18
|
+
label,
|
|
19
|
+
description,
|
|
20
|
+
tone = 'brand',
|
|
21
|
+
size = 'md',
|
|
22
|
+
disabled = false,
|
|
23
|
+
onchange,
|
|
24
|
+
class: className = '',
|
|
25
|
+
...rest
|
|
26
|
+
}: Props = $props();
|
|
27
|
+
|
|
28
|
+
const sizes: Record<SwitchSize, { track: string; thumb: string; travel: string }> = {
|
|
29
|
+
sm: { track: 'h-5 w-9', thumb: 'size-4', travel: 'translate-x-4' },
|
|
30
|
+
md: { track: 'h-6 w-11', thumb: 'size-5', travel: 'translate-x-5' }
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function toggle() {
|
|
34
|
+
checked = !checked;
|
|
35
|
+
onchange?.(checked);
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<div class="inline-flex items-start gap-3 {disabled ? 'opacity-50' : ''} {className}">
|
|
40
|
+
<button
|
|
41
|
+
type="button"
|
|
42
|
+
role="switch"
|
|
43
|
+
aria-checked={checked}
|
|
44
|
+
aria-label={label}
|
|
45
|
+
{disabled}
|
|
46
|
+
onclick={toggle}
|
|
47
|
+
class="relative mt-0.5 inline-flex shrink-0 items-center rounded-full p-0.5 transition-colors duration-200 ease-brand-out disabled:pointer-events-none
|
|
48
|
+
{sizes[size].track} {checked ? toneFill[tone] : 'bg-hairline-strong'} {focusRing} {toneRing[tone]}"
|
|
49
|
+
{...rest}
|
|
50
|
+
>
|
|
51
|
+
<span
|
|
52
|
+
class="rounded-full bg-bg shadow-sm transition-transform duration-200 ease-brand-out
|
|
53
|
+
{sizes[size].thumb} {checked ? sizes[size].travel : 'translate-x-0'}"
|
|
54
|
+
></span>
|
|
55
|
+
</button>
|
|
56
|
+
{#if label || description}
|
|
57
|
+
<span class="flex flex-col gap-0.5 font-sans text-sm">
|
|
58
|
+
{#if label}<span class="leading-snug text-text">{label}</span>{/if}
|
|
59
|
+
{#if description}
|
|
60
|
+
<span class="text-[13px] leading-snug text-text-muted">{description}</span>
|
|
61
|
+
{/if}
|
|
62
|
+
</span>
|
|
63
|
+
{/if}
|
|
64
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
2
|
+
import { type Tone } from '../../core/tones.js';
|
|
3
|
+
export type SwitchSize = 'sm' | 'md';
|
|
4
|
+
interface Props extends Omit<HTMLButtonAttributes, 'onclick' | 'onchange'> {
|
|
5
|
+
checked?: boolean;
|
|
6
|
+
label?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
tone?: Tone;
|
|
9
|
+
size?: SwitchSize;
|
|
10
|
+
onchange?: (checked: boolean) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const Switch: import("svelte").Component<Props, {}, "checked">;
|
|
13
|
+
type Switch = ReturnType<typeof Switch>;
|
|
14
|
+
export default Switch;
|