diff --git a/packages/react-admin-core/src/FinalForm.tsx b/packages/react-admin-core/src/FinalForm.tsx index ecdc5c947ac..da879b81db6 100644 --- a/packages/react-admin-core/src/FinalForm.tsx +++ b/packages/react-admin-core/src/FinalForm.tsx @@ -10,6 +10,7 @@ import { ApolloConsumer } from "react-apollo"; import { Form, FormRenderProps } from "react-final-form"; import { EditDialogApiContext } from "./EditDialogApiContext"; import * as sc from "./FinalForm.sc"; +import { CorrectFormRenderProps, renderComponent } from "./FinalFormRenderComponent"; import { IStackApi, StackApiContext } from "./stack"; import { IWithDirtyHandlerApiProps, withDirtyHandlerApi } from "./table/withDirtyHandlerApi"; import { IWithTableQueryProps, withTableQueryContext } from "./table/withTableQueryContext"; @@ -82,12 +83,12 @@ class FinalForm extends React.Component { ); } - private renderForm = (formRenderProps: FormRenderProps) => { + private renderForm = (formRenderProps: CorrectFormRenderProps) => { this.formRenderProps = formRenderProps; const { classes } = this.props; return (
- {this.props.children} + {renderComponent(formRenderProps)} {formRenderProps.submitError &&
{formRenderProps.submitError}
} {editDialogApi => { diff --git a/packages/react-admin-core/src/finalFormRenderComponent.tsx b/packages/react-admin-core/src/finalFormRenderComponent.tsx new file mode 100644 index 00000000000..a464ff7fb40 --- /dev/null +++ b/packages/react-admin-core/src/finalFormRenderComponent.tsx @@ -0,0 +1,22 @@ +import * as React from "react"; +import { AnyObject, FormRenderProps, RenderableProps } from "react-final-form"; + +// call to render-children consists of ...rest, ...renderProps, __versions, see https://github.com/final-form/react-final-form/blob/master/src/ReactFinalForm.js#L195 +// whereby ...rest is FormProps destructed with all Config attributes and FormProps specific attributes, see https://github.com/final-form/react-final-form/blob/master/src/ReactFinalForm.js#L42 +// which left RenderableProps in ...rest. (click FormProps and check extends). But they are missing in FormRenderProps-Type +export type CorrectFormRenderProps = FormRenderProps & RenderableProps>; + +// Render children like final-form does. +export function renderComponent(formRenderProps: CorrectFormRenderProps) { + const { render, children, component } = formRenderProps; // not using this.props as final-form-render-component does also use function-parameters and this solves "multiple implementations" hint + if (component) { + return React.createElement>(component, { ...formRenderProps, children, render }); + } + if (render) { + return render(children === undefined ? formRenderProps : { ...formRenderProps, children }); // inject children back in + } + if (typeof children !== "function") { + return children; + } + return children(formRenderProps); +} diff --git a/packages/react-admin-core/src/table/TableFilterFinalForm.tsx b/packages/react-admin-core/src/table/TableFilterFinalForm.tsx index ccaf1983702..e25edbc4b5b 100644 --- a/packages/react-admin-core/src/table/TableFilterFinalForm.tsx +++ b/packages/react-admin-core/src/table/TableFilterFinalForm.tsx @@ -4,7 +4,8 @@ import CancelIcon from "@material-ui/icons/Cancel"; import { debounce } from "debounce"; import isEqual = require("lodash.isequal"); import * as React from "react"; -import { Form, FormRenderProps, FormSpy, FormSpyRenderProps } from "react-final-form"; +import { AnyObject, Form, FormProps, FormSpy, FormSpyRenderProps } from "react-final-form"; +import { CorrectFormRenderProps, renderComponent } from "../finalFormRenderComponent"; import * as sc from "./TableFilterFinalForm.sc"; import { IWithTableQueryProps, withTableQueryContext } from "./withTableQueryContext"; @@ -45,17 +46,43 @@ class AutoSave extends React.Component { const ExtendedAutoSave = withTableQueryContext(AutoSave); -interface IProps { +type Props = Omit, "onSubmit"> & { modifySubmitVariables?: (variables: any) => any; headline?: string; resetButton?: boolean; -} + onSubmit?: FormProps["onSubmit"]; +}; + // tslint:disable-next-line:max-classes-per-file -export class TableFilterFinalForm extends React.Component { +export class TableFilterFinalForm extends React.Component> { public render() { - return ; + // remove render, children and component from forwardProps as we define render and those would interfere + const { modifySubmitVariables, headline, resetButton, render, children, component, ...forwardProps } = this.props; + return ( + { + return; + } + } + render={this.renderForm} + {...forwardProps} + /> + ); } - private renderForm = (formRenderProps: FormRenderProps) => { + private renderForm = (formRenderProps: CorrectFormRenderProps) => { + // remove render as this is defined by us and should not be contained in childFormRenderProps + const { render: ownRender, ...finalFormChildrenRenderProps } = formRenderProps; + const { render, children, component } = this.props; + // add render, children and component from own-props to childFormRenderProps as they are used to render the children + const completeFinalFormChildRenderProps = { + ...finalFormChildrenRenderProps, + render, + children, + component, + }; return ( {(this.props.headline || this.props.resetButton) && ( @@ -87,14 +114,11 @@ export class TableFilterFinalForm extends React.Component { )} - {this.props.children} + {renderComponent(completeFinalFormChildRenderProps)} {renderProps => } ); }; - private handleSubmit = () => { - return; - }; }