Skip to content

Commit

Permalink
Improve input customization exprience and add new examples
Browse files Browse the repository at this point in the history
  • Loading branch information
dmtrKovalenko committed May 9, 2020
1 parent 30c5bed commit d9c7277
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 49 deletions.
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';
import { styled } from '@material-ui/core';
import { DesktopDatePicker } from '@material-ui/pickers';

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

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.

<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
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
27 changes: 15 additions & 12 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,25 @@ 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
),
};
}

0 comments on commit d9c7277

Please sign in to comment.