Skip to content

Commit 0d3f7d9

Browse files
committed
feat(tasty): recipes * 2
1 parent 277f36b commit 0d3f7d9

File tree

9 files changed

+29
-23
lines changed

9 files changed

+29
-23
lines changed

src/stories/Tasty.docs.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ configure({
130130
| `tokens` | `Record<string, string \| number>` | - | Predefined tokens replaced during parsing |
131131
| `keyframes` | `Record<string, KeyframesSteps>` | - | Global keyframes for animations |
132132
| `properties` | `Record<string, PropertyDefinition>` | - | Global CSS @property definitions |
133-
| `recipes` | `Record<string, StylesWithoutSelectors>` | - | Predefined style recipes (named style bundles) |
133+
| `recipes` | `Record<string, RecipeStyles>` | - | Predefined style recipes (named style bundles) |
134134
135135
### Predefined Tokens
136136

src/stories/tastyStatic.docs.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ module.exports = {
171171
| `output` | `string` | `'tasty.css'` | Path for generated CSS file |
172172
| `config.states` | `Record<string, string>` | `{}` | Predefined state aliases |
173173
| `config.devMode` | `boolean` | `false` | Add source comments to CSS |
174-
| `config.recipes` | `Record<string, StylesWithoutSelectors>` | `{}` | Predefined style recipes |
174+
| `config.recipes` | `Record<string, RecipeStyles>` | `{}` | Predefined style recipes |
175175

176176
---
177177

src/tasty/config.ts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {
3232
import type { KeyframesSteps, PropertyDefinition } from './injector/types';
3333
import type { StyleDetails, UnitHandler } from './parser/types';
3434
import type { TastyPlugin } from './plugins/types';
35-
import type { StylesWithoutSelectors } from './styles/types';
35+
import type { RecipeStyles } from './styles/types';
3636
import type { StyleHandlerDefinition } from './utils/styles';
3737

3838
/**
@@ -234,7 +234,7 @@ export interface TastyConfig {
234234
* });
235235
* ```
236236
*/
237-
recipes?: Record<string, StylesWithoutSelectors>;
237+
recipes?: Record<string, RecipeStyles>;
238238
}
239239

240240
// Warnings tracking to avoid duplicates
@@ -269,7 +269,7 @@ let globalKeyframes: Record<string, KeyframesSteps> | null = null;
269269
let globalProperties: Record<string, PropertyDefinition> | null = null;
270270

271271
// Global recipes storage (null = no recipes configured)
272-
let globalRecipes: Record<string, StylesWithoutSelectors> | null = null;
272+
let globalRecipes: Record<string, RecipeStyles> | null = null;
273273

274274
/**
275275
* Internal properties required by tasty core features.
@@ -499,20 +499,15 @@ export function hasGlobalRecipes(): boolean {
499499
* Get global recipes configuration.
500500
* Returns null if no recipes configured (fast path for zero-overhead).
501501
*/
502-
export function getGlobalRecipes(): Record<
503-
string,
504-
StylesWithoutSelectors
505-
> | null {
502+
export function getGlobalRecipes(): Record<string, RecipeStyles> | null {
506503
return globalRecipes;
507504
}
508505

509506
/**
510507
* Set global recipes (called from configure).
511508
* Internal use only.
512509
*/
513-
function setGlobalRecipes(
514-
recipes: Record<string, StylesWithoutSelectors>,
515-
): void {
510+
function setGlobalRecipes(recipes: Record<string, RecipeStyles>): void {
516511
if (stylesGenerated) {
517512
warnOnce(
518513
'recipes-after-styles',
@@ -531,7 +526,7 @@ function setGlobalRecipes(
531526
`recipe-selector-${name}-${key}`,
532527
`[Tasty] Recipe "${name}" contains sub-element key "${key}". ` +
533528
`Recipes must be flat styles without sub-element keys. ` +
534-
`The sub-element key will be ignored during resolution.`,
529+
`Remove the sub-element key from the recipe definition.`,
535530
);
536531
}
537532
if (key === 'recipe') {
@@ -597,7 +592,7 @@ export function configure(config: Partial<TastyConfig> = {}): void {
597592
let mergedFuncs: Record<string, (groups: StyleDetails[]) => string> = {};
598593
let mergedHandlers: Record<string, StyleHandlerDefinition> = {};
599594
let mergedTokens: Record<string, string | number | boolean> = {};
600-
let mergedRecipes: Record<string, StylesWithoutSelectors> = {};
595+
let mergedRecipes: Record<string, RecipeStyles> = {};
601596

602597
// Process plugins in order
603598
if (config.plugins) {

src/tasty/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export type {
101101
StylesInterface,
102102
Styles,
103103
StylesWithoutSelectors,
104+
RecipeStyles,
104105
NoType,
105106
Selector,
106107
SuffixForSelector,

src/tasty/plugins/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { StyleDetails, UnitHandler } from '../parser/types';
2-
import type { StylesWithoutSelectors } from '../styles/types';
2+
import type { RecipeStyles } from '../styles/types';
33
import type { StyleHandlerDefinition } from '../utils/styles';
44

55
/**
@@ -43,7 +43,7 @@ export interface TastyPlugin {
4343
* }
4444
* ```
4545
*/
46-
recipes?: Record<string, StylesWithoutSelectors>;
46+
recipes?: Record<string, RecipeStyles>;
4747
}
4848

4949
/**

src/tasty/styles/types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,16 @@ export type StylesWithoutSelectors = {
569569
| StyleValueStateMap<StylesInterface[key]>;
570570
};
571571

572+
/**
573+
* Style type for recipe definitions.
574+
* Like StylesWithoutSelectors but also allows `@keyframes` and `@properties`.
575+
* Excludes `recipe` to prevent recursive references.
576+
*/
577+
export type RecipeStyles = StylesWithoutSelectors & {
578+
'@keyframes'?: StylesInterface['@keyframes'];
579+
'@properties'?: StylesInterface['@properties'];
580+
};
581+
572582
/** Special properties that are not regular style values */
573583
export interface SpecialStyleProperties {
574584
'@keyframes'?: StylesInterface['@keyframes'];

src/tasty/utils/resolve-recipes.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ describe('resolveRecipes', () => {
255255
'@keyframes': {
256256
fadeIn: { from: { opacity: '0' }, to: { opacity: '1' } },
257257
},
258-
} as any,
258+
},
259259
},
260260
});
261261

src/tasty/utils/resolve-recipes.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import { getGlobalRecipes } from '../config';
1414
import { isSelector } from '../pipeline';
15-
import { Styles, StylesWithoutSelectors } from '../styles/types';
15+
import { RecipeStyles, Styles } from '../styles/types';
1616

1717
import { isDevEnv } from './is-dev-env';
1818

@@ -40,7 +40,7 @@ function parseRecipeNames(value: unknown): string[] | null {
4040
*/
4141
function resolveRecipesForLevel(
4242
styles: Record<string, unknown>,
43-
recipes: Record<string, StylesWithoutSelectors>,
43+
recipes: Record<string, RecipeStyles>,
4444
): Record<string, unknown> | null {
4545
if (!('recipe' in styles)) return null;
4646

@@ -106,8 +106,8 @@ export function resolveRecipes(styles: Styles): Styles {
106106
changed = true;
107107
result = topResolved;
108108
} else {
109-
// Copy reference for potential sub-element changes
110-
result = { ...(styles as Record<string, unknown>) };
109+
// Keep reference; a shallow copy is deferred until a sub-element actually changes
110+
result = styles as Record<string, unknown>;
111111
}
112112

113113
// Resolve sub-element recipes

src/tasty/zero/babel.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { declare } from '@babel/helper-plugin-utils';
2121
import * as t from '@babel/types';
2222

2323
import { configure } from '../config';
24-
import { Styles, StylesWithoutSelectors } from '../styles/types';
24+
import { RecipeStyles, Styles } from '../styles/types';
2525
import { mergeStyles } from '../utils/merge-styles';
2626
import { resolveRecipes } from '../utils/resolve-recipes';
2727
import { StyleHandlerDefinition } from '../utils/styles';
@@ -128,7 +128,7 @@ export interface TastyZeroConfig {
128128
* }
129129
* ```
130130
*/
131-
recipes?: Record<string, StylesWithoutSelectors>;
131+
recipes?: Record<string, RecipeStyles>;
132132
}
133133

134134
export interface TastyZeroBabelOptions {

0 commit comments

Comments
 (0)