Skip to content

Commit

Permalink
Merge pull request #27 from iusehooks/ADD_INNER_REF_AND_SETVALUE_CUST…
Browse files Browse the repository at this point in the history
…OM_CMP

innerRef - setValue for type='custom'
  • Loading branch information
antoniopangallo authored Jan 12, 2021
2 parents e0717d1 + 4b9b826 commit 4bb7cf8
Show file tree
Hide file tree
Showing 29 changed files with 275 additions and 93 deletions.
22 changes: 20 additions & 2 deletions __tests__/Form.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import React from "react";
import { render, cleanup, fireEvent, waitFor } from "@testing-library/react";
import {
render,
cleanup,
fireEvent,
waitFor,
act
} from "@testing-library/react";

import { SimpleFormTestSumbission } from "./helpers/components/SimpleFormTestSumbission";
import { CollectionDynamicCart } from "./helpers/components/CollectionDynamicField";
Expand All @@ -12,7 +18,7 @@ import {
} from "./helpers/components/ComplexForm";
import { mountForm } from "./helpers/utils/mountForm";

import { Input, Select, Collection, TextArea } from "./../src";
import { Input, Select, Collection, TextArea, Form } from "./../src";

const dataTestid = "email";
const typeInput = "text";
Expand Down Expand Up @@ -514,6 +520,18 @@ describe("Component => Form", () => {
);
});

it("should accept an innerRef prop to access to DOM", () => {
const name = "foo";
const ref = React.createRef();

act(() => {
render(<Form innerRef={ref} name={name} />);
});

expect(ref.current).toBeDefined();
expect(ref.current.name).toBe(name);
});

