@usetheo/ui 0.19.0 → 0.20.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.
@@ -0,0 +1 @@
1
+ export { Stepper, deriveSteps, type StepStatus, type StepperProps, type StepperStepData, } from "./stepper.js";
@@ -0,0 +1,47 @@
1
+ import type { HTMLAttributes, ReactNode } from "react";
2
+ /**
3
+ * Stepper — multi-step pipeline progress, promoted from the theo-cloud
4
+ * dashboard build-timeline (production). Read-only by design: steps are NOT
5
+ * clickable (pipeline visualization, not a wizard). 100% controlled — live
6
+ * updates (SSE/polling) belong to the consumer.
7
+ *
8
+ * Contract: step `id`s MUST be unique (React keys); at most ONE step should
9
+ * be `active` (`aria-current="step"` is emitted per active step as-is).
10
+ * A `label` is required — it names the pipeline for screen readers.
11
+ *
12
+ * <Stepper label="Build pipeline" steps={[
13
+ * { id: "queued", label: "Queued", status: "done" },
14
+ * { id: "build", label: "Building", status: "active" },
15
+ * ]} />
16
+ *
17
+ * For the simple "wizard position" case, derive the array from an index:
18
+ * <Stepper label="Onboarding" steps={deriveSteps(defs, activeIndex)} />
19
+ */
20
+ export type StepStatus = "pending" | "active" | "done" | "failed";
21
+ export interface StepperStepData {
22
+ /** Unique key for the step (consumer contract: no duplicates). */
23
+ id: string;
24
+ label: string;
25
+ /** For failed steps, pass the failure cause here — it is read by screen readers inside the same item (F-dom-3). */
26
+ description?: string;
27
+ status: StepStatus;
28
+ /** Optional slot — prefer `<Timestamp value={...} />` from this library. */
29
+ timestamp?: ReactNode;
30
+ /** Optional slot rendered ONLY when status === "failed" (the action belongs to the consumer). */
31
+ retry?: ReactNode;
32
+ }
33
+ export interface StepperProps extends HTMLAttributes<HTMLOListElement> {
34
+ /** Accessible name for the pipeline (aria-label of the list). */
35
+ label: string;
36
+ steps: StepperStepData[];
37
+ /** @default "vertical" — both production cases (build/ingest) are vertical. */
38
+ orientation?: "vertical" | "horizontal";
39
+ }
40
+ /**
41
+ * Pure helper for the simple index-driven case: steps before `activeIndex`
42
+ * are done, the step at it is active, later ones are pending. Out-of-range
43
+ * indexes are safe: past the end → all done; negative → all pending.
44
+ */
45
+ export declare function deriveSteps(defs: Array<Pick<StepperStepData, "id" | "label" | "description">>, activeIndex: number): StepperStepData[];
46
+ declare const Stepper: import("react").ForwardRefExoticComponent<StepperProps & import("react").RefAttributes<HTMLOListElement>>;
47
+ export { Stepper };
package/dist/index.d.ts CHANGED
@@ -48,6 +48,7 @@ export { PinInput, type PinInputProps } from "./components/primitives/pin-input/
48
48
  export { DataTable, type DataTableColumn, type DataTableProps, type DataTableSort, } from "./components/composites/data-table/index.js";
49
49
  export { PageShell, type PageShellProps } from "./components/composites/page-shell/index.js";
50
50
  export { linScale, niceMax, seriesPath, TrendChart, type TrendChartProps, type TrendPoint, type TrendSeries, } from "./components/composites/trend-chart/index.js";
51
+ export { Stepper, deriveSteps, type StepStatus, type StepperProps, type StepperStepData, } from "./components/composites/stepper/index.js";
51
52
  export { MetricsPanel, type Metric } from "./components/primitives/metrics-panel/index.js";
52
53
  export { SocialAuthRow, type SocialProvider, } from "./components/primitives/social-auth-row/index.js";
53
54
  export { LoginSplit } from "./components/primitives/login-split/index.js";
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { Slot } from '@radix-ui/react-slot';
4
4
  import { cva } from 'class-variance-authority';
5
5
  import { forwardRef, useState, useRef, useEffect, useCallback, createContext, useId, useMemo, Children, isValidElement, cloneElement, Fragment as Fragment$1, useContext, createElement } from 'react';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
