Skip to content

Commit

Permalink
[DateTimePicker] Inline makePickerWithState call
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon committed Mar 7, 2021
1 parent c985fea commit c00ce51
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 30 deletions.
54 changes: 38 additions & 16 deletions docs/pages/api-docs/date-time-picker.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,50 @@
"props": {
"onChange": { "type": { "name": "func" }, "required": true },
"renderInput": { "type": { "name": "func" }, "required": true },
"acceptRegex": { "type": { "name": "instanceOf", "description": "RegExp" } },
"acceptRegex": {
"type": { "name": "instanceOf", "description": "RegExp" },
"default": "/\\dap/gi"
},
"allowKeyboardControl": { "type": { "name": "bool" } },
"allowSameDateSelection": { "type": { "name": "bool" } },
"ampm": { "type": { "name": "bool" } },
"ampmInClock": { "type": { "name": "bool" } },
"cancelText": { "type": { "name": "node" } },
"cancelText": { "type": { "name": "node" }, "default": "\"CANCEL\"" },
"className": { "type": { "name": "string" } },
"clearable": { "type": { "name": "bool" } },
"clearText": { "type": { "name": "node" } },
"clearText": { "type": { "name": "node" }, "default": "\"CLEAR\"" },
"components": {
"type": {
"name": "shape",
"description": "{ LeftArrowButton?: elementType, LeftArrowIcon?: elementType, RightArrowButton?: elementType, RightArrowIcon?: elementType, SwitchViewButton?: elementType, SwitchViewIcon?: elementType }"
}
},
"default": "{}"
},
"componentsProps": { "type": { "name": "object" } },
"componentsProps": { "type": { "name": "object" }, "default": "{}" },
"dateRangeIcon": { "type": { "name": "node" } },
"defaultCalendarMonth": { "type": { "name": "any" } },
"desktopModeMediaQuery": { "type": { "name": "string" } },
"desktopModeMediaQuery": {
"type": { "name": "string" },
"default": "\"@media (pointer: fine)\""
},
"DialogProps": { "type": { "name": "object" } },
"disableCloseOnSelect": { "type": { "name": "bool" } },
"disableCloseOnSelect": {
"type": { "name": "bool" },
"default": "`true` for Desktop, `false` for Mobile (based on the chosen wrapper and `desktopModeMediaQuery` prop)."
},
"disabled": { "type": { "name": "bool" } },
"disableHighlightToday": { "type": { "name": "bool" } },
"disableIgnoringDatePartForTimeValidation": { "type": { "name": "bool" } },
"disableMaskedInput": { "type": { "name": "bool" } },
"disableOpenPicker": { "type": { "name": "bool" } },
"getClockLabelText": { "type": { "name": "func" } },
"getOpenDialogAriaText": { "type": { "name": "func" } },
"getClockLabelText": {
"type": { "name": "func" },
"default": "<TDate extends any>(\n view: 'hours' | 'minutes' | 'seconds',\n time: TDate,\n adapter: MuiPickersAdapter<TDate>,\n) => `Select ${view}. Selected time is ${adapter.format(time, 'fullTime')}`"
},
"getOpenDialogAriaText": {
"type": { "name": "func" },
"default": "(value, utils) => `Choose date, selected date is ${utils.format(utils.date(value), 'fullDate')}`"
},
"getViewSwitchingButtonText": { "type": { "name": "func" } },
"hideTabs": { "type": { "name": "bool" } },
"InputAdornmentProps": { "type": { "name": "object" } },
Expand All @@ -49,8 +65,8 @@
"description": "any<br>&#124;&nbsp;Date<br>&#124;&nbsp;number<br>&#124;&nbsp;string"
}
},
"minutesStep": { "type": { "name": "number" } },
"okText": { "type": { "name": "node" } },
"minutesStep": { "type": { "name": "number" }, "default": "1" },
"okText": { "type": { "name": "node" }, "default": "\"OK\"" },
"onAccept": { "type": { "name": "func" } },
"onClose": { "type": { "name": "func" } },
"onError": { "type": { "name": "func" } },
Expand All @@ -72,9 +88,15 @@
},
"PopperProps": { "type": { "name": "object" } },
"readOnly": { "type": { "name": "bool" } },
"reduceAnimations": { "type": { "name": "bool" } },
"reduceAnimations": {
"type": { "name": "bool" },
"default": "typeof navigator !== 'undefined' && /(android)/i.test(navigator.userAgent)"
},
"renderDay": { "type": { "name": "func" } },
"renderLoading": { "type": { "name": "func" } },
"renderLoading": {
"type": { "name": "func" },
"default": "() => <span data-mui-test=\"loading-progress\">...</span>"
},
"rifmFormatter": { "type": { "name": "func" } },
"rightArrowButtonText": { "type": { "name": "string" } },
"shouldDisableDate": { "type": { "name": "func" } },
Expand All @@ -84,11 +106,11 @@
"showTodayButton": { "type": { "name": "bool" } },
"showToolbar": { "type": { "name": "bool" } },
"timeIcon": { "type": { "name": "node" } },
"todayText": { "type": { "name": "node" } },
"todayText": { "type": { "name": "node" }, "default": "\"TODAY\"" },
"ToolbarComponent": { "type": { "name": "elementType" } },
"toolbarFormat": { "type": { "name": "string" } },
"toolbarPlaceholder": { "type": { "name": "node" } },
"toolbarTitle": { "type": { "name": "node" } },
"toolbarPlaceholder": { "type": { "name": "node" }, "default": "\"\"" },
"toolbarTitle": { "type": { "name": "node" }, "default": "\"SELECT DATE\"" },
"TransitionComponent": { "type": { "name": "elementType" } },
"value": {
"type": {
Expand Down
79 changes: 65 additions & 14 deletions packages/material-ui-lab/src/DateTimePicker/DateTimePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { useUtils } from '../internal/pickers/hooks/useUtils';
import { unstable_useThemeProps as useThemeProps } from '@material-ui/core/styles';
import { useUtils, MuiPickersAdapter } from '../internal/pickers/hooks/useUtils';
import DateTimePickerToolbar from './DateTimePickerToolbar';
import { ExportedClockPickerProps } from '../ClockPicker/ClockPicker';
import { ResponsiveWrapper } from '../internal/pickers/wrappers/ResponsiveWrapper';
Expand All @@ -10,11 +11,7 @@ import {
OverrideParsableDateProps,
} from '../internal/pickers/hooks/date-helpers-hooks';
import { ExportedDayPickerProps } from '../DayPicker/DayPicker';
import {
makePickerWithState,
SharedPickerProps,
} from '../internal/pickers/Picker/makePickerWithState';
import { SomeWrapper } from '../internal/pickers/wrappers/Wrapper';
import { SomeWrapper, PublicWrapperProps } from '../internal/pickers/wrappers/Wrapper';
import { WithViewsProps, AllSharedPickerProps } from '../internal/pickers/Picker/SharedPickerProps';
import { DateAndTimeValidationError, validateDateAndTime } from './date-time-utils';
import { makeValidationHook, ValidationProps } from '../internal/pickers/hooks/useValidation';
Expand All @@ -23,6 +20,26 @@ import {
defaultMinDate,
defaultMaxDate,
} from '../internal/pickers/constants/prop-types';
import Picker from '../internal/pickers/Picker/Picker';
import { parsePickerInputValue } from '../internal/pickers/date-utils';
import { KeyboardDateInput } from '../internal/pickers/KeyboardDateInput';
import { makeWrapperComponent } from '../internal/pickers/wrappers/makeWrapperComponent';
import { PureDateInput } from '../internal/pickers/PureDateInput';
import { usePickerState, PickerStateValueManager } from '../internal/pickers/hooks/usePickerState';

type AllPickerProps<T, TWrapper extends SomeWrapper = SomeWrapper> = T &
AllSharedPickerProps &
PublicWrapperProps<TWrapper>;

const valueManager: PickerStateValueManager<unknown, unknown> = {
emptyValue: null,
parseInput: parsePickerInputValue,
areValuesEqual: (utils: MuiPickersAdapter, a: unknown, b: unknown) => utils.isEqual(a, b),
};

type SharedPickerProps<TDate, TWrapper extends SomeWrapper> = PublicWrapperProps<TWrapper> &
AllSharedPickerProps<ParsableDate<TDate>, TDate | null> &
React.RefAttributes<HTMLInputElement>;

type DateTimePickerViewsProps<TDate> = OverrideParsableDateProps<
TDate,
Expand Down Expand Up @@ -129,6 +146,17 @@ export type DateTimePickerGenericComponent<TWrapper extends SomeWrapper> = (<TDa
props: BaseDateTimePickerProps<TDate> & SharedPickerProps<TDate, TWrapper>,
) => JSX.Element) & { propTypes?: unknown };

type T = BaseDateTimePickerProps<unknown>;
const Wrapper = ResponsiveWrapper;
type TWrapper = typeof Wrapper;
const name = 'MuiDateTimePicker';
const { DefaultToolbarComponent } = dateTimePickerConfig;

const WrapperComponent = makeWrapperComponent(Wrapper, {
KeyboardDateInputComponent: KeyboardDateInput,
PureDateInputComponent: PureDateInput,
});

/**
*
* Demos:
Expand All @@ -139,15 +167,38 @@ export type DateTimePickerGenericComponent<TWrapper extends SomeWrapper> = (<TDa
*
* - [DateTimePicker API](https://material-ui.com/api/date-time-picker/)
*/
// @typescript-to-proptypes-generate
const DateTimePicker = makePickerWithState<BaseDateTimePickerProps<unknown>>(ResponsiveWrapper, {
name: 'MuiDateTimePicker',
...dateTimePickerConfig,
}) as DateTimePickerGenericComponent<typeof ResponsiveWrapper>;
const DateTimePicker = React.forwardRef(function DateTimePicker<TDate>(
__props: T & PublicWrapperProps<TWrapper> & AllSharedPickerProps<ParsableDate<TDate>, TDate>,
ref: React.Ref<HTMLInputElement>,
) {
const allProps = useInterceptProps(__props) as AllPickerProps<T, TWrapper>;
// This is technically unsound if the type parameters appear in optional props.
// Optional props can be filled by `useThemeProps` with types that don't match the type parameters.
const props: AllPickerProps<T, TWrapper> = useThemeProps({ props: allProps, name });

if (process.env.NODE_ENV !== 'production') {
(DateTimePicker as any).displayName = 'DateTimePicker';
}
const validationError = useValidation(props.value, props) !== null;
const { pickerProps, inputProps, wrapperProps } = usePickerState<ParsableDate<TDate>, TDate>(
props,
valueManager as PickerStateValueManager<ParsableDate<TDate>, TDate>,
);

// Note that we are passing down all the value without spread.
// It saves us >1kb gzip and make any prop available automatically on any level down.
const { value, onChange, ...other } = props;
const AllDateInputProps = { ...inputProps, ...other, ref, validationError };

return (
<WrapperComponent wrapperProps={wrapperProps} DateInputProps={AllDateInputProps} {...other}>
<Picker
{...pickerProps}
toolbarTitle={props.label || props.toolbarTitle}
ToolbarComponent={other.ToolbarComponent || DefaultToolbarComponent}
DateInputProps={AllDateInputProps}
{...other}
/>
</WrapperComponent>
);
}) as DateTimePickerGenericComponent<typeof ResponsiveWrapper>;

DateTimePicker.propTypes = {
// ----------------------------- Warning --------------------------------
Expand Down

0 comments on commit c00ce51

Please sign in to comment.