@ai-matrx/design-system 0.9.0 → 0.10.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/CHANGELOG.md +149 -0
- package/README.md +15 -1
- package/dist/index.cjs +174 -82
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +133 -8
- package/dist/index.d.ts +133 -8
- package/dist/index.js +174 -82
- package/dist/index.js.map +1 -1
- package/dist/styles.css +434 -0
- package/dist/tokens.css +25 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,154 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.10.0 — 2026-09-07
|
|
4
|
+
|
|
5
|
+
**THE MOTION SWEEP. Ten more primitives were animating with a host plugin this
|
|
6
|
+
package never declared and cannot declare — and three of the four consumers
|
|
7
|
+
never loaded it.** 0.8.0 and 0.9.0 closed the coin flip for `Accordion` and
|
|
8
|
+
`Collapsible` one primitive at a time. This release swept the rest of the
|
|
9
|
+
package for the same shape and found it everywhere at once.
|
|
10
|
+
|
|
11
|
+
Every floating surface here — `Dialog`, `AlertDialog`, `Sheet`,
|
|
12
|
+
`CommandDialog`, `Popover`, `DropdownMenu`, `ContextMenu`, `HoverCard`,
|
|
13
|
+
`Select`, `Tooltip` — carried a correctly spelled
|
|
14
|
+
`data-[state=open]:animate-in data-[state=closed]:animate-out
|
|
15
|
+
data-[state=closed]:fade-out-0 data-[state=open]:zoom-in-95
|
|
16
|
+
data-[side=bottom]:slide-in-from-top-2 …`. None of those is a Tailwind
|
|
17
|
+
utility. They come from the `tailwindcss-animate` plugin (or its v4 successor
|
|
18
|
+
`tw-animate-css`), which a host loads from its own CSS entry — something a
|
|
19
|
+
node_modules package can neither ship nor require.
|
|
20
|
+
|
|
21
|
+
Measured on each consumer's BUILT stylesheet before any of this landed
|
|
22
|
+
(`grep -c 'animate-in\|slide-in-from'`):
|
|
23
|
+
|
|
24
|
+
| Consumer | plugin | rules in built CSS |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| matrx-frontend | `@import "tw-animate-css"` in `globals.css` | present — animated |
|
|
27
|
+
| aidream/dashboard | none | **0** |
|
|
28
|
+
| aidream/workflow-studio | none | **0** |
|
|
29
|
+
| matrx-extend | `tailwindcss-animate` in `package.json`, **never loaded** (a Tailwind v3 plugin; extend is on v4 with no `@plugin` directive) | **0** |
|
|
30
|
+
|
|
31
|
+
So every dialog, dropdown, popover, tooltip, select and sheet in the two
|
|
32
|
+
aidream admin apps and the Chrome extension appeared instantly, with no
|
|
33
|
+
animation and no error, for as long as those components existed. The one host
|
|
34
|
+
that worked, worked by accident of its own CSS entry. That is the doctrine
|
|
35
|
+
sentence from `FEATURE.md` proven at scale: a primitive that leaves motion to
|
|
36
|
+
the host has not shipped motion, it has shipped a coin flip.
|
|
37
|
+
|
|
38
|
+
**The package now owns all of it.** `styles.css` gains a documented motion
|
|
39
|
+
layer: package-declared `@keyframes matrx-*`, applied through `matrx-`-prefixed
|
|
40
|
+
classes the components put on the DOM themselves, unlayered like the accordion
|
|
41
|
+
and collapsible rules so every consumer gets identical motion even where the
|
|
42
|
+
host plugin is still loaded.
|
|
43
|
+
|
|
44
|
+
| Motion | Class | Primitives |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| scrim fade | `matrx-motion-overlay` | Dialog, AlertDialog, Sheet, CommandDialog |
|
|
47
|
+
| centred card | `matrx-motion-dialog` | Dialog (desktop), AlertDialog, CommandDialog (desktop) |
|
|
48
|
+
| bottom sheet | `matrx-motion-bottom-sheet` | Dialog / CommandDialog below the mobile breakpoint |
|
|
49
|
+
| edge sheet | `matrx-motion-sheet-{top,bottom,left,right,center}` | Sheet, per `side` |
|
|
50
|
+
| popper | `matrx-motion-popper` | Popover, DropdownMenu, ContextMenu, HoverCard, Select, Tooltip |
|
|
51
|
+
| pulse | `matrx-pulse` | Skeleton |
|
|
52
|
+
| spin | `matrx-spin` | every inline busy indicator in the package |
|
|
53
|
+
|
|
54
|
+
Three things changed for the better on the way through:
|
|
55
|
+
|
|
56
|
+
- **The popper grows out of its trigger, not out of itself.** The rule reads
|
|
57
|
+
the anchor-facing origin Radix publishes — as a fallback CHAIN over
|
|
58
|
+
`--radix-popper-transform-origin` and each primitive's own alias
|
|
59
|
+
(`--radix-select-content-transform-origin`,
|
|
60
|
+
`--radix-tooltip-content-transform-origin`, …), because reusing one
|
|
61
|
+
primitive's measured variable on another is precisely the silent death
|
|
62
|
+
census row 19f recorded. The `zoom-in-95` original always scaled from the
|
|
63
|
+
element's centre.
|
|
64
|
+
- **Timing is a knob.** Every duration and easing resolves from a
|
|
65
|
+
`--matrx-motion-*` token in `tokens.css` (fast 150ms, base 200ms, slow
|
|
66
|
+
300ms, sheet 500ms, plus the two easings and the popper travel distance). An
|
|
67
|
+
org that wants calmer motion sets seven values instead of overriding twenty
|
|
68
|
+
rules. `prefers-reduced-motion` is NOT one of them — it is honoured in the
|
|
69
|
+
stylesheet regardless.
|
|
70
|
+
- **`animate-pulse` / `animate-spin` came home too.** Those two ARE core
|
|
71
|
+
Tailwind, so they survived in a Tailwind host — but a Skeleton that does not
|
|
72
|
+
pulse is an empty grey box and a spinner that does not spin says the work
|
|
73
|
+
stopped. Both are four lines; the package owns them. Under reduced motion
|
|
74
|
+
they SLOW rather than stop, because stopping them removes information rather
|
|
75
|
+
than removing motion.
|
|
76
|
+
|
|
77
|
+
**Where the line is, stated in the sheet:** this layer owns keyframe
|
|
78
|
+
animation — motion that either happens or silently does not. It deliberately
|
|
79
|
+
does not own Tailwind's `transition-*` / `duration-*` / `ease-*` utilities the
|
|
80
|
+
primitives also carry (a hover colour, the progress bar's width, a close
|
|
81
|
+
button's opacity). Those are core Tailwind, present in every Tailwind host,
|
|
82
|
+
and their absence degrades to an instant-but-correct change rather than to a
|
|
83
|
+
surface that lies about its state. Re-implementing them here would mean
|
|
84
|
+
shipping a copy of Tailwind.
|
|
85
|
+
|
|
86
|
+
**Opt-out:** `animated={false}` on `DialogContent`, `AlertDialogContent`,
|
|
87
|
+
`SheetContent`, `PopoverContent`, `HoverCardContent`, `TooltipContent`,
|
|
88
|
+
`SelectContent` and `Skeleton` returns the surface to instant. It is not the
|
|
89
|
+
reduced-motion switch; the stylesheet already handles that.
|
|
90
|
+
|
|
91
|
+
Guards, all proven failing-then-passing by re-introducing a
|
|
92
|
+
`data-[state=open]:animate-in` on `PopoverContent`:
|
|
93
|
+
|
|
94
|
+
- `motion.ts` — ONE exported constant per motion shape, so the eleventh
|
|
95
|
+
primitive cannot invent an eleventh spelling. Exported publicly
|
|
96
|
+
(`ALL_MOTION_CLASSES`, `FORBIDDEN_HOST_MOTION_UTILITIES`) so a consumer can
|
|
97
|
+
audit its own CSS against the same list.
|
|
98
|
+
- `motion.test.tsx` — one case per primitive, asserting BOTH halves: the
|
|
99
|
+
rendered element carries the class, AND `styles.css` defines a rule for it
|
|
100
|
+
whose keyframe that same sheet declares. A class-name assertion alone would
|
|
101
|
+
have passed throughout the defect. Plus: every Sheet side wears its own edge
|
|
102
|
+
class and no other; the mobile bottom sheet does not wear the card's
|
|
103
|
+
keyframe; every opt-out actually opts out and leaves geometry alone.
|
|
104
|
+
- `styles.test.ts` — no component may reference a host-plugin utility again;
|
|
105
|
+
every keyframe referenced is declared; every keyframe is `matrx-` prefixed;
|
|
106
|
+
every overlay duration comes from a token; every motion class appears in a
|
|
107
|
+
`prefers-reduced-motion` block; the popper origin chain is complete; and the
|
|
108
|
+
class list is exhaustive in BOTH directions.
|
|
109
|
+
- The packed-tarball canary asserts thirteen rules, six keyframes, both origin
|
|
110
|
+
variables, the timing tokens, and — the assertion that would have caught
|
|
111
|
+
this whole release from outside — that **every keyframe the packed sheet
|
|
112
|
+
references is declared in that same packed sheet**, read from the artifact a
|
|
113
|
+
consumer installs with no host in the room.
|
|
114
|
+
|
|
115
|
+
### Consumer action (C28)
|
|
116
|
+
|
|
117
|
+
- 🔶 **This is a VISIBLE change in three of the four consumers, on purpose.**
|
|
118
|
+
`aidream/dashboard`, `aidream/workflow-studio` and `matrx-extend` get open /
|
|
119
|
+
close animation on every dialog, dropdown, popover, tooltip, select and
|
|
120
|
+
sheet **for the first time**. They need no code change and no CSS: they
|
|
121
|
+
already import `@ai-matrx/design-system/styles.css`, so bumping the version
|
|
122
|
+
is the whole adoption. If a specific surface must not move, pass
|
|
123
|
+
`animated={false}` — do not re-add a host plugin.
|
|
124
|
+
- **matrx-frontend: `tw-animate-css` is no longer required by anything this
|
|
125
|
+
package renders.** Every `animate-in` / `slide-in-from-*` this package
|
|
126
|
+
emitted is gone. Audit your own components for remaining uses before
|
|
127
|
+
deleting the `@import "tw-animate-css"` from `app/globals.css` and the
|
|
128
|
+
dependency from `package.json`; the package no longer needs either.
|
|
129
|
+
- **matrx-extend: delete `tailwindcss-animate` from `package.json`.** It has
|
|
130
|
+
never been loaded — it is a Tailwind v3 plugin in a v4 app with no `@plugin`
|
|
131
|
+
directive, and the built stylesheet proves it contributed zero rules. It is
|
|
132
|
+
dead weight that also makes the app look like it has motion support.
|
|
133
|
+
- **Retiming is a token change now.** Do not override the motion rules; set
|
|
134
|
+
`--matrx-motion-duration-*` / `--matrx-motion-ease-*` /
|
|
135
|
+
`--matrx-motion-popper-travel`.
|
|
136
|
+
- New type exports: `PopoverContentProps`, `SelectContentProps`,
|
|
137
|
+
`SkeletonProps`. New value exports: `ALL_MOTION_CLASSES`,
|
|
138
|
+
`FORBIDDEN_HOST_MOTION_UTILITIES`, `MOTION_OVERLAY`, `MOTION_DIALOG`,
|
|
139
|
+
`MOTION_BOTTOM_SHEET`, `MOTION_POPPER`, `MOTION_SHEET`, `MOTION_PULSE`,
|
|
140
|
+
`MOTION_SPIN`.
|
|
141
|
+
- **Not fixed here, and named so it is not lost:** `@ai-matrx/kit`'s
|
|
142
|
+
`src/confirm/alert-dialog.tsx` carries the identical defect (`animate-in`,
|
|
143
|
+
`zoom-in-95`, `slide-in-from-top-[48%]`) and ships NO stylesheet at all, so
|
|
144
|
+
its confirm dialog is unanimated in the same three consumers. It cannot
|
|
145
|
+
import these rules: `@ai-matrx/design-system` depends on `@ai-matrx/kit`,
|
|
146
|
+
so the fix is a package-graph decision (move the confirm dialog, or invert
|
|
147
|
+
the dependency), not a class rename. `@ai-matrx/tap-target` has one
|
|
148
|
+
`animate-spin` in `src/tap-buttons.tsx` — core Tailwind, so it survives in
|
|
149
|
+
every current consumer, but it is the same class of host reliance and rides
|
|
150
|
+
the next tap-target release.
|
|
151
|
+
|
|
3
152
|
## 0.9.0 — 2026-09-07
|
|
4
153
|
|
|
5
154
|
**`Collapsible` gets the open/close transition the package never shipped
|
package/README.md
CHANGED
|
@@ -12,7 +12,21 @@ The small, semantic UI foundation shared by AI Matrx React applications — prim
|
|
|
12
12
|
|
|
13
13
|
Where hosts had forked a primitive over DENSITY, density is a prop, not a fork: `Card size="sm|md|lg"`, `Table size="sm|md"`, `Accordion size="sm|md"`, `Switch`/`Avatar`/`Checkbox`/`Slider`/`RadioGroup`/`Toggle` `size`, `ResizableHandle size="xs".."4xl"`. It is declared once on the root and every item reads it from context, so a card cannot mix paddings and a radio group cannot mix control sizes.
|
|
14
14
|
|
|
15
|
-
**Motion ships with the component
|
|
15
|
+
**Motion ships with the component — ALL of it.** Every animated surface here
|
|
16
|
+
(`Dialog`, `AlertDialog`, `Sheet`, `CommandDialog`, `Popover`, `DropdownMenu`,
|
|
17
|
+
`ContextMenu`, `HoverCard`, `Select`, `Tooltip`, `Accordion`, `Collapsible`,
|
|
18
|
+
`Skeleton`) animates out of the box from keyframes in `styles.css`. **You never
|
|
19
|
+
define keyframes, add an `animate-*` utility, or install `tailwindcss-animate`
|
|
20
|
+
/ `tw-animate-css` for anything this package renders** — that plugin is loaded
|
|
21
|
+
from a host's CSS entry, which is why three of the four apps that already used
|
|
22
|
+
this package had zero animation on every overlay and no error to show for it
|
|
23
|
+
(0.10.0). `prefers-reduced-motion` is honoured in the sheet.
|
|
24
|
+
|
|
25
|
+
Retiming is a token change, not an override — set `--matrx-motion-duration-fast`
|
|
26
|
+
/ `-base` / `-slow` / `-sheet`, `--matrx-motion-ease-out` / `-in`, or
|
|
27
|
+
`--matrx-motion-popper-travel`. For one surface that must appear instantly,
|
|
28
|
+
pass `animated={false}`; `CollapsibleContent`'s opt-out additionally stops it
|
|
29
|
+
clipping its body, for the rare panel with a child that must overflow.
|
|
16
30
|
|
|
17
31
|
**Mobile is the Drawer's job.** `Drawer` owns the iOS rules every host was re-deriving — `dvh` never `vh`, `pb-safe`/`pt-safe` safe-area padding, a 44px grab-handle target, `DrawerBody` as the `flex-1 min-h-0` scroll shard — and `direction` makes a top/side drawer a prop rather than a fork. Every touch control (`Slider`, `RadioGroup`, `ResizableHandle`) carries an invisible 44px target on coarse pointers, with desktop density untouched.
|
|
18
32
|
|