@wireservers-ui/react-natives 1.0.1-rc3 → 2.0.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/CHANGELOG.md +58 -0
- package/README.md +418 -34
- package/bin/cli.js +376 -376
- package/package.json +6 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@wireservers-ui/react-natives` are documented here.
|
|
4
|
+
|
|
5
|
+
Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|
6
|
+
Versioning: [Semantic Versioning](https://semver.org/)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [2.0.0] - 2026-03-15
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `.gitattributes` enforcing LF line endings for all source, script, and config files — prevents CRLF from breaking `npx` on Unix/macOS/Linux on Windows-developed repos
|
|
14
|
+
- `engines` field in `package.json` declaring Node.js `>=18.0.0` requirement
|
|
15
|
+
- Full `global.css` theme file in README manual setup (Step C) with complete light (`:root`) and dark (`.dark`) token sets for all color groups: `primary`, `secondary`, `tertiary`, `error`, `success`, `warning`, `info`, `typography`, `outline`, `background`, `indicator`
|
|
16
|
+
- Collapsible light/dark theme reference blocks in README
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- **[Breaking on Unix/macOS/Linux]** `bin/cli.js` had CRLF line endings causing `env: 'bash\r': No such file or directory` and `node\r: No such file or directory` when consumers ran `npx @wireservers-ui/react-natives init` on non-Windows systems
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- README restructured: easy setup is now the primary path; manual setup is a detailed step-by-step with full file examples
|
|
23
|
+
- README `## Theming` section now points to the full `global.css` in manual Step C instead of repeating an abbreviated snippet
|
|
24
|
+
- README version badge updated to `v2.0.0`
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## [1.0.1] - 2026-03-14
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
- `bin/cli.js` — CLI init command runnable via `npx @wireservers-ui/react-natives init`
|
|
32
|
+
- Automatic peer-dependency installation by `init` (`nativewind`, `tailwindcss`, `tailwind-variants`, `tailwind-merge`, `react-native-reanimated`, `react-native-worklets`, `react-native-svg`, `react-dom`, `react-native-web`)
|
|
33
|
+
- `react-dom` version is matched exactly to the consumer's installed `react` version to prevent React/DOM mismatch on web
|
|
34
|
+
- pnpm compatibility: `init` creates/updates `.npmrc` with `node-linker=hoisted` when pnpm is detected and triggers a reinstall pass
|
|
35
|
+
- Tailwind content path for library source added to generated `tailwind.config.js` (`node_modules/@wireservers-ui/react-natives/src/**`)
|
|
36
|
+
- Non-destructive init: all file creation follows skip-if-exists semantics — no consumer file is ever overwritten
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
- `nativewind/babel` placed in `presets` (not `plugins`) in generated `babel.config.js` — was causing Babel runtime errors and bundle failures
|
|
40
|
+
- Missing `react-native-worklets` dependency causing Metro bundler to fail
|
|
41
|
+
- Missing `react-native-svg` causing SVG component resolution failures
|
|
42
|
+
- Missing `tailwind-merge` causing variant merge errors at runtime
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
- Tailwind class generation now works correctly for library components (colors, slider, etc.) because consumer Tailwind config scans library source
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## [1.0.0] - 2026-03-01
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
- Initial release of `@wireservers-ui/react-natives`
|
|
53
|
+
- 70+ React Native components: Accordion, ActionSheet, Alert, AlertDialog, Avatar, Badge, Button, Calendar, Card, Carousel, Checkbox, CircularProgress, ColorPicker, Collapsible, DatePicker, Drawer, Empty, Fab, FormControl, Heading, Icon, IconButton, Image, Input, Kbd, Link, List, Menu, Modal, NumberInput, Overlay, Pagination, PasswordInput, PinInput, Popover, Portal, Pressable, Progress, Radio, Rating, SearchInput, SegmentedControl, Select, Skeleton, Slider, Snackbar, Spinner, Stack, Stat, Stepper, Switch, Table, Tabs, Tag, TagsInput, Text, Textarea, Timeline, Toast, Toggle, ToggleGroup, Tooltip, VisuallyHidden
|
|
54
|
+
- NativeWind v4 + Tailwind CSS 3 styling with `tailwind-variants` for type-safe variant APIs
|
|
55
|
+
- CSS variable token system for light/dark theming
|
|
56
|
+
- `tailwind-preset.js` Tailwind preset for consumers
|
|
57
|
+
- TypeScript source ships directly (no build step)
|
|
58
|
+
- MIT license
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**A comprehensive React Native component library built with NativeWind and Tailwind Variants.**
|
|
4
4
|
|
|
5
|
-
> **Note:** This project is in
|
|
5
|
+
> **Note:** This project is in active development (v2.0.0). We're building out components, documentation, and tooling. Contributions and feedback are welcome!
|
|
6
6
|
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[](https://www.npmjs.com/package/@wireservers-ui/react-natives)
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
React-Natives is a collection of 70+ production-ready, accessible React Native components. Every component is TypeScript-first, themeable via CSS variables, and styled with NativeWind (Tailwind CSS for React Native).
|
|
15
15
|
|
|
16
|
-
**Live Demo:** [reactnatives.
|
|
16
|
+
**Live Demo:** [www.reactnatives.dev](https://www.reactnatives.dev)
|
|
17
17
|
|
|
18
18
|
### Key Features
|
|
19
19
|
|
|
@@ -34,40 +34,442 @@ React-Natives is a collection of 70+ production-ready, accessible React Native c
|
|
|
34
34
|
|
|
35
35
|
---
|
|
36
36
|
|
|
37
|
-
##
|
|
37
|
+
## Setup
|
|
38
38
|
|
|
39
|
-
###
|
|
39
|
+
### 1. Easy Setup (Recommended)
|
|
40
|
+
|
|
41
|
+
Use this for the fastest first-time setup in a new Expo app.
|
|
40
42
|
|
|
41
43
|
```bash
|
|
42
|
-
|
|
44
|
+
npx create-expo-app@latest wsui-init --template blank-typescript
|
|
45
|
+
cd wsui-init
|
|
46
|
+
npm install @wireservers-ui/react-natives@2.0.0
|
|
47
|
+
npx @wireservers-ui/react-natives@2.0.0 init
|
|
48
|
+
npx expo start --clear --web
|
|
43
49
|
```
|
|
44
50
|
|
|
45
|
-
|
|
51
|
+
What `init` does for you:
|
|
52
|
+
|
|
53
|
+
- Installs required runtime dependencies
|
|
54
|
+
- Matches `react-dom` exactly to your installed `react` version
|
|
55
|
+
- Creates setup files only if missing
|
|
56
|
+
- Never overwrites existing files in your project
|
|
57
|
+
|
|
58
|
+
### 2. Manual Setup (Detailed)
|
|
59
|
+
|
|
60
|
+
Use this path if you want full control over every file.
|
|
61
|
+
|
|
62
|
+
#### Step A: Install packages
|
|
46
63
|
|
|
47
64
|
```bash
|
|
48
|
-
npm install
|
|
65
|
+
npm install @wireservers-ui/react-natives@2.0.0
|
|
66
|
+
npm install nativewind tailwindcss tailwind-variants tailwind-merge react-native-reanimated react-native-worklets react-native-svg react-native-web react-dom
|
|
49
67
|
```
|
|
50
68
|
|
|
51
|
-
|
|
69
|
+
Important:
|
|
52
70
|
|
|
53
|
-
|
|
71
|
+
- Ensure `react-dom` matches your `react` version exactly.
|
|
72
|
+
- Example: if `react` is `19.2.0`, use `react-dom@19.2.0`.
|
|
54
73
|
|
|
55
|
-
|
|
74
|
+
#### Step B: Create or update `tailwind.config.js`
|
|
56
75
|
|
|
57
76
|
```js
|
|
58
77
|
/** @type {import('tailwindcss').Config} */
|
|
59
78
|
module.exports = {
|
|
60
79
|
content: [
|
|
80
|
+
"./App.{js,jsx,ts,tsx}",
|
|
61
81
|
"./app/**/*.{js,jsx,ts,tsx}",
|
|
62
|
-
|
|
82
|
+
"./components/**/*.{js,jsx,ts,tsx}",
|
|
83
|
+
"./node_modules/@wireservers-ui/react-natives/src/**/*.{js,jsx,ts,tsx}",
|
|
63
84
|
],
|
|
64
85
|
presets: [require("@wireservers-ui/react-natives/tailwind-preset")],
|
|
65
86
|
};
|
|
66
87
|
```
|
|
67
88
|
|
|
68
|
-
|
|
89
|
+
#### Step C: Create `global.css`
|
|
90
|
+
|
|
91
|
+
GitHub README does not support real tabs, so the sections below use collapsible blocks (tab-like) for Light and Dark theme tokens.
|
|
92
|
+
|
|
93
|
+
Use this full file content in `global.css`:
|
|
94
|
+
|
|
95
|
+
```css
|
|
96
|
+
@tailwind base;
|
|
97
|
+
@tailwind components;
|
|
98
|
+
@tailwind utilities;
|
|
99
|
+
|
|
100
|
+
:root {
|
|
101
|
+
--color-primary-0: 255 255 255;
|
|
102
|
+
--color-primary-50: 238 237 253;
|
|
103
|
+
--color-primary-100: 214 211 249;
|
|
104
|
+
--color-primary-200: 172 166 242;
|
|
105
|
+
--color-primary-300: 132 122 235;
|
|
106
|
+
--color-primary-400: 105 95 233;
|
|
107
|
+
--color-primary-500: 80 70 230;
|
|
108
|
+
--color-primary-600: 63 55 198;
|
|
109
|
+
--color-primary-700: 47 41 163;
|
|
110
|
+
--color-primary-800: 33 29 128;
|
|
111
|
+
--color-primary-900: 22 20 96;
|
|
112
|
+
--color-primary-950: 13 11 64;
|
|
113
|
+
|
|
114
|
+
--color-secondary-0: 255 255 255;
|
|
115
|
+
--color-secondary-50: 241 241 243;
|
|
116
|
+
--color-secondary-100: 220 220 224;
|
|
117
|
+
--color-secondary-200: 186 186 194;
|
|
118
|
+
--color-secondary-300: 152 152 163;
|
|
119
|
+
--color-secondary-400: 121 121 137;
|
|
120
|
+
--color-secondary-500: 92 92 112;
|
|
121
|
+
--color-secondary-600: 72 72 92;
|
|
122
|
+
--color-secondary-700: 54 54 72;
|
|
123
|
+
--color-secondary-800: 38 38 54;
|
|
124
|
+
--color-secondary-900: 24 24 38;
|
|
125
|
+
--color-secondary-950: 14 14 24;
|
|
126
|
+
|
|
127
|
+
--color-tertiary-50: 250 245 255;
|
|
128
|
+
--color-tertiary-100: 243 232 255;
|
|
129
|
+
--color-tertiary-200: 222 200 252;
|
|
130
|
+
--color-tertiary-300: 196 160 246;
|
|
131
|
+
--color-tertiary-400: 168 120 238;
|
|
132
|
+
--color-tertiary-500: 140 80 228;
|
|
133
|
+
--color-tertiary-600: 114 58 200;
|
|
134
|
+
--color-tertiary-700: 90 40 170;
|
|
135
|
+
--color-tertiary-800: 68 28 138;
|
|
136
|
+
--color-tertiary-900: 48 18 106;
|
|
137
|
+
--color-tertiary-950: 30 8 72;
|
|
138
|
+
|
|
139
|
+
--color-error-0: 255 255 255;
|
|
140
|
+
--color-error-50: 254 242 242;
|
|
141
|
+
--color-error-100: 254 226 226;
|
|
142
|
+
--color-error-200: 252 165 165;
|
|
143
|
+
--color-error-300: 248 113 113;
|
|
144
|
+
--color-error-400: 240 82 82;
|
|
145
|
+
--color-error-500: 230 53 53;
|
|
146
|
+
--color-error-600: 204 37 37;
|
|
147
|
+
--color-error-700: 178 24 24;
|
|
148
|
+
--color-error-800: 150 16 16;
|
|
149
|
+
--color-error-900: 122 10 10;
|
|
150
|
+
--color-error-950: 80 5 5;
|
|
151
|
+
|
|
152
|
+
--color-success-0: 255 255 255;
|
|
153
|
+
--color-success-50: 237 252 241;
|
|
154
|
+
--color-success-100: 210 245 221;
|
|
155
|
+
--color-success-200: 147 226 172;
|
|
156
|
+
--color-success-300: 96 207 128;
|
|
157
|
+
--color-success-400: 56 189 92;
|
|
158
|
+
--color-success-500: 34 168 66;
|
|
159
|
+
--color-success-600: 24 140 52;
|
|
160
|
+
--color-success-700: 18 112 40;
|
|
161
|
+
--color-success-800: 14 88 32;
|
|
162
|
+
--color-success-900: 10 64 22;
|
|
163
|
+
--color-success-950: 5 40 12;
|
|
164
|
+
|
|
165
|
+
--color-warning-0: 255 255 255;
|
|
166
|
+
--color-warning-50: 255 249 235;
|
|
167
|
+
--color-warning-100: 255 240 198;
|
|
168
|
+
--color-warning-200: 252 217 119;
|
|
169
|
+
--color-warning-300: 247 195 56;
|
|
170
|
+
--color-warning-400: 240 176 14;
|
|
171
|
+
--color-warning-500: 220 155 6;
|
|
172
|
+
--color-warning-600: 182 123 4;
|
|
173
|
+
--color-warning-700: 145 96 4;
|
|
174
|
+
--color-warning-800: 112 72 5;
|
|
175
|
+
--color-warning-900: 82 52 6;
|
|
176
|
+
--color-warning-950: 48 30 4;
|
|
177
|
+
|
|
178
|
+
--color-info-0: 255 255 255;
|
|
179
|
+
--color-info-50: 240 248 255;
|
|
180
|
+
--color-info-100: 224 240 253;
|
|
181
|
+
--color-info-200: 168 213 248;
|
|
182
|
+
--color-info-300: 110 184 240;
|
|
183
|
+
--color-info-400: 66 158 232;
|
|
184
|
+
--color-info-500: 34 134 220;
|
|
185
|
+
--color-info-600: 22 110 190;
|
|
186
|
+
--color-info-700: 14 88 158;
|
|
187
|
+
--color-info-800: 10 68 126;
|
|
188
|
+
--color-info-900: 6 50 96;
|
|
189
|
+
--color-info-950: 2 32 64;
|
|
190
|
+
|
|
191
|
+
--color-typography-0: 255 255 255;
|
|
192
|
+
--color-typography-50: 245 245 245;
|
|
193
|
+
--color-typography-100: 229 229 229;
|
|
194
|
+
--color-typography-200: 212 212 212;
|
|
195
|
+
--color-typography-300: 163 163 163;
|
|
196
|
+
--color-typography-400: 140 140 140;
|
|
197
|
+
--color-typography-500: 115 115 115;
|
|
198
|
+
--color-typography-600: 82 82 82;
|
|
199
|
+
--color-typography-700: 64 64 64;
|
|
200
|
+
--color-typography-800: 38 38 38;
|
|
201
|
+
--color-typography-900: 23 23 23;
|
|
202
|
+
--color-typography-950: 10 10 10;
|
|
203
|
+
|
|
204
|
+
--color-outline-0: 255 255 255;
|
|
205
|
+
--color-outline-50: 245 245 245;
|
|
206
|
+
--color-outline-100: 229 229 229;
|
|
207
|
+
--color-outline-200: 212 212 212;
|
|
208
|
+
--color-outline-300: 196 196 196;
|
|
209
|
+
--color-outline-400: 163 163 163;
|
|
210
|
+
--color-outline-500: 140 140 140;
|
|
211
|
+
--color-outline-600: 115 115 115;
|
|
212
|
+
--color-outline-700: 82 82 82;
|
|
213
|
+
--color-outline-800: 51 51 51;
|
|
214
|
+
--color-outline-900: 33 33 33;
|
|
215
|
+
--color-outline-950: 18 18 18;
|
|
216
|
+
|
|
217
|
+
--color-background-0: 255 255 255;
|
|
218
|
+
--color-background-50: 249 249 249;
|
|
219
|
+
--color-background-100: 242 242 242;
|
|
220
|
+
--color-background-200: 228 228 228;
|
|
221
|
+
--color-background-300: 212 212 212;
|
|
222
|
+
--color-background-400: 189 189 189;
|
|
223
|
+
--color-background-500: 163 163 163;
|
|
224
|
+
--color-background-600: 115 115 115;
|
|
225
|
+
--color-background-700: 82 82 82;
|
|
226
|
+
--color-background-800: 51 51 51;
|
|
227
|
+
--color-background-900: 33 33 33;
|
|
228
|
+
--color-background-950: 18 18 18;
|
|
229
|
+
--color-background-error: 254 226 226;
|
|
230
|
+
--color-background-warning: 255 243 224;
|
|
231
|
+
--color-background-muted: 245 245 245;
|
|
232
|
+
--color-background-success: 228 247 235;
|
|
233
|
+
--color-background-info: 224 240 253;
|
|
234
|
+
|
|
235
|
+
--color-indicator-primary: 80 70 230;
|
|
236
|
+
--color-indicator-info: 34 134 220;
|
|
237
|
+
--color-indicator-error: 230 53 53;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.dark {
|
|
241
|
+
--color-primary-0: 13 11 64;
|
|
242
|
+
--color-primary-50: 22 20 96;
|
|
243
|
+
--color-primary-100: 33 29 128;
|
|
244
|
+
--color-primary-200: 47 41 163;
|
|
245
|
+
--color-primary-300: 63 55 198;
|
|
246
|
+
--color-primary-400: 80 70 230;
|
|
247
|
+
--color-primary-500: 105 95 233;
|
|
248
|
+
--color-primary-600: 132 122 235;
|
|
249
|
+
--color-primary-700: 172 166 242;
|
|
250
|
+
--color-primary-800: 214 211 249;
|
|
251
|
+
--color-primary-900: 238 237 253;
|
|
252
|
+
--color-primary-950: 255 255 255;
|
|
253
|
+
|
|
254
|
+
--color-secondary-0: 14 14 24;
|
|
255
|
+
--color-secondary-50: 24 24 38;
|
|
256
|
+
--color-secondary-100: 38 38 54;
|
|
257
|
+
--color-secondary-200: 54 54 72;
|
|
258
|
+
--color-secondary-300: 72 72 92;
|
|
259
|
+
--color-secondary-400: 92 92 112;
|
|
260
|
+
--color-secondary-500: 121 121 137;
|
|
261
|
+
--color-secondary-600: 152 152 163;
|
|
262
|
+
--color-secondary-700: 186 186 194;
|
|
263
|
+
--color-secondary-800: 220 220 224;
|
|
264
|
+
--color-secondary-900: 241 241 243;
|
|
265
|
+
--color-secondary-950: 255 255 255;
|
|
266
|
+
|
|
267
|
+
--color-tertiary-50: 30 8 72;
|
|
268
|
+
--color-tertiary-100: 48 18 106;
|
|
269
|
+
--color-tertiary-200: 68 28 138;
|
|
270
|
+
--color-tertiary-300: 90 40 170;
|
|
271
|
+
--color-tertiary-400: 114 58 200;
|
|
272
|
+
--color-tertiary-500: 140 80 228;
|
|
273
|
+
--color-tertiary-600: 168 120 238;
|
|
274
|
+
--color-tertiary-700: 196 160 246;
|
|
275
|
+
--color-tertiary-800: 222 200 252;
|
|
276
|
+
--color-tertiary-900: 243 232 255;
|
|
277
|
+
--color-tertiary-950: 250 245 255;
|
|
278
|
+
|
|
279
|
+
--color-error-0: 80 5 5;
|
|
280
|
+
--color-error-50: 122 10 10;
|
|
281
|
+
--color-error-100: 150 16 16;
|
|
282
|
+
--color-error-200: 178 24 24;
|
|
283
|
+
--color-error-300: 204 37 37;
|
|
284
|
+
--color-error-400: 230 53 53;
|
|
285
|
+
--color-error-500: 240 82 82;
|
|
286
|
+
--color-error-600: 248 113 113;
|
|
287
|
+
--color-error-700: 252 165 165;
|
|
288
|
+
--color-error-800: 254 226 226;
|
|
289
|
+
--color-error-900: 254 242 242;
|
|
290
|
+
--color-error-950: 255 255 255;
|
|
291
|
+
|
|
292
|
+
--color-success-0: 5 40 12;
|
|
293
|
+
--color-success-50: 10 64 22;
|
|
294
|
+
--color-success-100: 14 88 32;
|
|
295
|
+
--color-success-200: 18 112 40;
|
|
296
|
+
--color-success-300: 24 140 52;
|
|
297
|
+
--color-success-400: 34 168 66;
|
|
298
|
+
--color-success-500: 56 189 92;
|
|
299
|
+
--color-success-600: 96 207 128;
|
|
300
|
+
--color-success-700: 147 226 172;
|
|
301
|
+
--color-success-800: 210 245 221;
|
|
302
|
+
--color-success-900: 237 252 241;
|
|
303
|
+
--color-success-950: 255 255 255;
|
|
304
|
+
|
|
305
|
+
--color-warning-0: 48 30 4;
|
|
306
|
+
--color-warning-50: 82 52 6;
|
|
307
|
+
--color-warning-100: 112 72 5;
|
|
308
|
+
--color-warning-200: 145 96 4;
|
|
309
|
+
--color-warning-300: 182 123 4;
|
|
310
|
+
--color-warning-400: 220 155 6;
|
|
311
|
+
--color-warning-500: 240 176 14;
|
|
312
|
+
--color-warning-600: 247 195 56;
|
|
313
|
+
--color-warning-700: 252 217 119;
|
|
314
|
+
--color-warning-800: 255 240 198;
|
|
315
|
+
--color-warning-900: 255 249 235;
|
|
316
|
+
--color-warning-950: 255 255 255;
|
|
317
|
+
|
|
318
|
+
--color-info-0: 2 32 64;
|
|
319
|
+
--color-info-50: 6 50 96;
|
|
320
|
+
--color-info-100: 10 68 126;
|
|
321
|
+
--color-info-200: 14 88 158;
|
|
322
|
+
--color-info-300: 22 110 190;
|
|
323
|
+
--color-info-400: 34 134 220;
|
|
324
|
+
--color-info-500: 66 158 232;
|
|
325
|
+
--color-info-600: 110 184 240;
|
|
326
|
+
--color-info-700: 168 213 248;
|
|
327
|
+
--color-info-800: 224 240 253;
|
|
328
|
+
--color-info-900: 240 248 255;
|
|
329
|
+
--color-info-950: 255 255 255;
|
|
330
|
+
|
|
331
|
+
--color-typography-0: 10 10 10;
|
|
332
|
+
--color-typography-50: 23 23 23;
|
|
333
|
+
--color-typography-100: 38 38 38;
|
|
334
|
+
--color-typography-200: 64 64 64;
|
|
335
|
+
--color-typography-300: 82 82 82;
|
|
336
|
+
--color-typography-400: 115 115 115;
|
|
337
|
+
--color-typography-500: 140 140 140;
|
|
338
|
+
--color-typography-600: 163 163 163;
|
|
339
|
+
--color-typography-700: 212 212 212;
|
|
340
|
+
--color-typography-800: 229 229 229;
|
|
341
|
+
--color-typography-900: 245 245 245;
|
|
342
|
+
--color-typography-950: 255 255 255;
|
|
343
|
+
|
|
344
|
+
--color-outline-0: 18 18 18;
|
|
345
|
+
--color-outline-50: 33 33 33;
|
|
346
|
+
--color-outline-100: 51 51 51;
|
|
347
|
+
--color-outline-200: 82 82 82;
|
|
348
|
+
--color-outline-300: 115 115 115;
|
|
349
|
+
--color-outline-400: 140 140 140;
|
|
350
|
+
--color-outline-500: 163 163 163;
|
|
351
|
+
--color-outline-600: 196 196 196;
|
|
352
|
+
--color-outline-700: 212 212 212;
|
|
353
|
+
--color-outline-800: 229 229 229;
|
|
354
|
+
--color-outline-900: 245 245 245;
|
|
355
|
+
--color-outline-950: 255 255 255;
|
|
356
|
+
|
|
357
|
+
--color-background-0: 24 23 25;
|
|
358
|
+
--color-background-50: 38 38 40;
|
|
359
|
+
--color-background-100: 51 51 53;
|
|
360
|
+
--color-background-200: 66 66 68;
|
|
361
|
+
--color-background-300: 82 82 85;
|
|
362
|
+
--color-background-400: 104 104 108;
|
|
363
|
+
--color-background-500: 130 130 135;
|
|
364
|
+
--color-background-600: 163 163 169;
|
|
365
|
+
--color-background-700: 196 196 201;
|
|
366
|
+
--color-background-800: 221 221 226;
|
|
367
|
+
--color-background-900: 240 240 245;
|
|
368
|
+
--color-background-950: 255 255 255;
|
|
369
|
+
--color-background-error: 80 5 5;
|
|
370
|
+
--color-background-warning: 48 30 4;
|
|
371
|
+
--color-background-muted: 38 38 40;
|
|
372
|
+
--color-background-success: 5 40 12;
|
|
373
|
+
--color-background-info: 2 32 64;
|
|
374
|
+
|
|
375
|
+
--color-indicator-primary: 132 122 235;
|
|
376
|
+
--color-indicator-info: 66 158 232;
|
|
377
|
+
--color-indicator-error: 240 82 82;
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Optional tab-like reference blocks (same values split by mode):
|
|
382
|
+
|
|
383
|
+
<details>
|
|
384
|
+
<summary>Light Theme Tokens (:root)</summary>
|
|
385
|
+
|
|
386
|
+
```css
|
|
387
|
+
/* Use the :root block from the full file above */
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
</details>
|
|
391
|
+
|
|
392
|
+
<details>
|
|
393
|
+
<summary>Dark Theme Tokens (.dark)</summary>
|
|
394
|
+
|
|
395
|
+
```css
|
|
396
|
+
/* Use the .dark block from the full file above */
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
</details>
|
|
400
|
+
|
|
401
|
+
#### Step D: Create or update `babel.config.js`
|
|
402
|
+
|
|
403
|
+
```js
|
|
404
|
+
module.exports = function (api) {
|
|
405
|
+
api.cache(true);
|
|
406
|
+
return {
|
|
407
|
+
presets: [
|
|
408
|
+
["babel-preset-expo", { jsxImportSource: "nativewind" }],
|
|
409
|
+
"nativewind/babel",
|
|
410
|
+
],
|
|
411
|
+
};
|
|
412
|
+
};
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
#### Step E: Create or update `metro.config.js`
|
|
69
416
|
|
|
70
|
-
|
|
417
|
+
```js
|
|
418
|
+
const { getDefaultConfig } = require("expo/metro-config");
|
|
419
|
+
const { withNativeWind } = require("nativewind/metro");
|
|
420
|
+
|
|
421
|
+
const config = getDefaultConfig(__dirname);
|
|
422
|
+
|
|
423
|
+
module.exports = withNativeWind(config, { input: "./global.css" });
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### Step F: Add NativeWind types file `nativewind-env.d.ts`
|
|
427
|
+
|
|
428
|
+
```ts
|
|
429
|
+
/// <reference types="nativewind/types" />
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
#### Step G: Import `global.css` in your app entry
|
|
433
|
+
|
|
434
|
+
Example `App.tsx`:
|
|
435
|
+
|
|
436
|
+
```tsx
|
|
437
|
+
import "./global.css";
|
|
438
|
+
import React from "react";
|
|
439
|
+
import { View, Text } from "react-native";
|
|
440
|
+
|
|
441
|
+
export default function App() {
|
|
442
|
+
return (
|
|
443
|
+
<View className="flex-1 items-center justify-center bg-background-0">
|
|
444
|
+
<Text className="text-typography-900">React-Natives ready</Text>
|
|
445
|
+
</View>
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
#### Step H: Optional pnpm compatibility (`.npmrc`)
|
|
451
|
+
|
|
452
|
+
If you use pnpm with Expo/Metro, add:
|
|
453
|
+
|
|
454
|
+
```ini
|
|
455
|
+
node-linker=hoisted
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
Then run:
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
pnpm install
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
#### Step I: Start the app
|
|
465
|
+
|
|
466
|
+
```bash
|
|
467
|
+
npx expo start --clear --web
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
## Example Usage
|
|
71
473
|
|
|
72
474
|
```tsx
|
|
73
475
|
import { Button, ButtonText, Card, CardHeader, CardBody } from "@wireservers-ui/react-natives";
|
|
@@ -124,29 +526,11 @@ Toggle, ToggleGroup, Collapsible, Calendar
|
|
|
124
526
|
|
|
125
527
|
## Theming
|
|
126
528
|
|
|
127
|
-
Components use CSS variables for theming.
|
|
128
|
-
|
|
129
|
-
```css
|
|
130
|
-
@tailwind base;
|
|
131
|
-
@tailwind components;
|
|
132
|
-
@tailwind utilities;
|
|
133
|
-
|
|
134
|
-
:root {
|
|
135
|
-
--color-primary-500: 80 70 230;
|
|
136
|
-
--color-background-0: 255 255 255;
|
|
137
|
-
--color-typography-900: 23 23 23;
|
|
138
|
-
/* ... */
|
|
139
|
-
}
|
|
529
|
+
Components use CSS variables for theming.
|
|
140
530
|
|
|
141
|
-
|
|
142
|
-
--color-primary-500: 120 110 255;
|
|
143
|
-
--color-background-0: 24 23 25;
|
|
144
|
-
--color-typography-900: 245 245 245;
|
|
145
|
-
/* ... */
|
|
146
|
-
}
|
|
147
|
-
```
|
|
531
|
+
For the complete theming file (full `:root` + `.dark` token sets), use the manual setup instructions in **Step C: Create `global.css`** above.
|
|
148
532
|
|
|
149
|
-
|
|
533
|
+
Token groups include `primary`, `secondary`, `tertiary`, `error`, `success`, `warning`, `info`, `typography`, `outline`, `background`, and `indicator`.
|
|
150
534
|
|
|
151
535
|
---
|
|
152
536
|
|
package/bin/cli.js
CHANGED
|
@@ -1,376 +1,376 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const { execSync } = require("child_process");
|
|
4
|
-
const fs = require("fs");
|
|
5
|
-
const path = require("path");
|
|
6
|
-
|
|
7
|
-
const args = process.argv.slice(2);
|
|
8
|
-
const command = args[0];
|
|
9
|
-
|
|
10
|
-
if (command !== "init") {
|
|
11
|
-
console.error(`Unknown command: ${command}`);
|
|
12
|
-
console.error("Usage: npx @wireservers-ui/react-natives init");
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const cwd = process.cwd();
|
|
17
|
-
|
|
18
|
-
// ── Detect package manager ─────────────────────────────────────────────────
|
|
19
|
-
function detectPackageManager() {
|
|
20
|
-
if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
21
|
-
if (fs.existsSync(path.join(cwd, "yarn.lock"))) return "yarn";
|
|
22
|
-
if (fs.existsSync(path.join(cwd, "bun.lockb"))) return "bun";
|
|
23
|
-
return "npm";
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const pm = detectPackageManager();
|
|
27
|
-
const installCmd = pm === "yarn" ? "yarn add" : `${pm} install`;
|
|
28
|
-
let needsReinstall = false;
|
|
29
|
-
|
|
30
|
-
function getInstalledReactVersion() {
|
|
31
|
-
const reactPkgPath = path.join(cwd, "node_modules", "react", "package.json");
|
|
32
|
-
if (!fs.existsSync(reactPkgPath)) return null;
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
const reactPkg = JSON.parse(fs.readFileSync(reactPkgPath, "utf8"));
|
|
36
|
-
return typeof reactPkg.version === "string" ? reactPkg.version : null;
|
|
37
|
-
} catch {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
console.log(`\n🚀 Initializing @wireservers-ui/react-natives...\n`);
|
|
43
|
-
console.log(` Package manager: ${pm}`);
|
|
44
|
-
|
|
45
|
-
// ── 0. Create .npmrc for pnpm (Metro needs hoisted modules) ────────────────
|
|
46
|
-
if (pm === "pnpm") {
|
|
47
|
-
const npmrcPath = path.join(cwd, ".npmrc");
|
|
48
|
-
const npmrcLine = "node-linker=hoisted";
|
|
49
|
-
if (fs.existsSync(npmrcPath)) {
|
|
50
|
-
const existing = fs.readFileSync(npmrcPath, "utf8");
|
|
51
|
-
if (!existing.includes("node-linker")) {
|
|
52
|
-
fs.appendFileSync(npmrcPath, `\n${npmrcLine}\n`, "utf8");
|
|
53
|
-
console.log(
|
|
54
|
-
" ✏️ Added node-linker=hoisted to .npmrc (required by Metro)",
|
|
55
|
-
);
|
|
56
|
-
needsReinstall = true;
|
|
57
|
-
}
|
|
58
|
-
} else {
|
|
59
|
-
fs.writeFileSync(npmrcPath, `${npmrcLine}\n`, "utf8");
|
|
60
|
-
console.log(
|
|
61
|
-
" ✏️ Created .npmrc with node-linker=hoisted (required by Metro)",
|
|
62
|
-
);
|
|
63
|
-
needsReinstall = true;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// ── 1. Re-install with hoisted layout (pnpm only) ─────────────────────────
|
|
68
|
-
if (needsReinstall) {
|
|
69
|
-
console.log("\n📦 Re-installing with hoisted node_modules...\n");
|
|
70
|
-
try {
|
|
71
|
-
execSync(`${pm} install`, { cwd, stdio: "inherit" });
|
|
72
|
-
} catch {
|
|
73
|
-
console.error("Failed to reinstall. Run `pnpm install` manually.");
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// ── 2. Install peer dependencies ───────────────────────────────────────────
|
|
78
|
-
console.log("\n📦 Installing peer dependencies...\n");
|
|
79
|
-
const reactVersion = getInstalledReactVersion();
|
|
80
|
-
const reactDomPackage = reactVersion
|
|
81
|
-
? `react-dom@${reactVersion}`
|
|
82
|
-
: "react-dom";
|
|
83
|
-
|
|
84
|
-
const peers = [
|
|
85
|
-
"nativewind@^4",
|
|
86
|
-
"tailwindcss@^3",
|
|
87
|
-
"tailwind-variants",
|
|
88
|
-
"tailwind-merge",
|
|
89
|
-
"react-native-reanimated",
|
|
90
|
-
"react-native-worklets",
|
|
91
|
-
"react-native-svg",
|
|
92
|
-
reactDomPackage,
|
|
93
|
-
"react-native-web",
|
|
94
|
-
];
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
execSync(`${installCmd} ${peers.join(" ")}`, { cwd, stdio: "inherit" });
|
|
98
|
-
} catch {
|
|
99
|
-
console.error(
|
|
100
|
-
"Failed to install peer dependencies. You may need to install them manually:",
|
|
101
|
-
);
|
|
102
|
-
console.error(` ${installCmd} ${peers.join(" ")}`);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// ── 3. Create tailwind.config.js ───────────────────────────────────────────
|
|
106
|
-
const tailwindConfig = `/** @type {import('tailwindcss').Config} */
|
|
107
|
-
module.exports = {
|
|
108
|
-
content: [
|
|
109
|
-
"./App.{js,jsx,ts,tsx}",
|
|
110
|
-
"./app/**/*.{js,jsx,ts,tsx}",
|
|
111
|
-
"./components/**/*.{js,jsx,ts,tsx}",
|
|
112
|
-
"./node_modules/@wireservers-ui/react-natives/src/**/*.{js,jsx,ts,tsx}",
|
|
113
|
-
],
|
|
114
|
-
presets: [require("@wireservers-ui/react-natives/tailwind-preset")],
|
|
115
|
-
};
|
|
116
|
-
`;
|
|
117
|
-
|
|
118
|
-
writeIfMissing("tailwind.config.js", tailwindConfig);
|
|
119
|
-
|
|
120
|
-
// ── 4. Create global.css ───────────────────────────────────────────────────
|
|
121
|
-
const globalCss = `@tailwind base;
|
|
122
|
-
@tailwind components;
|
|
123
|
-
@tailwind utilities;
|
|
124
|
-
|
|
125
|
-
:root {
|
|
126
|
-
--color-primary-0: 255 255 255;
|
|
127
|
-
--color-primary-50: 238 237 253;
|
|
128
|
-
--color-primary-100: 214 211 249;
|
|
129
|
-
--color-primary-200: 172 166 242;
|
|
130
|
-
--color-primary-300: 132 122 235;
|
|
131
|
-
--color-primary-400: 105 95 233;
|
|
132
|
-
--color-primary-500: 80 70 230;
|
|
133
|
-
--color-primary-600: 63 55 198;
|
|
134
|
-
--color-primary-700: 47 41 163;
|
|
135
|
-
--color-primary-800: 33 29 128;
|
|
136
|
-
--color-primary-900: 22 20 96;
|
|
137
|
-
--color-primary-950: 13 11 64;
|
|
138
|
-
|
|
139
|
-
--color-secondary-0: 255 255 255;
|
|
140
|
-
--color-secondary-50: 241 241 243;
|
|
141
|
-
--color-secondary-100: 220 220 224;
|
|
142
|
-
--color-secondary-200: 186 186 194;
|
|
143
|
-
--color-secondary-300: 152 152 163;
|
|
144
|
-
--color-secondary-400: 121 121 137;
|
|
145
|
-
--color-secondary-500: 92 92 112;
|
|
146
|
-
--color-secondary-600: 72 72 92;
|
|
147
|
-
--color-secondary-700: 54 54 72;
|
|
148
|
-
--color-secondary-800: 38 38 54;
|
|
149
|
-
--color-secondary-900: 24 24 38;
|
|
150
|
-
--color-secondary-950: 14 14 24;
|
|
151
|
-
|
|
152
|
-
--color-tertiary-50: 250 245 255;
|
|
153
|
-
--color-tertiary-100: 243 232 255;
|
|
154
|
-
--color-tertiary-200: 222 200 252;
|
|
155
|
-
--color-tertiary-300: 196 160 246;
|
|
156
|
-
--color-tertiary-400: 168 120 238;
|
|
157
|
-
--color-tertiary-500: 140 80 228;
|
|
158
|
-
--color-tertiary-600: 114 58 200;
|
|
159
|
-
--color-tertiary-700: 90 40 170;
|
|
160
|
-
--color-tertiary-800: 68 28 138;
|
|
161
|
-
--color-tertiary-900: 48 18 106;
|
|
162
|
-
--color-tertiary-950: 30 8 72;
|
|
163
|
-
|
|
164
|
-
--color-error-0: 255 255 255;
|
|
165
|
-
--color-error-50: 254 242 242;
|
|
166
|
-
--color-error-100: 254 226 226;
|
|
167
|
-
--color-error-200: 252 165 165;
|
|
168
|
-
--color-error-300: 248 113 113;
|
|
169
|
-
--color-error-400: 240 82 82;
|
|
170
|
-
--color-error-500: 230 53 53;
|
|
171
|
-
--color-error-600: 204 37 37;
|
|
172
|
-
--color-error-700: 178 24 24;
|
|
173
|
-
--color-error-800: 150 16 16;
|
|
174
|
-
--color-error-900: 122 10 10;
|
|
175
|
-
--color-error-950: 80 5 5;
|
|
176
|
-
|
|
177
|
-
--color-success-0: 255 255 255;
|
|
178
|
-
--color-success-50: 237 252 241;
|
|
179
|
-
--color-success-100: 210 245 221;
|
|
180
|
-
--color-success-200: 147 226 172;
|
|
181
|
-
--color-success-300: 96 207 128;
|
|
182
|
-
--color-success-400: 56 189 92;
|
|
183
|
-
--color-success-500: 34 168 66;
|
|
184
|
-
--color-success-600: 24 140 52;
|
|
185
|
-
--color-success-700: 18 112 40;
|
|
186
|
-
--color-success-800: 14 88 32;
|
|
187
|
-
--color-success-900: 10 64 22;
|
|
188
|
-
--color-success-950: 5 40 12;
|
|
189
|
-
|
|
190
|
-
--color-warning-0: 255 255 255;
|
|
191
|
-
--color-warning-50: 255 249 235;
|
|
192
|
-
--color-warning-100: 255 240 198;
|
|
193
|
-
--color-warning-200: 252 217 119;
|
|
194
|
-
--color-warning-300: 247 195 56;
|
|
195
|
-
--color-warning-400: 240 176 14;
|
|
196
|
-
--color-warning-500: 220 155 6;
|
|
197
|
-
--color-warning-600: 182 123 4;
|
|
198
|
-
--color-warning-700: 145 96 4;
|
|
199
|
-
--color-warning-800: 112 72 5;
|
|
200
|
-
--color-warning-900: 82 52 6;
|
|
201
|
-
--color-warning-950: 48 30 4;
|
|
202
|
-
|
|
203
|
-
--color-info-0: 255 255 255;
|
|
204
|
-
--color-info-50: 240 248 255;
|
|
205
|
-
--color-info-100: 224 240 253;
|
|
206
|
-
--color-info-200: 168 213 248;
|
|
207
|
-
--color-info-300: 110 184 240;
|
|
208
|
-
--color-info-400: 66 158 232;
|
|
209
|
-
--color-info-500: 34 134 220;
|
|
210
|
-
--color-info-600: 22 110 190;
|
|
211
|
-
--color-info-700: 14 88 158;
|
|
212
|
-
--color-info-800: 10 68 126;
|
|
213
|
-
--color-info-900: 6 50 96;
|
|
214
|
-
--color-info-950: 2 32 64;
|
|
215
|
-
|
|
216
|
-
--color-typography-0: 255 255 255;
|
|
217
|
-
--color-typography-50: 245 245 245;
|
|
218
|
-
--color-typography-100: 229 229 229;
|
|
219
|
-
--color-typography-200: 212 212 212;
|
|
220
|
-
--color-typography-300: 163 163 163;
|
|
221
|
-
--color-typography-400: 140 140 140;
|
|
222
|
-
--color-typography-500: 115 115 115;
|
|
223
|
-
--color-typography-600: 82 82 82;
|
|
224
|
-
--color-typography-700: 64 64 64;
|
|
225
|
-
--color-typography-800: 38 38 38;
|
|
226
|
-
--color-typography-900: 23 23 23;
|
|
227
|
-
--color-typography-950: 10 10 10;
|
|
228
|
-
|
|
229
|
-
--color-outline-0: 255 255 255;
|
|
230
|
-
--color-outline-50: 245 245 245;
|
|
231
|
-
--color-outline-100: 229 229 229;
|
|
232
|
-
--color-outline-200: 212 212 212;
|
|
233
|
-
--color-outline-300: 196 196 196;
|
|
234
|
-
--color-outline-400: 163 163 163;
|
|
235
|
-
--color-outline-500: 140 140 140;
|
|
236
|
-
--color-outline-600: 115 115 115;
|
|
237
|
-
--color-outline-700: 82 82 82;
|
|
238
|
-
--color-outline-800: 51 51 51;
|
|
239
|
-
--color-outline-900: 33 33 33;
|
|
240
|
-
--color-outline-950: 18 18 18;
|
|
241
|
-
|
|
242
|
-
--color-background-0: 255 255 255;
|
|
243
|
-
--color-background-50: 249 249 249;
|
|
244
|
-
--color-background-100: 242 242 242;
|
|
245
|
-
--color-background-200: 228 228 228;
|
|
246
|
-
--color-background-300: 212 212 212;
|
|
247
|
-
--color-background-400: 189 189 189;
|
|
248
|
-
--color-background-500: 163 163 163;
|
|
249
|
-
--color-background-600: 115 115 115;
|
|
250
|
-
--color-background-700: 82 82 82;
|
|
251
|
-
--color-background-800: 51 51 51;
|
|
252
|
-
--color-background-900: 33 33 33;
|
|
253
|
-
--color-background-950: 18 18 18;
|
|
254
|
-
--color-background-error: 254 226 226;
|
|
255
|
-
--color-background-warning: 255 243 224;
|
|
256
|
-
--color-background-muted: 245 245 245;
|
|
257
|
-
--color-background-success: 228 247 235;
|
|
258
|
-
--color-background-info: 224 240 253;
|
|
259
|
-
|
|
260
|
-
--color-indicator-primary: 80 70 230;
|
|
261
|
-
--color-indicator-info: 34 134 220;
|
|
262
|
-
--color-indicator-error: 230 53 53;
|
|
263
|
-
}
|
|
264
|
-
`;
|
|
265
|
-
|
|
266
|
-
writeIfMissing("global.css", globalCss);
|
|
267
|
-
|
|
268
|
-
// ── 5. Create nativewind-env.d.ts ──────────────────────────────────────────
|
|
269
|
-
writeIfMissing(
|
|
270
|
-
"nativewind-env.d.ts",
|
|
271
|
-
'/// <reference types="nativewind/types" />\n',
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
// ── 6. Create/update metro.config.js ───────────────────────────────────────
|
|
275
|
-
const metroConfig = `const { getDefaultConfig } = require("expo/metro-config");
|
|
276
|
-
const { withNativeWind } = require("nativewind/metro");
|
|
277
|
-
|
|
278
|
-
const config = getDefaultConfig(__dirname);
|
|
279
|
-
|
|
280
|
-
module.exports = withNativeWind(config, { input: "./global.css" });
|
|
281
|
-
`;
|
|
282
|
-
|
|
283
|
-
writeFile("metro.config.js", metroConfig);
|
|
284
|
-
|
|
285
|
-
// ── 7. Create/update babel.config.js ───────────────────────────────────────
|
|
286
|
-
const babelConfig = `module.exports = function (api) {
|
|
287
|
-
api.cache(true);
|
|
288
|
-
return {
|
|
289
|
-
presets: [
|
|
290
|
-
["babel-preset-expo", { jsxImportSource: "nativewind" }],
|
|
291
|
-
"nativewind/babel",
|
|
292
|
-
],
|
|
293
|
-
};
|
|
294
|
-
};
|
|
295
|
-
`;
|
|
296
|
-
|
|
297
|
-
writeFile("babel.config.js", babelConfig);
|
|
298
|
-
|
|
299
|
-
// ── 8. Create the demo App.tsx ─────────────────────────────────────────────
|
|
300
|
-
const appTsx = `import "./global.css";
|
|
301
|
-
import React, { useState } from "react";
|
|
302
|
-
import { View, Text } from "react-native";
|
|
303
|
-
import {
|
|
304
|
-
Slider,
|
|
305
|
-
SliderTrack,
|
|
306
|
-
SliderFilledTrack,
|
|
307
|
-
SliderThumb,
|
|
308
|
-
} from "@wireservers-ui/react-natives";
|
|
309
|
-
|
|
310
|
-
export default function App() {
|
|
311
|
-
const [volume, setVolume] = useState(50);
|
|
312
|
-
|
|
313
|
-
return (
|
|
314
|
-
<View className="flex-1 items-center justify-center bg-background-0 px-8">
|
|
315
|
-
<Text className="text-2xl font-bold text-typography-900 mb-2">
|
|
316
|
-
Volume Control
|
|
317
|
-
</Text>
|
|
318
|
-
<Text className="text-lg text-typography-500 mb-8">
|
|
319
|
-
{volume}%
|
|
320
|
-
</Text>
|
|
321
|
-
<View className="w-full max-w-xs">
|
|
322
|
-
<Slider
|
|
323
|
-
value={volume}
|
|
324
|
-
onValueChange={setVolume}
|
|
325
|
-
min={0}
|
|
326
|
-
max={100}
|
|
327
|
-
size="lg"
|
|
328
|
-
>
|
|
329
|
-
<SliderTrack>
|
|
330
|
-
<SliderFilledTrack />
|
|
331
|
-
</SliderTrack>
|
|
332
|
-
<SliderThumb />
|
|
333
|
-
</Slider>
|
|
334
|
-
</View>
|
|
335
|
-
<Text className="text-sm text-typography-400 mt-6">
|
|
336
|
-
Drag the slider to adjust volume
|
|
337
|
-
</Text>
|
|
338
|
-
</View>
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
`;
|
|
342
|
-
|
|
343
|
-
writeFile("App.tsx", appTsx);
|
|
344
|
-
|
|
345
|
-
// ── Done ───────────────────────────────────────────────────────────────────
|
|
346
|
-
console.log("\n✅ Setup complete!\n");
|
|
347
|
-
console.log(" Created if missing (existing files were preserved):");
|
|
348
|
-
console.log(" • tailwind.config.js");
|
|
349
|
-
console.log(" • global.css (with theme variables)");
|
|
350
|
-
console.log(" • nativewind-env.d.ts");
|
|
351
|
-
console.log(" • metro.config.js");
|
|
352
|
-
console.log(" • babel.config.js");
|
|
353
|
-
console.log(" • App.tsx (volume slider demo)");
|
|
354
|
-
console.log("\n Run your app:\n");
|
|
355
|
-
console.log(" npx expo start --clear\n");
|
|
356
|
-
|
|
357
|
-
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
358
|
-
function writeFile(name, content) {
|
|
359
|
-
const filePath = path.join(cwd, name);
|
|
360
|
-
if (fs.existsSync(filePath)) {
|
|
361
|
-
console.log(` ⏭️ ${name} already exists, skipping`);
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
fs.writeFileSync(filePath, content, "utf8");
|
|
365
|
-
console.log(` ✏️ Created ${name}`);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
function writeIfMissing(name, content) {
|
|
369
|
-
const filePath = path.join(cwd, name);
|
|
370
|
-
if (fs.existsSync(filePath)) {
|
|
371
|
-
console.log(` ⏭️ ${name} already exists, skipping`);
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
fs.writeFileSync(filePath, content, "utf8");
|
|
375
|
-
console.log(` ✏️ Created ${name}`);
|
|
376
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync } = require("child_process");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const command = args[0];
|
|
9
|
+
|
|
10
|
+
if (command !== "init") {
|
|
11
|
+
console.error(`Unknown command: ${command}`);
|
|
12
|
+
console.error("Usage: npx @wireservers-ui/react-natives init");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const cwd = process.cwd();
|
|
17
|
+
|
|
18
|
+
// ── Detect package manager ─────────────────────────────────────────────────
|
|
19
|
+
function detectPackageManager() {
|
|
20
|
+
if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
21
|
+
if (fs.existsSync(path.join(cwd, "yarn.lock"))) return "yarn";
|
|
22
|
+
if (fs.existsSync(path.join(cwd, "bun.lockb"))) return "bun";
|
|
23
|
+
return "npm";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const pm = detectPackageManager();
|
|
27
|
+
const installCmd = pm === "yarn" ? "yarn add" : `${pm} install`;
|
|
28
|
+
let needsReinstall = false;
|
|
29
|
+
|
|
30
|
+
function getInstalledReactVersion() {
|
|
31
|
+
const reactPkgPath = path.join(cwd, "node_modules", "react", "package.json");
|
|
32
|
+
if (!fs.existsSync(reactPkgPath)) return null;
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const reactPkg = JSON.parse(fs.readFileSync(reactPkgPath, "utf8"));
|
|
36
|
+
return typeof reactPkg.version === "string" ? reactPkg.version : null;
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
console.log(`\n🚀 Initializing @wireservers-ui/react-natives...\n`);
|
|
43
|
+
console.log(` Package manager: ${pm}`);
|
|
44
|
+
|
|
45
|
+
// ── 0. Create .npmrc for pnpm (Metro needs hoisted modules) ────────────────
|
|
46
|
+
if (pm === "pnpm") {
|
|
47
|
+
const npmrcPath = path.join(cwd, ".npmrc");
|
|
48
|
+
const npmrcLine = "node-linker=hoisted";
|
|
49
|
+
if (fs.existsSync(npmrcPath)) {
|
|
50
|
+
const existing = fs.readFileSync(npmrcPath, "utf8");
|
|
51
|
+
if (!existing.includes("node-linker")) {
|
|
52
|
+
fs.appendFileSync(npmrcPath, `\n${npmrcLine}\n`, "utf8");
|
|
53
|
+
console.log(
|
|
54
|
+
" ✏️ Added node-linker=hoisted to .npmrc (required by Metro)",
|
|
55
|
+
);
|
|
56
|
+
needsReinstall = true;
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
fs.writeFileSync(npmrcPath, `${npmrcLine}\n`, "utf8");
|
|
60
|
+
console.log(
|
|
61
|
+
" ✏️ Created .npmrc with node-linker=hoisted (required by Metro)",
|
|
62
|
+
);
|
|
63
|
+
needsReinstall = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ── 1. Re-install with hoisted layout (pnpm only) ─────────────────────────
|
|
68
|
+
if (needsReinstall) {
|
|
69
|
+
console.log("\n📦 Re-installing with hoisted node_modules...\n");
|
|
70
|
+
try {
|
|
71
|
+
execSync(`${pm} install`, { cwd, stdio: "inherit" });
|
|
72
|
+
} catch {
|
|
73
|
+
console.error("Failed to reinstall. Run `pnpm install` manually.");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ── 2. Install peer dependencies ───────────────────────────────────────────
|
|
78
|
+
console.log("\n📦 Installing peer dependencies...\n");
|
|
79
|
+
const reactVersion = getInstalledReactVersion();
|
|
80
|
+
const reactDomPackage = reactVersion
|
|
81
|
+
? `react-dom@${reactVersion}`
|
|
82
|
+
: "react-dom";
|
|
83
|
+
|
|
84
|
+
const peers = [
|
|
85
|
+
"nativewind@^4",
|
|
86
|
+
"tailwindcss@^3",
|
|
87
|
+
"tailwind-variants",
|
|
88
|
+
"tailwind-merge",
|
|
89
|
+
"react-native-reanimated",
|
|
90
|
+
"react-native-worklets",
|
|
91
|
+
"react-native-svg",
|
|
92
|
+
reactDomPackage,
|
|
93
|
+
"react-native-web",
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
execSync(`${installCmd} ${peers.join(" ")}`, { cwd, stdio: "inherit" });
|
|
98
|
+
} catch {
|
|
99
|
+
console.error(
|
|
100
|
+
"Failed to install peer dependencies. You may need to install them manually:",
|
|
101
|
+
);
|
|
102
|
+
console.error(` ${installCmd} ${peers.join(" ")}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ── 3. Create tailwind.config.js ───────────────────────────────────────────
|
|
106
|
+
const tailwindConfig = `/** @type {import('tailwindcss').Config} */
|
|
107
|
+
module.exports = {
|
|
108
|
+
content: [
|
|
109
|
+
"./App.{js,jsx,ts,tsx}",
|
|
110
|
+
"./app/**/*.{js,jsx,ts,tsx}",
|
|
111
|
+
"./components/**/*.{js,jsx,ts,tsx}",
|
|
112
|
+
"./node_modules/@wireservers-ui/react-natives/src/**/*.{js,jsx,ts,tsx}",
|
|
113
|
+
],
|
|
114
|
+
presets: [require("@wireservers-ui/react-natives/tailwind-preset")],
|
|
115
|
+
};
|
|
116
|
+
`;
|
|
117
|
+
|
|
118
|
+
writeIfMissing("tailwind.config.js", tailwindConfig);
|
|
119
|
+
|
|
120
|
+
// ── 4. Create global.css ───────────────────────────────────────────────────
|
|
121
|
+
const globalCss = `@tailwind base;
|
|
122
|
+
@tailwind components;
|
|
123
|
+
@tailwind utilities;
|
|
124
|
+
|
|
125
|
+
:root {
|
|
126
|
+
--color-primary-0: 255 255 255;
|
|
127
|
+
--color-primary-50: 238 237 253;
|
|
128
|
+
--color-primary-100: 214 211 249;
|
|
129
|
+
--color-primary-200: 172 166 242;
|
|
130
|
+
--color-primary-300: 132 122 235;
|
|
131
|
+
--color-primary-400: 105 95 233;
|
|
132
|
+
--color-primary-500: 80 70 230;
|
|
133
|
+
--color-primary-600: 63 55 198;
|
|
134
|
+
--color-primary-700: 47 41 163;
|
|
135
|
+
--color-primary-800: 33 29 128;
|
|
136
|
+
--color-primary-900: 22 20 96;
|
|
137
|
+
--color-primary-950: 13 11 64;
|
|
138
|
+
|
|
139
|
+
--color-secondary-0: 255 255 255;
|
|
140
|
+
--color-secondary-50: 241 241 243;
|
|
141
|
+
--color-secondary-100: 220 220 224;
|
|
142
|
+
--color-secondary-200: 186 186 194;
|
|
143
|
+
--color-secondary-300: 152 152 163;
|
|
144
|
+
--color-secondary-400: 121 121 137;
|
|
145
|
+
--color-secondary-500: 92 92 112;
|
|
146
|
+
--color-secondary-600: 72 72 92;
|
|
147
|
+
--color-secondary-700: 54 54 72;
|
|
148
|
+
--color-secondary-800: 38 38 54;
|
|
149
|
+
--color-secondary-900: 24 24 38;
|
|
150
|
+
--color-secondary-950: 14 14 24;
|
|
151
|
+
|
|
152
|
+
--color-tertiary-50: 250 245 255;
|
|
153
|
+
--color-tertiary-100: 243 232 255;
|
|
154
|
+
--color-tertiary-200: 222 200 252;
|
|
155
|
+
--color-tertiary-300: 196 160 246;
|
|
156
|
+
--color-tertiary-400: 168 120 238;
|
|
157
|
+
--color-tertiary-500: 140 80 228;
|
|
158
|
+
--color-tertiary-600: 114 58 200;
|
|
159
|
+
--color-tertiary-700: 90 40 170;
|
|
160
|
+
--color-tertiary-800: 68 28 138;
|
|
161
|
+
--color-tertiary-900: 48 18 106;
|
|
162
|
+
--color-tertiary-950: 30 8 72;
|
|
163
|
+
|
|
164
|
+
--color-error-0: 255 255 255;
|
|
165
|
+
--color-error-50: 254 242 242;
|
|
166
|
+
--color-error-100: 254 226 226;
|
|
167
|
+
--color-error-200: 252 165 165;
|
|
168
|
+
--color-error-300: 248 113 113;
|
|
169
|
+
--color-error-400: 240 82 82;
|
|
170
|
+
--color-error-500: 230 53 53;
|
|
171
|
+
--color-error-600: 204 37 37;
|
|
172
|
+
--color-error-700: 178 24 24;
|
|
173
|
+
--color-error-800: 150 16 16;
|
|
174
|
+
--color-error-900: 122 10 10;
|
|
175
|
+
--color-error-950: 80 5 5;
|
|
176
|
+
|
|
177
|
+
--color-success-0: 255 255 255;
|
|
178
|
+
--color-success-50: 237 252 241;
|
|
179
|
+
--color-success-100: 210 245 221;
|
|
180
|
+
--color-success-200: 147 226 172;
|
|
181
|
+
--color-success-300: 96 207 128;
|
|
182
|
+
--color-success-400: 56 189 92;
|
|
183
|
+
--color-success-500: 34 168 66;
|
|
184
|
+
--color-success-600: 24 140 52;
|
|
185
|
+
--color-success-700: 18 112 40;
|
|
186
|
+
--color-success-800: 14 88 32;
|
|
187
|
+
--color-success-900: 10 64 22;
|
|
188
|
+
--color-success-950: 5 40 12;
|
|
189
|
+
|
|
190
|
+
--color-warning-0: 255 255 255;
|
|
191
|
+
--color-warning-50: 255 249 235;
|
|
192
|
+
--color-warning-100: 255 240 198;
|
|
193
|
+
--color-warning-200: 252 217 119;
|
|
194
|
+
--color-warning-300: 247 195 56;
|
|
195
|
+
--color-warning-400: 240 176 14;
|
|
196
|
+
--color-warning-500: 220 155 6;
|
|
197
|
+
--color-warning-600: 182 123 4;
|
|
198
|
+
--color-warning-700: 145 96 4;
|
|
199
|
+
--color-warning-800: 112 72 5;
|
|
200
|
+
--color-warning-900: 82 52 6;
|
|
201
|
+
--color-warning-950: 48 30 4;
|
|
202
|
+
|
|
203
|
+
--color-info-0: 255 255 255;
|
|
204
|
+
--color-info-50: 240 248 255;
|
|
205
|
+
--color-info-100: 224 240 253;
|
|
206
|
+
--color-info-200: 168 213 248;
|
|
207
|
+
--color-info-300: 110 184 240;
|
|
208
|
+
--color-info-400: 66 158 232;
|
|
209
|
+
--color-info-500: 34 134 220;
|
|
210
|
+
--color-info-600: 22 110 190;
|
|
211
|
+
--color-info-700: 14 88 158;
|
|
212
|
+
--color-info-800: 10 68 126;
|
|
213
|
+
--color-info-900: 6 50 96;
|
|
214
|
+
--color-info-950: 2 32 64;
|
|
215
|
+
|
|
216
|
+
--color-typography-0: 255 255 255;
|
|
217
|
+
--color-typography-50: 245 245 245;
|
|
218
|
+
--color-typography-100: 229 229 229;
|
|
219
|
+
--color-typography-200: 212 212 212;
|
|
220
|
+
--color-typography-300: 163 163 163;
|
|
221
|
+
--color-typography-400: 140 140 140;
|
|
222
|
+
--color-typography-500: 115 115 115;
|
|
223
|
+
--color-typography-600: 82 82 82;
|
|
224
|
+
--color-typography-700: 64 64 64;
|
|
225
|
+
--color-typography-800: 38 38 38;
|
|
226
|
+
--color-typography-900: 23 23 23;
|
|
227
|
+
--color-typography-950: 10 10 10;
|
|
228
|
+
|
|
229
|
+
--color-outline-0: 255 255 255;
|
|
230
|
+
--color-outline-50: 245 245 245;
|
|
231
|
+
--color-outline-100: 229 229 229;
|
|
232
|
+
--color-outline-200: 212 212 212;
|
|
233
|
+
--color-outline-300: 196 196 196;
|
|
234
|
+
--color-outline-400: 163 163 163;
|
|
235
|
+
--color-outline-500: 140 140 140;
|
|
236
|
+
--color-outline-600: 115 115 115;
|
|
237
|
+
--color-outline-700: 82 82 82;
|
|
238
|
+
--color-outline-800: 51 51 51;
|
|
239
|
+
--color-outline-900: 33 33 33;
|
|
240
|
+
--color-outline-950: 18 18 18;
|
|
241
|
+
|
|
242
|
+
--color-background-0: 255 255 255;
|
|
243
|
+
--color-background-50: 249 249 249;
|
|
244
|
+
--color-background-100: 242 242 242;
|
|
245
|
+
--color-background-200: 228 228 228;
|
|
246
|
+
--color-background-300: 212 212 212;
|
|
247
|
+
--color-background-400: 189 189 189;
|
|
248
|
+
--color-background-500: 163 163 163;
|
|
249
|
+
--color-background-600: 115 115 115;
|
|
250
|
+
--color-background-700: 82 82 82;
|
|
251
|
+
--color-background-800: 51 51 51;
|
|
252
|
+
--color-background-900: 33 33 33;
|
|
253
|
+
--color-background-950: 18 18 18;
|
|
254
|
+
--color-background-error: 254 226 226;
|
|
255
|
+
--color-background-warning: 255 243 224;
|
|
256
|
+
--color-background-muted: 245 245 245;
|
|
257
|
+
--color-background-success: 228 247 235;
|
|
258
|
+
--color-background-info: 224 240 253;
|
|
259
|
+
|
|
260
|
+
--color-indicator-primary: 80 70 230;
|
|
261
|
+
--color-indicator-info: 34 134 220;
|
|
262
|
+
--color-indicator-error: 230 53 53;
|
|
263
|
+
}
|
|
264
|
+
`;
|
|
265
|
+
|
|
266
|
+
writeIfMissing("global.css", globalCss);
|
|
267
|
+
|
|
268
|
+
// ── 5. Create nativewind-env.d.ts ──────────────────────────────────────────
|
|
269
|
+
writeIfMissing(
|
|
270
|
+
"nativewind-env.d.ts",
|
|
271
|
+
'/// <reference types="nativewind/types" />\n',
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
// ── 6. Create/update metro.config.js ───────────────────────────────────────
|
|
275
|
+
const metroConfig = `const { getDefaultConfig } = require("expo/metro-config");
|
|
276
|
+
const { withNativeWind } = require("nativewind/metro");
|
|
277
|
+
|
|
278
|
+
const config = getDefaultConfig(__dirname);
|
|
279
|
+
|
|
280
|
+
module.exports = withNativeWind(config, { input: "./global.css" });
|
|
281
|
+
`;
|
|
282
|
+
|
|
283
|
+
writeFile("metro.config.js", metroConfig);
|
|
284
|
+
|
|
285
|
+
// ── 7. Create/update babel.config.js ───────────────────────────────────────
|
|
286
|
+
const babelConfig = `module.exports = function (api) {
|
|
287
|
+
api.cache(true);
|
|
288
|
+
return {
|
|
289
|
+
presets: [
|
|
290
|
+
["babel-preset-expo", { jsxImportSource: "nativewind" }],
|
|
291
|
+
"nativewind/babel",
|
|
292
|
+
],
|
|
293
|
+
};
|
|
294
|
+
};
|
|
295
|
+
`;
|
|
296
|
+
|
|
297
|
+
writeFile("babel.config.js", babelConfig);
|
|
298
|
+
|
|
299
|
+
// ── 8. Create the demo App.tsx ─────────────────────────────────────────────
|
|
300
|
+
const appTsx = `import "./global.css";
|
|
301
|
+
import React, { useState } from "react";
|
|
302
|
+
import { View, Text } from "react-native";
|
|
303
|
+
import {
|
|
304
|
+
Slider,
|
|
305
|
+
SliderTrack,
|
|
306
|
+
SliderFilledTrack,
|
|
307
|
+
SliderThumb,
|
|
308
|
+
} from "@wireservers-ui/react-natives";
|
|
309
|
+
|
|
310
|
+
export default function App() {
|
|
311
|
+
const [volume, setVolume] = useState(50);
|
|
312
|
+
|
|
313
|
+
return (
|
|
314
|
+
<View className="flex-1 items-center justify-center bg-background-0 px-8">
|
|
315
|
+
<Text className="text-2xl font-bold text-typography-900 mb-2">
|
|
316
|
+
Volume Control
|
|
317
|
+
</Text>
|
|
318
|
+
<Text className="text-lg text-typography-500 mb-8">
|
|
319
|
+
{volume}%
|
|
320
|
+
</Text>
|
|
321
|
+
<View className="w-full max-w-xs">
|
|
322
|
+
<Slider
|
|
323
|
+
value={volume}
|
|
324
|
+
onValueChange={setVolume}
|
|
325
|
+
min={0}
|
|
326
|
+
max={100}
|
|
327
|
+
size="lg"
|
|
328
|
+
>
|
|
329
|
+
<SliderTrack>
|
|
330
|
+
<SliderFilledTrack />
|
|
331
|
+
</SliderTrack>
|
|
332
|
+
<SliderThumb />
|
|
333
|
+
</Slider>
|
|
334
|
+
</View>
|
|
335
|
+
<Text className="text-sm text-typography-400 mt-6">
|
|
336
|
+
Drag the slider to adjust volume
|
|
337
|
+
</Text>
|
|
338
|
+
</View>
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
`;
|
|
342
|
+
|
|
343
|
+
writeFile("App.tsx", appTsx);
|
|
344
|
+
|
|
345
|
+
// ── Done ───────────────────────────────────────────────────────────────────
|
|
346
|
+
console.log("\n✅ Setup complete!\n");
|
|
347
|
+
console.log(" Created if missing (existing files were preserved):");
|
|
348
|
+
console.log(" • tailwind.config.js");
|
|
349
|
+
console.log(" • global.css (with theme variables)");
|
|
350
|
+
console.log(" • nativewind-env.d.ts");
|
|
351
|
+
console.log(" • metro.config.js");
|
|
352
|
+
console.log(" • babel.config.js");
|
|
353
|
+
console.log(" • App.tsx (volume slider demo)");
|
|
354
|
+
console.log("\n Run your app:\n");
|
|
355
|
+
console.log(" npx expo start --clear\n");
|
|
356
|
+
|
|
357
|
+
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
358
|
+
function writeFile(name, content) {
|
|
359
|
+
const filePath = path.join(cwd, name);
|
|
360
|
+
if (fs.existsSync(filePath)) {
|
|
361
|
+
console.log(` ⏭️ ${name} already exists, skipping`);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
fs.writeFileSync(filePath, content, "utf8");
|
|
365
|
+
console.log(` ✏️ Created ${name}`);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function writeIfMissing(name, content) {
|
|
369
|
+
const filePath = path.join(cwd, name);
|
|
370
|
+
if (fs.existsSync(filePath)) {
|
|
371
|
+
console.log(` ⏭️ ${name} already exists, skipping`);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
fs.writeFileSync(filePath, content, "utf8");
|
|
375
|
+
console.log(` ✏️ Created ${name}`);
|
|
376
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wireservers-ui/react-natives",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A comprehensive React Native component library built with NativeWind and Tailwind Variants",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"src",
|
|
9
9
|
"tailwind-preset.js",
|
|
10
|
-
"bin"
|
|
10
|
+
"bin",
|
|
11
|
+
"CHANGELOG.md"
|
|
11
12
|
],
|
|
12
13
|
"bin": {
|
|
13
14
|
"react-natives": "./bin/cli.js"
|
|
@@ -27,6 +28,9 @@
|
|
|
27
28
|
"directory": "packages/react-natives"
|
|
28
29
|
},
|
|
29
30
|
"license": "MIT",
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18.0.0"
|
|
33
|
+
},
|
|
30
34
|
"peerDependencies": {
|
|
31
35
|
"nativewind": ">=4.0.0",
|
|
32
36
|
"react": ">=18.0.0",
|