@react-native-ama/forms 1.2.1 → 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.
Files changed (40) hide show
  1. package/dist/components/Form.d.ts +5 -2
  2. package/dist/components/Form.js +14 -31
  3. package/dist/components/FormSubmit.d.ts +7 -9
  4. package/dist/components/FormSubmit.js +2 -14
  5. package/dist/components/TextInput.d.ts +36 -4
  6. package/dist/components/TextInput.js +20 -73
  7. package/dist/hooks/useFocus.d.ts +4 -0
  8. package/dist/hooks/useFocus.js +69 -0
  9. package/dist/hooks/useFormField.d.ts +1 -7
  10. package/dist/hooks/useFormField.js +32 -25
  11. package/dist/hooks/useFormSubmit.d.ts +4 -0
  12. package/dist/hooks/useFormSubmit.js +14 -0
  13. package/dist/hooks/useTextInput.d.ts +59 -231
  14. package/dist/hooks/useTextInput.js +2 -37
  15. package/dist/index.d.ts +9 -12
  16. package/dist/index.js +3 -8
  17. package/dist/utils/checkFocusTrap.d.ts +8 -0
  18. package/dist/utils/checkFocusTrap.js +30 -0
  19. package/package.json +59 -18
  20. package/src/components/Form.test.tsx +63 -70
  21. package/src/components/Form.tsx +28 -52
  22. package/src/components/FormField.test.tsx +32 -16
  23. package/src/components/FormField.tsx +0 -1
  24. package/src/components/FormSubmit.test.tsx +17 -55
  25. package/src/components/FormSubmit.tsx +9 -36
  26. package/src/components/TextInput.test.tsx +83 -397
  27. package/src/components/TextInput.tsx +41 -109
  28. package/src/hooks/useFocus.test.ts +130 -0
  29. package/src/hooks/useFocus.ts +62 -0
  30. package/src/hooks/useFormField.test.tsx +183 -78
  31. package/src/hooks/useFormField.ts +36 -28
  32. package/src/hooks/useFormSubmit.test.tsx +18 -0
  33. package/src/hooks/useFormSubmit.ts +17 -0
  34. package/src/hooks/useTextInput.ts +10 -55
  35. package/src/index.ts +14 -19
  36. package/src/utils/checkFocusTrap.test.ts +80 -0
  37. package/src/utils/checkFocusTrap.ts +40 -0
  38. package/dist/components/FormSwitch.d.ts +0 -4
  39. package/dist/components/FormSwitch.js +0 -15
  40. 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<Omit<FormProps, "ref"> & React.RefAttributes<FormActions>>;
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>;
@@ -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, core_1.useFocus)();
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 = (0, internal_1.isFocused)(nextRefElement.current) ? 50 : 0;
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
- }, [checks, setFocus]);
84
- const focusFieldAt = React.useCallback((position) => {
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
- }, [focusField]);
92
- const focusFirstInvalidField = React.useCallback(() => {
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
- }, [focusFieldAt, checks]);
102
- const submitForm = React.useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
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
- }), [focusFirstInvalidField, onSubmit]);
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
- import { PressableProps } from 'react-native';
3
- export type FormSubmitProps = React.PropsWithChildren<{
4
- accessibilityLabel: string;
5
- accessibilityHint?: string;
6
- busy: boolean;
7
- style?: PressableProps['style'];
8
- testID?: string;
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 = (props) => {
9
+ const FormSubmit = ({ children }) => {
13
10
  const { submitForm } = (0, Form_1.useForm)();
14
- const { isScreenReaderEnabled } = (0, core_1.useAMAContext)();
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 type TextInputProps = RNTextInputProps & Omit<UseTextInput, 'required' | 'accessibilityLabel'> & {
5
- labelComponent: JSX.Element;
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 declare const TextInput: React.ForwardRefExoticComponent<Omit<TextInputProps, "ref"> & React.RefAttributes<RNTextInput>>;
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 { labelComponent, labelPosition = 'beforeInput', nextFormField, id, nextFieldId, accessibilityHint, hasError, errorComponent, errorPosition = 'afterInput', hasValidation, errorMessage } = _a, rest = __rest(_a, ["labelComponent", "labelPosition", "nextFormField", "id", "nextFieldId", "accessibilityHint", "hasError", "errorComponent", "errorPosition", "hasValidation", "errorMessage"]);
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 checks = __DEV__ ? core_2.useChecks === null || core_2.useChecks === void 0 ? void 0 : (0, core_2.useChecks)() : undefined;
57
- __DEV__ &&
58
- (checks === null || checks === void 0 ? void 0 : checks.noUndefinedProperty({
59
- properties: { labelComponent },
60
- property: 'labelComponent',
61
- rule: 'NO_FORM_LABEL',
62
- }));
63
- __DEV__ &&
64
- (checks === null || checks === void 0 ? void 0 : checks.noUndefinedProperty({
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,4 @@
1
+ import * as React from 'react';
2
+ export declare const useFocus: (refComponent?: React.RefObject<any>) => {
3
+ setFocus: (component: null | number | React.Component<any, any> | React.ComponentClass<any>) => void;
4
+ };
@@ -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, style, }: UseFormField) => {
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 useFormField = ({ ref, hasFocusCallback, id, nextFieldId, nextFormFieldRef, hasValidation, hasError, accessibilityHint, errorMessage, editable = true, suppressError, style = {}, }) => {
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 checks = __DEV__ ? core_1.useChecks === null || core_1.useChecks === void 0 ? void 0 : (0, core_1.useChecks)() : undefined;
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
- (currentField === null || currentField === void 0 ? void 0 : currentField.hasFocusCallback) &&
33
- (checks === null || checks === void 0 ? void 0 : checks.checkFocusTrap({
34
- ref: (_a = currentField === null || currentField === void 0 ? void 0 : currentField.ref) === null || _a === void 0 ? void 0 : _a.current,
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 __DEV__
80
- ? {
81
- focusNextFormField,
82
- isLastField,
83
- style: internal_1.applyStyle === null || internal_1.applyStyle === void 0 ? void 0 : (0, internal_1.applyStyle)({ style, debugStyle: checks === null || checks === void 0 ? void 0 : checks.debugStyle }),
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,4 @@
1
+ export type UseFormSubmit = {
2
+ submitForm: () => Promise<void>;
3
+ };
4
+ export declare const useFormSubmit: () => UseFormSubmit;
@@ -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;