@ai-matrx/design-system 0.11.0 → 0.11.1

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 CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.11.1 — 2026-09-07
4
+
5
+ **The 0.10.1 dialog-centring fix, on the current line.** 0.11.0 was cut and
6
+ published minutes before the fix landed, so `latest` briefly carried the
7
+ regression: `Dialog`, `AlertDialog` and `CommandDialog` flew in from beyond the
8
+ viewport's top-left corner and snapped into place at the end of their 200ms
9
+ animation. **`ConfirmDialog`, which arrived in 0.11.0, is an `AlertDialog` and
10
+ was therefore affected on every Tailwind v4 host** — this is the release that
11
+ fixes it.
12
+
13
+ Root cause, census, the `.matrx-dialog-centered` / `.matrx-popper-offset` fix
14
+ and its failing-then-passing guard are all documented in § 0.10.1 below; this
15
+ release is that change and nothing else. 0.10.1 exists for anyone still on the
16
+ 0.10.x line and is published under a side dist-tag so it cannot pull `latest`
17
+ backwards past the confirm surface.
18
+
19
+ ### Consumer action (C28)
20
+
21
+ **None** — no API change, resting geometry identical. Take the patch. The three
22
+ consumers that regressed at 0.10.0 and stayed regressed at 0.11.0:
23
+ **aidream/dashboard**, **aidream/workflow-studio**, **matrx-extend**.
24
+ matrx-frontend was never visibly changed (its pre-0.10.0 `tw-animate-css`
25
+ spelling had the identical flaw) but should take it too.
26
+
3
27
  ## 0.11.0 — 2026-09-07
4
28
 
5
29
  **THE CONFIRM SURFACE MOVES IN.** `ConfirmDialog` and `ConfirmDialogHost` — the
@@ -68,6 +92,84 @@ Mount `<ConfirmDialogHost />` from **here** and keep calling `confirm()` from
68
92
  imperative import — is in `@ai-matrx/kit` CHANGELOG § 0.9.0 § Consumer action.
69
93
  Take both releases together: design-system >= 0.11.0 with kit >= 0.9.0.
70
94
 
95
+ ## 0.10.1 — 2026-09-07
96
+
97
+ **THE CENTRED DIALOG FLEW IN FROM OFF THE SCREEN.** 0.10.0 shipped a live
98
+ regression: `Dialog`, `AlertDialog` and `CommandDialog` entered from beyond the
99
+ top-left corner of the viewport and SNAPPED into place at the end of their
100
+ 200ms animation. Independent review caught it on the live surface, measured it,
101
+ and proved the cause rather than inferring it.
102
+
103
+ **The cause is that one Tailwind class means two different things.**
104
+
105
+ | | `translate-x-[-50%] translate-y-[-50%]` compiles to |
106
+ |---|---|
107
+ | Tailwind **v3** | `transform: translate(-50%, -50%)` — REPLACED by an animation of `transform` |
108
+ | Tailwind **v4** | `translate: -50% -50%` — an independent property that **composes with** `transform` |
109
+
110
+ 0.10.0's keyframes restated the centring inside `transform`
111
+ (`translate(-50%,-48%)` -> `translate(-50%,-50%)`), which is correct under v3
112
+ and doubles the centring under v4. Measured on the live element, viewport
113
+ 2560x1289, `getComputedStyle(el).translate === "-50% -50%"` while
114
+ `transform === "none"` at rest:
115
+
116
+ | | x | y |
117
+ |---|---|---|
118
+ | resting (correct) | 128 | 32 |
119
+ | `currentTime = 0` | **-966** | **-525** |
120
+ | `currentTime = 100` | **-1015** | **-571** |
121
+ | `currentTime = 199`, `el.style.translate = "none"` | 137 | 41 |
122
+
123
+ That last row is the proof: removing the `translate` property mid-animation
124
+ restores the resting position exactly, because the element was wearing the
125
+ centring twice.
126
+
127
+ **The fix is not a different spelling of the keyframes** — there isn't one that
128
+ works in both hosts. Restate the offset and v4 applies it twice; omit it and v3
129
+ drops it for the animation's duration and snaps at the end. So the offset stops
130
+ being a Tailwind utility at all. This package now owns it, in the `translate`
131
+ property, in its own stylesheet:
132
+
133
+ - `.matrx-dialog-centered` (`translate: -50% -50%`) carries the centring, and
134
+ the keyframes carry ONLY the delta — `opacity`, plus a 2% rise scaled up from
135
+ 95% in `transform`, ending on `transform: none`. Resting geometry is
136
+ byte-identical to 0.10.0's; `transform` and `translate` never restate each
137
+ other again, in any host.
138
+ - **Census — the same hazard, one more surface.** `Select` in `popper` position
139
+ held its 4px gap from the trigger with `data-[side=bottom]:translate-y-1` and
140
+ three siblings, while `matrx-popper-*` keyframes animate `transform`. Same
141
+ defect, 4px instead of half a viewport, failing the other way round (a v3
142
+ host ate the gap for the animation and snapped it back). It is now
143
+ `.matrx-popper-offset`, sized by the new `--matrx-popper-offset` token.
144
+ - `Sheet`, the mobile bottom sheet and every other popper were **not** affected
145
+ and are unchanged — their translate utilities are zero-valued or absent.
146
+
147
+ **The guard, proven failing-then-passing.** jsdom cannot measure a composite
148
+ transform, so the hazard is asserted as a RULE over the sources in
149
+ `motion.test.tsx`: *no component may pair a NON-ZERO Tailwind translate utility
150
+ with a package motion class*, plus the centred keyframes may not mention `-50%`
151
+ and must end on `transform: none`, plus each of the three surfaces must render
152
+ the package's centring class. Restoring 0.10.0's exact shape (the utility in
153
+ `DIALOG_DESKTOP_CLASSES` and the centring back in the keyframes) turns 4 of
154
+ these red; the fix turns them green. `motion.test.tsx`'s old assertion that
155
+ `translate-x-[-50%]` survives `animated={false}` PINNED the defect — it now
156
+ asserts the centring class survives and the utility is gone. The C26 canaries
157
+ grew too: both new rules are required in `styles.test.ts` and in the packed
158
+ tarball.
159
+
160
+ ### Consumer action (C28)
161
+
162
+ **None.** No API changed, no class a consumer writes changed, and resting
163
+ geometry is identical. Take the patch.
164
+
165
+ Named, because they are the ones that regressed: **aidream/dashboard**,
166
+ **aidream/workflow-studio** and **matrx-extend** loaded no animation rules at
167
+ all before 0.10.0, so their dialogs had always appeared instantly and correctly
168
+ centred — 0.10.0 is what gave them a dialog that flies in from off-screen.
169
+ matrx-frontend was NOT visibly changed by either release: its pre-0.10.0
170
+ `tw-animate-css` spelling had the identical stacking flaw. All four are correct
171
+ on 0.10.1.
172
+
71
173
  ## 0.10.0 — 2026-09-07
