@conscia-labs/design-system 0.4.0 → 1.0.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/README.md CHANGED
@@ -5,6 +5,10 @@ The shared React component library for building clear, consistent, and accessibl
5
5
  `@conscia-labs/design-system` brings Conscia’s visual foundation, reusable interface primitives, and common product patterns together in one package. It is designed for operational applications where information density, predictable interaction, and accessibility matter.
6
6
 
7
7
  > **Package:** available publicly as [`@conscia-labs/design-system`](https://www.npmjs.com/package/@conscia-labs/design-system).
8
+ >
9
+ > **v1.0.0:** this README documents the clean-break v1 contract. The repository is now preparing the `1.0.0` release candidate for publication through the Phase 8 workflow.
10
+ >
11
+ > **Migration:** upgrading an application to v1? Follow the [Design System v1 Migration Guide](https://github.com/conscia-labs/design-system/blob/main/docs/design-system-v1-migration.md).
8
12
 
9
13
  ## Why this package exists
10
14
 
@@ -32,6 +36,19 @@ Use the design system to:
32
36
 
33
37
  Product applications remain responsible for routing, authentication, permissions, data fetching, mutations, validation, and business-specific behavior.
34
38
 
39
+ ## Migrating to v1.0.0
40
+
41
+ Version `1.0.0` is a clean API and implementation break. Component concepts and
42
+ public names remain recognizable, but Radix and shadcn implementation details
43
+ are no longer part of the contract. In particular:
44
+
45
+ - Replace `asChild` with the documented `render` prop where custom-host composition is required.
46
+ - Replace legacy token utilities such as `bg-primary`, `bg-muted`, and `border-input` with the canonical Conscia semantic roles documented in the migration guide.
47
+ - Do not add `@base-ui/react`, `@radix-ui/*`, or copied shadcn components to the application; Base UI is bundled and used internally by the design system.
48
+ - Recheck dialogs, sheets, menus, selects, comboboxes, tabs, tooltips, forms, tables, and icon-only actions against the application’s keyboard and accessibility tests.
49
+
50
+ The complete, agent-readable upgrade runbook is [`docs/design-system-v1-migration.md`](./docs/design-system-v1-migration.md) in this repository. You can also open the [migration guide on GitHub](https://github.com/conscia-labs/design-system/blob/main/docs/design-system-v1-migration.md). The guide is intentionally kept in the repository’s `docs/` directory rather than the npm tarball, so the GitHub link is the durable location for app owners and coding agents.
51
+
35
52
  ## What is included
36
53
 
37
54
  ### Foundation
@@ -46,12 +63,15 @@ Semantic CSS variables for:
46
63
 
47
64
  ### Primitives
48
65
 
49
- Reusable interface building blocks composed from React, Radix UI, and ShadCN conventions:
66
+ Reusable Conscia-owned interface building blocks composed from native React
67
+ markup and Base UI behavior where interaction complexity requires it:
50
68
 
51
69
  - Alert
70
+ - AlertDialog
52
71
  - Avatar
53
72
  - Badge
54
73
  - Button
74
+ - IconButton
55
75
  - Card
56
76
  - Checkbox
57
77
  - Collapsible
@@ -59,13 +79,19 @@ Reusable interface building blocks composed from React, Radix UI, and ShadCN con
59
79
  - Dropdown menu
60
80
  - Field and form controls
61
81
  - Input and textarea
62
- - Select and searchable select
82
+ - Select, FormSelect, and searchable select
63
83
  - Sheet
64
84
  - Skeleton
65
85
  - Switch
66
86
  - Table
67
87
  - Tabs and navigation tabs
68
88
  - Tooltip
89
+ - Popover
90
+ - Shortcut hint
91
+ - Spinner
92
+ - Avatar group
93
+ - Filter chip
94
+ - Toast provider and viewport
69
95
 
70
96
  ### Patterns
71
97
 
@@ -80,21 +106,75 @@ Higher-level compositions for recurring product workflows:
80
106
  - Empty, loading, and error states
81
107
  - Activity lists and metric bands
82
108
  - Code blocks and value meters
109
+ - Command palette
110
+ - Filter bar
111
+
112
+ ### Supporting interaction patterns
113
+
114
+ #### Command palette
115
+
116
+ `CommandPalette` accepts an explicit list of commands, filters labels and
117
+ keywords, and supports keyboard navigation without a global command registry:
118
+
119
+ ```tsx
120
+ import { Button, CommandPalette } from "@conscia-labs/design-system";
121
+
122
+ <CommandPalette
123
+ items={[{ id: "settings", label: "Open settings", keywords: ["preferences"] }]}
124
+ onSelect={(item) => openCommand(item.id)}
125
+ trigger={<Button variant="outline">Open commands</Button>}
126
+ />
127
+ ```
128
+
129
+ #### Toasts
130
+
131
+ Toasts are opt-in. Mount one provider and viewport, then use `useToast` from a
132
+ descendant component:
133
+
134
+ ```tsx
135
+ import {
136
+ Button,
137
+ ToastProvider,
138
+ ToastViewport,
139
+ useToast,
140
+ } from "@conscia-labs/design-system";
141
+
142
+ function SaveButton() {
143
+ const { add } = useToast();
144
+ return (
145
+ <Button onClick={() => add({ title: "Saved", variant: "success" })}>
146
+ Save
147
+ </Button>
148
+ );
149
+ }
150
+
151
+ function App() {
152
+ return (
153
+ <ToastProvider>
154
+ <SaveButton />
155
+ <ToastViewport />
156
+ </ToastProvider>
157
+ );
158
+ }
159
+ ```
83
160
 
84
161
  ## Quick start
85
162
 
86
163
  ### 1. Install the package
87
164
 
165
+ For the v1 release, install the explicit `1.0.0` range after Phase 8 publishes
166
+ the package.
167
+
88
168
  Using pnpm:
89
169
 
90
170
  ```bash
91
- pnpm add @conscia-labs/design-system
171
+ pnpm add @conscia-labs/design-system@^1.0.0
92
172
  ```
93
173
 
94
174
  Using npm:
95
175
 
96
176
  ```bash
97
- npm install @conscia-labs/design-system
177
+ npm install @conscia-labs/design-system@^1.0.0
98
178
  ```
99
179
 
100
180
  The package targets React 19 and ships as modern ESM with TypeScript
@@ -413,6 +493,20 @@ lockups, collapsed navigation identity, and other shared brand placements.
413
493
  The icon is decorative by default. Add an `aria-label` when the mark conveys
414
494
  meaning without adjacent text, and use `className` to control its size.
415
495
 
496
+ ### BrandWordmark
497
+
498
+ `BrandWordmark` is the shared no-tagline Conscia lockup. It embeds the supplied
499
+ 496×113 vector geometry and uses `currentColor`, so applications do not need
500
+ separate black and white assets or runtime asset paths. The default treatment
501
+ matches `BrandIcon`: foreground in light mode and white in dark mode.
502
+
503
+ The wordmark is decorative by default. Add an `aria-label` when it is the only
504
+ accessible naming content, and use `className` to control its width.
505
+
506
+ ```tsx
507
+ <BrandWordmark aria-label="Conscia" className="w-36" />
508
+ ```
509
+
416
510
  ### Sidebar variants and semantic surfaces
417
511
 
418
512
  `AppSidebar` keeps the historical dark treatment by default. Consumers that
@@ -432,14 +526,12 @@ an explicitly light sidebar.
432
526
  </AppShell>
433
527
  ```
434
528
 
435
- The default is intentionally backwards compatible. The sidebar scope exposes
436
- reusable semantic aliases for its canvas, header, content, hover, active,
437
- search, footer, text, icon, group label, count, border, and focus-ring roles.
529
+ The sidebar scope exposes reusable semantic roles for its canvas, header,
530
+ content, hover, active, search, footer, text, icon, group label, count,
531
+ border, and focus-ring roles.
438
532
  Use the generated utilities such as `bg-sidebar-canvas`,
439
533
  `bg-sidebar-hover`, `text-sidebar-primary-text`, and
440
534
  `text-sidebar-metadata-text` in shared or application-owned compositions.
441
- Legacy aliases including `bg-sidebar`, `bg-sidebar-accent`, and
442
- `text-sidebar-foreground` remain supported.
443
535
 
444
536
  Form controls and outline buttons use `bg-surface-control`, with
445
537
  `bg-surface-control-hover` for the outline hover state. These semantic surfaces
@@ -458,16 +550,16 @@ Dark mode uses a calm charcoal surface ladder rather than a pure-black canvas:
458
550
 
459
551
  | Role | Token | Dark value |
460
552
  | --- | --- | --- |
461
- | Application canvas | `--background` / `--canvas` | `#17191c` |
462
- | Standard surface | `--card` / `--surface` | `#1d2024` |
553
+ | Application canvas | `--canvas` | `#17191c` |
554
+ | Standard surface | `--surface` | `#1d2024` |
463
555
  | Raised surface and control | `--surface-raised` / `--surface-control` | `#24272c` |
464
556
  | Muted and control-hover surface | `--surface-muted` / `--surface-control-hover` | `#282b31` |
465
- | Floating surface | `--surface-floating` / `--popover` | `#2c2f36` |
557
+ | Floating surface | `--surface-floating` | `#2c2f36` |
466
558
  | Overlay surface | `--surface-overlay` | `#31343a` |
467
559
 
468
560
  The adjacent steps are intentionally close enough for a calm reading
469
561
  environment while remaining distinguishable through luminance, borders, and
470
- elevation. `--foreground` is a soft high-priority text role (`#eff1f4`), while
562
+ elevation. `--text-primary` is a soft high-priority text role (`#eff1f4`), while
471
563
  `--text-secondary`, `--text-supporting`, and `--text-muted` step down to
472
564
  `#d4d8df`, `#b3bac5`, and `#929aa7`. Use the semantic `bg-surface-*` and
473
565
  `text-*` utilities instead of copying these values into an application. The
@@ -576,7 +668,7 @@ Color communicates meaning rather than palette choice:
576
668
  | --- | --- |
577
669
  | `brand` | Conscia identity and signature moments |
578
670
  | `brand-secondary` | Supporting brand expression |
579
- | `primary` | The primary next action |
671
+ | `action-*` | Primary actions and their hover, active, foreground, and tinted-background roles |
580
672
  | `selection-*` | Current selection or active destination |
581
673
  | `information-*` | Informational messages and evidence |
582
674
  | `success-*` | Healthy, verified, approved, or completed states |
@@ -606,7 +698,7 @@ Prefer semantic variables over component-specific descendant selectors. This kee
606
698
 
607
699
  Accessibility is part of the component contract:
608
700
 
609
- - Radix-backed components provide keyboard interaction and focus management.
701
+ - Base UI-backed components provide keyboard interaction and focus management.
610
702
  - Route-backed navigation uses semantic links and `aria-current`.
611
703
  - Dialogs and sheets provide labelled modal structure.
612
704
  - Form controls expose native labelling and validation attributes.
@@ -689,23 +781,45 @@ Reusable foundation, primitive, and pattern code belongs in `src`. Fixtures and
689
781
 
690
782
  ## Releasing
691
783
 
692
- Releases are published from GitHub Actions through npm trusted publishing. The
693
- release tag must exactly match the version in `package.json`.
784
+ The `1.0.0` release is the first public v1 package. Releases are published from
785
+ GitHub Actions through npm trusted publishing, with the release tag required to
786
+ match the version in `package.json` exactly. npm’s trusted-publishing flow
787
+ provides short-lived CI authentication and provenance for the published
788
+ package.
789
+
790
+ Before creating the v1 release tag, complete the release checklist in the
791
+ [migration ledger](./docs/base-ui-migration.md), finalize the
792
+ [app-owner migration guide](./docs/design-system-v1-migration.md), and run the
793
+ full local validation suite:
794
+
795
+ ```bash
796
+ pnpm lint
797
+ pnpm lint:playground
798
+ pnpm typecheck
799
+ pnpm typecheck:playground
800
+ pnpm test
801
+ pnpm test:package
802
+ pnpm test:consumer
803
+ pnpm build:playground
804
+ pnpm test:visual
805
+ ```
694
806
 
695
- For example, to publish the next patch:
807
+ Then prepare and tag the release:
696
808
 
697
809
  ```bash
698
- pnpm version patch --no-git-tag-version
699
- git add package.json
700
- git commit -m "Release v0.2.1"
701
- git tag -a v0.2.1 -m "Release v0.2.1"
810
+ pnpm version 1.0.0 --no-git-tag-version
811
+ git add package.json README.md docs/base-ui-migration.md docs/design-system-v1-migration.md
812
+ git commit -m "Release v1.0.0"
813
+ git tag -a v1.0.0 -m "Release v1.0.0"
702
814
  git push origin main
703
- git push origin v0.2.1
815
+ git push origin v1.0.0
704
816
  ```
705
817
 
706
- Pushing the tag starts the `npm-production` release workflow. The
707
- workflow verifies the tag, runs the package tests, builds the publishable
708
- artifacts, and publishes without a long-lived npm token.
818
+ Pushing the tag starts the `npm-production` release workflow. The workflow
819
+ verifies that `v1.0.0` matches `package.json`, runs the release validation, and
820
+ publishes the package to npm without a long-lived npm token. Because this is a
821
+ scoped public package, the release configuration must retain public access;
822
+ see npm’s [scoped-package publishing guidance](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages/).
709
823
 
710
824
  ## Design-system boundaries
711
825
 
@@ -0,0 +1,49 @@
1
+ import * as class_variance_authority_types from 'class-variance-authority/types';
2
+ import * as React from 'react';
3
+ import { useRender } from '@base-ui/react/use-render';
4
+ import { VariantProps } from 'class-variance-authority';
5
+
6
+ declare const buttonVariants: (props?: ({
7
+ variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
8
+ size?: "default" | "sm" | "lg" | "icon" | null | undefined;
9
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
10
+ type ButtonProps = React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
11
+ render?: useRender.ComponentProps<"button">["render"];
12
+ };
13
+ declare function Button({ className, variant, size, render, type, ...props }: ButtonProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
14
+ type IconButtonNameProps = {
15
+ "aria-label": string;
16
+ "aria-labelledby"?: string;
17
+ } | {
18
+ "aria-label"?: string;
19
+ "aria-labelledby": string;
20
+ };
21
+ type IconButtonProps = Omit<ButtonProps, "children" | "size" | "aria-label" | "aria-labelledby"> & IconButtonNameProps & {
22
+ children: React.ReactNode;
23
+ size?: "sm" | "default" | "lg";
24
+ };
25
+ declare function IconButton({ className, size, ...props }: IconButtonProps): React.JSX.Element;
26
+
27
+ declare function Input({ className, type, ...props }: React.ComponentProps<"input">): React.JSX.Element;
28
+
29
+ type SeparatorProps = React.ComponentProps<"div"> & {
30
+ decorative?: boolean;
31
+ orientation?: "horizontal" | "vertical";
32
+ };
33
+ declare function Separator({ className, orientation, decorative, role, ...props }: SeparatorProps): React.JSX.Element;
34
+
35
+ declare const cardVariants: (props?: ({
36
+ variant?: "default" | "muted" | "elevated" | null | undefined;
37
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
38
+ type CardProps = React.ComponentProps<"div"> & VariantProps<typeof cardVariants>;
39
+ declare function Card({ className, variant, ...props }: CardProps): React.JSX.Element;
40
+ type CardHeaderProps = React.ComponentProps<"div"> & {
41
+ action?: React.ReactNode;
42
+ };
43
+ declare function CardHeader({ action, children, className, ...props }: CardHeaderProps): React.JSX.Element;
44
+ declare function CardTitle({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
45
+ declare function CardDescription({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
46
+ declare function CardContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
47
+ declare function CardFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
48
+
49
+ export { Button as B, Card as C, IconButton as I, Separator as S, type ButtonProps as a, CardContent as b, CardDescription as c, CardFooter as d, CardHeader as e, type CardHeaderProps as f, type CardProps as g, CardTitle as h, type IconButtonProps as i, Input as j, type SeparatorProps as k, buttonVariants as l, cardVariants as m };