@oxyhq/bloom 0.3.12 → 0.5.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/README.md +133 -90
- package/lib/commonjs/bottom-sheet/index.js +341 -98
- package/lib/commonjs/bottom-sheet/index.js.map +1 -1
- package/lib/commonjs/context-menu/index.js +18 -19
- package/lib/commonjs/context-menu/index.js.map +1 -1
- package/lib/commonjs/dialog/BloomDialogProvider.js +61 -0
- package/lib/commonjs/dialog/BloomDialogProvider.js.map +1 -0
- package/lib/commonjs/dialog/BloomDialogProvider.web.js +45 -0
- package/lib/commonjs/dialog/BloomDialogProvider.web.js.map +1 -0
- package/lib/commonjs/dialog/Dialog.js +197 -100
- package/lib/commonjs/dialog/Dialog.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +194 -84
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/dialog/SheetShell.js +149 -0
- package/lib/commonjs/dialog/SheetShell.js.map +1 -0
- package/lib/commonjs/dialog/alert-store.js +116 -0
- package/lib/commonjs/dialog/alert-store.js.map +1 -0
- package/lib/commonjs/dialog/alert.js +38 -0
- package/lib/commonjs/dialog/alert.js.map +1 -0
- package/lib/commonjs/dialog/context.js +10 -2
- package/lib/commonjs/dialog/context.js.map +1 -1
- package/lib/commonjs/dialog/index.js +8 -24
- package/lib/commonjs/dialog/index.js.map +1 -1
- package/lib/commonjs/dialog/index.web.js +10 -20
- package/lib/commonjs/dialog/index.web.js.map +1 -1
- package/lib/commonjs/index.js +101 -66
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +101 -66
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/menu/index.js +21 -23
- package/lib/commonjs/menu/index.js.map +1 -1
- package/lib/commonjs/select/index.js +26 -27
- package/lib/commonjs/select/index.js.map +1 -1
- package/lib/commonjs/toast/index.js +42 -13
- package/lib/commonjs/toast/index.js.map +1 -1
- package/lib/commonjs/toast/index.web.js +19 -15
- package/lib/commonjs/toast/index.web.js.map +1 -1
- package/lib/module/bottom-sheet/index.js +341 -98
- package/lib/module/bottom-sheet/index.js.map +1 -1
- package/lib/module/context-menu/index.js +15 -16
- package/lib/module/context-menu/index.js.map +1 -1
- package/lib/module/dialog/BloomDialogProvider.js +57 -0
- package/lib/module/dialog/BloomDialogProvider.js.map +1 -0
- package/lib/module/dialog/BloomDialogProvider.web.js +41 -0
- package/lib/module/dialog/BloomDialogProvider.web.js.map +1 -0
- package/lib/module/dialog/Dialog.js +199 -87
- package/lib/module/dialog/Dialog.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +195 -70
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/dialog/SheetShell.js +143 -0
- package/lib/module/dialog/SheetShell.js.map +1 -0
- package/lib/module/dialog/alert-store.js +107 -0
- package/lib/module/dialog/alert-store.js.map +1 -0
- package/lib/module/dialog/alert.js +35 -0
- package/lib/module/dialog/alert.js.map +1 -0
- package/lib/module/dialog/context.js +10 -2
- package/lib/module/dialog/context.js.map +1 -1
- package/lib/module/dialog/index.js +3 -1
- package/lib/module/dialog/index.js.map +1 -1
- package/lib/module/dialog/index.web.js +9 -7
- package/lib/module/dialog/index.web.js.map +1 -1
- package/lib/module/index.js +2 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +2 -3
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/menu/index.js +11 -13
- package/lib/module/menu/index.js.map +1 -1
- package/lib/module/select/index.js +27 -28
- package/lib/module/select/index.js.map +1 -1
- package/lib/module/toast/index.js +41 -11
- package/lib/module/toast/index.js.map +1 -1
- package/lib/module/toast/index.web.js +18 -13
- package/lib/module/toast/index.web.js.map +1 -1
- package/lib/typescript/commonjs/__tests__/Dialog.test.d.ts +2 -0
- package/lib/typescript/commonjs/__tests__/Dialog.test.d.ts.map +1 -0
- package/lib/typescript/commonjs/bottom-sheet/index.d.ts +47 -1
- package/lib/typescript/commonjs/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/context-menu/index.d.ts +4 -3
- package/lib/typescript/commonjs/context-menu/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/BloomDialogProvider.d.ts +27 -0
- package/lib/typescript/commonjs/dialog/BloomDialogProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/dialog/BloomDialogProvider.web.d.ts +15 -0
- package/lib/typescript/commonjs/dialog/BloomDialogProvider.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/dialog/Dialog.d.ts +37 -10
- package/lib/typescript/commonjs/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts +26 -10
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/SheetShell.d.ts +31 -0
- package/lib/typescript/commonjs/dialog/SheetShell.d.ts.map +1 -0
- package/lib/typescript/commonjs/dialog/alert-store.d.ts +70 -0
- package/lib/typescript/commonjs/dialog/alert-store.d.ts.map +1 -0
- package/lib/typescript/commonjs/dialog/alert.d.ts +27 -0
- package/lib/typescript/commonjs/dialog/alert.d.ts.map +1 -0
- package/lib/typescript/commonjs/dialog/context.d.ts +7 -0
- package/lib/typescript/commonjs/dialog/context.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/index.d.ts +5 -2
- package/lib/typescript/commonjs/dialog/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/index.web.d.ts +5 -2
- package/lib/typescript/commonjs/dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/types.d.ts +70 -15
- package/lib/typescript/commonjs/dialog/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +3 -3
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +3 -3
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/menu/index.d.ts +4 -4
- package/lib/typescript/commonjs/menu/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/select/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/toast/index.d.ts +32 -3
- package/lib/typescript/commonjs/toast/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/toast/index.web.d.ts +14 -7
- package/lib/typescript/commonjs/toast/index.web.d.ts.map +1 -1
- package/lib/typescript/module/__tests__/Dialog.test.d.ts +2 -0
- package/lib/typescript/module/__tests__/Dialog.test.d.ts.map +1 -0
- package/lib/typescript/module/bottom-sheet/index.d.ts +47 -1
- package/lib/typescript/module/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/module/context-menu/index.d.ts +4 -3
- package/lib/typescript/module/context-menu/index.d.ts.map +1 -1
- package/lib/typescript/module/dialog/BloomDialogProvider.d.ts +27 -0
- package/lib/typescript/module/dialog/BloomDialogProvider.d.ts.map +1 -0
- package/lib/typescript/module/dialog/BloomDialogProvider.web.d.ts +15 -0
- package/lib/typescript/module/dialog/BloomDialogProvider.web.d.ts.map +1 -0
- package/lib/typescript/module/dialog/Dialog.d.ts +37 -10
- package/lib/typescript/module/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.web.d.ts +26 -10
- package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/SheetShell.d.ts +31 -0
- package/lib/typescript/module/dialog/SheetShell.d.ts.map +1 -0
- package/lib/typescript/module/dialog/alert-store.d.ts +70 -0
- package/lib/typescript/module/dialog/alert-store.d.ts.map +1 -0
- package/lib/typescript/module/dialog/alert.d.ts +27 -0
- package/lib/typescript/module/dialog/alert.d.ts.map +1 -0
- package/lib/typescript/module/dialog/context.d.ts +7 -0
- package/lib/typescript/module/dialog/context.d.ts.map +1 -1
- package/lib/typescript/module/dialog/index.d.ts +5 -2
- package/lib/typescript/module/dialog/index.d.ts.map +1 -1
- package/lib/typescript/module/dialog/index.web.d.ts +5 -2
- package/lib/typescript/module/dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/types.d.ts +70 -15
- package/lib/typescript/module/dialog/types.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +3 -3
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +3 -3
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/menu/index.d.ts +4 -4
- package/lib/typescript/module/menu/index.d.ts.map +1 -1
- package/lib/typescript/module/select/index.d.ts.map +1 -1
- package/lib/typescript/module/toast/index.d.ts +32 -3
- package/lib/typescript/module/toast/index.d.ts.map +1 -1
- package/lib/typescript/module/toast/index.web.d.ts +14 -7
- package/lib/typescript/module/toast/index.web.d.ts.map +1 -1
- package/package.json +3 -14
- package/src/__tests__/BottomSheet.test.tsx +149 -2
- package/src/__tests__/Dialog.test.tsx +177 -0
- package/src/bottom-sheet/index.tsx +367 -83
- package/src/context-menu/index.tsx +12 -12
- package/src/dialog/BloomDialogProvider.tsx +61 -0
- package/src/dialog/BloomDialogProvider.web.tsx +46 -0
- package/src/dialog/Dialog.tsx +217 -64
- package/src/dialog/Dialog.web.tsx +240 -75
- package/src/dialog/SheetShell.tsx +154 -0
- package/src/dialog/alert-store.ts +126 -0
- package/src/dialog/alert.ts +42 -0
- package/src/dialog/context.ts +14 -3
- package/src/dialog/index.ts +14 -2
- package/src/dialog/index.web.ts +20 -8
- package/src/dialog/types.ts +73 -16
- package/src/index.ts +17 -3
- package/src/index.web.ts +17 -3
- package/src/menu/index.tsx +13 -17
- package/src/select/index.tsx +30 -30
- package/src/toast/index.tsx +55 -11
- package/src/toast/index.web.tsx +33 -13
- package/lib/commonjs/prompt/Prompt.js +0 -267
- package/lib/commonjs/prompt/Prompt.js.map +0 -1
- package/lib/commonjs/prompt/index.js +0 -61
- package/lib/commonjs/prompt/index.js.map +0 -1
- package/lib/module/prompt/Prompt.js +0 -250
- package/lib/module/prompt/Prompt.js.map +0 -1
- package/lib/module/prompt/index.js +0 -4
- package/lib/module/prompt/index.js.map +0 -1
- package/lib/typescript/commonjs/prompt/Prompt.d.ts +0 -42
- package/lib/typescript/commonjs/prompt/Prompt.d.ts.map +0 -1
- package/lib/typescript/commonjs/prompt/index.d.ts +0 -3
- package/lib/typescript/commonjs/prompt/index.d.ts.map +0 -1
- package/lib/typescript/module/prompt/Prompt.d.ts +0 -42
- package/lib/typescript/module/prompt/Prompt.d.ts.map +0 -1
- package/lib/typescript/module/prompt/index.d.ts +0 -3
- package/lib/typescript/module/prompt/index.d.ts.map +0 -1
- package/src/prompt/Prompt.tsx +0 -247
- package/src/prompt/index.ts +0 -13
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Shared UI component library for the Oxy ecosystem. Built for React Native + Expo
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
|
-
|
|
8
|
+
bun add @oxyhq/bloom
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
### Peer dependencies
|
|
@@ -18,10 +18,10 @@ Required:
|
|
|
18
18
|
|
|
19
19
|
Optional:
|
|
20
20
|
|
|
21
|
-
- `@gorhom/bottom-sheet >= 5` (native `Dialog` and `Prompt`) — also requires wrapping the app root with `BottomSheetModalProvider`, see [Dialog](#dialog).
|
|
22
21
|
- `react-native-reanimated >= 3` (native `Dialog`, `BottomSheet`, Loading `top` variant)
|
|
23
22
|
- `react-native-gesture-handler >= 2` (native `Dialog`, `BottomSheet`) — also requires wrapping the app root with `GestureHandlerRootView`, see [Dialog](#dialog).
|
|
24
23
|
- `react-native-svg >= 13` (Avatar `squircle` shape)
|
|
24
|
+
- `sonner >= 2` / `sonner-native >= 0.17` (`toast`)
|
|
25
25
|
|
|
26
26
|
## Usage
|
|
27
27
|
|
|
@@ -50,76 +50,107 @@ const theme = useTheme();
|
|
|
50
50
|
|
|
51
51
|
4 modes: `light`, `dark`, `system`, `adaptive` (uses iOS/Android native dynamic colors when available).
|
|
52
52
|
|
|
53
|
-
### Modal components: Dialog,
|
|
53
|
+
### Modal & feedback components: Dialog, BottomSheet, toast / alert
|
|
54
54
|
|
|
55
|
-
Bloom ships three
|
|
55
|
+
Bloom ships three primitives for modal, sheet, and feedback presentation. Pick the one that matches your use case:
|
|
56
56
|
|
|
57
57
|
| Component | Native | Web | Use when |
|
|
58
58
|
|-----------|--------|-----|----------|
|
|
59
|
-
| `Dialog` | Bottom
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
|
|
63
|
-
`Prompt` is built on top of `Dialog` (so the provider requirements are the same). `BottomSheet` is a separate, standalone implementation.
|
|
59
|
+
| `Dialog` | Bottom-sheet card (Bloom's own) | Centered modal | Confirmation flows AND custom modal content — same component handles both |
|
|
60
|
+
| `BottomSheet` | Draggable sheet | RN `Modal` polyfill | You need direct control over snap points, scroll handoff, keyboard, detached/flush layout |
|
|
61
|
+
| `toast` / `alert` | Sonner-native + Bloom theme | Sonner + Bloom theme | Passive feedback (`toast`) or one-shot confirmations (`alert`) called imperatively from anywhere |
|
|
64
62
|
|
|
65
63
|
### Dialog
|
|
66
64
|
|
|
67
|
-
|
|
65
|
+
A single `<Dialog>` component for both confirmation flows AND custom modal content. Bottom-sheet card on native, centered modal on web.
|
|
68
66
|
|
|
69
|
-
> **Required providers (native).**
|
|
67
|
+
> **Required providers (native).** Your app root **must** be wrapped with `GestureHandlerRootView` from `react-native-gesture-handler` for the bottom-sheet pan gestures to work.
|
|
70
68
|
|
|
71
69
|
```tsx
|
|
72
70
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
73
|
-
import {
|
|
74
|
-
import { BloomThemeProvider } from '@oxyhq/bloom/theme';
|
|
71
|
+
import { BloomThemeProvider, BloomDialogProvider } from '@oxyhq/bloom';
|
|
75
72
|
|
|
76
73
|
export default function Root() {
|
|
77
74
|
return (
|
|
78
75
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
79
76
|
<BloomThemeProvider mode="system" colorPreset="oxy">
|
|
80
|
-
<
|
|
77
|
+
<BloomDialogProvider>
|
|
81
78
|
<App />
|
|
82
|
-
</
|
|
79
|
+
</BloomDialogProvider>
|
|
83
80
|
</BloomThemeProvider>
|
|
84
81
|
</GestureHandlerRootView>
|
|
85
82
|
);
|
|
86
83
|
}
|
|
87
84
|
```
|
|
88
85
|
|
|
89
|
-
|
|
86
|
+
`BloomDialogProvider` powers the imperative `alert()` helper (see below) — mount it once near the app root.
|
|
90
87
|
|
|
91
|
-
|
|
92
|
-
import * as Dialog from '@oxyhq/bloom/dialog';
|
|
88
|
+
#### Declarative (the 90% case)
|
|
93
89
|
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
```tsx
|
|
91
|
+
import { Dialog, useDialogControl } from '@oxyhq/bloom';
|
|
96
92
|
|
|
93
|
+
function SignOutButton() {
|
|
94
|
+
const control = useDialogControl();
|
|
97
95
|
return (
|
|
98
96
|
<>
|
|
99
|
-
<Button onPress={() => control.open()}>
|
|
100
|
-
|
|
101
|
-
<Dialog
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
97
|
+
<Button onPress={() => control.open()}>Sign out</Button>
|
|
98
|
+
|
|
99
|
+
<Dialog
|
|
100
|
+
control={control}
|
|
101
|
+
title="Sign out?"
|
|
102
|
+
description="You'll need to enter your password to sign in again."
|
|
103
|
+
actions={[
|
|
104
|
+
{ label: 'Sign out', color: 'destructive', onPress: doSignOut },
|
|
105
|
+
{ label: 'Cancel', color: 'cancel' },
|
|
106
|
+
]}
|
|
107
|
+
/>
|
|
107
108
|
</>
|
|
108
109
|
);
|
|
109
110
|
}
|
|
110
111
|
```
|
|
111
112
|
|
|
112
|
-
|
|
113
|
+
#### Custom content
|
|
113
114
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
Provide any JSX as `children`. Combine with `title` to keep a consistent header.
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<Dialog control={control} title="Pick a tag">
|
|
119
|
+
<YourCustomBody />
|
|
120
|
+
</Dialog>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Pure custom
|
|
124
|
+
|
|
125
|
+
Drop the declarative props entirely — `children` owns every pixel.
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
<Dialog control={control}>
|
|
129
|
+
<YourEntirelyCustomLayout />
|
|
130
|
+
</Dialog>
|
|
131
|
+
```
|
|
119
132
|
|
|
120
|
-
|
|
133
|
+
#### Props
|
|
121
134
|
|
|
122
|
-
|
|
135
|
+
- `control` — from `useDialogControl()`.
|
|
136
|
+
- `title?: string` — header text.
|
|
137
|
+
- `description?: string` — supporting copy rendered below the title.
|
|
138
|
+
- `actions?: DialogAction[]` — confirmation buttons. Each action accepts:
|
|
139
|
+
- `label: string` — button text.
|
|
140
|
+
- `color?: 'default' | 'cancel' | 'destructive'` — defaults to `'default'`.
|
|
141
|
+
- `onPress?: (e) => void` — invoked after the dialog finishes closing.
|
|
142
|
+
- `disabled?: boolean`
|
|
143
|
+
- `shouldCloseOnPress?: boolean` — defaults to `true`. Set `false` while an async action is in flight.
|
|
144
|
+
- `testID?: string`
|
|
145
|
+
- `children?: React.ReactNode` — custom content rendered after the description.
|
|
146
|
+
- `onClose?: () => void` — fires after the dialog has finished closing.
|
|
147
|
+
- `style?` — applied to the dialog content container.
|
|
148
|
+
- `label?: string` — accessibility label.
|
|
149
|
+
- `testID?: string`
|
|
150
|
+
|
|
151
|
+
#### Web setup
|
|
152
|
+
|
|
153
|
+
Inject the CSS animations into your global styles once:
|
|
123
154
|
|
|
124
155
|
```tsx
|
|
125
156
|
import { BLOOM_DIALOG_CSS } from '@oxyhq/bloom/dialog';
|
|
@@ -128,66 +159,49 @@ import { BLOOM_DIALOG_CSS } from '@oxyhq/bloom/dialog';
|
|
|
128
159
|
<style>{BLOOM_DIALOG_CSS}</style>
|
|
129
160
|
```
|
|
130
161
|
|
|
131
|
-
###
|
|
132
|
-
|
|
133
|
-
Confirmation dialogs built on top of `Dialog`. On native, constrained to a 40% bottom sheet (Gorhom); on web, a centered 320px modal. Same provider requirements as [Dialog](#dialog).
|
|
162
|
+
### toast
|
|
134
163
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
`Prompt.Basic` — one-shot confirm dialog:
|
|
164
|
+
Passive notifications, sonner under the hood, themed by bloom.
|
|
138
165
|
|
|
139
166
|
```tsx
|
|
140
|
-
import
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
confirmButtonCta="Delete"
|
|
154
|
-
confirmButtonColor="negative"
|
|
155
|
-
onConfirm={() => handleDelete()}
|
|
156
|
-
/>
|
|
157
|
-
</>
|
|
158
|
-
);
|
|
159
|
-
}
|
|
167
|
+
import { toast } from '@oxyhq/bloom';
|
|
168
|
+
import { ToastOutlet } from '@oxyhq/bloom/toast';
|
|
169
|
+
|
|
170
|
+
// Mount once near the app root, inside BloomThemeProvider:
|
|
171
|
+
<ToastOutlet />
|
|
172
|
+
|
|
173
|
+
// Anywhere in your app:
|
|
174
|
+
toast('Saved');
|
|
175
|
+
toast.success('Profile updated');
|
|
176
|
+
toast.error('Network error', { duration: 5000 });
|
|
177
|
+
toast.warning('Please verify your email');
|
|
178
|
+
toast.info('A new version is available');
|
|
179
|
+
toast.dismiss(id);
|
|
160
180
|
```
|
|
161
181
|
|
|
162
|
-
`
|
|
182
|
+
`toast(content, options?)` accepts strings or React elements. `options.type` (`'default' | 'success' | 'error' | 'warning' | 'info'`) is overridden by the typed helpers above.
|
|
163
183
|
|
|
164
|
-
|
|
165
|
-
- `title: string`
|
|
166
|
-
- `description?: string`
|
|
167
|
-
- `confirmButtonCta?: string` — defaults to `'Confirm'`.
|
|
168
|
-
- `cancelButtonCta?: string` — defaults to `'Cancel'`.
|
|
169
|
-
- `confirmButtonColor?: ActionColor` — defaults to `'primary'`.
|
|
170
|
-
- `onConfirm: (e) => void`
|
|
171
|
-
- `showCancel?: boolean` — defaults to `true`.
|
|
184
|
+
### alert()
|
|
172
185
|
|
|
173
|
-
|
|
186
|
+
Imperative one-shot confirmation dialogs, matching React Native's `Alert.alert(title, message?, buttons?)` signature. Calls are queued and rendered through `BloomDialogProvider` — you can call `alert()` from anywhere, including before the provider mounts (alerts queue and drain on subscribe).
|
|
174
187
|
|
|
175
188
|
```tsx
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
</Prompt.Outer>
|
|
189
|
+
import { alert } from '@oxyhq/bloom';
|
|
190
|
+
|
|
191
|
+
alert('Sign out?', 'Are you sure you want to sign out of this device?', [
|
|
192
|
+
{ text: 'Cancel', style: 'cancel' },
|
|
193
|
+
{ text: 'Sign out', style: 'destructive', onPress: doSignOut },
|
|
194
|
+
]);
|
|
195
|
+
|
|
196
|
+
// Single OK button (default when no buttons passed):
|
|
197
|
+
alert('Saved');
|
|
186
198
|
```
|
|
187
199
|
|
|
188
|
-
|
|
200
|
+
Each button:
|
|
189
201
|
|
|
190
|
-
`
|
|
202
|
+
- `text: string` — required label.
|
|
203
|
+
- `style?: 'default' | 'cancel' | 'destructive'` — defaults to `'default'`.
|
|
204
|
+
- `onPress?: () => void` — fires after the dialog finishes closing.
|
|
191
205
|
|
|
192
206
|
### BottomSheet
|
|
193
207
|
|
|
@@ -222,9 +236,37 @@ function Example() {
|
|
|
222
236
|
- `enableHandlePanningGesture?: boolean` — defaults to `true`.
|
|
223
237
|
- `onDismissAttempt?: () => boolean` — return `false` to veto a dismiss attempt.
|
|
224
238
|
- `detached?: boolean` — when `true`, the sheet floats with horizontal margins and rounded corners on all sides; when `false`, it's flush to the bottom edges with rounded top corners only.
|
|
239
|
+
- `showHandle?: boolean` — defaults to `true`. Toggles the drag handle pill at the top of the sheet.
|
|
240
|
+
- `backdropOpacity?: number` — opacity (0–1) of the dimming backdrop once fully visible. Defaults to `0.5`. Use a higher value (e.g. `0.7`) when stacking a sheet over another sheet.
|
|
225
241
|
- `backgroundComponent?` — custom background renderer.
|
|
226
242
|
- `backdropComponent?` — custom backdrop renderer.
|
|
227
243
|
- `style?`
|
|
244
|
+
- `scrollable?: boolean` — defaults to `true`. When `false`, renders `children` directly without the internal `Animated.ScrollView` wrapper. **Required when the sheet's content owns its own scrolling primitive** (e.g. `FlatList`, `SectionList`, or any `VirtualizedList`) — nesting a virtualized list inside the internal ScrollView breaks windowing and triggers a React Native warning. Combine with `manualActivation` so the handle stays draggable while the inner list owns the scroll.
|
|
245
|
+
- `manualActivation?: boolean` — defaults to `false`. When `true`, the body pan uses RNGH's `manualActivation` and only activates when (a) the inner ScrollView is at the top AND (b) the user has moved their finger downward by > 8dp. This is the `@gorhom/bottom-sheet` coordination model — recommended for sheets that contain a scrolling region on Android (the legacy always-active pan can steal vertical events from the inner scroller). Enabling this also gives the drag handle its own dedicated, unconditionally-active gesture so users can always grab the handle even mid-scroll.
|
|
246
|
+
- `dynamicBackdrop?: boolean` — defaults to `false`. When `true`, the backdrop dims proportionally to drag distance — fades from full `backdropOpacity` (sheet at rest) to 30% as the sheet is pulled down 40% of the screen height. This is the iOS Photos / iMessage drag-to-dismiss look. The base `backdropOpacity` still controls the resting dim.
|
|
247
|
+
- `handleComponent?: () => React.ReactNode` — custom drag-handle renderer. When provided (and `showHandle` is `true`), replaces the default 36×5 pill. In `manualActivation` mode the rendered handle sits inside the dedicated handle hit-area and gesture detector so it remains unconditionally draggable.
|
|
248
|
+
|
|
249
|
+
**Pattern: sheet with a `FlatList` inside.** Use `scrollable={false}` so the BottomSheet doesn't wrap the list in its own ScrollView, plus `manualActivation` so the drag handle remains the dedicated drag-to-dismiss surface while the list owns vertical scroll:
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
<BottomSheet ref={sheetRef} scrollable={false} manualActivation>
|
|
253
|
+
<FlatList data={items} renderItem={renderItem} />
|
|
254
|
+
</BottomSheet>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Pattern: iOS Photos-style backdrop dim.** Combine `manualActivation` (so the inner photo grid keeps scroll ownership) with `dynamicBackdrop` (so the overlay fades as the user pulls down):
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
<BottomSheet
|
|
261
|
+
ref={sheetRef}
|
|
262
|
+
scrollable={false}
|
|
263
|
+
manualActivation
|
|
264
|
+
dynamicBackdrop
|
|
265
|
+
backdropOpacity={0.85}
|
|
266
|
+
>
|
|
267
|
+
<PhotoGrid />
|
|
268
|
+
</BottomSheet>
|
|
269
|
+
```
|
|
228
270
|
|
|
229
271
|
### Button
|
|
230
272
|
|
|
@@ -368,9 +410,9 @@ import {
|
|
|
368
410
|
|
|
369
411
|
```ts
|
|
370
412
|
import { BloomThemeProvider, useTheme } from '@oxyhq/bloom/theme';
|
|
371
|
-
import
|
|
372
|
-
import * as Prompt from '@oxyhq/bloom/prompt';
|
|
413
|
+
import { Dialog, BloomDialogProvider, alert, useDialogControl } from '@oxyhq/bloom/dialog';
|
|
373
414
|
import { BottomSheet, type BottomSheetRef } from '@oxyhq/bloom/bottom-sheet';
|
|
415
|
+
import { toast, ToastOutlet } from '@oxyhq/bloom/toast';
|
|
374
416
|
import { Button, IconButton } from '@oxyhq/bloom/button';
|
|
375
417
|
import { GroupedButtons } from '@oxyhq/bloom/grouped-buttons';
|
|
376
418
|
import { Divider } from '@oxyhq/bloom/divider';
|
|
@@ -385,10 +427,11 @@ import { PromptInput, PromptInputTextarea } from '@oxyhq/bloom/prompt-input';
|
|
|
385
427
|
## Development
|
|
386
428
|
|
|
387
429
|
```sh
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
430
|
+
bun install
|
|
431
|
+
bun run build # react-native-builder-bob
|
|
432
|
+
bun run typescript # type-check
|
|
433
|
+
bun run test # jest
|
|
434
|
+
bun run clean # remove lib/
|
|
392
435
|
```
|
|
393
436
|
|
|
394
437
|
## License
|