@nqmcreative/ui 0.4.0 → 0.4.2
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 +17 -19
- package/dist/core/calendar.d.ts +1 -1
- package/dist/core/calendar.js +1 -1
- package/dist/core/date.d.ts +3 -3
- package/dist/core/date.js +1 -1
- package/dist/core/files.d.ts +2 -3
- package/dist/core/files.js +2 -3
- package/dist/core/index.d.ts +2 -4
- package/dist/core/index.js +2 -4
- package/dist/core/password.d.ts +1 -1
- package/dist/core/password.js +1 -1
- package/dist/core/tones.d.ts +10 -0
- package/dist/core/tones.js +19 -0
- package/dist/core/trigger.d.ts +8 -0
- package/dist/core/trigger.js +11 -0
- package/dist/styles/matte/Alert.svelte +2 -4
- package/dist/styles/matte/Avatar.svelte +16 -3
- package/dist/styles/matte/Breadcrumb.svelte +1 -4
- package/dist/styles/matte/Button.svelte +6 -2
- package/dist/styles/matte/Calendar.svelte +6 -9
- package/dist/styles/matte/Checkbox.svelte +49 -30
- package/dist/styles/matte/CheckboxGroup.svelte +15 -4
- package/dist/styles/matte/ColorInput.svelte +1 -4
- package/dist/styles/matte/Combobox.svelte +14 -8
- package/dist/styles/matte/CommandPalette.svelte +3 -6
- package/dist/styles/matte/ConfirmDialog.svelte +11 -6
- package/dist/styles/matte/ContextMenu.svelte +1 -4
- package/dist/styles/matte/CurrencyInput.svelte +1 -1
- package/dist/styles/matte/CurrencyInput.svelte.d.ts +1 -1
- package/dist/styles/matte/DatePicker.svelte +18 -11
- package/dist/styles/matte/DatePicker.svelte.d.ts +3 -0
- package/dist/styles/matte/Divider.svelte +1 -1
- package/dist/styles/matte/Drawer.svelte +11 -5
- package/dist/styles/matte/Dropdown.svelte +2 -5
- package/dist/styles/matte/Dropdown.svelte.d.ts +1 -1
- package/dist/styles/matte/Dropzone.svelte +9 -12
- package/dist/styles/matte/Dropzone.svelte.d.ts +1 -1
- package/dist/styles/matte/Field.svelte +59 -3
- package/dist/styles/matte/FileInput.svelte +11 -14
- package/dist/styles/matte/FileInput.svelte.d.ts +2 -2
- package/dist/styles/matte/Footer.svelte +15 -4
- package/dist/styles/matte/Footer.svelte.d.ts +1 -1
- package/dist/styles/matte/Input.svelte +9 -2
- package/dist/styles/matte/Label.svelte +3 -1
- package/dist/styles/matte/Link.svelte +13 -2
- package/dist/styles/matte/MenuItem.svelte +11 -4
- package/dist/styles/matte/Modal.svelte +11 -5
- package/dist/styles/matte/MultiSelect.svelte +5 -8
- package/dist/styles/matte/Navbar.svelte +5 -11
- package/dist/styles/matte/Pagination.svelte +3 -6
- package/dist/styles/matte/PinInput.svelte +1 -4
- package/dist/styles/matte/Radio.svelte +41 -22
- package/dist/styles/matte/RadioGroup.svelte +15 -4
- package/dist/styles/matte/SearchInput.svelte +1 -4
- package/dist/styles/matte/Select.svelte +4 -2
- package/dist/styles/matte/Sidebar.svelte +3 -6
- package/dist/styles/matte/Skeleton.svelte +2 -1
- package/dist/styles/matte/Spinner.svelte +2 -5
- package/dist/styles/matte/Spinner.svelte.d.ts +1 -1
- package/dist/styles/matte/Stat.svelte +27 -3
- package/dist/styles/matte/Switch.svelte +6 -1
- package/dist/styles/matte/Table.svelte +5 -8
- package/dist/styles/matte/Tabs.svelte +1 -1
- package/dist/styles/matte/TagsInput.svelte +5 -8
- package/dist/styles/matte/Textarea.svelte +4 -2
- package/dist/styles/matte/ThemeToggle.svelte +5 -8
- package/dist/styles/matte/TimeInput.svelte +2 -5
- package/dist/styles/matte/Toaster.svelte +23 -8
- package/dist/styles/matte/Tooltip.svelte +8 -1
- package/dist/styles/matte/index.d.ts +2 -3
- package/dist/styles/matte/index.js +1 -3
- package/dist/styles/matte/theme.css +21 -0
- package/dist/styles/paper/Alert.svelte +3 -5
- package/dist/styles/paper/Avatar.svelte +14 -3
- package/dist/styles/paper/Breadcrumb.svelte +1 -4
- package/dist/styles/paper/Button.svelte +5 -1
- package/dist/styles/paper/Calendar.svelte +6 -9
- package/dist/styles/paper/Card.svelte +1 -1
- package/dist/styles/paper/Checkbox.svelte +55 -36
- package/dist/styles/paper/CheckboxGroup.svelte +15 -4
- package/dist/styles/paper/ColorInput.svelte +1 -4
- package/dist/styles/paper/Combobox.svelte +14 -8
- package/dist/styles/paper/CommandPalette.svelte +3 -6
- package/dist/styles/paper/ConfirmDialog.svelte +9 -6
- package/dist/styles/paper/ContextMenu.svelte +1 -4
- package/dist/styles/paper/CurrencyInput.svelte +1 -1
- package/dist/styles/paper/CurrencyInput.svelte.d.ts +1 -1
- package/dist/styles/paper/DatePicker.svelte +18 -11
- package/dist/styles/paper/DatePicker.svelte.d.ts +3 -0
- package/dist/styles/paper/Divider.svelte +1 -1
- package/dist/styles/paper/Drawer.svelte +9 -5
- package/dist/styles/paper/Dropdown.svelte +2 -5
- package/dist/styles/paper/Dropdown.svelte.d.ts +1 -1
- package/dist/styles/paper/Dropzone.svelte +9 -12
- package/dist/styles/paper/Dropzone.svelte.d.ts +1 -1
- package/dist/styles/paper/Field.svelte +59 -3
- package/dist/styles/paper/FileInput.svelte +11 -14
- package/dist/styles/paper/FileInput.svelte.d.ts +2 -2
- package/dist/styles/paper/Footer.svelte +15 -4
- package/dist/styles/paper/Footer.svelte.d.ts +1 -1
- package/dist/styles/paper/Input.svelte +9 -2
- package/dist/styles/paper/Label.svelte +3 -1
- package/dist/styles/paper/Link.svelte +13 -2
- package/dist/styles/paper/MenuItem.svelte +11 -4
- package/dist/styles/paper/Modal.svelte +9 -5
- package/dist/styles/paper/MultiSelect.svelte +5 -8
- package/dist/styles/paper/Navbar.svelte +5 -11
- package/dist/styles/paper/Pagination.svelte +3 -6
- package/dist/styles/paper/PinInput.svelte +1 -4
- package/dist/styles/paper/Radio.svelte +41 -22
- package/dist/styles/paper/RadioGroup.svelte +15 -4
- package/dist/styles/paper/SearchInput.svelte +1 -4
- package/dist/styles/paper/SegmentedControl.svelte +2 -2
- package/dist/styles/paper/Select.svelte +4 -2
- package/dist/styles/paper/Sidebar.svelte +3 -6
- package/dist/styles/paper/Skeleton.svelte +2 -1
- package/dist/styles/paper/Spinner.svelte +2 -5
- package/dist/styles/paper/Spinner.svelte.d.ts +1 -1
- package/dist/styles/paper/Stat.svelte +24 -2
- package/dist/styles/paper/Switch.svelte +6 -1
- package/dist/styles/paper/Table.svelte +5 -8
- package/dist/styles/paper/Tabs.svelte +1 -1
- package/dist/styles/paper/TagsInput.svelte +5 -8
- package/dist/styles/paper/Textarea.svelte +4 -2
- package/dist/styles/paper/ThemeToggle.svelte +5 -8
- package/dist/styles/paper/TimeInput.svelte +2 -5
- package/dist/styles/paper/Toaster.svelte +22 -9
- package/dist/styles/paper/Tooltip.svelte +8 -1
- package/dist/styles/paper/index.d.ts +2 -3
- package/dist/styles/paper/index.js +1 -3
- package/dist/styles/paper/theme.css +21 -0
- package/dist/styles/sprout/Alert.svelte +4 -6
- package/dist/styles/sprout/Avatar.svelte +14 -3
- package/dist/styles/sprout/Breadcrumb.svelte +2 -5
- package/dist/styles/sprout/Button.svelte +8 -4
- package/dist/styles/sprout/Calendar.svelte +7 -10
- package/dist/styles/sprout/Card.svelte +2 -2
- package/dist/styles/sprout/Checkbox.svelte +55 -36
- package/dist/styles/sprout/CheckboxGroup.svelte +15 -4
- package/dist/styles/sprout/ColorInput.svelte +2 -5
- package/dist/styles/sprout/Combobox.svelte +15 -9
- package/dist/styles/sprout/CommandPalette.svelte +3 -6
- package/dist/styles/sprout/ConfirmDialog.svelte +9 -6
- package/dist/styles/sprout/ContextMenu.svelte +1 -4
- package/dist/styles/sprout/CurrencyInput.svelte +1 -1
- package/dist/styles/sprout/CurrencyInput.svelte.d.ts +1 -1
- package/dist/styles/sprout/DatePicker.svelte +20 -13
- package/dist/styles/sprout/DatePicker.svelte.d.ts +3 -0
- package/dist/styles/sprout/Divider.svelte +1 -1
- package/dist/styles/sprout/Drawer.svelte +9 -5
- package/dist/styles/sprout/Dropdown.svelte +2 -5
- package/dist/styles/sprout/Dropdown.svelte.d.ts +1 -1
- package/dist/styles/sprout/Dropzone.svelte +10 -13
- package/dist/styles/sprout/Dropzone.svelte.d.ts +1 -1
- package/dist/styles/sprout/Field.svelte +59 -3
- package/dist/styles/sprout/FileInput.svelte +14 -17
- package/dist/styles/sprout/FileInput.svelte.d.ts +2 -2
- package/dist/styles/sprout/Footer.svelte +15 -4
- package/dist/styles/sprout/Footer.svelte.d.ts +1 -1
- package/dist/styles/sprout/Input.svelte +9 -2
- package/dist/styles/sprout/Label.svelte +3 -1
- package/dist/styles/sprout/Link.svelte +13 -2
- package/dist/styles/sprout/LogoCloud.svelte +1 -1
- package/dist/styles/sprout/MenuItem.svelte +11 -4
- package/dist/styles/sprout/Modal.svelte +9 -5
- package/dist/styles/sprout/MultiSelect.svelte +8 -11
- package/dist/styles/sprout/Navbar.svelte +5 -11
- package/dist/styles/sprout/Pagination.svelte +3 -6
- package/dist/styles/sprout/PinInput.svelte +1 -4
- package/dist/styles/sprout/Radio.svelte +41 -22
- package/dist/styles/sprout/RadioGroup.svelte +15 -4
- package/dist/styles/sprout/SearchInput.svelte +2 -5
- package/dist/styles/sprout/SegmentedControl.svelte +2 -2
- package/dist/styles/sprout/Select.svelte +4 -2
- package/dist/styles/sprout/Sidebar.svelte +5 -7
- package/dist/styles/sprout/Skeleton.svelte +2 -1
- package/dist/styles/sprout/Spinner.svelte +2 -5
- package/dist/styles/sprout/Spinner.svelte.d.ts +1 -1
- package/dist/styles/sprout/Stat.svelte +24 -2
- package/dist/styles/sprout/Switch.svelte +6 -1
- package/dist/styles/sprout/Table.svelte +6 -9
- package/dist/styles/sprout/Tabs.svelte +1 -1
- package/dist/styles/sprout/TagsInput.svelte +6 -9
- package/dist/styles/sprout/Textarea.svelte +4 -2
- package/dist/styles/sprout/ThemeToggle.svelte +5 -8
- package/dist/styles/sprout/TimeInput.svelte +3 -6
- package/dist/styles/sprout/Toaster.svelte +25 -12
- package/dist/styles/sprout/Tooltip.svelte +8 -1
- package/dist/styles/sprout/index.d.ts +3 -4
- package/dist/styles/sprout/index.js +2 -4
- package/dist/styles/sprout/lift.d.ts +14 -0
- package/dist/styles/sprout/lift.js +23 -0
- package/dist/styles/sprout/theme.css +50 -24
- package/package.json +2 -19
- package/registry.json +7 -46
- package/dist/core/locale.svelte.d.ts +0 -101
- package/dist/core/locale.svelte.js +0 -167
- package/dist/styles/matte/LocaleProvider.svelte +0 -24
- package/dist/styles/matte/LocaleProvider.svelte.d.ts +0 -10
- package/dist/styles/paper/LocaleProvider.svelte +0 -24
- package/dist/styles/paper/LocaleProvider.svelte.d.ts +0 -10
- package/dist/styles/sprout/LocaleProvider.svelte +0 -24
- package/dist/styles/sprout/LocaleProvider.svelte.d.ts +0 -10
|
@@ -44,13 +44,24 @@
|
|
|
44
44
|
children,
|
|
45
45
|
...rest
|
|
46
46
|
}: Props = $props();
|
|
47
|
+
|
|
48
|
+
const uid = $props.id();
|
|
49
|
+
// The group's own hint and error sit outside every control in it, so the
|
|
50
|
+
// fieldset is what has to point at them.
|
|
51
|
+
const messageId = $derived(error ? `${uid}-error` : hint ? `${uid}-hint` : undefined);
|
|
47
52
|
</script>
|
|
48
53
|
|
|
49
|
-
<fieldset
|
|
54
|
+
<fieldset
|
|
55
|
+
aria-describedby={messageId}
|
|
56
|
+
class="flex flex-col gap-3 border-0 p-0 {className}"
|
|
57
|
+
{...rest}
|
|
58
|
+
>
|
|
50
59
|
{#if legend}
|
|
51
60
|
<legend class="mb-1 font-sans text-sm font-medium text-text">
|
|
52
61
|
{legend}
|
|
53
|
-
{#if required}<span class="ml-0.5 text-danger" aria-hidden="true">*</span
|
|
62
|
+
{#if required}<span class="ml-0.5 text-danger" aria-hidden="true">*</span><span
|
|
63
|
+
class="sr-only">(required)</span
|
|
64
|
+
>{/if}
|
|
54
65
|
</legend>
|
|
55
66
|
{/if}
|
|
56
67
|
|
|
@@ -94,8 +105,8 @@
|
|
|
94
105
|
</div>
|
|
95
106
|
|
|
96
107
|
{#if error}
|
|
97
|
-
<p class="font-sans text-[13px] text-danger">{error}</p>
|
|
108
|
+
<p id="{uid}-error" role="alert" class="font-sans text-[13px] text-danger">{error}</p>
|
|
98
109
|
{:else if hint}
|
|
99
|
-
<p class="font-sans text-[13px] text-text-muted">{hint}</p>
|
|
110
|
+
<p id="{uid}-hint" class="font-sans text-[13px] text-text-muted">{hint}</p>
|
|
100
111
|
{/if}
|
|
101
112
|
</fieldset>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
4
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
4
|
import type { Tone } from '../../core/tones.js';
|
|
6
5
|
import Input, { type InputSize } from './Input.svelte';
|
|
7
6
|
|
|
@@ -37,8 +36,6 @@
|
|
|
37
36
|
...rest
|
|
38
37
|
}: Props = $props();
|
|
39
38
|
|
|
40
|
-
const t = useLocale();
|
|
41
|
-
|
|
42
39
|
// The timer is cleared by the effect's own teardown, so a keystroke that
|
|
43
40
|
// lands mid-wait restarts the clock rather than queueing a second call.
|
|
44
41
|
$effect(() => {
|
|
@@ -75,7 +72,7 @@
|
|
|
75
72
|
<button
|
|
76
73
|
type="button"
|
|
77
74
|
onclick={clear}
|
|
78
|
-
aria-label=
|
|
75
|
+
aria-label="Clear search"
|
|
79
76
|
class="-mr-1 rounded p-1 text-text-muted transition-colors duration-150 hover:bg-bg-inset hover:text-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current"
|
|
80
77
|
>
|
|
81
78
|
<svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
-
import { focusRing, toneRing, type Tone } from '../../core/tones.js';
|
|
4
|
+
import { focusRing, toneRing, toneText, type Tone } from '../../core/tones.js';
|
|
5
5
|
import { iconMd } from './icon.js';
|
|
6
6
|
|
|
7
7
|
export interface SegmentOption {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
onclick={() => select(option)}
|
|
93
93
|
class="inline-flex items-center justify-center rounded-md font-sans font-medium whitespace-nowrap transition-all duration-150 ease-brand-out disabled:pointer-events-none disabled:opacity-40
|
|
94
94
|
{iconOnly ? squares[size] : sizes[size]} {focusRing} {toneRing[tone]}
|
|
95
|
-
{value === option.value ?
|
|
95
|
+
{value === option.value ? `bg-bg ${toneText[tone]} shadow-xs` : 'text-text-muted hover:text-text'}"
|
|
96
96
|
>
|
|
97
97
|
{#if option.icon}<span class={iconMd}>{@render option.icon()}</span>{/if}
|
|
98
98
|
{#if !iconOnly}{option.label}{/if}
|
|
@@ -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 '../../core/tones.js';
|
|
4
|
+
import { focusRing, toneFocusBorder, toneRing, type Tone } from '../../core/tones.js';
|
|
5
5
|
|
|
6
6
|
export interface SelectOption {
|
|
7
7
|
value: string;
|
|
@@ -35,7 +35,9 @@
|
|
|
35
35
|
<select
|
|
36
36
|
bind:value
|
|
37
37
|
aria-invalid={invalid ? 'true' : undefined}
|
|
38
|
-
class="
|
|
38
|
+
class="{focusRing} {toneRing[
|
|
39
|
+
tone
|
|
40
|
+
]} h-10 w-full appearance-none rounded-md border bg-bg py-0 pr-9 pl-3 font-sans text-sm text-text shadow-xs transition-colors duration-150 ease-brand-out disabled:pointer-events-none disabled:opacity-50
|
|
39
41
|
{invalid ? 'border-danger' : `border-hairline-strong ${toneFocusBorder[tone]}`} {className}"
|
|
40
42
|
{...rest}
|
|
41
43
|
>
|
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
</script>
|
|
36
36
|
|
|
37
37
|
<script lang="ts">
|
|
38
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
39
38
|
import { iconMd } from './icon.js';
|
|
40
39
|
import { focusRing, toneRing, toneSoft, type Tone } from '../../core/tones.js';
|
|
41
40
|
|
|
@@ -69,8 +68,6 @@
|
|
|
69
68
|
class: className = ''
|
|
70
69
|
}: Props = $props();
|
|
71
70
|
|
|
72
|
-
const t = useLocale();
|
|
73
|
-
|
|
74
71
|
const keyOf = (item: SidebarItem) => item.id ?? item.href ?? item.label;
|
|
75
72
|
|
|
76
73
|
/** Groups start open when asked, or when they contain the active item. */
|
|
@@ -141,7 +138,7 @@
|
|
|
141
138
|
</div>
|
|
142
139
|
{/if}
|
|
143
140
|
|
|
144
|
-
<nav aria-label=
|
|
141
|
+
<nav aria-label="Navigation" class="flex-1 overflow-y-auto p-2">
|
|
145
142
|
{#each sections as section, i (section.label ?? i)}
|
|
146
143
|
<div class="flex flex-col gap-0.5 {i > 0 ? 'mt-4' : ''}">
|
|
147
144
|
{#if section.label && !collapsed}
|
|
@@ -230,7 +227,7 @@
|
|
|
230
227
|
<button
|
|
231
228
|
type="button"
|
|
232
229
|
onclick={() => (collapsed = !collapsed)}
|
|
233
|
-
aria-label={collapsed ?
|
|
230
|
+
aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
|
|
234
231
|
class="inline-flex h-8 items-center justify-center gap-2 rounded-md font-sans text-xs text-text-muted transition-colors duration-150 hover:bg-bg-inset hover:text-text {focusRing} {toneRing[
|
|
235
232
|
tone
|
|
236
233
|
]}"
|
|
@@ -248,7 +245,7 @@
|
|
|
248
245
|
stroke-linecap="round"
|
|
249
246
|
/>
|
|
250
247
|
</svg>
|
|
251
|
-
{#if !collapsed}<span>
|
|
248
|
+
{#if !collapsed}<span>Collapse sidebar</span>{/if}
|
|
252
249
|
</button>
|
|
253
250
|
{/if}
|
|
254
251
|
</div>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
</script>
|
|
30
30
|
|
|
31
31
|
{#if variant === 'text' && lines > 1}
|
|
32
|
-
<div class="flex w-full flex-col gap-2 {className}" {...rest}>
|
|
32
|
+
<div aria-hidden="true" class="flex w-full flex-col gap-2 {className}" {...rest}>
|
|
33
33
|
{#each { length: lines }, i (i)}
|
|
34
34
|
<div
|
|
35
35
|
class="h-4 animate-pulse rounded-md bg-bg-inset {i === lines - 1 ? 'w-2/3' : 'w-full'}"
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
</div>
|
|
40
40
|
{:else}
|
|
41
41
|
<div
|
|
42
|
+
aria-hidden="true"
|
|
42
43
|
class="animate-pulse bg-bg-inset {variants[variant]} {className}"
|
|
43
44
|
style="{width ? `width:${width};` : ''}{height ? `height:${height};` : ''}"
|
|
44
45
|
{...rest}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
3
|
import { toneText, type Tone } from '../../core/tones.js';
|
|
4
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
4
|
|
|
6
5
|
export type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
7
6
|
|
|
@@ -9,12 +8,10 @@
|
|
|
9
8
|
size?: SpinnerSize;
|
|
10
9
|
/** Omit to inherit the parent's `currentColor` (e.g. inside a Button). */
|
|
11
10
|
tone?: Tone;
|
|
12
|
-
/** Defaults to
|
|
11
|
+
/** Defaults to `Loading`; pass `''` to hide it. */
|
|
13
12
|
label?: string;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
const t = useLocale();
|
|
17
|
-
|
|
18
15
|
let { size = 'md', tone, label, class: className = '', ...rest }: Props = $props();
|
|
19
16
|
|
|
20
17
|
const sizes: Record<SpinnerSize, string> = {
|
|
@@ -27,7 +24,7 @@
|
|
|
27
24
|
|
|
28
25
|
<span
|
|
29
26
|
role="status"
|
|
30
|
-
aria-label={label ??
|
|
27
|
+
aria-label={label ?? 'Loading'}
|
|
31
28
|
class="inline-block shrink-0 animate-spin rounded-full border-current/25 border-t-current
|
|
32
29
|
{sizes[size]} {tone ? toneText[tone] : ''} {className}"
|
|
33
30
|
{...rest}
|
|
@@ -5,7 +5,7 @@ interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
|
5
5
|
size?: SpinnerSize;
|
|
6
6
|
/** Omit to inherit the parent's `currentColor` (e.g. inside a Button). */
|
|
7
7
|
tone?: Tone;
|
|
8
|
-
/** Defaults to
|
|
8
|
+
/** Defaults to `Loading`; pass `''` to hide it. */
|
|
9
9
|
label?: string;
|
|
10
10
|
}
|
|
11
11
|
declare const Spinner: import("svelte").Component<Props, {}, "">;
|
|
@@ -32,7 +32,15 @@
|
|
|
32
32
|
}: Props = $props();
|
|
33
33
|
|
|
34
34
|
const trendTone: Record<StatTrend, Tone> = { up: 'success', down: 'danger', flat: 'neutral' };
|
|
35
|
-
|
|
35
|
+
// Drawn rather than typed. `↑` renders in whatever face the reader's system
|
|
36
|
+
// substitutes for it and is announced as "up arrow" or nothing at all, and
|
|
37
|
+
// the colour beside it says nothing either — so the word ships with it.
|
|
38
|
+
const trendPath: Record<StatTrend, string> = {
|
|
39
|
+
up: 'M7 11V3.5M7 3l3.5 3.5M7 3 3.5 6.5',
|
|
40
|
+
down: 'M7 3v7.5M7 11l3.5-3.5M7 11 3.5 7.5',
|
|
41
|
+
flat: 'M3 7h7.5M11 7 7.5 3.5M11 7l-3.5 3.5'
|
|
42
|
+
};
|
|
43
|
+
const trendWord: Record<StatTrend, string> = { up: 'up', down: 'down', flat: 'no change' };
|
|
36
44
|
</script>
|
|
37
45
|
|
|
38
46
|
<div class="flex flex-col gap-1 font-sans {className}" {...rest}>
|
|
@@ -49,7 +57,21 @@
|
|
|
49
57
|
</span>
|
|
50
58
|
{#if delta}
|
|
51
59
|
<span class="text-sm font-medium {toneText[trendTone[trend]]}">
|
|
52
|
-
|
|
60
|
+
<svg
|
|
61
|
+
class="inline-block size-[1em] align-[-0.115em]"
|
|
62
|
+
viewBox="0 0 14 14"
|
|
63
|
+
fill="none"
|
|
64
|
+
aria-hidden="true"
|
|
65
|
+
>
|
|
66
|
+
<path
|
|
67
|
+
d={trendPath[trend]}
|
|
68
|
+
stroke="currentColor"
|
|
69
|
+
stroke-width="1.6"
|
|
70
|
+
stroke-linecap="round"
|
|
71
|
+
stroke-linejoin="round"
|
|
72
|
+
/>
|
|
73
|
+
</svg>
|
|
74
|
+
<span class="sr-only">{trendWord[trend]}</span>
|
|
53
75
|
{delta}
|
|
54
76
|
</span>
|
|
55
77
|
{/if}
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
md: { track: 'h-6 w-11', thumb: 'size-5', travel: 'translate-x-5' }
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
const uid = $props.id();
|
|
34
|
+
|
|
33
35
|
function toggle() {
|
|
34
36
|
checked = !checked;
|
|
35
37
|
onchange?.(checked);
|
|
@@ -42,6 +44,7 @@
|
|
|
42
44
|
role="switch"
|
|
43
45
|
aria-checked={checked}
|
|
44
46
|
aria-label={label}
|
|
47
|
+
aria-describedby={description ? `${uid}-description` : undefined}
|
|
45
48
|
{disabled}
|
|
46
49
|
onclick={toggle}
|
|
47
50
|
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
|
|
@@ -57,7 +60,9 @@
|
|
|
57
60
|
<span class="flex flex-col gap-0.5 font-sans text-sm">
|
|
58
61
|
{#if label}<span class="leading-snug text-text">{label}</span>{/if}
|
|
59
62
|
{#if description}
|
|
60
|
-
<span class="text-[13px] leading-snug text-text-muted"
|
|
63
|
+
<span id="{uid}-description" class="text-[13px] leading-snug text-text-muted"
|
|
64
|
+
>{description}</span
|
|
65
|
+
>
|
|
61
66
|
{/if}
|
|
62
67
|
</span>
|
|
63
68
|
{/if}
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
import Checkbox from './Checkbox.svelte';
|
|
17
17
|
import type { Tone } from '../../core/tones.js';
|
|
18
18
|
import { nextSort, sortRows, toggleKey, type TableSort } from '../../core/table.js';
|
|
19
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
20
19
|
|
|
21
20
|
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'onselect'> {
|
|
22
21
|
columns: TableColumn[];
|
|
@@ -82,8 +81,6 @@
|
|
|
82
81
|
...rest
|
|
83
82
|
}: Props = $props();
|
|
84
83
|
|
|
85
|
-
const t = useLocale();
|
|
86
|
-
|
|
87
84
|
const aligns = {
|
|
88
85
|
left: 'text-left',
|
|
89
86
|
center: 'text-center',
|
|
@@ -139,14 +136,14 @@
|
|
|
139
136
|
>
|
|
140
137
|
<span class="font-sans text-[13px] font-semibold text-text">
|
|
141
138
|
{selected.length}
|
|
142
|
-
|
|
139
|
+
selected
|
|
143
140
|
</span>
|
|
144
141
|
<button
|
|
145
142
|
type="button"
|
|
146
143
|
onclick={clearSelection}
|
|
147
144
|
class="rounded font-sans text-[13px] font-medium text-text-muted transition-colors duration-150 hover:text-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current"
|
|
148
145
|
>
|
|
149
|
-
|
|
146
|
+
Clear selection
|
|
150
147
|
</button>
|
|
151
148
|
<div class="ml-auto flex flex-wrap items-center gap-2">
|
|
152
149
|
{@render bulkActions?.({ selected, clear: clearSelection })}
|
|
@@ -176,7 +173,7 @@
|
|
|
176
173
|
checked={allSelected}
|
|
177
174
|
indeterminate={someSelected}
|
|
178
175
|
{tone}
|
|
179
|
-
aria-label=
|
|
176
|
+
aria-label="Select all rows"
|
|
180
177
|
onchange={toggleAll}
|
|
181
178
|
/>
|
|
182
179
|
</th>
|
|
@@ -223,7 +220,7 @@
|
|
|
223
220
|
colspan={columns.length + (selectable ? 1 : 0)}
|
|
224
221
|
class="px-4 py-10 text-center text-sm text-text-muted"
|
|
225
222
|
>
|
|
226
|
-
{#if empty}{@render empty()}{:else}{
|
|
223
|
+
{#if empty}{@render empty()}{:else}No data{/if}
|
|
227
224
|
</td>
|
|
228
225
|
</tr>
|
|
229
226
|
{:else}
|
|
@@ -240,7 +237,7 @@
|
|
|
240
237
|
<Checkbox
|
|
241
238
|
checked={isSelected}
|
|
242
239
|
{tone}
|
|
243
|
-
aria-label=
|
|
240
|
+
aria-label="Select row"
|
|
244
241
|
onchange={() => toggleRow(row)}
|
|
245
242
|
/>
|
|
246
243
|
</td>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
3
2
|
import { addTag, splitTags, type TagRejection } from '../../core/tags.js';
|
|
4
3
|
import { toneFocusWithinBorder, toneSoft, type Tone } from '../../core/tones.js';
|
|
5
4
|
|
|
@@ -46,8 +45,6 @@
|
|
|
46
45
|
class: className = ''
|
|
47
46
|
}: Props = $props();
|
|
48
47
|
|
|
49
|
-
const t = useLocale();
|
|
50
|
-
|
|
51
48
|
let draft = $state('');
|
|
52
49
|
let field: HTMLInputElement | null = $state(null);
|
|
53
50
|
/** The last refusal, cleared as soon as the next keystroke lands. */
|
|
@@ -111,8 +108,8 @@
|
|
|
111
108
|
const messages: Record<TagRejection, string> = $derived({
|
|
112
109
|
empty: '',
|
|
113
110
|
short: `${minLength}+`,
|
|
114
|
-
duplicate:
|
|
115
|
-
full: `$
|
|
111
|
+
duplicate: 'Already added',
|
|
112
|
+
full: `$selected ${tags.length}/${max}`
|
|
116
113
|
});
|
|
117
114
|
</script>
|
|
118
115
|
|
|
@@ -136,7 +133,7 @@
|
|
|
136
133
|
<button
|
|
137
134
|
type="button"
|
|
138
135
|
onclick={() => remove(index)}
|
|
139
|
-
aria-label="
|
|
136
|
+
aria-label="Remove {tag}"
|
|
140
137
|
class="inline-flex size-4 items-center justify-center rounded transition-colors duration-150 hover:bg-bg/70 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-current"
|
|
141
138
|
>
|
|
142
139
|
<svg class="size-2.5" viewBox="0 0 10 10" fill="none" aria-hidden="true">
|
|
@@ -156,8 +153,8 @@
|
|
|
156
153
|
bind:value={draft}
|
|
157
154
|
{disabled}
|
|
158
155
|
readonly={full}
|
|
159
|
-
placeholder={tags.length === 0 ? (placeholder ??
|
|
160
|
-
aria-label={placeholder ??
|
|
156
|
+
placeholder={tags.length === 0 ? (placeholder ?? 'Add a tag') : ''}
|
|
157
|
+
aria-label={placeholder ?? 'Add a tag'}
|
|
161
158
|
aria-invalid={invalid ? 'true' : undefined}
|
|
162
159
|
onkeydown={onKeydown}
|
|
163
160
|
onpaste={onPaste}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLTextareaAttributes } from 'svelte/elements';
|
|
3
|
-
import { toneFocusBorder, type Tone } from '../../core/tones.js';
|
|
3
|
+
import { focusRing, toneFocusBorder, toneRing, type Tone } from '../../core/tones.js';
|
|
4
4
|
|
|
5
5
|
interface Props extends HTMLTextareaAttributes {
|
|
6
6
|
value?: string;
|
|
@@ -48,7 +48,9 @@
|
|
|
48
48
|
bind:value
|
|
49
49
|
{rows}
|
|
50
50
|
aria-invalid={invalid ? 'true' : undefined}
|
|
51
|
-
class="
|
|
51
|
+
class="{focusRing} {toneRing[
|
|
52
|
+
tone
|
|
53
|
+
]} w-full rounded-md border bg-bg px-3 py-2 font-sans text-sm text-text shadow-xs transition-colors duration-150 ease-brand-out placeholder:text-text-muted disabled:pointer-events-none disabled:opacity-50
|
|
52
54
|
{autoresize ? 'resize-none overflow-hidden' : 'resize-y'}
|
|
53
55
|
{invalid ? 'border-danger' : `border-hairline-strong ${toneFocusBorder[tone]}`} {className}"
|
|
54
56
|
{...rest}></textarea>
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
storedTheme,
|
|
11
11
|
type Theme
|
|
12
12
|
} from '../../core/theme.svelte.js';
|
|
13
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
14
13
|
|
|
15
14
|
interface Props {
|
|
16
15
|
/** Bindable. `'system'` follows the OS until the visitor chooses. */
|
|
@@ -33,8 +32,6 @@
|
|
|
33
32
|
class: className = ''
|
|
34
33
|
}: Props = $props();
|
|
35
34
|
|
|
36
|
-
const t = useLocale();
|
|
37
|
-
|
|
38
35
|
$effect(() => {
|
|
39
36
|
applyTheme(theme);
|
|
40
37
|
if (persist) persistTheme(theme);
|
|
@@ -50,8 +47,8 @@
|
|
|
50
47
|
}
|
|
51
48
|
|
|
52
49
|
const options = $derived([
|
|
53
|
-
{ value: 'light' as Theme, label:
|
|
54
|
-
{ value: 'dark' as Theme, label:
|
|
50
|
+
{ value: 'light' as Theme, label: 'Light' },
|
|
51
|
+
{ value: 'dark' as Theme, label: 'Dark' },
|
|
55
52
|
{ value: 'system' as Theme, label: 'Auto' }
|
|
56
53
|
]);
|
|
57
54
|
</script>
|
|
@@ -95,7 +92,7 @@
|
|
|
95
92
|
{#if variant === 'segmented'}
|
|
96
93
|
<div
|
|
97
94
|
role="radiogroup"
|
|
98
|
-
aria-label=
|
|
95
|
+
aria-label="Toggle theme"
|
|
99
96
|
class="inline-flex items-center gap-1 rounded-lg border border-hairline bg-bg-inset p-1 {className}"
|
|
100
97
|
>
|
|
101
98
|
{#each options as option (option.value)}
|
|
@@ -119,8 +116,8 @@
|
|
|
119
116
|
<button
|
|
120
117
|
type="button"
|
|
121
118
|
onclick={cycle}
|
|
122
|
-
aria-label="
|
|
123
|
-
title=
|
|
119
|
+
aria-label="Toggle theme ({theme})"
|
|
120
|
+
title="Toggle theme"
|
|
124
121
|
class="inline-flex size-9 items-center justify-center rounded-md border border-hairline bg-bg text-text-secondary shadow-xs transition-colors duration-150 ease-brand-out hover:bg-bg-alt hover:text-text {focusRing} {toneRing[
|
|
125
122
|
tone
|
|
126
123
|
]} {className}"
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
4
3
|
import { clampTime, formatTime, parseTime, stepTime } from '../../core/time.js';
|
|
5
4
|
import type { Tone } from '../../core/tones.js';
|
|
6
5
|
import Input, { type InputSize } from './Input.svelte';
|
|
@@ -38,8 +37,6 @@
|
|
|
38
37
|
...rest
|
|
39
38
|
}: Props = $props();
|
|
40
39
|
|
|
41
|
-
const t = useLocale();
|
|
42
|
-
|
|
43
40
|
// Typed text and the bound value are separate until the field settles:
|
|
44
41
|
// `9` is a valid thing to be halfway through typing and an invalid time.
|
|
45
42
|
let text = $state('');
|
|
@@ -120,7 +117,7 @@
|
|
|
120
117
|
class={stepper}
|
|
121
118
|
{disabled}
|
|
122
119
|
onclick={() => nudge(1)}
|
|
123
|
-
aria-label=
|
|
120
|
+
aria-label="Increase"
|
|
124
121
|
>
|
|
125
122
|
<svg class="size-3" viewBox="0 0 12 12" fill="none" aria-hidden="true">
|
|
126
123
|
<path
|
|
@@ -137,7 +134,7 @@
|
|
|
137
134
|
class={stepper}
|
|
138
135
|
{disabled}
|
|
139
136
|
onclick={() => nudge(-1)}
|
|
140
|
-
aria-label=
|
|
137
|
+
aria-label="Decrease"
|
|
141
138
|
>
|
|
142
139
|
<svg class="size-3" viewBox="0 0 12 12" fill="none" aria-hidden="true">
|
|
143
140
|
<path
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
import { toneText } from '../../core/tones.js';
|
|
7
7
|
import { iconMd } from './icon.js';
|
|
8
8
|
import Spinner from './Spinner.svelte';
|
|
9
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
10
9
|
|
|
11
10
|
export type ToasterPosition =
|
|
12
11
|
'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
|
|
@@ -18,8 +17,6 @@
|
|
|
18
17
|
|
|
19
18
|
let { position = 'bottom-right', class: className = '' }: Props = $props();
|
|
20
19
|
|
|
21
|
-
const t = useLocale();
|
|
22
|
-
|
|
23
20
|
const positions: Record<ToasterPosition, string> = {
|
|
24
21
|
'top-left': 'top-4 left-4 items-start',
|
|
25
22
|
'top-center': 'top-4 left-1/2 -translate-x-1/2 items-center',
|
|
@@ -33,16 +30,32 @@
|
|
|
33
30
|
const fromLeft = $derived(position.endsWith('left'));
|
|
34
31
|
const fromCenter = $derived(position.endsWith('center'));
|
|
35
32
|
|
|
33
|
+
/**
|
|
34
|
+
* A card sliding in from the edge of the screen, and a stack of them shuffling
|
|
35
|
+
* to make room, is exactly the motion this preference exists to stop. Under it
|
|
36
|
+
* the toast fades in place and the stack reorders instantly — the state change
|
|
37
|
+
* still reads, it just stops travelling.
|
|
38
|
+
*
|
|
39
|
+
* ponytail: read once at mount. Someone who flips the OS setting mid-session
|
|
40
|
+
* gets the new behaviour on the next load; a live listener is the upgrade.
|
|
41
|
+
*/
|
|
42
|
+
const stillness =
|
|
43
|
+
typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
44
|
+
|
|
36
45
|
const enter = $derived(
|
|
37
|
-
|
|
46
|
+
stillness
|
|
47
|
+
? { x: 0, y: 0 }
|
|
48
|
+
: fromCenter
|
|
49
|
+
? { y: fromTop ? -16 : 16, x: 0 }
|
|
50
|
+
: { x: fromLeft ? -16 : 16, y: 0 }
|
|
38
51
|
);
|
|
39
52
|
</script>
|
|
40
53
|
|
|
41
54
|
<div
|
|
42
55
|
use:portal
|
|
43
56
|
aria-live="polite"
|
|
44
|
-
aria-label=
|
|
45
|
-
class="pointer-events-none fixed z-
|
|
57
|
+
aria-label="Notifications"
|
|
58
|
+
class="pointer-events-none fixed z-100 flex w-[min(24rem,calc(100vw-2rem))] flex-col gap-2.5 {positions[
|
|
46
59
|
position
|
|
47
60
|
]} {fromTop ? '' : 'flex-col-reverse'} {className}"
|
|
48
61
|
>
|
|
@@ -53,7 +66,7 @@
|
|
|
53
66
|
would fight the page underneath.
|
|
54
67
|
-->
|
|
55
68
|
<div
|
|
56
|
-
animate:flip={{ duration: 200 }}
|
|
69
|
+
animate:flip={{ duration: stillness ? 0 : 200 }}
|
|
57
70
|
in:fly={{ ...enter, duration: 220 }}
|
|
58
71
|
out:fly={{ ...enter, duration: 160 }}
|
|
59
72
|
role={item.tone === 'danger' ? 'alert' : 'status'}
|
|
@@ -95,7 +108,7 @@
|
|
|
95
108
|
</span>
|
|
96
109
|
|
|
97
110
|
<div class="flex min-w-0 flex-1 flex-col gap-1">
|
|
98
|
-
<p class="text-sm leading-snug font-semibold text-text">{item.title}</p>
|
|
111
|
+
<p class="font-heading text-sm leading-snug font-semibold text-text">{item.title}</p>
|
|
99
112
|
{#if item.description}
|
|
100
113
|
<p class="text-[13px] leading-relaxed text-text-secondary">{item.description}</p>
|
|
101
114
|
{/if}
|
|
@@ -118,7 +131,7 @@
|
|
|
118
131
|
<button
|
|
119
132
|
type="button"
|
|
120
133
|
onclick={() => toast.dismiss(item.id)}
|
|
121
|
-
aria-label=
|
|
134
|
+
aria-label="Dismiss"
|
|
122
135
|
class="-m-1 shrink-0 rounded p-1 text-text-muted transition-colors duration-150 hover:bg-bg-inset hover:text-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current"
|
|
123
136
|
>
|
|
124
137
|
<svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
+
import { describedBy } from '../../core/trigger.js';
|
|
3
4
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
5
|
|
|
5
6
|
export type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
|
|
@@ -13,6 +14,11 @@
|
|
|
13
14
|
|
|
14
15
|
let { content, placement = 'top', class: className = '', children, ...rest }: Props = $props();
|
|
15
16
|
|
|
17
|
+
const uid = $props.id();
|
|
18
|
+
let wrapper: HTMLElement | null = $state(null);
|
|
19
|
+
|
|
20
|
+
$effect(() => describedBy(wrapper, `${uid}-tip`));
|
|
21
|
+
|
|
16
22
|
const placements: Record<TooltipPlacement, string> = {
|
|
17
23
|
top: 'bottom-full left-1/2 mb-1.5 -translate-x-1/2',
|
|
18
24
|
bottom: 'top-full left-1/2 mt-1.5 -translate-x-1/2',
|
|
@@ -21,9 +27,10 @@
|
|
|
21
27
|
};
|
|
22
28
|
</script>
|
|
23
29
|
|
|
24
|
-
<span class="group/tt relative inline-flex" {...rest}>
|
|
30
|
+
<span bind:this={wrapper} class="group/tt relative inline-flex" {...rest}>
|
|
25
31
|
{@render children()}
|
|
26
32
|
<span
|
|
33
|
+
id="{uid}-tip"
|
|
27
34
|
role="tooltip"
|
|
28
35
|
class="pointer-events-none invisible absolute z-50 rounded-md bg-text px-2 py-1 font-sans text-xs font-medium whitespace-nowrap text-text-inverse opacity-0 shadow-lg transition-opacity duration-150 ease-brand-out group-focus-within/tt:visible group-focus-within/tt:opacity-100 group-hover/tt:visible group-hover/tt:opacity-100
|
|
29
36
|
{placements[placement]} {className}"
|
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* `@nqmcreative/ui/core`, re-exported below so this one import covers
|
|
6
6
|
* the whole style.
|
|
7
7
|
*/
|
|
8
|
-
export { TONES, focusRing, peerFocusRing, toneBorder, toneBorderLeft, toneBorderSoft, toneFill, toneFocusBorder, toneFocusWithinBorder, toneHoverBorder, toneHoverText, tonePeerChecked, tonePeerFocus, toneRing, toneSoft, toneSoftHover, toneSolid, toneSolidHover, toneSurface, toneText, anchored, clickOutside, focusTrap, focusable, navigateList, portal, toast,
|
|
9
|
-
export type { Tone, Placement, AnchorOptions, ClickOutsideOptions, FocusTrapOptions, Toast, ToastOptions, ToastAction,
|
|
10
|
-
export { default as LocaleProvider } from './LocaleProvider.svelte';
|
|
8
|
+
export { TONES, focusRing, peerFocusRing, toneBorder, toneBorderLeft, toneBorderSoft, toneFill, toneFocusBorder, toneFocusWithinBorder, focusWithinRing, toneFocusWithinRing, toneHoverBorder, toneHoverText, tonePeerChecked, tonePeerFocus, toneRing, toneSoft, toneSoftHover, toneSolid, toneSolidHover, toneSurface, toneText, anchored, clickOutside, focusTrap, focusable, navigateList, portal, toast, applyTheme, storedTheme, toISO, fromISO, today, isSameDay, addDays, addMonths, monthGrid, weekdayNames, monthLabel, isOutOfRange, formatISO, parseFormatted } from '../../core/index.js';
|
|
9
|
+
export type { Tone, Placement, AnchorOptions, ClickOutsideOptions, FocusTrapOptions, Toast, ToastOptions, ToastAction, Theme, DateFormat, TableSort, SortDirection, RejectedFile } from '../../core/index.js';
|
|
11
10
|
export { default as Button } from './Button.svelte';
|
|
12
11
|
export type { ButtonVariant, ButtonSize } from './Button.svelte';
|
|
13
12
|
export { default as Link } from './Link.svelte';
|
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
* the whole style.
|
|
7
7
|
*/
|
|
8
8
|
/* --- shared behaviour --- */
|
|
9
|
-
export { TONES, focusRing, peerFocusRing, toneBorder, toneBorderLeft, toneBorderSoft, toneFill, toneFocusBorder, toneFocusWithinBorder, toneHoverBorder, toneHoverText, tonePeerChecked, tonePeerFocus, toneRing, toneSoft, toneSoftHover, toneSolid, toneSolidHover, toneSurface, toneText, anchored, clickOutside, focusTrap, focusable, navigateList, portal, toast,
|
|
10
|
-
/* --- locale --- */
|
|
11
|
-
export { default as LocaleProvider } from './LocaleProvider.svelte';
|
|
9
|
+
export { TONES, focusRing, peerFocusRing, toneBorder, toneBorderLeft, toneBorderSoft, toneFill, toneFocusBorder, toneFocusWithinBorder, focusWithinRing, toneFocusWithinRing, toneHoverBorder, toneHoverText, tonePeerChecked, tonePeerFocus, toneRing, toneSoft, toneSoftHover, toneSolid, toneSolidHover, toneSurface, toneText, anchored, clickOutside, focusTrap, focusable, navigateList, portal, toast, applyTheme, storedTheme, toISO, fromISO, today, isSameDay, addDays, addMonths, monthGrid, weekdayNames, monthLabel, isOutOfRange, formatISO, parseFormatted } from '../../core/index.js';
|
|
12
10
|
/* --- actions --- */
|
|
13
11
|
export { default as Button } from './Button.svelte';
|
|
14
12
|
export { default as Link } from './Link.svelte';
|
|
@@ -223,3 +223,24 @@
|
|
|
223
223
|
--color-neutral-border: #374151;
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
|
+
|
|
227
|
+
/*
|
|
228
|
+
* The surfaces the browser draws for us.
|
|
229
|
+
*
|
|
230
|
+
* A caret and a highlight in the user-agent's blue belong to no design system,
|
|
231
|
+
* and they are the two the reader touches most: one sits in every field they
|
|
232
|
+
* type into, the other appears the moment they drag across a paragraph. The
|
|
233
|
+
* selection is mixed from the brand rather than pinned to a token so it stays
|
|
234
|
+
* a wash — the text underneath keeps its own colour and its own contrast.
|
|
235
|
+
*/
|
|
236
|
+
@layer base {
|
|
237
|
+
::selection {
|
|
238
|
+
background-color: color-mix(in oklab, var(--color-brand) 24%, transparent);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
input,
|
|
242
|
+
textarea,
|
|
243
|
+
[contenteditable] {
|
|
244
|
+
caret-color: var(--color-brand);
|
|
245
|
+
}
|
|
246
|
+
}
|