@react-native-ama/forms 1.0.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/core/src/components/AMAProvider.d.ts +26 -0
- package/dist/core/src/components/AMAProvider.js +147 -0
- package/dist/core/src/components/AutofocusContainer.d.ts +9 -0
- package/dist/core/src/components/AutofocusContainer.js +58 -0
- package/dist/core/src/components/HideChildrenFromAccessibilityTree.d.ts +6 -0
- package/dist/core/src/components/HideChildrenFromAccessibilityTree.js +40 -0
- package/dist/core/src/hooks/useButtonChecks.d.ts +6 -0
- package/dist/core/src/hooks/useButtonChecks.js +51 -0
- package/dist/core/src/hooks/useChecks.d.ts +15 -0
- package/dist/core/src/hooks/useChecks.js +152 -0
- package/dist/core/src/hooks/useFocus.d.ts +4 -0
- package/dist/core/src/hooks/useFocus.js +55 -0
- package/dist/core/src/hooks/useTimedAction.d.ts +3 -0
- package/dist/core/src/hooks/useTimedAction.js +63 -0
- package/dist/core/src/index.d.ts +7 -0
- package/dist/core/src/index.js +20 -0
- package/dist/forms/src/components/Form.d.ts +24 -0
- package/dist/forms/src/components/Form.js +122 -0
- package/dist/forms/src/components/FormField.d.ts +7 -0
- package/dist/forms/src/components/FormField.js +52 -0
- package/dist/forms/src/components/FormSubmit.d.ts +10 -0
- package/dist/forms/src/components/FormSubmit.js +25 -0
- package/dist/forms/src/components/FormSwitch.d.ts +4 -0
- package/dist/forms/src/components/FormSwitch.js +15 -0
- package/dist/forms/src/components/TextInput.d.ts +26 -0
- package/dist/forms/src/components/TextInput.js +123 -0
- package/dist/forms/src/hooks/useFormField.d.ts +26 -0
- package/dist/forms/src/hooks/useFormField.js +92 -0
- package/dist/forms/src/hooks/useTextInput.d.ts +350 -0
- package/dist/forms/src/hooks/useTextInput.js +102 -0
- package/dist/forms/src/index.d.ts +16 -0
- package/dist/forms/src/index.js +24 -0
- package/dist/internal/src/checks/checkAccessibilityRole.d.ts +3 -0
- package/dist/internal/src/checks/checkAccessibilityRole.js +32 -0
- package/dist/internal/src/checks/checkFocusTrap.d.ts +8 -0
- package/dist/internal/src/checks/checkFocusTrap.js +34 -0
- package/dist/internal/src/checks/checkForAccessibilityState.d.ts +7 -0
- package/dist/internal/src/checks/checkForAccessibilityState.js +48 -0
- package/dist/internal/src/checks/checkMinimumSize.d.ts +3 -0
- package/dist/internal/src/checks/checkMinimumSize.js +29 -0
- package/dist/internal/src/checks/contrastChecker.d.ts +8 -0
- package/dist/internal/src/checks/contrastChecker.js +77 -0
- package/dist/internal/src/checks/noUndefinedProperty.d.ts +8 -0
- package/dist/internal/src/checks/noUndefinedProperty.js +14 -0
- package/dist/internal/src/checks/uppercaseChecker.d.ts +8 -0
- package/dist/internal/src/checks/uppercaseChecker.js +18 -0
- package/dist/internal/src/checks/uppercaseStringChecker.d.ts +8 -0
- package/dist/internal/src/checks/uppercaseStringChecker.js +29 -0
- package/dist/internal/src/index.d.ts +20 -0
- package/dist/internal/src/index.js +56 -0
- package/dist/internal/src/types.d.ts +17 -0
- package/dist/internal/src/types.js +2 -0
- package/dist/internal/src/utils/applyStyle.d.ts +9 -0
- package/dist/internal/src/utils/applyStyle.js +33 -0
- package/dist/internal/src/utils/constants.d.ts +3 -0
- package/dist/internal/src/utils/constants.js +32 -0
- package/dist/internal/src/utils/error.style.d.ts +6 -0
- package/dist/internal/src/utils/error.style.js +11 -0
- package/dist/internal/src/utils/generateAccessibilityStateFromProp.d.ts +9 -0
- package/dist/internal/src/utils/generateAccessibilityStateFromProp.js +35 -0
- package/dist/internal/src/utils/getPropertyFromStyle.d.ts +2 -0
- package/dist/internal/src/utils/getPropertyFromStyle.js +10 -0
- package/dist/internal/src/utils/interpolateAnimationStates.d.ts +2 -0
- package/dist/internal/src/utils/interpolateAnimationStates.js +43 -0
- package/dist/internal/src/utils/isFocused.d.ts +2 -0
- package/dist/internal/src/utils/isFocused.js +7 -0
- package/dist/internal/src/utils/logger.d.ts +16 -0
- package/dist/internal/src/utils/logger.js +53 -0
- package/dist/internal/src/utils/logger.rules.d.ts +15 -0
- package/dist/internal/src/utils/logger.rules.js +74 -0
- package/dist/internal/src/utils/maybeGenerateStringFromElement.d.ts +2 -0
- package/dist/internal/src/utils/maybeGenerateStringFromElement.js +51 -0
- package/dist/internal/src/utils/minimumTouchableSize.d.ts +3 -0
- package/dist/internal/src/utils/minimumTouchableSize.js +9 -0
- package/dist/react-native/src/components/ExpandablePressable.d.ts +6 -0
- package/dist/react-native/src/components/ExpandablePressable.js +26 -0
- package/dist/react-native/src/components/Pressable.d.ts +5 -0
- package/dist/react-native/src/components/Pressable.js +49 -0
- package/dist/react-native/src/components/SwitchListItem.d.ts +12 -0
- package/dist/react-native/src/components/SwitchListItem.js +44 -0
- package/dist/react-native/src/components/SwitchWrapper.d.ts +11 -0
- package/dist/react-native/src/components/SwitchWrapper.js +36 -0
- package/dist/react-native/src/components/Text.d.ts +6 -0
- package/dist/react-native/src/components/Text.js +77 -0
- package/dist/react-native/src/components/TouchableOpacity.d.ts +6 -0
- package/dist/react-native/src/components/TouchableOpacity.js +48 -0
- package/dist/react-native/src/components/TouchableWithoutFeedback.d.ts +5 -0
- package/dist/react-native/src/components/TouchableWithoutFeedback.js +48 -0
- package/dist/react-native/src/hooks/useExpandable.d.ts +13 -0
- package/dist/react-native/src/hooks/useExpandable.js +31 -0
- package/dist/react-native/src/hooks/usePressable.d.ts +16 -0
- package/dist/react-native/src/hooks/usePressable.js +44 -0
- package/dist/react-native/src/hooks/useSwitch.d.ts +10 -0
- package/dist/react-native/src/hooks/useSwitch.js +25 -0
- package/dist/react-native/src/index.d.ts +10 -0
- package/dist/react-native/src/index.js +25 -0
- package/package.json +82 -0
- package/src/components/Form.test.tsx +262 -0
- package/src/components/Form.tsx +138 -0
- package/src/components/FormField.test.tsx +54 -0
- package/src/components/FormField.tsx +45 -0
- package/src/components/FormSubmit.test.tsx +71 -0
- package/src/components/FormSubmit.tsx +43 -0
- package/src/components/FormSwitch.tsx +17 -0
- package/src/components/TextInput.test.tsx +540 -0
- package/src/components/TextInput.tsx +168 -0
- package/src/hooks/useFormField.test.tsx +183 -0
- package/src/hooks/useFormField.ts +133 -0
- package/src/hooks/useTextInput.ts +128 -0
- package/src/index.ts +39 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useTimedAction = exports.useFocus = exports.useChecks = exports.useButtonChecks = exports.HideChildrenFromAccessibilityTree = exports.useAMAContext = exports.AMAProvider = exports.AutofocusContainer = void 0;
|
|
4
|
+
// Components
|
|
5
|
+
var AutofocusContainer_1 = require("./components/AutofocusContainer");
|
|
6
|
+
Object.defineProperty(exports, "AutofocusContainer", { enumerable: true, get: function () { return AutofocusContainer_1.AutofocusContainer; } });
|
|
7
|
+
var AMAProvider_1 = require("./components/AMAProvider");
|
|
8
|
+
Object.defineProperty(exports, "AMAProvider", { enumerable: true, get: function () { return AMAProvider_1.AMAProvider; } });
|
|
9
|
+
Object.defineProperty(exports, "useAMAContext", { enumerable: true, get: function () { return AMAProvider_1.useAMAContext; } });
|
|
10
|
+
var HideChildrenFromAccessibilityTree_1 = require("./components/HideChildrenFromAccessibilityTree");
|
|
11
|
+
Object.defineProperty(exports, "HideChildrenFromAccessibilityTree", { enumerable: true, get: function () { return HideChildrenFromAccessibilityTree_1.HideChildrenFromAccessibilityTree; } });
|
|
12
|
+
// Hooks
|
|
13
|
+
var useButtonChecks_1 = require("./hooks/useButtonChecks");
|
|
14
|
+
Object.defineProperty(exports, "useButtonChecks", { enumerable: true, get: function () { return useButtonChecks_1.useButtonChecks; } });
|
|
15
|
+
var useChecks_1 = require("./hooks/useChecks");
|
|
16
|
+
Object.defineProperty(exports, "useChecks", { enumerable: true, get: function () { return useChecks_1.useChecks; } });
|
|
17
|
+
var useFocus_1 = require("./hooks/useFocus");
|
|
18
|
+
Object.defineProperty(exports, "useFocus", { enumerable: true, get: function () { return useFocus_1.useFocus; } });
|
|
19
|
+
var useTimedAction_1 = require("./hooks/useTimedAction");
|
|
20
|
+
Object.defineProperty(exports, "useTimedAction", { enumerable: true, get: function () { return useTimedAction_1.useTimedAction; } });
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type FormProps = React.PropsWithChildren<{
|
|
3
|
+
onSubmit: () => boolean | Promise<boolean>;
|
|
4
|
+
ref?: React.RefObject<FormActions>;
|
|
5
|
+
}>;
|
|
6
|
+
export type FormActions = {
|
|
7
|
+
focusFirstInvalidField: () => void;
|
|
8
|
+
};
|
|
9
|
+
export declare const Form: React.ForwardRefExoticComponent<Omit<FormProps, "ref"> & React.RefAttributes<FormActions>>;
|
|
10
|
+
export type FormContextValue = {
|
|
11
|
+
refs?: FormRef[];
|
|
12
|
+
submitForm: () => Promise<void>;
|
|
13
|
+
focusField?: (nextField?: Partial<FormRef> | undefined) => void;
|
|
14
|
+
};
|
|
15
|
+
export type FormRef = {
|
|
16
|
+
ref: React.RefObject<any>;
|
|
17
|
+
hasFocusCallback: boolean;
|
|
18
|
+
id: string | undefined;
|
|
19
|
+
hasValidation: boolean;
|
|
20
|
+
hasError?: boolean;
|
|
21
|
+
isEditable?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export declare const FormContext: React.Context<FormContextValue | null>;
|
|
24
|
+
export declare const useForm: () => FormContextValue;
|
|
@@ -0,0 +1,122 @@
|
|
|
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
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
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
|
+
const React = __importStar(require("react"));
|
|
39
|
+
const react_native_1 = require("react-native");
|
|
40
|
+
exports.Form = React.forwardRef(({ children, onSubmit }, ref) => {
|
|
41
|
+
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;
|
|
44
|
+
const focusField = (nextField) => {
|
|
45
|
+
var _a, _b, _c;
|
|
46
|
+
/**
|
|
47
|
+
* Refs passed as prop have another ".current"
|
|
48
|
+
*/
|
|
49
|
+
const nextRefElement = ((_b = (_a = nextField === null || nextField === void 0 ? void 0 : nextField.ref) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.current)
|
|
50
|
+
? nextField === null || nextField === void 0 ? void 0 : nextField.ref.current
|
|
51
|
+
: nextField === null || nextField === void 0 ? void 0 : nextField.ref;
|
|
52
|
+
const callFocus =
|
|
53
|
+
// @ts-ignore
|
|
54
|
+
((_c = nextRefElement === null || nextRefElement === void 0 ? void 0 : nextRefElement.current) === null || _c === void 0 ? void 0 : _c.focus) &&
|
|
55
|
+
(nextField === null || nextField === void 0 ? void 0 : nextField.hasFocusCallback) &&
|
|
56
|
+
(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
|
+
if (callFocus) {
|
|
64
|
+
/**
|
|
65
|
+
* On some apps, if we call focus immediately and the field is already focused we lose the focus.
|
|
66
|
+
* Same happens if we do not call `focus` if the field is already focused.
|
|
67
|
+
*/
|
|
68
|
+
const timeoutValue = (0, internal_1.isFocused)(nextRefElement.current) ? 50 : 0;
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
var _a;
|
|
71
|
+
(_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
|
+
}, timeoutValue);
|
|
79
|
+
}
|
|
80
|
+
else if (nextRefElement === null || nextRefElement === void 0 ? void 0 : nextRefElement.current) {
|
|
81
|
+
setFocus(nextRefElement === null || nextRefElement === void 0 ? void 0 : nextRefElement.current);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const submitForm = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
85
|
+
const isValid = yield onSubmit();
|
|
86
|
+
if (isValid) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
focusFirstInvalidField();
|
|
90
|
+
});
|
|
91
|
+
const focusFirstInvalidField = () => {
|
|
92
|
+
react_native_1.InteractionManager.runAfterInteractions(() => {
|
|
93
|
+
setTimeout(() => {
|
|
94
|
+
const fieldWithError = (refs.current || []).find(fieldRef => fieldRef.hasValidation && fieldRef.hasError);
|
|
95
|
+
__DEV__ &&
|
|
96
|
+
fieldWithError == null &&
|
|
97
|
+
(checks === null || checks === void 0 ? void 0 : checks.logResult('Form', {
|
|
98
|
+
message: 'The form validation has failed, but no component with error was found',
|
|
99
|
+
rule: 'NO_UNDEFINED',
|
|
100
|
+
}));
|
|
101
|
+
focusField(fieldWithError);
|
|
102
|
+
}, 0);
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
React.useImperativeHandle(ref, () => ({
|
|
106
|
+
focusFirstInvalidField,
|
|
107
|
+
}));
|
|
108
|
+
return (<exports.FormContext.Provider value={{ refs: refs.current, submitForm, focusField }}>
|
|
109
|
+
{children}
|
|
110
|
+
</exports.FormContext.Provider>);
|
|
111
|
+
});
|
|
112
|
+
exports.FormContext = React.createContext(null);
|
|
113
|
+
const useForm = () => {
|
|
114
|
+
const context = React.useContext(exports.FormContext);
|
|
115
|
+
if (!context) {
|
|
116
|
+
__DEV__ &&
|
|
117
|
+
console.error('Please wrap your form field inside the <Form /> component');
|
|
118
|
+
throw new Error('useForm must be used within a FormContextProvider, please wrap your form field inside the <Form /> component');
|
|
119
|
+
}
|
|
120
|
+
return context;
|
|
121
|
+
};
|
|
122
|
+
exports.useForm = useForm;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { TouchableWithoutFeedbackProps } from 'react-native';
|
|
3
|
+
import { UseFormField } from '../hooks/useFormField';
|
|
4
|
+
export type FormFieldProps = React.PropsWithChildren<TouchableWithoutFeedbackProps & Omit<UseFormField, 'hasFocusCallback' | 'nextFormFieldRef' | 'nextFieldId' | 'editable'> & {
|
|
5
|
+
wrapInsideAccessibleView?: boolean;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const FormField: ({ children, wrapInsideAccessibleView, ...props }: FormFieldProps) => React.JSX.Element;
|
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
26
|
+
var t = {};
|
|
27
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
28
|
+
t[p] = s[p];
|
|
29
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
30
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
31
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
32
|
+
t[p[i]] = s[p[i]];
|
|
33
|
+
}
|
|
34
|
+
return t;
|
|
35
|
+
};
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.FormField = void 0;
|
|
38
|
+
const React = __importStar(require("react"));
|
|
39
|
+
const react_native_1 = require("react-native");
|
|
40
|
+
const useFormField_1 = require("../hooks/useFormField");
|
|
41
|
+
const FormField = (_a) => {
|
|
42
|
+
var { children, wrapInsideAccessibleView = true } = _a, props = __rest(_a, ["children", "wrapInsideAccessibleView"]);
|
|
43
|
+
const viewRef = React.useRef(null);
|
|
44
|
+
// @ts-ignore
|
|
45
|
+
const formProps = (0, useFormField_1.useFormField)(Object.assign({ hasFocusCallback: false, ref: viewRef }, props));
|
|
46
|
+
return wrapInsideAccessibleView ? (<react_native_1.TouchableWithoutFeedback {...props} ref={viewRef} {...formProps}>
|
|
47
|
+
<react_native_1.View accessible>{children}</react_native_1.View>
|
|
48
|
+
</react_native_1.TouchableWithoutFeedback>) : (<react_native_1.TouchableWithoutFeedback {...props} ref={viewRef} {...formProps}>
|
|
49
|
+
<>{children}</>
|
|
50
|
+
</react_native_1.TouchableWithoutFeedback>);
|
|
51
|
+
};
|
|
52
|
+
exports.FormField = FormField;
|
|
@@ -0,0 +1,10 @@
|
|
|
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;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FormSubmit = void 0;
|
|
7
|
+
const core_1 = require("@react-native-ama/core");
|
|
8
|
+
const core_2 = require("@react-native-ama/core");
|
|
9
|
+
const react_1 = __importDefault(require("react"));
|
|
10
|
+
const react_native_1 = require("react-native");
|
|
11
|
+
const Form_1 = require("../components/Form");
|
|
12
|
+
const FormSubmit = (props) => {
|
|
13
|
+
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>);
|
|
19
|
+
};
|
|
20
|
+
exports.FormSubmit = FormSubmit;
|
|
21
|
+
const FormSubmitForScreenReader = ({ children, }) => {
|
|
22
|
+
return (<core_2.HideChildrenFromAccessibilityTree>
|
|
23
|
+
{children}
|
|
24
|
+
</core_2.HideChildrenFromAccessibilityTree>);
|
|
25
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FormSwitch = void 0;
|
|
7
|
+
const react_native_1 = require("@react-native-ama/react-native");
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const FormField_1 = require("./FormField");
|
|
10
|
+
const FormSwitch = (props) => {
|
|
11
|
+
return (<FormField_1.FormField hasValidation={false}>
|
|
12
|
+
<react_native_1.SwitchListItem {...props}/>
|
|
13
|
+
</FormField_1.FormField>);
|
|
14
|
+
};
|
|
15
|
+
exports.FormSwitch = FormSwitch;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { TextInput as RNTextInput, TextInputProps as RNTextInputProps } from 'react-native';
|
|
3
|
+
export type TextInputProps = RNTextInputProps & {
|
|
4
|
+
labelComponent: JSX.Element;
|
|
5
|
+
labelPosition?: 'beforeInput' | 'afterInput';
|
|
6
|
+
nextFormField?: React.RefObject<RNTextInput>;
|
|
7
|
+
id?: string;
|
|
8
|
+
nextFieldId?: string;
|
|
9
|
+
hasValidation: boolean;
|
|
10
|
+
errorComponent?: JSX.Element;
|
|
11
|
+
hasError?: boolean;
|
|
12
|
+
errorPosition?: 'belowLabel' | 'afterInput';
|
|
13
|
+
errorMessage?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const TextInput: React.ForwardRefExoticComponent<RNTextInputProps & {
|
|
16
|
+
labelComponent: JSX.Element;
|
|
17
|
+
labelPosition?: "beforeInput" | "afterInput" | undefined;
|
|
18
|
+
nextFormField?: React.RefObject<RNTextInput> | undefined;
|
|
19
|
+
id?: string | undefined;
|
|
20
|
+
nextFieldId?: string | undefined;
|
|
21
|
+
hasValidation: boolean;
|
|
22
|
+
errorComponent?: JSX.Element | undefined;
|
|
23
|
+
hasError?: boolean | undefined;
|
|
24
|
+
errorPosition?: "afterInput" | "belowLabel" | undefined;
|
|
25
|
+
errorMessage?: string | undefined;
|
|
26
|
+
} & React.RefAttributes<RNTextInput>>;
|
|
@@ -0,0 +1,123 @@
|
|
|
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
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
26
|
+
var t = {};
|
|
27
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
28
|
+
t[p] = s[p];
|
|
29
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
30
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
31
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
32
|
+
t[p[i]] = s[p[i]];
|
|
33
|
+
}
|
|
34
|
+
return t;
|
|
35
|
+
};
|
|
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");
|
|
42
|
+
const React = __importStar(require("react"));
|
|
43
|
+
const react_native_1 = require("react-native");
|
|
44
|
+
const useTextInput_1 = require("../hooks/useTextInput");
|
|
45
|
+
exports.TextInput = React.forwardRef((_a, forwardedRef) => {
|
|
46
|
+
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"]);
|
|
48
|
+
const inputRef = React.useRef(null);
|
|
49
|
+
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
|
+
// @ts-ignore
|
|
53
|
+
const textInputProps = (0, useTextInput_1.useTextInput)(Object.assign({ required: false, ref: inputRef, id,
|
|
54
|
+
nextFieldId, nextFormFieldRef: nextFormField, hasError,
|
|
55
|
+
hasValidation,
|
|
56
|
+
errorMessage,
|
|
57
|
+
accessibilityLabel }, rest));
|
|
58
|
+
const checks = __DEV__ ? core_2.useChecks === null || core_2.useChecks === void 0 ? void 0 : (0, core_2.useChecks)() : undefined;
|
|
59
|
+
__DEV__ &&
|
|
60
|
+
(checks === null || checks === void 0 ? void 0 : checks.noUndefinedProperty({
|
|
61
|
+
properties: { labelComponent },
|
|
62
|
+
property: 'labelComponent',
|
|
63
|
+
rule: 'NO_FORM_LABEL',
|
|
64
|
+
}));
|
|
65
|
+
__DEV__ &&
|
|
66
|
+
(checks === null || checks === void 0 ? void 0 : checks.noUndefinedProperty({
|
|
67
|
+
properties: { accessibilityLabel },
|
|
68
|
+
property: 'accessibilityLabel',
|
|
69
|
+
rule: 'NO_ACCESSIBILITY_LABEL',
|
|
70
|
+
}));
|
|
71
|
+
__DEV__ &&
|
|
72
|
+
(accessibilityLabel === null || accessibilityLabel === void 0 ? void 0 : accessibilityLabel.trim()) === '' &&
|
|
73
|
+
(checks === null || checks === void 0 ? void 0 : checks.logResult('NO_ACCESSIBILITY_LABEL', {
|
|
74
|
+
rule: 'NO_ACCESSIBILITY_LABEL',
|
|
75
|
+
message: 'No accessibility label provided',
|
|
76
|
+
}));
|
|
77
|
+
__DEV__ &&
|
|
78
|
+
hasValidation &&
|
|
79
|
+
(checks === null || checks === void 0 ? void 0 : checks.noUndefinedProperty({
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
properties: { errorComponent },
|
|
82
|
+
property: 'errorComponent',
|
|
83
|
+
rule: 'NO_FORM_ERROR',
|
|
84
|
+
}));
|
|
85
|
+
const style = __DEV__ && // @ts-ignore
|
|
86
|
+
(internal_1.applyStyle === null || internal_1.applyStyle === void 0 ? void 0 : (0, internal_1.applyStyle)({
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
style: (textInputProps === null || textInputProps === void 0 ? void 0 : textInputProps.style) || {},
|
|
89
|
+
debugStyle: checks === null || checks === void 0 ? void 0 : checks.debugStyle,
|
|
90
|
+
}));
|
|
91
|
+
const accessibilityHiddenLabel = React.useMemo(() => (<core_1.HideChildrenFromAccessibilityTree>
|
|
92
|
+
{labelComponent}
|
|
93
|
+
</core_1.HideChildrenFromAccessibilityTree>), [labelComponent]);
|
|
94
|
+
const errorText = React.useMemo(() => {
|
|
95
|
+
return hasValidation && hasError
|
|
96
|
+
? (0, internal_2.maybeGenerateStringFromElement)(errorComponent, errorMessage)
|
|
97
|
+
: '';
|
|
98
|
+
}, [hasValidation, hasError, errorComponent, errorMessage]);
|
|
99
|
+
const renderError = () => {
|
|
100
|
+
return (<core_1.HideChildrenFromAccessibilityTree>
|
|
101
|
+
{errorComponent}
|
|
102
|
+
</core_1.HideChildrenFromAccessibilityTree>);
|
|
103
|
+
};
|
|
104
|
+
const fullAccessibilityHint = (_b = [accessibilityHint || '', errorText || '']
|
|
105
|
+
.filter(item => item.length > 0)) === null || _b === void 0 ? void 0 : _b.join(', ');
|
|
106
|
+
return __DEV__ ? (<>
|
|
107
|
+
{showLabelBeforeInput ? accessibilityHiddenLabel : null}
|
|
108
|
+
{hasError && errorPosition === 'belowLabel' ? renderError() : null}
|
|
109
|
+
<react_native_1.TextInput
|
|
110
|
+
// @ts-ignore
|
|
111
|
+
ref={inputRef} {...rest} {...textInputProps} style={style} accessibilityLabel={accessibilityLabel} accessibilityHint={fullAccessibilityHint}/>
|
|
112
|
+
{showLabelBeforeInput ? null : accessibilityHiddenLabel}
|
|
113
|
+
{hasError && errorPosition === 'afterInput' ? renderError() : null}
|
|
114
|
+
</>) : (<>
|
|
115
|
+
{showLabelBeforeInput ? accessibilityHiddenLabel : null}
|
|
116
|
+
{hasError && errorPosition === 'belowLabel' ? renderError() : null}
|
|
117
|
+
<react_native_1.TextInput
|
|
118
|
+
// @ts-ignore
|
|
119
|
+
ref={inputRef} {...rest} {...textInputProps} accessibilityLabel={accessibilityLabel} accessibilityHint={fullAccessibilityHint}/>
|
|
120
|
+
{showLabelBeforeInput ? null : accessibilityHiddenLabel}
|
|
121
|
+
{hasError && errorPosition === 'afterInput' ? renderError() : null}
|
|
122
|
+
</>);
|
|
123
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ViewStyle } from 'react-native';
|
|
3
|
+
export type UseFormField = {
|
|
4
|
+
ref?: React.RefObject<any> | React.ForwardedRef<any> | null;
|
|
5
|
+
hasFocusCallback: boolean;
|
|
6
|
+
id?: string;
|
|
7
|
+
nextFieldId?: string;
|
|
8
|
+
nextFormFieldRef?: React.RefObject<any>;
|
|
9
|
+
accessibilityHint?: string;
|
|
10
|
+
style?: ViewStyle;
|
|
11
|
+
editable?: boolean;
|
|
12
|
+
hasValidation: boolean;
|
|
13
|
+
hasError?: boolean;
|
|
14
|
+
errorMessage?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const useFormField: ({ ref, hasFocusCallback, id, nextFieldId, nextFormFieldRef, hasValidation, hasError, accessibilityHint, errorMessage, editable, style, }: UseFormField) => {
|
|
17
|
+
focusNextFormField: () => void;
|
|
18
|
+
isLastField: () => boolean;
|
|
19
|
+
style: any;
|
|
20
|
+
accessibilityHint: string;
|
|
21
|
+
} | {
|
|
22
|
+
focusNextFormField: () => void;
|
|
23
|
+
accessibilityHint: string;
|
|
24
|
+
isLastField: () => boolean;
|
|
25
|
+
style?: undefined;
|
|
26
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useFormField = void 0;
|
|
7
|
+
const core_1 = require("@react-native-ama/core");
|
|
8
|
+
const internal_1 = require("@react-native-ama/internal");
|
|
9
|
+
const react_1 = __importDefault(require("react"));
|
|
10
|
+
const react_native_1 = require("react-native");
|
|
11
|
+
const Form_1 = require("../components/Form");
|
|
12
|
+
const useFormField = ({ ref, hasFocusCallback, id, nextFieldId, nextFormFieldRef, hasValidation, hasError, accessibilityHint, errorMessage, editable = true, style = {}, }) => {
|
|
13
|
+
const { refs, submitForm, focusField } = (0, Form_1.useForm)();
|
|
14
|
+
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;
|
|
16
|
+
const getMyIndex = () => {
|
|
17
|
+
const allRefs = refs;
|
|
18
|
+
const item = allRefs.find(r => r.ref === fieldRef);
|
|
19
|
+
return item ? allRefs.indexOf(item) : -1;
|
|
20
|
+
};
|
|
21
|
+
const focusNextFormField = () => {
|
|
22
|
+
var _a;
|
|
23
|
+
const isLastItem = isLastField();
|
|
24
|
+
if (isLastItem) {
|
|
25
|
+
react_native_1.Keyboard.dismiss();
|
|
26
|
+
submitForm();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const currentField = refs[getMyIndex()];
|
|
30
|
+
focusField === null || focusField === void 0 ? void 0 : focusField(getNextFieldRef());
|
|
31
|
+
__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,
|
|
35
|
+
shouldHaveFocus: false,
|
|
36
|
+
}));
|
|
37
|
+
};
|
|
38
|
+
const getNextFieldRef = () => {
|
|
39
|
+
const allRefs = refs || [];
|
|
40
|
+
if (nextFormFieldRef) {
|
|
41
|
+
return {
|
|
42
|
+
ref: nextFormFieldRef,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
else if (nextFieldId) {
|
|
46
|
+
return allRefs.find(item => item.id === nextFieldId);
|
|
47
|
+
}
|
|
48
|
+
return allRefs[getMyIndex() + 1];
|
|
49
|
+
};
|
|
50
|
+
const isLastField = () => {
|
|
51
|
+
const myIndex = getMyIndex();
|
|
52
|
+
return myIndex === refs.length - 1;
|
|
53
|
+
};
|
|
54
|
+
react_1.default.useEffect(() => {
|
|
55
|
+
refs === null || refs === void 0 ? void 0 : refs.push({
|
|
56
|
+
ref: fieldRef,
|
|
57
|
+
hasFocusCallback,
|
|
58
|
+
id,
|
|
59
|
+
hasValidation,
|
|
60
|
+
hasError,
|
|
61
|
+
isEditable: editable,
|
|
62
|
+
});
|
|
63
|
+
return () => {
|
|
64
|
+
const myIndex = getMyIndex();
|
|
65
|
+
refs === null || refs === void 0 ? void 0 : refs.splice(myIndex, 1);
|
|
66
|
+
};
|
|
67
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
68
|
+
}, []);
|
|
69
|
+
react_1.default.useEffect(() => {
|
|
70
|
+
const myRefIndex = refs === null || refs === void 0 ? void 0 : refs.findIndex(item => item.ref === fieldRef);
|
|
71
|
+
// @ts-ignore
|
|
72
|
+
refs[myRefIndex].hasError = hasError;
|
|
73
|
+
// @ts-ignore
|
|
74
|
+
refs[myRefIndex].isEditable = editable;
|
|
75
|
+
}, [editable, hasError, refs]);
|
|
76
|
+
const fullAccessibilityHint = [accessibilityHint, errorMessage]
|
|
77
|
+
.filter(Boolean)
|
|
78
|
+
.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
|
+
};
|
|
91
|
+
};
|
|
92
|
+
exports.useFormField = useFormField;
|