styledwind-native 0.0.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 ADDED
@@ -0,0 +1,88 @@
1
+ # styledwind-native
2
+
3
+ > A tiny wrapper for [`twrnc`](https://github.com/jaredh159/tailwind-react-native-classnames) that brings a familiar [`styled-components`](https://github.com/styled-components/styled-components)-like API to React Native, making it easy to apply dynamic Tailwind CSS styles while avoiding verbose inline styling.
4
+
5
+ ## Description
6
+
7
+ `styledwind-native` is a lightweight utility designed to offer a familiar [`styled-components`](https://github.com/styled-components/styled-components) API on top of [`twrnc`](https://github.com/jaredh159/tailwind-react-native-classnames) for React Native. It allows you to apply Tailwind utility classes in a clean, declarative manner, making your components more maintainable by avoiding excessive inline styles.
8
+
9
+ With `styledwind-native`, you can:
10
+ - Define React Native components with Tailwind utility classes using a concise API.
11
+ - Dynamically adjust styles based on component props.
12
+ - Seamlessly handle safe-area insets for modern devices.
13
+ - Keep your components cleaner and easier to maintain, while still leveraging the full power of Tailwind CSS and [`twrnc`](https://github.com/jaredh159/tailwind-react-native-classnames).
14
+
15
+ ## Features
16
+
17
+ - **Familiar API**: Styled-components-like API, so you can define your styles and components without verbose inline styles.
18
+ - **Tailwind CSS for React Native**: Leverages the power of [`twrnc`](https://github.com/jaredh159/tailwind-react-native-classnames) to bring utility-first styling to your components.
19
+ - **Dynamic Styling with Props**: Conditionally apply styles based on props, making your components more flexible and reusable.
20
+ - **Support for Core React Native Components**: Easily style components like `View`, `Text`, `ScrollView`, and many more.
21
+ - **Safe-Area Insets Support**: Automatically adjust layouts for safe-area insets to handle notches and system bars on modern devices.
22
+ - **Fully Configurable**: Works seamlessly with your own Tailwind configuration via `tailwind.config.js`.
23
+
24
+
25
+ ## Installation
26
+
27
+ To install `styledwind-native` along with [`twrnc`](https://github.com/jaredh159/tailwind-react-native-classnames), run:
28
+
29
+ ```bash
30
+ npm install styledwind-native twrnc
31
+ ```
32
+
33
+ ## Usage Example
34
+
35
+ Here's how you can use styledwind-native to create dynamically styled components:
36
+
37
+ ```tsx
38
+ import React from 'react';
39
+ import tw from 'styledwind-native';
40
+
41
+ const Text = tw.Text<{ isBig?: boolean }>`
42
+ text-base
43
+
44
+ ${props => props.isBig && tw`text-2xl`}
45
+ `;
46
+
47
+ const MyComponent = () => {
48
+ return (
49
+ <Text isBig>
50
+ This text is styled with Tailwind!
51
+ </Text>
52
+ );
53
+ };
54
+
55
+ export default MyComponent;
56
+ ```
57
+
58
+ ## VS Code Intellisense
59
+
60
+ Add the following to the settings of the
61
+ [official Tailwind plugin](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)
62
+ for VS Code.
63
+
64
+ ```jsonc
65
+ // ...
66
+ "editor.quickSuggestions": {
67
+ "strings": true // forces VS Code to trigger completions when editing "string" content
68
+ },
69
+ "tailwindCSS.classAttributes": [
70
+ // ...
71
+ "style"
72
+ ],
73
+ "tailwindCSS.includeLanguages": {
74
+ "typescript": "javascript", // if you are using typescript
75
+ "typescriptreact": "javascript" // if you are using typescript with react
76
+ },
77
+ "tailwindCSS.experimental.classRegex": [
78
+ "tw`([^`]*)", // tw`...`
79
+ "tw\\.[^`]+`([^`]*)`" // tw.xxx<xxx>`...`
80
+ ],
81
+ ```
82
+
83
+ More detailed instructions, including how to add snippets, are available
84
+ [here](https://github.com/jaredh159/tailwind-react-native-classnames/discussions/124).
85
+
86
+ ## Why Use `styledwind-native`?
87
+
88
+ If you're building a React Native app and want to use Tailwind CSS for styling, `styledwind-native` simplifies the process by wrapping [`twrnc`](https://github.com/jaredh159/tailwind-react-native-classnames) with a [`styled-components`](https://github.com/styled-components/styled-components)-like API. This reduces the need for verbose inline styles, making your components cleaner, easier to read, and more maintainable.
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import RN from 'react-native';
3
+ import { type TailwindFn, type Style } from 'twrnc';
4
+ interface ImageProps extends RN.ImageProps {
5
+ tintColor?: string;
6
+ }
7
+ type TailwindComponents = TailwindFn & {
8
+ ActivityIndicator: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.ActivityIndicatorProps & T>;
9
+ AnimatedFlatList: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.Animated.AnimatedProps<RN.FlatListProps<any>> & T>;
10
+ AnimatedImage: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.Animated.AnimatedProps<ImageProps> & T>;
11
+ AnimatedScrollView: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.Animated.AnimatedProps<RN.ScrollViewProps> & T>;
12
+ AnimatedSectionList: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.Animated.AnimatedProps<RN.SectionListProps<any>> & T>;
13
+ AnimatedText: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.Animated.AnimatedProps<RN.TextProps> & T>;
14
+ AnimatedView: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.Animated.AnimatedProps<RN.ViewProps> & T>;
15
+ Button: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.ButtonProps & T>;
16
+ FlatList: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.FlatListProps<any> & T>;
17
+ Image: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<ImageProps & T>;
18
+ Modal: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.ModalProps & T>;
19
+ SafeAreaView: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.ViewProps & T>;
20
+ ScrollView: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.ScrollViewProps & T>;
21
+ SectionList: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.SectionListProps<any> & T>;
22
+ StatusBar: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.StatusBarProps & T>;
23
+ Switch: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.SwitchProps & T>;
24
+ Text: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.TextProps & T>;
25
+ TextInput: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.TextInputProps & T>;
26
+ TouchableHighlight: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.TouchableHighlightProps & T>;
27
+ TouchableNativeFeedback: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.TouchableNativeFeedbackProps & T>;
28
+ TouchableOpacity: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.TouchableOpacityProps & T>;
29
+ View: <T = {}>(styles: TemplateStringsArray, ...interpolations: ((props: T) => false | Style | undefined)[]) => React.FC<RN.ViewProps & T>;
30
+ };
31
+ declare const tw: TailwindComponents;
32
+ export * from 'twrnc';
33
+ export default tw;
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,114 @@
1
+ import React from 'react';
2
+ import RN from 'react-native';
3
+ import { useDeviceContext, create } from 'twrnc';
4
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
+ import path from 'path';
6
+ import fs from 'fs';
7
+ let tailwindConfig;
8
+ const configPaths = [
9
+ path.resolve(process.cwd(), 'tailwind.config.js'),
10
+ path.resolve(process.cwd(), 'tailwind.config.ts'),
11
+ path.resolve(process.cwd(), 'tailwind.config.mjs'),
12
+ ];
13
+ const configPath = configPaths.find(fs.existsSync);
14
+ if (configPath) {
15
+ tailwindConfig = require(configPath);
16
+ }
17
+ const twrnc = create(tailwindConfig);
18
+ const allowedComponents = [
19
+ 'ActivityIndicator',
20
+ 'AnimatedFlatList',
21
+ 'AnimatedImage',
22
+ 'AnimatedScrollView',
23
+ 'AnimatedSectionList',
24
+ 'AnimatedText',
25
+ 'AnimatedView',
26
+ 'Button',
27
+ 'FlatList',
28
+ 'Image',
29
+ 'Modal',
30
+ 'SafeAreaView',
31
+ 'ScrollView',
32
+ 'SectionList',
33
+ 'StatusBar',
34
+ 'Switch',
35
+ 'Text',
36
+ 'TextInput',
37
+ 'TouchableHighlight',
38
+ 'TouchableNativeFeedback',
39
+ 'TouchableOpacity',
40
+ 'View',
41
+ ];
42
+ function createTailwindComponent(Component, styles, ...interpolations) {
43
+ const classNames = styles.filter(style => !['', ','].includes(style.trim())).join();
44
+ return function TailwindComponent({ children, component, ...props }) {
45
+ var _a;
46
+ useDeviceContext(twrnc);
47
+ let BaseComponent = Component;
48
+ let baseStyle = null;
49
+ if (typeof component === 'function') {
50
+ const CustomComponent = component;
51
+ baseStyle = (_a = CustomComponent.defaultProps) === null || _a === void 0 ? void 0 : _a.style;
52
+ BaseComponent = CustomComponent;
53
+ }
54
+ const insets = useSafeAreaInsets();
55
+ let style = twrnc `${classNames}`;
56
+ interpolations.forEach(interpolation => {
57
+ const interpolatedStyle = interpolation(props);
58
+ if (interpolatedStyle) {
59
+ style = { ...style, ...interpolatedStyle };
60
+ }
61
+ });
62
+ if (classNames.includes('safe:pt'))
63
+ style.paddingTop = insets.top;
64
+ if (classNames.includes('safe:pb'))
65
+ style.paddingBottom = insets.bottom;
66
+ if (classNames.includes('safe:pl'))
67
+ style.paddingLeft = insets.left;
68
+ if (classNames.includes('safe:pr'))
69
+ style.paddingRight = insets.right;
70
+ if (classNames.includes('safe:mt'))
71
+ style.marginTop = insets.top;
72
+ if (classNames.includes('safe:mb'))
73
+ style.marginBottom = insets.bottom;
74
+ if (classNames.includes('safe:ml'))
75
+ style.marginLeft = insets.left;
76
+ if (classNames.includes('safe:mr'))
77
+ style.marginRight = insets.right;
78
+ if (classNames.includes('safe:top'))
79
+ style.top = insets.top;
80
+ if (classNames.includes('safe:bottom'))
81
+ style.bottom = insets.bottom;
82
+ if (classNames.includes('safe:left'))
83
+ style.left = insets.left;
84
+ if (classNames.includes('safe:right'))
85
+ style.right = insets.right;
86
+ if (classNames.includes('safe:h-top'))
87
+ style.height = insets.top;
88
+ if (classNames.includes('safe:h-bottom'))
89
+ style.height = insets.bottom;
90
+ if (classNames.includes('safe:w-left'))
91
+ style.width = insets.left;
92
+ if (classNames.includes('safe:w-right'))
93
+ style.width = insets.right;
94
+ return (<BaseComponent {...props} style={[baseStyle, style, props.style]}>
95
+ {children}
96
+ </BaseComponent>);
97
+ };
98
+ }
99
+ function generateTailwindStyledComponents() {
100
+ return allowedComponents.reduce((acc, componentName) => {
101
+ const animatedComponentName = componentName.startsWith('Animated')
102
+ ? componentName.split('Animated')[1]
103
+ : null;
104
+ const Component = animatedComponentName
105
+ ? RN.Animated[animatedComponentName]
106
+ : RN[componentName];
107
+ acc[componentName] = (styles, ...interpolations) => createTailwindComponent(Component, styles, ...interpolations);
108
+ return acc;
109
+ }, twrnc);
110
+ }
111
+ const tw = generateTailwindStyledComponents();
112
+ export * from 'twrnc';
113
+ export default tw;
114
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "styledwind-native",
3
+ "version": "0.0.1",
4
+ "description": "A lightweight utility for applying dynamic Tailwind CSS styles in React Native",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "prepublishOnly": "npm run build",
11
+ "test": "jest",
12
+ "release:patch": "npm version patch && git push && git push --tags",
13
+ "release:minor": "npm version minor && git push && git push --tags",
14
+ "release:major": "npm version major && git push && git push --tags"
15
+ },
16
+ "keywords": [
17
+ "tailwind",
18
+ "tailwindcss",
19
+ "react-native",
20
+ "classnames",
21
+ "styled-components",
22
+ "styled-wind"
23
+ ],
24
+ "author": "Silvestre Herrera",
25
+ "license": "ISC",
26
+ "peerDependencies": {
27
+ "react": ">=18.2.0",
28
+ "react-native": ">=0.74.5",
29
+ "react-native-safe-area-context": ">=4.11.0",
30
+ "twrnc": ">=4.5.1"
31
+ },
32
+ "devDependencies": {
33
+ "@types/react": "^18.3.10",
34
+ "typescript": ">=5.6.2"
35
+ }
36
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,228 @@
1
+ import React from 'react';
2
+ import RN from 'react-native';
3
+ import { useDeviceContext, create, type TailwindFn, type Style } from 'twrnc';
4
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
+ import path from 'path';
6
+ import fs from 'fs';
7
+
8
+ let tailwindConfig;
9
+ const configPaths = [
10
+ path.resolve(process.cwd(), 'tailwind.config.js'),
11
+ path.resolve(process.cwd(), 'tailwind.config.ts'),
12
+ path.resolve(process.cwd(), 'tailwind.config.mjs'),
13
+ ];
14
+
15
+ const configPath = configPaths.find(fs.existsSync);
16
+
17
+ if (configPath) {
18
+ tailwindConfig = require(configPath);
19
+ }
20
+
21
+ const twrnc = create(tailwindConfig);
22
+
23
+ const allowedComponents = [
24
+ 'ActivityIndicator',
25
+ 'AnimatedFlatList',
26
+ 'AnimatedImage',
27
+ 'AnimatedScrollView',
28
+ 'AnimatedSectionList',
29
+ 'AnimatedText',
30
+ 'AnimatedView',
31
+ 'Button',
32
+ 'FlatList',
33
+ 'Image',
34
+ 'Modal',
35
+ 'SafeAreaView',
36
+ 'ScrollView',
37
+ 'SectionList',
38
+ 'StatusBar',
39
+ 'Switch',
40
+ 'Text',
41
+ 'TextInput',
42
+ 'TouchableHighlight',
43
+ 'TouchableNativeFeedback',
44
+ 'TouchableOpacity',
45
+ 'View',
46
+ ];
47
+
48
+ interface ImageProps extends RN.ImageProps {
49
+ tintColor?: string;
50
+ }
51
+
52
+ interface TailwindComponentProps {
53
+ children?: React.ReactNode;
54
+ component?: React.FC<any>;
55
+ [key: string]: any;
56
+ }
57
+
58
+ type TailwindComponents = TailwindFn & {
59
+ ActivityIndicator: <T = {}>(
60
+ styles: TemplateStringsArray,
61
+ ...interpolations: ((props: T) => false | Style | undefined)[]
62
+ ) => React.FC<RN.ActivityIndicatorProps & T>;
63
+ AnimatedFlatList: <T = {}>(
64
+ styles: TemplateStringsArray,
65
+ ...interpolations: ((props: T) => false | Style | undefined)[]
66
+ ) => React.FC<RN.Animated.AnimatedProps<RN.FlatListProps<any>> & T>;
67
+ AnimatedImage: <T = {}>(
68
+ styles: TemplateStringsArray,
69
+ ...interpolations: ((props: T) => false | Style | undefined)[]
70
+ ) => React.FC<RN.Animated.AnimatedProps<ImageProps> & T>;
71
+ AnimatedScrollView: <T = {}>(
72
+ styles: TemplateStringsArray,
73
+ ...interpolations: ((props: T) => false | Style | undefined)[]
74
+ ) => React.FC<RN.Animated.AnimatedProps<RN.ScrollViewProps> & T>;
75
+ AnimatedSectionList: <T = {}>(
76
+ styles: TemplateStringsArray,
77
+ ...interpolations: ((props: T) => false | Style | undefined)[]
78
+ ) => React.FC<RN.Animated.AnimatedProps<RN.SectionListProps<any>> & T>;
79
+ AnimatedText: <T = {}>(
80
+ styles: TemplateStringsArray,
81
+ ...interpolations: ((props: T) => false | Style | undefined)[]
82
+ ) => React.FC<RN.Animated.AnimatedProps<RN.TextProps> & T>;
83
+ AnimatedView: <T = {}>(
84
+ styles: TemplateStringsArray,
85
+ ...interpolations: ((props: T) => false | Style | undefined)[]
86
+ ) => React.FC<RN.Animated.AnimatedProps<RN.ViewProps> & T>;
87
+ Button: <T = {}>(
88
+ styles: TemplateStringsArray,
89
+ ...interpolations: ((props: T) => false | Style | undefined)[]
90
+ ) => React.FC<RN.ButtonProps & T>;
91
+ FlatList: <T = {}>(
92
+ styles: TemplateStringsArray,
93
+ ...interpolations: ((props: T) => false | Style | undefined)[]
94
+ ) => React.FC<RN.FlatListProps<any> & T>;
95
+ Image: <T = {}>(
96
+ styles: TemplateStringsArray,
97
+ ...interpolations: ((props: T) => false | Style | undefined)[]
98
+ ) => React.FC<ImageProps & T>;
99
+ Modal: <T = {}>(
100
+ styles: TemplateStringsArray,
101
+ ...interpolations: ((props: T) => false | Style | undefined)[]
102
+ ) => React.FC<RN.ModalProps & T>;
103
+ SafeAreaView: <T = {}>(
104
+ styles: TemplateStringsArray,
105
+ ...interpolations: ((props: T) => false | Style | undefined)[]
106
+ ) => React.FC<RN.ViewProps & T>;
107
+ ScrollView: <T = {}>(
108
+ styles: TemplateStringsArray,
109
+ ...interpolations: ((props: T) => false | Style | undefined)[]
110
+ ) => React.FC<RN.ScrollViewProps & T>;
111
+ SectionList: <T = {}>(
112
+ styles: TemplateStringsArray,
113
+ ...interpolations: ((props: T) => false | Style | undefined)[]
114
+ ) => React.FC<RN.SectionListProps<any> & T>;
115
+ StatusBar: <T = {}>(
116
+ styles: TemplateStringsArray,
117
+ ...interpolations: ((props: T) => false | Style | undefined)[]
118
+ ) => React.FC<RN.StatusBarProps & T>;
119
+ Switch: <T = {}>(
120
+ styles: TemplateStringsArray,
121
+ ...interpolations: ((props: T) => false | Style | undefined)[]
122
+ ) => React.FC<RN.SwitchProps & T>;
123
+ Text: <T = {}>(
124
+ styles: TemplateStringsArray,
125
+ ...interpolations: ((props: T) => false | Style | undefined)[]
126
+ ) => React.FC<RN.TextProps & T>;
127
+ TextInput: <T = {}>(
128
+ styles: TemplateStringsArray,
129
+ ...interpolations: ((props: T) => false | Style | undefined)[]
130
+ ) => React.FC<RN.TextInputProps & T>;
131
+ TouchableHighlight: <T = {}>(
132
+ styles: TemplateStringsArray,
133
+ ...interpolations: ((props: T) => false | Style | undefined)[]
134
+ ) => React.FC<RN.TouchableHighlightProps & T>;
135
+ TouchableNativeFeedback: <T = {}>(
136
+ styles: TemplateStringsArray,
137
+ ...interpolations: ((props: T) => false | Style | undefined)[]
138
+ ) => React.FC<RN.TouchableNativeFeedbackProps & T>;
139
+ TouchableOpacity: <T = {}>(
140
+ styles: TemplateStringsArray,
141
+ ...interpolations: ((props: T) => false | Style | undefined)[]
142
+ ) => React.FC<RN.TouchableOpacityProps & T>;
143
+ View: <T = {}>(
144
+ styles: TemplateStringsArray,
145
+ ...interpolations: ((props: T) => false | Style | undefined)[]
146
+ ) => React.FC<RN.ViewProps & T>;
147
+ };
148
+
149
+ function createTailwindComponent<T = {}>(
150
+ Component: React.FC<any>,
151
+ styles: TemplateStringsArray,
152
+ ...interpolations: ((props: T) => false | Style | undefined)[]
153
+ ) {
154
+ const classNames = styles.filter(style => !['', ','].includes(style.trim())).join();
155
+
156
+ return function TailwindComponent({ children, component, ...props }: TailwindComponentProps) {
157
+ useDeviceContext(twrnc);
158
+
159
+ let BaseComponent = Component;
160
+ let baseStyle = null;
161
+
162
+ if (typeof component === 'function') {
163
+ const CustomComponent = component;
164
+ baseStyle = (CustomComponent.defaultProps as React.ComponentProps<typeof BaseComponent>)
165
+ ?.style;
166
+ BaseComponent = CustomComponent;
167
+ }
168
+
169
+ const insets = useSafeAreaInsets();
170
+ let style = twrnc`${classNames}`;
171
+
172
+ interpolations.forEach(interpolation => {
173
+ const interpolatedStyle = interpolation(props as T);
174
+ if (interpolatedStyle) {
175
+ style = { ...style, ...interpolatedStyle };
176
+ }
177
+ });
178
+
179
+ if (classNames.includes('safe:pt')) style.paddingTop = insets.top;
180
+ if (classNames.includes('safe:pb')) style.paddingBottom = insets.bottom;
181
+ if (classNames.includes('safe:pl')) style.paddingLeft = insets.left;
182
+ if (classNames.includes('safe:pr')) style.paddingRight = insets.right;
183
+
184
+ if (classNames.includes('safe:mt')) style.marginTop = insets.top;
185
+ if (classNames.includes('safe:mb')) style.marginBottom = insets.bottom;
186
+ if (classNames.includes('safe:ml')) style.marginLeft = insets.left;
187
+ if (classNames.includes('safe:mr')) style.marginRight = insets.right;
188
+
189
+ if (classNames.includes('safe:top')) style.top = insets.top;
190
+ if (classNames.includes('safe:bottom')) style.bottom = insets.bottom;
191
+ if (classNames.includes('safe:left')) style.left = insets.left;
192
+ if (classNames.includes('safe:right')) style.right = insets.right;
193
+
194
+ if (classNames.includes('safe:h-top')) style.height = insets.top;
195
+ if (classNames.includes('safe:h-bottom')) style.height = insets.bottom;
196
+ if (classNames.includes('safe:w-left')) style.width = insets.left;
197
+ if (classNames.includes('safe:w-right')) style.width = insets.right;
198
+
199
+ return (
200
+ <BaseComponent {...props} style={[baseStyle, style, props.style]}>
201
+ {children}
202
+ </BaseComponent>
203
+ );
204
+ };
205
+ }
206
+
207
+ function generateTailwindStyledComponents(): TailwindComponents {
208
+ return allowedComponents.reduce<TailwindComponents>((acc, componentName) => {
209
+ const animatedComponentName = componentName.startsWith('Animated')
210
+ ? componentName.split('Animated')[1]
211
+ : null;
212
+ const Component = animatedComponentName
213
+ ? (RN.Animated as any)[animatedComponentName as keyof typeof RN.Animated]
214
+ : RN[componentName as keyof typeof RN];
215
+
216
+ (acc as Record<string, any>)[componentName] = (
217
+ styles: TemplateStringsArray,
218
+ ...interpolations: ((props: any) => false | Style | undefined)[]
219
+ ) => createTailwindComponent(Component, styles, ...interpolations);
220
+
221
+ return acc;
222
+ }, twrnc as TailwindComponents);
223
+ }
224
+
225
+ const tw = generateTailwindStyledComponents();
226
+
227
+ export * from 'twrnc';
228
+ export default tw;
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2018",
4
+ "module": "esnext",
5
+ "lib": ["es2018"],
6
+ "jsx": "react-native",
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "sourceMap": true,
10
+ "outDir": "./dist",
11
+ "rootDir": "./src",
12
+ "strict": true,
13
+ "moduleResolution": "node",
14
+ "baseUrl": "./",
15
+ "allowSyntheticDefaultImports": true,
16
+ "esModuleInterop": true,
17
+ "skipLibCheck": true
18
+ },
19
+ "include": ["src/**/*"],
20
+ "exclude": ["node_modules", "dist"]
21
+ }