Skip to content

Commit

Permalink
refactor: redesign studio and fix 'React not defined' error (#2073)
Browse files Browse the repository at this point in the history
* refactor: studio

* fix: stop color warning
  • Loading branch information
segunadebayo authored Jan 23, 2024
1 parent 770c7aa commit 7a492d7
Show file tree
Hide file tree
Showing 62 changed files with 2,394 additions and 1,112 deletions.
5 changes: 5 additions & 0 deletions .changeset/quiet-kangaroos-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@pandacss/studio': patch
---

Fix issue where throws "React is not defined error"
1 change: 1 addition & 0 deletions packages/studio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"src",
"public",
"styled-system",
"tsconfig.json",
"*.ts",
"*.mjs"
],
Expand Down
32 changes: 5 additions & 27 deletions packages/studio/panda.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,41 +55,19 @@ export default {
border: {
value: { base: '{colors.neutral.300}', _dark: '{colors.neutral.700}' },
},
accent: {
value: { base: '{colors.yellow.600}', _dark: '{colors.yellow.300}' },
},
},
},
},
},
patterns: {
extend: {
styledLink: {
properties: {},
transform: (props: any) => ({
display: 'inline-flex',
alignItems: 'center',
opacity: '0.5',
borderBottom: '1px solid transparent',
cursor: 'pointer',
_hover: { opacity: 1, borderBottomColor: 'black' },
...props,
}),
},
},
},
staticCss: {
css: [
{
properties: {
color: ['red.400'],
},
},
],
},
globalCss: {
':root': {
'--global-color-border': 'colors.border',
'--global-color-placeholder': 'colors.neutral.500',
fontFamily: 'Inter, Avenir, Helvetica, Arial, sans-serif',
fontSize: 'md',
fontSize: '0.84em',
lineHeight: 'normal',
fontWeight: 'normal',
colorScheme: 'light dark',
Expand All @@ -104,7 +82,7 @@ export default {

body: {
margin: 0,
minHeight: '100vh',
minHeight: '100dvh',
},
},
} satisfies Config
107 changes: 40 additions & 67 deletions packages/studio/src/components/color-constrast.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,51 @@
import { useState } from 'react'
import * as React from 'react'
import { HStack, Stack, VStack, panda } from '../../styled-system/jsx'
import { getContrastPairs, getContrastRatio } from '../lib/color'
import context from '../lib/panda.context'
import { ErrorIcon, SuccessIcon } from './icons'
import * as context from '../lib/panda-context'
import { Select } from './input'
import { TestScore } from './test-score'
import { TokenContent } from './token-content'
import { TokenGroup } from './token-group'

function TestScore(props: { score: { WCAG_AA: boolean; WCAG_AAA: boolean }; size: 'regular' | 'large' }) {
const { score, size } = props
interface ColorSelectProps {
title: string
value: string
colors: {
label: string
value: string
}[]
onChange: (value: string) => void
}

function ColorSelect(props: ColorSelectProps) {
const { title, colors, onChange, value } = props
return (
<>
<HStack justify="space-between" fontWeight="medium">
<HStack gap="2">
<span>{score.WCAG_AA ? <SuccessIcon /> : <ErrorIcon />}</span>
<span>AA</span>
</HStack>
<span>{size === 'regular' ? '4.5:1' : '3:1'}</span>
</HStack>
<HStack justify="space-between" fontWeight="medium">
<HStack gap="2">
<span>{score.WCAG_AAA ? <SuccessIcon /> : <ErrorIcon />}</span>
<span>AAA</span>
</HStack>
<span>{size === 'regular' ? '7:1' : '4.5:1'}</span>
</HStack>
</>
<Stack flex="1">
<panda.span fontWeight="semibold">{title}</panda.span>
<panda.div
display="flex"
flexDirection="column"
borderWidth="1px"
borderColor="card"
pt="16"
style={{ background: value }}
/>
<Select value={value} onChange={(e) => onChange(e.currentTarget.value)}>
{colors.map((color) => (
<option key={color.label} value={color.label}>
{color.label}
</option>
))}
</Select>
</Stack>
)
}

export function ColorContrastChecker() {
const colorsMap = context.getCategory('colors')
const values = Array.from(colorsMap.values())

const colors = values
.filter((color) => !color.isConditional && !color.extensions.isVirtual)
.map((color) => ({
label: color.extensions.prop,
value: color.value,
}))
export default function ColorContrastChecker() {
const colors = context.colors

const [foreground, setForeGround] = useState('#000000')
const [background, setBackground] = useState('#ffffff')
const [foreground, setForeGround] = React.useState('#000000')
const [background, setBackground] = React.useState('#ffffff')

const activeForeground = (colors.find((col) => col.label === foreground)?.value || foreground) as string
const activeBackground = (colors.find((col) => col.label === background)?.value || background) as string
Expand All @@ -52,40 +57,8 @@ export function ColorContrastChecker() {
<TokenGroup>
<TokenContent>
<HStack gap="3" p="2">
<panda.div
display="flex"
flexDirection="column"
borderWidth="1px"
borderColor="card"
flex="1"
pt="16"
style={{ background: activeForeground }}
>
<select value={foreground} onChange={(e: any) => setForeGround(e.currentTarget.value)}>
{colors.map((color) => (
<option key={color.label} value={color.label}>
{color.label}
</option>
))}
</select>
</panda.div>
<panda.div
display="flex"
flexDirection="column"
borderWidth="1px"
borderColor="card"
flex="1"
pt="16"
style={{ background: activeBackground }}
>
<select value={background} onChange={(e: any) => setBackground(e.currentTarget.value)}>
{colors.map((color) => (
<option key={color.label} value={color.label}>
{color.label}
</option>
))}
</select>
</panda.div>
<ColorSelect title="Background" value={activeBackground} onChange={setBackground} colors={colors} />
<ColorSelect title="Foreground" value={activeForeground} onChange={setForeGround} colors={colors} />
</HStack>

<HStack
Expand Down
45 changes: 21 additions & 24 deletions packages/studio/src/components/color-wrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
import { type HTMLPandaProps, panda } from '../../styled-system/jsx'
import { panda } from '../../styled-system/jsx'

export function ColorWrapper(props: HTMLPandaProps<'div'>) {
return (
<panda.div
width="full"
height="10"
borderRadius="sm"
position="relative"
overflow="hidden"
shadow="inset"
_before={{
content: "''",
position: 'absolute',
borderRadius: 'sm',
width: '100%',
height: '100%',
backgroundSize: '24px',
zIndex: '-1',
backgroundImage: 'check',
}}
{...props}
/>
)
}
export const ColorWrapper = panda('div', {
base: {
width: 'full',
height: '10',
borderRadius: 'sm',
position: 'relative',
overflow: 'hidden',
shadow: 'inset',
_before: {
content: "''",
position: 'absolute',
borderRadius: 'sm',
width: '100%',
height: '100%',
backgroundSize: '24px',
zIndex: '-1',
backgroundImage: 'check',
},
},
})
107 changes: 57 additions & 50 deletions packages/studio/src/components/colors.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import type { Token } from '@pandacss/token-dictionary'
import * as React from 'react'
import { Grid, HStack, Stack, panda } from '../../styled-system/jsx'
import { ColorWrapper } from '../components/color-wrapper'
import { TokenContent } from '../components/token-content'
import { TokenGroup } from '../components/token-group'
import { useColorDocs } from '../lib/use-color-docs'
import { Input } from './input'
import { SemanticColorDisplay } from './semantic-color'
import { StickyTop } from './sticky-top'

const UNCATEGORIZED_ID = 'uncategorized' as const

function getColorFromReference(reference: string) {
return reference.match(/{colors\.(.*?)}/)?.[1]
}

export function Colors() {
export default function Colors() {
const { filterQuery, setFilterQuery, semanticTokens, hasResults, uncategorizedColors, categorizedColors } =
useColorDocs()

const renderSemanticTokens = () => {
return semanticTokens.map(([name, colors], i) => {
return (
<Stack gap="1" key={i} width="full">
<Stack gap="2" key={i} width="full">
<HStack gap="1">
<SemanticColorDisplay
value={colors.base.value}
Expand All @@ -38,68 +41,72 @@ export function Colors() {
)
})
}
const renderColors = (values: any[]) => {
return values?.map((color, i) => {
return (
<Stack gap="1" key={i}>
<ColorWrapper style={{ background: color.value }} />
<Stack mt="2" gap="0.5">
<panda.div fontWeight="medium">{color.extensions.prop}</panda.div>
<panda.div opacity="0.7" fontSize="sm" textTransform="uppercase">
{color.value}
</panda.div>
</Stack>
</Stack>
)
})
}

return (
<TokenGroup>
<panda.div mb="3.5" position="sticky" top="0" zIndex="1">
<StickyTop>
<Input
value={filterQuery}
onChange={(e) => setFilterQuery(e.target.value)}
placeholder="Filter tokens by text, property or value"
/>
</panda.div>
</StickyTop>

<TokenContent>
<Stack gap="10">
{!!categorizedColors.length &&
categorizedColors.map(([category, colors]) => (
<div key={category}>
<panda.span fontWeight="medium" textTransform="capitalize" fontSize="xl">
{category}
</panda.span>
{categorizedColors.map(([category, colors]) => (
<ColorGroup key={category} title={category} colors={colors} />
))}

<ColorGroup title={UNCATEGORIZED_ID} colors={uncategorizedColors} />

{!!semanticTokens.length && <ColorGroup title="Semantic Tokens">{renderSemanticTokens()}</ColorGroup>}

<Grid gap="4" minChildWidth="13rem" my="5" mx="0" key={category}>
{renderColors(colors)}
</Grid>
</div>
))}
{!!uncategorizedColors?.length && (
<div>
<panda.span fontWeight="medium" textTransform="capitalize" fontSize="xl">
{UNCATEGORIZED_ID}
</panda.span>
<Grid gap="4" minChildWidth="13rem" my="5" mx="0">
{renderColors(uncategorizedColors)}
</Grid>
</div>
)}
{!!semanticTokens.length && (
<div>
<panda.span fontWeight="medium" textTransform="capitalize" fontSize="xl">
Semantic tokens
</panda.span>
<Grid gap="4" minChildWidth="30rem" my="5" mx="0">
{renderSemanticTokens()}
</Grid>
</div>
)}
{!hasResults && <div>No result found! 🐼</div>}
</Stack>
</TokenContent>
</TokenGroup>
)
}

function PrimitiveColors(props: { values?: Token[] }) {
const { values = [] } = props
return values.map((color, i) => {
return (
<Stack gap="1" key={i}>
<ColorWrapper style={{ background: color.value }} />
<Stack mt="2" gap="0.5">
<panda.div fontWeight="medium">{color.extensions.prop}</panda.div>
<panda.div opacity="0.7" fontSize="sm" textTransform="uppercase">
{color.value}
</panda.div>
</Stack>
</Stack>
)
})
}

function ColorGroup(props: { colors?: Token[]; title: string; children?: React.ReactNode }) {
const { children, colors, title } = props

const isEmpty = colors == null || colors.length === 0

if (!children && isEmpty) return null

return (
<div>
<panda.span fontWeight="medium" textTransform="capitalize" fontSize="xl">
{title}
</panda.span>
{children ? (
<Stack gap="10" mt="10">
{children}
</Stack>
) : (
<Grid gap="4" minChildWidth="13rem" my="5" mx="0">
<PrimitiveColors values={colors} />
</Grid>
)}
</div>
)
}
Loading

3 comments on commit 7a492d7

@vercel
Copy link

@vercel vercel bot commented on 7a492d7 Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

panda-docs – ./website

panda-docs.vercel.app
panda-docs-chakra-ui.vercel.app
panda-css.com
panda-docs-git-main-chakra-ui.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 7a492d7 Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 7a492d7 Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

panda-studio – ./

panda-app.vercel.app
panda-studio-chakra-ui.vercel.app
panda-studio-git-main-chakra-ui.vercel.app

Please sign in to comment.