@pandacss/studio 0.3.0 → 0.3.1

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 (31) hide show
  1. package/LICENSE.md +1 -1
  2. package/package.json +8 -8
  3. package/src/components/analyzer/category-utilities.tsx +12 -4
  4. package/src/components/analyzer/data-combobox.tsx +27 -10
  5. package/src/components/analyzer/external-icon.tsx +1 -1
  6. package/src/components/analyzer/report-item-columns.tsx +1 -1
  7. package/src/components/analyzer/report-item-link.tsx +1 -1
  8. package/src/components/analyzer/truncated-text.tsx +3 -1
  9. package/src/components/analyzer/utility-details.tsx +31 -25
  10. package/src/components/color-item.tsx +1 -1
  11. package/src/components/colors.tsx +12 -3
  12. package/src/components/icons.tsx +49 -0
  13. package/src/components/semantic-color.tsx +25 -19
  14. package/src/components/token-analyzer.tsx +7 -5
  15. package/src/layouts/Layout.astro +1 -1
  16. package/styled-system/chunks/src__components__analyzer__category-utilities.css +21 -173
  17. package/styled-system/chunks/src__components__analyzer__data-combobox.css +60 -210
  18. package/styled-system/chunks/src__components__analyzer__report-item-columns.css +12 -4
  19. package/styled-system/chunks/src__components__analyzer__report-item-link.css +10 -106
  20. package/styled-system/chunks/src__components__analyzer__truncated-text.css +4 -16
  21. package/styled-system/chunks/src__components__analyzer__utility-details.css +32 -120
  22. package/styled-system/chunks/src__components__color-item.css +2 -2
  23. package/styled-system/chunks/src__components__colors.css +10 -2
  24. package/styled-system/chunks/src__components__semantic-color.css +28 -8
  25. package/styled-system/chunks/src__components__token-analyzer.css +18 -1361
  26. package/styled-system/styles.css +64 -94
  27. package/styled-system/types/pattern.d.ts +7 -6
  28. package/styled-system/jsx/absolute-center.d.ts +0 -8
  29. package/styled-system/jsx/absolute-center.mjs +0 -9
  30. package/styled-system/patterns/absolute-center.d.ts +0 -14
  31. package/styled-system/patterns/absolute-center.mjs +0 -23
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022 Segun Adebayo
3
+ Copyright (c) 2023 Segun Adebayo
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pandacss/studio",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "The automated token documentation for Panda CSS",
5
5
  "main": "dist/studio.js",
6
6
  "module": "dist/studio.mjs",
@@ -32,19 +32,19 @@
32
32
  "react": "18.2.0",
33
33
  "react-dom": "18.2.0",
34
34
  "vite": "4.3.9",
35
- "@pandacss/types": "0.3.0",
36
- "@pandacss/config": "0.3.0",
37
- "@pandacss/shared": "0.3.0",
38
- "@pandacss/token-dictionary": "0.3.0",
39
- "@pandacss/logger": "0.3.0",
40
- "@pandacss/node": "0.3.0"
35
+ "@pandacss/types": "0.3.1",
36
+ "@pandacss/config": "0.3.1",
37
+ "@pandacss/shared": "0.3.1",
38
+ "@pandacss/token-dictionary": "0.3.1",
39
+ "@pandacss/logger": "0.3.1",
40
+ "@pandacss/node": "0.3.1"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/react": "18.2.12",
44
44
  "@types/react-dom": "18.2.5",
45
45
  "@vitejs/plugin-react": "4.0.0",
46
46
  "execa": "7.1.1",
47
- "@pandacss/dev": "0.3.0"
47
+ "@pandacss/dev": "0.3.1"
48
48
  },
