@a4ui/core 0.10.1 → 0.11.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.
@@ -22,8 +22,8 @@ interface AppShellProps extends ParentProps {
22
22
  * an optional sidebar slot plus a content column (optional banner + topbar +
23
23
  * routed `<main>`). Slot-based and unopinionated about the sidebar — pass
24
24
  * your own component via `sidebar` and it manages its own width/collapse.
25
- * `<main>` is wrapped in `Suspense` + an `ErrorBoundary` (with a ~160ms page
26
- * cross-fade) so a route chunk failing or still loading never blanks the shell.
25
+ * `<main>` is wrapped in `Suspense` + an `ErrorBoundary` so a route chunk
26
+ * failing or still loading never blanks the shell.
27
27
  *
28
28
  * @example
29
29
  * ```tsx
@@ -1,4 +1,5 @@
1
1
  import { Accessor } from 'solid-js';
2
+ export { animate, inView, scroll, stagger, spring } from 'motion';
2
3
  /**
3
4
  * Snapshot of the user's reduced-motion preference at call time. Not
4
5
  * reactive to preference changes mid-session (matches theme.ts's one-shot
@@ -46,11 +47,8 @@ export declare function setMotionForced(on: boolean): void;
46
47
  */
47
48
  export declare function motionReduced(): boolean;
48
49
  /**
49
- * Tweens a numeric signal toward `target()` using requestAnimationFrame +
50
- * an ease-out curve (solid-motionone/@motionone don't expose spring easing
51
- * yet, and this needs to interpolate a plain number rather than a DOM
52
- * property, so it's a small hand-rolled WAAPI-adjacent tween for KPI count-up).
53
- * Jumps straight to the target under prefers-reduced-motion.
50
+ * Tweens a numeric signal toward `target()` with Motion's `animate` (ease-out),
51
+ * for KPI count-ups. Jumps straight to the target under reduced motion.
54
52
  *
55
53
  * @example
56
54
  * ```tsx
@@ -59,3 +57,20 @@ export declare function motionReduced(): boolean;
59
57
  * ```
60
58
  */
61
59
  export declare function createCountUp(target: Accessor<number>, durationMs?: number): Accessor<number>;
60
+ /**
61
+ * Fade + slide an element in on mount with Motion (ease-out), respecting
62
+ * reduced motion (a no-op then). Call it from a ref/onMount; use `delay` to
63
+ * stagger a row.
64
+ *
65
+ * @example
66
+ * ```tsx
67
+ * let el!: HTMLDivElement
68
+ * onMount(() => animateIn(el, { delay: 0.1 }))
69
+ * return <div ref={el}>…</div>
70
+ * ```
71
+ */
72
+ export declare function animateIn(el: Element, opts?: {
73
+ y?: number;
74
+ duration?: number;
75
+ delay?: number;
76
+ }): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a4ui/core",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "description": "A4ui — Spatial Glass design system & component library for SolidJS (Kobalte behavior + Tailwind glass tokens + motion).",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -106,8 +106,7 @@
106
106
  "@tanstack/solid-virtual": "^3.13.33",
107
107
  "clsx": "^2.1.1",
108
108
  "lucide-solid": "^1.23.0",
109
- "solid-motionone": "^1.0.4",
110
- "solid-transition-group": "^0.3.0",
109
+ "motion": "^12.42.2",
111
110
  "tailwind-merge": "^3.6.0"
112
111
  },
113
112
  "devDependencies": {
package/preset.js CHANGED
@@ -66,6 +66,31 @@ const glass = plugin(({ addComponents }) => {
66
66
  'radial-gradient(240px circle at var(--mx, 50%) var(--my, 50%), hsl(var(--primary) / 1), hsl(var(--accent) / 0.55) 42%, transparent 72%)',
67
67
  },
68
68
 
69
+ // ---- Field focus/error "bloom" ----
70
+ // Theme-aware glow for text fields: the colour comes from the theme's --ring
71
+ // (focus) or --destructive (invalid), so each theme blooms in its own hue.
72
+ // Applied via the `a4-field` class on inputs/triggers.
73
+ '.a4-field': {
74
+ transition: 'box-shadow .16s ease, border-color .16s ease',
75
+ },
76
+ '.a4-field:focus, .a4-field:focus-within': {
77
+ outline: 'none',
78
+ borderColor: 'hsl(var(--ring))',
79
+ boxShadow: '0 0 0 3px hsl(var(--ring) / 0.22), 0 0 16px -2px hsl(var(--ring) / 0.55)',
80
+ },
81
+ '.a4-field[aria-invalid="true"], .a4-field[data-invalid]': {
82
+ borderColor: 'hsl(var(--destructive))',
83
+ boxShadow: '0 0 0 2px hsl(var(--destructive) / 0.18)',
84
+ },
85
+ '.a4-field[aria-invalid="true"]:focus, .a4-field[data-invalid]:focus': {
86
+ outline: 'none',
87
+ boxShadow: '0 0 0 3px hsl(var(--destructive) / 0.3), 0 0 16px -2px hsl(var(--destructive) / 0.6)',
88
+ },
89
+ // Light backgrounds swallow soft glows — bloom a touch stronger there.
90
+ "[data-theme='light'] .a4-field:focus, [data-theme='light'] .a4-field:focus-within": {
91
+ boxShadow: '0 0 0 3px hsl(var(--ring) / 0.3), 0 0 18px -2px hsl(var(--ring) / 0.65)',
92
+ },
93
+
69
94
  // ---- Floating overlay glass (menus, modals, drawers, toasts) ----
70
95
  '.bg-glass': {
71
96
  background: 'hsl(var(--card) / 0.72)',