@mgcrea/react-native-tailwind 0.4.0 → 0.5.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 +527 -136
- package/dist/babel/index.cjs +767 -274
- package/dist/babel/index.d.ts +2 -1
- package/dist/babel/index.ts +319 -16
- package/dist/components/Pressable.d.ts +32 -0
- package/dist/components/Pressable.js +1 -0
- package/dist/components/TextInput.d.ts +56 -0
- package/dist/components/TextInput.js +1 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.js +1 -1
- package/dist/parser/aspectRatio.d.ts +16 -0
- package/dist/parser/aspectRatio.js +1 -0
- package/dist/parser/aspectRatio.test.d.ts +1 -0
- package/dist/parser/aspectRatio.test.js +1 -0
- package/dist/parser/borders.js +1 -1
- package/dist/parser/borders.test.d.ts +1 -0
- package/dist/parser/borders.test.js +1 -0
- package/dist/parser/colors.d.ts +1 -0
- package/dist/parser/colors.js +1 -1
- package/dist/parser/colors.test.d.ts +1 -0
- package/dist/parser/colors.test.js +1 -0
- package/dist/parser/index.d.ts +4 -0
- package/dist/parser/index.js +1 -1
- package/dist/parser/layout.d.ts +2 -0
- package/dist/parser/layout.js +1 -1
- package/dist/parser/layout.test.d.ts +1 -0
- package/dist/parser/layout.test.js +1 -0
- package/dist/parser/modifiers.d.ts +47 -0
- package/dist/parser/modifiers.js +1 -0
- package/dist/parser/modifiers.test.d.ts +1 -0
- package/dist/parser/modifiers.test.js +1 -0
- package/dist/parser/shadows.d.ts +22 -0
- package/dist/parser/shadows.js +1 -0
- package/dist/parser/shadows.test.d.ts +1 -0
- package/dist/parser/shadows.test.js +1 -0
- package/dist/parser/sizing.test.d.ts +1 -0
- package/dist/parser/sizing.test.js +1 -0
- package/dist/parser/spacing.d.ts +1 -1
- package/dist/parser/spacing.js +1 -1
- package/dist/parser/spacing.test.d.ts +1 -0
- package/dist/parser/spacing.test.js +1 -0
- package/dist/parser/typography.d.ts +2 -1
- package/dist/parser/typography.js +1 -1
- package/dist/parser/typography.test.d.ts +1 -0
- package/dist/parser/typography.test.js +1 -0
- package/dist/types.d.ts +4 -3
- package/package.json +7 -6
- package/src/babel/index.ts +319 -16
- package/src/components/Pressable.tsx +46 -0
- package/src/components/TextInput.tsx +90 -0
- package/src/index.ts +20 -2
- package/src/parser/aspectRatio.test.ts +191 -0
- package/src/parser/aspectRatio.ts +73 -0
- package/src/parser/borders.test.ts +329 -0
- package/src/parser/borders.ts +187 -108
- package/src/parser/colors.test.ts +335 -0
- package/src/parser/colors.ts +117 -6
- package/src/parser/index.ts +13 -2
- package/src/parser/layout.test.ts +459 -0
- package/src/parser/layout.ts +128 -0
- package/src/parser/modifiers.test.ts +375 -0
- package/src/parser/modifiers.ts +104 -0
- package/src/parser/shadows.test.ts +192 -0
- package/src/parser/shadows.ts +84 -0
- package/src/parser/sizing.test.ts +256 -0
- package/src/parser/spacing.test.ts +226 -0
- package/src/parser/spacing.ts +93 -138
- package/src/parser/typography.test.ts +221 -0
- package/src/parser/typography.ts +143 -112
- package/src/types.ts +1 -3
- package/dist/react-native.d.js +0 -1
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/@mgcrea/react-native-tailwind)
|
|
6
6
|
[](https://www.npmjs.com/package/@mgcrea/react-native-tailwind)
|
|
7
7
|
[](https://github.com/mgcrea/react-native-tailwind/blob/main/LICENSE)
|
|
8
|
+
[](https://github.com/mgcrea/react-native-tailwind/actions/workflows/main.yaml)
|
|
8
9
|
|
|
9
10
|
</div>
|
|
10
11
|
|
|
@@ -15,14 +16,15 @@ Compile-time Tailwind CSS for React Native with zero runtime overhead. Transform
|
|
|
15
16
|
## Features
|
|
16
17
|
|
|
17
18
|
- ⚡ **Zero runtime overhead** — All transformations happen at compile time
|
|
18
|
-
-
|
|
19
|
+
- 🔧 **No dependencies** — Direct-to-React-Native style generation without tailwindcss package
|
|
20
|
+
- 🎯 **Babel-only setup** — No Metro configuration required
|
|
19
21
|
- 📝 **TypeScript-first** — Full type safety and autocomplete support
|
|
20
|
-
- 🚀 **Optimized performance** —
|
|
22
|
+
- 🚀 **Optimized performance** — Compiles down to `StyleSheet.create` for optimal performance
|
|
21
23
|
- 📦 **Small bundle size** — Only includes actual styles used in your app
|
|
22
|
-
- 🔧 **No dependencies** — Direct-to-React-Native style generation without tailwindcss package
|
|
23
24
|
- 🎨 **Custom colors** — Extend the default palette via `tailwind.config.*`
|
|
24
25
|
- 📐 **Arbitrary values** — Use custom sizes and borders: `w-[123px]`, `rounded-[20px]`
|
|
25
26
|
- 🔀 **Dynamic className** — Conditional styles with hybrid compile-time optimization
|
|
27
|
+
- 🎯 **State modifiers** — `active:`, `hover:`, `focus:`, and `disabled:` modifiers for interactive components
|
|
26
28
|
- 📜 **Special style props** — Support for `contentContainerClassName`, `columnWrapperClassName`, and more
|
|
27
29
|
|
|
28
30
|
## Installation
|
|
@@ -120,102 +122,6 @@ const _twStyles = StyleSheet.create({
|
|
|
120
122
|
});
|
|
121
123
|
```
|
|
122
124
|
|
|
123
|
-
## API Reference
|
|
124
|
-
|
|
125
|
-
### Spacing
|
|
126
|
-
|
|
127
|
-
**Margin & Padding:**
|
|
128
|
-
|
|
129
|
-
- `m-{size}`, `p-{size}` — All sides
|
|
130
|
-
- `mx-{size}`, `my-{size}`, `px-{size}`, `py-{size}` — Horizontal/vertical
|
|
131
|
-
- `mt-{size}`, `mr-{size}`, `mb-{size}`, `ml-{size}` — Directional margin
|
|
132
|
-
- `pt-{size}`, `pr-{size}`, `pb-{size}`, `pl-{size}` — Directional padding
|
|
133
|
-
- `gap-{size}` — Gap between flex items
|
|
134
|
-
|
|
135
|
-
**Available sizes:** `0`, `0.5`, `1`, `1.5`, `2`, `2.5`, `3`, `3.5`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `14`, `16`, `20`, `24`, `28`, `32`, `36`, `40`, `44`, `48`, `52`, `56`, `60`, `64`, `72`, `80`, `96`
|
|
136
|
-
|
|
137
|
-
### Layout
|
|
138
|
-
|
|
139
|
-
**Flexbox:**
|
|
140
|
-
|
|
141
|
-
- `flex`, `flex-1`, `flex-auto`, `flex-none` — Flex sizing
|
|
142
|
-
- `flex-row`, `flex-row-reverse`, `flex-col`, `flex-col-reverse` — Direction
|
|
143
|
-
- `flex-wrap`, `flex-wrap-reverse`, `flex-nowrap` — Wrapping
|
|
144
|
-
- `items-start`, `items-end`, `items-center`, `items-baseline`, `items-stretch` — Align items
|
|
145
|
-
- `justify-start`, `justify-end`, `justify-center`, `justify-between`, `justify-around`, `justify-evenly` — Justify content
|
|
146
|
-
- `self-auto`, `self-start`, `self-end`, `self-center`, `self-stretch`, `self-baseline` — Align self
|
|
147
|
-
- `grow`, `grow-0`, `shrink`, `shrink-0` — Flex grow/shrink
|
|
148
|
-
|
|
149
|
-
**Other:**
|
|
150
|
-
|
|
151
|
-
- `absolute`, `relative` — Position
|
|
152
|
-
- `overflow-hidden`, `overflow-visible`, `overflow-scroll` — Overflow
|
|
153
|
-
- `flex`, `hidden` — Display
|
|
154
|
-
|
|
155
|
-
### Colors
|
|
156
|
-
|
|
157
|
-
- `bg-{color}-{shade}` — Background color
|
|
158
|
-
- `text-{color}-{shade}` — Text color
|
|
159
|
-
- `border-{color}-{shade}` — Border color
|
|
160
|
-
|
|
161
|
-
**Available colors:** `gray`, `red`, `blue`, `green`, `yellow`, `purple`, `pink`, `orange`, `indigo`, `white`, `black`, `transparent`
|
|
162
|
-
|
|
163
|
-
**Available shades:** `50`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`
|
|
164
|
-
|
|
165
|
-
> **Note:** You can extend the color palette with custom colors via `tailwind.config.*` — see [Custom Colors](#custom-colors)
|
|
166
|
-
|
|
167
|
-
### Typography
|
|
168
|
-
|
|
169
|
-
**Font Size:**
|
|
170
|
-
|
|
171
|
-
`text-xs`, `text-sm`, `text-base`, `text-lg`, `text-xl`, `text-2xl`, `text-3xl`, `text-4xl`, `text-5xl`, `text-6xl`, `text-7xl`, `text-8xl`, `text-9xl`
|
|
172
|
-
|
|
173
|
-
**Font Weight:**
|
|
174
|
-
|
|
175
|
-
`font-thin`, `font-extralight`, `font-light`, `font-normal`, `font-medium`, `font-semibold`, `font-bold`, `font-extrabold`, `font-black`
|
|
176
|
-
|
|
177
|
-
**Other:**
|
|
178
|
-
|
|
179
|
-
- `italic`, `not-italic` — Font style
|
|
180
|
-
- `text-left`, `text-center`, `text-right`, `text-justify` — Text alignment
|
|
181
|
-
- `underline`, `line-through`, `no-underline` — Text decoration
|
|
182
|
-
- `uppercase`, `lowercase`, `capitalize`, `normal-case` — Text transform
|
|
183
|
-
- `leading-none`, `leading-tight`, `leading-snug`, `leading-normal`, `leading-relaxed`, `leading-loose` — Line height
|
|
184
|
-
|
|
185
|
-
### Borders
|
|
186
|
-
|
|
187
|
-
**Width:**
|
|
188
|
-
|
|
189
|
-
- `border`, `border-0`, `border-2`, `border-4`, `border-8` — All sides
|
|
190
|
-
- `border-t`, `border-r`, `border-b`, `border-l` (with variants `-0`, `-2`, `-4`, `-8`) — Directional
|
|
191
|
-
- `border-[8px]`, `border-t-[12px]` — Arbitrary values
|
|
192
|
-
|
|
193
|
-
**Radius:**
|
|
194
|
-
|
|
195
|
-
- `rounded-none`, `rounded-sm`, `rounded`, `rounded-md`, `rounded-lg`, `rounded-xl`, `rounded-2xl`, `rounded-3xl`, `rounded-full` — All corners
|
|
196
|
-
- `rounded-t`, `rounded-r`, `rounded-b`, `rounded-l` (with size variants) — Directional
|
|
197
|
-
- `rounded-tl`, `rounded-tr`, `rounded-bl`, `rounded-br` (with size variants) — Individual corners
|
|
198
|
-
- `rounded-[12px]`, `rounded-t-[8px]`, `rounded-tl-[16px]` — Arbitrary values
|
|
199
|
-
|
|
200
|
-
**Style:**
|
|
201
|
-
|
|
202
|
-
`border-solid`, `border-dotted`, `border-dashed`
|
|
203
|
-
|
|
204
|
-
### Sizing
|
|
205
|
-
|
|
206
|
-
- `w-{size}`, `h-{size}` — Width/height
|
|
207
|
-
- `min-w-{size}`, `min-h-{size}` — Min width/height
|
|
208
|
-
- `max-w-{size}`, `max-h-{size}` — Max width/height
|
|
209
|
-
|
|
210
|
-
**Available sizes:**
|
|
211
|
-
|
|
212
|
-
- **Numeric:** `0`-`96` (same as spacing scale)
|
|
213
|
-
- **Fractional:** `1/2`, `1/3`, `2/3`, `1/4`, `3/4`, `1/5`, `2/5`, `3/5`, `4/5`, `1/6`, `2/6`, `3/6`, `4/6`, `5/6`
|
|
214
|
-
- **Special:** `full` (100%), `auto`
|
|
215
|
-
- **Arbitrary:** `w-[123px]`, `h-[50%]`, `min-w-[200px]`, `max-h-[80%]`
|
|
216
|
-
|
|
217
|
-
> **Note:** Arbitrary sizing supports pixel values (`[123px]` or `[123]`) and percentages (`[50%]`). Other units (`rem`, `em`, `vh`, `vw`) are not supported in React Native.
|
|
218
|
-
|
|
219
125
|
## Usage Examples
|
|
220
126
|
|
|
221
127
|
### Basic Example
|
|
@@ -235,14 +141,18 @@ export function MyComponent() {
|
|
|
235
141
|
### Card Component
|
|
236
142
|
|
|
237
143
|
```tsx
|
|
238
|
-
import { View, Text
|
|
144
|
+
import { View, Text } from "react-native";
|
|
145
|
+
import { Pressable } from "@mgcrea/react-native-tailwind";
|
|
239
146
|
|
|
240
147
|
export function Card({ title, description, onPress }) {
|
|
241
148
|
return (
|
|
242
149
|
<View className="bg-white rounded-lg p-6 mb-4 border border-gray-200">
|
|
243
150
|
<Text className="text-xl font-semibold text-gray-900 mb-2">{title}</Text>
|
|
244
151
|
<Text className="text-base text-gray-600 mb-4">{description}</Text>
|
|
245
|
-
<Pressable
|
|
152
|
+
<Pressable
|
|
153
|
+
className="bg-blue-500 active:bg-blue-700 px-4 py-2 rounded-lg items-center"
|
|
154
|
+
onPress={onPress}
|
|
155
|
+
>
|
|
246
156
|
<Text className="text-white font-semibold">Learn More</Text>
|
|
247
157
|
</Pressable>
|
|
248
158
|
</View>
|
|
@@ -368,6 +278,177 @@ The Babel plugin will merge them:
|
|
|
368
278
|
</View>
|
|
369
279
|
```
|
|
370
280
|
|
|
281
|
+
### State Modifiers
|
|
282
|
+
|
|
283
|
+
Apply styles based on component state with zero runtime overhead. The Babel plugin automatically generates optimized style functions.
|
|
284
|
+
|
|
285
|
+
#### Active Modifier (Pressable)
|
|
286
|
+
|
|
287
|
+
Use the `active:` modifier to apply styles when a `Pressable` component is pressed. **Requires using the enhanced `Pressable` component from this package.**
|
|
288
|
+
|
|
289
|
+
**Basic Example:**
|
|
290
|
+
|
|
291
|
+
```tsx
|
|
292
|
+
import { Text } from "react-native";
|
|
293
|
+
import { Pressable } from "@mgcrea/react-native-tailwind";
|
|
294
|
+
|
|
295
|
+
export function MyButton() {
|
|
296
|
+
return (
|
|
297
|
+
<Pressable className="bg-blue-500 active:bg-blue-700 p-4 rounded-lg">
|
|
298
|
+
<Text className="text-white font-semibold">Press Me</Text>
|
|
299
|
+
</Pressable>
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Transforms to:**
|
|
305
|
+
|
|
306
|
+
```tsx
|
|
307
|
+
<Pressable
|
|
308
|
+
style={({ pressed }) => [_twStyles._bg_blue_500_p_4_rounded_lg, pressed && _twStyles._active_bg_blue_700]}
|
|
309
|
+
>
|
|
310
|
+
<Text style={_twStyles._font_semibold_text_white}>Press Me</Text>
|
|
311
|
+
</Pressable>;
|
|
312
|
+
|
|
313
|
+
// Generated styles:
|
|
314
|
+
const _twStyles = StyleSheet.create({
|
|
315
|
+
_bg_blue_500_p_4_rounded_lg: { backgroundColor: "#3B82F6", padding: 16, borderRadius: 8 },
|
|
316
|
+
_active_bg_blue_700: { backgroundColor: "#1D4ED8" },
|
|
317
|
+
_font_semibold_text_white: { fontWeight: "600", color: "#FFFFFF" },
|
|
318
|
+
});
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Multiple Active Modifiers:**
|
|
322
|
+
|
|
323
|
+
```tsx
|
|
324
|
+
<Pressable className="bg-green-500 active:bg-green-700 p-4 active:p-6 rounded-lg">
|
|
325
|
+
<Text className="text-white">Press for darker & larger padding</Text>
|
|
326
|
+
</Pressable>
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Complex Styling:**
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
<Pressable className="bg-purple-500 active:bg-purple-800 border-2 border-purple-700 active:border-purple-900 p-4 rounded-lg">
|
|
333
|
+
<Text className="text-white">Background + Border Changes</Text>
|
|
334
|
+
</Pressable>
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Key Features:**
|
|
338
|
+
|
|
339
|
+
- ✅ **Zero runtime overhead** — All parsing happens at compile-time
|
|
340
|
+
- ✅ **Native Pressable API** — Uses Pressable's `style={({ pressed }) => ...}` pattern
|
|
341
|
+
- ✅ **Type-safe** — Full TypeScript autocomplete for `active:` classes
|
|
342
|
+
- ✅ **Optimized** — Styles deduplicated via `StyleSheet.create`
|
|
343
|
+
- ✅ **Works with custom colors** — `active:bg-primary`, `active:bg-secondary`, etc.
|
|
344
|
+
|
|
345
|
+
#### Focus Modifier (TextInput)
|
|
346
|
+
|
|
347
|
+
Use the `focus:` modifier to apply styles when a `TextInput` component is focused. **Requires using the enhanced `TextInput` component from this package.**
|
|
348
|
+
|
|
349
|
+
**Basic Example:**
|
|
350
|
+
|
|
351
|
+
```tsx
|
|
352
|
+
import { TextInput } from "@mgcrea/react-native-tailwind";
|
|
353
|
+
|
|
354
|
+
export function MyInput() {
|
|
355
|
+
return (
|
|
356
|
+
<TextInput
|
|
357
|
+
className="border-2 border-gray-300 focus:border-blue-500 p-3 rounded-lg bg-white"
|
|
358
|
+
placeholder="Email address"
|
|
359
|
+
/>
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**How it works:**
|
|
365
|
+
|
|
366
|
+
The package exports an enhanced `TextInput` component that:
|
|
367
|
+
|
|
368
|
+
1. Manages focus state internally using `onFocus`/`onBlur` callbacks
|
|
369
|
+
2. Passes focus state to the style function: `style={({ focused }) => ...}`
|
|
370
|
+
3. Works seamlessly with the `focus:` modifier in className
|
|
371
|
+
|
|
372
|
+
**Multiple Focus Modifiers:**
|
|
373
|
+
|
|
374
|
+
```tsx
|
|
375
|
+
<TextInput className="border-2 border-gray-300 focus:border-green-500 bg-gray-50 focus:bg-white p-3 rounded-lg" />
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
**Supported Modifiers by Component:**
|
|
379
|
+
|
|
380
|
+
| Component | Supported Modifiers | Notes |
|
|
381
|
+
| ---------------------- | ------------------------------------------ | ------------------------------------------ |
|
|
382
|
+
| `Pressable` (enhanced) | `active:`, `hover:`, `focus:`, `disabled:` | Use `@mgcrea/react-native-tailwind` export |
|
|
383
|
+
| `TextInput` (enhanced) | `focus:`, `disabled:` | Use `@mgcrea/react-native-tailwind` export |
|
|
384
|
+
|
|
385
|
+
#### Disabled Modifier (Pressable & TextInput)
|
|
386
|
+
|
|
387
|
+
Use the `disabled:` modifier to apply styles when a component is disabled. **Requires using the enhanced components from this package.**
|
|
388
|
+
|
|
389
|
+
**Pressable Example:**
|
|
390
|
+
|
|
391
|
+
```tsx
|
|
392
|
+
import { Pressable, Text } from "@mgcrea/react-native-tailwind";
|
|
393
|
+
|
|
394
|
+
export function SubmitButton({ isLoading }) {
|
|
395
|
+
return (
|
|
396
|
+
<Pressable
|
|
397
|
+
disabled={isLoading}
|
|
398
|
+
className="bg-blue-500 active:bg-blue-700 disabled:bg-gray-400 p-4 rounded-lg"
|
|
399
|
+
>
|
|
400
|
+
<Text className="text-white font-semibold">{isLoading ? "Loading..." : "Submit"}</Text>
|
|
401
|
+
</Pressable>
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
**TextInput Example:**
|
|
407
|
+
|
|
408
|
+
```tsx
|
|
409
|
+
import { TextInput } from "@mgcrea/react-native-tailwind";
|
|
410
|
+
|
|
411
|
+
export function MyInput({ isEditing }) {
|
|
412
|
+
return (
|
|
413
|
+
<TextInput
|
|
414
|
+
disabled={!isEditing}
|
|
415
|
+
className="border-2 border-gray-300 focus:border-blue-500 disabled:bg-gray-100 disabled:border-gray-200 p-3 rounded-lg"
|
|
416
|
+
placeholder="Enter text"
|
|
417
|
+
/>
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
**How it works:**
|
|
423
|
+
|
|
424
|
+
The enhanced components inject the `disabled` prop value into the style function context:
|
|
425
|
+
|
|
426
|
+
- **Pressable**: Extends the existing `{ pressed, hovered, focused }` state with `disabled`
|
|
427
|
+
- **TextInput**: Provides `{ focused, disabled }` state to style functions
|
|
428
|
+
|
|
429
|
+
**TextInput `disabled` Prop:**
|
|
430
|
+
|
|
431
|
+
The enhanced `TextInput` also provides a convenient `disabled` prop that overrides React Native's `editable` prop:
|
|
432
|
+
|
|
433
|
+
```tsx
|
|
434
|
+
// These are equivalent:
|
|
435
|
+
<TextInput disabled={true} />
|
|
436
|
+
<TextInput editable={false} />
|
|
437
|
+
|
|
438
|
+
// If both are provided, disabled takes precedence:
|
|
439
|
+
<TextInput disabled={true} editable={true} /> // Component is disabled
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
**Important Notes:**
|
|
443
|
+
|
|
444
|
+
- ⚠️ **Enhanced components required** — State modifiers require using the enhanced components from this package
|
|
445
|
+
- ℹ️ **Component-specific** — Each modifier only works on compatible components
|
|
446
|
+
- ℹ️ **No nested modifiers** — Combinations like `active:focus:bg-blue-500` are not currently supported
|
|
447
|
+
- ✅ **Zero styling overhead** — All className parsing happens at compile-time
|
|
448
|
+
- ✅ **Minimal runtime cost** — Only adds state management (focus tracking, disabled injection)
|
|
449
|
+
- ✅ **Type-safe** — Full TypeScript autocomplete for all modifiers
|
|
450
|
+
- ✅ **Works with custom colors** — `focus:border-primary`, `active:bg-secondary`, `disabled:bg-gray-200`, etc.
|
|
451
|
+
|
|
371
452
|
### ScrollView Content Container
|
|
372
453
|
|
|
373
454
|
Use `contentContainerClassName` to style the ScrollView's content container:
|
|
@@ -441,70 +522,380 @@ export function ListWithHeaderFooter({ items }) {
|
|
|
441
522
|
}
|
|
442
523
|
```
|
|
443
524
|
|
|
444
|
-
|
|
525
|
+
### Building Reusable Components
|
|
445
526
|
|
|
446
|
-
|
|
527
|
+
When building reusable components, use static `className` strings internally. To support `className` props from parent components, you **must** accept the corresponding `style` props (the Babel plugin transforms `className` to `style` before your component receives it):
|
|
447
528
|
|
|
448
|
-
|
|
529
|
+
```tsx
|
|
530
|
+
import { Pressable, Text, View, StyleProp, ViewStyle } from "react-native";
|
|
531
|
+
|
|
532
|
+
type ButtonProps = {
|
|
533
|
+
title: string;
|
|
534
|
+
onPress?: () => void;
|
|
535
|
+
// REQUIRED: Must accept style props for className to work
|
|
536
|
+
style?: StyleProp<ViewStyle>;
|
|
537
|
+
containerStyle?: StyleProp<ViewStyle>;
|
|
538
|
+
// Optional: Include in type for TypeScript compatibility
|
|
539
|
+
className?: string; // compile-time only
|
|
540
|
+
containerClassName?: string; // compile-time only
|
|
541
|
+
};
|
|
449
542
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
543
|
+
export function Button({ title, onPress, style, containerStyle }: ButtonProps) {
|
|
544
|
+
// Use static className strings - these get optimized at compile-time
|
|
545
|
+
return (
|
|
546
|
+
<View className="p-2 bg-gray-100 rounded-lg" style={containerStyle}>
|
|
547
|
+
<Pressable className="bg-blue-500 px-6 py-4 rounded-lg items-center" onPress={onPress} style={style}>
|
|
548
|
+
<Text className="text-white text-center font-semibold text-base">{title}</Text>
|
|
549
|
+
</Pressable>
|
|
550
|
+
</View>
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
```
|
|
455
554
|
|
|
456
|
-
|
|
555
|
+
**Key Points:**
|
|
457
556
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
557
|
+
- ✅ Use **static className strings** internally for default styling
|
|
558
|
+
- ✅ **Must accept `style` props** - the Babel plugin transforms `className` → `style` before your component receives it
|
|
559
|
+
- ✅ Include `className` props in the type (for TypeScript compatibility)
|
|
560
|
+
- ✅ **Don't destructure** className props - they're already transformed to `style` and will be `undefined` at runtime
|
|
561
|
+
- ✅ Babel plugin optimizes all static strings to `StyleSheet.create` calls
|
|
463
562
|
|
|
464
|
-
**
|
|
563
|
+
**Usage:**
|
|
465
564
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
565
|
+
```tsx
|
|
566
|
+
// Default styling (uses internal static classNames)
|
|
567
|
+
<Button title="Click Me" onPress={handlePress} />
|
|
568
|
+
|
|
569
|
+
// Override with runtime styles
|
|
570
|
+
<Button
|
|
571
|
+
title="Custom"
|
|
572
|
+
style={{ backgroundColor: '#10B981' }}
|
|
573
|
+
containerStyle={{ padding: 16 }}
|
|
574
|
+
onPress={handlePress}
|
|
575
|
+
/>
|
|
576
|
+
|
|
577
|
+
// className props are accepted but transformed by Babel upstream
|
|
578
|
+
<Button className="bg-red-500 p-8" title="Red Button" />
|
|
579
|
+
// At compile-time, this becomes:
|
|
580
|
+
// <Button style={_twStyles._bg_red_500_p_8} title="Red Button" />
|
|
581
|
+
// At runtime, className is undefined (already transformed to style)
|
|
582
|
+
```
|
|
470
583
|
|
|
471
|
-
|
|
584
|
+
This pattern allows you to build component libraries with optimized default styling while still supporting full customization.
|
|
472
585
|
|
|
473
|
-
|
|
586
|
+
## API Reference
|
|
587
|
+
|
|
588
|
+
### Spacing
|
|
589
|
+
|
|
590
|
+
**Margin & Padding:**
|
|
591
|
+
|
|
592
|
+
- `m-{size}`, `p-{size}` — All sides
|
|
593
|
+
- `mx-{size}`, `my-{size}`, `px-{size}`, `py-{size}` — Horizontal/vertical
|
|
594
|
+
- `mt-{size}`, `mr-{size}`, `mb-{size}`, `ml-{size}` — Directional margin
|
|
595
|
+
- `pt-{size}`, `pr-{size}`, `pb-{size}`, `pl-{size}` — Directional padding
|
|
596
|
+
- `gap-{size}` — Gap between flex items
|
|
597
|
+
|
|
598
|
+
**Available sizes:** `0`, `0.5`, `1`, `1.5`, `2`, `2.5`, `3`, `3.5`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `14`, `16`, `20`, `24`, `28`, `32`, `36`, `40`, `44`, `48`, `52`, `56`, `60`, `64`, `72`, `80`, `96`
|
|
599
|
+
|
|
600
|
+
**Arbitrary values:** `m-[16px]`, `p-[20]`, `mx-[24px]`, `gap-[12px]` — Custom spacing values (px only)
|
|
601
|
+
|
|
602
|
+
### Layout
|
|
603
|
+
|
|
604
|
+
**Flexbox:**
|
|
605
|
+
|
|
606
|
+
- `flex`, `flex-1`, `flex-auto`, `flex-none` — Flex sizing
|
|
607
|
+
- `flex-row`, `flex-row-reverse`, `flex-col`, `flex-col-reverse` — Direction
|
|
608
|
+
- `flex-wrap`, `flex-wrap-reverse`, `flex-nowrap` — Wrapping
|
|
609
|
+
- `items-start`, `items-end`, `items-center`, `items-baseline`, `items-stretch` — Align items
|
|
610
|
+
- `justify-start`, `justify-end`, `justify-center`, `justify-between`, `justify-around`, `justify-evenly` — Justify content
|
|
611
|
+
- `self-auto`, `self-start`, `self-end`, `self-center`, `self-stretch`, `self-baseline` — Align self
|
|
612
|
+
- `grow`, `grow-0`, `shrink`, `shrink-0` — Flex grow/shrink
|
|
613
|
+
|
|
614
|
+
**Other:**
|
|
615
|
+
|
|
616
|
+
- `absolute`, `relative` — Position
|
|
617
|
+
- `overflow-hidden`, `overflow-visible`, `overflow-scroll` — Overflow
|
|
618
|
+
- `flex`, `hidden` — Display
|
|
619
|
+
|
|
620
|
+
### Colors
|
|
621
|
+
|
|
622
|
+
- `bg-{color}-{shade}` — Background color
|
|
623
|
+
- `text-{color}-{shade}` — Text color
|
|
624
|
+
- `border-{color}-{shade}` — Border color
|
|
625
|
+
|
|
626
|
+
**Available colors:** `gray`, `red`, `blue`, `green`, `yellow`, `purple`, `pink`, `orange`, `indigo`, `white`, `black`, `transparent`
|
|
627
|
+
|
|
628
|
+
**Available shades:** `50`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`
|
|
629
|
+
|
|
630
|
+
> **Note:** You can extend the color palette with custom colors via `tailwind.config.*` — see [Custom Colors](#custom-colors)
|
|
631
|
+
|
|
632
|
+
**Opacity Modifiers:**
|
|
633
|
+
|
|
634
|
+
Apply transparency to any color using the `/` operator with a percentage value (0-100):
|
|
474
635
|
|
|
475
636
|
```tsx
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
637
|
+
<View className="bg-black/50 p-4">
|
|
638
|
+
{" "}
|
|
639
|
+
{/* 50% opacity black background */}
|
|
640
|
+
<Text className="text-gray-900/80">
|
|
641
|
+
{" "}
|
|
642
|
+
{/* 80% opacity gray text */}
|
|
643
|
+
Semi-transparent content
|
|
644
|
+
</Text>
|
|
645
|
+
<View className="border-2 border-red-500/30" /> {/* 30% opacity red border */}
|
|
646
|
+
</View>
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
- Works with all color types: `bg-*`, `text-*`, `border-*`
|
|
650
|
+
- Supports preset colors: `bg-blue-500/75`, `text-red-600/50`
|
|
651
|
+
- Supports arbitrary colors: `bg-[#ff0000]/40`, `text-[#3B82F6]/90`
|
|
652
|
+
- Supports custom colors: `bg-primary/60`, `text-brand/80`
|
|
653
|
+
- Uses React Native's 8-digit hex format: `#RRGGBBAA`
|
|
654
|
+
|
|
655
|
+
**Examples:**
|
|
656
|
+
|
|
657
|
+
```tsx
|
|
658
|
+
// Background opacity
|
|
659
|
+
<View className="bg-white/90" /> // #FFFFFFE6
|
|
660
|
+
<View className="bg-blue-500/50" /> // #3B82F680
|
|
661
|
+
|
|
662
|
+
// Text opacity
|
|
663
|
+
<Text className="text-black/70" /> // #000000B3
|
|
664
|
+
<Text className="text-gray-900/60" /> // #11182799
|
|
665
|
+
|
|
666
|
+
// Border opacity
|
|
667
|
+
<View className="border-2 border-purple-500/40" /> // #A855F766
|
|
668
|
+
|
|
669
|
+
// Arbitrary colors with opacity
|
|
670
|
+
<View className="bg-[#ff6b6b]/25" /> // #FF6B6B40
|
|
479
671
|
|
|
480
|
-
//
|
|
481
|
-
<View className="
|
|
672
|
+
// Edge cases
|
|
673
|
+
<View className="bg-black/0" /> // Fully transparent
|
|
674
|
+
<View className="bg-blue-500/100" /> // Fully opaque
|
|
675
|
+
<View className="bg-transparent/50" /> // Remains transparent
|
|
482
676
|
```
|
|
483
677
|
|
|
484
|
-
|
|
678
|
+
### Typography
|
|
679
|
+
|
|
680
|
+
**Font Size:**
|
|
681
|
+
|
|
682
|
+
`text-xs`, `text-sm`, `text-base`, `text-lg`, `text-xl`, `text-2xl`, `text-3xl`, `text-4xl`, `text-5xl`, `text-6xl`, `text-7xl`, `text-8xl`, `text-9xl`
|
|
683
|
+
|
|
684
|
+
**Font Weight:**
|
|
685
|
+
|
|
686
|
+
`font-thin`, `font-extralight`, `font-light`, `font-normal`, `font-medium`, `font-semibold`, `font-bold`, `font-extrabold`, `font-black`
|
|
687
|
+
|
|
688
|
+
**Other:**
|
|
689
|
+
|
|
690
|
+
- `italic`, `not-italic` — Font style
|
|
691
|
+
- `text-left`, `text-center`, `text-right`, `text-justify` — Text alignment
|
|
692
|
+
- `underline`, `line-through`, `no-underline` — Text decoration
|
|
693
|
+
- `uppercase`, `lowercase`, `capitalize`, `normal-case` — Text transform
|
|
694
|
+
- `leading-none`, `leading-tight`, `leading-snug`, `leading-normal`, `leading-relaxed`, `leading-loose` — Line height
|
|
695
|
+
|
|
696
|
+
### Borders
|
|
697
|
+
|
|
698
|
+
**Width:**
|
|
699
|
+
|
|
700
|
+
- `border`, `border-0`, `border-2`, `border-4`, `border-8` — All sides
|
|
701
|
+
- `border-t`, `border-r`, `border-b`, `border-l` (with variants `-0`, `-2`, `-4`, `-8`) — Directional
|
|
702
|
+
- `border-[8px]`, `border-t-[12px]` — Arbitrary values
|
|
703
|
+
|
|
704
|
+
**Radius:**
|
|
705
|
+
|
|
706
|
+
- `rounded-none`, `rounded-sm`, `rounded`, `rounded-md`, `rounded-lg`, `rounded-xl`, `rounded-2xl`, `rounded-3xl`, `rounded-full` — All corners
|
|
707
|
+
- `rounded-t`, `rounded-r`, `rounded-b`, `rounded-l` (with size variants) — Directional
|
|
708
|
+
- `rounded-tl`, `rounded-tr`, `rounded-bl`, `rounded-br` (with size variants) — Individual corners
|
|
709
|
+
- `rounded-[12px]`, `rounded-t-[8px]`, `rounded-tl-[16px]` — Arbitrary values
|
|
710
|
+
|
|
711
|
+
**Style:**
|
|
712
|
+
|
|
713
|
+
`border-solid`, `border-dotted`, `border-dashed`
|
|
714
|
+
|
|
715
|
+
### Shadows & Elevation
|
|
716
|
+
|
|
717
|
+
Apply platform-specific shadows and elevation to create depth and visual hierarchy. Automatically uses iOS shadow properties or Android elevation based on the platform:
|
|
718
|
+
|
|
719
|
+
**Available shadow sizes:**
|
|
720
|
+
|
|
721
|
+
- `shadow-sm` — Subtle shadow
|
|
722
|
+
- `shadow` — Default shadow
|
|
723
|
+
- `shadow-md` — Medium shadow
|
|
724
|
+
- `shadow-lg` — Large shadow
|
|
725
|
+
- `shadow-xl` — Extra large shadow
|
|
726
|
+
- `shadow-2xl` — Extra extra large shadow
|
|
727
|
+
- `shadow-none` — Remove shadow
|
|
728
|
+
|
|
729
|
+
**Platform Differences:**
|
|
730
|
+
|
|
731
|
+
| Platform | Properties Used | Example Output |
|
|
732
|
+
| ----------- | -------------------------------------------------------------- | ------------------------------------------ |
|
|
733
|
+
| **iOS** | `shadowColor`, `shadowOffset`, `shadowOpacity`, `shadowRadius` | Native iOS shadow rendering |
|
|
734
|
+
| **Android** | `elevation` | Native Android elevation (Material Design) |
|
|
735
|
+
|
|
736
|
+
**Examples:**
|
|
737
|
+
|
|
738
|
+
```tsx
|
|
739
|
+
// Card with shadow
|
|
740
|
+
<View className="bg-white rounded-lg shadow-lg p-6 m-4">
|
|
741
|
+
<Text className="text-xl font-bold">Card Title</Text>
|
|
742
|
+
<Text className="text-gray-600">Card with large shadow</Text>
|
|
743
|
+
</View>
|
|
744
|
+
|
|
745
|
+
// Button with subtle shadow
|
|
746
|
+
<Pressable className="bg-blue-500 shadow-sm rounded-lg px-6 py-3">
|
|
747
|
+
<Text className="text-white">Press Me</Text>
|
|
748
|
+
</Pressable>
|
|
749
|
+
|
|
750
|
+
// Different shadow sizes
|
|
751
|
+
<View className="shadow-sm p-4">Subtle</View>
|
|
752
|
+
<View className="shadow p-4">Default</View>
|
|
753
|
+
<View className="shadow-md p-4">Medium</View>
|
|
754
|
+
<View className="shadow-lg p-4">Large</View>
|
|
755
|
+
<View className="shadow-xl p-4">Extra Large</View>
|
|
756
|
+
<View className="shadow-2xl p-4">2X Large</View>
|
|
757
|
+
|
|
758
|
+
// Remove shadow
|
|
759
|
+
<View className="shadow-lg md:shadow-none p-4">
|
|
760
|
+
Conditional shadow removal
|
|
761
|
+
</View>
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
**iOS Shadow Values:**
|
|
765
|
+
|
|
766
|
+
| Class | shadowOpacity | shadowRadius | shadowOffset |
|
|
767
|
+
| ------------ | ------------- | ------------ | ------------------------ |
|
|
768
|
+
| `shadow-sm` | 0.05 | 1 | { width: 0, height: 1 } |
|
|
769
|
+
| `shadow` | 0.1 | 2 | { width: 0, height: 1 } |
|
|
770
|
+
| `shadow-md` | 0.15 | 4 | { width: 0, height: 3 } |
|
|
771
|
+
| `shadow-lg` | 0.2 | 8 | { width: 0, height: 6 } |
|
|
772
|
+
| `shadow-xl` | 0.25 | 12 | { width: 0, height: 10 } |
|
|
773
|
+
| `shadow-2xl` | 0.3 | 24 | { width: 0, height: 20 } |
|
|
774
|
+
|
|
775
|
+
**Android Elevation Values:**
|
|
776
|
+
|
|
777
|
+
| Class | elevation |
|
|
778
|
+
| ------------ | --------- |
|
|
779
|
+
| `shadow-sm` | 1 |
|
|
780
|
+
| `shadow` | 2 |
|
|
781
|
+
| `shadow-md` | 4 |
|
|
782
|
+
| `shadow-lg` | 8 |
|
|
783
|
+
| `shadow-xl` | 12 |
|
|
784
|
+
| `shadow-2xl` | 16 |
|
|
785
|
+
|
|
786
|
+
> **Note:** All shadow parsing happens at compile-time with zero runtime overhead. The platform detection uses React Native's `Platform.select()` API.
|
|
787
|
+
|
|
788
|
+
### Aspect Ratio
|
|
789
|
+
|
|
790
|
+
Control the aspect ratio of views using preset or arbitrary values. Requires React Native 0.71+:
|
|
791
|
+
|
|
792
|
+
**Preset values:**
|
|
793
|
+
|
|
794
|
+
- `aspect-auto` — Remove aspect ratio constraint
|
|
795
|
+
- `aspect-square` — 1:1 aspect ratio
|
|
796
|
+
- `aspect-video` — 16:9 aspect ratio
|
|
797
|
+
|
|
798
|
+
**Arbitrary values:**
|
|
799
|
+
|
|
800
|
+
Use `aspect-[width/height]` for custom ratios:
|
|
801
|
+
|
|
802
|
+
```tsx
|
|
803
|
+
<View className="aspect-[4/3]" /> // 4:3 ratio (1.333...)
|
|
804
|
+
<View className="aspect-[16/9]" /> // 16:9 ratio (1.778...)
|
|
805
|
+
<View className="aspect-[21/9]" /> // 21:9 ultrawide
|
|
806
|
+
<View className="aspect-[9/16]" /> // 9:16 portrait
|
|
807
|
+
<View className="aspect-[3/2]" /> // 3:2 ratio (1.5)
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
**Examples:**
|
|
811
|
+
|
|
812
|
+
```tsx
|
|
813
|
+
// Square image container
|
|
814
|
+
<View className="w-full aspect-square bg-gray-200">
|
|
815
|
+
<Image source={avatar} className="w-full h-full" />
|
|
816
|
+
</View>
|
|
817
|
+
|
|
818
|
+
// Video player container (16:9)
|
|
819
|
+
<View className="w-full aspect-video bg-black">
|
|
820
|
+
<VideoPlayer />
|
|
821
|
+
</View>
|
|
822
|
+
|
|
823
|
+
// Instagram-style square grid
|
|
824
|
+
<View className="flex-row flex-wrap gap-2">
|
|
825
|
+
{photos.map((photo) => (
|
|
826
|
+
<View key={photo.id} className="w-[32%] aspect-square">
|
|
827
|
+
<Image source={photo.uri} className="w-full h-full rounded" />
|
|
828
|
+
</View>
|
|
829
|
+
))}
|
|
830
|
+
</View>
|
|
831
|
+
|
|
832
|
+
// Custom aspect ratio for wide images
|
|
833
|
+
<View className="w-full aspect-[21/9] rounded-lg overflow-hidden">
|
|
834
|
+
<Image source={banner} className="w-full h-full" resizeMode="cover" />
|
|
835
|
+
</View>
|
|
836
|
+
|
|
837
|
+
// Portrait orientation
|
|
838
|
+
<View className="h-full aspect-[9/16]">
|
|
839
|
+
<Story />
|
|
840
|
+
</View>
|
|
841
|
+
|
|
842
|
+
// Remove aspect ratio constraint
|
|
843
|
+
<View className="aspect-square md:aspect-auto">
|
|
844
|
+
Responsive aspect ratio
|
|
845
|
+
</View>
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
**Common Aspect Ratios:**
|
|
849
|
+
|
|
850
|
+
| Ratio | Class | Decimal | Use Case |
|
|
851
|
+
| ----- | --------------- | ------- | ---------------------------- |
|
|
852
|
+
| 1:1 | `aspect-square` | 1.0 | Profile pictures, thumbnails |
|
|
853
|
+
| 16:9 | `aspect-video` | 1.778 | Videos, landscape photos |
|
|
854
|
+
| 4:3 | `aspect-[4/3]` | 1.333 | Standard photos |
|
|
855
|
+
| 3:2 | `aspect-[3/2]` | 1.5 | Classic photography |
|
|
856
|
+
| 21:9 | `aspect-[21/9]` | 2.333 | Ultrawide/cinematic |
|
|
857
|
+
| 9:16 | `aspect-[9/16]` | 0.5625 | Stories, vertical video |
|
|
858
|
+
|
|
859
|
+
> **Note:** The aspect ratio is calculated as `width / height`. When combined with `w-full`, the height will be automatically calculated to maintain the ratio.
|
|
860
|
+
|
|
861
|
+
### Sizing
|
|
862
|
+
|
|
863
|
+
- `w-{size}`, `h-{size}` — Width/height
|
|
864
|
+
- `min-w-{size}`, `min-h-{size}` — Min width/height
|
|
865
|
+
- `max-w-{size}`, `max-h-{size}` — Max width/height
|
|
866
|
+
|
|
867
|
+
**Available sizes:**
|
|
868
|
+
|
|
869
|
+
- **Numeric:** `0`-`96` (same as spacing scale)
|
|
870
|
+
- **Fractional:** `1/2`, `1/3`, `2/3`, `1/4`, `3/4`, `1/5`, `2/5`, `3/5`, `4/5`, `1/6`, `2/6`, `3/6`, `4/6`, `5/6`
|
|
871
|
+
- **Special:** `full` (100%), `auto`
|
|
872
|
+
- **Arbitrary:** `w-[123px]`, `h-[50%]`, `min-w-[200px]`, `max-h-[80%]`
|
|
873
|
+
|
|
874
|
+
> **Note:** Arbitrary sizing supports pixel values (`[123px]` or `[123]`) and percentages (`[50%]`). Other units (`rem`, `em`, `vh`, `vw`) are not supported in React Native.
|
|
485
875
|
|
|
486
876
|
## Advanced
|
|
487
877
|
|
|
488
878
|
### Arbitrary Values
|
|
489
879
|
|
|
490
|
-
Use arbitrary values for custom sizes and borders not in the preset scales:
|
|
880
|
+
Use arbitrary values for custom sizes, spacing, and borders not in the preset scales:
|
|
491
881
|
|
|
492
882
|
```tsx
|
|
493
|
-
<View className="w-[350px] h-[85%] border-[3px] rounded-[20px]" />
|
|
883
|
+
<View className="w-[350px] h-[85%] m-[16px] p-[24px] border-[3px] rounded-[20px]" />
|
|
494
884
|
```
|
|
495
885
|
|
|
496
886
|
**Supported:**
|
|
497
887
|
|
|
498
|
-
- **
|
|
499
|
-
- **
|
|
500
|
-
- **Border
|
|
888
|
+
- **Spacing:** `m-[...]`, `mx-[...]`, `my-[...]`, `mt-[...]`, `p-[...]`, `px-[...]`, `gap-[...]`, etc. (px only)
|
|
889
|
+
- **Sizing:** `w-[...]`, `h-[...]`, `min-w-[...]`, `min-h-[...]`, `max-w-[...]`, `max-h-[...]` (px and %)
|
|
890
|
+
- **Border width:** `border-[...]`, `border-t-[...]`, `border-r-[...]`, `border-b-[...]`, `border-l-[...]` (px only)
|
|
891
|
+
- **Border radius:** `rounded-[...]`, `rounded-t-[...]`, `rounded-tl-[...]`, etc. (px only)
|
|
501
892
|
|
|
502
893
|
**Formats:**
|
|
503
894
|
|
|
504
|
-
- Pixels: `[123px]` or `[123]`
|
|
505
|
-
- Percentages: `[50%]`, `[33.333%]`
|
|
895
|
+
- Pixels: `[123px]` or `[123]` — Supported by all utilities
|
|
896
|
+
- Percentages: `[50%]`, `[33.333%]` — Only supported by sizing utilities (`w-*`, `h-*`, etc.)
|
|
506
897
|
|
|
507
|
-
> **Note:**
|
|
898
|
+
> **Note:** CSS units (`rem`, `em`, `vh`, `vw`) are not supported by React Native.
|
|
508
899
|
|
|
509
900
|
### Custom Colors
|
|
510
901
|
|