@oxyhq/bloom 0.45.0 → 0.48.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/lib/commonjs/bottom-sheet/BottomSheetBase.js +34 -12
- package/lib/commonjs/bottom-sheet/BottomSheetBase.js.map +1 -1
- package/lib/commonjs/combobox/Combobox.js +3 -3
- package/lib/commonjs/combobox/Combobox.js.map +1 -1
- package/lib/commonjs/command/Command.js +3 -3
- package/lib/commonjs/command/Command.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.js +86 -8
- package/lib/commonjs/dialog/Dialog.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +176 -18
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/dialog/DialogBottomSheet.js +84 -29
- package/lib/commonjs/dialog/DialogBottomSheet.js.map +1 -1
- package/lib/commonjs/dialog/DialogHeader.js +365 -0
- package/lib/commonjs/dialog/DialogHeader.js.map +1 -0
- package/lib/commonjs/dialog/index.js +7 -0
- package/lib/commonjs/dialog/index.js.map +1 -1
- package/lib/commonjs/dialog/index.web.js +7 -0
- package/lib/commonjs/dialog/index.web.js.map +1 -1
- package/lib/commonjs/index.js +40 -4
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +84 -48
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/react-native-className.d.js +6 -0
- package/lib/commonjs/react-native-className.d.js.map +1 -0
- package/lib/commonjs/{search-input → search}/index.js +5 -3
- package/lib/commonjs/search/index.js.map +1 -0
- package/lib/commonjs/settings-list/SettingsList.js +5 -1
- package/lib/commonjs/settings-list/SettingsList.js.map +1 -1
- package/lib/commonjs/surfaces/SurfaceHost.js +202 -0
- package/lib/commonjs/surfaces/SurfaceHost.js.map +1 -0
- package/lib/commonjs/surfaces/api.js +83 -0
- package/lib/commonjs/surfaces/api.js.map +1 -0
- package/lib/commonjs/surfaces/index.js +82 -0
- package/lib/commonjs/surfaces/index.js.map +1 -0
- package/lib/commonjs/surfaces/index.web.js +77 -0
- package/lib/commonjs/surfaces/index.web.js.map +1 -0
- package/lib/commonjs/surfaces/prompts.js +154 -0
- package/lib/commonjs/surfaces/prompts.js.map +1 -0
- package/lib/commonjs/surfaces/surfaceStore.js +172 -0
- package/lib/commonjs/surfaces/surfaceStore.js.map +1 -0
- package/lib/commonjs/surfaces/types.js +6 -0
- package/lib/commonjs/surfaces/types.js.map +1 -0
- package/lib/commonjs/surfaces/useSurface.js +36 -0
- package/lib/commonjs/surfaces/useSurface.js.map +1 -0
- package/lib/commonjs/text-field/index.js +22 -6
- package/lib/commonjs/text-field/index.js.map +1 -1
- package/lib/module/bottom-sheet/BottomSheetBase.js +34 -12
- package/lib/module/bottom-sheet/BottomSheetBase.js.map +1 -1
- package/lib/module/combobox/Combobox.js +3 -3
- package/lib/module/combobox/Combobox.js.map +1 -1
- package/lib/module/command/Command.js +3 -3
- package/lib/module/command/Command.js.map +1 -1
- package/lib/module/dialog/Dialog.js +88 -10
- package/lib/module/dialog/Dialog.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +179 -21
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/dialog/DialogBottomSheet.js +85 -30
- package/lib/module/dialog/DialogBottomSheet.js.map +1 -1
- package/lib/module/dialog/DialogHeader.js +356 -0
- package/lib/module/dialog/DialogHeader.js.map +1 -0
- package/lib/module/dialog/index.js +1 -0
- package/lib/module/dialog/index.js.map +1 -1
- package/lib/module/dialog/index.web.js +1 -0
- package/lib/module/dialog/index.web.js.map +1 -1
- package/lib/module/index.js +7 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +7 -2
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/react-native-className.d.js +20 -0
- package/lib/module/react-native-className.d.js.map +1 -0
- package/lib/module/{search-input → search}/index.js +6 -2
- package/lib/module/search/index.js.map +1 -0
- package/lib/module/settings-list/SettingsList.js +5 -1
- package/lib/module/settings-list/SettingsList.js.map +1 -1
- package/lib/module/surfaces/SurfaceHost.js +197 -0
- package/lib/module/surfaces/SurfaceHost.js.map +1 -0
- package/lib/module/surfaces/api.js +48 -0
- package/lib/module/surfaces/api.js.map +1 -0
- package/lib/module/surfaces/index.js +24 -0
- package/lib/module/surfaces/index.js.map +1 -0
- package/lib/module/surfaces/index.web.js +19 -0
- package/lib/module/surfaces/index.web.js.map +1 -0
- package/lib/module/surfaces/prompts.js +148 -0
- package/lib/module/surfaces/prompts.js.map +1 -0
- package/lib/module/surfaces/surfaceStore.js +159 -0
- package/lib/module/surfaces/surfaceStore.js.map +1 -0
- package/lib/module/surfaces/types.js +4 -0
- package/lib/module/surfaces/types.js.map +1 -0
- package/lib/module/surfaces/useSurface.js +31 -0
- package/lib/module/surfaces/useSurface.js.map +1 -0
- package/lib/module/text-field/index.js +22 -6
- package/lib/module/text-field/index.js.map +1 -1
- package/lib/typescript/commonjs/bottom-sheet/BottomSheetBase.d.ts +23 -0
- package/lib/typescript/commonjs/bottom-sheet/BottomSheetBase.d.ts.map +1 -1
- package/lib/typescript/commonjs/combobox/Combobox.d.ts +1 -1
- package/lib/typescript/commonjs/command/Command.d.ts +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/DialogBottomSheet.d.ts +2 -2
- package/lib/typescript/commonjs/dialog/DialogBottomSheet.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/DialogHeader.d.ts +86 -0
- package/lib/typescript/commonjs/dialog/DialogHeader.d.ts.map +1 -0
- package/lib/typescript/commonjs/dialog/index.d.ts +2 -1
- package/lib/typescript/commonjs/dialog/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/index.web.d.ts +2 -1
- package/lib/typescript/commonjs/dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/types.d.ts +85 -0
- package/lib/typescript/commonjs/dialog/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/icons/common.d.ts +1 -0
- package/lib/typescript/commonjs/icons/common.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +5 -3
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +5 -3
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/input-group/types.d.ts +1 -1
- package/lib/typescript/commonjs/{search-input → search}/index.d.ts +1 -1
- package/lib/typescript/commonjs/search/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/surfaces/SurfaceHost.d.ts +25 -0
- package/lib/typescript/commonjs/surfaces/SurfaceHost.d.ts.map +1 -0
- package/lib/typescript/commonjs/surfaces/api.d.ts +41 -0
- package/lib/typescript/commonjs/surfaces/api.d.ts.map +1 -0
- package/lib/typescript/commonjs/surfaces/index.d.ts +25 -0
- package/lib/typescript/commonjs/surfaces/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/surfaces/index.web.d.ts +20 -0
- package/lib/typescript/commonjs/surfaces/index.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/surfaces/prompts.d.ts +13 -0
- package/lib/typescript/commonjs/surfaces/prompts.d.ts.map +1 -0
- package/lib/typescript/commonjs/surfaces/surfaceStore.d.ts +51 -0
- package/lib/typescript/commonjs/surfaces/surfaceStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/surfaces/types.d.ts +161 -0
- package/lib/typescript/commonjs/surfaces/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/surfaces/useSurface.d.ts +21 -0
- package/lib/typescript/commonjs/surfaces/useSurface.d.ts.map +1 -0
- package/lib/typescript/commonjs/text-field/index.d.ts +2 -1
- package/lib/typescript/commonjs/text-field/index.d.ts.map +1 -1
- package/lib/typescript/module/bottom-sheet/BottomSheetBase.d.ts +23 -0
- package/lib/typescript/module/bottom-sheet/BottomSheetBase.d.ts.map +1 -1
- package/lib/typescript/module/combobox/Combobox.d.ts +1 -1
- package/lib/typescript/module/command/Command.d.ts +1 -1
- package/lib/typescript/module/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/DialogBottomSheet.d.ts +2 -2
- package/lib/typescript/module/dialog/DialogBottomSheet.d.ts.map +1 -1
- package/lib/typescript/module/dialog/DialogHeader.d.ts +86 -0
- package/lib/typescript/module/dialog/DialogHeader.d.ts.map +1 -0
- package/lib/typescript/module/dialog/index.d.ts +2 -1
- package/lib/typescript/module/dialog/index.d.ts.map +1 -1
- package/lib/typescript/module/dialog/index.web.d.ts +2 -1
- package/lib/typescript/module/dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/types.d.ts +85 -0
- package/lib/typescript/module/dialog/types.d.ts.map +1 -1
- package/lib/typescript/module/icons/common.d.ts +1 -0
- package/lib/typescript/module/icons/common.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +5 -3
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +5 -3
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/input-group/types.d.ts +1 -1
- package/lib/typescript/module/{search-input → search}/index.d.ts +1 -1
- package/lib/typescript/module/search/index.d.ts.map +1 -0
- package/lib/typescript/module/surfaces/SurfaceHost.d.ts +25 -0
- package/lib/typescript/module/surfaces/SurfaceHost.d.ts.map +1 -0
- package/lib/typescript/module/surfaces/api.d.ts +41 -0
- package/lib/typescript/module/surfaces/api.d.ts.map +1 -0
- package/lib/typescript/module/surfaces/index.d.ts +25 -0
- package/lib/typescript/module/surfaces/index.d.ts.map +1 -0
- package/lib/typescript/module/surfaces/index.web.d.ts +20 -0
- package/lib/typescript/module/surfaces/index.web.d.ts.map +1 -0
- package/lib/typescript/module/surfaces/prompts.d.ts +13 -0
- package/lib/typescript/module/surfaces/prompts.d.ts.map +1 -0
- package/lib/typescript/module/surfaces/surfaceStore.d.ts +51 -0
- package/lib/typescript/module/surfaces/surfaceStore.d.ts.map +1 -0
- package/lib/typescript/module/surfaces/types.d.ts +161 -0
- package/lib/typescript/module/surfaces/types.d.ts.map +1 -0
- package/lib/typescript/module/surfaces/useSurface.d.ts +21 -0
- package/lib/typescript/module/surfaces/useSurface.d.ts.map +1 -0
- package/lib/typescript/module/text-field/index.d.ts +2 -1
- package/lib/typescript/module/text-field/index.d.ts.map +1 -1
- package/package.json +24 -8
- package/src/__tests__/BottomSheet.test.tsx +47 -0
- package/src/__tests__/DialogBottomSheet.test.tsx +30 -5
- package/src/__tests__/surfaceStore.test.ts +219 -0
- package/src/bottom-sheet/BottomSheetBase.tsx +59 -10
- package/src/combobox/Combobox.tsx +3 -3
- package/src/command/Command.tsx +3 -3
- package/src/dialog/Dialog.tsx +88 -7
- package/src/dialog/Dialog.web.tsx +179 -29
- package/src/dialog/DialogBottomSheet.tsx +90 -28
- package/src/dialog/DialogHeader.tsx +420 -0
- package/src/dialog/index.ts +2 -0
- package/src/dialog/index.web.ts +2 -0
- package/src/dialog/types.ts +86 -0
- package/src/index.ts +18 -1
- package/src/index.web.ts +18 -1
- package/src/input-group/types.ts +1 -1
- package/src/react-native-className.d.ts +38 -0
- package/src/{search-input → search}/index.tsx +8 -5
- package/src/settings-list/SettingsList.tsx +5 -1
- package/src/surfaces/SurfaceHost.tsx +222 -0
- package/src/surfaces/api.ts +55 -0
- package/src/surfaces/index.ts +38 -0
- package/src/surfaces/index.web.ts +33 -0
- package/src/surfaces/prompts.tsx +178 -0
- package/src/surfaces/surfaceStore.ts +168 -0
- package/src/surfaces/types.ts +172 -0
- package/src/surfaces/useSurface.ts +33 -0
- package/src/text-field/index.tsx +24 -5
- package/lib/commonjs/search-input/index.js.map +0 -1
- package/lib/module/search-input/index.js.map +0 -1
- package/lib/typescript/commonjs/search-input/index.d.ts.map +0 -1
- package/lib/typescript/module/search-input/index.d.ts.map +0 -1
package/src/dialog/types.ts
CHANGED
|
@@ -1,9 +1,51 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
1
2
|
import type { GestureResponderEvent, StyleProp, ViewStyle } from 'react-native';
|
|
2
3
|
|
|
3
4
|
import type { ResponsiveDialogPlacement } from './placement';
|
|
4
5
|
|
|
5
6
|
export type { DialogPlacement, ResponsiveDialogPlacement } from './placement';
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Config for the Dialog's OWN navigation header — a DISTINCT surface mode from
|
|
10
|
+
* the declarative `title`/`description`/`actions` centered-heading path. When
|
|
11
|
+
* present it turns the Dialog into a scrolling page with a sticky, gradient top
|
|
12
|
+
* bar (left + right slots) and a large collapsing title that lives in the
|
|
13
|
+
* Dialog's own scroll content; as the large title scrolls under the bar a small
|
|
14
|
+
* title cross-fades into the bar center. Screens render NO header of their own.
|
|
15
|
+
*
|
|
16
|
+
* A surface seeds this from its registry config; a mounted screen may override
|
|
17
|
+
* or augment any field at runtime via `useDialogHeader` (a dynamic title, a Save
|
|
18
|
+
* action on the right, etc.).
|
|
19
|
+
*/
|
|
20
|
+
export interface DialogHeaderConfig {
|
|
21
|
+
/** Collapsing title — rendered large in-content and small in the nav bar. */
|
|
22
|
+
title?: string;
|
|
23
|
+
/** Supporting copy under the large title (and, optionally, in the bar). */
|
|
24
|
+
subtitle?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Whether to render the large collapsing title in the scroll content.
|
|
27
|
+
* Defaults to `true`. When `false`, only the small nav-bar title shows (always
|
|
28
|
+
* visible, no collapse) and the content starts flush under the bar.
|
|
29
|
+
*/
|
|
30
|
+
largeTitle?: boolean;
|
|
31
|
+
/** Custom left slot node. Overrides the default back button. */
|
|
32
|
+
left?: ReactNode;
|
|
33
|
+
/** Custom right slot node. Overrides the default close button. */
|
|
34
|
+
right?: ReactNode;
|
|
35
|
+
/**
|
|
36
|
+
* When set, the default left slot renders a back button that calls this. A
|
|
37
|
+
* custom `left` node still wins. Set by the surface host when the surface can
|
|
38
|
+
* navigate back.
|
|
39
|
+
*/
|
|
40
|
+
onBack?: () => void;
|
|
41
|
+
/**
|
|
42
|
+
* Whether the default right slot renders a close button (dismiss). Defaults to
|
|
43
|
+
* `true`. A custom `right` node still wins. `false` suppresses the close
|
|
44
|
+
* affordance entirely (e.g. a blocking surface).
|
|
45
|
+
*/
|
|
46
|
+
showClose?: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
7
49
|
/**
|
|
8
50
|
* Side-sheet inset (px) from the root overlay's edges. Lets a host place a
|
|
9
51
|
* `left`/`right` placement "inside its own shell" — e.g. offset from the top
|
|
@@ -134,6 +176,40 @@ export type DialogProps = React.PropsWithChildren<{
|
|
|
134
176
|
inset?: DialogInset;
|
|
135
177
|
/** Whether to render the drag handle in bottom-sheet mode. Defaults to `true`. */
|
|
136
178
|
showHandle?: boolean;
|
|
179
|
+
/**
|
|
180
|
+
* Turns on the Dialog's OWN navigation header (see {@link DialogHeaderConfig}).
|
|
181
|
+
* When present the Dialog renders a sticky gradient nav bar + a large
|
|
182
|
+
* collapsing title over its own scroll content, and its content is inset below
|
|
183
|
+
* the bar — a DISTINCT mode from the declarative
|
|
184
|
+
* `title`/`description`/`actions` centered heading (a confirm/alert dialog
|
|
185
|
+
* passes NO `header` and is unchanged). Screens render no header of their own;
|
|
186
|
+
* the title/slots come from this config, refined at runtime by a mounted
|
|
187
|
+
* screen's `useDialogHeader` contribution.
|
|
188
|
+
*/
|
|
189
|
+
header?: DialogHeaderConfig;
|
|
190
|
+
/**
|
|
191
|
+
* Open-INTENT seed for a freshly-mounted placement branch, distinct from the
|
|
192
|
+
* controlled `open` prop. It ONLY seeds a branch's initial visible state on
|
|
193
|
+
* mount — it never switches the dialog into controlled close semantics, so
|
|
194
|
+
* the imperative `control.close()` still owns the exit animation and fires
|
|
195
|
+
* `onClose` post-exit (no synchronous-`onClose` entry leak). Set by the
|
|
196
|
+
* surface stack so a responsive `Dialog` that swaps its inner component across
|
|
197
|
+
* a breakpoint (centered card ↔ bottom sheet on resize) re-mounts the new
|
|
198
|
+
* branch ALREADY OPEN instead of blank. Ignored when the controlled `open`
|
|
199
|
+
* prop is provided (that path seeds itself).
|
|
200
|
+
*/
|
|
201
|
+
startOpen?: boolean;
|
|
202
|
+
/**
|
|
203
|
+
* Whether the dialog wraps its content in an internal scroll container.
|
|
204
|
+
* Defaults to `true`. Set `false` when the content owns its own scrolling
|
|
205
|
+
* primitive (a `FlatList` / `SectionList` / any VirtualizedList, or its own
|
|
206
|
+
* `ScrollView`): the surface then renders children WITHOUT a ScrollView wrap —
|
|
207
|
+
* a bounded, overflow-clipped card on the centered/side placements and a
|
|
208
|
+
* non-scrollable `BottomSheet` body on the bottom placement — so the child
|
|
209
|
+
* gets a bounded height and owns its scroll, and no "VirtualizedList inside a
|
|
210
|
+
* plain ScrollView" warning is emitted.
|
|
211
|
+
*/
|
|
212
|
+
scrollable?: boolean;
|
|
137
213
|
/**
|
|
138
214
|
* Inner padding (px) of the dialog content container, applied uniformly across
|
|
139
215
|
* every placement (centered panel, side-sheet body, bottom-sheet body).
|
|
@@ -163,6 +239,16 @@ export type DialogProps = React.PropsWithChildren<{
|
|
|
163
239
|
containerClassName?: string;
|
|
164
240
|
/** Accessibility label, applied to the dialog role on web. */
|
|
165
241
|
label?: string;
|
|
242
|
+
/**
|
|
243
|
+
* Stacking layer index within a coordinated surface stack. Multiplies
|
|
244
|
+
* `Z_INDEX_LAYER_STEP` onto this dialog's overlay z-indices (backdrop +
|
|
245
|
+
* panel) so a dialog presented on top of another paints above it. Defaults to
|
|
246
|
+
* `0` — the single-dialog case, byte-for-byte unchanged. Set by the shared
|
|
247
|
+
* surface stack (`src/surfaces`); direct consumers rarely need it. No-op for
|
|
248
|
+
* the `bottom` placement, which already stacks in mount order (native RN
|
|
249
|
+
* `<Modal>` / the web portal), so `layer` is harmless there.
|
|
250
|
+
*/
|
|
251
|
+
layer?: number;
|
|
166
252
|
}>;
|
|
167
253
|
|
|
168
254
|
/**
|
package/src/index.ts
CHANGED
|
@@ -59,6 +59,7 @@ export {
|
|
|
59
59
|
alert,
|
|
60
60
|
useDialogContext,
|
|
61
61
|
useDialogControl,
|
|
62
|
+
useDialogHeader,
|
|
62
63
|
} from './dialog';
|
|
63
64
|
export type {
|
|
64
65
|
AlertButton,
|
|
@@ -67,11 +68,27 @@ export type {
|
|
|
67
68
|
DialogActionColor,
|
|
68
69
|
DialogContextProps,
|
|
69
70
|
DialogControlProps,
|
|
71
|
+
DialogHeaderConfig,
|
|
70
72
|
DialogInset,
|
|
71
73
|
DialogPlacement,
|
|
72
74
|
DialogProps,
|
|
73
75
|
ResponsiveDialogPlacement,
|
|
74
76
|
} from './dialog';
|
|
77
|
+
// Surface stack — the shared, coordinated overlay system. The imperative API is
|
|
78
|
+
// the `surfaces` object (its members would otherwise clash with alert-dialog's
|
|
79
|
+
// `confirm`); the individual functions are also named exports of
|
|
80
|
+
// `@oxyhq/bloom/surfaces`.
|
|
81
|
+
export { surfaces, SurfaceProvider, SurfaceHost, useSurface } from './surfaces';
|
|
82
|
+
export type {
|
|
83
|
+
SurfacePresentation,
|
|
84
|
+
PresentOptions,
|
|
85
|
+
SurfaceControls,
|
|
86
|
+
SurfaceRenderFn,
|
|
87
|
+
SurfaceStatus,
|
|
88
|
+
SurfaceEntry,
|
|
89
|
+
SurfaceConfirmOptions,
|
|
90
|
+
SurfacePromptOptions,
|
|
91
|
+
} from './surfaces';
|
|
75
92
|
export * from './button';
|
|
76
93
|
export { Fab } from './fab';
|
|
77
94
|
export type { FabProps, FabVariant, FabSize, FabPlacement } from './fab';
|
|
@@ -129,7 +146,7 @@ export type { AnimatedCheckProps, AnimatedCheckRef } from './animated-check';
|
|
|
129
146
|
// Form components
|
|
130
147
|
export * from './text-field';
|
|
131
148
|
export * from './segmented-control';
|
|
132
|
-
export {
|
|
149
|
+
export { Search } from './search';
|
|
133
150
|
export { Label } from './label';
|
|
134
151
|
export type { LabelProps } from './label';
|
|
135
152
|
export { Field } from './field';
|
package/src/index.web.ts
CHANGED
|
@@ -64,6 +64,7 @@ export {
|
|
|
64
64
|
alert,
|
|
65
65
|
useDialogContext,
|
|
66
66
|
useDialogControl,
|
|
67
|
+
useDialogHeader,
|
|
67
68
|
} from './dialog/index.web';
|
|
68
69
|
export type {
|
|
69
70
|
AlertButton,
|
|
@@ -72,11 +73,27 @@ export type {
|
|
|
72
73
|
DialogActionColor,
|
|
73
74
|
DialogContextProps,
|
|
74
75
|
DialogControlProps,
|
|
76
|
+
DialogHeaderConfig,
|
|
75
77
|
DialogInset,
|
|
76
78
|
DialogPlacement,
|
|
77
79
|
DialogProps,
|
|
78
80
|
ResponsiveDialogPlacement,
|
|
79
81
|
} from './dialog/index.web';
|
|
82
|
+
// Surface stack — the shared, coordinated overlay system. The imperative API is
|
|
83
|
+
// the `surfaces` object (its members would otherwise clash with alert-dialog's
|
|
84
|
+
// `confirm`); the individual functions are also named exports of
|
|
85
|
+
// `@oxyhq/bloom/surfaces`.
|
|
86
|
+
export { surfaces, SurfaceProvider, SurfaceHost, useSurface } from './surfaces/index.web';
|
|
87
|
+
export type {
|
|
88
|
+
SurfacePresentation,
|
|
89
|
+
PresentOptions,
|
|
90
|
+
SurfaceControls,
|
|
91
|
+
SurfaceRenderFn,
|
|
92
|
+
SurfaceStatus,
|
|
93
|
+
SurfaceEntry,
|
|
94
|
+
SurfaceConfirmOptions,
|
|
95
|
+
SurfacePromptOptions,
|
|
96
|
+
} from './surfaces/index.web';
|
|
80
97
|
export * from './button/index.web';
|
|
81
98
|
export { Fab } from './fab/index.web';
|
|
82
99
|
export type { FabProps, FabVariant, FabSize, FabPlacement } from './fab/index.web';
|
|
@@ -134,7 +151,7 @@ export type { AnimatedCheckProps, AnimatedCheckRef } from './animated-check';
|
|
|
134
151
|
// Form components
|
|
135
152
|
export * from './text-field';
|
|
136
153
|
export * from './segmented-control';
|
|
137
|
-
export {
|
|
154
|
+
export { Search } from './search';
|
|
138
155
|
export { Label } from './label';
|
|
139
156
|
export type { LabelProps } from './label';
|
|
140
157
|
export { Field } from './field';
|
package/src/input-group/types.ts
CHANGED
|
@@ -21,7 +21,7 @@ export interface InputGroupAddonProps {
|
|
|
21
21
|
export interface InputGroupProps {
|
|
22
22
|
/**
|
|
23
23
|
* Group children. Place `InputGroup.Addon` elements before/after the input
|
|
24
|
-
* (a Bloom `TextFieldInput`, a `
|
|
24
|
+
* (a Bloom `TextFieldInput`, a `Search`, or any control). The middle
|
|
25
25
|
* child stretches to fill.
|
|
26
26
|
*/
|
|
27
27
|
children: React.ReactNode;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `className` support for React Native core components in Bloom.
|
|
3
|
+
*
|
|
4
|
+
* Bloom styles some primitives with NativeWind/`react-native-css` utility
|
|
5
|
+
* classes (`className="..."`). react-native-css applies them at runtime — on web
|
|
6
|
+
* as real CSS classes emitted by the consumer's Tailwind pipeline (`@source`-
|
|
7
|
+
* scanning Bloom's lib), on native as compiled styles. This ambient augmentation
|
|
8
|
+
* makes `className` type-valid on the RN primitives we set it on.
|
|
9
|
+
*
|
|
10
|
+
* Heritage-free (a plain interface-merge `declare module`, no `extends` / import
|
|
11
|
+
* of RN's own module graph) so it never drags a second `@types/react` copy into
|
|
12
|
+
* the RN 0.85 / React 19 tree — the same hazard the `mergeRefs` note calls out.
|
|
13
|
+
*/
|
|
14
|
+
// `export {}` makes this file a MODULE, so the `declare module` below MERGES
|
|
15
|
+
// with react-native's real types (an augmentation) instead of replacing the
|
|
16
|
+
// module and hiding its exports.
|
|
17
|
+
export {};
|
|
18
|
+
|
|
19
|
+
declare module 'react-native' {
|
|
20
|
+
interface ViewProps {
|
|
21
|
+
className?: string;
|
|
22
|
+
}
|
|
23
|
+
interface TextProps {
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
interface ImageProps {
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
interface PressableProps {
|
|
30
|
+
className?: string;
|
|
31
|
+
}
|
|
32
|
+
interface ScrollViewProps {
|
|
33
|
+
className?: string;
|
|
34
|
+
}
|
|
35
|
+
interface TextInputProps {
|
|
36
|
+
className?: string;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -8,7 +8,10 @@ import { TextField, TextFieldIcon, TextFieldInput, type TextFieldInputProps } fr
|
|
|
8
8
|
import { MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlassIcon } from '../icons/MagnifyingGlass';
|
|
9
9
|
import { TimesLarge_Stroke2_Corner0_Rounded as X } from '../icons/Times';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/** Fully-rounded (pill) corner radius — clamps to half the field height. */
|
|
12
|
+
const PILL_RADIUS = 999;
|
|
13
|
+
|
|
14
|
+
type SearchProps = Omit<TextFieldInputProps, 'label'> & {
|
|
12
15
|
label?: TextFieldInputProps['label'];
|
|
13
16
|
/**
|
|
14
17
|
* Called when the user presses the clear (X) button.
|
|
@@ -16,14 +19,14 @@ type SearchInputProps = Omit<TextFieldInputProps, 'label'> & {
|
|
|
16
19
|
onClearText?: () => void;
|
|
17
20
|
};
|
|
18
21
|
|
|
19
|
-
export const
|
|
20
|
-
function
|
|
22
|
+
export const Search = forwardRef<TextInput, SearchProps>(
|
|
23
|
+
function Search({ value, label = 'Search', onClearText, ...rest }, ref) {
|
|
21
24
|
const theme = useTheme();
|
|
22
25
|
const showClear = value != null && value.length > 0;
|
|
23
26
|
|
|
24
27
|
return (
|
|
25
28
|
<View style={[a.w_full, a.relative]}>
|
|
26
|
-
<TextField>
|
|
29
|
+
<TextField radius={PILL_RADIUS}>
|
|
27
30
|
<TextFieldIcon icon={MagnifyingGlassIcon} />
|
|
28
31
|
<TextFieldInput
|
|
29
32
|
inputRef={ref}
|
|
@@ -70,4 +73,4 @@ export const SearchInput = forwardRef<TextInput, SearchInputProps>(
|
|
|
70
73
|
);
|
|
71
74
|
},
|
|
72
75
|
);
|
|
73
|
-
|
|
76
|
+
Search.displayName = 'Search';
|
|
@@ -243,7 +243,11 @@ const styles = StyleSheet.create({
|
|
|
243
243
|
marginBottom: 16,
|
|
244
244
|
},
|
|
245
245
|
groupCard: {
|
|
246
|
-
|
|
246
|
+
// No horizontal self-inset: a `SettingsListGroup` fills its parent's content
|
|
247
|
+
// width, so the single horizontal inset comes from the ONE content padding
|
|
248
|
+
// the screen/Dialog already applies (the same `px-screen-margin` that pads
|
|
249
|
+
// the title/search). Keeping a self-margin here double-inset grouped rows on
|
|
250
|
+
// every screen that also applies that padding.
|
|
247
251
|
borderRadius: 16,
|
|
248
252
|
overflow: 'hidden',
|
|
249
253
|
},
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useEffect,
|
|
4
|
+
useMemo,
|
|
5
|
+
useSyncExternalStore,
|
|
6
|
+
} from 'react';
|
|
7
|
+
import { BackHandler, Platform } from 'react-native';
|
|
8
|
+
|
|
9
|
+
import { useDialogControl } from '../dialog/context';
|
|
10
|
+
import type { DialogProps } from '../dialog/types';
|
|
11
|
+
import {
|
|
12
|
+
finalizeClose,
|
|
13
|
+
getSnapshot,
|
|
14
|
+
present,
|
|
15
|
+
requestDismiss,
|
|
16
|
+
resetSurfaces,
|
|
17
|
+
subscribe,
|
|
18
|
+
} from './surfaceStore';
|
|
19
|
+
import { SurfaceContext } from './useSurface';
|
|
20
|
+
import type { SurfaceControls, SurfaceEntry, SurfacePresentation } from './types';
|
|
21
|
+
|
|
22
|
+
type DialogComponent = React.ComponentType<DialogProps>;
|
|
23
|
+
|
|
24
|
+
/** Default placement — the ecosystem's responsive "sheet" (bottom → centered). */
|
|
25
|
+
const DEFAULT_PLACEMENT: SurfacePresentation['placement'] = {
|
|
26
|
+
base: 'bottom',
|
|
27
|
+
md: 'center',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/** Map a surface's presentation config onto the shared `Dialog` props. */
|
|
31
|
+
function placementFor(p: SurfacePresentation): Partial<DialogProps> {
|
|
32
|
+
return {
|
|
33
|
+
placement: p.placement ?? DEFAULT_PLACEMENT,
|
|
34
|
+
width: p.width,
|
|
35
|
+
maxWidth: p.maxWidth,
|
|
36
|
+
maxHeightRatio: p.maxHeightRatio,
|
|
37
|
+
inset: p.inset,
|
|
38
|
+
showHandle: p.showHandle,
|
|
39
|
+
dismissOnBackdrop: p.dismissOnBackdrop,
|
|
40
|
+
contentPadding: p.contentPadding,
|
|
41
|
+
header: p.header,
|
|
42
|
+
scrollable: p.scrollable,
|
|
43
|
+
style: p.style,
|
|
44
|
+
panelStyle: p.panelStyle,
|
|
45
|
+
panelClassName: p.panelClassName,
|
|
46
|
+
containerStyle: p.containerStyle,
|
|
47
|
+
containerClassName: p.containerClassName,
|
|
48
|
+
label: p.label,
|
|
49
|
+
testID: p.testID,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Build the `<SurfaceHost>` + `<SurfaceProvider>` bound to a platform `Dialog`.
|
|
55
|
+
*
|
|
56
|
+
* `Dialog` is platform-forked (native `BottomSheet`-backed vs. pure-DOM web
|
|
57
|
+
* overlay), so — like `createAlertDialog` — the platform entry files
|
|
58
|
+
* (`index.ts` / `index.web.ts`) inject the correct one. The stack logic below is
|
|
59
|
+
* single-source, no duplication.
|
|
60
|
+
*/
|
|
61
|
+
export function createSurfaceHost(Dialog: DialogComponent) {
|
|
62
|
+
/**
|
|
63
|
+
* One stacked surface. Bridges a store entry onto an IMPERATIVE `Dialog`
|
|
64
|
+
* (`useDialogControl()` + `open()`/`close()`) — never the controlled
|
|
65
|
+
* `open`/`onClose` boolean path, which fires `onClose` synchronously as the
|
|
66
|
+
* dismiss REQUEST and has no post-exit callback, so it could never tell the
|
|
67
|
+
* store WHEN to splice the entry after the exit animation.
|
|
68
|
+
*/
|
|
69
|
+
function SurfaceLayer({
|
|
70
|
+
entry,
|
|
71
|
+
index,
|
|
72
|
+
}: {
|
|
73
|
+
entry: SurfaceEntry;
|
|
74
|
+
index: number;
|
|
75
|
+
}) {
|
|
76
|
+
const control = useDialogControl();
|
|
77
|
+
const { id, status } = entry;
|
|
78
|
+
|
|
79
|
+
const controls = useMemo<SurfaceControls>(
|
|
80
|
+
() => ({
|
|
81
|
+
dismiss: (result?: unknown) => requestDismiss(id, result),
|
|
82
|
+
present: (render, opts) => present(render, opts),
|
|
83
|
+
}),
|
|
84
|
+
[id],
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// Open imperatively on mount (mirrors `AlertDialog`'s canonical
|
|
88
|
+
// fresh-mount open-from-effect; `control` is stable for the layer's life).
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
control.open();
|
|
91
|
+
}, [control]);
|
|
92
|
+
|
|
93
|
+
// When the store flips this entry to 'closing' (a programmatic dismiss,
|
|
94
|
+
// dismissAll, dismissToRoot, Escape, or Android-back), run the exit
|
|
95
|
+
// animation. A user backdrop/Escape handled by the Dialog itself instead
|
|
96
|
+
// drives its own internal close; either way `onClose` fires post-exit.
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (status === 'closing') control.close();
|
|
99
|
+
}, [status, control]);
|
|
100
|
+
|
|
101
|
+
// Fires AFTER the exit animation settles (imperative mode), for ANY
|
|
102
|
+
// dismissal path — user backdrop/Escape/back OR a programmatic dismiss.
|
|
103
|
+
// `requestDismiss` resolves-once (a programmatic dismiss already resolved
|
|
104
|
+
// with its result; this is a no-op then), then `finalizeClose` splices the
|
|
105
|
+
// entry out. Guarded by unique ids + `'closing'` status in the store.
|
|
106
|
+
const handleClose = useCallback(() => {
|
|
107
|
+
requestDismiss(id);
|
|
108
|
+
finalizeClose(id);
|
|
109
|
+
}, [id]);
|
|
110
|
+
|
|
111
|
+
const placement = useMemo(
|
|
112
|
+
() => placementFor(entry.presentation),
|
|
113
|
+
[entry.presentation],
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
// `startOpen` is the surface's open-INTENT (true while not closing). It
|
|
118
|
+
// ONLY seeds a freshly-mounted Dialog branch's visible state — the
|
|
119
|
+
// imperative `control` still owns open/close — so when a responsive Dialog
|
|
120
|
+
// swaps its inner component on resize (centered card ↔ bottom sheet) the
|
|
121
|
+
// new branch mounts STILL OPEN instead of dismissing the surface. A real
|
|
122
|
+
// dismiss (backdrop/Escape/back/programmatic) still resolves + splices
|
|
123
|
+
// exactly once via `control.close()` → `handleClose`, post-exit.
|
|
124
|
+
<Dialog
|
|
125
|
+
control={control}
|
|
126
|
+
onClose={handleClose}
|
|
127
|
+
layer={index}
|
|
128
|
+
startOpen={status !== 'closing'}
|
|
129
|
+
{...placement}
|
|
130
|
+
>
|
|
131
|
+
<SurfaceContext.Provider value={controls}>
|
|
132
|
+
{entry.render(controls)}
|
|
133
|
+
</SurfaceContext.Provider>
|
|
134
|
+
</Dialog>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function SurfaceHost() {
|
|
139
|
+
const stack = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
140
|
+
|
|
141
|
+
useAndroidBackDismissesTop();
|
|
142
|
+
useEscapeDismissesTop();
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<>
|
|
146
|
+
{stack.map((entry, index) => (
|
|
147
|
+
<SurfaceLayer key={entry.id} entry={entry} index={index} />
|
|
148
|
+
))}
|
|
149
|
+
</>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
SurfaceHost.displayName = 'SurfaceHost';
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Mount ONCE near your app root — renders `children` plus the stack host.
|
|
156
|
+
* Requires the Bloom Portal provider to be mounted too (same as any `<Dialog>`
|
|
157
|
+
* usage): on web the Portal auto-creates `#bloom-portal-root`; on native mount
|
|
158
|
+
* `<Provider>`/`<Outlet>` from `@oxyhq/bloom/portal`. Can equally be folded
|
|
159
|
+
* next to that Portal provider — `<SurfaceHost>` used directly does the same
|
|
160
|
+
* job without wrapping `children`.
|
|
161
|
+
*/
|
|
162
|
+
function SurfaceProvider({ children }: { children: React.ReactNode }) {
|
|
163
|
+
// Resolve any pending awaiters if the provider unmounts so no `present()`
|
|
164
|
+
// promise is stranded.
|
|
165
|
+
useEffect(() => () => resetSurfaces(), []);
|
|
166
|
+
return (
|
|
167
|
+
<>
|
|
168
|
+
{children}
|
|
169
|
+
<SurfaceHost />
|
|
170
|
+
</>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
SurfaceProvider.displayName = 'SurfaceProvider';
|
|
174
|
+
|
|
175
|
+
return { SurfaceHost, SurfaceProvider };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* ONE Android hardware-back handler for the whole stack → dismiss the TOP
|
|
180
|
+
* surface. Reads the live top from the store so a single registration always
|
|
181
|
+
* targets the current top. Returns `false` when the stack is empty so app-level
|
|
182
|
+
* back navigation is untouched.
|
|
183
|
+
*/
|
|
184
|
+
function useAndroidBackDismissesTop(): void {
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
if (Platform.OS !== 'android') return;
|
|
187
|
+
const sub = BackHandler.addEventListener('hardwareBackPress', () => {
|
|
188
|
+
const stack = getSnapshot();
|
|
189
|
+
const top = stack[stack.length - 1];
|
|
190
|
+
if (!top) return false;
|
|
191
|
+
if (top.presentation.dismissOnBackdrop === false) return true;
|
|
192
|
+
requestDismiss(top.id);
|
|
193
|
+
return true;
|
|
194
|
+
});
|
|
195
|
+
return () => sub.remove();
|
|
196
|
+
}, []);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Web-only: route Escape to the TOP surface only. A window-CAPTURE listener runs
|
|
201
|
+
* before each `Dialog`'s own document-level keydown, so `stopImmediatePropagation`
|
|
202
|
+
* prevents the lower stacked dialogs from ALSO handling Escape (they each add a
|
|
203
|
+
* document listener) — Escape dismisses strictly the top, LIFO. No-op on native.
|
|
204
|
+
*/
|
|
205
|
+
function useEscapeDismissesTop(): void {
|
|
206
|
+
useEffect(() => {
|
|
207
|
+
if (Platform.OS !== 'web') return;
|
|
208
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') return;
|
|
209
|
+
const handler = (e: KeyboardEvent) => {
|
|
210
|
+
if (e.key !== 'Escape') return;
|
|
211
|
+
const stack = getSnapshot();
|
|
212
|
+
const top = stack[stack.length - 1];
|
|
213
|
+
if (!top) return;
|
|
214
|
+
if (top.presentation.dismissOnBackdrop === false) return;
|
|
215
|
+
e.stopImmediatePropagation();
|
|
216
|
+
e.preventDefault();
|
|
217
|
+
requestDismiss(top.id);
|
|
218
|
+
};
|
|
219
|
+
window.addEventListener('keydown', handler, true);
|
|
220
|
+
return () => window.removeEventListener('keydown', handler, true);
|
|
221
|
+
}, []);
|
|
222
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
dismissAll,
|
|
3
|
+
dismissToRoot,
|
|
4
|
+
dismissTop,
|
|
5
|
+
present,
|
|
6
|
+
requestDismiss,
|
|
7
|
+
} from './surfaceStore';
|
|
8
|
+
import { confirm, prompt } from './prompts';
|
|
9
|
+
import type { PresentOptions, SurfaceRenderFn } from './types';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Dismiss the TOP surface, resolving its `present()` promise with `result`.
|
|
13
|
+
* The public counterpart of the store's `dismissTop`.
|
|
14
|
+
*/
|
|
15
|
+
function dismiss(result?: unknown): void {
|
|
16
|
+
dismissTop(result);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Dismiss a SPECIFIC surface by id, resolving its `present()` promise with
|
|
21
|
+
* `result`. Rarely needed — most call sites use `dismiss()` (top) or the
|
|
22
|
+
* per-surface `SurfaceControls.dismiss`.
|
|
23
|
+
*/
|
|
24
|
+
function dismissById(id: string, result?: unknown): void {
|
|
25
|
+
requestDismiss(id, result);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The shared imperative surface-stack API — a module singleton (mirrors
|
|
30
|
+
* `alert()`'s shape) so any consumer, in the SDK or an app, presents into the
|
|
31
|
+
* SAME coordinated Bloom stack from anywhere without threading a provider.
|
|
32
|
+
*
|
|
33
|
+
* Exposed at the package root as `surfaces` (avoids a bare `present`/`confirm`
|
|
34
|
+
* name clash with the existing `alert-dialog` `confirm`); the individual
|
|
35
|
+
* functions are also named exports of `@oxyhq/bloom/surfaces` for direct import.
|
|
36
|
+
*/
|
|
37
|
+
export const surfaces = {
|
|
38
|
+
/** Present a new surface on top. Resolves with the dismissal result. */
|
|
39
|
+
present: <Result = unknown>(render: SurfaceRenderFn, opts?: PresentOptions) =>
|
|
40
|
+
present<Result>(render, opts),
|
|
41
|
+
/** Dismiss the top surface. */
|
|
42
|
+
dismiss,
|
|
43
|
+
/** Dismiss a specific surface by id. */
|
|
44
|
+
dismissById,
|
|
45
|
+
/** Dismiss everything above the root surface. */
|
|
46
|
+
dismissToRoot,
|
|
47
|
+
/** Dismiss the entire stack (resolves pending awaiters with `undefined`). */
|
|
48
|
+
dismissAll,
|
|
49
|
+
/** Present a confirm surface; resolves `true`/`false`. */
|
|
50
|
+
confirm,
|
|
51
|
+
/** Present a prompt surface; resolves the string or `null`. */
|
|
52
|
+
prompt,
|
|
53
|
+
} as const;
|
|
54
|
+
|
|
55
|
+
export { confirm, dismiss, dismissAll, dismissById, dismissToRoot, present, prompt };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Dialog } from '../dialog';
|
|
2
|
+
import { createSurfaceHost } from './SurfaceHost';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The shared, content-agnostic SURFACE STACK.
|
|
6
|
+
*
|
|
7
|
+
* `<SurfaceProvider>`/`<SurfaceHost>` render the coordinated stack; the
|
|
8
|
+
* imperative `surfaces` API (+ its named functions) present into it from
|
|
9
|
+
* anywhere; `useSurface()` gives a presented surface its own controls.
|
|
10
|
+
*
|
|
11
|
+
* `SurfaceHost`/`SurfaceProvider` are bound to the NATIVE `Dialog` here; the web
|
|
12
|
+
* fork (`./index.web`) binds the web `Dialog`. The store, imperative API, hook,
|
|
13
|
+
* and types are platform-agnostic and shared by both.
|
|
14
|
+
*/
|
|
15
|
+
const { SurfaceHost, SurfaceProvider } = createSurfaceHost(Dialog);
|
|
16
|
+
|
|
17
|
+
export { SurfaceHost, SurfaceProvider };
|
|
18
|
+
export {
|
|
19
|
+
surfaces,
|
|
20
|
+
present,
|
|
21
|
+
dismiss,
|
|
22
|
+
dismissById,
|
|
23
|
+
dismissToRoot,
|
|
24
|
+
dismissAll,
|
|
25
|
+
confirm,
|
|
26
|
+
prompt,
|
|
27
|
+
} from './api';
|
|
28
|
+
export { useSurface } from './useSurface';
|
|
29
|
+
export type {
|
|
30
|
+
SurfacePresentation,
|
|
31
|
+
PresentOptions,
|
|
32
|
+
SurfaceControls,
|
|
33
|
+
SurfaceRenderFn,
|
|
34
|
+
SurfaceStatus,
|
|
35
|
+
SurfaceEntry,
|
|
36
|
+
SurfaceConfirmOptions,
|
|
37
|
+
SurfacePromptOptions,
|
|
38
|
+
} from './types';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Dialog } from '../dialog/index.web';
|
|
2
|
+
import { createSurfaceHost } from './SurfaceHost';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Web variant of the surface stack barrel. Identical surface area to the native
|
|
6
|
+
* `./index.ts` — it just binds the web-fork `Dialog` (`Dialog.web.tsx`, a
|
|
7
|
+
* pure-DOM overlay) instead of the native `BottomSheet`-backed one. The store,
|
|
8
|
+
* imperative API, hook, and types are shared, platform-agnostic modules.
|
|
9
|
+
*/
|
|
10
|
+
const { SurfaceHost, SurfaceProvider } = createSurfaceHost(Dialog);
|
|
11
|
+
|
|
12
|
+
export { SurfaceHost, SurfaceProvider };
|
|
13
|
+
export {
|
|
14
|
+
surfaces,
|
|
15
|
+
present,
|
|
16
|
+
dismiss,
|
|
17
|
+
dismissById,
|
|
18
|
+
dismissToRoot,
|
|
19
|
+
dismissAll,
|
|
20
|
+
confirm,
|
|
21
|
+
prompt,
|
|
22
|
+
} from './api';
|
|
23
|
+
export { useSurface } from './useSurface';
|
|
24
|
+
export type {
|
|
25
|
+
SurfacePresentation,
|
|
26
|
+
PresentOptions,
|
|
27
|
+
SurfaceControls,
|
|
28
|
+
SurfaceRenderFn,
|
|
29
|
+
SurfaceStatus,
|
|
30
|
+
SurfaceEntry,
|
|
31
|
+
SurfaceConfirmOptions,
|
|
32
|
+
SurfacePromptOptions,
|
|
33
|
+
} from './types';
|