@jobber/components-native 0.107.3 → 0.108.1-visual-reg-5479aeb.25
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/docs/AtlantisThemeContext/AtlantisThemeContext.md +40 -0
- package/dist/docs/ContentOverlay/ContentOverlay.md +4 -0
- package/dist/docs/Icon/Icon.md +60 -53
- package/dist/docs/InputTime/InputTime.md +8 -0
- package/dist/docs/ProgressBar/ProgressBar.md +9 -0
- package/dist/package.json +3 -3
- package/dist/src/ContentOverlay/ContentOverlay.js +15 -10
- package/dist/src/ContentOverlay/computeContentOverlayBehavior.js +7 -4
- package/dist/src/ContentOverlay/computeContentOverlayBehavior.test.js +31 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/src/ContentOverlay/ContentOverlay.d.ts +1 -1
- package/dist/types/src/ContentOverlay/computeContentOverlayBehavior.d.ts +1 -0
- package/dist/types/src/ContentOverlay/types.d.ts +23 -0
- package/package.json +3 -3
- package/src/ContentOverlay/ContentOverlay.tsx +57 -33
- package/src/ContentOverlay/computeContentOverlayBehavior.test.ts +40 -0
- package/src/ContentOverlay/computeContentOverlayBehavior.ts +8 -4
- package/src/ContentOverlay/types.ts +28 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { ContentOverlayProps } from "./types";
|
|
3
3
|
export declare function useIsKeyboardHandledByScrollView(): boolean;
|
|
4
|
-
export declare function ContentOverlay({ children, title, accessibilityLabel, fullScreen, showDismiss, isDraggable, adjustToContentHeight, keyboardShouldPersistTaps, scrollEnabled, modalBackgroundColor, onClose, onOpen, onBeforeExit, loading, ref, }: ContentOverlayProps): React.JSX.Element;
|
|
4
|
+
export declare function ContentOverlay({ children, title, accessibilityLabel, fullScreen, showDismiss, isDraggable, adjustToContentHeight, keyboardShouldPersistTaps, scrollEnabled, modalBackgroundColor, onClose, onOpen, onBeforeExit, allowDragWithBeforeExit, enablePanDownToClose, enableContentPanningGesture, snapPoints: customSnapPoints, loading, ref, }: ContentOverlayProps): React.JSX.Element;
|
|
@@ -63,6 +63,29 @@ export interface ContentOverlayProps {
|
|
|
63
63
|
* Callback that is called between overlay is closed and when the "x" button is pressed
|
|
64
64
|
*/
|
|
65
65
|
readonly onBeforeExit?: () => void;
|
|
66
|
+
/**
|
|
67
|
+
* Whether panning down on the content area closes the sheet. Set false to prevent the sheet from being closed by panning down.
|
|
68
|
+
* Defaults to the resolved draggable state.
|
|
69
|
+
*/
|
|
70
|
+
readonly enablePanDownToClose?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* When `true`, `onBeforeExit` intercepts the dismiss button and back press
|
|
73
|
+
* but does not disable drag. Drag-to-dismiss bypasses `onBeforeExit`.
|
|
74
|
+
* @default false
|
|
75
|
+
*/
|
|
76
|
+
readonly allowDragWithBeforeExit?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Whether pan on the content area drags the sheet. Set `false` to let
|
|
79
|
+
* nested scrollables own the gesture. Defaults to the resolved draggable
|
|
80
|
+
* state.
|
|
81
|
+
*/
|
|
82
|
+
readonly enableContentPanningGesture?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Explicit snap points for the overlay (percentages or pixel values).
|
|
85
|
+
* When provided, `adjustToContentHeight` is ignored and the sheet snaps
|
|
86
|
+
* to these positions instead of the measured content height.
|
|
87
|
+
*/
|
|
88
|
+
readonly snapPoints?: (string | number)[];
|
|
66
89
|
/**
|
|
67
90
|
* Boolean to show a disabled state
|
|
68
91
|
* @default false
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.108.1-visual-reg-5479aeb.25+5479aebb",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React Native implementation of Atlantis",
|
|
6
6
|
"repository": {
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@babel/runtime": "^7.29.2",
|
|
75
75
|
"@gorhom/bottom-sheet": "^5.2.8",
|
|
76
|
-
"@jobber/design": "0.107.
|
|
76
|
+
"@jobber/design": "0.107.1-visual-reg-5479aeb.32+5479aebb",
|
|
77
77
|
"@jobber/hooks": "2.21.0",
|
|
78
78
|
"@react-native-community/datetimepicker": "^8.4.5",
|
|
79
79
|
"@react-native/babel-preset": "^0.82.1",
|
|
@@ -124,5 +124,5 @@
|
|
|
124
124
|
"react-native-screens": ">=4.18.0",
|
|
125
125
|
"react-native-svg": ">=12.0.0"
|
|
126
126
|
},
|
|
127
|
-
"gitHead": "
|
|
127
|
+
"gitHead": "5479aebba6969f3d68ca0fb11654375c8439ab96"
|
|
128
128
|
}
|
|
@@ -36,7 +36,10 @@ import { useIsScreenReaderEnabled } from "../hooks";
|
|
|
36
36
|
import { IconButton } from "../IconButton";
|
|
37
37
|
import { Heading } from "../Heading";
|
|
38
38
|
import { useAtlantisI18n } from "../hooks/useAtlantisI18n";
|
|
39
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
AtlantisThemeContextProvider,
|
|
41
|
+
useAtlantisTheme,
|
|
42
|
+
} from "../AtlantisThemeContext";
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
45
|
* Signals whether keyboard handling inside a ContentOverlay is delegated to
|
|
@@ -81,6 +84,10 @@ export function ContentOverlay({
|
|
|
81
84
|
onClose,
|
|
82
85
|
onOpen,
|
|
83
86
|
onBeforeExit,
|
|
87
|
+
allowDragWithBeforeExit = false,
|
|
88
|
+
enablePanDownToClose,
|
|
89
|
+
enableContentPanningGesture,
|
|
90
|
+
snapPoints: customSnapPoints,
|
|
84
91
|
loading = false,
|
|
85
92
|
ref,
|
|
86
93
|
}: ContentOverlayProps) {
|
|
@@ -92,7 +99,7 @@ export function ContentOverlay({
|
|
|
92
99
|
|
|
93
100
|
const styles = useStyles();
|
|
94
101
|
const { t } = useAtlantisI18n();
|
|
95
|
-
const { tokens } = useAtlantisTheme();
|
|
102
|
+
const { theme, tokens } = useAtlantisTheme();
|
|
96
103
|
const isScreenReaderEnabled = useIsScreenReaderEnabled();
|
|
97
104
|
|
|
98
105
|
const behavior = computeContentOverlayBehavior(
|
|
@@ -101,6 +108,7 @@ export function ContentOverlay({
|
|
|
101
108
|
adjustToContentHeight,
|
|
102
109
|
isDraggable,
|
|
103
110
|
hasOnBeforeExit: onBeforeExit !== undefined,
|
|
111
|
+
allowDragWithBeforeExit,
|
|
104
112
|
showDismiss,
|
|
105
113
|
},
|
|
106
114
|
{
|
|
@@ -124,12 +132,16 @@ export function ContentOverlay({
|
|
|
124
132
|
|
|
125
133
|
// enableDynamicSizing will add another snap point of the content height
|
|
126
134
|
const snapPoints = useMemo(() => {
|
|
135
|
+
if (customSnapPoints && customSnapPoints.length > 0) {
|
|
136
|
+
return customSnapPoints;
|
|
137
|
+
}
|
|
138
|
+
|
|
127
139
|
// There is a bug with "restore" behavior after keyboard is dismissed.
|
|
128
140
|
// https://github.com/gorhom/react-native-bottom-sheet/issues/2465
|
|
129
141
|
// providing a 100% snap point "fixes" it for now, but there is an approved PR to fix it
|
|
130
142
|
// that just needs to be merged and released: https://github.com/gorhom/react-native-bottom-sheet/pull/2511
|
|
131
143
|
return ["100%"];
|
|
132
|
-
}, []);
|
|
144
|
+
}, [customSnapPoints]);
|
|
133
145
|
|
|
134
146
|
const onCloseController = () => {
|
|
135
147
|
if (!onBeforeExit) {
|
|
@@ -296,43 +308,55 @@ export function ContentOverlay({
|
|
|
296
308
|
handleIndicatorStyle={handleIndicatorStyles}
|
|
297
309
|
backdropComponent={backdropComponent}
|
|
298
310
|
snapPoints={snapPoints}
|
|
299
|
-
enablePanDownToClose={effectiveIsDraggable}
|
|
300
|
-
enableContentPanningGesture={
|
|
311
|
+
enablePanDownToClose={enablePanDownToClose ?? effectiveIsDraggable}
|
|
312
|
+
enableContentPanningGesture={
|
|
313
|
+
enableContentPanningGesture ?? effectiveIsDraggable
|
|
314
|
+
}
|
|
301
315
|
enableHandlePanningGesture={effectiveIsDraggable}
|
|
302
|
-
enableDynamicSizing={
|
|
316
|
+
enableDynamicSizing={
|
|
317
|
+
!customSnapPoints && behavior.initialHeight === "contentHeight"
|
|
318
|
+
}
|
|
303
319
|
keyboardBehavior="interactive"
|
|
304
320
|
keyboardBlurBehavior="restore"
|
|
305
321
|
topInset={topInset}
|
|
306
322
|
onDismiss={() => onClose?.()}
|
|
307
323
|
>
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
<View
|
|
328
|
-
style={{ paddingBottom: insets.bottom }}
|
|
329
|
-
testID="ATL-Overlay-Children"
|
|
324
|
+
{/*
|
|
325
|
+
BottomSheetModal renders its children through a portal mounted outside
|
|
326
|
+
this component's subtree, so the AtlantisThemeContext is lost. Re-apply
|
|
327
|
+
the active theme here so descendants (e.g. the header title) resolve the
|
|
328
|
+
correct themed tokens.
|
|
329
|
+
*/}
|
|
330
|
+
<AtlantisThemeContextProvider dangerouslyOverrideTheme={theme}>
|
|
331
|
+
<ContentOverlayKeyboardContext.Provider value={scrollEnabled}>
|
|
332
|
+
{scrollEnabled ? (
|
|
333
|
+
<BottomSheetKeyboardAwareScrollView
|
|
334
|
+
ref={scrollViewRef}
|
|
335
|
+
contentContainerStyle={{ paddingBottom: insets.bottom }}
|
|
336
|
+
keyboardShouldPersistTaps={
|
|
337
|
+
keyboardShouldPersistTaps ? "handled" : "never"
|
|
338
|
+
}
|
|
339
|
+
showsVerticalScrollIndicator={false}
|
|
340
|
+
onScroll={handleOnScroll}
|
|
341
|
+
stickyHeaderIndices={[0]}
|
|
342
|
+
bottomOffset={KEYBOARD_TOP_PADDING_AUTO_SCROLL}
|
|
330
343
|
>
|
|
331
|
-
{
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
344
|
+
{renderHeader()}
|
|
345
|
+
<View testID="ATL-Overlay-Children">{children}</View>
|
|
346
|
+
</BottomSheetKeyboardAwareScrollView>
|
|
347
|
+
) : (
|
|
348
|
+
<BottomSheetView>
|
|
349
|
+
{renderHeader()}
|
|
350
|
+
<View
|
|
351
|
+
style={{ paddingBottom: insets.bottom }}
|
|
352
|
+
testID="ATL-Overlay-Children"
|
|
353
|
+
>
|
|
354
|
+
{children}
|
|
355
|
+
</View>
|
|
356
|
+
</BottomSheetView>
|
|
357
|
+
)}
|
|
358
|
+
</ContentOverlayKeyboardContext.Provider>
|
|
359
|
+
</AtlantisThemeContextProvider>
|
|
336
360
|
</BottomSheetModal>
|
|
337
361
|
);
|
|
338
362
|
}
|
|
@@ -11,6 +11,7 @@ const defaultConfig: ContentOverlayConfig = {
|
|
|
11
11
|
adjustToContentHeight: false,
|
|
12
12
|
isDraggable: true,
|
|
13
13
|
hasOnBeforeExit: false,
|
|
14
|
+
allowDragWithBeforeExit: false,
|
|
14
15
|
showDismiss: false,
|
|
15
16
|
};
|
|
16
17
|
|
|
@@ -112,6 +113,45 @@ describe("computeContentOverlayBehavior", () => {
|
|
|
112
113
|
|
|
113
114
|
expect(result.isDraggable).toBe(false);
|
|
114
115
|
});
|
|
116
|
+
|
|
117
|
+
it("respects isDraggable=true when onBeforeExit is present and allowDragWithBeforeExit=true", () => {
|
|
118
|
+
const config = aConfig({
|
|
119
|
+
isDraggable: true,
|
|
120
|
+
hasOnBeforeExit: true,
|
|
121
|
+
allowDragWithBeforeExit: true,
|
|
122
|
+
});
|
|
123
|
+
const state = aState();
|
|
124
|
+
|
|
125
|
+
const result = computeContentOverlayBehavior(config, state);
|
|
126
|
+
|
|
127
|
+
expect(result.isDraggable).toBe(true);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("respects isDraggable=false when onBeforeExit is present and allowDragWithBeforeExit=true", () => {
|
|
131
|
+
const config = aConfig({
|
|
132
|
+
isDraggable: false,
|
|
133
|
+
hasOnBeforeExit: true,
|
|
134
|
+
allowDragWithBeforeExit: true,
|
|
135
|
+
});
|
|
136
|
+
const state = aState();
|
|
137
|
+
|
|
138
|
+
const result = computeContentOverlayBehavior(config, state);
|
|
139
|
+
|
|
140
|
+
expect(result.isDraggable).toBe(false);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("still overrides to false when onBeforeExit is present and allowDragWithBeforeExit=false (default)", () => {
|
|
144
|
+
const config = aConfig({
|
|
145
|
+
isDraggable: true,
|
|
146
|
+
hasOnBeforeExit: true,
|
|
147
|
+
allowDragWithBeforeExit: false,
|
|
148
|
+
});
|
|
149
|
+
const state = aState();
|
|
150
|
+
|
|
151
|
+
const result = computeContentOverlayBehavior(config, state);
|
|
152
|
+
|
|
153
|
+
expect(result.isDraggable).toBe(false);
|
|
154
|
+
});
|
|
115
155
|
});
|
|
116
156
|
|
|
117
157
|
describe("showDismiss", () => {
|
|
@@ -3,6 +3,7 @@ export interface ContentOverlayConfig {
|
|
|
3
3
|
adjustToContentHeight: boolean;
|
|
4
4
|
isDraggable: boolean;
|
|
5
5
|
hasOnBeforeExit: boolean;
|
|
6
|
+
allowDragWithBeforeExit: boolean;
|
|
6
7
|
showDismiss: boolean;
|
|
7
8
|
}
|
|
8
9
|
|
|
@@ -76,14 +77,17 @@ function computeInitialHeight(
|
|
|
76
77
|
|
|
77
78
|
/**
|
|
78
79
|
* Draggability determination:
|
|
79
|
-
* - hasOnBeforeExit: true → false (
|
|
80
|
+
* - hasOnBeforeExit: true && !allowDragWithBeforeExit → false (legacy override)
|
|
81
|
+
* - hasOnBeforeExit: true && allowDragWithBeforeExit → use isDraggable prop value
|
|
80
82
|
* - Otherwise → use isDraggable prop value
|
|
81
83
|
*
|
|
82
|
-
*
|
|
83
|
-
* and dragging would bypass that interception.
|
|
84
|
+
* The legacy override exists because onBeforeExit needs to intercept close
|
|
85
|
+
* attempts, and dragging would bypass that interception. Consumers that
|
|
86
|
+
* explicitly accept the asymmetry (e.g. button-press confirmation,
|
|
87
|
+
* drag-dismiss silent) can opt out via `allowDragWithBeforeExit`.
|
|
84
88
|
*/
|
|
85
89
|
function computeIsDraggable(config: ContentOverlayConfig): boolean {
|
|
86
|
-
if (config.hasOnBeforeExit) {
|
|
90
|
+
if (config.hasOnBeforeExit && !config.allowDragWithBeforeExit) {
|
|
87
91
|
return false;
|
|
88
92
|
}
|
|
89
93
|
|
|
@@ -66,6 +66,34 @@ export interface ContentOverlayProps {
|
|
|
66
66
|
*/
|
|
67
67
|
readonly onBeforeExit?: () => void;
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Whether panning down on the content area closes the sheet. Set false to prevent the sheet from being closed by panning down.
|
|
71
|
+
* Defaults to the resolved draggable state.
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
readonly enablePanDownToClose?: boolean;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* When `true`, `onBeforeExit` intercepts the dismiss button and back press
|
|
78
|
+
* but does not disable drag. Drag-to-dismiss bypasses `onBeforeExit`.
|
|
79
|
+
* @default false
|
|
80
|
+
*/
|
|
81
|
+
readonly allowDragWithBeforeExit?: boolean;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Whether pan on the content area drags the sheet. Set `false` to let
|
|
85
|
+
* nested scrollables own the gesture. Defaults to the resolved draggable
|
|
86
|
+
* state.
|
|
87
|
+
*/
|
|
88
|
+
readonly enableContentPanningGesture?: boolean;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Explicit snap points for the overlay (percentages or pixel values).
|
|
92
|
+
* When provided, `adjustToContentHeight` is ignored and the sheet snaps
|
|
93
|
+
* to these positions instead of the measured content height.
|
|
94
|
+
*/
|
|
95
|
+
readonly snapPoints?: (string | number)[];
|
|
96
|
+
|
|
69
97
|
/**
|
|
70
98
|
* Boolean to show a disabled state
|
|
71
99
|
* @default false
|