@enigmax/primitives 0.19.1 → 0.21.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/dist/chunk-JCCL7XKC.js +465 -0
- package/dist/{chunk-T4F3BWR5.js → chunk-LMZJBOZG.js} +68 -6
- package/dist/{chunk-XPKWJD5O.js → chunk-NPHRS2Q7.js} +1 -1
- package/dist/{flags-fLwIl2hG.d.ts → flags-BQU1V9rE.d.ts} +13 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js +3 -3
- package/dist/react/flag.d.ts +1 -1
- package/dist/react/flag.js +2 -2
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +3 -3
- package/dist/react/toast.d.ts +14 -13
- package/dist/react/toast.js +2 -2
- package/dist/react-router/index.d.ts +1 -1
- package/dist/react-router/index.js +3 -3
- package/package.json +1 -1
- package/recipes/toast/styles.css +173 -100
- package/registry.json +9 -4
- package/src/core/flags.ts +155 -11
- package/src/react/toast-styles.ts +247 -0
- package/src/react/toaster.tsx +174 -21
- package/dist/chunk-ZCUFYBPB.js +0 -154
package/dist/react/index.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export { RelativeTime, RelativeTimeProps } from './relative-time.js';
|
|
|
20
20
|
export { R as RelativeTimeFormat, a as RelativeTimeOptions, b as RelativeTimePrecision, c as RelativeTimeStyle, d as RelativeTimeTense } from '../relative-time-YpRTG7YH.js';
|
|
21
21
|
export { N as Notification, a as NotificationAction, b as NotificationInput, c as NotificationTone, e as NotificationsOptions } from '../notifications-BpVV6sel.js';
|
|
22
22
|
export { Flag, FlagProps } from './flag.js';
|
|
23
|
-
export { c as FlagFormat, d as FlagOptions, e as FlagShape, f as FlagSource, h as configureFlags, i as flagAttributes, k as flagName, l as flagSrc, m as flagView, n as normalizeFlagCode } from '../flags-
|
|
23
|
+
export { c as FlagFormat, d as FlagOptions, e as FlagShape, f as FlagSource, h as configureFlags, i as flagAttributes, k as flagName, l as flagSrc, m as flagView, n as normalizeFlagCode } from '../flags-BQU1V9rE.js';
|
|
24
24
|
export { PaletteContent, PaletteContextValue, PaletteField, PaletteFooter, PaletteItem, PaletteList, PaletteListProps, PaletteRoot, PaletteRootProps, PaletteRow, PaletteSection, PaletteTrigger, SearchPalette, SearchPaletteProps, usePaletteContext } from './palette.js';
|
|
25
25
|
export { R as RecentEntry, b as RecentStore, e as createRecentStore, g as groupRows, i as isPaletteShortcut, m as moveActive, r as recentKey, s as shortcutLabel } from '../palette-D7iuQh_T.js';
|
|
26
26
|
|
package/dist/react/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
export { useInput } from '../chunk-U3V4EHOB.js';
|
|
3
3
|
export { PasswordStrength } from '../chunk-XQHCZAPJ.js';
|
|
4
|
-
export { Flag } from '../chunk-
|
|
5
|
-
export { Toaster } from '../chunk-
|
|
4
|
+
export { Flag } from '../chunk-NPHRS2Q7.js';
|
|
5
|
+
export { Toaster } from '../chunk-JCCL7XKC.js';
|
|
6
6
|
export { useMarquee } from '../chunk-ZWR2EXHQ.js';
|
|
7
7
|
export { useSearch } from '../chunk-QQFNAKMY.js';
|
|
8
8
|
export { useNetworkState } from '../chunk-S653GLSF.js';
|
|
@@ -10,7 +10,7 @@ export { createNotificationQueue, defaultQueue, useNotifications } from '../chun
|
|
|
10
10
|
export { RelativeTime } from '../chunk-OCMI7R6H.js';
|
|
11
11
|
import '../chunk-KJINGUQN.js';
|
|
12
12
|
export { estimatePasswordStrength, generatePassword } from '../chunk-HC2ME5PU.js';
|
|
13
|
-
export { configureFlags, flagAttributes, flagName, flagSrc, flagView, normalizeFlagCode } from '../chunk-
|
|
13
|
+
export { configureFlags, flagAttributes, flagName, flagSrc, flagView, normalizeFlagCode } from '../chunk-LMZJBOZG.js';
|
|
14
14
|
import '../chunk-UOSSNUSC.js';
|
|
15
15
|
import '../chunk-2QFTRNAZ.js';
|
|
16
16
|
import '../chunk-SNYUBXWQ.js';
|
package/dist/react/toast.d.ts
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
import { d as Notifications, N as Notification } from '../notifications-BpVV6sel.js';
|
|
2
|
+
export { a as NotificationAction, b as NotificationInput, c as NotificationTone } from '../notifications-BpVV6sel.js';
|
|
2
3
|
import { ReactNode, CSSProperties } from 'react';
|
|
4
|
+
export { createNotificationQueue, defaultQueue, useNotifications } from './notifications.js';
|
|
3
5
|
|
|
4
|
-
/**
|
|
5
|
-
* `<Toaster />` - the stack, the movement and the gestures. No colours.
|
|
6
|
-
*
|
|
7
|
-
* The queue underneath already owns ordering, dedupe by key, sticky errors and timers that
|
|
8
|
-
* HOLD while the tab is hidden. What this adds is everything you cannot express in a queue:
|
|
9
|
-
* a toast that is on its way out is still on screen, a pointer resting on the stack must
|
|
10
|
-
* stop the clock, and a swipe has to follow the finger before it decides anything.
|
|
11
|
-
*
|
|
12
|
-
* Every part carries a data attribute, so the theme is a stylesheet you own. `enigma add
|
|
13
|
-
* toast --copy` writes one.
|
|
14
|
-
*/
|
|
15
6
|
type ToastPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
|
|
16
7
|
interface ToasterProps {
|
|
17
8
|
/** Which queue to render. The shared one by default. */
|
|
@@ -27,6 +18,16 @@ interface ToasterProps {
|
|
|
27
18
|
swipeThreshold?: number;
|
|
28
19
|
/** Render a toast yourself. The default renders title, body and the action. */
|
|
29
20
|
children?: (notification: Notification, controls: ToastControls) => ReactNode;
|
|
21
|
+
/** How many toasts are drawn at once. The rest wait behind them. Default 3. */
|
|
22
|
+
visibleCount?: number;
|
|
23
|
+
/** Fan the stack out permanently, instead of only while the pointer is on it. */
|
|
24
|
+
expand?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Inject the theme. On by default - see the note above; `false` leaves the markup
|
|
27
|
+
* unstyled for your own stylesheet, and `@enigmax/primitives/toast.css` is the same
|
|
28
|
+
* sheet if you would rather import it.
|
|
29
|
+
*/
|
|
30
|
+
styles?: boolean;
|
|
30
31
|
/** Accessible name for the region. */
|
|
31
32
|
label?: string;
|
|
32
33
|
className?: string;
|
|
@@ -35,6 +36,6 @@ interface ToasterProps {
|
|
|
35
36
|
interface ToastControls {
|
|
36
37
|
dismiss: () => void;
|
|
37
38
|
}
|
|
38
|
-
declare function Toaster({ queue, position, exitDuration, swipeThreshold, children, label, className, style }: ToasterProps): ReactNode;
|
|
39
|
+
declare function Toaster({ queue, position, exitDuration, swipeThreshold, visibleCount, expand, styles: withStyles, children, label, className, style }: ToasterProps): ReactNode;
|
|
39
40
|
|
|
40
|
-
export { type ToastControls, type ToastPosition, Toaster, type ToasterProps };
|
|
41
|
+
export { Notification, Notifications, type ToastControls, type ToastPosition, Toaster, type ToasterProps };
|
package/dist/react/toast.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { Toaster } from '../chunk-
|
|
3
|
-
|
|
2
|
+
export { Toaster } from '../chunk-JCCL7XKC.js';
|
|
3
|
+
export { createNotificationQueue, defaultQueue, useNotifications } from '../chunk-QYMUIW5I.js';
|
|
4
4
|
import '../chunk-SNYUBXWQ.js';
|
|
@@ -18,7 +18,7 @@ export { RelativeTime, RelativeTimeProps } from '../react/relative-time.js';
|
|
|
18
18
|
export { R as RelativeTimeFormat, a as RelativeTimeOptions, b as RelativeTimePrecision, c as RelativeTimeStyle, d as RelativeTimeTense } from '../relative-time-YpRTG7YH.js';
|
|
19
19
|
export { N as Notification, a as NotificationAction, b as NotificationInput, c as NotificationTone, e as NotificationsOptions } from '../notifications-BpVV6sel.js';
|
|
20
20
|
export { Flag, FlagProps } from '../react/flag.js';
|
|
21
|
-
export { c as FlagFormat, d as FlagOptions, e as FlagShape, f as FlagSource, h as configureFlags, i as flagAttributes, k as flagName, l as flagSrc, m as flagView, n as normalizeFlagCode } from '../flags-
|
|
21
|
+
export { c as FlagFormat, d as FlagOptions, e as FlagShape, f as FlagSource, h as configureFlags, i as flagAttributes, k as flagName, l as flagSrc, m as flagView, n as normalizeFlagCode } from '../flags-BQU1V9rE.js';
|
|
22
22
|
export { PaletteContent, PaletteContextValue, PaletteField, PaletteFooter, PaletteItem, PaletteList, PaletteListProps, PaletteRoot, PaletteRootProps, PaletteRow, PaletteSection, PaletteTrigger, SearchPalette, SearchPaletteProps, usePaletteContext } from '../react/palette.js';
|
|
23
23
|
export { R as RecentEntry, b as RecentStore, e as createRecentStore, g as groupRows, i as isPaletteShortcut, m as moveActive, r as recentKey, s as shortcutLabel } from '../palette-D7iuQh_T.js';
|
|
24
24
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
export { useInput } from '../chunk-U3V4EHOB.js';
|
|
3
3
|
export { PasswordStrength } from '../chunk-XQHCZAPJ.js';
|
|
4
|
-
export { Flag } from '../chunk-
|
|
5
|
-
export { Toaster } from '../chunk-
|
|
4
|
+
export { Flag } from '../chunk-NPHRS2Q7.js';
|
|
5
|
+
export { Toaster } from '../chunk-JCCL7XKC.js';
|
|
6
6
|
export { useMarquee } from '../chunk-ZWR2EXHQ.js';
|
|
7
7
|
export { useSearch } from '../chunk-QQFNAKMY.js';
|
|
8
8
|
export { useNetworkState } from '../chunk-S653GLSF.js';
|
|
@@ -10,7 +10,7 @@ export { createNotificationQueue, defaultQueue, useNotifications } from '../chun
|
|
|
10
10
|
export { RelativeTime } from '../chunk-OCMI7R6H.js';
|
|
11
11
|
import '../chunk-KJINGUQN.js';
|
|
12
12
|
export { estimatePasswordStrength, generatePassword } from '../chunk-HC2ME5PU.js';
|
|
13
|
-
export { configureFlags, flagAttributes, flagName, flagSrc, flagView, normalizeFlagCode } from '../chunk-
|
|
13
|
+
export { configureFlags, flagAttributes, flagName, flagSrc, flagView, normalizeFlagCode } from '../chunk-LMZJBOZG.js';
|
|
14
14
|
import '../chunk-UOSSNUSC.js';
|
|
15
15
|
import '../chunk-2QFTRNAZ.js';
|
|
16
16
|
import '../chunk-SNYUBXWQ.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enigmax/primitives",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Headless components: the behaviour, the timing and the accessibility, with no styles of their own. Framework-agnostic core plus thin adapters.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
package/recipes/toast/styles.css
CHANGED
|
@@ -1,165 +1,238 @@
|
|
|
1
1
|
/*
|
|
2
|
-
*
|
|
2
|
+
* The toast theme.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* GENERATED from src/react/toast-styles.ts by scripts/sync-recipes.mjs - edit that file, not
|
|
5
|
+
* this one. It exists as a stylesheet as well as a string because <Toaster /> injects the
|
|
6
|
+
* theme itself, and this is the same look for anyone who would rather import it, copy it
|
|
7
|
+
* with `enigma add toast --copy`, or fork it outright.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
* a different
|
|
9
|
+
* Every value is a custom property on [data-enigma-toaster]: override them there, or on
|
|
10
|
+
* :root, and you have a different toast without touching a selector.
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
-
:
|
|
13
|
-
--enigma-toast-
|
|
14
|
-
--enigma-toast-gap:
|
|
15
|
-
--enigma-toast-
|
|
16
|
-
--enigma-toast-
|
|
17
|
-
--enigma-toast-
|
|
12
|
+
[data-enigma-toaster] {
|
|
13
|
+
--enigma-toast-width: 356px;
|
|
14
|
+
--enigma-toast-edge: 24px;
|
|
15
|
+
--enigma-toast-gap: 14px;
|
|
16
|
+
--enigma-toast-peek: 14px;
|
|
17
|
+
--enigma-toast-scale-step: 0.06;
|
|
18
|
+
--enigma-toast-radius: 12px;
|
|
19
|
+
--enigma-toast-enter: 420ms;
|
|
20
|
+
--enigma-toast-exit: 350ms;
|
|
18
21
|
|
|
19
22
|
--enigma-toast-bg: #101010;
|
|
20
23
|
--enigma-toast-border: #2a2a2a;
|
|
21
24
|
--enigma-toast-text: #f5f5f5;
|
|
22
25
|
--enigma-toast-muted: #a3a3a3;
|
|
23
|
-
--enigma-toast-shadow: 0
|
|
26
|
+
--enigma-toast-shadow: 0 6px 22px rgb(0 0 0 / 34%);
|
|
27
|
+
|
|
28
|
+
--enigma-toast-success: hsl(150 80% 72%);
|
|
29
|
+
--enigma-toast-success-bg: hsl(150 38% 9%);
|
|
30
|
+
--enigma-toast-success-border: hsl(147 55% 18%);
|
|
31
|
+
--enigma-toast-error: hsl(358 100% 82%);
|
|
32
|
+
--enigma-toast-error-bg: hsl(358 42% 12%);
|
|
33
|
+
--enigma-toast-error-border: hsl(357 55% 24%);
|
|
34
|
+
--enigma-toast-info: hsl(216 87% 74%);
|
|
35
|
+
--enigma-toast-info-bg: hsl(215 45% 11%);
|
|
36
|
+
--enigma-toast-info-border: hsl(223 50% 24%);
|
|
37
|
+
--enigma-toast-warning: hsl(46 87% 70%);
|
|
38
|
+
--enigma-toast-warning-bg: hsl(40 55% 9%);
|
|
39
|
+
--enigma-toast-warning-border: hsl(40 55% 20%);
|
|
24
40
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
--enigma-toast-
|
|
28
|
-
|
|
29
|
-
|
|
41
|
+
position: fixed;
|
|
42
|
+
z-index: 999999;
|
|
43
|
+
width: var(--enigma-toast-width);
|
|
44
|
+
margin: 0;
|
|
45
|
+
padding: 0;
|
|
46
|
+
list-style: none;
|
|
47
|
+
outline: none;
|
|
48
|
+
font-family: inherit;
|
|
49
|
+
font-size: 13px;
|
|
50
|
+
/* The stack is a positioning context: every toast is absolute inside it, which is what
|
|
51
|
+
lets the ones behind be clipped to the front one's height. */
|
|
52
|
+
transition: transform 350ms ease;
|
|
30
53
|
}
|
|
31
54
|
|
|
32
55
|
@media (prefers-color-scheme: light) {
|
|
33
|
-
|
|
56
|
+
[data-enigma-toaster] {
|
|
34
57
|
--enigma-toast-bg: #ffffff;
|
|
35
58
|
--enigma-toast-border: #e5e5e5;
|
|
36
59
|
--enigma-toast-text: #171717;
|
|
37
60
|
--enigma-toast-muted: #737373;
|
|
38
|
-
--enigma-toast-shadow: 0
|
|
61
|
+
--enigma-toast-shadow: 0 6px 22px rgb(0 0 0 / 12%);
|
|
62
|
+
--enigma-toast-success-bg: hsl(143 85% 96%);
|
|
63
|
+
--enigma-toast-success-border: hsl(145 92% 87%);
|
|
64
|
+
--enigma-toast-success: hsl(140 100% 27%);
|
|
65
|
+
--enigma-toast-error-bg: hsl(359 100% 97%);
|
|
66
|
+
--enigma-toast-error-border: hsl(359 100% 94%);
|
|
67
|
+
--enigma-toast-error: hsl(360 100% 45%);
|
|
68
|
+
--enigma-toast-info-bg: hsl(208 100% 97%);
|
|
69
|
+
--enigma-toast-info-border: hsl(221 91% 93%);
|
|
70
|
+
--enigma-toast-info: hsl(210 92% 45%);
|
|
71
|
+
--enigma-toast-warning-bg: hsl(49 100% 97%);
|
|
72
|
+
--enigma-toast-warning-border: hsl(49 91% 84%);
|
|
73
|
+
--enigma-toast-warning: hsl(31 92% 45%);
|
|
39
74
|
}
|
|
40
75
|
}
|
|
41
76
|
|
|
42
|
-
[data-enigma-toaster] {
|
|
43
|
-
position: fixed;
|
|
44
|
-
z-index: 9999;
|
|
45
|
-
display: flex;
|
|
46
|
-
flex-direction: column;
|
|
47
|
-
gap: var(--enigma-toast-gap);
|
|
48
|
-
width: min(var(--enigma-toast-width), calc(100vw - var(--enigma-toast-edge) * 2));
|
|
49
|
-
/* The region is a layout box, not a wall: clicks pass through the gaps between toasts. */
|
|
50
|
-
pointer-events: none;
|
|
51
|
-
margin: 0;
|
|
52
|
-
padding: 0;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
[data-enigma-toaster][data-position^="top"] { top: var(--enigma-toast-edge); flex-direction: column-reverse; }
|
|
77
|
+
[data-enigma-toaster][data-position^="top"] { top: var(--enigma-toast-edge); }
|
|
56
78
|
[data-enigma-toaster][data-position^="bottom"] { bottom: var(--enigma-toast-edge); }
|
|
57
|
-
[data-enigma-toaster][data-position$="-left"] { left: var(--enigma-toast-edge); }
|
|
58
79
|
[data-enigma-toaster][data-position$="-right"] { right: var(--enigma-toast-edge); }
|
|
80
|
+
[data-enigma-toaster][data-position$="-left"] { left: var(--enigma-toast-edge); }
|
|
59
81
|
[data-enigma-toaster][data-position$="-center"] { left: 50%; transform: translateX(-50%); }
|
|
82
|
+
/* The whole stack lifts a little when it fans out, so the front toast does not sit on the
|
|
83
|
+
exact pixel it did a moment ago. */
|
|
84
|
+
[data-enigma-toaster][data-expanded][data-position^="bottom"] { transform: translateY(-6px); }
|
|
85
|
+
[data-enigma-toaster][data-expanded][data-position^="top"] { transform: translateY(6px); }
|
|
86
|
+
[data-enigma-toaster][data-expanded][data-position="bottom-center"] { transform: translateX(-50%) translateY(-6px); }
|
|
87
|
+
[data-enigma-toaster][data-expanded][data-position="top-center"] { transform: translateX(-50%) translateY(6px); }
|
|
60
88
|
|
|
61
89
|
[data-enigma-toast] {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
90
|
+
position: absolute;
|
|
91
|
+
left: 0;
|
|
92
|
+
right: 0;
|
|
93
|
+
width: 100%;
|
|
94
|
+
box-sizing: border-box;
|
|
95
|
+
display: flex;
|
|
66
96
|
align-items: center;
|
|
67
|
-
gap:
|
|
68
|
-
padding:
|
|
97
|
+
gap: 10px;
|
|
98
|
+
padding: 15px 16px;
|
|
69
99
|
color: var(--enigma-toast-text);
|
|
70
100
|
background: var(--enigma-toast-bg);
|
|
71
101
|
border: 1px solid var(--enigma-toast-border);
|
|
72
102
|
border-radius: var(--enigma-toast-radius);
|
|
73
103
|
box-shadow: var(--enigma-toast-shadow);
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
transition: translate 180ms cubic-bezier(0.22, 1, 0.36, 1), opacity 180ms ease-out;
|
|
77
|
-
touch-action: pan-y;
|
|
104
|
+
overflow-wrap: anywhere;
|
|
105
|
+
touch-action: none;
|
|
78
106
|
outline: none;
|
|
107
|
+
z-index: var(--enigma-toast-z, 1);
|
|
108
|
+
transition:
|
|
109
|
+
transform var(--enigma-toast-enter) cubic-bezier(0.21, 1.02, 0.73, 1),
|
|
110
|
+
opacity var(--enigma-toast-exit),
|
|
111
|
+
height 350ms;
|
|
79
112
|
}
|
|
80
113
|
|
|
81
|
-
[data-enigma-toaster][data-position
|
|
114
|
+
[data-enigma-toaster][data-position^="bottom"] [data-enigma-toast] { bottom: 0; transform-origin: bottom center; }
|
|
115
|
+
[data-enigma-toaster][data-position^="top"] [data-enigma-toast] { top: 0; transform-origin: top center; }
|
|
116
|
+
|
|
117
|
+
/* Enter from off screen, in the direction the stack is pinned to. */
|
|
118
|
+
[data-enigma-toaster][data-position^="bottom"] [data-enigma-toast] { transform: translateY(110%); opacity: 0; }
|
|
119
|
+
[data-enigma-toaster][data-position^="top"] [data-enigma-toast] { transform: translateY(-110%); opacity: 0; }
|
|
120
|
+
/* Scoped to the toaster so it OUTRANKS the enter rules above, which are scoped the same
|
|
121
|
+
way: at equal specificity the later rule wins, and a mounted toast that lost this one sat
|
|
122
|
+
at its entry offset forever - visible, and 110% of its own height off the bottom. */
|
|
123
|
+
[data-enigma-toaster] [data-enigma-toast][data-mounted] { opacity: 1; transform: translateY(0); }
|
|
124
|
+
|
|
125
|
+
/* Collapsed: the ones behind are clipped to the FRONT toast's height and scaled back, so
|
|
126
|
+
the stack reads as depth rather than as a list. Their content is hidden but present -
|
|
127
|
+
removing it would make the box jump when the stack expands. */
|
|
128
|
+
[data-enigma-toaster]:not([data-expanded]) [data-enigma-toast][data-mounted]:not([data-front]) {
|
|
129
|
+
height: var(--enigma-toast-front-height);
|
|
130
|
+
transform: translateY(calc(var(--enigma-toast-before) * var(--enigma-toast-peek) * -1))
|
|
131
|
+
scale(calc(1 - var(--enigma-toast-before) * var(--enigma-toast-scale-step)));
|
|
132
|
+
}
|
|
133
|
+
[data-enigma-toaster][data-position^="top"]:not([data-expanded]) [data-enigma-toast][data-mounted]:not([data-front]) {
|
|
134
|
+
transform: translateY(calc(var(--enigma-toast-before) * var(--enigma-toast-peek)))
|
|
135
|
+
scale(calc(1 - var(--enigma-toast-before) * var(--enigma-toast-scale-step)));
|
|
136
|
+
}
|
|
137
|
+
[data-enigma-toaster]:not([data-expanded]) [data-enigma-toast]:not([data-front]) > * { opacity: 0; }
|
|
138
|
+
[data-enigma-toast] > * { transition: opacity 350ms; }
|
|
82
139
|
|
|
83
|
-
/*
|
|
84
|
-
|
|
85
|
-
|
|
140
|
+
/* Expanded: each toast is lifted by the summed height of the ones in front of it. */
|
|
141
|
+
[data-enigma-toaster][data-expanded][data-position^="bottom"] [data-enigma-toast][data-mounted] {
|
|
142
|
+
transform: translateY(calc(var(--enigma-toast-offset) * -1));
|
|
143
|
+
}
|
|
144
|
+
[data-enigma-toaster][data-expanded][data-position^="top"] [data-enigma-toast][data-mounted] {
|
|
145
|
+
transform: translateY(var(--enigma-toast-offset));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* Past the visible count it is still in the DOM, still counted, and not on screen. */
|
|
149
|
+
[data-enigma-toast][data-hidden] { opacity: 0; pointer-events: none; }
|
|
150
|
+
|
|
151
|
+
[data-enigma-toast][data-state="leaving"] { opacity: 0; }
|
|
152
|
+
[data-enigma-toaster]:not([data-expanded]) [data-enigma-toast][data-state="leaving"] { transform: translateY(150%) scale(0.9); }
|
|
153
|
+
[data-enigma-toaster][data-expanded][data-position^="bottom"] [data-enigma-toast][data-state="leaving"] {
|
|
154
|
+
transform: translateY(calc(var(--enigma-toast-offset) * -1 + 110%));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* While a finger is down the toast tracks it exactly: a transition here would lag behind the
|
|
158
|
+
pointer, which reads as a broken gesture rather than a smooth one. */
|
|
159
|
+
[data-enigma-toast][data-swiping] {
|
|
160
|
+
transition: opacity 200ms;
|
|
161
|
+
transform: translateX(var(--enigma-toast-swipe, 0px));
|
|
162
|
+
}
|
|
86
163
|
|
|
87
164
|
[data-enigma-toast]:focus-visible { box-shadow: var(--enigma-toast-shadow), 0 0 0 2px var(--enigma-toast-info); }
|
|
88
165
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
background: var(--enigma-toast-
|
|
166
|
+
[data-enigma-toast][data-tone="success"] {
|
|
167
|
+
color: var(--enigma-toast-success);
|
|
168
|
+
background: var(--enigma-toast-success-bg);
|
|
169
|
+
border-color: var(--enigma-toast-success-border);
|
|
170
|
+
}
|
|
171
|
+
[data-enigma-toast][data-tone="error"] {
|
|
172
|
+
color: var(--enigma-toast-error);
|
|
173
|
+
background: var(--enigma-toast-error-bg);
|
|
174
|
+
border-color: var(--enigma-toast-error-border);
|
|
175
|
+
}
|
|
176
|
+
[data-enigma-toast][data-tone="info"] {
|
|
177
|
+
color: var(--enigma-toast-info);
|
|
178
|
+
background: var(--enigma-toast-info-bg);
|
|
179
|
+
border-color: var(--enigma-toast-info-border);
|
|
180
|
+
}
|
|
181
|
+
[data-enigma-toast][data-tone="warning"] {
|
|
182
|
+
color: var(--enigma-toast-warning);
|
|
183
|
+
background: var(--enigma-toast-warning-bg);
|
|
184
|
+
border-color: var(--enigma-toast-warning-border);
|
|
97
185
|
}
|
|
98
186
|
|
|
99
|
-
[data-enigma-toast
|
|
100
|
-
[data-enigma-toast
|
|
101
|
-
[data-enigma-toast][data-tone="
|
|
102
|
-
|
|
103
|
-
[data-enigma-toast][data-tone="loading"] { --enigma-toast-tone: var(--enigma-toast-loading); }
|
|
187
|
+
[data-enigma-toast-icon] { display: flex; flex-shrink: 0; width: 20px; height: 20px; }
|
|
188
|
+
[data-enigma-toast-icon] svg { width: 20px; height: 20px; display: block; }
|
|
189
|
+
[data-enigma-toast-icon][data-tone="loading"] svg { animation: enigma-toast-spin 900ms linear infinite; }
|
|
190
|
+
@keyframes enigma-toast-spin { to { transform: rotate(360deg); } }
|
|
104
191
|
|
|
105
|
-
[data-enigma-toast-
|
|
106
|
-
[data-enigma-toast-
|
|
192
|
+
[data-enigma-toast-content] { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
|
|
193
|
+
[data-enigma-toast-title] { margin: 0; font-weight: 600; line-height: 1.4; }
|
|
194
|
+
[data-enigma-toast-body] { margin: 0; font-size: 12px; line-height: 1.45; opacity: 0.75; }
|
|
107
195
|
|
|
108
196
|
[data-enigma-toast-action] {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
padding: 0.3125rem 0.625rem;
|
|
197
|
+
flex-shrink: 0;
|
|
198
|
+
padding: 5px 10px;
|
|
112
199
|
font: inherit;
|
|
113
|
-
font-size:
|
|
200
|
+
font-size: 12px;
|
|
114
201
|
font-weight: 600;
|
|
115
202
|
color: var(--enigma-toast-bg);
|
|
116
|
-
background:
|
|
203
|
+
background: currentColor;
|
|
117
204
|
border: 0;
|
|
118
|
-
border-radius:
|
|
205
|
+
border-radius: 6px;
|
|
119
206
|
cursor: pointer;
|
|
120
207
|
}
|
|
121
208
|
|
|
122
209
|
[data-enigma-toast-close] {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
color:
|
|
210
|
+
flex-shrink: 0;
|
|
211
|
+
display: grid;
|
|
212
|
+
place-items: center;
|
|
213
|
+
width: 20px;
|
|
214
|
+
height: 20px;
|
|
215
|
+
padding: 0;
|
|
216
|
+
color: inherit;
|
|
130
217
|
background: none;
|
|
131
218
|
border: 0;
|
|
219
|
+
border-radius: 5px;
|
|
132
220
|
cursor: pointer;
|
|
133
221
|
/* Shown on hover or focus, so it never covers the message while it is being read - but
|
|
134
|
-
always reachable by keyboard, which
|
|
222
|
+
always reachable by keyboard, which display:none would take away. */
|
|
135
223
|
opacity: 0;
|
|
136
224
|
transition: opacity 120ms ease-out;
|
|
137
225
|
}
|
|
138
|
-
|
|
139
226
|
[data-enigma-toast]:hover [data-enigma-toast-close],
|
|
140
|
-
[data-enigma-toast-close]:focus-visible { opacity:
|
|
141
|
-
|
|
142
|
-
/* Enter from the edge it is pinned to, leave the same way. */
|
|
143
|
-
@keyframes enigma-toast-in-right { from { opacity: 0; translate: 100% 0; } to { opacity: 1; translate: 0 0; } }
|
|
144
|
-
@keyframes enigma-toast-in-left { from { opacity: 0; translate: -100% 0; } to { opacity: 1; translate: 0 0; } }
|
|
145
|
-
@keyframes enigma-toast-in-top { from { opacity: 0; translate: 0 -100%; } to { opacity: 1; translate: 0 0; } }
|
|
146
|
-
@keyframes enigma-toast-in-bottom { from { opacity: 0; translate: 0 100%; } to { opacity: 1; translate: 0 0; } }
|
|
147
|
-
@keyframes enigma-toast-out { to { opacity: 0; scale: 0.94; } }
|
|
148
|
-
|
|
149
|
-
[data-position$="-right"] [data-enigma-toast][data-state="open"] { animation: enigma-toast-in-right 260ms cubic-bezier(0.22, 1, 0.36, 1); }
|
|
150
|
-
[data-position$="-left"] [data-enigma-toast][data-state="open"] { animation: enigma-toast-in-left 260ms cubic-bezier(0.22, 1, 0.36, 1); }
|
|
151
|
-
[data-position="top-center"] [data-enigma-toast][data-state="open"] { animation: enigma-toast-in-top 260ms cubic-bezier(0.22, 1, 0.36, 1); }
|
|
152
|
-
[data-position="bottom-center"] [data-enigma-toast][data-state="open"] { animation: enigma-toast-in-bottom 260ms cubic-bezier(0.22, 1, 0.36, 1); }
|
|
227
|
+
[data-enigma-toast-close]:focus-visible { opacity: 0.7; }
|
|
228
|
+
[data-enigma-toast-close]:hover { opacity: 1; }
|
|
153
229
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
[data-enigma-toast][data-state="leaving"] {
|
|
157
|
-
animation: enigma-toast-out var(--enigma-toast-exit) ease-in forwards;
|
|
158
|
-
pointer-events: none;
|
|
230
|
+
@media (max-width: 600px) {
|
|
231
|
+
[data-enigma-toaster] { right: 14px; left: 14px; width: auto; }
|
|
159
232
|
}
|
|
160
233
|
|
|
161
234
|
@media (prefers-reduced-motion: reduce) {
|
|
162
235
|
/* The movement goes, the state change stays: a toast still appears and still leaves. */
|
|
163
|
-
[data-enigma-toast]
|
|
164
|
-
[data-enigma-toast][data-
|
|
236
|
+
[data-enigma-toast], [data-enigma-toast] > * { transition: opacity 200ms !important; }
|
|
237
|
+
[data-enigma-toast][data-mounted] { transform: none !important; }
|
|
165
238
|
}
|
package/registry.json
CHANGED
|
@@ -711,12 +711,12 @@
|
|
|
711
711
|
{
|
|
712
712
|
"name": "toast",
|
|
713
713
|
"title": "Toast",
|
|
714
|
-
"description": "The notification queue with a renderer on top:
|
|
714
|
+
"description": "The notification queue with a renderer on top: the newest toast in front, the older ones stacked behind it and fanning out when the pointer arrives, swipe to dismiss, a pointer that stops the clock, and a toast that is still on screen while it animates out. It brings its own theme - a toast at the edge of the screen is the one component a forgotten stylesheet ruins rather than merely undresses.",
|
|
715
715
|
"targets": [
|
|
716
716
|
"react"
|
|
717
717
|
],
|
|
718
718
|
"entry": {
|
|
719
|
-
"react": "@enigmax/primitives/react"
|
|
719
|
+
"react": "@enigmax/primitives/react/toast"
|
|
720
720
|
},
|
|
721
721
|
"exports": {
|
|
722
722
|
"react": [
|
|
@@ -774,15 +774,20 @@
|
|
|
774
774
|
}
|
|
775
775
|
}
|
|
776
776
|
],
|
|
777
|
-
"styles":
|
|
777
|
+
"styles": true,
|
|
778
778
|
"themeHooks": [
|
|
779
779
|
"[data-enigma-toaster]",
|
|
780
780
|
"[data-enigma-toaster][data-position]",
|
|
781
|
+
"[data-enigma-toaster][data-expanded]",
|
|
781
782
|
"[data-enigma-toast]",
|
|
782
783
|
"[data-enigma-toast][data-tone=error]",
|
|
784
|
+
"[data-enigma-toast][data-front]",
|
|
785
|
+
"[data-enigma-toast][data-mounted]",
|
|
783
786
|
"[data-enigma-toast][data-state=leaving]",
|
|
784
787
|
"[data-enigma-toast][data-swiping]",
|
|
785
|
-
"[data-enigma-toast][data-
|
|
788
|
+
"[data-enigma-toast][data-hidden]",
|
|
789
|
+
"[data-enigma-toast-icon]",
|
|
790
|
+
"[data-enigma-toast-content]",
|
|
786
791
|
"[data-enigma-toast-title]",
|
|
787
792
|
"[data-enigma-toast-body]",
|
|
788
793
|
"[data-enigma-toast-action]",
|