@ai-matrx/design-system 0.6.0 → 0.7.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 CHANGED
@@ -1,5 +1,114 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.0 — 2026-09-07
4
+
5
+ **GROWTH WAVE 2 (C18).** Wave 1 (0.5.0) deleted 34 forked primitives but had
6
+ to KEEP every primitive this package did not ship. A fresh import-site census
7
+ of matrx-frontend `components/ui/` ranked what was left; this release ships all
8
+ of it, so those forks die too.
9
+
10
+ Ten new primitive families, ordered by the host fan-out they close:
11
+ `Tooltip` (182 sites), `Drawer` (121), `AlertDialog` (78), `Alert` (76),
12
+ `Slider` (46), `Resizable` (38), `RadioGroup` (30), `HoverCard` (16),
13
+ `ToggleGroup` + `Toggle` (10). Each was built from EVERY host variant, not from
14
+ one repo's copy.
15
+
16
+ ### The tooltip collapse
17
+
18
+ `@ai-matrx/tap-target` shipped a Tooltip family that four repos adopted — and
19
+ its own file header said what it was: an inlined PORT of matrx-frontend's
20
+ `components/ui/tooltip.tsx`. So the fleet ran TWO copies, and a
21
+ button-geometry package was the accidental owner of a design-system surface.
22
+ A tooltip is a design-system surface: it lives here now. `tap-target@0.2.0`
23
+ takes this package as an ordinary sibling dependency, imports the Tooltip from
24
+ it, deletes its own copy, and **re-exports nothing** — one implementation, one
25
+ import path. The sibling DAG already ordered design-system before tap-target,
26
+ so no cycle is introduced.
27
+
28
+ The port also restores the seam tap-target's copy had dropped: tooltips resolve
29
+ their portal target through `PortalContainerProvider`, so a tooltip inside a
30
+ popped-out panel lands in the right document instead of always `document.body`.
31
+
32
+ ### Real defects fixed in the port (never "preserved")
33
+
34
+ - **`AlertDialogContent` was not clamped to the viewport.** A confirm dialog
35
+ listing what is about to be deleted pushed Cancel/Continue below the fold on
36
+ a short viewport — and Radix does NOT dismiss an ALERT dialog on backdrop
37
+ click, so the surface was a genuine dead end. It is now
38
+ `max-h-[85dvh] overflow-y-auto` with a sticky, edge-bleeding footer, matching
39
+ `Dialog`.
40
+ - **`Slider` rendered exactly one thumb.** The host copy hardcoded a single
41
+ `Thumb`, so any two-value range silently lost its upper handle. One thumb is
42
+ now rendered per value.
43
+ - **`HoverCard` rendered inline instead of portalling**, so a card inside an
44
+ `overflow-hidden` ancestor was clipped and one inside a popped-out panel could
45
+ not exist. It now portals through the same seam — which is why its layer moved
46
+ from `z-50` to `z-[10001]`: at the body it would otherwise sit UNDER a modal.
47
+ - **`ResizableHandle` always said `cursor: col-resize`**, inline, including on
48
+ the horizontal separator of a vertical group, which wants `row-resize`. The
49
+ cursor is now orientation-aware.
50
+ - **Every touch target under 44px** on `Slider`, `RadioGroup`, `ResizableHandle`
51
+ and the `Drawer` grab handle. The visible control keeps its size; an invisible
52
+ pseudo-target expands the hit area on coarse pointers only, so desktop density
53
+ is untouched.
54
+
55
+ ### Density is a prop, not a fork (C18), on four more primitives
56
+
57
+ `Slider size`, `RadioGroup size` (declared on the root, inherited by items),
58
+ `Toggle`/`ToggleGroup size`, `ResizableHandle size`. That last one collapses
59
+ TWO host files: matrx-frontend shipped `components/ui/resizable.tsx` AND
60
+ `components/ui/matrx/resizable.tsx`, whose only difference was an eight-step
61
+ handle-thickness scale.
62
+
63
+ ### The Drawer owns the mobile-first rules
64
+
65
+ matrx-frontend's doctrine is "Drawer, not Dialog, on mobile", so the Drawer is
66
+ where most of the platform's mobile UX lands. It now owns those rules so no
67
+ host re-derives them: `dvh` never `vh`; `pb-safe` / `pt-safe` safe-area padding
68
+ (`pt-safe` is new in `styles.css`); a 44px grab-handle target around the 4px
69
+ pill; `DrawerBody` as the `flex-1 min-h-0` scroll shard with a `mt-auto` footer;
70
+ and `direction` as a prop, so a side or top drawer is not a fork.
71
+
72
+ It also closes the last CONTEXT twin: `RadixDialogModalProvider` still had a
73
+ host copy at `components/ui/radix-dialog-modal-context.tsx`, and a host copy of
74
+ a React context is the quiet twin — `useContext` matches by object identity, so
75
+ the host Drawer's provider and this package's Sheet consumer were two different
76
+ contexts that merely looked alike. `BottomSheet` now composes `Drawer` too, so
77
+ there is ONE vaul wrapper in the package instead of two.
78
+
79
+ ### Alert ships the whole status vocabulary
80
+
81
+ `default | destructive | warning | success | info`, all token-driven. The host
82
+ copy had only two variants, which is why the census found dozens of hand-rolled
83
+ amber/emerald banners with literal palette classes across four repos.
84
+
85
+ ### Consumer action (C28)
86
+
87
+ Install `@ai-matrx/design-system@0.7.0` (and `@ai-matrx/tap-target@0.2.0`), then:
88
+
89
+ 1. **Tooltip imports move.** Anything importing `Tooltip`, `TooltipTrigger`,
90
+ `TooltipContent` or `TooltipProvider` from `@ai-matrx/tap-target` must import
91
+ them from `@ai-matrx/design-system` instead — tap-target no longer exports
92
+ them. Affected today: aidream `apps/dashboard` (10 files), aidream
93
+ `apps/workflow-studio` (18 files), matrx-extend (1), matrx-frontend (1).
94
+ 2. **Delete these host forks** and re-point or shim their imports:
95
+ - matrx-frontend `components/ui/tooltip.tsx`, `drawer.tsx`,
96
+ `alert-dialog.tsx`, `alert.tsx`, `slider.tsx`, `resizable.tsx`,
97
+ `matrx/resizable.tsx`, `radio-group.tsx`, `hover-card.tsx`,
98
+ `toggle-group.tsx`, `toggle.tsx`, `radix-dialog-modal-context.tsx`.
99
+ - No other consumer repo carries a fork of these — verified by census on
100
+ 2026-09-07 across matrx-extend, matrx-games, aidream `apps/dashboard` and
101
+ `apps/workflow-studio`.
102
+ 3. **`matrx/resizable.tsx` callers keep their `size` prop** — it is the same
103
+ eight-step scale, now on the one component. Callers of the plain
104
+ `resizable.tsx` get the identical 2px default (`size="sm"`).
105
+ 4. **Check any `z-50` assumption around HoverCard**; it now portals to the body
106
+ at `z-[10001]`.
107
+ 5. **`react-resizable-panels` v4 overwrites `data-testid`** with its own
108
+ generated id. Tests that query a handle by test id must query
109
+ `role="separator"` instead.
110
+ 6. Register the new names in each repo's `package-twins.json`.
111
+
3
112
  ## 0.6.0 — 2026-09-07
