From 248e403a7433c1c8ea0b152b9670462e33a32030 Mon Sep 17 00:00:00 2001 From: seongminn Date: Sat, 21 Mar 2026 15:21:19 +0900 Subject: [PATCH 1/2] fix: support ComplexStyleRule array in recipe base --- .../concentric-order/__tests__/recipe.test.ts | 41 +++++++++++++++++++ .../shared-utils/recipe-property-processor.ts | 16 ++++---- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/css-rules/concentric-order/__tests__/recipe.test.ts b/src/css-rules/concentric-order/__tests__/recipe.test.ts index 0eff340..0704a85 100644 --- a/src/css-rules/concentric-order/__tests__/recipe.test.ts +++ b/src/css-rules/concentric-order/__tests__/recipe.test.ts @@ -41,6 +41,20 @@ run({ } }); `, + + // Recipe with base as array (ComplexStyleRule) + ` + import { recipe } from '@vanilla-extract/recipes'; + + const myRecipe = recipe({ + base: [{ + position: 'relative', + display: 'flex', + backgroundColor: 'white', + width: '100%' + }], + }); + `, ], invalid: [ // Recipe with incorrect ordering @@ -97,5 +111,32 @@ run({ }); `, }, + + // Recipe with base array in incorrect order + { + code: ` + import { recipe } from '@vanilla-extract/recipes'; + const myRecipe = recipe({ + base: [{ + backgroundColor: 'white', + width: '100%', + display: 'flex', + position: 'relative' + }], + }); + `, + errors: [{ messageId: 'incorrectOrder' }], + output: ` + import { recipe } from '@vanilla-extract/recipes'; + const myRecipe = recipe({ + base: [{ + position: 'relative', + display: 'flex', + backgroundColor: 'white', + width: '100%' + }], + }); + `, + }, ], }); diff --git a/src/css-rules/shared-utils/recipe-property-processor.ts b/src/css-rules/shared-utils/recipe-property-processor.ts index 79ae722..beaa8a3 100644 --- a/src/css-rules/shared-utils/recipe-property-processor.ts +++ b/src/css-rules/shared-utils/recipe-property-processor.ts @@ -1,5 +1,6 @@ import type { Rule } from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; +import { processStyleNode } from './style-node-processor.js'; /** * Processes the `base` and `variants` properties of a recipe object. @@ -8,11 +9,12 @@ import { TSESTree } from '@typescript-eslint/utils'; * @param processProperty A callback function to process each property object (e.g., for alphabetical or concentric ordering). * * This function iterates through the properties of the recipe object: - * - For the `base` property, it directly processes the object. - * - For the `variants` property, it processes each variant's options individually. + * - For the `base` property, it processes object or array style nodes. + * - For the `variants` property, it processes each variant option as object or array style nodes. * * The function skips any non-Property nodes or nodes without an Identifier key. - * It only processes ObjectExpression values to ensure type safety. + * It delegates node handling to `processStyleNode`, which safely supports + * ObjectExpression and ArrayExpression values. */ export const processRecipeProperties = ( ruleContext: Rule.RuleContext, @@ -25,8 +27,8 @@ export const processRecipeProperties = ( } // Process the `base` property - if (property.key.name === 'base' && property.value.type === 'ObjectExpression') { - processProperty(ruleContext, property.value); + if (property.key.name === 'base') { + processStyleNode(ruleContext, property.value, processProperty); } // Process the `variants` property @@ -34,8 +36,8 @@ export const processRecipeProperties = ( property.value.properties.forEach((variantProperty) => { if (variantProperty.type === 'Property' && variantProperty.value.type === 'ObjectExpression') { variantProperty.value.properties.forEach((optionProperty) => { - if (optionProperty.type === 'Property' && optionProperty.value.type === 'ObjectExpression') { - processProperty(ruleContext, optionProperty.value); + if (optionProperty.type === 'Property') { + processStyleNode(ruleContext, optionProperty.value, processProperty); } }); } From 0bd37dd744e0214ad350df8ff08b492a3f530254 Mon Sep 17 00:00:00 2001 From: seongminn Date: Sat, 21 Mar 2026 17:36:04 +0900 Subject: [PATCH 2/2] cover base array sorting in alphabetical and custom order rules --- .../__tests__/recipe.test.ts | 35 +++++++++++ .../custom-order/__tests__/recipe.test.ts | 58 +++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/src/css-rules/alphabetical-order/__tests__/recipe.test.ts b/src/css-rules/alphabetical-order/__tests__/recipe.test.ts index 82ba7ed..971774d 100644 --- a/src/css-rules/alphabetical-order/__tests__/recipe.test.ts +++ b/src/css-rules/alphabetical-order/__tests__/recipe.test.ts @@ -36,6 +36,18 @@ run({ } }); `, + + // Recipe with base as array (ComplexStyleRule) + ` + import { recipe } from '@vanilla-extract/recipes'; + + const myRecipe = recipe({ + base: [{ + alignItems: 'center', + display: 'flex' + }], + }); + `, ], invalid: [ // Recipe with incorrect ordering @@ -88,5 +100,28 @@ run({ }); `, }, + + // Recipe with base array in incorrect order + { + code: ` + import { recipe } from '@vanilla-extract/recipes'; + const myRecipe = recipe({ + base: [{ + display: 'flex', + alignItems: 'center' + }], + }); + `, + errors: [{ messageId: 'alphabeticalOrder' }], + output: ` + import { recipe } from '@vanilla-extract/recipes'; + const myRecipe = recipe({ + base: [{ + alignItems: 'center', + display: 'flex' + }], + }); + `, + }, ], }); diff --git a/src/css-rules/custom-order/__tests__/recipe.test.ts b/src/css-rules/custom-order/__tests__/recipe.test.ts index 16e66e7..871dcdc 100644 --- a/src/css-rules/custom-order/__tests__/recipe.test.ts +++ b/src/css-rules/custom-order/__tests__/recipe.test.ts @@ -88,6 +88,29 @@ run({ }, ], }, + + // Recipe with base as array (ComplexStyleRule) + { + code: ` + import { recipe } from '@vanilla-extract/recipes'; + + const myRecipe = recipe({ + base: [{ + width: '100%', + margin: 0, + display: 'flex', + alignItems: 'center', + backgroundColor: 'white' + }], + }); + `, + options: [ + { + groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'], + sortRemainingProperties: 'concentric', + }, + ], + }, ], invalid: [ // Recipe with incorrect ordering (concentric for remaining) @@ -207,5 +230,40 @@ run({ }); `, }, + + // Recipe with base array in incorrect order + { + code: ` + import { recipe } from '@vanilla-extract/recipes'; + const myRecipe = recipe({ + base: [{ + backgroundColor: 'white', + width: '100%', + display: 'flex', + alignItems: 'center', + margin: 0 + }], + }); + `, + options: [ + { + groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'], + sortRemainingProperties: 'concentric', + }, + ], + errors: [{ messageId: 'incorrectOrder' }], + output: ` + import { recipe } from '@vanilla-extract/recipes'; + const myRecipe = recipe({ + base: [{ + width: '100%', + margin: 0, + display: 'flex', + alignItems: 'center', + backgroundColor: 'white' + }], + }); + `, + }, ], });