@evervault/react-native 2.0.0 → 2.2.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/android/build.gradle +6 -1
- package/build/Card/Root.d.ts +4 -0
- package/build/Card/Root.d.ts.map +1 -1
- package/build/Input.d.ts +4 -0
- package/build/Input.d.ts.map +1 -1
- package/build/index.cjs.js +70 -47
- package/build/index.cjs.js.map +1 -1
- package/build/index.esm.js +71 -48
- package/package.json +2 -1
- package/src/Card/Root.tsx +40 -8
- package/src/Input.test.tsx +204 -6
- package/src/Input.tsx +22 -2
package/android/build.gradle
CHANGED
|
@@ -17,8 +17,13 @@ apply plugin: 'com.facebook.react'
|
|
|
17
17
|
apply plugin: 'org.jetbrains.kotlin.android'
|
|
18
18
|
|
|
19
19
|
android {
|
|
20
|
-
compileSdkVersion safeExtGet('compileSdkVersion',
|
|
20
|
+
compileSdkVersion safeExtGet('compileSdkVersion', 35)
|
|
21
21
|
namespace "com.nativeevervault"
|
|
22
|
+
|
|
23
|
+
defaultConfig {
|
|
24
|
+
minSdkVersion safeExtGet('minSdkVersion', 24)
|
|
25
|
+
targetSdkVersion safeExtGet('targetSdkVersion', 35)
|
|
26
|
+
}
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
repositories {
|
package/build/Card/Root.d.ts
CHANGED
|
@@ -14,6 +14,10 @@ export interface CardProps extends PropsWithChildren, CardConfig {
|
|
|
14
14
|
* Triggered whenever the component's state is updated.
|
|
15
15
|
*/
|
|
16
16
|
onChange?(payload: CardPayload): void;
|
|
17
|
+
/**
|
|
18
|
+
* Triggered when a native error occurs.
|
|
19
|
+
*/
|
|
20
|
+
onError?(error: Error): void;
|
|
17
21
|
/**
|
|
18
22
|
* The validation mode to use for the form.
|
|
19
23
|
*
|
package/build/Card/Root.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Root.d.ts","sourceRoot":"","sources":["../../src/Card/Root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,
|
|
1
|
+
{"version":3,"file":"Root.d.ts","sourceRoot":"","sources":["../../src/Card/Root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,EAMlB,MAAM,OAAO,CAAC;AACf,OAAO,EAAiB,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAWjE,MAAM,WAAW,SAAU,SAAQ,iBAAiB,EAAE,UAAU;IAC9D;;OAEG;IACH,aAAa,CAAC,EAAE;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAEtC;;OAEG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAE7B;;;;;;;;;OASG;IACH,cAAc,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,KAAK,CAAC;CAC9D;AAED,MAAM,WAAW,IAAI;IACnB;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;CACf;AAED,eAAO,MAAM,IAAI,4FAwFf,CAAC"}
|
package/build/Input.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { ReactNode, Ref } from "react";
|
|
2
2
|
import { TextInput, TextInputProps } from "react-native";
|
|
3
3
|
import { Mask, MaskArray } from "react-native-mask-input";
|
|
4
|
+
export interface EvervaultInputContextValue {
|
|
5
|
+
validationMode: "onChange" | "onBlur" | "onTouched" | "all";
|
|
6
|
+
}
|
|
7
|
+
export declare const EvervaultInputContext: import("react").Context<EvervaultInputContextValue>;
|
|
4
8
|
export type EvervaultInput = Pick<TextInput, "isFocused" | "focus" | "blur" | "clear" | "measure" | "measureInWindow" | "measureLayout">;
|
|
5
9
|
export type BaseEvervaultInputProps = Omit<TextInputProps, "onChange" | "onChangeText" | "value" | "defaultValue">;
|
|
6
10
|
export declare function mask(format: string): MaskArray;
|
package/build/Input.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../src/Input.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../src/Input.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,SAAS,EACT,GAAG,EAMJ,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGzD,OAAkB,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAErE,MAAM,WAAW,0BAA0B;IACzC,cAAc,EAAE,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,KAAK,CAAC;CAC7D;AAED,eAAO,MAAM,qBAAqB,qDAEhC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,SAAS,EACP,WAAW,GACX,OAAO,GACP,MAAM,GACN,OAAO,GACP,SAAS,GACT,iBAAiB,GACjB,eAAe,CAClB,CAAC;AA4CF,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,cAAc,EACd,UAAU,GAAG,cAAc,GAAG,OAAO,GAAG,cAAc,CACvD,CAAC;AAEF,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAO9C;AAED,MAAM,WAAW,mBAAmB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACzE,SAAQ,uBAAuB;IAC/B,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAED,eAAO,MAAM,cAAc,EAuDrB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3C,KAAK,EAAE,mBAAmB,CAAC,MAAM,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAA;CAAE,KAC/D,SAAS,CAAC"}
|
package/build/index.cjs.js
CHANGED
|
@@ -7184,51 +7184,6 @@ const r=(t,r,o)=>{if(t&&"reportValidity"in t){const s=get(o,r);t.setCustomValidi
|
|
|
7184
7184
|
|
|
7185
7185
|
function n(r,e){for(var n={};r.length;){var s=r[0],t=s.code,i=s.message,a=s.path.join(".");if(!n[a])if("unionErrors"in s){var u=s.unionErrors[0].errors[0];n[a]={message:u.message,type:u.code};}else n[a]={message:i,type:t};if("unionErrors"in s&&s.unionErrors.forEach(function(e){return e.errors.forEach(function(e){return r.push(e)})}),e){var c=n[a].types,f=c&&c[s.code];n[a]=appendErrors(a,e,n,t,f?[].concat(f,s.message):s.message);}r.shift();}return n}function s(o$1,s,t){return void 0===t&&(t={}),function(i,a,u){try{return Promise.resolve(function(e,n){try{var a=Promise.resolve(o$1["sync"===t.mode?"parse":"parseAsync"](i,s)).then(function(e){return u.shouldUseNativeValidation&&o({},u),{errors:{},values:t.raw?Object.assign({},i):e}});}catch(r){return n(r)}return a&&a.then?a.then(void 0,n):a}(0,function(r){if(function(r){return Array.isArray(null==r?void 0:r.errors)}(r))return {values:{},errors:s$1(n(r.errors,!u.shouldUseNativeValidation&&"all"===u.criteriaMode),u)};throw r}))}catch(r){return Promise.reject(r)}}}
|
|
7186
7186
|
|
|
7187
|
-
const DEFAULT_ACCEPTED_BRANDS = [];
|
|
7188
|
-
const Card$1 = React.forwardRef(function Card({ children, defaultValues, onChange, acceptedBrands = DEFAULT_ACCEPTED_BRANDS, validationMode = "all", }, ref) {
|
|
7189
|
-
const evervault = useEvervault();
|
|
7190
|
-
const resolver = React.useMemo(() => {
|
|
7191
|
-
const schema = getCardFormSchema(acceptedBrands);
|
|
7192
|
-
return s(schema);
|
|
7193
|
-
}, [acceptedBrands]);
|
|
7194
|
-
const methods = useForm({
|
|
7195
|
-
defaultValues,
|
|
7196
|
-
resolver,
|
|
7197
|
-
mode: validationMode,
|
|
7198
|
-
shouldUseNativeValidation: false,
|
|
7199
|
-
});
|
|
7200
|
-
React.useEffect(() => {
|
|
7201
|
-
if (!onChange)
|
|
7202
|
-
return;
|
|
7203
|
-
let abortController;
|
|
7204
|
-
function handleChange(values) {
|
|
7205
|
-
if (abortController) {
|
|
7206
|
-
abortController.abort();
|
|
7207
|
-
}
|
|
7208
|
-
abortController = new AbortController();
|
|
7209
|
-
const signal = abortController.signal;
|
|
7210
|
-
requestAnimationFrame(async () => {
|
|
7211
|
-
const payload = await formatPayload(values, {
|
|
7212
|
-
encrypt: evervault.encrypt,
|
|
7213
|
-
form: methods,
|
|
7214
|
-
});
|
|
7215
|
-
if (signal.aborted)
|
|
7216
|
-
return;
|
|
7217
|
-
onChange?.(payload);
|
|
7218
|
-
});
|
|
7219
|
-
}
|
|
7220
|
-
handleChange(methods.getValues());
|
|
7221
|
-
const subscription = methods.watch(handleChange);
|
|
7222
|
-
return () => subscription.unsubscribe();
|
|
7223
|
-
}, [evervault.encrypt, onChange]);
|
|
7224
|
-
React.useImperativeHandle(ref, React.useCallback(() => ({
|
|
7225
|
-
reset() {
|
|
7226
|
-
methods.reset();
|
|
7227
|
-
},
|
|
7228
|
-
}), []));
|
|
7229
|
-
return jsxRuntime.jsx(FormProvider, { ...methods, children: children });
|
|
7230
|
-
});
|
|
7231
|
-
|
|
7232
7187
|
// Taken from https://github.com/gregberge/react-merge-refs
|
|
7233
7188
|
function mergeRefs(...refs) {
|
|
7234
7189
|
return (value) => {
|
|
@@ -7428,6 +7383,9 @@ var MaskInput = /*#__PURE__*/React__namespace.forwardRef(function (props, ref) {
|
|
|
7428
7383
|
}));
|
|
7429
7384
|
});
|
|
7430
7385
|
|
|
7386
|
+
const EvervaultInputContext = React.createContext({
|
|
7387
|
+
validationMode: "all",
|
|
7388
|
+
});
|
|
7431
7389
|
function useForwardedInputRef(ref) {
|
|
7432
7390
|
const inputRef = React.useRef(null);
|
|
7433
7391
|
React.useImperativeHandle(ref, React.useCallback(() => ({
|
|
@@ -7464,6 +7422,7 @@ function mask(format) {
|
|
|
7464
7422
|
});
|
|
7465
7423
|
}
|
|
7466
7424
|
const EvervaultInput = React.forwardRef(function EvervaultInput({ name, mask, ...props }, ref) {
|
|
7425
|
+
const { validationMode } = React.useContext(EvervaultInputContext);
|
|
7467
7426
|
const inputRef = useForwardedInputRef(ref);
|
|
7468
7427
|
const methods = useFormContext();
|
|
7469
7428
|
return (jsxRuntime.jsx(Controller, { control: methods.control, name: name, shouldUnregister: true, render: ({ field, fieldState }) => (jsxRuntime.jsx(MaskInput
|
|
@@ -7473,22 +7432,86 @@ const EvervaultInput = React.forwardRef(function EvervaultInput({ name, mask, ..
|
|
|
7473
7432
|
id: field.name, ...props,
|
|
7474
7433
|
// Strict props
|
|
7475
7434
|
ref: mergeRefs(inputRef, field.ref), editable: !field.disabled && (props.editable ?? true), onBlur: (evt) => {
|
|
7435
|
+
const shouldValidate = validationMode === "onBlur" ||
|
|
7436
|
+
validationMode === "onTouched" ||
|
|
7437
|
+
validationMode === "all";
|
|
7476
7438
|
methods.setValue(field.name, field.value, {
|
|
7477
7439
|
shouldDirty: true,
|
|
7478
7440
|
shouldTouch: true,
|
|
7479
|
-
shouldValidate
|
|
7441
|
+
shouldValidate,
|
|
7480
7442
|
});
|
|
7481
7443
|
props.onBlur?.(evt);
|
|
7482
7444
|
}, mask: mask, maskAutoComplete: !!mask, value: field.value, onChangeText: (masked, unmasked) => {
|
|
7445
|
+
const shouldValidate = (validationMode === "onTouched" && fieldState.isTouched) ||
|
|
7446
|
+
((validationMode === "onChange" || validationMode === "all") &&
|
|
7447
|
+
(!!fieldState.error || fieldState.isTouched));
|
|
7483
7448
|
methods.setValue(field.name, unmasked, {
|
|
7484
7449
|
shouldDirty: true,
|
|
7485
|
-
shouldValidate
|
|
7450
|
+
shouldValidate,
|
|
7486
7451
|
});
|
|
7487
7452
|
},
|
|
7488
7453
|
// Remove unwanted props
|
|
7489
7454
|
defaultValue: undefined, onChange: undefined })) }));
|
|
7490
7455
|
});
|
|
7491
7456
|
|
|
7457
|
+
const DEFAULT_ACCEPTED_BRANDS = [];
|
|
7458
|
+
const Card$1 = React.forwardRef(function Card({ children, defaultValues, onChange, onError, acceptedBrands = DEFAULT_ACCEPTED_BRANDS, validationMode = "all", }, ref) {
|
|
7459
|
+
const evervault = useEvervault();
|
|
7460
|
+
const resolver = React.useMemo(() => {
|
|
7461
|
+
const schema = getCardFormSchema(acceptedBrands);
|
|
7462
|
+
return s(schema);
|
|
7463
|
+
}, [acceptedBrands]);
|
|
7464
|
+
const methods = useForm({
|
|
7465
|
+
defaultValues,
|
|
7466
|
+
resolver,
|
|
7467
|
+
mode: validationMode,
|
|
7468
|
+
shouldUseNativeValidation: false,
|
|
7469
|
+
});
|
|
7470
|
+
const inputContext = React.useMemo(() => ({
|
|
7471
|
+
validationMode,
|
|
7472
|
+
}), [validationMode]);
|
|
7473
|
+
// Use refs to prevent closures from being captured
|
|
7474
|
+
const onChangeRef = React.useRef(onChange);
|
|
7475
|
+
onChangeRef.current = onChange;
|
|
7476
|
+
const onErrorRef = React.useRef(onError);
|
|
7477
|
+
onErrorRef.current = onError;
|
|
7478
|
+
React.useEffect(() => {
|
|
7479
|
+
if (!onChange)
|
|
7480
|
+
return;
|
|
7481
|
+
let abortController;
|
|
7482
|
+
function handleChange(values) {
|
|
7483
|
+
if (abortController) {
|
|
7484
|
+
abortController.abort();
|
|
7485
|
+
}
|
|
7486
|
+
abortController = new AbortController();
|
|
7487
|
+
const signal = abortController.signal;
|
|
7488
|
+
requestAnimationFrame(async () => {
|
|
7489
|
+
try {
|
|
7490
|
+
const payload = await formatPayload(values, {
|
|
7491
|
+
encrypt: evervault.encrypt,
|
|
7492
|
+
form: methods,
|
|
7493
|
+
});
|
|
7494
|
+
if (signal.aborted)
|
|
7495
|
+
return;
|
|
7496
|
+
onChangeRef.current?.(payload);
|
|
7497
|
+
}
|
|
7498
|
+
catch (error) {
|
|
7499
|
+
onErrorRef.current?.(error);
|
|
7500
|
+
}
|
|
7501
|
+
});
|
|
7502
|
+
}
|
|
7503
|
+
handleChange(methods.getValues());
|
|
7504
|
+
const subscription = methods.watch(handleChange);
|
|
7505
|
+
return () => subscription.unsubscribe();
|
|
7506
|
+
}, [evervault.encrypt]);
|
|
7507
|
+
React.useImperativeHandle(ref, React.useCallback(() => ({
|
|
7508
|
+
reset() {
|
|
7509
|
+
methods.reset();
|
|
7510
|
+
},
|
|
7511
|
+
}), []));
|
|
7512
|
+
return (jsxRuntime.jsx(FormProvider, { ...methods, children: jsxRuntime.jsx(EvervaultInputContext.Provider, { value: inputContext, children: children }) }));
|
|
7513
|
+
});
|
|
7514
|
+
|
|
7492
7515
|
const CardHolder = React.forwardRef(function CardHolder(props, ref) {
|
|
7493
7516
|
return (jsxRuntime.jsx(EvervaultInput, { placeholder: "Johnny Appleseed", ...props, ref: ref, name: "name", inputMode: "text", autoComplete: reactNative.Platform.select({
|
|
7494
7517
|
ios: "cc-name",
|