@enigmax/primitives 0.21.0 → 0.23.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.
Files changed (83) hide show
  1. package/dist/chunk-3BQVOOAM.js +388 -0
  2. package/dist/{chunk-QQFNAKMY.js → chunk-45UHLZYT.js} +1 -1
  3. package/dist/chunk-4VUHQFAT.js +130 -0
  4. package/dist/{chunk-D5A2ZMAG.js → chunk-4ZPMP47J.js} +6 -1
  5. package/dist/chunk-DSBYVA7V.js +713 -0
  6. package/dist/{chunk-FWVWX67R.js → chunk-FGBIZDV2.js} +3 -3
  7. package/dist/{chunk-R4ZAEE7V.js → chunk-KEVZ5XQV.js} +1 -1
  8. package/dist/chunk-N6PDHMAX.js +213 -0
  9. package/dist/chunk-NONGREXC.js +248 -0
  10. package/dist/chunk-VKL3DEIQ.js +804 -0
  11. package/dist/chunk-WPTBURIC.js +1627 -0
  12. package/dist/chunk-WSQC3PCC.js +466 -0
  13. package/dist/context-menu-D3FtTn7v.d.ts +174 -0
  14. package/dist/{index-dTdAbOWl.d.ts → index-DQNnohoo.d.ts} +1 -1
  15. package/dist/index.d.ts +5 -1
  16. package/dist/index.js +8 -4
  17. package/dist/keys-D2zJs1uB.d.ts +100 -0
  18. package/dist/next/index.d.ts +12 -5
  19. package/dist/next/index.js +21 -14
  20. package/dist/react/button.d.ts +2 -2
  21. package/dist/react/context-menu.d.ts +202 -0
  22. package/dist/react/context-menu.js +6 -0
  23. package/dist/react/index.d.ts +11 -4
  24. package/dist/react/index.js +20 -13
  25. package/dist/react/input.d.ts +2 -2
  26. package/dist/react/input.js +1 -1
  27. package/dist/react/palette.d.ts +1 -1
  28. package/dist/react/palette.js +3 -3
  29. package/dist/react/search.d.ts +1 -1
  30. package/dist/react/search.js +2 -2
  31. package/dist/react/select.d.ts +217 -0
  32. package/dist/react/select.js +7 -0
  33. package/dist/react/selection.d.ts +104 -0
  34. package/dist/react/selection.js +4 -0
  35. package/dist/react/slot.d.ts +2 -2
  36. package/dist/react/toast.d.ts +165 -32
  37. package/dist/react/toast.js +1 -1
  38. package/dist/react-router/index.d.ts +12 -5
  39. package/dist/react-router/index.js +21 -14
  40. package/dist/search/index.d.ts +2 -2
  41. package/dist/search/index.js +1 -1
  42. package/dist/{search-DXxY8SEH.d.ts → search-DYgqRp37.d.ts} +20 -3
  43. package/dist/{search-UQEXAPQB.js → search-PBZORZ7P.js} +1 -1
  44. package/dist/select-ClSy-J1f.d.ts +100 -0
  45. package/dist/selection-B_pmzHpy.d.ts +150 -0
  46. package/package.json +21 -2
  47. package/recipes/context-menu/styles.css +177 -0
  48. package/recipes/input/styles.css +9 -0
  49. package/recipes/palette/styles.css +3 -0
  50. package/recipes/search/tailwind.tsx +3 -2
  51. package/recipes/select/styles.css +230 -0
  52. package/recipes/toast/styles.css +688 -192
  53. package/registry.json +434 -29
  54. package/src/core/context-menu.ts +694 -0
  55. package/src/core/keys.ts +264 -0
  56. package/src/core/search.ts +25 -1
  57. package/src/core/select.ts +404 -0
  58. package/src/core/selection.ts +648 -0
  59. package/src/index.ts +60 -1
  60. package/src/react/context-menu/context.ts +57 -0
  61. package/src/react/context-menu/index.tsx +94 -0
  62. package/src/react/context-menu/root.tsx +846 -0
  63. package/src/react/context-menu/styles.ts +186 -0
  64. package/src/react/index.ts +70 -2
  65. package/src/react/palette/root.tsx +2 -2
  66. package/src/react/select/context.ts +56 -0
  67. package/src/react/select/index.tsx +96 -0
  68. package/src/react/select/root.tsx +839 -0
  69. package/src/react/select/styles.ts +238 -0
  70. package/src/react/selection/index.tsx +115 -0
  71. package/src/react/selection/use-selection.ts +260 -0
  72. package/src/react/toast/NOTICE +20 -0
  73. package/src/react/toast/assets.tsx +85 -0
  74. package/src/react/toast/cn.ts +10 -0
  75. package/src/react/toast/hooks.ts +13 -0
  76. package/src/react/toast/index.tsx +736 -0
  77. package/src/react/toast/state.ts +207 -0
  78. package/src/react/toast/styles.ts +738 -0
  79. package/src/react/toast/types.ts +193 -0
  80. package/src/react/toaster.tsx +76 -341
  81. package/dist/chunk-JCCL7XKC.js +0 -465
  82. package/src/react/toast-styles.ts +0 -247
  83. /package/dist/{chunk-U3V4EHOB.js → chunk-3HDEZ2E7.js} +0 -0