72
174
 
73
175
  **THE MOTION SWEEP. Ten more primitives were animating with a host plugin this
package/dist/index.cjs CHANGED
@@ -62,6 +62,7 @@ __export(src_exports, {
62
62
  BottomSheetFooter: () => BottomSheetFooter,
63
63
  BottomSheetHeader: () => BottomSheetHeader,
64
64
  Button: () => Button,
65
+ CENTERED_DIALOG: () => CENTERED_DIALOG,
65
66
  Card: () => Card,
66
67
  CardAction: () => CardAction,
67
68
  CardContent: () => CardContent,
@@ -157,6 +158,7 @@ __export(src_exports, {
157
158
  MOTION_SHEET: () => MOTION_SHEET,
158
159
  MOTION_SPIN: () => MOTION_SPIN,
159
160
  OverflowToolbar: () => OverflowToolbar,
161
+ POPPER_OFFSET: () => POPPER_OFFSET,
160
162
  Popover: () => Popover,
161
163
  PopoverAnchor: () => PopoverAnchor,
162
164
  PopoverContent: () => PopoverContent,
@@ -952,6 +954,8 @@ Button.displayName = "Button";
952
954
  // src/motion.ts
953
955
  var MOTION_OVERLAY = "matrx-motion-overlay";
954
956
  var MOTION_DIALOG = "matrx-motion-dialog";
957
+ var CENTERED_DIALOG = "matrx-dialog-centered";
958
+ var POPPER_OFFSET = "matrx-popper-offset";
955
959
  var MOTION_BOTTOM_SHEET = "matrx-motion-bottom-sheet";
956
960
  var MOTION_POPPER = "matrx-motion-popper";
957
961
  var MOTION_SHEET = {
@@ -1056,7 +1060,7 @@ var AlertDialogContent = React7.forwardRef(({ className, children, container, an
1056
1060
  ref,
1057
1061
  "data-slot": "alert-dialog-content",
1058
1062
  className: cn(
1059
- "fixed left-[50%] top-[50%] z-[10000] grid min-w-0 w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg",
1063
+ `fixed left-[50%] top-[50%] z-[10000] grid min-w-0 w-full max-w-lg ${CENTERED_DIALOG} gap-4 border bg-background p-6 shadow-lg`,
1060
1064
  // Ruling 3 — never taller than the viewport, always scrollable, and
1061
1065
  // the footer stays reachable via --dialog-pad like Dialog's.
1062
1066
  "max-h-[85dvh] overflow-y-auto overscroll-contain [--dialog-pad:1.5rem] overflow-x-clip [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full",
@@ -1397,7 +1401,7 @@ var Command = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__
1397
1401
  }
1398
1402
  ));
1399
1403
  Command.displayName = import_cmdk.Command.displayName;
1400
- var DIALOG_DESKTOP_CLASSES = "fixed left-[50%] top-[50%] z-[10000] grid min-w-0 w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 overflow-x-clip border bg-background p-6 shadow-lg [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full sm:rounded-lg";
1404
+ var DIALOG_DESKTOP_CLASSES = `fixed left-[50%] top-[50%] z-[10000] grid min-w-0 w-full max-w-lg ${CENTERED_DIALOG} gap-4 overflow-x-clip border bg-background p-6 shadow-lg [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full sm:rounded-lg`;
1401
1405
  var DIALOG_MOBILE_SHEET_CLASSES = "fixed inset-x-0 bottom-0 left-0 right-0 top-auto z-[10000] flex min-w-0 flex-col w-full max-w-full max-h-[90dvh] translate-x-0 translate-y-0 gap-4 overflow-x-clip border-t bg-background p-4 pb-safe shadow-lg [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full rounded-t-2xl rounded-b-none overflow-y-auto overscroll-contain";
1402
1406
  var DIALOG_MOBILE_SHEET_OVERRIDE = "inset-x-0 bottom-0 left-0 right-0 top-auto translate-x-0 translate-y-0 w-full max-w-full max-h-[90dvh] rounded-b-none rounded-t-2xl overflow-y-auto";
1403
1407
  var CommandDialogContent = React13.forwardRef(({ className, children, container, ...props }, ref) => {
@@ -2119,7 +2123,7 @@ var DialogContentPrimitive = React17.forwardRef((props, ref) => {
2119
2123
  );
2120
2124
  });
2121
2125
  DialogContentPrimitive.displayName = "DialogContentPrimitive";
2122
- var DIALOG_DESKTOP_CLASSES2 = "fixed left-[50%] top-[50%] z-[10000] grid min-w-0 w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 max-h-[85dvh] overflow-y-auto overscroll-contain [--dialog-pad:1.5rem] overflow-x-clip border bg-background p-6 shadow-lg [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full sm:rounded-lg";
2126
+ var DIALOG_DESKTOP_CLASSES2 = `fixed left-[50%] top-[50%] z-[10000] grid min-w-0 w-full max-w-lg ${CENTERED_DIALOG} gap-4 max-h-[85dvh] overflow-y-auto overscroll-contain [--dialog-pad:1.5rem] overflow-x-clip border bg-background p-6 shadow-lg [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full sm:rounded-lg`;
2123
2127
  var DIALOG_MOBILE_SHEET_CLASSES2 = "matrx-mobile-sheet fixed inset-x-0 bottom-0 left-0 right-0 top-auto z-[10000] flex min-w-0 flex-col w-full max-w-full max-h-[90dvh] translate-x-0 translate-y-0 gap-4 [--dialog-pad:1rem] overflow-x-clip border-t bg-background p-4 pb-safe shadow-lg [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full rounded-t-2xl rounded-b-none overflow-y-auto overscroll-contain";
2124
2128
  var DIALOG_MOBILE_SHEET_OVERRIDE2 = "inset-x-0 bottom-0 left-0 right-0 top-auto translate-x-0 translate-y-0 w-full max-w-full max-h-[90dvh] rounded-b-none rounded-t-2xl overflow-y-auto";
2125
2129
  var DialogContent = React17.forwardRef(
@@ -3180,7 +3184,12 @@ var SelectContent = React24.forwardRef(
3180
3184
  className: cn(
3181
3185
  "relative z-[10001] max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md",
3182
3186
  animated && MOTION_POPPER,
3183
- position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
3187
+ // The resting gap from the trigger. It is the `translate` property
3188
+ // (POPPER_OFFSET), never Tailwind translate utilities: those compose
3189
+ // with `transform` on a v4 host and are REPLACED by it on a v3 one,
3190
+ // so on v3 the animation ate the gap and the surface snapped 4px at
3191
+ // the end. Same law as the centred dialog card — see motion.ts.
3192
+ position === "popper" && POPPER_OFFSET,
3184
3193
  className
3185
3194
  ),
3186
3195
  position,