@jobber/components-native 0.95.2-JOB-141866-990fa70.9 → 0.95.2-JOB-141866-a6ee36d.22
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/package.json +2 -2
- package/dist/src/ContentOverlay/ContentOverlay.js +2 -1
- package/dist/src/Form/Form.js +10 -17
- package/dist/src/InputText/InputText.js +3 -45
- package/dist/src/InputText/context/InputAccessoriesContext.js +0 -2
- package/dist/src/InputText/context/InputAccessoriesProvider.js +1 -6
- package/dist/src/hooks/index.js +0 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/src/Form/types.d.ts +7 -0
- package/dist/types/src/InputText/InputText.d.ts +0 -5
- package/dist/types/src/InputText/context/types.d.ts +0 -2
- package/dist/types/src/hooks/index.d.ts +0 -1
- package/package.json +2 -2
- package/src/ContentOverlay/ContentOverlay.tsx +2 -1
- package/src/Form/Form.tsx +12 -24
- package/src/Form/types.ts +8 -0
- package/src/InputText/InputText.tsx +2 -37
- package/src/InputText/context/InputAccessoriesContext.ts +0 -2
- package/src/InputText/context/InputAccessoriesProvider.tsx +0 -7
- package/src/InputText/context/types.ts +0 -2
- package/src/hooks/index.ts +0 -1
- /package/dist/src/{hooks → ContentOverlay/hooks}/useKeyboardVisibility.js +0 -0
- /package/dist/types/src/{hooks → ContentOverlay/hooks}/useKeyboardVisibility.d.ts +0 -0
- /package/src/{hooks → ContentOverlay/hooks}/useKeyboardVisibility.test.ts +0 -0
- /package/src/{hooks → ContentOverlay/hooks}/useKeyboardVisibility.ts +0 -0
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components-native",
|
|
3
|
-
"version": "0.95.2-JOB-141866-
|
|
3
|
+
"version": "0.95.2-JOB-141866-a6ee36d.22+a6ee36d10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React Native implementation of Atlantis",
|
|
6
6
|
"repository": {
|
|
@@ -96,5 +96,5 @@
|
|
|
96
96
|
"react-native-safe-area-context": "^5.4.0",
|
|
97
97
|
"react-native-svg": ">=12.0.0"
|
|
98
98
|
},
|
|
99
|
-
"gitHead": "
|
|
99
|
+
"gitHead": "a6ee36d10f2c1ba08f20ad6bb9019e274bcee16f"
|
|
100
100
|
}
|
|
@@ -2,10 +2,11 @@ import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useRef, u
|
|
|
2
2
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
3
3
|
import { AccessibilityInfo, Platform, View, findNodeHandle, useWindowDimensions, } from "react-native";
|
|
4
4
|
import { Portal } from "react-native-portalize";
|
|
5
|
+
import { useKeyboardVisibility } from "./hooks/useKeyboardVisibility";
|
|
5
6
|
import { useStyles } from "./ContentOverlay.style";
|
|
6
7
|
import { useViewLayoutHeight } from "./hooks/useViewLayoutHeight";
|
|
7
8
|
import { UNSAFE_WrappedModalize } from "./UNSAFE_WrappedModalize";
|
|
8
|
-
import { useIsScreenReaderEnabled
|
|
9
|
+
import { useIsScreenReaderEnabled } from "../hooks";
|
|
9
10
|
import { IconButton } from "../IconButton";
|
|
10
11
|
import { Heading } from "../Heading";
|
|
11
12
|
import { useAtlantisI18n } from "../hooks/useAtlantisI18n";
|
package/dist/src/Form/Form.js
CHANGED
|
@@ -18,7 +18,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
18
18
|
}
|
|
19
19
|
return t;
|
|
20
20
|
};
|
|
21
|
-
import React, {
|
|
21
|
+
import React, { useState } from "react";
|
|
22
22
|
import { FormProvider } from "react-hook-form";
|
|
23
23
|
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
|
|
24
24
|
import { Keyboard, Platform, View, findNodeHandle } from "react-native";
|
|
@@ -39,7 +39,7 @@ import { FormSaveButton } from "./components/FormSaveButton";
|
|
|
39
39
|
import { useSaveButtonPosition } from "./hooks/useSaveButtonPosition";
|
|
40
40
|
import { FormCache } from "./components/FormCache/FormCache";
|
|
41
41
|
import { useAtlantisFormContext } from "./context/AtlantisFormContext";
|
|
42
|
-
import { InputAccessoriesProvider
|
|
42
|
+
import { InputAccessoriesProvider } from "../InputText";
|
|
43
43
|
import { tokens } from "../utils/design";
|
|
44
44
|
import { ErrorMessageProvider } from "../ErrorMessageWrapper";
|
|
45
45
|
export function Form(_a) {
|
|
@@ -49,12 +49,11 @@ export function Form(_a) {
|
|
|
49
49
|
React.createElement(ErrorMessageProvider, null, child)));
|
|
50
50
|
}
|
|
51
51
|
// eslint-disable-next-line max-statements
|
|
52
|
-
function InternalForm({ children, onBeforeSubmit, onSubmit, onSubmitError, onSubmitSuccess, bannerErrors, bannerMessages, initialValues, mode = "onTouched", reValidateMode = "onChange", formRef, saveButtonLabel, renderStickySection, localCacheKey, localCacheExclude, localCacheId, secondaryActions, saveButtonOffset, showStickySaveButton = false, renderFooter, UNSAFE_allowDiscardLocalCacheWhenOffline, }) {
|
|
52
|
+
function InternalForm({ children, onBeforeSubmit, onSubmit, onSubmitError, onSubmitSuccess, bannerErrors, bannerMessages, initialValues, mode = "onTouched", reValidateMode = "onChange", formRef, saveButtonLabel, renderStickySection, localCacheKey, localCacheExclude, localCacheId, secondaryActions, saveButtonOffset, showStickySaveButton = false, disableKeyboardAwareScroll = false, renderFooter, UNSAFE_allowDiscardLocalCacheWhenOffline, }) {
|
|
53
53
|
var _a;
|
|
54
54
|
const { scrollViewRef, bottomViewRef, scrollToTop } = useFormViewRefs();
|
|
55
55
|
const [saveButtonHeight, setSaveButtonHeight] = useState(0);
|
|
56
56
|
const [messageBannerHeight, setMessageBannerHeight] = useState(0);
|
|
57
|
-
const { setIsScrolling } = useInputAccessoriesContext();
|
|
58
57
|
const { formMethods, handleSubmit, isSubmitting, removeListenerRef, setLocalCache, } = useInternalForm({
|
|
59
58
|
mode,
|
|
60
59
|
reValidateMode,
|
|
@@ -82,11 +81,8 @@ function InternalForm({ children, onBeforeSubmit, onSubmit, onSubmitError, onSub
|
|
|
82
81
|
keyboardScreenY,
|
|
83
82
|
});
|
|
84
83
|
const [isSecondaryActionLoading, setIsSecondaryActionLoading] = useState(false);
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
calculatedKeyboardHeight: keyboardHeight - (paddingBottom + KEYBOARD_SAVE_BUTTON_DISTANCE),
|
|
88
|
-
};
|
|
89
|
-
}, [paddingBottom, keyboardHeight]);
|
|
84
|
+
const extraViewHeight = paddingBottom + KEYBOARD_SAVE_BUTTON_DISTANCE;
|
|
85
|
+
const calculatedKeyboardHeight = keyboardHeight - extraViewHeight;
|
|
90
86
|
useScrollToError({
|
|
91
87
|
formState: formMethods.formState,
|
|
92
88
|
refNode: findNodeHandle(scrollViewRef.current),
|
|
@@ -104,6 +100,9 @@ function InternalForm({ children, onBeforeSubmit, onSubmit, onSubmitError, onSub
|
|
|
104
100
|
onKeyboardDidShow: handleKeyboardShow,
|
|
105
101
|
},
|
|
106
102
|
});
|
|
103
|
+
const onLayout = (event) => {
|
|
104
|
+
setMessageBannerHeight(event.nativeEvent.layout.height);
|
|
105
|
+
};
|
|
107
106
|
const styles = useStyles();
|
|
108
107
|
const { edgeToEdgeEnabled } = useAtlantisFormContext();
|
|
109
108
|
return (React.createElement(FormProvider, Object.assign({}, formMethods),
|
|
@@ -111,17 +110,11 @@ function InternalForm({ children, onBeforeSubmit, onSubmit, onSubmitError, onSub
|
|
|
111
110
|
(isSubmitting || isSecondaryActionLoading) && React.createElement(FormMask, null),
|
|
112
111
|
React.createElement(FormCache, { localCacheKey: localCacheKey, localCacheExclude: localCacheExclude, setLocalCache: setLocalCache }),
|
|
113
112
|
React.createElement(FormBody, { keyboardHeight: calculateSaveButtonOffset(), submit: handleSubmit(internalSubmit), isFormSubmitting: isSubmitting, saveButtonLabel: saveButtonLabel, shouldRenderActionBar: saveButtonPosition === "sticky", renderStickySection: renderStickySection, secondaryActions: secondaryActions, setSecondaryActionLoading: setIsSecondaryActionLoading, setSaveButtonHeight: setSaveButtonHeight, saveButtonOffset: saveButtonOffset },
|
|
114
|
-
React.createElement(KeyboardAwareScrollView, Object.assign({ enableResetScrollToCoords: false, enableAutomaticScroll:
|
|
115
|
-
setIsScrolling(true);
|
|
116
|
-
}, onScrollEndDrag: () => {
|
|
117
|
-
setIsScrolling(false);
|
|
118
|
-
} }),
|
|
113
|
+
React.createElement(KeyboardAwareScrollView, Object.assign({ enableResetScrollToCoords: false, enableAutomaticScroll: !disableKeyboardAwareScroll, enableOnAndroid: edgeToEdgeEnabled, keyboardOpeningTime: Platform.OS === "ios" ? tokens["timing-slowest"] : 0, keyboardShouldPersistTaps: "handled", ref: scrollViewRef }, keyboardProps, { extraHeight: headerHeight, extraScrollHeight: edgeToEdgeEnabled ? tokens["space-large"] : 0, contentContainerStyle: !keyboardHeight && styles.scrollContentContainer }),
|
|
119
114
|
React.createElement(View, { onLayout: ({ nativeEvent }) => {
|
|
120
115
|
setFormContentHeight(nativeEvent.layout.height);
|
|
121
116
|
} },
|
|
122
|
-
React.createElement(View, { onLayout:
|
|
123
|
-
setMessageBannerHeight(nativeEvent.layout.height);
|
|
124
|
-
} },
|
|
117
|
+
React.createElement(View, { onLayout: onLayout },
|
|
125
118
|
React.createElement(FormMessageBanner, { bannerMessages: bannerMessages }),
|
|
126
119
|
React.createElement(FormErrorBanner, { networkError: bannerErrors === null || bannerErrors === void 0 ? void 0 : bannerErrors.networkError, bannerError: bannerErrors === null || bannerErrors === void 0 ? void 0 : bannerErrors.bannerError })),
|
|
127
120
|
React.createElement(View, { style: styles.formChildContainer },
|
|
@@ -40,7 +40,7 @@ function InputTextInternal({ invalid, disabled, readonly = false, name, placehol
|
|
|
40
40
|
placeholderTextColor: "transparent",
|
|
41
41
|
}));
|
|
42
42
|
const _name = name !== null && name !== void 0 ? name : field.name;
|
|
43
|
-
const { inputAccessoryID, register, unregister, setFocusedInput, canFocusNext,
|
|
43
|
+
const { inputAccessoryID, register, unregister, setFocusedInput, canFocusNext, onFocusNext, } = useInputAccessoriesContext();
|
|
44
44
|
useEffect(() => {
|
|
45
45
|
_name &&
|
|
46
46
|
register(_name, () => {
|
|
@@ -75,40 +75,8 @@ function InputTextInternal({ invalid, disabled, readonly = false, name, placehol
|
|
|
75
75
|
}
|
|
76
76
|
const styles = useStyles();
|
|
77
77
|
const commonInputStyles = useCommonInputStyles();
|
|
78
|
-
// const { headerHeight, windowHeight } = useScreenInformation();
|
|
79
|
-
// State to track if the InputText component can fully fit on screen
|
|
80
|
-
// (i.e., it's completely visible). Use this state to handle visibility issues.
|
|
81
|
-
// const [canFullyFitOnScreen, setCanFullyFitOnScreen] = useState(true);
|
|
82
78
|
return (React.createElement(InputFieldWrapper, { prefix: prefix, suffix: suffix, hasValue: hasValue, placeholderMode: placeholderMode, assistiveText: assistiveText, focused: focused, error: error, invalid: invalid, placeholder: placeholder, disabled: disabled, onClear: handleClear, showClearAction: showClear, styleOverride: styleOverride, toolbar: toolbar, toolbarVisibility: toolbarVisibility, loading: loading, loadingType: loadingType },
|
|
83
|
-
React.createElement(TextInput
|
|
84
|
-
// onLayout={(event: LayoutChangeEvent) => {
|
|
85
|
-
// event.target?.measureInWindow((_, y, __, height) => {
|
|
86
|
-
// // Check if component can't fully fit on screen (height only)
|
|
87
|
-
// // Account for headerHeight at the top of the screen and buffer zone
|
|
88
|
-
// const visibleTop = headerHeight + KEYBOARD_AWARE_DETECTION_BUFFER; // Top of visible area (below header) with buffer
|
|
89
|
-
// const visibleBottom =
|
|
90
|
-
// windowHeight - KEYBOARD_AWARE_DETECTION_BUFFER; // Bottom of visible area with buffer
|
|
91
|
-
// const isOffScreen =
|
|
92
|
-
// y < visibleTop || // Top edge is behind or above the header (with buffer)
|
|
93
|
-
// y + height > visibleBottom; // Bottom edge is below the window (with buffer)
|
|
94
|
-
// setCanFullyFitOnScreen(!isOffScreen);
|
|
95
|
-
// });
|
|
96
|
-
// }}
|
|
97
|
-
, Object.assign({
|
|
98
|
-
// onLayout={(event: LayoutChangeEvent) => {
|
|
99
|
-
// event.target?.measureInWindow((_, y, __, height) => {
|
|
100
|
-
// // Check if component can't fully fit on screen (height only)
|
|
101
|
-
// // Account for headerHeight at the top of the screen and buffer zone
|
|
102
|
-
// const visibleTop = headerHeight + KEYBOARD_AWARE_DETECTION_BUFFER; // Top of visible area (below header) with buffer
|
|
103
|
-
// const visibleBottom =
|
|
104
|
-
// windowHeight - KEYBOARD_AWARE_DETECTION_BUFFER; // Bottom of visible area with buffer
|
|
105
|
-
// const isOffScreen =
|
|
106
|
-
// y < visibleTop || // Top edge is behind or above the header (with buffer)
|
|
107
|
-
// y + height > visibleBottom; // Bottom edge is below the window (with buffer)
|
|
108
|
-
// setCanFullyFitOnScreen(!isOffScreen);
|
|
109
|
-
// });
|
|
110
|
-
// }}
|
|
111
|
-
inputAccessoryViewID: inputAccessoryID || undefined, testID: testID, autoCapitalize: autoCapitalize, autoCorrect: autoCorrect, spellCheck: spellCheck, style: [
|
|
79
|
+
React.createElement(TextInput, Object.assign({ inputAccessoryViewID: inputAccessoryID || undefined, testID: testID, autoCapitalize: autoCapitalize, autoCorrect: autoCorrect, spellCheck: spellCheck, style: [
|
|
112
80
|
commonInputStyles.input,
|
|
113
81
|
styles.inputPaddingTop,
|
|
114
82
|
!miniLabelActive && commonInputStyles.inputEmpty,
|
|
@@ -121,17 +89,7 @@ function InputTextInternal({ invalid, disabled, readonly = false, name, placehol
|
|
|
121
89
|
styles.multilineWithoutMiniLabel,
|
|
122
90
|
styleOverride === null || styleOverride === void 0 ? void 0 : styleOverride.inputText,
|
|
123
91
|
loading && loadingType === "glimmer" && { color: "transparent" },
|
|
124
|
-
],
|
|
125
|
-
// Prevent focus during scroll for multiline inputs to avoid
|
|
126
|
-
// the input focusing when the user is trying to scroll the form
|
|
127
|
-
readOnly: readonly || (multiline && isScrolling && !focused),
|
|
128
|
-
// readOnly={readonly}
|
|
129
|
-
editable: !disabled, keyboardType: keyboard, value: inputTransform(internalValue), autoFocus: autoFocus, autoComplete: autoComplete, multiline: multiline,
|
|
130
|
-
// Makes sure it doesn't jump to the top of the screen when the keyboard is shown and a new line is added.
|
|
131
|
-
// State for tracking if the input should be scrollable.
|
|
132
|
-
// This is tech debt related to an issue where keyboard aware scrollview doesn't work if `scrollEnabled` is true. However,
|
|
133
|
-
// when `scrollEnabled` is false it causes an issue where super long text inputs will jump to the top when a new line is added to the bottom of the input.
|
|
134
|
-
scrollEnabled: Platform.OS === "ios", textContentType: textContentType, onChangeText: handleChangeText, onSubmitEditing: handleOnSubmitEditing, returnKeyType: returnKeyType, blurOnSubmit: shouldBlurOnSubmit, accessibilityLabel: accessibilityLabel || placeholder, accessibilityHint: accessibilityHint, accessibilityState: { busy: loading }, secureTextEntry: secureTextEntry }, androidA11yProps, { onFocus: event => {
|
|
92
|
+
], readOnly: readonly, editable: !disabled, keyboardType: keyboard, value: inputTransform(internalValue), autoFocus: autoFocus, autoComplete: autoComplete, multiline: multiline, scrollEnabled: false, textContentType: textContentType, onChangeText: handleChangeText, onSubmitEditing: handleOnSubmitEditing, returnKeyType: returnKeyType, blurOnSubmit: shouldBlurOnSubmit, accessibilityLabel: accessibilityLabel || placeholder, accessibilityHint: accessibilityHint, accessibilityState: { busy: loading }, secureTextEntry: secureTextEntry }, androidA11yProps, { onFocus: event => {
|
|
135
93
|
_name && setFocusedInput(_name);
|
|
136
94
|
setFocused(true);
|
|
137
95
|
onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
|
|
@@ -10,8 +10,6 @@ const inputAccessoriesContextDefaultValues = {
|
|
|
10
10
|
onFocusNext: () => undefined,
|
|
11
11
|
onFocusPrevious: () => undefined,
|
|
12
12
|
setFocusedInput: () => undefined,
|
|
13
|
-
isScrolling: false,
|
|
14
|
-
setIsScrolling: () => undefined,
|
|
15
13
|
};
|
|
16
14
|
export const InputAccessoriesContext = createContext(inputAccessoriesContextDefaultValues);
|
|
17
15
|
export function useInputAccessoriesContext() {
|
|
@@ -5,7 +5,7 @@ import { InputAccessoriesContext } from "./InputAccessoriesContext";
|
|
|
5
5
|
import { useStyles } from "./InputAccessoriesProvider.style";
|
|
6
6
|
export function InputAccessoriesProvider({ children, }) {
|
|
7
7
|
const inputAccessoryID = useRef(v4()).current;
|
|
8
|
-
const { focusedInput, setFocusedInput, canFocusNext, canFocusPrevious, elements, setElements, previousKey, nextKey,
|
|
8
|
+
const { focusedInput, setFocusedInput, canFocusNext, canFocusPrevious, elements, setElements, previousKey, nextKey, } = useInputAccessoriesProviderState();
|
|
9
9
|
const colorScheme = useColorScheme();
|
|
10
10
|
const styles = useStyles();
|
|
11
11
|
return (React.createElement(InputAccessoriesContext.Provider, { value: {
|
|
@@ -19,8 +19,6 @@ export function InputAccessoriesProvider({ children, }) {
|
|
|
19
19
|
onFocusNext,
|
|
20
20
|
onFocusPrevious,
|
|
21
21
|
setFocusedInput,
|
|
22
|
-
isScrolling,
|
|
23
|
-
setIsScrolling,
|
|
24
22
|
} },
|
|
25
23
|
children,
|
|
26
24
|
Platform.OS === "ios" && (React.createElement(InputAccessoryView, { nativeID: inputAccessoryID },
|
|
@@ -51,7 +49,6 @@ function useInputAccessoriesProviderState() {
|
|
|
51
49
|
const [canFocusNext, setCanFocusNext] = useState(false);
|
|
52
50
|
const [canFocusPrevious, setCanFocusPrevious] = useState(false);
|
|
53
51
|
const [elements, setElements] = useState({});
|
|
54
|
-
const [isScrolling, setIsScrolling] = useState(false);
|
|
55
52
|
const keys = Object.keys(elements);
|
|
56
53
|
const selectedIndex = keys.findIndex(key => key === focusedInput);
|
|
57
54
|
const nextKey = keys[selectedIndex + 1];
|
|
@@ -71,7 +68,5 @@ function useInputAccessoriesProviderState() {
|
|
|
71
68
|
setCanFocusPrevious,
|
|
72
69
|
elements,
|
|
73
70
|
setElements,
|
|
74
|
-
isScrolling,
|
|
75
|
-
setIsScrolling,
|
|
76
71
|
};
|
|
77
72
|
}
|
package/dist/src/hooks/index.js
CHANGED