Skip to content

Commit 01496c6

Browse files
authored
fix(language-server): support escape hatched colors (#73)
1 parent 101ba76 commit 01496c6

File tree

4 files changed

+76
-10
lines changed

4 files changed

+76
-10
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@pandacss/language-server': minor
3+
---
4+
5+
handle escape hatched colors

packages/language-server/__tests__/get-token.test.ts

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,42 @@ test('CSS var', () => {
4545
test('token reference with curly braces', () => {
4646
const ctx = createContext()
4747
expect(getTokenFromPropValue(ctx, 'border', '{colors.gray.300}')).toMatchInlineSnapshot(`
48-
{
48+
_Token {
49+
"description": undefined,
4950
"extensions": {
50-
"kind": "invalid-token-path",
51+
"category": "colors",
52+
"colorPalette": "gray",
53+
"colorPaletteRoots": [
54+
[
55+
"gray",
56+
],
57+
],
58+
"colorPaletteTokenKeys": [
59+
[
60+
"300",
61+
],
62+
],
63+
"condition": "base",
64+
"kind": "semantic-color",
65+
"prop": "gray.300",
66+
"var": "--colors-gray-300",
67+
"varRef": "var(--colors-gray-300)",
68+
"vscodeColor": {
69+
"alpha": 1,
70+
"blue": 0.8588235294117647,
71+
"green": 0.8352941176470589,
72+
"red": 0.8196078431372549,
73+
},
5174
},
52-
"name": "{colors.gray.300}",
53-
"path": "borders.{colors.gray.300}",
75+
"name": "colors.gray.300",
76+
"originalValue": "#d1d5db",
77+
"path": [
78+
"colors",
79+
"gray",
80+
"300",
81+
],
5482
"type": "color",
55-
"value": "{colors.gray.300}",
83+
"value": "#d1d5db",
5684
}
5785
`)
5886
})
@@ -189,6 +217,27 @@ test('color: #fff', () => {
189217
`)
190218
})
191219

220+
test('color: [#fff]', () => {
221+
const ctx = createContext()
222+
expect(getTokenFromPropValue(ctx, 'color', '[#fff]')).toMatchInlineSnapshot(`
223+
{
224+
"extensions": {
225+
"kind": "native-color",
226+
"vscodeColor": {
227+
"alpha": 1,
228+
"blue": 1,
229+
"green": 1,
230+
"red": 1,
231+
},
232+
},
233+
"name": "#fff",
234+
"path": "colors.#fff",
235+
"type": "color",
236+
"value": "#fff",
237+
}
238+
`)
239+
})
240+
192241
test('width: xs', () => {
193242
const ctx = createContext()
194243
expect(getTokenFromPropValue(ctx, 'width', 'xs')).toMatchInlineSnapshot(`

packages/language-server/src/tokens/expand-token-fn.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import type { Token } from '@pandacss/token-dictionary'
1111
/**
1212
* Regex for matching a tokenized reference.
1313
*/
14-
const REFERENCE_REGEX = /({([^}]*)})/g
15-
const curlyBracketRegex = /[{}]/g
14+
const REFERENCE_REGEX = /({([^}]*)})/
15+
const curlyBracketRegex = /[{}]/
1616

1717
/**
1818
* Returns all references in a string

packages/language-server/src/tokens/get-token.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ import { color2kToVsCodeColor } from './color2k-to-vscode-color'
44
import { isColor } from './is-color'
55
import { getTokensInString, hasTokenRef } from './expand-token-fn'
66

7+
const ESCAPE_HATCHED = /^(\[)(.*)(\])$/
8+
9+
const removeEscapeHatch = (value: string) => {
10+
if (ESCAPE_HATCHED.test(value)) {
11+
return value.match(ESCAPE_HATCHED)?.[2] as string
12+
}
13+
return value
14+
}
15+
716
const getColorExtensions = (value: string, kind: string) => {
817
const vscodeColor = color2kToVsCodeColor(value)
918
if (!vscodeColor) return
@@ -43,12 +52,15 @@ export const getTokenFromPropValue = (ctx: PandaContext, prop: string, value: st
4352
.find((t) => t.token !== undefined)
4453

4554
const token = matchedToken?.token
46-
// If token was located use the first category and value
47-
const tokenPath = matchedToken?.tokenPath ?? [potentialCategories[0], value].join('.')
4855

4956
// arbitrary value like
5057
// display: "block", zIndex: 1, ...
5158
if (!token) {
59+
// remove escape hatch if found
60+
value = removeEscapeHatch(value)
61+
// Use the first category for the token path
62+
const tokenPath = [potentialCategories[0], value].join('.')
63+
5264
// any color
5365
// color: "blue", color: "#000", color: "rgb(0, 0, 0)", ...
5466
if (isColor(value)) {
@@ -96,7 +108,7 @@ export const getTokenFromPropValue = (ctx: PandaContext, prop: string, value: st
96108

97109
let color = token.value
98110
// could be a semantic token, so the token.value wouldn't be a color directly, it's actually a CSS variable
99-
if (!isColor(color) && typeof token.value === "string" && token.value.startsWith('var(--')) {
111+
if (!isColor(color) && typeof token.value === 'string' && token.value.startsWith('var(--')) {
100112
const [tokenRef] = ctx.tokens.getReferences(token.originalValue)
101113
if (tokenRef?.value) {
102114
color = tokenRef.value

0 commit comments

Comments
 (0)