canvas-ui-sdk 0.3.13 → 0.3.14

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
@@ -1,6 +1,6 @@
1
1
  # Canvas UI SDK
2
2
 
3
- A comprehensive UI component library with design tokens for building beautiful interfaces.
3
+ A themeable React component library with a shadcn-style CLI for copying components into consumer projects, a visual theme editor, and an MCP server for Claude Code.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,57 +8,34 @@ A comprehensive UI component library with design tokens for building beautiful i
8
8
  npm install canvas-ui-sdk
9
9
  ```
10
10
 
11
- ## Usage
11
+ ## CLI
12
12
 
13
- ```tsx
14
- import { Button, DashboardShell, DataTable } from 'canvas-ui-sdk';
15
-
16
- export default function MyPage() {
17
- return (
18
- <DashboardShell>
19
- <Button variant="primary">Click me</Button>
20
- <DataTable data={myData} columns={myColumns} />
21
- </DashboardShell>
22
- );
23
- }
24
- ```
13
+ Components are copied as editable source files into your project. Dependencies are auto-resolved and npm packages auto-installed.
25
14
 
26
- ## CSS Variables
15
+ ```bash
16
+ # See all 140+ available components
17
+ npx canvas-ui list
27
18
 
28
- This SDK uses CSS custom properties (variables) for theming. Define these in your project's `globals.css`:
19
+ # Copy components into your project
20
+ npx canvas-ui add <component-name>
29
21
 
30
- ```css
31
- :root {
32
- /* Colors */
33
- --canvas-primary: #2563eb;
34
- --canvas-secondary: #64748b;
35
- --canvas-background: #ffffff;
36
- --canvas-foreground: #0f172a;
37
- --canvas-border: #e2e8f0;
38
-
39
- /* Typography */
40
- --typo-font-primary: 'Inter', sans-serif;
41
- --typo-base-size: 16px;
42
-
43
- /* Spacing */
44
- --spacing-xs: 4px;
45
- --spacing-sm: 8px;
46
- --spacing-md: 16px;
47
- --spacing-lg: 24px;
48
- --spacing-xl: 32px;
49
-
50
- /* Border Radius */
51
- --radius-sm: 4px;
52
- --radius-md: 8px;
53
- --radius-lg: 12px;
54
- }
22
+ # Examples:
23
+ npx canvas-ui add button # Copies button + utils
24
+ npx canvas-ui add dashboard-shell # Copies shell + sidebar + header + 15 deps
25
+ npx canvas-ui add standard-data-table # Copies table + pagination + deps
55
26
  ```
56
27
 
57
- See `styles/tokens.reference.css` for a complete list of available CSS variables.
28
+ Then import from local paths:
58
29
 
59
- ## Tailwind v4
30
+ ```tsx
31
+ import { DashboardShell } from "@/components/layout/dashboard-shell";
32
+ import { StandardDataTable } from "@/components/blocks/data-tables/standard-data-table";
33
+ import { Button } from "@/components/ui/button";
34
+ ```
60
35
 
61
- If you're using Tailwind CSS v4, add these imports to your CSS file:
36
+ ## CSS Setup
37
+
38
+ Add these imports to your `globals.css` (Tailwind v4):
62
39
 
63
40
  ```css
64
41
  @import "tailwindcss";
@@ -67,43 +44,53 @@ If you're using Tailwind CSS v4, add these imports to your CSS file:
67
44
  @source "../../node_modules/canvas-ui-sdk/dist";
68
45
  ```
69
46
 
70
- - `canvas-ui-sdk/tailwind` maps the SDK's design tokens to Tailwind's semantic color names (`bg-muted`, `text-primary`, etc.)
47
+ - `canvas-ui-sdk/tailwind` maps design tokens to Tailwind's semantic color names (`bg-muted`, `text-primary`, etc.)
48
+ - `canvas-ui-sdk/styles` loads the design system's CSS variables (colors, typography, spacing, etc.)
71
49
  - `@source` tells Tailwind to scan the SDK's compiled output for utility classes — adjust the relative path based on your `globals.css` location
