@dev-dga/react 0.6.0 → 0.8.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 +54 -0
- package/README.md +6 -4
- package/dist/index.cjs +2735 -127
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +709 -11
- package/dist/index.d.ts +709 -11
- package/dist/index.js +2632 -137
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
# @dev-dga/react
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
#### Components (9 new)
|
|
8
|
+
|
|
9
|
+
- **`Table` (+ `TableHeader` / `TableBody` / `TableFooter` / `TableRow` / `TableHead` / `TableCell` / `TableCaption`)** — the presentational data-table compound, modeled on `DescriptionList` (semantic compound, descendant-selector CSS). Root wraps `<table>` in a focusable, **named scroll region** (`role="region"` + `tabindex` when `aria-label`/`-labelledby` is given; degrades to a plain scroll container + dev-warn when unnamed). cva root variants: `size` sm/md/lg, independent `striped` / `divided` / `bordered` / `stickyHeader`, plus `maxHeight` (caps the scroll region so `stickyHeader` actually engages). `TableHead` sort affordance = `sortable` + `sortDirection` → `aria-sort` + a real `<button>` + caret icons, with a caller-localized `sortLabel` folded into the button via the new global `.ddga-sr-only` utility — **affordance + ARIA live in the primitive, the sort logic is the consumer's**. `align` start/center/end (logical); `TableRow selected` → `data-state="selected"`. No `asChild` (table elements have a fixed parent/child structure). A `DataTable` **recipe story** wires `@tanstack/react-table` (devDep only — _not_ a runtime dep) for sort/select/paginate, keeping that state in the consumer. No new runtime deps. 24 tests.
|
|
10
|
+
|
|
11
|
+
- **`Command` (+ `CommandDialog` / `CommandInput` / `CommandList` / `CommandEmpty` / `CommandGroup` / `CommandItem` / `CommandSeparator`)** — ⌘K command palette on `cmdk` (already a dep — no new deps), modeled on `Combobox` (cmdk wiring) + `Modal` (Radix Dialog overlay). Inline `Command` compound + `CommandDialog` (Portal to `ctx.portalEl`, named via a visually-hidden `DialogTitle`, built-in **⌘K / Ctrl+K** toggle, opt-out via `shortcut={false}`). Action-oriented `CommandItem` (`value` required, `startIcon` / `shortcut`, `onSelect(value)` — no selection/check). **Arabic/i18n search:** items auto-fold their string label into cmdk `keywords`, so typing the visible (Arabic) label matches even when `value` is a stable Latin slug. No `asChild` (cmdk-primitive carve-out). 21 unit tests.
|
|
12
|
+
|
|
13
|
+
- **`InputOTP`** — OTP / PIN field (Saudi SMS OTP = 6 digits). **Hand-built, no new dep** — a single real `<input>` overlays decorative slots so paste / SMS autofill (`autocomplete="one-time-code"`) / Backspace all flow through one `onChange` (the `input-otp` library was rejected: no `"sideEffects": false`, so it leaked ~3.3 KB into _every_ component's bundle). `length` (default 6) / `groupSizes` / `separator`, controlled + uncontrolled, `onComplete` (ref-guarded against IME/autofill double-fire), `pattern` (default digits-only, lenient paste strips whitespace/hyphens), `mask` (PIN dots), sizes. Field a11y via `useFieldA11y` + `FieldMessage`; slot row forced `dir="ltr"` + `aria-hidden` (the single input is the AT target). No `asChild` (form-control carve-out). 23 unit tests.
|
|
14
|
+
|
|
15
|
+
- **`Link`** — the styled `<a>` primitive (Button is for actions; `asChild` on Button styles nav _as a button_). Three visual variants on one axis — `default` (inline prose, always underlined for WCAG 1.4.1) / `subtle` (underline on hover) / `standalone` (block CTA). **`external` is an orthogonal boolean, not a 4th variant** → appends a decorative ↗ + `rel="noopener noreferrer"` (merged + de-duped with any consumer `rel`); `target` left to the consumer. No size prop (inherits font-size; icons in `em`). `startIcon` / `endIcon` (decorative); `iconFlip` via the shared `ddga-icon-flip` utility (relocated from `button.css` to `reset.css` so it's a real cross-component utility). `asChild` composes with framework routers; dev-warns on `<a>` with no `href`. New internal `ExternalLink` icon. No new deps. 19 unit tests.
|
|
16
|
+
|
|
17
|
+
- **`SearchBox`** — search-styled field composing `Input` (reuses its field a11y / label / helper / error / sizing / adornments). Earns its existence over the "no wrapper for defaults" rule with real behavior: leading magnifier, a clear (×) button shown only when non-empty (refocuses on clear), **Escape-to-clear** (stops propagation only when it actually clears, so a second Esc bubbles to a parent Modal/Popover), and **`onSearch`** fired on Enter. `type="search"` → `role="searchbox"`; native WebKit search affordances suppressed. Controlled + uncontrolled (clearing dispatches a native `input` event so `onChange` fires in both modes). No `asChild` (form control). No new deps. 14 unit tests.
|
|
18
|
+
|
|
19
|
+
- **`List` (+ `ListItem` / `ListItemIcon` / `ListItemContent` / `ListItemAction`)** — general-purpose content-list compound (sibling to `Timeline` / `DescriptionList`), closing the gap between `DescriptionList` (`<dl>` key-value) and a rich item list. Semantic `<ul>` / `<ol>` + `<li>`, cva on root. Four variants: `plain` (flex rows: icon/content/action) / `bulleted` / `numbered` / `lettered` — and the ordered ones are **direction-localized**: `numbered` → `decimal` (LTR) / `arabic-indic` ١٢٣ (RTL); `lettered` → `lower-alpha` (LTR) / `arabic-abjad` أ‑ب‑ج (RTL, via a `@counter-style` using the exact W3C symbols). `numbered` / `lettered` render `<ol>` and expose `start` / `reversed`. No `asChild` (`<ul>`/`<ol>` carve-out). No new deps. 18 unit tests.
|
|
20
|
+
|
|
21
|
+
- **`Quote` (+ `QuoteContent` / `QuoteCaption` / `QuoteAuthor` / `QuoteSource`)** — visual-only quote / pullquote / testimonial. Semantic `<blockquote>`, wrapped in `<figure>` + `<figcaption>` **only when textual attribution** (`author` / `byline` / `source`) is present (an empty `<figcaption>` is invalid). Four variants `default` (SA-Green inline-start accent) / `pullquote` / `testimonial` (card surface) / `plain`; optional `quoteMark` glyph (new internal `QuoteMark` icon, `scaleX(-1)` in RTL); `avatar` slot (dropped without textual attribution so the caption never goes empty-to-AT). Attribution: `author` · **`byline`** (job title — _named `byline`, not `role`, so the native ARIA `role` attribute stays forwardable_) · `source` → real `<cite>` · `cite` → `cite=` URL. No root `asChild` (varying figure/blockquote composite); sub-parts have it. No new deps. 26 unit tests.
|
|
22
|
+
|
|
23
|
+
- **`Collapsible` (+ `CollapsibleTrigger` / `CollapsibleContent`)** — the single-panel disclosure primitive Accordion is built on. Thin themed wrapper over Radix Collapsible; no `cva` / size / variant (the consumer owns the trigger's look, `asChild`-first → forwarded to Radix). Content height-slides via `--radix-collapsible-content-height` with a `prefers-reduced-motion` guard (mirrors Accordion). No new deps (radix-ui umbrella). 15 unit tests.
|
|
24
|
+
|
|
25
|
+
- **`TagInput`** — free-entry token / chip field (recipient fields, tag entry, filter builders). Distinct from `Combobox` (which selects from a fixed list) — TagInput **creates** arbitrary values. Inline-wrap layout (chips + input share one bordered flex-wrap box); value contract `string[]`, controlled + uncontrolled. Add via Enter or any `delimiters` char (paste splits on delimiters + newline); accept pipeline trim → `max` cap → dedup (case-insensitive by default; `caseSensitive` / `allowDuplicates` opt out) → optional `validate(tag, tags)` (reject keeps the draft). Backspace-on-empty removes last; chip × removes specific. Reuses `useFieldA11y` + `FieldMessage` + **Badge** chips; polite `aria-live` region announces add/remove. No `asChild` (form-control carve-out). No new deps. 31 unit tests.
|
|
26
|
+
|
|
27
|
+
#### Component enhancements
|
|
28
|
+
|
|
29
|
+
- **`Tabs` — icon + icon-only triggers.** `TabsTrigger` gains `startIcon` + `endIcon` (decorative, em-sized). Icon-only is **auto-detected** (icon + no text child → squared padding + an `aria-label`/`-labelledby` dev-warn, mirroring Button). `asChild` ignores the icon props + dev-warns (Slot single-child constraint). +10 unit tests.
|
|
30
|
+
|
|
31
|
+
- **`Button` — `fab` (floating action button) modifier.** Modeled as an **orthogonal boolean** (`fab` cva variant), not a color-variant value — composes with any `variant` + `size`. Round + elevated; `size="icon"` → circle, text size → extended pill. Focus-ring override uses a two-class selector so it wins on specificity, not source order. Positioning is left to the consumer (recipe in stories). +5 unit tests.
|
|
32
|
+
|
|
33
|
+
- **`Stat` — richer metric variants.** Four additive enhancements (existing flat/elevated/accent/sm/md/lg unchanged): `size="xl"` hero value; `changeVariant="chip"` tinted-pill change; **`StatChart`** (a new exported compound part — a styled consumer-sparkline slot, no charting dep); `variant="gradient"` soft sentiment-tinted surface. +8 unit tests.
|
|
34
|
+
|
|
35
|
+
- **`CircularProgress` — segmented / radial-stepper mode.** New `segments?: number` prop (`>= 2` → N discrete arc segments with centered gaps; filled = `round(pct × segments)`); `showLabel` shows `filled/segments` when segmented. Determinate-only; butt caps so gaps don't close at small sizes. +8 unit tests.
|
|
36
|
+
|
|
37
|
+
## 0.7.0
|
|
38
|
+
|
|
39
|
+
### Minor Changes
|
|
40
|
+
|
|
41
|
+
#### Components (8 new)
|
|
42
|
+
|
|
43
|
+
- **`EmptyState` (+ `EmptyStateMedia` / `EmptyStateTitle` / `EmptyStateDescription` / `EmptyStateActions`)** — centered placeholder for blank / no-results / error states (media badge + title + description + actions). Hybrid API: props build the body, or `children` fully replaces it. 4 variants (`default` / `search` neutral-gray, `error`, `success`) drive the tint + the default icon, × 3 sizes (sm/md/lg). `asChild` on Media/Title/Description/Actions; Title defaults to `<h3>`. Tints flow through `--ddga-empty-state-tint-*` custom props (dark-mode + forced-colors handled). New internal `Inbox` / `Search` icons. Radix `Slot` only — no new deps. 20 tests.
|
|
44
|
+
|
|
45
|
+
- **`Stat` + `StatGroup`** — self-contained KPI tile (label + value + change + icon) that owns its own card surface, so it's used as `<Stat>` directly (no `Card` wrapper). Hybrid API: props build the label-row → value → change-row, `children` append (sparkline slot). **Decoupled `trend` (caret icon) and `sentiment` (color)** — sentiment derives from trend unless set explicitly, so an inverted metric (a falling error rate) can show a down caret in green. 3 sizes; compound parts (`StatLabel` / `StatValue` / `StatChange`, the last self-coloring when standalone); 3 variants `flat` / `elevated` (shadow + brand badge) / `accent` (sentiment-colored edge bar). Sentiment color via `--ddga-stat-change-color` / `--ddga-stat-accent-*` keyed off `data-sentiment`. New internal `CaretUp` / `CaretDown` icons. **`StatGroup`** is the layout parent: `orientation` horizontal (responsive auto-fit grid, or fixed `columns` collapsing to 1 under 40rem, via `--ddga-stat-group-columns`) / vertical, `gap` sm/md/lg; inside a group tiles drop their standalone `max-inline-size` cap. No Radix, no new deps. 33 tests.
|
|
46
|
+
|
|
47
|
+
- **`Popover` (+ `PopoverTrigger` / `PopoverAnchor` / `PopoverContent` / `PopoverClose`)** — Radix Popover, the generic interactive floating panel between `Tooltip` and `DropdownMenu`. Content portal-anchored to `ctx.portalEl` (falls back to `rootEl`); `size` sm/md + default `max-inline-size` 20rem; optional bordered `arrow` (off by default). `PopoverClose` defaults to a corner-X (`Close` icon, localized `closeLabel`, `asChild`, falsy children fall through to the X). Non-modal by default (`modal` passes through to Root). Content renders `role="dialog"` and **dev-warns** when it has no `aria-label` / `aria-labelledby`. Dark-mode auto (semantic tokens) + forced-colors block. 22 unit + 6 Playwright tests. No new deps.
|
|
48
|
+
|
|
49
|
+
- **`Sidebar` (~21 parts)** — app-shell navigation and the first **context-stateful** compound (`SidebarProvider` + `useSidebar`). Desktop **icon-rail** collapse (full ↔ slim, synchronized 250ms animation) + **mobile off-canvas reusing `Drawer`** (free focus trap / scroll lock / portal-to-`portalEl`). Variants `sidebar` / `floating` / `inset` × `collapsible` icon/offcanvas/none × logical `side` (RTL-flips). State controlled (`open` / `onOpenChange`) or uncontrolled (`defaultOpen`), no built-in persistence; `isMobile` via `matchMedia` (`useIsMobile`); **Cmd/Ctrl+B** toggle (on by default, `keyboardShortcut={false}` opts out). `SidebarMenuButton`: `asChild` (router Link), `isActive` → `data-active` + `aria-current="page"`, sizes, auto-`Tooltip` when collapsed. Nested nav = documented composition (Radix `Collapsible` inline when expanded / `Popover` flyout when collapsed). New `PanelLeft` icon. **No new deps** (`Collapsible` from the `radix-ui` umbrella). 36 tests.
|
|
50
|
+
|
|
51
|
+
- **`ScrollArea`** — single wrapper around Radix ScrollArea (no new dep). `orientation` vertical / horizontal / both; `type` hover (default) / always / scroll / auto; `viewportRef` + `viewportProps`. Viewport is always `tabIndex={0}`; `role="region"` + accessible name only when `aria-label` / `aria-labelledby` is given (else dev-warns, mirroring Popover). No `asChild` (documented Radix-wrapper carve-out). 15 unit + 6 Playwright tests (jsdom can't measure the scrollbar corner / RTL placement).
|
|
52
|
+
|
|
53
|
+
- **`Menubar`** — Radix Menubar wrapper, the horizontal File/Edit/View app-bar pattern (no new dep — `radix-ui` already exports Menubar). Built as a near-1:1 mirror of `DropdownMenu`: full part parity (Root/Menu/Trigger/Content/Item/Checkbox/Radio/Label/Separator/Group/Sub\*) plus the bar parts, `startIcon` / `shortcut` / `destructive` item extras, `sm` / `md` Content. Dedicated `menubar.css` with an **SA-green open-menu underline indicator** (mirroring the Tabs active-tab accent). Trigger `variant`: `default` (flat + green underline) / `outline` (bordered chip). No `asChild` (Radix-primitive carve-out). Portal-anchored + containment regression test. 19 unit + 5 Playwright tests.
|
|
54
|
+
|
|
55
|
+
- **`Timeline` (+ `TimelineItem` / `TimelineMarker` / `TimelineContent` / `TimelineTitle` / `TimelineDescription` / `TimelineTime`)** — visual-only chronological compound for audit trails / order history / activity feeds, modeled on `Steps`. Semantic `<ol>` / `<li>` with a CSS-drawn connector line (full-height per item, RTL via logical properties) and status markers (`default` / `success` / `error` / `warning` / `info` → solid semantic `--ddga-color-*`, so dark mode adapts automatically) with a custom-icon child or a plain dot. **Connector is a completed-progress fill** — a segment takes the previous node's color only when the next node is also reached, so `complete → pending` stays neutral (Steps semantics, via a `data-reached` attr + a `:has()` gate). `TimelineTime` renders `<time>` with `dateTime`. Vertical + horizontal, sm/md. No `asChild` (`<ol>`/`<li>` carve-out, mirrors `Steps`); `ActivityFeed` is a composition story (Timeline + Avatar), not a component. No new deps, no new icons. 28 tests.
|
|
56
|
+
|
|
3
57
|
## 0.6.0
|
|
4
58
|
|
|
5
59
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -82,13 +82,15 @@ function MyField({ label, helperText, error, errorMessage, ...rest }) {
|
|
|
82
82
|
|
|
83
83
|
## Components
|
|
84
84
|
|
|
85
|
-
**Form:** `Button` · `Input` · `Textarea` · `NumberInput` · `Checkbox` · `RadioGroup` + `Radio` · `Switch` · `Select` + `SelectItem` · `Combobox` + `ComboboxItem` (+ `ComboboxGroup` · `ComboboxSeparator`) · `DatePicker` (Hijri toggle) · `Slider` (single/range) · `Rating` (half-star) · `FileUpload` · `Toggle` + `ToggleGroup` (+ `ToggleGroupItem`)
|
|
85
|
+
**Form:** `Button` · `Input` · `Textarea` · `NumberInput` · `InputOTP` (OTP/PIN) · `SearchBox` · `TagInput` (token/chip) · `Checkbox` · `RadioGroup` + `Radio` · `Switch` · `Select` + `SelectItem` · `Combobox` + `ComboboxItem` (+ `ComboboxGroup` · `ComboboxSeparator`) · `DatePicker` (Hijri toggle) · `Slider` (single/range) · `Rating` (half-star) · `FileUpload` · `Toggle` + `ToggleGroup` (+ `ToggleGroupItem`)
|
|
86
86
|
|
|
87
|
-
**Display:** `Card` (+ `CardImage`/`CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`) · `Badge` · `Divider` · `Avatar` (+ `AvatarImage`/`AvatarFallback`/`AvatarGroup`) · `DescriptionList` (+ `DescriptionItem`/`DescriptionTerm`/`DescriptionDetails`)
|
|
87
|
+
**Display:** `Card` (+ `CardImage`/`CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`) · `Table` (+ `TableHeader`/`TableBody`/`TableFooter`/`TableRow`/`TableHead`/`TableCell`/`TableCaption`) · `List` (+ `ListItem`/`ListItemIcon`/`ListItemContent`/`ListItemAction`) · `Quote` (+ `QuoteContent`/`QuoteCaption`/`QuoteAuthor`/`QuoteSource`) · `Badge` · `Divider` · `Avatar` (+ `AvatarImage`/`AvatarFallback`/`AvatarGroup`) · `DescriptionList` (+ `DescriptionItem`/`DescriptionTerm`/`DescriptionDetails`) · `Stat` + `StatGroup` (KPI tiles) · `Timeline` (+ `TimelineItem`/`TimelineMarker`/`TimelineContent`/`TimelineTitle`/`TimelineDescription`/`TimelineTime`) · `EmptyState` (+ `EmptyStateMedia`/`EmptyStateTitle`/`EmptyStateDescription`/`EmptyStateActions`)
|
|
88
88
|
|
|
89
|
-
**Feedback / overlay:** `Tooltip` · `Alert` · `Modal` · `Toast` (imperative API) · `Drawer` (off-canvas, 4 sides) · `DropdownMenu` (compound w/ CheckboxItem, RadioGroup, Sub)
|
|
89
|
+
**Feedback / overlay:** `Tooltip` · `Alert` · `Modal` · `Toast` (imperative API) · `Drawer` (off-canvas, 4 sides) · `DropdownMenu` (compound w/ CheckboxItem, RadioGroup, Sub) · `Popover` (generic floating panel) · `Command` + `CommandDialog` (⌘K palette)
|
|
90
90
|
|
|
91
|
-
**Navigation:** `Tabs` · `Breadcrumb` · `Pagination` · `Accordion` · `Steps`
|
|
91
|
+
**Navigation:** `Tabs` · `Breadcrumb` · `Pagination` · `Accordion` · `Steps` · `Sidebar` (app-shell, collapsible) · `Menubar` (File/Edit/View app-bar) · `Link` (styled `<a>`, `external`)
|
|
92
|
+
|
|
93
|
+
**Layout:** `ScrollArea` · `Collapsible` (+ `CollapsibleTrigger`/`CollapsibleContent`)
|
|
92
94
|
|
|
93
95
|
**Status:** `Spinner` · `Skeleton` · `Progress` + `CircularProgress`
|
|
94
96
|
|