4
113
 
5
114
  **THE BUTTON SCALE.** matrx-frontend carried a 127-line CVA button fork
package/README.md CHANGED
@@ -2,13 +2,17 @@
2
2
 
3
3
  The small, semantic UI foundation shared by AI Matrx React applications — primitives whose behavior and variants are identical across Vite and Next.js hosts.
4
4
 
5
- **Controls:** Button, Badge, Label, Separator, the Input family, the Textarea family, Checkbox, Switch, Avatar, Progress.
6
- **Surfaces:** Card, Table, Tabs, Collapsible, ScrollArea, Popover, Sheet, Dialog, BottomSheet + TabbedBottomSheet, Skeleton.
5
+ **Controls:** Button, Badge, Label, Separator, the Input family, the Textarea family, Checkbox, Switch, RadioGroup, Slider, Toggle + ToggleGroup, Avatar, Progress.
6
+ **Surfaces:** Card, Table, Tabs, Collapsible, ScrollArea, Popover, Tooltip, HoverCard, Sheet, Dialog, AlertDialog, Drawer, BottomSheet + TabbedBottomSheet, Alert, Resizable, Skeleton.
7
7
  **Menus:** DropdownMenu, ContextMenu, Command / CommandDialog, Select, CreatablePicker.
8
8
  **Composed:** EditableLabel, SegmentedControl, ScoreRing, OverflowToolbar.
9
- **Hooks + utilities:** `useScrollFade`, `useIsMobile`, `usePortalContainer`, `useDialogContainer`, `cn`.
9
+ **Hooks + utilities:** `useScrollFade`, `useIsMobile`, `usePortalContainer`, `useDialogContainer`, `useDrawerDirection`, `cn`.
10
10
 
11
- Where hosts had forked a primitive over DENSITY, density is a prop, not a fork: `Card size="sm|md|lg"`, `Table size="sm|md"`, `Switch`/`Avatar`/`Checkbox` `size`. It is declared once on the root and every section reads it from context, so a card cannot mix paddings.
11
+ **The Tooltip lives here, and only here.** `@ai-matrx/tap-target` used to ship its own copy; since design-system 0.7.0 / tap-target 0.2.0 it consumes this one and re-exports nothing.
12
+
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"`, `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
+
15
+ **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.
12
16
 
13
17
  ```bash
14
18
  pnpm add @ai-matrx/design-system