@oxyhq/bloom 0.4.0 → 0.5.1
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 +105 -90
- package/lib/commonjs/bottom-sheet/index.js +2 -2
- 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/fonts/FontLoader.js +6 -5
- package/lib/commonjs/fonts/FontLoader.js.map +1 -1
- package/lib/commonjs/fonts/apply-font-faces.js +4 -4
- package/lib/commonjs/fonts/apply-font-faces.web.js +13 -12
- package/lib/commonjs/fonts/apply-font-faces.web.js.map +1 -1
- package/lib/commonjs/fonts/font-assets.js +2 -2
- package/lib/commonjs/fonts/font-data.web.js +22 -0
- package/lib/commonjs/fonts/font-data.web.js.map +1 -0
- 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 +2 -2
- 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/fonts/FontLoader.js +6 -5
- package/lib/module/fonts/FontLoader.js.map +1 -1
- package/lib/module/fonts/apply-font-faces.js +4 -4
- package/lib/module/fonts/apply-font-faces.web.js +13 -10
- package/lib/module/fonts/apply-font-faces.web.js.map +1 -1
- package/lib/module/fonts/font-assets.js +2 -2
- package/lib/module/fonts/font-data.web.js +18 -0
- package/lib/module/fonts/font-data.web.js.map +1 -0
- package/lib/module/fonts/index.web.js +4 -4
- 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/bottom-sheet/index.d.ts +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/fonts/FontLoader.d.ts.map +1 -1
- package/lib/typescript/commonjs/fonts/apply-font-faces.web.d.ts +8 -1
- package/lib/typescript/commonjs/fonts/apply-font-faces.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/fonts/font-data.web.d.ts +5 -0
- package/lib/typescript/commonjs/fonts/font-data.web.d.ts.map +1 -0
- 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/bottom-sheet/index.d.ts +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/fonts/FontLoader.d.ts.map +1 -1
- package/lib/typescript/module/fonts/apply-font-faces.web.d.ts +8 -1
- package/lib/typescript/module/fonts/apply-font-faces.web.d.ts.map +1 -1
- package/lib/typescript/module/fonts/font-data.web.d.ts +5 -0
- package/lib/typescript/module/fonts/font-data.web.d.ts.map +1 -0
- 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 +38 -18
- package/src/__tests__/Dialog.test.tsx +177 -0
- package/src/avatar/Avatar.stories.tsx +69 -0
- package/src/bottom-sheet/BottomSheet.stories.tsx +92 -0
- package/src/bottom-sheet/index.tsx +3 -3
- package/src/button/Button.stories.tsx +94 -0
- package/src/context-menu/ContextMenu.stories.tsx +71 -0
- 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.stories.tsx +112 -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/fonts/FontLoader.tsx +6 -5
- package/src/fonts/apply-font-faces.ts +4 -4
- package/src/fonts/apply-font-faces.web.ts +18 -10
- package/src/fonts/font-assets.ts +2 -2
- package/src/fonts/font-data.web.ts +15 -0
- package/src/fonts/index.web.ts +4 -4
- package/src/index.ts +17 -3
- package/src/index.web.ts +17 -3
- package/src/loading/Loading.stories.tsx +60 -0
- package/src/menu/Menu.stories.tsx +79 -0
- package/src/menu/index.tsx +13 -17
- package/src/prompt-input/PromptInput.stories.tsx +82 -0
- package/src/select/Select.stories.tsx +84 -0
- package/src/select/index.tsx +30 -30
- package/src/settings-list/SettingsList.stories.tsx +106 -0
- package/src/text-field/TextField.stories.tsx +90 -0
- package/src/toast/Toast.stories.tsx +109 -0
- package/src/toast/index.tsx +55 -11
- package/src/toast/index.web.tsx +33 -13
- package/lib/commonjs/fonts/assets/BlomusModernus-Bold.woff2 +0 -0
- package/lib/commonjs/fonts/assets/BlomusModernus-Regular.woff2 +0 -0
- package/lib/commonjs/fonts/assets/GeistMono-Variable.woff2 +0 -0
- package/lib/commonjs/fonts/assets/InterVariable.woff2 +0 -0
- 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/fonts/assets/BlomusModernus-Bold.woff2 +0 -0
- package/lib/module/fonts/assets/BlomusModernus-Regular.woff2 +0 -0
- package/lib/module/fonts/assets/GeistMono-Variable.woff2 +0 -0
- package/lib/module/fonts/assets/InterVariable.woff2 +0 -0
- 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/__tests__/BloomThemeProvider.fonts-web.test.d.ts +0 -5
- package/lib/typescript/commonjs/__tests__/BloomThemeProvider.fonts-web.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/BloomThemeProvider.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/BloomThemeProvider.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/BottomSheet.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/BottomSheet.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/Button.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/Button.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/Code.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/Code.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/FontLoader.native.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/FontLoader.native.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/Pre.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/Pre.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/SettingsList.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/SettingsList.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/apply-font-faces.test.d.ts +0 -5
- package/lib/typescript/commonjs/__tests__/apply-font-faces.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/theme.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/theme.test.d.ts.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/__tests__/BloomThemeProvider.fonts-web.test.d.ts +0 -5
- package/lib/typescript/module/__tests__/BloomThemeProvider.fonts-web.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/BloomThemeProvider.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/BloomThemeProvider.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/BottomSheet.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/BottomSheet.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/Button.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/Button.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/Code.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/Code.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/FontLoader.native.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/FontLoader.native.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/Pre.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/Pre.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/SettingsList.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/SettingsList.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/apply-font-faces.test.d.ts +0 -5
- package/lib/typescript/module/__tests__/apply-font-faces.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/theme.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/theme.test.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/src/dialog/Dialog.tsx
CHANGED
|
@@ -1,33 +1,83 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useEffect,
|
|
4
|
+
useId,
|
|
5
|
+
useImperativeHandle,
|
|
6
|
+
useMemo,
|
|
7
|
+
useRef,
|
|
8
|
+
} from 'react';
|
|
9
|
+
import {
|
|
10
|
+
Text,
|
|
11
|
+
TouchableOpacity,
|
|
12
|
+
View,
|
|
13
|
+
type GestureResponderEvent,
|
|
14
|
+
} from 'react-native';
|
|
3
15
|
|
|
4
16
|
import { BottomSheet, type BottomSheetRef } from '../bottom-sheet';
|
|
17
|
+
import type { ThemeColors } from '../theme/types';
|
|
5
18
|
import { useTheme } from '../theme/use-theme';
|
|
6
|
-
import { Context, useDialogContext } from './context';
|
|
7
|
-
import type {
|
|
19
|
+
import { Context, useDialogContext, useDialogControl } from './context';
|
|
20
|
+
import type {
|
|
21
|
+
DialogAction,
|
|
22
|
+
DialogActionColor,
|
|
23
|
+
DialogControlProps,
|
|
24
|
+
DialogProps,
|
|
25
|
+
} from './types';
|
|
8
26
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Native variant of `<Dialog>`.
|
|
29
|
+
*
|
|
30
|
+
* Uses bloom's own `BottomSheet` in `detached` mode as the underlying
|
|
31
|
+
* surface — a floating, dynamically-sized, content-hugging card that
|
|
32
|
+
* gracefully degrades from sheet (phone) to centered card (tablet, via the
|
|
33
|
+
* 500px max-width cap).
|
|
34
|
+
*
|
|
35
|
+
* The component accepts three rendering modes simultaneously:
|
|
36
|
+
*
|
|
37
|
+
* 1. Declarative — `title`, `description`, `actions`. Bloom renders a
|
|
38
|
+
* standard confirm/destructive/cancel layout.
|
|
39
|
+
* 2. Custom children — caller passes JSX, bloom renders the chrome (title
|
|
40
|
+
* + close behaviour) and the children fill the body.
|
|
41
|
+
* 3. Pure children — no `title`/`description`/`actions`; caller owns
|
|
42
|
+
* every pixel.
|
|
43
|
+
*
|
|
44
|
+
* All three share the same dismissal semantics: tapping the backdrop, the
|
|
45
|
+
* drag handle, swiping down, or `control.close()` runs the queued close
|
|
46
|
+
* callbacks once the sheet's exit animation has settled.
|
|
47
|
+
*/
|
|
48
|
+
export function Dialog({
|
|
14
49
|
control,
|
|
15
50
|
onClose,
|
|
16
51
|
testID,
|
|
17
|
-
|
|
52
|
+
title,
|
|
53
|
+
description,
|
|
54
|
+
actions,
|
|
55
|
+
style,
|
|
56
|
+
label,
|
|
57
|
+
children,
|
|
58
|
+
}: DialogProps) {
|
|
18
59
|
const theme = useTheme();
|
|
19
60
|
const ref = useRef<BottomSheetRef>(null);
|
|
20
61
|
const closeCallbacks = useRef<(() => void)[]>([]);
|
|
62
|
+
const titleId = useId();
|
|
63
|
+
const descriptionId = useId();
|
|
21
64
|
|
|
65
|
+
// Drain queued close callbacks atomically — capturing the list and
|
|
66
|
+
// resetting it before invocation ensures a callback that synchronously
|
|
67
|
+
// re-opens the dialog (and queues fresh callbacks) does not see the old
|
|
68
|
+
// ones replayed against the new session.
|
|
22
69
|
const callQueuedCallbacks = useCallback(() => {
|
|
23
|
-
|
|
70
|
+
const queued = closeCallbacks.current;
|
|
71
|
+
closeCallbacks.current = [];
|
|
72
|
+
for (const cb of queued) {
|
|
24
73
|
try {
|
|
25
74
|
cb();
|
|
26
75
|
} catch (e) {
|
|
27
|
-
|
|
76
|
+
if (typeof console !== 'undefined' && console.error) {
|
|
77
|
+
console.error('Dialog close callback error:', e);
|
|
78
|
+
}
|
|
28
79
|
}
|
|
29
80
|
}
|
|
30
|
-
closeCallbacks.current = [];
|
|
31
81
|
}, []);
|
|
32
82
|
|
|
33
83
|
const open = useCallback(() => {
|
|
@@ -41,10 +91,6 @@ export function Outer({
|
|
|
41
91
|
ref.current?.dismiss();
|
|
42
92
|
}, []);
|
|
43
93
|
|
|
44
|
-
// onDismiss fires after the BottomSheet's close animation finishes — this is
|
|
45
|
-
// the integration point for the closeCallbacks queue. Consumers (e.g.
|
|
46
|
-
// Prompt.Action) rely on the queued callback running AFTER the sheet has
|
|
47
|
-
// visually closed so the screen transition feels natural.
|
|
48
94
|
const handleDismiss = useCallback(() => {
|
|
49
95
|
callQueuedCallbacks();
|
|
50
96
|
onClose?.();
|
|
@@ -65,9 +111,9 @@ export function Outer({
|
|
|
65
111
|
() => ({
|
|
66
112
|
maxWidth: 500,
|
|
67
113
|
backgroundColor: theme.colors.background,
|
|
68
|
-
// All four corners rounded —
|
|
69
|
-
//
|
|
70
|
-
//
|
|
114
|
+
// All four corners rounded — bloom's BottomSheet defaults to top-only
|
|
115
|
+
// radius in flush mode, but we use `detached` so the whole card is
|
|
116
|
+
// floating and rounded uniformly.
|
|
71
117
|
borderRadius: 20,
|
|
72
118
|
}),
|
|
73
119
|
[theme.colors.background],
|
|
@@ -79,75 +125,182 @@ export function Outer({
|
|
|
79
125
|
onDismiss={handleDismiss}
|
|
80
126
|
enablePanDownToClose
|
|
81
127
|
detached
|
|
82
|
-
// Stronger dim
|
|
83
|
-
//
|
|
128
|
+
// Stronger dim when a Dialog is stacked over another sheet so the
|
|
129
|
+
// underlying sheet's handle/content doesn't bleed through.
|
|
84
130
|
backdropOpacity={0.7}
|
|
85
131
|
style={sheetStyle}
|
|
86
132
|
>
|
|
87
133
|
<Context.Provider value={context}>
|
|
88
134
|
<View
|
|
89
135
|
testID={testID}
|
|
90
|
-
|
|
136
|
+
accessibilityLabel={label}
|
|
137
|
+
aria-labelledby={title ? titleId : undefined}
|
|
138
|
+
aria-describedby={description ? descriptionId : undefined}
|
|
139
|
+
style={[
|
|
140
|
+
// Detached BottomSheet already adds `marginBottom: insets.bottom + 16`
|
|
141
|
+
// to the sheet container — the floating card sits ABOVE the
|
|
142
|
+
// system gesture bar, so we don't add `insets.bottom` here.
|
|
143
|
+
{ paddingTop: 20, paddingHorizontal: 20, paddingBottom: 20 },
|
|
144
|
+
{ backgroundColor: theme.colors.background },
|
|
145
|
+
style,
|
|
146
|
+
]}
|
|
91
147
|
>
|
|
148
|
+
{title ? (
|
|
149
|
+
<Text
|
|
150
|
+
nativeID={titleId}
|
|
151
|
+
style={{
|
|
152
|
+
fontSize: 22,
|
|
153
|
+
fontWeight: '600',
|
|
154
|
+
color: theme.colors.text,
|
|
155
|
+
paddingBottom: description ? 4 : 16,
|
|
156
|
+
lineHeight: 30,
|
|
157
|
+
}}
|
|
158
|
+
>
|
|
159
|
+
{title}
|
|
160
|
+
</Text>
|
|
161
|
+
) : null}
|
|
162
|
+
{description ? (
|
|
163
|
+
<Text
|
|
164
|
+
nativeID={descriptionId}
|
|
165
|
+
style={{
|
|
166
|
+
fontSize: 16,
|
|
167
|
+
color: theme.colors.textSecondary,
|
|
168
|
+
paddingBottom: 16,
|
|
169
|
+
lineHeight: 22,
|
|
170
|
+
}}
|
|
171
|
+
>
|
|
172
|
+
{description}
|
|
173
|
+
</Text>
|
|
174
|
+
) : null}
|
|
92
175
|
{children}
|
|
176
|
+
{actions && actions.length > 0 ? (
|
|
177
|
+
<ActionRow actions={actions} />
|
|
178
|
+
) : null}
|
|
93
179
|
</View>
|
|
94
180
|
</Context.Provider>
|
|
95
181
|
</BottomSheet>
|
|
96
182
|
);
|
|
97
183
|
}
|
|
98
184
|
|
|
99
|
-
|
|
100
|
-
// Dialog renders inside a `detached` BottomSheet, which already adds
|
|
101
|
-
// `marginBottom: insets.bottom + 16` to the sheet container — the floating
|
|
102
|
-
// card sits ABOVE the system gesture bar, so we don't add `insets.bottom`
|
|
103
|
-
// here. Doing so double-padded the bottom on Android edge-to-edge displays.
|
|
185
|
+
function ActionRow({ actions }: { actions: DialogAction[] }) {
|
|
104
186
|
return (
|
|
105
|
-
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
>
|
|
114
|
-
{children}
|
|
115
|
-
</View>
|
|
116
|
-
</>
|
|
187
|
+
<View style={{ width: '100%', gap: 8, justifyContent: 'flex-end' }}>
|
|
188
|
+
{actions.map((action, idx) => (
|
|
189
|
+
<ActionButton
|
|
190
|
+
key={`${action.label}-${idx}`}
|
|
191
|
+
action={action}
|
|
192
|
+
/>
|
|
193
|
+
))}
|
|
194
|
+
</View>
|
|
117
195
|
);
|
|
118
196
|
}
|
|
119
197
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
198
|
+
function ActionButton({ action }: { action: DialogAction }) {
|
|
199
|
+
const { close } = useDialogContext();
|
|
200
|
+
const theme = useTheme();
|
|
201
|
+
const color: DialogActionColor = action.color ?? 'default';
|
|
202
|
+
const shouldCloseOnPress = action.shouldCloseOnPress ?? true;
|
|
123
203
|
|
|
124
|
-
const
|
|
125
|
-
container: { position: 'absolute', width: '100%', alignItems: 'center', zIndex: 10, height: 20 },
|
|
126
|
-
bar: { top: 8, width: 35, height: 5, borderRadius: 3, alignSelf: 'center', opacity: 0.5 },
|
|
127
|
-
});
|
|
204
|
+
const { background, foreground } = getActionPalette(color, theme.colors);
|
|
128
205
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
206
|
+
const handlePress = useCallback(
|
|
207
|
+
(e: GestureResponderEvent) => {
|
|
208
|
+
const onPress = action.onPress;
|
|
209
|
+
if (color === 'cancel') {
|
|
210
|
+
// Cancel always dismisses; consumer's onPress (rare) runs after.
|
|
211
|
+
close(onPress ? () => onPress(e) : undefined);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (shouldCloseOnPress) {
|
|
215
|
+
close(onPress ? () => onPress(e) : undefined);
|
|
216
|
+
} else {
|
|
217
|
+
onPress?.(e);
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
[action.onPress, close, color, shouldCloseOnPress],
|
|
221
|
+
);
|
|
132
222
|
|
|
133
223
|
return (
|
|
134
|
-
<
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
224
|
+
<TouchableOpacity
|
|
225
|
+
style={{
|
|
226
|
+
borderRadius: 9999,
|
|
227
|
+
alignItems: 'center',
|
|
228
|
+
justifyContent: 'center',
|
|
229
|
+
backgroundColor: background,
|
|
230
|
+
opacity: action.disabled ? 0.5 : 1,
|
|
231
|
+
paddingVertical: 12,
|
|
232
|
+
paddingHorizontal: 24,
|
|
233
|
+
}}
|
|
234
|
+
onPress={handlePress}
|
|
235
|
+
disabled={action.disabled}
|
|
236
|
+
activeOpacity={0.7}
|
|
237
|
+
testID={action.testID}
|
|
238
|
+
>
|
|
239
|
+
<Text style={{ fontSize: 16, fontWeight: '500', color: foreground }}>
|
|
240
|
+
{action.label}
|
|
241
|
+
</Text>
|
|
242
|
+
</TouchableOpacity>
|
|
144
243
|
);
|
|
145
244
|
}
|
|
146
245
|
|
|
147
|
-
|
|
148
|
-
|
|
246
|
+
function getActionPalette(
|
|
247
|
+
color: DialogActionColor,
|
|
248
|
+
colors: ThemeColors,
|
|
249
|
+
): { background: string; foreground: string } {
|
|
250
|
+
switch (color) {
|
|
251
|
+
case 'destructive':
|
|
252
|
+
return {
|
|
253
|
+
background: colors.negative,
|
|
254
|
+
foreground: colors.negativeForeground,
|
|
255
|
+
};
|
|
256
|
+
case 'cancel':
|
|
257
|
+
return { background: colors.contrast50, foreground: colors.text };
|
|
258
|
+
case 'default':
|
|
259
|
+
return { background: colors.primary, foreground: '#FFFFFF' };
|
|
260
|
+
/* c8 ignore next 2 -- TS exhaustiveness check guards this branch */
|
|
261
|
+
default: {
|
|
262
|
+
const _exhaustive: never = color;
|
|
263
|
+
return { background: colors.primary, foreground: '#FFFFFF' };
|
|
264
|
+
}
|
|
265
|
+
}
|
|
149
266
|
}
|
|
150
267
|
|
|
151
|
-
|
|
152
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Helper used by the imperative `alert()` API. Mounts a `<Dialog>` against
|
|
270
|
+
* a fresh control and presents it immediately. `onResolve` is invoked
|
|
271
|
+
* exactly once when the dialog finishes closing (regardless of how the
|
|
272
|
+
* dismissal happened).
|
|
273
|
+
*
|
|
274
|
+
* Kept private to the dialog module — `alert()` is the public surface.
|
|
275
|
+
*/
|
|
276
|
+
export function AutoMountedDialog({
|
|
277
|
+
title,
|
|
278
|
+
description,
|
|
279
|
+
actions,
|
|
280
|
+
onResolve,
|
|
281
|
+
}: {
|
|
282
|
+
title?: string;
|
|
283
|
+
description?: string;
|
|
284
|
+
actions: DialogAction[];
|
|
285
|
+
onResolve: () => void;
|
|
286
|
+
}) {
|
|
287
|
+
const control = useDialogControl();
|
|
288
|
+
|
|
289
|
+
// `control` is referentially stable for the lifetime of the component
|
|
290
|
+
// (memoised by `useDialogControl` on `[id]`), so this effect runs exactly
|
|
291
|
+
// once per mount — present-on-mount semantics for an `alert()` call
|
|
292
|
+
// without re-presenting on subsequent renders.
|
|
293
|
+
useEffect(() => {
|
|
294
|
+
control.open();
|
|
295
|
+
}, [control]);
|
|
296
|
+
|
|
297
|
+
return (
|
|
298
|
+
<Dialog
|
|
299
|
+
control={control}
|
|
300
|
+
title={title}
|
|
301
|
+
description={description}
|
|
302
|
+
actions={actions}
|
|
303
|
+
onClose={onResolve}
|
|
304
|
+
/>
|
|
305
|
+
);
|
|
153
306
|
}
|