it("should run reducer functions applied to Form on fields removal", () => {
const reducers = jest.fn(value => {
const { cart = {} } = value;
Expand Down
21 changes: 17 additions & 4 deletions __tests__/Input.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,23 @@ describe("Component => Input", () => {
expect(fileInputMultiple.files[1]).toStrictEqual(files[1]);
});

it("should accept an innerRef prop to access to DOM", () => {
const type = "text";
const name = "email";
const ref = React.createRef();
const children = [
<Input key="1" innerRef={ref} type={type} name={name} value="1" />
];
act(() => {
mountForm({ children });
});

expect(ref.current).toBeDefined();
expect(ref.current.type).toBe(type);
expect(ref.current.value).toBe("1");
expect(ref.current.name).toBe(name);
});

it("should trigger onChange event when the Input value changes", () => {
const onChangeInput = jest.fn(value => value);
const children = [
Expand Down Expand Up @@ -518,11 +535,7 @@ describe("Component => Input", () => {
expect(checkbox.checked).toBe(true);

onInit.mockClear();
children = [<Input key="1" type="custom" name={name} value={{ a: 1 }} />];
mountForm({ props, children });
expect(onInit).toHaveBeenCalledWith({ [name]: { a: 1 } }, true);

onInit.mockClear();
children = [
<Input
key="1"
Expand Down
20 changes: 20 additions & 0 deletions __tests__/Select.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,26 @@ describe("Component => Select", () => {
expect(onReset).toHaveBeenCalledWith({ [name]: ["1", "2"] }, true);
});

it("should accept an innerRef prop to access to DOM", () => {
const name = "test";
const value = "1";
const ref = React.createRef();
const children = [
<Select key="1" innerRef={ref} name={name} value={value}>
<option value="" />
<option value={value}>{value}</option>
</Select>
];

act(() => {
mountForm({ children });
});

expect(ref.current).toBeDefined();
expect(ref.current.value).toBe("1");
expect(ref.current.name).toBe(name);
});

it("should use a reducer to reduce the Select value", () => {
const props = { onInit };
const reducer = value => value + 2;
Expand Down
20 changes: 19 additions & 1 deletion __tests__/TextArea.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { fireEvent, cleanup } from "@testing-library/react";
import { fireEvent, cleanup, act } from "@testing-library/react";
import { mountForm } from "./helpers/utils/mountForm";
import { TextArea } from "./../src";

Expand Down Expand Up @@ -29,4 +29,22 @@ describe("Component => TextArea", () => {
expect(onChange).toHaveBeenCalledWith({ [name]: value }, true);
expect(textArea.value).toBe(value);
});

it("should accept an innerRef prop to access to DOM", () => {
const type = "textarea";
const name = "foo";
const ref = React.createRef();
const children = [
<TextArea key="1" innerRef={ref} name={name} value="1" />
];

act(() => {
mountForm({ children });
});

expect(ref.current).toBeDefined();
expect(ref.current.type).toBe(type);
expect(ref.current.value).toBe("1");
expect(ref.current.name).toBe(name);
});
});
8 changes: 7 additions & 1 deletion __tests__/helpers/components/CustomField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ export const CustomField = withIndex(
valueToChange = "5"
}) => {
const props = useField({ type, name, value });
const onChange = () => props.onChange({ target: { value: valueToChange } });
const onChange = () => {
if (type === "custom") {
props.setValue(valueToChange);
} else {
props.onChange({ target: { value: valueToChange } });
}
};
useEffect(() => {
jestFN(props.value);
}, []);
Expand Down
13 changes: 11 additions & 2 deletions __tests__/hooks/useField.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,18 @@ describe("Hooks => useField", () => {
const props = { onInit, onChange };
const initial = { a: "test" };
const jestFN = jest.fn();
const valueToChange = prev => {
return { ...prev, a: "BeBo" };
};

const children = [
<CustomField key="1" name={name} value={initial} jestFN={jestFN} />
<CustomField
key="1"
valueToChange={valueToChange}
name={name}
value={initial}
jestFN={jestFN}
/>
];
const { getByTestId } = mountForm({ children, props });

Expand All @@ -70,7 +79,7 @@ describe("Hooks => useField", () => {
fireEvent.click(buttonChange);
});

expect(onChange).toHaveBeenCalledWith({ [name]: "5" }, true);
expect(onChange).toHaveBeenCalledWith({ [name]: { a: "BeBo" } }, true);
});

it("should render a Field of type text with an initial value passed as prop", () => {
Expand Down
12 changes: 7 additions & 5 deletions docs/Collection.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Collection, useValidation, Input, useAsyncValidation } from './../src';
It creates a nested piece of state within a Form. <br />
A Collection can be of type: **object** or **array**.

### Props
## Props

**`object`**: boolean

Expand All @@ -24,13 +24,15 @@ It creates a collecion of type **object** if "true".

It creates a collecion of type **array** if "true".

**`name`**: string - (except for **Collection** children of Collection of type array)
**`name`**: string

A field's name in Usetheform state.
A field's name in Usetheform state. <br />
If your Collection is rendered within a `<Collection array />`, **name** is not allowed as prop.

**`index`**: string - (only for **Collection** children of Collection of type array)
**`index`**: string

A field's index in array Collection.
A field's index in array Collection. <br />
**index** is only allowed If your Collection is rendered within a `<Collection array /> `.

**`touched`**: boolean

Expand Down
11 changes: 10 additions & 1 deletion docs/Form.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Input } from './../src';
# Form
The Form is the most important component in Usetheform. It renders all the Fields and keeps synchronized the entire form state.

### Props
## Props

**`onInit`**: function

Expand Down Expand Up @@ -81,6 +81,15 @@ Possible values:
- An absolute URL - points to another web site (like action="http://www.example.com/example.htm")
- A relative URL - points to a file within a web site (like action="example.htm")
**`innerRef`**: object (a mutable ref object)
When you need to access the underlying DOM node created by Form (e.g. to call focus), you can use a ref to store a reference to the form dom node.
```javascript
const ref = useRef(null)
<Form innerRef={ref} name="form">...fields...</Form>
```
## Basic usage
### Example 1
Expand Down
2 changes: 1 addition & 1 deletion docs/FormContext.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Input, useForm } from './../src';

It is a react component that provides a context of the "form" at wider level.

### Props
## Props

**`onInit`**: function

Expand Down
21 changes: 16 additions & 5 deletions docs/Input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ import { Input, useValidation, useAsyncValidation } from './../src';
# Input
It renders all the inputs of type listed at: [W3schools Input Types](https://www.w3schools.com/html/html_form_input_types.asp) and accepts as props any html attribute listed at: [Html Input Attributes](https://www.w3schools.com/tags/tag_input.asp).

### Props
## Props

**`type`**: string

Type listed at: [W3schools Input Types](https://www.w3schools.com/html/html_form_input_types.asp).

**`name`**: string - (except for **Input** children of Collection of type array)
**`name`**: string

A field's name in Usetheform state.
A field's name in Usetheform state. <br />
If your Input is rendered within a `<Collection array />`, **name** is not allowed as prop.

**`index`**: string - (only for **Input** children of Collection of type array)
**`index`**: string

A field's index in array Collection.
A field's index in array Collection. <br />
**index** is only allowed If your Input is rendered within a `<Collection array /> `.

**`value`**: string | number

Expand All @@ -48,6 +50,15 @@ If *true* validation messages (sync and async) will be showing only when the eve
An array whose values correspond to different reducing functions.
Reducers functions specify how the Input's value change.

**`innerRef`**: object (a mutable ref object)

When you need to access the underlying DOM node created by Input (e.g. to call focus), you can use a ref to store a reference to the input dom node.

```javascript
const ref = useRef(null)
<Input innerRef={ref} type="text" name="test" />
```

## Basic usage

```javascript
Expand Down
25 changes: 20 additions & 5 deletions docs/Select.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ import { Select, useValidation, useAsyncValidation } from './../src';
The *select* element is used to create a drop-down list. <br />
It accepts as props any html attribute listed at: [Html Select Attributes](https://www.w3schools.com/tags/tag_select.asp).

### Props
## Props

**`name`**: string - (except for **Select** children of Collection of type array)
**`name`**: string

A field's name in Usetheform state.
A field's name in Usetheform state. <br />
If your Select is rendered within a `<Collection array />`, **name** is not allowed as prop.

**`index`**: string - (only for **Select** children of Collection of type array)
**`index`**: string

A field's index in array Collection.
A field's index in array Collection. <br />
**index** is only allowed If your Select is rendered within a `<Collection array /> `.

**`value`**: string

Expand All @@ -32,6 +34,10 @@ A field that has been touched/visited. Default value *false*.

If *true* validation messages (sync and async) will be showing only when the event onBlur of the field is triggered by the user action.

**`multiple`**: boolean

When present, it specifies that multiple options can be selected at once. Default value *false*.

**`reducers`**: array | function

```javascript
Expand All @@ -41,6 +47,15 @@ If *true* validation messages (sync and async) will be showing only when the eve
An array whose values correspond to different reducing functions.
Reducers functions specify how the Select's value change.

**`innerRef`**: object (a mutable ref object)

When you need to access the underlying DOM node created by Select (e.g. to call focus), you can use a ref to store a reference to the select dom node.

```javascript
const ref = useRef(null)
<Select innerRef={ref} name="test">...options...</Select>
```

## Basic usage

### Single options
Expand Down
21 changes: 16 additions & 5 deletions docs/TextArea.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ import { TextArea, useValidation, useAsyncValidation } from './../src';
# TextArea
It renders a *textarea* element: [W3schools Textarea](https://www.w3schools.com/tags/tag_textarea.asp) and accepts as props any html attribute listed at: [Html Textarea Attributes](https://www.w3schools.com/tags/tag_textarea.asp).

### Props
## Props

**`name`**: string - (except for **TextArea** children of Collection of type array)
**`name`**: string

A field's name in Usetheform state.
A field's name in Usetheform state. <br />
If your TextArea is rendered within a `<Collection array />`, **name** is not allowed as prop.

**`index`**: string - (only for **TextArea** children of Collection of type array)
**`index`**: string

A field's index in array Collection.
A field's index in array Collection. <br />
**index** is only allowed If your TextArea is rendered within a `<Collection array /> `.

**`value`**: string

Expand All @@ -40,6 +42,15 @@ If *true* validation messages (sync and async) will be showing only when the eve
An array whose values correspond to different reducing functions.
Reducers functions specify how the TextArea's value change.

**`innerRef`**: object (a mutable ref object)

When you need to access the underlying DOM node created by TextArea (e.g. to call focus), you can use a ref to store a reference to the textarea dom node.

```javascript
const ref = useRef(null)
<TextArea innerRef={ref} name="textarea" value="test" />
```

## Basic usage

```javascript
Expand Down
Loading

0 comments on commit 4bb7cf8

Please sign in to comment.