Skip to content

Commit

Permalink
refactor: packages/core factories (#1929)
Browse files Browse the repository at this point in the history
* refactor: core

* docs: add changelog
  • Loading branch information
segunadebayo authored Jan 3, 2024
1 parent c8ff825 commit 61ebf3d
Show file tree
Hide file tree
Showing 26 changed files with 749 additions and 373 deletions.
5 changes: 5 additions & 0 deletions .changeset/spotty-ducks-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@pandacss/core': patch
---

Fix issue where config slot recipes with compound variants were not processed correctly
74 changes: 46 additions & 28 deletions packages/core/__tests__/rule-processor.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { describe, expect, test } from 'vitest'
import { createRuleProcessor } from './fixture'
import type { Dict } from '@pandacss/types'
import { createGeneratorContext } from '@pandacss/fixture'
import type { Dict, RecipeDefinition, SlotRecipeDefinition } from '@pandacss/types'
import { describe, expect, test } from 'vitest'
import { RuleProcessor } from '../src/rule-processor'
import { createRuleProcessor } from './fixture'

const css = (styles: Dict) => {
const result = createRuleProcessor().css(styles)
Expand All @@ -14,11 +14,16 @@ const recipe = (name: string, styles: Dict) => {
return { className: result.className, css: result.toCss() }
}

const cva = (styles: Dict) => {
const cva = (styles: RecipeDefinition) => {
const result = createRuleProcessor().cva(styles)!
return { className: result.className, css: result.toCss() }
}

const sva = (styles: SlotRecipeDefinition) => {
const result = createRuleProcessor().sva(styles)!
return { className: result.className, css: result.toCss() }
}

const buttonRecipe = {
className: 'btn',
base: {
Expand Down Expand Up @@ -506,7 +511,7 @@ describe('rule processor', () => {

test('sva', () => {
// packages/fixture/src/slot-recipes.ts
const checkbox = cva({
const checkbox = sva({
slots: ['root', 'control', 'label'],
base: {
root: { display: 'flex', alignItems: 'center', gap: '2' },
Expand Down Expand Up @@ -781,8 +786,14 @@ describe('rule processor', () => {
const processor = new RuleProcessor(ctx as any)

const step1 = processor.prepare()
step1.encoder.fromJSON(JSON.stringify({ styles: { atomic: ['color]___[value:red', 'color]___[value:blue'] } }))

step1.encoder.fromJSON({
schemaVersion: 'x',
styles: { atomic: ['color]___[value:red', 'color]___[value:blue'] },
})

step1.decoder.collect(step1.encoder)

expect(processor.toCss()).toMatchInlineSnapshot(`
"@layer utilities {
.text_red {
Expand All @@ -796,8 +807,14 @@ describe('rule processor', () => {
`)

const step2 = processor.prepare()
step2.encoder.fromJSON(JSON.stringify({ styles: { recipes: { buttonStyle: ['variant]___[value:solid'] } } }))

step2.encoder.fromJSON({
schemaVersion: 'x',
styles: { recipes: { buttonStyle: ['variant]___[value:solid'] } },
})

step2.decoder.collect(step2.encoder)

expect(processor.toCss()).toMatchInlineSnapshot(`
"@layer recipes {
.variant_solid {
Expand Down Expand Up @@ -830,29 +847,30 @@ describe('rule processor', () => {
`)

const step3 = processor.prepare()
step3.encoder.fromJSON(
JSON.stringify({
styles: {
atomic: [
'display]___[value:none',
'height]___[value:100%',
'transition]___[value:all .3s ease-in-out',
'opacity]___[value:0 !important',
'opacity]___[value:1',
'height]___[value:10px',
'backgroundGradient]___[value:to-b',
'gradientFrom]___[value:rgb(200 200 200 / .4)',

step3.encoder.fromJSON({
schemaVersion: 'x',
styles: {
atomic: [
'display]___[value:none',
'height]___[value:100%',
'transition]___[value:all .3s ease-in-out',
'opacity]___[value:0 !important',
'opacity]___[value:1',
'height]___[value:10px',
'backgroundGradient]___[value:to-b',
'gradientFrom]___[value:rgb(200 200 200 / .4)',
],
recipes: {
checkbox: [
'size]___[value:md]___[recipe:checkbox]___[slot:container',
'size]___[value:md]___[recipe:checkbox]___[slot:control',
'size]___[value:md]___[recipe:checkbox]___[slot:label',
],
recipes: {
checkbox: [
'size]___[value:md]___[recipe:checkbox]___[slot:container',
'size]___[value:md]___[recipe:checkbox]___[slot:control',
'size]___[value:md]___[recipe:checkbox]___[slot:label',
],
},
},
}),
)
},
})

step3.decoder.collect(step3.encoder)
expect(step3.toCss()).toMatchInlineSnapshot(`
"@layer recipes {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/__tests__/static-css.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, test } from 'vitest'
import { fixtureDefaults } from '@pandacss/fixture'
import { type StaticCssOptions } from '@pandacss/types'
import { describe, expect, test } from 'vitest'
import { CoreContext } from '../src/core-context'

describe('static-css', () => {
Expand Down
122 changes: 66 additions & 56 deletions packages/core/__tests__/style-decoder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import type { Dict } from '@pandacss/types'
import { describe, expect, test } from 'vitest'
import { createRuleProcessor } from './fixture'

/* -----------------------------------------------------------------------------
* Test Setup
* -----------------------------------------------------------------------------*/

const css = (styles: Dict) => {
const ctx = createGeneratorContext()
ctx.encoder.processAtomic(styles)
Expand All @@ -12,35 +16,29 @@ const css = (styles: Dict) => {

const recipe = (name: string, styles: Dict) => {
const ctx = createGeneratorContext()
const recipeConfig = ctx.recipes.getConfig(name)
if (!recipeConfig) throw new Error(`Recipe ${name} not found`)

ctx.encoder.processRecipe(name, styles)
ctx.decoder.collect(ctx.encoder)

if ('slots' in recipeConfig) {
const base = {} as Dict
recipeConfig.slots.map((slot) => {
const recipeKey = ctx.recipes.getSlotKey(name, slot)
base[slot] = ctx.decoder.recipes_base.get(recipeKey)!
})
return { base, variants: ctx.decoder.recipes.get(name)! }
}

return { base: ctx.decoder.recipes_base.get(name)!, variants: ctx.decoder.recipes.get(name)! }
return ctx.decoder.getRecipeResult(name)
}

const cva = (styles: Dict) => {
const ctx = createGeneratorContext()
if ('slots' in styles) {
ctx.encoder.processAtomicSlotRecipe(styles)
}

ctx.encoder.processAtomicRecipe(styles)
ctx.decoder.collect(ctx.encoder)
return ctx.decoder.atomic
}

const sva = (styles: Dict) => {
const ctx = createGeneratorContext()
ctx.encoder.processAtomicSlotRecipe(styles)
ctx.decoder.collect(ctx.encoder)
return ctx.decoder.atomic
}

/* -----------------------------------------------------------------------------
* Actual Tests
* -----------------------------------------------------------------------------*/

describe('style decoder', () => {
test('css', () => {
const result = css({
Expand Down Expand Up @@ -1582,7 +1580,7 @@ describe('style decoder', () => {

test('sva', () => {
// packages/fixture/src/slot-recipes.ts
const checkbox = cva({
const checkbox = sva({
slots: ['root', 'control', 'label'],
base: {
root: { display: 'flex', alignItems: 'center', gap: '2' },
Expand Down Expand Up @@ -1884,7 +1882,10 @@ describe('style decoder', () => {
const encoder = ctx.encoder
const decoder = ctx.decoder

encoder.fromJSON(JSON.stringify({ styles: { atomic: ['color]___[value:red', 'color]___[value:blue'] } }))
encoder.fromJSON({
schemaVersion: 'x',
styles: { atomic: ['color]___[value:red', 'color]___[value:blue'] },
})

expect(decoder.collect(encoder).atomic).toMatchInlineSnapshot(`
Set {
Expand Down Expand Up @@ -1921,7 +1922,10 @@ describe('style decoder', () => {
}
`)

encoder.fromJSON(JSON.stringify({ styles: { recipes: { buttonStyle: ['variant]___[value:solid'] } } }))
encoder.fromJSON({
schemaVersion: 'x',
styles: { recipes: { buttonStyle: ['variant]___[value:solid'] } },
})

expect(decoder.collect(encoder).recipes).toMatchInlineSnapshot(`
Map {
Expand Down Expand Up @@ -2108,30 +2112,31 @@ describe('style decoder', () => {
}
`)

const forked = encoder.clone().fromJSON(
JSON.stringify({
styles: {
atomic: [
'display]___[value:none',
'height]___[value:100%',
'transition]___[value:all .3s ease-in-out',
'opacity]___[value:0 !important',
'opacity]___[value:1',
'height]___[value:10px',
'backgroundGradient]___[value:to-b',
'gradientFrom]___[value:rgb(200 200 200 / .4)',
const _encoder = encoder.clone().fromJSON({
schemaVersion: 'x',
styles: {
atomic: [
'display]___[value:none',
'height]___[value:100%',
'transition]___[value:all .3s ease-in-out',
'opacity]___[value:0 !important',
'opacity]___[value:1',
'height]___[value:10px',
'backgroundGradient]___[value:to-b',
'gradientFrom]___[value:rgb(200 200 200 / .4)',
],
recipes: {
checkbox: [
'size]___[value:md]___[recipe:checkbox]___[slot:container',
'size]___[value:md]___[recipe:checkbox]___[slot:control',
'size]___[value:md]___[recipe:checkbox]___[slot:label',
],
recipes: {
checkbox: [
'size]___[value:md]___[recipe:checkbox]___[slot:container',
'size]___[value:md]___[recipe:checkbox]___[slot:control',
'size]___[value:md]___[recipe:checkbox]___[slot:label',
],
},
},
}),
)
expect(decoder.clone().collect(forked).results).toMatchInlineSnapshot(`
},
})

const { results } = decoder.clone().collect(_encoder)
expect(results).toMatchInlineSnapshot(`
{
"atomic": Set {
{
Expand Down Expand Up @@ -2421,9 +2426,10 @@ describe('style decoder', () => {
"entry": {
"prop": "display",
"recipe": "checkbox",
"slot": "root",
"value": "flex",
},
"hash": "display]___[value:flex]___[recipe:checkbox",
"hash": "display]___[value:flex]___[recipe:checkbox]___[slot:root",
"result": {
"display": "flex",
},
Expand All @@ -2433,9 +2439,10 @@ describe('style decoder', () => {
"entry": {
"prop": "alignItems",
"recipe": "checkbox",
"slot": "root",
"value": "center",
},
"hash": "alignItems]___[value:center]___[recipe:checkbox",
"hash": "alignItems]___[value:center]___[recipe:checkbox]___[slot:root",
"result": {
"alignItems": "center",
},
Expand All @@ -2445,18 +2452,19 @@ describe('style decoder', () => {
"entry": {
"prop": "gap",
"recipe": "checkbox",
"slot": "root",
"value": 2,
},
"hash": "gap]___[value:2]___[recipe:checkbox",
"hash": "gap]___[value:2]___[recipe:checkbox]___[slot:root",
"result": {
"gap": "var(--spacing-2)",
},
},
],
"hashSet": Set {
"display]___[value:flex]___[recipe:checkbox",
"alignItems]___[value:center]___[recipe:checkbox",
"gap]___[value:2]___[recipe:checkbox",
"display]___[value:flex]___[recipe:checkbox]___[slot:root",
"alignItems]___[value:center]___[recipe:checkbox]___[slot:root",
"gap]___[value:2]___[recipe:checkbox]___[slot:root",
},
"recipe": "checkbox",
"result": {
Expand All @@ -2478,9 +2486,10 @@ describe('style decoder', () => {
"entry": {
"prop": "borderWidth",
"recipe": "checkbox",
"slot": "control",
"value": "1px",
},
"hash": "borderWidth]___[value:1px]___[recipe:checkbox",
"hash": "borderWidth]___[value:1px]___[recipe:checkbox]___[slot:control",
"result": {
"borderWidth": "1px",
},
Expand All @@ -2490,17 +2499,18 @@ describe('style decoder', () => {
"entry": {
"prop": "borderRadius",
"recipe": "checkbox",
"slot": "control",
"value": "sm",
},
"hash": "borderRadius]___[value:sm]___[recipe:checkbox",
"hash": "borderRadius]___[value:sm]___[recipe:checkbox]___[slot:control",
"result": {
"borderRadius": "var(--radii-sm)",
},
},
],
"hashSet": Set {
"borderWidth]___[value:1px]___[recipe:checkbox",
"borderRadius]___[value:sm]___[recipe:checkbox",
"borderWidth]___[value:1px]___[recipe:checkbox]___[slot:control",
"borderRadius]___[value:sm]___[recipe:checkbox]___[slot:control",
},
"recipe": "checkbox",
"result": {
Expand All @@ -2521,16 +2531,17 @@ describe('style decoder', () => {
"entry": {
"prop": "marginInlineStart",
"recipe": "checkbox",
"slot": "label",
"value": 2,
},
"hash": "marginInlineStart]___[value:2]___[recipe:checkbox",
"hash": "marginInlineStart]___[value:2]___[recipe:checkbox]___[slot:label",
"result": {
"marginInlineStart": "var(--spacing-2)",
},
},
],
"hashSet": Set {
"marginInlineStart]___[value:2]___[recipe:checkbox",
"marginInlineStart]___[value:2]___[recipe:checkbox]___[slot:label",
},
"recipe": "checkbox",
"result": {
Expand All @@ -2548,7 +2559,6 @@ describe('style decoder', () => {

test('css - boolean utility', () => {
const result = css({ truncate: false })

expect(result).toMatchInlineSnapshot(`
Set {
{
Expand Down
Loading

3 comments on commit 61ebf3d

@vercel
Copy link

@vercel vercel bot commented on 61ebf3d Jan 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 61ebf3d Jan 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

panda-studio – ./

panda-studio-chakra-ui.vercel.app
panda-studio-git-main-chakra-ui.vercel.app
panda-app.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 61ebf3d Jan 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

panda-docs – ./website

panda-css.com
panda-docs.vercel.app
panda-docs-git-main-chakra-ui.vercel.app
panda-docs-chakra-ui.vercel.app

Please sign in to comment.