Skip to content

Commit 3f5fea2

Browse files
committed
refactor: spec command
1 parent b6e9646 commit 3f5fea2

File tree

16 files changed

+1261
-194
lines changed

16 files changed

+1261
-194
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@pandacss/generator': patch
3+
---
4+
5+
### Spec
6+
7+
- Fixed issue in recipe specs where boolean variant values were incorrectly formatted with quotes (e.g.,
8+
`button({ primary: true })` instead of `button({ primary: 'true' })`)
9+
- Updated color palette spec generation to dynamically discover and use actual available tokens
Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
import { describe, expect, test } from 'vitest'
2+
import { createContext } from '@pandacss/fixture'
3+
import { generateColorPaletteSpec } from '../src/spec/color-palette'
4+
5+
describe('color palette spec generation', () => {
6+
test('should generate color palette spec with numeric shades', () => {
7+
const ctx = createContext({
8+
eject: true,
9+
theme: {
10+
tokens: {
11+
colors: {
12+
blue: {
13+
50: { value: '#eff6ff' },
14+
100: { value: '#dbeafe' },
15+
200: { value: '#bfdbfe' },
16+
300: { value: '#93c5fd' },
17+
400: { value: '#60a5fa' },
18+
500: { value: '#3b82f6' },
19+
600: { value: '#2563eb' },
20+
700: { value: '#1d4ed8' },
21+
800: { value: '#1e40af' },
22+
900: { value: '#1e3a8a' },
23+
},
24+
red: {
25+
500: { value: '#ef4444' },
26+
},
27+
},
28+
},
29+
},
30+
})
31+
32+
const spec = generateColorPaletteSpec(ctx)
33+
expect(spec).toMatchInlineSnapshot(`
34+
{
35+
"data": {
36+
"functionExamples": [
37+
"css({ colorPalette: 'blue' })",
38+
"css({ colorPalette: 'blue', bg: 'colorPalette.100', color: 'colorPalette.200' })",
39+
],
40+
"jsxExamples": [
41+
"<Box colorPalette="blue" />",
42+
"<Box colorPalette="blue" bg="colorPalette.100" color="colorPalette.200" />",
43+
],
44+
"values": [
45+
"blue",
46+
"red",
47+
],
48+
},
49+
"type": "color-palette",
50+
}
51+
`)
52+
})
53+
54+
test('should generate color palette spec with non-numeric tokens', () => {
55+
const ctx = createContext({
56+
eject: true,
57+
theme: {
58+
tokens: {
59+
colors: {
60+
brand: {
61+
primary: { value: '#0066cc' },
62+
secondary: { value: '#6699ff' },
63+
tertiary: { value: '#003366' },
64+
},
65+
ui: {
66+
background: { value: '#ffffff' },
67+
text: { value: '#333333' },
68+
border: { value: '#e0e0e0' },
69+
},
70+
},
71+
},
72+
},
73+
})
74+
75+
const spec = generateColorPaletteSpec(ctx)
76+
expect(spec).toMatchInlineSnapshot(`
77+
{
78+
"data": {
79+
"functionExamples": [
80+
"css({ colorPalette: 'brand' })",
81+
"css({ colorPalette: 'brand', bg: 'colorPalette.primary', color: 'colorPalette.secondary' })",
82+
],
83+
"jsxExamples": [
84+
"<Box colorPalette="brand" />",
85+
"<Box colorPalette="brand" bg="colorPalette.primary" color="colorPalette.secondary" />",
86+
],
87+
"values": [
88+
"brand",
89+
"ui",
90+
],
91+
},
92+
"type": "color-palette",
93+
}
94+
`)
95+
})
96+
97+
test('should generate color palette spec with mixed token types', () => {
98+
const ctx = createContext({
99+
eject: true,
100+
theme: {
101+
tokens: {
102+
colors: {
103+
accent: {
104+
DEFAULT: { value: '#8b5cf6' },
105+
hover: { value: '#7c3aed' },
106+
active: { value: '#6d28d9' },
107+
disabled: { value: '#c4b5fd' },
108+
},
109+
neutral: {
110+
50: { value: '#fafafa' },
111+
100: { value: '#f5f5f5' },
112+
base: { value: '#737373' },
113+
dark: { value: '#404040' },
114+
},
115+
},
116+
},
117+
},
118+
})
119+
120+
const spec = generateColorPaletteSpec(ctx)
121+
expect(spec).toMatchInlineSnapshot(`
122+
{
123+
"data": {
124+
"functionExamples": [
125+
"css({ colorPalette: 'accent' })",
126+
"css({ colorPalette: 'accent', bg: 'colorPalette', color: 'colorPalette.active' })",
127+
],
128+
"jsxExamples": [
129+
"<Box colorPalette="accent" />",
130+
"<Box colorPalette="accent" bg="colorPalette" color="colorPalette.active" />",
131+
],
132+
"values": [
133+
"accent",
134+
"neutral",
135+
],
136+
},
137+
"type": "color-palette",
138+
}
139+
`)
140+
})
141+
142+
test('should handle single token in color palette', () => {
143+
const ctx = createContext({
144+
eject: true,
145+
theme: {
146+
tokens: {
147+
colors: {
148+
primary: { value: '#0066cc' },
149+
},
150+
},
151+
},
152+
})
153+
154+
const spec = generateColorPaletteSpec(ctx)
155+
expect(spec).toMatchInlineSnapshot(`
156+
{
157+
"data": {
158+
"functionExamples": [
159+
"css({ colorPalette: 'primary' })",
160+
"css({ colorPalette: 'primary', bg: 'colorPalette' })",
161+
],
162+
"jsxExamples": [
163+
"<Box colorPalette="primary" />",
164+
"<Box colorPalette="primary" bg="colorPalette" />",
165+
],
166+
"values": [
167+
"primary",
168+
],
169+
},
170+
"type": "color-palette",
171+
}
172+
`)
173+
})
174+
175+
test('should handle color palette with no virtual tokens', () => {
176+
const ctx = createContext({
177+
eject: true,
178+
theme: {
179+
tokens: {
180+
colors: {
181+
basic: {
182+
red: { value: '#ff0000' },
183+
green: { value: '#00ff00' },
184+
blue: { value: '#0000ff' },
185+
},
186+
},
187+
},
188+
},
189+
})
190+
191+
const spec = generateColorPaletteSpec(ctx)
192+
expect(spec).toMatchInlineSnapshot(`
193+
{
194+
"data": {
195+
"functionExamples": [
196+
"css({ colorPalette: 'basic' })",
197+
"css({ colorPalette: 'basic', bg: 'colorPalette.blue', color: 'colorPalette.green' })",
198+
],
199+
"jsxExamples": [
200+
"<Box colorPalette="basic" />",
201+
"<Box colorPalette="basic" bg="colorPalette.blue" color="colorPalette.green" />",
202+
],
203+
"values": [
204+
"basic",
205+
],
206+
},
207+
"type": "color-palette",
208+
}
209+
`)
210+
})
211+
212+
test('should handle jsxStyleProps minimal setting', () => {
213+
const ctx = createContext({
214+
eject: true,
215+
jsxStyleProps: 'minimal',
216+
theme: {
217+
tokens: {
218+
colors: {
219+
theme: {
220+
light: { value: '#f8f9fa' },
221+
dark: { value: '#212529' },
222+
},
223+
},
224+
},
225+
},
226+
})
227+
228+
const spec = generateColorPaletteSpec(ctx)
229+
expect(spec).toMatchInlineSnapshot(`
230+
{
231+
"data": {
232+
"functionExamples": [
233+
"css({ colorPalette: 'theme' })",
234+
"css({ colorPalette: 'theme', bg: 'colorPalette.dark', color: 'colorPalette.light' })",
235+
],
236+
"jsxExamples": [
237+
"<Box css={{ colorPalette: 'theme' }} />",
238+
"<Box css={{ colorPalette: 'theme', bg: 'colorPalette.dark', color: 'colorPalette.light' }} />",
239+
],
240+
"values": [
241+
"theme",
242+
],
243+
},
244+
"type": "color-palette",
245+
}
246+
`)
247+
})
248+
249+
test('should handle jsxStyleProps none setting', () => {
250+
const ctx = createContext({
251+
eject: true,
252+
jsxStyleProps: 'none',
253+
theme: {
254+
tokens: {
255+
colors: {
256+
status: {
257+
success: { value: '#10b981' },
258+
error: { value: '#ef4444' },
259+
},
260+
},
261+
},
262+
},
263+
})
264+
265+
const spec = generateColorPaletteSpec(ctx)
266+
expect(spec).toMatchInlineSnapshot(`
267+
{
268+
"data": {
269+
"functionExamples": [
270+
"css({ colorPalette: 'status' })",
271+
"css({ colorPalette: 'status', bg: 'colorPalette.error', color: 'colorPalette.success' })",
272+
],
273+
"jsxExamples": [],
274+
"values": [
275+
"status",
276+
],
277+
},
278+
"type": "color-palette",
279+
}
280+
`)
281+
})
282+
283+
test('should handle disabled color palette', () => {
284+
const ctx = createContext({
285+
eject: true,
286+
theme: {
287+
colorPalette: {
288+
enabled: false,
289+
},
290+
tokens: {
291+
colors: {
292+
primary: { value: '#0066cc' },
293+
},
294+
},
295+
},
296+
})
297+
298+
const spec = generateColorPaletteSpec(ctx)
299+
expect(spec).toBeNull()
300+
})
301+
302+
test('should handle deeply nested color tokens', () => {
303+
const ctx = createContext({
304+
eject: true,
305+
theme: {
306+
tokens: {
307+
colors: {
308+
theme: {
309+
primary: {
310+
base: { value: '#3b82f6' },
311+
hover: { value: '#2563eb' },
312+
active: { value: '#1d4ed8' },
313+
},
314+
secondary: {
315+
base: { value: '#8b5cf6' },
316+
hover: { value: '#7c3aed' },
317+
},
318+
},
319+
},
320+
},
321+
},
322+
})
323+
324+
const spec = generateColorPaletteSpec(ctx)
325+
expect(spec).toMatchInlineSnapshot(`
326+
{
327+
"data": {
328+
"functionExamples": [
329+
"css({ colorPalette: 'theme' })",
330+
"css({ colorPalette: 'theme', bg: 'colorPalette.primary.active', color: 'colorPalette.primary.base' })",
331+
],
332+
"jsxExamples": [
333+
"<Box colorPalette="theme" />",
334+
"<Box colorPalette="theme" bg="colorPalette.primary.active" color="colorPalette.primary.base" />",
335+
],
336+
"values": [
337+
"theme",
338+
"theme.primary",
339+
"theme.secondary",
340+
],
341+
},
342+
"type": "color-palette",
343+
}
344+
`)
345+
})
346+
})

0 commit comments

Comments
 (0)