@dorsk/tsumikit 0.73.2 → 0.75.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 +38 -1
- package/dist/autoresize.d.ts +2 -0
- package/dist/autoresize.js +8 -1
- package/dist/components/atoms/Artwork.svelte +12 -5
- package/dist/components/atoms/Avatar.svelte +1 -1
- package/dist/components/atoms/Badge.svelte +59 -23
- package/dist/components/atoms/Button.svelte +130 -96
- package/dist/components/atoms/Button.svelte.d.ts +2 -0
- package/dist/components/atoms/Card.svelte +10 -4
- package/dist/components/atoms/Checkbox.svelte +36 -9
- package/dist/components/atoms/Checkbox.svelte.d.ts +2 -0
- package/dist/components/atoms/Gauge.svelte +20 -14
- package/dist/components/atoms/Heading.svelte +1 -1
- package/dist/components/atoms/Icon.svelte +1 -0
- package/dist/components/atoms/Input.svelte +67 -13
- package/dist/components/atoms/Kbd.svelte +3 -3
- package/dist/components/atoms/Link.svelte +7 -2
- package/dist/components/atoms/Progress.svelte +12 -6
- package/dist/components/atoms/Scrim.svelte +3 -8
- package/dist/components/atoms/SegmentedProgress.svelte +5 -4
- package/dist/components/atoms/Select.svelte +58 -27
- package/dist/components/atoms/Skeleton.svelte +14 -8
- package/dist/components/atoms/Slider.svelte +79 -22
- package/dist/components/atoms/Slider.svelte.d.ts +2 -0
- package/dist/components/atoms/Spinner.svelte +464 -5
- package/dist/components/atoms/Spinner.svelte.d.ts +2 -0
- package/dist/components/atoms/Swatch.svelte +19 -8
- package/dist/components/atoms/Switch.svelte +34 -21
- package/dist/components/atoms/Switch.svelte.d.ts +2 -0
- package/dist/components/atoms/Text.svelte +1 -1
- package/dist/components/atoms/Textarea.svelte +34 -12
- package/dist/components/atoms/TimeDisplay.svelte +4 -2
- package/dist/components/layouts/AppShell.svelte +26 -15
- package/dist/components/layouts/MasterDetail.svelte +23 -21
- package/dist/components/layouts/NavBar.svelte +11 -8
- package/dist/components/layouts/NavItem.svelte +15 -7
- package/dist/components/layouts/NavSection.svelte +1 -1
- package/dist/components/layouts/ResizablePanel.svelte +37 -16
- package/dist/components/layouts/TabBar.svelte +24 -14
- package/dist/components/layouts/TabBar.svelte.d.ts +2 -0
- package/dist/components/molecules/Accordion.svelte +4 -0
- package/dist/components/molecules/Accordion.svelte.d.ts +2 -0
- package/dist/components/molecules/AttachmentList.svelte +14 -11
- package/dist/components/molecules/Breadcrumb.svelte +13 -9
- package/dist/components/molecules/Callout.svelte +3 -3
- package/dist/components/molecules/CapBar.svelte +23 -22
- package/dist/components/molecules/Carousel.svelte +27 -17
- package/dist/components/molecules/ChatBubble.svelte +2 -2
- package/dist/components/molecules/CodeBlock.svelte +2 -2
- package/dist/components/molecules/Combobox.svelte +30 -1
- package/dist/components/molecules/Combobox.svelte.d.ts +4 -0
- package/dist/components/molecules/Composer.svelte +2 -2
- package/dist/components/molecules/ConfirmModal.svelte +4 -0
- package/dist/components/molecules/ConfirmModal.svelte.d.ts +2 -0
- package/dist/components/molecules/CopyButton.svelte +46 -2
- package/dist/components/molecules/CopyButton.svelte.d.ts +2 -0
- package/dist/components/molecules/Disclosure.svelte +23 -12
- package/dist/components/molecules/Disclosure.svelte.d.ts +2 -0
- package/dist/components/molecules/Drawer.svelte +43 -23
- package/dist/components/molecules/Drawer.svelte.d.ts +2 -0
- package/dist/components/molecules/Dropzone.svelte +24 -8
- package/dist/components/molecules/EmojiPicker.svelte +27 -8
- package/dist/components/molecules/EmojiPicker.svelte.d.ts +2 -0
- package/dist/components/molecules/EmptyState.svelte +5 -5
- package/dist/components/molecules/Fieldset.svelte +8 -13
- package/dist/components/molecules/FileButton.svelte +57 -31
- package/dist/components/molecules/FileButton.svelte.d.ts +2 -0
- package/dist/components/molecules/FilterInput.svelte +51 -11
- package/dist/components/molecules/FontScalePicker.svelte +20 -9
- package/dist/components/molecules/GitRef.svelte +9 -7
- package/dist/components/molecules/GlyphStack.svelte +38 -14
- package/dist/components/molecules/IconButton.svelte +6 -3
- package/dist/components/molecules/IconButton.svelte.d.ts +2 -0
- package/dist/components/molecules/InputGroup.svelte +13 -12
- package/dist/components/molecules/LoadMore.svelte +6 -1
- package/dist/components/molecules/LoadMore.svelte.d.ts +2 -0
- package/dist/components/molecules/Menu.svelte +33 -7
- package/dist/components/molecules/Menu.svelte.d.ts +2 -0
- package/dist/components/molecules/Metric.svelte +11 -9
- package/dist/components/molecules/Modal.svelte +76 -26
- package/dist/components/molecules/Modal.svelte.d.ts +2 -0
- package/dist/components/molecules/OptionButton.svelte +28 -10
- package/dist/components/molecules/OptionButton.svelte.d.ts +2 -0
- package/dist/components/molecules/Pagination.svelte +26 -9
- package/dist/components/molecules/Pagination.svelte.d.ts +2 -0
- package/dist/components/molecules/Popover.svelte +107 -51
- package/dist/components/molecules/Popover.svelte.d.ts +2 -0
- package/dist/components/molecules/Prose.svelte +1 -1
- package/dist/components/molecules/PullToRefresh.svelte +14 -10
- package/dist/components/molecules/PullToRefresh.svelte.d.ts +2 -0
- package/dist/components/molecules/RadialMenu.svelte +52 -19
- package/dist/components/molecules/RadialMenu.svelte.d.ts +2 -0
- package/dist/components/molecules/RadioGroup.svelte +38 -23
- package/dist/components/molecules/RadioGroup.svelte.d.ts +2 -0
- package/dist/components/molecules/SectionHeader.svelte +13 -8
- package/dist/components/molecules/SeekSlider.svelte +38 -27
- package/dist/components/molecules/SeekSlider.svelte.d.ts +2 -0
- package/dist/components/molecules/SegmentedControl.svelte +139 -86
- package/dist/components/molecules/SegmentedControl.svelte.d.ts +2 -0
- package/dist/components/molecules/SelectButton.svelte +21 -6
- package/dist/components/molecules/SelectButton.svelte.d.ts +2 -0
- package/dist/components/molecules/SortableList.svelte +10 -11
- package/dist/components/molecules/SoundSettings.svelte +161 -0
- package/dist/components/molecules/SoundSettings.svelte.d.ts +17 -0
- package/dist/components/molecules/SplitButton.svelte +30 -3
- package/dist/components/molecules/SplitButton.svelte.d.ts +2 -0
- package/dist/components/molecules/SwipeRow.svelte +18 -15
- package/dist/components/molecules/SwipeRow.svelte.d.ts +2 -0
- package/dist/components/molecules/Tabs.svelte +92 -10
- package/dist/components/molecules/Tabs.svelte.d.ts +2 -0
- package/dist/components/molecules/ThemePicker.svelte +25 -10
- package/dist/components/molecules/Timestamp.svelte +12 -7
- package/dist/components/molecules/Toaster.svelte +65 -14
- package/dist/components/molecules/Toaster.svelte.d.ts +2 -0
- package/dist/components/molecules/Toggle.svelte +36 -13
- package/dist/components/molecules/Toggle.svelte.d.ts +2 -0
- package/dist/components/molecules/Tooltip.svelte +41 -10
- package/dist/components/molecules/Tooltip.svelte.d.ts +1 -1
- package/dist/components/molecules/VolumeSlider.svelte +34 -14
- package/dist/components/molecules/VolumeSlider.svelte.d.ts +2 -0
- package/dist/components/molecules/WorkingDir.svelte +1 -0
- package/dist/components/organisms/ConversationFeed.svelte +4 -0
- package/dist/components/organisms/DataTable.svelte +37 -14
- package/dist/floating.js +26 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -1
- package/dist/sound-synth.d.ts +3 -0
- package/dist/sound-synth.js +91 -0
- package/dist/sound.d.ts +1 -0
- package/dist/sound.js +3 -0
- package/dist/stores/sound.svelte.d.ts +20 -0
- package/dist/stores/sound.svelte.js +150 -0
- package/dist/stores/toast.svelte.d.ts +9 -0
- package/dist/stores/toast.svelte.js +45 -9
- package/dist/styles/reset.css +19 -2
- package/dist/styles/tokens.css +89 -6
- package/package.json +1 -1
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import Button from '../atoms/Button.svelte';
|
|
8
8
|
import Icon from '../atoms/Icon.svelte';
|
|
9
9
|
import { copyToClipboard } from '../../clipboard';
|
|
10
|
+
import { playSound } from '../../sound';
|
|
10
11
|
|
|
11
12
|
let {
|
|
12
13
|
text,
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
box,
|
|
18
19
|
hitArea = 'auto',
|
|
19
20
|
resetMs = 1500,
|
|
21
|
+
sound = true,
|
|
20
22
|
class: klass = ''
|
|
21
23
|
}: {
|
|
22
24
|
/** The string to copy. */
|
|
@@ -30,6 +32,8 @@
|
|
|
30
32
|
box?: 'xs' | 'sm' | 'md' | 'lg';
|
|
31
33
|
hitArea?: 'auto' | 'compact';
|
|
32
34
|
resetMs?: number;
|
|
35
|
+
/** Play UI sounds when enabled globally; false silences this instance. */
|
|
36
|
+
sound?: boolean;
|
|
33
37
|
class?: string;
|
|
34
38
|
} = $props();
|
|
35
39
|
|
|
@@ -40,6 +44,7 @@
|
|
|
40
44
|
|
|
41
45
|
async function copy() {
|
|
42
46
|
const ok = await copyToClipboard(text);
|
|
47
|
+
playSound(ok ? 'success' : 'error', sound);
|
|
43
48
|
copied = ok;
|
|
44
49
|
status = ok ? copiedLabel : 'Copy failed';
|
|
45
50
|
clearTimeout(timer);
|
|
@@ -55,12 +60,51 @@
|
|
|
55
60
|
{variant}
|
|
56
61
|
{box}
|
|
57
62
|
{hitArea}
|
|
58
|
-
class={klass}
|
|
63
|
+
class="copy-btn {klass}"
|
|
64
|
+
sound={false}
|
|
59
65
|
onclick={copy}
|
|
60
66
|
aria-label={copied ? copiedLabel : label}
|
|
61
67
|
title={label}
|
|
62
68
|
>
|
|
63
|
-
<
|
|
69
|
+
<span class="glyphs" class:copied aria-hidden="true">
|
|
70
|
+
<span class="glyph copy"><Icon name="copy" /></span>
|
|
71
|
+
<span class="glyph check"><Icon name="check" /></span>
|
|
72
|
+
</span>
|
|
64
73
|
{#if labelShown}<span>{copied ? copiedLabel : label}</span>{/if}
|
|
65
74
|
</Button>
|
|
66
75
|
<span class="sr-only" role="status" aria-live="polite">{status}</span>
|
|
76
|
+
|
|
77
|
+
<style>
|
|
78
|
+
/* Both glyphs share one grid cell so the swap never changes the width. The
|
|
79
|
+
check springs in (the kit's one bounce: a rare confirmation); the copy
|
|
80
|
+
glyph fades out fast and back in over the base duration on revert. */
|
|
81
|
+
.glyphs {
|
|
82
|
+
display: inline-grid;
|
|
83
|
+
place-items: center;
|
|
84
|
+
}
|
|
85
|
+
.glyph {
|
|
86
|
+
grid-area: 1 / 1;
|
|
87
|
+
display: inline-flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
justify-content: center;
|
|
90
|
+
transition: opacity var(--dur-fast) ease;
|
|
91
|
+
}
|
|
92
|
+
.check {
|
|
93
|
+
opacity: 0;
|
|
94
|
+
scale: 0.6;
|
|
95
|
+
transition:
|
|
96
|
+
opacity var(--dur-fast) ease,
|
|
97
|
+
scale var(--dur-fast) var(--ease-out);
|
|
98
|
+
}
|
|
99
|
+
.copied .copy {
|
|
100
|
+
opacity: 0;
|
|
101
|
+
transition-duration: var(--dur-exit-fast);
|
|
102
|
+
}
|
|
103
|
+
.copied .check {
|
|
104
|
+
opacity: 1;
|
|
105
|
+
scale: 1;
|
|
106
|
+
transition:
|
|
107
|
+
opacity var(--dur-spring-bounce) ease,
|
|
108
|
+
scale var(--dur-spring-bounce) var(--ease-spring-bounce);
|
|
109
|
+
}
|
|
110
|
+
</style>
|
|
@@ -10,6 +10,8 @@ type $$ComponentProps = {
|
|
|
10
10
|
box?: 'xs' | 'sm' | 'md' | 'lg';
|
|
11
11
|
hitArea?: 'auto' | 'compact';
|
|
12
12
|
resetMs?: number;
|
|
13
|
+
/** Play UI sounds when enabled globally; false silences this instance. */
|
|
14
|
+
sound?: boolean;
|
|
13
15
|
class?: string;
|
|
14
16
|
};
|
|
15
17
|
declare const CopyButton: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import type { Snippet } from 'svelte';
|
|
14
14
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
15
15
|
import Icon from '../atoms/Icon.svelte';
|
|
16
|
+
import { playSound } from '../../sound';
|
|
16
17
|
|
|
17
18
|
let {
|
|
18
19
|
open = $bindable(false),
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
id,
|
|
24
25
|
onchange,
|
|
25
26
|
disabled = false,
|
|
27
|
+
sound = true,
|
|
26
28
|
class: klass = '',
|
|
27
29
|
style: styleProp = '',
|
|
28
30
|
buttonClass = '',
|
|
@@ -45,6 +47,8 @@
|
|
|
45
47
|
id?: string;
|
|
46
48
|
onchange?: (open: boolean) => void;
|
|
47
49
|
disabled?: boolean;
|
|
50
|
+
/** Play UI sounds when enabled globally; false silences this instance. */
|
|
51
|
+
sound?: boolean;
|
|
48
52
|
class?: string;
|
|
49
53
|
style?: string;
|
|
50
54
|
buttonClass?: string;
|
|
@@ -58,6 +62,7 @@
|
|
|
58
62
|
|
|
59
63
|
function toggle() {
|
|
60
64
|
open = !open;
|
|
65
|
+
playSound(open ? 'open' : 'close', sound);
|
|
61
66
|
onchange?.(open);
|
|
62
67
|
}
|
|
63
68
|
</script>
|
|
@@ -119,16 +124,18 @@
|
|
|
119
124
|
cursor: pointer;
|
|
120
125
|
user-select: none;
|
|
121
126
|
}
|
|
122
|
-
|
|
123
|
-
|
|
127
|
+
@media (hover: hover) and (pointer: fine) {
|
|
128
|
+
.disclosure__button:hover:not(:disabled) {
|
|
129
|
+
background: var(--bg-elevated-2);
|
|
130
|
+
}
|
|
124
131
|
}
|
|
125
132
|
.disclosure__button:focus-visible {
|
|
126
|
-
outline:
|
|
127
|
-
outline-offset: -
|
|
133
|
+
outline: var(--focus-ring);
|
|
134
|
+
outline-offset: var(--focus-ring-offset-inset);
|
|
128
135
|
}
|
|
129
136
|
.disclosure__button:disabled {
|
|
130
137
|
cursor: not-allowed;
|
|
131
|
-
opacity:
|
|
138
|
+
opacity: var(--disabled-opacity);
|
|
132
139
|
}
|
|
133
140
|
.disclosure__header {
|
|
134
141
|
display: flex;
|
|
@@ -141,20 +148,24 @@
|
|
|
141
148
|
display: inline-flex;
|
|
142
149
|
flex: none;
|
|
143
150
|
color: var(--text-muted);
|
|
144
|
-
transition:
|
|
151
|
+
transition: rotate var(--dur-base) var(--ease-out);
|
|
145
152
|
}
|
|
146
153
|
.disclosure--open .disclosure__chevron {
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
@media (prefers-reduced-motion: reduce) {
|
|
150
|
-
.disclosure__chevron {
|
|
151
|
-
transition: none;
|
|
152
|
-
}
|
|
154
|
+
rotate: 180deg;
|
|
153
155
|
}
|
|
154
156
|
.disclosure__panel {
|
|
155
157
|
padding: var(--disclosure-panel-pad, 0 var(--sp-4) var(--sp-4));
|
|
156
158
|
font-size: var(--disclosure-fs, var(--fs-sm));
|
|
157
159
|
color: var(--text-muted);
|
|
160
|
+
transition:
|
|
161
|
+
opacity var(--dur-base) var(--ease-out),
|
|
162
|
+
translate var(--dur-base) var(--ease-out);
|
|
163
|
+
}
|
|
164
|
+
@starting-style {
|
|
165
|
+
.disclosure__panel:not([hidden]) {
|
|
166
|
+
opacity: 0;
|
|
167
|
+
translate: 0 calc(-1 * var(--shift-xs));
|
|
168
|
+
}
|
|
158
169
|
}
|
|
159
170
|
.disclosure--compact {
|
|
160
171
|
--disclosure-pad: var(--sp-1) var(--sp-2);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { browser } from '../../env';
|
|
7
7
|
import Icon, { type IconName } from '../atoms/Icon.svelte';
|
|
8
8
|
import IconButton from './IconButton.svelte';
|
|
9
|
+
import { playSound } from '../../sound';
|
|
9
10
|
|
|
10
11
|
let {
|
|
11
12
|
open = $bindable(),
|
|
@@ -23,7 +24,8 @@
|
|
|
23
24
|
children,
|
|
24
25
|
footer,
|
|
25
26
|
class: className,
|
|
26
|
-
style
|
|
27
|
+
style,
|
|
28
|
+
sound = true
|
|
27
29
|
}: {
|
|
28
30
|
/** Controlled visibility. When provided the `<dialog>` stays mounted and
|
|
29
31
|
* `showModal()`/`close()` follow the value; closing sets it back to false.
|
|
@@ -53,6 +55,8 @@
|
|
|
53
55
|
footer?: Snippet;
|
|
54
56
|
class?: string;
|
|
55
57
|
style?: string;
|
|
58
|
+
/** Play UI sounds when enabled globally; false silences this instance. */
|
|
59
|
+
sound?: boolean;
|
|
56
60
|
} = $props();
|
|
57
61
|
|
|
58
62
|
const titleId = `drawer-title-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -61,14 +65,20 @@
|
|
|
61
65
|
const controlled = $derived(open !== undefined);
|
|
62
66
|
const shown = $derived(!controlled || open === true);
|
|
63
67
|
|
|
68
|
+
// Mounting (or mounting with `open` already true) is a sync, not a
|
|
69
|
+
// transition, so it stays silent.
|
|
70
|
+
let synced = false;
|
|
64
71
|
$effect(() => {
|
|
65
72
|
if (!dialogEl) return;
|
|
66
73
|
if (!controlled) {
|
|
67
74
|
dialogEl.showModal();
|
|
68
75
|
return;
|
|
69
76
|
}
|
|
70
|
-
if (open && !dialogEl.open)
|
|
71
|
-
|
|
77
|
+
if (open && !dialogEl.open) {
|
|
78
|
+
dialogEl.showModal();
|
|
79
|
+
if (synced) playSound('open', sound);
|
|
80
|
+
} else if (!open && dialogEl.open) dialogEl.close();
|
|
81
|
+
synced = true;
|
|
72
82
|
});
|
|
73
83
|
|
|
74
84
|
$effect(() => {
|
|
@@ -82,6 +92,7 @@
|
|
|
82
92
|
|
|
83
93
|
function requestClose() {
|
|
84
94
|
if (controlled) open = false;
|
|
95
|
+
else playSound('close', sound);
|
|
85
96
|
onclose?.();
|
|
86
97
|
}
|
|
87
98
|
|
|
@@ -111,6 +122,7 @@
|
|
|
111
122
|
}}
|
|
112
123
|
onclose={() => {
|
|
113
124
|
if (controlled) open = false;
|
|
125
|
+
playSound('close', sound);
|
|
114
126
|
}}
|
|
115
127
|
onpointerdown={onDialogPointerDown}
|
|
116
128
|
onclick={onDialogClick}
|
|
@@ -126,7 +138,7 @@
|
|
|
126
138
|
{@render header()}
|
|
127
139
|
{:else}
|
|
128
140
|
<div class="panel-head">
|
|
129
|
-
{#if icon}<span class="panel-icon"><Icon name={icon}
|
|
141
|
+
{#if icon}<span class="panel-icon"><Icon name={icon} /></span>{/if}
|
|
130
142
|
<span id={titleId} class="panel-title truncate">{title}</span>
|
|
131
143
|
{#if page}<span class="panel-page truncate">{page}</span>{/if}
|
|
132
144
|
<div class="spacer"></div>
|
|
@@ -163,6 +175,10 @@
|
|
|
163
175
|
color: var(--text);
|
|
164
176
|
display: flex;
|
|
165
177
|
justify-content: flex-end;
|
|
178
|
+
/* Exits run natively on close(): the box leaves the top layer once the panel is gone. */
|
|
179
|
+
transition:
|
|
180
|
+
display var(--dur-exit-slow) allow-discrete,
|
|
181
|
+
overlay var(--dur-exit-slow) allow-discrete;
|
|
166
182
|
}
|
|
167
183
|
.drawer:not([open]) {
|
|
168
184
|
display: none;
|
|
@@ -172,10 +188,18 @@
|
|
|
172
188
|
}
|
|
173
189
|
.drawer::backdrop {
|
|
174
190
|
background: rgba(0, 0, 0, 0.55);
|
|
175
|
-
|
|
191
|
+
opacity: 0;
|
|
192
|
+
transition:
|
|
193
|
+
opacity var(--dur-exit) var(--ease-out),
|
|
194
|
+
display var(--dur-exit) allow-discrete,
|
|
195
|
+
overlay var(--dur-exit) allow-discrete;
|
|
196
|
+
}
|
|
197
|
+
.drawer[open]::backdrop {
|
|
198
|
+
opacity: 1;
|
|
199
|
+
transition-duration: var(--dur-base);
|
|
176
200
|
}
|
|
177
|
-
@
|
|
178
|
-
|
|
201
|
+
@starting-style {
|
|
202
|
+
.drawer[open]::backdrop {
|
|
179
203
|
opacity: 0;
|
|
180
204
|
}
|
|
181
205
|
}
|
|
@@ -192,28 +216,23 @@
|
|
|
192
216
|
width: 100%;
|
|
193
217
|
height: 100%;
|
|
194
218
|
background: var(--bg-elevated);
|
|
195
|
-
will-change:
|
|
219
|
+
will-change: translate;
|
|
196
220
|
padding-top: var(--safe-top);
|
|
197
221
|
padding-bottom: var(--safe-bottom);
|
|
198
|
-
|
|
222
|
+
--drawer-from: 100% 0;
|
|
223
|
+
translate: var(--drawer-from);
|
|
224
|
+
transition: translate var(--dur-exit-slow) var(--ease-drawer);
|
|
199
225
|
}
|
|
200
226
|
.drawer[data-side='left'] .panel {
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
@keyframes drawer-slide-right {
|
|
204
|
-
from {
|
|
205
|
-
transform: translateX(100%);
|
|
206
|
-
}
|
|
227
|
+
--drawer-from: -100% 0;
|
|
207
228
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
229
|
+
.drawer[open] .panel {
|
|
230
|
+
translate: 0;
|
|
231
|
+
transition-duration: var(--dur-sheet);
|
|
212
232
|
}
|
|
213
|
-
@
|
|
214
|
-
.drawer
|
|
215
|
-
|
|
216
|
-
animation: none;
|
|
233
|
+
@starting-style {
|
|
234
|
+
.drawer[open] .panel {
|
|
235
|
+
translate: var(--drawer-from);
|
|
217
236
|
}
|
|
218
237
|
}
|
|
219
238
|
|
|
@@ -228,6 +247,7 @@
|
|
|
228
247
|
.panel-icon {
|
|
229
248
|
display: inline-flex;
|
|
230
249
|
flex: none;
|
|
250
|
+
font-size: var(--icon-lg);
|
|
231
251
|
color: var(--text-muted);
|
|
232
252
|
}
|
|
233
253
|
.panel-title {
|
|
@@ -29,6 +29,8 @@ type $$ComponentProps = {
|
|
|
29
29
|
footer?: Snippet;
|
|
30
30
|
class?: string;
|
|
31
31
|
style?: string;
|
|
32
|
+
/** Play UI sounds when enabled globally; false silences this instance. */
|
|
33
|
+
sound?: boolean;
|
|
32
34
|
};
|
|
33
35
|
declare const Drawer: import("svelte").Component<$$ComponentProps, {}, "open">;
|
|
34
36
|
type Drawer = ReturnType<typeof Drawer>;
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
{@render children?.()}
|
|
123
123
|
{#if over}
|
|
124
124
|
<div class="dz-overlay" aria-hidden="true">
|
|
125
|
-
<Icon name="upload"
|
|
125
|
+
<Icon name="upload" />
|
|
126
126
|
<span class="dz-label">{label}</span>
|
|
127
127
|
</div>
|
|
128
128
|
{/if}
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
{#if children}
|
|
164
164
|
{@render children()}
|
|
165
165
|
{:else}
|
|
166
|
-
<Icon name="upload"
|
|
166
|
+
<Icon name="upload" />
|
|
167
167
|
<span class="dz-label">{label}</span>
|
|
168
168
|
<span class="dz-hint">{hint}</span>
|
|
169
169
|
{/if}
|
|
@@ -185,15 +185,25 @@
|
|
|
185
185
|
border-radius: var(--r-lg);
|
|
186
186
|
cursor: pointer;
|
|
187
187
|
transition:
|
|
188
|
-
border-color
|
|
189
|
-
background
|
|
190
|
-
color
|
|
188
|
+
border-color var(--dur-fast) ease,
|
|
189
|
+
background-color var(--dur-fast) ease,
|
|
190
|
+
color var(--dur-fast) ease;
|
|
191
|
+
}
|
|
192
|
+
.dz > :global(svg),
|
|
193
|
+
.dz-overlay > :global(svg) {
|
|
194
|
+
font-size: var(--icon-xl);
|
|
191
195
|
}
|
|
192
|
-
.dz:hover:not(.disabled),
|
|
193
196
|
.dz:focus-visible {
|
|
194
197
|
border-color: var(--accent);
|
|
195
198
|
color: var(--text);
|
|
196
|
-
outline:
|
|
199
|
+
outline: var(--focus-ring);
|
|
200
|
+
outline-offset: var(--focus-ring-offset);
|
|
201
|
+
}
|
|
202
|
+
@media (hover: hover) and (pointer: fine) {
|
|
203
|
+
.dz:hover:not(.disabled) {
|
|
204
|
+
border-color: var(--accent);
|
|
205
|
+
color: var(--text);
|
|
206
|
+
}
|
|
197
207
|
}
|
|
198
208
|
.dz.over {
|
|
199
209
|
border-color: var(--accent);
|
|
@@ -201,7 +211,7 @@
|
|
|
201
211
|
color: var(--text);
|
|
202
212
|
}
|
|
203
213
|
.dz.disabled {
|
|
204
|
-
opacity:
|
|
214
|
+
opacity: var(--disabled-opacity);
|
|
205
215
|
cursor: not-allowed;
|
|
206
216
|
}
|
|
207
217
|
|
|
@@ -233,6 +243,12 @@
|
|
|
233
243
|
border-radius: var(--r-lg);
|
|
234
244
|
pointer-events: none;
|
|
235
245
|
backdrop-filter: blur(1px);
|
|
246
|
+
transition: opacity var(--dur-fast) ease;
|
|
247
|
+
}
|
|
248
|
+
@starting-style {
|
|
249
|
+
.dz-overlay {
|
|
250
|
+
opacity: 0;
|
|
251
|
+
}
|
|
236
252
|
}
|
|
237
253
|
|
|
238
254
|
.dz-label {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import Input from '../atoms/Input.svelte';
|
|
6
6
|
import Popover from './Popover.svelte';
|
|
7
7
|
import { type EmojiGroup, EMOJI_GROUPS, searchEmoji } from '../../emoji';
|
|
8
|
+
import { playSound } from '../../sound';
|
|
8
9
|
|
|
9
10
|
let {
|
|
10
11
|
value = '',
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
placement = 'bottom-start',
|
|
18
19
|
triggerClass = '',
|
|
19
20
|
disabled = false,
|
|
21
|
+
sound = true,
|
|
20
22
|
class: klass = '',
|
|
21
23
|
style: styleProp = '',
|
|
22
24
|
}: {
|
|
@@ -33,6 +35,8 @@
|
|
|
33
35
|
placement?: 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end';
|
|
34
36
|
triggerClass?: string;
|
|
35
37
|
disabled?: boolean;
|
|
38
|
+
/** Play UI sounds when enabled globally; false silences this instance. */
|
|
39
|
+
sound?: boolean;
|
|
36
40
|
class?: string;
|
|
37
41
|
style?: string;
|
|
38
42
|
} = $props();
|
|
@@ -110,10 +114,13 @@
|
|
|
110
114
|
style={styleProp}
|
|
111
115
|
control
|
|
112
116
|
role="dialog"
|
|
117
|
+
{sound}
|
|
113
118
|
onopen={() => {
|
|
114
119
|
query = '';
|
|
115
120
|
cursor = 0;
|
|
121
|
+
playSound('open', sound);
|
|
116
122
|
}}
|
|
123
|
+
onclose={() => playSound('close', sound)}
|
|
117
124
|
>
|
|
118
125
|
{#snippet trigger()}
|
|
119
126
|
<span class="emoji-trigger" aria-hidden="true">{picked || '🙂'}</span>
|
|
@@ -198,7 +205,7 @@
|
|
|
198
205
|
<style>
|
|
199
206
|
.emoji-trigger {
|
|
200
207
|
font-size: var(--fs-md);
|
|
201
|
-
line-height:
|
|
208
|
+
line-height: var(--lh-none);
|
|
202
209
|
}
|
|
203
210
|
.picker {
|
|
204
211
|
display: flex;
|
|
@@ -221,24 +228,36 @@
|
|
|
221
228
|
background: none;
|
|
222
229
|
color: inherit;
|
|
223
230
|
font-size: var(--fs-lg);
|
|
224
|
-
line-height:
|
|
231
|
+
line-height: var(--lh-none);
|
|
225
232
|
cursor: pointer;
|
|
233
|
+
--cell-scale-dur: var(--dur-fast);
|
|
234
|
+
transition:
|
|
235
|
+
background-color var(--dur-fast) ease,
|
|
236
|
+
border-color var(--dur-fast) ease,
|
|
237
|
+
scale var(--cell-scale-dur) var(--ease-out);
|
|
226
238
|
}
|
|
227
239
|
.tab.on,
|
|
228
240
|
.cell.on {
|
|
229
241
|
border-color: var(--accent);
|
|
230
242
|
background: var(--bg-elevated-2);
|
|
231
243
|
}
|
|
232
|
-
.tab:hover,
|
|
233
|
-
.cell:hover,
|
|
234
244
|
.tab:focus-visible,
|
|
235
245
|
.cell:focus-visible {
|
|
236
246
|
background: var(--bg-elevated-2);
|
|
237
|
-
}
|
|
238
|
-
.tab:focus-visible,
|
|
239
|
-
.cell:focus-visible {
|
|
240
247
|
outline: var(--focus-ring);
|
|
241
|
-
outline-offset: var(--focus-ring-offset);
|
|
248
|
+
outline-offset: var(--focus-ring-offset-inset);
|
|
249
|
+
}
|
|
250
|
+
.tab:active,
|
|
251
|
+
.cell:active {
|
|
252
|
+
--cell-scale-dur: var(--dur-press);
|
|
253
|
+
scale: var(--press-scale-sm);
|
|
254
|
+
}
|
|
255
|
+
@media (hover: hover) and (pointer: fine) {
|
|
256
|
+
.tab:hover,
|
|
257
|
+
.cell:hover {
|
|
258
|
+
background: var(--bg-elevated-2);
|
|
259
|
+
transition-duration: var(--dur-instant);
|
|
260
|
+
}
|
|
242
261
|
}
|
|
243
262
|
.grid {
|
|
244
263
|
display: grid;
|
|
@@ -13,6 +13,8 @@ type $$ComponentProps = {
|
|
|
13
13
|
placement?: 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end';
|
|
14
14
|
triggerClass?: string;
|
|
15
15
|
disabled?: boolean;
|
|
16
|
+
/** Play UI sounds when enabled globally; false silences this instance. */
|
|
17
|
+
sound?: boolean;
|
|
16
18
|
class?: string;
|
|
17
19
|
style?: string;
|
|
18
20
|
};
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
width: 3rem;
|
|
133
133
|
height: 3rem;
|
|
134
134
|
border-radius: var(--r-lg);
|
|
135
|
-
font-size:
|
|
135
|
+
font-size: var(--fs-xl);
|
|
136
136
|
color: var(--empty-tone);
|
|
137
137
|
background: color-mix(in srgb, var(--empty-tone) 14%, transparent);
|
|
138
138
|
border: 1px solid color-mix(in srgb, var(--empty-tone) 30%, transparent);
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
.empty-compact .empty-chip {
|
|
141
141
|
width: 2.25rem;
|
|
142
142
|
height: 2.25rem;
|
|
143
|
-
font-size:
|
|
143
|
+
font-size: var(--fs-lg);
|
|
144
144
|
}
|
|
145
145
|
.empty-inline {
|
|
146
146
|
flex-direction: row;
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
.empty-inline .empty-chip {
|
|
152
152
|
width: auto;
|
|
153
153
|
height: auto;
|
|
154
|
-
font-size:
|
|
154
|
+
font-size: var(--icon-md);
|
|
155
155
|
background: none;
|
|
156
156
|
border: none;
|
|
157
157
|
}
|
|
@@ -171,14 +171,14 @@
|
|
|
171
171
|
font-size: var(--fs-md);
|
|
172
172
|
font-weight: var(--fw-semibold);
|
|
173
173
|
color: var(--text);
|
|
174
|
-
line-height:
|
|
174
|
+
line-height: var(--lh-snug);
|
|
175
175
|
}
|
|
176
176
|
.empty-desc {
|
|
177
177
|
margin: 0;
|
|
178
178
|
max-width: 32ch;
|
|
179
179
|
font-size: var(--fs-sm);
|
|
180
180
|
color: var(--text-muted);
|
|
181
|
-
line-height:
|
|
181
|
+
line-height: var(--lh-normal);
|
|
182
182
|
}
|
|
183
183
|
.empty-action {
|
|
184
184
|
margin-top: var(--sp-1);
|
|
@@ -129,8 +129,8 @@
|
|
|
129
129
|
border-radius: var(--r-lg);
|
|
130
130
|
background: var(--bg);
|
|
131
131
|
transition:
|
|
132
|
-
border-color
|
|
133
|
-
background
|
|
132
|
+
border-color var(--dur-fast) ease,
|
|
133
|
+
background-color var(--dur-fast) ease;
|
|
134
134
|
}
|
|
135
135
|
.fieldset.dashed {
|
|
136
136
|
border-style: dashed;
|
|
@@ -151,16 +151,16 @@
|
|
|
151
151
|
.fieldset-legend {
|
|
152
152
|
position: absolute;
|
|
153
153
|
top: -13px;
|
|
154
|
-
left:
|
|
154
|
+
left: var(--sp-4);
|
|
155
155
|
display: inline-flex;
|
|
156
156
|
align-items: center;
|
|
157
157
|
gap: var(--sp-2);
|
|
158
|
-
max-width: calc(100% -
|
|
159
|
-
padding: 0
|
|
158
|
+
max-width: calc(100% - var(--sp-8));
|
|
159
|
+
padding: 0 var(--sp-2);
|
|
160
160
|
background: var(--bg);
|
|
161
161
|
font-size: var(--fs-sm);
|
|
162
162
|
font-weight: var(--fw-semibold);
|
|
163
|
-
line-height:
|
|
163
|
+
line-height: var(--lh-normal);
|
|
164
164
|
color: var(--text);
|
|
165
165
|
}
|
|
166
166
|
|
|
@@ -182,12 +182,7 @@
|
|
|
182
182
|
pointer-events: none;
|
|
183
183
|
}
|
|
184
184
|
.fieldset.disabled {
|
|
185
|
-
opacity:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
@media (prefers-reduced-motion: reduce) {
|
|
189
|
-
.fieldset {
|
|
190
|
-
transition: none;
|
|
191
|
-
}
|
|
185
|
+
opacity: var(--disabled-opacity);
|
|
186
|
+
cursor: not-allowed;
|
|
192
187
|
}
|
|
193
188
|
</style>
|