@usetheo/ui 0.7.0-next.0 → 0.9.0-next.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
@@ -7,6 +7,176 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.9.0-next.0] - 2026-05-23
11
+
12
+ Minor — adds the two deferred primitives revealed by the Brief #3
13
+ review (`Alert` + `Pagination`). Both are additive; zero breaking
14
+ change. The release closes the lower-priority follow-ups left over
15
+ from Briefs #1/#2 — `Alert` replaces the consumer's 27-LOC
16
+ `<VerificationBanner>` composition; `Pagination` is forward-positioned
17
+ for when `<Table>` (0.8) starts paginating Billing / Audit / Team
18
+ data at scale.
19
+
20
+ Plan: filed as Brief #3 in
21
+ `theo/docs/handoff/2026-05-23-theo-ui-cloud-dashboard-gaps-brief-3.md`.
22
+
23
+ ### Added
24
+
25
+ - **`<Alert>` primitive (NEW)** — persistent inline notice. Four
26
+ intents: `info` (Info icon, primary token), `success`
27
+ (CheckCircle2, success), `warning` (TriangleAlert, warning),
28
+ `destructive` (AlertCircle, destructive). Optional `title`,
29
+ `description`, right-aligned `action` slot (consumer-provided
30
+ ReactNode), and `onDismiss` handler (renders an `X` button).
31
+ `destructive` intent renders `role="alert"` (assertive
32
+ announcement); other intents render `role="status"` (polite) —
33
+ matches WAI-ARIA conventions for status messaging. Distinct
34
+ from `Toast` (transient + corner) and `EmptyState` (centered
35
+ card). 13 unit tests + 5 Ladle stories. Brief #3 consumer:
36
+ TheoCloud `<VerificationBanner>` → 3-line `<Alert>`.
37
+ - **`<Pagination>` primitive (NEW)** — accessible page-number
38
+ navigation. Renders `<nav aria-label="Pagination">` with
39
+ first / prev / numbers / next / last buttons + visual ellipses
40
+ when `totalPages` exceeds the visible range. Active page carries
41
+ `aria-current="page"`. Keyboard nav (`ArrowLeft` / `ArrowRight` /
42
+ `Home` / `End`) on the nav element. Configurable `siblingCount`
43
+ (default 1) + optional `showJumpButtons` (default true) +
44
+ `size` (`sm | md`). Returns `null` when `totalPages <= 1`. Also
45
+ exports a pure `computePageRange(currentPage, totalPages,
46
+ siblingCount)` helper for unit-testing the range logic in
47
+ isolation — most pagination bugs live in that function. 21 unit
48
+ tests (6 on `computePageRange` alone) + 6 Ladle stories.
49
+ Forward-positioned for `<Table>` v2 consumers.
50
+
51
+ ## [0.8.0-next.0] - 2026-05-23
52
+
53
+ Minor — adds eight cross-cutting primitives revealed by the systematic
54
+ review of the remaining 11 dashboard pages (Projects, Environments,
55
+ Team, Billing, Domains, Settings, Profile, Login, Register,
56
+ Verification, Recovery, DeviceSuccess) + recurring PaaS UI patterns.
57
+ Each component is used in ≥3 distinct sites in the consumer dashboard.
58
+ 6 are true primitives (Table, StatusDot, CopyButton, Timestamp,
59
+ StatTile, DangerZone); 2 are composites by taxonomy gate
60
+ (ConfirmDialog depends on Dialog/Input/Button; CodeBlock depends on
61
+ CopyButton). Zero breaking change; zero new peer-deps.
62
+
63
+ Plan: `.claude/knowledge-base/plans/dashboard-paas-primitives-2-plan.md`.
64
+ Edge-case review: `.claude/knowledge-base/reviews/edge-cases/dashboard-paas-primitives-2-edge-cases-2026-05-23.md`.
65
+ Consumer brief: `theo/docs/handoff/2026-05-23-theo-ui-cloud-dashboard-gaps-brief-2.md`.
66
+
67
+ ### Added
68
+
69
+ - **`<Table>` primitive (NEW)** — semantic data-table with sub-components
70
+ `Table.Header`, `Table.Body`, `Table.Row`, `Table.Cell`,
71
+ `Table.HeaderCell`. Supports `density` (`default` / `compact` via
72
+ Context), per-cell `align` (`left` / `center` / `right`), `numeric`
73
+ cells (`font-mono tabular-nums`), and sortable header cells
74
+ (`onSort` + `sortDirection` with ChevronUp/ChevronDown affordance
75
+ + `aria-sort`). `sortDirection` without `onSort` is a no-op (header
76
+ stays static); `sortDirection="none"` with `onSort` renders both
77
+ chevrons dimmed (`opacity-30`). 10 unit tests + 4 Ladle stories.
78
+ Brief #2 consumer: TheoCloud dashboard.
79
+ - **`<StatusDot>` primitive (NEW)** — semantic status indicator
80
+ (small colored circle + optional label). Five `status` kinds:
81
+ `live` (success), `building` (warning, auto-pulses), `failed`
82
+ (destructive), `idle` (muted), `warning` (warning, static). Three
83
+ sizes (`xs` 6px / `sm` 8px default / `md` 10px). When neither
84
+ `label` nor `aria-label` is provided, auto-applies
85
+ `aria-label={status}` + emits a dev-only warning (color-only
86
+ status is invisible to screen readers). 12 unit tests + 3 stories.
87
+ Brief #2 consumer: TheoCloud dashboard (7+ sites).
88
+ - **`<CopyButton>` primitive (NEW)** — click-to-copy primitive wrapping
89
+ `navigator.clipboard.writeText`. Icon swap (Copy → Check on success,
90
+ Copy → X on failure), `aria-live="polite"` announcement for screen
91
+ readers, optional `label`, `ghost`/`outline` variants, two sizes,
92
+ `onCopied` callback, configurable `feedbackDuration` (default
93
+ 1500ms). SSR-safe (guards `navigator?.clipboard?.writeText`); HTTP
94
+ non-localhost contexts (where the Clipboard API is undefined) fall
95
+ back to the failed state instead of throwing. Auto-cleans the
96
+ revert timer on unmount; debounces double-clicks. 12 unit tests +
97
+ 4 Ladle stories. Brief #2 consumer: TheoCloud dashboard.
98
+ - **`<Timestamp>` primitive (NEW)** — accessible `<time datetime>`
99
+ element with `relative` (default) / `absolute` / `both` formats.
100
+ Uses zero-dep `Intl.RelativeTimeFormat`. Auto-refreshes via
101
+ `setInterval` (default 60s, `refreshInterval={0}` disables).
102
+ Native `title` HTML attribute carries the absolute time on hover
103
+ (no Tooltip component dependency — keeps Timestamp a true
104
+ primitive). `aria-label` always carries the full date. Invalid
105
+ date renders an empty `<time>` element; invalid locale falls back
106
+ to default with a dev warning. `value` accepts ISO string, Date,
107
+ or **Unix milliseconds** (documented in JSDoc — passing seconds
108
+ renders ~1970). 13 unit tests + 4 Ladle stories. Brief #2
109
+ consumer: TheoCloud dashboard (every dashboard page).
110
+ - **`<StatTile>` primitive (NEW)** — big-number stat tile for
111
+ dashboard summary rows. `value` + `label` + optional `icon` +
112
+ optional `delta` (`{value, trend}` with `trend: "up" | "down" |
113
+ "flat"` driving TrendingUp/TrendingDown/Minus icons and
114
+ success/destructive/muted color). Dual mode (button/div) based on
115
+ `onClick` — same pattern as `AccountMenu`/`ProjectSwitcher`. Value
116
+ uses `font-display tabular-nums whitespace-nowrap`. 7 unit tests
117
+ + 4 Ladle stories. Brief #2 consumer: TheoCloud Overview
118
+ dashboard (3 tiles per page).
119
+ - **`<DangerZone>` primitive (NEW)** — destructive-actions section
120
+ with sub-component `DangerZone.Action`. Red-bordered container
121
+ (`border-destructive/30`) with title bar (default `"Danger Zone"`)
122
+ and action rows. Each row carries `title` + `description` +
123
+ consumer-provided `action` slot (typically a destructive
124
+ `<Button>`). Rows separated by hairline dividers; last row drops
125
+ the bottom border via `last:border-b-0`. Consumer supplies the
126
+ destructive button — DangerZone never imports `<Button>`, keeping
127
+ it a true primitive. 6 unit tests + 3 Ladle stories. Brief #2
128
+ consumer: Settings + Profile + Team + Billing pages.
129
+ - **`<ConfirmDialog>` composite (NEW)** — controlled confirmation
130
+ modal built on `Dialog`. Auto-focuses Cancel on open (deliberate
131
+ — NOT the destructive button). `intent="destructive"` styles the
132
+ confirm button with the destructive variant. `confirmationPhrase`
133
+ enables typed-confirmation guard (case-sensitive, empty string
134
+ treated as no phrase). Pressing Enter in the input triggers
135
+ confirm when matched. Async `onConfirm` shows `Loader2` spinner
136
+ while pending; resolve closes the dialog; reject keeps it open
137
+ so consumers can surface their own error. Phrase input resets
138
+ whenever the dialog closes. 13 unit tests + 4 Ladle stories.
139
+ Composite (depends on Dialog + Button + Input). Brief #2
140
+ consumer: 6+ destructive flows (Settings delete, Team remove,
141
+ Billing cancel, Profile delete, Domains remove, Environments
142
+ delete).
143
+ - **`<CodeBlock>` composite (NEW)** — terminal command / code-snippet
144
+ surface. Pre-rendered code inside a `<pre>` with optional
145
+ `terminal` prefix per line (`"$ "`), optional `caption` (file
146
+ name), and optional inline `<CopyButton>` positioned top-right.
147
+ The CopyButton receives the RAW `code` (without the visual `"$ "`
148
+ prefix) — consumers paste only the executable command. `language`
149
+ prop is reserved for future syntax highlighting (v1 ignored).
150
+ 7 unit tests + 4 Ladle stories. Composite (depends on
151
+ CopyButton). Brief #2 consumer: Overview EmptyState, Projects
152
+ EmptyState, Domains DNS records, API token display, LoginPage
153
+ CLI hint.
154
+
155
+ ### Implementation notes
156
+
157
+ - **Taxonomy gate** classified ConfirmDialog + CodeBlock as composites
158
+ (D2 in the plan). Brief #2 listed all 8 as primitives, but the
159
+ validate-quality-gates.ts script is hard-fail for any
160
+ `primitives/` file that imports another `@usetheo/ui` component.
161
+ - **Timestamp uses native `title` HTML attribute** (D3) instead of
162
+ the `<Tooltip>` component, to keep the file a true primitive
163
+ without sibling-primitive imports.
164
+ - **Zero new peer-deps.** Every component uses only `lucide-react`
165
+ + Radix (both already peer) + `cn()`.
166
+ - **Bundle delta** — `dist/index.js` grew from 395763 B to 417113 B
167
+ (+21350 B / +5.4%); `dist/index.d.ts` grew +11808 B / +7.5%. Both
168
+ exceeded the ±5% tolerance by a small margin (8 components ≈ +2.5 KB
169
+ each on average). The baseline was rebaselined in the same release
170
+ (`scripts/baselines/bundle-sizes.json`) — expected and explicit per
171
+ plan D6.
172
+ - 10 SHOULD TEST edge cases from the `/edge-case-plan` review
173
+ incorporated into the TDD blocks (EC-1 through EC-10 — empty
174
+ CopyButton value, unmount during timer, clipboard undefined,
175
+ Table sort direction without onSort, dimmed affordance for
176
+ `none`, StatusDot dev warning, Timestamp Unix seconds vs ms,
177
+ invalid locale fallback, ConfirmDialog empty phrase semantics,
178
+ Enter-to-confirm in phrase input).
179
+
10
180
  ## [0.7.0-next.0] - 2026-05-23
