Initial commit — Singular Particular Space v1
Homepage (site/index.html): integration-v14 promoted, Writings section integrated with 33 pieces clustered by type (stories/essays/miscellany), Writings welcome lightbox, content frame at 98% opacity. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
77
skills/react-native-skills/rules/ui-native-modals.md
Normal file
77
skills/react-native-skills/rules/ui-native-modals.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
title: Use Native Modals Over JS-Based Bottom Sheets
|
||||
impact: HIGH
|
||||
impactDescription: native performance, gestures, accessibility
|
||||
tags: modals, bottom-sheet, native, react-navigation
|
||||
---
|
||||
|
||||
## Use Native Modals Over JS-Based Bottom Sheets
|
||||
|
||||
Use native `<Modal>` with `presentationStyle="formSheet"` or React Navigation
|
||||
v7's native form sheet instead of JS-based bottom sheet libraries. Native modals
|
||||
have built-in gestures, accessibility, and better performance. Rely on native UI
|
||||
for low-level primitives.
|
||||
|
||||
**Incorrect (JS-based bottom sheet):**
|
||||
|
||||
```tsx
|
||||
import BottomSheet from 'custom-js-bottom-sheet'
|
||||
|
||||
function MyScreen() {
|
||||
const sheetRef = useRef<BottomSheet>(null)
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<Button onPress={() => sheetRef.current?.expand()} title='Open' />
|
||||
<BottomSheet ref={sheetRef} snapPoints={['50%', '90%']}>
|
||||
<View>
|
||||
<Text>Sheet content</Text>
|
||||
</View>
|
||||
</BottomSheet>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
**Correct (native Modal with formSheet):**
|
||||
|
||||
```tsx
|
||||
import { Modal, View, Text, Button } from 'react-native'
|
||||
|
||||
function MyScreen() {
|
||||
const [visible, setVisible] = useState(false)
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<Button onPress={() => setVisible(true)} title='Open' />
|
||||
<Modal
|
||||
visible={visible}
|
||||
presentationStyle='formSheet'
|
||||
animationType='slide'
|
||||
onRequestClose={() => setVisible(false)}
|
||||
>
|
||||
<View>
|
||||
<Text>Sheet content</Text>
|
||||
</View>
|
||||
</Modal>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
**Correct (React Navigation v7 native form sheet):**
|
||||
|
||||
```tsx
|
||||
// In your navigator
|
||||
<Stack.Screen
|
||||
name='Details'
|
||||
component={DetailsScreen}
|
||||
options={{
|
||||
presentation: 'formSheet',
|
||||
sheetAllowedDetents: 'fitToContents',
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
Native modals provide swipe-to-dismiss, proper keyboard avoidance, and
|
||||
accessibility out of the box.
|
||||
Reference in New Issue
Block a user