@nqmcreative/ui 0.1.1 → 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 +89 -34
- 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/styles/matte/index.d.ts +109 -0
- package/dist/styles/matte/index.js +83 -0
- 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
- /package/dist/{fonts.css → styles/matte/fonts.css} +0 -0
- /package/dist/{theme.css → styles/matte/theme.css} +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import { toneBorder, toneFill, toneSoft, toneText, type Tone } from '../../core/tones.js';
|
|
5
|
+
|
|
6
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
7
|
+
name: string;
|
|
8
|
+
/** Already formatted — the component does not do currency. */
|
|
9
|
+
price: string;
|
|
10
|
+
/** `/ month`, `per seat`, whatever follows the figure. */
|
|
11
|
+
period?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
/** One line each. Rendered with a tick. */
|
|
14
|
+
features?: string[];
|
|
15
|
+
/** Pill in the top corner, e.g. "Most popular". */
|
|
16
|
+
badge?: string;
|
|
17
|
+
/** Thicker border and a tinted header — for the plan you want chosen. */
|
|
18
|
+
featured?: boolean;
|
|
19
|
+
tone?: Tone;
|
|
20
|
+
/** The button. */
|
|
21
|
+
action?: Snippet;
|
|
22
|
+
/** Extra content under the feature list. */
|
|
23
|
+
children?: Snippet;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let {
|
|
27
|
+
name,
|
|
28
|
+
price,
|
|
29
|
+
period,
|
|
30
|
+
description,
|
|
31
|
+
features = [],
|
|
32
|
+
badge,
|
|
33
|
+
featured = false,
|
|
34
|
+
tone = 'brand',
|
|
35
|
+
action,
|
|
36
|
+
class: className = '',
|
|
37
|
+
children,
|
|
38
|
+
...rest
|
|
39
|
+
}: Props = $props();
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<div
|
|
43
|
+
class="flex flex-col bg-bg {featured
|
|
44
|
+
? `border-2 ${toneBorder[tone]}`
|
|
45
|
+
: 'border border-hairline'} {className}"
|
|
46
|
+
{...rest}
|
|
47
|
+
>
|
|
48
|
+
<div class="flex flex-col gap-4 p-6 {featured ? toneSoft[tone] : ''}">
|
|
49
|
+
<div class="flex items-start justify-between gap-3">
|
|
50
|
+
<h3 class="font-heading text-lg font-medium tracking-tight {featured ? '' : 'text-text'}">
|
|
51
|
+
{name}
|
|
52
|
+
</h3>
|
|
53
|
+
{#if badge}
|
|
54
|
+
<span
|
|
55
|
+
class="shrink-0 rounded-full px-2.5 py-1 font-mono text-[10px] tracking-wide {featured
|
|
56
|
+
? `${toneFill[tone]} text-text-inverse`
|
|
57
|
+
: toneSoft[tone]}"
|
|
58
|
+
>
|
|
59
|
+
{badge}
|
|
60
|
+
</span>
|
|
61
|
+
{/if}
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<div class="flex items-baseline gap-1.5">
|
|
65
|
+
<span
|
|
66
|
+
class="font-heading text-4xl font-medium tracking-tight {featured
|
|
67
|
+
? toneText[tone]
|
|
68
|
+
: 'text-text'}"
|
|
69
|
+
>
|
|
70
|
+
{price}
|
|
71
|
+
</span>
|
|
72
|
+
{#if period}
|
|
73
|
+
<span class="font-sans text-sm text-text-muted">{period}</span>
|
|
74
|
+
{/if}
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
{#if description}
|
|
78
|
+
<p class="font-sans text-sm leading-relaxed text-text-secondary">{description}</p>
|
|
79
|
+
{/if}
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
{#if features.length}
|
|
83
|
+
<ul class="flex flex-1 flex-col gap-3 border-t border-hairline p-6">
|
|
84
|
+
{#each features as feature (feature)}
|
|
85
|
+
<li class="flex items-start gap-3 font-sans text-sm text-text-secondary">
|
|
86
|
+
<svg
|
|
87
|
+
class="mt-0.5 size-4 shrink-0 {toneText[tone]}"
|
|
88
|
+
viewBox="0 0 16 16"
|
|
89
|
+
fill="none"
|
|
90
|
+
aria-hidden="true"
|
|
91
|
+
>
|
|
92
|
+
<path d="m3 8 3.2 3.2L13 4.4" stroke="currentColor" stroke-width="1.6" />
|
|
93
|
+
</svg>
|
|
94
|
+
<span class="leading-snug">{feature}</span>
|
|
95
|
+
</li>
|
|
96
|
+
{/each}
|
|
97
|
+
</ul>
|
|
98
|
+
{/if}
|
|
99
|
+
|
|
100
|
+
{#if children}
|
|
101
|
+
<div class="px-6 pb-2">{@render children()}</div>
|
|
102
|
+
{/if}
|
|
103
|
+
|
|
104
|
+
{#if action}
|
|
105
|
+
<div class="p-6 pt-2">{@render action()}</div>
|
|
106
|
+
{/if}
|
|
107
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { type Tone } from '../../core/tones.js';
|
|
4
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
name: string;
|
|
6
|
+
/** Already formatted — the component does not do currency. */
|
|
7
|
+
price: string;
|
|
8
|
+
/** `/ month`, `per seat`, whatever follows the figure. */
|
|
9
|
+
period?: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
/** One line each. Rendered with a tick. */
|
|
12
|
+
features?: string[];
|
|
13
|
+
/** Pill in the top corner, e.g. "Most popular". */
|
|
14
|
+
badge?: string;
|
|
15
|
+
/** Thicker border and a tinted header — for the plan you want chosen. */
|
|
16
|
+
featured?: boolean;
|
|
17
|
+
tone?: Tone;
|
|
18
|
+
/** The button. */
|
|
19
|
+
action?: Snippet;
|
|
20
|
+
/** Extra content under the feature list. */
|
|
21
|
+
children?: Snippet;
|
|
22
|
+
}
|
|
23
|
+
declare const PricingCard: import("svelte").Component<Props, {}, "">;
|
|
24
|
+
type PricingCard = ReturnType<typeof PricingCard>;
|
|
25
|
+
export default PricingCard;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import { toneFill, type Tone } from '
|
|
3
|
+
import { toneFill, type Tone } from '../../core/tones.js';
|
|
4
|
+
import { percentOf } from '../../core/number.js';
|
|
4
5
|
|
|
5
6
|
export type ProgressSize = 'sm' | 'md' | 'lg';
|
|
6
7
|
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
}: Props = $props();
|
|
30
31
|
|
|
31
32
|
const sizes: Record<ProgressSize, string> = { sm: 'h-1', md: 'h-2', lg: 'h-3' };
|
|
32
|
-
const pct = $derived(
|
|
33
|
+
const pct = $derived(percentOf(value, 0, max));
|
|
33
34
|
</script>
|
|
34
35
|
|
|
35
36
|
<div class="flex w-full flex-col gap-2 {className}" {...rest}>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Tone } from '
|
|
2
|
+
import { type Tone } from '../../core/tones.js';
|
|
3
3
|
export type ProgressSize = 'sm' | 'md' | 'lg';
|
|
4
4
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
5
|
value?: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
4
|
-
import { peerFocusRing, tonePeerChecked, tonePeerFocus, type Tone } from '
|
|
4
|
+
import { peerFocusRing, tonePeerChecked, tonePeerFocus, type Tone } from '../../core/tones.js';
|
|
5
5
|
|
|
6
6
|
interface Props extends Omit<HTMLInputAttributes, 'type' | 'size'> {
|
|
7
7
|
/** Bind the same variable across a set of radios. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
import { type Tone } from '
|
|
3
|
+
import { type Tone } from '../../core/tones.js';
|
|
4
4
|
interface Props extends Omit<HTMLInputAttributes, 'type' | 'size'> {
|
|
5
5
|
/** Bind the same variable across a set of radios. */
|
|
6
6
|
group?: string;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLFieldsetAttributes } from 'svelte/elements';
|
|
4
4
|
import Radio from './Radio.svelte';
|
|
5
|
-
import type { Tone } from '
|
|
5
|
+
import type { Tone } from '../../core/tones.js';
|
|
6
6
|
|
|
7
7
|
export interface RadioOption {
|
|
8
8
|
value: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import { focusRing, toneRing, toneSoft, type Tone } from '
|
|
3
|
+
import { focusRing, toneRing, toneSoft, type Tone } from '../../core/tones.js';
|
|
4
4
|
|
|
5
5
|
export interface SegmentOption {
|
|
6
6
|
value: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLSelectAttributes } from 'svelte/elements';
|
|
4
|
-
import { toneFocusBorder, type Tone } from '
|
|
4
|
+
import { toneFocusBorder, type Tone } from '../../core/tones.js';
|
|
5
5
|
|
|
6
6
|
export interface SelectOption {
|
|
7
7
|
value: string;
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
|
|
22
22
|
<script lang="ts">
|
|
23
23
|
import type { Snippet } from 'svelte';
|
|
24
|
-
import { useLocale } from '
|
|
25
|
-
import { focusRing, toneRing, toneSoft, type Tone } from '
|
|
24
|
+
import { useLocale } from '../../core/locale.svelte.js';
|
|
25
|
+
import { focusRing, toneRing, toneSoft, type Tone } from '../../core/tones.js';
|
|
26
26
|
|
|
27
27
|
interface Props {
|
|
28
28
|
sections: SidebarSection[];
|
|
@@ -16,7 +16,7 @@ export interface SidebarSection {
|
|
|
16
16
|
items: SidebarItem[];
|
|
17
17
|
}
|
|
18
18
|
import type { Snippet } from 'svelte';
|
|
19
|
-
import { type Tone } from '
|
|
19
|
+
import { type Tone } from '../../core/tones.js';
|
|
20
20
|
interface Props {
|
|
21
21
|
sections: SidebarSection[];
|
|
22
22
|
/** Bindable — the `id` (or `href`) of the current item. */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
import { toneText, type Tone } from '
|
|
3
|
+
import { toneText, type Tone } from '../../core/tones.js';
|
|
4
|
+
import { percentOf } from '../../core/number.js';
|
|
4
5
|
|
|
5
6
|
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
|
|
6
7
|
value?: number;
|
|
@@ -32,7 +33,7 @@
|
|
|
32
33
|
...rest
|
|
33
34
|
}: Props = $props();
|
|
34
35
|
|
|
35
|
-
const pct = $derived(
|
|
36
|
+
const pct = $derived(percentOf(value, min, max));
|
|
36
37
|
|
|
37
38
|
// The filled part of the track and the thumb both paint with `currentColor`,
|
|
38
39
|
// so a single tone class on the input drives every vendor pseudo-element.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Tone } from '
|
|
2
|
+
import { type Tone } from '../../core/tones.js';
|
|
3
3
|
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
|
|
4
4
|
value?: number;
|
|
5
5
|
min?: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import { toneText, type Tone } from '
|
|
4
|
-
import { useLocale } from '
|
|
3
|
+
import { toneText, type Tone } from '../../core/tones.js';
|
|
4
|
+
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
5
|
|
|
6
6
|
export type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
7
7
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Tone } from '
|
|
2
|
+
import { type Tone } from '../../core/tones.js';
|
|
3
3
|
export type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
4
4
|
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
5
5
|
size?: SpinnerSize;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Tone } from '
|
|
2
|
+
import { type Tone } from '../../core/tones.js';
|
|
3
3
|
export type StatTrend = 'up' | 'down' | 'flat';
|
|
4
4
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
5
|
label: string;
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
/** Hairline grid rather than free-standing figures. */
|
|
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 class="max-w-xl font-heading text-3xl font-medium tracking-tight text-balance text-text">
|
|
38
|
+
{title}
|
|
39
|
+
</h2>
|
|
40
|
+
{/if}
|
|
41
|
+
|
|
42
|
+
<div class="grid {cols} {bordered ? 'gap-px border border-hairline bg-hairline' : 'gap-10'}">
|
|
43
|
+
{#each stats as stat (stat.label)}
|
|
44
|
+
<div class={bordered ? 'bg-bg p-6' : ''}>
|
|
45
|
+
<Stat
|
|
46
|
+
label={stat.label}
|
|
47
|
+
value={stat.value}
|
|
48
|
+
delta={stat.delta}
|
|
49
|
+
trend={stat.trend}
|
|
50
|
+
hint={stat.hint}
|
|
51
|
+
tone={stat.tone}
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
{/each}
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</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
|
+
/** Hairline grid rather than free-standing figures. */
|
|
16
|
+
bordered?: boolean;
|
|
17
|
+
}
|
|
18
|
+
declare const StatsBand: import("svelte").Component<Props, {}, "">;
|
|
19
|
+
type StatsBand = ReturnType<typeof StatsBand>;
|
|
20
|
+
export default StatsBand;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
<script lang="ts">
|
|
12
12
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
13
|
-
import { focusRing, toneFill, toneRing, toneText, type Tone } from '
|
|
13
|
+
import { focusRing, toneFill, toneRing, toneText, type Tone } from '../../core/tones.js';
|
|
14
14
|
|
|
15
15
|
interface Props extends Omit<HTMLAttributes<HTMLElement>, 'onchange'> {
|
|
16
16
|
items: StepItem[];
|
|
@@ -6,7 +6,7 @@ export interface StepItem {
|
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
}
|
|
8
8
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
9
|
-
import { type Tone } from '
|
|
9
|
+
import { type Tone } from '../../core/tones.js';
|
|
10
10
|
interface Props extends Omit<HTMLAttributes<HTMLElement>, 'onchange'> {
|
|
11
11
|
items: StepItem[];
|
|
12
12
|
/** Bindable, zero-based. Steps before it count as done. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
-
import { focusRing, toneFill, toneRing, type Tone } from '
|
|
3
|
+
import { focusRing, toneFill, toneRing, type Tone } from '../../core/tones.js';
|
|
4
4
|
|
|
5
5
|
export type SwitchSize = 'sm' | 'md';
|
|
6
6
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Tone } from '
|
|
2
|
+
import { type Tone } from '../../core/tones.js';
|
|
3
3
|
export type SwitchSize = 'sm' | 'md';
|
|
4
4
|
interface Props extends Omit<HTMLButtonAttributes, 'onclick' | 'onchange'> {
|
|
5
5
|
checked?: boolean;
|
|
@@ -8,21 +8,15 @@
|
|
|
8
8
|
/** Allow clicking the header to sort by this column. */
|
|
9
9
|
sortable?: boolean;
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
export type SortDirection = 'asc' | 'desc';
|
|
13
|
-
|
|
14
|
-
export interface TableSort {
|
|
15
|
-
key: string;
|
|
16
|
-
direction: SortDirection;
|
|
17
|
-
}
|
|
18
11
|
</script>
|
|
19
12
|
|
|
20
13
|
<script lang="ts" generics="T extends Record<string, unknown>">
|
|
21
14
|
import type { Snippet } from 'svelte';
|
|
22
15
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
23
16
|
import Checkbox from './Checkbox.svelte';
|
|
24
|
-
import type { Tone } from '
|
|
25
|
-
import {
|
|
17
|
+
import type { Tone } from '../../core/tones.js';
|
|
18
|
+
import { nextSort, sortRows, toggleKey, type TableSort } from '../../core/table.js';
|
|
19
|
+
import { useLocale } from '../../core/locale.svelte.js';
|
|
26
20
|
|
|
27
21
|
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'onselect'> {
|
|
28
22
|
columns: TableColumn[];
|
|
@@ -85,26 +79,11 @@
|
|
|
85
79
|
|
|
86
80
|
const pad = $derived(compact ? 'px-4 py-2' : 'px-4 py-3');
|
|
87
81
|
|
|
88
|
-
const sorted = $derived
|
|
89
|
-
if (!sort || !sortLocally) return rows;
|
|
90
|
-
const { key, direction } = sort;
|
|
91
|
-
const factor = direction === 'asc' ? 1 : -1;
|
|
92
|
-
return [...rows].sort((a, b) => {
|
|
93
|
-
const x = a[key];
|
|
94
|
-
const y = b[key];
|
|
95
|
-
if (x == null) return 1;
|
|
96
|
-
if (y == null) return -1;
|
|
97
|
-
if (typeof x === 'number' && typeof y === 'number') return (x - y) * factor;
|
|
98
|
-
return String(x).localeCompare(String(y), undefined, { numeric: true }) * factor;
|
|
99
|
-
});
|
|
100
|
-
});
|
|
82
|
+
const sorted = $derived(sortLocally ? sortRows(rows, sort) : rows);
|
|
101
83
|
|
|
102
84
|
function toggleSort(column: TableColumn) {
|
|
103
85
|
if (!column.sortable) return;
|
|
104
|
-
|
|
105
|
-
if (sort?.key !== column.key) next = { key: column.key, direction: 'asc' };
|
|
106
|
-
else if (sort.direction === 'asc') next = { key: column.key, direction: 'desc' };
|
|
107
|
-
else next = null;
|
|
86
|
+
const next = nextSort(sort, column.key);
|
|
108
87
|
sort = next;
|
|
109
88
|
onsort?.(next);
|
|
110
89
|
}
|
|
@@ -124,8 +103,7 @@
|
|
|
124
103
|
}
|
|
125
104
|
|
|
126
105
|
function toggleRow(row: T) {
|
|
127
|
-
|
|
128
|
-
selected = selected.includes(key) ? selected.filter((k) => k !== key) : [...selected, key];
|
|
106
|
+
selected = toggleKey(selected, keyOf(row));
|
|
129
107
|
onselect?.(selected);
|
|
130
108
|
}
|
|
131
109
|
</script>
|
|
@@ -7,14 +7,10 @@ export interface TableColumn {
|
|
|
7
7
|
/** Allow clicking the header to sort by this column. */
|
|
8
8
|
sortable?: boolean;
|
|
9
9
|
}
|
|
10
|
-
export type SortDirection = 'asc' | 'desc';
|
|
11
|
-
export interface TableSort {
|
|
12
|
-
key: string;
|
|
13
|
-
direction: SortDirection;
|
|
14
|
-
}
|
|
15
10
|
import type { Snippet } from 'svelte';
|
|
16
11
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
17
|
-
import type { Tone } from '
|
|
12
|
+
import type { Tone } from '../../core/tones.js';
|
|
13
|
+
import { type TableSort } from '../../core/table.js';
|
|
18
14
|
declare function $$render<T extends Record<string, unknown>>(): {
|
|
19
15
|
props: Omit<HTMLAttributes<HTMLDivElement>, "onselect"> & {
|
|
20
16
|
columns: TableColumn[];
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
focusRing,
|
|
5
|
+
toneBorder,
|
|
6
|
+
toneRing,
|
|
7
|
+
toneSoft,
|
|
8
|
+
toneText,
|
|
9
|
+
type Tone
|
|
10
|
+
} from '../../core/tones.js';
|
|
4
11
|
|
|
5
12
|
export interface TabItem {
|
|
6
13
|
value: string;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import Avatar from './Avatar.svelte';
|
|
5
|
+
import { toneBorderLeft, toneSurface, toneText, type Tone } from '../../core/tones.js';
|
|
6
|
+
|
|
7
|
+
export type TestimonialVariant = 'plain' | 'card' | 'accent';
|
|
8
|
+
|
|
9
|
+
interface Props extends HTMLAttributes<HTMLElement> {
|
|
10
|
+
quote: string;
|
|
11
|
+
author: string;
|
|
12
|
+
role?: string;
|
|
13
|
+
/** Avatar image. Falls back to the author's initials. */
|
|
14
|
+
avatar?: string;
|
|
15
|
+
tone?: Tone;
|
|
16
|
+
variant?: TestimonialVariant;
|
|
17
|
+
/** Bigger type, for a single pull quote. */
|
|
18
|
+
large?: boolean;
|
|
19
|
+
children?: Snippet;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let {
|
|
23
|
+
quote,
|
|
24
|
+
author,
|
|
25
|
+
role,
|
|
26
|
+
avatar,
|
|
27
|
+
tone = 'brand',
|
|
28
|
+
variant = 'plain',
|
|
29
|
+
large = false,
|
|
30
|
+
class: className = '',
|
|
31
|
+
children,
|
|
32
|
+
...rest
|
|
33
|
+
}: Props = $props();
|
|
34
|
+
|
|
35
|
+
const variants = $derived({
|
|
36
|
+
plain: '',
|
|
37
|
+
card: 'border border-hairline bg-bg p-6',
|
|
38
|
+
accent: `${toneSurface[tone]} border-l-2 ${toneBorderLeft[tone]} p-6`
|
|
39
|
+
});
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<figure class="flex flex-col gap-5 {variants[variant]} {className}" {...rest}>
|
|
43
|
+
<blockquote
|
|
44
|
+
class="font-sans leading-relaxed text-pretty text-text-secondary {large
|
|
45
|
+
? 'text-xl leading-relaxed sm:text-2xl'
|
|
46
|
+
: ''}"
|
|
47
|
+
>
|
|
48
|
+
<span class="{toneText[tone]} select-none" aria-hidden="true">“</span>{quote}<span
|
|
49
|
+
class="{toneText[tone]} select-none"
|
|
50
|
+
aria-hidden="true">”</span
|
|
51
|
+
>
|
|
52
|
+
</blockquote>
|
|
53
|
+
|
|
54
|
+
{#if children}
|
|
55
|
+
{@render children()}
|
|
56
|
+
{/if}
|
|
57
|
+
|
|
58
|
+
<figcaption class="flex items-center gap-3">
|
|
59
|
+
<Avatar src={avatar} name={author} size="sm" {tone} />
|
|
60
|
+
<div class="flex min-w-0 flex-col">
|
|
61
|
+
<span class="font-sans text-sm font-medium text-text">{author}</span>
|
|
62
|
+
{#if role}
|
|
63
|
+
<span class="font-sans text-xs text-text-muted">{role}</span>
|
|
64
|
+
{/if}
|
|
65
|
+
</div>
|
|
66
|
+
</figcaption>
|
|
67
|
+
</figure>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { type Tone } from '../../core/tones.js';
|
|
4
|
+
export type TestimonialVariant = 'plain' | 'card' | 'accent';
|
|
5
|
+
interface Props extends HTMLAttributes<HTMLElement> {
|
|
6
|
+
quote: string;
|
|
7
|
+
author: string;
|
|
8
|
+
role?: string;
|
|
9
|
+
/** Avatar image. Falls back to the author's initials. */
|
|
10
|
+
avatar?: string;
|
|
11
|
+
tone?: Tone;
|
|
12
|
+
variant?: TestimonialVariant;
|
|
13
|
+
/** Bigger type, for a single pull quote. */
|
|
14
|
+
large?: boolean;
|
|
15
|
+
children?: Snippet;
|
|
16
|
+
}
|
|
17
|
+
declare const Testimonial: import("svelte").Component<Props, {}, "">;
|
|
18
|
+
type Testimonial = ReturnType<typeof Testimonial>;
|
|
19
|
+
export default Testimonial;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLTextareaAttributes } from 'svelte/elements';
|
|
3
|
-
import { toneFocusBorder, type Tone } from '
|
|
3
|
+
import { toneFocusBorder, type Tone } from '../../core/tones.js';
|
|
4
4
|
|
|
5
5
|
interface Props extends HTMLTextareaAttributes {
|
|
6
6
|
value?: string;
|