-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[docs] Add full custom field creation example (mui#15194)
Signed-off-by: Flavien DELANGLE <[email protected]> Signed-off-by: Lukas Tyla <[email protected]> Co-authored-by: Lukas Tyla <[email protected]>
- Loading branch information
1 parent
aa515ec
commit c7f8cd6
Showing
6 changed files
with
337 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
docs/data/date-pickers/custom-field/behavior-tutorial/MaterialDatePicker.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import * as React from 'react'; | ||
import dayjs from 'dayjs'; | ||
import TextField from '@mui/material/TextField'; | ||
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; | ||
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; | ||
import { DatePicker } from '@mui/x-date-pickers/DatePicker'; | ||
import { | ||
useSplitFieldProps, | ||
useParsedFormat, | ||
usePickerContext, | ||
} from '@mui/x-date-pickers/hooks'; | ||
import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; | ||
|
||
function CustomDateField(props) { | ||
// TextField does not support slots and slotProps before `@mui/material` v6.0 | ||
const { slots, slotProps, ...other } = props; | ||
const { internalProps, forwardedProps } = useSplitFieldProps(other, 'date'); | ||
|
||
const pickerContext = usePickerContext(); | ||
const placeholder = useParsedFormat(); | ||
const [inputValue, setInputValue] = useInputValue(); | ||
|
||
// Check if the current value is valid or not. | ||
const { hasValidationError } = useValidation({ | ||
value: pickerContext.value, | ||
timezone: pickerContext.timezone, | ||
props: internalProps, | ||
validator: validateDate, | ||
}); | ||
|
||
const handleChange = (event) => { | ||
const newInputValue = event.target.value; | ||
const newValue = dayjs(newInputValue, pickerContext.fieldFormat); | ||
setInputValue(newInputValue); | ||
pickerContext.setValue(newValue); | ||
}; | ||
|
||
return ( | ||
<TextField | ||
{...forwardedProps} | ||
placeholder={placeholder} | ||
value={inputValue} | ||
onChange={handleChange} | ||
error={hasValidationError} | ||
/> | ||
); | ||
} | ||
|
||
function useInputValue() { | ||
const pickerContext = usePickerContext(); | ||
const [lastValueProp, setLastValueProp] = React.useState(pickerContext.value); | ||
const [inputValue, setInputValue] = React.useState(() => | ||
createInputValue(pickerContext.value, pickerContext.fieldFormat), | ||
); | ||
|
||
if (lastValueProp !== pickerContext.value) { | ||
setLastValueProp(pickerContext.value); | ||
if (pickerContext.value && pickerContext.value.isValid()) { | ||
setInputValue( | ||
createInputValue(pickerContext.value, pickerContext.fieldFormat), | ||
); | ||
} | ||
} | ||
|
||
return [inputValue, setInputValue]; | ||
} | ||
|
||
function createInputValue(value, format) { | ||
if (value == null) { | ||
return ''; | ||
} | ||
|
||
return value.isValid() ? value.format(format) : ''; | ||
} | ||
|
||
function CustomFieldDatePicker(props) { | ||
return ( | ||
<DatePicker slots={{ ...props.slots, field: CustomDateField }} {...props} /> | ||
); | ||
} | ||
|
||
export default function MaterialDatePicker() { | ||
return ( | ||
<LocalizationProvider dateAdapter={AdapterDayjs}> | ||
<CustomFieldDatePicker /> | ||
</LocalizationProvider> | ||
); | ||
} |
92 changes: 92 additions & 0 deletions
92
docs/data/date-pickers/custom-field/behavior-tutorial/MaterialDatePicker.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import * as React from 'react'; | ||
import dayjs, { Dayjs } from 'dayjs'; | ||
import TextField from '@mui/material/TextField'; | ||
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; | ||
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; | ||
import { | ||
DatePicker, | ||
DatePickerProps, | ||
DatePickerFieldProps, | ||
} from '@mui/x-date-pickers/DatePicker'; | ||
import { | ||
useSplitFieldProps, | ||
useParsedFormat, | ||
usePickerContext, | ||
} from '@mui/x-date-pickers/hooks'; | ||
import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; | ||
|
||
function CustomDateField(props: DatePickerFieldProps) { | ||
// TextField does not support slots and slotProps before `@mui/material` v6.0 | ||
const { slots, slotProps, ...other } = props; | ||
const { internalProps, forwardedProps } = useSplitFieldProps(other, 'date'); | ||
|
||
const pickerContext = usePickerContext(); | ||
const placeholder = useParsedFormat(); | ||
const [inputValue, setInputValue] = useInputValue(); | ||
|
||
// Check if the current value is valid or not. | ||
const { hasValidationError } = useValidation({ | ||
value: pickerContext.value, | ||
timezone: pickerContext.timezone, | ||
props: internalProps, | ||
validator: validateDate, | ||
}); | ||
|
||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { | ||
const newInputValue = event.target.value; | ||
const newValue = dayjs(newInputValue, pickerContext.fieldFormat); | ||
setInputValue(newInputValue); | ||
pickerContext.setValue(newValue); | ||
}; | ||
|
||
return ( | ||
<TextField | ||
{...forwardedProps} | ||
placeholder={placeholder} | ||
value={inputValue} | ||
onChange={handleChange} | ||
error={hasValidationError} | ||
/> | ||
); | ||
} | ||
|
||
function useInputValue() { | ||
const pickerContext = usePickerContext(); | ||
const [lastValueProp, setLastValueProp] = React.useState(pickerContext.value); | ||
const [inputValue, setInputValue] = React.useState(() => | ||
createInputValue(pickerContext.value, pickerContext.fieldFormat), | ||
); | ||
|
||
if (lastValueProp !== pickerContext.value) { | ||
setLastValueProp(pickerContext.value); | ||
if (pickerContext.value && pickerContext.value.isValid()) { | ||
setInputValue( | ||
createInputValue(pickerContext.value, pickerContext.fieldFormat), | ||
); | ||
} | ||
} | ||
|
||
return [inputValue, setInputValue] as const; | ||
} | ||
|
||
function createInputValue(value: Dayjs | null, format: string) { | ||
if (value == null) { | ||
return ''; | ||
} | ||
|
||
return value.isValid() ? value.format(format) : ''; | ||
} | ||
|
||
function CustomFieldDatePicker(props: DatePickerProps) { | ||
return ( | ||
<DatePicker slots={{ ...props.slots, field: CustomDateField }} {...props} /> | ||
); | ||
} | ||
|
||
export default function MaterialDatePicker() { | ||
return ( | ||
<LocalizationProvider dateAdapter={AdapterDayjs}> | ||
<CustomFieldDatePicker /> | ||
</LocalizationProvider> | ||
); | ||
} |
1 change: 1 addition & 0 deletions
1
docs/data/date-pickers/custom-field/behavior-tutorial/MaterialDatePicker.tsx.preview
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<CustomFieldDatePicker /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters