From 0ead1221f999948bcb558744582aa76ef2ce77cb Mon Sep 17 00:00:00 2001 From: Lukas Date: Tue, 3 Oct 2023 15:50:39 +0300 Subject: [PATCH] [docs] Add `DateRangePicker` example with a `Button` trigger (#10485) Signed-off-by: Lukas Co-authored-by: Nora <72460825+noraleonte@users.noreply.github.com> --- .../DateRangePickerWithButtonField.js | 72 +++++++++++++++ .../DateRangePickerWithButtonField.tsx | 91 +++++++++++++++++++ ...DateRangePickerWithButtonField.tsx.preview | 11 +++ .../custom-field/PickerWithButtonField.js | 17 ++-- .../custom-field/PickerWithButtonField.tsx | 17 ++-- .../PickerWithButtonField.tsx.preview | 4 +- .../date-pickers/custom-field/custom-field.md | 4 + 7 files changed, 191 insertions(+), 25 deletions(-) create mode 100644 docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.js create mode 100644 docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.tsx create mode 100644 docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.tsx.preview diff --git a/docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.js b/docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.js new file mode 100644 index 000000000000..7180636a94dd --- /dev/null +++ b/docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.js @@ -0,0 +1,72 @@ +import * as React from 'react'; + +import Button from '@mui/material/Button'; +import useForkRef from '@mui/utils/useForkRef'; + +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; + +const DateRangeButtonField = React.forwardRef((props, ref) => { + const { + setOpen, + label, + id, + disabled, + InputProps: { ref: containerRef } = {}, + inputProps: { 'aria-label': ariaLabel } = {}, + } = props; + + const handleRef = useForkRef(ref, containerRef); + + return ( + + ); +}); + +DateRangeButtonField.fieldType = 'single-input'; + +const ButtonDateRangePicker = React.forwardRef((props, ref) => { + const [open, setOpen] = React.useState(false); + + return ( + setOpen(false)} + onOpen={() => setOpen(true)} + /> + ); +}); + +export default function DateRangePickerWithButtonField() { + const [value, setValue] = React.useState([null, null]); + + return ( + + (date ? date.format('MM/DD/YYYY') : 'null')) + .join(' - ') + } + value={value} + onChange={(newValue) => setValue(newValue)} + /> + + ); +} diff --git a/docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.tsx b/docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.tsx new file mode 100644 index 000000000000..8b597fac8c61 --- /dev/null +++ b/docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.tsx @@ -0,0 +1,91 @@ +import * as React from 'react'; +import { Dayjs } from 'dayjs'; +import Button from '@mui/material/Button'; +import useForkRef from '@mui/utils/useForkRef'; +import { DateRange } from '@mui/x-date-pickers-pro'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { + DateRangePicker, + DateRangePickerProps, +} from '@mui/x-date-pickers-pro/DateRangePicker'; +import { SingleInputDateRangeFieldProps } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; + +interface DateRangeButtonFieldProps extends SingleInputDateRangeFieldProps { + setOpen?: React.Dispatch>; +} + +type DateRangeButtonFieldComponent = (( + props: DateRangeButtonFieldProps & React.RefAttributes, +) => React.JSX.Element) & { fieldType?: string }; + +const DateRangeButtonField = React.forwardRef( + (props: DateRangeButtonFieldProps, ref: React.Ref) => { + const { + setOpen, + label, + id, + disabled, + InputProps: { ref: containerRef } = {}, + inputProps: { 'aria-label': ariaLabel } = {}, + } = props; + + const handleRef = useForkRef(ref, containerRef); + + return ( + + ); + }, +) as DateRangeButtonFieldComponent; + +DateRangeButtonField.fieldType = 'single-input'; + +const ButtonDateRangePicker = React.forwardRef( + ( + props: Omit, 'open' | 'onOpen' | 'onClose'>, + ref: React.Ref, + ) => { + const [open, setOpen] = React.useState(false); + + return ( + setOpen(false)} + onOpen={() => setOpen(true)} + /> + ); + }, +); + +export default function DateRangePickerWithButtonField() { + const [value, setValue] = React.useState>([null, null]); + + return ( + + (date ? date.format('MM/DD/YYYY') : 'null')) + .join(' - ') + } + value={value} + onChange={(newValue) => setValue(newValue)} + /> + + ); +} diff --git a/docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.tsx.preview b/docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.tsx.preview new file mode 100644 index 000000000000..3a8d6daacd70 --- /dev/null +++ b/docs/data/date-pickers/custom-field/DateRangePickerWithButtonField.tsx.preview @@ -0,0 +1,11 @@ + (date ? date.format('MM/DD/YYYY') : 'null')) + .join(' - ') + } + value={value} + onChange={(newValue) => setValue(newValue)} +/> \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/PickerWithButtonField.js b/docs/data/date-pickers/custom-field/PickerWithButtonField.js index fe6502169e81..255784386528 100644 --- a/docs/data/date-pickers/custom-field/PickerWithButtonField.js +++ b/docs/data/date-pickers/custom-field/PickerWithButtonField.js @@ -1,7 +1,6 @@ import * as React from 'react'; import Button from '@mui/material/Button'; -import Stack from '@mui/material/Stack'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; @@ -25,7 +24,7 @@ function ButtonField(props) { aria-label={ariaLabel} onClick={() => setOpen?.((prev) => !prev)} > - {label ?? 'Pick a date'} + {label ? `Current date: ${label}` : 'Pick a date'} ); } @@ -50,15 +49,11 @@ export default function PickerWithButtonField() { return ( - - setValue(newValue)} - /> - + setValue(newValue)} + /> ); } diff --git a/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx b/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx index e7137238b01c..c8cfc01a1964 100644 --- a/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx +++ b/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; import { Dayjs } from 'dayjs'; import Button from '@mui/material/Button'; -import Stack from '@mui/material/Stack'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker, DatePickerProps } from '@mui/x-date-pickers/DatePicker'; @@ -42,7 +41,7 @@ function ButtonField(props: ButtonFieldProps) { aria-label={ariaLabel} onClick={() => setOpen?.((prev) => !prev)} > - {label ?? 'Pick a date'} + {label ? `Current date: ${label}` : 'Pick a date'} ); } @@ -69,15 +68,11 @@ export default function PickerWithButtonField() { return ( - - setValue(newValue)} - /> - + setValue(newValue)} + /> ); } diff --git a/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx.preview b/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx.preview index 77227d949155..173a0ba16962 100644 --- a/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx.preview +++ b/docs/data/date-pickers/custom-field/PickerWithButtonField.tsx.preview @@ -1,7 +1,5 @@ setValue(newValue)} /> \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/custom-field.md b/docs/data/date-pickers/custom-field/custom-field.md index 5c1f7ffe9969..75582f09ea41 100644 --- a/docs/data/date-pickers/custom-field/custom-field.md +++ b/docs/data/date-pickers/custom-field/custom-field.md @@ -93,6 +93,10 @@ you can replace the field with a `Button`: {{"demo": "PickerWithButtonField.js", "defaultCodeOpen": false}} +The same can be applied to the `DateRangePicker`: + +{{"demo": "DateRangePickerWithButtonField.js", "defaultCodeOpen": false}} + ## How to build a custom field The main challenge when building a custom field, is to make sure that all the relevant props passed by the pickers are correctly handled.