@dev-dga/react 0.3.0 → 0.5.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,79 @@
1
1
  # @dev-dga/react
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ #### Navigation batch (5 components)
8
+
9
+ - **`Tabs`** — Radix Tabs compound (`Tabs` + `TabsList` + `TabsTrigger` + `TabsContent`). Two variants — `line` (underline indicator) and `pill` (filled pill on muted bg) — cascade from the root via CSS so a single source-of-truth on the root drives the look. Sizes `sm`/`md`, `fullWidth` on `TabsList`, `orientation` horizontal/vertical, `activationMode` automatic/manual pass through to Radix. Indicator uses logical properties so RTL flip is free (Radix wires `dir` from `DgaProvider`). `asChild` on `Trigger`/`Content` via Radix native. Disabled state matches `[data-disabled]` and `[aria-disabled='true']` for asChild parity. 21 unit tests + 7 Playwright tests covering the JSDOM-impossible flows (Arrow LTR/RTL, Home/End, manual activation, disabled-skip, vertical).
10
+
11
+ - **`Breadcrumb`** — shadcn-style compound (`Breadcrumb` + `BreadcrumbList` + `BreadcrumbItem` + `BreadcrumbLink` + `BreadcrumbPage` + `BreadcrumbSeparator` + `BreadcrumbEllipsis`). `<nav aria-label="Breadcrumb">` default with `<ol>` semantic list. Current page uses `aria-current="page"` (not a link); separators are `role="presentation" aria-hidden` and the default `ChevronRight` flips via `[dir='rtl'] transform: scaleX(-1)`. `asChild` on `Link` + `Page` for router/heading composition.
12
+
13
+ - **`Pagination`** — shadcn-style compound (`Pagination` + `PaginationContent` + `PaginationItem` + `PaginationLink` + `PaginationPrevious` + `PaginationNext` + `PaginationEllipsis`). `PaginationLink` has `isActive` as the single source of truth for both visual state and `aria-current='page'` (can't drift). Previous/Next chevrons flip via CSS so "back" and "forward" are always direction-correct.
14
+
15
+ - **`Accordion`** — Radix Accordion compound (`Accordion` + `AccordionItem` + `AccordionTrigger` + `AccordionContent`). Discriminated union on `type`: `'single'` (with optional `collapsible`) vs `'multiple'`. `ChevronDown` rotates 180° via `data-state='open'`. Content height animated using Radix's `--radix-accordion-content-height` CSS var (inner div carries padding so the clipped wrapper doesn't pop).
16
+
17
+ - **`Steps`** — visual-only stepper. `<ol>` semantic list; each `Step` has `state: 'completed' | 'current' | 'upcoming'` as the single source of truth for both `aria-current='step'` and visual classes. Indicator is a numbered circle for current/upcoming and a primary-filled check for completed. Separator lines drawn as `::before` pseudo-elements between siblings (primary when both adjacent steps are completed, neutral otherwise). Horizontal + vertical orientations.
18
+
19
+ #### Next-wave batch (6 components)
20
+
21
+ - **`Spinner`** — promoted from internal to public. Animated SVG loading indicator with cva `size` variants (sm/md/lg), `role='status'` + default `aria-label='Loading'`. Passing `aria-hidden='true'` (e.g. from a Button label) drops both so it stays invisible to AT inside an already-labeled parent. Sized via inherited `font-size` (1em) unless an explicit `size` is passed.
22
+
23
+ - **`Skeleton`** — pure-CSS placeholder. `shape: text | circle | rectangle`, `animation: pulse | wave | none`, plus numeric or string `width`/`height` props. Decorative — `aria-hidden` by default; parent surface should carry `aria-busy`. RTL shimmer reverses direction; `prefers-reduced-motion` suppresses both animations.
24
+
25
+ - **`Progress` + `CircularProgress`** — linear bar (Radix Progress) plus a custom-SVG circular ring. Both share `value`/`max`/`size` (sm/md/lg)/`color` (primary/success/warning/destructive). `value=null` (or omitted) renders the indeterminate animation. `data-state` mirrors Radix vocabulary (`loading` / `complete` / `indeterminate`) across both so consumers can target one selector. `CircularProgress` supports an optional inline `showLabel` and a `thickness` override; SVG dasharray math handles the determinate offset. RTL indeterminate slide reverses on the linear bar; `prefers-reduced-motion` drops both animations.
26
+
27
+ - **`DropdownMenu`** — Radix DropdownMenu compound (`Root` + `Trigger` + `Content` + `Item` + `CheckboxItem` + `RadioGroup`/`RadioItem` + `Label` + `Separator` + `Group` + `Sub`/`SubTrigger`/`SubContent`). Portal anchored to `DgaContext.rootEl` so theming + dark mode inherit (regression test mirrors Select). Items support `startIcon` + `shortcut` hint + `destructive`. **`CheckboxItem` and `RadioItem` default `onSelect` to `preventDefault`** so the menu stays open across toggles — multi-select + radio confirmation feel right; consumers override by passing their own `onSelect`. Sub chevron flips in RTL. 15 unit tests + 9 Playwright tests covering click/Space open, Arrow + Home/End, ESC close + focus return, type-ahead, ArrowRight/Left submenu (incl. RTL), disabled-skip.
28
+
29
+ - **`Drawer`** — off-canvas panel on Radix Dialog. Same focus-trap + scroll-lock + ESC + overlay-click contract as `Modal`, but slides in from an edge. `side: 'start' | 'end' | 'top' | 'bottom'` is logical (`start`/`end` flip in RTL); slide animations branch on `[dir]` so the panel always emerges from the correct edge. `size` (sm/md/lg/full) controls inline-size for start/end and block-size for top/bottom, capped at viewport. Compound: `Trigger` + `Content` + `Header` + `Title` + `Description` + `Body` (scrollable) + `Footer` + `Close`. Portal anchored to `DgaContext.rootEl`. 7 Playwright tests for focus trap (12-cycle Tab + Shift+Tab), ESC + focus return, overlay/X close, and scroll lock — also retroactively cover `Modal` (same Radix Dialog underneath).
30
+
31
+ - **`Combobox` + `ComboboxItem` + `ComboboxGroup` + `ComboboxSeparator`** — searchable Select built on Radix Popover + `cmdk` (new dep, see below). Closed compound: pass `ComboboxItem` children (+ optional `ComboboxGroup`/`ComboboxSeparator`). Field a11y wires the same way as Select (`label`/`helperText`/`error`/`errorMessage`/`required`). Synchronous `React.Children` traversal builds the value → label map so the trigger renders the right label on first paint without waiting for the popover to open. `getLabel` prop overrides the lookup for async-loaded options. `keywords` on `ComboboxItem` are extra search terms cmdk matches (synonyms / aliases). 23 unit tests + 8 Playwright tests.
32
+
33
+ #### Button extensions
34
+
35
+ - **3 destructive sub-variants** — `destructive-outline`, `destructive-subtle`, `destructive-ghost` — paralleling the existing non-destructive family.
36
+ - **`inverted` prop** for non-filled variants (outline/ghost/subtle) when rendered on colored or dark surfaces (filled variants ignore it).
37
+
38
+ #### Badge `dismissible`
39
+
40
+ - New `dismissible` + `open` (controlled) + `onDismiss` + `closeLabel` (i18n) props turn `Badge` into the DGA Tag/Chip pattern without a new component. Uncontrolled: clicking the close button hides the badge. Controlled: `open` owns visibility; `onDismiss` is the only signal. Reuses the internal `Close` icon. Dev-warns when combined with `asChild` (would nest an interactive button inside the consumer's `<a>` — invalid HTML); close button is suppressed in that combo.
41
+
42
+ ### Patch Changes
43
+
44
+ - **Vitest 2.x matcher augmentation fix.** `jest-dom` and `vitest-axe` both ship augmentations targeting `vitest`'s `Assertion<T>` (or the legacy `Vi.Assertion`), but Vitest 2.x declares the interface inside `@vitest/expect` and only re-exports it from `vitest` — so neither upstream augmentation actually applied. `src/test/matchers.d.ts` consolidates the augmentation against `@vitest/expect` + the global `jest.Matchers` namespace; the prior `vitest-axe.d.ts` shim is folded in and deleted. Runtime was unaffected (the setup file's `expect.extend(matchers)` works regardless); the symptom was `pnpm typecheck` silently failing for every `toBeInTheDocument` / `toHaveNoViolations` assertion.
45
+ - **`Radio` Storybook documentation.** Added `tags: ['autodocs']` and a component-level description covering the compound-API contract, `useFieldA11y` wiring, and controlled/uncontrolled modes. (No code change.)
46
+ - **Spinner CSS moved out of `button.css`.** `.ddga-spinner` + `@keyframes ddga-spin` + the spinner clause of `prefers-reduced-motion` now live in `spinner.css`. The `.ddga-spinner` class name is preserved so existing Button spinner-class assertions still hit. `button.css` keeps the Button-specific `transition: none` in the reduced-motion media query.
47
+ - **Playwright e2e harness.** Standalone Playwright in `apps/docs/e2e/`, Chromium-only, drives the Storybook dev server via `playwright.config.ts`'s `webServer` block. New scripts: `pnpm --filter docs test:e2e[:install]`. CI step appended to the existing `verify` job with browser cache keyed on `pnpm-lock.yaml` hash. Specs in this release: `tabs.spec.ts` (7 tests), `dropdown-menu.spec.ts` (9), `drawer.spec.ts` (7), `combobox.spec.ts` (8).
48
+
49
+ ### New Dependencies
50
+
51
+ - **`cmdk@^1.1.1`** — for `Combobox`. Direct dep + `tsup` external so consumers transitively install it. ~3KB additional install footprint.
52
+
53
+ ## 0.4.0
54
+
55
+ ### Minor Changes
56
+
57
+ #### Display batch (4 components)
58
+
59
+ - **`Card`** — compound (`Card` + `CardImage` + `CardHeader` + `CardTitle` + `CardDescription` + `CardContent` + `CardFooter`). 6 variants: `default`, `outline`, `elevated`, `filled`, `gradient` (SA-Green hero), `ghost` (bare). `padding` scale (`sm`/`md`/`lg`), `interactive` (hover + focus ring), `orientation` (`vertical`/`horizontal` for side-by-side media + content). `CardImage` with `aspectRatio`. `asChild` on the root + every subcomponent.
60
+
61
+ - **`Badge`** — 14 variants total: 8 solid (`default`, `primary`, `secondary`, `outline`, `destructive`, `success`, `warning`, `info`) + 6 subtle/tonal counterparts (`primary-subtle`, `secondary-subtle`, `destructive-subtle`, `success-subtle`, `warning-subtle`, `info-subtle`). Sizes `sm`/`md`. `dot` prop (status pill), `startIcon`/`endIcon` props (parallel to Button). `asChild`.
62
+
63
+ - **`Divider`** — `orientation` horizontal/vertical, `variant` solid/dashed, optional label `children` with `labelPosition` start/center/end (logical, RTL-aware). `decorative` prop strips the role from the a11y tree.
64
+
65
+ - **`Avatar`** — built on Radix Avatar primitive. Compound (`Avatar` + `AvatarImage` + `AvatarFallback` + `AvatarGroup`). Sizes `xs`/`sm`/`md`/`lg`/`xl`, shapes `circle`/`square`, `status` corner indicator (`online`/`busy`/`away`/`offline`, RTL-aware). `AvatarFallback` ships `colorScheme` with 7 tonal `-100`/`-700` pairs. `AvatarGroup` cascades size/shape to children and collapses overflow into a `+N` chip.
66
+
67
+ #### Feedback / overlay batch (4 components)
68
+
69
+ - **`Tooltip`** — Radix Tooltip. Compound (`Tooltip` + `TooltipTrigger` + `TooltipContent`). Sizes `sm`/`md`. `arrow` (default true) + `sideOffset` (default 6). Portal anchored to `DgaContext.rootEl` for theme inheritance. `TooltipProvider` already nested in `DgaProvider` — no extra setup needed. `asChild` on `Trigger` via Radix native.
70
+
71
+ - **`Alert`** — compound (`Alert` + `AlertTitle` + `AlertDescription`). 4 variants (`info`/`success`/`warning`/`destructive`) using a subtle tonal palette plus an accent edge. Default per-variant icon from internal icons (Info / Check / AlertTriangle / AlertCircle); override via `icon` prop or hide with `icon={false}`. `dismissible` (uncontrolled or `open`-controlled). `live: 'polite' | 'assertive'` toggles role + aria-live. `asChild` on root.
72
+
73
+ - **`Modal`** — Radix Dialog. Compound (`Modal` + `ModalTrigger` + `ModalContent` + `ModalHeader` + `ModalTitle` + `ModalDescription` + `ModalFooter` + `ModalClose`). Sizes `sm`/`md`/`lg`/`xl`/`full`. `showCloseButton` (corner X, default true) + `closeLabel` for i18n. Portal anchored to `DgaContext.rootEl`. `aria-labelledby`/`aria-describedby` auto-wired by Radix `Title`/`Description`. Focus trap + scroll lock + ESC/overlay close handled by Radix.
74
+
75
+ - **`Toast`** — Radix Toast + module-level singleton store (Sonner pattern). Imperative API: `toast()`, `toast.success/info/warning/error/destructive/dismiss`. `<Toaster />` mounted once inside `DgaProvider`. 5 variants with per-variant icons + accent edge. 6 logical positions (`top`/`bottom` × `start`/`center`/`end`; `start`/`end` flip in RTL). `duration` per-toast or via Toaster default. `action: { label, onClick }`, `closeButton`, `closeLabel`. Reusing the same `id` updates in place (loading → success pattern). z-index 70 (above Modal).
76
+
3
77
  ## 0.3.0