- import { Check, X, Copy, Loader2, ArrowUpCircle, AlertCircle, ChevronDown, ChevronUp, Minus, Circle, ChevronRight, ChevronsUpDown, TrendingDown, TrendingUp, ArrowUpRight, TriangleAlert, CheckCircle2, Info, ChevronsLeft, ChevronLeft, ChevronsRight, Search, Filter, GitCommit, GitBranch, Activity, Plus, Lock, EyeOff, Eye, Trash2, GitPullRequest, Server, ExternalLink, Globe, ShieldCheck, ShieldX, Clock, RotateCcw, ArrowDownLeft, MoreHorizontal } from 'lucide-react';
7
+ import { Check, X, Copy, Loader2, ArrowUpCircle, AlertCircle, ChevronDown, ChevronUp, Minus, Circle, ChevronRight, ChevronsUpDown, TrendingDown, TrendingUp, ArrowUpRight, TriangleAlert, CheckCircle2, Info, ChevronsLeft, ChevronLeft, ChevronsRight, Search, Filter, CircleDashed, GitCommit, GitBranch, Activity, Plus, Lock, EyeOff, Eye, Trash2, GitPullRequest, Server, ExternalLink, Globe, ShieldCheck, ShieldX, Clock, RotateCcw, ArrowDownLeft, MoreHorizontal } from 'lucide-react';
8
8
  import { Command, useCommandState } from 'cmdk';
9
9
  import * as SliderPrimitive from '@radix-ui/react-slider';
10
10
  import * as DialogPrimitive from '@radix-ui/react-dialog';
@@ -4539,6 +4539,95 @@ var TrendChart = forwardRef(
4539
4539
  }
4540
4540
  );
4541
4541
  TrendChart.displayName = "TrendChart";
4542
+ function deriveSteps(defs, activeIndex) {
4543
+ return defs.map((def, i) => ({
4544
+ ...def,
4545
+ status: i < activeIndex ? "done" : i === activeIndex ? "active" : "pending"
4546
+ }));
4547
+ }
4548
+ var ICON = {
4549
+ done: Check,
4550
+ active: Loader2,
4551
+ failed: X,
4552
+ pending: CircleDashed
4553
+ };
4554
+ var ICON_TONE = {
4555
+ done: "text-success",
4556
+ active: "animate-spin text-primary",
4557
+ failed: "text-destructive",
4558
+ pending: "text-muted-foreground"
4559
+ };
4560
+ var LABEL_TONE = {
4561
+ done: "font-medium text-foreground",
4562
+ active: "font-semibold text-primary",
4563
+ failed: "font-semibold text-destructive",
4564
+ pending: "font-medium text-muted-foreground"
4565
+ };
4566
+ var SR_STATE_TEXT = {
4567
+ done: " \u2014 completed",
4568
+ active: null,
4569
+ failed: " \u2014 failed",
4570
+ pending: " \u2014 not started"
4571
+ };
4572
+ var Stepper = forwardRef(
4573
+ ({ label, steps, orientation = "vertical", className, ...props }, ref) => /* @__PURE__ */ jsx(
4574
+ "ol",
4575
+ {
4576
+ "data-slot": "stepper",
4577
+ "data-orientation": orientation,
4578
+ ref,
4579
+ "aria-label": label,
4580
+ className: cn(
4581
+ orientation === "horizontal" ? "flex flex-wrap gap-x-6 gap-y-3" : "space-y-3",
4582
+ className
4583
+ ),
4584
+ ...props,
4585
+ children: steps.map((s) => {
4586
+ const status = Object.hasOwn(ICON, s.status) ? s.status : "pending";
4587
+ const Icon2 = ICON[status];
4588
+ return /* @__PURE__ */ jsxs(
4589
+ "li",
4590
+ {
4591
+ "data-slot": "stepper-step",
4592
+ "data-state": status,
4593
+ "aria-current": status === "active" ? "step" : void 0,
4594
+ className: "flex items-start gap-3",
4595
+ children: [
4596
+ /* @__PURE__ */ jsx(
4597
+ "span",
4598
+ {
4599
+ "aria-hidden": "true",
4600
+ className: "mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-full border border-border",
4601
+ "data-slot": "stepper-icon",
4602
+ children: /* @__PURE__ */ jsx(Icon2, { className: cn("size-3", ICON_TONE[status]) })
4603
+ }
4604
+ ),
4605
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
4606
+ /* @__PURE__ */ jsxs(
4607
+ "p",
4608
+ {
4609
+ "data-slot": "stepper-label",
4610
+ title: s.label,
4611
+ className: cn("truncate text-body-sm", LABEL_TONE[status]),
4612
+ children: [
4613
+ s.label,
4614
+ SR_STATE_TEXT[status] && /* @__PURE__ */ jsx("span", { className: "sr-only", children: SR_STATE_TEXT[status] })
4615
+ ]
4616
+ }
4617
+ ),
4618
+ s.description && /* @__PURE__ */ jsx("p", { className: "text-label text-muted-foreground", children: s.description }),
4619
+ s.timestamp && /* @__PURE__ */ jsx("p", { "data-slot": "stepper-timestamp", className: "text-label text-muted-foreground", children: s.timestamp }),
4620
+ status === "failed" && s.retry && /* @__PURE__ */ jsx("div", { "data-slot": "stepper-retry", className: "mt-1", children: s.retry })
4621
+ ] })
4622
+ ]
4623
+ },
4624
+ s.id
4625
+ );
4626
+ })
4627
+ }
4628
+ )
4629
+ );
4630
+ Stepper.displayName = "Stepper";
4542
4631
  var MetricsPanel = forwardRef(
4543
4632
  ({ className, title, description, metrics, columns, ...props }, ref) => /* @__PURE__ */ jsxs(
4544
4633
  "div",
@@ -5469,4 +5558,4 @@ function CommandPalette({
5469
5558
  ] }) });
