@mgcrea/react-native-tailwind 0.3.0 → 0.5.0
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 +459 -39
- package/dist/babel/index.cjs +810 -279
- package/dist/babel/index.d.ts +2 -1
- package/dist/babel/index.ts +328 -22
- package/dist/components/Pressable.d.ts +32 -0
- package/dist/components/Pressable.js +1 -0
- package/dist/components/TextInput.d.ts +56 -0
- package/dist/components/TextInput.js +1 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.js +1 -1
- package/dist/parser/aspectRatio.d.ts +16 -0
- package/dist/parser/aspectRatio.js +1 -0
- package/dist/parser/aspectRatio.test.d.ts +1 -0
- package/dist/parser/aspectRatio.test.js +1 -0
- package/dist/parser/borders.js +1 -1
- package/dist/parser/borders.test.d.ts +1 -0
- package/dist/parser/borders.test.js +1 -0
- package/dist/parser/colors.d.ts +1 -0
- package/dist/parser/colors.js +1 -1
- package/dist/parser/colors.test.d.ts +1 -0
- package/dist/parser/colors.test.js +1 -0
- package/dist/parser/index.d.ts +4 -0
- package/dist/parser/index.js +1 -1
- package/dist/parser/layout.d.ts +2 -0
- package/dist/parser/layout.js +1 -1
- package/dist/parser/layout.test.d.ts +1 -0
- package/dist/parser/layout.test.js +1 -0
- package/dist/parser/modifiers.d.ts +47 -0
- package/dist/parser/modifiers.js +1 -0
- package/dist/parser/modifiers.test.d.ts +1 -0
- package/dist/parser/modifiers.test.js +1 -0
- package/dist/parser/shadows.d.ts +26 -0
- package/dist/parser/shadows.js +1 -0
- package/dist/parser/shadows.test.d.ts +1 -0
- package/dist/parser/shadows.test.js +1 -0
- package/dist/parser/sizing.test.d.ts +1 -0
- package/dist/parser/sizing.test.js +1 -0
- package/dist/parser/spacing.d.ts +1 -1
- package/dist/parser/spacing.js +1 -1
- package/dist/parser/spacing.test.d.ts +1 -0
- package/dist/parser/spacing.test.js +1 -0
- package/dist/parser/typography.d.ts +2 -1
- package/dist/parser/typography.js +1 -1
- package/dist/parser/typography.test.d.ts +1 -0
- package/dist/parser/typography.test.js +1 -0
- package/dist/types.d.ts +5 -2
- package/package.json +7 -6
- package/src/babel/index.ts +328 -22
- package/src/components/Pressable.tsx +46 -0
- package/src/components/TextInput.tsx +90 -0
- package/src/index.ts +20 -2
- package/src/parser/aspectRatio.test.ts +191 -0
- package/src/parser/aspectRatio.ts +73 -0
- package/src/parser/borders.test.ts +329 -0
- package/src/parser/borders.ts +187 -108
- package/src/parser/colors.test.ts +335 -0
- package/src/parser/colors.ts +117 -6
- package/src/parser/index.ts +13 -2
- package/src/parser/layout.test.ts +459 -0
- package/src/parser/layout.ts +128 -0
- package/src/parser/modifiers.test.ts +375 -0
- package/src/parser/modifiers.ts +104 -0
- package/src/parser/shadows.test.ts +201 -0
- package/src/parser/shadows.ts +133 -0
- package/src/parser/sizing.test.ts +256 -0
- package/src/parser/spacing.test.ts +226 -0
- package/src/parser/spacing.ts +93 -138
- package/src/parser/typography.test.ts +221 -0
- package/src/parser/typography.ts +143 -112
- package/src/types.ts +2 -2
- package/dist/react-native.d.js +0 -1
package/src/parser/spacing.ts
CHANGED
|
@@ -43,92 +43,85 @@ export const SPACING_SCALE: Record<string, number> = {
|
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* Parse spacing
|
|
47
|
-
*
|
|
46
|
+
* Parse arbitrary spacing value: [16px], [20]
|
|
47
|
+
* Returns number for px values, null for unsupported formats
|
|
48
48
|
*/
|
|
49
|
-
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
49
|
+
function parseArbitrarySpacing(value: string): number | null {
|
|
50
|
+
// Match: [16px] or [16] (pixels only)
|
|
51
|
+
const pxMatch = value.match(/^\[(\d+)(?:px)?\]$/);
|
|
52
|
+
if (pxMatch) {
|
|
53
|
+
return parseInt(pxMatch[1], 10);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Warn about unsupported formats
|
|
57
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
58
|
+
if (process.env.NODE_ENV !== "production") {
|
|
59
|
+
console.warn(
|
|
60
|
+
`[react-native-tailwind] Unsupported arbitrary spacing value: ${value}. Only px values are supported (e.g., [16px] or [16]).`,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
return null;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
/**
|
|
69
|
-
* Parse margin
|
|
70
|
+
* Parse spacing classes (margin, padding, gap)
|
|
71
|
+
* Examples: m-4, mx-2, mt-8, p-4, px-2, pt-8, gap-4, m-[16px]
|
|
70
72
|
*/
|
|
71
|
-
function
|
|
72
|
-
// m-4
|
|
73
|
-
const
|
|
74
|
-
if (
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
export function parseSpacing(cls: string): StyleObject | null {
|
|
74
|
+
// Margin: m-4, mx-2, mt-8, m-[16px], etc.
|
|
75
|
+
const marginMatch = cls.match(/^m([xytrbls]?)-(.+)$/);
|
|
76
|
+
if (marginMatch) {
|
|
77
|
+
const [, dir, valueStr] = marginMatch;
|
|
78
|
+
|
|
79
|
+
// Try arbitrary value first
|
|
80
|
+
const arbitraryValue = parseArbitrarySpacing(valueStr);
|
|
81
|
+
if (arbitraryValue !== null) {
|
|
82
|
+
return getMarginStyle(dir, arbitraryValue);
|
|
78
83
|
}
|
|
79
|
-
}
|
|
80
84
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (value !== undefined) {
|
|
86
|
-
return { marginHorizontal: value };
|
|
85
|
+
// Try preset scale
|
|
86
|
+
const scaleValue = SPACING_SCALE[valueStr];
|
|
87
|
+
if (scaleValue !== undefined) {
|
|
88
|
+
return getMarginStyle(dir, scaleValue);
|
|
87
89
|
}
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
//
|
|
91
|
-
const
|
|
92
|
-
if (
|
|
93
|
-
const
|
|
94
|
-
if (value !== undefined) {
|
|
95
|
-
return { marginVertical: value };
|
|
96
|
-
}
|
|
97
|
-
}
|
|
92
|
+
// Padding: p-4, px-2, pt-8, p-[16px], etc.
|
|
93
|
+
const paddingMatch = cls.match(/^p([xytrbls]?)-(.+)$/);
|
|
94
|
+
if (paddingMatch) {
|
|
95
|
+
const [, dir, valueStr] = paddingMatch;
|
|
98
96
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (value !== undefined) {
|
|
104
|
-
return { marginTop: value };
|
|
97
|
+
// Try arbitrary value first
|
|
98
|
+
const arbitraryValue = parseArbitrarySpacing(valueStr);
|
|
99
|
+
if (arbitraryValue !== null) {
|
|
100
|
+
return getPaddingStyle(dir, arbitraryValue);
|
|
105
101
|
}
|
|
106
|
-
}
|
|
107
102
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (value !== undefined) {
|
|
113
|
-
return { marginRight: value };
|
|
103
|
+
// Try preset scale
|
|
104
|
+
const scaleValue = SPACING_SCALE[valueStr];
|
|
105
|
+
if (scaleValue !== undefined) {
|
|
106
|
+
return getPaddingStyle(dir, scaleValue);
|
|
114
107
|
}
|
|
115
108
|
}
|
|
116
109
|
|
|
117
|
-
//
|
|
118
|
-
const
|
|
119
|
-
if (
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
110
|
+
// Gap: gap-4, gap-[16px]
|
|
111
|
+
const gapMatch = cls.match(/^gap-(.+)$/);
|
|
112
|
+
if (gapMatch) {
|
|
113
|
+
const valueStr = gapMatch[1];
|
|
114
|
+
|
|
115
|
+
// Try arbitrary value first
|
|
116
|
+
const arbitraryValue = parseArbitrarySpacing(valueStr);
|
|
117
|
+
if (arbitraryValue !== null) {
|
|
118
|
+
return { gap: arbitraryValue };
|
|
123
119
|
}
|
|
124
|
-
}
|
|
125
120
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (value !== undefined) {
|
|
131
|
-
return { marginLeft: value };
|
|
121
|
+
// Try preset scale
|
|
122
|
+
const scaleValue = SPACING_SCALE[valueStr];
|
|
123
|
+
if (scaleValue !== undefined) {
|
|
124
|
+
return { gap: scaleValue };
|
|
132
125
|
}
|
|
133
126
|
}
|
|
134
127
|
|
|
@@ -136,87 +129,49 @@ function parseMargin(cls: string): StyleObject | null {
|
|
|
136
129
|
}
|
|
137
130
|
|
|
138
131
|
/**
|
|
139
|
-
*
|
|
132
|
+
* Get margin style object based on direction
|
|
140
133
|
*/
|
|
141
|
-
function
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
134
|
+
function getMarginStyle(dir: string, value: number): StyleObject {
|
|
135
|
+
switch (dir) {
|
|
136
|
+
case "":
|
|
137
|
+
return { margin: value };
|
|
138
|
+
case "x":
|
|
139
|
+
return { marginHorizontal: value };
|
|
140
|
+
case "y":
|
|
141
|
+
return { marginVertical: value };
|
|
142
|
+
case "t":
|
|
143
|
+
return { marginTop: value };
|
|
144
|
+
case "r":
|
|
145
|
+
return { marginRight: value };
|
|
146
|
+
case "b":
|
|
147
|
+
return { marginBottom: value };
|
|
148
|
+
case "l":
|
|
149
|
+
return { marginLeft: value };
|
|
150
|
+
default:
|
|
151
|
+
return {};
|
|
149
152
|
}
|
|
153
|
+
}
|
|
150
154
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
155
|
+
/**
|
|
156
|
+
* Get padding style object based on direction
|
|
157
|
+
*/
|
|
158
|
+
function getPaddingStyle(dir: string, value: number): StyleObject {
|
|
159
|
+
switch (dir) {
|
|
160
|
+
case "":
|
|
161
|
+
return { padding: value };
|
|
162
|
+
case "x":
|
|
156
163
|
return { paddingHorizontal: value };
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// py-4 -> paddingVertical: 16
|
|
161
|
-
const yMatch = cls.match(/^py-(\d+(?:\.\d+)?)$/);
|
|
162
|
-
if (yMatch) {
|
|
163
|
-
const value = SPACING_SCALE[yMatch[1]];
|
|
164
|
-
if (value !== undefined) {
|
|
164
|
+
case "y":
|
|
165
165
|
return { paddingVertical: value };
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// pt-4 -> paddingTop: 16
|
|
170
|
-
const tMatch = cls.match(/^pt-(\d+(?:\.\d+)?)$/);
|
|
171
|
-
if (tMatch) {
|
|
172
|
-
const value = SPACING_SCALE[tMatch[1]];
|
|
173
|
-
if (value !== undefined) {
|
|
166
|
+
case "t":
|
|
174
167
|
return { paddingTop: value };
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// pr-4 -> paddingRight: 16
|
|
179
|
-
const rMatch = cls.match(/^pr-(\d+(?:\.\d+)?)$/);
|
|
180
|
-
if (rMatch) {
|
|
181
|
-
const value = SPACING_SCALE[rMatch[1]];
|
|
182
|
-
if (value !== undefined) {
|
|
168
|
+
case "r":
|
|
183
169
|
return { paddingRight: value };
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// pb-4 -> paddingBottom: 16
|
|
188
|
-
const bMatch = cls.match(/^pb-(\d+(?:\.\d+)?)$/);
|
|
189
|
-
if (bMatch) {
|
|
190
|
-
const value = SPACING_SCALE[bMatch[1]];
|
|
191
|
-
if (value !== undefined) {
|
|
170
|
+
case "b":
|
|
192
171
|
return { paddingBottom: value };
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// pl-4 -> paddingLeft: 16
|
|
197
|
-
const lMatch = cls.match(/^pl-(\d+(?:\.\d+)?)$/);
|
|
198
|
-
if (lMatch) {
|
|
199
|
-
const value = SPACING_SCALE[lMatch[1]];
|
|
200
|
-
if (value !== undefined) {
|
|
172
|
+
case "l":
|
|
201
173
|
return { paddingLeft: value };
|
|
202
|
-
|
|
174
|
+
default:
|
|
175
|
+
return {};
|
|
203
176
|
}
|
|
204
|
-
|
|
205
|
-
return null;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Parse gap classes
|
|
210
|
-
*/
|
|
211
|
-
function parseGap(cls: string): StyleObject | null {
|
|
212
|
-
// gap-4 -> gap: 16
|
|
213
|
-
const match = cls.match(/^gap-(\d+(?:\.\d+)?)$/);
|
|
214
|
-
if (match) {
|
|
215
|
-
const value = SPACING_SCALE[match[1]];
|
|
216
|
-
if (value !== undefined) {
|
|
217
|
-
return { gap: value };
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return null;
|
|
222
177
|
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { FONT_SIZES, LETTER_SPACING_SCALE, parseTypography } from "./typography";
|
|
3
|
+
|
|
4
|
+
describe("FONT_SIZES", () => {
|
|
5
|
+
it("should export complete font size scale", () => {
|
|
6
|
+
expect(FONT_SIZES).toMatchSnapshot();
|
|
7
|
+
});
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe("LETTER_SPACING_SCALE", () => {
|
|
11
|
+
it("should export complete letter spacing scale", () => {
|
|
12
|
+
expect(LETTER_SPACING_SCALE).toMatchSnapshot();
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe("parseTypography - font size", () => {
|
|
17
|
+
it("should parse font size with preset values", () => {
|
|
18
|
+
expect(parseTypography("text-xs")).toEqual({ fontSize: 12 });
|
|
19
|
+
expect(parseTypography("text-sm")).toEqual({ fontSize: 14 });
|
|
20
|
+
expect(parseTypography("text-base")).toEqual({ fontSize: 16 });
|
|
21
|
+
expect(parseTypography("text-lg")).toEqual({ fontSize: 18 });
|
|
22
|
+
expect(parseTypography("text-xl")).toEqual({ fontSize: 20 });
|
|
23
|
+
expect(parseTypography("text-2xl")).toEqual({ fontSize: 24 });
|
|
24
|
+
expect(parseTypography("text-3xl")).toEqual({ fontSize: 30 });
|
|
25
|
+
expect(parseTypography("text-4xl")).toEqual({ fontSize: 36 });
|
|
26
|
+
expect(parseTypography("text-5xl")).toEqual({ fontSize: 48 });
|
|
27
|
+
expect(parseTypography("text-6xl")).toEqual({ fontSize: 60 });
|
|
28
|
+
expect(parseTypography("text-7xl")).toEqual({ fontSize: 72 });
|
|
29
|
+
expect(parseTypography("text-8xl")).toEqual({ fontSize: 96 });
|
|
30
|
+
expect(parseTypography("text-9xl")).toEqual({ fontSize: 128 });
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("should parse font size with arbitrary pixel values", () => {
|
|
34
|
+
expect(parseTypography("text-[18px]")).toEqual({ fontSize: 18 });
|
|
35
|
+
expect(parseTypography("text-[18]")).toEqual({ fontSize: 18 });
|
|
36
|
+
expect(parseTypography("text-[22px]")).toEqual({ fontSize: 22 });
|
|
37
|
+
expect(parseTypography("text-[22]")).toEqual({ fontSize: 22 });
|
|
38
|
+
expect(parseTypography("text-[100px]")).toEqual({ fontSize: 100 });
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("parseTypography - font weight", () => {
|
|
43
|
+
it("should parse font weight values", () => {
|
|
44
|
+
expect(parseTypography("font-thin")).toEqual({ fontWeight: "100" });
|
|
45
|
+
expect(parseTypography("font-extralight")).toEqual({ fontWeight: "200" });
|
|
46
|
+
expect(parseTypography("font-light")).toEqual({ fontWeight: "300" });
|
|
47
|
+
expect(parseTypography("font-normal")).toEqual({ fontWeight: "400" });
|
|
48
|
+
expect(parseTypography("font-medium")).toEqual({ fontWeight: "500" });
|
|
49
|
+
expect(parseTypography("font-semibold")).toEqual({ fontWeight: "600" });
|
|
50
|
+
expect(parseTypography("font-bold")).toEqual({ fontWeight: "700" });
|
|
51
|
+
expect(parseTypography("font-extrabold")).toEqual({ fontWeight: "800" });
|
|
52
|
+
expect(parseTypography("font-black")).toEqual({ fontWeight: "900" });
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe("parseTypography - font style", () => {
|
|
57
|
+
it("should parse font style values", () => {
|
|
58
|
+
expect(parseTypography("italic")).toEqual({ fontStyle: "italic" });
|
|
59
|
+
expect(parseTypography("not-italic")).toEqual({ fontStyle: "normal" });
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe("parseTypography - text alignment", () => {
|
|
64
|
+
it("should parse text alignment values", () => {
|
|
65
|
+
expect(parseTypography("text-left")).toEqual({ textAlign: "left" });
|
|
66
|
+
expect(parseTypography("text-center")).toEqual({ textAlign: "center" });
|
|
67
|
+
expect(parseTypography("text-right")).toEqual({ textAlign: "right" });
|
|
68
|
+
expect(parseTypography("text-justify")).toEqual({ textAlign: "justify" });
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe("parseTypography - text decoration", () => {
|
|
73
|
+
it("should parse text decoration values", () => {
|
|
74
|
+
expect(parseTypography("underline")).toEqual({
|
|
75
|
+
textDecorationLine: "underline",
|
|
76
|
+
});
|
|
77
|
+
expect(parseTypography("line-through")).toEqual({
|
|
78
|
+
textDecorationLine: "line-through",
|
|
79
|
+
});
|
|
80
|
+
expect(parseTypography("no-underline")).toEqual({
|
|
81
|
+
textDecorationLine: "none",
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe("parseTypography - text transform", () => {
|
|
87
|
+
it("should parse text transform values", () => {
|
|
88
|
+
expect(parseTypography("uppercase")).toEqual({
|
|
89
|
+
textTransform: "uppercase",
|
|
90
|
+
});
|
|
91
|
+
expect(parseTypography("lowercase")).toEqual({
|
|
92
|
+
textTransform: "lowercase",
|
|
93
|
+
});
|
|
94
|
+
expect(parseTypography("capitalize")).toEqual({
|
|
95
|
+
textTransform: "capitalize",
|
|
96
|
+
});
|
|
97
|
+
expect(parseTypography("normal-case")).toEqual({ textTransform: "none" });
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe("parseTypography - line height", () => {
|
|
102
|
+
it("should parse line height with preset values", () => {
|
|
103
|
+
expect(parseTypography("leading-none")).toEqual({ lineHeight: 16 });
|
|
104
|
+
expect(parseTypography("leading-tight")).toEqual({ lineHeight: 20 });
|
|
105
|
+
expect(parseTypography("leading-snug")).toEqual({ lineHeight: 22 });
|
|
106
|
+
expect(parseTypography("leading-normal")).toEqual({ lineHeight: 24 });
|
|
107
|
+
expect(parseTypography("leading-relaxed")).toEqual({ lineHeight: 28 });
|
|
108
|
+
expect(parseTypography("leading-loose")).toEqual({ lineHeight: 32 });
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("should parse line height with arbitrary pixel values", () => {
|
|
112
|
+
expect(parseTypography("leading-[24px]")).toEqual({ lineHeight: 24 });
|
|
113
|
+
expect(parseTypography("leading-[24]")).toEqual({ lineHeight: 24 });
|
|
114
|
+
expect(parseTypography("leading-[30px]")).toEqual({ lineHeight: 30 });
|
|
115
|
+
expect(parseTypography("leading-[30]")).toEqual({ lineHeight: 30 });
|
|
116
|
+
expect(parseTypography("leading-[50px]")).toEqual({ lineHeight: 50 });
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe("parseTypography - letter spacing", () => {
|
|
121
|
+
it("should parse letter spacing with preset values", () => {
|
|
122
|
+
expect(parseTypography("tracking-tighter")).toEqual({
|
|
123
|
+
letterSpacing: -0.8,
|
|
124
|
+
});
|
|
125
|
+
expect(parseTypography("tracking-tight")).toEqual({ letterSpacing: -0.4 });
|
|
126
|
+
expect(parseTypography("tracking-normal")).toEqual({ letterSpacing: 0 });
|
|
127
|
+
expect(parseTypography("tracking-wide")).toEqual({ letterSpacing: 0.4 });
|
|
128
|
+
expect(parseTypography("tracking-wider")).toEqual({ letterSpacing: 0.8 });
|
|
129
|
+
expect(parseTypography("tracking-widest")).toEqual({ letterSpacing: 1.6 });
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe("parseTypography - edge cases", () => {
|
|
134
|
+
it("should return null for invalid classes", () => {
|
|
135
|
+
expect(parseTypography("invalid")).toBeNull();
|
|
136
|
+
expect(parseTypography("text")).toBeNull();
|
|
137
|
+
expect(parseTypography("font")).toBeNull();
|
|
138
|
+
expect(parseTypography("leading")).toBeNull();
|
|
139
|
+
expect(parseTypography("tracking")).toBeNull();
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("should return null for invalid font size values", () => {
|
|
143
|
+
expect(parseTypography("text-invalid")).toBeNull();
|
|
144
|
+
expect(parseTypography("text-10xl")).toBeNull();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("should return null for invalid font weight values", () => {
|
|
148
|
+
expect(parseTypography("font-invalid")).toBeNull();
|
|
149
|
+
expect(parseTypography("font-100")).toBeNull();
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it("should return null for arbitrary values with unsupported units", () => {
|
|
153
|
+
expect(parseTypography("text-[16rem]")).toBeNull();
|
|
154
|
+
expect(parseTypography("text-[2em]")).toBeNull();
|
|
155
|
+
expect(parseTypography("leading-[2rem]")).toBeNull();
|
|
156
|
+
expect(parseTypography("leading-[1.5em]")).toBeNull();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("should return null for malformed arbitrary values", () => {
|
|
160
|
+
expect(parseTypography("text-[16")).toBeNull();
|
|
161
|
+
expect(parseTypography("text-16]")).toBeNull();
|
|
162
|
+
expect(parseTypography("text-[]")).toBeNull();
|
|
163
|
+
expect(parseTypography("leading-[24")).toBeNull();
|
|
164
|
+
expect(parseTypography("leading-24]")).toBeNull();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("should not match partial class names", () => {
|
|
168
|
+
expect(parseTypography("mytext-lg")).toBeNull();
|
|
169
|
+
expect(parseTypography("font-bold-extra")).toBeNull();
|
|
170
|
+
expect(parseTypography("italic-text")).toBeNull();
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe("parseTypography - comprehensive coverage", () => {
|
|
175
|
+
it("should handle all typography categories independently", () => {
|
|
176
|
+
// Font size
|
|
177
|
+
expect(parseTypography("text-base")).toEqual({ fontSize: 16 });
|
|
178
|
+
// Font weight
|
|
179
|
+
expect(parseTypography("font-bold")).toEqual({ fontWeight: "700" });
|
|
180
|
+
// Font style
|
|
181
|
+
expect(parseTypography("italic")).toEqual({ fontStyle: "italic" });
|
|
182
|
+
// Text alignment
|
|
183
|
+
expect(parseTypography("text-center")).toEqual({ textAlign: "center" });
|
|
184
|
+
// Text decoration
|
|
185
|
+
expect(parseTypography("underline")).toEqual({
|
|
186
|
+
textDecorationLine: "underline",
|
|
187
|
+
});
|
|
188
|
+
// Text transform
|
|
189
|
+
expect(parseTypography("uppercase")).toEqual({
|
|
190
|
+
textTransform: "uppercase",
|
|
191
|
+
});
|
|
192
|
+
// Line height
|
|
193
|
+
expect(parseTypography("leading-normal")).toEqual({ lineHeight: 24 });
|
|
194
|
+
// Letter spacing
|
|
195
|
+
expect(parseTypography("tracking-wide")).toEqual({ letterSpacing: 0.4 });
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it("should handle arbitrary values for font size and line height", () => {
|
|
199
|
+
expect(parseTypography("text-[19px]")).toEqual({ fontSize: 19 });
|
|
200
|
+
expect(parseTypography("text-[19]")).toEqual({ fontSize: 19 });
|
|
201
|
+
expect(parseTypography("leading-[26px]")).toEqual({ lineHeight: 26 });
|
|
202
|
+
expect(parseTypography("leading-[26]")).toEqual({ lineHeight: 26 });
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("should handle edge case values", () => {
|
|
206
|
+
// Smallest font size
|
|
207
|
+
expect(parseTypography("text-xs")).toEqual({ fontSize: 12 });
|
|
208
|
+
// Largest font size
|
|
209
|
+
expect(parseTypography("text-9xl")).toEqual({ fontSize: 128 });
|
|
210
|
+
// Smallest line height
|
|
211
|
+
expect(parseTypography("leading-none")).toEqual({ lineHeight: 16 });
|
|
212
|
+
// Largest line height
|
|
213
|
+
expect(parseTypography("leading-loose")).toEqual({ lineHeight: 32 });
|
|
214
|
+
// Negative letter spacing
|
|
215
|
+
expect(parseTypography("tracking-tighter")).toEqual({
|
|
216
|
+
letterSpacing: -0.8,
|
|
217
|
+
});
|
|
218
|
+
// Positive letter spacing
|
|
219
|
+
expect(parseTypography("tracking-widest")).toEqual({ letterSpacing: 1.6 });
|
|
220
|
+
});
|
|
221
|
+
});
|