@gryt/ui-native 0.8.2 → 0.9.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.
|
@@ -16,9 +16,25 @@ interface ToastContextValue {
|
|
|
16
16
|
* Toasts need somewhere to live, which on the web is a portal at the document
|
|
17
17
|
* root and here is a provider near the top of the tree.
|
|
18
18
|
*
|
|
19
|
+
* **Mount it above everything else it has to cover.** The viewport is rendered
|
|
20
|
+
* as a sibling *after* `children`, so it paints over anything inside them —
|
|
21
|
+
* including a `Sheet`, whose content goes through `@gorhom/portal` to a host
|
|
22
|
+
* that is itself inside those children. Put `ToastProvider` below
|
|
23
|
+
* `SheetProvider` and the sheet wins instead, which is the wrong way round: a
|
|
24
|
+
* sheet is a surface you are working in, and a toast is the app telling you
|
|
25
|
+
* something happened while you work.
|
|
26
|
+
*
|
|
19
27
|
* They are deliberately not built on `Modal` like the dialogs are. A modal
|
|
20
28
|
* intercepts touches for the whole screen, and a toast that blocked the app
|
|
21
29
|
* until it faded would be worse than no toast.
|
|
30
|
+
*
|
|
31
|
+
* **What that costs, stated rather than discovered:** a `Modal` is a separate
|
|
32
|
+
* native window, so anything built on one — `Dialog`, `AlertDialog`, `Drawer`,
|
|
33
|
+
* and the platform's own `ActionSheetIOS` — draws *over* a toast, whatever the
|
|
34
|
+
* z-index says. React Native has no z-index across windows. A flow that raises
|
|
35
|
+
* a dialog and toasts at the same moment should toast after the dialog closes;
|
|
36
|
+
* there is nothing this component can do about it from inside the tree, and
|
|
37
|
+
* the alternative is a toast that can block the app, which is worse.
|
|
22
38
|
*/
|
|
23
39
|
export declare function ToastProvider({ children }: {
|
|
24
40
|
children?: ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../src/components/Toast/Toast.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5G,OAAO,EAAyB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../src/components/Toast/Toast.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5G,OAAO,EAAyB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AASrF,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAMD,UAAU,iBAAiB;IACzB,IAAI,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,MAAM,CAAC;IACtC,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAID;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAoBnE;AAED,wBAAgB,QAAQ,IAAI,iBAAiB,CAI5C;AAyHD,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { Pressable, Text, View } from "react-native";
|
|
4
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
4
5
|
import Animated, { useAnimatedStyle, useSharedValue } from "react-native-reanimated";
|
|
5
6
|
import { grytScaleSteps } from "@gryt/theme";
|
|
6
7
|
import { useReducedMotion } from "../../hooks/useReducedMotion.js";
|
|
@@ -11,9 +12,25 @@ const ToastContext = createContext(null);
|
|
|
11
12
|
* Toasts need somewhere to live, which on the web is a portal at the document
|
|
12
13
|
* root and here is a provider near the top of the tree.
|
|
13
14
|
*
|
|
15
|
+
* **Mount it above everything else it has to cover.** The viewport is rendered
|
|
16
|
+
* as a sibling *after* `children`, so it paints over anything inside them —
|
|
17
|
+
* including a `Sheet`, whose content goes through `@gorhom/portal` to a host
|
|
18
|
+
* that is itself inside those children. Put `ToastProvider` below
|
|
19
|
+
* `SheetProvider` and the sheet wins instead, which is the wrong way round: a
|
|
20
|
+
* sheet is a surface you are working in, and a toast is the app telling you
|
|
21
|
+
* something happened while you work.
|
|
22
|
+
*
|
|
14
23
|
* They are deliberately not built on `Modal` like the dialogs are. A modal
|
|
15
24
|
* intercepts touches for the whole screen, and a toast that blocked the app
|
|
16
25
|
* until it faded would be worse than no toast.
|
|
26
|
+
*
|
|
27
|
+
* **What that costs, stated rather than discovered:** a `Modal` is a separate
|
|
28
|
+
* native window, so anything built on one — `Dialog`, `AlertDialog`, `Drawer`,
|
|
29
|
+
* and the platform's own `ActionSheetIOS` — draws *over* a toast, whatever the
|
|
30
|
+
* z-index says. React Native has no z-index across windows. A flow that raises
|
|
31
|
+
* a dialog and toasts at the same moment should toast after the dialog closes;
|
|
32
|
+
* there is nothing this component can do about it from inside the tree, and
|
|
33
|
+
* the alternative is a toast that can block the app, which is worse.
|
|
17
34
|
*/
|
|
18
35
|
export function ToastProvider({ children }) {
|
|
19
36
|
const [toasts, setToasts] = useState([]);
|
|
@@ -42,6 +59,7 @@ const RAMP = {
|
|
|
42
59
|
};
|
|
43
60
|
function Viewport({ toasts, onDismiss, }) {
|
|
44
61
|
const theme = useTheme();
|
|
62
|
+
const insets = useSafeAreaInsets();
|
|
45
63
|
if (toasts.length === 0)
|
|
46
64
|
return null;
|
|
47
65
|
return (_jsx(View
|
|
@@ -52,9 +70,26 @@ function Viewport({ toasts, onDismiss, }) {
|
|
|
52
70
|
position: "absolute",
|
|
53
71
|
left: 0,
|
|
54
72
|
right: 0,
|
|
55
|
-
|
|
73
|
+
/* The top, which on a phone is the only edge that is reliably free.
|
|
74
|
+
*
|
|
75
|
+
* The bottom is where a tab bar sits, where the home indicator sits,
|
|
76
|
+
* and where every sheet in the app rises from — so a toast there is
|
|
77
|
+
* either under the chrome or in the way of the gesture. It is also
|
|
78
|
+
* where iOS puts nothing of its own, precisely because that edge is
|
|
79
|
+
* the user's.
|
|
80
|
+
*
|
|
81
|
+
* Below the status bar rather than over it: the clock and the battery
|
|
82
|
+
* are not ours to cover, and a toast that starts under the notch reads
|
|
83
|
+
* as a system banner rather than as this app talking. */
|
|
84
|
+
top: insets.top + theme.space(2),
|
|
56
85
|
paddingHorizontal: theme.space(4),
|
|
57
86
|
gap: theme.space(2),
|
|
87
|
+
/* Explicit rather than relying on paint order. Within this tree the
|
|
88
|
+
* viewport is already last, but a caller can put something absolutely
|
|
89
|
+
* positioned after it — a floating bar, a call pill — and the toast
|
|
90
|
+
* has to win. `elevation` is the Android half of the same statement. */
|
|
91
|
+
zIndex: 1000,
|
|
92
|
+
elevation: 24,
|
|
58
93
|
}, children: toasts.map((toast) => (_jsx(ToastItem, { toast: toast, onDismiss: onDismiss }, toast.id))) }));
|
|
59
94
|
}
|
|
60
95
|
function ToastItem({ toast, onDismiss, }) {
|