@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.
@@ -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', 33)
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 {
@@ -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
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Root.d.ts","sourceRoot":"","sources":["../../src/Card/Root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,EAKlB,MAAM,OAAO,CAAC;AACf,OAAO,EAAiB,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AASjE,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;;;;;;;;;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,4FAgEf,CAAC"}
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;
@@ -1 +1 @@
1
- {"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../src/Input.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,SAAS,EACT,GAAG,EAKJ,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,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,EA6CrB,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"}
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"}
@@ -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: true,
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: !!fieldState.error || fieldState.isTouched,
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",