Skip to content

Commit 7c713f2

Browse files
committed
feat(cli): show semantic tokens and named themes in panda studio
1 parent 674f178 commit 7c713f2

5 files changed

Lines changed: 250 additions & 25 deletions

File tree

.changeset/cli-studio-semantic.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@pandacss/cli': patch
3+
---
4+
5+
Show semantic tokens in `panda studio`. Each semantic token renders a swatch per condition (`base`, `_dark`, …) and per named theme, resolved to real values, so you can see what a token becomes in every mode.

packages/cli/__tests__/studio.test.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import { existsSync, readFileSync } from 'node:fs'
22
import { join } from 'node:path'
33
import { afterEach, describe, expect, it } from 'vitest'
4-
import { buildTokensSnapshot, runStudioGenerate, runStudioServe, viewFiles, viewerFiles } from '../src'
4+
import {
5+
buildSemanticMap,
6+
buildTokensSnapshot,
7+
runStudioGenerate,
8+
runStudioServe,
9+
viewFiles,
10+
viewerFiles,
11+
} from '../src'
512
import type { StudioToken } from '../src'
613
import { cleanupFixture, createFixture } from './helpers'
714

@@ -119,3 +126,34 @@ describe('studio viewer', () => {
119126
}
120127
})
121128
})
129+
130+
describe('studio semantic tokens', () => {
131+
const spec = { tokens: { categories: {}, values: { 'colors.white': '#fff', 'colors.black': '#000' } } } as never
132+
const config = {
133+
theme: { semanticTokens: { colors: { bg: { value: { base: '{colors.white}', _dark: '{colors.black}' } } } } },
134+
themes: { ocean: { semanticTokens: { colors: { bg: { value: { base: '#e0f2fe' } } } } } },
135+
}
136+
137+
it('resolves semantic conditions and named themes against token values', () => {
138+
expect(buildSemanticMap(spec, config)).toEqual({
139+
'colors.bg': { base: '#fff', _dark: '#000', 'ocean · base': '#e0f2fe' },
140+
})
141+
})
142+
143+
it('emits semantic tokens with conditions, base as the display value', () => {
144+
const semantic = buildSemanticMap(spec, config)
145+
const tokens = buildTokensSnapshot(spec, semantic)
146+
const bg = tokens.find((token) => token.path === 'colors.bg')
147+
expect(bg).toMatchObject({ category: 'colors', name: 'bg', value: '#fff' })
148+
expect(bg?.conditions).toEqual({ base: '#fff', _dark: '#000', 'ocean · base': '#e0f2fe' })
149+
})
150+
151+
it('keeps semantic paths out of the primitive list', () => {
152+
const specWithSemantic = {
153+
tokens: { categories: { colors: { values: ['bg'] } }, values: { 'colors.bg': 'var(--colors-white)' } },
154+
} as never
155+
const tokens = buildTokensSnapshot(specWithSemantic, { 'colors.bg': { base: '#fff' } })
156+
expect(tokens.filter((token) => token.path === 'colors.bg')).toHaveLength(1)
157+
expect(tokens[0].value).toBe('#fff')
158+
})
159+
})

packages/cli/src/commands/studio.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { studioGenerateFlagsSchema, studioServeFlagsSchema } from '../schema'
1010
import type { StudioGenerateFlags, StudioGenerateResult, StudioServeFlags, StudioServeResult } from '../schema'
1111
import { serveStudio, type StudioServer } from '../studio-server'
1212
import {
13+
buildSemanticMap,
1314
buildTokensSnapshot,
1415
keyframesToCss,
1516
viewFiles,
@@ -58,7 +59,8 @@ export async function runStudioGenerate(
5859
failData: () => ({ files: [], framework: 'react' as StudioFramework }),
5960
async execute(ctx) {
6061
const framework = resolveFramework(ctx.driver.config.jsxFramework)
61-
const tokens = buildTokensSnapshot(ctx.driver.compiler.spec())
62+
const spec = ctx.driver.compiler.spec()
63+
const tokens = buildTokensSnapshot(spec, buildSemanticMap(spec, ctx.driver.config))
6264
const keyframes = keyframesToCss(readKeyframes(ctx.driver.config))
6365
const outdir = flags.outdir ? ctx.driver.resolvePath(flags.outdir) : join(ctx.driver.getOutdir(), 'studio')
6466

@@ -86,7 +88,8 @@ export async function runStudioServe(
8688
keepTracing: true,
8789
failData: () => ({}),
8890
async execute(ctx) {
89-
const tokens = buildTokensSnapshot(ctx.driver.compiler.spec())
91+
const spec = ctx.driver.compiler.spec()
92+
const tokens = buildTokensSnapshot(spec, buildSemanticMap(spec, ctx.driver.config))
9093
const keyframes = keyframesToCss(readKeyframes(ctx.driver.config))
9194
const dir = mkdtempSync(join(tmpdir(), 'panda-studio-'))
9295
writeStudioFiles(dir, viewerFiles(tokens, keyframes))

packages/cli/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export { runAnalyze } from './commands/analyze'
99
export { infoDriver, runInfo } from './commands/info'
1010
export { runInit, setupGitIgnore } from './commands/init'
1111
export { runStudioGenerate, runStudioServe } from './commands/studio'
12-
export { buildTokensSnapshot, viewFiles, viewerFiles } from './studio-codegen'
12+
export { buildSemanticMap, buildTokensSnapshot, keyframesToCss, viewFiles, viewerFiles } from './studio-codegen'
1313
export type { StudioToken, StudioFile, StudioFramework } from './studio-codegen'
1414
export { serveStudio } from './studio-server'
1515
export type {

0 commit comments

Comments
 (0)