@mgcrea/react-native-tailwind 0.2.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 +576 -0
- package/dist/babel/config-loader.d.ts +25 -0
- package/dist/babel/config-loader.ts +134 -0
- package/dist/babel/index.cjs +1111 -0
- package/dist/babel/index.d.ts +16 -0
- package/dist/babel/index.ts +286 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +1 -0
- package/dist/parser/borders.d.ts +10 -0
- package/dist/parser/borders.js +1 -0
- package/dist/parser/colors.d.ts +9 -0
- package/dist/parser/colors.js +1 -0
- package/dist/parser/index.d.ts +25 -0
- package/dist/parser/index.js +1 -0
- package/dist/parser/layout.d.ts +8 -0
- package/dist/parser/layout.js +1 -0
- package/dist/parser/sizing.d.ts +10 -0
- package/dist/parser/sizing.js +1 -0
- package/dist/parser/spacing.d.ts +10 -0
- package/dist/parser/spacing.js +1 -0
- package/dist/parser/typography.d.ts +9 -0
- package/dist/parser/typography.js +1 -0
- package/dist/react-native.d.js +1 -0
- package/dist/react-native.d.ts +138 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.js +1 -0
- package/dist/utils/styleKey.d.ts +9 -0
- package/dist/utils/styleKey.js +1 -0
- package/package.json +83 -0
- package/src/babel/config-loader.ts +134 -0
- package/src/babel/index.ts +286 -0
- package/src/index.ts +20 -0
- package/src/parser/borders.ts +198 -0
- package/src/parser/colors.ts +160 -0
- package/src/parser/index.ts +71 -0
- package/src/parser/layout.ts +114 -0
- package/src/parser/sizing.ts +239 -0
- package/src/parser/spacing.ts +222 -0
- package/src/parser/typography.ts +156 -0
- package/src/react-native.d.ts +138 -0
- package/src/types.ts +15 -0
- package/src/utils/styleKey.ts +23 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Border utilities (border width, radius, style)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { StyleObject } from "../types";
|
|
6
|
+
|
|
7
|
+
// Border width scale
|
|
8
|
+
export const BORDER_WIDTH_SCALE: Record<string, number> = {
|
|
9
|
+
"": 1,
|
|
10
|
+
"0": 0,
|
|
11
|
+
"2": 2,
|
|
12
|
+
"4": 4,
|
|
13
|
+
"8": 8,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// Border radius scale
|
|
17
|
+
export const BORDER_RADIUS_SCALE: Record<string, number> = {
|
|
18
|
+
none: 0,
|
|
19
|
+
sm: 2,
|
|
20
|
+
"": 4,
|
|
21
|
+
md: 6,
|
|
22
|
+
lg: 8,
|
|
23
|
+
xl: 12,
|
|
24
|
+
"2xl": 16,
|
|
25
|
+
"3xl": 24,
|
|
26
|
+
full: 9999,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Parse border classes
|
|
31
|
+
*/
|
|
32
|
+
export function parseBorder(cls: string): StyleObject | null {
|
|
33
|
+
// Border width (border-0, border-t, border-[8px], etc.)
|
|
34
|
+
if (cls.startsWith("border-")) {
|
|
35
|
+
return parseBorderWidth(cls);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (cls === "border") {
|
|
39
|
+
return { borderWidth: 1 };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Border radius (rounded, rounded-t, rounded-[12px], etc.)
|
|
43
|
+
if (cls.startsWith("rounded")) {
|
|
44
|
+
return parseBorderRadius(cls);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Border style
|
|
48
|
+
if (cls === "border-solid") return { borderStyle: "solid" };
|
|
49
|
+
if (cls === "border-dotted") return { borderStyle: "dotted" };
|
|
50
|
+
if (cls === "border-dashed") return { borderStyle: "dashed" };
|
|
51
|
+
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Parse border width classes
|
|
57
|
+
*/
|
|
58
|
+
function parseBorderWidth(cls: string): StyleObject | null {
|
|
59
|
+
// All borders with arbitrary values: border-[8px]
|
|
60
|
+
const allArbMatch = cls.match(/^border-\[(\d+)(?:px)?\]$/);
|
|
61
|
+
if (allArbMatch) {
|
|
62
|
+
return { borderWidth: parseInt(allArbMatch[1], 10) };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Directional borders with arbitrary values: border-t-[8px]
|
|
66
|
+
const dirArbMatch = cls.match(/^border-([trbl])-\[(\d+)(?:px)?\]$/);
|
|
67
|
+
if (dirArbMatch) {
|
|
68
|
+
const dir = dirArbMatch[1];
|
|
69
|
+
const value = parseInt(dirArbMatch[2], 10);
|
|
70
|
+
const propMap: Record<string, string> = {
|
|
71
|
+
t: "borderTopWidth",
|
|
72
|
+
r: "borderRightWidth",
|
|
73
|
+
b: "borderBottomWidth",
|
|
74
|
+
l: "borderLeftWidth",
|
|
75
|
+
};
|
|
76
|
+
return { [propMap[dir]]: value };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Preset directional borders: border-t-0, border-t-2, etc.
|
|
80
|
+
const dirMatch = cls.match(/^border-([trbl])-?(\d*)$/);
|
|
81
|
+
if (dirMatch) {
|
|
82
|
+
const dir = dirMatch[1];
|
|
83
|
+
const scaleKey = dirMatch[2] || ""; // empty string for border-t
|
|
84
|
+
const value = BORDER_WIDTH_SCALE[scaleKey];
|
|
85
|
+
|
|
86
|
+
if (typeof value === "number") {
|
|
87
|
+
const propMap: Record<string, string> = {
|
|
88
|
+
t: "borderTopWidth",
|
|
89
|
+
r: "borderRightWidth",
|
|
90
|
+
b: "borderBottomWidth",
|
|
91
|
+
l: "borderLeftWidth",
|
|
92
|
+
};
|
|
93
|
+
return { [propMap[dir]]: value };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Preset all borders: border-0, border-2, etc.
|
|
98
|
+
const allMatch = cls.match(/^border-(\d+)$/);
|
|
99
|
+
if (allMatch) {
|
|
100
|
+
const value = BORDER_WIDTH_SCALE[allMatch[1]];
|
|
101
|
+
if (value !== undefined) {
|
|
102
|
+
return { borderWidth: value };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Parse border radius classes
|
|
111
|
+
*/
|
|
112
|
+
function parseBorderRadius(cls: string): StyleObject | null {
|
|
113
|
+
// All corners with arbitrary values: rounded-[12px]
|
|
114
|
+
const allArbMatch = cls.match(/^rounded-\[(\d+)(?:px)?\]$/);
|
|
115
|
+
if (allArbMatch) {
|
|
116
|
+
return { borderRadius: parseInt(allArbMatch[1], 10) };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Specific corners with arbitrary values: rounded-tl-[8px]
|
|
120
|
+
const cornerArbMatch = cls.match(/^rounded-(tl|tr|bl|br)-\[(\d+)(?:px)?\]$/);
|
|
121
|
+
if (cornerArbMatch) {
|
|
122
|
+
const corner = cornerArbMatch[1];
|
|
123
|
+
const value = parseInt(cornerArbMatch[2], 10);
|
|
124
|
+
const propMap: Record<string, string> = {
|
|
125
|
+
tl: "borderTopLeftRadius",
|
|
126
|
+
tr: "borderTopRightRadius",
|
|
127
|
+
bl: "borderBottomLeftRadius",
|
|
128
|
+
br: "borderBottomRightRadius",
|
|
129
|
+
};
|
|
130
|
+
return { [propMap[corner]]: value };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Sides with arbitrary values: rounded-t-[8px]
|
|
134
|
+
const sideArbMatch = cls.match(/^rounded-([trbl])-\[(\d+)(?:px)?\]$/);
|
|
135
|
+
if (sideArbMatch) {
|
|
136
|
+
const side = sideArbMatch[1];
|
|
137
|
+
const value = parseInt(sideArbMatch[2], 10);
|
|
138
|
+
const propMap: Record<string, string[]> = {
|
|
139
|
+
t: ["borderTopLeftRadius", "borderTopRightRadius"],
|
|
140
|
+
r: ["borderTopRightRadius", "borderBottomRightRadius"],
|
|
141
|
+
b: ["borderBottomLeftRadius", "borderBottomRightRadius"],
|
|
142
|
+
l: ["borderTopLeftRadius", "borderBottomLeftRadius"],
|
|
143
|
+
};
|
|
144
|
+
const result: StyleObject = {};
|
|
145
|
+
propMap[side].forEach((prop) => (result[prop] = value));
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// All corners with preset values: rounded, rounded-lg, etc.
|
|
150
|
+
const allMatch = cls.match(/^rounded(-\w+)?$/);
|
|
151
|
+
if (allMatch) {
|
|
152
|
+
const scaleKey = allMatch[1] ? allMatch[1].substring(1) : ""; // remove leading dash
|
|
153
|
+
const value = BORDER_RADIUS_SCALE[scaleKey];
|
|
154
|
+
if (value !== undefined) {
|
|
155
|
+
return { borderRadius: value };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Sides with preset values: rounded-t, rounded-t-lg, etc.
|
|
160
|
+
const sideMatch = cls.match(/^rounded-([trbl])(?:-(\w+))?$/);
|
|
161
|
+
if (sideMatch) {
|
|
162
|
+
const side = sideMatch[1];
|
|
163
|
+
const scaleKey = sideMatch[2] || ""; // empty string for rounded-t
|
|
164
|
+
const value = BORDER_RADIUS_SCALE[scaleKey];
|
|
165
|
+
|
|
166
|
+
if (value !== undefined) {
|
|
167
|
+
const propMap: Record<string, string[]> = {
|
|
168
|
+
t: ["borderTopLeftRadius", "borderTopRightRadius"],
|
|
169
|
+
r: ["borderTopRightRadius", "borderBottomRightRadius"],
|
|
170
|
+
b: ["borderBottomLeftRadius", "borderBottomRightRadius"],
|
|
171
|
+
l: ["borderTopLeftRadius", "borderBottomLeftRadius"],
|
|
172
|
+
};
|
|
173
|
+
const result: StyleObject = {};
|
|
174
|
+
propMap[side].forEach((prop) => (result[prop] = value));
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Specific corners with preset values: rounded-tl, rounded-tl-lg, etc.
|
|
180
|
+
const cornerMatch = cls.match(/^rounded-(tl|tr|bl|br)(?:-(\w+))?$/);
|
|
181
|
+
if (cornerMatch) {
|
|
182
|
+
const corner = cornerMatch[1];
|
|
183
|
+
const scaleKey = cornerMatch[2] || "";
|
|
184
|
+
const value = BORDER_RADIUS_SCALE[scaleKey];
|
|
185
|
+
|
|
186
|
+
if (value !== undefined) {
|
|
187
|
+
const propMap: Record<string, string> = {
|
|
188
|
+
tl: "borderTopLeftRadius",
|
|
189
|
+
tr: "borderTopRightRadius",
|
|
190
|
+
bl: "borderBottomLeftRadius",
|
|
191
|
+
br: "borderBottomRightRadius",
|
|
192
|
+
};
|
|
193
|
+
return { [propMap[corner]]: value };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Color utilities (background, text, border colors)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { StyleObject } from "../types";
|
|
6
|
+
|
|
7
|
+
// Tailwind color palette
|
|
8
|
+
export const COLORS: Record<string, string> = {
|
|
9
|
+
// Gray
|
|
10
|
+
"gray-50": "#F9FAFB",
|
|
11
|
+
"gray-100": "#F3F4F6",
|
|
12
|
+
"gray-200": "#E5E7EB",
|
|
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",
|
|
80
|
+
|
|
81
|
+
// Pink
|
|
82
|
+
"pink-50": "#FDF2F8",
|
|
83
|
+
"pink-100": "#FCE7F3",
|
|
84
|
+
"pink-200": "#FBCFE8",
|
|
85
|
+
"pink-300": "#F9A8D4",
|
|
86
|
+
"pink-400": "#F472B6",
|
|
87
|
+
"pink-500": "#EC4899",
|
|
88
|
+
"pink-600": "#DB2777",
|
|
89
|
+
"pink-700": "#BE185D",
|
|
90
|
+
"pink-800": "#9D174D",
|
|
91
|
+
"pink-900": "#831843",
|
|
92
|
+
|
|
93
|
+
// Orange
|
|
94
|
+
"orange-50": "#FFF7ED",
|
|
95
|
+
"orange-100": "#FFEDD5",
|
|
96
|
+
"orange-200": "#FED7AA",
|
|
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",
|
|
104
|
+
|
|
105
|
+
// Indigo
|
|
106
|
+
"indigo-50": "#EEF2FF",
|
|
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",
|
|
116
|
+
|
|
117
|
+
// Basic colors
|
|
118
|
+
white: "#FFFFFF",
|
|
119
|
+
black: "#000000",
|
|
120
|
+
transparent: "transparent",
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Parse color classes (background, text, border)
|
|
125
|
+
*/
|
|
126
|
+
export function parseColor(cls: string, customColors?: Record<string, string>): StyleObject | null {
|
|
127
|
+
// Helper to get color with custom override (custom colors take precedence)
|
|
128
|
+
const getColor = (key: string): string | undefined => {
|
|
129
|
+
return customColors?.[key] ?? COLORS[key];
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// Background color: bg-blue-500
|
|
133
|
+
if (cls.startsWith("bg-")) {
|
|
134
|
+
const colorKey = cls.substring(3);
|
|
135
|
+
const color = getColor(colorKey);
|
|
136
|
+
if (color) {
|
|
137
|
+
return { backgroundColor: color };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Text color: text-blue-500
|
|
142
|
+
if (cls.startsWith("text-")) {
|
|
143
|
+
const colorKey = cls.substring(5);
|
|
144
|
+
const color = getColor(colorKey);
|
|
145
|
+
if (color) {
|
|
146
|
+
return { color: color };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Border color: border-blue-500
|
|
151
|
+
if (cls.startsWith("border-") && !cls.match(/^border-[0-9]/)) {
|
|
152
|
+
const colorKey = cls.substring(7);
|
|
153
|
+
const color = getColor(colorKey);
|
|
154
|
+
if (color) {
|
|
155
|
+
return { borderColor: color };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tailwind class parser for React Native
|
|
3
|
+
* Converts Tailwind-like class names to React Native style objects
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { StyleObject } from "../types";
|
|
7
|
+
import { parseBorder } from "./borders";
|
|
8
|
+
import { parseColor } from "./colors";
|
|
9
|
+
import { parseLayout } from "./layout";
|
|
10
|
+
import { parseSizing } from "./sizing";
|
|
11
|
+
import { parseSpacing } from "./spacing";
|
|
12
|
+
import { parseTypography } from "./typography";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Parse a className string and return a React Native style object
|
|
16
|
+
* @param className - Space-separated class names
|
|
17
|
+
* @param customColors - Optional custom colors from tailwind.config
|
|
18
|
+
* @returns React Native style object
|
|
19
|
+
*/
|
|
20
|
+
export function parseClassName(className: string, customColors?: Record<string, string>): StyleObject {
|
|
21
|
+
const classes = className.split(/\s+/).filter(Boolean);
|
|
22
|
+
const style: StyleObject = {};
|
|
23
|
+
|
|
24
|
+
for (const cls of classes) {
|
|
25
|
+
const parsedStyle = parseClass(cls, customColors);
|
|
26
|
+
Object.assign(style, parsedStyle);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return style;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parse a single class name
|
|
34
|
+
* @param cls - Single class name
|
|
35
|
+
* @param customColors - Optional custom colors from tailwind.config
|
|
36
|
+
* @returns React Native style object
|
|
37
|
+
*/
|
|
38
|
+
export function parseClass(cls: string, customColors?: Record<string, string>): StyleObject {
|
|
39
|
+
// Try each parser in order
|
|
40
|
+
// parseColor gets custom colors, others don't need it
|
|
41
|
+
const parsers: Array<(cls: string) => StyleObject | null> = [
|
|
42
|
+
parseSpacing,
|
|
43
|
+
(cls: string) => parseColor(cls, customColors),
|
|
44
|
+
parseLayout,
|
|
45
|
+
parseTypography,
|
|
46
|
+
parseBorder,
|
|
47
|
+
parseSizing,
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
for (const parser of parsers) {
|
|
51
|
+
const result = parser(cls);
|
|
52
|
+
if (result !== null) {
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Warn about unknown class in development
|
|
58
|
+
if (process.env.NODE_ENV !== "production") {
|
|
59
|
+
console.warn(`[react-native-tailwind] Unknown class: "${cls}"`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Re-export parsers for testing/advanced usage
|
|
66
|
+
export { parseBorder } from "./borders";
|
|
67
|
+
export { parseColor } from "./colors";
|
|
68
|
+
export { parseLayout } from "./layout";
|
|
69
|
+
export { parseSizing } from "./sizing";
|
|
70
|
+
export { parseSpacing } from "./spacing";
|
|
71
|
+
export { parseTypography } from "./typography";
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout utilities (flexbox, positioning, display)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { StyleObject } from "../types";
|
|
6
|
+
|
|
7
|
+
// Display utilities
|
|
8
|
+
const DISPLAY_MAP: Record<string, StyleObject> = {
|
|
9
|
+
flex: { display: "flex" },
|
|
10
|
+
hidden: { display: "none" },
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// Flex direction utilities
|
|
14
|
+
const FLEX_DIRECTION_MAP: Record<string, StyleObject> = {
|
|
15
|
+
"flex-row": { flexDirection: "row" },
|
|
16
|
+
"flex-row-reverse": { flexDirection: "row-reverse" },
|
|
17
|
+
"flex-col": { flexDirection: "column" },
|
|
18
|
+
"flex-col-reverse": { flexDirection: "column-reverse" },
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Flex wrap utilities
|
|
22
|
+
const FLEX_WRAP_MAP: Record<string, StyleObject> = {
|
|
23
|
+
"flex-wrap": { flexWrap: "wrap" },
|
|
24
|
+
"flex-wrap-reverse": { flexWrap: "wrap-reverse" },
|
|
25
|
+
"flex-nowrap": { flexWrap: "nowrap" },
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Flex utilities
|
|
29
|
+
const FLEX_MAP: Record<string, StyleObject> = {
|
|
30
|
+
"flex-1": { flex: 1 },
|
|
31
|
+
"flex-auto": { flex: 1 },
|
|
32
|
+
"flex-none": { flex: 0 },
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Flex grow/shrink utilities
|
|
36
|
+
const GROW_SHRINK_MAP: Record<string, StyleObject> = {
|
|
37
|
+
grow: { flexGrow: 1 },
|
|
38
|
+
"grow-0": { flexGrow: 0 },
|
|
39
|
+
shrink: { flexShrink: 1 },
|
|
40
|
+
"shrink-0": { flexShrink: 0 },
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Justify content utilities
|
|
44
|
+
const JUSTIFY_CONTENT_MAP: Record<string, StyleObject> = {
|
|
45
|
+
"justify-start": { justifyContent: "flex-start" },
|
|
46
|
+
"justify-end": { justifyContent: "flex-end" },
|
|
47
|
+
"justify-center": { justifyContent: "center" },
|
|
48
|
+
"justify-between": { justifyContent: "space-between" },
|
|
49
|
+
"justify-around": { justifyContent: "space-around" },
|
|
50
|
+
"justify-evenly": { justifyContent: "space-evenly" },
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Align items utilities
|
|
54
|
+
const ALIGN_ITEMS_MAP: Record<string, StyleObject> = {
|
|
55
|
+
"items-start": { alignItems: "flex-start" },
|
|
56
|
+
"items-end": { alignItems: "flex-end" },
|
|
57
|
+
"items-center": { alignItems: "center" },
|
|
58
|
+
"items-baseline": { alignItems: "baseline" },
|
|
59
|
+
"items-stretch": { alignItems: "stretch" },
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// Align self utilities
|
|
63
|
+
const ALIGN_SELF_MAP: Record<string, StyleObject> = {
|
|
64
|
+
"self-auto": { alignSelf: "auto" },
|
|
65
|
+
"self-start": { alignSelf: "flex-start" },
|
|
66
|
+
"self-end": { alignSelf: "flex-end" },
|
|
67
|
+
"self-center": { alignSelf: "center" },
|
|
68
|
+
"self-stretch": { alignSelf: "stretch" },
|
|
69
|
+
"self-baseline": { alignSelf: "baseline" },
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// Align content utilities
|
|
73
|
+
const ALIGN_CONTENT_MAP: Record<string, StyleObject> = {
|
|
74
|
+
"content-start": { alignContent: "flex-start" },
|
|
75
|
+
"content-end": { alignContent: "flex-end" },
|
|
76
|
+
"content-center": { alignContent: "center" },
|
|
77
|
+
"content-between": { alignContent: "space-between" },
|
|
78
|
+
"content-around": { alignContent: "space-around" },
|
|
79
|
+
"content-stretch": { alignContent: "stretch" },
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// Position utilities
|
|
83
|
+
const POSITION_MAP: Record<string, StyleObject> = {
|
|
84
|
+
absolute: { position: "absolute" },
|
|
85
|
+
relative: { position: "relative" },
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// Overflow utilities
|
|
89
|
+
const OVERFLOW_MAP: Record<string, StyleObject> = {
|
|
90
|
+
"overflow-hidden": { overflow: "hidden" },
|
|
91
|
+
"overflow-visible": { overflow: "visible" },
|
|
92
|
+
"overflow-scroll": { overflow: "scroll" },
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Parse layout classes
|
|
97
|
+
*/
|
|
98
|
+
export function parseLayout(cls: string): StyleObject | null {
|
|
99
|
+
// Try each lookup table in order
|
|
100
|
+
return (
|
|
101
|
+
DISPLAY_MAP[cls] ??
|
|
102
|
+
FLEX_DIRECTION_MAP[cls] ??
|
|
103
|
+
FLEX_WRAP_MAP[cls] ??
|
|
104
|
+
FLEX_MAP[cls] ??
|
|
105
|
+
GROW_SHRINK_MAP[cls] ??
|
|
106
|
+
JUSTIFY_CONTENT_MAP[cls] ??
|
|
107
|
+
ALIGN_ITEMS_MAP[cls] ??
|
|
108
|
+
ALIGN_SELF_MAP[cls] ??
|
|
109
|
+
ALIGN_CONTENT_MAP[cls] ??
|
|
110
|
+
POSITION_MAP[cls] ??
|
|
111
|
+
OVERFLOW_MAP[cls] ??
|
|
112
|
+
null
|
|
113
|
+
);
|
|
114
|
+
}
|