@gryt/ui-native 0.9.0 → 0.11.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 +55 -1
- package/dist/components/Sheet/Sheet.d.ts.map +1 -1
- package/dist/components/Sheet/Sheet.js +135 -32
- 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,59 @@ 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
|
+
*
|
|
90
|
+
* ## Why it is `height: "100%"`
|
|
91
|
+
*
|
|
92
|
+
* `flex: 1` is not enough on its own: `BottomSheetView` measures its children,
|
|
93
|
+
* so there is no bounded height for a flex child to be all of. Anything inside
|
|
94
|
+
* that wants to be the whole sheet — a column with a row pinned to the bottom,
|
|
95
|
+
* a list — collapses to the height of its own content instead.
|
|
96
|
+
*
|
|
97
|
+
* Every caller in the mobile app passed `height: "100%"` to get around that,
|
|
98
|
+
* all three for the same reason, which is a default being wrong rather than
|
|
99
|
+
* three callers being unusual. It is in the style array before `style`, so a
|
|
100
|
+
* caller can still override it exactly as it can the padding. GRYT-516.
|
|
101
|
+
*
|
|
102
|
+
* A sheet whose content is genuinely shorter than the snap point is unchanged
|
|
103
|
+
* by this: the view has no background of its own, so a full-height one draws
|
|
104
|
+
* the same as a short one.
|
|
105
|
+
*/
|
|
81
106
|
declare function Content({ children, style }: SheetContentProps): import("react").JSX.Element;
|
|
107
|
+
export type SheetScrollViewProps = ComponentProps<typeof BottomSheetScrollView>;
|
|
108
|
+
/**
|
|
109
|
+
* The sheet's body, for content that might not fit.
|
|
110
|
+
*
|
|
111
|
+
* **In place of `Sheet.Content`, not inside it.** React Native's own
|
|
112
|
+
* `ScrollView` does not scroll inside a sheet at all — the sheet's pan gesture
|
|
113
|
+
* and the scroll view's native recogniser both want the touch, and
|
|
114
|
+
* gesture-handler settles that by reference, so the two have to know about each
|
|
115
|
+
* other. `BottomSheetScrollView` is that introduction, which is the same answer
|
|
116
|
+
* `Drawer.ScrollView` reaches by the same route.
|
|
117
|
+
*
|
|
118
|
+
* Being the sheet's body rather than a child of one is what makes it a single
|
|
119
|
+
* component to reach for. Three callers in the app had assembled this by hand
|
|
120
|
+
* and all three had to get four things right together: `padding: 0` and
|
|
121
|
+
* `height: "100%"` on `Sheet.Content`, so the scrollable has a bounded height
|
|
122
|
+
* to scroll within rather than a box that grows with it; the keyboard inset;
|
|
123
|
+
* and `keyboardShouldPersistTaps`, without which the first tap on a button only
|
|
124
|
+
* dismisses the keyboard. GRYT-492.
|
|
125
|
+
*
|
|
126
|
+
* What it does not decide is the snap point. A sheet that takes a keyboard
|
|
127
|
+
* wants a tall one — at 46% the field and the button underneath it are both
|
|
128
|
+
* behind the keyboard — and how tall depends on what is in it.
|
|
129
|
+
*
|
|
130
|
+
* The padding is the same as `Sheet.Content`'s, moved to the content container
|
|
131
|
+
* where it belongs: on the scrollable itself it would clip the scrolling
|
|
132
|
+
* content instead of spacing it.
|
|
133
|
+
*/
|
|
134
|
+
declare function ScrollView({ children, style, contentContainerStyle, ...props }: SheetScrollViewProps): import("react").JSX.Element;
|
|
82
135
|
export interface SheetCloseProps {
|
|
83
136
|
children?: ReactNode;
|
|
84
137
|
style?: StyleProp<ViewStyle>;
|
|
@@ -92,6 +145,7 @@ declare function Title({ children, style }: SheetTitleProps): import("react").JS
|
|
|
92
145
|
export declare const Sheet: typeof Root & {
|
|
93
146
|
Trigger: typeof Trigger;
|
|
94
147
|
Content: typeof Content;
|
|
148
|
+
ScrollView: typeof ScrollView;
|
|
95
149
|
Close: typeof Close;
|
|
96
150
|
Title: typeof Title;
|
|
97
151
|
};
|
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,iBAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,iBAAiB,+BAuCtD;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,36 +182,80 @@ 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
|
+
* ## Why it is `height: "100%"`
|
|
238
|
+
*
|
|
239
|
+
* `flex: 1` is not enough on its own: `BottomSheetView` measures its children,
|
|
240
|
+
* so there is no bounded height for a flex child to be all of. Anything inside
|
|
241
|
+
* that wants to be the whole sheet — a column with a row pinned to the bottom,
|
|
242
|
+
* a list — collapses to the height of its own content instead.
|
|
243
|
+
*
|
|
244
|
+
* Every caller in the mobile app passed `height: "100%"` to get around that,
|
|
245
|
+
* all three for the same reason, which is a default being wrong rather than
|
|
246
|
+
* three callers being unusual. It is in the style array before `style`, so a
|
|
247
|
+
* caller can still override it exactly as it can the padding. GRYT-516.
|
|
248
|
+
*
|
|
249
|
+
* A sheet whose content is genuinely shorter than the snap point is unchanged
|
|
250
|
+
* by this: the view has no background of its own, so a full-height one draws
|
|
251
|
+
* the same as a short one.
|
|
252
|
+
*/
|
|
253
|
+
function Content({ children, style }) {
|
|
254
|
+
const { theme, insets, sheet, modalProps } = useSheetModal();
|
|
255
|
+
return (_jsx(BottomSheetModal, { ...modalProps, children: _jsx(BottomSheetView, { style: [
|
|
206
256
|
{
|
|
207
257
|
flex: 1,
|
|
258
|
+
height: "100%",
|
|
208
259
|
padding: theme.space(4),
|
|
209
260
|
// The home indicator's strip, on top of whatever padding the caller
|
|
210
261
|
// asked for. Without it the last row of content is clipped by it —
|
|
@@ -214,6 +265,52 @@ function Content({ children, style }) {
|
|
|
214
265
|
style,
|
|
215
266
|
], children: _jsx(SheetContext.Provider, { value: sheet, children: children }) }) }));
|
|
216
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* The sheet's body, for content that might not fit.
|
|
270
|
+
*
|
|
271
|
+
* **In place of `Sheet.Content`, not inside it.** React Native's own
|
|
272
|
+
* `ScrollView` does not scroll inside a sheet at all — the sheet's pan gesture
|
|
273
|
+
* and the scroll view's native recogniser both want the touch, and
|
|
274
|
+
* gesture-handler settles that by reference, so the two have to know about each
|
|
275
|
+
* other. `BottomSheetScrollView` is that introduction, which is the same answer
|
|
276
|
+
* `Drawer.ScrollView` reaches by the same route.
|
|
277
|
+
*
|
|
278
|
+
* Being the sheet's body rather than a child of one is what makes it a single
|
|
279
|
+
* component to reach for. Three callers in the app had assembled this by hand
|
|
280
|
+
* and all three had to get four things right together: `padding: 0` and
|
|
281
|
+
* `height: "100%"` on `Sheet.Content`, so the scrollable has a bounded height
|
|
282
|
+
* to scroll within rather than a box that grows with it; the keyboard inset;
|
|
283
|
+
* and `keyboardShouldPersistTaps`, without which the first tap on a button only
|
|
284
|
+
* dismisses the keyboard. GRYT-492.
|
|
285
|
+
*
|
|
286
|
+
* What it does not decide is the snap point. A sheet that takes a keyboard
|
|
287
|
+
* wants a tall one — at 46% the field and the button underneath it are both
|
|
288
|
+
* behind the keyboard — and how tall depends on what is in it.
|
|
289
|
+
*
|
|
290
|
+
* The padding is the same as `Sheet.Content`'s, moved to the content container
|
|
291
|
+
* where it belongs: on the scrollable itself it would clip the scrolling
|
|
292
|
+
* content instead of spacing it.
|
|
293
|
+
*/
|
|
294
|
+
function ScrollView({ children, style, contentContainerStyle, ...props }) {
|
|
295
|
+
const { theme, insets, sheet, modalProps } = useSheetModal();
|
|
296
|
+
return (_jsx(BottomSheetModal, { ...modalProps, children: _jsx(BottomSheetScrollView
|
|
297
|
+
// The keyboard's height as a bottom inset, so what it covers can still
|
|
298
|
+
// be scrolled into what is left of the sheet.
|
|
299
|
+
, {
|
|
300
|
+
// The keyboard's height as a bottom inset, so what it covers can still
|
|
301
|
+
// be scrolled into what is left of the sheet.
|
|
302
|
+
automaticallyAdjustKeyboardInsets: true,
|
|
303
|
+
// Or the first tap on anything only dismisses the keyboard, and the
|
|
304
|
+
// button has to be pressed twice.
|
|
305
|
+
keyboardShouldPersistTaps: "handled", ...props, style: [{ flex: 1 }, style], contentContainerStyle: [
|
|
306
|
+
{
|
|
307
|
+
padding: theme.space(4),
|
|
308
|
+
// The home indicator's strip, as in `Content`.
|
|
309
|
+
paddingBottom: theme.space(4) + insets.bottom,
|
|
310
|
+
},
|
|
311
|
+
contentContainerStyle,
|
|
312
|
+
], children: _jsx(SheetContext.Provider, { value: sheet, children: children }) }) }));
|
|
313
|
+
}
|
|
217
314
|
function Close({ children, style }) {
|
|
218
315
|
const sheet = useSheet("Close");
|
|
219
316
|
return (_jsx(Pressable, { onPress: sheet.close, style: style, children: children }));
|
|
@@ -227,4 +324,10 @@ function Title({ children, style }) {
|
|
|
227
324
|
marginBottom: theme.space(2),
|
|
228
325
|
}, children: children }) }));
|
|
229
326
|
}
|
|
230
|
-
export const Sheet = Object.assign(Root, {
|
|
327
|
+
export const Sheet = Object.assign(Root, {
|
|
328
|
+
Trigger,
|
|
329
|
+
Content,
|
|
330
|
+
ScrollView,
|
|
331
|
+
Close,
|
|
332
|
+
Title,
|
|
333
|
+
});
|
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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"}
|