canon-ds 0.1.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/LICENSE +21 -0
- package/README.md +153 -0
- package/THIRD_PARTY_NOTICES.md +55 -0
- package/bin/canon.js +6 -0
- package/lib/build-manifest.mjs +54 -0
- package/lib/build.mjs +69 -0
- package/lib/cli.mjs +273 -0
- package/lib/color.js +160 -0
- package/lib/components/_shared.mjs +93 -0
- package/lib/components/accordion.mjs +136 -0
- package/lib/components/account-card.mjs +166 -0
- package/lib/components/activity-feed.mjs +176 -0
- package/lib/components/activity-gauge.mjs +98 -0
- package/lib/components/agent-presence.mjs +156 -0
- package/lib/components/alert.mjs +154 -0
- package/lib/components/app-store-button.mjs +108 -0
- package/lib/components/avatar-group.mjs +128 -0
- package/lib/components/avatar.mjs +225 -0
- package/lib/components/badge-group.mjs +55 -0
- package/lib/components/badge.mjs +174 -0
- package/lib/components/banner.mjs +116 -0
- package/lib/components/breadcrumb.mjs +170 -0
- package/lib/components/button-group.mjs +114 -0
- package/lib/components/button.mjs +197 -0
- package/lib/components/card-header.mjs +115 -0
- package/lib/components/card.mjs +106 -0
- package/lib/components/carousel.mjs +182 -0
- package/lib/components/chart-frame.mjs +101 -0
- package/lib/components/checkbox.mjs +163 -0
- package/lib/components/close-button.mjs +49 -0
- package/lib/components/code.mjs +123 -0
- package/lib/components/color-picker.mjs +122 -0
- package/lib/components/combobox.mjs +210 -0
- package/lib/components/command-palette.mjs +226 -0
- package/lib/components/content-divider.mjs +104 -0
- package/lib/components/counter.mjs +86 -0
- package/lib/components/credit-card.mjs +126 -0
- package/lib/components/date-picker.mjs +202 -0
- package/lib/components/description-list.mjs +88 -0
- package/lib/components/dialog.mjs +140 -0
- package/lib/components/divider.mjs +115 -0
- package/lib/components/drawer.mjs +150 -0
- package/lib/components/empty-state.mjs +112 -0
- package/lib/components/featured-card.mjs +124 -0
- package/lib/components/featured-icon.mjs +67 -0
- package/lib/components/field.mjs +122 -0
- package/lib/components/file-dropzone.mjs +166 -0
- package/lib/components/filter-bar.mjs +179 -0
- package/lib/components/header-navigation.mjs +94 -0
- package/lib/components/icon-button.mjs +179 -0
- package/lib/components/index.mjs +52 -0
- package/lib/components/inline-cta.mjs +139 -0
- package/lib/components/input-group.mjs +164 -0
- package/lib/components/input.mjs +197 -0
- package/lib/components/kanban.mjs +179 -0
- package/lib/components/kbd.mjs +70 -0
- package/lib/components/kicker.mjs +79 -0
- package/lib/components/link.mjs +108 -0
- package/lib/components/list.mjs +117 -0
- package/lib/components/media-frame.mjs +119 -0
- package/lib/components/menu.mjs +190 -0
- package/lib/components/message.mjs +249 -0
- package/lib/components/metric-group.mjs +210 -0
- package/lib/components/mobile-header.mjs +173 -0
- package/lib/components/multi-select.mjs +218 -0
- package/lib/components/notification.mjs +175 -0
- package/lib/components/number-input.mjs +149 -0
- package/lib/components/page-header.mjs +68 -0
- package/lib/components/pagination.mjs +236 -0
- package/lib/components/pin-input.mjs +120 -0
- package/lib/components/popover.mjs +126 -0
- package/lib/components/progress-circle.mjs +115 -0
- package/lib/components/progress.mjs +93 -0
- package/lib/components/prose.mjs +96 -0
- package/lib/components/radio.mjs +160 -0
- package/lib/components/rating.mjs +93 -0
- package/lib/components/rich-text-editor.mjs +178 -0
- package/lib/components/section-header.mjs +62 -0
- package/lib/components/segmented-control.mjs +121 -0
- package/lib/components/select.mjs +163 -0
- package/lib/components/sidebar-nav.mjs +172 -0
- package/lib/components/sidebar.mjs +124 -0
- package/lib/components/skeleton.mjs +66 -0
- package/lib/components/slider.mjs +122 -0
- package/lib/components/social-button.mjs +119 -0
- package/lib/components/spinner.mjs +69 -0
- package/lib/components/stat.mjs +120 -0
- package/lib/components/stepper.mjs +228 -0
- package/lib/components/switch.mjs +159 -0
- package/lib/components/table.mjs +212 -0
- package/lib/components/tabs.mjs +207 -0
- package/lib/components/tag.mjs +196 -0
- package/lib/components/tags-input.mjs +146 -0
- package/lib/components/textarea.mjs +117 -0
- package/lib/components/timeline.mjs +135 -0
- package/lib/components/toast.mjs +115 -0
- package/lib/components/tooltip.mjs +86 -0
- package/lib/components/topbar.mjs +207 -0
- package/lib/components/tree-view.mjs +156 -0
- package/lib/components/video-player.mjs +189 -0
- package/lib/connect.mjs +110 -0
- package/lib/design-files.mjs +175 -0
- package/lib/distribution.mjs +109 -0
- package/lib/editor.js +940 -0
- package/lib/engine.js +339 -0
- package/lib/generators/agents.mjs +68 -0
- package/lib/generators/connection.md +58 -0
- package/lib/generators/css.mjs +2 -0
- package/lib/generators/designmd.mjs +324 -0
- package/lib/generators/documentation.css +82 -0
- package/lib/generators/documentation.html +81 -0
- package/lib/generators/documentation.js +96 -0
- package/lib/generators/documentation.mjs +35 -0
- package/lib/generators/dtcg.mjs +60 -0
- package/lib/generators/preview.css +279 -0
- package/lib/generators/preview.mjs +225 -0
- package/lib/generators/react.mjs +162 -0
- package/lib/generators/tailwind.mjs +114 -0
- package/lib/install.mjs +108 -0
- package/lib/lint.mjs +538 -0
- package/lib/mcp.mjs +268 -0
- package/lib/open.mjs +7 -0
- package/lib/patterns/_app.mjs +56 -0
- package/lib/patterns/app-shell.mjs +25 -0
- package/lib/patterns/audit-log.mjs +37 -0
- package/lib/patterns/auth-pages.mjs +44 -0
- package/lib/patterns/billing-page.mjs +39 -0
- package/lib/patterns/calendar-page.mjs +55 -0
- package/lib/patterns/dashboard-page.mjs +28 -0
- package/lib/patterns/files-page.mjs +30 -0
- package/lib/patterns/first-run.mjs +31 -0
- package/lib/patterns/form-layout.mjs +24 -0
- package/lib/patterns/inbox-page.mjs +58 -0
- package/lib/patterns/index.mjs +29 -0
- package/lib/patterns/list-detail-page.mjs +24 -0
- package/lib/patterns/mobile-app.mjs +46 -0
- package/lib/patterns/modal-flows.mjs +32 -0
- package/lib/patterns/onboarding-page.mjs +42 -0
- package/lib/patterns/permissions-page.mjs +38 -0
- package/lib/patterns/profile-page.mjs +32 -0
- package/lib/patterns/settings-page.mjs +24 -0
- package/lib/project.mjs +28 -0
- package/lib/serve.mjs +279 -0
- package/lib/system.mjs +210 -0
- package/lib/tokens/base.js +251 -0
- package/lib/tokens/canon-preset.mjs +67 -0
- package/lib/tokens/index.mjs +1 -0
- package/lib/tokens/legacy-canon.json +559 -0
- package/lib/tokens/presets.mjs +161 -0
- package/lib/tokens/resolve.mjs +1 -0
- package/lib/types.mjs +4 -0
- package/lib/version.mjs +2 -0
- package/package.json +54 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { CANON_BRAND, CANON_OVERRIDES } from "./canon-preset.mjs";
|
|
2
|
+
const NEVER_COMMON = [
|
|
3
|
+
'Generic "SaaS dashboard" layouts: a grid of identical cards with soft shadows and an icon in a colored circle.',
|
|
4
|
+
'Purple/blue gradients, glassmorphism, glowing borders, neon accents, floating blobs as decoration.',
|
|
5
|
+
'Raw hex/rgb/hsl colors, raw px sizes, or Tailwind palette classes (bg-blue-500) anywhere outside the token file.',
|
|
6
|
+
'Inventing a new component, variant, size or color when an existing one is listed in the spec.',
|
|
7
|
+
'Rounded-full pill buttons mixed with rounded-md buttons on the same screen; mixing radii.',
|
|
8
|
+
'Emoji as icons in product UI. Use the icon set defined in the spec.',
|
|
9
|
+
'Centered hero text with three feature cards below it as the default landing layout.',
|
|
10
|
+
'Placeholder copy such as "Lorem ipsum", "Feature 1", "Your company" in delivered UI.',
|
|
11
|
+
'More than one primary (filled action) button visible in the same view region.',
|
|
12
|
+
'Colored text for emphasis when weight, size or the kicker style would do.',
|
|
13
|
+
'Box-shadow on everything. Shadows are for floating layers; resting surfaces use a 1px hairline.',
|
|
14
|
+
];
|
|
15
|
+
export const PRESETS = {
|
|
16
|
+
canon: {
|
|
17
|
+
id: 'canon',
|
|
18
|
+
label: 'Canon (white, neutral greys, Vera pink accents, DM Sans)',
|
|
19
|
+
seeds: {
|
|
20
|
+
brand: CANON_BRAND,
|
|
21
|
+
neutralHue: 255,
|
|
22
|
+
neutralChroma: 0.003,
|
|
23
|
+
canvasLight: '#FFFFFF',
|
|
24
|
+
inkDark: '#151B21',
|
|
25
|
+
fontSans: '"DM Sans", system-ui, -apple-system, "Segoe UI", sans-serif',
|
|
26
|
+
fontMono: '"IBM Plex Mono", ui-monospace, "SF Mono", monospace',
|
|
27
|
+
radiusScale: 0.75,
|
|
28
|
+
baseFontSize: 14,
|
|
29
|
+
controlHeight: 40,
|
|
30
|
+
defaultTheme: 'light',
|
|
31
|
+
overrides: CANON_OVERRIDES,
|
|
32
|
+
},
|
|
33
|
+
direction: {
|
|
34
|
+
summary: 'Canon keeps a white canvas, neutral grey surfaces and familiar product layouts. Its character lives in the details: Vera’s orchid pink for actions, DM Sans, flat controls and compact corners. IBM Plex Mono labels technical details; a fine leading rule marks selection.',
|
|
35
|
+
principles: [
|
|
36
|
+
'Large surfaces stay white or neutral grey. Pink is a small action or selection detail; do not tint the page background.',
|
|
37
|
+
'Controls are 40px with 14px medium text and 6px corners. Use a flat fill or a single outline, without a bevel or resting shadow.',
|
|
38
|
+
'Cards have 10px corners and a hairline. Hover strengthens the edge; selection adds a leading rule. Reserve elevation for floating layers.',
|
|
39
|
+
'DM Sans for reading and headings; IBM Plex Mono for compact section labels, IDs and code. Product headings are 22–34px, with short, useful copy.',
|
|
40
|
+
'Navigation distinguishes hover from selection: quiet hover, a persistent line or solid segment for the current view. Do not turn every label into a pill.',
|
|
41
|
+
'Featured icons use a simple outlined frame with a small corner cut; avoid concentric rings. Use one only when it helps identify the block.',
|
|
42
|
+
'Focus uses a visible 3px ring in both themes. Dark surfaces use lighter pink actions with dark ink labels.',
|
|
43
|
+
],
|
|
44
|
+
never: [...NEVER_COMMON, 'Inset bevels, concentric icon halos or purple as the default brand palette.', 'A hover state that looks selected when it is not.', 'Low-contrast labels on either theme; check the foreground against its actual surface.'],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
editorial: {
|
|
48
|
+
id: 'editorial',
|
|
49
|
+
label: 'Editorial (neutral ink on paper, mono kickers)',
|
|
50
|
+
seeds: {
|
|
51
|
+
brand: '#1F1F1F',
|
|
52
|
+
neutralHue: 260,
|
|
53
|
+
neutralChroma: 0.004,
|
|
54
|
+
canvasLight: '#FAFAFA',
|
|
55
|
+
inkDark: '#171717',
|
|
56
|
+
radiusScale: 1,
|
|
57
|
+
baseFontSize: 14,
|
|
58
|
+
controlHeight: 36,
|
|
59
|
+
defaultTheme: 'light',
|
|
60
|
+
},
|
|
61
|
+
direction: {
|
|
62
|
+
summary: 'Quiet, precise, editorial. Ink on paper. One action color, hairline borders, generous whitespace, mono uppercase kickers as the signature. The UI should feel hand-fitted, not generated.',
|
|
63
|
+
principles: [
|
|
64
|
+
'Hierarchy through weight and size, not color. Color means something (action, status, brand) or it is not there.',
|
|
65
|
+
'One primary action per view. Everything else is secondary, ghost or a link.',
|
|
66
|
+
'1px hairlines separate; shadows only float (menus, dialogs). Resting cards do not cast shadows.',
|
|
67
|
+
'Density follows the job: tables and lists are dense (body-sm, 8px vertical rhythm); reading surfaces are airy (body-lg, 24–32px rhythm).',
|
|
68
|
+
'Motion is short (120–260ms) and only confirms an interaction. Nothing moves on its own except a loading indicator.',
|
|
69
|
+
'Text is left-aligned. Centering is for empty states and marketing heroes only.',
|
|
70
|
+
'The kicker (mono, uppercase, tracked) labels sections; headings carry meaning; body text explains. Never skip a level.',
|
|
71
|
+
],
|
|
72
|
+
never: NEVER_COMMON,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
vera: {
|
|
76
|
+
id: 'vera',
|
|
77
|
+
label: 'Vera / Vero family (orchid + charcoal, Geist)',
|
|
78
|
+
seeds: {
|
|
79
|
+
brand: '#B4309F',
|
|
80
|
+
action: '#2B2B2B',
|
|
81
|
+
neutralHue: 304,
|
|
82
|
+
neutralChroma: 0.003,
|
|
83
|
+
canvasLight: '#F1F0F2',
|
|
84
|
+
inkDark: '#1F1F1F',
|
|
85
|
+
fontSans: '"Geist", "Inter", system-ui, sans-serif',
|
|
86
|
+
fontMono: '"Geist Mono", ui-monospace, "SF Mono", Menlo, monospace',
|
|
87
|
+
radiusScale: 1.25,
|
|
88
|
+
baseFontSize: 14,
|
|
89
|
+
controlHeight: 40,
|
|
90
|
+
shadowTint: '#2E142A',
|
|
91
|
+
defaultTheme: 'light',
|
|
92
|
+
},
|
|
93
|
+
direction: {
|
|
94
|
+
summary: 'The Vera family look: slightly lilac off-white canvas (#F1F0F2), white cards with #E3E3E3 hairlines, charcoal as the action color, orchid reserved for brand moments and "an agent is working" presence. Geist everywhere; Geist Mono uppercase kicker with a 6×6 orchid square before section titles. Top navigation with 4–5 question-shaped tabs, kanban boards, drawers instead of detail pages.',
|
|
95
|
+
principles: [
|
|
96
|
+
'Charcoal is the action. Orchid is identity and liveness — never body text, never a big fill.',
|
|
97
|
+
'Cards are white on the lilac canvas with a 1px #E3E3E3 border and radius 10–14px. Shadows are plum-tinted and only on floating layers.',
|
|
98
|
+
'Every section starts with a kicker: a 6×6px orchid square + Geist Mono uppercase label.',
|
|
99
|
+
'Navigation is a top bar with few tabs phrased as user questions; detail opens in a drawer, not a new page.',
|
|
100
|
+
'Agents are colleagues: show presence (dot), state pill ("trabalhando") and a live "agora" line.',
|
|
101
|
+
'Chips are mono uppercase pills: accent (#FBEAFA/#7A1F6D), grey (#F2F2F2/#737373), amber (#FDF4E3/#B07908).',
|
|
102
|
+
'Transitions 180ms ease; respect prefers-reduced-motion.',
|
|
103
|
+
],
|
|
104
|
+
never: [...NEVER_COMMON, 'Pure black shadows (use the plum tint).', 'Blue links or blue CTAs.', 'A left sidebar with one entry per database table.'],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
clean: {
|
|
108
|
+
id: 'clean',
|
|
109
|
+
label: 'Clean (white, black buttons, one green detail)',
|
|
110
|
+
seeds: {
|
|
111
|
+
brand: '#10A37F',
|
|
112
|
+
action: '#0D0D0D',
|
|
113
|
+
neutralHue: 0,
|
|
114
|
+
neutralChroma: 0,
|
|
115
|
+
canvasLight: '#FFFFFF',
|
|
116
|
+
inkDark: '#0D0D0D',
|
|
117
|
+
fontSans: '"Inter", system-ui, -apple-system, sans-serif',
|
|
118
|
+
radiusScale: 1.33,
|
|
119
|
+
baseFontSize: 14,
|
|
120
|
+
controlHeight: 40,
|
|
121
|
+
defaultTheme: 'light',
|
|
122
|
+
},
|
|
123
|
+
direction: {
|
|
124
|
+
summary: 'White canvas, black primary buttons, hairline greys. The single accent green appears only in small details (a status dot, a selected tick, the progress meter). Text does most of the work.',
|
|
125
|
+
principles: [
|
|
126
|
+
'Black is the action; green is a detail, not a fill.',
|
|
127
|
+
'One primary action per screen. Secondary actions are outline or text.',
|
|
128
|
+
'Surfaces are white on white, separated by 1px #E5E5E5 hairlines, never by shadows.',
|
|
129
|
+
'Generous whitespace and short line lengths (≤ 65ch).',
|
|
130
|
+
],
|
|
131
|
+
never: [...NEVER_COMMON, 'Green as button fill or heading color.'],
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
dark: {
|
|
135
|
+
id: 'dark',
|
|
136
|
+
label: 'Dark (near-black canvas, white action, x.ai-like)',
|
|
137
|
+
seeds: {
|
|
138
|
+
brand: '#FFFFFF',
|
|
139
|
+
action: '#FFFFFF',
|
|
140
|
+
neutralHue: 0,
|
|
141
|
+
neutralChroma: 0,
|
|
142
|
+
canvasLight: '#FAFAFA',
|
|
143
|
+
inkDark: '#0A0A0A',
|
|
144
|
+
fontSans: '"Inter", system-ui, -apple-system, sans-serif',
|
|
145
|
+
fontMono: '"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace',
|
|
146
|
+
radiusScale: 1,
|
|
147
|
+
baseFontSize: 14,
|
|
148
|
+
controlHeight: 36,
|
|
149
|
+
defaultTheme: 'dark',
|
|
150
|
+
},
|
|
151
|
+
direction: {
|
|
152
|
+
summary: 'Dark by default: near-black canvas, #161616 surfaces, white text and white primary buttons. Monochrome, technical, restrained. Light theme exists but the product is designed dark-first.',
|
|
153
|
+
principles: [
|
|
154
|
+
'Monochrome: white is the action; greys build hierarchy. Color only for status.',
|
|
155
|
+
'Borders are low-contrast (#262626); surfaces are separated by tone more than by lines.',
|
|
156
|
+
'No glow, no gradients. Depth comes from tone steps (canvas → surface → raised).',
|
|
157
|
+
],
|
|
158
|
+
never: [...NEVER_COMMON, 'Neon accents, glowing borders, gradient text.'],
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { REF_RE, indexTokens, toCssVars, toLiteral, isThemed, refsIn } from '../engine.js';
|
package/lib/types.mjs
ADDED
package/lib/version.mjs
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "canon-ds",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A design system for apps built with coding agents: shared tokens, components, layouts, CSS and React exports, focused instructions, lint and MCP tools.",
|
|
5
|
+
"homepage": "https://marcosdocanto.github.io/canon/",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/marcosdocanto/canon.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/marcosdocanto/canon/issues"
|
|
12
|
+
},
|
|
13
|
+
"keywords": ["design-system", "coding-agents", "mcp", "studio", "design-tokens", "css", "react", "vibe-coding"],
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public",
|
|
16
|
+
"registry": "https://registry.npmjs.org/"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"bin": {
|
|
20
|
+
"canon": "bin/canon.js"
|
|
21
|
+
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=22.18.0"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"test": "node scripts/test.mjs",
|
|
27
|
+
"test:browser": "node scripts/test.mjs --browser",
|
|
28
|
+
"test:ci": "npm run typecheck && npm test && npm run test:browser",
|
|
29
|
+
"typecheck": "tsc --project tsconfig.json",
|
|
30
|
+
"build": "node scripts/build.mjs",
|
|
31
|
+
"build:site": "node scripts/build-site.mjs",
|
|
32
|
+
"release:check": "node scripts/release-check.mjs",
|
|
33
|
+
"prepublishOnly": "npm run test:ci && npm run release:check",
|
|
34
|
+
"prepack": "npm run build --silent",
|
|
35
|
+
"build:example": "node bin/canon.js init Canon --design examples/default/design"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"bin",
|
|
39
|
+
"lib",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE",
|
|
42
|
+
"THIRD_PARTY_NOTICES.md"
|
|
43
|
+
],
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "20.19.43",
|
|
47
|
+
"@types/react": "19.2.18",
|
|
48
|
+
"@types/react-dom": "19.2.5",
|
|
49
|
+
"playwright": "1.63.0",
|
|
50
|
+
"react": "19.2.8",
|
|
51
|
+
"react-dom": "19.2.8",
|
|
52
|
+
"typescript": "5.9.3"
|
|
53
|
+
}
|
|
54
|
+
}
|