@ai-matrx/design-system 0.4.2 → 0.5.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,131 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.1
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/design-system/v0.5.0..npm/design-system/v0.5.1 -- apps/shared/design-system`).
7
+ No source changes intended and no consumer action required.
8
+
9
+ ## 0.5.0 — 2026-09-07
10
+
11
+ **THE GROWTH WAVE (C18).** The 2026-09-07 adoption lane deleted 34 forked
12
+ primitives across four repos but had to KEEP every primitive this package did
13
+ not ship. This release ships them, so those forks can die too.
14
+
15
+ Thirteen new primitives, each built from EVERY host variant rather than from
16
+ one repo's copy: `Avatar`, `Card`, `Checkbox`, `Collapsible`, `ContextMenu`,
17
+ `Dialog`, `DropdownMenu`, `Progress`, `ScrollArea`, `Switch`, `Table`, `Tabs`,
18
+ `Textarea`. Plus `useIsMobile` / `MOBILE_BREAKPOINT`, lifted out of
19
+ `command.tsx` (where it was private) because Dialog needed the same answer and
20
+ two breakpoint hooks in one package is the duplication this package exists to
21
+ end.
22
+
23
+ **Density is a prop, never a fork.** The single biggest reason four hosts kept
24
+ four cards and four tables was padding. `Card` (`size` sm/md/lg → p-2/p-4/p-6)
25
+ and `Table` (`size` sm/md → p-2/p-3) declare density ONCE on the root; every
26
+ section reads it from context, so a card cannot end up with a `p-6` header
27
+ above a `p-2` body. `Switch`, `Avatar` and `Checkbox` carry the same treatment
28
+ for the box sizes their forks disagreed on.
29
+
30
+ **Rulings the forks had already paid for, now carried once:**
31
+
32
+ - **No hydration mount gates.** Dialog, DropdownMenu, ContextMenu, Tabs and
33
+ Collapsible all render their roots unconditionally. The gate they inherited
34
+ rested on a false premise (Radix ids come from React's SSR-stable `useId`)
35
+ and deleted always-visible triggers from SSR and the first client paint —
36
+ around a list row, the list painted EMPTY and filled in after hydration.
37
+ - **The dialog is clamped and scrolls inside itself; its footer is sticky.**
38
+ From the live incident where an 851px dialog in a 657px viewport put its
39
+ Create button below the fold, leaving only a backdrop click that dismisses
40
+ WITHOUT writing.
41
+ - **Inactive tab panels UNMOUNT.** `forceMount` is opt-in. Force-mounting every
42
+ panel once let a HIDDEN tab win a provider tie-break and serve the VISIBLE
43
+ tab another tab's rows.
44
+ - **A menu longer than the viewport scrolls instead of growing off-screen** —
45
+ both menus cap at the height Radix measured.
46
+ - **An indeterminate `Progress` no longer renders as a confident 0%.** The
47
+ shadcn body every host copied computed `translateX(-${100 - (value || 0)}%)`,
48
+ turning "nobody knows" into "not started". Indeterminate now sweeps and
49
+ carries `data-state="indeterminate"`.
50
+ - **An indeterminate `Checkbox` shows a different glyph than a checked one** —
51
+ a half-selected "select all" wearing a full check states something false.
52
+
53
+ **Seams.** Dialog, DropdownMenu and ContextMenu portal through
54
+ `usePortalContainer`; `DialogContent` PROVIDES that container to its own
55
+ children, so a popover or menu opened inside a dialog mounts inside it (staying
56
+ in the scroll shard where its wheel events work). `useDialogContainer` exposes
57
+ the same element. An explicit `container` prop always wins.
58
+ `ScrollArea` exposes `viewportClassName` / `viewportRef` / `scrollBarClassName`
59
+ — the viewport being unreachable is precisely why workflow-studio forked it,
60
+ and `viewportRef` is the scrolling element programmatic scroll-to-bottom needs.
61
+
62
+ **CSS (C26):**
63
+
64
+ - `styles.css` gains `.shadow-textarea` and `.matrx-progress-indeterminate`
65
+ (plus its keyframes, declared unlayered because keyframes cannot live inside
66
+ a layer's rule set portably). Still zero hardcoded colour.
67
+ - `tokens.css` gains `--shadow-textarea`, defaulting to `--shadow-input`.
68
+
69
+ **Corrections shipped with the ports (visual, deliberate, listed so nobody
70
+ reports them as regressions):**
71
+
72
+ - `shadow-textarea` NOW EXISTS. The ported Textarea asked for it at every call
73
+ site and NO host defined the token or generated the utility, so ~125 fields
74
+ rendered flat while their code said otherwise. Set `--shadow-textarea: none`
75
+ for the old flat look.
76
+ - Textarea colour moves onto tokens (literal black/white body text, raw
77
+ palette placeholder and focus ring, and a dark elevation referencing a
78
+ property no host defined — which computed to no shadow at all).
79
+ - `Input` / `BasicInput` gain `file:text-foreground`, so a file input's button
80
+ label follows the theme instead of the UA default.
81
+ - Switch's OFF track reads `bg-input` everywhere (workflow-studio's fork used
82
+ `bg-muted`, which makes an off switch vanish into a muted panel).
83
+ - `CardHeader` / `CardFooter` corner rounding is `rounded-t/b-[inherit]`, so it
84
+ matches whatever radius the card actually has (matrx-frontend's fork rounded
85
+ sections to `lg` inside an `xl` card).
86
+ - `AvatarFallback` carries defined type (`text-muted-foreground`, sized by the
87
+ avatar's `size`) instead of inheriting whatever the surrounding row used.
88
+ - `Table` keeps matrx-frontend's horizontal-scroll wrapper as the default
89
+ (`wrap={false}` to opt out) and offers dashboard's sticky header as
90
+ `<TableHeader sticky>`.
91
+
92
+ **Radix packages are ordinary dependencies of this package, not peers** (only
93
+ `react`/`react-dom` are peers), and all of them moved to current latest.
94
+
95
+ ### Consumer action (C28)
96
+
97
+ Install `@ai-matrx/design-system@0.5.0` and DELETE these forks. Every one is a
98
+ copy of something this version now ships:
99
+
100
+ - **matrx-frontend** — `components/ui/{avatar,card,checkbox,collapsible,dialog,dropdown-menu,progress,scroll-area,switch,table,tabs,textarea}.tsx`
101
+ and `components/ui/context-menu/context-menu.tsx`. High-fanout files become
102
+ re-export shims that bind this repo's historical variant (`Card size="sm"`,
103
+ `Switch size="sm"`, `Table size="sm"`), matching what the 08-30 swap
104
+ established for `button` / `badge` / `label` / `separator`. The
105
+ clipboard/motion variants (`CopyInput`, `FancyInput`, `DeleteInput`,
106
+ `CopyTextarea`, `FancyTextarea`) stay host-owned under the C8 split-out law.
107
+ - **matrx-extend** — `src/components/ui/{card,scroll-area,switch,tabs,textarea}.tsx`.
108
+ `src/components/ui/collapsible.tsx` is NOT a fork of this package's
109
+ `Collapsible` — it is a bespoke labelled-section control with its own API —
110
+ and stays.
111
+ - **matrx-games** — `components/ui/{avatar,dropdown-menu,progress,tabs}.tsx`
112
+ (dead code: zero import sites) and `components/ui/scroll-area.tsx`.
113
+ `card.tsx` and `dialog.tsx` are a different generation (Base UI, not Radix)
114
+ carrying that app's own visual language; they are DEFERRED, not forgotten —
115
+ see FEATURE.md § Deferred.
116
+ - **aidream/apps/dashboard** — `src/components/ui/{avatar,card,checkbox,context-menu,dialog,dropdown-menu,scroll-area,switch,table,tabs,textarea}.tsx`.
117
+ Pass `Card size="lg"` and `Table size="md"` to keep this app's density.
118
+ - **aidream/apps/workflow-studio** — `src/components/ui/{dialog,dropdown-menu,scroll-area,switch,tabs,textarea}.tsx`.
119
+ Its ScrollArea viewport hack becomes `viewportClassName="[&>div]:!block [&>div]:min-w-0"`.
120
+
121
+ Hosts that do not already import the stylesheets must, or the new structural
122
+ rules do nothing:
123
+
124
+ ```ts
125
+ import "@ai-matrx/design-system/tokens.css";
126
+ import "@ai-matrx/design-system/styles.css";
127
+ ```
128
+
3
129
  ## 0.4.2
4
130
 
5
131
  Automatic changed-only republish (docs/metadata drift since the last tag — see
@@ -81,12 +207,28 @@ palette colour.
81
207
  ```