4
78
 
5
79
  ### Breaking Changes
package/README.md CHANGED
@@ -82,7 +82,15 @@ function MyField({ label, helperText, error, errorMessage, ...rest }) {
82
82
 
83
83
  ## Components
84
84
 
85
- **Form:** `Button` · `Input` · `Textarea` · `Checkbox` · `RadioGroup` + `Radio` · `Switch` · `Select` + `SelectItem`
85
+ **Form:** `Button` · `Input` · `Textarea` · `Checkbox` · `RadioGroup` + `Radio` · `Switch` · `Select` + `SelectItem` · `Combobox` + `ComboboxItem` (+ `ComboboxGroup` · `ComboboxSeparator`)
86
+
87
+ **Display:** `Card` (+ `CardImage`/`CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`) · `Badge` · `Divider` · `Avatar` (+ `AvatarImage`/`AvatarFallback`/`AvatarGroup`)
88
+
89
+ **Feedback / overlay:** `Tooltip` · `Alert` · `Modal` · `Toast` (imperative API) · `Drawer` (off-canvas, 4 sides) · `DropdownMenu` (compound w/ CheckboxItem, RadioGroup, Sub)
90
+
91
+ **Navigation:** `Tabs` · `Breadcrumb` · `Pagination` · `Accordion` · `Steps`
92
+
93
+ **Status:** `Spinner` · `Skeleton` · `Progress` + `CircularProgress`
86
94
 
87
95
  **Primitives:** `DgaProvider` · `useDga` · `useDir` · `useFieldA11y` · `FieldMessage` · `cn`
88
96