@gryt/ui-native 0.8.2 → 0.10.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/dist/components/Button/Button.d.ts.map +1 -1
- package/dist/components/Button/Button.js +25 -3
- package/dist/components/Sheet/Sheet.d.ts +39 -1
- package/dist/components/Sheet/Sheet.d.ts.map +1 -1
- package/dist/components/Sheet/Sheet.js +118 -32
- package/dist/components/Toast/Toast.d.ts +16 -0
- package/dist/components/Toast/Toast.d.ts.map +1 -1
- package/dist/components/Toast/Toast.js +36 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAQtB,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAClF,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AASjE,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,UAAU,CAAC;IAC7E,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAWD,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,IAAgB,EAChB,IAAe,EACf,SAAS,EACT,OAAO,EACP,KAAK,EACL,QAAgB,EAChB,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,WAAW,+
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAQtB,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAClF,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AASjE,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,UAAU,CAAC;IAC7E,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAWD,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,IAAgB,EAChB,IAAe,EACf,SAAS,EACT,OAAO,EACP,KAAK,EACL,QAAgB,EAChB,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,WAAW,+BA8Fb"}
|
|
@@ -25,7 +25,7 @@ export function Button({ children, tone = "primary", size = "medium", startIcon,
|
|
|
25
25
|
const metrics = SIZES[size];
|
|
26
26
|
const animate = !reducedMotion && !hasPopup && !disabled;
|
|
27
27
|
const press = usePressScale(PRESSED_SCALE, !animate);
|
|
28
|
-
const
|
|
28
|
+
const fill = tone === "primary"
|
|
29
29
|
? theme.color.accent
|
|
30
30
|
: tone === "secondary"
|
|
31
31
|
? theme.color.secondary
|
|
@@ -34,7 +34,7 @@ export function Button({ children, tone = "primary", size = "medium", startIcon,
|
|
|
34
34
|
: tone === "danger"
|
|
35
35
|
? theme.color.danger
|
|
36
36
|
: "transparent";
|
|
37
|
-
const
|
|
37
|
+
const label = tone === "primary"
|
|
38
38
|
? theme.color.onAccent
|
|
39
39
|
: tone === "secondary"
|
|
40
40
|
? theme.color.onSecondary
|
|
@@ -43,6 +43,23 @@ export function Button({ children, tone = "primary", size = "medium", startIcon,
|
|
|
43
43
|
: tone === "ghost"
|
|
44
44
|
? theme.color.muted
|
|
45
45
|
: theme.color.text;
|
|
46
|
+
/**
|
|
47
|
+
* Disabled drops the fill rather than fading it.
|
|
48
|
+
*
|
|
49
|
+
* Every tone used to share one `opacity: 0.5`, and on the quiet tones that
|
|
50
|
+
* reads. On a filled one it does not: the accent at half opacity over a dark
|
|
51
|
+
* screen is still a saturated purple button, and nothing in it says it will
|
|
52
|
+
* not respond. That cost two taps on a Save button before I believed it was
|
|
53
|
+
* inert, having written the disabled condition myself half an hour earlier.
|
|
54
|
+
* GRYT-511, and the web's Button makes the same change in the same commit.
|
|
55
|
+
*
|
|
56
|
+
* So a disabled filled button becomes the surface it sits on, with a muted
|
|
57
|
+
* label — same size, same word, no longer claiming to be the action. Ghost
|
|
58
|
+
* has no fill to lose and its label is already muted, so the opacity below is
|
|
59
|
+
* what carries it.
|
|
60
|
+
*/
|
|
61
|
+
const background = disabled && tone !== "ghost" ? theme.color.surfaceRaised : fill;
|
|
62
|
+
const foreground = disabled ? theme.color.muted : label;
|
|
46
63
|
return (_jsx(Animated.View, { style: [press.style, style], children: _jsxs(Pressable, { accessibilityRole: "button", accessibilityState: { disabled: !!disabled }, disabled: disabled, onPressIn: press.onPressIn, onPressOut: press.onPressOut, style: {
|
|
47
64
|
minHeight: metrics.minHeight,
|
|
48
65
|
paddingHorizontal: metrics.paddingH,
|
|
@@ -52,7 +69,12 @@ export function Button({ children, tone = "primary", size = "medium", startIcon,
|
|
|
52
69
|
gap: theme.space(2),
|
|
53
70
|
borderRadius: theme.radius.full,
|
|
54
71
|
backgroundColor: background,
|
|
55
|
-
|
|
72
|
+
/* Lighter than it was, because the fill swap is doing the work now.
|
|
73
|
+
It is kept because `startIcon` and `endIcon` are the caller's
|
|
74
|
+
elements with the caller's colours — nothing here can mute those,
|
|
75
|
+
and an icon at full strength on a dead button is the same lie in
|
|
76
|
+
miniature. */
|
|
77
|
+
opacity: disabled ? 0.6 : 1,
|
|
56
78
|
}, ...rest, children: [startIcon, typeof children === "string" ? (_jsx(Text, { numberOfLines: 1, style: {
|
|
57
79
|
color: foreground,
|
|
58
80
|
fontSize: metrics.fontSize,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type ReactNode } from "react";
|
|
1
|
+
import { type ComponentProps, type ReactNode } from "react";
|
|
2
2
|
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
import { BottomSheetScrollView } from "@gorhom/bottom-sheet";
|
|
3
4
|
import { type OpenStateProps } from "../../overlay/useOpenState.js";
|
|
4
5
|
/**
|
|
5
6
|
* A bottom sheet, which is the phone's modal.
|
|
@@ -78,7 +79,43 @@ export interface SheetContentProps {
|
|
|
78
79
|
children?: ReactNode;
|
|
79
80
|
style?: StyleProp<ViewStyle>;
|
|
80
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* The sheet's body, for content that fits.
|
|
84
|
+
*
|
|
85
|
+
* Use `Sheet.ScrollView` instead when it might not — this is a
|
|
86
|
+
* `BottomSheetView`, which sizes itself to its children, so a scrollable inside
|
|
87
|
+
* it has no bounded height to scroll within and simply grows until the sheet
|
|
88
|
+
* clips it.
|
|
89
|
+
*/
|
|
81
90
|
declare function Content({ children, style }: SheetContentProps): import("react").JSX.Element;
|
|
91
|
+
export type SheetScrollViewProps = ComponentProps<typeof BottomSheetScrollView>;
|
|
92
|
+
/**
|
|
93
|
+
* The sheet's body, for content that might not fit.
|
|
94
|
+
*
|
|
95
|
+
* **In place of `Sheet.Content`, not inside it.** React Native's own
|
|
96
|
+
* `ScrollView` does not scroll inside a sheet at all — the sheet's pan gesture
|
|
97
|
+
* and the scroll view's native recogniser both want the touch, and
|
|
98
|
+
* gesture-handler settles that by reference, so the two have to know about each
|
|
99
|
+
* other. `BottomSheetScrollView` is that introduction, which is the same answer
|
|
100
|
+
* `Drawer.ScrollView` reaches by the same route.
|
|
101
|
+
*
|
|
102
|
+
* Being the sheet's body rather than a child of one is what makes it a single
|
|
103
|
+
* component to reach for. Three callers in the app had assembled this by hand
|
|
104
|
+
* and all three had to get four things right together: `padding: 0` and
|
|
105
|
+
* `height: "100%"` on `Sheet.Content`, so the scrollable has a bounded height
|
|
106
|
+
* to scroll within rather than a box that grows with it; the keyboard inset;
|
|
107
|
+
* and `keyboardShouldPersistTaps`, without which the first tap on a button only
|
|
108
|
+
* dismisses the keyboard. GRYT-492.
|
|
109
|
+
*
|
|
110
|
+
* What it does not decide is the snap point. A sheet that takes a keyboard
|
|
111
|
+
* wants a tall one — at 46% the field and the button underneath it are both
|
|
112
|
+
* behind the keyboard — and how tall depends on what is in it.
|
|
113
|
+
*
|
|
114
|
+
* The padding is the same as `Sheet.Content`'s, moved to the content container
|
|
115
|
+
* where it belongs: on the scrollable itself it would clip the scrolling
|
|
116
|
+
* content instead of spacing it.
|
|
117
|
+
*/
|
|
118
|
+
declare function ScrollView({ children, style, contentContainerStyle, ...props }: SheetScrollViewProps): import("react").JSX.Element;
|
|
82
119
|
export interface SheetCloseProps {
|
|
83
120
|
children?: ReactNode;
|
|
84
121
|
style?: StyleProp<ViewStyle>;
|
|
@@ -92,6 +129,7 @@ declare function Title({ children, style }: SheetTitleProps): import("react").JS
|
|
|
92
129
|
export declare const Sheet: typeof Root & {
|
|
93
130
|
Trigger: typeof Trigger;
|
|
94
131
|
Content: typeof Content;
|
|
132
|
+
ScrollView: typeof ScrollView;
|
|
95
133
|
Close: typeof Close;
|
|
96
134
|
Title: typeof Title;
|
|
97
135
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sheet.d.ts","sourceRoot":"","sources":["../../../src/components/Sheet/Sheet.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAyB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Sheet.d.ts","sourceRoot":"","sources":["../../../src/components/Sheet/Sheet.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAyB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAIL,qBAAqB,EAKtB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAI/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,kBAAkB,+BAE7D;AAeD,MAAM,WAAW,UAAW,SAAQ,cAAc;IAChD;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,iBAAS,IAAI,CAAC,EACZ,UAAoB,EACpB,QAAQ,EACR,GAAG,SAAS,EACb,EAAE,UAAU,+BAqBZ;AAWD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED;;;;;GAKG;AACH,iBAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,iBAAiB,+BAOtD;AAuMD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,iBAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,iBAAiB,+BAsCtD;AAED,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,iBAAS,UAAU,CAAC,EAClB,QAAQ,EACR,KAAK,EACL,qBAAqB,EACrB,GAAG,KAAK,EACT,EAAE,oBAAoB,+BA4BtB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,eAAe,+BAOlD;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,eAAe,+BAiBlD;AAED,eAAO,MAAM,KAAK;;;;;;CAMhB,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, } from "react";
|
|
3
3
|
import { Pressable, Text, View } from "react-native";
|
|
4
|
-
import { BottomSheetBackdrop, BottomSheetModal, BottomSheetModalProvider, BottomSheetView, useBottomSheetTimingConfigs, } from "@gorhom/bottom-sheet";
|
|
4
|
+
import { BottomSheetBackdrop, BottomSheetModal, BottomSheetModalProvider, BottomSheetScrollView, BottomSheetView, useBottomSheetTimingConfigs, } from "@gorhom/bottom-sheet";
|
|
5
5
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
6
6
|
import { grytDrawerBleed } from "@gryt/theme";
|
|
7
7
|
import { durations, easeSpringTight } from "../../motion/index.js";
|
|
@@ -54,7 +54,14 @@ function Trigger({ children, style }) {
|
|
|
54
54
|
const sheet = useSheet("Trigger");
|
|
55
55
|
return (_jsx(Pressable, { onPress: sheet.open, style: style, children: children }));
|
|
56
56
|
}
|
|
57
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Everything about presenting the modal, shared by `Content` and `ScrollView`.
|
|
59
|
+
*
|
|
60
|
+
* The two are alternatives rather than one inside the other, so both need the
|
|
61
|
+
* whole `BottomSheetModal` — the effect that presents it, the backdrop, the
|
|
62
|
+
* background and the animation curve. This is that, once.
|
|
63
|
+
*/
|
|
64
|
+
function useSheetModal() {
|
|
58
65
|
const theme = useTheme();
|
|
59
66
|
/**
|
|
60
67
|
* The phone's own furniture, which the sheet has to stay clear of at both
|
|
@@ -71,7 +78,7 @@ function Content({ children, style }) {
|
|
|
71
78
|
// on the provider inside the modal.
|
|
72
79
|
const sheet = useContext(SheetContext);
|
|
73
80
|
if (!state || !sheet) {
|
|
74
|
-
throw new Error("Sheet.Content must be rendered inside Sheet.");
|
|
81
|
+
throw new Error("Sheet.Content and Sheet.ScrollView must be rendered inside Sheet.");
|
|
75
82
|
}
|
|
76
83
|
const { ref, isOpen, setOpen, snapPoints } = state;
|
|
77
84
|
/**
|
|
@@ -175,34 +182,61 @@ function Content({ children, style }) {
|
|
|
175
182
|
// Tracks the drag, so dragging the sheet down lightens the scrim
|
|
176
183
|
// rather than holding full opacity until it snaps shut.
|
|
177
184
|
opacity: 0.6, pressBehavior: "close" })), []);
|
|
178
|
-
return
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
185
|
+
return {
|
|
186
|
+
theme,
|
|
187
|
+
insets,
|
|
188
|
+
/* Re-provided inside the modal by whichever part renders the children. See
|
|
189
|
+
* the note at the call sites — `@gorhom/portal` does not carry context. */
|
|
190
|
+
sheet,
|
|
191
|
+
modalProps: {
|
|
192
|
+
ref,
|
|
193
|
+
snapPoints,
|
|
194
|
+
// So a sheet at 100% stops below the Dynamic Island rather than running
|
|
195
|
+
// its content under it.
|
|
196
|
+
topInset: insets.top,
|
|
197
|
+
// Off, because `snapPoints` is the whole point of this component.
|
|
198
|
+
//
|
|
199
|
+
// gorhom v5 defaults dynamic sizing on, which measures the content and
|
|
200
|
+
// sizes the sheet to it — overriding the snap points entirely. A sheet
|
|
201
|
+
// asked for 70% whose content had no intrinsic height collapsed to the
|
|
202
|
+
// height of its own footer, which looks like the snap points being
|
|
203
|
+
// ignored because they were.
|
|
204
|
+
enableDynamicSizing: false,
|
|
205
|
+
enablePanDownToClose: true,
|
|
206
|
+
// A flick down or a tap on the backdrop closes it without anything in
|
|
207
|
+
// React asking, so the state has to be told. Uncontrolled, this is what
|
|
208
|
+
// makes the next `present` work; controlled, it is how the parent finds
|
|
209
|
+
// out its sheet is gone.
|
|
210
|
+
//
|
|
211
|
+
// `presented` first, and not as a tidy-up: the modal has already
|
|
212
|
+
// dismissed itself by the time this runs, and leaving the ref true lets
|
|
213
|
+
// the effect below dismiss it a second time. See the note on the ref.
|
|
214
|
+
onDismiss: () => {
|
|
215
|
+
presented.current = false;
|
|
216
|
+
setOpen(false);
|
|
217
|
+
},
|
|
218
|
+
animationConfigs,
|
|
219
|
+
backdropComponent: renderBackdrop,
|
|
220
|
+
backgroundComponent: renderBackground,
|
|
221
|
+
handleIndicatorStyle: {
|
|
222
|
+
backgroundColor: theme.color.border,
|
|
223
|
+
width: 36,
|
|
224
|
+
height: 4,
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* The sheet's body, for content that fits.
|
|
231
|
+
*
|
|
232
|
+
* Use `Sheet.ScrollView` instead when it might not — this is a
|
|
233
|
+
* `BottomSheetView`, which sizes itself to its children, so a scrollable inside
|
|
234
|
+
* it has no bounded height to scroll within and simply grows until the sheet
|
|
235
|
+
* clips it.
|
|
236
|
+
*/
|
|
237
|
+
function Content({ children, style }) {
|
|
238
|
+
const { theme, insets, sheet, modalProps } = useSheetModal();
|
|
239
|
+
return (_jsx(BottomSheetModal, { ...modalProps, children: _jsx(BottomSheetView, { style: [
|
|
206
240
|
{
|
|
207
241
|
flex: 1,
|
|
208
242
|
padding: theme.space(4),
|
|
@@ -214,6 +248,52 @@ function Content({ children, style }) {
|
|
|
214
248
|
style,
|
|
215
249
|
], children: _jsx(SheetContext.Provider, { value: sheet, children: children }) }) }));
|
|
216
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* The sheet's body, for content that might not fit.
|
|
253
|
+
*
|
|
254
|
+
* **In place of `Sheet.Content`, not inside it.** React Native's own
|
|
255
|
+
* `ScrollView` does not scroll inside a sheet at all — the sheet's pan gesture
|
|
256
|
+
* and the scroll view's native recogniser both want the touch, and
|
|
257
|
+
* gesture-handler settles that by reference, so the two have to know about each
|
|
258
|
+
* other. `BottomSheetScrollView` is that introduction, which is the same answer
|
|
259
|
+
* `Drawer.ScrollView` reaches by the same route.
|
|
260
|
+
*
|
|
261
|
+
* Being the sheet's body rather than a child of one is what makes it a single
|
|
262
|
+
* component to reach for. Three callers in the app had assembled this by hand
|
|
263
|
+
* and all three had to get four things right together: `padding: 0` and
|
|
264
|
+
* `height: "100%"` on `Sheet.Content`, so the scrollable has a bounded height
|
|
265
|
+
* to scroll within rather than a box that grows with it; the keyboard inset;
|
|
266
|
+
* and `keyboardShouldPersistTaps`, without which the first tap on a button only
|
|
267
|
+
* dismisses the keyboard. GRYT-492.
|
|
268
|
+
*
|
|
269
|
+
* What it does not decide is the snap point. A sheet that takes a keyboard
|
|
270
|
+
* wants a tall one — at 46% the field and the button underneath it are both
|
|
271
|
+
* behind the keyboard — and how tall depends on what is in it.
|
|
272
|
+
*
|
|
273
|
+
* The padding is the same as `Sheet.Content`'s, moved to the content container
|
|
274
|
+
* where it belongs: on the scrollable itself it would clip the scrolling
|
|
275
|
+
* content instead of spacing it.
|
|
276
|
+
*/
|
|
277
|
+
function ScrollView({ children, style, contentContainerStyle, ...props }) {
|
|
278
|
+
const { theme, insets, sheet, modalProps } = useSheetModal();
|
|
279
|
+
return (_jsx(BottomSheetModal, { ...modalProps, children: _jsx(BottomSheetScrollView
|
|
280
|
+
// The keyboard's height as a bottom inset, so what it covers can still
|
|
281
|
+
// be scrolled into what is left of the sheet.
|
|
282
|
+
, {
|
|
283
|
+
// The keyboard's height as a bottom inset, so what it covers can still
|
|
284
|
+
// be scrolled into what is left of the sheet.
|
|
285
|
+
automaticallyAdjustKeyboardInsets: true,
|
|
286
|
+
// Or the first tap on anything only dismisses the keyboard, and the
|
|
287
|
+
// button has to be pressed twice.
|
|
288
|
+
keyboardShouldPersistTaps: "handled", ...props, style: [{ flex: 1 }, style], contentContainerStyle: [
|
|
289
|
+
{
|
|
290
|
+
padding: theme.space(4),
|
|
291
|
+
// The home indicator's strip, as in `Content`.
|
|
292
|
+
paddingBottom: theme.space(4) + insets.bottom,
|
|
293
|
+
},
|
|
294
|
+
contentContainerStyle,
|
|
295
|
+
], children: _jsx(SheetContext.Provider, { value: sheet, children: children }) }) }));
|
|
296
|
+
}
|
|
217
297
|
function Close({ children, style }) {
|
|
218
298
|
const sheet = useSheet("Close");
|
|
219
299
|
return (_jsx(Pressable, { onPress: sheet.close, style: style, children: children }));
|
|
@@ -227,4 +307,10 @@ function Title({ children, style }) {
|
|
|
227
307
|
marginBottom: theme.space(2),
|
|
228
308
|
}, children: children }) }));
|
|
229
309
|
}
|
|
230
|
-
export const Sheet = Object.assign(Root, {
|
|
310
|
+
export const Sheet = Object.assign(Root, {
|
|
311
|
+
Trigger,
|
|
312
|
+
Content,
|
|
313
|
+
ScrollView,
|
|
314
|
+
Close,
|
|
315
|
+
Title,
|
|
316
|
+
});
|
|
@@ -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, }) {
|
package/dist/index.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export { Drawer, type DrawerPopupProps, type DrawerRootProps, type DrawerSide, }
|
|
|
30
30
|
export { NumberField, type NumberFieldProps } from "./components/NumberField/NumberField.js";
|
|
31
31
|
export { OtpField, type OtpFieldProps } from "./components/OtpField/OtpField.js";
|
|
32
32
|
export { ScrollArea, type ScrollAreaProps } from "./components/ScrollArea/ScrollArea.js";
|
|
33
|
-
export { Sheet, type SheetCloseProps, type SheetContentProps, type SheetProps, SheetProvider, type SheetProviderProps, type SheetTitleProps, type SheetTriggerProps, } from "./components/Sheet/Sheet.js";
|
|
33
|
+
export { Sheet, type SheetCloseProps, type SheetContentProps, type SheetProps, SheetProvider, type SheetProviderProps, type SheetScrollViewProps, type SheetTitleProps, type SheetTriggerProps, } from "./components/Sheet/Sheet.js";
|
|
34
34
|
export { ToastProvider, useToast, type ToastOptions, type ToastSeverity, } from "./components/Toast/Toast.js";
|
|
35
35
|
export { Toolbar, ToolbarSeparator, type ToolbarProps, type ToolbarSeparatorProps, } from "./components/Toolbar/Toolbar.js";
|
|
36
36
|
export { AnchoredPopup, type AnchoredPopupProps } from "./overlay/AnchoredPopup.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|