react-native-nitro-modal 0.2.0 → 0.3.1-rc
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 +52 -4
- package/android/src/main/java/com/margelo/nitro/nitromodal/BottomSheetPresenter.kt +399 -34
- package/android/src/main/java/com/margelo/nitro/nitromodal/HybridNitroModal.kt +67 -22
- package/android/src/main/java/com/margelo/nitro/nitromodal/ModalConfig.kt +35 -1
- package/android/src/main/java/com/margelo/nitro/nitromodal/ModalContentRoot.kt +48 -5
- package/android/src/main/java/com/margelo/nitro/nitromodal/ModalPresenter.kt +63 -4
- package/android/src/main/java/com/margelo/nitro/nitromodal/NitroModalHostView.kt +68 -8
- package/ios/HybridNitroModal.swift +115 -20
- package/ios/ModalConfig.swift +48 -2
- package/ios/NitroModalHostView.swift +73 -8
- package/ios/SheetView.swift +647 -0
- package/ios/SheetViewController.swift +19 -450
- package/lib/module/NitroModal.js +54 -6
- package/lib/module/NitroModal.js.map +1 -1
- package/lib/module/NitroModalView.web.js +86 -26
- package/lib/module/NitroModalView.web.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/web/AnimatedValue.js +3 -0
- package/lib/module/web/AnimatedValue.js.map +1 -1
- package/lib/module/web/ModalConfig.js +10 -4
- package/lib/module/web/ModalConfig.js.map +1 -1
- package/lib/module/web/ModalController.js +29 -2
- package/lib/module/web/ModalController.js.map +1 -1
- package/lib/module/web/ModalPresenter.js +47 -12
- package/lib/module/web/ModalPresenter.js.map +1 -1
- package/lib/module/web/SheetPresenter.js +118 -34
- package/lib/module/web/SheetPresenter.js.map +1 -1
- package/lib/module/web/dom.js +16 -0
- package/lib/module/web/dom.js.map +1 -1
- package/lib/typescript/src/NitroModal.d.ts +42 -2
- package/lib/typescript/src/NitroModal.d.ts.map +1 -1
- package/lib/typescript/src/NitroModal.nitro.d.ts +37 -2
- package/lib/typescript/src/NitroModal.nitro.d.ts.map +1 -1
- package/lib/typescript/src/NitroModalView.web.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/web/AnimatedValue.d.ts +1 -0
- package/lib/typescript/src/web/AnimatedValue.d.ts.map +1 -1
- package/lib/typescript/src/web/ModalConfig.d.ts +10 -0
- package/lib/typescript/src/web/ModalConfig.d.ts.map +1 -1
- package/lib/typescript/src/web/ModalController.d.ts +5 -0
- package/lib/typescript/src/web/ModalController.d.ts.map +1 -1
- package/lib/typescript/src/web/ModalPresenter.d.ts +13 -0
- package/lib/typescript/src/web/ModalPresenter.d.ts.map +1 -1
- package/lib/typescript/src/web/SheetPresenter.d.ts +13 -2
- package/lib/typescript/src/web/SheetPresenter.d.ts.map +1 -1
- package/lib/typescript/src/web/dom.d.ts +4 -0
- package/lib/typescript/src/web/dom.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridNitroModalSpec.cpp +78 -6
- package/nitrogen/generated/android/c++/JHybridNitroModalSpec.hpp +14 -2
- package/nitrogen/generated/android/c++/JNamedSheetDetent.hpp +64 -0
- package/nitrogen/generated/android/c++/JSheetDetent.cpp +26 -0
- package/nitrogen/generated/android/c++/JSheetDetent.hpp +42 -37
- package/nitrogen/generated/android/c++/views/JHybridNitroModalStateUpdater.cpp +30 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromodal/HybridNitroModalSpec.kt +52 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromodal/NamedSheetDetent.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromodal/SheetDetent.kt +47 -10
- package/nitrogen/generated/android/nitromodal+autolinking.cmake +1 -0
- package/nitrogen/generated/ios/NitroModal-Swift-Cxx-Bridge.hpp +68 -8
- package/nitrogen/generated/ios/NitroModal-Swift-Cxx-Umbrella.hpp +4 -3
- package/nitrogen/generated/ios/c++/HybridNitroModalSpecSwift.hpp +46 -5
- package/nitrogen/generated/ios/c++/views/HybridNitroModalComponent.mm +36 -0
- package/nitrogen/generated/ios/swift/HybridNitroModalSpec.swift +6 -0
- package/nitrogen/generated/ios/swift/HybridNitroModalSpec_cxx.swift +158 -5
- package/nitrogen/generated/ios/swift/NamedSheetDetent.swift +48 -0
- package/nitrogen/generated/ios/swift/SheetDetent.swift +15 -33
- package/nitrogen/generated/shared/c++/HybridNitroModalSpec.cpp +12 -0
- package/nitrogen/generated/shared/c++/HybridNitroModalSpec.hpp +18 -5
- package/nitrogen/generated/shared/c++/{SheetDetent.hpp → NamedSheetDetent.hpp} +17 -17
- package/nitrogen/generated/shared/c++/views/HybridNitroModalComponent.cpp +13 -1
- package/nitrogen/generated/shared/c++/views/HybridNitroModalComponent.hpp +21 -2
- package/nitrogen/generated/shared/json/NitroModalConfig.json +6 -0
- package/package.json +1 -1
- package/src/NitroModal.nitro.ts +38 -2
- package/src/NitroModal.tsx +93 -4
- package/src/NitroModalView.web.tsx +79 -12
- package/src/index.tsx +2 -0
- package/src/web/AnimatedValue.ts +4 -0
- package/src/web/ModalConfig.ts +19 -3
- package/src/web/ModalController.ts +35 -2
- package/src/web/ModalPresenter.ts +50 -11
- package/src/web/SheetPresenter.ts +169 -37
- package/src/web/dom.ts +20 -0
package/README.md
CHANGED
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
|
|
18
18
|
## Features
|
|
19
19
|
|
|
20
|
-
- 📄 **Native bottom sheets** with multiple detents (`small`, `medium`, `large`, `fitContent`) and swipe-to-dismiss
|
|
20
|
+
- 📄 **Native bottom sheets** with multiple detents (`small`, `medium`, `large`, `fitContent` or a height) and swipe-to-dismiss
|
|
21
|
+
- 📌 **Inline sheets** — a persistent sheet that is part of your screen, with the views behind it still usable
|
|
22
|
+
- 🔄 **Pull to refresh** — pulling a sheet down past its lowest detent, with a native activity indicator
|
|
21
23
|
- 🪟 **Centered popups** with native `scale` / `fade` transitions
|
|
22
24
|
- 📏 **Content-sized sheets** — `fitContent` measures your React content and grows with it
|
|
23
25
|
- ⌨️ **Keyboard aware** — the sheet or card follows the keyboard animation (`pan` or `resize`)
|
|
@@ -111,6 +113,40 @@ Detents are listed smallest first. `initialDetentIndex` selects where the sheet
|
|
|
111
113
|
</NitroModal>
|
|
112
114
|
```
|
|
113
115
|
|
|
116
|
+
### Inline (persistent) bottom sheet
|
|
117
|
+
|
|
118
|
+
`presentation="inline"` keeps the sheet inside the component's own frame instead of presenting it over the app — like a sheet that is part of the screen. There is no backdrop, the views behind it stay interactive, it moves with your screen during navigation, and the user can't dismiss it. Position the frame with `style` (it fills its parent by default); the sheet rests against its bottom edge and its largest detent reaches its top edge.
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
<View style={{ flex: 1 }}>
|
|
122
|
+
<ScreenContent />
|
|
123
|
+
|
|
124
|
+
<NitroModal
|
|
125
|
+
isOpen
|
|
126
|
+
presentation="inline"
|
|
127
|
+
style={{ top: headerHeight }}
|
|
128
|
+
detents={[320, 'large']}
|
|
129
|
+
refreshing={isRefreshing}
|
|
130
|
+
onPullToRefresh={refresh}
|
|
131
|
+
>
|
|
132
|
+
<FlatList data={rows} renderItem={renderRow} nestedScrollEnabled />
|
|
133
|
+
</NitroModal>
|
|
134
|
+
</View>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
A number in `detents` is the content height in dp/pt above the bottom safe area.
|
|
138
|
+
|
|
139
|
+
### Scrolling content and pull to refresh
|
|
140
|
+
|
|
141
|
+
A sheet hands drags off to the scroll view under the finger:
|
|
142
|
+
|
|
143
|
+
- Dragging up expands the sheet first, then scrolls the content.
|
|
144
|
+
- Dragging down scrolls the content back to its top. Once the content has scrolled during a drag, that drag never moves the sheet; the next drag collapses it.
|
|
145
|
+
- With `onPullToRefresh` set, a drag that starts with the sheet resting on its lowest detent can pull it further down. Letting go past the threshold calls `onPullToRefresh` (with haptic feedback when it is crossed). This needs a sheet that can't be swiped away: inline, or `dismissOnSwipe={false}`.
|
|
146
|
+
- With `refreshing` set too, an activity indicator shows in the gap the pull uncovers, and the sheet stays pulled down while `refreshing` is `true`, like `RefreshControl`. Set it to `true` in `onPullToRefresh` and back to `false` when the refresh is done. Setting it to `true` yourself shows the indicator without a pull.
|
|
147
|
+
|
|
148
|
+
On Android, scrollable content takes part through nested scrolling, so set `nestedScrollEnabled` on it.
|
|
149
|
+
|
|
114
150
|
### Popup
|
|
115
151
|
|
|
116
152
|
```tsx
|
|
@@ -168,7 +204,9 @@ const sheet = useRef<NitroModalRef>(null);
|
|
|
168
204
|
| ------------------------ | ---------------------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------- |
|
|
169
205
|
| `isOpen` | `boolean` | — | Controls visibility. Leave undefined to use the [ref API](#nitromodalref) instead. |
|
|
170
206
|
| `mode` | `'bottomSheet' \| 'popup'` | `'bottomSheet'` | How the modal is presented. |
|
|
171
|
-
| `
|
|
207
|
+
| `presentation` | `'modal' \| 'inline'` | `'modal'` | `inline` keeps a bottom sheet inside the component's frame, as part of the screen. See [Inline](#inline-persistent-bottom-sheet). |
|
|
208
|
+
| `style` | `StyleProp<ViewStyle>` | `absoluteFill` | Inline only: the frame the sheet lives in. |
|
|
209
|
+
| `detents` | `SheetDetent[]` | `['fitContent']` | Sheet heights, smallest first: named sizes or a content height in dp/pt. Android uses at most three. |
|
|
172
210
|
| `initialDetentIndex` | `number` | `0` | Index into `detents` the sheet opens at. |
|
|
173
211
|
| `backdropColor` | `ColorValue` | `'black'` | Backdrop color. |
|
|
174
212
|
| `backdropOpacity` | `number` | `0.4` | Backdrop opacity, `0`–`1`. |
|
|
@@ -181,6 +219,8 @@ const sheet = useRef<NitroModalRef>(null);
|
|
|
181
219
|
| `backgroundColor` | `ColorValue` | system surface | Background of the sheet/card. |
|
|
182
220
|
| `keyboardBehavior` | `'pan' \| 'resize' \| 'none'` | `'pan'` | How the modal reacts to the software keyboard. |
|
|
183
221
|
| `popupAnimation` | `'scale' \| 'fade' \| 'none'` | `'scale'` | Enter/exit transition of a popup. |
|
|
222
|
+
| `refreshing` | `boolean` | — | A refresh is in progress: the sheet stays pulled down with an activity indicator. See [pull to refresh](#scrolling-content-and-pull-to-refresh). |
|
|
223
|
+
| `refreshIndicatorColor` | `ColorValue` | platform default | Color of the refresh indicator. |
|
|
184
224
|
| `contentContainerStyle` | `StyleProp<ViewStyle>` | — | Style of the view that wraps `children` inside the modal. |
|
|
185
225
|
| `testID` | `string` | — | Applied to the content container. |
|
|
186
226
|
| `ref` | `Ref<NitroModalRef>` | — | Imperative handle. |
|
|
@@ -194,6 +234,7 @@ const sheet = useRef<NitroModalRef>(null);
|
|
|
194
234
|
| `onDetentChange` | `(index: number) => void` | A bottom sheet settled on a different detent. |
|
|
195
235
|
| `onBackdropPress` | `() => void` | The backdrop was tapped (fires even when `dismissOnBackdropPress` is `false`). |
|
|
196
236
|
| `onBackButtonPress` | `() => void` | The Android hardware/gesture back (Escape on web) was pressed. |
|
|
237
|
+
| `onPullToRefresh` | `() => void` | The sheet was pulled down past its lowest detent and released. See [pull to refresh](#scrolling-content-and-pull-to-refresh). |
|
|
197
238
|
|
|
198
239
|
### `NitroModalRef`
|
|
199
240
|
|
|
@@ -208,12 +249,17 @@ const sheet = useRef<NitroModalRef>(null);
|
|
|
208
249
|
```ts
|
|
209
250
|
type ModalMode = 'bottomSheet' | 'popup';
|
|
210
251
|
|
|
211
|
-
type
|
|
252
|
+
type ModalPresentation = 'modal' | 'inline';
|
|
253
|
+
|
|
254
|
+
type NamedSheetDetent =
|
|
212
255
|
| 'small' // ~25% of the available height
|
|
213
256
|
| 'medium' // ~50% of the available height
|
|
214
257
|
| 'large' // the full available height
|
|
215
258
|
| 'fitContent'; // the measured height of your content
|
|
216
259
|
|
|
260
|
+
// A named height, or the content height in dp/pt above the bottom safe area.
|
|
261
|
+
type SheetDetent = NamedSheetDetent | number;
|
|
262
|
+
|
|
217
263
|
type KeyboardBehavior = 'pan' | 'resize' | 'none';
|
|
218
264
|
|
|
219
265
|
type PopupAnimation = 'scale' | 'fade' | 'none';
|
|
@@ -228,6 +274,8 @@ import type {
|
|
|
228
274
|
DismissReason,
|
|
229
275
|
KeyboardBehavior,
|
|
230
276
|
ModalMode,
|
|
277
|
+
ModalPresentation,
|
|
278
|
+
NamedSheetDetent,
|
|
231
279
|
NitroModalProps,
|
|
232
280
|
NitroModalRef,
|
|
233
281
|
PopupAnimation,
|
|
@@ -237,7 +285,7 @@ import type {
|
|
|
237
285
|
|
|
238
286
|
## How it works
|
|
239
287
|
|
|
240
|
-
`<NitroModal>` mounts a zero-size placeholder in your React tree. When opened, the native side presents a real view controller (iOS) or window (Android) and hosts your React children inside it. Children mount when the modal opens and stay mounted until the native exit animation completes, so content never disappears mid-transition. The native side also reports the exact area available to the content (accounting for rotation, keyboard and sheet size), and the content container is sized accordingly.
|
|
288
|
+
`<NitroModal>` mounts a zero-size placeholder in your React tree. When opened, the native side presents a real view controller (iOS) or window (Android) and hosts your React children inside it. An inline sheet instead lives in a view laid out with `style`, in your screen's own hierarchy: touches that miss the sheet go to the views behind it, and `keyboardBehavior` doesn't apply (the screen's own keyboard handling does). Children mount when the modal opens and stay mounted until the native exit animation completes, so content never disappears mid-transition. The native side also reports the exact area available to the content (accounting for rotation, keyboard and sheet size), and the content container is sized accordingly.
|
|
241
289
|
|
|
242
290
|
## Platform notes
|
|
243
291
|
|