prev-cli 0.24.18 → 0.24.19
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/package.json +5 -2
- package/src/jsx/adapters/html.test.ts +191 -0
- package/src/jsx/adapters/html.ts +404 -0
- package/src/jsx/adapters/react.test.ts +172 -0
- package/src/jsx/adapters/react.tsx +346 -0
- package/src/jsx/define-component.ts +129 -0
- package/src/jsx/index.ts +47 -0
- package/src/jsx/jsx-runtime.test.ts +63 -0
- package/src/jsx/jsx-runtime.ts +117 -0
- package/src/jsx/migrate.test.ts +72 -0
- package/src/jsx/migrate.ts +451 -0
- package/src/jsx/schemas/index.ts +4 -0
- package/src/jsx/schemas/primitives.ts +107 -0
- package/src/jsx/schemas/tokens.ts +60 -0
- package/src/jsx/validation.ts +77 -0
- package/src/jsx/vnode.ts +159 -0
- package/src/primitives/index.ts +8 -0
- package/src/primitives/migrate.test.ts +317 -0
- package/src/primitives/migrate.ts +364 -0
- package/src/primitives/parser.test.ts +265 -0
- package/src/primitives/parser.ts +442 -0
- package/src/primitives/template-parser.test.ts +297 -0
- package/src/primitives/template-parser.ts +374 -0
- package/src/primitives/template-renderer.test.ts +359 -0
- package/src/primitives/template-renderer.ts +497 -0
- package/src/primitives/tokens.css +82 -0
- package/src/primitives/types.ts +248 -0
- package/src/tokens/defaults.test.ts +137 -0
- package/src/tokens/defaults.ts +77 -0
- package/src/tokens/defaults.yaml +76 -0
- package/src/tokens/resolver.test.ts +229 -0
- package/src/tokens/resolver.ts +173 -0
- package/src/tokens/utils.test.ts +172 -0
- package/src/tokens/utils.ts +104 -0
- package/src/tokens/validation.test.ts +118 -0
- package/src/tokens/validation.ts +226 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
// src/primitives/types.ts
|
|
2
|
+
// Type definitions for layout and content primitives
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Design token types for consistent spacing, sizing, and styling
|
|
6
|
+
* Using shadcn/ui-compatible naming conventions
|
|
7
|
+
*/
|
|
8
|
+
export type SpacingToken = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
|
9
|
+
export type AlignToken = 'start' | 'center' | 'end' | 'stretch' | 'between'
|
|
10
|
+
|
|
11
|
+
// Background tokens - shadcn-compatible
|
|
12
|
+
export type BackgroundToken =
|
|
13
|
+
| 'transparent'
|
|
14
|
+
| 'background'
|
|
15
|
+
| 'card'
|
|
16
|
+
| 'primary'
|
|
17
|
+
| 'secondary'
|
|
18
|
+
| 'muted'
|
|
19
|
+
| 'accent'
|
|
20
|
+
| 'destructive'
|
|
21
|
+
| 'input'
|
|
22
|
+
|
|
23
|
+
export type RadiusToken = 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full'
|
|
24
|
+
|
|
25
|
+
// Color tokens - shadcn-compatible (foreground colors for text)
|
|
26
|
+
export type ColorToken =
|
|
27
|
+
| 'foreground'
|
|
28
|
+
| 'card-foreground'
|
|
29
|
+
| 'primary'
|
|
30
|
+
| 'primary-foreground'
|
|
31
|
+
| 'secondary'
|
|
32
|
+
| 'secondary-foreground'
|
|
33
|
+
| 'muted'
|
|
34
|
+
| 'muted-foreground'
|
|
35
|
+
| 'accent'
|
|
36
|
+
| 'accent-foreground'
|
|
37
|
+
| 'destructive'
|
|
38
|
+
| 'destructive-foreground'
|
|
39
|
+
| 'border'
|
|
40
|
+
| 'ring'
|
|
41
|
+
|
|
42
|
+
// Typography size tokens
|
|
43
|
+
export type SizeToken = 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl'
|
|
44
|
+
|
|
45
|
+
export type WeightToken = 'normal' | 'medium' | 'semibold' | 'bold'
|
|
46
|
+
export type FitToken = 'cover' | 'contain' | 'fill'
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* All primitive type names
|
|
50
|
+
*/
|
|
51
|
+
export type PrimitiveType =
|
|
52
|
+
| '$col'
|
|
53
|
+
| '$row'
|
|
54
|
+
| '$box'
|
|
55
|
+
| '$spacer'
|
|
56
|
+
| '$slot'
|
|
57
|
+
| '$text'
|
|
58
|
+
| '$icon'
|
|
59
|
+
| '$image'
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Layout primitive: $col - Vertical stack
|
|
63
|
+
*/
|
|
64
|
+
export interface ColPrimitive {
|
|
65
|
+
type: '$col'
|
|
66
|
+
gap?: SpacingToken
|
|
67
|
+
align?: AlignToken
|
|
68
|
+
padding?: SpacingToken
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Layout primitive: $row - Horizontal stack
|
|
73
|
+
*/
|
|
74
|
+
export interface RowPrimitive {
|
|
75
|
+
type: '$row'
|
|
76
|
+
gap?: SpacingToken
|
|
77
|
+
align?: AlignToken
|
|
78
|
+
padding?: SpacingToken
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Layout primitive: $box - Container with styling
|
|
83
|
+
*/
|
|
84
|
+
export interface BoxPrimitive {
|
|
85
|
+
type: '$box'
|
|
86
|
+
padding?: SpacingToken
|
|
87
|
+
bg?: BackgroundToken
|
|
88
|
+
radius?: RadiusToken
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Layout primitive: $spacer - Whitespace
|
|
93
|
+
*/
|
|
94
|
+
export interface SpacerPrimitive {
|
|
95
|
+
type: '$spacer'
|
|
96
|
+
size?: SpacingToken // If absent, flex grow
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Layout primitive: $slot - State-dependent placeholder
|
|
101
|
+
*/
|
|
102
|
+
export interface SlotPrimitive {
|
|
103
|
+
type: '$slot'
|
|
104
|
+
name: string
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Content primitive: $text - Text content
|
|
109
|
+
*/
|
|
110
|
+
export interface TextPrimitive {
|
|
111
|
+
type: '$text'
|
|
112
|
+
content: string // Prop reference or quoted literal
|
|
113
|
+
size?: SizeToken
|
|
114
|
+
weight?: WeightToken
|
|
115
|
+
color?: ColorToken
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Content primitive: $icon - Icon
|
|
120
|
+
*/
|
|
121
|
+
export interface IconPrimitive {
|
|
122
|
+
type: '$icon'
|
|
123
|
+
name: string // Prop reference or string
|
|
124
|
+
size?: SizeToken
|
|
125
|
+
color?: ColorToken
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Content primitive: $image - Image
|
|
130
|
+
*/
|
|
131
|
+
export interface ImagePrimitive {
|
|
132
|
+
type: '$image'
|
|
133
|
+
src: string // Prop reference or URL
|
|
134
|
+
alt?: string
|
|
135
|
+
fit?: FitToken
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Union of all primitives
|
|
140
|
+
*/
|
|
141
|
+
export type Primitive =
|
|
142
|
+
| ColPrimitive
|
|
143
|
+
| RowPrimitive
|
|
144
|
+
| BoxPrimitive
|
|
145
|
+
| SpacerPrimitive
|
|
146
|
+
| SlotPrimitive
|
|
147
|
+
| TextPrimitive
|
|
148
|
+
| IconPrimitive
|
|
149
|
+
| ImagePrimitive
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Parsed primitive with original string
|
|
153
|
+
*/
|
|
154
|
+
export interface ParsedPrimitive<T extends Primitive = Primitive> {
|
|
155
|
+
primitive: T
|
|
156
|
+
raw: string
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Template node - container or leaf
|
|
161
|
+
*/
|
|
162
|
+
export interface TemplateContainerNode {
|
|
163
|
+
type: string // Primitive string like "$col(gap:lg)"
|
|
164
|
+
children?: Record<string, TemplateNode>
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface TemplateLeafNode {
|
|
168
|
+
value: string // Primitive or ref like "$text(label)" or "components/button"
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export type TemplateNode = TemplateContainerNode | string
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Template root structure
|
|
175
|
+
*/
|
|
176
|
+
export interface Template {
|
|
177
|
+
root: TemplateNode
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Slots mapping: state name -> content ref
|
|
182
|
+
*/
|
|
183
|
+
export type Slots = Record<string, Record<string, string>>
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Screen v2 config with template and slots
|
|
187
|
+
*/
|
|
188
|
+
export interface ScreenV2Config {
|
|
189
|
+
kind: 'screen'
|
|
190
|
+
id: string
|
|
191
|
+
title: string
|
|
192
|
+
schemaVersion: '2.0'
|
|
193
|
+
states?: Record<string, { description?: string }>
|
|
194
|
+
template: Template
|
|
195
|
+
slots?: Slots
|
|
196
|
+
// Legacy field for backwards compatibility
|
|
197
|
+
layoutByRenderer?: Record<string, unknown>
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Component v2 config with props and template
|
|
202
|
+
*/
|
|
203
|
+
export interface ComponentV2Config {
|
|
204
|
+
kind: 'component'
|
|
205
|
+
id: string
|
|
206
|
+
title: string
|
|
207
|
+
schemaVersion: '2.0'
|
|
208
|
+
props?: Record<string, {
|
|
209
|
+
type?: string
|
|
210
|
+
required?: boolean
|
|
211
|
+
default?: unknown
|
|
212
|
+
values?: unknown[]
|
|
213
|
+
}>
|
|
214
|
+
template?: Template
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Check if a string is a primitive (starts with $)
|
|
219
|
+
*/
|
|
220
|
+
export function isPrimitive(value: string): boolean {
|
|
221
|
+
return value.startsWith('$')
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Check if a string is a component/screen/flow ref (contains /)
|
|
226
|
+
*/
|
|
227
|
+
export function isRef(value: string): boolean {
|
|
228
|
+
return value.includes('/') && !value.startsWith('$')
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Check if a template node is a container (has type and children)
|
|
233
|
+
*/
|
|
234
|
+
export function isContainerNode(node: unknown): node is TemplateContainerNode {
|
|
235
|
+
return (
|
|
236
|
+
typeof node === 'object' &&
|
|
237
|
+
node !== null &&
|
|
238
|
+
'type' in node &&
|
|
239
|
+
typeof (node as Record<string, unknown>).type === 'string'
|
|
240
|
+
)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Check if a template node is a leaf (string value)
|
|
245
|
+
*/
|
|
246
|
+
export function isLeafNode(node: unknown): node is string {
|
|
247
|
+
return typeof node === 'string'
|
|
248
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// src/tokens/defaults.test.ts
|
|
2
|
+
import { describe, test, expect, beforeAll } from 'bun:test'
|
|
3
|
+
import { load as parse } from 'js-yaml'
|
|
4
|
+
import { readFileSync } from 'fs'
|
|
5
|
+
import { join } from 'path'
|
|
6
|
+
|
|
7
|
+
interface TokensConfig {
|
|
8
|
+
colors: Record<string, string>
|
|
9
|
+
backgrounds: Record<string, string>
|
|
10
|
+
spacing: Record<string, string>
|
|
11
|
+
typography: {
|
|
12
|
+
sizes: Record<string, string>
|
|
13
|
+
weights: Record<string, number>
|
|
14
|
+
}
|
|
15
|
+
radius: Record<string, string>
|
|
16
|
+
shadows: Record<string, string>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe('defaults.yaml', () => {
|
|
20
|
+
let tokens: TokensConfig
|
|
21
|
+
|
|
22
|
+
beforeAll(() => {
|
|
23
|
+
const content = readFileSync(join(import.meta.dir, 'defaults.yaml'), 'utf-8')
|
|
24
|
+
tokens = parse(content) as TokensConfig
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test('is valid YAML', () => {
|
|
28
|
+
const content = readFileSync(join(import.meta.dir, 'defaults.yaml'), 'utf-8')
|
|
29
|
+
expect(() => parse(content)).not.toThrow()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
test('has all shadcn color tokens', () => {
|
|
33
|
+
expect(tokens.colors).toHaveProperty('primary')
|
|
34
|
+
expect(tokens.colors).toHaveProperty('secondary')
|
|
35
|
+
expect(tokens.colors).toHaveProperty('muted-foreground')
|
|
36
|
+
expect(tokens.colors).toHaveProperty('destructive')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('has spacing scale', () => {
|
|
40
|
+
expect(Object.keys(tokens.spacing)).toEqual(['none', 'xs', 'sm', 'md', 'lg', 'xl', '2xl'])
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('spacing values match Tailwind scale', () => {
|
|
44
|
+
expect(tokens.spacing.none).toBe('0')
|
|
45
|
+
expect(tokens.spacing.xs).toBe('4px')
|
|
46
|
+
expect(tokens.spacing.sm).toBe('8px')
|
|
47
|
+
expect(tokens.spacing.md).toBe('16px')
|
|
48
|
+
expect(tokens.spacing.lg).toBe('24px')
|
|
49
|
+
expect(tokens.spacing.xl).toBe('32px')
|
|
50
|
+
expect(tokens.spacing['2xl']).toBe('48px')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('has all shadcn foreground tokens', () => {
|
|
54
|
+
expect(tokens.colors).toHaveProperty('foreground')
|
|
55
|
+
expect(tokens.colors).toHaveProperty('card-foreground')
|
|
56
|
+
expect(tokens.colors).toHaveProperty('primary-foreground')
|
|
57
|
+
expect(tokens.colors).toHaveProperty('secondary-foreground')
|
|
58
|
+
expect(tokens.colors).toHaveProperty('accent-foreground')
|
|
59
|
+
expect(tokens.colors).toHaveProperty('destructive-foreground')
|
|
60
|
+
expect(tokens.colors).toHaveProperty('popover-foreground')
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('has border and ring tokens', () => {
|
|
64
|
+
expect(tokens.colors).toHaveProperty('border')
|
|
65
|
+
expect(tokens.colors).toHaveProperty('ring')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('primary color is blue', () => {
|
|
69
|
+
expect(tokens.colors.primary).toBe('#2563eb')
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test('destructive color is red', () => {
|
|
73
|
+
expect(tokens.colors.destructive).toBe('#ef4444')
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
test('has typography sizes', () => {
|
|
77
|
+
expect(Object.keys(tokens.typography.sizes)).toEqual(['xs', 'sm', 'base', 'lg', 'xl', '2xl'])
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
test('typography size values are correct', () => {
|
|
81
|
+
expect(tokens.typography.sizes.xs).toBe('12px')
|
|
82
|
+
expect(tokens.typography.sizes.sm).toBe('14px')
|
|
83
|
+
expect(tokens.typography.sizes.base).toBe('16px')
|
|
84
|
+
expect(tokens.typography.sizes.lg).toBe('18px')
|
|
85
|
+
expect(tokens.typography.sizes.xl).toBe('20px')
|
|
86
|
+
expect(tokens.typography.sizes['2xl']).toBe('24px')
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('has typography weights', () => {
|
|
90
|
+
expect(Object.keys(tokens.typography.weights)).toEqual(['normal', 'medium', 'semibold', 'bold'])
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
test('typography weight values are correct', () => {
|
|
94
|
+
expect(tokens.typography.weights.normal).toBe(400)
|
|
95
|
+
expect(tokens.typography.weights.medium).toBe(500)
|
|
96
|
+
expect(tokens.typography.weights.semibold).toBe(600)
|
|
97
|
+
expect(tokens.typography.weights.bold).toBe(700)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test('has radius scale', () => {
|
|
101
|
+
expect(Object.keys(tokens.radius)).toEqual(['none', 'sm', 'md', 'lg', 'xl', 'full'])
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
test('radius values are correct', () => {
|
|
105
|
+
expect(tokens.radius.none).toBe('0')
|
|
106
|
+
expect(tokens.radius.sm).toBe('4px')
|
|
107
|
+
expect(tokens.radius.md).toBe('6px')
|
|
108
|
+
expect(tokens.radius.lg).toBe('8px')
|
|
109
|
+
expect(tokens.radius.xl).toBe('12px')
|
|
110
|
+
expect(tokens.radius.full).toBe('9999px')
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
test('has shadow scale', () => {
|
|
114
|
+
expect(Object.keys(tokens.shadows)).toEqual(['none', 'sm', 'md', 'lg', 'xl'])
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
test('has background tokens', () => {
|
|
118
|
+
expect(tokens.backgrounds).toHaveProperty('transparent')
|
|
119
|
+
expect(tokens.backgrounds).toHaveProperty('background')
|
|
120
|
+
expect(tokens.backgrounds).toHaveProperty('card')
|
|
121
|
+
expect(tokens.backgrounds).toHaveProperty('primary')
|
|
122
|
+
expect(tokens.backgrounds).toHaveProperty('secondary')
|
|
123
|
+
expect(tokens.backgrounds).toHaveProperty('muted')
|
|
124
|
+
expect(tokens.backgrounds).toHaveProperty('accent')
|
|
125
|
+
expect(tokens.backgrounds).toHaveProperty('destructive')
|
|
126
|
+
expect(tokens.backgrounds).toHaveProperty('input')
|
|
127
|
+
expect(tokens.backgrounds).toHaveProperty('popover')
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
test('background values are correct', () => {
|
|
131
|
+
expect(tokens.backgrounds.transparent).toBe('transparent')
|
|
132
|
+
expect(tokens.backgrounds.background).toBe('#ffffff')
|
|
133
|
+
expect(tokens.backgrounds.card).toBe('#ffffff')
|
|
134
|
+
expect(tokens.backgrounds.popover).toBe('#ffffff')
|
|
135
|
+
expect(tokens.backgrounds.primary).toBe('#2563eb')
|
|
136
|
+
})
|
|
137
|
+
})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// src/tokens/defaults.ts
|
|
2
|
+
// Default shadcn design tokens for prev-cli
|
|
3
|
+
// Users can override these in their project's tokens.yaml
|
|
4
|
+
|
|
5
|
+
import type { TokensConfig } from './resolver'
|
|
6
|
+
|
|
7
|
+
export const DEFAULT_TOKENS: TokensConfig = {
|
|
8
|
+
colors: {
|
|
9
|
+
foreground: "#0f172a",
|
|
10
|
+
"card-foreground": "#0f172a",
|
|
11
|
+
"popover-foreground": "#0f172a",
|
|
12
|
+
primary: "#2563eb",
|
|
13
|
+
"primary-foreground": "#ffffff",
|
|
14
|
+
secondary: "#64748b",
|
|
15
|
+
"secondary-foreground": "#0f172a",
|
|
16
|
+
muted: "#94a3b8",
|
|
17
|
+
"muted-foreground": "#64748b",
|
|
18
|
+
accent: "#2563eb",
|
|
19
|
+
"accent-foreground": "#ffffff",
|
|
20
|
+
destructive: "#ef4444",
|
|
21
|
+
"destructive-foreground": "#ffffff",
|
|
22
|
+
border: "#e2e8f0",
|
|
23
|
+
ring: "#2563eb",
|
|
24
|
+
},
|
|
25
|
+
backgrounds: {
|
|
26
|
+
transparent: "transparent",
|
|
27
|
+
background: "#ffffff",
|
|
28
|
+
card: "#ffffff",
|
|
29
|
+
popover: "#ffffff",
|
|
30
|
+
primary: "#2563eb",
|
|
31
|
+
secondary: "#f1f5f9",
|
|
32
|
+
muted: "#f1f5f9",
|
|
33
|
+
accent: "#f1f5f9",
|
|
34
|
+
destructive: "#ef4444",
|
|
35
|
+
input: "#ffffff",
|
|
36
|
+
},
|
|
37
|
+
spacing: {
|
|
38
|
+
none: "0",
|
|
39
|
+
xs: "4px",
|
|
40
|
+
sm: "8px",
|
|
41
|
+
md: "16px",
|
|
42
|
+
lg: "24px",
|
|
43
|
+
xl: "32px",
|
|
44
|
+
"2xl": "48px",
|
|
45
|
+
},
|
|
46
|
+
typography: {
|
|
47
|
+
sizes: {
|
|
48
|
+
xs: "12px",
|
|
49
|
+
sm: "14px",
|
|
50
|
+
base: "16px",
|
|
51
|
+
lg: "18px",
|
|
52
|
+
xl: "20px",
|
|
53
|
+
"2xl": "24px",
|
|
54
|
+
},
|
|
55
|
+
weights: {
|
|
56
|
+
normal: 400,
|
|
57
|
+
medium: 500,
|
|
58
|
+
semibold: 600,
|
|
59
|
+
bold: 700,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
radius: {
|
|
63
|
+
none: "0",
|
|
64
|
+
sm: "4px",
|
|
65
|
+
md: "6px",
|
|
66
|
+
lg: "8px",
|
|
67
|
+
xl: "12px",
|
|
68
|
+
full: "9999px",
|
|
69
|
+
},
|
|
70
|
+
shadows: {
|
|
71
|
+
none: "none",
|
|
72
|
+
sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
|
|
73
|
+
md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
|
|
74
|
+
lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
|
|
75
|
+
xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
|
|
76
|
+
},
|
|
77
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# src/tokens/defaults.yaml
|
|
2
|
+
# Default shadcn design tokens for prev-cli
|
|
3
|
+
# Users can override these in their project's tokens.yaml
|
|
4
|
+
|
|
5
|
+
# Semantic color tokens
|
|
6
|
+
colors:
|
|
7
|
+
foreground: "#0f172a"
|
|
8
|
+
card-foreground: "#0f172a"
|
|
9
|
+
popover-foreground: "#0f172a"
|
|
10
|
+
primary: "#2563eb"
|
|
11
|
+
primary-foreground: "#ffffff"
|
|
12
|
+
secondary: "#64748b"
|
|
13
|
+
secondary-foreground: "#0f172a"
|
|
14
|
+
muted: "#94a3b8"
|
|
15
|
+
muted-foreground: "#64748b"
|
|
16
|
+
accent: "#2563eb"
|
|
17
|
+
accent-foreground: "#ffffff"
|
|
18
|
+
destructive: "#ef4444"
|
|
19
|
+
destructive-foreground: "#ffffff"
|
|
20
|
+
border: "#e2e8f0"
|
|
21
|
+
ring: "#2563eb"
|
|
22
|
+
|
|
23
|
+
# Background tokens
|
|
24
|
+
backgrounds:
|
|
25
|
+
transparent: transparent
|
|
26
|
+
background: "#ffffff"
|
|
27
|
+
card: "#ffffff"
|
|
28
|
+
popover: "#ffffff"
|
|
29
|
+
primary: "#2563eb"
|
|
30
|
+
secondary: "#f1f5f9"
|
|
31
|
+
muted: "#f1f5f9"
|
|
32
|
+
accent: "#f1f5f9"
|
|
33
|
+
destructive: "#ef4444"
|
|
34
|
+
input: "#ffffff"
|
|
35
|
+
|
|
36
|
+
# Spacing scale
|
|
37
|
+
spacing:
|
|
38
|
+
none: "0"
|
|
39
|
+
xs: "4px"
|
|
40
|
+
sm: "8px"
|
|
41
|
+
md: "16px"
|
|
42
|
+
lg: "24px"
|
|
43
|
+
xl: "32px"
|
|
44
|
+
2xl: "48px"
|
|
45
|
+
|
|
46
|
+
# Typography
|
|
47
|
+
typography:
|
|
48
|
+
sizes:
|
|
49
|
+
xs: "12px"
|
|
50
|
+
sm: "14px"
|
|
51
|
+
base: "16px"
|
|
52
|
+
lg: "18px"
|
|
53
|
+
xl: "20px"
|
|
54
|
+
2xl: "24px"
|
|
55
|
+
weights:
|
|
56
|
+
normal: 400
|
|
57
|
+
medium: 500
|
|
58
|
+
semibold: 600
|
|
59
|
+
bold: 700
|
|
60
|
+
|
|
61
|
+
# Border radius scale
|
|
62
|
+
radius:
|
|
63
|
+
none: "0"
|
|
64
|
+
sm: "4px"
|
|
65
|
+
md: "6px"
|
|
66
|
+
lg: "8px"
|
|
67
|
+
xl: "12px"
|
|
68
|
+
full: "9999px"
|
|
69
|
+
|
|
70
|
+
# Shadow scale
|
|
71
|
+
shadows:
|
|
72
|
+
none: none
|
|
73
|
+
sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)"
|
|
74
|
+
md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"
|
|
75
|
+
lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
|
|
76
|
+
xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"
|