@@ -1,247 +0,0 @@
1
- /**
2
- * The toast theme, as a string, because `<Toaster />` injects it.
3
- *
4
- * A toast is the one component where "bring your own CSS" is the wrong default: it is
5
- * rendered into a portal at the edge of the screen, it stacks, and it animates - so a
6
- * consumer who forgets the stylesheet does not get an unstyled toast, they get a pile of
7
- * text in the corner. `<Toaster styles={false} />` turns it off for anyone who wants their
8
- * own, and the injected sheet is PREPENDED to `<head>` so any stylesheet in the document
9
- * outranks it by source order without needing a single `!important`.
10
- *
11
- * This module is the source of truth for `recipes/toast/styles.css` too, which
12
- * `scripts/sync-recipes.mjs` writes from it - one look, whether it is injected or copied.
13
- *
14
- * The geometry is the stacked-card pattern: the newest toast is the front one, older ones
15
- * sit behind it scaled down and clipped to the front one's height, and hovering the stack
16
- * fans them out by the summed height of the ones in front. Every number below is one of
17
- * those two states.
18
- */
19
- export const TOAST_STYLES = `
20
- [data-enigma-toaster] {
21
- --enigma-toast-width: 356px;
22
- --enigma-toast-edge: 24px;
23
- --enigma-toast-gap: 14px;
24
- --enigma-toast-peek: 14px;
25
- --enigma-toast-scale-step: 0.06;
26
- --enigma-toast-radius: 12px;
27
- --enigma-toast-enter: 420ms;
28
- --enigma-toast-exit: 350ms;
29
-
30
- --enigma-toast-bg: #101010;
31
- --enigma-toast-border: #2a2a2a;
32
- --enigma-toast-text: #f5f5f5;
33
- --enigma-toast-muted: #a3a3a3;
34
- --enigma-toast-shadow: 0 6px 22px rgb(0 0 0 / 34%);
35
-
36
- --enigma-toast-success: hsl(150 80% 72%);
37
- --enigma-toast-success-bg: hsl(150 38% 9%);
38
- --enigma-toast-success-border: hsl(147 55% 18%);
39
- --enigma-toast-error: hsl(358 100% 82%);
40
- --enigma-toast-error-bg: hsl(358 42% 12%);
41
- --enigma-toast-error-border: hsl(357 55% 24%);
42
- --enigma-toast-info: hsl(216 87% 74%);
43
- --enigma-toast-info-bg: hsl(215 45% 11%);
44
- --enigma-toast-info-border: hsl(223 50% 24%);
45
- --enigma-toast-warning: hsl(46 87% 70%);
46
- --enigma-toast-warning-bg: hsl(40 55% 9%);
47
- --enigma-toast-warning-border: hsl(40 55% 20%);
48
-
49
- position: fixed;
50
- z-index: 999999;
51
- width: var(--enigma-toast-width);
52
- margin: 0;
53
- padding: 0;
54
- list-style: none;
55
- outline: none;
56
- font-family: inherit;
57
- font-size: 13px;
58
- /* The stack is a positioning context: every toast is absolute inside it, which is what
59
- lets the ones behind be clipped to the front one's height. */
60
- transition: transform 350ms ease;
61
- }
62
-
63
- @media (prefers-color-scheme: light) {
64
- [data-enigma-toaster] {
65
- --enigma-toast-bg: #ffffff;
66
- --enigma-toast-border: #e5e5e5;
67
- --enigma-toast-text: #171717;
68
- --enigma-toast-muted: #737373;
69
- --enigma-toast-shadow: 0 6px 22px rgb(0 0 0 / 12%);
70
- --enigma-toast-success-bg: hsl(143 85% 96%);
71
- --enigma-toast-success-border: hsl(145 92% 87%);
72
- --enigma-toast-success: hsl(140 100% 27%);
73
- --enigma-toast-error-bg: hsl(359 100% 97%);
74
- --enigma-toast-error-border: hsl(359 100% 94%);
75
- --enigma-toast-error: hsl(360 100% 45%);
76
- --enigma-toast-info-bg: hsl(208 100% 97%);
77
- --enigma-toast-info-border: hsl(221 91% 93%);
78
- --enigma-toast-info: hsl(210 92% 45%);
79
- --enigma-toast-warning-bg: hsl(49 100% 97%);
80
- --enigma-toast-warning-border: hsl(49 91% 84%);
81
- --enigma-toast-warning: hsl(31 92% 45%);
82
- }
83
- }
84
-
85
- [data-enigma-toaster][data-position^="top"] { top: var(--enigma-toast-edge); }
86
- [data-enigma-toaster][data-position^="bottom"] { bottom: var(--enigma-toast-edge); }
87
- [data-enigma-toaster][data-position$="-right"] { right: var(--enigma-toast-edge); }
88
- [data-enigma-toaster][data-position$="-left"] { left: var(--enigma-toast-edge); }
89
- [data-enigma-toaster][data-position$="-center"] { left: 50%; transform: translateX(-50%); }
90
- /* The whole stack lifts a little when it fans out, so the front toast does not sit on the
91
- exact pixel it did a moment ago. */
92
- [data-enigma-toaster][data-expanded][data-position^="bottom"] { transform: translateY(-6px); }
93
- [data-enigma-toaster][data-expanded][data-position^="top"] { transform: translateY(6px); }
94
- [data-enigma-toaster][data-expanded][data-position="bottom-center"] { transform: translateX(-50%) translateY(-6px); }
95
- [data-enigma-toaster][data-expanded][data-position="top-center"] { transform: translateX(-50%) translateY(6px); }
96
-
97
- [data-enigma-toast] {
98
- position: absolute;
99
- left: 0;
100
- right: 0;
101
- width: 100%;
102
- box-sizing: border-box;
103
- display: flex;
104
- align-items: center;
105
- gap: 10px;
106
- padding: 15px 16px;
107
- color: var(--enigma-toast-text);
108
- background: var(--enigma-toast-bg);
109
- border: 1px solid var(--enigma-toast-border);
110
- border-radius: var(--enigma-toast-radius);
111
- box-shadow: var(--enigma-toast-shadow);
112
- overflow-wrap: anywhere;
113
- touch-action: none;
114
- outline: none;
115
- z-index: var(--enigma-toast-z, 1);
116
- transition:
117
- transform var(--enigma-toast-enter) cubic-bezier(0.21, 1.02, 0.73, 1),
118
- opacity var(--enigma-toast-exit),
119
- height 350ms;
120
- }
121
-
122
- [data-enigma-toaster][data-position^="bottom"] [data-enigma-toast] { bottom: 0; transform-origin: bottom center; }
123
- [data-enigma-toaster][data-position^="top"] [data-enigma-toast] { top: 0; transform-origin: top center; }
124
-
125
- /* Enter from off screen, in the direction the stack is pinned to. */
126
- [data-enigma-toaster][data-position^="bottom"] [data-enigma-toast] { transform: translateY(110%); opacity: 0; }
127
- [data-enigma-toaster][data-position^="top"] [data-enigma-toast] { transform: translateY(-110%); opacity: 0; }
128
- /* Scoped to the toaster so it OUTRANKS the enter rules above, which are scoped the same
129
- way: at equal specificity the later rule wins, and a mounted toast that lost this one sat
130
- at its entry offset forever - visible, and 110% of its own height off the bottom. */
131
- [data-enigma-toaster] [data-enigma-toast][data-mounted] { opacity: 1; transform: translateY(0); }
132
-
133
- /* Collapsed: the ones behind are clipped to the FRONT toast's height and scaled back, so
134
- the stack reads as depth rather than as a list. Their content is hidden but present -
135
- removing it would make the box jump when the stack expands. */
136
- [data-enigma-toaster]:not([data-expanded]) [data-enigma-toast][data-mounted]:not([data-front]) {
137
- height: var(--enigma-toast-front-height);
138
- transform: translateY(calc(var(--enigma-toast-before) * var(--enigma-toast-peek) * -1))
139
- scale(calc(1 - var(--enigma-toast-before) * var(--enigma-toast-scale-step)));
140
- }
141
- [data-enigma-toaster][data-position^="top"]:not([data-expanded]) [data-enigma-toast][data-mounted]:not([data-front]) {
142
- transform: translateY(calc(var(--enigma-toast-before) * var(--enigma-toast-peek)))
143
- scale(calc(1 - var(--enigma-toast-before) * var(--enigma-toast-scale-step)));
144
- }
145
- [data-enigma-toaster]:not([data-expanded]) [data-enigma-toast]:not([data-front]) > * { opacity: 0; }
146
- [data-enigma-toast] > * { transition: opacity 350ms; }
147
-
148
- /* Expanded: each toast is lifted by the summed height of the ones in front of it. */
149
- [data-enigma-toaster][data-expanded][data-position^="bottom"] [data-enigma-toast][data-mounted] {
150
- transform: translateY(calc(var(--enigma-toast-offset) * -1));
151
- }
152
- [data-enigma-toaster][data-expanded][data-position^="top"] [data-enigma-toast][data-mounted] {
153
- transform: translateY(var(--enigma-toast-offset));
154
- }
155
-
156
- /* Past the visible count it is still in the DOM, still counted, and not on screen. */
157
- [data-enigma-toast][data-hidden] { opacity: 0; pointer-events: none; }
158
-
159
- [data-enigma-toast][data-state="leaving"] { opacity: 0; }
160
- [data-enigma-toaster]:not([data-expanded]) [data-enigma-toast][data-state="leaving"] { transform: translateY(150%) scale(0.9); }
161
- [data-enigma-toaster][data-expanded][data-position^="bottom"] [data-enigma-toast][data-state="leaving"] {
162
- transform: translateY(calc(var(--enigma-toast-offset) * -1 + 110%));
163
- }
164
-
165
- /* While a finger is down the toast tracks it exactly: a transition here would lag behind the
166
- pointer, which reads as a broken gesture rather than a smooth one. */
167
- [data-enigma-toast][data-swiping] {
168
- transition: opacity 200ms;
169
- transform: translateX(var(--enigma-toast-swipe, 0px));
170
- }
171
-
172
- [data-enigma-toast]:focus-visible { box-shadow: var(--enigma-toast-shadow), 0 0 0 2px var(--enigma-toast-info); }
173
-
174
- [data-enigma-toast][data-tone="success"] {
175
- color: var(--enigma-toast-success);
176
- background: var(--enigma-toast-success-bg);
177
- border-color: var(--enigma-toast-success-border);
178
- }
179
- [data-enigma-toast][data-tone="error"] {
180
- color: var(--enigma-toast-error);
181
- background: var(--enigma-toast-error-bg);
182
- border-color: var(--enigma-toast-error-border);
183
- }
184
- [data-enigma-toast][data-tone="info"] {
185
- color: var(--enigma-toast-info);
186
- background: var(--enigma-toast-info-bg);
187
- border-color: var(--enigma-toast-info-border);
188
- }
189
- [data-enigma-toast][data-tone="warning"] {
190
- color: var(--enigma-toast-warning);
191
- background: var(--enigma-toast-warning-bg);
192
- border-color: var(--enigma-toast-warning-border);
193
- }
194
-
195
- [data-enigma-toast-icon] { display: flex; flex-shrink: 0; width: 20px; height: 20px; }
196
- [data-enigma-toast-icon] svg { width: 20px; height: 20px; display: block; }
197
- [data-enigma-toast-icon][data-tone="loading"] svg { animation: enigma-toast-spin 900ms linear infinite; }
198
- @keyframes enigma-toast-spin { to { transform: rotate(360deg); } }
199
-
200
- [data-enigma-toast-content] { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
201
- [data-enigma-toast-title] { margin: 0; font-weight: 600; line-height: 1.4; }
202
- [data-enigma-toast-body] { margin: 0; font-size: 12px; line-height: 1.45; opacity: 0.75; }
203
-
204
- [data-enigma-toast-action] {
205
- flex-shrink: 0;
206
- padding: 5px 10px;
207
- font: inherit;
208
- font-size: 12px;
209
- font-weight: 600;
210
- color: var(--enigma-toast-bg);
211
- background: currentColor;
212
- border: 0;
213
- border-radius: 6px;
214
- cursor: pointer;
215
- }
216
-
217
- [data-enigma-toast-close] {
218
- flex-shrink: 0;
219
- display: grid;
220
- place-items: center;
221
- width: 20px;
222
- height: 20px;
223
- padding: 0;
224
- color: inherit;
225
- background: none;
226
- border: 0;
227
- border-radius: 5px;
228
- cursor: pointer;
229
- /* Shown on hover or focus, so it never covers the message while it is being read - but
230
- always reachable by keyboard, which display:none would take away. */
231
- opacity: 0;
232
- transition: opacity 120ms ease-out;
233
- }
234
- [data-enigma-toast]:hover [data-enigma-toast-close],
235
- [data-enigma-toast-close]:focus-visible { opacity: 0.7; }
236
- [data-enigma-toast-close]:hover { opacity: 1; }
237
-
238
- @media (max-width: 600px) {
239
- [data-enigma-toaster] { right: 14px; left: 14px; width: auto; }
240
- }
241
-
242
- @media (prefers-reduced-motion: reduce) {
243
- /* The movement goes, the state change stays: a toast still appears and still leaves. */
244
- [data-enigma-toast], [data-enigma-toast] > * { transition: opacity 200ms !important; }
245
- [data-enigma-toast][data-mounted] { transform: none !important; }
246
- }
247
- `;
File without changes