@evinvest/uikit 0.15.2 → 0.17.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evinvest/uikit",
3
- "version": "0.15.2",
3
+ "version": "0.17.0",
4
4
  "description": "Dep-light React UI kit: shadcn-semantics components with zero @radix-ui / cva, mirroring the ev_lib::uikit Rust feature. Ships the shared design tokens.",
5
5
  "license": "BlueOak-1.0.0",
6
6
  "publishConfig": {
package/styles/tokens.css CHANGED
@@ -37,7 +37,7 @@
37
37
  */
38
38
 
39
39
  /*
40
- * Toast (sonner) enter/exit motion, shared by both ports. Imported by the token
40
+ * Toast (sonner) and Drawer enter/exit motion, shared by both ports. Imported by the token
41
41
  * sheets so the lifecycle ships with the theme contract.
42
42
  */
43
43
 
@@ -209,6 +209,140 @@
209
209
  }
210
210
  }
211
211
 
212
+ /* ── Drawer (Vaul-style) motion, shared by both ports via data-slot ──────────
213
+ Both ports render the panel as [data-slot="drawer-content"] with
214
+ data-vaul-drawer-direction + data-state, and the scrim as
215
+ [data-slot="drawer-overlay"] with data-state. The enter is a keyframe (plays
216
+ on DOM insertion — no JS mount flip, same reason as the toast above) on the
217
+ independent `translate` property, so it composes with the `transform` the
218
+ React port writes while a finger drags the panel. Closing flips
219
+ data-state=closed: `transform` transitions to the off-screen edge and the
220
+ node is dropped on that transitionend. A drag sets data-dragging on the panel
221
+ and the scrim to kill their transitions for 1:1 finger tracking, then clears
222
+ it on release so the same transition either snaps the panel home or (with
223
+ data-state=closed in the same frame) carries it off from where the finger
224
+ left it. Timing is Vaul's: 500ms cubic-bezier(0.32, 0.72, 0, 1) both ways.
225
+
226
+ touch-action:none on the panel keeps the browser from turning a touch into a
227
+ page pan (which would pointercancel the drag). It does NOT reach into a
228
+ scroll container nested in the panel — that one keeps native touch scrolling,
229
+ and the React port only starts a drag from it when it sits at its top. So
230
+ the scrollable region of a drawer belongs INSIDE the panel, not on it. */
231
+
232
+ [data-slot="drawer-content"] {
233
+ --ev-drawer-ease: cubic-bezier(0.32, 0.72, 0, 1);
234
+ touch-action: none;
235
+ will-change: transform;
236
+ transition: transform 500ms var(--ev-drawer-ease);
237
+ animation: ev-drawer-enter 500ms var(--ev-drawer-ease) backwards;
238
+ }
239
+ [data-slot="drawer-content"][data-vaul-drawer-direction="bottom"] {
240
+ --ev-drawer-from: 0 100%;
241
+ --ev-drawer-out: translate3d(0, 100%, 0);
242
+ }
243
+ [data-slot="drawer-content"][data-vaul-drawer-direction="top"] {
244
+ --ev-drawer-from: 0 -100%;
245
+ --ev-drawer-out: translate3d(0, -100%, 0);
246
+ }
247
+ [data-slot="drawer-content"][data-vaul-drawer-direction="left"] {
248
+ --ev-drawer-from: -100% 0;
249
+ --ev-drawer-out: translate3d(-100%, 0, 0);
250
+ }
251
+ [data-slot="drawer-content"][data-vaul-drawer-direction="right"] {
252
+ --ev-drawer-from: 100% 0;
253
+ --ev-drawer-out: translate3d(100%, 0, 0);
254
+ }
255
+ @keyframes ev-drawer-enter {
256
+ from {
257
+ translate: var(--ev-drawer-from, 0 100%);
258
+ }
259
+ to {
260
+ translate: 0 0;
261
+ }
262
+ }
263
+ [data-slot="drawer-content"][data-state="closed"] {
264
+ transform: var(--ev-drawer-out, translate3d(0, 100%, 0));
265
+ }
266
+
267
+ /* the over-drag away from the edge is dampened but still moves the panel, so
268
+ the panel's own background extends past its docked edge to cover the gap */
269
+ [data-slot="drawer-content"]::after {
270
+ content: "";
271
+ position: absolute;
272
+ background: inherit;
273
+ pointer-events: none;
274
+ }
275
+ [data-slot="drawer-content"][data-vaul-drawer-direction="bottom"]::after {
276
+ top: 100%;
277
+ left: 0;
278
+ right: 0;
279
+ height: 200%;
280
+ }
281
+ [data-slot="drawer-content"][data-vaul-drawer-direction="top"]::after {
282
+ bottom: 100%;
283
+ left: 0;
284
+ right: 0;
285
+ height: 200%;
286
+ }
287
+ [data-slot="drawer-content"][data-vaul-drawer-direction="left"]::after {
288
+ right: 100%;
289
+ top: 0;
290
+ bottom: 0;
291
+ width: 200%;
292
+ }
293
+ [data-slot="drawer-content"][data-vaul-drawer-direction="right"]::after {
294
+ left: 100%;
295
+ top: 0;
296
+ bottom: 0;
297
+ width: 200%;
298
+ }
299
+
300
+ [data-slot="drawer-overlay"] {
301
+ touch-action: none;
302
+ will-change: opacity;
303
+ transition: opacity 500ms cubic-bezier(0.32, 0.72, 0, 1);
304
+ animation: ev-drawer-fade-in 500ms cubic-bezier(0.32, 0.72, 0, 1) backwards;
305
+ }
306
+ @keyframes ev-drawer-fade-in {
307
+ from {
308
+ opacity: 0;
309
+ }
310
+ }
311
+ [data-slot="drawer-overlay"][data-state="closed"] {
312
+ opacity: 0;
313
+ }
314
+
315
+ /* 1:1 finger tracking during a drag — kill the transitions */
316
+ [data-slot="drawer-content"][data-dragging="true"],
317
+ [data-slot="drawer-overlay"][data-dragging="true"] {
318
+ transition: none;
319
+ }
320
+
321
+ /* a mouse drag would otherwise start a text selection alongside the panel */
322
+ @media (hover: hover) and (pointer: fine) {
323
+ [data-slot="drawer-content"] {
324
+ user-select: none;
325
+ }
326
+ }
327
+
328
+ /* reduced motion: fade only. The transform transition stays (1ms) so its
329
+ transitionend still fires and the closing node is still dropped. */
330
+ @media (prefers-reduced-motion: reduce) {
331
+ [data-slot="drawer-content"] {
332
+ transition:
333
+ transform 1ms linear,
334
+ opacity 200ms;
335
+ animation: ev-drawer-fade-in 200ms;
336
+ }
337
+ [data-slot="drawer-content"][data-state="closed"] {
338
+ opacity: 0;
339
+ }
340
+ [data-slot="drawer-overlay"] {
341
+ transition: opacity 200ms;
342
+ animation: ev-drawer-fade-in 200ms;
343
+ }
344
+ }
345
+
212
346
  @theme inline {
213
347
  --radius-sm: calc(var(--radius) - 4px);
214
348
  --radius-md: calc(var(--radius) - 2px);