@mgcrea/react-native-tailwind 0.5.2 → 0.6.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.
- package/README.md +141 -10
- package/dist/babel/index.cjs +625 -111
- package/dist/components/Pressable.d.ts +2 -0
- package/dist/components/TextInput.d.ts +2 -0
- package/dist/config/palettes.d.ts +302 -0
- package/dist/config/palettes.js +1 -0
- package/dist/parser/colors.js +1 -1
- package/dist/parser/colors.test.js +1 -1
- package/dist/parser/index.d.ts +1 -0
- package/dist/parser/index.js +1 -1
- package/dist/parser/layout.js +1 -1
- package/dist/parser/layout.test.js +1 -1
- package/dist/parser/transforms.d.ts +13 -0
- package/dist/parser/transforms.js +1 -0
- package/dist/parser/transforms.test.js +1 -0
- package/dist/parser/typography.js +1 -1
- package/dist/parser/typography.test.js +1 -1
- package/dist/types.d.ts +32 -2
- package/package.json +1 -1
- package/src/components/Pressable.tsx +1 -0
- package/src/components/TextInput.tsx +1 -0
- package/src/config/palettes.ts +304 -0
- package/src/parser/colors.test.ts +57 -31
- package/src/parser/colors.ts +34 -111
- package/src/parser/index.ts +3 -0
- package/src/parser/layout.test.ts +35 -0
- package/src/parser/layout.ts +26 -0
- package/src/parser/transforms.test.ts +318 -0
- package/src/parser/transforms.ts +406 -0
- package/src/parser/typography.test.ts +12 -0
- package/src/parser/typography.ts +8 -0
- package/src/types.ts +22 -1
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
export type TailwindPalette = {
|
|
2
|
+
"50": string;
|
|
3
|
+
"100": string;
|
|
4
|
+
"200": string;
|
|
5
|
+
"300": string;
|
|
6
|
+
"400": string;
|
|
7
|
+
"500": string;
|
|
8
|
+
"600": string;
|
|
9
|
+
"700": string;
|
|
10
|
+
"800": string;
|
|
11
|
+
"900": string;
|
|
12
|
+
"950": string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const TAILWIND_PALETTES = {
|
|
16
|
+
red: {
|
|
17
|
+
"50": "#fef2f2",
|
|
18
|
+
"100": "#ffe2e2",
|
|
19
|
+
"200": "#ffc9c9",
|
|
20
|
+
"300": "#ffa2a2",
|
|
21
|
+
"400": "#ff6467",
|
|
22
|
+
"500": "#fb2c36",
|
|
23
|
+
"600": "#e7000b",
|
|
24
|
+
"700": "#c10007",
|
|
25
|
+
"800": "#9f0712",
|
|
26
|
+
"900": "#82181a",
|
|
27
|
+
"950": "#460809",
|
|
28
|
+
},
|
|
29
|
+
orange: {
|
|
30
|
+
"50": "#fff7ed",
|
|
31
|
+
"100": "#ffedd4",
|
|
32
|
+
"200": "#ffd6a7",
|
|
33
|
+
"300": "#ffb86a",
|
|
34
|
+
"400": "#ff8904",
|
|
35
|
+
"500": "#ff6900",
|
|
36
|
+
"600": "#f54900",
|
|
37
|
+
"700": "#ca3500",
|
|
38
|
+
"800": "#9f2d00",
|
|
39
|
+
"900": "#7e2a0c",
|
|
40
|
+
"950": "#441306",
|
|
41
|
+
},
|
|
42
|
+
amber: {
|
|
43
|
+
"50": "#fffbeb",
|
|
44
|
+
"100": "#fef3c6",
|
|
45
|
+
"200": "#fee685",
|
|
46
|
+
"300": "#ffd230",
|
|
47
|
+
"400": "#ffb900",
|
|
48
|
+
"500": "#fe9a00",
|
|
49
|
+
"600": "#e17100",
|
|
50
|
+
"700": "#bb4d00",
|
|
51
|
+
"800": "#973c00",
|
|
52
|
+
"900": "#7b3306",
|
|
53
|
+
"950": "#461901",
|
|
54
|
+
},
|
|
55
|
+
yellow: {
|
|
56
|
+
"50": "#fefce8",
|
|
57
|
+
"100": "#fef9c2",
|
|
58
|
+
"200": "#fff085",
|
|
59
|
+
"300": "#ffdf20",
|
|
60
|
+
"400": "#fdc700",
|
|
61
|
+
"500": "#f0b100",
|
|
62
|
+
"600": "#d08700",
|
|
63
|
+
"700": "#a65f00",
|
|
64
|
+
"800": "#894b00",
|
|
65
|
+
"900": "#733e0a",
|
|
66
|
+
"950": "#432004",
|
|
67
|
+
},
|
|
68
|
+
lime: {
|
|
69
|
+
"50": "#f7fee7",
|
|
70
|
+
"100": "#ecfcca",
|
|
71
|
+
"200": "#d8f999",
|
|
72
|
+
"300": "#bbf451",
|
|
73
|
+
"400": "#9ae600",
|
|
74
|
+
"500": "#7ccf00",
|
|
75
|
+
"600": "#5ea500",
|
|
76
|
+
"700": "#497d00",
|
|
77
|
+
"800": "#3c6300",
|
|
78
|
+
"900": "#35530e",
|
|
79
|
+
"950": "#192e03",
|
|
80
|
+
},
|
|
81
|
+
green: {
|
|
82
|
+
"50": "#f0fdf4",
|
|
83
|
+
"100": "#dcfce7",
|
|
84
|
+
"200": "#b9f8cf",
|
|
85
|
+
"300": "#7bf1a8",
|
|
86
|
+
"400": "#05df72",
|
|
87
|
+
"500": "#00c950",
|
|
88
|
+
"600": "#00a63e",
|
|
89
|
+
"700": "#008236",
|
|
90
|
+
"800": "#016630",
|
|
91
|
+
"900": "#0d542b",
|
|
92
|
+
"950": "#032e15",
|
|
93
|
+
},
|
|
94
|
+
emerald: {
|
|
95
|
+
"50": "#ecfdf5",
|
|
96
|
+
"100": "#d0fae5",
|
|
97
|
+
"200": "#a4f4cf",
|
|
98
|
+
"300": "#5ee9b5",
|
|
99
|
+
"400": "#00d492",
|
|
100
|
+
"500": "#00bc7d",
|
|
101
|
+
"600": "#009966",
|
|
102
|
+
"700": "#007a55",
|
|
103
|
+
"800": "#006045",
|
|
104
|
+
"900": "#004f3b",
|
|
105
|
+
"950": "#002c22",
|
|
106
|
+
},
|
|
107
|
+
teal: {
|
|
108
|
+
"50": "#f0fdfa",
|
|
109
|
+
"100": "#cbfbf1",
|
|
110
|
+
"200": "#96f7e4",
|
|
111
|
+
"300": "#46ecd5",
|
|
112
|
+
"400": "#00d5be",
|
|
113
|
+
"500": "#00bba7",
|
|
114
|
+
"600": "#009689",
|
|
115
|
+
"700": "#00786f",
|
|
116
|
+
"800": "#005f5a",
|
|
117
|
+
"900": "#0b4f4a",
|
|
118
|
+
"950": "#022f2e",
|
|
119
|
+
},
|
|
120
|
+
cyan: {
|
|
121
|
+
"50": "#ecfeff",
|
|
122
|
+
"100": "#cefafe",
|
|
123
|
+
"200": "#a2f4fd",
|
|
124
|
+
"300": "#53eafd",
|
|
125
|
+
"400": "#00d3f2",
|
|
126
|
+
"500": "#00b8db",
|
|
127
|
+
"600": "#0092b8",
|
|
128
|
+
"700": "#007595",
|
|
129
|
+
"800": "#005f78",
|
|
130
|
+
"900": "#104e64",
|
|
131
|
+
"950": "#053345",
|
|
132
|
+
},
|
|
133
|
+
sky: {
|
|
134
|
+
"50": "#f0f9ff",
|
|
135
|
+
"100": "#dff2fe",
|
|
136
|
+
"200": "#b8e6fe",
|
|
137
|
+
"300": "#74d4ff",
|
|
138
|
+
"400": "#00bcff",
|
|
139
|
+
"500": "#00a6f4",
|
|
140
|
+
"600": "#0084d1",
|
|
141
|
+
"700": "#0069a8",
|
|
142
|
+
"800": "#00598a",
|
|
143
|
+
"900": "#024a70",
|
|
144
|
+
"950": "#052f4a",
|
|
145
|
+
},
|
|
146
|
+
blue: {
|
|
147
|
+
"50": "#eff6ff",
|
|
148
|
+
"100": "#dbeafe",
|
|
149
|
+
"200": "#bedbff",
|
|
150
|
+
"300": "#8ec5ff",
|
|
151
|
+
"400": "#51a2ff",
|
|
152
|
+
"500": "#2b7fff",
|
|
153
|
+
"600": "#155dfc",
|
|
154
|
+
"700": "#1447e6",
|
|
155
|
+
"800": "#193cb8",
|
|
156
|
+
"900": "#1c398e",
|
|
157
|
+
"950": "#162456",
|
|
158
|
+
},
|
|
159
|
+
indigo: {
|
|
160
|
+
"50": "#eef2ff",
|
|
161
|
+
"100": "#e0e7ff",
|
|
162
|
+
"200": "#c6d2ff",
|
|
163
|
+
"300": "#a3b3ff",
|
|
164
|
+
"400": "#7c86ff",
|
|
165
|
+
"500": "#615fff",
|
|
166
|
+
"600": "#4f39f6",
|
|
167
|
+
"700": "#432dd7",
|
|
168
|
+
"800": "#372aac",
|
|
169
|
+
"900": "#312c85",
|
|
170
|
+
"950": "#1e1a4d",
|
|
171
|
+
},
|
|
172
|
+
violet: {
|
|
173
|
+
"50": "#f5f3ff",
|
|
174
|
+
"100": "#ede9fe",
|
|
175
|
+
"200": "#ddd6ff",
|
|
176
|
+
"300": "#c4b4ff",
|
|
177
|
+
"400": "#a684ff",
|
|
178
|
+
"500": "#8e51ff",
|
|
179
|
+
"600": "#7f22fe",
|
|
180
|
+
"700": "#7008e7",
|
|
181
|
+
"800": "#5d0ec0",
|
|
182
|
+
"900": "#4d179a",
|
|
183
|
+
"950": "#2f0d68",
|
|
184
|
+
},
|
|
185
|
+
purple: {
|
|
186
|
+
"50": "#faf5ff",
|
|
187
|
+
"100": "#f3e8ff",
|
|
188
|
+
"200": "#e9d4ff",
|
|
189
|
+
"300": "#dab2ff",
|
|
190
|
+
"400": "#c27aff",
|
|
191
|
+
"500": "#ad46ff",
|
|
192
|
+
"600": "#9810fa",
|
|
193
|
+
"700": "#8200db",
|
|
194
|
+
"800": "#6e11b0",
|
|
195
|
+
"900": "#59168b",
|
|
196
|
+
"950": "#3c0366",
|
|
197
|
+
},
|
|
198
|
+
fuchsia: {
|
|
199
|
+
"50": "#fdf4ff",
|
|
200
|
+
"100": "#fae8ff",
|
|
201
|
+
"200": "#f6cfff",
|
|
202
|
+
"300": "#f4a8ff",
|
|
203
|
+
"400": "#ed6aff",
|
|
204
|
+
"500": "#e12afb",
|
|
205
|
+
"600": "#c800de",
|
|
206
|
+
"700": "#a800b7",
|
|
207
|
+
"800": "#8a0194",
|
|
208
|
+
"900": "#721378",
|
|
209
|
+
"950": "#4b004f",
|
|
210
|
+
},
|
|
211
|
+
pink: {
|
|
212
|
+
"50": "#fdf2f8",
|
|
213
|
+
"100": "#fce7f3",
|
|
214
|
+
"200": "#fccee8",
|
|
215
|
+
"300": "#fda5d5",
|
|
216
|
+
"400": "#fb64b6",
|
|
217
|
+
"500": "#f6339a",
|
|
218
|
+
"600": "#e60076",
|
|
219
|
+
"700": "#c6005c",
|
|
220
|
+
"800": "#a3004c",
|
|
221
|
+
"900": "#861043",
|
|
222
|
+
"950": "#510424",
|
|
223
|
+
},
|
|
224
|
+
rose: {
|
|
225
|
+
"50": "#fff1f2",
|
|
226
|
+
"100": "#ffe4e6",
|
|
227
|
+
"200": "#ffccd3",
|
|
228
|
+
"300": "#ffa1ad",
|
|
229
|
+
"400": "#ff637e",
|
|
230
|
+
"500": "#ff2056",
|
|
231
|
+
"600": "#ec003f",
|
|
232
|
+
"700": "#c70036",
|
|
233
|
+
"800": "#a50036",
|
|
234
|
+
"900": "#8b0836",
|
|
235
|
+
"950": "#4d0218",
|
|
236
|
+
},
|
|
237
|
+
slate: {
|
|
238
|
+
"50": "#f8fafc",
|
|
239
|
+
"100": "#f1f5f9",
|
|
240
|
+
"200": "#e2e8f0",
|
|
241
|
+
"300": "#cad5e2",
|
|
242
|
+
"400": "#90a1b9",
|
|
243
|
+
"500": "#62748e",
|
|
244
|
+
"600": "#45556c",
|
|
245
|
+
"700": "#314158",
|
|
246
|
+
"800": "#1d293d",
|
|
247
|
+
"900": "#0f172b",
|
|
248
|
+
"950": "#020618",
|
|
249
|
+
},
|
|
250
|
+
gray: {
|
|
251
|
+
"50": "#f9fafb",
|
|
252
|
+
"100": "#f3f4f6",
|
|
253
|
+
"200": "#e5e7eb",
|
|
254
|
+
"300": "#d1d5dc",
|
|
255
|
+
"400": "#99a1af",
|
|
256
|
+
"500": "#6a7282",
|
|
257
|
+
"600": "#4a5565",
|
|
258
|
+
"700": "#364153",
|
|
259
|
+
"800": "#1e2939",
|
|
260
|
+
"900": "#101828",
|
|
261
|
+
"950": "#030712",
|
|
262
|
+
},
|
|
263
|
+
zinc: {
|
|
264
|
+
"50": "#fafafa",
|
|
265
|
+
"100": "#f4f4f5",
|
|
266
|
+
"200": "#e4e4e7",
|
|
267
|
+
"300": "#d4d4d8",
|
|
268
|
+
"400": "#9f9fa9",
|
|
269
|
+
"500": "#71717b",
|
|
270
|
+
"600": "#52525c",
|
|
271
|
+
"700": "#3f3f46",
|
|
272
|
+
"800": "#27272a",
|
|
273
|
+
"900": "#18181b",
|
|
274
|
+
"950": "#09090b",
|
|
275
|
+
},
|
|
276
|
+
neutral: {
|
|
277
|
+
"50": "#fafafa",
|
|
278
|
+
"100": "#f5f5f5",
|
|
279
|
+
"200": "#e5e5e5",
|
|
280
|
+
"300": "#d4d4d4",
|
|
281
|
+
"400": "#a1a1a1",
|
|
282
|
+
"500": "#737373",
|
|
283
|
+
"600": "#525252",
|
|
284
|
+
"700": "#404040",
|
|
285
|
+
"800": "#262626",
|
|
286
|
+
"900": "#171717",
|
|
287
|
+
"950": "#0a0a0a",
|
|
288
|
+
},
|
|
289
|
+
stone: {
|
|
290
|
+
"50": "#fafaf9",
|
|
291
|
+
"100": "#f5f5f4",
|
|
292
|
+
"200": "#e7e5e4",
|
|
293
|
+
"300": "#d6d3d1",
|
|
294
|
+
"400": "#a6a09b",
|
|
295
|
+
"500": "#79716b",
|
|
296
|
+
"600": "#57534d",
|
|
297
|
+
"700": "#44403b",
|
|
298
|
+
"800": "#292524",
|
|
299
|
+
"900": "#1c1917",
|
|
300
|
+
"950": "#0c0a09",
|
|
301
|
+
},
|
|
302
|
+
} satisfies Record<string, TailwindPalette>;
|
|
303
|
+
|
|
304
|
+
export type TailwindColor = keyof typeof TAILWIND_PALETTES;
|
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import { COLORS, parseColor } from "./colors";
|
|
3
3
|
|
|
4
|
+
// Helper to apply opacity to hex color for testing
|
|
5
|
+
function applyOpacity(hex: string, opacity: number): string {
|
|
6
|
+
if (hex === "transparent") return "transparent";
|
|
7
|
+
const cleanHex = hex.replace(/^#/, "");
|
|
8
|
+
const fullHex =
|
|
9
|
+
cleanHex.length === 3
|
|
10
|
+
? cleanHex
|
|
11
|
+
.split("")
|
|
12
|
+
.map((char) => char + char)
|
|
13
|
+
.join("")
|
|
14
|
+
: cleanHex;
|
|
15
|
+
const alpha = Math.round((opacity / 100) * 255);
|
|
16
|
+
const alphaHex = alpha.toString(16).padStart(2, "0").toUpperCase();
|
|
17
|
+
return `#${fullHex.toUpperCase()}${alphaHex}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
4
20
|
describe("COLORS", () => {
|
|
5
21
|
it("should export complete color palette", () => {
|
|
6
22
|
expect(COLORS).toMatchSnapshot();
|
|
@@ -9,10 +25,10 @@ describe("COLORS", () => {
|
|
|
9
25
|
|
|
10
26
|
describe("parseColor - background colors", () => {
|
|
11
27
|
it("should parse background colors with preset values", () => {
|
|
12
|
-
expect(parseColor("bg-blue-500")).toEqual({ backgroundColor: "
|
|
13
|
-
expect(parseColor("bg-red-500")).toEqual({ backgroundColor: "
|
|
14
|
-
expect(parseColor("bg-green-500")).toEqual({ backgroundColor: "
|
|
15
|
-
expect(parseColor("bg-gray-300")).toEqual({ backgroundColor: "
|
|
28
|
+
expect(parseColor("bg-blue-500")).toEqual({ backgroundColor: COLORS["blue-500"] });
|
|
29
|
+
expect(parseColor("bg-red-500")).toEqual({ backgroundColor: COLORS["red-500"] });
|
|
30
|
+
expect(parseColor("bg-green-500")).toEqual({ backgroundColor: COLORS["green-500"] });
|
|
31
|
+
expect(parseColor("bg-gray-300")).toEqual({ backgroundColor: COLORS["gray-300"] });
|
|
16
32
|
});
|
|
17
33
|
|
|
18
34
|
it("should parse background colors with basic values", () => {
|
|
@@ -57,10 +73,10 @@ describe("parseColor - background colors", () => {
|
|
|
57
73
|
|
|
58
74
|
describe("parseColor - text colors", () => {
|
|
59
75
|
it("should parse text colors with preset values", () => {
|
|
60
|
-
expect(parseColor("text-blue-500")).toEqual({ color: "
|
|
61
|
-
expect(parseColor("text-red-500")).toEqual({ color: "
|
|
62
|
-
expect(parseColor("text-green-500")).toEqual({ color: "
|
|
63
|
-
expect(parseColor("text-gray-700")).toEqual({ color: "
|
|
76
|
+
expect(parseColor("text-blue-500")).toEqual({ color: COLORS["blue-500"] });
|
|
77
|
+
expect(parseColor("text-red-500")).toEqual({ color: COLORS["red-500"] });
|
|
78
|
+
expect(parseColor("text-green-500")).toEqual({ color: COLORS["green-500"] });
|
|
79
|
+
expect(parseColor("text-gray-700")).toEqual({ color: COLORS["gray-700"] });
|
|
64
80
|
});
|
|
65
81
|
|
|
66
82
|
it("should parse text colors with basic values", () => {
|
|
@@ -88,10 +104,10 @@ describe("parseColor - text colors", () => {
|
|
|
88
104
|
|
|
89
105
|
describe("parseColor - border colors", () => {
|
|
90
106
|
it("should parse border colors with preset values", () => {
|
|
91
|
-
expect(parseColor("border-blue-500")).toEqual({ borderColor: "
|
|
92
|
-
expect(parseColor("border-red-500")).toEqual({ borderColor: "
|
|
93
|
-
expect(parseColor("border-green-500")).toEqual({ borderColor: "
|
|
94
|
-
expect(parseColor("border-gray-200")).toEqual({ borderColor: "
|
|
107
|
+
expect(parseColor("border-blue-500")).toEqual({ borderColor: COLORS["blue-500"] });
|
|
108
|
+
expect(parseColor("border-red-500")).toEqual({ borderColor: COLORS["red-500"] });
|
|
109
|
+
expect(parseColor("border-green-500")).toEqual({ borderColor: COLORS["green-500"] });
|
|
110
|
+
expect(parseColor("border-gray-200")).toEqual({ borderColor: COLORS["gray-200"] });
|
|
95
111
|
});
|
|
96
112
|
|
|
97
113
|
it("should parse border colors with basic values", () => {
|
|
@@ -153,7 +169,7 @@ describe("parseColor - custom colors", () => {
|
|
|
153
169
|
});
|
|
154
170
|
|
|
155
171
|
it("should fallback to preset colors when custom color not found", () => {
|
|
156
|
-
expect(parseColor("bg-red-500", customColors)).toEqual({ backgroundColor: "
|
|
172
|
+
expect(parseColor("bg-red-500", customColors)).toEqual({ backgroundColor: COLORS["red-500"] });
|
|
157
173
|
});
|
|
158
174
|
});
|
|
159
175
|
|
|
@@ -192,6 +208,16 @@ describe("parseColor - edge cases", () => {
|
|
|
192
208
|
expect(parseColor("bg-[rgb(255,0,0)]")).toBeNull(); // RGB format not supported
|
|
193
209
|
});
|
|
194
210
|
|
|
211
|
+
it("should return null for non-color arbitrary values (to let other parsers handle them)", () => {
|
|
212
|
+
// These should be handled by typography parser
|
|
213
|
+
expect(parseColor("text-[13px]")).toBeNull();
|
|
214
|
+
expect(parseColor("text-[18px]")).toBeNull();
|
|
215
|
+
expect(parseColor("text-[24]")).toBeNull();
|
|
216
|
+
// These should be handled by sizing parser
|
|
217
|
+
expect(parseColor("bg-[100%]")).toBeNull();
|
|
218
|
+
expect(parseColor("bg-[50px]")).toBeNull();
|
|
219
|
+
});
|
|
220
|
+
|
|
195
221
|
it("should not match partial class names", () => {
|
|
196
222
|
expect(parseColor("background-blue-500")).toBeNull();
|
|
197
223
|
expect(parseColor("textcolor-red-500")).toBeNull();
|
|
@@ -210,9 +236,9 @@ describe("parseColor - edge cases", () => {
|
|
|
210
236
|
|
|
211
237
|
describe("parseColor - comprehensive coverage", () => {
|
|
212
238
|
it("should parse all color types with same preset color", () => {
|
|
213
|
-
expect(parseColor("bg-blue-500")).toEqual({ backgroundColor: "
|
|
214
|
-
expect(parseColor("text-blue-500")).toEqual({ color: "
|
|
215
|
-
expect(parseColor("border-blue-500")).toEqual({ borderColor: "
|
|
239
|
+
expect(parseColor("bg-blue-500")).toEqual({ backgroundColor: COLORS["blue-500"] });
|
|
240
|
+
expect(parseColor("text-blue-500")).toEqual({ color: COLORS["blue-500"] });
|
|
241
|
+
expect(parseColor("border-blue-500")).toEqual({ borderColor: COLORS["blue-500"] });
|
|
216
242
|
});
|
|
217
243
|
|
|
218
244
|
it("should parse all color types with same arbitrary hex", () => {
|
|
@@ -251,23 +277,23 @@ describe("parseColor - comprehensive coverage", () => {
|
|
|
251
277
|
|
|
252
278
|
describe("parseColor - opacity modifiers", () => {
|
|
253
279
|
it("should parse background colors with opacity modifiers", () => {
|
|
254
|
-
expect(parseColor("bg-black/50")).toEqual({ backgroundColor:
|
|
255
|
-
expect(parseColor("bg-white/50")).toEqual({ backgroundColor:
|
|
256
|
-
expect(parseColor("bg-blue-500/80")).toEqual({ backgroundColor: "
|
|
257
|
-
expect(parseColor("bg-red-500/30")).toEqual({ backgroundColor: "
|
|
280
|
+
expect(parseColor("bg-black/50")).toEqual({ backgroundColor: applyOpacity(COLORS.black, 50) });
|
|
281
|
+
expect(parseColor("bg-white/50")).toEqual({ backgroundColor: applyOpacity(COLORS.white, 50) });
|
|
282
|
+
expect(parseColor("bg-blue-500/80")).toEqual({ backgroundColor: applyOpacity(COLORS["blue-500"], 80) });
|
|
283
|
+
expect(parseColor("bg-red-500/30")).toEqual({ backgroundColor: applyOpacity(COLORS["red-500"], 30) });
|
|
258
284
|
});
|
|
259
285
|
|
|
260
286
|
it("should parse text colors with opacity modifiers", () => {
|
|
261
|
-
expect(parseColor("text-black/80")).toEqual({ color:
|
|
262
|
-
expect(parseColor("text-white/90")).toEqual({ color:
|
|
263
|
-
expect(parseColor("text-gray-900/70")).toEqual({ color: "
|
|
264
|
-
expect(parseColor("text-blue-500/50")).toEqual({ color: "
|
|
287
|
+
expect(parseColor("text-black/80")).toEqual({ color: applyOpacity(COLORS.black, 80) });
|
|
288
|
+
expect(parseColor("text-white/90")).toEqual({ color: applyOpacity(COLORS.white, 90) });
|
|
289
|
+
expect(parseColor("text-gray-900/70")).toEqual({ color: applyOpacity(COLORS["gray-900"], 70) });
|
|
290
|
+
expect(parseColor("text-blue-500/50")).toEqual({ color: applyOpacity(COLORS["blue-500"], 50) });
|
|
265
291
|
});
|
|
266
292
|
|
|
267
293
|
it("should parse border colors with opacity modifiers", () => {
|
|
268
|
-
expect(parseColor("border-black/25")).toEqual({ borderColor:
|
|
269
|
-
expect(parseColor("border-red-500/60")).toEqual({ borderColor: "
|
|
270
|
-
expect(parseColor("border-gray-200/40")).toEqual({ borderColor: "
|
|
294
|
+
expect(parseColor("border-black/25")).toEqual({ borderColor: applyOpacity(COLORS.black, 25) });
|
|
295
|
+
expect(parseColor("border-red-500/60")).toEqual({ borderColor: applyOpacity(COLORS["red-500"], 60) });
|
|
296
|
+
expect(parseColor("border-gray-200/40")).toEqual({ borderColor: applyOpacity(COLORS["gray-200"], 40) });
|
|
271
297
|
});
|
|
272
298
|
|
|
273
299
|
it("should handle opacity modifier with arbitrary hex colors", () => {
|
|
@@ -283,13 +309,13 @@ describe("parseColor - opacity modifiers", () => {
|
|
|
283
309
|
});
|
|
284
310
|
|
|
285
311
|
it("should handle opacity 0 (fully transparent)", () => {
|
|
286
|
-
expect(parseColor("bg-black/0")).toEqual({ backgroundColor:
|
|
287
|
-
expect(parseColor("text-red-500/0")).toEqual({ color: "
|
|
312
|
+
expect(parseColor("bg-black/0")).toEqual({ backgroundColor: applyOpacity(COLORS.black, 0) });
|
|
313
|
+
expect(parseColor("text-red-500/0")).toEqual({ color: applyOpacity(COLORS["red-500"], 0) });
|
|
288
314
|
});
|
|
289
315
|
|
|
290
316
|
it("should handle opacity 100 (fully opaque)", () => {
|
|
291
|
-
expect(parseColor("bg-black/100")).toEqual({ backgroundColor:
|
|
292
|
-
expect(parseColor("text-blue-500/100")).toEqual({ color: "
|
|
317
|
+
expect(parseColor("bg-black/100")).toEqual({ backgroundColor: applyOpacity(COLORS.black, 100) });
|
|
318
|
+
expect(parseColor("text-blue-500/100")).toEqual({ color: applyOpacity(COLORS["blue-500"], 100) });
|
|
293
319
|
});
|
|
294
320
|
|
|
295
321
|
it("should handle transparent color with opacity modifier", () => {
|
package/src/parser/colors.ts
CHANGED
|
@@ -2,123 +2,32 @@
|
|
|
2
2
|
* Color utilities (background, text, border colors)
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { TAILWIND_PALETTES } from "../config/palettes";
|
|
5
6
|
import type { StyleObject } from "../types";
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"gray-300": "#D1D5DB",
|
|
14
|
-
"gray-400": "#9CA3AF",
|
|
15
|
-
"gray-500": "#6B7280",
|
|
16
|
-
"gray-600": "#4B5563",
|
|
17
|
-
"gray-700": "#374151",
|
|
18
|
-
"gray-800": "#1F2937",
|
|
19
|
-
"gray-900": "#111827",
|
|
20
|
-
|
|
21
|
-
// Red
|
|
22
|
-
"red-50": "#FEF2F2",
|
|
23
|
-
"red-100": "#FEE2E2",
|
|
24
|
-
"red-200": "#FECACA",
|
|
25
|
-
"red-300": "#FCA5A5",
|
|
26
|
-
"red-400": "#F87171",
|
|
27
|
-
"red-500": "#EF4444",
|
|
28
|
-
"red-600": "#DC2626",
|
|
29
|
-
"red-700": "#B91C1C",
|
|
30
|
-
"red-800": "#991B1B",
|
|
31
|
-
"red-900": "#7F1D1D",
|
|
32
|
-
|
|
33
|
-
// Blue
|
|
34
|
-
"blue-50": "#EFF6FF",
|
|
35
|
-
"blue-100": "#DBEAFE",
|
|
36
|
-
"blue-200": "#BFDBFE",
|
|
37
|
-
"blue-300": "#93C5FD",
|
|
38
|
-
"blue-400": "#60A5FA",
|
|
39
|
-
"blue-500": "#3B82F6",
|
|
40
|
-
"blue-600": "#2563EB",
|
|
41
|
-
"blue-700": "#1D4ED8",
|
|
42
|
-
"blue-800": "#1E40AF",
|
|
43
|
-
"blue-900": "#1E3A8A",
|
|
44
|
-
|
|
45
|
-
// Green
|
|
46
|
-
"green-50": "#F0FDF4",
|
|
47
|
-
"green-100": "#DCFCE7",
|
|
48
|
-
"green-200": "#BBF7D0",
|
|
49
|
-
"green-300": "#86EFAC",
|
|
50
|
-
"green-400": "#4ADE80",
|
|
51
|
-
"green-500": "#22C55E",
|
|
52
|
-
"green-600": "#16A34A",
|
|
53
|
-
"green-700": "#15803D",
|
|
54
|
-
"green-800": "#166534",
|
|
55
|
-
"green-900": "#14532D",
|
|
56
|
-
|
|
57
|
-
// Yellow
|
|
58
|
-
"yellow-50": "#FEFCE8",
|
|
59
|
-
"yellow-100": "#FEF9C3",
|
|
60
|
-
"yellow-200": "#FEF08A",
|
|
61
|
-
"yellow-300": "#FDE047",
|
|
62
|
-
"yellow-400": "#FACC15",
|
|
63
|
-
"yellow-500": "#EAB308",
|
|
64
|
-
"yellow-600": "#CA8A04",
|
|
65
|
-
"yellow-700": "#A16207",
|
|
66
|
-
"yellow-800": "#854D0E",
|
|
67
|
-
"yellow-900": "#713F12",
|
|
68
|
-
|
|
69
|
-
// Purple
|
|
70
|
-
"purple-50": "#FAF5FF",
|
|
71
|
-
"purple-100": "#F3E8FF",
|
|
72
|
-
"purple-200": "#E9D5FF",
|
|
73
|
-
"purple-300": "#D8B4FE",
|
|
74
|
-
"purple-400": "#C084FC",
|
|
75
|
-
"purple-500": "#A855F7",
|
|
76
|
-
"purple-600": "#9333EA",
|
|
77
|
-
"purple-700": "#7E22CE",
|
|
78
|
-
"purple-800": "#6B21A8",
|
|
79
|
-
"purple-900": "#581C87",
|
|
8
|
+
/**
|
|
9
|
+
* Flatten TAILWIND_PALETTES nested structure into flat color map
|
|
10
|
+
* Converts { red: { "50": "#fff", "100": "#eee" } } to { "red-50": "#fff", "red-100": "#eee" }
|
|
11
|
+
*/
|
|
12
|
+
function flattenColors(): Record<string, string> {
|
|
13
|
+
const flat: Record<string, string> = {};
|
|
80
14
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
"pink-400": "#F472B6",
|
|
87
|
-
"pink-500": "#EC4899",
|
|
88
|
-
"pink-600": "#DB2777",
|
|
89
|
-
"pink-700": "#BE185D",
|
|
90
|
-
"pink-800": "#9D174D",
|
|
91
|
-
"pink-900": "#831843",
|
|
15
|
+
for (const [colorName, shades] of Object.entries(TAILWIND_PALETTES)) {
|
|
16
|
+
for (const [shade, hex] of Object.entries(shades)) {
|
|
17
|
+
flat[`${colorName}-${shade}`] = hex;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
92
20
|
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
"orange-300": "#FDBA74",
|
|
98
|
-
"orange-400": "#FB923C",
|
|
99
|
-
"orange-500": "#F97316",
|
|
100
|
-
"orange-600": "#EA580C",
|
|
101
|
-
"orange-700": "#C2410C",
|
|
102
|
-
"orange-800": "#9A3412",
|
|
103
|
-
"orange-900": "#7C2D12",
|
|
21
|
+
// Add basic colors
|
|
22
|
+
flat.white = "#FFFFFF";
|
|
23
|
+
flat.black = "#000000";
|
|
24
|
+
flat.transparent = "transparent";
|
|
104
25
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
"indigo-100": "#E0E7FF",
|
|
108
|
-
"indigo-200": "#C7D2FE",
|
|
109
|
-
"indigo-300": "#A5B4FC",
|
|
110
|
-
"indigo-400": "#818CF8",
|
|
111
|
-
"indigo-500": "#6366F1",
|
|
112
|
-
"indigo-600": "#4F46E5",
|
|
113
|
-
"indigo-700": "#4338CA",
|
|
114
|
-
"indigo-800": "#3730A3",
|
|
115
|
-
"indigo-900": "#312E81",
|
|
26
|
+
return flat;
|
|
27
|
+
}
|
|
116
28
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
black: "#000000",
|
|
120
|
-
transparent: "transparent",
|
|
121
|
-
};
|
|
29
|
+
// Tailwind color palette (flattened from config)
|
|
30
|
+
export const COLORS: Record<string, string> = flattenColors();
|
|
122
31
|
|
|
123
32
|
/**
|
|
124
33
|
* Apply opacity to hex color by appending alpha channel
|
|
@@ -241,8 +150,13 @@ export function parseColor(cls: string, customColors?: Record<string, string>):
|
|
|
241
150
|
};
|
|
242
151
|
|
|
243
152
|
// Background color: bg-blue-500, bg-blue-500/50, bg-[#ff0000]/80
|
|
153
|
+
// Only parse arbitrary values that look like colors (start with #)
|
|
244
154
|
if (cls.startsWith("bg-")) {
|
|
245
155
|
const colorKey = cls.substring(3);
|
|
156
|
+
// Skip arbitrary values that don't look like colors (e.g., bg-[100%] is sizing)
|
|
157
|
+
if (colorKey.startsWith("[") && !colorKey.startsWith("[#")) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
246
160
|
const color = parseColorWithOpacity(colorKey);
|
|
247
161
|
if (color) {
|
|
248
162
|
return { backgroundColor: color };
|
|
@@ -250,8 +164,13 @@ export function parseColor(cls: string, customColors?: Record<string, string>):
|
|
|
250
164
|
}
|
|
251
165
|
|
|
252
166
|
// Text color: text-blue-500, text-blue-500/50, text-[#ff0000]/80
|
|
167
|
+
// Only parse arbitrary values that look like colors (start with #)
|
|
253
168
|
if (cls.startsWith("text-")) {
|
|
254
169
|
const colorKey = cls.substring(5);
|
|
170
|
+
// Skip arbitrary values that don't look like colors (e.g., text-[13px] is font size)
|
|
171
|
+
if (colorKey.startsWith("[") && !colorKey.startsWith("[#")) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
255
174
|
const color = parseColorWithOpacity(colorKey);
|
|
256
175
|
if (color) {
|
|
257
176
|
return { color: color };
|
|
@@ -261,6 +180,10 @@ export function parseColor(cls: string, customColors?: Record<string, string>):
|
|
|
261
180
|
// Border color: border-blue-500, border-blue-500/50, border-[#ff0000]/80
|
|
262
181
|
if (cls.startsWith("border-") && !cls.match(/^border-[0-9]/)) {
|
|
263
182
|
const colorKey = cls.substring(7);
|
|
183
|
+
// Skip arbitrary values that don't look like colors (e.g., border-[3px] is width)
|
|
184
|
+
if (colorKey.startsWith("[") && !colorKey.startsWith("[#")) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
264
187
|
const color = parseColorWithOpacity(colorKey);
|
|
265
188
|
if (color) {
|
|
266
189
|
return { borderColor: color };
|
package/src/parser/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { parseLayout } from "./layout";
|
|
|
11
11
|
import { parseShadow } from "./shadows";
|
|
12
12
|
import { parseSizing } from "./sizing";
|
|
13
13
|
import { parseSpacing } from "./spacing";
|
|
14
|
+
import { parseTransform } from "./transforms";
|
|
14
15
|
import { parseTypography } from "./typography";
|
|
15
16
|
|
|
16
17
|
/**
|
|
@@ -50,6 +51,7 @@ export function parseClass(cls: string, customColors?: Record<string, string>):
|
|
|
50
51
|
parseSizing,
|
|
51
52
|
parseShadow,
|
|
52
53
|
parseAspectRatio,
|
|
54
|
+
parseTransform,
|
|
53
55
|
];
|
|
54
56
|
|
|
55
57
|
for (const parser of parsers) {
|
|
@@ -75,6 +77,7 @@ export { parseLayout } from "./layout";
|
|
|
75
77
|
export { parseShadow } from "./shadows";
|
|
76
78
|
export { parseSizing } from "./sizing";
|
|
77
79
|
export { parseSpacing } from "./spacing";
|
|
80
|
+
export { parseTransform } from "./transforms";
|
|
78
81
|
export { parseTypography } from "./typography";
|
|
79
82
|
|
|
80
83
|
// Re-export modifier utilities
|