@pandacss/studio 0.27.3 → 0.28.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.
Files changed (61) hide show
  1. package/package.json +10 -9
  2. package/panda.config.ts +5 -27
  3. package/src/components/color-constrast.tsx +40 -67
  4. package/src/components/color-wrapper.tsx +21 -24
  5. package/src/components/colors.tsx +57 -50
  6. package/src/components/empty-state.tsx +4 -2
  7. package/src/components/font-family.tsx +4 -4
  8. package/src/components/font-tokens.tsx +17 -26
  9. package/src/components/icons.tsx +2 -0
  10. package/src/components/input.tsx +4 -2
  11. package/src/components/layer-styles.tsx +4 -3
  12. package/src/components/overview.tsx +77 -57
  13. package/src/components/radii.tsx +6 -5
  14. package/src/components/semantic-color.tsx +4 -6
  15. package/src/components/side-nav-item.astro +1 -1
  16. package/src/components/side-nav.astro +3 -3
  17. package/src/components/sizes.tsx +7 -6
  18. package/src/components/sticky-top.tsx +10 -0
  19. package/src/components/test-score.tsx +35 -0
  20. package/src/components/text-styles.tsx +3 -2
  21. package/src/components/theme-toggle.astro +1 -1
  22. package/src/components/token-content.tsx +8 -4
  23. package/src/components/token-group.tsx +9 -4
  24. package/src/components/typography-playground.tsx +17 -16
  25. package/src/{components → icons}/logo.tsx +6 -1
  26. package/src/icons/moon.tsx +1 -0
  27. package/src/icons/sun.tsx +1 -0
  28. package/src/icons/yums.tsx +1144 -0
  29. package/src/layouts/Layout.astro +2 -1
  30. package/src/layouts/Sidebar.astro +6 -6
  31. package/src/lib/constants.ts +0 -7
  32. package/src/lib/panda-context.ts +33 -0
  33. package/src/lib/truncate.ts +4 -0
  34. package/src/lib/use-color-docs.ts +20 -14
  35. package/src/pages/colors.astro +1 -1
  36. package/src/pages/font-sizes.astro +4 -4
  37. package/src/pages/font-weights.astro +3 -4
  38. package/src/pages/index.astro +1 -1
  39. package/src/pages/layer-styles.astro +1 -1
  40. package/src/pages/letter-spacings.astro +4 -3
  41. package/src/pages/line-heights.astro +3 -4
  42. package/src/pages/playground/contrast-checker.astro +2 -2
  43. package/src/pages/playground/typography.astro +2 -2
  44. package/src/pages/radii.astro +1 -1
  45. package/src/pages/sizes.astro +4 -3
  46. package/src/pages/spacing.astro +3 -3
  47. package/src/pages/text-styles.astro +1 -1
  48. package/styled-system/jsx/index.d.ts +0 -1
  49. package/styled-system/jsx/index.mjs +1 -2
  50. package/styled-system/jsx/is-valid-prop.mjs +1 -1
  51. package/styled-system/patterns/index.d.ts +1 -2
  52. package/styled-system/patterns/index.mjs +1 -2
  53. package/styled-system/styles.css +708 -599
  54. package/styled-system/tokens/index.mjs +4 -0
  55. package/styled-system/tokens/tokens.d.ts +4 -4
  56. package/styled-system/types/prop-type.d.ts +1 -1
  57. package/tsconfig.json +8 -0
  58. package/src/components/nav-item.tsx +0 -39
  59. package/src/lib/create-context.ts +0 -27
  60. package/src/lib/panda.context.ts +0 -19
  61. package/src/lib/truncate.tsx +0 -7
@@ -1,65 +1,85 @@
1
- import { css } from '../../styled-system/css'
2
- import { panda, Wrap } from '../../styled-system/jsx'
3
- import { NavItem } from './nav-item'
1
+ import * as React from 'react'
2
+ import { css, cva } from '../../styled-system/css'
3
+ import { flex, hstack, square, vstack } from '../../styled-system/patterns'
4
+ import { Yums } from '../icons/yums'
5
+ import { Logo } from '../icons/logo'
6
+ import { Wrap } from '../../styled-system/jsx'
4
7
  import { navItems } from '../lib/constants'
5
- import { Logo } from './logo'
6
8
 