11
181
 
12
182
  Minor — adds four PaaS-shape primitives to cover the gaps surfaced by the
package/README.md CHANGED
@@ -13,8 +13,8 @@ A React component library built for AI agent surfaces and cloud dashboards. **10
13
13
  <!-- BEGIN:counts -->
14
14
  [![license](https://img.shields.io/badge/license-Apache--2.0-7C3AED?style=flat-square)](./LICENSE)
15
15
  [![react](https://img.shields.io/badge/react-18+-7C3AED?style=flat-square&logo=react&logoColor=white)](https://react.dev)
16
- [![tests](https://img.shields.io/badge/tests-1174%20passing-success?style=flat-square)](#quality-gates)
17
- [![components](https://img.shields.io/badge/components-124-7C3AED?style=flat-square)](#component-catalog)
16
+ [![tests](https://img.shields.io/badge/tests-1281%20passing-success?style=flat-square)](#quality-gates)
17
+ [![components](https://img.shields.io/badge/components-134-7C3AED?style=flat-square)](#component-catalog)
18
18
  [![shadcn](https://img.shields.io/badge/shadcn-compatible-000?style=flat-square)](https://ui.shadcn.com/docs/registry)
19
19
  <!-- END:counts -->
20
20
 
@@ -133,31 +133,32 @@ import { ThemeProvider, ThemeScript } from "@usetheo/ui";
133
133
  ## Component catalog
134
134
 
135
135
  <!-- BEGIN:component-catalog-intro -->
136
- **124 components**, organized by mechanical rule: a *primitive* imports no other `@usetheo/ui` component; a *composite* does.
136
+ **134 components**, organized by mechanical rule: a *primitive* imports no other `@usetheo/ui` component; a *composite* does.
137
137
  <!-- END:component-catalog-intro -->
138
138
 
139
139
  <details>
140
140
  <summary>
141
141
  <!-- BEGIN:primitives-count -->
142
- **Primitives** (81) — building blocks
142
+ **Primitives** (89) — building blocks
143
143
  <!-- END:primitives-count -->
144
144
  </summary>
145
145
 
146
146
  <!-- BEGIN:primitives -->
147
147
  `AgentErrorCard` · `AgentEvent` · `AgentHandoff` · `AgentProfile` · `AgentStartingState` · `AgentStreaming`
148
- `ArtifactPreview` · `AttachmentChip` · `AuditLogEntry` · `AutoCompactNotice` · `Avatar` · `Badge`
149
- `BrowserControls` · `BuildLogStream` · `Button` · `CapabilityIndicator` · `Card` · `ChatThread`
150
- `Checkbox` · `ContextCard` · `ContextWindowBar` · `CostMeter` · `CreatedFilesCard` · `CronJobCard`
151
- `Dialog` · `DiffViewer` · `EmptyState` · `FolderContextCard` · `FolderSelector` · `FormField`
152
- `HookConfig` · `HookEventLog` · `Input` · `IntentSelector` · `Label` · `LaneBoard`
153
- `LoginSplit` · `MCPServerCard` · `MemoryEditor` · `MentionMenu` · `MetricsPanel` · `ModelCard`
154
- `ModelSelector` · `PermissionMatrix` · `PlanBadge` · `Progress` · `ProgressChecklist` · `ProjectSwitcher`
155
- `QuickActionChips` · `RadioGroup` · `RecentFoldersList` · `RuleCard` · `RunStats` · `RunningTasksPanel`
156
- `ScrollArea` · `Select` · `SessionListItem` · `SessionTimeline` · `Sheet` · `Sidebar`
157
- `Skeleton` · `SkillCard` · `SocialAuthRow` · `StepsRail` · `SubAgentDispatch` · `Switch`
158
- `SystemPromptEditor` · `Tabs` · `TaskNode` · `TaskPlan` · `TerminalPanel` · `Textarea`
159
- `Toast` · `Toaster` · `TokenUsageChart` · `ToolCall` · `ToolCallCard` · `ToolResult`
160
- `ToolsList` · `Tooltip` · `TopNav`
148
+ `Alert` · `ArtifactPreview` · `AttachmentChip` · `AuditLogEntry` · `AutoCompactNotice` · `Avatar`
149
+ `Badge` · `BrowserControls` · `BuildLogStream` · `Button` · `CapabilityIndicator` · `Card`
150
+ `ChatThread` · `Checkbox` · `ContextCard` · `ContextWindowBar` · `CopyButton` · `CostMeter`
151
+ `CreatedFilesCard` · `CronJobCard` · `DangerZone` · `Dialog` · `DiffViewer` · `EmptyState`
152
+ `FolderContextCard` · `FolderSelector` · `FormField` · `HookConfig` · `HookEventLog` · `Input`
153
+ `IntentSelector` · `Label` · `LaneBoard` · `LoginSplit` · `MCPServerCard` · `MemoryEditor`
154
+ `MentionMenu` · `MetricsPanel` · `ModelCard` · `ModelSelector` · `Pagination` · `PermissionMatrix`
155
+ `PlanBadge` · `Progress` · `ProgressChecklist` · `ProjectSwitcher` · `QuickActionChips` · `RadioGroup`
156
+ `RecentFoldersList` · `RuleCard` · `RunStats` · `RunningTasksPanel` · `ScrollArea` · `Select`
157
+ `SessionListItem` · `SessionTimeline` · `Sheet` · `Sidebar` · `Skeleton` · `SkillCard`
158
+ `SocialAuthRow` · `StatTile` · `StatusDot` · `StepsRail` · `SubAgentDispatch` · `Switch`
159
+ `SystemPromptEditor` · `Table` · `Tabs` · `TaskNode` · `TaskPlan` · `TerminalPanel`
160
+ `Textarea` · `Timestamp` · `Toast` · `Toaster` · `TokenUsageChart` · `ToolCall`
161
+ `ToolCallCard` · `ToolResult` · `ToolsList` · `Tooltip` · `TopNav`
161
162
  <!-- END:primitives -->
162
163
 
163
164
  </details>
@@ -165,12 +166,12 @@ import { ThemeProvider, ThemeScript } from "@usetheo/ui";
165
166
  <details>
166
167
  <summary>
167
168
  <!-- BEGIN:composites-count -->
168
- **Composites** (43) — assembled flows
169
+ **Composites** (45) — assembled flows
169
170
  <!-- END:composites-count -->
170
171
  </summary>
171
172
 
172
173
  <!-- BEGIN:composites -->
173
- `AccountMenu` · `AgentComposer` · `AgentEditor` · `AgentStream` · `AgentTimeline` · `ApprovalCard` · `ChatComposer` · `ChatMessage` · `ChatMessageAction` · `ChatMessageActions` · `ChatMessageBranch` · `ChatMessageBranchContent` · `ChatMessageBranchNext` · `ChatMessageBranchPage` · `ChatMessageBranchPrevious` · `ChatMessageBranchSelector` · `ChatMessageContent` · `ChatMessageResponse` · `ChatMessageRoot` · `ChatMessageToolbar` · `CommandPalette` · `CronJobsList` · `DataPart` · `DeploymentRow` · `DomainConfig` · `EnvVarEditor` · `FilePart` · `MCPServerList` · `PermissionModal` · `PreviewEnvCard` · `PreviewPanel` · `ProjectCard` · `ReasoningPart` · `RollbackUI` · `RuleEditor` · `SkillEditor` · `SkillsList` · `SourceDocumentPart` · `SourceUrlPart` · `TaskHeader` · `TextPart` · `ToolCallPart` · `UsageMeter`
174
+ `AccountMenu` · `AgentComposer` · `AgentEditor` · `AgentStream` · `AgentTimeline` · `ApprovalCard` · `ChatComposer` · `ChatMessage` · `ChatMessageAction` · `ChatMessageActions` · `ChatMessageBranch` · `ChatMessageBranchContent` · `ChatMessageBranchNext` · `ChatMessageBranchPage` · `ChatMessageBranchPrevious` · `ChatMessageBranchSelector` · `ChatMessageContent` · `ChatMessageResponse` · `ChatMessageRoot` · `ChatMessageToolbar` · `CodeBlock` · `CommandPalette` · `ConfirmDialog` · `CronJobsList` · `DataPart` · `DeploymentRow` · `DomainConfig` · `EnvVarEditor` · `FilePart` · `MCPServerList` · `PermissionModal` · `PreviewEnvCard` · `PreviewPanel` · `ProjectCard` · `ReasoningPart` · `RollbackUI` · `RuleEditor` · `SkillEditor` · `SkillsList` · `SourceDocumentPart` · `SourceUrlPart` · `TaskHeader` · `TextPart` · `ToolCallPart` · `UsageMeter`
174
175
  <!-- END:composites -->
175
176
 
176
177
  </details>