49
49
  "scripts": {
50
50
  "codegen": "panda",
@@ -12,7 +12,15 @@ import { css, cx } from '../../../styled-system/css'
12
12
  import { ReportItemLink } from './report-item-link'
13
13
  import { SortIcon } from './sort-icon'
14
14
 
15
- const selectOptionClass = css({ padding: '4px 8px', bg: 'white' })
15
+ const selectOptionClass = css({
16
+ padding: '4px 8px',
17
+ bg: 'card',
18
+ rounded: 'md',
19
+ '& li': {
20
+ cursor: 'pointer',
21
+ _hover: { opacity: 0.8 },
22
+ },
23
+ })
16
24
 
17
25
  type SortBy = 'property name' | 'tokens count'
18
26
  const defaultOption = { label: 'tokens count', value: 'tokens count' as SortBy }
@@ -40,9 +48,9 @@ export const ByCategory = ({ byCategory }: { byCategory: Record<string, number[]
40
48
  {({ selectedOption }) => (
41
49
  <>
42
50
  <SelectTrigger>
43
- <panda.button display="flex" alignItems="center">
51
+ <panda.button display="flex" alignItems="center" cursor="pointer" _hover={{ opacity: 0.6 }}>
44
52
  Sort by {selectedOption?.label}
45
- <panda.div w="26px" ml="2">
53
+ <panda.div w="26px" ml="2" color="text">
46
54
  <SortIcon />
47
55
  </panda.div>
48
56
  </panda.button>
@@ -121,7 +129,7 @@ const CategoryUtilities = ({
121
129
  })
122
130
 
123
131
  return (
124
- <Stack key={category} p="4" bg="card" color="text" gap="2" className={className}>
132
+ <Stack key={category} p="4" bg="card" color="text" rounded="md" gap="2" className={className}>
125
133
  <panda.h4>
126
134
  <panda.a className={styledLink({})} href={getUtilityLink({ category })}>
127
135
  <TextWithCount count={values.length}>
@@ -12,6 +12,7 @@ import {
12
12
  import { useEffect, useState } from 'react'
13
13
  import { css } from '../../../styled-system/css'
14
14
  import { panda } from '../../../styled-system/jsx'
15
+ import { ChevronDownIcon, ChevronUpIcon, XMarkIcon } from '../icons'
15
16
 
16
17
  export type DataComboboxOption = {
17
18
  value: string
@@ -52,14 +53,20 @@ export const DataCombobox = ({ options: allOptions, label, ...props }: DataCombo
52
53
  )}
53
54
  <panda.div
54
55
  display="flex"
55
- _focus={{
56
- border: '1px solid token(colors.blue.400, blue)',
57
- }}
56
+ rounded="sm"
57
+ border="solid 1px"
58
+ borderColor={{ base: 'border', _focusWithin: { base: 'yellow.200', _dark: 'yellow.300' } }}
58
59
  >
59
60
  <ComboboxInput
60
61
  defaultValue={props.defaultValue}
61
62
  placeholder={props.placeholder ?? 'Search...'}
62
- className={css({ width: 'full', p: 2 })}
63
+ className={css({
64
+ width: 'full',
65
+ p: 2,
66
+ color: 'text',
67
+ bg: 'transparent',
68
+ _focus: { outline: 'none' },
69
+ })}
63
70
  onChange={(e) => {
64
71
  const value = e.target.value
65
72
  if (!value) {
@@ -74,20 +81,27 @@ export const DataCombobox = ({ options: allOptions, label, ...props }: DataCombo
74
81
  />
75
82
  {state.selectedValue && (
76
83
  <panda.span
84
+ display="flex"
77
85
  px="2"
78
- mr="-2"
79
86
  cursor="pointer"
80
87
  userSelect="none"
81
- fontSize="lg"
82
- fontWeight="bold"
83
88
  onClick={() => state.clearValue()}
89
+ alignItems="center"
84
90
  >
85
- X
91
+ <XMarkIcon />
86
92
  </panda.span>
87
93
  )}
88
94
  <ComboboxTrigger>
89
- <panda.span ml="auto" px="2" cursor="pointer">
90
- {state.isOpen ? '▲' : '▼'}
95
+ <panda.span
96
+ ml="auto"
97
+ p="2"
98
+ display="flex"
99
+ cursor="pointer"
100
+ borderLeft="solid 1px"
101
+ borderColor="border"
102
+ color="text"
103
+ >
104
+ {state.isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />}
91
105
  </panda.span>
92
106
  </ComboboxTrigger>
93
107
  </panda.div>
@@ -104,6 +118,7 @@ export const DataCombobox = ({ options: allOptions, label, ...props }: DataCombo
104
118
  listStyle: 'none',
105
119
  rounded: 'md',
106
120
  border: '1px solid token(colors.border)',
121
+ shadow: 'sm',
107
122
  })}
108
123
  >
109
124
  {/* TODO virtualization */}
@@ -114,6 +129,8 @@ export const DataCombobox = ({ options: allOptions, label, ...props }: DataCombo
114
129
  label={option.label}
115
130
  className={css({
116
131
  padding: '4px 8px',
132
+ rounded: 'md',
133
+ wordWrap: 'break-word',
117
134
  _highlighted: {
118
135
  bg: 'border',
119
136
  },
@@ -1,7 +1,7 @@
1
1
  /** @see https://iconmonstr.com/share-11-svg/ */
2
2
  export const ExternalIcon = () => {
3
3
  return (
4
- <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100%" viewBox="0 0 24 24">
4
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
5
5
  <path d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z" />
6
6
  </svg>
7
7
  )
@@ -29,7 +29,7 @@ export const reportItemColumns = [
29
29
  {!item.isKnown && (
30
30
  <QuickTooltip
31
31
  tooltip={
32
- <panda.span p="2" bgColor="white" border="1px solid rgba(0, 0, 0, 0.1)">
32
+ <panda.span p="2" bgColor="card" border="1px solid token(colors.border)" shadow="sm" rounded="md">
33
33
  unknown token
34
34
  </panda.span>
35
35
  }
@@ -78,7 +78,7 @@ export const ReportItemOpenInEditorLink = ({ withRange, ...reportItem }: ReportI
78
78
  </panda.a>
79
79
  <QuickTooltip
80
80
  tooltip={
81
- <panda.span p="2" bgColor="card" border="border">
81
+ <panda.span p="2" bgColor="card" border="1px solid token(colors.border)" shadow="sm" rounded="md">
82
82
  Click to open in editor
83
83
  </panda.span>
84
84
  }
@@ -17,7 +17,9 @@ export const TruncatedText = ({
17
17
  </panda.span>
18
18
  }
19
19
  >
20
- <panda.span {...props}>{text.substring(0, characters) + '...'}</panda.span>
20
+ <panda.span color="text" {...props}>
21
+ {text.substring(0, characters) + '...'}
22
+ </panda.span>
21
23
  </QuickTooltip>
22
24
  )
23
25
  }
@@ -10,7 +10,7 @@ import {
10
10
  import { useState } from 'react'
11
11
 
12
12
  import { css, cx } from '../../../styled-system/css'
13
- import { Wrap, panda } from '../../../styled-system/jsx'
13
+ import { Flex, Wrap, panda } from '../../../styled-system/jsx'
14
14
  import { styledLink } from '../../../styled-system/patterns'
15
15
 
16
16
  import { analysisData } from '../../lib/analysis-data'
@@ -23,6 +23,7 @@ import { getReportInfosFrom } from './get-report-infos-from'
23
23
  import { reportItemColumns } from './report-item-columns'
24
24
  import { Section } from './section'
25
25
  import { TextWithCount } from './text-with-count'
26
+ import { XMarkIcon } from '../icons'
26
27
 
27
28
  export const UtilityDetails = () => {
28
29
  const search = new URLSearchParams(window.location.search)
@@ -110,7 +111,34 @@ const UtilityFilters = () => {
110
111
 
111
112
  return (
112
113
  <panda.div mb="4">
113
- <panda.h3>Filters</panda.h3>
114
+ <Flex>
115
+ <panda.h3>Filters</panda.h3>
116
+ {infos.hasParam && (
117
+ <panda.button
118
+ ml="auto"
119
+ cursor="pointer"
120
+ userSelect="none"
121
+ bg="card"
122
+ px="3"
123
+ py="2"
124
+ rounded="md"
125
+ _hover={{ opacity: 0.8 }}
126
+ onClick={() => {
127
+ updateSearchParam('value', undefined)
128
+ updateSearchParam('category', undefined)
129
+ updateSearchParam('propName', undefined)
130
+ updateSearchParam('from', undefined)
131
+ updateSearchParam('filepath', undefined)
132
+ setParams({})
133
+ setResetKey((k) => k + 1)
134
+ }}
135
+ >
136
+ <panda.span display="flex" gap="2" alignItems="center">
137
+ <XMarkIcon width="16" height="16" /> Clear filters
138
+ </panda.span>
139
+ </panda.button>
140
+ )}
141
+ </Flex>
114
142
  <Wrap key={resetKey}>
115
143
  <DataCombobox
116
144
  label="Token name"
@@ -157,28 +185,6 @@ const UtilityFilters = () => {
157
185
  }}
158
186
  defaultValue={String(infos.params.filepath ?? '')}
159
187
  />
160
- {infos.hasParam && (
161
- <panda.span
162
- display="block"
163
- alignSelf="flex-end"
164
- mt="2"
165
- cursor="pointer"
166
- userSelect="none"
167
- fontSize="lg"
168
- fontWeight="bold"
169
- onClick={() => {
170
- updateSearchParam('value', undefined)
171
- updateSearchParam('category', undefined)
172
- updateSearchParam('propName', undefined)
173
- updateSearchParam('from', undefined)
174
- updateSearchParam('filepath', undefined)
175
- setParams({})
176
- setResetKey((k) => k + 1)
177
- }}
178
- >
179
- [X] Clear filters
180
- </panda.span>
181
- )}
182
188
  </Wrap>
183
189
  </panda.div>
184
190
  )
@@ -249,7 +255,7 @@ const ReportItemMatchingFiltersTable = (infos: Infos) => {
249
255
  title={
250
256
  <>
251
257
  <SelectLabel>By </SelectLabel>
252
- <SelectTrigger>
258
+ <SelectTrigger asChild>
253
259
  <button>{selectedOption?.label}</button>
254
260
  </SelectTrigger>
255
261
  </>
@@ -28,7 +28,7 @@ export const ColorItem = ({
28
28
  {children}
29
29
 
30
30
  {tokenName !== value && (
31
- <panda.div opacity={0.1}>
31
+ <panda.div opacity={0.7}>
32
32
  <panda.span>{value}</panda.span>
33
33
  </panda.div>
34
34
  )}
@@ -8,6 +8,10 @@ import { SemanticColorDisplay } from './semantic-color'
8
8
 
9
9
  const UNCATEGORIZED_ID = 'uncategorized' as const
10
10
 
11
+ function getColorFromReference(reference: string) {
12
+ return reference.match(/{colors\.(.*?)}/)?.[1]
13
+ }
14
+
11
15
  export function Colors() {
12
16
  const { filterQuery, setFilterQuery, semanticTokens, hasResults, uncategorizedColors, categorizedColors } =
13
17
  useColorDocs()
@@ -17,14 +21,19 @@ export function Colors() {
17
21
  return (
18
22
  <Stack gap="1" key={i} width="full">
19
23
  <HStack gap="1">
24
+ <SemanticColorDisplay
25
+ value={colors.base.value}
26
+ condition="base"
27
+ token={getColorFromReference(colors.extensions.conditions.base)}
28
+ />
20
29
  <SemanticColorDisplay
21
30
  value={colors[colors.extensions.condition].value}
22
31
  condition={colors.extensions.condition}
32
+ token={getColorFromReference(colors.extensions.conditions[colors.extensions.condition])}
23
33
  />
24
- <SemanticColorDisplay value={colors.base.value} condition="base" />
25
34
  </HStack>
26
35
 
27
- <panda.span fontWeight="medium">{name}</panda.span>
36
+ <panda.span fontWeight="semibold">{name}</panda.span>
28
37
  </Stack>
29
38
  )
30
39
  })
@@ -83,7 +92,7 @@ export function Colors() {
83
92
  <panda.span fontWeight="medium" textTransform="capitalize" fontSize="xl">
84
93
  Semantic tokens
85
94
  </panda.span>
86
- <Grid gap="4" minChildWidth="13rem" my="5" mx="0">
95
+ <Grid gap="4" minChildWidth="30rem" my="5" mx="0">
87
96
  {renderSemanticTokens()}
88
97
  </Grid>
89
98
  </div>
@@ -205,3 +205,52 @@ export function ColorContrastIcon() {
205
205
  </svg>
206
206
  )
207
207
  }
208
+
209
+ export function ChevronUpIcon() {
210
+ return (
211
+ <svg
212
+ xmlns="http://www.w3.org/2000/svg"
213
+ fill="none"
214
+ viewBox="0 0 24 24"
215
+ strokeWidth={1.5}
216
+ stroke="currentColor"
217
+ width="12"
218
+ height="12"
219
+ >
220
+ <path strokeLinecap="round" strokeLinejoin="round" d="M4.5 15.75l7.5-7.5 7.5 7.5" />
221
+ </svg>
222
+ )
223
+ }
224
+
225
+ export function ChevronDownIcon() {
226
+ return (
227
+ <svg
228
+ xmlns="http://www.w3.org/2000/svg"
229
+ fill="none"
230
+ viewBox="0 0 24 24"
231
+ strokeWidth={1.5}
232
+ stroke="currentColor"
233
+ width="12"
234
+ height="12"
235
+ >
236
+ <path strokeLinecap="round" strokeLinejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
237
+ </svg>
238
+ )
239
+ }
240
+
241
+ export function XMarkIcon(props: React.SVGProps<SVGSVGElement>) {
242
+ return (
243
+ <svg
244
+ xmlns="http://www.w3.org/2000/svg"
245
+ fill="none"
246
+ viewBox="0 0 24 24"
247
+ strokeWidth={1.5}
248
+ stroke="currentColor"
249
+ width="12"
250
+ height="12"
251
+ {...props}
252
+ >
253
+ <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
254
+ </svg>
255
+ )
256
+ }
@@ -1,27 +1,33 @@
1
- import { panda } from '../../styled-system/jsx'
1
+ import { Flex, panda } from '../../styled-system/jsx'
2
2
  import { ColorWrapper } from './color-wrapper'
3
3
 
4
4
  // remove initial underscore
5
5
  const cleanCondition = (condition: string) => condition.replace(/^_/, '')
6
6
 
7
- export function SemanticColorDisplay(props: { value: string; condition: string }) {
8
- const { value, condition } = props
7
+ export function SemanticColorDisplay(props: { value: string; condition: string; token?: string }) {
8
+ const { value, condition, token } = props
9
9
  return (
10
- <ColorWrapper height="12" style={{ background: value }}>
11
- <panda.span
12
- fontWeight="medium"
13
- fontSize="sm"
14
- minW="5"
15
- bg="neutral.800"
16
- px="1"
17
- py="1"
18
- color="white"
19
- roundedBottomRight="sm"
20
- borderWidth="1px"
21
- borderColor="neutral.700"
22
- >
23
- {cleanCondition(condition)}
24
- </panda.span>
25
- </ColorWrapper>
10
+ <Flex direction="column" w="full">
11
+ <ColorWrapper height="12" style={{ background: value }}>
12
+ <panda.span
13
+ fontWeight="medium"
14
+ fontSize="sm"
15
+ minW="5"
16
+ bg="neutral.800"
17
+ px="1"
18
+ py="1"
19
+ color="white"
20
+ roundedBottomRight="sm"
21
+ borderWidth="1px"
22
+ borderColor="neutral.700"
23
+ >
24
+ {cleanCondition(condition)}
25
+ </panda.span>
26
+ </ColorWrapper>
27
+ {token && <panda.div fontWeight="medium">{token}</panda.div>}
28
+ <panda.div opacity="0.7" fontSize="sm" textTransform="uppercase">
29
+ {value}
30
+ </panda.div>
31
+ </Flex>
26
32
  )
27
33
  }
@@ -152,6 +152,7 @@ const HeadlineSummary = () => {
152
152
 
153
153
  const selectOptionClass = css({
154
154
  padding: '4px 8px',
155
+ bg: 'card',
155
156
  rounded: 'md',
156
157
  '& li': {
157
158
  cursor: 'pointer',
@@ -284,16 +285,16 @@ const FilesAccordionList = () => {
284
285
  {({ selectedOption }) => (
285
286
  <>
286
287
  <SelectTrigger>
287
- <panda.button display="flex" alignItems="center">
288
+ <panda.button display="flex" alignItems="center" cursor="pointer" _hover={{ opacity: 0.6 }}>
288
289
  Sort by {selectedOption?.label}
289
- <panda.div w="26px" ml="2" color="text">
290
+ <panda.div w="5" ml="2" color="text">
290
291
  <SortIcon />
291
292
  </panda.div>
292
293
  </panda.button>
293
294
  </SelectTrigger>
294
295
  <Portal>
295
296
  <SelectPositioner>
296
- <SelectContent className={cx(selectOptionClass, css({ listStyle: 'none', bg: 'card' }))}>
297
+ <SelectContent className={cx(selectOptionClass, css({ listStyle: 'none' }))}>
297
298
  <SelectOption className={selectOptionClass} value="name" label="name" />
298
299
  <SelectOption className={selectOptionClass} value="tokens count" label="tokens count" />
299
300
  <SelectOption className={selectOptionClass} value="file path" label="file path" />
@@ -329,7 +330,7 @@ const FilesAccordionList = () => {
329
330
  {(props) => (
330
331
  <>
331
332
  <AccordionTrigger asChild>
332
- <panda.button display="flex" bg="none" w="full" pt="6" pl="6" pr="4" cursor="pointer">
333
+ <panda.button display="flex" bg="none" w="full" pt="6" pl="6" pr="4" cursor="pointer" color="text">
333
334
  <panda.a
334
335
  className={styledLink({})}
335
336
  href={getFileLink({ filepath })}
@@ -374,7 +375,8 @@ const FilesAccordionList = () => {
374
375
  py="2"
375
376
  px="4"
376
377
  transition="all 0.2s ease"
377
- _hover={{ bg: 'gray.100' }}
378
+ _hover={{ bg: 'border' }}
379
+ rounded="md"
378
380
  >
379
381
  <TruncatedText text={key} />
380
382
  </ColorItem>
@@ -10,7 +10,7 @@ import context from '../lib/panda.context'
10
10
  <Head />
11
11
  <Fragment set:html={context.inject.head} />
12
12
  <meta name="generator" content={Astro.generator} />
13
- <title>Panda Playground</title>
13
+ <title>Panda Studio</title>
14
14
  </head>
15
15
  <body>
16
16
  <Fragment set:html={context.inject.body} />