72
50
 
51
+ ## CSS Variables
52
+
53
+ Override design tokens in your `globals.css`:
54
+
55
+ ```css
56
+ :root {
57
+ --canvas-primary: #16a34a;
58
+ --canvas-primary-dark: #15803d;
59
+ --canvas-primary-foreground: #ffffff;
60
+ }
61
+ ```
62
+
63
+ See `styles/tokens.reference.css` for the full list of available CSS variables.
64
+
65
+ ## MCP Server (Claude Code)
66
+
67
+ Connect the MCP server so Claude Code can discover all components, templates, and design tokens:
68
+
69
+ ```bash
70
+ claude mcp add canvas-ui-sdk node node_modules/canvas-ui-sdk/mcp/dist/index.js
71
+ ```
72
+
73
+ ## Live Theme Editor
74
+
75
+ The `<ThemeDrawer>` component provides a visual editor for customizing colors, typography, button sizes, input styles, and branding in real-time. When you're happy with your theme, bake it into source code with `prompts/bake-theme.md`.
76
+
73
77
  ## Components
74
78
 
75
- ### UI Components
76
- - Button, Input, Select, Checkbox, Switch
77
- - Dialog, Popover, Dropdown
78
- - Avatar, Badge, Card
79
- - And more...
79
+ ### UI Primitives
80
+ Button, Input, Select, Checkbox, Switch, Dialog, Popover, Dropdown, Avatar, Tabs, Tooltip, and more.
80
81
 
81
82
  ### Blocks
82
- - DataTable, ChatBubble, ProfileCard
83
- - Marketing sections (Hero, Testimonials, CTA)
84
- - Pricing components
85
- - Graph and metric tiles
86
-
87
- ### Layouts
88
- - DashboardShell
89
- - IconSidebarShell
90
- - DoubleSidebarShell
91
- - StandardPageShell
92
- - AccountSettingsShell
93
- - MultistepShell
94
- - MobileMenuShell
83
+ Data tables, social feeds, charts, metric tiles, chat widgets, forms, calendars, and more.
84
+
85
+ ### Layout Shells
86
+ DashboardShell, IconSidebarShell, DoubleSidebarShell, StandardPageShell, AccountSettingsShell, MultistepShell, MobileMenuShell.
95
87
 
96
88
  ## Development
97
89
 
98
90
  ```bash
99
- # Install dependencies
100
- npm install
101
-
102
- # Build the package
103
- npm run build
104
-
105
- # Watch mode for development
106
- npm run dev
91
+ npm install # Install dependencies
92
+ npm run build # Build dist + registry + CLI
93
+ npm run dev # Watch mode
107
94
  ```
108
95
 
109
96
  ## License
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvas-ui-sdk",
3
- "version": "0.3.13",
3
+ "version": "0.3.14",
4
4
  "type": "module",
5
5
  "description": "A comprehensive UI component library with design tokens for building beautiful interfaces",
6
6
  "bin": {
@@ -30,7 +30,8 @@
30
30
  "dist",
31
31
  "styles",
32
32
  "registry",
33
- "mcp/dist"
33
+ "mcp/dist",
34
+ "prompts"
34
35
  ],
