@tekton-ui/core 0.2.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 +758 -0
- package/dist/blueprint.d.ts +44 -0
- package/dist/blueprint.d.ts.map +1 -0
- package/dist/blueprint.js +163 -0
- package/dist/blueprint.js.map +1 -0
- package/dist/component-schemas.d.ts +78 -0
- package/dist/component-schemas.d.ts.map +1 -0
- package/dist/component-schemas.js +1037 -0
- package/dist/component-schemas.js.map +1 -0
- package/dist/css-generator.d.ts +42 -0
- package/dist/css-generator.d.ts.map +1 -0
- package/dist/css-generator.js +339 -0
- package/dist/css-generator.js.map +1 -0
- package/dist/icon-library.d.ts +109 -0
- package/dist/icon-library.d.ts.map +1 -0
- package/dist/icon-library.js +204 -0
- package/dist/icon-library.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/layout-css-generator.d.ts +158 -0
- package/dist/layout-css-generator.d.ts.map +1 -0
- package/dist/layout-css-generator.js +901 -0
- package/dist/layout-css-generator.js.map +1 -0
- package/dist/layout-resolver.d.ts +92 -0
- package/dist/layout-resolver.d.ts.map +1 -0
- package/dist/layout-resolver.js +275 -0
- package/dist/layout-resolver.js.map +1 -0
- package/dist/layout-tokens/index.d.ts +16 -0
- package/dist/layout-tokens/index.d.ts.map +1 -0
- package/dist/layout-tokens/index.js +16 -0
- package/dist/layout-tokens/index.js.map +1 -0
- package/dist/layout-tokens/keyboard.d.ts +254 -0
- package/dist/layout-tokens/keyboard.d.ts.map +1 -0
- package/dist/layout-tokens/keyboard.js +407 -0
- package/dist/layout-tokens/keyboard.js.map +1 -0
- package/dist/layout-tokens/mobile-shells.d.ts +78 -0
- package/dist/layout-tokens/mobile-shells.d.ts.map +1 -0
- package/dist/layout-tokens/mobile-shells.js +635 -0
- package/dist/layout-tokens/mobile-shells.js.map +1 -0
- package/dist/layout-tokens/pages.d.ts +100 -0
- package/dist/layout-tokens/pages.d.ts.map +1 -0
- package/dist/layout-tokens/pages.js +576 -0
- package/dist/layout-tokens/pages.js.map +1 -0
- package/dist/layout-tokens/responsive.d.ts +109 -0
- package/dist/layout-tokens/responsive.d.ts.map +1 -0
- package/dist/layout-tokens/responsive.js +167 -0
- package/dist/layout-tokens/responsive.js.map +1 -0
- package/dist/layout-tokens/safe-area.d.ts +156 -0
- package/dist/layout-tokens/safe-area.d.ts.map +1 -0
- package/dist/layout-tokens/safe-area.js +316 -0
- package/dist/layout-tokens/safe-area.js.map +1 -0
- package/dist/layout-tokens/sections-advanced.d.ts +277 -0
- package/dist/layout-tokens/sections-advanced.d.ts.map +1 -0
- package/dist/layout-tokens/sections-advanced.js +593 -0
- package/dist/layout-tokens/sections-advanced.js.map +1 -0
- package/dist/layout-tokens/sections.d.ts +137 -0
- package/dist/layout-tokens/sections.d.ts.map +1 -0
- package/dist/layout-tokens/sections.js +694 -0
- package/dist/layout-tokens/sections.js.map +1 -0
- package/dist/layout-tokens/shells.d.ts +77 -0
- package/dist/layout-tokens/shells.d.ts.map +1 -0
- package/dist/layout-tokens/shells.js +408 -0
- package/dist/layout-tokens/shells.js.map +1 -0
- package/dist/layout-tokens/touch-target.d.ts +119 -0
- package/dist/layout-tokens/touch-target.d.ts.map +1 -0
- package/dist/layout-tokens/touch-target.js +156 -0
- package/dist/layout-tokens/touch-target.js.map +1 -0
- package/dist/layout-tokens/types.d.ts +632 -0
- package/dist/layout-tokens/types.d.ts.map +1 -0
- package/dist/layout-tokens/types.js +49 -0
- package/dist/layout-tokens/types.js.map +1 -0
- package/dist/layout-validation.d.ts +1547 -0
- package/dist/layout-validation.d.ts.map +1 -0
- package/dist/layout-validation.js +628 -0
- package/dist/layout-validation.js.map +1 -0
- package/dist/render.d.ts +23 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +244 -0
- package/dist/render.js.map +1 -0
- package/dist/schema-validation.d.ts +208 -0
- package/dist/schema-validation.d.ts.map +1 -0
- package/dist/schema-validation.js +205 -0
- package/dist/schema-validation.js.map +1 -0
- package/dist/screen-generation/generators/css-in-js-generator.d.ts +82 -0
- package/dist/screen-generation/generators/css-in-js-generator.d.ts.map +1 -0
- package/dist/screen-generation/generators/css-in-js-generator.js +335 -0
- package/dist/screen-generation/generators/css-in-js-generator.js.map +1 -0
- package/dist/screen-generation/generators/index.d.ts +13 -0
- package/dist/screen-generation/generators/index.d.ts.map +1 -0
- package/dist/screen-generation/generators/index.js +32 -0
- package/dist/screen-generation/generators/index.js.map +1 -0
- package/dist/screen-generation/generators/react-generator.d.ts +100 -0
- package/dist/screen-generation/generators/react-generator.d.ts.map +1 -0
- package/dist/screen-generation/generators/react-generator.js +379 -0
- package/dist/screen-generation/generators/react-generator.js.map +1 -0
- package/dist/screen-generation/generators/tailwind-generator.d.ts +105 -0
- package/dist/screen-generation/generators/tailwind-generator.d.ts.map +1 -0
- package/dist/screen-generation/generators/tailwind-generator.js +355 -0
- package/dist/screen-generation/generators/tailwind-generator.js.map +1 -0
- package/dist/screen-generation/generators/types.d.ts +136 -0
- package/dist/screen-generation/generators/types.d.ts.map +1 -0
- package/dist/screen-generation/generators/types.js +18 -0
- package/dist/screen-generation/generators/types.js.map +1 -0
- package/dist/screen-generation/generators/utils.d.ts +187 -0
- package/dist/screen-generation/generators/utils.d.ts.map +1 -0
- package/dist/screen-generation/generators/utils.js +312 -0
- package/dist/screen-generation/generators/utils.js.map +1 -0
- package/dist/screen-generation/index.d.ts +14 -0
- package/dist/screen-generation/index.d.ts.map +1 -0
- package/dist/screen-generation/index.js +33 -0
- package/dist/screen-generation/index.js.map +1 -0
- package/dist/screen-generation/resolver/component-resolver.d.ts +157 -0
- package/dist/screen-generation/resolver/component-resolver.d.ts.map +1 -0
- package/dist/screen-generation/resolver/component-resolver.js +295 -0
- package/dist/screen-generation/resolver/component-resolver.js.map +1 -0
- package/dist/screen-generation/resolver/index.d.ts +10 -0
- package/dist/screen-generation/resolver/index.d.ts.map +1 -0
- package/dist/screen-generation/resolver/index.js +46 -0
- package/dist/screen-generation/resolver/index.js.map +1 -0
- package/dist/screen-generation/resolver/layout-resolver.d.ts +155 -0
- package/dist/screen-generation/resolver/layout-resolver.d.ts.map +1 -0
- package/dist/screen-generation/resolver/layout-resolver.js +193 -0
- package/dist/screen-generation/resolver/layout-resolver.js.map +1 -0
- package/dist/screen-generation/resolver/screen-resolver.d.ts +174 -0
- package/dist/screen-generation/resolver/screen-resolver.d.ts.map +1 -0
- package/dist/screen-generation/resolver/screen-resolver.js +373 -0
- package/dist/screen-generation/resolver/screen-resolver.js.map +1 -0
- package/dist/screen-generation/resolver/token-resolver.d.ts +170 -0
- package/dist/screen-generation/resolver/token-resolver.d.ts.map +1 -0
- package/dist/screen-generation/resolver/token-resolver.js +260 -0
- package/dist/screen-generation/resolver/token-resolver.js.map +1 -0
- package/dist/screen-generation/types.d.ts +116 -0
- package/dist/screen-generation/types.d.ts.map +1 -0
- package/dist/screen-generation/types.js +33 -0
- package/dist/screen-generation/types.js.map +1 -0
- package/dist/screen-generation/validators.d.ts +286 -0
- package/dist/screen-generation/validators.d.ts.map +1 -0
- package/dist/screen-generation/validators.js +323 -0
- package/dist/screen-generation/validators.js.map +1 -0
- package/dist/screen-templates/__tests__/registry.test.d.ts +6 -0
- package/dist/screen-templates/__tests__/registry.test.d.ts.map +1 -0
- package/dist/screen-templates/__tests__/registry.test.js +247 -0
- package/dist/screen-templates/__tests__/registry.test.js.map +1 -0
- package/dist/screen-templates/__tests__/templates.test.d.ts +6 -0
- package/dist/screen-templates/__tests__/templates.test.d.ts.map +1 -0
- package/dist/screen-templates/__tests__/templates.test.js +179 -0
- package/dist/screen-templates/__tests__/templates.test.js.map +1 -0
- package/dist/screen-templates/index.d.ts +39 -0
- package/dist/screen-templates/index.d.ts.map +1 -0
- package/dist/screen-templates/index.js +79 -0
- package/dist/screen-templates/index.js.map +1 -0
- package/dist/screen-templates/registry.d.ts +177 -0
- package/dist/screen-templates/registry.d.ts.map +1 -0
- package/dist/screen-templates/registry.js +274 -0
- package/dist/screen-templates/registry.js.map +1 -0
- package/dist/screen-templates/templates/account/index.d.ts +6 -0
- package/dist/screen-templates/templates/account/index.d.ts.map +1 -0
- package/dist/screen-templates/templates/account/index.js +6 -0
- package/dist/screen-templates/templates/account/index.js.map +1 -0
- package/dist/screen-templates/templates/account/profile.d.ts +23 -0
- package/dist/screen-templates/templates/account/profile.d.ts.map +1 -0
- package/dist/screen-templates/templates/account/profile.js +249 -0
- package/dist/screen-templates/templates/account/profile.js.map +1 -0
- package/dist/screen-templates/templates/auth/forgot-password.d.ts +23 -0
- package/dist/screen-templates/templates/auth/forgot-password.d.ts.map +1 -0
- package/dist/screen-templates/templates/auth/forgot-password.js +203 -0
- package/dist/screen-templates/templates/auth/forgot-password.js.map +1 -0
- package/dist/screen-templates/templates/auth/index.d.ts +9 -0
- package/dist/screen-templates/templates/auth/index.d.ts.map +1 -0
- package/dist/screen-templates/templates/auth/index.js +9 -0
- package/dist/screen-templates/templates/auth/index.js.map +1 -0
- package/dist/screen-templates/templates/auth/login.d.ts +24 -0
- package/dist/screen-templates/templates/auth/login.d.ts.map +1 -0
- package/dist/screen-templates/templates/auth/login.js +254 -0
- package/dist/screen-templates/templates/auth/login.js.map +1 -0
- package/dist/screen-templates/templates/auth/signup.d.ts +24 -0
- package/dist/screen-templates/templates/auth/signup.d.ts.map +1 -0
- package/dist/screen-templates/templates/auth/signup.js +315 -0
- package/dist/screen-templates/templates/auth/signup.js.map +1 -0
- package/dist/screen-templates/templates/auth/verification.d.ts +23 -0
- package/dist/screen-templates/templates/auth/verification.d.ts.map +1 -0
- package/dist/screen-templates/templates/auth/verification.js +239 -0
- package/dist/screen-templates/templates/auth/verification.js.map +1 -0
- package/dist/screen-templates/templates/feedback/confirmation.d.ts +9 -0
- package/dist/screen-templates/templates/feedback/confirmation.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/confirmation.js +107 -0
- package/dist/screen-templates/templates/feedback/confirmation.js.map +1 -0
- package/dist/screen-templates/templates/feedback/empty.d.ts +9 -0
- package/dist/screen-templates/templates/feedback/empty.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/empty.js +90 -0
- package/dist/screen-templates/templates/feedback/empty.js.map +1 -0
- package/dist/screen-templates/templates/feedback/error.d.ts +9 -0
- package/dist/screen-templates/templates/feedback/error.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/error.js +99 -0
- package/dist/screen-templates/templates/feedback/error.js.map +1 -0
- package/dist/screen-templates/templates/feedback/index.d.ts +10 -0
- package/dist/screen-templates/templates/feedback/index.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/index.js +10 -0
- package/dist/screen-templates/templates/feedback/index.js.map +1 -0
- package/dist/screen-templates/templates/feedback/loading.d.ts +9 -0
- package/dist/screen-templates/templates/feedback/loading.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/loading.js +77 -0
- package/dist/screen-templates/templates/feedback/loading.js.map +1 -0
- package/dist/screen-templates/templates/feedback/success.d.ts +9 -0
- package/dist/screen-templates/templates/feedback/success.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/success.js +99 -0
- package/dist/screen-templates/templates/feedback/success.js.map +1 -0
- package/dist/screen-templates/templates/home/index.d.ts +6 -0
- package/dist/screen-templates/templates/home/index.d.ts.map +1 -0
- package/dist/screen-templates/templates/home/index.js +6 -0
- package/dist/screen-templates/templates/home/index.js.map +1 -0
- package/dist/screen-templates/templates/home/landing.d.ts +24 -0
- package/dist/screen-templates/templates/home/landing.d.ts.map +1 -0
- package/dist/screen-templates/templates/home/landing.js +197 -0
- package/dist/screen-templates/templates/home/landing.js.map +1 -0
- package/dist/screen-templates/templates/settings/index.d.ts +6 -0
- package/dist/screen-templates/templates/settings/index.d.ts.map +1 -0
- package/dist/screen-templates/templates/settings/index.js +6 -0
- package/dist/screen-templates/templates/settings/index.js.map +1 -0
- package/dist/screen-templates/templates/settings/preferences.d.ts +24 -0
- package/dist/screen-templates/templates/settings/preferences.d.ts.map +1 -0
- package/dist/screen-templates/templates/settings/preferences.js +265 -0
- package/dist/screen-templates/templates/settings/preferences.js.map +1 -0
- package/dist/screen-templates/types.d.ts +229 -0
- package/dist/screen-templates/types.d.ts.map +1 -0
- package/dist/screen-templates/types.js +7 -0
- package/dist/screen-templates/types.js.map +1 -0
- package/dist/theme-v2.d.ts +228 -0
- package/dist/theme-v2.d.ts.map +1 -0
- package/dist/theme-v2.js +158 -0
- package/dist/theme-v2.js.map +1 -0
- package/dist/theme.d.ts +60 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +76 -0
- package/dist/theme.js.map +1 -0
- package/dist/token-resolver.d.ts +69 -0
- package/dist/token-resolver.d.ts.map +1 -0
- package/dist/token-resolver.js +122 -0
- package/dist/token-resolver.js.map +1 -0
- package/dist/token-validation.d.ts +432 -0
- package/dist/token-validation.d.ts.map +1 -0
- package/dist/token-validation.js +140 -0
- package/dist/token-validation.js.map +1 -0
- package/dist/tokens.d.ts +158 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +10 -0
- package/dist/tokens.js.map +1 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
# @tekton/core
|
|
2
|
+
|
|
3
|
+
**Minimal design system pipeline** - Theme → Blueprint → Screen generation
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
89,993 LOC → **1,526 LOC** (98.3% reduction)
|
|
8
|
+
|
|
9
|
+
This package replaces 14 bloated packages with a single, focused implementation of the core pipeline.
|
|
10
|
+
|
|
11
|
+
### NEW: Screen Generation Pipeline (SPEC-LAYOUT-002) ✅
|
|
12
|
+
|
|
13
|
+
Transform JSON screen definitions into production-ready React components with multiple CSS frameworks.
|
|
14
|
+
|
|
15
|
+
**Features:**
|
|
16
|
+
|
|
17
|
+
- 🎯 **JSON Schema-based definitions** - Type-safe with TypeScript and Zod validation
|
|
18
|
+
- 🔄 **Token resolver pipeline** - Automatic layout and component token resolution
|
|
19
|
+
- 🎨 **Multiple CSS outputs** - CSS-in-JS (styled-components, Emotion) and Tailwind support
|
|
20
|
+
- ⚛️ **React component generation** - TypeScript React functional components
|
|
21
|
+
- 🤖 **MCP server integration** - 3 tools for Claude Code/Desktop LLM usage
|
|
22
|
+
- ✅ **85%+ test coverage** - TRUST 5 framework compliant
|
|
23
|
+
|
|
24
|
+
**Quick Start:**
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import {
|
|
28
|
+
validateScreenDefinition,
|
|
29
|
+
resolveScreen,
|
|
30
|
+
generateReactComponent,
|
|
31
|
+
} from '@tekton/core/screen-generation';
|
|
32
|
+
|
|
33
|
+
const validation = validateScreenDefinition(screenDef);
|
|
34
|
+
const resolved = await resolveScreen(screenDef);
|
|
35
|
+
const result = generateReactComponent(resolved);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**📚 Documentation:**
|
|
39
|
+
|
|
40
|
+
- [Screen Generation README](./src/screen-generation/README.md) - Complete overview
|
|
41
|
+
- [Phase 1: Schema & Validation](./src/screen-generation/PHASE-1.md)
|
|
42
|
+
- [Phase 2: Resolver Pipeline](./src/screen-generation/PHASE-2.md)
|
|
43
|
+
- [Phase 3: Output Generators](./src/screen-generation/PHASE-3.md)
|
|
44
|
+
- [API Reference](./src/screen-generation/API.md)
|
|
45
|
+
- [Integration Guide](./src/screen-generation/INTEGRATION.md)
|
|
46
|
+
- [MCP Tools](../mcp-server/SCREEN-TOOLS.md)
|
|
47
|
+
|
|
48
|
+
### NEW: Responsive Web Enhancement (SPEC-LAYOUT-003) ✅
|
|
49
|
+
|
|
50
|
+
Advanced responsive design system with xl/2xl breakpoints, Container Queries, and Orientation support.
|
|
51
|
+
|
|
52
|
+
**Features:**
|
|
53
|
+
|
|
54
|
+
- 📱 **Extended Breakpoints** - xl (1280px), 2xl (1536px) for large displays
|
|
55
|
+
- 📦 **Container Queries** - Component-level responsiveness independent of viewport
|
|
56
|
+
- 🔄 **Orientation Support** - Portrait/Landscape optimizations for tablets
|
|
57
|
+
- 🎯 **27 Layout Tokens Updated** - All shells, pages, and sections enhanced
|
|
58
|
+
- ✅ **100% Test Coverage** - 1041/1041 tests passing
|
|
59
|
+
- 🌐 **Browser Compatibility** - Chrome 105+, Safari 16+, Firefox 110+ with fallback
|
|
60
|
+
|
|
61
|
+
**Quick Start:**
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import {
|
|
65
|
+
generateResponsiveCSS,
|
|
66
|
+
generateContainerQueryCSS,
|
|
67
|
+
generateOrientationCSS,
|
|
68
|
+
} from '@tekton/core/layout-tokens';
|
|
69
|
+
|
|
70
|
+
// Responsive breakpoints including xl/2xl
|
|
71
|
+
const responsive = generateResponsiveCSS({
|
|
72
|
+
default: { gridColumns: 1 },
|
|
73
|
+
md: { gridColumns: 2 },
|
|
74
|
+
xl: { gridColumns: 4 },
|
|
75
|
+
'2xl': { gridColumns: 6 },
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Container Queries for component-level responsiveness
|
|
79
|
+
const container = generateContainerQueryCSS({
|
|
80
|
+
name: 'card-grid',
|
|
81
|
+
type: 'inline-size',
|
|
82
|
+
breakpoints: {
|
|
83
|
+
md: { minWidth: 480, css: { 'grid-template-columns': 'repeat(2, 1fr)' } },
|
|
84
|
+
lg: { minWidth: 640, css: { 'grid-template-columns': 'repeat(3, 1fr)' } },
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Orientation support for tablets
|
|
89
|
+
const orientation = generateOrientationCSS({
|
|
90
|
+
portrait: { gridColumns: 1 },
|
|
91
|
+
landscape: { gridColumns: 2 },
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**📚 Documentation:**
|
|
96
|
+
|
|
97
|
+
- [Responsive Design Guide](../../docs/guides/responsive-design.md)
|
|
98
|
+
- [Browser Compatibility Matrix](../../docs/guides/browser-compatibility.md)
|
|
99
|
+
- [SPEC-LAYOUT-003 Specification](../../.moai/specs/SPEC-LAYOUT-003/spec.md)
|
|
100
|
+
- [Acceptance Report](../../.moai/specs/SPEC-LAYOUT-003/acceptance.md)
|
|
101
|
+
|
|
102
|
+
## Installation
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
pnpm add @tekton/core
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Quick Start
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { loadTheme, createBlueprint, render } from '@tekton/core';
|
|
112
|
+
|
|
113
|
+
// 1. Load theme
|
|
114
|
+
const theme = loadTheme('calm-wellness');
|
|
115
|
+
|
|
116
|
+
// 2. Create blueprint
|
|
117
|
+
const blueprint = createBlueprint({
|
|
118
|
+
name: 'Dashboard',
|
|
119
|
+
themeId: theme.id,
|
|
120
|
+
layout: 'dashboard',
|
|
121
|
+
components: [
|
|
122
|
+
{ type: 'Heading', props: { level: 1 }, children: ['Welcome'] },
|
|
123
|
+
{
|
|
124
|
+
type: 'Card',
|
|
125
|
+
children: [
|
|
126
|
+
{ type: 'Text', children: ['Your stats here'] },
|
|
127
|
+
{ type: 'Button', props: { variant: 'primary' }, children: ['View More'] },
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// 3. Render to JSX
|
|
134
|
+
const result = render(blueprint);
|
|
135
|
+
console.log(result.code);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Features
|
|
139
|
+
|
|
140
|
+
### 🎨 3-Layer Token System (NEW)
|
|
141
|
+
|
|
142
|
+
Professional design token architecture with atomic, semantic, and component layers:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import type { ThemeWithTokens } from '@tekton/core';
|
|
146
|
+
import { resolveToken, generateThemeCSS } from '@tekton/core';
|
|
147
|
+
|
|
148
|
+
// Define theme with 3-layer token structure
|
|
149
|
+
const theme: ThemeWithTokens = {
|
|
150
|
+
id: 'my-theme',
|
|
151
|
+
name: 'My Theme',
|
|
152
|
+
tokens: {
|
|
153
|
+
// Layer 1: Atomic Tokens (raw values)
|
|
154
|
+
atomic: {
|
|
155
|
+
color: {
|
|
156
|
+
blue: { '500': '#3b82f6', '600': '#2563eb' },
|
|
157
|
+
neutral: { '50': '#f9fafb', '900': '#111827' },
|
|
158
|
+
},
|
|
159
|
+
spacing: { '4': '16px', '8': '32px' },
|
|
160
|
+
radius: { md: '8px' },
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
// Layer 2: Semantic Tokens (meaning-based)
|
|
164
|
+
semantic: {
|
|
165
|
+
background: {
|
|
166
|
+
page: 'atomic.color.neutral.50',
|
|
167
|
+
surface: '#ffffff',
|
|
168
|
+
},
|
|
169
|
+
foreground: {
|
|
170
|
+
primary: 'atomic.color.neutral.900',
|
|
171
|
+
accent: 'atomic.color.blue.500',
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
// Layer 3: Component Tokens (component-specific)
|
|
176
|
+
component: {
|
|
177
|
+
button: {
|
|
178
|
+
primary: {
|
|
179
|
+
background: 'semantic.foreground.accent',
|
|
180
|
+
foreground: '#ffffff',
|
|
181
|
+
hover: { background: 'atomic.color.blue.600' },
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// Resolve token with automatic reference resolution
|
|
189
|
+
const color = resolveToken('component.button.primary.background', theme.tokens);
|
|
190
|
+
// → '#3b82f6' (semantic.foreground.accent → atomic.color.blue.500)
|
|
191
|
+
|
|
192
|
+
// Generate CSS Variables
|
|
193
|
+
const css = generateThemeCSS(theme);
|
|
194
|
+
// Outputs:
|
|
195
|
+
// :root {
|
|
196
|
+
// --color-blue-500: #3b82f6;
|
|
197
|
+
// --background-page: #f9fafb;
|
|
198
|
+
// --button-primary-background: #3b82f6;
|
|
199
|
+
// }
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Key Features:**
|
|
203
|
+
|
|
204
|
+
- ✅ **3-Layer Architecture**: Atomic → Semantic → Component
|
|
205
|
+
- ✅ **Automatic Resolution**: Multi-level reference resolution with circular detection
|
|
206
|
+
- ✅ **Fallback Chain**: Component → Semantic → Atomic
|
|
207
|
+
- ✅ **Type Safety**: Full TypeScript support with Zod validation
|
|
208
|
+
- ✅ **Dark Mode**: Built-in dark mode token overrides
|
|
209
|
+
- ✅ **CSS Variables**: Auto-generate CSS custom properties
|
|
210
|
+
- ✅ **Zero Dependencies**: Only Zod for runtime validation
|
|
211
|
+
|
|
212
|
+
### 🎯 Token Resolution
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
import { resolveToken, resolveWithFallback } from '@tekton/core';
|
|
216
|
+
|
|
217
|
+
// Simple resolution
|
|
218
|
+
resolveToken('atomic.color.blue.500', tokens);
|
|
219
|
+
// → '#3b82f6'
|
|
220
|
+
|
|
221
|
+
// Multi-level resolution
|
|
222
|
+
resolveToken('component.button.primary.background', tokens);
|
|
223
|
+
// → '#3b82f6' (resolves through semantic layer)
|
|
224
|
+
|
|
225
|
+
// Fallback chain (most specific to least specific)
|
|
226
|
+
resolveWithFallback(
|
|
227
|
+
'component.button.custom.background', // Try component first
|
|
228
|
+
'semantic.foreground.accent', // Fallback to semantic
|
|
229
|
+
'atomic.color.blue.500', // Final fallback to atomic
|
|
230
|
+
tokens
|
|
231
|
+
);
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### 🌓 Dark Mode Support
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
const theme: ThemeWithTokens = {
|
|
238
|
+
// ... base theme ...
|
|
239
|
+
darkMode: {
|
|
240
|
+
tokens: {
|
|
241
|
+
semantic: {
|
|
242
|
+
background: {
|
|
243
|
+
page: 'atomic.color.neutral.900',
|
|
244
|
+
surface: 'atomic.color.neutral.800',
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
component: {
|
|
248
|
+
button: {
|
|
249
|
+
primary: {
|
|
250
|
+
background: 'atomic.color.blue.400',
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// Generate CSS with dark mode
|
|
259
|
+
const css = generateThemeCSS(theme);
|
|
260
|
+
// Outputs:
|
|
261
|
+
// :root { /* light mode variables */ }
|
|
262
|
+
// .dark { /* dark mode overrides */ }
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### ✅ Runtime Validation
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
import { validateTheme } from '@tekton/core';
|
|
269
|
+
|
|
270
|
+
const result = validateTheme(myTheme);
|
|
271
|
+
|
|
272
|
+
if (!result.valid) {
|
|
273
|
+
console.error('Validation errors:', result.errors);
|
|
274
|
+
// → ['tokens.atomic.color: Required', 'tokens.semantic.background.page: Required']
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## API Reference
|
|
279
|
+
|
|
280
|
+
### Token Module
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
// Type definitions
|
|
284
|
+
import type { AtomicTokens, SemanticTokens, ComponentTokens, ThemeWithTokens } from '@tekton/core';
|
|
285
|
+
|
|
286
|
+
// Token resolution
|
|
287
|
+
import { resolveToken, resolveWithFallback } from '@tekton/core';
|
|
288
|
+
|
|
289
|
+
// CSS generation
|
|
290
|
+
import { generateThemeCSS } from '@tekton/core';
|
|
291
|
+
|
|
292
|
+
// Validation
|
|
293
|
+
import { validateTheme } from '@tekton/core';
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
#### `resolveToken(ref, tokens)`
|
|
297
|
+
|
|
298
|
+
Resolves a token reference to its final value with multi-level resolution.
|
|
299
|
+
|
|
300
|
+
**Parameters:**
|
|
301
|
+
|
|
302
|
+
- `ref: string` - Token reference in dot notation (e.g., `'atomic.color.blue.500'`)
|
|
303
|
+
- `tokens: ThemeWithTokens['tokens']` - Theme token structure
|
|
304
|
+
|
|
305
|
+
**Returns:** `string` - Resolved token value
|
|
306
|
+
|
|
307
|
+
**Throws:**
|
|
308
|
+
|
|
309
|
+
- `Error` - If token not found
|
|
310
|
+
- `Error` - If circular reference detected
|
|
311
|
+
|
|
312
|
+
**Examples:**
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
// Direct atomic token
|
|
316
|
+
resolveToken('atomic.color.blue.500', tokens);
|
|
317
|
+
// → '#3b82f6'
|
|
318
|
+
|
|
319
|
+
// Semantic token (references atomic)
|
|
320
|
+
resolveToken('semantic.background.page', tokens);
|
|
321
|
+
// → '#f9fafb' (via atomic.color.neutral.50)
|
|
322
|
+
|
|
323
|
+
// Component token (multi-level resolution)
|
|
324
|
+
resolveToken('component.button.primary.background', tokens);
|
|
325
|
+
// → '#3b82f6' (semantic.foreground.accent → atomic.color.blue.500)
|
|
326
|
+
|
|
327
|
+
// Direct value (returned as-is)
|
|
328
|
+
resolveToken('#3b82f6', tokens);
|
|
329
|
+
// → '#3b82f6'
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
#### `resolveWithFallback(componentRef, semanticRef, atomicRef, tokens)`
|
|
333
|
+
|
|
334
|
+
Resolves token with graceful fallback: Component → Semantic → Atomic.
|
|
335
|
+
|
|
336
|
+
**Parameters:**
|
|
337
|
+
|
|
338
|
+
- `componentRef: string` - Component-level token reference
|
|
339
|
+
- `semanticRef: string` - Semantic-level token reference (fallback)
|
|
340
|
+
- `atomicRef: string` - Atomic-level token reference (final fallback)
|
|
341
|
+
- `tokens: ThemeWithTokens['tokens']` - Theme token structure
|
|
342
|
+
|
|
343
|
+
**Returns:** `string` - Resolved value from first successful resolution
|
|
344
|
+
|
|
345
|
+
**Throws:** `Error` - If all fallback attempts fail
|
|
346
|
+
|
|
347
|
+
**Example:**
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
resolveWithFallback(
|
|
351
|
+
'component.button.custom.background', // Missing (skipped)
|
|
352
|
+
'semantic.foreground.accent', // Exists → returns '#3b82f6'
|
|
353
|
+
'atomic.color.blue.500', // Not evaluated
|
|
354
|
+
tokens
|
|
355
|
+
);
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
#### `generateThemeCSS(theme)`
|
|
359
|
+
|
|
360
|
+
Generates complete CSS with CSS Variables from theme tokens.
|
|
361
|
+
|
|
362
|
+
**Parameters:**
|
|
363
|
+
|
|
364
|
+
- `theme: ThemeWithTokens` - Theme with 3-layer token structure
|
|
365
|
+
|
|
366
|
+
**Returns:** `string` - Generated CSS with `:root` and `.dark` selectors
|
|
367
|
+
|
|
368
|
+
**Example:**
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
const css = generateThemeCSS(theme);
|
|
372
|
+
|
|
373
|
+
// Output structure:
|
|
374
|
+
// :root {
|
|
375
|
+
// /* Layer 1: Atomic Tokens */
|
|
376
|
+
// --color-blue-500: #3b82f6;
|
|
377
|
+
// --spacing-4: 16px;
|
|
378
|
+
//
|
|
379
|
+
// /* Layer 2: Semantic Tokens */
|
|
380
|
+
// --background-page: #f9fafb;
|
|
381
|
+
// --foreground-accent: #3b82f6;
|
|
382
|
+
//
|
|
383
|
+
// /* Layer 3: Component Tokens */
|
|
384
|
+
// --button-primary-background: #3b82f6;
|
|
385
|
+
// --button-primary-hover-background: #2563eb;
|
|
386
|
+
// }
|
|
387
|
+
//
|
|
388
|
+
// .dark {
|
|
389
|
+
// --background-page: #111827;
|
|
390
|
+
// }
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
#### `validateTheme(theme)`
|
|
394
|
+
|
|
395
|
+
Validates theme with token structure using Zod schemas.
|
|
396
|
+
|
|
397
|
+
**Parameters:**
|
|
398
|
+
|
|
399
|
+
- `theme: unknown` - Theme object to validate
|
|
400
|
+
|
|
401
|
+
**Returns:** `ValidationResult`
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
interface ValidationResult {
|
|
405
|
+
valid: boolean;
|
|
406
|
+
errors?: string[]; // Present if valid is false
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**Example:**
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
const result = validateTheme(myTheme);
|
|
414
|
+
|
|
415
|
+
if (result.valid) {
|
|
416
|
+
console.log('✅ Theme is valid');
|
|
417
|
+
} else {
|
|
418
|
+
console.error('❌ Validation failed:');
|
|
419
|
+
result.errors?.forEach(err => console.error(` - ${err}`));
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Theme Module
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
// Load theme by ID
|
|
427
|
+
const theme = loadTheme('calm-wellness');
|
|
428
|
+
|
|
429
|
+
// List all available themes
|
|
430
|
+
const themes = listThemes();
|
|
431
|
+
|
|
432
|
+
// Check if theme is built-in
|
|
433
|
+
const isBuiltin = isBuiltinTheme('calm-wellness'); // true
|
|
434
|
+
|
|
435
|
+
// Generate CSS variables from theme
|
|
436
|
+
const cssVars = generateCSSVariables(theme);
|
|
437
|
+
|
|
438
|
+
// Convert OKLCH to CSS
|
|
439
|
+
const css = oklchToCSS({ l: 0.7, c: 0.1, h: 170 }); // 'oklch(0.7 0.1 170)'
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Blueprint Module
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// Create blueprint
|
|
446
|
+
const blueprint = createBlueprint({
|
|
447
|
+
name: 'Page Name',
|
|
448
|
+
description: 'Optional description',
|
|
449
|
+
themeId: 'calm-wellness',
|
|
450
|
+
layout: 'single-column', // or 'two-column', 'sidebar-left', 'dashboard', 'landing'
|
|
451
|
+
components: [{ type: 'Button', children: ['Click'] }],
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
// Validate blueprint
|
|
455
|
+
const validation = validateBlueprint(blueprint);
|
|
456
|
+
if (!validation.valid) {
|
|
457
|
+
console.error(validation.errors);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Check component validity
|
|
461
|
+
isValidComponent('Button'); // true
|
|
462
|
+
isValidComponent('FakeComponent'); // false
|
|
463
|
+
|
|
464
|
+
// Get layout slots
|
|
465
|
+
const slots = getLayoutSlots('dashboard');
|
|
466
|
+
// [{ name: 'header', required: true }, { name: 'sidebar', required: true }, ...]
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### Render Module
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
// Render blueprint to JSX
|
|
473
|
+
const result = render(blueprint);
|
|
474
|
+
if (result.success) {
|
|
475
|
+
console.log(result.code);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Render with theme CSS variables included
|
|
479
|
+
const resultWithTheme = renderWithTheme(blueprint);
|
|
480
|
+
|
|
481
|
+
// Render options
|
|
482
|
+
const result = render(blueprint, {
|
|
483
|
+
typescript: true, // Generate TypeScript (default: true)
|
|
484
|
+
indent: 2, // Indentation spaces (default: 2)
|
|
485
|
+
semicolons: true, // Include semicolons (default: true)
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
// Quick render single component
|
|
489
|
+
const jsx = renderSingleComponent({ type: 'Button', children: ['Click'] });
|
|
490
|
+
|
|
491
|
+
// Render multiple components without layout
|
|
492
|
+
const jsx = renderComponents([
|
|
493
|
+
{ type: 'Heading', children: ['Title'] },
|
|
494
|
+
{ type: 'Text', children: ['Content'] },
|
|
495
|
+
]);
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
## CSS Variables Naming Convention
|
|
499
|
+
|
|
500
|
+
The token system generates CSS Variables with a consistent naming pattern:
|
|
501
|
+
|
|
502
|
+
### Atomic Tokens
|
|
503
|
+
|
|
504
|
+
```css
|
|
505
|
+
--color-{palette}-{shade}: {value}
|
|
506
|
+
--spacing-{size}: {value}
|
|
507
|
+
--radius-{size}: {value}
|
|
508
|
+
--typography-{name}-size: {value}
|
|
509
|
+
--typography-{name}-line-height: {value}
|
|
510
|
+
--typography-{name}-weight: {value}
|
|
511
|
+
--shadow-{name}: {value}
|
|
512
|
+
--transition-{name}: {value}
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
**Examples:**
|
|
516
|
+
|
|
517
|
+
```css
|
|
518
|
+
--color-blue-500: #3b82f6;
|
|
519
|
+
--color-neutral-50: #f9fafb;
|
|
520
|
+
--spacing-4: 16px;
|
|
521
|
+
--radius-md: 8px;
|
|
522
|
+
--typography-body-size: 16px;
|
|
523
|
+
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### Semantic Tokens
|
|
527
|
+
|
|
528
|
+
```css
|
|
529
|
+
--{category}-{name}: {value}
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Examples:**
|
|
533
|
+
|
|
534
|
+
```css
|
|
535
|
+
--background-page: #f9fafb;
|
|
536
|
+
--foreground-primary: #111827;
|
|
537
|
+
--border-default: #e5e7eb;
|
|
538
|
+
--surface-primary: #ffffff;
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
### Component Tokens
|
|
542
|
+
|
|
543
|
+
```css
|
|
544
|
+
--{component}-{variant}-{property}: {value}
|
|
545
|
+
--{component}-{variant}-{state}-{property}: {value}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
**Examples:**
|
|
549
|
+
|
|
550
|
+
```css
|
|
551
|
+
/* Button primary variant */
|
|
552
|
+
--button-primary-background: #3b82f6;
|
|
553
|
+
--button-primary-foreground: #ffffff;
|
|
554
|
+
--button-primary-hover-background: #2563eb;
|
|
555
|
+
--button-primary-disabled-foreground: #9ca3af;
|
|
556
|
+
|
|
557
|
+
/* Input component */
|
|
558
|
+
--input-background: #ffffff;
|
|
559
|
+
--input-border: #e5e7eb;
|
|
560
|
+
--input-focus-ring: #3b82f6;
|
|
561
|
+
--input-error-border: #ef4444;
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Dark Mode Overrides
|
|
565
|
+
|
|
566
|
+
Dark mode uses the same variable names but scoped to `.dark` class:
|
|
567
|
+
|
|
568
|
+
```css
|
|
569
|
+
.dark {
|
|
570
|
+
--background-page: #111827;
|
|
571
|
+
--foreground-primary: #f9fafb;
|
|
572
|
+
--button-primary-background: #60a5fa;
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
**Usage in Components:**
|
|
577
|
+
|
|
578
|
+
```css
|
|
579
|
+
.button-primary {
|
|
580
|
+
background: var(--button-primary-background);
|
|
581
|
+
color: var(--button-primary-foreground);
|
|
582
|
+
border-radius: var(--radius-md);
|
|
583
|
+
padding: var(--spacing-4);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
.button-primary:hover {
|
|
587
|
+
background: var(--button-primary-hover-background);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.button-primary:disabled {
|
|
591
|
+
background: var(--button-primary-disabled-background);
|
|
592
|
+
color: var(--button-primary-disabled-foreground);
|
|
593
|
+
}
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
## Migration Guide
|
|
597
|
+
|
|
598
|
+
### From Old Theme System
|
|
599
|
+
|
|
600
|
+
**Before (0.1.0):**
|
|
601
|
+
|
|
602
|
+
```typescript
|
|
603
|
+
const theme = loadTheme('calm-wellness');
|
|
604
|
+
const cssVars = generateCSSVariables(theme);
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
**After (0.2.0 with Token System):**
|
|
608
|
+
|
|
609
|
+
```typescript
|
|
610
|
+
import type { ThemeWithTokens } from '@tekton/core';
|
|
611
|
+
import { generateThemeCSS } from '@tekton/core';
|
|
612
|
+
|
|
613
|
+
// Old themes still work (backward compatible)
|
|
614
|
+
const theme = loadTheme('calm-wellness');
|
|
615
|
+
|
|
616
|
+
// New: Extend with token system
|
|
617
|
+
const themeWithTokens: ThemeWithTokens = {
|
|
618
|
+
...theme,
|
|
619
|
+
tokens: {
|
|
620
|
+
atomic: {
|
|
621
|
+
/* ... */
|
|
622
|
+
},
|
|
623
|
+
semantic: {
|
|
624
|
+
/* ... */
|
|
625
|
+
},
|
|
626
|
+
component: {
|
|
627
|
+
/* ... */
|
|
628
|
+
},
|
|
629
|
+
},
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
const css = generateThemeCSS(themeWithTokens);
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
### Key Changes
|
|
636
|
+
|
|
637
|
+
1. **New Token Structure**: 3-layer architecture (atomic/semantic/component)
|
|
638
|
+
2. **Type Safety**: Full TypeScript support with `ThemeWithTokens` interface
|
|
639
|
+
3. **Runtime Validation**: Zod schema validation with `validateTheme()`
|
|
640
|
+
4. **CSS Generation**: New `generateThemeCSS()` replaces `generateCSSVariables()`
|
|
641
|
+
5. **Dark Mode**: Built-in dark mode support via `darkMode` property
|
|
642
|
+
|
|
643
|
+
### Breaking Changes
|
|
644
|
+
|
|
645
|
+
None - the token system is an additive feature in 0.2.0.
|
|
646
|
+
|
|
647
|
+
## Available Layouts
|
|
648
|
+
|
|
649
|
+
| Layout | Slots |
|
|
650
|
+
| --------------- | ------------------------------- |
|
|
651
|
+
| `single-column` | header?, main, footer? |
|
|
652
|
+
| `two-column` | header?, left, right, footer? |
|
|
653
|
+
| `sidebar-left` | header?, sidebar, main, footer? |
|
|
654
|
+
| `sidebar-right` | header?, main, sidebar, footer? |
|
|
655
|
+
| `dashboard` | header, sidebar, main, footer? |
|
|
656
|
+
| `landing` | hero, features?, cta?, footer? |
|
|
657
|
+
|
|
658
|
+
## Available Components
|
|
659
|
+
|
|
660
|
+
Button, Input, Card, Text, Heading, Image, Link, List, Form, Modal, Tabs, Table, Badge, Avatar, Dropdown, Checkbox, Radio, Switch, Slider, Progress
|
|
661
|
+
|
|
662
|
+
## Built-in Themes
|
|
663
|
+
|
|
664
|
+
- `calm-wellness` - Soft, meditative atmosphere
|
|
665
|
+
- `dynamic-fitness` - Energetic, bold design
|
|
666
|
+
- `korean-fintech` - Clean, trustworthy finance
|
|
667
|
+
- `media-streaming` - Dark, immersive entertainment
|
|
668
|
+
- `premium-editorial` - Elegant, typography-focused
|
|
669
|
+
- `saas-dashboard` - Professional, data-rich
|
|
670
|
+
- `saas-modern` - Clean, modern SaaS
|
|
671
|
+
- `tech-startup` - Bold, innovative tech
|
|
672
|
+
- `warm-humanist` - Friendly, approachable
|
|
673
|
+
|
|
674
|
+
## Architecture
|
|
675
|
+
|
|
676
|
+
```
|
|
677
|
+
@tekton/core (1,526 LOC)
|
|
678
|
+
├── Core Pipeline (742 LOC)
|
|
679
|
+
│ ├── types.ts (94 LOC) - Core type definitions
|
|
680
|
+
│ ├── theme.ts (131 LOC) - Theme loading & CSS generation
|
|
681
|
+
│ ├── blueprint.ts (169 LOC) - Blueprint creation & validation
|
|
682
|
+
│ ├── render.ts (297 LOC) - Template-based JSX generation
|
|
683
|
+
│ └── index.ts (51 LOC) - Public API exports
|
|
684
|
+
│
|
|
685
|
+
└── Token System (784 LOC) [NEW in 0.2.0]
|
|
686
|
+
├── tokens.ts (189 LOC) - 3-layer token type definitions
|
|
687
|
+
├── token-resolver.ts (146 LOC) - Token resolution & fallback logic
|
|
688
|
+
├── token-validation.ts (176 LOC) - Zod schema validation
|
|
689
|
+
└── css-generator.ts (273 LOC) - CSS Variables generation
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
### Design Decisions
|
|
693
|
+
|
|
694
|
+
**3-Layer Token Architecture**:
|
|
695
|
+
|
|
696
|
+
- **Atomic Layer**: Raw design values (colors, spacing) - foundation
|
|
697
|
+
- **Semantic Layer**: Meaning-based mappings (background.page, foreground.primary) - context
|
|
698
|
+
- **Component Layer**: Component-specific bindings (button.primary.background) - usage
|
|
699
|
+
|
|
700
|
+
Benefits:
|
|
701
|
+
|
|
702
|
+
- Clear separation of concerns
|
|
703
|
+
- Maintainable theming system
|
|
704
|
+
- Type-safe token references
|
|
705
|
+
- Automatic dark mode support
|
|
706
|
+
- Scalable to complex design systems
|
|
707
|
+
|
|
708
|
+
**Template-based rendering** (not AST-based):
|
|
709
|
+
|
|
710
|
+
- Zero dependencies (no Babel, Prettier)
|
|
711
|
+
- Faster execution
|
|
712
|
+
- Easier to understand and debug
|
|
713
|
+
- Sufficient for JSX generation use case
|
|
714
|
+
|
|
715
|
+
**What was removed**:
|
|
716
|
+
|
|
717
|
+
- Babel AST builders
|
|
718
|
+
- Prettier formatting
|
|
719
|
+
- Slot registries (Global/Local)
|
|
720
|
+
- Semantic scoring engine
|
|
721
|
+
- Safety protocols (4 validators)
|
|
722
|
+
- MCP server infrastructure
|
|
723
|
+
- 13 unnecessary packages
|
|
724
|
+
|
|
725
|
+
## Testing
|
|
726
|
+
|
|
727
|
+
```bash
|
|
728
|
+
pnpm test # Run tests
|
|
729
|
+
pnpm test:watch # Watch mode
|
|
730
|
+
pnpm test:coverage # Coverage report
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
Current: **132 tests**, **96.37% coverage**
|
|
734
|
+
|
|
735
|
+
### Test Coverage by Module
|
|
736
|
+
|
|
737
|
+
| Module | Tests | Coverage |
|
|
738
|
+
| ---------------- | ----- | -------- |
|
|
739
|
+
| Token Types | 28 | 100% |
|
|
740
|
+
| Token Resolution | 35 | 98.5% |
|
|
741
|
+
| Token Validation | 32 | 97.2% |
|
|
742
|
+
| CSS Generation | 37 | 95.8% |
|
|
743
|
+
| Core Pipeline | - | 83% |
|
|
744
|
+
|
|
745
|
+
## Performance
|
|
746
|
+
|
|
747
|
+
Token system is highly optimized for production use:
|
|
748
|
+
|
|
749
|
+
- **Token Resolution**: < 1ms per token (avg 0.3ms)
|
|
750
|
+
- **Multi-level Resolution**: < 1ms for deep references
|
|
751
|
+
- **CSS Generation**: ~5ms for complete theme
|
|
752
|
+
- **Validation**: < 10ms for full theme structure
|
|
753
|
+
|
|
754
|
+
Benchmarked on Node.js 20, Apple M1.
|
|
755
|
+
|
|
756
|
+
## License
|
|
757
|
+
|
|
758
|
+
MIT
|