Skip to content
This repository was archived by the owner on Jul 19, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions docs/pages/demo/datepicker/AdvancedKeyboard.example.jsx

This file was deleted.

28 changes: 28 additions & 0 deletions docs/pages/demo/datepicker/CustomInput.example.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { useState } from 'react';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?
import * as React from 'react';

import { styled } from '@material-ui/core';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?
import { styled } from '@material-ui/core/styles';

import { DesktopDatePicker } from '@material-ui/pickers';

const InputContainer = styled('div')({
display: 'flex',
alignItems: 'center',
});

function CustomInput() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?
export default function CustomInput()

const [selectedDate, handleDateChange] = useState(new Date());

return (
<DesktopDatePicker
label="Advanced keyboard"
value={selectedDate}
onChange={date => handleDateChange(date)}
renderInput={({ ref, inputProps, InputProps }) => (
<InputContainer ref={ref}>
<input {...inputProps} />
{InputProps?.endAdornment}
</InputContainer>
)}
/>
);
}

export default CustomInput;
8 changes: 4 additions & 4 deletions docs/pages/demo/datepicker/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as ViewsDatePicker from './ViewsDatePicker.example';
import * as BasicDatePicker from './BasicDatePicker.example';
import * as StaticDatePicker from './StaticDatePicker.example';
import * as DatePickers from './DatePickers.example';
import * as AdvancedKeyboard from './AdvancedKeyboard.example';
import * as CustomInput from './CustomInput.example';

<PageMeta component="DatePicker" />

Expand Down Expand Up @@ -53,11 +53,11 @@ For that use `StaticDatePicker`.
<Example paddingBottom source={StaticDatePicker} />
</Hidden>

#### Advanced keyboard input
#### Custom input component

We are providing default localized formats, but you can change this behaviour with `format` and `mask` props.
You can customize rendering input by `renderInput` prop. But make sure you will spread `ref` and `inputProps` correctly to the custom input component.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe?

The `renderInput` prop allows you to customize the rendered input.
The first argument of this render prop contains props that you need to forward.
Pay specific attention to the `ref` and `inputProps` keys.

cc @mbrookes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We must specify that props are https://material-ui.com/api/text-field/#textfield-api. Will refer this comment at #1761

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way the type of renderInput looks to awful

