@nqmcreative/ui 0.2.3 → 0.3.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 +15 -15
- package/cli/index.mjs +81 -42
- package/dist/core/toast.svelte.d.ts +3 -0
- package/dist/styles/matte/AccordionItem.svelte +5 -0
- package/dist/styles/matte/AccordionItem.svelte.d.ts +2 -0
- package/dist/styles/matte/Avatar.svelte +15 -0
- package/dist/styles/matte/Avatar.svelte.d.ts +3 -0
- package/dist/styles/matte/Badge.svelte +5 -0
- package/dist/styles/matte/Badge.svelte.d.ts +2 -0
- package/dist/styles/matte/Breadcrumb.svelte +11 -4
- package/dist/styles/matte/Breadcrumb.svelte.d.ts +3 -0
- package/dist/styles/matte/Button.svelte +58 -7
- package/dist/styles/matte/Button.svelte.d.ts +14 -2
- package/dist/styles/matte/Card.svelte +6 -1
- package/dist/styles/matte/Card.svelte.d.ts +2 -0
- package/dist/styles/matte/CheckboxGroup.svelte +6 -0
- package/dist/styles/matte/CheckboxGroup.svelte.d.ts +2 -0
- package/dist/styles/matte/Combobox.svelte +5 -0
- package/dist/styles/matte/Combobox.svelte.d.ts +3 -0
- package/dist/styles/matte/CommandPalette.svelte +6 -0
- package/dist/styles/matte/CommandPalette.svelte.d.ts +3 -0
- package/dist/styles/matte/Drawer.svelte +5 -0
- package/dist/styles/matte/Drawer.svelte.d.ts +2 -0
- package/dist/styles/matte/Footer.svelte +6 -2
- package/dist/styles/matte/Footer.svelte.d.ts +2 -0
- package/dist/styles/matte/Link.svelte +9 -0
- package/dist/styles/matte/Link.svelte.d.ts +4 -0
- package/dist/styles/matte/MenuItem.svelte +2 -1
- package/dist/styles/matte/Modal.svelte +5 -0
- package/dist/styles/matte/Modal.svelte.d.ts +2 -0
- package/dist/styles/matte/MultiSelect.svelte +7 -1
- package/dist/styles/matte/MultiSelect.svelte.d.ts +3 -0
- package/dist/styles/matte/Navbar.svelte +18 -4
- package/dist/styles/matte/Navbar.svelte.d.ts +2 -0
- package/dist/styles/matte/PricingCard.svelte +16 -8
- package/dist/styles/matte/PricingCard.svelte.d.ts +2 -0
- package/dist/styles/matte/RadioGroup.svelte +6 -0
- package/dist/styles/matte/RadioGroup.svelte.d.ts +2 -0
- package/dist/styles/matte/SegmentedControl.svelte +16 -2
- package/dist/styles/matte/SegmentedControl.svelte.d.ts +5 -0
- package/dist/styles/matte/Sidebar.svelte +2 -1
- package/dist/styles/matte/Stat.svelte +8 -1
- package/dist/styles/matte/Stat.svelte.d.ts +3 -0
- package/dist/styles/matte/Steps.svelte +7 -0
- package/dist/styles/matte/Steps.svelte.d.ts +3 -0
- package/dist/styles/matte/Table.svelte +153 -97
- package/dist/styles/matte/Table.svelte.d.ts +12 -0
- package/dist/styles/matte/Tabs.svelte +5 -0
- package/dist/styles/matte/Tabs.svelte.d.ts +3 -0
- package/dist/styles/matte/Toaster.svelte +3 -0
- package/dist/styles/matte/icon.d.ts +21 -0
- package/dist/styles/matte/icon.js +21 -0
- package/dist/styles/matte/index.d.ts +0 -2
- package/dist/styles/matte/index.js +0 -2
- package/dist/styles/paper/AccordionItem.svelte +5 -0
- package/dist/styles/paper/AccordionItem.svelte.d.ts +2 -0
- package/dist/styles/paper/Avatar.svelte +15 -0
- package/dist/styles/paper/Avatar.svelte.d.ts +3 -0
- package/dist/styles/paper/Badge.svelte +5 -0
- package/dist/styles/paper/Badge.svelte.d.ts +2 -0
- package/dist/styles/paper/Breadcrumb.svelte +8 -4
- package/dist/styles/paper/Breadcrumb.svelte.d.ts +3 -0
- package/dist/styles/paper/Button.svelte +58 -7
- package/dist/styles/paper/Button.svelte.d.ts +14 -2
- package/dist/styles/paper/Card.svelte +6 -1
- package/dist/styles/paper/Card.svelte.d.ts +2 -0
- package/dist/styles/paper/CheckboxGroup.svelte +6 -0
- package/dist/styles/paper/CheckboxGroup.svelte.d.ts +2 -0
- package/dist/styles/paper/Combobox.svelte +5 -0
- package/dist/styles/paper/Combobox.svelte.d.ts +3 -0
- package/dist/styles/paper/CommandPalette.svelte +6 -0
- package/dist/styles/paper/CommandPalette.svelte.d.ts +3 -0
- package/dist/styles/paper/Drawer.svelte +5 -0
- package/dist/styles/paper/Drawer.svelte.d.ts +2 -0
- package/dist/styles/paper/Footer.svelte +6 -2
- package/dist/styles/paper/Footer.svelte.d.ts +2 -0
- package/dist/styles/paper/Link.svelte +9 -0
- package/dist/styles/paper/Link.svelte.d.ts +4 -0
- package/dist/styles/paper/MenuItem.svelte +2 -1
- package/dist/styles/paper/Modal.svelte +5 -0
- package/dist/styles/paper/Modal.svelte.d.ts +2 -0
- package/dist/styles/paper/MultiSelect.svelte +7 -1
- package/dist/styles/paper/MultiSelect.svelte.d.ts +3 -0
- package/dist/styles/paper/Navbar.svelte +18 -4
- package/dist/styles/paper/Navbar.svelte.d.ts +2 -0
- package/dist/styles/paper/PricingCard.svelte +23 -15
- package/dist/styles/paper/PricingCard.svelte.d.ts +2 -0
- package/dist/styles/paper/RadioGroup.svelte +6 -0
- package/dist/styles/paper/RadioGroup.svelte.d.ts +2 -0
- package/dist/styles/paper/SegmentedControl.svelte +16 -2
- package/dist/styles/paper/SegmentedControl.svelte.d.ts +5 -0
- package/dist/styles/paper/Sidebar.svelte +2 -1
- package/dist/styles/paper/Stat.svelte +8 -1
- package/dist/styles/paper/Stat.svelte.d.ts +3 -0
- package/dist/styles/paper/Steps.svelte +7 -0
- package/dist/styles/paper/Steps.svelte.d.ts +3 -0
- package/dist/styles/paper/Table.svelte +153 -97
- package/dist/styles/paper/Table.svelte.d.ts +12 -0
- package/dist/styles/paper/Tabs.svelte +5 -0
- package/dist/styles/paper/Tabs.svelte.d.ts +3 -0
- package/dist/styles/paper/Toaster.svelte +3 -0
- package/dist/styles/paper/icon.d.ts +21 -0
- package/dist/styles/paper/icon.js +21 -0
- package/dist/styles/paper/index.d.ts +0 -2
- package/dist/styles/paper/index.js +0 -2
- package/dist/styles/sprout/AccordionItem.svelte +5 -0
- package/dist/styles/sprout/AccordionItem.svelte.d.ts +2 -0
- package/dist/styles/sprout/Avatar.svelte +15 -0
- package/dist/styles/sprout/Avatar.svelte.d.ts +3 -0
- package/dist/styles/sprout/Badge.svelte +5 -0
- package/dist/styles/sprout/Badge.svelte.d.ts +2 -0
- package/dist/styles/sprout/Breadcrumb.svelte +8 -4
- package/dist/styles/sprout/Breadcrumb.svelte.d.ts +3 -0
- package/dist/styles/sprout/Button.svelte +58 -7
- package/dist/styles/sprout/Button.svelte.d.ts +14 -2
- package/dist/styles/sprout/Card.svelte +6 -1
- package/dist/styles/sprout/Card.svelte.d.ts +2 -0
- package/dist/styles/sprout/CheckboxGroup.svelte +6 -0
- package/dist/styles/sprout/CheckboxGroup.svelte.d.ts +2 -0
- package/dist/styles/sprout/Combobox.svelte +5 -0
- package/dist/styles/sprout/Combobox.svelte.d.ts +3 -0
- package/dist/styles/sprout/CommandPalette.svelte +6 -0
- package/dist/styles/sprout/CommandPalette.svelte.d.ts +3 -0
- package/dist/styles/sprout/Drawer.svelte +5 -0
- package/dist/styles/sprout/Drawer.svelte.d.ts +2 -0
- package/dist/styles/sprout/Footer.svelte +6 -2
- package/dist/styles/sprout/Footer.svelte.d.ts +2 -0
- package/dist/styles/sprout/Link.svelte +9 -0
- package/dist/styles/sprout/Link.svelte.d.ts +4 -0
- package/dist/styles/sprout/MenuItem.svelte +2 -1
- package/dist/styles/sprout/Modal.svelte +5 -0
- package/dist/styles/sprout/Modal.svelte.d.ts +2 -0
- package/dist/styles/sprout/MultiSelect.svelte +7 -1
- package/dist/styles/sprout/MultiSelect.svelte.d.ts +3 -0
- package/dist/styles/sprout/Navbar.svelte +18 -4
- package/dist/styles/sprout/Navbar.svelte.d.ts +2 -0
- package/dist/styles/sprout/PricingCard.svelte +23 -15
- package/dist/styles/sprout/PricingCard.svelte.d.ts +2 -0
- package/dist/styles/sprout/RadioGroup.svelte +6 -0
- package/dist/styles/sprout/RadioGroup.svelte.d.ts +2 -0
- package/dist/styles/sprout/SegmentedControl.svelte +16 -2
- package/dist/styles/sprout/SegmentedControl.svelte.d.ts +5 -0
- package/dist/styles/sprout/Sidebar.svelte +2 -1
- package/dist/styles/sprout/Stat.svelte +8 -1
- package/dist/styles/sprout/Stat.svelte.d.ts +3 -0
- package/dist/styles/sprout/Steps.svelte +7 -0
- package/dist/styles/sprout/Steps.svelte.d.ts +3 -0
- package/dist/styles/sprout/Table.svelte +153 -97
- package/dist/styles/sprout/Table.svelte.d.ts +12 -0
- package/dist/styles/sprout/Tabs.svelte +5 -0
- package/dist/styles/sprout/Tabs.svelte.d.ts +3 -0
- package/dist/styles/sprout/Toaster.svelte +3 -0
- package/dist/styles/sprout/icon.d.ts +21 -0
- package/dist/styles/sprout/icon.js +21 -0
- package/dist/styles/sprout/index.d.ts +0 -2
- package/dist/styles/sprout/index.js +0 -2
- package/package.json +2 -26
- package/registry.json +1 -35
- package/dist/styles/matte/NumberInput.svelte +0 -96
- package/dist/styles/matte/NumberInput.svelte.d.ts +0 -15
- package/dist/styles/matte/PasswordInput.svelte +0 -95
- package/dist/styles/matte/PasswordInput.svelte.d.ts +0 -12
- package/dist/styles/paper/NumberInput.svelte +0 -96
- package/dist/styles/paper/NumberInput.svelte.d.ts +0 -15
- package/dist/styles/paper/PasswordInput.svelte +0 -100
- package/dist/styles/paper/PasswordInput.svelte.d.ts +0 -12
- package/dist/styles/sprout/NumberInput.svelte +0 -97
- package/dist/styles/sprout/NumberInput.svelte.d.ts +0 -15
- package/dist/styles/sprout/PasswordInput.svelte +0 -101
- package/dist/styles/sprout/PasswordInput.svelte.d.ts +0 -12
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
import type { HTMLFieldsetAttributes } from 'svelte/elements';
|
|
4
4
|
import Checkbox from './Checkbox.svelte';
|
|
5
5
|
import type { Tone } from '../../core/tones.js';
|
|
6
|
+
import { iconLg } from './icon.js';
|
|
6
7
|
|
|
7
8
|
export interface CheckboxOption {
|
|
8
9
|
value: string;
|
|
9
10
|
label: string;
|
|
11
|
+
/** Leading icon, 20px. Drawn in `boxed` mode only. */
|
|
12
|
+
icon?: Snippet;
|
|
10
13
|
description?: string;
|
|
11
14
|
disabled?: boolean;
|
|
12
15
|
}
|
|
@@ -76,6 +79,9 @@
|
|
|
76
79
|
{checked ? 'border-text bg-bg-alt' : 'border-hairline hover:border-hairline-strong'}
|
|
77
80
|
{disabled ? 'pointer-events-none opacity-50' : ''}"
|
|
78
81
|
>
|
|
82
|
+
{#if option.icon}
|
|
83
|
+
<span class={iconLg}>{@render option.icon()}</span>
|
|
84
|
+
{/if}
|
|
79
85
|
<Checkbox
|
|
80
86
|
{checked}
|
|
81
87
|
{disabled}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { anchored } from '../../core/actions/anchor.js';
|
|
3
4
|
import { clickOutside, portal } from '../../core/actions/dismissable.js';
|
|
4
5
|
import { ListCursor, groupItems, matchQuery, revealIndex } from '../../core/list.svelte.js';
|
|
5
6
|
import { toneFocusWithinBorder, toneSoft, toneText, type Tone } from '../../core/tones.js';
|
|
6
7
|
import { useLocale } from '../../core/locale.svelte.js';
|
|
8
|
+
import { iconMd } from './icon.js';
|
|
7
9
|
|
|
8
10
|
export interface ComboboxOption {
|
|
9
11
|
value: string;
|
|
10
12
|
label: string;
|
|
13
|
+
/** Leading icon, 16px. */
|
|
14
|
+
icon?: Snippet;
|
|
11
15
|
/** Second line under the label. */
|
|
12
16
|
description?: string;
|
|
13
17
|
disabled?: boolean;
|
|
@@ -234,6 +238,7 @@
|
|
|
234
238
|
{index === active ? toneSoft[tone] : 'text-text-secondary'}"
|
|
235
239
|
>
|
|
236
240
|
<span class="flex items-center gap-2">
|
|
241
|
+
{#if option.icon}<span class={iconMd}>{@render option.icon()}</span>{/if}
|
|
237
242
|
<span class="min-w-0 flex-1 truncate">{option.label}</span>
|
|
238
243
|
{#if option.value === value}
|
|
239
244
|
<svg
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import { type Tone } from '../../core/tones.js';
|
|
2
3
|
export interface ComboboxOption {
|
|
3
4
|
value: string;
|
|
4
5
|
label: string;
|
|
6
|
+
/** Leading icon, 16px. */
|
|
7
|
+
icon?: Snippet;
|
|
5
8
|
/** Second line under the label. */
|
|
6
9
|
description?: string;
|
|
7
10
|
disabled?: boolean;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
2
4
|
export interface CommandItem {
|
|
3
5
|
id: string;
|
|
4
6
|
label: string;
|
|
7
|
+
/** Leading icon, 16px. */
|
|
8
|
+
icon?: Snippet;
|
|
5
9
|
/** Second line under the label. */
|
|
6
10
|
description?: string;
|
|
7
11
|
/** Items sharing a group are rendered under one heading. */
|
|
@@ -22,6 +26,7 @@
|
|
|
22
26
|
import { useLocale } from '../../core/locale.svelte.js';
|
|
23
27
|
import { toneSoft, type Tone } from '../../core/tones.js';
|
|
24
28
|
import { isTypingTarget } from '../../core/trigger.js';
|
|
29
|
+
import { iconMd } from './icon.js';
|
|
25
30
|
import Kbd from './Kbd.svelte';
|
|
26
31
|
|
|
27
32
|
interface Props {
|
|
@@ -218,6 +223,7 @@
|
|
|
218
223
|
{item.disabled ? 'pointer-events-none opacity-40' : ''}
|
|
219
224
|
{index === active ? toneSoft[tone] : 'text-text-secondary'}"
|
|
220
225
|
>
|
|
226
|
+
{#if item.icon}<span class={iconMd}>{@render item.icon()}</span>{/if}
|
|
221
227
|
<span class="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
222
228
|
<span class="truncate">{item.label}</span>
|
|
223
229
|
{#if item.description}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
export interface CommandItem {
|
|
2
3
|
id: string;
|
|
3
4
|
label: string;
|
|
5
|
+
/** Leading icon, 16px. */
|
|
6
|
+
icon?: Snippet;
|
|
4
7
|
/** Second line under the label. */
|
|
5
8
|
description?: string;
|
|
6
9
|
/** Items sharing a group are rendered under one heading. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
+
import { iconLg } from './icon.js';
|
|
3
4
|
import type { HTMLDialogAttributes } from 'svelte/elements';
|
|
4
5
|
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
6
|
import { isBackdropClick, syncDialog } from '../../core/dialog.svelte.js';
|
|
@@ -15,6 +16,8 @@
|
|
|
15
16
|
size?: DrawerSize;
|
|
16
17
|
title?: string;
|
|
17
18
|
description?: string;
|
|
19
|
+
/** Leading icon beside the title. */
|
|
20
|
+
icon?: Snippet;
|
|
18
21
|
dismissible?: boolean;
|
|
19
22
|
footer?: Snippet;
|
|
20
23
|
onclose?: () => void;
|
|
@@ -27,6 +30,7 @@
|
|
|
27
30
|
size = 'md',
|
|
28
31
|
title,
|
|
29
32
|
description,
|
|
33
|
+
icon,
|
|
30
34
|
dismissible = true,
|
|
31
35
|
footer,
|
|
32
36
|
onclose,
|
|
@@ -92,6 +96,7 @@
|
|
|
92
96
|
<div class="flex h-full flex-col">
|
|
93
97
|
{#if title || dismissible}
|
|
94
98
|
<div class="flex items-start gap-4 border-b border-hairline px-5 py-4">
|
|
99
|
+
{#if icon}<span class={iconLg}>{@render icon()}</span>{/if}
|
|
95
100
|
<div class="flex min-w-0 flex-1 flex-col gap-1">
|
|
96
101
|
{#if title}
|
|
97
102
|
<h2 class="font-heading text-lg font-medium tracking-tight">{title}</h2>
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
export interface FooterLink {
|
|
3
3
|
label: string;
|
|
4
4
|
href?: string;
|
|
5
|
+
/** Leading icon, 14px. */
|
|
6
|
+
icon?: Snippet;
|
|
5
7
|
external?: boolean;
|
|
6
8
|
}
|
|
7
9
|
|
|
@@ -14,6 +16,7 @@
|
|
|
14
16
|
<script lang="ts">
|
|
15
17
|
import type { Snippet } from 'svelte';
|
|
16
18
|
import { toneHoverText, type Tone } from '../../core/tones.js';
|
|
19
|
+
import { iconSm } from './icon.js';
|
|
17
20
|
|
|
18
21
|
interface Props {
|
|
19
22
|
columns?: FooterColumn[];
|
|
@@ -59,11 +62,12 @@
|
|
|
59
62
|
href={item.href}
|
|
60
63
|
target={item.external ? '_blank' : undefined}
|
|
61
64
|
rel={item.external ? 'noreferrer' : undefined}
|
|
62
|
-
class="font-sans text-sm text-text-secondary transition-colors duration-150 ease-brand-out {toneHoverText[
|
|
65
|
+
class="inline-flex items-center gap-2 font-sans text-sm text-text-secondary transition-colors duration-150 ease-brand-out {toneHoverText[
|
|
63
66
|
tone
|
|
64
67
|
]}"
|
|
65
68
|
>
|
|
66
|
-
{item.
|
|
69
|
+
{#if item.icon}<span class={iconSm}>{@render item.icon()}</span
|
|
70
|
+
>{/if}{item.label}
|
|
67
71
|
{#if item.external}<span aria-hidden="true" class="text-[0.85em]">↗</span
|
|
68
72
|
>{/if}
|
|
69
73
|
</a>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
4
4
|
import { focusRing, toneHoverText, toneRing, toneText, type Tone } from '../../core/tones.js';
|
|
5
|
+
import { iconSm } from './icon.js';
|
|
5
6
|
|
|
6
7
|
interface Props extends HTMLAnchorAttributes {
|
|
7
8
|
tone?: Tone;
|
|
@@ -11,6 +12,10 @@
|
|
|
11
12
|
external?: boolean;
|
|
12
13
|
/** Inherit the surrounding text colour instead of the tone. */
|
|
13
14
|
muted?: boolean;
|
|
15
|
+
/** Leading icon, 14px. */
|
|
16
|
+
icon?: Snippet;
|
|
17
|
+
/** Trailing icon, before the external mark. */
|
|
18
|
+
iconEnd?: Snippet;
|
|
14
19
|
children: Snippet;
|
|
15
20
|
}
|
|
16
21
|
|
|
@@ -19,6 +24,8 @@
|
|
|
19
24
|
underline = 'hover',
|
|
20
25
|
external = false,
|
|
21
26
|
muted = false,
|
|
27
|
+
icon,
|
|
28
|
+
iconEnd,
|
|
22
29
|
class: className = '',
|
|
23
30
|
children,
|
|
24
31
|
...rest
|
|
@@ -39,6 +46,8 @@
|
|
|
39
46
|
{underlines[underline]} {focusRing} {toneRing[tone]} {className}"
|
|
40
47
|
{...rest}
|
|
41
48
|
>
|
|
49
|
+
{#if icon}<span class={iconSm}>{@render icon()}</span>{/if}
|
|
42
50
|
{@render children()}
|
|
51
|
+
{#if iconEnd}<span class={iconSm}>{@render iconEnd()}</span>{/if}
|
|
43
52
|
{#if external}<span aria-hidden="true" class="text-[0.85em]">↗</span>{/if}
|
|
44
53
|
</a>
|
|
@@ -9,6 +9,10 @@ interface Props extends HTMLAnchorAttributes {
|
|
|
9
9
|
external?: boolean;
|
|
10
10
|
/** Inherit the surrounding text colour instead of the tone. */
|
|
11
11
|
muted?: boolean;
|
|
12
|
+
/** Leading icon, 14px. */
|
|
13
|
+
icon?: Snippet;
|
|
14
|
+
/** Trailing icon, before the external mark. */
|
|
15
|
+
iconEnd?: Snippet;
|
|
12
16
|
children: Snippet;
|
|
13
17
|
}
|
|
14
18
|
declare const Link: import("svelte").Component<Props, {}, "">;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
4
4
|
import { toneSoftHover, toneText, type Tone } from '../../core/tones.js';
|
|
5
|
+
import { iconMd } from './icon.js';
|
|
5
6
|
|
|
6
7
|
interface Props extends HTMLButtonAttributes {
|
|
7
8
|
/** Renders an `<a>` instead of a `<button>`. */
|
|
@@ -49,7 +50,7 @@
|
|
|
49
50
|
<path d="m2 7 3.2 3.2L12 3.6" stroke="currentColor" stroke-width="1.6" />
|
|
50
51
|
</svg>
|
|
51
52
|
{:else if icon}
|
|
52
|
-
<span class=
|
|
53
|
+
<span class={iconMd}>{@render icon()}</span>
|
|
53
54
|
{/if}
|
|
54
55
|
<span class="min-w-0 flex-1 truncate">{@render children()}</span>
|
|
55
56
|
{#if shortcut}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
+
import { iconLg } from './icon.js';
|
|
3
4
|
import type { HTMLDialogAttributes } from 'svelte/elements';
|
|
4
5
|
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
6
|
import { isBackdropClick, syncDialog } from '../../core/dialog.svelte.js';
|
|
@@ -11,6 +12,8 @@
|
|
|
11
12
|
open?: boolean;
|
|
12
13
|
title?: string;
|
|
13
14
|
description?: string;
|
|
15
|
+
/** Leading icon beside the title. */
|
|
16
|
+
icon?: Snippet;
|
|
14
17
|
size?: ModalSize;
|
|
15
18
|
/** Clicking the backdrop or pressing Escape closes the dialog. */
|
|
16
19
|
dismissible?: boolean;
|
|
@@ -26,6 +29,7 @@
|
|
|
26
29
|
open = $bindable(false),
|
|
27
30
|
title,
|
|
28
31
|
description,
|
|
32
|
+
icon,
|
|
29
33
|
size = 'md',
|
|
30
34
|
dismissible = true,
|
|
31
35
|
showClose,
|
|
@@ -75,6 +79,7 @@
|
|
|
75
79
|
<div class="flex flex-col">
|
|
76
80
|
{#if title || closable}
|
|
77
81
|
<div class="flex items-start gap-4 border-b border-hairline px-5 py-4">
|
|
82
|
+
{#if icon}<span class={iconLg}>{@render icon()}</span>{/if}
|
|
78
83
|
<div class="flex min-w-0 flex-1 flex-col gap-1">
|
|
79
84
|
{#if title}
|
|
80
85
|
<h2 class="font-heading text-lg font-medium tracking-tight">{title}</h2>
|
|
@@ -6,6 +6,8 @@ interface Props extends HTMLDialogAttributes {
|
|
|
6
6
|
open?: boolean;
|
|
7
7
|
title?: string;
|
|
8
8
|
description?: string;
|
|
9
|
+
/** Leading icon beside the title. */
|
|
10
|
+
icon?: Snippet;
|
|
9
11
|
size?: ModalSize;
|
|
10
12
|
/** Clicking the backdrop or pressing Escape closes the dialog. */
|
|
11
13
|
dismissible?: boolean;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
2
4
|
export interface MultiSelectOption {
|
|
3
5
|
value: string;
|
|
4
6
|
label: string;
|
|
7
|
+
/** Leading icon, 16px. */
|
|
8
|
+
icon?: Snippet;
|
|
5
9
|
description?: string;
|
|
6
10
|
disabled?: boolean;
|
|
7
11
|
group?: string;
|
|
@@ -13,6 +17,7 @@
|
|
|
13
17
|
import { clickOutside, portal } from '../../core/actions/dismissable.js';
|
|
14
18
|
import { ListCursor, groupItems, matchQuery, revealIndex } from '../../core/list.svelte.js';
|
|
15
19
|
import { useLocale } from '../../core/locale.svelte.js';
|
|
20
|
+
import { iconMd, iconSm } from './icon.js';
|
|
16
21
|
import { toneFocusWithinBorder, toneSoft, toneText, type Tone } from '../../core/tones.js';
|
|
17
22
|
|
|
18
23
|
interface Props {
|
|
@@ -153,7 +158,7 @@
|
|
|
153
158
|
tone
|
|
154
159
|
]}"
|
|
155
160
|
>
|
|
156
|
-
{option.label}
|
|
161
|
+
{#if option.icon}<span class={iconSm}>{@render option.icon()}</span>{/if}{option.label}
|
|
157
162
|
<button
|
|
158
163
|
type="button"
|
|
159
164
|
onclick={() => remove(option)}
|
|
@@ -259,6 +264,7 @@
|
|
|
259
264
|
</svg>
|
|
260
265
|
{/if}
|
|
261
266
|
</span>
|
|
267
|
+
{#if option.icon}<span class={iconMd}>{@render option.icon()}</span>{/if}
|
|
262
268
|
<span class="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
263
269
|
<span class="truncate">{option.label}</span>
|
|
264
270
|
{#if option.description}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
export interface NavItem {
|
|
3
3
|
label: string;
|
|
4
4
|
href?: string;
|
|
5
|
+
/** Leading icon, 16px. */
|
|
6
|
+
icon?: Snippet;
|
|
5
7
|
/** Marks the current page — also sets `aria-current`. */
|
|
6
8
|
active?: boolean;
|
|
7
9
|
disabled?: boolean;
|
|
@@ -15,6 +17,7 @@
|
|
|
15
17
|
<script lang="ts">
|
|
16
18
|
import type { Snippet } from 'svelte';
|
|
17
19
|
import { useLocale } from '../../core/locale.svelte.js';
|
|
20
|
+
import { iconMd } from './icon.js';
|
|
18
21
|
import { focusRing, toneRing, toneText, type Tone } from '../../core/tones.js';
|
|
19
22
|
import Drawer from './Drawer.svelte';
|
|
20
23
|
import Dropdown from './Dropdown.svelte';
|
|
@@ -82,6 +85,7 @@
|
|
|
82
85
|
? toneText[tone]
|
|
83
86
|
: 'text-text-secondary hover:text-text'}"
|
|
84
87
|
>
|
|
88
|
+
{#if item.icon}<span class={iconMd}>{@render item.icon()}</span>{/if}
|
|
85
89
|
{item.label}
|
|
86
90
|
<svg class="size-3" viewBox="0 0 16 16" fill="none" aria-hidden="true">
|
|
87
91
|
<path
|
|
@@ -94,7 +98,12 @@
|
|
|
94
98
|
</button>
|
|
95
99
|
{/snippet}
|
|
96
100
|
{#each item.items as child (child.label)}
|
|
97
|
-
<MenuItem
|
|
101
|
+
<MenuItem
|
|
102
|
+
href={child.href}
|
|
103
|
+
disabled={child.disabled}
|
|
104
|
+
selected={child.active}
|
|
105
|
+
icon={child.icon}
|
|
106
|
+
>
|
|
98
107
|
{child.label}
|
|
99
108
|
</MenuItem>
|
|
100
109
|
{/each}
|
|
@@ -109,6 +118,7 @@
|
|
|
109
118
|
? 'pointer-events-none opacity-50'
|
|
110
119
|
: ''}"
|
|
111
120
|
>
|
|
121
|
+
{#if item.icon}<span class={iconMd}>{@render item.icon()}</span>{/if}
|
|
112
122
|
{item.label}
|
|
113
123
|
{#if item.badge !== undefined}
|
|
114
124
|
<span class="font-mono text-[11px] text-text-muted">{item.badge}</span>
|
|
@@ -154,7 +164,10 @@
|
|
|
154
164
|
? toneText[tone]
|
|
155
165
|
: 'text-text-secondary'} {item.disabled ? 'pointer-events-none opacity-50' : ''}"
|
|
156
166
|
>
|
|
157
|
-
|
|
167
|
+
<span class="flex min-w-0 items-center gap-2.5">
|
|
168
|
+
{#if item.icon}<span class={iconMd}>{@render item.icon()}</span>{/if}
|
|
169
|
+
{item.label}
|
|
170
|
+
</span>
|
|
158
171
|
{#if item.badge !== undefined}
|
|
159
172
|
<span class="font-mono text-[11px] text-text-muted">{item.badge}</span>
|
|
160
173
|
{/if}
|
|
@@ -166,9 +179,10 @@
|
|
|
166
179
|
<a
|
|
167
180
|
href={child.href}
|
|
168
181
|
onclick={() => (menuOpen = false)}
|
|
169
|
-
class="
|
|
182
|
+
class="flex items-center gap-2.5 py-2 font-sans text-sm text-text-muted"
|
|
170
183
|
>
|
|
171
|
-
{child.
|
|
184
|
+
{#if child.icon}<span class={iconMd}>{@render child.icon()}</span
|
|
185
|
+
>{/if}{child.label}
|
|
172
186
|
</a>
|
|
173
187
|
</li>
|
|
174
188
|
{/each}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
4
|
import { toneBorder, toneFill, toneSoft, toneText, type Tone } from '../../core/tones.js';
|
|
5
|
+
import { iconMd } from './icon.js';
|
|
5
6
|
|
|
6
7
|
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
7
8
|
name: string;
|
|
@@ -12,6 +13,8 @@
|
|
|
12
13
|
description?: string;
|
|
13
14
|
/** One line each. Rendered with a tick. */
|
|
14
15
|
features?: string[];
|
|
16
|
+
/** Replaces the tick beside every feature. */
|
|
17
|
+
featureIcon?: Snippet;
|
|
15
18
|
/** Pill in the top corner, e.g. "Most popular". */
|
|
16
19
|
badge?: string;
|
|
17
20
|
/** Thicker border and a tinted header — for the plan you want chosen. */
|
|
@@ -29,6 +32,7 @@
|
|
|
29
32
|
period,
|
|
30
33
|
description,
|
|
31
34
|
features = [],
|
|
35
|
+
featureIcon,
|
|
32
36
|
badge,
|
|
33
37
|
featured = false,
|
|
34
38
|
tone = 'brand',
|
|
@@ -83,14 +87,18 @@
|
|
|
83
87
|
<ul class="flex flex-1 flex-col gap-3 border-t border-hairline p-5">
|
|
84
88
|
{#each features as feature (feature)}
|
|
85
89
|
<li class="flex items-start gap-3 font-sans text-sm text-text-secondary">
|
|
86
|
-
|
|
87
|
-
class="mt-0.5
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
{#if featureIcon}
|
|
91
|
+
<span class="mt-0.5 {iconMd}">{@render featureIcon()}</span>
|
|
92
|
+
{:else}
|
|
93
|
+
<svg
|
|
94
|
+
class="mt-0.5 size-4 shrink-0 {toneText[tone]}"
|
|
95
|
+
viewBox="0 0 16 16"
|
|
96
|
+
fill="none"
|
|
97
|
+
aria-hidden="true"
|
|
98
|
+
>
|
|
99
|
+
<path d="m3 8 3.2 3.2L13 4.4" stroke="currentColor" stroke-width="1.6" />
|
|
100
|
+
</svg>
|
|
101
|
+
{/if}
|
|
94
102
|
<span class="leading-snug">{feature}</span>
|
|
95
103
|
</li>
|
|
96
104
|
{/each}
|
|
@@ -10,6 +10,8 @@ interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
|
10
10
|
description?: string;
|
|
11
11
|
/** One line each. Rendered with a tick. */
|
|
12
12
|
features?: string[];
|
|
13
|
+
/** Replaces the tick beside every feature. */
|
|
14
|
+
featureIcon?: Snippet;
|
|
13
15
|
/** Pill in the top corner, e.g. "Most popular". */
|
|
14
16
|
badge?: string;
|
|
15
17
|
/** Thicker border and a tinted header — for the plan you want chosen. */
|
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
import type { HTMLFieldsetAttributes } from 'svelte/elements';
|
|
4
4
|
import Radio from './Radio.svelte';
|
|
5
5
|
import type { Tone } from '../../core/tones.js';
|
|
6
|
+
import { iconLg } from './icon.js';
|
|
6
7
|
|
|
7
8
|
export interface RadioOption {
|
|
8
9
|
value: string;
|
|
9
10
|
label: string;
|
|
11
|
+
/** Leading icon, 20px. Drawn in `boxed` mode only. */
|
|
12
|
+
icon?: Snippet;
|
|
10
13
|
description?: string;
|
|
11
14
|
disabled?: boolean;
|
|
12
15
|
}
|
|
@@ -60,6 +63,9 @@
|
|
|
60
63
|
{value === option.value ? 'border-text bg-bg-alt' : 'border-hairline hover:border-hairline-strong'}
|
|
61
64
|
{option.disabled ? 'pointer-events-none opacity-50' : ''}"
|
|
62
65
|
>
|
|
66
|
+
{#if option.icon}
|
|
67
|
+
<span class={iconLg}>{@render option.icon()}</span>
|
|
68
|
+
{/if}
|
|
63
69
|
<Radio
|
|
64
70
|
bind:group={value}
|
|
65
71
|
value={option.value}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
4
|
import { focusRing, toneRing, toneSoft, type Tone } from '../../core/tones.js';
|
|
5
|
+
import { iconMd } from './icon.js';
|
|
4
6
|
|
|
5
7
|
export interface SegmentOption {
|
|
6
8
|
value: string;
|
|
7
9
|
label: string;
|
|
10
|
+
/** Leading icon, 16px. */
|
|
11
|
+
icon?: Snippet;
|
|
8
12
|
disabled?: boolean;
|
|
9
13
|
}
|
|
10
14
|
|
|
@@ -20,6 +24,8 @@
|
|
|
20
24
|
tone?: Tone;
|
|
21
25
|
/** Spread the segments evenly across the full width. */
|
|
22
26
|
fullWidth?: boolean;
|
|
27
|
+
/** Icons only — each option's `label` becomes its accessible name. */
|
|
28
|
+
iconOnly?: boolean;
|
|
23
29
|
label?: string;
|
|
24
30
|
disabled?: boolean;
|
|
25
31
|
onchange?: (value: string) => void;
|
|
@@ -32,6 +38,7 @@
|
|
|
32
38
|
size = 'md',
|
|
33
39
|
tone = 'brand',
|
|
34
40
|
fullWidth = false,
|
|
41
|
+
iconOnly = false,
|
|
35
42
|
label,
|
|
36
43
|
disabled = false,
|
|
37
44
|
class: className = '',
|
|
@@ -44,6 +51,11 @@
|
|
|
44
51
|
md: 'h-9 px-3.5 text-sm'
|
|
45
52
|
};
|
|
46
53
|
|
|
54
|
+
const squares: Record<SegmentedSize, string> = {
|
|
55
|
+
sm: 'size-8 text-[13px]',
|
|
56
|
+
md: 'size-9 text-sm'
|
|
57
|
+
};
|
|
58
|
+
|
|
47
59
|
function select(option: SegmentOption) {
|
|
48
60
|
if (option.disabled || disabled) return;
|
|
49
61
|
value = option.value;
|
|
@@ -74,14 +86,16 @@
|
|
|
74
86
|
type="button"
|
|
75
87
|
role="radio"
|
|
76
88
|
aria-checked={value === option.value}
|
|
89
|
+
aria-label={iconOnly ? option.label : undefined}
|
|
77
90
|
disabled={option.disabled || disabled}
|
|
78
91
|
tabindex={value === option.value ? 0 : -1}
|
|
79
92
|
onclick={() => select(option)}
|
|
80
93
|
class="inline-flex items-center justify-center font-sans whitespace-nowrap transition-colors duration-150 ease-brand-out disabled:pointer-events-none disabled:opacity-40
|
|
81
|
-
{sizes[size]} {focusRing} {toneRing[tone]}
|
|
94
|
+
{iconOnly ? squares[size] : sizes[size]} {focusRing} {toneRing[tone]}
|
|
82
95
|
{value === option.value ? `${toneSoft[tone]} font-medium` : 'text-text-secondary hover:text-text'}"
|
|
83
96
|
>
|
|
84
|
-
{option.
|
|
97
|
+
{#if option.icon}<span class={iconMd}>{@render option.icon()}</span>{/if}
|
|
98
|
+
{#if !iconOnly}{option.label}{/if}
|
|
85
99
|
</button>
|
|
86
100
|
{/each}
|
|
87
101
|
{#if name}<input type="hidden" {name} {value} />{/if}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
3
|
import { type Tone } from '../../core/tones.js';
|
|
3
4
|
export interface SegmentOption {
|
|
4
5
|
value: string;
|
|
5
6
|
label: string;
|
|
7
|
+
/** Leading icon, 16px. */
|
|
8
|
+
icon?: Snippet;
|
|
6
9
|
disabled?: boolean;
|
|
7
10
|
}
|
|
8
11
|
export type SegmentedSize = 'sm' | 'md';
|
|
@@ -16,6 +19,8 @@ interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'onchange'> {
|
|
|
16
19
|
tone?: Tone;
|
|
17
20
|
/** Spread the segments evenly across the full width. */
|
|
18
21
|
fullWidth?: boolean;
|
|
22
|
+
/** Icons only — each option's `label` becomes its accessible name. */
|
|
23
|
+
iconOnly?: boolean;
|
|
19
24
|
label?: string;
|
|
20
25
|
disabled?: boolean;
|
|
21
26
|
onchange?: (value: string) => void;
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
<script lang="ts">
|
|
38
38
|
import { useLocale } from '../../core/locale.svelte.js';
|
|
39
|
+
import { iconMd } from './icon.js';
|
|
39
40
|
import { focusRing, toneRing, toneSoft, type Tone } from '../../core/tones.js';
|
|
40
41
|
|
|
41
42
|
interface Props {
|
|
@@ -126,7 +127,7 @@
|
|
|
126
127
|
<!-- One box for every glyph, so rows line up whether or not an item has one. -->
|
|
127
128
|
{#snippet glyph(item: SidebarItem)}
|
|
128
129
|
{#if item.icon}
|
|
129
|
-
<span class=
|
|
130
|
+
<span class={iconMd}>{@render item.icon()}</span>
|
|
130
131
|
{/if}
|
|
131
132
|
{/snippet}
|
|
132
133
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
4
|
import { toneText, type Tone } from '../../core/tones.js';
|
|
5
|
+
import { iconMd } from './icon.js';
|
|
4
6
|
|
|
5
7
|
export type StatTrend = 'up' | 'down' | 'flat';
|
|
6
8
|
|
|
@@ -11,6 +13,8 @@
|
|
|
11
13
|
delta?: string;
|
|
12
14
|
trend?: StatTrend;
|
|
13
15
|
hint?: string;
|
|
16
|
+
/** Leading icon on the label row. */
|
|
17
|
+
icon?: Snippet;
|
|
14
18
|
/** Colour of the value itself. Leave unset for plain `text`. */
|
|
15
19
|
tone?: Tone;
|
|
16
20
|
}
|
|
@@ -21,6 +25,7 @@
|
|
|
21
25
|
delta,
|
|
22
26
|
trend = 'flat',
|
|
23
27
|
hint,
|
|
28
|
+
icon,
|
|
24
29
|
tone,
|
|
25
30
|
class: className = '',
|
|
26
31
|
...rest
|
|
@@ -31,7 +36,9 @@
|
|
|
31
36
|
</script>
|
|
32
37
|
|
|
33
38
|
<div class="flex flex-col gap-1 font-sans {className}" {...rest}>
|
|
34
|
-
<span class="font-mono text-xs tracking-wide text-text-muted uppercase"
|
|
39
|
+
<span class="flex items-center gap-2 font-mono text-xs tracking-wide text-text-muted uppercase"
|
|
40
|
+
>{#if icon}<span class={iconMd}>{@render icon()}</span>{/if}{label}</span
|
|
41
|
+
>
|
|
35
42
|
<div class="flex items-baseline gap-2">
|
|
36
43
|
<span
|
|
37
44
|
class="font-heading text-3xl font-medium tracking-tight {tone ? toneText[tone] : 'text-text'}"
|