remix-validated-form 4.5.0-beta.1 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,17 +1,17 @@
1
1
  $ vite build
2
2
  vite v2.9.5 building for production...
3
3
  transforming...
4
- ✓ 319 modules transformed.
4
+ ✓ 320 modules transformed.
5
5
  rendering chunks...
6
- dist/remix-validated-form.cjs.js  45.48 KiB / gzip: 17.10 KiB
7
- dist/remix-validated-form.cjs.js.map 252.52 KiB
8
- dist/remix-validated-form.es.js  101.16 KiB / gzip: 23.79 KiB
9
- dist/remix-validated-form.es.js.map 260.47 KiB
10
- dist/remix-validated-form.umd.js  45.73 KiB / gzip: 17.22 KiB
11
- dist/remix-validated-form.umd.js.map 252.50 KiB
6
+ dist/remix-validated-form.cjs.js  47.23 KiB / gzip: 17.41 KiB
7
+ dist/remix-validated-form.cjs.js.map 265.34 KiB
8
+ dist/remix-validated-form.es.js  104.23 KiB / gzip: 24.22 KiB
9
+ dist/remix-validated-form.es.js.map 273.50 KiB
10
+ dist/remix-validated-form.umd.js  47.48 KiB / gzip: 17.53 KiB
11
+ dist/remix-validated-form.umd.js.map 265.31 KiB
12
12
  
13
13
  [vite:dts] Start generate declaration files...
14
- [vite:dts] Declaration files built in 1849ms.
14
+ [vite:dts] Declaration files built in 1961ms.
15
15
  
16
16
  No name was provided for external module 'react' in output.globals – guessing 'React'
17
17
  No name was provided for external module '@remix-run/react' in output.globals – guessing 'react'
