@lyeve-labs/ui-kit 0.27.0 → 0.28.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.
|
@@ -3,9 +3,25 @@
|
|
|
3
3
|
import { HIT_AREA } from '../internal/touch.js';
|
|
4
4
|
import type { Snippet } from 'svelte';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* How long a confirmation holds before it clears itself. The same five
|
|
8
|
+
* seconds Alert waits, because a reader crossing between the two surfaces
|
|
9
|
+
* should not have to learn two timings.
|
|
10
|
+
*/
|
|
11
|
+
const DISMISS_AFTER = 5000;
|
|
12
|
+
|
|
6
13
|
interface Props {
|
|
7
14
|
tone?: StatusToneInput;
|
|
8
15
|
dismissible?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Milliseconds before the banner closes itself, or `true` for the default.
|
|
18
|
+
*
|
|
19
|
+
* A confirmation clears itself. A warning and a failure stay until
|
|
20
|
+
* dismissed, so this is off by default. Pass it wherever the banner
|
|
21
|
+
* reports the outcome of a submit; leave it off where it states a standing
|
|
22
|
+
* condition, which does not stop being true after five seconds.
|
|
23
|
+
*/
|
|
24
|
+
autoDismiss?: number | boolean;
|
|
9
25
|
ondismiss?: () => void;
|
|
10
26
|
class?: string;
|
|
11
27
|
children: Snippet;
|
|
@@ -15,6 +31,7 @@
|
|
|
15
31
|
let {
|
|
16
32
|
tone = 'brand',
|
|
17
33
|
dismissible = false,
|
|
34
|
+
autoDismiss = false,
|
|
18
35
|
ondismiss = undefined,
|
|
19
36
|
class: cls = '',
|
|
20
37
|
children,
|
|
@@ -22,12 +39,25 @@
|
|
|
22
39
|
}: Props = $props();
|
|
23
40
|
|
|
24
41
|
let visible = $state(true);
|
|
42
|
+
/** The pointer is over the banner, or focus is inside it. */
|
|
43
|
+
let held = $state(false);
|
|
25
44
|
|
|
26
45
|
function dismiss() {
|
|
27
46
|
visible = false;
|
|
28
47
|
ondismiss?.();
|
|
29
48
|
}
|
|
30
49
|
|
|
50
|
+
const delay = $derived(autoDismiss === true ? DISMISS_AFTER : Number(autoDismiss) || 0);
|
|
51
|
+
|
|
52
|
+
/** A banner that can close itself can also be closed by hand. */
|
|
53
|
+
const closable = $derived(dismissible || delay > 0);
|
|
54
|
+
|
|
55
|
+
$effect(() => {
|
|
56
|
+
if (!visible || held || delay <= 0) return;
|
|
57
|
+
const timer = setTimeout(dismiss, delay);
|
|
58
|
+
return () => clearTimeout(timer);
|
|
59
|
+
});
|
|
60
|
+
|
|
31
61
|
const tones: Record<StatusTone, string> = {
|
|
32
62
|
neutral: 'bg-surface-2 border-line',
|
|
33
63
|
brand: 'bg-brand/10 border-brand/20',
|
|
@@ -40,9 +70,16 @@
|
|
|
40
70
|
</script>
|
|
41
71
|
|
|
42
72
|
{#if visible}
|
|
73
|
+
<!-- The timer stops while the pointer is over the banner or focus is inside
|
|
74
|
+
it, and starts again when they leave. Text is never pulled away from
|
|
75
|
+
somebody reading it. -->
|
|
43
76
|
<div
|
|
44
77
|
role="status"
|
|
45
78
|
class="relative flex items-center gap-3 border-b px-4 py-3 text-sm {tones[t]} {cls}"
|
|
79
|
+
onmouseenter={closable ? () => (held = true) : undefined}
|
|
80
|
+
onmouseleave={closable ? () => (held = false) : undefined}
|
|
81
|
+
onfocusin={closable ? () => (held = true) : undefined}
|
|
82
|
+
onfocusout={closable ? () => (held = false) : undefined}
|
|
46
83
|
>
|
|
47
84
|
<div class="flex flex-1 items-center justify-center gap-3 text-fg">
|
|
48
85
|
{@render children()}
|
|
@@ -52,7 +89,7 @@
|
|
|
52
89
|
<div class="shrink-0">{@render action()}</div>
|
|
53
90
|
{/if}
|
|
54
91
|
|
|
55
|
-
{#if
|
|
92
|
+
{#if closable}
|
|
56
93
|
<button
|
|
57
94
|
type="button"
|
|
58
95
|
onclick={dismiss}
|
|
@@ -3,6 +3,15 @@ import type { Snippet } from 'svelte';
|
|
|
3
3
|
interface Props {
|
|
4
4
|
tone?: StatusToneInput;
|
|
5
5
|
dismissible?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Milliseconds before the banner closes itself, or `true` for the default.
|
|
8
|
+
*
|
|
9
|
+
* A confirmation clears itself. A warning and a failure stay until
|
|
10
|
+
* dismissed, so this is off by default. Pass it wherever the banner
|
|
11
|
+
* reports the outcome of a submit; leave it off where it states a standing
|
|
12
|
+
* condition, which does not stop being true after five seconds.
|
|
13
|
+
*/
|
|
14
|
+
autoDismiss?: number | boolean;
|
|
6
15
|
ondismiss?: () => void;
|
|
7
16
|
class?: string;
|
|
8
17
|
children: Snippet;
|
package/dist/index.d.ts
CHANGED
|
@@ -93,4 +93,4 @@ export { cn, type ClassValue } from './utils/cn.js';
|
|
|
93
93
|
export { getTheme, getThemePreference, nextThemePreference, resolveTheme, setTheme, setThemePreference, systemTheme, themeBootScript, toggleTheme, watchSystemTheme, THEME_PREFERENCES, type Theme, type ThemePreference, } from './utils/theme.js';
|
|
94
94
|
export * as motion from './motion.js';
|
|
95
95
|
export type { Rung as MotionRung, Curve as MotionCurve } from './motion.js';
|
|
96
|
-
export declare const VERSION = "0.
|
|
96
|
+
export declare const VERSION = "0.28.0";
|
package/dist/index.js
CHANGED
|
@@ -103,4 +103,4 @@ export * as motion from './motion.js';
|
|
|
103
103
|
// ── Version ────────────────────────────────────────────────────────────────
|
|
104
104
|
// Generated from package.json by `pnpm version:sync`. Bump package.json, never
|
|
105
105
|
// this line; the build and the test suite fail when the two disagree.
|
|
106
|
-
export const VERSION = '0.
|
|
106
|
+
export const VERSION = '0.28.0';
|
package/package.json
CHANGED