@react-native-ama/forms 1.2.0 → 2.0.0-beta.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/Form.d.ts +5 -2
- package/dist/components/Form.js +14 -31
- package/dist/components/FormSubmit.d.ts +7 -9
- package/dist/components/FormSubmit.js +2 -14
- package/dist/components/TextInput.d.ts +36 -4
- package/dist/components/TextInput.js +20 -73
- package/dist/hooks/useFocus.d.ts +4 -0
- package/dist/hooks/useFocus.js +69 -0
- package/dist/hooks/useFormField.d.ts +1 -7
- package/dist/hooks/useFormField.js +32 -25
- package/dist/hooks/useFormSubmit.d.ts +4 -0
- package/dist/hooks/useFormSubmit.js +14 -0
- package/dist/hooks/useTextInput.d.ts +59 -231
- package/dist/hooks/useTextInput.js +2 -37
- package/dist/index.d.ts +10 -13
- package/dist/index.js +3 -8
- package/dist/utils/checkFocusTrap.d.ts +8 -0
- package/dist/utils/checkFocusTrap.js +30 -0
- package/package.json +59 -18
- package/src/components/Form.test.tsx +63 -70
- package/src/components/Form.tsx +28 -52
- package/src/components/FormField.test.tsx +32 -16
- package/src/components/FormField.tsx +0 -1
- package/src/components/FormSubmit.test.tsx +17 -55
- package/src/components/FormSubmit.tsx +9 -36
- package/src/components/TextInput.test.tsx +83 -397
- package/src/components/TextInput.tsx +41 -109
- package/src/hooks/useFocus.test.ts +130 -0
- package/src/hooks/useFocus.ts +62 -0
- package/src/hooks/useFormField.test.tsx +183 -78
- package/src/hooks/useFormField.ts +36 -28
- package/src/hooks/useFormSubmit.test.tsx +18 -0
- package/src/hooks/useFormSubmit.ts +17 -0
- package/src/hooks/useTextInput.ts +10 -55
- package/src/index.ts +15 -20
- package/src/utils/checkFocusTrap.test.ts +80 -0
- package/src/utils/checkFocusTrap.ts +40 -0
- package/dist/components/FormSwitch.d.ts +0 -4
- package/dist/components/FormSwitch.js +0 -15
- package/src/components/FormSwitch.tsx +0 -17
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
export type FormProps = React.PropsWithChildren<{
|
|
3
3
|
onSubmit: () => boolean | Promise<boolean>;
|
|
4
|
-
ref?: React.RefObject<FormActions>;
|
|
5
4
|
}>;
|
|
6
5
|
export type FormActions = {
|
|
7
6
|
focusFirstInvalidField: () => void;
|
|
8
7
|
focusFieldAt: (fieldNumber: number) => void;
|
|
9
8
|
};
|
|
10
|
-
export declare const Form: React.ForwardRefExoticComponent<
|
|
9
|
+
export declare const Form: React.ForwardRefExoticComponent<{
|
|
10
|
+
onSubmit: () => boolean | Promise<boolean>;
|
|
11
|
+
} & {
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
} & React.RefAttributes<FormActions>>;
|
|
11
14
|
export type FormContextValue = {
|
|
12
15
|
refs?: FormRef[];
|
|
13
16
|
submitForm: () => Promise<void>;
|
package/dist/components/Form.js
CHANGED
|
@@ -33,14 +33,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
33
33
|
};
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
35
|
exports.useForm = exports.FormContext = exports.Form = void 0;
|
|
36
|
-
const core_1 = require("@react-native-ama/core");
|
|
37
|
-
const internal_1 = require("@react-native-ama/internal");
|
|
38
36
|
const React = __importStar(require("react"));
|
|
39
37
|
const react_native_1 = require("react-native");
|
|
38
|
+
const useFocus_1 = require("../hooks/useFocus");
|
|
40
39
|
exports.Form = React.forwardRef(({ children, onSubmit }, ref) => {
|
|
41
40
|
const refs = React.useRef([]);
|
|
42
|
-
const { setFocus } = (0,
|
|
43
|
-
const checks = __DEV__ ? core_1.useChecks === null || core_1.useChecks === void 0 ? void 0 : (0, core_1.useChecks)() : undefined;
|
|
41
|
+
const { setFocus } = (0, useFocus_1.useFocus)();
|
|
44
42
|
const focusField = React.useCallback((nextField) => {
|
|
45
43
|
var _a, _b, _c;
|
|
46
44
|
/**
|
|
@@ -54,58 +52,40 @@ exports.Form = React.forwardRef(({ children, onSubmit }, ref) => {
|
|
|
54
52
|
((_c = nextRefElement === null || nextRefElement === void 0 ? void 0 : nextRefElement.current) === null || _c === void 0 ? void 0 : _c.focus) &&
|
|
55
53
|
(nextField === null || nextField === void 0 ? void 0 : nextField.hasFocusCallback) &&
|
|
56
54
|
(nextField === null || nextField === void 0 ? void 0 : nextField.isEditable);
|
|
57
|
-
__DEV__ &&
|
|
58
|
-
nextRefElement == null &&
|
|
59
|
-
(checks === null || checks === void 0 ? void 0 : checks.logResult('nextRefElement', {
|
|
60
|
-
message: 'No next field found. Make sure you wrapped your form inside the <Form /> component',
|
|
61
|
-
rule: 'NO_UNDEFINED',
|
|
62
|
-
}));
|
|
63
55
|
if (callFocus) {
|
|
64
56
|
/**
|
|
65
57
|
* On some apps, if we call focus immediately and the field is already focused we lose the focus.
|
|
66
58
|
* Same happens if we do not call `focus` if the field is already focused.
|
|
67
59
|
*/
|
|
68
|
-
const timeoutValue =
|
|
60
|
+
const timeoutValue = isFocused(nextRefElement.current) ? 50 : 0;
|
|
69
61
|
setTimeout(() => {
|
|
70
62
|
var _a;
|
|
71
63
|
(_a = nextRefElement === null || nextRefElement === void 0 ? void 0 : nextRefElement.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
72
|
-
__DEV__ &&
|
|
73
|
-
nextRefElement &&
|
|
74
|
-
(checks === null || checks === void 0 ? void 0 : checks.checkFocusTrap({
|
|
75
|
-
ref: nextRefElement,
|
|
76
|
-
shouldHaveFocus: true,
|
|
77
|
-
}));
|
|
78
64
|
}, timeoutValue);
|
|
79
65
|
}
|
|
80
66
|
else if (nextRefElement === null || nextRefElement === void 0 ? void 0 : nextRefElement.current) {
|
|
81
67
|
setFocus(nextRefElement === null || nextRefElement === void 0 ? void 0 : nextRefElement.current);
|
|
82
68
|
}
|
|
83
|
-
}, [
|
|
84
|
-
const focusFieldAt =
|
|
69
|
+
}, [setFocus]);
|
|
70
|
+
const focusFieldAt = (position) => {
|
|
85
71
|
react_native_1.InteractionManager.runAfterInteractions(() => {
|
|
86
72
|
setTimeout(() => {
|
|
87
73
|
const fieldWithError = refs.current[position];
|
|
88
74
|
focusField(fieldWithError);
|
|
89
75
|
}, 0);
|
|
90
76
|
});
|
|
91
|
-
}
|
|
92
|
-
const focusFirstInvalidField =
|
|
93
|
-
const fieldWithError = (refs.current || []).findIndex(fieldRef => fieldRef.hasValidation && fieldRef.hasError);
|
|
94
|
-
__DEV__ &&
|
|
95
|
-
fieldWithError == null &&
|
|
96
|
-
(checks === null || checks === void 0 ? void 0 : checks.logResult('Form', {
|
|
97
|
-
message: 'The form validation has failed, but no component with error was found',
|
|
98
|
-
rule: 'NO_UNDEFINED',
|
|
99
|
-
}));
|
|
77
|
+
};
|
|
78
|
+
const focusFirstInvalidField = () => {
|
|
79
|
+
const fieldWithError = (refs.current || []).findIndex((fieldRef) => fieldRef.hasValidation && fieldRef.hasError);
|
|
100
80
|
focusFieldAt(fieldWithError);
|
|
101
|
-
}
|
|
102
|
-
const submitForm =
|
|
81
|
+
};
|
|
82
|
+
const submitForm = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
83
|
const isValid = yield onSubmit();
|
|
104
84
|
if (isValid) {
|
|
105
85
|
return;
|
|
106
86
|
}
|
|
107
87
|
focusFirstInvalidField();
|
|
108
|
-
})
|
|
88
|
+
});
|
|
109
89
|
React.useImperativeHandle(ref, () => ({
|
|
110
90
|
focusFirstInvalidField,
|
|
111
91
|
focusFieldAt,
|
|
@@ -133,3 +113,6 @@ const useForm = ({ suppressError } = { suppressError: false }) => {
|
|
|
133
113
|
return context;
|
|
134
114
|
};
|
|
135
115
|
exports.useForm = useForm;
|
|
116
|
+
const isFocused = (input) => {
|
|
117
|
+
return input === null || input === void 0 ? void 0 : input.isFocused();
|
|
118
|
+
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}>;
|
|
10
|
-
export declare const FormSubmit: (props: FormSubmitProps) => React.JSX.Element;
|
|
2
|
+
export type FormSubmitRenderProps = {
|
|
3
|
+
onPress: () => Promise<void>;
|
|
4
|
+
};
|
|
5
|
+
export type FormSubmitProps = {
|
|
6
|
+
children: (props: FormSubmitRenderProps) => React.ReactNode;
|
|
7
|
+
};
|
|
8
|
+
export declare const FormSubmit: ({ children }: FormSubmitProps) => React.JSX.Element;
|
|
@@ -4,22 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.FormSubmit = void 0;
|
|
7
|
-
const core_1 = require("@react-native-ama/core");
|
|
8
|
-
const core_2 = require("@react-native-ama/core");
|
|
9
7
|
const react_1 = __importDefault(require("react"));
|
|
10
|
-
const react_native_1 = require("react-native");
|
|
11
8
|
const Form_1 = require("../components/Form");
|
|
12
|
-
const FormSubmit = (
|
|
9
|
+
const FormSubmit = ({ children }) => {
|
|
13
10
|
const { submitForm } = (0, Form_1.useForm)();
|
|
14
|
-
|
|
15
|
-
return (<react_native_1.Pressable accessibilityRole="button" pointerEvents="box-only" // prevent event propagation to children eg Pressable
|
|
16
|
-
{...props} onPress={submitForm}>
|
|
17
|
-
{isScreenReaderEnabled ? (<FormSubmitForScreenReader children={props.children}/>) : (props.children)}
|
|
18
|
-
</react_native_1.Pressable>);
|
|
11
|
+
return <>{children({ onPress: submitForm })}</>;
|
|
19
12
|
};
|
|
20
13
|
exports.FormSubmit = FormSubmit;
|
|
21
|
-
const FormSubmitForScreenReader = ({ children, }) => {
|
|
22
|
-
return (<core_2.HideChildrenFromAccessibilityTree>
|
|
23
|
-
{children}
|
|
24
|
-
</core_2.HideChildrenFromAccessibilityTree>);
|
|
25
|
-
};
|
|
@@ -1,13 +1,45 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { TextInput as RNTextInput, TextInputProps as RNTextInputProps } from 'react-native';
|
|
3
3
|
import { UseTextInput } from '../hooks/useTextInput';
|
|
4
|
-
export
|
|
5
|
-
|
|
4
|
+
export declare const a11yProps: Pick<TextInputProps, 'accessibilityElementsHidden' | 'importantForAccessibility'>;
|
|
5
|
+
type A11yProps = typeof a11yProps;
|
|
6
|
+
type TextInputBaseProps = Omit<RNTextInputProps, 'accessibilityLabel' | 'aria-label'> & Omit<UseTextInput, 'required' | 'accessibilityLabel'> & {
|
|
6
7
|
labelPosition?: 'beforeInput' | 'afterInput';
|
|
7
8
|
nextFormField?: React.RefObject<RNTextInput>;
|
|
8
9
|
id?: string;
|
|
9
10
|
nextFieldId?: string;
|
|
10
|
-
errorComponent?: JSX.Element;
|
|
11
11
|
errorPosition?: 'belowLabel' | 'afterInput';
|
|
12
|
+
renderLabel?: (a11yProps: A11yProps) => React.ReactNode;
|
|
13
|
+
renderError?: (a11yProps: A11yProps) => React.ReactNode;
|
|
12
14
|
};
|
|
13
|
-
export
|
|
15
|
+
export type TextInputProps = (TextInputBaseProps & {
|
|
16
|
+
accessibilityLabel: string;
|
|
17
|
+
'aria-label'?: never;
|
|
18
|
+
}) | (TextInputBaseProps & {
|
|
19
|
+
'aria-label': string;
|
|
20
|
+
accessibilityLabel?: never;
|
|
21
|
+
});
|
|
22
|
+
export declare const TextInput: React.ForwardRefExoticComponent<(Omit<Omit<RNTextInputProps, "accessibilityLabel" | "aria-label"> & Omit<UseTextInput, "accessibilityLabel" | "required"> & {
|
|
23
|
+
labelPosition?: "beforeInput" | "afterInput" | undefined;
|
|
24
|
+
nextFormField?: React.RefObject<RNTextInput> | undefined;
|
|
25
|
+
id?: string | undefined;
|
|
26
|
+
nextFieldId?: string | undefined;
|
|
27
|
+
errorPosition?: "afterInput" | "belowLabel" | undefined;
|
|
28
|
+
renderLabel?: ((a11yProps: A11yProps) => React.ReactNode) | undefined;
|
|
29
|
+
renderError?: ((a11yProps: A11yProps) => React.ReactNode) | undefined;
|
|
30
|
+
} & {
|
|
31
|
+
accessibilityLabel: string;
|
|
32
|
+
'aria-label'?: undefined;
|
|
33
|
+
}, "ref"> | Omit<Omit<RNTextInputProps, "accessibilityLabel" | "aria-label"> & Omit<UseTextInput, "accessibilityLabel" | "required"> & {
|
|
34
|
+
labelPosition?: "beforeInput" | "afterInput" | undefined;
|
|
35
|
+
nextFormField?: React.RefObject<RNTextInput> | undefined;
|
|
36
|
+
id?: string | undefined;
|
|
37
|
+
nextFieldId?: string | undefined;
|
|
38
|
+
errorPosition?: "afterInput" | "belowLabel" | undefined;
|
|
39
|
+
renderLabel?: ((a11yProps: A11yProps) => React.ReactNode) | undefined;
|
|
40
|
+
renderError?: ((a11yProps: A11yProps) => React.ReactNode) | undefined;
|
|
41
|
+
} & {
|
|
42
|
+
'aria-label': string;
|
|
43
|
+
accessibilityLabel?: undefined;
|
|
44
|
+
}, "ref">) & React.RefAttributes<RNTextInput>>;
|
|
45
|
+
export {};
|
|
@@ -34,88 +34,35 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
34
34
|
return t;
|
|
35
35
|
};
|
|
36
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
-
exports.TextInput = void 0;
|
|
38
|
-
const core_1 = require("@react-native-ama/core");
|
|
39
|
-
const core_2 = require("@react-native-ama/core");
|
|
40
|
-
const internal_1 = require("@react-native-ama/internal");
|
|
41
|
-
const internal_2 = require("@react-native-ama/internal");
|
|
37
|
+
exports.TextInput = exports.a11yProps = void 0;
|
|
42
38
|
const React = __importStar(require("react"));
|
|
43
39
|
const react_native_1 = require("react-native");
|
|
44
40
|
const useTextInput_1 = require("../hooks/useTextInput");
|
|
41
|
+
exports.a11yProps = {
|
|
42
|
+
importantForAccessibility: 'no-hide-descendants',
|
|
43
|
+
accessibilityElementsHidden: true,
|
|
44
|
+
};
|
|
45
|
+
const labelA11yProps = {
|
|
46
|
+
importantForAccessibility: 'no-hide-descendants',
|
|
47
|
+
accessibilityElementsHidden: true,
|
|
48
|
+
};
|
|
45
49
|
exports.TextInput = React.forwardRef((_a, forwardedRef) => {
|
|
46
50
|
var _b;
|
|
47
|
-
var {
|
|
51
|
+
var { nextFormField, id, nextFieldId, accessibilityHint, hasError, hasValidation, errorMessage, accessibilityLabel, labelPosition = 'beforeInput', errorPosition = 'afterInput', renderLabel, renderError } = _a, rest = __rest(_a, ["nextFormField", "id", "nextFieldId", "accessibilityHint", "hasError", "hasValidation", "errorMessage", "accessibilityLabel", "labelPosition", "errorPosition", "renderLabel", "renderError"]);
|
|
48
52
|
const inputRef = React.useRef(null);
|
|
49
53
|
React.useImperativeHandle(forwardedRef, () => inputRef.current);
|
|
50
|
-
const showLabelBeforeInput = labelPosition === 'beforeInput';
|
|
51
|
-
const accessibilityLabel = React.useMemo(() => (0, internal_2.maybeGenerateStringFromElement)(labelComponent, rest.accessibilityLabel), [labelComponent, rest.accessibilityLabel]);
|
|
52
54
|
const textInputProps = (0, useTextInput_1.useTextInput)(Object.assign(Object.assign({}, rest), { ref: inputRef, id,
|
|
53
55
|
nextFieldId, nextFormFieldRef: nextFormField, hasError,
|
|
54
56
|
hasValidation,
|
|
55
|
-
errorMessage, required: false, accessibilityLabel }));
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
properties: { accessibilityLabel },
|
|
66
|
-
property: 'accessibilityLabel',
|
|
67
|
-
rule: 'NO_ACCESSIBILITY_LABEL',
|
|
68
|
-
}));
|
|
69
|
-
__DEV__ &&
|
|
70
|
-
(accessibilityLabel === null || accessibilityLabel === void 0 ? void 0 : accessibilityLabel.trim()) === '' &&
|
|
71
|
-
(checks === null || checks === void 0 ? void 0 : checks.logResult('NO_ACCESSIBILITY_LABEL', {
|
|
72
|
-
rule: 'NO_ACCESSIBILITY_LABEL',
|
|
73
|
-
message: 'No accessibility label provided',
|
|
74
|
-
}));
|
|
75
|
-
__DEV__ &&
|
|
76
|
-
hasValidation &&
|
|
77
|
-
(checks === null || checks === void 0 ? void 0 : checks.noUndefinedProperty({
|
|
78
|
-
// @ts-ignore
|
|
79
|
-
properties: { errorComponent },
|
|
80
|
-
property: 'errorComponent',
|
|
81
|
-
rule: 'NO_FORM_ERROR',
|
|
82
|
-
}));
|
|
83
|
-
const style = __DEV__ && // @ts-ignore
|
|
84
|
-
(internal_1.applyStyle === null || internal_1.applyStyle === void 0 ? void 0 : (0, internal_1.applyStyle)({
|
|
85
|
-
// @ts-ignore
|
|
86
|
-
style: (textInputProps === null || textInputProps === void 0 ? void 0 : textInputProps.style) || {},
|
|
87
|
-
debugStyle: checks === null || checks === void 0 ? void 0 : checks.debugStyle,
|
|
88
|
-
}));
|
|
89
|
-
const accessibilityHiddenLabel = React.useMemo(() => (<core_1.HideChildrenFromAccessibilityTree>
|
|
90
|
-
{labelComponent}
|
|
91
|
-
</core_1.HideChildrenFromAccessibilityTree>), [labelComponent]);
|
|
92
|
-
const errorText = React.useMemo(() => {
|
|
93
|
-
return hasValidation && hasError
|
|
94
|
-
? (0, internal_2.maybeGenerateStringFromElement)(errorComponent, errorMessage)
|
|
95
|
-
: '';
|
|
96
|
-
}, [hasValidation, hasError, errorComponent, errorMessage]);
|
|
97
|
-
const renderError = () => {
|
|
98
|
-
return (<core_1.HideChildrenFromAccessibilityTree>
|
|
99
|
-
{errorComponent}
|
|
100
|
-
</core_1.HideChildrenFromAccessibilityTree>);
|
|
101
|
-
};
|
|
102
|
-
const fullAccessibilityHint = (_b = [accessibilityHint || '', errorText || '']
|
|
103
|
-
.filter(item => item.length > 0)) === null || _b === void 0 ? void 0 : _b.join(', ');
|
|
104
|
-
return __DEV__ ? (<>
|
|
105
|
-
{showLabelBeforeInput ? accessibilityHiddenLabel : null}
|
|
106
|
-
{hasError && errorPosition === 'belowLabel' ? renderError() : null}
|
|
107
|
-
<react_native_1.TextInput
|
|
108
|
-
// @ts-ignore
|
|
109
|
-
ref={inputRef} {...rest} {...textInputProps} style={style} accessibilityLabel={accessibilityLabel} accessibilityHint={fullAccessibilityHint}/>
|
|
110
|
-
{showLabelBeforeInput ? null : accessibilityHiddenLabel}
|
|
111
|
-
{hasError && errorPosition === 'afterInput' ? renderError() : null}
|
|
112
|
-
</>) : (<>
|
|
113
|
-
{showLabelBeforeInput ? accessibilityHiddenLabel : null}
|
|
114
|
-
{hasError && errorPosition === 'belowLabel' ? renderError() : null}
|
|
115
|
-
<react_native_1.TextInput
|
|
116
|
-
// @ts-ignore
|
|
117
|
-
ref={inputRef} {...rest} {...textInputProps} accessibilityLabel={accessibilityLabel} accessibilityHint={fullAccessibilityHint}/>
|
|
118
|
-
{showLabelBeforeInput ? null : accessibilityHiddenLabel}
|
|
119
|
-
{hasError && errorPosition === 'afterInput' ? renderError() : null}
|
|
57
|
+
errorMessage, required: false, accessibilityLabel: accessibilityLabel || (rest === null || rest === void 0 ? void 0 : rest['aria-label']) }));
|
|
58
|
+
const fullAccessibilityHint = (_b = [accessibilityHint, errorMessage]
|
|
59
|
+
.filter(Boolean)) === null || _b === void 0 ? void 0 : _b.join(', ');
|
|
60
|
+
const showError = hasError && renderError;
|
|
61
|
+
return (<>
|
|
62
|
+
{labelPosition === 'beforeInput' ? renderLabel === null || renderLabel === void 0 ? void 0 : renderLabel(labelA11yProps) : null}
|
|
63
|
+
{errorPosition === 'belowLabel' && showError ? renderError === null || renderError === void 0 ? void 0 : renderError(labelA11yProps) : null}
|
|
64
|
+
<react_native_1.TextInput ref={inputRef} {...rest} {...textInputProps} accessibilityLabel={accessibilityLabel !== null && accessibilityLabel !== void 0 ? accessibilityLabel : rest['aria-label']} accessibilityHint={fullAccessibilityHint}/>
|
|
65
|
+
{labelPosition === 'afterInput' ? renderLabel === null || renderLabel === void 0 ? void 0 : renderLabel(labelA11yProps) : null}
|
|
66
|
+
{errorPosition === 'afterInput' && showError ? renderError === null || renderError === void 0 ? void 0 : renderError(labelA11yProps) : null}
|
|
120
67
|
</>);
|
|
121
68
|
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.useFocus = void 0;
|
|
27
|
+
const React = __importStar(require("react"));
|
|
28
|
+
const react_native_1 = require("react-native");
|
|
29
|
+
const useFocus = (refComponent) => {
|
|
30
|
+
const setFocus = React.useCallback((component) => {
|
|
31
|
+
if (!component) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
react_native_1.InteractionManager.runAfterInteractions(() => {
|
|
35
|
+
try {
|
|
36
|
+
const elementId = (0, react_native_1.findNodeHandle)(component);
|
|
37
|
+
if (elementId) {
|
|
38
|
+
react_native_1.AccessibilityInfo.setAccessibilityFocus(elementId);
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
react_native_1.AccessibilityInfo.setAccessibilityFocus(elementId); //ISSUE: https://github.com/facebook/react-native/issues/30097
|
|
41
|
+
}, 100);
|
|
42
|
+
}
|
|
43
|
+
else if (__DEV__) {
|
|
44
|
+
console.warn(
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
`${SHELL_COLORS.BG_RED}AMA.${SHELL_COLORS.RESET} ${SHELL_COLORS.BLUE}useFocus${SHELL_COLORS.RESET}: ${SHELL_COLORS.YELLOW}Ref element not found${SHELL_COLORS.RESET}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
if (__DEV__) {
|
|
51
|
+
console.warn(
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
`${SHELL_COLORS.BG_RED}AMA.${SHELL_COLORS.RESET} ${SHELL_COLORS.BLUE}useFocus${SHELL_COLORS.RESET}: ${SHELL_COLORS.YELLOW}Error finding node handle${SHELL_COLORS.RESET} \n`, error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}, []);
|
|
58
|
+
React.useEffect(() => {
|
|
59
|
+
if (!refComponent) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
setFocus(refComponent.current);
|
|
63
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
64
|
+
}, [refComponent]);
|
|
65
|
+
return {
|
|
66
|
+
setFocus,
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
exports.useFocus = useFocus;
|
|
@@ -14,14 +14,8 @@ export type UseFormField = {
|
|
|
14
14
|
errorMessage?: string;
|
|
15
15
|
suppressError?: boolean;
|
|
16
16
|
};
|
|
17
|
-
export declare const useFormField: ({ ref, hasFocusCallback, id, nextFieldId, nextFormFieldRef, hasValidation, hasError, accessibilityHint, errorMessage, editable, suppressError,
|
|
18
|
-
focusNextFormField: () => void;
|
|
19
|
-
isLastField: () => boolean;
|
|
20
|
-
style: any;
|
|
21
|
-
accessibilityHint: string;
|
|
22
|
-
} | {
|
|
17
|
+
export declare const useFormField: ({ ref, hasFocusCallback, id, nextFieldId, nextFormFieldRef, hasValidation, hasError, accessibilityHint, errorMessage, editable, suppressError, }: UseFormField) => {
|
|
23
18
|
focusNextFormField: () => void;
|
|
24
19
|
accessibilityHint: string;
|
|
25
20
|
isLastField: () => boolean;
|
|
26
|
-
style?: undefined;
|
|
27
21
|
};
|
|
@@ -4,36 +4,50 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.useFormField = void 0;
|
|
7
|
-
const core_1 = require("@react-native-ama/core");
|
|
8
|
-
const internal_1 = require("@react-native-ama/internal");
|
|
9
7
|
const react_1 = __importDefault(require("react"));
|
|
10
8
|
const react_native_1 = require("react-native");
|
|
11
9
|
const Form_1 = require("../components/Form");
|
|
12
|
-
const
|
|
10
|
+
const checkFocusTrap_1 = require("../utils/checkFocusTrap");
|
|
11
|
+
let _useAMAContext = null;
|
|
12
|
+
try {
|
|
13
|
+
_useAMAContext = require('@react-native-ama/core').useAMAContext;
|
|
14
|
+
}
|
|
15
|
+
catch (_a) {
|
|
16
|
+
// core is an optional peer — fall back to null
|
|
17
|
+
}
|
|
18
|
+
const getTrackError = () => {
|
|
19
|
+
var _a, _b;
|
|
20
|
+
try {
|
|
21
|
+
return (_b = (_a = _useAMAContext === null || _useAMAContext === void 0 ? void 0 : _useAMAContext()) === null || _a === void 0 ? void 0 : _a.trackError) !== null && _b !== void 0 ? _b : null;
|
|
22
|
+
}
|
|
23
|
+
catch (_c) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const useFormField = ({ ref, hasFocusCallback, id, nextFieldId, nextFormFieldRef, hasValidation, hasError, accessibilityHint, errorMessage, editable = true, suppressError, }) => {
|
|
13
28
|
const { refs, submitForm, focusField } = (0, Form_1.useForm)({ suppressError });
|
|
14
29
|
const fieldRef = react_1.default.useRef(ref);
|
|
15
|
-
const
|
|
30
|
+
const trackError = __DEV__ ? getTrackError() : null;
|
|
16
31
|
const getMyIndex = () => {
|
|
17
32
|
const allRefs = refs;
|
|
18
|
-
const item = allRefs.find(r => r.ref === fieldRef);
|
|
33
|
+
const item = allRefs.find((r) => r.ref === fieldRef);
|
|
19
34
|
return item ? allRefs.indexOf(item) : -1;
|
|
20
35
|
};
|
|
21
36
|
const focusNextFormField = () => {
|
|
22
|
-
var _a;
|
|
23
37
|
const isLastItem = isLastField();
|
|
24
38
|
if (isLastItem) {
|
|
25
39
|
react_native_1.Keyboard.dismiss();
|
|
26
40
|
submitForm();
|
|
27
41
|
return;
|
|
28
42
|
}
|
|
29
|
-
const currentField = refs[getMyIndex()];
|
|
30
|
-
focusField === null || focusField === void 0 ? void 0 : focusField(getNextFieldRef());
|
|
31
43
|
__DEV__ &&
|
|
32
|
-
|
|
33
|
-
(
|
|
34
|
-
ref:
|
|
44
|
+
hasFocusCallback &&
|
|
45
|
+
(checkFocusTrap_1.checkFocusTrap === null || checkFocusTrap_1.checkFocusTrap === void 0 ? void 0 : (0, checkFocusTrap_1.checkFocusTrap)({
|
|
46
|
+
ref: fieldRef.current,
|
|
35
47
|
shouldHaveFocus: false,
|
|
48
|
+
trackError: trackError !== null && trackError !== void 0 ? trackError : null,
|
|
36
49
|
}));
|
|
50
|
+
focusField === null || focusField === void 0 ? void 0 : focusField(getNextFieldRef());
|
|
37
51
|
};
|
|
38
52
|
const getNextFieldRef = () => {
|
|
39
53
|
const allRefs = refs || [];
|
|
@@ -43,7 +57,7 @@ const useFormField = ({ ref, hasFocusCallback, id, nextFieldId, nextFormFieldRef
|
|
|
43
57
|
};
|
|
44
58
|
}
|
|
45
59
|
else if (nextFieldId) {
|
|
46
|
-
return allRefs.find(item => item.id === nextFieldId);
|
|
60
|
+
return allRefs.find((item) => item.id === nextFieldId);
|
|
47
61
|
}
|
|
48
62
|
return allRefs[getMyIndex() + 1];
|
|
49
63
|
};
|
|
@@ -67,7 +81,7 @@ const useFormField = ({ ref, hasFocusCallback, id, nextFieldId, nextFormFieldRef
|
|
|
67
81
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
68
82
|
}, []);
|
|
69
83
|
react_1.default.useEffect(() => {
|
|
70
|
-
const myRefIndex = refs === null || refs === void 0 ? void 0 : refs.findIndex(item => item.ref === fieldRef);
|
|
84
|
+
const myRefIndex = refs === null || refs === void 0 ? void 0 : refs.findIndex((item) => item.ref === fieldRef);
|
|
71
85
|
// @ts-ignore
|
|
72
86
|
refs[myRefIndex].hasError = hasError;
|
|
73
87
|
// @ts-ignore
|
|
@@ -76,17 +90,10 @@ const useFormField = ({ ref, hasFocusCallback, id, nextFieldId, nextFormFieldRef
|
|
|
76
90
|
const fullAccessibilityHint = [accessibilityHint, errorMessage]
|
|
77
91
|
.filter(Boolean)
|
|
78
92
|
.join(',');
|
|
79
|
-
return
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
accessibilityHint: fullAccessibilityHint,
|
|
85
|
-
}
|
|
86
|
-
: {
|
|
87
|
-
focusNextFormField,
|
|
88
|
-
accessibilityHint: fullAccessibilityHint,
|
|
89
|
-
isLastField,
|
|
90
|
-
};
|
|
93
|
+
return {
|
|
94
|
+
focusNextFormField,
|
|
95
|
+
accessibilityHint: fullAccessibilityHint,
|
|
96
|
+
isLastField,
|
|
97
|
+
};
|
|
91
98
|
};
|
|
92
99
|
exports.useFormField = useFormField;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useFormSubmit = void 0;
|
|
4
|
+
const Form_1 = require("../components/Form");
|
|
5
|
+
const useFormSubmit = () => {
|
|
6
|
+
const { submitForm } = (0, Form_1.useForm)();
|
|
7
|
+
const handleSubmit = () => {
|
|
8
|
+
return submitForm();
|
|
9
|
+
};
|
|
10
|
+
return {
|
|
11
|
+
submitForm: handleSubmit,
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
exports.useFormSubmit = useFormSubmit;
|