@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.
Files changed (42) hide show
  1. package/README.md +576 -0
  2. package/dist/babel/config-loader.d.ts +25 -0
  3. package/dist/babel/config-loader.ts +134 -0
  4. package/dist/babel/index.cjs +1111 -0
  5. package/dist/babel/index.d.ts +16 -0
  6. package/dist/babel/index.ts +286 -0
  7. package/dist/index.d.ts +12 -0
  8. package/dist/index.js +1 -0
  9. package/dist/parser/borders.d.ts +10 -0
  10. package/dist/parser/borders.js +1 -0
  11. package/dist/parser/colors.d.ts +9 -0
  12. package/dist/parser/colors.js +1 -0
  13. package/dist/parser/index.d.ts +25 -0
  14. package/dist/parser/index.js +1 -0
  15. package/dist/parser/layout.d.ts +8 -0
  16. package/dist/parser/layout.js +1 -0
  17. package/dist/parser/sizing.d.ts +10 -0
  18. package/dist/parser/sizing.js +1 -0
  19. package/dist/parser/spacing.d.ts +10 -0
  20. package/dist/parser/spacing.js +1 -0
  21. package/dist/parser/typography.d.ts +9 -0
  22. package/dist/parser/typography.js +1 -0
  23. package/dist/react-native.d.js +1 -0
  24. package/dist/react-native.d.ts +138 -0
  25. package/dist/types.d.ts +11 -0
  26. package/dist/types.js +1 -0
  27. package/dist/utils/styleKey.d.ts +9 -0
  28. package/dist/utils/styleKey.js +1 -0
  29. package/package.json +83 -0
  30. package/src/babel/config-loader.ts +134 -0
  31. package/src/babel/index.ts +286 -0
  32. package/src/index.ts +20 -0
  33. package/src/parser/borders.ts +198 -0
  34. package/src/parser/colors.ts +160 -0
  35. package/src/parser/index.ts +71 -0
  36. package/src/parser/layout.ts +114 -0
  37. package/src/parser/sizing.ts +239 -0
  38. package/src/parser/spacing.ts +222 -0
  39. package/src/parser/typography.ts +156 -0
  40. package/src/react-native.d.ts +138 -0
  41. package/src/types.ts +15 -0
  42. package/src/utils/styleKey.ts +23 -0
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Babel plugin for react-native-tailwind
3
+ * Transforms className props to style props at compile time
4
+ */
5
+ import type { PluginObj, PluginPass } from "@babel/core";
6
+ import * as BabelTypes from "@babel/types";
7
+ type PluginState = PluginPass & {
8
+ styleRegistry: Map<string, Record<string, string | number>>;
9
+ hasClassNames: boolean;
10
+ hasStyleSheetImport: boolean;
11
+ customColors: Record<string, string>;
12
+ };
13
+ export default function reactNativeTailwindBabelPlugin({ types: t, }: {
14
+ types: typeof BabelTypes;
15
+ }): PluginObj<PluginState>;
16
+ export {};
@@ -0,0 +1,286 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
3
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
4
+ /* eslint-disable @typescript-eslint/no-explicit-any */
5
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
6
+
7
+ /**
8
+ * Babel plugin for react-native-tailwind
9
+ * Transforms className props to style props at compile time
10
+ */
11
+
12
+ import type { NodePath, PluginObj, PluginPass } from "@babel/core";
13
+ import * as BabelTypes from "@babel/types";
14
+ import { parseClassName as parseClassNameFn } from "../parser/index.js";
15
+ import { generateStyleKey as generateStyleKeyFn } from "../utils/styleKey.js";
16
+ import { extractCustomColors } from "./config-loader.js";
17
+
18
+ type PluginState = PluginPass & {
19
+ styleRegistry: Map<string, Record<string, string | number>>;
20
+ hasClassNames: boolean;
21
+ hasStyleSheetImport: boolean;
22
+ customColors: Record<string, string>;
23
+ };
24
+
25
+ /**
26
+ * Supported className-like attributes
27
+ */
28
+ const SUPPORTED_CLASS_ATTRIBUTES = [
29
+ "className",
30
+ "contentContainerClassName",
31
+ "columnWrapperClassName",
32
+ "ListHeaderComponentClassName",
33
+ "ListFooterComponentClassName",
34
+ ] as const;
35
+
36
+ /**
37
+ * Get the target style prop name based on the className attribute
38
+ */
39
+ function getTargetStyleProp(attributeName: string): string {
40
+ if (attributeName === "contentContainerClassName") {
41
+ return "contentContainerStyle";
42
+ }
43
+ if (attributeName === "columnWrapperClassName") {
44
+ return "columnWrapperStyle";
45
+ }
46
+ if (attributeName === "ListHeaderComponentClassName") {
47
+ return "ListHeaderComponentStyle";
48
+ }
49
+ if (attributeName === "ListFooterComponentClassName") {
50
+ return "ListFooterComponentStyle";
51
+ }
52
+ return "style";
53
+ }
54
+
55
+ export default function reactNativeTailwindBabelPlugin({
56
+ types: t,
57
+ }: {
58
+ types: typeof BabelTypes;
59
+ }): PluginObj<PluginState> {
60
+ return {
61
+ name: "react-native-tailwind",
62
+
63
+ visitor: {
64
+ Program: {
65
+ enter(_path: NodePath, state: PluginState) {
66
+ // Initialize state for this file
67
+ state.styleRegistry = new Map();
68
+ state.hasClassNames = false;
69
+ state.hasStyleSheetImport = false;
70
+
71
+ // Load custom colors from tailwind.config.*
72
+ state.customColors = extractCustomColors(state.file.opts.filename ?? "");
73
+ },
74
+
75
+ exit(path: NodePath, state: PluginState) {
76
+ // If no classNames were found, skip StyleSheet generation
77
+ if (!state.hasClassNames || state.styleRegistry.size === 0) {
78
+ return;
79
+ }
80
+
81
+ // Add StyleSheet import if not already present
82
+ if (!state.hasStyleSheetImport) {
83
+ addStyleSheetImport(path, t);
84
+ }
85
+
86
+ // Generate and inject StyleSheet.create at the end of the file
87
+ injectStyles(path, state.styleRegistry, t);
88
+ },
89
+ },
90
+
91
+ // Check if StyleSheet is already imported
92
+ ImportDeclaration(path: NodePath, state: PluginState) {
93
+ const node = path.node as any;
94
+ if (node.source.value === "react-native") {
95
+ const specifiers = node.specifiers;
96
+ const hasStyleSheet = specifiers.some((spec: any) => {
97
+ if (t.isImportSpecifier(spec) && t.isIdentifier(spec.imported)) {
98
+ return spec.imported.name === "StyleSheet";
99
+ }
100
+ return false;
101
+ });
102
+
103
+ if (hasStyleSheet) {
104
+ state.hasStyleSheetImport = true;
105
+ } else {
106
+ // Add StyleSheet to existing import
107
+ node.specifiers.push(t.importSpecifier(t.identifier("StyleSheet"), t.identifier("StyleSheet")));
108
+ state.hasStyleSheetImport = true;
109
+ }
110
+ }
111
+ },
112
+
113
+ JSXAttribute(path: NodePath, state: PluginState) {
114
+ const node = path.node as any;
115
+ const attributeName = node.name.name;
116
+
117
+ // Only process className-like attributes
118
+ if (!SUPPORTED_CLASS_ATTRIBUTES.includes(attributeName)) {
119
+ return;
120
+ }
121
+
122
+ const value = node.value;
123
+
124
+ // Only handle static string literals
125
+ if (!t.isStringLiteral(value)) {
126
+ // Warn about dynamic className in development
127
+ if (process.env.NODE_ENV !== "production") {
128
+ const filename = state.file.opts.filename ?? "unknown";
129
+ const targetStyleProp = getTargetStyleProp(attributeName);
130
+ console.warn(
131
+ `[react-native-tailwind] Dynamic ${attributeName} values are not supported at ${filename}. ` +
132
+ `Use the ${targetStyleProp} prop for dynamic values.`,
133
+ );
134
+ }
135
+ return;
136
+ }
137
+
138
+ const className = value.value.trim();
139
+
140
+ // Skip empty classNames
141
+ if (!className) {
142
+ path.remove();
143
+ return;
144
+ }
145
+
146
+ state.hasClassNames = true;
147
+
148
+ // Parse className to React Native styles
149
+ const styleObject = parseClassName(className, state.customColors);
150
+
151
+ // Generate unique style key
152
+ const styleKey = generateStyleKey(className);
153
+
154
+ // Store in registry
155
+ state.styleRegistry.set(styleKey, styleObject);
156
+
157
+ // Determine target style prop based on attribute name
158
+ const targetStyleProp = getTargetStyleProp(attributeName);
159
+
160
+ // Check if there's already a style prop on this element
161
+ const parent = path.parent as any;
162
+ const styleAttribute = parent.attributes.find(
163
+ (attr: any) => t.isJSXAttribute(attr) && attr.name.name === targetStyleProp,
164
+ );
165
+
166
+ if (styleAttribute) {
167
+ // Merge with existing style prop
168
+ mergeStyleAttribute(path, styleAttribute, styleKey, t);
169
+ } else {
170
+ // Replace className with style prop
171
+ replaceWithStyleAttribute(path, styleKey, targetStyleProp, t);
172
+ }
173
+ },
174
+ },
175
+ };
176
+ }
177
+
178
+ /**
179
+ * Add StyleSheet import to the file
180
+ */
181
+ function addStyleSheetImport(path: NodePath, t: typeof BabelTypes) {
182
+ const importDeclaration = t.importDeclaration(
183
+ [t.importSpecifier(t.identifier("StyleSheet"), t.identifier("StyleSheet"))],
184
+ t.stringLiteral("react-native"),
185
+ );
186
+
187
+ // Add import at the top of the file
188
+ (path as any).unshiftContainer("body", importDeclaration);
189
+ }
190
+
191
+ /**
192
+ * Replace className with style attribute
193
+ */
194
+ function replaceWithStyleAttribute(
195
+ classNamePath: NodePath,
196
+ styleKey: string,
197
+ targetStyleProp: string,
198
+ t: typeof BabelTypes,
199
+ ) {
200
+ const styleAttribute = t.jsxAttribute(
201
+ t.jsxIdentifier(targetStyleProp),
202
+ t.jsxExpressionContainer(t.memberExpression(t.identifier("styles"), t.identifier(styleKey))),
203
+ );
204
+
205
+ classNamePath.replaceWith(styleAttribute);
206
+ }
207
+
208
+ /**
209
+ * Merge className styles with existing style prop
210
+ */
211
+ function mergeStyleAttribute(
212
+ classNamePath: NodePath,
213
+ styleAttribute: any,
214
+ styleKey: string,
215
+ t: typeof BabelTypes,
216
+ ) {
217
+ const existingStyle = styleAttribute.value.expression;
218
+
219
+ // Create array with className styles first, then existing styles
220
+ // This allows existing styles to override className styles
221
+ const styleArray = t.arrayExpression([
222
+ t.memberExpression(t.identifier("styles"), t.identifier(styleKey)),
223
+ existingStyle,
224
+ ]);
225
+
226
+ styleAttribute.value = t.jsxExpressionContainer(styleArray);
227
+
228
+ // Remove the className attribute
229
+ classNamePath.remove();
230
+ }
231
+
232
+ /**
233
+ * Inject StyleSheet.create with all collected styles
234
+ */
235
+ function injectStyles(
236
+ path: NodePath,
237
+ styleRegistry: Map<string, Record<string, string | number>>,
238
+ t: typeof BabelTypes,
239
+ ) {
240
+ // Build style object properties
241
+ const styleProperties: any[] = [];
242
+
243
+ for (const [key, styleObject] of styleRegistry) {
244
+ const properties = Object.entries(styleObject).map(([styleProp, styleValue]) => {
245
+ let valueNode;
246
+
247
+ if (typeof styleValue === "number") {
248
+ valueNode = t.numericLiteral(styleValue);
249
+ } else if (typeof styleValue === "string") {
250
+ valueNode = t.stringLiteral(styleValue);
251
+ } else {
252
+ // Fallback for other types
253
+ valueNode = t.valueToNode(styleValue);
254
+ }
255
+
256
+ return t.objectProperty(t.identifier(styleProp), valueNode);
257
+ });
258
+
259
+ styleProperties.push(t.objectProperty(t.identifier(key), t.objectExpression(properties)));
260
+ }
261
+
262
+ // Create: const styles = StyleSheet.create({ ... })
263
+ const styleSheet = t.variableDeclaration("const", [
264
+ t.variableDeclarator(
265
+ t.identifier("styles"),
266
+ t.callExpression(t.memberExpression(t.identifier("StyleSheet"), t.identifier("create")), [
267
+ t.objectExpression(styleProperties),
268
+ ]),
269
+ ),
270
+ ]);
271
+
272
+ // Add StyleSheet.create at the end of the file
273
+ (path as any).pushContainer("body", styleSheet);
274
+ }
275
+
276
+ // Helper functions that use the imported parser
277
+ function parseClassName(
278
+ className: string,
279
+ customColors: Record<string, string>,
280
+ ): Record<string, string | number> {
281
+ return parseClassNameFn(className, customColors);
282
+ }
283
+
284
+ function generateStyleKey(className: string): string {
285
+ return generateStyleKeyFn(className);
286
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @mgcrea/react-native-tailwind
3
+ * Compile-time Tailwind CSS for React Native
4
+ */
5
+ export { parseClass, parseClassName } from "./parser";
6
+ export { generateStyleKey } from "./utils/styleKey";
7
+ export type { RNStyle, StyleObject } from "./types";
8
+ export { parseBorder, parseColor, parseLayout, parseSizing, parseSpacing, parseTypography } from "./parser";
9
+ export { COLORS } from "./parser/colors";
10
+ export { SIZE_PERCENTAGES, SIZE_SCALE } from "./parser/sizing";
11
+ export { SPACING_SCALE } from "./parser/spacing";
12
+ export { FONT_SIZES } from "./parser/typography";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"COLORS",{enumerable:true,get:function get(){return _colors.COLORS;}});Object.defineProperty(exports,"FONT_SIZES",{enumerable:true,get:function get(){return _typography.FONT_SIZES;}});Object.defineProperty(exports,"SIZE_PERCENTAGES",{enumerable:true,get:function get(){return _sizing.SIZE_PERCENTAGES;}});Object.defineProperty(exports,"SIZE_SCALE",{enumerable:true,get:function get(){return _sizing.SIZE_SCALE;}});Object.defineProperty(exports,"SPACING_SCALE",{enumerable:true,get:function get(){return _spacing.SPACING_SCALE;}});Object.defineProperty(exports,"generateStyleKey",{enumerable:true,get:function get(){return _styleKey.generateStyleKey;}});Object.defineProperty(exports,"parseBorder",{enumerable:true,get:function get(){return _parser.parseBorder;}});Object.defineProperty(exports,"parseClass",{enumerable:true,get:function get(){return _parser.parseClass;}});Object.defineProperty(exports,"parseClassName",{enumerable:true,get:function get(){return _parser.parseClassName;}});Object.defineProperty(exports,"parseColor",{enumerable:true,get:function get(){return _parser.parseColor;}});Object.defineProperty(exports,"parseLayout",{enumerable:true,get:function get(){return _parser.parseLayout;}});Object.defineProperty(exports,"parseSizing",{enumerable:true,get:function get(){return _parser.parseSizing;}});Object.defineProperty(exports,"parseSpacing",{enumerable:true,get:function get(){return _parser.parseSpacing;}});Object.defineProperty(exports,"parseTypography",{enumerable:true,get:function get(){return _parser.parseTypography;}});var _parser=require("./parser");var _styleKey=require("./utils/styleKey");var _colors=require("./parser/colors");var _sizing=require("./parser/sizing");var _spacing=require("./parser/spacing");var _typography=require("./parser/typography");
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Border utilities (border width, radius, style)
3
+ */
4
+ import type { StyleObject } from "../types";
5
+ export declare const BORDER_WIDTH_SCALE: Record<string, number>;
6
+ export declare const BORDER_RADIUS_SCALE: Record<string, number>;
7
+ /**
8
+ * Parse border classes
9
+ */
10
+ export declare function parseBorder(cls: string): StyleObject | null;
@@ -0,0 +1 @@
1
+ var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.BORDER_WIDTH_SCALE=exports.BORDER_RADIUS_SCALE=void 0;exports.parseBorder=parseBorder;var _defineProperty2=_interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));var BORDER_WIDTH_SCALE=exports.BORDER_WIDTH_SCALE={"":1,"0":0,"2":2,"4":4,"8":8};var BORDER_RADIUS_SCALE=exports.BORDER_RADIUS_SCALE={none:0,sm:2,"":4,md:6,lg:8,xl:12,"2xl":16,"3xl":24,full:9999};function parseBorder(cls){if(cls.startsWith("border-")){return parseBorderWidth(cls);}if(cls==="border"){return{borderWidth:1};}if(cls.startsWith("rounded")){return parseBorderRadius(cls);}if(cls==="border-solid")return{borderStyle:"solid"};if(cls==="border-dotted")return{borderStyle:"dotted"};if(cls==="border-dashed")return{borderStyle:"dashed"};return null;}function parseBorderWidth(cls){var allArbMatch=cls.match(/^border-\[(\d+)(?:px)?\]$/);if(allArbMatch){return{borderWidth:parseInt(allArbMatch[1],10)};}var dirArbMatch=cls.match(/^border-([trbl])-\[(\d+)(?:px)?\]$/);if(dirArbMatch){var dir=dirArbMatch[1];var value=parseInt(dirArbMatch[2],10);var propMap={t:"borderTopWidth",r:"borderRightWidth",b:"borderBottomWidth",l:"borderLeftWidth"};return(0,_defineProperty2.default)({},propMap[dir],value);}var dirMatch=cls.match(/^border-([trbl])-?(\d*)$/);if(dirMatch){var _dir=dirMatch[1];var scaleKey=dirMatch[2]||"";var _value=BORDER_WIDTH_SCALE[scaleKey];if(typeof _value==="number"){var _propMap={t:"borderTopWidth",r:"borderRightWidth",b:"borderBottomWidth",l:"borderLeftWidth"};return(0,_defineProperty2.default)({},_propMap[_dir],_value);}}var allMatch=cls.match(/^border-(\d+)$/);if(allMatch){var _value2=BORDER_WIDTH_SCALE[allMatch[1]];if(_value2!==undefined){return{borderWidth:_value2};}}return null;}function parseBorderRadius(cls){var allArbMatch=cls.match(/^rounded-\[(\d+)(?:px)?\]$/);if(allArbMatch){return{borderRadius:parseInt(allArbMatch[1],10)};}var cornerArbMatch=cls.match(/^rounded-(tl|tr|bl|br)-\[(\d+)(?:px)?\]$/);if(cornerArbMatch){var corner=cornerArbMatch[1];var value=parseInt(cornerArbMatch[2],10);var propMap={tl:"borderTopLeftRadius",tr:"borderTopRightRadius",bl:"borderBottomLeftRadius",br:"borderBottomRightRadius"};return(0,_defineProperty2.default)({},propMap[corner],value);}var sideArbMatch=cls.match(/^rounded-([trbl])-\[(\d+)(?:px)?\]$/);if(sideArbMatch){var side=sideArbMatch[1];var _value3=parseInt(sideArbMatch[2],10);var _propMap2={t:["borderTopLeftRadius","borderTopRightRadius"],r:["borderTopRightRadius","borderBottomRightRadius"],b:["borderBottomLeftRadius","borderBottomRightRadius"],l:["borderTopLeftRadius","borderBottomLeftRadius"]};var result={};_propMap2[side].forEach(function(prop){return result[prop]=_value3;});return result;}var allMatch=cls.match(/^rounded(-\w+)?$/);if(allMatch){var scaleKey=allMatch[1]?allMatch[1].substring(1):"";var _value4=BORDER_RADIUS_SCALE[scaleKey];if(_value4!==undefined){return{borderRadius:_value4};}}var sideMatch=cls.match(/^rounded-([trbl])(?:-(\w+))?$/);if(sideMatch){var _side=sideMatch[1];var _scaleKey=sideMatch[2]||"";var _value5=BORDER_RADIUS_SCALE[_scaleKey];if(_value5!==undefined){var _propMap3={t:["borderTopLeftRadius","borderTopRightRadius"],r:["borderTopRightRadius","borderBottomRightRadius"],b:["borderBottomLeftRadius","borderBottomRightRadius"],l:["borderTopLeftRadius","borderBottomLeftRadius"]};var _result={};_propMap3[_side].forEach(function(prop){return _result[prop]=_value5;});return _result;}}var cornerMatch=cls.match(/^rounded-(tl|tr|bl|br)(?:-(\w+))?$/);if(cornerMatch){var _corner=cornerMatch[1];var _scaleKey2=cornerMatch[2]||"";var _value6=BORDER_RADIUS_SCALE[_scaleKey2];if(_value6!==undefined){var _propMap4={tl:"borderTopLeftRadius",tr:"borderTopRightRadius",bl:"borderBottomLeftRadius",br:"borderBottomRightRadius"};return(0,_defineProperty2.default)({},_propMap4[_corner],_value6);}}return null;}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Color utilities (background, text, border colors)
3
+ */
4
+ import type { StyleObject } from "../types";
5
+ export declare const COLORS: Record<string, string>;
6
+ /**
7
+ * Parse color classes (background, text, border)
8
+ */
9
+ export declare function parseColor(cls: string, customColors?: Record<string, string>): StyleObject | null;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});exports.COLORS=void 0;exports.parseColor=parseColor;var COLORS=exports.COLORS={"gray-50":"#F9FAFB","gray-100":"#F3F4F6","gray-200":"#E5E7EB","gray-300":"#D1D5DB","gray-400":"#9CA3AF","gray-500":"#6B7280","gray-600":"#4B5563","gray-700":"#374151","gray-800":"#1F2937","gray-900":"#111827","red-50":"#FEF2F2","red-100":"#FEE2E2","red-200":"#FECACA","red-300":"#FCA5A5","red-400":"#F87171","red-500":"#EF4444","red-600":"#DC2626","red-700":"#B91C1C","red-800":"#991B1B","red-900":"#7F1D1D","blue-50":"#EFF6FF","blue-100":"#DBEAFE","blue-200":"#BFDBFE","blue-300":"#93C5FD","blue-400":"#60A5FA","blue-500":"#3B82F6","blue-600":"#2563EB","blue-700":"#1D4ED8","blue-800":"#1E40AF","blue-900":"#1E3A8A","green-50":"#F0FDF4","green-100":"#DCFCE7","green-200":"#BBF7D0","green-300":"#86EFAC","green-400":"#4ADE80","green-500":"#22C55E","green-600":"#16A34A","green-700":"#15803D","green-800":"#166534","green-900":"#14532D","yellow-50":"#FEFCE8","yellow-100":"#FEF9C3","yellow-200":"#FEF08A","yellow-300":"#FDE047","yellow-400":"#FACC15","yellow-500":"#EAB308","yellow-600":"#CA8A04","yellow-700":"#A16207","yellow-800":"#854D0E","yellow-900":"#713F12","purple-50":"#FAF5FF","purple-100":"#F3E8FF","purple-200":"#E9D5FF","purple-300":"#D8B4FE","purple-400":"#C084FC","purple-500":"#A855F7","purple-600":"#9333EA","purple-700":"#7E22CE","purple-800":"#6B21A8","purple-900":"#581C87","pink-50":"#FDF2F8","pink-100":"#FCE7F3","pink-200":"#FBCFE8","pink-300":"#F9A8D4","pink-400":"#F472B6","pink-500":"#EC4899","pink-600":"#DB2777","pink-700":"#BE185D","pink-800":"#9D174D","pink-900":"#831843","orange-50":"#FFF7ED","orange-100":"#FFEDD5","orange-200":"#FED7AA","orange-300":"#FDBA74","orange-400":"#FB923C","orange-500":"#F97316","orange-600":"#EA580C","orange-700":"#C2410C","orange-800":"#9A3412","orange-900":"#7C2D12","indigo-50":"#EEF2FF","indigo-100":"#E0E7FF","indigo-200":"#C7D2FE","indigo-300":"#A5B4FC","indigo-400":"#818CF8","indigo-500":"#6366F1","indigo-600":"#4F46E5","indigo-700":"#4338CA","indigo-800":"#3730A3","indigo-900":"#312E81",white:"#FFFFFF",black:"#000000",transparent:"transparent"};function parseColor(cls,customColors){var getColor=function getColor(key){var _customColors$key;return(_customColors$key=customColors==null?void 0:customColors[key])!=null?_customColors$key:COLORS[key];};if(cls.startsWith("bg-")){var colorKey=cls.substring(3);var color=getColor(colorKey);if(color){return{backgroundColor:color};}}if(cls.startsWith("text-")){var _colorKey=cls.substring(5);var _color=getColor(_colorKey);if(_color){return{color:_color};}}if(cls.startsWith("border-")&&!cls.match(/^border-[0-9]/)){var _colorKey2=cls.substring(7);var _color2=getColor(_colorKey2);if(_color2){return{borderColor:_color2};}}return null;}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Tailwind class parser for React Native
3
+ * Converts Tailwind-like class names to React Native style objects
4
+ */
5
+ import type { StyleObject } from "../types";
6
+ /**
7
+ * Parse a className string and return a React Native style object
8
+ * @param className - Space-separated class names
9
+ * @param customColors - Optional custom colors from tailwind.config
10
+ * @returns React Native style object
11
+ */
12
+ export declare function parseClassName(className: string, customColors?: Record<string, string>): StyleObject;
13
+ /**
14
+ * Parse a single class name
15
+ * @param cls - Single class name
16
+ * @param customColors - Optional custom colors from tailwind.config
17
+ * @returns React Native style object
18
+ */
19
+ export declare function parseClass(cls: string, customColors?: Record<string, string>): StyleObject;
20
+ export { parseBorder } from "./borders";
21
+ export { parseColor } from "./colors";
22
+ export { parseLayout } from "./layout";
23
+ export { parseSizing } from "./sizing";
24
+ export { parseSpacing } from "./spacing";
25
+ export { parseTypography } from "./typography";
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"parseBorder",{enumerable:true,get:function get(){return _borders.parseBorder;}});exports.parseClass=parseClass;exports.parseClassName=parseClassName;Object.defineProperty(exports,"parseColor",{enumerable:true,get:function get(){return _colors.parseColor;}});Object.defineProperty(exports,"parseLayout",{enumerable:true,get:function get(){return _layout.parseLayout;}});Object.defineProperty(exports,"parseSizing",{enumerable:true,get:function get(){return _sizing.parseSizing;}});Object.defineProperty(exports,"parseSpacing",{enumerable:true,get:function get(){return _spacing.parseSpacing;}});Object.defineProperty(exports,"parseTypography",{enumerable:true,get:function get(){return _typography.parseTypography;}});var _borders=require("./borders");var _colors=require("./colors");var _layout=require("./layout");var _sizing=require("./sizing");var _spacing=require("./spacing");var _typography=require("./typography");function parseClassName(className,customColors){var classes=className.split(/\s+/).filter(Boolean);var style={};for(var cls of classes){var parsedStyle=parseClass(cls,customColors);Object.assign(style,parsedStyle);}return style;}function parseClass(cls,customColors){var parsers=[_spacing.parseSpacing,function(cls){return(0,_colors.parseColor)(cls,customColors);},_layout.parseLayout,_typography.parseTypography,_borders.parseBorder,_sizing.parseSizing];for(var parser of parsers){var result=parser(cls);if(result!==null){return result;}}if(process.env.NODE_ENV!=="production"){console.warn(`[react-native-tailwind] Unknown class: "${cls}"`);}return{};}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Layout utilities (flexbox, positioning, display)
3
+ */
4
+ import type { StyleObject } from "../types";
5
+ /**
6
+ * Parse layout classes
7
+ */
8
+ export declare function parseLayout(cls: string): StyleObject | null;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});exports.parseLayout=parseLayout;var DISPLAY_MAP={flex:{display:"flex"},hidden:{display:"none"}};var FLEX_DIRECTION_MAP={"flex-row":{flexDirection:"row"},"flex-row-reverse":{flexDirection:"row-reverse"},"flex-col":{flexDirection:"column"},"flex-col-reverse":{flexDirection:"column-reverse"}};var FLEX_WRAP_MAP={"flex-wrap":{flexWrap:"wrap"},"flex-wrap-reverse":{flexWrap:"wrap-reverse"},"flex-nowrap":{flexWrap:"nowrap"}};var FLEX_MAP={"flex-1":{flex:1},"flex-auto":{flex:1},"flex-none":{flex:0}};var GROW_SHRINK_MAP={grow:{flexGrow:1},"grow-0":{flexGrow:0},shrink:{flexShrink:1},"shrink-0":{flexShrink:0}};var JUSTIFY_CONTENT_MAP={"justify-start":{justifyContent:"flex-start"},"justify-end":{justifyContent:"flex-end"},"justify-center":{justifyContent:"center"},"justify-between":{justifyContent:"space-between"},"justify-around":{justifyContent:"space-around"},"justify-evenly":{justifyContent:"space-evenly"}};var ALIGN_ITEMS_MAP={"items-start":{alignItems:"flex-start"},"items-end":{alignItems:"flex-end"},"items-center":{alignItems:"center"},"items-baseline":{alignItems:"baseline"},"items-stretch":{alignItems:"stretch"}};var ALIGN_SELF_MAP={"self-auto":{alignSelf:"auto"},"self-start":{alignSelf:"flex-start"},"self-end":{alignSelf:"flex-end"},"self-center":{alignSelf:"center"},"self-stretch":{alignSelf:"stretch"},"self-baseline":{alignSelf:"baseline"}};var ALIGN_CONTENT_MAP={"content-start":{alignContent:"flex-start"},"content-end":{alignContent:"flex-end"},"content-center":{alignContent:"center"},"content-between":{alignContent:"space-between"},"content-around":{alignContent:"space-around"},"content-stretch":{alignContent:"stretch"}};var POSITION_MAP={absolute:{position:"absolute"},relative:{position:"relative"}};var OVERFLOW_MAP={"overflow-hidden":{overflow:"hidden"},"overflow-visible":{overflow:"visible"},"overflow-scroll":{overflow:"scroll"}};function parseLayout(cls){var _ref,_ref2,_ref3,_ref4,_ref5,_ref6,_ref7,_ref8,_ref9,_ref0,_DISPLAY_MAP$cls;return(_ref=(_ref2=(_ref3=(_ref4=(_ref5=(_ref6=(_ref7=(_ref8=(_ref9=(_ref0=(_DISPLAY_MAP$cls=DISPLAY_MAP[cls])!=null?_DISPLAY_MAP$cls:FLEX_DIRECTION_MAP[cls])!=null?_ref0:FLEX_WRAP_MAP[cls])!=null?_ref9:FLEX_MAP[cls])!=null?_ref8:GROW_SHRINK_MAP[cls])!=null?_ref7:JUSTIFY_CONTENT_MAP[cls])!=null?_ref6:ALIGN_ITEMS_MAP[cls])!=null?_ref5:ALIGN_SELF_MAP[cls])!=null?_ref4:ALIGN_CONTENT_MAP[cls])!=null?_ref3:POSITION_MAP[cls])!=null?_ref2:OVERFLOW_MAP[cls])!=null?_ref:null;}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Sizing utilities (width, height, min/max)
3
+ */
4
+ import type { StyleObject } from "../types";
5
+ export declare const SIZE_SCALE: Record<string, number>;
6
+ export declare const SIZE_PERCENTAGES: Record<string, string>;
7
+ /**
8
+ * Parse sizing classes
9
+ */
10
+ export declare function parseSizing(cls: string): StyleObject | null;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});exports.SIZE_SCALE=exports.SIZE_PERCENTAGES=void 0;exports.parseSizing=parseSizing;var SIZE_SCALE=exports.SIZE_SCALE={0:0,0.5:2,1:4,1.5:6,2:8,2.5:10,3:12,3.5:14,4:16,5:20,6:24,7:28,8:32,9:36,10:40,11:44,12:48,14:56,16:64,20:80,24:96,28:112,32:128,36:144,40:160,44:176,48:192,52:208,56:224,60:240,64:256,72:288,80:320,96:384};var SIZE_PERCENTAGES=exports.SIZE_PERCENTAGES={full:"100%","1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%","1/5":"20%","2/5":"40%","3/5":"60%","4/5":"80%","1/6":"16.666667%","2/6":"33.333333%","3/6":"50%","4/6":"66.666667%","5/6":"83.333333%"};function parseArbitrarySize(value){var pxMatch=value.match(/^\[(\d+)(?:px)?\]$/);if(pxMatch){return parseInt(pxMatch[1],10);}var percentMatch=value.match(/^\[(\d+(?:\.\d+)?)%\]$/);if(percentMatch){return`${percentMatch[1]}%`;}if(value.startsWith("[")&&value.endsWith("]")){if(process.env.NODE_ENV!=="production"){console.warn(`[react-native-tailwind] Unsupported arbitrary size unit: ${value}. Only px and % are supported.`);}return null;}return null;}function parseSizing(cls){if(cls.startsWith("w-")){var sizeKey=cls.substring(2);var arbitrarySize=parseArbitrarySize(sizeKey);if(arbitrarySize!==null){return{width:arbitrarySize};}var percentage=SIZE_PERCENTAGES[sizeKey];if(percentage){return{width:percentage};}var numericSize=SIZE_SCALE[sizeKey];if(numericSize!==undefined){return{width:numericSize};}if(sizeKey==="auto"){return{width:"auto"};}}if(cls.startsWith("h-")){var _sizeKey=cls.substring(2);var _arbitrarySize=parseArbitrarySize(_sizeKey);if(_arbitrarySize!==null){return{height:_arbitrarySize};}var _percentage=SIZE_PERCENTAGES[_sizeKey];if(_percentage){return{height:_percentage};}var _numericSize=SIZE_SCALE[_sizeKey];if(_numericSize!==undefined){return{height:_numericSize};}if(_sizeKey==="auto"){return{height:"auto"};}}if(cls.startsWith("min-w-")){var _sizeKey2=cls.substring(6);var _arbitrarySize2=parseArbitrarySize(_sizeKey2);if(_arbitrarySize2!==null){return{minWidth:_arbitrarySize2};}var _percentage2=SIZE_PERCENTAGES[_sizeKey2];if(_percentage2){return{minWidth:_percentage2};}var _numericSize2=SIZE_SCALE[_sizeKey2];if(_numericSize2!==undefined){return{minWidth:_numericSize2};}}if(cls.startsWith("min-h-")){var _sizeKey3=cls.substring(6);var _arbitrarySize3=parseArbitrarySize(_sizeKey3);if(_arbitrarySize3!==null){return{minHeight:_arbitrarySize3};}var _percentage3=SIZE_PERCENTAGES[_sizeKey3];if(_percentage3){return{minHeight:_percentage3};}var _numericSize3=SIZE_SCALE[_sizeKey3];if(_numericSize3!==undefined){return{minHeight:_numericSize3};}}if(cls.startsWith("max-w-")){var _sizeKey4=cls.substring(6);var _arbitrarySize4=parseArbitrarySize(_sizeKey4);if(_arbitrarySize4!==null){return{maxWidth:_arbitrarySize4};}var _percentage4=SIZE_PERCENTAGES[_sizeKey4];if(_percentage4){return{maxWidth:_percentage4};}var _numericSize4=SIZE_SCALE[_sizeKey4];if(_numericSize4!==undefined){return{maxWidth:_numericSize4};}}if(cls.startsWith("max-h-")){var _sizeKey5=cls.substring(6);var _arbitrarySize5=parseArbitrarySize(_sizeKey5);if(_arbitrarySize5!==null){return{maxHeight:_arbitrarySize5};}var _percentage5=SIZE_PERCENTAGES[_sizeKey5];if(_percentage5){return{maxHeight:_percentage5};}var _numericSize5=SIZE_SCALE[_sizeKey5];if(_numericSize5!==undefined){return{maxHeight:_numericSize5};}}return null;}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Spacing utilities (margin, padding, gap)
3
+ */
4
+ import type { StyleObject } from "../types";
5
+ export declare const SPACING_SCALE: Record<string, number>;
6
+ /**
7
+ * Parse spacing classes (margin, padding, gap)
8
+ * Examples: m-4, mx-2, mt-8, p-4, px-2, pt-8, gap-4
9
+ */
10
+ export declare function parseSpacing(cls: string): StyleObject | null;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});exports.SPACING_SCALE=void 0;exports.parseSpacing=parseSpacing;var SPACING_SCALE=exports.SPACING_SCALE={0:0,0.5:2,1:4,1.5:6,2:8,2.5:10,3:12,3.5:14,4:16,5:20,6:24,7:28,8:32,9:36,10:40,11:44,12:48,14:56,16:64,20:80,24:96,28:112,32:128,36:144,40:160,44:176,48:192,52:208,56:224,60:240,64:256,72:288,80:320,96:384};function parseSpacing(cls){if(cls.startsWith("m-")||cls.startsWith("m")){return parseMargin(cls);}if(cls.startsWith("p-")||cls.startsWith("p")){return parsePadding(cls);}if(cls.startsWith("gap-")){return parseGap(cls);}return null;}function parseMargin(cls){var allMatch=cls.match(/^m-(\d+(?:\.\d+)?)$/);if(allMatch){var value=SPACING_SCALE[allMatch[1]];if(value!==undefined){return{margin:value};}}var xMatch=cls.match(/^mx-(\d+(?:\.\d+)?)$/);if(xMatch){var _value=SPACING_SCALE[xMatch[1]];if(_value!==undefined){return{marginHorizontal:_value};}}var yMatch=cls.match(/^my-(\d+(?:\.\d+)?)$/);if(yMatch){var _value2=SPACING_SCALE[yMatch[1]];if(_value2!==undefined){return{marginVertical:_value2};}}var tMatch=cls.match(/^mt-(\d+(?:\.\d+)?)$/);if(tMatch){var _value3=SPACING_SCALE[tMatch[1]];if(_value3!==undefined){return{marginTop:_value3};}}var rMatch=cls.match(/^mr-(\d+(?:\.\d+)?)$/);if(rMatch){var _value4=SPACING_SCALE[rMatch[1]];if(_value4!==undefined){return{marginRight:_value4};}}var bMatch=cls.match(/^mb-(\d+(?:\.\d+)?)$/);if(bMatch){var _value5=SPACING_SCALE[bMatch[1]];if(_value5!==undefined){return{marginBottom:_value5};}}var lMatch=cls.match(/^ml-(\d+(?:\.\d+)?)$/);if(lMatch){var _value6=SPACING_SCALE[lMatch[1]];if(_value6!==undefined){return{marginLeft:_value6};}}return null;}function parsePadding(cls){var allMatch=cls.match(/^p-(\d+(?:\.\d+)?)$/);if(allMatch){var value=SPACING_SCALE[allMatch[1]];if(value!==undefined){return{padding:value};}}var xMatch=cls.match(/^px-(\d+(?:\.\d+)?)$/);if(xMatch){var _value7=SPACING_SCALE[xMatch[1]];if(_value7!==undefined){return{paddingHorizontal:_value7};}}var yMatch=cls.match(/^py-(\d+(?:\.\d+)?)$/);if(yMatch){var _value8=SPACING_SCALE[yMatch[1]];if(_value8!==undefined){return{paddingVertical:_value8};}}var tMatch=cls.match(/^pt-(\d+(?:\.\d+)?)$/);if(tMatch){var _value9=SPACING_SCALE[tMatch[1]];if(_value9!==undefined){return{paddingTop:_value9};}}var rMatch=cls.match(/^pr-(\d+(?:\.\d+)?)$/);if(rMatch){var _value0=SPACING_SCALE[rMatch[1]];if(_value0!==undefined){return{paddingRight:_value0};}}var bMatch=cls.match(/^pb-(\d+(?:\.\d+)?)$/);if(bMatch){var _value1=SPACING_SCALE[bMatch[1]];if(_value1!==undefined){return{paddingBottom:_value1};}}var lMatch=cls.match(/^pl-(\d+(?:\.\d+)?)$/);if(lMatch){var _value10=SPACING_SCALE[lMatch[1]];if(_value10!==undefined){return{paddingLeft:_value10};}}return null;}function parseGap(cls){var match=cls.match(/^gap-(\d+(?:\.\d+)?)$/);if(match){var value=SPACING_SCALE[match[1]];if(value!==undefined){return{gap:value};}}return null;}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Typography utilities (font size, weight, line height, text align)
3
+ */
4
+ import type { StyleObject } from "../types";
5
+ export declare const FONT_SIZES: Record<string, number>;
6
+ /**
7
+ * Parse typography classes
8
+ */
9
+ export declare function parseTypography(cls: string): StyleObject | null;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});exports.FONT_SIZES=void 0;exports.parseTypography=parseTypography;var FONT_SIZES=exports.FONT_SIZES={xs:12,sm:14,base:16,lg:18,xl:20,"2xl":24,"3xl":30,"4xl":36,"5xl":48,"6xl":60,"7xl":72,"8xl":96,"9xl":128};function parseTypography(cls){if(cls.startsWith("text-")){var sizeKey=cls.substring(5);var fontSize=FONT_SIZES[sizeKey];if(fontSize!==undefined){return{fontSize:fontSize};}}if(cls==="font-thin"){return{fontWeight:"100"};}if(cls==="font-extralight"){return{fontWeight:"200"};}if(cls==="font-light"){return{fontWeight:"300"};}if(cls==="font-normal"){return{fontWeight:"400"};}if(cls==="font-medium"){return{fontWeight:"500"};}if(cls==="font-semibold"){return{fontWeight:"600"};}if(cls==="font-bold"){return{fontWeight:"700"};}if(cls==="font-extrabold"){return{fontWeight:"800"};}if(cls==="font-black"){return{fontWeight:"900"};}if(cls==="italic"){return{fontStyle:"italic"};}if(cls==="not-italic"){return{fontStyle:"normal"};}if(cls==="text-left"){return{textAlign:"left"};}if(cls==="text-center"){return{textAlign:"center"};}if(cls==="text-right"){return{textAlign:"right"};}if(cls==="text-justify"){return{textAlign:"justify"};}if(cls==="underline"){return{textDecorationLine:"underline"};}if(cls==="line-through"){return{textDecorationLine:"line-through"};}if(cls==="no-underline"){return{textDecorationLine:"none"};}if(cls==="uppercase"){return{textTransform:"uppercase"};}if(cls==="lowercase"){return{textTransform:"lowercase"};}if(cls==="capitalize"){return{textTransform:"capitalize"};}if(cls==="normal-case"){return{textTransform:"none"};}if(cls==="leading-none"){return{lineHeight:16};}if(cls==="leading-tight"){return{lineHeight:20};}if(cls==="leading-snug"){return{lineHeight:22};}if(cls==="leading-normal"){return{lineHeight:24};}if(cls==="leading-relaxed"){return{lineHeight:28};}if(cls==="leading-loose"){return{lineHeight:32};}return null;}
@@ -0,0 +1 @@
1
+ require("react-native");
@@ -0,0 +1,138 @@
1
+ /* eslint-disable @typescript-eslint/consistent-type-definitions */
2
+
3
+ /**
4
+ * TypeScript declarations to add className prop to React Native components
5
+ * This file provides module augmentation for react-native to add className prop support
6
+ */
7
+
8
+ import "react-native";
9
+
10
+ declare module "react-native" {
11
+ interface ViewProps {
12
+ /**
13
+ * Tailwind-like class names for styling
14
+ * @example
15
+ * <View className="flex items-center justify-center m-4 p-2 bg-blue-500 rounded-lg" />
16
+ */
17
+ className?: string;
18
+ }
19
+
20
+ interface TextProps {
21
+ /**
22
+ * Tailwind-like class names for styling
23
+ * @example
24
+ * <Text className="text-lg font-bold text-blue-500 text-center" />
25
+ */
26
+ className?: string;
27
+ }
28
+
29
+ interface ImageProps {
30
+ /**
31
+ * Tailwind-like class names for styling
32
+ * @example
33
+ * <Image className="w-full h-64 rounded-lg" source={...} />
34
+ */
35
+ className?: string;
36
+ }
37
+
38
+ interface ScrollViewProps {
39
+ /**
40
+ * Tailwind-like class names for styling
41
+ * @example
42
+ * <ScrollView className="flex-1 bg-gray-100 p-4" />
43
+ */
44
+ className?: string;
45
+
46
+ /**
47
+ * Tailwind-like class names for styling the content container
48
+ * @example
49
+ * <ScrollView contentContainerClassName="items-center p-4 gap-4" />
50
+ */
51
+ contentContainerClassName?: string;
52
+ }
53
+
54
+ interface TouchableOpacityProps {
55
+ /**
56
+ * Tailwind-like class names for styling
57
+ * @example
58
+ * <TouchableOpacity className="px-4 py-2 bg-blue-500 rounded-lg items-center" />
59
+ */
60
+ className?: string;
61
+ }
62
+
63
+ interface PressableProps {
64
+ /**
65
+ * Tailwind-like class names for styling
66
+ * @example
67
+ * <Pressable className="px-4 py-2 bg-blue-500 rounded-lg items-center" />
68
+ */
69
+ className?: string;
70
+ }
71
+
72
+ interface FlatListProps<_ItemT> {
73
+ /**
74
+ * Tailwind-like class names for styling
75
+ * @example
76
+ * <FlatList className="flex-1 bg-gray-100" data={items} renderItem={...} />
77
+ */
78
+ className?: string;
79
+
80
+ /**
81
+ * Tailwind-like class names for styling the content container
82
+ * @example
83
+ * <FlatList contentContainerClassName="p-4 gap-4" data={items} renderItem={...} />
84
+ */
85
+ contentContainerClassName?: string;
86
+
87
+ /**
88
+ * Tailwind-like class names for styling the column wrapper (when numColumns > 1)
89
+ * @example
90
+ * <FlatList columnWrapperClassName="gap-4 mb-4" numColumns={2} data={items} renderItem={...} />
91
+ */
92
+ columnWrapperClassName?: string;
93
+
94
+ /**
95
+ * Tailwind-like class names for styling the list header component
96
+ * @example
97
+ * <FlatList ListHeaderComponentClassName="p-4 bg-gray-200" data={items} renderItem={...} />
98
+ */
99
+ ListHeaderComponentClassName?: string;
100
+
101
+ /**
102
+ * Tailwind-like class names for styling the list footer component
103
+ * @example
104
+ * <FlatList ListFooterComponentClassName="p-4 bg-gray-200" data={items} renderItem={...} />
105
+ */
106
+ ListFooterComponentClassName?: string;
107
+ }
108
+
109
+ interface SectionListProps<_ItemT, _SectionT> {
110
+ /**
111
+ * Tailwind-like class names for styling
112
+ * @example
113
+ * <SectionList className="flex-1 bg-gray-100" sections={sections} renderItem={...} />
114
+ */
115
+ className?: string;
116
+
117
+ /**
118
+ * Tailwind-like class names for styling the content container
119
+ * @example
120
+ * <SectionList contentContainerClassName="p-4 gap-4" sections={sections} renderItem={...} />
121
+ */
122
+ contentContainerClassName?: string;
123
+
124
+ /**
125
+ * Tailwind-like class names for styling the list header component
126
+ * @example
127
+ * <SectionList ListHeaderComponentClassName="p-4 bg-gray-200" sections={sections} renderItem={...} />
128
+ */
129
+ ListHeaderComponentClassName?: string;
130
+
131
+ /**
132
+ * Tailwind-like class names for styling the list footer component
133
+ * @example
134
+ * <SectionList ListFooterComponentClassName="p-4 bg-gray-200" sections={sections} renderItem={...} />
135
+ */
136
+ ListFooterComponentClassName?: string;
137
+ }
138
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Core type definitions
3
+ */
4
+ import type { ImageStyle, TextStyle, ViewStyle } from "react-native";
5
+ export type RNStyle = ViewStyle | TextStyle | ImageStyle;
6
+ export type StyleObject = {
7
+ [key: string]: string | number;
8
+ };
9
+ export type SpacingValue = number;
10
+ export type ColorValue = string;
11
+ export type Parser = (className: string) => StyleObject | null;
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Utility to generate unique, stable style keys from class names
3
+ */
4
+ /**
5
+ * Generate a unique style key from a className string
6
+ * @param className - Space-separated class names
7
+ * @returns Unique style key suitable for use as JavaScript identifier
8
+ */
9
+ export declare function generateStyleKey(className: string): string;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});exports.generateStyleKey=generateStyleKey;function generateStyleKey(className){var classes=className.split(/\s+/).filter(Boolean).sort();var key="_"+classes.join("_").replace(/[^a-zA-Z0-9_]/g,"_").replace(/_+/g,"_");return key;}