82
208
 
83
209
  2. **Declare the layer order once**, as the first line of your Tailwind/CSS
84
- entry, so the package's default token values stay below your own:
210
+ entry:
85
211
 
86
212
  ```css
87
213
  @layer matrx-design-system-tokens, matrx-design-system;
88
214
  ```
89
215
 
216
+ **What actually protects your brand (corrected 2026-09-07, learned adopting four
217
+ more apps):** Tailwind v4 does NOT emit this statement into the built sheet — it
218
+ survives only as the relative order of the two package layers. Your tokens win
219
+ because host `:root` declarations are UNLAYERED and unlayered beats every layer.
220
+ So: keep your `:root { --primary: … }` declarations unlayered (never wrap them in
221
+ `@layer`), or the package defaults will override them. Verify on the BUILT css:
222
+ the package `--success` should appear inside `@layer matrx-design-system-tokens`
223
+ and your own `--success` later, unlayered.
224
+
225
+ 2b. **Map the status colours or Badge/ScoreRing render NO css.** The package's
226
+ `Badge` `success`/`warning`/`info` variants and the ScoreRing helpers resolve
227
+ `--color-success` / `--color-warning` / `--color-info`. A host whose `@theme`
228
+ does not define those three gets empty utilities — silently. Four consumer apps
229
+ shipped that way for a week (found 2026-09-07). Define them in your `@theme`
230
+ (or import `theme.css` if you have no theme of your own).
231
+
90
232
  3. **Delete your host copies of the moved rules** — `.matrx-scroll-fade[…]`,
91
233
  the `.matrx-mobile-sheet` block, `.matrx-glass-thin-border` (+ its
92
234
  `:hover` / `:active` / `:has(> a:…)` states). They now ship in the package;
package/README.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # @ai-matrx/design-system
2
2
 
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. Version 0.2 ships Button, Badge, Label, Separator, the Input family, Popover, Sheet, Skeleton, EditableLabel, SegmentedControl, ScoreRing, BottomSheet + TabbedBottomSheet, OverflowToolbar, the `useScrollFade` hook, and the `cn` utility.
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
+
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.
7
+ **Menus:** DropdownMenu, ContextMenu, Command / CommandDialog, Select, CreatablePicker.
8
+ **Composed:** EditableLabel, SegmentedControl, ScoreRing, OverflowToolbar.
9
+ **Hooks + utilities:** `useScrollFade`, `useIsMobile`, `usePortalContainer`, `useDialogContainer`, `cn`.
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.
4
12
 
5
13
  ```bash
6
14
  pnpm add @ai-matrx/design-system