7
- export function Overview() {
9
+ const buttonRecipe = cva({
10
+ base: {
11
+ display: 'inline-flex',
12
+ px: '6',
13
+ py: '3',
14
+ fontWeight: 'medium',
15
+ fontSize: '2xl',
16
+ rounded: 'sm',
17
+ },
18
+ variants: {
19
+ variant: {
20
+ solid: {
21
+ bg: 'yellow.300',
22
+ color: 'black',
23
+ },
24
+ outline: {
25
+ borderWidth: '1px',
26
+ color: 'yellow.300',
27
+ },
28
+ },
29
+ },
30
+ })
31
+
32
+ export default function Overview() {
8
33
  return (
9
- <panda.div display="flex" flexDir="column">
10
- <panda.span fontWeight="bold" fontSize="2xl" px="8" py="4" display="flex" gap="2">
34
+ <div
35
+ className={flex({
36
+ direction: 'column',
37
+ minH: 'dvh',
38
+ borderTopWidth: '8px',
39
+ borderTopColor: 'accent',
40
+ })}
41
+ >
42
+ <div className={vstack({ px: '8', py: '12dvh', mb: '10', flex: '1' })}>
11
43
  <Logo />
12
- </panda.span>
13
- <panda.div px="8" py="24" mb="10" background="card">
14
- <panda.span display="block" fontSize="3xl" fontWeight="semibold" mb="6">
15
- Design System
16
- </panda.span>
17
- <p>Build great products, faster.</p>
18
- <panda.a
19
- href="/colors"
20
- className={css({
21
- background: '#646cff',
22
- color: 'white',
23
- width: 'fit-content',
24
- fontSize: 'small',
25
- fontWeight: 'semibold',
26
- px: '6',
27
- py: '1',
28
- borderRadius: 'sm',
29
- marginTop: '6',
30
- transition: 'all 0.2s ease',
31
- display: 'block',
32
- '&:hover': {
33
- background: '#4049f0',
34
- boxShadow: 'lg',
35
- },
36
- })}
37
- >
38
- Explore
39
- </panda.a>
40
- </panda.div>
41
- <Wrap gap="6" p="8" my="2">
42
- <div>
43
- <panda.span display="block">TOKENS</panda.span>
44
- <Wrap my="2" p="0" gap="6">
45
- {navItems
46
- .filter((k) => k.type === 'token')
47
- .map((data, index) => (
48
- <NavItem key={index} {...data} />
49
- ))}
50
- </Wrap>
44
+
45
+ <div className={vstack({ my: '10', textAlign: 'center' })}>
46
+ <Yums className={css({ fontSize: '24rem' })} />
47
+ <span className={css({ fontSize: '7xl', letterSpacing: 'tighter', fontWeight: 'medium' })}>Panda Studio</span>
48
+ <p className={css({ fontSize: '2xl' })}>Live documentation for your design tokens (colors, fonts, etc.)</p>
51
49
  </div>
52
- <div>
53
- <panda.span display="block">PLAYGROUND</panda.span>
54
- <Wrap my="2" p="0" gap="6">
55
- {navItems
56
- .filter((k) => k.type === 'playground')
57
- .map((data, index) => (
58
- <NavItem key={index} {...data} />
59
- ))}
60
- </Wrap>
50
+
51
+ <div className={hstack({ gap: '6' })}>
52
+ <a href="/colors" className={buttonRecipe({ variant: 'solid' })}>
53
+ Get Started
54
+ </a>
55
+ <a href="https://panda-css.com?ref=studio" target="_blank" className={buttonRecipe({ variant: 'outline' })}>
56
+ View Docs
57
+ </a>
61
58
  </div>
62
- </Wrap>
63
- </panda.div>
59
+
60
+ <Wrap mt="20" p="0" gap="6" justify="center">
61
+ {navItems
62
+ .filter((k) => k.type === 'token')
63
+ .map((item, index) => (
64
+ <div key={index}>
65
+ <a
66
+ title={item.label}
67
+ href={`/${item.id}`}
68
+ className={square({
69
+ size: '20',
70
+ fontSize: '2xl',
71
+ fontWeight: 'medium',
72
+ color: 'accent',
73
+ borderWidth: '1px',
74
+ borderColor: 'card',
75
+ })}
76
+ >
77
+ <item.icon />
78
+ </a>
79
+ </div>
80
+ ))}
81
+ </Wrap>
82
+ </div>
83
+ </div>
64
84
  )
65
85
  }
@@ -1,12 +1,13 @@
1
+ import * as React from 'react'
1
2
  import { toPx } from '@pandacss/shared'
2
3
  import { Grid, panda, Stack } from '../../styled-system/jsx'
3
- import context from '../lib/panda.context'
4
+ import * as context from '../lib/panda-context'
4
5
  import { getSortedSizes } from '../lib/sizes-sort'
5
6
  import { TokenGroup } from './token-group'
6
7
 
7
- const radii = context.getCategory('radii')
8
+ const radii = context.getTokens('radii')
8
9
 
9
- export function Radii() {
10
+ export default function Radii() {
10
11
  return (
11
12
  <TokenGroup>
12
13
  {radii && (
@@ -14,14 +15,14 @@ export function Radii() {
14
15
  {getSortedSizes([...radii.values()])
15
16
  .sort((a, b) => parseFloat(toPx(a.value)!) - parseFloat(toPx(b.value)!))
16
17
  .map((size, index) => (
17
- <Stack direction="column" align="center" key={index}>
18
+ <Stack direction="column" key={index}>
18
19
  <panda.div
19
20
  width="80px"
20
21
  height="80px"
21
22
  background="rgba(255, 192, 203, 0.5)"
22
23
  style={{ borderRadius: size.value }}
23
24
  />
24
- <Stack gap="1" align="center">
25
+ <Stack gap="1">
25
26
  <b>{size.extensions.prop}</b>
26
27
  <panda.span opacity="0.7">{size.value}</panda.span>
27
28
  </Stack>
@@ -1,6 +1,7 @@
1
+ import * as React from 'react'
1
2
  import { Flex, panda } from '../../styled-system/jsx'
2
3
  import { ColorWrapper } from './color-wrapper'
3
- import context from '../lib/panda.context'
4
+ import * as context from '../lib/panda-context'
4
5
 
5
6
  const getSemanticColorValue = (variable: string): string => {
6
7
  const _name = variable.match(/var\(\s*--(.*?)\s*\)/)
@@ -22,7 +23,7 @@ const getSemanticColorValue = (variable: string): string => {
22
23
  const cleanCondition = (condition: string) => condition.replace(/^_/, '')
23
24
 
24
25
  export function SemanticColorDisplay(props: { value: string; condition: string; token?: string }) {
25
- const { value, condition, token } = props
26
+ const { value, condition } = props
26
27
 
27
28
  const tokenValue = getSemanticColorValue(value)
28
29
 
@@ -44,10 +45,7 @@ export function SemanticColorDisplay(props: { value: string; condition: string;
44
45
  {cleanCondition(condition)}
45
46
  </panda.span>
46
47
  </ColorWrapper>
47
- <panda.div fontWeight="medium" mt="2">
48
- {token} &nbsp;
49
- </panda.div>
50
- <panda.div opacity="0.7" fontSize="sm" textTransform="uppercase">
48
+ <panda.div opacity="0.7" fontSize="sm">
51
49
  {value} {value !== tokenValue && `- ${tokenValue}`}
52
50
  </panda.div>
53
51
  </Flex>
@@ -18,7 +18,7 @@ const isActive = Astro.url.pathname.startsWith(href)
18
18
  fontSize="md"
19
19
  fontWeight="medium"
20
20
  aria-current={isActive ? 'page' : undefined}
21
- color={{ _hover: 'yellow.300', _currentPage: 'yellow.300' }}
21
+ color={{ _hover: 'accent', _currentPage: 'accent' }}
22
22
  >
23
23
  <slot />
24
24
  </panda.a>
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  import { navItems } from '../lib/constants'
3
3
  import { panda, Stack } from '../../styled-system/jsx'
4
- import NavItem from './side-nav-item.astro'
4
+ import SideNavItem from './side-nav-item.astro'
5
5
  ---
6
6
 
7
7
  <panda.nav marginTop="8">
@@ -12,7 +12,7 @@ import NavItem from './side-nav-item.astro'
12
12
  {
13
13
  navItems
14
14
  .filter((item) => item.type === 'token')
15
- .map((item) => <NavItem href={`/${item.id}`}>{item.label}</NavItem>)
15
+ .map((item) => <SideNavItem href={`/${item.id}`}>{item.label}</SideNavItem>)
16
16
  }
17
17
  </panda.ul>
18
18
  </div>
@@ -22,7 +22,7 @@ import NavItem from './side-nav-item.astro'
22
22
  {
23
23
  navItems
24
24
  .filter((item) => item.type === 'playground')
25
- .map((item) => <NavItem href={`/${item.id}`}>{item.label}</NavItem>)
25
+ .map((item) => <SideNavItem href={`/${item.id}`}>{item.label}</SideNavItem>)
26
26
  }
27
27
  </panda.ul>
28
28
  </div>
@@ -1,21 +1,22 @@
1
+ import * as React from 'react'
1
2
  import { toPx } from '@pandacss/shared'
2
3
  import { Fragment } from 'react'
3
4
  import { Grid, panda } from '../../styled-system/jsx'
4
5
  import { getSortedSizes } from '../lib/sizes-sort'
5
6
  import { TokenGroup } from './token-group'
7
+ import type { Token } from '@pandacss/token-dictionary'
6
8
 
7
9
  export interface SizesProps {
8
- sizes: Map<string, any>
10
+ sizes: Token[]
9
11
  }
10
12
 
11
13
  const contentRegex = /^(min|max|fit)-content$/
12
14
  const unitRegex = /(ch|%)$/
13
15
 
14
- export function Sizes(props: SizesProps) {
15
- const { sizes: tokens } = props
16
- const values = Array.from(tokens.values())
16
+ export default function Sizes(props: SizesProps) {
17
+ const { sizes } = props
17
18
 
18
- const sizes = getSortedSizes(values).filter(
19
+ const sortedSizes = getSortedSizes(sizes).filter(
19
20
  (token) =>
20
21
  // remove negative values
21
22
  !token.extensions.isNegative &&
@@ -35,7 +36,7 @@ export function Sizes(props: SizesProps) {
35
36
  Pixels
36
37
  </panda.span>
37
38
  <panda.hr gridColumn="span 5 / span 5" />
38
- {sizes
39
+ {sortedSizes
39
40
  .sort((a, b) => a.extensions.prop - b.extensions.prop)
40
41
  .map((size, index) => (
41
42
  <Fragment key={index}>
@@ -0,0 +1,10 @@
1
+ import { panda } from '../../styled-system/jsx'
2
+
3
+ export const StickyTop = panda('div', {
4
+ base: {
5
+ position: 'sticky',
6
+ top: '6',
7
+ zIndex: '1',
8
+ mb: '4',
9
+ },
10
+ })
@@ -0,0 +1,35 @@
1
+ import * as React from 'react'
2
+ import { HStack } from '../../styled-system/jsx'
3
+ import { ErrorIcon, SuccessIcon } from './icons'
4
+
5
+ interface TestScore {
6
+ WCAG_AA: boolean
7
+ WCAG_AAA: boolean
8
+ }
9
+
10
+ interface TestScoreProps {
11
+ score: TestScore
12
+ size: 'regular' | 'large'
13
+ }
14
+
15
+ export function TestScore(props: TestScoreProps) {
16
+ const { score, size } = props
17
+ return (
18
+ <>
19
+ <HStack justify="space-between" fontWeight="medium">
20
+ <HStack gap="2">
21
+ <span>{score.WCAG_AA ? <SuccessIcon /> : <ErrorIcon />}</span>
22
+ <span>AA</span>
23
+ </HStack>
24
+ <span>{size === 'regular' ? '4.5:1' : '3:1'}</span>
25
+ </HStack>
26
+ <HStack justify="space-between" fontWeight="medium">
27
+ <HStack gap="2">
28
+ <span>{score.WCAG_AAA ? <SuccessIcon /> : <ErrorIcon />}</span>
29
+ <span>AAA</span>
30
+ </HStack>
31
+ <span>{size === 'regular' ? '7:1' : '4.5:1'}</span>
32
+ </HStack>
33
+ </>
34
+ )
35
+ }
@@ -1,11 +1,12 @@
1
+ import * as React from 'react'
1
2
  import { panda } from '../../styled-system/jsx'
2
- import context from '../lib/panda.context'
3
+ import * as context from '../lib/panda-context'
3
4
  import { EmptyState } from './empty-state'
4
5
  import { TextStylesIcon } from './icons'
5
6
  import { TokenContent } from './token-content'
6
7
  import { TokenGroup } from './token-group'
7
8
 
8
- export function TextStyles() {
9
+ export default function TextStyles() {
9
10
  const textStyles = Object.entries(context.textStyles)
10
11
 
11
12
  return (
@@ -17,7 +17,7 @@ const buttonStyles = hstack({
17
17
  const iconStyles = css({
18
18
  cursor: 'pointer',
19
19
  '&.active': {
20
- color: 'yellow.300',
20
+ color: 'accent',
21
21
  },
22
22
  })
23
23
  ---
@@ -1,5 +1,9 @@
1
- import { type HTMLPandaProps, panda } from '../../styled-system/jsx'
1
+ import { panda } from '../../styled-system/jsx'
2
2
 
3
- export function TokenContent(props: HTMLPandaProps<'div'>) {
4
- return <panda.div display="flex" flexDir="column" gap="12" {...props} />
5
- }
3
+ export const TokenContent = panda('div', {
4
+ base: {
5
+ display: 'flex',
6
+ flexDirection: 'column',
7
+ gap: '12',
8
+ },
9
+ })
@@ -1,6 +1,11 @@
1
- import type { HTMLPandaProps } from '../../styled-system/jsx'
2
1
  import { panda } from '../../styled-system/jsx'
3
2
 
4
- export function TokenGroup(props: HTMLPandaProps<'div'>) {
5
- return <panda.div display="flex" flexDir="column" gap="3" width="full" marginTop="5" {...props} />
6
- }
3
+ export const TokenGroup = panda('div', {
4
+ base: {
5
+ display: 'flex',
6
+ flexDir: 'column',
7
+ gap: '3',
8
+ width: 'full',
9
+ marginTop: '5',
10
+ },
11
+ })
@@ -1,23 +1,24 @@
1
+ import type { Token } from '@pandacss/token-dictionary'
2
+ import * as React from 'react'
1
3
  import { useState } from 'react'
2
4
  import { Stack, panda } from '../../styled-system/jsx'
3
- import context from '../lib/panda.context'
5
+ import * as context from '../lib/panda-context'
6
+ import { Select } from './input'
4
7
  import { TokenContent } from './token-content'
5
8
  import { TokenGroup } from './token-group'
6
- import type { Token } from '@pandacss/token-dictionary'
7
9
 
8
- const getFirstToken = <T extends Map<string, any>>(token?: T) =>
9
- token ? Array.from(token.values())[0].extensions.prop : {}
10
10
  const tokens = Object.fromEntries<Map<string, Token> | undefined>(context.tokens.categoryMap)
11
11
 
12
12
  const defaultConfig = {
13
- fontSize: getFirstToken(tokens.fontSizes),
14
- letterSpacing: getFirstToken(tokens.letterSpacings),
15
- fontWeight: getFirstToken(tokens.fontWeights),
16
- lineHeight: getFirstToken(tokens.lineHeights),
13
+ fontSize: '',
14
+ letterSpacing: '',
15
+ fontWeight: '',
16
+ lineHeight: '',
17
17
  }
18
18
 
19
- export function TypographyPlayground() {
19
+ export default function TypographyPlayground() {
20
20
  const [config, setConfig] = useState(defaultConfig)
21
+
21
22
  const configValues = Object.entries(config).reduce(
22
23
  (acc, [token, label]) => ({
23
24
  ...acc,
@@ -38,18 +39,18 @@ export function TypographyPlayground() {
38
39
  updateConfig(key, event.currentTarget.value)
39
40
  }
40
41
 
41
- const renderTokenSwitch = (token: keyof typeof defaultConfig) => {
42
- const _token = tokens[`${token}s`]
43
- if (!_token) return
44
- const values = Array.from(_token.values())
42
+ const renderTokenSwitch = (token: any) => {
43
+ const currentTokens = tokens[`${token}s`]
44
+ if (!currentTokens) return
45
+ const values = Array.from(currentTokens.values())
45
46
  return (
46
- <panda.select background="card" value={config[token]} onChange={(e) => onChangeConfig(e, token)}>
47
+ <Select value={config[token]} onChange={(e) => onChangeConfig(e, token)}>
47
48
  {values.map((token) => (
48
49
  <option key={token.value} value={token.extensions.prop}>
49
50
  {`${token.extensions.prop} (${token.value})`}
50
51
  </option>
51
52
  ))}
52
- </panda.select>
53
+ </Select>
53
54
  )
54
55
  }
55
56
 
@@ -67,7 +68,7 @@ export function TypographyPlayground() {
67
68
  width="fit-content"
68
69
  style={configValues}
69
70
  >
70
- Lorem ipsum dolor sit amet, consectetur adipiscing elit.
71
+ Write type-safe styles with ease using Panda CSS
71
72
  </panda.div>
72
73
 
73
74
  <Stack gap="4">
@@ -1,4 +1,9 @@
1
- export function Logo(props: React.ComponentPropsWithoutRef<'svg'>) {
1
+ import * as React from 'react'
2
+ import { logo } from '../lib/panda-context'
3
+
4
+ export function Logo(props: React.ComponentProps<'svg'>) {
5
+ if (logo) return <img src={logo} width="16" alt="logo" />
6
+
2
7
  return (
3
8
  <svg width="124" height="34" viewBox="0 0 124 34" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
4
9
  <path
@@ -1,3 +1,4 @@
1
+ import * as React from 'react'
1
2
  import type { ComponentProps } from 'react'
2
3
 
3
4
  export const MoonIcon = (props: ComponentProps<'svg'>) => (
package/src/icons/sun.tsx CHANGED
@@ -1,3 +1,4 @@
1
+ import * as React from 'react'
1
2
  import type { ComponentProps } from 'react'
2
3
 
3
4
  export const SunIcon = (props: ComponentProps<'svg'>) => (