@pandacss/studio 0.37.0 → 0.37.2

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/astro.config.mjs CHANGED
@@ -1,9 +1,8 @@
1
- import react from '@astrojs/react'
2
1
  import studio from '@pandacss/astro-plugin-studio'
3
2
  import { defineConfig } from 'astro/config'
4
3
 
5
4
  // https://astro.build/config
6
5
  export default defineConfig({
7
6
  devToolbar: { enabled: true },
8
- integrations: [react(), studio()],
7
+ integrations: [studio()],
9
8
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pandacss/studio",
3
- "version": "0.37.0",
3
+ "version": "0.37.2",
4
4
  "description": "The automated token documentation for Panda CSS",
5
5
  "main": "dist/studio.js",
6
6
  "module": "dist/studio.mjs",
@@ -47,13 +47,13 @@
47
47
  "astro": "4.4.0",
48
48
  "react": "18.2.0",
49
49
  "react-dom": "18.2.0",
50
- "vite": "5.1.3",
51
- "@pandacss/config": "0.37.0",
52
- "@pandacss/logger": "0.37.0",
53
- "@pandacss/shared": "0.37.0",
54
- "@pandacss/token-dictionary": "0.37.0",
55
- "@pandacss/types": "0.37.0",
56
- "@pandacss/astro-plugin-studio": "0.37.0"
50
+ "vite": "5.1.7",
51
+ "@pandacss/config": "0.37.2",
52
+ "@pandacss/logger": "0.37.2",
53
+ "@pandacss/shared": "0.37.2",
54
+ "@pandacss/token-dictionary": "0.37.2",
55
+ "@pandacss/types": "0.37.2",
56
+ "@pandacss/astro-plugin-studio": "0.37.2"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@types/react": "18.2.55",
@@ -27,12 +27,12 @@ export default function Colors() {
27
27
  <SemanticColorDisplay
28
28
  value={colors.base.value}
29
29
  condition="base"
30
- token={getColorFromReference(colors.extensions.conditions.base)}
30
+ token={getColorFromReference(colors.extensions.conditions!.base)}
31
31
  />
32
32
  <SemanticColorDisplay
33
- value={colors[colors.extensions.condition].value}
34
- condition={colors.extensions.condition}
35
- token={getColorFromReference(colors.extensions.conditions[colors.extensions.condition])}
33
+ value={colors[colors.extensions.condition!].value}
34
+ condition={colors.extensions.condition!}
35
+ token={getColorFromReference(colors.extensions.conditions![colors.extensions.condition!])}
36
36
  />
37
37
  </HStack>
38
38
 
@@ -1,6 +1,8 @@
1
1
  import * as React from 'react'
2
2
  import { Flex, HStack, Square, Stack, panda } from '../../styled-system/jsx'
3
3
  import * as context from '../lib/panda-context'
4
+ import { EmptyState } from './empty-state'
5
+ import { TypographyIcon } from './icons'
4
6
 
5
7
  const fonts = context.getTokens('fonts')
6
8
 
@@ -9,6 +11,14 @@ const symbols = Array.from({ length: 10 }, (_, i) => String.fromCharCode(48 + i)
9
11
  const specials = ['@', '#', '$', '%', '&', '!', '?', '+', '-']
10
12
 
11
13
  export const FontFamily = () => {
14
+ if (fonts.length === 0) {
15
+ return (
16
+ <EmptyState title="No Tokens" icon={<TypographyIcon />}>
17
+ The panda config does not contain any font family
18
+ </EmptyState>
19
+ )
20
+ }
21
+
12
22
  return (
13
23
  <Stack gap="10">
14
24
  {fonts.map((font) => (
@@ -5,6 +5,8 @@ import { TokenContent } from '../components/token-content'
5
5
  import { TokenGroup } from '../components/token-group'
6
6
  import { Input, Textarea } from './input'
7
7
  import { StickyTop } from './sticky-top'
8
+ import { EmptyState } from './empty-state'
9
+ import { TypographyIcon, XMarkIcon } from './icons'
8
10
 
9
11
  interface FontTokensProps {
10
12
  text?: string
@@ -23,6 +25,14 @@ export default function FontTokens(props: FontTokensProps) {
23
25
  setText(event.target.value)
24
26
  }
25
27
 
28
+ if (fontTokens.length === 0) {
29
+ return (
30
+ <EmptyState title="No Tokens" icon={<TypographyIcon />}>
31
+ The panda config does not contain any `{token}` tokens
32
+ </EmptyState>
33
+ )
34
+ }
35
+
26
36
  return (
27
37
  <TokenGroup>
28
38
  <StickyTop>
@@ -44,7 +44,7 @@ export default function Overview() {
44
44
  <Logo />
45
45
 
46
46
  <div className={vstack({ my: '10', textAlign: 'center' })}>
47
- <Yums className={css({ fontSize: '24rem' })} />
47
+ <Yums className={css({ fontSize: '24rem', h: '300px' })} />
48
48
  <span className={css({ fontSize: '7xl', letterSpacing: 'tighter', fontWeight: 'medium' })}>Panda Studio</span>
49
49
  <p className={css({ fontSize: '2xl' })}>Live documentation for your design tokens (colors, fonts, etc.)</p>
50
50
  </div>
@@ -3,29 +3,13 @@ import { Flex, panda } from '../../styled-system/jsx'
3
3
  import { ColorWrapper } from './color-wrapper'
4
4
  import * as context from '../lib/panda-context'
5
5
 
6
- const getSemanticColorValue = (variable: string): string => {
7
- const _name = variable?.match(/var\(\s*--(.*?)\s*\)/)
8
- if (!_name) return variable
9
-
10
- const name = _name[1].replaceAll('-', '.')
11
- const token = context.tokens.getByName(name)
12
-
13
- if (!token) {
14
- const defaultToken = context.tokens.getByName(`${name}.default`)
15
- return getSemanticColorValue(defaultToken?.value)
16
- }
17
-
18
- if (token.value.startsWith('var(--')) return getSemanticColorValue(token.value)
19
- return token.value
20
- }
21
-
22
6
  // remove initial underscore
23
7
  const cleanCondition = (condition: string) => condition.replace(/^_/, '')
24
8
 
25
9
  export function SemanticColorDisplay(props: { value: string; condition: string; token?: string }) {
26
10
  const { value, condition } = props
27
11
 
28
- const tokenValue = getSemanticColorValue(value)
12
+ const tokenValue = context.tokens.deepResolveReference(value)
29
13
 
30
14
  return (
31
15
  <Flex direction="column" w="full">
@@ -5,16 +5,19 @@ import { Grid, panda } from '../../styled-system/jsx'
5
5
  import { getSortedSizes } from '../lib/sizes-sort'
6
6
  import { TokenGroup } from './token-group'
7
7
  import type { Token } from '@pandacss/token-dictionary'
8
+ import { EmptyState } from './empty-state'
9
+ import { SizesIcon } from './icons'
8
10
 
9
11
  export interface SizesProps {
10
12
  sizes: Token[]
13
+ name: string
11
14
  }
12
15
 
13
16
  const contentRegex = /^(min|max|fit)-content$/
14
17
  const unitRegex = /(ch|%)$/
15
18
 
16
19
  export default function Sizes(props: SizesProps) {
17
- const { sizes } = props
20
+ const { sizes, name } = props
18
21
 
19
22
  const sortedSizes = getSortedSizes(sizes).filter(
20
23
  (token) =>
@@ -27,6 +30,14 @@ export default function Sizes(props: SizesProps) {
27
30
  !unitRegex.test(token.value),
28
31
  )
29
32
 
33
+ if (sortedSizes.length === 0) {
34
+ return (
35
+ <EmptyState title="No Tokens" icon={<SizesIcon />}>
36
+ The panda config does not contain any `{name}`` tokens
37
+ </EmptyState>
38
+ )
39
+ }
40
+
30
41
  return (
31
42
  <TokenGroup>
32
43
  <Grid display="grid" columnGap="10" rowGap="2.5" columns={5}>
@@ -5,6 +5,7 @@ import { EmptyState } from './empty-state'
5
5
  import { TextStylesIcon } from './icons'
6
6
  import { TokenContent } from './token-content'
7
7
  import { TokenGroup } from './token-group'
8
+ import type { Dict } from '../../styled-system/types'
8
9
 
9
10
  export default function TextStyles() {
10
11
  const textStyles = Object.entries(context.textStyles)
@@ -18,7 +19,7 @@ export default function TextStyles() {
18
19
  <panda.div borderColor="card">
19
20
  <panda.span fontWeight="medium">{name}</panda.span>
20
21
  </panda.div>
21
- <panda.div flex="auto" my="3" style={styles} truncate>
22
+ <panda.div flex="auto" my="3" style={removeEscapeHatchSyntax(styles)} truncate>
22
23
  Panda textStyles are time saving
23
24
  </panda.div>
24
25
  </panda.div>
@@ -32,3 +33,15 @@ export default function TextStyles() {
32
33
  </TokenGroup>
33
34
  )
34
35
  }
36
+
37
+ const removeEscapeHatchSyntax = (styles: Dict) => {
38
+ return Object.fromEntries(
39
+ Object.entries(styles).map(([key, value]) => {
40
+ if (typeof value === 'string' && value[0] === '[' && value[value.length - 1] === ']') {
41
+ return [key, value.slice(1, -1)]
42
+ }
43
+
44
+ return [key, value]
45
+ }),
46
+ )
47
+ }
@@ -1,4 +1,4 @@
1
- import type { Token } from '@pandacss/token-dictionary'
1
+ import type { Token, TokenExtensions } from '@pandacss/token-dictionary'
2
2
  import { useState } from 'react'
3
3
  import * as context from './panda-context'
4
4
 
@@ -10,33 +10,36 @@ interface Color {
10
10
  path: string[]
11
11
  }
12
12
 
13
- type ColorToken = Token & Color
13
+ type ColorToken = Token & Color & TokenExtensions
14
14
 
15
15
  const UNCATEGORIZED_ID = 'uncategorized' as const
16
16
 
17
- const groupByColorPalette = (colors: Token[], filterMethod?: (token: ColorToken) => boolean) => {
17
+ const groupByColorPalette = (colors: ColorToken[], filterMethod?: (token: ColorToken) => boolean) => {
18
18
  const values = colors.filter((color) => !color.isConditional && !color.extensions.isVirtual)
19
19
 
20
- return values.reduce<Record<string, any>>((acc, color) => {
21
- if (!filterMethod?.(color)) return acc
20
+ return values.reduce(
21
+ (acc, color) => {
22
+ if (!filterMethod?.(color)) return acc
22
23
 
23
- const colorPalette = color.extensions.colorPalette || UNCATEGORIZED_ID
24
+ const colorPalette = color.extensions.colorPalette || UNCATEGORIZED_ID
24
25
 
25
- if (!(colorPalette in acc)) {
26
- acc[colorPalette] = []
27
- }
26
+ if (!(colorPalette in acc)) {
27
+ acc[colorPalette] = []
28
+ }
28
29
 
29
- const exists = (acc[colorPalette] as any[]).find((tok) => tok.name === color.name)
30
- if (!exists) acc[colorPalette].push(color)
30
+ const exists = (acc[colorPalette] as any[]).find((tok) => tok.name === color.name)
31
+ if (!exists) acc[colorPalette].push(color)
31
32
 
32
- return acc
33
- }, {})
33
+ return acc
34
+ },
35
+ {} as Record<string, ColorToken[]>,
36
+ )
34
37
  }
35
38
 
36
- const getSemanticTokens = (allTokens: ColorToken[], filterMethod?: (token: ColorToken) => boolean) => {
39
+ const getSemanticTokens = (allTokens: Token[], filterMethod?: (token: ColorToken) => boolean) => {
37
40
  const semanticTokens = allTokens.filter(
38
41
  (token) => token.type === 'color' && token.isConditional && !token.extensions?.isVirtual,
39
- )
42
+ ) as ColorToken[]
40
43
  return semanticTokens
41
44
  .reduce((acc, nxt) => {
42
45
  if (!filterMethod) {
@@ -50,7 +53,7 @@ const getSemanticTokens = (allTokens: ColorToken[], filterMethod?: (token: Color
50
53
  }
51
54
  return acc
52
55
  }, [] as ColorToken[])
53
- .reduce<Record<string, any>>(
56
+ .reduce<Record<string, ColorToken>>(
54
57
  (acc, nxt) => ({
55
58
  ...acc,
56
59
  [nxt.extensions?.prop]: {
@@ -85,14 +88,17 @@ export const useColorDocs = () => {
85
88
  .some((prop) => prop.includes(filterQuery))
86
89
  }
87
90
 
88
- const colorsInCategories = groupByColorPalette(colors, filterMethod)
91
+ const colorsInCategories = groupByColorPalette(colors as ColorToken[], filterMethod)
89
92
  const uncategorizedColors = colorsInCategories[UNCATEGORIZED_ID]
90
93
 
91
94
  const categorizedColors = Object.entries<any[]>(colorsInCategories).filter(
92
95
  ([category]) => category !== UNCATEGORIZED_ID,
93
96
  )
94
97
 
95
- const semanticTokens = Object.entries<Record<string, any>>(getSemanticTokens(allTokens, filterMethod))
98
+ const semanticTokens = Object.entries<Record<string, any>>(getSemanticTokens(allTokens, filterMethod)) as [
99
+ string,
100
+ Record<string, ColorToken>,
101
+ ][]
96
102
  const hasResults =
97
103
  !!categorizedColors.length || !!uncategorizedColors?.length || !!Object.values(semanticTokens).length
98
104
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- import Sizes from '../components/sizes'
2
+ import Sizes from '../components/sizes'
3
3
  import Layout from '../layouts/Layout.astro'
4
4
  import Sidebar from '../layouts/Sidebar.astro'
5
5
  import * as context from '../lib/panda-context'
@@ -9,7 +9,6 @@ const tokens = context.getTokens('sizes')
9
9
 
10
10
  <Layout>
11
11
  <Sidebar title="Sizes">
12
- <Sizes sizes={tokens} client:load />
12
+ <Sizes sizes={tokens} name="sizes" client:load />
13
13
  </Sidebar>
14
14
  </Layout>
15
-
@@ -1,5 +1,5 @@
1
1
  ---
2
- import Sizes from '../components/sizes'
2
+ import Sizes from '../components/sizes'
3
3
  import Layout from '../layouts/Layout.astro'
4
4
  import Sidebar from '../layouts/Sidebar.astro'
5
5
  import * as context from '../lib/panda-context'
@@ -8,7 +8,7 @@ const tokens = context.getTokens('spacing')
8
8
  ---
9
9
 
10
10
  <Layout>
11
- <Sidebar title="Spacing">
12
- <Sizes sizes={tokens} client:load />
13
- </Sidebar>
11
+ <Sidebar title="Spacing">
12
+ <Sizes sizes={tokens} name="spacing" client:load />
13
+ </Sidebar>
14
14
  </Layout>
@@ -11,9 +11,10 @@ const defaults = (conf) => ({
11
11
 
12
12
  export function cva(config) {
13
13
  const { base, variants, defaultVariants, compoundVariants } = defaults(config)
14
+ const getVariantProps = (variants) => ({ ...defaultVariants, ...compact(variants) })
14
15
 
15
16
  function resolve(props = {}) {
16
- const computedVariants = { ...defaultVariants, ...compact(props) }
17
+ const computedVariants = getVariantProps(props)
17
18
  let variantCss = { ...base }
18
19
  for (const [key, value] of Object.entries(computedVariants)) {
19
20
  if (variants[key]?.[value]) {
@@ -57,6 +58,7 @@ export function cva(config) {
57
58
  config,
58
59
  merge,
59
60
  splitVariantProps,
61
+ getVariantProps
60
62
  })
61
63
  }
62
64
 
@@ -1,4 +1,4 @@
1
- import { getSlotRecipes, memo, splitProps } from '../helpers.mjs';
1
+ import { compact, getSlotRecipes, memo, splitProps } from '../helpers.mjs';
2
2
  import { cva } from './cva.mjs';
3
3
  import { cx } from './cx.mjs';
4
4
 
@@ -6,6 +6,7 @@ const slotClass = (className, slot) => className + '__' + slot
6
6
 
7
7
  export function sva(config) {
8
8
  const slots = Object.entries(getSlotRecipes(config)).map(([slot, slotCva]) => [slot, cva(slotCva)])
9
+ const defaultVariants = config.defaultVariants ?? {}
9
10
 
10
11
  function svaFn(props) {
11
12
  const result = slots.map(([slot, cvaFn]) => [slot, cx(cvaFn(props), config.className && slotClass(config.className, slot))])
@@ -23,6 +24,7 @@ export function sva(config) {
23
24
  function splitVariantProps(props) {
24
25
  return splitProps(props, variantKeys);
25
26
  }
27
+ const getVariantProps = (variants) => ({ ...(defaultVariants || {}), ...compact(variants) })
26
28
 
27
29
  const variantMap = Object.fromEntries(
28
30
  Object.entries(variants).map(([key, value]) => [key, Object.keys(value)])
@@ -34,5 +36,6 @@ export function sva(config) {
34
36
  variantMap,
35
37
  variantKeys,
36
38
  splitVariantProps,
39
+ getVariantProps,
37
40
  })
38
41
  }
@@ -229,7 +229,7 @@ var patternFns = {
229
229
  isCssUnit
230
230
  };
231
231
  var getPatternStyles = (pattern, styles) => {
232
- if (!pattern.defaultValues)
232
+ if (!pattern?.defaultValues)
233
233
  return styles;
234
234
  const defaults = typeof pattern.defaultValues === "function" ? pattern.defaultValues(styles) : pattern.defaultValues;
235
235
  return Object.assign({}, defaults, compact(styles));
@@ -707,7 +707,6 @@
707
707
  }
708
708
 
709
709
  @layer utilities{
710
-
711
710
  .d_flex {
712
711
  display: flex;
713
712
  }
@@ -957,6 +956,10 @@
957
956
  margin-block: var(--spacing-10);
958
957
  }
959
958
 
959
+ .h_300px {
960
+ height: 300px;
961
+ }
962
+
960
963
  .tracking_tighter {
961
964
  letter-spacing: var(--letter-spacings-tighter);
962
965
  }
@@ -1422,4 +1425,4 @@
1422
1425
  padding-inline: var(--spacing-8);
1423
1426
  }
1424
1427
  }
1425
- }
1428
+ }
@@ -208,7 +208,7 @@ type WithColorOpacityModifier<T> = T extends string ? `${T}/${string}` : T
208
208
  type ImportantMark = "!" | "!important"
209
209
  type WhitespaceImportant = ` ${ImportantMark}`
210
210
  type Important = ImportantMark | WhitespaceImportant
211
- type WithImportant<T> = T extends string ? `${T}${Important}${string}` : T
211
+ type WithImportant<T> = T extends string ? `${T}${Important}` & { __important?: true } : T;
212
212
 
213
213
  /**
214
214
  * Only relevant when using `strictTokens` or `strictPropertyValues` in your config.
@@ -226,7 +226,7 @@ type WithImportant<T> = T extends string ? `${T}${Important}${string}` : T
226
226
  * @see https://panda-css.com/docs/concepts/writing-styles#stricttokens
227
227
  * @see https://panda-css.com/docs/concepts/writing-styles#strictpropertyvalues
228
228
  */
229
- export type WithEscapeHatch<T> = T | `[${string}]` | (T extends string ? WithColorOpacityModifier<string> | WithImportant<T> : T)
229
+ export type WithEscapeHatch<T> = T | `[${string}]` | WithColorOpacityModifier<T> | WithImportant<T>
230
230
 
231
231
  /**
232
232
  * Will restrict the value of properties that have predefined values to those values only.
@@ -46,6 +46,7 @@ export interface RecipeRuntimeFn<T extends RecipeVariantRecord> extends RecipeVa
46
46
  splitVariantProps<Props extends RecipeSelection<T>>(
47
47
  props: Props,
48
48
  ): [RecipeSelection<T>, Pretty<DistributiveOmit<Props, keyof T>>]
49
+ getVariantProps: (props?: RecipeSelection<T>) => RecipeSelection<T>
49
50
  }
50
51
 
51
52
  type OneOrMore<T> = T | Array<T>
@@ -122,7 +123,10 @@ export interface SlotRecipeRuntimeFn<S extends string, T extends SlotRecipeVaria
122
123
  raw: (props?: RecipeSelection<T>) => Record<S, SystemStyleObject>
123
124
  variantKeys: (keyof T)[]
124
125
  variantMap: RecipeVariantMap<T>
125
- splitVariantProps<Props extends RecipeSelection<T>>(props: Props): [RecipeSelection<T>, Pretty<Omit<Props, keyof T>>]
126
+ splitVariantProps<Props extends RecipeSelection<T>>(
127
+ props: Props,
128
+ ): [RecipeSelection<T>, Pretty<DistributiveOmit<Props, keyof T>>]
129
+ getVariantProps: (props?: RecipeSelection<T>) => RecipeSelection<T>
126
130
  }
127
131
 
128
132
  export type SlotRecipeCompoundVariant<S extends string, T> = T & {