@pandacss/generator 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -2,6 +2,26 @@ import * as _pandacss_types from '@pandacss/types';
2
2
  import { LoadConfigResult, ArtifactId, CssArtifactType } from '@pandacss/types';
3
3
  import { Context, Stylesheet, StyleDecoder } from '@pandacss/core';
4
4
 
5
+ interface SplitCssArtifact {
6
+ type: 'layer' | 'recipe' | 'theme';
7
+ name: string;
8
+ file: string;
9
+ code: string;
10
+ /** Directory relative to styles/ */
11
+ dir?: string;
12
+ }
13
+ interface SplitCssResult {
14
+ /** Layer CSS files (reset, global, tokens, utilities) */
15
+ layers: SplitCssArtifact[];
16
+ /** Recipe CSS files */
17
+ recipes: SplitCssArtifact[];
18
+ /** Theme CSS files (not auto-imported) */
19
+ themes: SplitCssArtifact[];
20
+ /** Content for recipes.css */
21
+ recipesIndex: string;
22
+ /** Content for main styles.css */
23
+ index: string;
24
+ }
5
25
  declare class Generator extends Context {
6
26
  constructor(conf: LoadConfigResult);
7
27
  getArtifacts: (ids?: ArtifactId[] | undefined) => _pandacss_types.Artifact[];
@@ -11,6 +31,28 @@ declare class Generator extends Context {
11
31
  appendParserCss: (sheet: Stylesheet) => void;
12
32
  getParserCss: (decoder: StyleDecoder) => string;
13
33
  getCss: (stylesheet?: Stylesheet) => string;
34
+ /**
35
+ * Get CSS for a specific layer from the stylesheet
36
+ */
37
+ getLayerCss: (sheet: Stylesheet, layer: "reset" | "base" | "tokens" | "recipes" | "utilities") => string;
38
+ /**
39
+ * Get CSS for a specific recipe
40
+ */
41
+ getRecipeCss: (recipeName: string) => string;
42
+ /**
43
+ * Get all recipe names from the decoder
44
+ */
45
+ getRecipeNames: () => string[];
46
+ /**
47
+ * Get all split CSS artifacts for the stylesheet
48
+ * Used when --splitting flag is enabled
49
+ */
50
+ getSplitCssArtifacts: (sheet: Stylesheet) => SplitCssResult;
14
51
  }
15
52
 
16
- export { Generator };
53
+ /**
54
+ * Get CSS for a specific theme
55
+ */
56
+ declare function getThemeCss(ctx: Context, themeName: string): string;
57
+
58
+ export { Generator, type SplitCssArtifact, type SplitCssResult, getThemeCss };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,26 @@ import * as _pandacss_types from '@pandacss/types';
2
2
  import { LoadConfigResult, ArtifactId, CssArtifactType } from '@pandacss/types';
3
3
  import { Context, Stylesheet, StyleDecoder } from '@pandacss/core';
4
4
 
5
+ interface SplitCssArtifact {
6
+ type: 'layer' | 'recipe' | 'theme';
7
+ name: string;
8
+ file: string;
9
+ code: string;
10
+ /** Directory relative to styles/ */
11
+ dir?: string;
12
+ }
13
+ interface SplitCssResult {
14
+ /** Layer CSS files (reset, global, tokens, utilities) */
15
+ layers: SplitCssArtifact[];
16
+ /** Recipe CSS files */
17
+ recipes: SplitCssArtifact[];
18
+ /** Theme CSS files (not auto-imported) */
19
+ themes: SplitCssArtifact[];
20
+ /** Content for recipes.css */
21
+ recipesIndex: string;
22
+ /** Content for main styles.css */
23
+ index: string;
24
+ }
5
25
  declare class Generator extends Context {
6
26
  constructor(conf: LoadConfigResult);
7
27
  getArtifacts: (ids?: ArtifactId[] | undefined) => _pandacss_types.Artifact[];
@@ -11,6 +31,28 @@ declare class Generator extends Context {
11
31
  appendParserCss: (sheet: Stylesheet) => void;
12
32
  getParserCss: (decoder: StyleDecoder) => string;
13
33
  getCss: (stylesheet?: Stylesheet) => string;
34
+ /**
35
+ * Get CSS for a specific layer from the stylesheet
36
+ */
37
+ getLayerCss: (sheet: Stylesheet, layer: "reset" | "base" | "tokens" | "recipes" | "utilities") => string;
38
+ /**
39
+ * Get CSS for a specific recipe
40
+ */
41
+ getRecipeCss: (recipeName: string) => string;
42
+ /**
43
+ * Get all recipe names from the decoder
44
+ */
45
+ getRecipeNames: () => string[];
46
+ /**
47
+ * Get all split CSS artifacts for the stylesheet
48
+ * Used when --splitting flag is enabled
49
+ */
50
+ getSplitCssArtifacts: (sheet: Stylesheet) => SplitCssResult;
14
51
  }
15
52
 
16
- export { Generator };
53
+ /**
54
+ * Get CSS for a specific theme
55
+ */
56
+ declare function getThemeCss(ctx: Context, themeName: string): string;
57
+
58
+ export { Generator, type SplitCssArtifact, type SplitCssResult, getThemeCss };
package/dist/index.js CHANGED
@@ -30,7 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- Generator: () => Generator
33
+ Generator: () => Generator,
34
+ getThemeCss: () => getThemeCss
34
35
  });
35
36
  module.exports = __toCommonJS(index_exports);
36
37
 
