Skip to content

Commit 1392190

Browse files
docs: add border, shadow, and elevation props to docs, README, and skill (#38)
1 parent 6ce7d49 commit 1392190

5 files changed

Lines changed: 113 additions & 7 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ transition={{ type: 'spring', damping: 10 }} → transitionType="spring", tran
5858
- `README.md` (props table + usage section)
5959
- `docs/docs/usage.mdx` (usage guide)
6060
- `docs/docs/api-reference.mdx` (API reference table)
61+
- `skills/react-native-ease-refactor/SKILL.md` (supported properties list, transition category keys, decision tree)
6162

6263
## Development Commands
6364

README.md

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ Available category keys:
248248
| `opacity` | opacity |
249249
| `borderRadius` | borderRadius |
250250
| `backgroundColor` | backgroundColor |
251+
| `border` | borderWidth, borderColor |
252+
| `shadow` | shadowOpacity, shadowRadius, shadowColor, shadowOffset, elevation |
251253

252254
Use `default` as a fallback for categories not explicitly listed:
253255

@@ -267,7 +269,7 @@ When no `default` key is provided, the library default (timing 300ms easeInOut)
267269
268270
### Border Radius
269271

270-
`borderRadius` can be animated just like other properties. It uses hardware-accelerated platform APIs — `ViewOutlineProvider` + `clipToOutline` on Android and `layer.cornerRadius` + `layer.masksToBounds` on iOS. Unlike RN's style-based `borderRadius` (which uses a Canvas drawable on Android), this clips children properly and is GPU-accelerated.
272+
`borderRadius` can be animated just like other properties. It uses hardware-accelerated platform APIs — `ViewOutlineProvider` + `clipToOutline` on Android and `layer.cornerRadius` on iOS.
271273

272274
```tsx
273275
<EaseView
@@ -302,6 +304,38 @@ On Android, background color uses `ValueAnimator.ofArgb()` (timing only — spri
302304
303305
When `backgroundColor` is in `animate`, any `backgroundColor` in `style` is automatically stripped to avoid conflicts.
304306

307+
### Border
308+
309+
`borderWidth` and `borderColor` can be animated. On iOS, these use Core Animation on the `CALayer` border properties. On Android, they use `BackgroundStyleApplicator` which updates the `BorderDrawable` each frame.
310+
311+
```tsx
312+
<EaseView
313+
animate={{
314+
borderWidth: selected ? 3 : 0,
315+
borderColor: selected ? '#3B82F6' : '#E5E7EB',
316+
}}
317+
transition={{ border: { type: 'spring', damping: 15, stiffness: 120 } }}
318+
style={styles.card}
319+
/>
320+
```
321+
322+
### Shadow / Elevation
323+
324+
Shadow properties are iOS-only (`shadowOpacity`, `shadowRadius`, `shadowColor`, `shadowOffset`). On Android, use `elevation` for material shadows.
325+
326+
```tsx
327+
<EaseView
328+
animate={{
329+
shadowOpacity: active ? 0.4 : 0,
330+
shadowRadius: active ? 16 : 0,
331+
shadowOffset: active ? { width: 0, height: 8 } : { width: 0, height: 0 },
332+
elevation: active ? 12 : 0,
333+
}}
334+
transition={{ shadow: { type: 'spring', damping: 15, stiffness: 120 } }}
335+
style={{ shadowColor: '#000', backgroundColor: '#fff', borderRadius: 16 }}
336+
/>
337+
```
338+
305339
### Animatable Properties
306340

307341
All properties are set in the `animate` prop as flat values (no transform array).
@@ -318,8 +352,15 @@ All properties are set in the `animate` prop as flat values (no transform array)
318352
rotate: 0, // Z-axis rotation in degrees
319353
rotateX: 0, // X-axis rotation in degrees (3D)
320354
rotateY: 0, // Y-axis rotation in degrees (3D)
321-
borderRadius: 0, // pixels (hardware-accelerated, clips children)
355+
borderRadius: 0, // pixels (hardware-accelerated)
322356
backgroundColor: 'transparent', // any RN color value
357+
borderWidth: 0, // pixels
358+
borderColor: 'black', // any RN color value
359+
shadowOpacity: 0, // 0–1 (iOS only)
360+
shadowRadius: 0, // pixels (iOS only)
361+
shadowColor: 'black', // any RN color value (iOS only)
362+
shadowOffset: { width: 0, height: 0 }, // iOS only
363+
elevation: 0, // Android material shadow
323364
}}
324365
/>
325366
```
@@ -502,8 +543,15 @@ A `View` that animates property changes using native platform APIs.
502543
| `rotate` | `number` | `0` | Z-axis rotation in degrees |
503544
| `rotateX` | `number` | `0` | X-axis rotation in degrees (3D) |
504545
| `rotateY` | `number` | `0` | Y-axis rotation in degrees (3D) |
505-
| `borderRadius` | `number` | `0` | Border radius in pixels (hardware-accelerated, clips children) |
546+
| `borderRadius` | `number` | `0` | Border radius in pixels (hardware-accelerated) |
506547
| `backgroundColor` | `ColorValue` | `'transparent'` | Background color (any RN color value). Timing-only on Android, spring+timing on iOS. |
548+
| `borderWidth` | `number` | `0` | Border width in pixels |
549+
| `borderColor` | `ColorValue` | `'black'` | Border color |
550+
| `shadowOpacity` | `number` | `0` | Shadow opacity 0–1 (iOS only) |
551+
| `shadowRadius` | `number` | `0` | Shadow blur radius (iOS only) |
552+
| `shadowColor` | `ColorValue` | `'black'` | Shadow color (iOS only) |
553+
| `shadowOffset` | `object` | `{width:0,height:0}` | Shadow offset `{ width, height }` (iOS only) |
554+
| `elevation` | `number` | `0` | Material shadow elevation (Android only) |
507555

508556
Properties not specified in `animate` default to their identity values.
509557

@@ -552,6 +600,8 @@ A per-property map that applies different transition configs to different proper
552600
| `opacity` | opacity |
553601
| `borderRadius` | borderRadius |
554602
| `backgroundColor` | backgroundColor |
603+
| `border` | borderWidth, borderColor |
604+
| `shadow` | shadowOpacity, shadowRadius, shadowColor, shadowOffset, elevation |
555605

556606
## Hardware Layers (Android)
557607

docs/docs/api-reference.mdx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ A `View` that animates property changes using native platform APIs.
3636
| `rotateY` | `number` | `0` | Y-axis rotation in degrees |
3737
| `borderRadius` | `number` | `0` | Border radius in pixels |
3838
| `backgroundColor` | `ColorValue` | `'transparent'` | Background color |
39+
| `borderWidth` | `number` | `0` | Border width in pixels |
40+
| `borderColor` | `ColorValue` | `'black'` | Border color |
41+
| `shadowOpacity` | `number` | `0` | Shadow opacity 0–1 (iOS only) |
42+
| `shadowRadius` | `number` | `0` | Shadow blur radius (iOS only) |
43+
| `shadowColor` | `ColorValue` | `'black'` | Shadow color (iOS only) |
44+
| `shadowOffset` | `object` | `{width:0,height:0}` | Shadow offset `{ width, height }` (iOS only) |
45+
| `elevation` | `number` | `0` | Material shadow elevation (Android only) |
3946

4047
## `TimingTransition`
4148

@@ -82,6 +89,8 @@ A per-property map that applies different transition configs to different proper
8289
| `opacity` | opacity |
8390
| `borderRadius` | borderRadius |
8491
| `backgroundColor` | backgroundColor |
92+
| `border` | borderWidth, borderColor |
93+
| `shadow` | shadowOpacity, shadowRadius, shadowColor, shadowOffset, elevation |
8594

8695
## Hardware layers (Android)
8796

docs/docs/usage.mdx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ Available category keys:
9191
| `opacity` | opacity |
9292
| `borderRadius` | borderRadius |
9393
| `backgroundColor` | backgroundColor |
94+
| `border` | borderWidth, borderColor |
95+
| `shadow` | shadowOpacity, shadowRadius, shadowColor, shadowOffset, elevation |
9496

9597
When no `default` key is provided, the library default (timing 300ms easeInOut) applies to all categories.
9698

@@ -125,6 +127,36 @@ When `borderRadius` is in `animate`, any `borderRadius` in `style` is automatica
125127

126128
On Android, background color uses timing animation only. On iOS, it supports both timing and spring transitions.
127129

130+
## Border
131+
132+
```tsx
133+
<EaseView
134+
animate={{
135+
borderWidth: selected ? 3 : 0,
136+
borderColor: selected ? '#3B82F6' : '#E5E7EB',
137+
}}
138+
transition={{ border: { type: 'spring', damping: 15, stiffness: 120 } }}
139+
style={styles.card}
140+
/>
141+
```
142+
143+
## Shadow / Elevation
144+
145+
Shadow properties are iOS-only. On Android, use `elevation` for material shadows.
146+
147+
```tsx
148+
<EaseView
149+
animate={{
150+
shadowOpacity: active ? 0.4 : 0,
151+
shadowRadius: active ? 16 : 0,
152+
shadowOffset: active ? { width: 0, height: 8 } : { width: 0, height: 0 },
153+
elevation: active ? 12 : 0,
154+
}}
155+
transition={{ shadow: { type: 'spring', damping: 15, stiffness: 120 } }}
156+
style={{ shadowColor: '#000', backgroundColor: '#fff', borderRadius: 16 }}
157+
/>
158+
```
159+
128160
## Animatable properties
129161

130162
```tsx
@@ -141,6 +173,13 @@ On Android, background color uses timing animation only. On iOS, it supports bot
141173
rotateY: 0,
142174
borderRadius: 0,
143175
backgroundColor: 'transparent',
176+
borderWidth: 0,
177+
borderColor: 'black',
178+
shadowOpacity: 0, // iOS only
179+
shadowRadius: 0, // iOS only
180+
shadowColor: 'black', // iOS only
181+
shadowOffset: { width: 0, height: 0 }, // iOS only
182+
elevation: 0, // Android only
144183
}}
145184
/>
146185
```

skills/react-native-ease-refactor/SKILL.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ Apply these checks in order. The first match determines the result:
6363
5c. **Uses `withDelay` wrapping `withSequence` or nested `withDelay`?** → NOT migratable — "Complex delay/sequencing not supported"
6464
6. **Uses complex `interpolate()`?** (more than 2 input/output values) → NOT migratable — "Complex interpolation"
6565
7. **Uses `layout={...}` prop?** → NOT migratable — "Layout animation"
66-
8. **Animates unsupported properties?** (anything besides: opacity, translateX, translateY, scale, scaleX, scaleY, rotate, rotateX, rotateY, borderRadius, backgroundColor) → NOT migratable — "Animates unsupported property: `<prop>`"
67-
9. **Uses different transition configs per property?** (e.g., opacity uses 200ms timing, scale uses spring) → MIGRATABLE — map to `TransitionMap` with category keys (`transform`, `opacity`, `borderRadius`, `backgroundColor`, `default`)
66+
8. **Animates unsupported properties?** (anything besides: opacity, translateX, translateY, scale, scaleX, scaleY, rotate, rotateX, rotateY, borderRadius, backgroundColor, borderWidth, borderColor, shadowOpacity, shadowRadius, shadowColor, shadowOffset, elevation) → NOT migratable — "Animates unsupported property: `<prop>`"
67+
9. **Uses different transition configs per property?** (e.g., opacity uses 200ms timing, scale uses spring) → MIGRATABLE — map to `TransitionMap` with category keys (`transform`, `opacity`, `borderRadius`, `backgroundColor`, `border`, `shadow`, `default`)
6868
10. **Not driven by state?** (animation triggered by gesture/scroll value, not React state) → NOT migratable — "Not state-driven"
6969
11. **Otherwise** → MIGRATABLE
7070

@@ -363,6 +363,13 @@ All properties in the `animate` prop:
363363
| `rotateY` | `number` | `0` | Y-axis rotation in degrees (3D) |
364364
| `borderRadius` | `number` | `0` | In pixels |
365365
| `backgroundColor` | `ColorValue` | `'transparent'` | Any RN color value |
366+
| `borderWidth` | `number` | `0` | In pixels |
367+
| `borderColor` | `ColorValue` | `'black'` | Any RN color value |
368+
| `shadowOpacity` | `number` | `0` | 0–1 (iOS only) |
369+
| `shadowRadius` | `number` | `0` | In pixels (iOS only) |
370+
| `shadowColor` | `ColorValue` | `'black'` | Any RN color value (iOS only) |
371+
| `shadowOffset` | `object` | `{width:0,height:0}` | `{ width, height }` (iOS only) |
372+
| `elevation` | `number` | `0` | Android material shadow |
366373
367374
### Transition Types
368375
@@ -400,7 +407,7 @@ transition={{ type: 'none' }}
400407

401408
- `animate` — target values for animated properties
402409
- `initialAnimate` — starting values (animates to `animate` on mount)
403-
- `transition` — animation config: a single `SingleTransition` (timing/spring/none) OR a `TransitionMap` with category keys (`default`, `transform`, `opacity`, `borderRadius`, `backgroundColor`)
410+
- `transition` — animation config: a single `SingleTransition` (timing/spring/none) OR a `TransitionMap` with category keys (`default`, `transform`, `opacity`, `borderRadius`, `backgroundColor`, `border`, `shadow`)
404411
- `onTransitionEnd` — callback with `{ finished: boolean }`
405412
- `transformOrigin` — pivot point as `{ x: 0-1, y: 0-1 }`, default center
406413
- `useHardwareLayer` — Android GPU optimization (boolean, default false)
@@ -409,7 +416,7 @@ transition={{ type: 'none' }}
409416
### Important Constraints
410417

411418
- **Loop requires timing** (not spring) and `initialAnimate` must define the start value
412-
- **Per-property transitions supported** — pass a `TransitionMap` with category keys (`default`, `transform`, `opacity`, `borderRadius`, `backgroundColor`) to use different configs per property group
419+
- **Per-property transitions supported** — pass a `TransitionMap` with category keys (`default`, `transform`, `opacity`, `borderRadius`, `backgroundColor`, `border`, `shadow`) to use different configs per property group
413420
- **No animation sequencing** — no equivalent to `withSequence`. Simple `withDelay` IS supported via the `delay` transition prop
414421
- **No gesture/scroll-driven animations** — EaseView is state-driven only
415422
- **Style/animate conflict** — if a property appears in both `style` and `animate`, the animated value wins

0 commit comments

Comments
 (0)