@pandacss/studio 0.0.0-dev-20230613163214
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/LICENSE.md +21 -0
- package/astro.config.ts +14 -0
- package/dist/studio.d.ts +13 -0
- package/dist/studio.js +2089 -0
- package/dist/studio.mjs +2087 -0
- package/index.ts +1 -0
- package/package.json +59 -0
- package/panda.config.ts +110 -0
- package/public/favicon.svg +13 -0
- package/src/components/analyzer/category-utilities.tsx +146 -0
- package/src/components/analyzer/data-combobox.tsx +125 -0
- package/src/components/analyzer/data-table.tsx +43 -0
- package/src/components/analyzer/external-icon.tsx +8 -0
- package/src/components/analyzer/file-details.tsx +101 -0
- package/src/components/analyzer/get-report-infos-from.ts +80 -0
- package/src/components/analyzer/quick-tooltip.tsx +15 -0
- package/src/components/analyzer/report-item-columns.tsx +52 -0
- package/src/components/analyzer/report-item-link.tsx +98 -0
- package/src/components/analyzer/section.tsx +24 -0
- package/src/components/analyzer/sort-icon.tsx +7 -0
- package/src/components/analyzer/text-with-count.tsx +28 -0
- package/src/components/analyzer/token-search-combobox.tsx +39 -0
- package/src/components/analyzer/truncated-text.tsx +26 -0
- package/src/components/analyzer/utility-details.tsx +312 -0
- package/src/components/color-constrast.tsx +131 -0
- package/src/components/color-item.tsx +37 -0
- package/src/components/color-wrapper.tsx +25 -0
- package/src/components/colors.tsx +96 -0
- package/src/components/empty-state.tsx +19 -0
- package/src/components/font-family.tsx +55 -0
- package/src/components/font-tokens.tsx +69 -0
- package/src/components/head.astro +35 -0
- package/src/components/icons.tsx +207 -0
- package/src/components/input.tsx +27 -0
- package/src/components/layer-styles.tsx +38 -0
- package/src/components/logo.tsx +34 -0
- package/src/components/nav-item.tsx +39 -0
- package/src/components/overview.tsx +65 -0
- package/src/components/radii.tsx +34 -0
- package/src/components/semantic-color.tsx +27 -0
- package/src/components/side-nav-item.astro +25 -0
- package/src/components/side-nav.astro +30 -0
- package/src/components/sizes.tsx +53 -0
- package/src/components/text-styles.tsx +33 -0
- package/src/components/theme-toggle.astro +56 -0
- package/src/components/token-analyzer.tsx +390 -0
- package/src/components/token-content.tsx +5 -0
- package/src/components/token-group.tsx +6 -0
- package/src/components/typography-playground.tsx +83 -0
- package/src/env.d.ts +1 -0
- package/src/icons/moon.tsx +15 -0
- package/src/icons/sun.tsx +19 -0
- package/src/layouts/Layout.astro +19 -0
- package/src/layouts/Sidebar.astro +35 -0
- package/src/lib/analysis-data.ts +17 -0
- package/src/lib/color-contrast-checker.ts +218 -0
- package/src/lib/color.ts +40 -0
- package/src/lib/constants.ts +140 -0
- package/src/lib/create-context.ts +27 -0
- package/src/lib/get-report-item.tsx +41 -0
- package/src/lib/group-in.ts +35 -0
- package/src/lib/panda.context.ts +23 -0
- package/src/lib/pick.ts +24 -0
- package/src/lib/sizes-sort.ts +10 -0
- package/src/lib/truncate.tsx +7 -0
- package/src/lib/use-color-docs.ts +101 -0
- package/src/pages/colors.astro +11 -0
- package/src/pages/font-sizes.astro +15 -0
- package/src/pages/font-weights.astro +15 -0
- package/src/pages/fonts.astro +11 -0
- package/src/pages/index.astro +8 -0
- package/src/pages/layer-styles.astro +11 -0
- package/src/pages/letter-spacings.astro +20 -0
- package/src/pages/line-heights.astro +21 -0
- package/src/pages/playground/contrast-checker.astro +11 -0
- package/src/pages/playground/typography.astro +11 -0
- package/src/pages/radii.astro +11 -0
- package/src/pages/sizes.astro +14 -0
- package/src/pages/spacing.astro +14 -0
- package/src/pages/text-styles.astro +11 -0
- package/src/pages/token-analyzer/file.astro +11 -0
- package/src/pages/token-analyzer/index.astro +11 -0
- package/src/pages/token-analyzer/utility.astro +11 -0
- package/styled-system/chunks/..__core____tests____composition.test.css +2 -0
- package/styled-system/chunks/src__components__analyzer__category-utilities.css +97 -0
- package/styled-system/chunks/src__components__analyzer__data-combobox.css +77 -0
- package/styled-system/chunks/src__components__analyzer__data-table.css +37 -0
- package/styled-system/chunks/src__components__analyzer__file-details.css +103 -0
- package/styled-system/chunks/src__components__analyzer__quick-tooltip.css +2 -0
- package/styled-system/chunks/src__components__analyzer__report-item-columns.css +29 -0
- package/styled-system/chunks/src__components__analyzer__report-item-link.css +109 -0
- package/styled-system/chunks/src__components__analyzer__section.css +29 -0
- package/styled-system/chunks/src__components__analyzer__text-with-count.css +33 -0
- package/styled-system/chunks/src__components__analyzer__truncated-text.css +13 -0
- package/styled-system/chunks/src__components__analyzer__utility-details.css +125 -0
- package/styled-system/chunks/src__components__color-constrast.css +114 -0
- package/styled-system/chunks/src__components__color-item.css +21 -0
- package/styled-system/chunks/src__components__color-wrapper.css +73 -0
- package/styled-system/chunks/src__components__colors.css +97 -0
- package/styled-system/chunks/src__components__empty-state.css +45 -0
- package/styled-system/chunks/src__components__font-family.css +85 -0
- package/styled-system/chunks/src__components__font-tokens.css +61 -0
- package/styled-system/chunks/src__components__input.css +68 -0
- package/styled-system/chunks/src__components__layer-styles.css +66 -0
- package/styled-system/chunks/src__components__nav-item.css +73 -0
- package/styled-system/chunks/src__components__overview.css +125 -0
- package/styled-system/chunks/src__components__radii.css +49 -0
- package/styled-system/chunks/src__components__semantic-color.css +45 -0
- package/styled-system/chunks/src__components__side-nav-item.css +33 -0
- package/styled-system/chunks/src__components__side-nav.css +49 -0
- package/styled-system/chunks/src__components__sizes.css +41 -0
- package/styled-system/chunks/src__components__text-styles.css +31 -0
- package/styled-system/chunks/src__components__theme-toggle.css +63 -0
- package/styled-system/chunks/src__components__token-analyzer.css +227 -0
- package/styled-system/chunks/src__components__token-content.css +13 -0
- package/styled-system/chunks/src__components__token-group.css +21 -0
- package/styled-system/chunks/src__components__token-search-combobox.css +2 -0
- package/styled-system/chunks/src__components__typography-playground.css +61 -0
- package/styled-system/chunks/src__layouts__Layout.css +2 -0
- package/styled-system/chunks/src__layouts__Sidebar.css +113 -0
- package/styled-system/chunks/src__pages__colors.css +2 -0
- package/styled-system/chunks/src__pages__font-sizes.css +2 -0
- package/styled-system/chunks/src__pages__font-weights.css +2 -0
- package/styled-system/chunks/src__pages__fonts.css +2 -0
- package/styled-system/chunks/src__pages__index.css +2 -0
- package/styled-system/chunks/src__pages__layer-styles.css +2 -0
- package/styled-system/chunks/src__pages__letter-spacings.css +2 -0
- package/styled-system/chunks/src__pages__line-heights.css +2 -0
- package/styled-system/chunks/src__pages__playground__contrast-checker.css +2 -0
- package/styled-system/chunks/src__pages__playground__typography.css +2 -0
- package/styled-system/chunks/src__pages__radii.css +2 -0
- package/styled-system/chunks/src__pages__sizes.css +2 -0
- package/styled-system/chunks/src__pages__spacing.css +2 -0
- package/styled-system/chunks/src__pages__text-styles.css +2 -0
- package/styled-system/chunks/src__pages__token-analyzer__file.css +2 -0
- package/styled-system/chunks/src__pages__token-analyzer__index.css +2 -0
- package/styled-system/chunks/src__pages__token-analyzer__utility.css +2 -0
- package/styled-system/css/conditions.mjs +147 -0
- package/styled-system/css/css.d.ts +2 -0
- package/styled-system/css/css.mjs +391 -0
- package/styled-system/css/cva.d.ts +5 -0
- package/styled-system/css/cva.mjs +63 -0
- package/styled-system/css/cx.d.ts +4 -0
- package/styled-system/css/cx.mjs +15 -0
- package/styled-system/css/index.d.ts +3 -0
- package/styled-system/css/index.mjs +3 -0
- package/styled-system/global.css +61 -0
- package/styled-system/helpers.mjs +251 -0
- package/styled-system/jsx/absolute-center.d.ts +8 -0
- package/styled-system/jsx/absolute-center.mjs +9 -0
- package/styled-system/jsx/aspect-ratio.d.ts +8 -0
- package/styled-system/jsx/aspect-ratio.mjs +9 -0
- package/styled-system/jsx/box.d.ts +8 -0
- package/styled-system/jsx/box.mjs +8 -0
- package/styled-system/jsx/center.d.ts +8 -0
- package/styled-system/jsx/center.mjs +9 -0
- package/styled-system/jsx/circle.d.ts +8 -0
- package/styled-system/jsx/circle.mjs +9 -0
- package/styled-system/jsx/container.d.ts +8 -0
- package/styled-system/jsx/container.mjs +8 -0
- package/styled-system/jsx/divider.d.ts +8 -0
- package/styled-system/jsx/divider.mjs +9 -0
- package/styled-system/jsx/factory.d.ts +2 -0
- package/styled-system/jsx/factory.mjs +59 -0
- package/styled-system/jsx/flex.d.ts +8 -0
- package/styled-system/jsx/flex.mjs +9 -0
- package/styled-system/jsx/float.d.ts +8 -0
- package/styled-system/jsx/float.mjs +9 -0
- package/styled-system/jsx/grid-item.d.ts +8 -0
- package/styled-system/jsx/grid-item.mjs +9 -0
- package/styled-system/jsx/grid.d.ts +8 -0
- package/styled-system/jsx/grid.mjs +9 -0
- package/styled-system/jsx/hstack.d.ts +8 -0
- package/styled-system/jsx/hstack.mjs +9 -0
- package/styled-system/jsx/index.d.ts +20 -0
- package/styled-system/jsx/index.mjs +19 -0
- package/styled-system/jsx/is-valid-prop.mjs +1010 -0
- package/styled-system/jsx/spacer.d.ts +8 -0
- package/styled-system/jsx/spacer.mjs +9 -0
- package/styled-system/jsx/square.d.ts +8 -0
- package/styled-system/jsx/square.mjs +9 -0
- package/styled-system/jsx/stack.d.ts +8 -0
- package/styled-system/jsx/stack.mjs +9 -0
- package/styled-system/jsx/styled-link.d.ts +8 -0
- package/styled-system/jsx/styled-link.mjs +8 -0
- package/styled-system/jsx/vstack.d.ts +8 -0
- package/styled-system/jsx/vstack.mjs +9 -0
- package/styled-system/jsx/wrap.d.ts +8 -0
- package/styled-system/jsx/wrap.mjs +9 -0
- package/styled-system/patterns/absolute-center.d.ts +14 -0
- package/styled-system/patterns/absolute-center.mjs +23 -0
- package/styled-system/patterns/aspect-ratio.d.ts +14 -0
- package/styled-system/patterns/aspect-ratio.mjs +25 -0
- package/styled-system/patterns/box.d.ts +14 -0
- package/styled-system/patterns/box.mjs +12 -0
- package/styled-system/patterns/center.d.ts +14 -0
- package/styled-system/patterns/center.mjs +18 -0
- package/styled-system/patterns/circle.d.ts +14 -0
- package/styled-system/patterns/circle.mjs +22 -0
- package/styled-system/patterns/container.d.ts +14 -0
- package/styled-system/patterns/container.mjs +18 -0
- package/styled-system/patterns/divider.d.ts +16 -0
- package/styled-system/patterns/divider.mjs +21 -0
- package/styled-system/patterns/flex.d.ts +20 -0
- package/styled-system/patterns/flex.mjs +23 -0
- package/styled-system/patterns/float.d.ts +17 -0
- package/styled-system/patterns/float.mjs +45 -0
- package/styled-system/patterns/grid-item.d.ts +19 -0
- package/styled-system/patterns/grid-item.mjs +20 -0
- package/styled-system/patterns/grid.d.ts +18 -0
- package/styled-system/patterns/grid.mjs +25 -0
- package/styled-system/patterns/hstack.d.ts +15 -0
- package/styled-system/patterns/hstack.mjs +20 -0
- package/styled-system/patterns/index.d.ts +18 -0
- package/styled-system/patterns/index.mjs +18 -0
- package/styled-system/patterns/spacer.d.ts +14 -0
- package/styled-system/patterns/spacer.mjs +18 -0
- package/styled-system/patterns/square.d.ts +14 -0
- package/styled-system/patterns/square.mjs +21 -0
- package/styled-system/patterns/stack.d.ts +17 -0
- package/styled-system/patterns/stack.mjs +20 -0
- package/styled-system/patterns/styled-link.d.ts +14 -0
- package/styled-system/patterns/styled-link.mjs +18 -0
- package/styled-system/patterns/vstack.d.ts +15 -0
- package/styled-system/patterns/vstack.mjs +20 -0
- package/styled-system/patterns/wrap.d.ts +18 -0
- package/styled-system/patterns/wrap.mjs +22 -0
- package/styled-system/reset.css +190 -0
- package/styled-system/static.css +5 -0
- package/styled-system/styles.css +938 -0
- package/styled-system/tokens/index.css +374 -0
- package/styled-system/tokens/index.d.ts +8 -0
- package/styled-system/tokens/index.mjs +1590 -0
- package/styled-system/tokens/keyframes.css +30 -0
- package/styled-system/tokens/tokens.d.ts +56 -0
- package/styled-system/types/composition.d.ts +110 -0
- package/styled-system/types/conditions.d.ts +135 -0
- package/styled-system/types/csstype.d.ts +20748 -0
- package/styled-system/types/global.d.ts +15 -0
- package/styled-system/types/helpers.d.ts +1 -0
- package/styled-system/types/index.d.ts +3 -0
- package/styled-system/types/jsx.d.ts +27 -0
- package/styled-system/types/parts.d.ts +5 -0
- package/styled-system/types/pattern.d.ts +52 -0
- package/styled-system/types/prop-type.d.ts +300 -0
- package/styled-system/types/recipe.d.ts +79 -0
- package/styled-system/types/selectors.d.ts +56 -0
- package/styled-system/types/style-props.d.ts +688 -0
- package/styled-system/types/system-types.d.ts +76 -0
- package/virtual-panda.ts +72 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// Credits: https://github.com/bbc/color-contrast-checker
|
|
2
|
+
|
|
3
|
+
type Pair = { colorA: string; colorB: string; fontSize: number }
|
|
4
|
+
type Rgb = { r: number; g: number; b: number }
|
|
5
|
+
|
|
6
|
+
class RgbClass {
|
|
7
|
+
r = 0
|
|
8
|
+
g = 0
|
|
9
|
+
b = 0
|
|
10
|
+
toString = () => {
|
|
11
|
+
return '<r: ' + this.r + ' g: ' + this.g + ' b: ' + this.b + ' >'
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class Result {
|
|
16
|
+
WCAG_AA = false
|
|
17
|
+
WCAG_AAA = false
|
|
18
|
+
customRatio: number | undefined = undefined
|
|
19
|
+
toString = () => {
|
|
20
|
+
return '< WCAG-AA: ' + (this.WCAG_AA ? 'pass' : 'fail') + ' WCAG-AAA: ' + (this.WCAG_AAA ? 'pass' : 'fail') + ' >'
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class ColorContrastChecker {
|
|
25
|
+
fontSize = 14
|
|
26
|
+
|
|
27
|
+
rgbClass = new RgbClass()
|
|
28
|
+
|
|
29
|
+
isValidSixDigitColorCode = (hex: string) => {
|
|
30
|
+
const regSixDigitColorcode = /^(#)?([0-9a-fA-F]{6})?$/
|
|
31
|
+
return regSixDigitColorcode.test(hex)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
isValidThreeDigitColorCode = (hex: string) => {
|
|
35
|
+
const regThreeDigitColorcode = /^(#)?([0-9a-fA-F]{3})?$/
|
|
36
|
+
return regThreeDigitColorcode.test(hex)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
isValidColorCode = (hex: string) => {
|
|
40
|
+
return this.isValidSixDigitColorCode(hex) || this.isValidThreeDigitColorCode(hex)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
isValidRatio = (ratio: unknown) => {
|
|
44
|
+
return typeof ratio === 'number'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
convertColorToSixDigit = (hex: string) => {
|
|
48
|
+
return '#' + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3]
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
hexToLuminance = (color: string) => {
|
|
52
|
+
if (!this.isValidColorCode(color)) {
|
|
53
|
+
throw new Error('Invalid Color :' + color)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (this.isValidThreeDigitColorCode(color)) {
|
|
57
|
+
color = this.convertColorToSixDigit(color)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const rgb = this.getRGBFromHex(color)
|
|
61
|
+
|
|
62
|
+
const LRGB = this.calculateLRGB(rgb)
|
|
63
|
+
|
|
64
|
+
return this.calculateLuminance(LRGB)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
check = (colorA: string, colorB: string, fontSize?: number, customRatio?: number) => {
|
|
68
|
+
if (typeof fontSize !== 'undefined') {
|
|
69
|
+
this.fontSize = fontSize
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!colorA || !colorB) {
|
|
73
|
+
return false
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const l1 = this.hexToLuminance(colorA) /* higher value */
|
|
77
|
+
const l2 = this.hexToLuminance(colorB) /* lower value */
|
|
78
|
+
const contrastRatio = this.getContrastRatio(l1, l2)
|
|
79
|
+
|
|
80
|
+
if (typeof customRatio !== 'undefined') {
|
|
81
|
+
if (!this.isValidRatio(customRatio)) {
|
|
82
|
+
return false
|
|
83
|
+
}
|
|
84
|
+
return this.verifyCustomContrastRatio(contrastRatio, customRatio)
|
|
85
|
+
} else {
|
|
86
|
+
return this.verifyContrastRatio(contrastRatio)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
checkPairs = (pairs: Pair[], customRatio?: number) => {
|
|
91
|
+
const results = []
|
|
92
|
+
|
|
93
|
+
for (const i in pairs) {
|
|
94
|
+
const pair = pairs[i]
|
|
95
|
+
if (typeof pair.fontSize !== 'undefined') {
|
|
96
|
+
results.push(this.check(pair.colorA, pair.colorB, pair.fontSize, customRatio))
|
|
97
|
+
} else {
|
|
98
|
+
results.push(this.check(pair.colorA, pair.colorB, void 0, customRatio))
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return results
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
calculateLuminance = (lRGB: Rgb) => {
|
|
105
|
+
return 0.2126 * lRGB.r + 0.7152 * lRGB.g + 0.0722 * lRGB.b
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
isLevelAA = (colorA: string, colorB: string, fontSize: number) => {
|
|
109
|
+
const result = this.check(colorA, colorB, fontSize)
|
|
110
|
+
return result.WCAG_AA
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
isLevelAAA = (colorA: string, colorB: string, fontSize: number) => {
|
|
114
|
+
const result = this.check(colorA, colorB, fontSize)
|
|
115
|
+
return result.WCAG_AAA
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
isLevelCustom = (colorA: string, colorB: string, ratio: number) => {
|
|
119
|
+
const result = this.check(colorA, colorB, undefined, ratio)
|
|
120
|
+
return result.customRatio
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
getRGBFromHex = (color: string) => {
|
|
124
|
+
const rgb = new RgbClass()
|
|
125
|
+
|
|
126
|
+
if (typeof color !== 'string') {
|
|
127
|
+
throw new Error('must use string')
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const rVal = parseInt(color.slice(1, 3), 16)
|
|
131
|
+
const gVal = parseInt(color.slice(3, 5), 16)
|
|
132
|
+
const bVal = parseInt(color.slice(5, 7), 16)
|
|
133
|
+
|
|
134
|
+
rgb.r = rVal
|
|
135
|
+
rgb.g = gVal
|
|
136
|
+
rgb.b = bVal
|
|
137
|
+
|
|
138
|
+
return rgb
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
calculateSRGB = (rgb: Rgb) => {
|
|
142
|
+
const sRGB = new RgbClass()
|
|
143
|
+
|
|
144
|
+
for (const key in rgb) {
|
|
145
|
+
sRGB[key as keyof Rgb] = parseFloat((rgb[key as keyof Rgb] / 255).toString())
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return sRGB
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
calculateLRGB = (rgb: Rgb) => {
|
|
152
|
+
const sRGB = this.calculateSRGB(rgb)
|
|
153
|
+
const lRGB = Object.create(this.rgbClass)
|
|
154
|
+
let val = 0
|
|
155
|
+
|
|
156
|
+
for (const key in sRGB) {
|
|
157
|
+
//@ts-ignore
|
|
158
|
+
val = parseFloat(sRGB[key])
|
|
159
|
+
if (val <= 0.03928) {
|
|
160
|
+
lRGB[key] = val / 12.92
|
|
161
|
+
} else {
|
|
162
|
+
lRGB[key] = Math.pow((val + 0.055) / 1.055, 2.4)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return lRGB
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
getContrastRatio = (lumA: number, lumB: number) => {
|
|
170
|
+
let lighter: number
|
|
171
|
+
let darker: number
|
|
172
|
+
|
|
173
|
+
if (lumA >= lumB) {
|
|
174
|
+
lighter = lumA
|
|
175
|
+
darker = lumB
|
|
176
|
+
} else {
|
|
177
|
+
lighter = lumB
|
|
178
|
+
darker = lumA
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const ratio = (lighter + 0.05) / (darker + 0.05)
|
|
182
|
+
|
|
183
|
+
return ratio
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
verifyContrastRatio = (ratio: number) => {
|
|
187
|
+
const WCAG_REQ_RATIO_AA_LG = 3.0,
|
|
188
|
+
WCAG_REQ_RATIO_AA_SM = 4.5,
|
|
189
|
+
WCAG_REQ_RATIO_AAA_LG = 4.5,
|
|
190
|
+
WCAG_REQ_RATIO_AAA_SM = 7.0,
|
|
191
|
+
WCAG_FONT_CUTOFF = 18
|
|
192
|
+
|
|
193
|
+
const results = new Result()
|
|
194
|
+
const fontSize = this.fontSize || 14
|
|
195
|
+
|
|
196
|
+
if (fontSize >= WCAG_FONT_CUTOFF) {
|
|
197
|
+
results.WCAG_AA = ratio >= WCAG_REQ_RATIO_AA_LG
|
|
198
|
+
results.WCAG_AAA = ratio >= WCAG_REQ_RATIO_AAA_LG
|
|
199
|
+
} else {
|
|
200
|
+
results.WCAG_AA = ratio >= WCAG_REQ_RATIO_AA_SM
|
|
201
|
+
results.WCAG_AAA = ratio >= WCAG_REQ_RATIO_AAA_SM
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return results
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
verifyCustomContrastRatio = (inputRatio: number, checkRatio: number) => {
|
|
208
|
+
const resultsClass = new Result()
|
|
209
|
+
resultsClass.toString = function () {
|
|
210
|
+
return '< Custom Ratio: ' + (this.customRatio ? 'pass' : 'fail') + ' >'
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const results = Object.create(resultsClass)
|
|
214
|
+
|
|
215
|
+
results.customRatio = inputRatio >= checkRatio
|
|
216
|
+
return results
|
|
217
|
+
}
|
|
218
|
+
}
|
package/src/lib/color.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ColorContrastChecker } from './color-contrast-checker'
|
|
2
|
+
|
|
3
|
+
export const getContrastPairs = (colorA: string, colorB: string) => {
|
|
4
|
+
const contrastChecker = new ColorContrastChecker()
|
|
5
|
+
let res
|
|
6
|
+
try {
|
|
7
|
+
res = contrastChecker.checkPairs([
|
|
8
|
+
{
|
|
9
|
+
colorA,
|
|
10
|
+
colorB,
|
|
11
|
+
fontSize: 14,
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
colorA,
|
|
15
|
+
colorB,
|
|
16
|
+
fontSize: 18,
|
|
17
|
+
},
|
|
18
|
+
])
|
|
19
|
+
} catch (error) {
|
|
20
|
+
//
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return res
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const getContrastRatio = (colorA: string, colorB: string) => {
|
|
27
|
+
const contrastChecker = new ColorContrastChecker()
|
|
28
|
+
let luminanceA, luminanceB
|
|
29
|
+
let ratio: number | undefined
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
luminanceA = contrastChecker.hexToLuminance(colorA)
|
|
33
|
+
luminanceB = contrastChecker.hexToLuminance(colorB)
|
|
34
|
+
ratio = contrastChecker.getContrastRatio(luminanceA, luminanceB)
|
|
35
|
+
} catch (error) {
|
|
36
|
+
//
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return ratio
|
|
40
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ColorContrastIcon,
|
|
3
|
+
ColorIcon,
|
|
4
|
+
FontSizesIcon,
|
|
5
|
+
FontWeightIcon,
|
|
6
|
+
LayerStylesIcon,
|
|
7
|
+
LetterSpacingIcon,
|
|
8
|
+
LineHeightIcon,
|
|
9
|
+
SizesIcon,
|
|
10
|
+
SpacingIcon,
|
|
11
|
+
TextStylesIcon,
|
|
12
|
+
TypographyIcon,
|
|
13
|
+
} from '../components/icons'
|
|
14
|
+
|
|
15
|
+
export enum NavKeys {
|
|
16
|
+
RADII = 'radii',
|
|
17
|
+
COLORS = 'colors',
|
|
18
|
+
LETTER_SPACINGS = 'letter-spacings',
|
|
19
|
+
LINE_HEIGHTS = 'line-heights',
|
|
20
|
+
FONT_WEIGHTS = 'font-weights',
|
|
21
|
+
FONT_SIZES = 'font-sizes',
|
|
22
|
+
SIZES = 'sizes',
|
|
23
|
+
SPACING = 'spacing',
|
|
24
|
+
FONTS = 'fonts',
|
|
25
|
+
TEXT_STYLES = 'text-styles',
|
|
26
|
+
LAYER_STYLES = 'layer-styles',
|
|
27
|
+
TOKEN_ANALYZER = 'token-analyzer',
|
|
28
|
+
TYPOGRAPHY_PLAYGROUND = 'playground/typography',
|
|
29
|
+
SPACING_PLAYGROUND = 'playground/spacing',
|
|
30
|
+
CONTRAST_CHECKER = 'playground/contrast-checker',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type NavItemData = {
|
|
34
|
+
label: string
|
|
35
|
+
id: NavKeys
|
|
36
|
+
description: string
|
|
37
|
+
icon: React.ElementType
|
|
38
|
+
type: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const navItems: NavItemData[] = [
|
|
42
|
+
{
|
|
43
|
+
label: 'Colors',
|
|
44
|
+
id: NavKeys.COLORS,
|
|
45
|
+
description: 'A solid color palette for any context',
|
|
46
|
+
icon: ColorIcon,
|
|
47
|
+
type: 'token',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
label: 'Fonts',
|
|
51
|
+
id: NavKeys.FONTS,
|
|
52
|
+
description: 'Preview your pre configured fonts.',
|
|
53
|
+
icon: FontSizesIcon,
|
|
54
|
+
type: 'token',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
label: 'Letter Spacings',
|
|
58
|
+
id: NavKeys.LETTER_SPACINGS,
|
|
59
|
+
description: 'Letter spacing is the space between text characters.',
|
|
60
|
+
icon: LetterSpacingIcon,
|
|
61
|
+
type: 'token',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
label: 'Line Heights',
|
|
65
|
+
id: NavKeys.LINE_HEIGHTS,
|
|
66
|
+
description: 'Line height is the vertical distance between two lines.',
|
|
67
|
+
icon: LineHeightIcon,
|
|
68
|
+
type: 'token',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
label: 'Font Weights',
|
|
72
|
+
id: NavKeys.FONT_WEIGHTS,
|
|
73
|
+
description: 'Font weight determines how bold or light text appears.',
|
|
74
|
+
icon: FontWeightIcon,
|
|
75
|
+
type: 'token',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
label: 'Font Sizes',
|
|
79
|
+
id: NavKeys.FONT_SIZES,
|
|
80
|
+
description: 'Font size updates the size of a font, and its relative units.',
|
|
81
|
+
icon: FontSizesIcon,
|
|
82
|
+
type: 'token',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
label: 'Sizes',
|
|
86
|
+
id: NavKeys.SIZES,
|
|
87
|
+
description: 'Preview your pre configured sizes.',
|
|
88
|
+
icon: SizesIcon,
|
|
89
|
+
type: 'token',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
label: 'Spacing',
|
|
93
|
+
id: NavKeys.SPACING,
|
|
94
|
+
description: 'Preview your pre configured spacing.',
|
|
95
|
+
icon: SpacingIcon,
|
|
96
|
+
type: 'token',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
label: 'Border Radius',
|
|
100
|
+
id: NavKeys.RADII,
|
|
101
|
+
description: 'Preview your pre configured radii.',
|
|
102
|
+
icon: SizesIcon,
|
|
103
|
+
type: 'token',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
label: 'Text Styles',
|
|
107
|
+
id: NavKeys.TEXT_STYLES,
|
|
108
|
+
description: 'Preview your pre configured text styles.',
|
|
109
|
+
icon: TextStylesIcon,
|
|
110
|
+
type: 'token',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
label: 'Layer Styles',
|
|
114
|
+
id: NavKeys.LAYER_STYLES,
|
|
115
|
+
description: 'Preview your pre configured layer styles.',
|
|
116
|
+
icon: LayerStylesIcon,
|
|
117
|
+
type: 'token',
|
|
118
|
+
},
|
|
119
|
+
// {
|
|
120
|
+
// label: 'Token analyzer',
|
|
121
|
+
// id: NavKeys.TOKEN_ANALYZER,
|
|
122
|
+
// description: 'Visualize your tokens usage in your app.',
|
|
123
|
+
// icon: LayerStylesIcon,
|
|
124
|
+
// type: 'token',
|
|
125
|
+
// },
|
|
126
|
+
{
|
|
127
|
+
label: 'Typography',
|
|
128
|
+
id: NavKeys.TYPOGRAPHY_PLAYGROUND,
|
|
129
|
+
description: 'Visually test font styles with any text.',
|
|
130
|
+
icon: TypographyIcon,
|
|
131
|
+
type: 'playground',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
label: 'Color Contrast',
|
|
135
|
+
id: NavKeys.CONTRAST_CHECKER,
|
|
136
|
+
description: 'Test contrast ratio between two colors.',
|
|
137
|
+
icon: ColorContrastIcon,
|
|
138
|
+
type: 'playground',
|
|
139
|
+
},
|
|
140
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createContext as createReactContext, useContext as useReactContext } from 'react'
|
|
2
|
+
|
|
3
|
+
function getErrorMessage(hook: string, provider: string) {
|
|
4
|
+
return `${hook} returned \`undefined\`. Seems you forgot to wrap component within ${provider}`
|
|
5
|
+
}
|
|
6
|
+
export function createContext<T>(
|
|
7
|
+
options: { name: string; strict?: boolean; hookName?: string; providerName?: string; errorMessage?: string } = {
|
|
8
|
+
name: '',
|
|
9
|
+
},
|
|
10
|
+
) {
|
|
11
|
+
const { name, strict = true, hookName = 'useContext', providerName = 'Provider', errorMessage } = options
|
|
12
|
+
const Context = createReactContext<T>(undefined as T)
|
|
13
|
+
Context.displayName = name
|
|
14
|
+
|
|
15
|
+
function useContext() {
|
|
16
|
+
const context = useReactContext(Context)
|
|
17
|
+
if (!context && strict) {
|
|
18
|
+
const error = new Error(errorMessage ?? getErrorMessage(hookName, providerName))
|
|
19
|
+
error.name = 'ContextError'
|
|
20
|
+
Error.captureStackTrace?.(error, useContext)
|
|
21
|
+
throw error
|
|
22
|
+
}
|
|
23
|
+
return context
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return [Context.Provider, useContext, Context] as const
|
|
27
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ReportItemJSON } from '@pandacss/types'
|
|
2
|
+
import { analysisData } from './analysis-data'
|
|
3
|
+
import { pick } from './pick'
|
|
4
|
+
|
|
5
|
+
export const getReportItem = (id: ReportItemJSON['id']) =>
|
|
6
|
+
(analysisData.details.byId as Record<string, any>)[id] as ReportItemJSON
|
|
7
|
+
|
|
8
|
+
export type SearchableReportItemAttributes = Partial<
|
|
9
|
+
Pick<ReportItemJSON, 'value' | 'category' | 'propName' | 'filepath' | 'from' | 'isKnown'> & {
|
|
10
|
+
important?: boolean
|
|
11
|
+
}
|
|
12
|
+
>
|
|
13
|
+
|
|
14
|
+
export const getUtilityLink = (reportItem: SearchableReportItemAttributes) => {
|
|
15
|
+
const searchParams = new URLSearchParams(
|
|
16
|
+
pick(reportItem, ['value', 'category', 'propName', 'from', 'filepath', 'isKnown', 'important']) as any,
|
|
17
|
+
)
|
|
18
|
+
return `/token-analyzer/utility?${searchParams.toString()}`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const getFileLink = (reportItem: SearchableReportItemAttributes) => {
|
|
22
|
+
const searchParams = new URLSearchParams(pick(reportItem, ['filepath']) as any)
|
|
23
|
+
return `/token-analyzer/file?${searchParams.toString()}`
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const getReportItemFromTokenName = (tokenName: string) => {
|
|
27
|
+
const reportItem = analysisData.details.globalMaps.byTokenName[tokenName]?.[0]
|
|
28
|
+
return getReportItem(reportItem)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const getReportRelativeFilePath = (filePath: string) => filePath.replace(analysisData.cwd + '/', '')
|
|
32
|
+
export const getReportRange = (reportItem: ReportItemJSON) => `:${reportItem.box.line}:${reportItem.box.column}`
|
|
33
|
+
|
|
34
|
+
const openInEditor = (filepath: string, line: number, column: number) => {
|
|
35
|
+
return fetch(`/__open-in-editor?file=${encodeURIComponent(`${filepath}:${line}:${column}`)}`)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const openReportItemInEditor = (reportItem: ReportItemJSON) => {
|
|
39
|
+
console.log(reportItem)
|
|
40
|
+
return openInEditor(reportItem.filepath, reportItem.box.line, reportItem.box.column)
|
|
41
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function groupIn<Key extends keyof T, T extends Record<string, any>>(
|
|
2
|
+
array: T[],
|
|
3
|
+
keyOrGetter: Key,
|
|
4
|
+
): Record<T[Key], T>
|
|
5
|
+
export function groupIn<T, KeyReturnT>(
|
|
6
|
+
array: T[],
|
|
7
|
+
keyOrGetter: (item: T) => KeyReturnT,
|
|
8
|
+
): KeyReturnT extends string | number ? Record<KeyReturnT, T> : never
|
|
9
|
+
export function groupIn<Key, T>(array: T[], keyOrGetter: Key) {
|
|
10
|
+
let kv
|
|
11
|
+
return array.reduce((r, a) => {
|
|
12
|
+
kv = typeof keyOrGetter === 'function' ? keyOrGetter(a) : a[keyOrGetter as unknown as keyof T]
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
r[kv] = a
|
|
15
|
+
return r
|
|
16
|
+
}, {})
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function groupBy<Key extends keyof T, T extends Record<string, any>>(
|
|
20
|
+
array: T[],
|
|
21
|
+
keyOrGetter: Key,
|
|
22
|
+
): Record<T[Key], T[]>
|
|
23
|
+
export function groupBy<T, KeyReturnT>(
|
|
24
|
+
array: T[],
|
|
25
|
+
keyOrGetter: (item: T) => KeyReturnT,
|
|
26
|
+
): KeyReturnT extends string | number ? Record<KeyReturnT, T[]> : never
|
|
27
|
+
export function groupBy<Key, T>(array: T[], keyOrGetter: Key) {
|
|
28
|
+
let kv
|
|
29
|
+
return array.reduce((r, a) => {
|
|
30
|
+
kv = typeof keyOrGetter === 'function' ? keyOrGetter(a) : a[keyOrGetter as unknown as keyof T]
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
r[kv] = [...(r[kv] || []), a]
|
|
33
|
+
return r
|
|
34
|
+
}, {})
|
|
35
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { flatten } from '@pandacss/shared'
|
|
2
|
+
import { TokenDictionary } from '@pandacss/token-dictionary'
|
|
3
|
+
import type { TokenDataTypes, UserConfig } from '@pandacss/types'
|
|
4
|
+
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
import { config as _config } from 'virtual:panda'
|
|
7
|
+
|
|
8
|
+
const config = _config as UserConfig
|
|
9
|
+
|
|
10
|
+
const { theme } = config
|
|
11
|
+
|
|
12
|
+
const context = {
|
|
13
|
+
tokens: new TokenDictionary(theme ?? {}),
|
|
14
|
+
getCategory(category: keyof TokenDataTypes) {
|
|
15
|
+
return this.tokens.categoryMap.get(category)!
|
|
16
|
+
},
|
|
17
|
+
textStyles: flatten(theme?.textStyles ?? {}),
|
|
18
|
+
layerStyles: flatten(theme?.layerStyles ?? {}),
|
|
19
|
+
logo: config.studio?.logo,
|
|
20
|
+
inject: config.studio?.inject ?? { head: '', body: '' },
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default context
|
package/src/lib/pick.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Pick given properties in object */
|
|
2
|
+
export function pick<T, K extends keyof T>(obj: T, paths: K[]): Pick<T, K> {
|
|
3
|
+
const result = {} as Pick<T, K>
|
|
4
|
+
|
|
5
|
+
Object.keys(obj as any).forEach((key) => {
|
|
6
|
+
if (!paths.includes(key as K)) return
|
|
7
|
+
// @ts-expect-error
|
|
8
|
+
result[key] = obj[key]
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
return result as Pick<T, K>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Omit given properties from object */
|
|
15
|
+
export function omit<T extends Record<string, any>, K extends keyof T>(object: T, keys: K[]) {
|
|
16
|
+
const result: Record<string, any> = {}
|
|
17
|
+
|
|
18
|
+
Object.keys(object).forEach((key) => {
|
|
19
|
+
if (keys.includes(key as K)) return
|
|
20
|
+
result[key] = object[key]
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
return result as Omit<T, K>
|
|
24
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { toPx } from '@pandacss/shared'
|
|
2
|
+
|
|
3
|
+
const num = (v: string | undefined) => parseFloat(toPx(v) ?? '-1')
|
|
4
|
+
|
|
5
|
+
export function getSortedSizes(sizes: any[]) {
|
|
6
|
+
return sizes.sort((a, b) => {
|
|
7
|
+
if (!a.originalValue || !b.originalValue) return 0
|
|
8
|
+
return num(a.originalValue) - num(b.originalValue)
|
|
9
|
+
})
|
|
10
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { Token } from '@pandacss/types'
|
|
2
|
+
import { useState } from 'react'
|
|
3
|
+
import context from './panda.context'
|
|
4
|
+
|
|
5
|
+
type Color = {
|
|
6
|
+
isConditional?: boolean
|
|
7
|
+
isReference?: boolean
|
|
8
|
+
name: string
|
|
9
|
+
originalValue: string
|
|
10
|
+
path: string[]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type ColorToken = Token & Color
|
|
14
|
+
|
|
15
|
+
const UNCATEGORIZED_ID = 'uncategorized' as const
|
|
16
|
+
|
|
17
|
+
const groupByColorPalette = (colors: Map<string, any>, filterMethod?: (token: ColorToken) => boolean) => {
|
|
18
|
+
const values = Array.from(colors.values()).filter((color) => !color.isConditional && !color.extensions.isVirtual)
|
|
19
|
+
return values.reduce((acc, nxt) => {
|
|
20
|
+
if (!filterMethod?.(nxt)) return acc
|
|
21
|
+
|
|
22
|
+
const colorPalette = nxt.extensions.colorPalette || UNCATEGORIZED_ID
|
|
23
|
+
if (!(colorPalette in acc)) acc[colorPalette] = []
|
|
24
|
+
const exists = (acc[colorPalette] as any[]).find((tok) => tok.name === nxt.name)
|
|
25
|
+
if (!exists) acc[colorPalette].push(nxt)
|
|
26
|
+
return acc
|
|
27
|
+
}, {})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const getSemanticTokens = (allTokens: ColorToken[], filterMethod?: (token: ColorToken) => boolean) => {
|
|
31
|
+
const semanticTokens = allTokens.filter(
|
|
32
|
+
(token) => token.type === 'color' && token.isConditional && !token.extensions?.isVirtual,
|
|
33
|
+
)
|
|
34
|
+
return semanticTokens
|
|
35
|
+
.reduce((acc, nxt) => {
|
|
36
|
+
if (!filterMethod) {
|
|
37
|
+
acc.push(nxt)
|
|
38
|
+
} else {
|
|
39
|
+
const rawQualified = semanticTokens.filter(filterMethod)
|
|
40
|
+
|
|
41
|
+
if (filterMethod(nxt) || rawQualified.some((tok) => tok.name === nxt.name)) {
|
|
42
|
+
acc.push(nxt)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return acc
|
|
46
|
+
}, [] as ColorToken[])
|
|
47
|
+
.reduce(
|
|
48
|
+
(acc, nxt) => ({
|
|
49
|
+
...acc,
|
|
50
|
+
[nxt.extensions?.prop]: {
|
|
51
|
+
//@ts-expect-error
|
|
52
|
+
...acc[nxt.extensions?.prop],
|
|
53
|
+
[nxt.extensions?.condition]: { value: nxt.value, isReference: nxt.isReference },
|
|
54
|
+
extensions: nxt.extensions,
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
{},
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const allTokens = context.tokens.allTokens
|
|
62
|
+
const colors = context.getCategory('colors')
|
|
63
|
+
|
|
64
|
+
export const useColorDocs = () => {
|
|
65
|
+
const [filterQuery, setFilterQuery] = useState('')
|
|
66
|
+
|
|
67
|
+
const filterMethod = (token: ColorToken) => {
|
|
68
|
+
return [
|
|
69
|
+
...token.path,
|
|
70
|
+
token.originalValue,
|
|
71
|
+
token.description,
|
|
72
|
+
token.value,
|
|
73
|
+
token.name,
|
|
74
|
+
token.extensions?.var,
|
|
75
|
+
token.extensions?.prop,
|
|
76
|
+
...Object.values(token.extensions?.conditions || {}),
|
|
77
|
+
]
|
|
78
|
+
.filter(Boolean)
|
|
79
|
+
.some((prop) => prop.includes(filterQuery))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const colorsInCategories = groupByColorPalette(colors, filterMethod)
|
|
83
|
+
const uncategorizedColors = colorsInCategories[UNCATEGORIZED_ID]
|
|
84
|
+
|
|
85
|
+
const categorizedColors = Object.entries<any[]>(colorsInCategories).filter(
|
|
86
|
+
([category]) => category !== UNCATEGORIZED_ID,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
const semanticTokens = Object.entries<Record<string, any>>(getSemanticTokens(allTokens, filterMethod))
|
|
90
|
+
const hasResults =
|
|
91
|
+
!!categorizedColors.length || !!uncategorizedColors?.length || !!Object.values(semanticTokens).length
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
filterQuery,
|
|
95
|
+
setFilterQuery,
|
|
96
|
+
uncategorizedColors,
|
|
97
|
+
categorizedColors,
|
|
98
|
+
semanticTokens,
|
|
99
|
+
hasResults,
|
|
100
|
+
}
|
|
101
|
+
}
|