(props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<...>

Because of core TextField typings (mui/material-ui#20716)

Copy link
Member

@oliviertassinari oliviertassinari May 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would a similar approach to Autocomplete work?

export interface AutocompleteRenderInputParams {
  id: string;
  disabled: boolean;
  InputLabelProps: object;
  InputProps: {
    ref: React.Ref<any>;
    className: string;
    startAdornment: React.ReactNode;
    endAdornment: React.ReactNode;
  };
  inputProps: object;
}

  /**
   * Render the input.
   *
   * @param {object} params
   * @returns {ReactNode}
   */
  renderInput: (params: AutocompleteRenderInputParams) => React.ReactNode;


<Example source={AdvancedKeyboard} />
<Example source={CustomInput} />

#### Customization

Expand Down
22 changes: 22 additions & 0 deletions docs/pages/demo/daterangepicker/CustomRangeInputs.example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { useState } from 'react';
import { DateRangePicker, DateRange } from '@material-ui/pickers';

function CustomRangeInputs() {
const [selectedDate, handleDateChange] = useState<DateRange>([null, null]);

return (
<DateRangePicker
label="Advanced keyboard"
value={selectedDate}
onChange={date => handleDateChange(date)}
renderInput={(startProps, endProps) => (
<>
<input ref={startProps.ref as React.Ref<HTMLInputElement>} {...startProps.inputProps} />
<input ref={endProps.ref as React.Ref<HTMLInputElement>} {...endProps.inputProps} />
</>
)}
/>
);
}

export default CustomRangeInputs;
8 changes: 8 additions & 0 deletions docs/pages/demo/daterangepicker/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as ResponsiveDateRangePicker from './ResponsiveDateRangePicker.example'
import * as MinMaxDateRangePicker from './MinMaxDateRangePicker.example';
import * as CalendarsDateRangePicker from './CalendarsDateRangePicker.example';
import * as StaticDateRangePicker from './StaticDateRangePicker.example';
import * as CustomRangeInputs from './CustomRangeInputs.example';

<PageMeta component="DateRangePicker" />

Expand Down Expand Up @@ -43,6 +44,13 @@ Disabling dates performs just like in simple `DatePicker`

<Example source={MinMaxDateRangePicker} />

#### Custom input component

You can customize rendering input by `renderInput` prop. For `DateRangePicker` it takes **2** parameters – for start and end input respectively.
So if you need to render custom input make sure you will spread `ref` and `inputProps` correctly to the input components.

<Example source={CustomRangeInputs} />

#### Static mode

It is possible to render any picker without modal or popper. For that use `StaticDateRangePicker`.
Expand Down
10 changes: 8 additions & 2 deletions docs/pages/regression/Regression.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,15 @@ function Regression() {
onChange={changeRange}
renderInput={(startProps, endProps) => (
<>
<TextField {...startProps} inputProps={{ 'data-mui-test': 'desktop-range-picker' }} />
<TextField
{...startProps}
inputProps={{ ...startProps.inputProps, 'data-mui-test': 'desktop-range-picker' }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side question, should we use a label to differentiate the two inputs instead of data-mui-test? Like label="Start date" and label="End date"?

/>
<DateRangeDelimiter> to </DateRangeDelimiter>
<TextField {...endProps} inputProps={{ 'data-mui-test': 'desktop-range-picker-end' }} />
<TextField
{...endProps}
inputProps={{ ...endProps.inputProps, 'data-mui-test': 'desktop-range-picker-end' }}
/>
</>
)}
/>
Expand Down
22 changes: 11 additions & 11 deletions lib/.size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
{
"build/dist/material-ui-pickers.esm.js": {
"bundled": 188938,
"minified": 101335,
"gzipped": 26402,
"bundled": 189105,
"minified": 101411,
"gzipped": 26429,
"treeshaked": {
"rollup": {
"code": 83375,
"code": 83443,
"import_statements": 2121
},
"webpack": {
"code": 92851
"code": 92919
}
}
},
"build/dist/material-ui-pickers.umd.js": {
"bundled": 299832,
"minified": 116954,
"gzipped": 33374
"bundled": 300017,
"minified": 117022,
"gzipped": 33387
},
"build/dist/material-ui-pickers.umd.min.js": {
"bundled": 258486,
"minified": 107815,
"gzipped": 30601
"bundled": 258671,
"minified": 107883,
"gzipped": 30626
}
}
6 changes: 5 additions & 1 deletion lib/src/DateRangePicker/DateRangePickerInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { CurrentlySelectingRangeEndProps } from './RangeTypes';
import { useMaskedInput } from '../_shared/hooks/useMaskedInput';
import { DateRangeValidationError } from '../_helpers/date-utils';
import { WrapperVariantContext } from '../wrappers/WrapperVariantContext';
import { DateInputProps, MuiTextFieldProps } from '../_shared/PureDateInput';
import { mergeRefs, executeInTheNextEventLoopTick } from '../_helpers/utils';
import { DateInputProps, MuiTextFieldProps } from '../_shared/PureDateInput';

export const useStyles = makeStyles(
theme => ({
Expand Down Expand Up @@ -147,6 +147,8 @@ export const DateRangePickerInput: React.FC<DateRangeInputProps> = ({
ref: startRef,
variant: 'outlined',
focused: open && currentlySelectingRangeEnd === 'start',
},
inputProps: {
onClick: !openOnFocus ? openRangeStartSelection : undefined,
onFocus: openOnFocus ? openRangeStartSelection : undefined,
},
Expand All @@ -164,6 +166,8 @@ export const DateRangePickerInput: React.FC<DateRangeInputProps> = ({
ref: endRef,
variant: 'outlined',
focused: open && currentlySelectingRangeEnd === 'end',
},
inputProps: {
onClick: !openOnFocus ? openRangeEndSelection : undefined,
onFocus: openOnFocus ? openRangeEndSelection : undefined,
},
Expand Down
12 changes: 8 additions & 4 deletions lib/src/_shared/PureDateInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,15 @@ export const PureDateInput: React.FC<DateInputProps & DateInputRefs> = ({
ref: containerRef,
inputRef: forwardedRef,
error: validationError,
'aria-label': getOpenDialogAriaText(rawValue, utils),
onClick: onOpen,
value: inputValue,
InputProps: PureDateInputProps,
onKeyDown: onSpaceOrEnter(onOpen),
inputProps: {
disabled,
'aria-readonly': true,
'aria-label': getOpenDialogAriaText(rawValue, utils),
value: inputValue,
onClick: onOpen,
onKeyDown: onSpaceOrEnter(onOpen),
},
...TextFieldProps,
});
};
Expand Down
29 changes: 15 additions & 14 deletions lib/src/_shared/hooks/useMaskedInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type MaskedInputProps = Omit<
| 'disableOpenPicker'
| 'getOpenDialogAriaText'
| 'OpenPickerButtonProps'
>;
> & { inputProps?: Partial<React.HTMLProps<HTMLInputElement>> };

export function useMaskedInput({
disableMaskedInput,
Expand All @@ -37,6 +37,7 @@ export function useMaskedInput({
readOnly,
TextFieldProps,
label,
inputProps,
}: MaskedInputProps): MuiTextFieldProps {
const utils = useUtils();
const isFocusedRef = React.useRef(false);
Expand Down Expand Up @@ -99,23 +100,23 @@ export function useMaskedInput({
};

return {
...inputStateArgs,
label,
disabled,
placeholder: formatHelperText,
error: validationError,
helperText: formatHelperText,
// @ts-ignore ??? fix typings for textfield finally
'data-mui-test': 'keyboard-date-input',
inputProps: { readOnly, type: shouldUseMaskedInput ? 'tel' : 'text' },
inputProps: {
...inputStateArgs,
disabled, // make spreading in custom input easier
placeholder: formatHelperText,
readOnly,
type: shouldUseMaskedInput ? 'tel' : 'text',
...inputProps,
onFocus: createDelegatedEventHandler(
() => (isFocusedRef.current = true),
inputProps?.onFocus
),
onBlur: createDelegatedEventHandler(() => (isFocusedRef.current = false), inputProps?.onBlur),
},
...TextFieldProps,
onFocus: createDelegatedEventHandler(
() => (isFocusedRef.current = true),
TextFieldProps?.onFocus
),
onBlur: createDelegatedEventHandler(
() => (isFocusedRef.current = false),
TextFieldProps?.onBlur
),
};
}