@@ -0,0 +1 @@
1
+ export declare const nestedObjectToPathObject: (val: any, acc: Record<string, any>, path: string) => any;
@@ -0,0 +1,47 @@
1
+ export const nestedObjectToPathObject = (val, acc, path) => {
2
+ if (Array.isArray(val)) {
3
+ val.forEach((v, index) => nestedObjectToPathObject(v, acc, `${path}[${index}]`));
4
+ return acc;
5
+ }
6
+ if (typeof val === "object") {
7
+ Object.entries(val).forEach(([key, value]) => {
8
+ const nextPath = path ? `${path}.${key}` : key;
9
+ nestedObjectToPathObject(value, acc, nextPath);
10
+ });
11
+ return acc;
12
+ }
13
+ if (val !== undefined) {
14
+ acc[path] = val;
15
+ }
16
+ return acc;
17
+ };
18
+ if (import.meta.vitest) {
19
+ const { describe, expect, it } = import.meta.vitest;
20
+ describe("nestedObjectToPathObject", () => {
21
+ it("should return an object with the correct path", () => {
22
+ const result = nestedObjectToPathObject({
23
+ a: 1,
24
+ b: 2,
25
+ c: { foo: "bar", baz: [true, false] },
26
+ d: [
27
+ { foo: "bar", baz: [true, false] },
28
+ { e: true, f: "hi" },
29
+ ],
30
+ g: undefined,
31
+ }, {}, "");
32
+ expect(result).toEqual({
33
+ a: 1,
34
+ b: 2,
35
+ "c.foo": "bar",
36
+ "c.baz[0]": true,
37
+ "c.baz[1]": false,
38
+ "d[0].foo": "bar",
39
+ "d[0].baz[0]": true,
40
+ "d[0].baz[1]": false,
41
+ "d[1].e": true,
42
+ "d[1].f": "hi",
43
+ });
44
+ expect(Object.keys(result)).toHaveLength(10);
45
+ });
46
+ });
47
+ }
@@ -0,0 +1,6 @@
1
+ export declare const getArray: (values: any, field: string) => unknown[];
2
+ export declare const swap: (array: unknown[], indexA: number, indexB: number) => void;
3
+ export declare const move: (array: unknown[], from: number, to: number) => void;
4
+ export declare const insert: (array: unknown[], index: number, value: unknown) => void;
5
+ export declare const remove: (array: unknown[], index: number) => void;
6
+ export declare const replace: (array: unknown[], index: number, value: unknown) => void;
@@ -0,0 +1,108 @@
1
+ import lodashGet from "lodash/get";
2
+ import lodashSet from "lodash/set";
3
+ import invariant from "tiny-invariant";
4
+ ////
5
+ // All of these array helpers are written in a way that mutates the original array.
6
+ // This is because we're working with immer.
7
+ ////
8
+ export const getArray = (values, field) => {
9
+ const value = lodashGet(values, field);
10
+ if (value === undefined || value === null) {
11
+ const newValue = [];
12
+ lodashSet(values, field, newValue);
13
+ return newValue;
14
+ }
15
+ invariant(Array.isArray(value), `FieldArray: defaultValue value for ${field} must be an array, null, or undefined`);
16
+ return value;
17
+ };
18
+ export const swap = (array, indexA, indexB) => {
19
+ const itemA = array[indexA];
20
+ const itemB = array[indexB];
21
+ array[indexA] = itemB;
22
+ array[indexB] = itemA;
23
+ };
24
+ export const move = (array, from, to) => {
25
+ const [item] = array.splice(from, 1);
26
+ array.splice(to, 0, item);
27
+ };
28
+ export const insert = (array, index, value) => {
29
+ array.splice(index, 0, value);
30
+ };
31
+ export const remove = (array, index) => {
32
+ array.splice(index, 1);
33
+ };
34
+ export const replace = (array, index, value) => {
35
+ array.splice(index, 1, value);
36
+ };
37
+ if (import.meta.vitest) {
38
+ const { describe, expect, it } = import.meta.vitest;
39
+ describe("getArray", () => {
40
+ it("shoud get a deeply nested array that can be mutated to update the nested value", () => {
41
+ const values = {
42
+ d: [
43
+ { foo: "bar", baz: [true, false] },
44
+ { e: true, f: "hi" },
45
+ ],
46
+ };
47
+ const result = getArray(values, "d[0].baz");
48
+ const finalValues = {
49
+ d: [
50
+ { foo: "bar", baz: [true, false, true] },
51
+ { e: true, f: "hi" },
52
+ ],
53
+ };
54
+ expect(result).toEqual([true, false]);
55
+ result.push(true);
56
+ expect(values).toEqual(finalValues);
57
+ });
58
+ it("should return an empty array that can be mutated if result is null or undefined", () => {
59
+ const values = {};
60
+ const result = getArray(values, "a.foo[0].bar");
61
+ const finalValues = {
62
+ a: { foo: [{ bar: ["Bob ross"] }] },
63
+ };
64
+ expect(result).toEqual([]);
65
+ result.push("Bob ross");
66
+ expect(values).toEqual(finalValues);
67
+ });
68
+ it("should throw if the value is defined and not an array", () => {
69
+ const values = { foo: "foo" };
70
+ expect(() => getArray(values, "foo")).toThrow();
71
+ });
72
+ });
73
+ describe("swap", () => {
74
+ it("should swap two items", () => {
75
+ const array = [1, 2, 3];
76
+ swap(array, 0, 1);
77
+ expect(array).toEqual([2, 1, 3]);
78
+ });
79
+ });
80
+ describe("move", () => {
81
+ it("should move an item to a new index", () => {
82
+ const array = [1, 2, 3];
83
+ move(array, 0, 1);
84
+ expect(array).toEqual([2, 1, 3]);
85
+ });
86
+ });
87
+ describe("insert", () => {
88
+ it("should insert an item at a new index", () => {
89
+ const array = [1, 2, 3];
90
+ insert(array, 1, 4);
91
+ expect(array).toEqual([1, 4, 2, 3]);
92
+ });
93
+ });
94
+ describe("remove", () => {
95
+ it("should remove an item at a given index", () => {
96
+ const array = [1, 2, 3];
97
+ remove(array, 1);
98
+ expect(array).toEqual([1, 3]);
99
+ });
100
+ });
101
+ describe("replace", () => {
102
+ it("should replace an item at a given index", () => {
103
+ const array = [1, 2, 3];
104
+ replace(array, 1, 4);
105
+ expect(array).toEqual([1, 4, 3]);
106
+ });
107
+ });
108
+ }
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ export declare const FieldArrayContext: React.Context<{
3
+ defaultValues: any[];
4
+ name: string;
5
+ } | null>;
6
+ export declare type FieldArrayHelpers = {
7
+ push: (item: any) => void;
8
+ swap: (indexA: number, indexB: number) => void;
9
+ move: (from: number, to: number) => void;
10
+ insert: (index: number, value: any) => void;
11
+ unshift: () => void;
12
+ remove: (index: number) => void;
13
+ pop: () => void;
14
+ replace: (index: number, value: any) => void;
15
+ };
16
+ export declare type FieldArrayProps = {
17
+ name: string;
18
+ children: (itemDefaults: any[], helpers: FieldArrayHelpers) => React.ReactNode;
19
+ formId?: string;
20
+ };
21
+ export declare const FieldArray: ({ name, children, formId }: FieldArrayProps) => JSX.Element;
@@ -0,0 +1,50 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useMemo, createContext } from "react";
3
+ import invariant from "tiny-invariant";
4
+ import { useInternalFormContext } from "../hooks";
5
+ import { useControllableValue } from "./controlledFields";
6
+ import { useFormStore } from "./storeHooks";
7
+ const useFieldArray = (context, field) => {
8
+ // TODO: Fieldarrays need to handle/update these things, too:
9
+ // - touchedFields & fieldErrors should be updated when fields are added/removed
10
+ // - Could probably move some of these callbacks into the store
11
+ // - There's a bug where adding a new field to the fieldarray validates the new field.
12
+ // - For some reason this only happens in the test-app, but not in the docs app.
13
+ const [value] = useControllableValue(context, field);
14
+ const arr = useFormStore(context.formId, (state) => state.controlledFields.array);
15
+ const helpers = useMemo(() => ({
16
+ push: (item) => {
17
+ arr.push(field, item);
18
+ },
19
+ swap: (indexA, indexB) => {
20
+ arr.swap(field, indexA, indexB);
21
+ },
22
+ move: (from, to) => {
23
+ arr.move(field, from, to);
24
+ },
25
+ insert: (index, value) => {
26
+ arr.insert(field, index, value);
27
+ },
28
+ unshift: () => {
29
+ arr.unshift(field);
30
+ },
31
+ remove: (index) => {
32
+ arr.remove(field, index);
33
+ },
34
+ pop: () => {
35
+ arr.pop(field);
36
+ },
37
+ replace: (index, value) => {
38
+ arr.replace(field, index, value);
39
+ },
40
+ }), [arr, field]);
41
+ return [value, helpers];
42
+ };
43
+ export const FieldArrayContext = createContext(null);
44
+ export const FieldArray = ({ name, children, formId }) => {
45
+ const context = useInternalFormContext(formId, "FieldArray");
46
+ const [value, helpers] = useFieldArray(context, name);
47
+ invariant(value === undefined || value === null || Array.isArray(value), `FieldArray: defaultValue value for ${name} must be an array, null, or undefined`);
48
+ const contextValue = useMemo(() => ({ defaultValues: value !== null && value !== void 0 ? value : [], name }), [name, value]);
49
+ return (_jsx(FieldArrayContext.Provider, { value: contextValue, children: children(contextValue.defaultValues, helpers) }, void 0));
50
+ };
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remix-validated-form",
3
- "version": "4.5.0-beta.1",
3
+ "version": "4.5.0",
4
4
  "description": "Form component and utils for easy form validation in remix",
5
5
  "browser": "./dist/remix-validated-form.cjs.js",
6
6
  "main": "./dist/remix-validated-form.umd.js",