5470
5559
  }
5471
5560
 
5472
- export { AccountMenu, ActionBar, Alert, Avatar, BadgeWithDot as Badge, Breadcrumb, Button, Card, Checkbox, CodeBlock, Combobox, CommandPalette, ConfirmDialog, CopyButton, DangerZone, DataTable, DeploymentRow, DescriptionList, Dialog, DomainConfig, DropdownMenu, EmptyState, EnvVarEditor, FormField, Input, JsonViewer, Label, LoginSplit, MetricCard, MetricsPanel, PageShell, Pagination, PinInput, PlanBadge, PreviewEnvCard, Progress, ProjectCard, RadioGroup, RollbackUI, ScrollArea, Select, Sheet, Sidebar, Skeleton, Slider, SocialAuthRow, StatTile, StatusDot, StatusIndicator, Switch, Table, Tabs, TaskHeader, Textarea, Timestamp, Toast, Toaster, TooltipWithStatics as Tooltip, TopNav, TrendChart, UpdateBanner, avatarVariants, badgeVariants, buttonVariants, cn, computePageRange, isNearBottom, linScale, niceMax, seriesPath, sheetVariants, useStickToBottom, useToast };
5561
+ export { AccountMenu, ActionBar, Alert, Avatar, BadgeWithDot as Badge, Breadcrumb, Button, Card, Checkbox, CodeBlock, Combobox, CommandPalette, ConfirmDialog, CopyButton, DangerZone, DataTable, DeploymentRow, DescriptionList, Dialog, DomainConfig, DropdownMenu, EmptyState, EnvVarEditor, FormField, Input, JsonViewer, Label, LoginSplit, MetricCard, MetricsPanel, PageShell, Pagination, PinInput, PlanBadge, PreviewEnvCard, Progress, ProjectCard, RadioGroup, RollbackUI, ScrollArea, Select, Sheet, Sidebar, Skeleton, Slider, SocialAuthRow, StatTile, StatusDot, StatusIndicator, Stepper, Switch, Table, Tabs, TaskHeader, Textarea, Timestamp, Toast, Toaster, TooltipWithStatics as Tooltip, TopNav, TrendChart, UpdateBanner, avatarVariants, badgeVariants, buttonVariants, cn, computePageRange, deriveSteps, isNearBottom, linScale, niceMax, seriesPath, sheetVariants, useStickToBottom, useToast };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usetheo/ui",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "description": "Violet Forge design system — generic React components + primitives (the non-AI foundation of @theokit/ui).",