@lyeve-labs/ui-kit 0.35.1 → 0.36.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 +1 -1
- package/dist/components/Autocomplete.svelte +6 -1
- package/dist/components/Button.svelte +11 -2
- package/dist/components/Button.svelte.d.ts +1 -1
- package/dist/components/CopyField.svelte +3 -1
- package/dist/components/Textarea.svelte +3 -1
- package/dist/components/ThemeToggle.svelte +9 -5
- package/dist/components/dialog/ConfirmDialog.svelte +3 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/CopyGlyph.svelte +12 -3
- package/dist/motion.js +18 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -175,7 +175,7 @@ in `styles.css` beside the palette:
|
|
|
175
175
|
|
|
176
176
|
| Token | Value | For |
|
|
177
177
|
| --------------------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
178
|
-
| `--duration-fast` | 120ms | a state change in place: color, opacity, border, shadow, focus
|
|
178
|
+
| `--duration-fast` | 120ms | a state change in place: color, opacity, border, shadow, focus |
|
|
179
179
|
| `--duration-base` | 200ms | movement in place (a knob, a chevron, a collapse) and a small surface arriving (menu, popover, tooltip, toast) |
|
|
180
180
|
| `--duration-slow` | 320ms | a large surface arriving (dialog, drawer) |
|
|
181
181
|
| `--duration-progress` | 500ms | a value moving (a progress bar's width) |
|
|
@@ -181,10 +181,15 @@
|
|
|
181
181
|
{/if}
|
|
182
182
|
|
|
183
183
|
<div class="relative" bind:this={fieldEl} use:anchor>
|
|
184
|
+
<!-- The form posts the chosen option's value. The visible input holds the
|
|
185
|
+
label, or the words being typed, so it carries no name: a form read it
|
|
186
|
+
as the value and posted "Alpha" where the option was "a". -->
|
|
187
|
+
{#if name}
|
|
188
|
+
<input type="hidden" {name} {disabled} value={value ?? ''} />
|
|
189
|
+
{/if}
|
|
184
190
|
<input
|
|
185
191
|
bind:this={inputEl}
|
|
186
192
|
id={fieldId}
|
|
187
|
-
{name}
|
|
188
193
|
{placeholder}
|
|
189
194
|
{disabled}
|
|
190
195
|
{required}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { TOUCH_GROW } from '../internal/touch.js';
|
|
8
8
|
|
|
9
9
|
type Variant = 'primary' | 'secondary' | 'danger' | 'ghost' | 'outline' | 'violet';
|
|
10
|
-
type Size = 'sm' | 'md' | 'lg';
|
|
10
|
+
type Size = 'sm' | 'md' | 'lg' | 'icon';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Attributes forwarded to whichever element renders. Naming them, rather than
|
|
@@ -96,10 +96,18 @@
|
|
|
96
96
|
'border border-line-strong text-fg hover:border-brand hover:text-brand active:bg-brand/10',
|
|
97
97
|
};
|
|
98
98
|
|
|
99
|
+
/*
|
|
100
|
+
* `icon` is a square for a button whose only content is an icon: the icon
|
|
101
|
+
* sets the size and the box adds 8px round it, so a 16px icon makes the 32px
|
|
102
|
+
* square the header controls use. Without it, an icon-only control beside
|
|
103
|
+
* ThemeToggle had to copy ThemeToggle's classes, and every copy drifted on
|
|
104
|
+
* its own. Name the button with `aria-label`, which also becomes its hint.
|
|
105
|
+
*/
|
|
99
106
|
const sizes: Record<Size, string> = {
|
|
100
107
|
sm: 'px-3 py-1.5 text-sm gap-1.5 rounded-md',
|
|
101
108
|
md: 'px-4 py-2 text-sm gap-2 rounded-lg',
|
|
102
109
|
lg: 'px-5 py-2.5 text-base gap-2 rounded-lg',
|
|
110
|
+
icon: 'p-2 rounded-lg',
|
|
103
111
|
};
|
|
104
112
|
|
|
105
113
|
const spinnerSize = $derived(size === 'lg' ? 18 : 15);
|
|
@@ -113,7 +121,8 @@
|
|
|
113
121
|
*
|
|
114
122
|
* TOUCH_GROW: under a coarse pointer the button takes the control height,
|
|
115
123
|
* which is 44px there, so a button and the input beside it grow together.
|
|
116
|
-
* A mouse sees 36px, 32px and 44px by size, as before
|
|
124
|
+
* A mouse sees 36px, 32px and 44px by size, as before, and an icon-only
|
|
125
|
+
* button its icon plus 16px.
|
|
117
126
|
*/
|
|
118
127
|
const cls = $derived(
|
|
119
128
|
`inline-flex items-center justify-center font-medium whitespace-nowrap transition-colors ` +
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
|
3
3
|
type Variant = 'primary' | 'secondary' | 'danger' | 'ghost' | 'outline' | 'violet';
|
|
4
|
-
type Size = 'sm' | 'md' | 'lg';
|
|
4
|
+
type Size = 'sm' | 'md' | 'lg' | 'icon';
|
|
5
5
|
/**
|
|
6
6
|
* Attributes forwarded to whichever element renders. Naming them, rather than
|
|
7
7
|
* accepting an open index signature, means a prop the component does not
|
|
@@ -99,7 +99,9 @@
|
|
|
99
99
|
{value}
|
|
100
100
|
onfocus={(e) => e.currentTarget.select()}
|
|
101
101
|
aria-describedby={describedBy(fieldId, failed ? COPY_FAILED_MESSAGE : undefined, hint)}
|
|
102
|
-
class="h-full min-w-0 flex-1 truncate bg-transparent px-3 text-sm text-fg outline-none {mono
|
|
102
|
+
class="h-full min-w-0 flex-1 truncate bg-transparent px-3 text-sm text-fg outline-none {mono
|
|
103
|
+
? 'font-mono'
|
|
104
|
+
: ''}"
|
|
103
105
|
/>
|
|
104
106
|
{@render actions?.()}
|
|
105
107
|
{#if secret}
|
|
@@ -76,7 +76,9 @@
|
|
|
76
76
|
{placeholder}
|
|
77
77
|
aria-invalid={error ? 'true' : undefined}
|
|
78
78
|
aria-describedby={describedBy(fieldId, error, hint)}
|
|
79
|
-
class="{CONTROL_MULTILINE} {controlBorder(!!error)} {resize ? 'resize-y' : 'resize-none'} {mono
|
|
79
|
+
class="{CONTROL_MULTILINE} {controlBorder(!!error)} {resize ? 'resize-y' : 'resize-none'} {mono
|
|
80
|
+
? 'font-mono'
|
|
81
|
+
: ''}"
|
|
80
82
|
bind:value
|
|
81
83
|
{oninput}
|
|
82
84
|
{onblur}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* implies the state.
|
|
16
16
|
*/
|
|
17
17
|
import { Monitor, Moon, Sun } from '@lucide/svelte';
|
|
18
|
-
import
|
|
18
|
+
import Button from './Button.svelte';
|
|
19
19
|
import {
|
|
20
20
|
THEME_PREFERENCES,
|
|
21
21
|
getThemePreference,
|
|
@@ -81,13 +81,17 @@
|
|
|
81
81
|
}
|
|
82
82
|
</script>
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
<!-- The kit's icon-only Button, so a control set beside this one takes the
|
|
85
|
+
same box by naming the same size, and the name shows on hover as well as
|
|
86
|
+
to a screen reader. -->
|
|
87
|
+
<Button
|
|
88
|
+
variant="ghost"
|
|
89
|
+
size="icon"
|
|
86
90
|
onclick={advance}
|
|
87
91
|
data-print="hide"
|
|
88
92
|
data-theme-preference={preference}
|
|
89
93
|
aria-label="Theme: {LABEL[preference]}. Switch to {LABEL[upcoming]}."
|
|
90
|
-
class=
|
|
94
|
+
class={klass}
|
|
91
95
|
>
|
|
92
96
|
<!-- The icon shows the state the control is in, not the one it moves to. It
|
|
93
97
|
showed the destination while the label named the same destination, which
|
|
@@ -99,4 +103,4 @@
|
|
|
99
103
|
{:else}
|
|
100
104
|
<Sun size={16} aria-hidden="true" />
|
|
101
105
|
{/if}
|
|
102
|
-
</
|
|
106
|
+
</Button>
|
|
@@ -44,7 +44,9 @@
|
|
|
44
44
|
);
|
|
45
45
|
// An identifier the message refers to. Set apart in monospace on its own
|
|
46
46
|
// line rather than inside the sentence, where a UUID wraps mid-string.
|
|
47
|
-
let detail = $derived(
|
|
47
|
+
let detail = $derived(
|
|
48
|
+
typeof entry.meta?.confirmDetail === 'string' ? entry.meta.confirmDetail : '',
|
|
49
|
+
);
|
|
48
50
|
|
|
49
51
|
async function handleConfirm() {
|
|
50
52
|
if (loading) return;
|
package/dist/index.d.ts
CHANGED
|
@@ -100,4 +100,4 @@ export { cn, type ClassValue } from './utils/cn.js';
|
|
|
100
100
|
export { getTheme, getThemePreference, nextThemePreference, resolveTheme, setTheme, setThemePreference, systemTheme, themeBootScript, watchThemePreference, toggleTheme, watchSystemTheme, THEME_PREFERENCES, type Theme, type ThemePreference, } from './utils/theme.js';
|
|
101
101
|
export * as motion from './motion.js';
|
|
102
102
|
export type { Rung as MotionRung, Curve as MotionCurve } from './motion.js';
|
|
103
|
-
export declare const VERSION = "0.
|
|
103
|
+
export declare const VERSION = "0.36.0";
|
package/dist/index.js
CHANGED
|
@@ -108,4 +108,4 @@ export * as motion from './motion.js';
|
|
|
108
108
|
// ── Version ────────────────────────────────────────────────────────────────
|
|
109
109
|
// Generated from package.json by `pnpm version:sync`. Bump package.json, never
|
|
110
110
|
// this line. The build and the test suite fail when the two disagree.
|
|
111
|
-
export const VERSION = '0.
|
|
111
|
+
export const VERSION = '0.36.0';
|
|
@@ -20,10 +20,19 @@
|
|
|
20
20
|
const HIDDEN = 'scale-50 opacity-0 duration-fast ease-exit';
|
|
21
21
|
</script>
|
|
22
22
|
|
|
23
|
-
<span
|
|
24
|
-
|
|
23
|
+
<span
|
|
24
|
+
class="grid place-items-center"
|
|
25
|
+
data-copy-state={copied ? 'copied' : 'idle'}
|
|
26
|
+
aria-hidden="true"
|
|
27
|
+
>
|
|
28
|
+
<Copy
|
|
29
|
+
{size}
|
|
30
|
+
class="col-start-1 row-start-1 transition-[opacity,transform] {copied ? HIDDEN : SHOWN}"
|
|
31
|
+
/>
|
|
25
32
|
<Check
|
|
26
33
|
{size}
|
|
27
|
-
class="col-start-1 row-start-1 text-success transition-[opacity,transform] {copied
|
|
34
|
+
class="col-start-1 row-start-1 text-success transition-[opacity,transform] {copied
|
|
35
|
+
? SHOWN
|
|
36
|
+
: HIDDEN}"
|
|
28
37
|
/>
|
|
29
38
|
</span>
|
package/dist/motion.js
CHANGED
|
@@ -125,9 +125,25 @@ export function still(node) {
|
|
|
125
125
|
return true;
|
|
126
126
|
return typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
127
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* A frame with the element's own transform put in front of the preset's.
|
|
130
|
+
*
|
|
131
|
+
* An animation replaces the inline style it animates, it does not add to it.
|
|
132
|
+
* Under `animate:`, Svelte holds a leaving item where it stood with an inline
|
|
133
|
+
* `translate(...)` set just before the exit starts. An exit that animates
|
|
134
|
+
* `transform` alone would replace that and draw the item from the list's
|
|
135
|
+
* corner. A frame that does not move `transform` is returned as it is.
|
|
136
|
+
*/
|
|
137
|
+
function composeTransform(frame, own) {
|
|
138
|
+
if (!own || own === 'none')
|
|
139
|
+
return frame;
|
|
140
|
+
return frame.replace(/transform:\s*([^;]+)/, (_match, preset) => `transform: ${own} ${preset}`);
|
|
141
|
+
}
|
|
128
142
|
/**
|
|
129
143
|
* One transition from the rung its entrance runs at and the frame it draws.
|
|
130
144
|
* The exit is derived, never chosen: one rung faster, on the exit curve.
|
|
145
|
+
* The element's inline transform is read when the transition starts, after
|
|
146
|
+
* Svelte has pinned a leaving list item, and kept in every frame.
|
|
131
147
|
*/
|
|
132
148
|
function surface(rung, css) {
|
|
133
149
|
return (node) => {
|
|
@@ -135,10 +151,11 @@ function surface(rung, css) {
|
|
|
135
151
|
return { duration: 0 };
|
|
136
152
|
return ({ direction } = { direction: 'in' }) => {
|
|
137
153
|
const leaving = direction === 'out';
|
|
154
|
+
const own = node.style?.transform ?? '';
|
|
138
155
|
return {
|
|
139
156
|
duration: duration(leaving ? EXIT_RUNG[rung] : rung),
|
|
140
157
|
easing: easing(leaving ? 'exit' : 'enter'),
|
|
141
|
-
css,
|
|
158
|
+
css: own ? (t, u) => composeTransform(css(t, u), own) : css,
|
|
142
159
|
};
|
|
143
160
|
};
|
|
144
161
|
};
|
package/package.json
CHANGED