import * as React from 'react' ; import { Children , isValidElement , ReactElement , ReactNode , HtmlHTMLAttributes , } from 'react' ; import PropTypes from 'prop-types' ; import { FormWithRedirect , FormWithRedirectProps , MutationMode , Record , RedirectionSideEffect , OnSuccess , OnFailure , } from 'ra-core' ; import get from 'lodash/get' ; import { useRouteMatch , useLocation } from 'react-router' ; import { ClassesOverride } from '../types' ; import { TabbedFormView , useTabbedFormViewStyles } from './TabbedFormView' ; example typedef Props prop { ReactElement [ ] } FormTab prop { Object } initialValues prop { Function } validate prop { boolean } submitOnEnter prop { string } redirect prop { ReactElement } toolbar prop { string } variant prop { string } margin prop { boolean } sanitizeEmptyValues param { Props } props export const TabbedForm = ( props ) => { const match = useRouteMatch ( ) ; const location = useLocation ( ) ; const formRootPathname = match ? match . url : location . pathname ; return ( < FormWithRedirect { ... props } formRootPathname = { formRootPathname } render = { formProps => < TabbedFormView { ... formProps } / > } />); } ; TabbedForm . propTypes = { children : PropTypes . node , initialValues : PropTypes . oneOfType ( [ PropTypes . object , PropTypes . func ] ) , mutationMode : PropTypes . oneOf ( [ 'pessimistic' , 'optimistic' , 'undoable' ] ) , record : PropTypes . object , redirect : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . bool , PropTypes . func , ] ) , save : PropTypes . func , saving : PropTypes . bool , submitOnEnter : PropTypes . bool , undoable : PropTypes . bool , validate : PropTypes . func , sanitizeEmptyValues : PropTypes . bool , } ; export interface TabbedFormProps extends Omit < FormWithRedirectProps , 'render' > , Omit < HtmlHTMLAttributes < HTMLFormElement > , 'defaultValue' | 'onSubmit' | 'children' > { basePath ? : string ; children : ReactNode ; className ? : string ; classes ? : ClassesOverride < typeof useTabbedFormViewStyles > ; initialValues ? : any ; margin ? : 'none' | 'normal' | 'dense' ; mutationMode ? : MutationMode ; record ? : Record ; redirect ? : RedirectionSideEffect ; resource ? : string ; sanitizeEmptyValues ? : boolean ; save ? : ( data : Partial < Record > , redirectTo : RedirectionSideEffect , options ? : { onSuccess ? : OnSuccess ; onFailure ? : OnFailure ; } ) => void ; submitOnEnter ? : boolean ; syncWithLocation ? : boolean ; tabs ? : ReactElement ; toolbar ? : ReactElement ; deprecated undoable ? : boolean ; variant ? : 'standard' | 'outlined' | 'filled' ; warnWhenUnsavedChanges ? : boolean ; } export const findTabsWithErrors = ( children , errors ) => { console . warn ( 'Deprecated. FormTab now wrap their content inside a FormGroupContextProvider. If you implemented custom forms with tabs, please use the FormGroupContextProvider. See https://marmelab.com/react-admin/CreateEdit.html#grouping-inputs' ) ; return Children . toArray ( children ) . reduce ( ( acc , child ) => { if ( ! isValidElement ( child ) ) { return acc ; } const inputs = Children . toArray ( child . props . children ) ; if ( inputs . some ( input => isValidElement ( input ) && get ( errors , input . props . source ) ) ) { return [ ... acc , child . props . label ] ; } return acc ; } , [ ] ) ; } ;