35
36
  "scripts": {
36
37
  "build": "tsup && node -e \"const fs = require('fs'); for (const f of ['dist/index.js','dist/charts.js']) { const c = fs.readFileSync(f,'utf8'); fs.writeFileSync(f, '\\\"use client\\\";\\n' + c); }\" && npm run cli:build",
@@ -0,0 +1,85 @@
1
+ # Canvas Consumer App
2
+
3
+ This is a Next.js app that uses the Canvas UI SDK component library.
4
+
5
+ ## Adding Components
6
+
7
+ This project uses a **shadcn-style CLI** to copy component source files from `canvas-ui-sdk` into the project for full customization.
8
+
9
+ ### Available commands
10
+
11
+ ```bash
12
+ # See all available components (145 total: layouts, blocks, UI primitives, hooks)
13
+ npx canvas-ui list
14
+
15
+ # Copy components into the project (auto-resolves dependencies)
16
+ npx canvas-ui add <component-name> [component-name...]
17
+
18
+ # Examples:
19
+ npx canvas-ui add button # Copies button + utils
20
+ npx canvas-ui add dashboard-shell # Copies shell + sidebar + header + 15 deps
21
+ npx canvas-ui add standard-data-table # Copies table + pagination + deps
22
+ ```
23
+
24
+ ### How it works
25
+
26
+ - Components are copied as **editable source files** into `src/components/`
27
+ - UI primitives go to `src/components/ui/`
28
+ - Layout shells go to `src/components/layout/`
29
+ - Block components go to `src/components/blocks/<category>/`
30
+ - Hooks go to `src/hooks/`
31
+ - Utilities go to `src/lib/`
32
+ - Import paths use `@/` aliases (e.g. `@/components/ui/button`, `@/lib/utils`)
33
+ - npm dependencies (like `@radix-ui/*`, `class-variance-authority`) are auto-installed
34
+
35
+ ### When building a page
36
+
37
+ 1. Decide which layout shell fits (run `npx canvas-ui list` to see options)
38
+ 2. Add the layout: `npx canvas-ui add <shell-name>`
39
+ 3. Add any blocks needed: `npx canvas-ui add <block-name> [block-name...]`
40
+ 4. Import components from their local paths (e.g. `import { Button } from "@/components/ui/button"`)
41
+ 5. Customize the copied source files as needed
42
+
43
+ ### What stays in the npm package (do NOT copy these)
44
+
45
+ - Design tokens / CSS variables (`canvas-ui-sdk/styles`)
46
+ - Tailwind theme mappings (`canvas-ui-sdk/tailwind`)
47
+ - Theme context and providers (`canvas-ui-sdk`)
48
+
49
+ These are imported directly from the npm package, not copied.
50
+
51
+ ## Design Tokens
52
+
53
+ When creating or modifying components, always use the canvas design token CSS variables. Never use raw Tailwind color classes (`bg-white`, `text-gray-500`, `border-gray-200`) or hardcoded pixel values for font sizes. Use the token system instead:
54
+
55
+ - **Colors**: `var(--canvas-background)`, `var(--canvas-text)`, `var(--canvas-primary)`, `var(--canvas-border)`, etc.
56
+ - **Typography**: `var(--typo-body-s-size)`, `var(--typo-body-m-size)`, `var(--typo-h4-size)`, `var(--typo-global-font)`, etc.
57
+ - **Spacing**: `var(--spacing-sm)`, `var(--spacing-md)`, `var(--spacing-lg)`, etc.
58
+ - **Radii**: `var(--radius-xs)`, `var(--radius-sm)`, `var(--radius-md)`, etc.
59
+ - **Inputs**: `var(--canvas-border-input)`, `var(--input-standard-height)`, `var(--input-standard-radius)`, etc.
60
+ - **Buttons**: `var(--btn-primary-bg)`, `var(--btn-standard-height)`, etc.
61
+
62
+ Reference the SDK's `styles/tokens.reference.css` for the full list of available tokens.
63
+
64
+ ## CSS Setup
65
+
66
+ The app's `src/app/globals.css` imports:
67
+ ```css
68
+ @import "tailwindcss";
69
+ @import "canvas-ui-sdk/tailwind";
70
+ @import "canvas-ui-sdk/styles";
71
+ @source "../../node_modules/canvas-ui-sdk/dist";
72
+ ```
73
+
74
+ ## Project Structure
75
+
76
+ ```
77
+ src/
78
+ app/ # Next.js app router pages
79
+ components/ # Copied Canvas UI components (editable)
80
+ ui/ # Primitives (button, input, dialog, etc.)
81
+ layout/ # Layout shells (dashboard-shell, sidebar, etc.)
82
+ blocks/ # Feature blocks (data-tables, forms, cards, etc.)
83
+ hooks/ # Copied hooks
84
+ lib/ # Utilities (utils.ts with cn() helper)
85
+ ```
@@ -0,0 +1,194 @@
1
+ # Bake Theme Into Source Code
2
+
3
+ ## What this does
4
+
5
+ Reads the saved theme from `.data/theme.json` and applies it as source-code defaults
6
+ so the app loads with the correct styling on first paint — no flash of unstyled content.
7
+
8
+ After baking, `.data/theme.json` is deleted and the ThemeDrawer starts fresh.
9
+
10
+ ---
11
+
12
+ ## Steps
13
+
14
+ ### 1. Read the saved theme
15
+
16
+ Read `.data/theme.json`. It has this shape:
17
+
18
+ ```json
19
+ {
20
+ "overrides": { "--canvas-primary": "#ee4c11", "--typo-global-font": "Lato", ... },
21
+ "branding": { "iconShape": "rounded", "iconName": "WifiHigh", ... },
22
+ "images": { "logoLight": "", "logoDark": "", ... },
23
+ "customButtonStyles": []
24
+ }
25
+ ```
26
+
27
+ If the file doesn't exist or is empty, stop — there's nothing to bake.
28
+
29
+ ### 2. Update `src/app/globals.css`
30
+
31
+ For each entry in `overrides`, add or update the CSS variable in the correct block:
32
+
33
+ | Variable pattern | Block | Notes |
34
+ |-----------------|-------|-------|
35
+ | `--canvas-*` (colors) | `:root { }` | e.g. `--canvas-primary: #ee4c11;` |
36
+ | `--typo-*-size`, `--typo-*-weight`, `--typo-*-spacing`, `--typo-*-height` | `body { }` | e.g. `--typo-menu-label-size: 40;` |
37
+ | `--typo-global-font` | `body { }` | Set as: `--typo-global-font: var(--font-FONTNAME), "FontName", sans-serif;` where FONTNAME is the lowercased, hyphenated font name. Also update the existing `--typo-global-font` line if present. |
38
+ | `--typo-*-font` (per-component) | `body { }` | Only if the value is a real font name (not empty). Set as: `--typo-COMPONENT-font: "FontName", sans-serif;`. Remove the corresponding `--typo-*-font: initial;` line from `:root` if present. |
39
+ | `--btn-*` (button styles) | `body { }` | e.g. `--btn-border-radius: 8;` |
40
+
41
+ **Important:** Keep any existing variables that aren't in the overrides. Only add/update the ones from the saved theme.
42
+
43
+ ### 3. Add Google Font imports in `src/app/layout.tsx`
44
+
45
+ For each unique font name found in the overrides (values of `--typo-*-font` variables):
46
+
47
+ 1. Add an import from `next/font/google` at the top of the file:
48
+ ```typescript
49
+ import { ExistingFont, NewFont } from "next/font/google";
50
+ ```
51
+
52
+ 2. Create the font instance:
53
+ ```typescript
54
+ const newFont = NewFont({
55
+ variable: "--font-new-font",
56
+ subsets: ["latin"],
57
+ weight: ["400", "500", "600", "700"],
58
+ });
59
+ ```
60
+
61
+ 3. Add the font's variable class to the `<body>` className:
62
+ ```typescript
63
+ <body className={`${existingFont.variable} ${newFont.variable} antialiased`}>
64
+ ```
65
+
66
+ **Variable naming convention:** The CSS variable name is `--font-` followed by the font name in lowercase with spaces replaced by hyphens. For example, "Open Sans" becomes `--font-open-sans`.
67
+
68
+ **Keep existing fonts.** Don't remove Inter, Geist, or Geist_Mono — they're still needed.
69
+
70
+ ### 4. Update `src/lib/theme-config.ts`
71
+
72
+ Write the `branding` and `images` objects from the saved theme into this file:
73
+
74
+ ```typescript
75
+ import type { BrandingState, ImageKey } from "canvas-ui-sdk";
76
+
77
+ export const savedBranding: BrandingState = {
78
+ // paste values from theme.json branding
79
+ };
80
+
81
+ export const savedImages: Record<ImageKey, string> = {
82
+ // paste values from theme.json images
83
+ };
84
+ ```
85
+
86
+ ### 5. Delete the saved theme file
87
+
88
+ Remove `.data/theme.json` — the overrides are now baked into the source code.
89
+
90
+ ```bash
91
+ rm .data/theme.json
92
+ ```
93
+
94
+ ### 6. Verify
95
+
96
+ Run `npm run dev` and confirm:
97
+ - The page loads with the correct colors, fonts, and branding on first paint
98
+ - No flash of default styles
99
+ - The theme drawer opens with no unsaved changes
100
+
101
+ ---
102
+
103
+ ## Example
104
+
105
+ Given this `.data/theme.json`:
106
+
107
+ ```json
108
+ {
109
+ "overrides": {
110
+ "--canvas-primary": "#ee4c11",
111
+ "--canvas-primary-dark": "#772609",
112
+ "--typo-global-font": "Lato",
113
+ "--typo-menu-label-font": "Open Sans",
114
+ "--typo-menu-label-size": "40",
115
+ "--typo-menu-label-weight": "700"
116
+ },
117
+ "branding": {
118
+ "iconShape": "rounded",
119
+ "iconName": "WifiHigh",
120
+ "bgColor": "var(--canvas-primary)",
121
+ "iconColor": "var(--canvas-primary-foreground)",
122
+ "wordmark": "ohhh"
123
+ },
124
+ "images": {
125
+ "logoLight": "",
126
+ "logoDark": "",
127
+ "faviconLight": "",
128
+ "faviconDark": ""
129
+ },
130
+ "customButtonStyles": []
131
+ }
132
+ ```
133
+
134
+ **globals.css** `:root` block gets:
135
+ ```css
136
+ :root {
137
+ --canvas-primary: #ee4c11;
138
+ --canvas-primary-dark: #772609;
139
+ /* ... keep other existing variables ... */
140
+
141
+ /* Remove --typo-menu-label-font: initial; since it now has a real value */
142
+ }
143
+ ```
144
+
145
+ **globals.css** `body` block gets:
146
+ ```css
147
+ body {
148
+ --typo-global-font: var(--font-lato), "Lato", sans-serif;
149
+ --typo-menu-label-font: "Open Sans", sans-serif;
150
+ --typo-menu-label-size: 40;
151
+ --typo-menu-label-weight: 700;
152
+ /* ... keep existing body styles ... */
153
+ }
154
+ ```
155
+
156
+ **layout.tsx** gets new font imports:
157
+ ```typescript
158
+ import { Inter, Geist, Geist_Mono, Lato, Open_Sans } from "next/font/google";
159
+
160
+ const lato = Lato({
161
+ variable: "--font-lato",
162
+ subsets: ["latin"],
163
+ weight: ["400", "700"],
164
+ });
165
+
166
+ const openSans = Open_Sans({
167
+ variable: "--font-open-sans",
168
+ subsets: ["latin"],
169
+ weight: ["400", "500", "600", "700"],
170
+ });
171
+
172
+ // In the body className:
173
+ <body className={`${inter.variable} ${geistSans.variable} ${geistMono.variable} ${lato.variable} ${openSans.variable} antialiased`}>
174
+ ```
175
+
176
+ **theme-config.ts** gets:
177
+ ```typescript
178
+ import type { BrandingState, ImageKey } from "canvas-ui-sdk";
179
+
180
+ export const savedBranding: BrandingState = {
181
+ iconShape: "rounded",
182
+ iconName: "WifiHigh",
183
+ bgColor: "var(--canvas-primary)",
184
+ iconColor: "var(--canvas-primary-foreground)",
185
+ wordmark: "ohhh",
186
+ };
187
+
188
+ export const savedImages: Record<ImageKey, string> = {
189
+ logoLight: "",
190
+ logoDark: "",
191
+ faviconLight: "",
192
+ faviconDark: "",
193
+ };
194
+ ```