import * as React from 'react' ; import { useCallback , FunctionComponent } from 'react' ; import PropTypes from 'prop-types' ; import get from 'lodash/get' ; import FormLabel from '@material-ui/core/FormLabel' ; import FormControl , { FormControlProps } from '@material-ui/core/FormControl' ; import FormGroup from '@material-ui/core/FormGroup' ; import FormHelperText from '@material-ui/core/FormHelperText' ; import { makeStyles } from '@material-ui/core/styles' ; import { CheckboxProps } from '@material-ui/core/Checkbox' ; import { FieldTitle , useInput , ChoicesInputProps , warning } from 'ra-core' ; import sanitizeInputRestProps from './sanitizeInputRestProps' ; import CheckboxGroupInputItem from './CheckboxGroupInputItem' ; import InputHelperText from './InputHelperText' ; import classnames from 'classnames' ; import Labeled from './Labeled' ; import { LinearProgress } from '../layout' ; import { ClassesOverride } from '../types' ; example example example example example example const CheckboxGroupInput = props => { const { choices = [ ] , className , classes : classesOverride , format , helperText , label , loaded , loading , margin = 'dense' , onBlur , onChange , onFocus , optionText , optionValue , options , parse , resource , row , source , translate , translateChoice , validate , ... rest } = props ; const classes = useStyles ( props ) ; warning ( source === undefined , `If you're not wrapping the CheckboxGroupInput inside a ReferenceArrayInput, you must provide the source prop` ) ; warning ( choices === undefined , `If you're not wrapping the CheckboxGroupInput inside a ReferenceArrayInput, you must provide the choices prop` ) ; const { id , input : { onChange : finalFormOnChange , onBlur : finalFormOnBlur , value } , isRequired , meta : { error , submitError , touched } , } = useInput ( { format , onBlur , onChange , onFocus , parse , resource , source , validate , ... rest , } ) ; const handleCheck = useCallback ( ( event , isChecked ) => { let newValue ; try { newValue = JSON . parse ( event . target . value ) ; } catch ( e ) { newValue = event . target . value ; } if ( isChecked ) { finalFormOnChange ( [ ... ( value || [ ] ) , ... [ newValue ] ] ) ; } else { finalFormOnChange ( value . filter ( v => v != newValue ) ) ; } finalFormOnBlur ( ) ; } , [ finalFormOnChange , finalFormOnBlur , value ] ) ; if ( loading ) { return ( < Labeled label = { label } source = { source } resource = { resource } className = { className } isRequired = { isRequired } margin = { margin } > < LinearProgress /> < /Labeled>); } return ( < FormControl component = "fieldset" margin = { margin } error = { touched && ! ! ( error || submitError ) } className = { classnames ( classes . root , className ) } { ... sanitizeRestProps ( rest ) } > < FormLabel component = "legend" className = { classes . label } > < FieldTitle label = { label } source = { source } resource = { resource } isRequired = { isRequired } / > < /FormLabel> < FormGroup row = { row } > { choices . map ( choice => ( < CheckboxGroupInputItem key = { get ( choice , optionValue ) } choice = { choice } id = { id } onChange = { handleCheck } options = { options } optionText = { optionText } optionValue = { optionValue } translateChoice = { translateChoice } value = { value } / > ) ) } < /FormGroup> < FormHelperText > < InputHelperText touched = { touched } error = { error || submitError } helperText = { helperText } / > < /FormHelperText> < /FormControl>); } ; const sanitizeRestProps = ( { refetch , setFilter , setPagination , setSort , loaded , touched , ... rest } ) => sanitizeInputRestProps ( rest ) ; const useStyles = makeStyles ( theme => ( { root : { } , label : { transform : 'translate(0, 8px) scale(0.75)' , transformOrigin : `top ${ theme . direction === 'ltr' ? 'left' : 'right' }` , } , } ) , { name : 'RaCheckboxGroupInput' } ) ; CheckboxGroupInput . propTypes = { choices : PropTypes . arrayOf ( PropTypes . object ) , className : PropTypes . string , label : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . bool ] ) , source : PropTypes . string , options : PropTypes . object , optionText : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . func , PropTypes . element , ] ) , optionValue : PropTypes . string , row : PropTypes . bool , resource : PropTypes . string , translateChoice : PropTypes . bool , } ; CheckboxGroupInput . defaultProps = { options : { } , optionText : 'name' , optionValue : 'id' , translateChoice : true , fullWidth : true , row : true , } ; export interface CheckboxGroupInputProps extends ChoicesInputProps < CheckboxProps > , FormControlProps { classes ? : ClassesOverride < typeof useStyles > ; } export default CheckboxGroupInput ;