Skip to content

Commit

Permalink
Add "formElement" props to allow any element to be render as a form (#…
Browse files Browse the repository at this point in the history
…599)

* add as props to render any elements

* add documentation

* rename 'as' props to 'formElement'

Co-authored-by: Thibaut Maréchal <t.marechal@evs.com>
  • Loading branch information
ThibautMarechal and ThibautMarechal committed Jan 20, 2021
1 parent 24c6285 commit da6ed38
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
15 changes: 15 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- [updateInputsWithError()](#updateInputsWithError)
- [updateInputsWithValue()](#updateInputsWithValue)
- [validationErrors](#validationErrors)
- [formElement](#formElement)
- [withFormsy](#withFormsy)
- [errorMessage](#errorMessage)
- [errorMessages](#errorMessages)
Expand Down Expand Up @@ -293,6 +294,20 @@ class MyForm extends React.Component {
With the `preventExternalInvalidation` the input will not be invalidated though it has an error when
`updateInputsWithError()` or an `invalidate` callback is called.

### <a id="formElement">formElement</a>
By default Formsy render the form with the HTML `form` element.
If you want to override this behaviour, you can pass the element to render in the `formElement` props

```jsx
<Formsy formElement="div">
...
</Formsy>

<Formsy formElement={MyCustomFormElement}>
...
</Formsy>
```

### <a id="withFormsy">`withFormsy`</a>

All Formsy input components must be wrapped in the `withFormsy` higher-order component, which provides the following
Expand Down
16 changes: 16 additions & 0 deletions __tests__/Formsy.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1049,3 +1049,19 @@ describe('onSubmit/onValidSubmit/onInvalidSubmit', () => {
});
});
});

describe('<Formsy /> can render any tag or element with the props as', () => {
it('as div', () => {
const form = mount(
<Formsy formElement="div" />
);
expect(form.find('div').length).toBe(1)
})
it('as CustumElement', () => {
const CustomElement = ({ children }) => <div>{children}</div>;
const form = mount(
<Formsy formElement={CustomElement} />
);
expect(form.find(CustomElement).length).toBe(1)
})
})
19 changes: 16 additions & 3 deletions src/Formsy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ type OnSubmitCallback = (
event: React.SyntheticEvent<React.FormHTMLAttributes<any>>,
) => void;

type FormElementType =
| string
| React.ComponentType<{
onReset?: (e: React.SyntheticEvent) => void;
onSubmit?: (e: React.SyntheticEvent) => void;
disabled?: boolean;
children?: React.ReactChildren;
}>;

export interface FormsyProps extends FormHTMLAttributesCleaned {
disabled: boolean;
mapping: null | ((model: IModel) => IModel);
Expand All @@ -41,6 +50,7 @@ export interface FormsyProps extends FormHTMLAttributesCleaned {
preventDefaultSubmit?: boolean;
preventExternalInvalidation?: boolean;
validationErrors?: null | object;
formElement?: FormElementType;
}

export interface FormsyState {
Expand All @@ -66,6 +76,7 @@ export class Formsy extends React.Component<FormsyProps, FormsyState> {
public static propTypes = {
disabled: PropTypes.bool,
mapping: PropTypes.func,
formElement: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.func]),
onChange: PropTypes.func,
onInvalid: PropTypes.func,
onInvalidSubmit: PropTypes.func,
Expand All @@ -91,6 +102,7 @@ export class Formsy extends React.Component<FormsyProps, FormsyState> {
preventDefaultSubmit: true,
preventExternalInvalidation: false,
validationErrors: {},
formElement: 'form',
};

private readonly throttledValidateForm: () => void;
Expand Down Expand Up @@ -476,7 +488,8 @@ export class Formsy extends React.Component<FormsyProps, FormsyState> {
preventDefaultSubmit,
preventExternalInvalidation,
validationErrors,
/* eslint-enable @typescript-eslint/no-unused-vars */
disabled,
formElement,
...nonFormsyProps
} = this.props;
const { contextValue } = this.state;
Expand All @@ -487,12 +500,12 @@ export class Formsy extends React.Component<FormsyProps, FormsyState> {
value: contextValue,
},
React.createElement(
'form',
formElement,
{
onReset: this.resetInternal,
onSubmit: this.submit,
...nonFormsyProps,
disabled: false,
disabled,
},
children,
),
Expand Down

0 comments on commit da6ed38

Please sign in to comment.