@@ -1228,12 +1229,33 @@ function generatePreactCreateStyleContext(ctx) {
1228
1229
  ${ctx.file.import("cx, css, sva", "../css/index")}
1229
1230
  ${ctx.file.import(factoryName, "./factory")}
1230
1231
  ${ctx.file.import("getDisplayName", "./factory-helper")}
1231
- import { createContext, useContext, createElement, forwardRef } from 'preact/compat'
1232
+ import { createContext } from 'preact'
1233
+ import { useContext } from 'preact/hooks'
1234
+ import { createElement, forwardRef } from 'preact/compat'
1235
+
1236
+ function createSafeContext(contextName) {
1237
+ const Context = createContext(undefined)
1238
+ const useStyleContext = (componentName, slot) => {
1239
+ const context = useContext(Context)
1240
+ if (context === undefined) {
1241
+ const componentInfo = componentName ? \`Component "\${componentName}"\` : 'A component'
1242
+ const slotInfo = slot ? \` (slot: "\${slot}")\` : ''
1243
+
1244
+ throw new Error(
1245
+ \`\${componentInfo}\${slotInfo} cannot access \${contextName} because it's missing its Provider.\`
1246
+ )
1247
+ }
1248
+ return context
1249
+ }
1250
+ return [Context, useStyleContext]
1251
+ }
1232
1252
 
1233
-
1234
1253
  export function createStyleContext(recipe) {
1235
- const StyleContext = createContext({})
1236
1254
  const isConfigRecipe = '__recipe__' in recipe
1255
+ const recipeName = isConfigRecipe && recipe.__name__ ? recipe.__name__ : undefined
1256
+ const contextName = recipeName ? \`createStyleContext("\${recipeName}")\` : 'createStyleContext'
1257
+
1258
+ const [StyleContext, useStyleContext] = createSafeContext(contextName)
1237
1259
  const svaFn = isConfigRecipe ? recipe : sva(recipe.config)
1238
1260
 
1239
1261
  const getResolvedProps = (props, slotStyles) => {
@@ -1273,7 +1295,7 @@ function generatePreactCreateStyleContext(ctx) {
1273
1295
  const withProvider = (Component, slot, options) => {
1274
1296
  const StyledComponent = ${factoryName}(Component, {}, options)
1275
1297
 
1276
- const WithProvider = forwardRef((props, ref) => {
1298
+ const WithProvider = forwardRef(function WithProvider(props, ref) {
1277
1299
  const [variantProps, restProps] = svaFn.splitVariantProps(props)
1278
1300
 
1279
1301
  const slotStyles = isConfigRecipe ? svaFn(variantProps) : svaFn.raw(variantProps)
@@ -1299,9 +1321,10 @@ function generatePreactCreateStyleContext(ctx) {
1299
1321
 
1300
1322
  const withContext = (Component, slot, options) => {
1301
1323
  const StyledComponent = ${factoryName}(Component, {}, options)
1324
+ const componentName = getDisplayName(Component)
1302
1325
 
1303
- const WithContext = forwardRef((props, ref) => {
1304
- const slotStyles = useContext(StyleContext)
1326
+ const WithContext = forwardRef(function WithContext(props, ref) {
1327
+ const slotStyles = useStyleContext(componentName, slot)
1305
1328
 
1306
1329
  const propsWithClass = { ...props, className: props.className ?? options?.defaultProps?.className }
1307
1330
  const resolvedProps = getResolvedProps(propsWithClass, slotStyles[slot])
@@ -1312,7 +1335,6 @@ function generatePreactCreateStyleContext(ctx) {
1312
1335
  })
1313
1336
  })
1314
1337
 
1315
- const componentName = getDisplayName(Component)
1316
1338
  WithContext.displayName = \`withContext(\${componentName})\`
1317
1339
 
1318
1340
  return WithContext
@@ -1328,7 +1350,7 @@ function generatePreactCreateStyleContext(ctx) {
1328
1350
  dts: import_outdent17.outdent`
1329
1351
  ${ctx.file.importType("SlotRecipeRuntimeFn, RecipeVariantProps", "../types/recipe")}
1330
1352
  ${ctx.file.importType("JsxHTMLProps, JsxStyleProps, Assign", "../types/system-types")}
1331
- ${ctx.file.importType("JsxFactoryOptions, DataAttrs", "../types/jsx")}
1353
+ ${ctx.file.importType("JsxFactoryOptions, DataAttrs, AsProps", "../types/jsx")}
1332
1354
  import type { ComponentType, ComponentProps, JSX } from 'preact/compat'
1333
1355
 
1334
1356
  interface UnstyledProps {
@@ -1352,7 +1374,7 @@ function generatePreactCreateStyleContext(ctx) {
1352
1374
  type InferSlot<R extends SlotRecipe> = R extends SlotRecipeFn ? R['__slot'] : R extends SvaFn<infer S> ? S : never
1353
1375
 
1354
1376
  type StyleContextProvider<T extends ElementType, R extends SlotRecipe> = ComponentType<
1355
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
1377
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
1356
1378
  >
1357
1379
 
1358
1380
  type StyleContextRootProvider<T extends ElementType, R extends SlotRecipe> = ComponentType<
@@ -1360,7 +1382,7 @@ function generatePreactCreateStyleContext(ctx) {
1360
1382
  >
1361
1383
 
1362
1384
  type StyleContextConsumer<T extends ElementType> = ComponentType<
1363
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, JsxStyleProps>
1385
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, JsxStyleProps>
1364
1386
  >
1365
1387
 
1366
1388
  export interface StyleContext<R extends SlotRecipe> {
@@ -2126,9 +2148,29 @@ function generateReactCreateStyleContext(ctx) {
2126
2148
  ${ctx.file.import("getDisplayName", "./factory-helper")}
2127
2149
  import { createContext, useContext, createElement, forwardRef } from 'react'
2128
2150
 
2151
+ function createSafeContext(contextName) {
2152
+ const Context = createContext(undefined)
2153
+ const useStyleContext = (componentName, slot) => {
2154
+ const context = useContext(Context)
2155
+ if (context === undefined) {
2156
+ const componentInfo = componentName ? \`Component "\${componentName}"\` : 'A component'
2157
+ const slotInfo = slot ? \` (slot: "\${slot}")\` : ''
2158
+
2159
+ throw new Error(
2160
+ \`\${componentInfo}\${slotInfo} cannot access \${contextName} because it's missing its Provider.\`
2161
+ )
2162
+ }
2163
+ return context
2164
+ }
2165
+ return [Context, useStyleContext]
2166
+ }
2167
+
2129
2168
  export function createStyleContext(recipe) {
2130
- const StyleContext = createContext({})
2131
2169
  const isConfigRecipe = '__recipe__' in recipe
2170
+ const recipeName = isConfigRecipe && recipe.__name__ ? recipe.__name__ : undefined
2171
+ const contextName = recipeName ? \`createStyleContext("\${recipeName}")\` : 'createStyleContext'
2172
+
2173
+ const [StyleContext, useStyleContext] = createSafeContext(contextName)
2132
2174
  const svaFn = isConfigRecipe ? recipe : sva(recipe.config)
2133
2175
 
2134
2176
  const getResolvedProps = (props, slotStyles) => {
@@ -2194,9 +2236,10 @@ function generateReactCreateStyleContext(ctx) {
2194
2236
 
2195
2237
  const withContext = (Component, slot, options) => {
2196
2238
  const StyledComponent = ${factoryName}(Component, {}, options)
2239
+ const componentName = getDisplayName(Component)
2197
2240
 
2198
2241
  const WithContext = forwardRef((props, ref) => {
2199
- const slotStyles = useContext(StyleContext)
2242
+ const slotStyles = useStyleContext(componentName, slot)
2200
2243
 
2201
2244
  const propsWithClass = { ...props, className: props.className ?? options?.defaultProps?.className }
2202
2245
  const resolvedProps = getResolvedProps(propsWithClass, slotStyles[slot])
@@ -2207,7 +2250,6 @@ function generateReactCreateStyleContext(ctx) {
2207
2250
  })
2208
2251
  })
2209
2252
 
2210
- const componentName = getDisplayName(Component)
2211
2253
  WithContext.displayName = \`withContext(\${componentName})\`
2212
2254
 
2213
2255
  return WithContext
@@ -2223,7 +2265,7 @@ function generateReactCreateStyleContext(ctx) {
2223
2265
  dts: import_outdent28.outdent`
2224
2266
  ${ctx.file.importType("SlotRecipeRuntimeFn, RecipeVariantProps", "../types/recipe")}
2225
2267
  ${ctx.file.importType("JsxHTMLProps, JsxStyleProps, Assign", "../types/system-types")}
2226
- ${ctx.file.importType("JsxFactoryOptions, ComponentProps, DataAttrs", "../types/jsx")}
2268
+ ${ctx.file.importType("JsxFactoryOptions, ComponentProps, DataAttrs, AsProps", "../types/jsx")}
2227
2269
  import type { ComponentType, ElementType } from 'react'
2228
2270
 
2229
2271
  interface UnstyledProps {
@@ -2245,7 +2287,7 @@ function generateReactCreateStyleContext(ctx) {
2245
2287
  }
2246
2288
 
2247
2289
  type StyleContextProvider<T extends ElementType, R extends SlotRecipe> = ComponentType<
2248
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
2290
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
2249
2291
  >
2250
2292
 
2251
2293
  type StyleContextRootProvider<T extends ElementType, R extends SlotRecipe> = ComponentType<
@@ -2253,7 +2295,7 @@ function generateReactCreateStyleContext(ctx) {
2253
2295
  >
2254
2296
 
2255
2297
  type StyleContextConsumer<T extends ElementType> = ComponentType<
2256
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, JsxStyleProps>
2298
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, JsxStyleProps>
2257
2299
  >
2258
2300
 
2259
2301
  export interface StyleContext<R extends SlotRecipe> {
@@ -2414,12 +2456,15 @@ function generateSolidJsxFactory(ctx) {
2414
2456
  return forwardFn(prop, cvaFn.variantKeys)
2415
2457
  }
2416
2458
 
2417
- const defaultProps = Object.assign(
2418
- options.dataAttr && configOrCva.__name__
2459
+ const getDefaultProps = () => {
2460
+ const baseDefaults = options.dataAttr && configOrCva.__name__
2419
2461
  ? { 'data-recipe': configOrCva.__name__ }
2420
- : {},
2421
- options.defaultProps
2422
- )
2462
+ : {}
2463
+ const defaults = typeof options.defaultProps === 'function'
2464
+ ? options.defaultProps()
2465
+ : options.defaultProps
2466
+ return Object.assign(baseDefaults, defaults)
2467
+ }
2423
2468
 
2424
2469
  const __cvaFn__ = composeCvaFn(element.__cva__, cvaFn)
2425
2470
  const __shouldForwardProps__ = composeShouldForwardProps(
@@ -2430,7 +2475,7 @@ function generateSolidJsxFactory(ctx) {
2430
2475
  const ${componentName} = (props) => {
2431
2476
  const mergedProps = mergeProps(
2432
2477
  { as: element.__base__ || element },
2433
- defaultProps,
2478
+ getDefaultProps(),
2434
2479
  props
2435
2480
  )
2436
2481
 
@@ -2620,12 +2665,9 @@ ${ctx.file.importType(upperName, "../types/jsx")}
2620
2665
  export declare const ${factoryName}: ${upperName}
2621
2666
  `,
2622
2667
  jsxType: import_outdent33.outdent`
2623
- import type { ComponentProps, Component, JSX } from 'solid-js'
2668
+ import type { Accessor, ComponentProps, Component, JSX } from 'solid-js'
2624
2669
  ${ctx.file.importType("RecipeDefinition, RecipeSelection, RecipeVariantRecord", "./recipe")}
2625
- ${ctx.file.importType(
2626
- "Assign, DistributiveOmit, DistributiveUnion, JsxHTMLProps, JsxStyleProps, Pretty",
2627
- "./system-types"
2628
- )}
2670
+ ${ctx.file.importType("Assign, DistributiveUnion, JsxHTMLProps, JsxStyleProps, Pretty", "./system-types")}
2629
2671
 
2630
2672
  interface Dict {
2631
2673
  [k: string]: unknown
@@ -2658,9 +2700,11 @@ interface RecipeFn {
2658
2700
  __type: any
2659
2701
  }
2660
2702
 
2703
+ export type MaybeAccessor<T> = T | Accessor<T>
2704
+
2661
2705
  export interface JsxFactoryOptions<TProps extends Dict> {
2662
2706
  dataAttr?: boolean
2663
- defaultProps?: Partial<TProps> & DataAttrs
2707
+ defaultProps?: MaybeAccessor<Partial<TProps> & DataAttrs>
2664
2708
  shouldForwardProp?: (prop: string, variantKeys: string[]) => boolean
2665
2709
  forwardProps?: string[]
2666
2710
  }
@@ -2706,9 +2750,29 @@ function generateSolidCreateStyleContext(ctx) {
2706
2750
  import { createComponent, mergeProps } from 'solid-js/web'
2707
2751
  import { createContext, createMemo, splitProps, useContext } from 'solid-js'
2708
2752
 
2753
+ function createSafeContext(contextName) {
2754
+ const Context = createContext(undefined)
2755
+ const useStyleContext = (componentName, slot) => {
2756
+ const context = useContext(Context)
2757
+ if (context === undefined) {
2758
+ const componentInfo = componentName ? \`Component "\${componentName}"\` : 'A component'
2759
+ const slotInfo = slot ? \` (slot: "\${slot}")\` : ''
2760
+
2761
+ throw new Error(
2762
+ \`\${componentInfo}\${slotInfo} cannot access \${contextName} because it's missing its Provider.\`
2763
+ )
2764
+ }
2765
+ return context
2766
+ }
2767
+ return [Context, useStyleContext]
2768
+ }
2769
+
2709
2770
  export function createStyleContext(recipe) {
2710
- const StyleContext = createContext({})
2711
2771
  const isConfigRecipe = '__recipe__' in recipe
2772
+ const recipeName = isConfigRecipe && recipe.__name__ ? recipe.__name__ : undefined
2773
+ const contextName = recipeName ? \`createStyleContext("\${recipeName}")\` : 'createStyleContext'
2774
+
2775
+ const [StyleContext, useStyleContext] = createSafeContext(contextName)
2712
2776
  const svaFn = isConfigRecipe ? recipe : sva(recipe.config)
2713
2777
 
2714
2778
  const getResolvedProps = (props, slotStyles) => {
@@ -2735,7 +2799,10 @@ function generateSolidCreateStyleContext(ctx) {
2735
2799
 
2736
2800
  const mergedProps = createMemo(() => {
2737
2801
  if (!options?.defaultProps) return propsWithoutChildren
2738
- return { ...options.defaultProps, ...propsWithoutChildren }
2802
+ const defaults = typeof options.defaultProps === 'function'
2803
+ ? options.defaultProps()
2804
+ : options.defaultProps
2805
+ return { ...defaults, ...propsWithoutChildren }
2739
2806
  })
2740
2807
 
2741
2808
  return createComponent(StyleContext.Provider, {
@@ -2807,9 +2874,10 @@ function generateSolidCreateStyleContext(ctx) {
2807
2874
 
2808
2875
  const withContext = (Component, slot, options) => {
2809
2876
  const StyledComponent = ${factoryName}(Component, {}, options)
2877
+ const componentName = getDisplayName(Component)
2810
2878
 
2811
2879
  const WithContext = (props) => {
2812
- const slotStyles = useContext(StyleContext)
2880
+ const slotStyles = useStyleContext(componentName, slot)
2813
2881
  const [local, propsWithoutChildren] = splitProps(props, ["children"])
2814
2882
 
2815
2883
  const resolvedProps = createMemo(() => {
@@ -2832,7 +2900,6 @@ function generateSolidCreateStyleContext(ctx) {
2832
2900
  )
2833
2901
  }
2834
2902
 
2835
- const componentName = getDisplayName(Component)
2836
2903
  WithContext.displayName = \`withContext(\${componentName})\`
2837
2904
  return WithContext
2838
2905
  }
@@ -2847,7 +2914,7 @@ function generateSolidCreateStyleContext(ctx) {
2847
2914
  dts: import_outdent34.outdent`
2848
2915
  ${ctx.file.importType("SlotRecipeRuntimeFn, RecipeVariantProps", "../types/recipe")}
2849
2916
  ${ctx.file.importType("JsxHTMLProps, JsxStyleProps, Assign", "../types/system-types")}
2850
- ${ctx.file.importType("JsxFactoryOptions, DataAttrs", "../types/jsx")}
2917
+ ${ctx.file.importType("JsxFactoryOptions, DataAttrs, MaybeAccessor, AsProps", "../types/jsx")}
2851
2918
  import type { Component, JSX, ComponentProps } from 'solid-js'
2852
2919
 
2853
2920
  interface UnstyledProps {
@@ -2855,7 +2922,7 @@ function generateSolidCreateStyleContext(ctx) {
2855
2922
  }
2856
2923
 
2857
2924
  interface WithProviderOptions<P> {
2858
- defaultProps?: (Partial<P> & DataAttrs) | undefined
2925
+ defaultProps?: MaybeAccessor<Partial<P> & DataAttrs> | undefined
2859
2926
  }
2860
2927
 
2861
2928
  type ElementType = keyof JSX.IntrinsicElements | Component<any>
@@ -2875,7 +2942,7 @@ function generateSolidCreateStyleContext(ctx) {
2875
2942
  : never
2876
2943
 
2877
2944
  type StyleContextProvider<T extends ElementType, R extends SlotRecipe> = Component<
2878
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
2945
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
2879
2946
  >
2880
2947
 
2881
2948
  type StyleContextRootProvider<T extends ElementType, R extends SlotRecipe> = Component<
@@ -2883,7 +2950,7 @@ function generateSolidCreateStyleContext(ctx) {
2883
2950
  >
2884
2951
 
2885
2952
  type StyleContextConsumer<T extends ElementType> = Component<
2886
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, JsxStyleProps>
2953
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, JsxStyleProps>
2887
2954
  >
2888
2955
 
2889
2956
  export interface StyleContext<R extends SlotRecipe> {
@@ -3343,7 +3410,22 @@ function generateVueCreateStyleContext(ctx) {
3343
3410
  export function createStyleContext(recipe) {
3344
3411
  const StyleContext = Symbol('StyleContext')
3345
3412
  const isConfigRecipe = '__recipe__' in recipe
3413
+ const recipeName = isConfigRecipe && recipe.__name__ ? recipe.__name__ : undefined
3414
+ const contextName = recipeName ? \`createStyleContext("\${recipeName}")\` : 'createStyleContext'
3346
3415
  const svaFn = isConfigRecipe ? recipe : sva(recipe.config)
3416
+
3417
+ function useStyleContext(componentName, slot) {
3418
+ const context = inject(StyleContext)
3419
+ if (context === undefined) {
3420
+ const componentInfo = componentName ? \`Component "\${componentName}"\` : 'A component'
3421
+ const slotInfo = slot ? \` (slot: "\${slot}")\` : ''
3422
+
3423
+ throw new Error(
3424
+ \`\${componentInfo}\${slotInfo} cannot access \${contextName} because it's missing its Provider.\`
3425
+ )
3426
+ }
3427
+ return context
3428
+ }
3347
3429
 
3348
3430
  const getResolvedProps = (props, slotStyles) => {
3349
3431
  const { unstyled, ...restProps } = props
@@ -3426,6 +3508,7 @@ function generateVueCreateStyleContext(ctx) {
3426
3508
 
3427
3509
  const withContext = (Component, slot, options) => {
3428
3510
  const StyledComponent = ${factoryName}(Component, {}, options)
3511
+ const componentName = getDisplayName(Component)
3429
3512
 
3430
3513
  const WithContext = defineComponent({
3431
3514
  props: ["unstyled"],
@@ -3436,7 +3519,7 @@ function generateVueCreateStyleContext(ctx) {
3436
3519
  propsWithClass.class = propsWithClass.class ?? options?.defaultProps?.class
3437
3520
  return propsWithClass
3438
3521
  })
3439
- const slotStyles = inject(StyleContext)
3522
+ const slotStyles = useStyleContext(componentName, slot)
3440
3523
 
3441
3524
  return () => {
3442
3525
  const resolvedProps = getResolvedProps(props.value, slotStyles.value[slot])
@@ -3446,7 +3529,6 @@ function generateVueCreateStyleContext(ctx) {
3446
3529
  },
3447
3530
  })
3448
3531
 
3449
- const componentName = getDisplayName(Component)
3450
3532
  WithContext.displayName = \`withContext(\${componentName})\`
3451
3533
 
3452
3534
  return WithContext
@@ -3462,7 +3544,7 @@ function generateVueCreateStyleContext(ctx) {
3462
3544
  dts: import_outdent40.outdent`
3463
3545
  ${ctx.file.importType("SlotRecipeRuntimeFn, RecipeVariantProps", "../types/recipe")}
3464
3546
  ${ctx.file.importType("JsxHTMLProps, JsxStyleProps, Assign", "../types/system-types")}
3465
- ${ctx.file.importType("JsxFactoryOptions, DataAttrs", "../types/jsx")}
3547
+ ${ctx.file.importType("JsxFactoryOptions, DataAttrs, AsProps", "../types/jsx")}
3466
3548
  import type { Component, FunctionalComponent, NativeElements } from 'vue'
3467
3549
 
3468
3550
  interface UnstyledProps {
@@ -3499,7 +3581,7 @@ function generateVueCreateStyleContext(ctx) {
3499
3581
  : never
3500
3582
 
3501
3583
  type StyleContextProvider<T extends ElementType, R extends SlotRecipe> = FunctionalComponent<
3502
- JsxHTMLProps<ComponentProps<T> & UnstyledProps & VModelProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
3584
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps & VModelProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
3503
3585
  >
3504
3586
 
3505
3587
  type StyleContextRootProvider<T extends ElementType, R extends SlotRecipe> = FunctionalComponent<
@@ -3507,7 +3589,7 @@ function generateVueCreateStyleContext(ctx) {
3507
3589
  >
3508
3590
 
3509
3591
  type StyleContextConsumer<T extends ElementType> = FunctionalComponent<
3510
- JsxHTMLProps<ComponentProps<T> & UnstyledProps & VModelProps, JsxStyleProps>
3592
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps & VModelProps, JsxStyleProps>
3511
3593
  >
3512
3594
 
3513
3595
  export interface StyleContext<R extends SlotRecipe> {
@@ -4910,34 +4992,35 @@ function cleanupSelectors(css, varSelector) {
4910
4992
 
4911
4993
  // src/artifacts/js/themes.ts
4912
4994
  var getThemeId = (themeName) => "panda-theme-" + themeName;
4913
- function generateThemes(ctx) {
4914
- const { themes } = ctx.config;
4915
- if (!themes) return;
4995
+ function getThemeCss(ctx, themeName) {
4916
4996
  const { tokens, conditions } = ctx;
4917
- return Object.entries(themes).map(([name, _themeVariant]) => {
4918
- const results = [];
4919
- const condName = ctx.conditions.getThemeName(name);
4920
- for (const [key, values] of tokens.view.vars.entries()) {
4921
- if (key.startsWith(condName)) {
4922
- const css = stringifyVars({ values, conditionKey: key, root: "", conditions });
4923
- if (css) {
4924
- results.push(css);
4925
- }
4997
+ const results = [];
4998
+ const condName = conditions.getThemeName(themeName);
4999
+ for (const [key, values] of tokens.view.vars.entries()) {
5000
+ if (key.startsWith(condName)) {
5001
+ const css = stringifyVars({ values, conditionKey: key, root: "", conditions });
5002
+ if (css) {
5003
+ results.push(css);
4926
5004
  }
4927
5005
  }
4928
- return {
4929
- name: `theme-${name}`,
4930
- json: JSON.stringify(
4931
- (0, import_shared5.compact)({
4932
- name,
4933
- id: getThemeId(name),
4934
- css: results.join("\n\n")
4935
- }),
4936
- null,
4937
- 2
4938
- )
4939
- };
4940
- });
5006
+ }
5007
+ return results.join("\n\n");
5008
+ }
5009
+ function generateThemes(ctx) {
5010
+ const { themes } = ctx.config;
5011
+ if (!themes) return;
5012
+ return Object.entries(themes).map(([name, _themeVariant]) => ({
5013
+ name: `theme-${name}`,
5014
+ json: JSON.stringify(
5015
+ (0, import_shared5.compact)({
5016
+ name,
5017
+ id: getThemeId(name),
5018
+ css: getThemeCss(ctx, name)
5019
+ }),
5020
+ null,
5021
+ 2
5022
+ )
5023
+ }));
4941
5024
  }
4942
5025
  function generateThemesIndex(ctx, files) {
4943
5026
  const { themes } = ctx.config;
@@ -5696,8 +5779,99 @@ var Generator = class extends import_core5.Context {
5696
5779
  }
5697
5780
  return css;
5698
5781
  };
5782
+ /**
5783
+ * Get CSS for a specific layer from the stylesheet
5784
+ */
5785
+ getLayerCss = (sheet, layer) => {
5786
+ return sheet.getLayerCss(layer);
5787
+ };
5788
+ /**
5789
+ * Get CSS for a specific recipe
5790
+ */
5791
+ getRecipeCss = (recipeName) => {
5792
+ const sheet = this.createSheet();
5793
+ const decoder = this.decoder.collect(this.encoder);
5794
+ sheet.processDecoderForRecipe(decoder, recipeName);
5795
+ return sheet.getLayerCss("recipes");
5796
+ };
5797
+ /**
5798
+ * Get all recipe names from the decoder
5799
+ */
5800
+ getRecipeNames = () => {
5801
+ const decoder = this.decoder.collect(this.encoder);
5802
+ return Array.from(decoder.recipes.keys());
5803
+ };
5804
+ /**
5805
+ * Get all split CSS artifacts for the stylesheet
5806
+ * Used when --splitting flag is enabled
5807
+ */
5808
+ getSplitCssArtifacts = (sheet) => {
5809
+ const layerNames = this.config.layers;
5810
+ const decoder = this.decoder.collect(this.encoder);
5811
+ const layerDefs = [
5812
+ { name: "reset", file: "reset.css", css: sheet.getLayerCss("reset") },
5813
+ { name: "global", file: "global.css", css: sheet.getLayerCss("base") },
5814
+ { name: "tokens", file: "tokens.css", css: sheet.getLayerCss("tokens") },
5815
+ { name: "utilities", file: "utilities.css", css: sheet.getLayerCss("utilities") }
5816
+ ];
5817
+ const layers = layerDefs.filter((l) => l.css.trim()).map((l) => ({
5818
+ type: "layer",
5819
+ name: l.name,
5820
+ file: l.file,
5821
+ code: l.css
5822
+ }));
5823
+ const recipes = [];
5824
+ for (const recipeName of decoder.recipes.keys()) {
5825
+ const recipeSheet = this.createSheet();
5826
+ recipeSheet.processDecoderForRecipe(decoder, recipeName);
5827
+ const code = recipeSheet.getLayerCss("recipes");
5828
+ if (code.trim()) {
5829
+ recipes.push({
5830
+ type: "recipe",
5831
+ name: recipeName,
5832
+ file: `${(0, import_shared7.dashCase)(recipeName)}.css`,
5833
+ code,
5834
+ dir: "recipes"
5835
+ });
5836
+ }
5837
+ }
5838
+ const themes = [];
5839
+ if (this.config.themes) {
5840
+ for (const themeName of Object.keys(this.config.themes)) {
5841
+ const css = getThemeCss(this, themeName);
5842
+ if (css.trim()) {
5843
+ themes.push({
5844
+ type: "theme",
5845
+ name: themeName,
5846
+ file: `${(0, import_shared7.dashCase)(themeName)}.css`,
5847
+ code: `@layer ${layerNames.tokens} {
5848
+ ${css}
5849
+ }`,
5850
+ dir: "themes"
5851
+ });
5852
+ }
5853
+ }
5854
+ }
5855
+ const recipesIndex = recipes.map((r) => `@import './recipes/${r.file}';`).join("\n");
5856
+ const layerOrder = [layerNames.reset, layerNames.base, layerNames.tokens, layerNames.recipes, layerNames.utilities];
5857
+ const imports = [`@layer ${layerOrder.join(", ")};`, ""];
5858
+ for (const layer of layers) {
5859
+ imports.push(`@import './styles/${layer.file}';`);
5860
+ }
5861
+ if (recipes.length) {
5862
+ imports.push(`@import './styles/recipes.css';`);
5863
+ }
5864
+ return {
5865
+ layers,
5866
+ recipes,
5867
+ themes,
5868
+ recipesIndex,
5869
+ index: imports.join("\n")
5870
+ };
5871
+ };
5699
5872
  };
5700
5873
  // Annotate the CommonJS export names for ESM import in node:
5701
5874
  0 && (module.exports = {
5702
- Generator
5875
+ Generator,
5876
+ getThemeCss
5703
5877
  });
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/generator.ts
2
2
  import { Context as Context2 } from "@pandacss/core";
3
- import { PandaError } from "@pandacss/shared";
3
+ import { dashCase, PandaError } from "@pandacss/shared";
4
4
  import { match as match15 } from "ts-pattern";
5
5
 
6
6
  // src/artifacts/setup-artifacts.ts
@@ -1192,12 +1192,33 @@ function generatePreactCreateStyleContext(ctx) {
1192
1192
  ${ctx.file.import("cx, css, sva", "../css/index")}
1193
1193
  ${ctx.file.import(factoryName, "./factory")}
1194
1194
  ${ctx.file.import("getDisplayName", "./factory-helper")}
1195
- import { createContext, useContext, createElement, forwardRef } from 'preact/compat'
1195
+ import { createContext } from 'preact'
1196
+ import { useContext } from 'preact/hooks'
1197
+ import { createElement, forwardRef } from 'preact/compat'
1198
+
1199
+ function createSafeContext(contextName) {
1200
+ const Context = createContext(undefined)
1201
+ const useStyleContext = (componentName, slot) => {
1202
+ const context = useContext(Context)
1203
+ if (context === undefined) {
1204
+ const componentInfo = componentName ? \`Component "\${componentName}"\` : 'A component'
1205
+ const slotInfo = slot ? \` (slot: "\${slot}")\` : ''
1206
+
1207
+ throw new Error(
1208
+ \`\${componentInfo}\${slotInfo} cannot access \${contextName} because it's missing its Provider.\`
1209
+ )
1210
+ }
1211
+ return context
1212
+ }
1213
+ return [Context, useStyleContext]
1214
+ }
1196
1215
 
1197
-
1198
1216
  export function createStyleContext(recipe) {
1199
- const StyleContext = createContext({})
1200
1217
  const isConfigRecipe = '__recipe__' in recipe
1218
+ const recipeName = isConfigRecipe && recipe.__name__ ? recipe.__name__ : undefined
1219
+ const contextName = recipeName ? \`createStyleContext("\${recipeName}")\` : 'createStyleContext'
1220
+
1221
+ const [StyleContext, useStyleContext] = createSafeContext(contextName)
1201
1222
  const svaFn = isConfigRecipe ? recipe : sva(recipe.config)
1202
1223
 
1203
1224
  const getResolvedProps = (props, slotStyles) => {
@@ -1237,7 +1258,7 @@ function generatePreactCreateStyleContext(ctx) {
1237
1258
  const withProvider = (Component, slot, options) => {
1238
1259
  const StyledComponent = ${factoryName}(Component, {}, options)
1239
1260
 
1240
- const WithProvider = forwardRef((props, ref) => {
1261
+ const WithProvider = forwardRef(function WithProvider(props, ref) {
1241
1262
  const [variantProps, restProps] = svaFn.splitVariantProps(props)
1242
1263
 
1243
1264
  const slotStyles = isConfigRecipe ? svaFn(variantProps) : svaFn.raw(variantProps)
@@ -1263,9 +1284,10 @@ function generatePreactCreateStyleContext(ctx) {
1263
1284
 
1264
1285
  const withContext = (Component, slot, options) => {
1265
1286
  const StyledComponent = ${factoryName}(Component, {}, options)
1287
+ const componentName = getDisplayName(Component)
1266
1288
 
1267
- const WithContext = forwardRef((props, ref) => {
1268
- const slotStyles = useContext(StyleContext)
1289
+ const WithContext = forwardRef(function WithContext(props, ref) {
1290
+ const slotStyles = useStyleContext(componentName, slot)
1269
1291
 
1270
1292
  const propsWithClass = { ...props, className: props.className ?? options?.defaultProps?.className }
1271
1293
  const resolvedProps = getResolvedProps(propsWithClass, slotStyles[slot])
@@ -1276,7 +1298,6 @@ function generatePreactCreateStyleContext(ctx) {
1276
1298
  })
1277
1299
  })
1278
1300
 
1279
- const componentName = getDisplayName(Component)
1280
1301
  WithContext.displayName = \`withContext(\${componentName})\`
1281
1302
 
1282
1303
  return WithContext
@@ -1292,7 +1313,7 @@ function generatePreactCreateStyleContext(ctx) {
1292
1313
  dts: outdent17`
1293
1314
  ${ctx.file.importType("SlotRecipeRuntimeFn, RecipeVariantProps", "../types/recipe")}
1294
1315
  ${ctx.file.importType("JsxHTMLProps, JsxStyleProps, Assign", "../types/system-types")}
1295
- ${ctx.file.importType("JsxFactoryOptions, DataAttrs", "../types/jsx")}
1316
+ ${ctx.file.importType("JsxFactoryOptions, DataAttrs, AsProps", "../types/jsx")}
1296
1317
  import type { ComponentType, ComponentProps, JSX } from 'preact/compat'
1297
1318
 
1298
1319
  interface UnstyledProps {
@@ -1316,7 +1337,7 @@ function generatePreactCreateStyleContext(ctx) {
1316
1337
  type InferSlot<R extends SlotRecipe> = R extends SlotRecipeFn ? R['__slot'] : R extends SvaFn<infer S> ? S : never
1317
1338
 
1318
1339
  type StyleContextProvider<T extends ElementType, R extends SlotRecipe> = ComponentType<
1319
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
1340
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
1320
1341
  >
1321
1342
 
1322
1343
  type StyleContextRootProvider<T extends ElementType, R extends SlotRecipe> = ComponentType<
@@ -1324,7 +1345,7 @@ function generatePreactCreateStyleContext(ctx) {
1324
1345
  >
1325
1346
 
1326
1347
  type StyleContextConsumer<T extends ElementType> = ComponentType<
1327
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, JsxStyleProps>
1348
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, JsxStyleProps>
1328
1349
  >
1329
1350
 
1330
1351
  export interface StyleContext<R extends SlotRecipe> {
@@ -2090,9 +2111,29 @@ function generateReactCreateStyleContext(ctx) {
2090
2111
  ${ctx.file.import("getDisplayName", "./factory-helper")}
2091
2112
  import { createContext, useContext, createElement, forwardRef } from 'react'
2092
2113
 
2114
+ function createSafeContext(contextName) {
2115
+ const Context = createContext(undefined)
2116
+ const useStyleContext = (componentName, slot) => {
2117
+ const context = useContext(Context)
2118
+ if (context === undefined) {
2119
+ const componentInfo = componentName ? \`Component "\${componentName}"\` : 'A component'
2120
+ const slotInfo = slot ? \` (slot: "\${slot}")\` : ''
2121
+
2122
+ throw new Error(
2123
+ \`\${componentInfo}\${slotInfo} cannot access \${contextName} because it's missing its Provider.\`
2124
+ )
2125
+ }
2126
+ return context
2127
+ }
2128
+ return [Context, useStyleContext]
2129
+ }
2130
+
2093
2131
  export function createStyleContext(recipe) {
2094
- const StyleContext = createContext({})
2095
2132
  const isConfigRecipe = '__recipe__' in recipe
2133
+ const recipeName = isConfigRecipe && recipe.__name__ ? recipe.__name__ : undefined
2134
+ const contextName = recipeName ? \`createStyleContext("\${recipeName}")\` : 'createStyleContext'
2135
+
2136
+ const [StyleContext, useStyleContext] = createSafeContext(contextName)
2096
2137
  const svaFn = isConfigRecipe ? recipe : sva(recipe.config)
2097
2138
 
2098
2139
  const getResolvedProps = (props, slotStyles) => {
@@ -2158,9 +2199,10 @@ function generateReactCreateStyleContext(ctx) {
2158
2199
 
2159
2200
  const withContext = (Component, slot, options) => {
2160
2201
  const StyledComponent = ${factoryName}(Component, {}, options)
2202
+ const componentName = getDisplayName(Component)
2161
2203
 
2162
2204
  const WithContext = forwardRef((props, ref) => {
2163
- const slotStyles = useContext(StyleContext)
2205
+ const slotStyles = useStyleContext(componentName, slot)
2164
2206
 
2165
2207
  const propsWithClass = { ...props, className: props.className ?? options?.defaultProps?.className }
2166
2208
  const resolvedProps = getResolvedProps(propsWithClass, slotStyles[slot])
@@ -2171,7 +2213,6 @@ function generateReactCreateStyleContext(ctx) {
2171
2213
  })
2172
2214
  })
2173
2215
 
2174
- const componentName = getDisplayName(Component)
2175
2216
  WithContext.displayName = \`withContext(\${componentName})\`
2176
2217
 
2177
2218
  return WithContext
@@ -2187,7 +2228,7 @@ function generateReactCreateStyleContext(ctx) {
2187
2228
  dts: outdent28`
2188
2229
  ${ctx.file.importType("SlotRecipeRuntimeFn, RecipeVariantProps", "../types/recipe")}
2189
2230
  ${ctx.file.importType("JsxHTMLProps, JsxStyleProps, Assign", "../types/system-types")}
2190
- ${ctx.file.importType("JsxFactoryOptions, ComponentProps, DataAttrs", "../types/jsx")}
2231
+ ${ctx.file.importType("JsxFactoryOptions, ComponentProps, DataAttrs, AsProps", "../types/jsx")}
2191
2232
  import type { ComponentType, ElementType } from 'react'
2192
2233
 
2193
2234
  interface UnstyledProps {
@@ -2209,7 +2250,7 @@ function generateReactCreateStyleContext(ctx) {
2209
2250
  }
2210
2251
 
2211
2252
  type StyleContextProvider<T extends ElementType, R extends SlotRecipe> = ComponentType<
2212
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
2253
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
2213
2254
  >
2214
2255
 
2215
2256
  type StyleContextRootProvider<T extends ElementType, R extends SlotRecipe> = ComponentType<
@@ -2217,7 +2258,7 @@ function generateReactCreateStyleContext(ctx) {
2217
2258
  >
2218
2259
 
2219
2260
  type StyleContextConsumer<T extends ElementType> = ComponentType<
2220
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, JsxStyleProps>
2261
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, JsxStyleProps>
2221
2262
  >
2222
2263
 
2223
2264
  export interface StyleContext<R extends SlotRecipe> {
@@ -2378,12 +2419,15 @@ function generateSolidJsxFactory(ctx) {
2378
2419
  return forwardFn(prop, cvaFn.variantKeys)
2379
2420
  }
2380
2421
 
2381
- const defaultProps = Object.assign(
2382
- options.dataAttr && configOrCva.__name__
2422
+ const getDefaultProps = () => {
2423
+ const baseDefaults = options.dataAttr && configOrCva.__name__
2383
2424
  ? { 'data-recipe': configOrCva.__name__ }
2384
- : {},
2385
- options.defaultProps
2386
- )
2425
+ : {}
2426
+ const defaults = typeof options.defaultProps === 'function'
2427
+ ? options.defaultProps()
2428
+ : options.defaultProps
2429
+ return Object.assign(baseDefaults, defaults)
2430
+ }
2387
2431
 
2388
2432
  const __cvaFn__ = composeCvaFn(element.__cva__, cvaFn)
2389
2433
  const __shouldForwardProps__ = composeShouldForwardProps(
@@ -2394,7 +2438,7 @@ function generateSolidJsxFactory(ctx) {
2394
2438
  const ${componentName} = (props) => {
2395
2439
  const mergedProps = mergeProps(
2396
2440
  { as: element.__base__ || element },
2397
- defaultProps,
2441
+ getDefaultProps(),
2398
2442
  props
2399
2443
  )
2400
2444
 
@@ -2584,12 +2628,9 @@ ${ctx.file.importType(upperName, "../types/jsx")}
2584
2628
  export declare const ${factoryName}: ${upperName}
2585
2629
  `,
2586
2630
  jsxType: outdent33`
2587
- import type { ComponentProps, Component, JSX } from 'solid-js'
2631
+ import type { Accessor, ComponentProps, Component, JSX } from 'solid-js'
2588
2632
  ${ctx.file.importType("RecipeDefinition, RecipeSelection, RecipeVariantRecord", "./recipe")}
2589
- ${ctx.file.importType(
2590
- "Assign, DistributiveOmit, DistributiveUnion, JsxHTMLProps, JsxStyleProps, Pretty",
2591
- "./system-types"
2592
- )}
2633
+ ${ctx.file.importType("Assign, DistributiveUnion, JsxHTMLProps, JsxStyleProps, Pretty", "./system-types")}
2593
2634
 
2594
2635
  interface Dict {
2595
2636
  [k: string]: unknown
@@ -2622,9 +2663,11 @@ interface RecipeFn {
2622
2663
  __type: any
2623
2664
  }
2624
2665
 
2666
+ export type MaybeAccessor<T> = T | Accessor<T>
2667
+
2625
2668
  export interface JsxFactoryOptions<TProps extends Dict> {
2626
2669
  dataAttr?: boolean
2627
- defaultProps?: Partial<TProps> & DataAttrs
2670
+ defaultProps?: MaybeAccessor<Partial<TProps> & DataAttrs>
2628
2671
  shouldForwardProp?: (prop: string, variantKeys: string[]) => boolean
2629
2672
  forwardProps?: string[]
2630
2673
  }
@@ -2670,9 +2713,29 @@ function generateSolidCreateStyleContext(ctx) {
2670
2713
  import { createComponent, mergeProps } from 'solid-js/web'
2671
2714
  import { createContext, createMemo, splitProps, useContext } from 'solid-js'
2672
2715
 
2716
+ function createSafeContext(contextName) {
2717
+ const Context = createContext(undefined)
2718
+ const useStyleContext = (componentName, slot) => {
2719
+ const context = useContext(Context)
2720
+ if (context === undefined) {
2721
+ const componentInfo = componentName ? \`Component "\${componentName}"\` : 'A component'
2722
+ const slotInfo = slot ? \` (slot: "\${slot}")\` : ''
2723
+
2724
+ throw new Error(
2725
+ \`\${componentInfo}\${slotInfo} cannot access \${contextName} because it's missing its Provider.\`
2726
+ )
2727
+ }
2728
+ return context
2729
+ }
2730
+ return [Context, useStyleContext]
2731
+ }
2732
+
2673
2733
  export function createStyleContext(recipe) {
2674
- const StyleContext = createContext({})
2675
2734
  const isConfigRecipe = '__recipe__' in recipe
2735
+ const recipeName = isConfigRecipe && recipe.__name__ ? recipe.__name__ : undefined
2736
+ const contextName = recipeName ? \`createStyleContext("\${recipeName}")\` : 'createStyleContext'
2737
+
2738
+ const [StyleContext, useStyleContext] = createSafeContext(contextName)
2676
2739
  const svaFn = isConfigRecipe ? recipe : sva(recipe.config)
2677
2740
 
2678
2741
  const getResolvedProps = (props, slotStyles) => {
@@ -2699,7 +2762,10 @@ function generateSolidCreateStyleContext(ctx) {
2699
2762
 
2700
2763
  const mergedProps = createMemo(() => {
2701
2764
  if (!options?.defaultProps) return propsWithoutChildren
2702
- return { ...options.defaultProps, ...propsWithoutChildren }
2765
+ const defaults = typeof options.defaultProps === 'function'
2766
+ ? options.defaultProps()
2767
+ : options.defaultProps
2768
+ return { ...defaults, ...propsWithoutChildren }
2703
2769
  })
2704
2770
 
2705
2771
  return createComponent(StyleContext.Provider, {
@@ -2771,9 +2837,10 @@ function generateSolidCreateStyleContext(ctx) {
2771
2837
 
2772
2838
  const withContext = (Component, slot, options) => {
2773
2839
  const StyledComponent = ${factoryName}(Component, {}, options)
2840
+ const componentName = getDisplayName(Component)
2774
2841
 
2775
2842
  const WithContext = (props) => {
2776
- const slotStyles = useContext(StyleContext)
2843
+ const slotStyles = useStyleContext(componentName, slot)
2777
2844
  const [local, propsWithoutChildren] = splitProps(props, ["children"])
2778
2845
 
2779
2846
  const resolvedProps = createMemo(() => {
@@ -2796,7 +2863,6 @@ function generateSolidCreateStyleContext(ctx) {
2796
2863
  )
2797
2864
  }
2798
2865
 
2799
- const componentName = getDisplayName(Component)
2800
2866
  WithContext.displayName = \`withContext(\${componentName})\`
2801
2867
  return WithContext
2802
2868
  }
@@ -2811,7 +2877,7 @@ function generateSolidCreateStyleContext(ctx) {
2811
2877
  dts: outdent34`
2812
2878
  ${ctx.file.importType("SlotRecipeRuntimeFn, RecipeVariantProps", "../types/recipe")}
2813
2879
  ${ctx.file.importType("JsxHTMLProps, JsxStyleProps, Assign", "../types/system-types")}
2814
- ${ctx.file.importType("JsxFactoryOptions, DataAttrs", "../types/jsx")}
2880
+ ${ctx.file.importType("JsxFactoryOptions, DataAttrs, MaybeAccessor, AsProps", "../types/jsx")}
2815
2881
  import type { Component, JSX, ComponentProps } from 'solid-js'
2816
2882
 
2817
2883
  interface UnstyledProps {
@@ -2819,7 +2885,7 @@ function generateSolidCreateStyleContext(ctx) {
2819
2885
  }
2820
2886
 
2821
2887
  interface WithProviderOptions<P> {
2822
- defaultProps?: (Partial<P> & DataAttrs) | undefined
2888
+ defaultProps?: MaybeAccessor<Partial<P> & DataAttrs> | undefined
2823
2889
  }
2824
2890
 
2825
2891
  type ElementType = keyof JSX.IntrinsicElements | Component<any>
@@ -2839,7 +2905,7 @@ function generateSolidCreateStyleContext(ctx) {
2839
2905
  : never
2840
2906
 
2841
2907
  type StyleContextProvider<T extends ElementType, R extends SlotRecipe> = Component<
2842
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
2908
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
2843
2909
  >
2844
2910
 
2845
2911
  type StyleContextRootProvider<T extends ElementType, R extends SlotRecipe> = Component<
@@ -2847,7 +2913,7 @@ function generateSolidCreateStyleContext(ctx) {
2847
2913
  >
2848
2914
 
2849
2915
  type StyleContextConsumer<T extends ElementType> = Component<
2850
- JsxHTMLProps<ComponentProps<T> & UnstyledProps, JsxStyleProps>
2916
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps, JsxStyleProps>
2851
2917
  >
2852
2918
 
2853
2919
  export interface StyleContext<R extends SlotRecipe> {
@@ -3307,7 +3373,22 @@ function generateVueCreateStyleContext(ctx) {
3307
3373
  export function createStyleContext(recipe) {
3308
3374
  const StyleContext = Symbol('StyleContext')
3309
3375
  const isConfigRecipe = '__recipe__' in recipe
3376
+ const recipeName = isConfigRecipe && recipe.__name__ ? recipe.__name__ : undefined
3377
+ const contextName = recipeName ? \`createStyleContext("\${recipeName}")\` : 'createStyleContext'
3310
3378
  const svaFn = isConfigRecipe ? recipe : sva(recipe.config)
3379
+
3380
+ function useStyleContext(componentName, slot) {
3381
+ const context = inject(StyleContext)
3382
+ if (context === undefined) {
3383
+ const componentInfo = componentName ? \`Component "\${componentName}"\` : 'A component'
3384
+ const slotInfo = slot ? \` (slot: "\${slot}")\` : ''
3385
+
3386
+ throw new Error(
3387
+ \`\${componentInfo}\${slotInfo} cannot access \${contextName} because it's missing its Provider.\`
3388
+ )
3389
+ }
3390
+ return context
3391
+ }
3311
3392
 
3312
3393
  const getResolvedProps = (props, slotStyles) => {
3313
3394
  const { unstyled, ...restProps } = props
@@ -3390,6 +3471,7 @@ function generateVueCreateStyleContext(ctx) {
3390
3471
 
3391
3472
  const withContext = (Component, slot, options) => {
3392
3473
  const StyledComponent = ${factoryName}(Component, {}, options)
3474
+ const componentName = getDisplayName(Component)
3393
3475
 
3394
3476
  const WithContext = defineComponent({
3395
3477
  props: ["unstyled"],
@@ -3400,7 +3482,7 @@ function generateVueCreateStyleContext(ctx) {
3400
3482
  propsWithClass.class = propsWithClass.class ?? options?.defaultProps?.class
3401
3483
  return propsWithClass
3402
3484
  })
3403
- const slotStyles = inject(StyleContext)
3485
+ const slotStyles = useStyleContext(componentName, slot)
3404
3486
 
3405
3487
  return () => {
3406
3488
  const resolvedProps = getResolvedProps(props.value, slotStyles.value[slot])
@@ -3410,7 +3492,6 @@ function generateVueCreateStyleContext(ctx) {
3410
3492
  },
3411
3493
  })
3412
3494
 
3413
- const componentName = getDisplayName(Component)
3414
3495
  WithContext.displayName = \`withContext(\${componentName})\`
3415
3496
 
3416
3497
  return WithContext
@@ -3426,7 +3507,7 @@ function generateVueCreateStyleContext(ctx) {
3426
3507
  dts: outdent40`
3427
3508
  ${ctx.file.importType("SlotRecipeRuntimeFn, RecipeVariantProps", "../types/recipe")}
3428
3509
  ${ctx.file.importType("JsxHTMLProps, JsxStyleProps, Assign", "../types/system-types")}
3429
- ${ctx.file.importType("JsxFactoryOptions, DataAttrs", "../types/jsx")}
3510
+ ${ctx.file.importType("JsxFactoryOptions, DataAttrs, AsProps", "../types/jsx")}
3430
3511
  import type { Component, FunctionalComponent, NativeElements } from 'vue'
3431
3512
 
3432
3513
  interface UnstyledProps {
@@ -3463,7 +3544,7 @@ function generateVueCreateStyleContext(ctx) {
3463
3544
  : never
3464
3545
 
3465
3546
  type StyleContextProvider<T extends ElementType, R extends SlotRecipe> = FunctionalComponent<
3466
- JsxHTMLProps<ComponentProps<T> & UnstyledProps & VModelProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
3547
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps & VModelProps, Assign<RecipeVariantProps<R>, JsxStyleProps>>
3467
3548
  >
3468
3549
 
3469
3550
  type StyleContextRootProvider<T extends ElementType, R extends SlotRecipe> = FunctionalComponent<
@@ -3471,7 +3552,7 @@ function generateVueCreateStyleContext(ctx) {
3471
3552
  >
3472
3553
 
3473
3554
  type StyleContextConsumer<T extends ElementType> = FunctionalComponent<
3474
- JsxHTMLProps<ComponentProps<T> & UnstyledProps & VModelProps, JsxStyleProps>
3555
+ JsxHTMLProps<ComponentProps<T> & UnstyledProps & AsProps & VModelProps, JsxStyleProps>
3475
3556
  >
3476
3557
 
3477
3558
  export interface StyleContext<R extends SlotRecipe> {
@@ -4874,34 +4955,35 @@ function cleanupSelectors(css, varSelector) {
4874
4955
 
4875
4956
  // src/artifacts/js/themes.ts
4876
4957
  var getThemeId = (themeName) => "panda-theme-" + themeName;
4877
- function generateThemes(ctx) {
4878
- const { themes } = ctx.config;
4879
- if (!themes) return;
4958
+ function getThemeCss(ctx, themeName) {
4880
4959
  const { tokens, conditions } = ctx;
4881
- return Object.entries(themes).map(([name, _themeVariant]) => {
4882
- const results = [];
4883
- const condName = ctx.conditions.getThemeName(name);
4884
- for (const [key, values] of tokens.view.vars.entries()) {
4885
- if (key.startsWith(condName)) {
4886
- const css = stringifyVars({ values, conditionKey: key, root: "", conditions });
4887
- if (css) {
4888
- results.push(css);
4889
- }
4960
+ const results = [];
4961
+ const condName = conditions.getThemeName(themeName);
4962
+ for (const [key, values] of tokens.view.vars.entries()) {
4963
+ if (key.startsWith(condName)) {
4964
+ const css = stringifyVars({ values, conditionKey: key, root: "", conditions });
4965
+ if (css) {
4966
+ results.push(css);
4890
4967
  }
4891
4968
  }
4892
- return {
4893
- name: `theme-${name}`,
4894
- json: JSON.stringify(
4895
- compact2({
4896
- name,
4897
- id: getThemeId(name),
4898
- css: results.join("\n\n")
4899
- }),
4900
- null,
4901
- 2
4902
- )
4903
- };
4904
- });
4969
+ }
4970
+ return results.join("\n\n");
4971
+ }
4972
+ function generateThemes(ctx) {
4973
+ const { themes } = ctx.config;
4974
+ if (!themes) return;
4975
+ return Object.entries(themes).map(([name, _themeVariant]) => ({
4976
+ name: `theme-${name}`,
4977
+ json: JSON.stringify(
4978
+ compact2({
4979
+ name,
4980
+ id: getThemeId(name),
4981
+ css: getThemeCss(ctx, name)
4982
+ }),
4983
+ null,
4984
+ 2
4985
+ )
4986
+ }));
4905
4987
  }
4906
4988
  function generateThemesIndex(ctx, files) {
4907
4989
  const { themes } = ctx.config;
@@ -5660,7 +5742,98 @@ var Generator = class extends Context2 {
5660
5742
  }
5661
5743
  return css;
5662
5744
  };
5745
+ /**
5746
+ * Get CSS for a specific layer from the stylesheet
5747
+ */
5748
+ getLayerCss = (sheet, layer) => {
5749
+ return sheet.getLayerCss(layer);
5750
+ };
5751
+ /**
5752
+ * Get CSS for a specific recipe
5753
+ */
5754
+ getRecipeCss = (recipeName) => {
5755
+ const sheet = this.createSheet();
5756
+ const decoder = this.decoder.collect(this.encoder);
5757
+ sheet.processDecoderForRecipe(decoder, recipeName);
5758
+ return sheet.getLayerCss("recipes");
5759
+ };
5760
+ /**
5761
+ * Get all recipe names from the decoder
5762
+ */
5763
+ getRecipeNames = () => {
5764
+ const decoder = this.decoder.collect(this.encoder);
5765
+ return Array.from(decoder.recipes.keys());
5766
+ };
5767
+ /**
5768
+ * Get all split CSS artifacts for the stylesheet
5769
+ * Used when --splitting flag is enabled
5770
+ */
5771
+ getSplitCssArtifacts = (sheet) => {
5772
+ const layerNames = this.config.layers;
5773
+ const decoder = this.decoder.collect(this.encoder);
5774
+ const layerDefs = [
5775
+ { name: "reset", file: "reset.css", css: sheet.getLayerCss("reset") },
5776
+ { name: "global", file: "global.css", css: sheet.getLayerCss("base") },
5777
+ { name: "tokens", file: "tokens.css", css: sheet.getLayerCss("tokens") },
5778
+ { name: "utilities", file: "utilities.css", css: sheet.getLayerCss("utilities") }
5779
+ ];
5780
+ const layers = layerDefs.filter((l) => l.css.trim()).map((l) => ({
5781
+ type: "layer",
5782
+ name: l.name,
5783
+ file: l.file,
5784
+ code: l.css
5785
+ }));
5786
+ const recipes = [];
5787
+ for (const recipeName of decoder.recipes.keys()) {
5788
+ const recipeSheet = this.createSheet();
5789
+ recipeSheet.processDecoderForRecipe(decoder, recipeName);
5790
+ const code = recipeSheet.getLayerCss("recipes");
5791
+ if (code.trim()) {
5792
+ recipes.push({
5793
+ type: "recipe",
5794
+ name: recipeName,
5795
+ file: `${dashCase(recipeName)}.css`,
5796
+ code,
5797
+ dir: "recipes"
5798
+ });
5799
+ }
5800
+ }
5801
+ const themes = [];
5802
+ if (this.config.themes) {
5803
+ for (const themeName of Object.keys(this.config.themes)) {
5804
+ const css = getThemeCss(this, themeName);
5805
+ if (css.trim()) {
5806
+ themes.push({
5807
+ type: "theme",
5808
+ name: themeName,
5809
+ file: `${dashCase(themeName)}.css`,
5810
+ code: `@layer ${layerNames.tokens} {
5811
+ ${css}
5812
+ }`,
5813
+ dir: "themes"
5814
+ });
5815
+ }
5816
+ }
5817
+ }
5818
+ const recipesIndex = recipes.map((r) => `@import './recipes/${r.file}';`).join("\n");
5819
+ const layerOrder = [layerNames.reset, layerNames.base, layerNames.tokens, layerNames.recipes, layerNames.utilities];
5820
+ const imports = [`@layer ${layerOrder.join(", ")};`, ""];
5821
+ for (const layer of layers) {
5822
+ imports.push(`@import './styles/${layer.file}';`);
5823
+ }
5824
+ if (recipes.length) {
5825
+ imports.push(`@import './styles/recipes.css';`);
5826
+ }
5827
+ return {
5828
+ layers,
5829
+ recipes,
5830
+ themes,
5831
+ recipesIndex,
5832
+ index: imports.join("\n")
5833
+ };
5834
+ };
5663
5835
  };
5664
5836
  export {
5665
- Generator
5837
+ Generator,
5838
+ getThemeCss
5666
5839
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pandacss/generator",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "The css generator for css panda",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -37,13 +37,13 @@
37
37
  "outdent": " ^0.8.0",
38
38
  "pluralize": "8.0.0",
39
39
  "postcss": "8.5.6",
40
- "ts-pattern": "5.8.0",
41
- "@pandacss/core": "1.5.0",
42
- "@pandacss/is-valid-prop": "^1.5.0",
43
- "@pandacss/logger": "1.5.0",
44
- "@pandacss/shared": "1.5.0",
45
- "@pandacss/token-dictionary": "1.5.0",
46
- "@pandacss/types": "1.5.0"
40
+ "ts-pattern": "5.9.0",
41
+ "@pandacss/core": "1.6.0",
42
+ "@pandacss/is-valid-prop": "^1.6.0",
43
+ "@pandacss/logger": "1.6.0",
44
+ "@pandacss/shared": "1.6.0",
45
+ "@pandacss/token-dictionary": "1.6.0",
46
+ "@pandacss/types": "1.6.0"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/pluralize": "0.0.33"