@totalsoft/rocket-ui
Version:
A set of reusable and composable React components built on top of Material UI core for developing fast and friendly web applications interfaces.
156 lines • 6 kB
JavaScript
import React, { useCallback, useLayoutEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import { TimePicker, LocalizationProvider, DatePicker, DateTimePicker } from '@mui/x-date-pickers';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { CalendarTodaySmallIcon } from './DateTimeStyles';
import * as R from 'ramda';
import ro from 'date-fns/locale/ro';
import fr from 'date-fns/locale/fr';
import ru from 'date-fns/locale/ru';
import de from 'date-fns/locale/de';
import enUS from 'date-fns/locale/en-US';
import DateTimeEndAdornment from './DateTimeEndAdornment';
import TextField from '../TextField';
const localeMap = {
de: de,
['en-US']: enUS,
fr: fr,
ro: ro,
ru: ru
};
const defaultComponents = {
OpenPickerIcon: CalendarTodaySmallIcon
};
const DateTime = ({ dateAdapter = AdapterDateFns, adapterLocale, showPicker = 'date', components, inputProps, format = 'ro', open: origOpen = false, onClose, value: origValue = null, onChange: origOnChange, isClearable, required, disabled, error, helperText, ...rest }) => {
// Code to serve the "Open/Close" functionality
const [open, setOpen] = useState(origOpen);
useLayoutEffect(() => {
setOpen(origOpen);
}, [origOpen]);
const handleOpen = useCallback(() => {
setOpen(true);
}, []);
const handleClose = useCallback(() => {
setOpen(false);
if (onClose)
onClose();
}, [onClose]);
// ---------------------------------------------
// Code to serve the "Clearable" functionality
const [value, setValue] = useState(origValue);
useLayoutEffect(() => {
setValue(origValue);
}, [origValue]);
const handleChange = useCallback((value) => {
const changeValue = origOnChange ?? setValue;
changeValue(value);
}, [origOnChange]);
const internalIsClearable = useMemo(() => Boolean(isClearable) && Boolean(value), [isClearable, value]);
const handleClear = useCallback(() => {
handleChange(null);
}, [handleChange]);
// ---------------------------------------------
const mergedComponents = useMemo(() => R.mergeRight(defaultComponents, components), [components]);
const renderInput = useCallback((params) => {
const OpenPickerIcon = mergedComponents.OpenPickerIcon;
return (React.createElement(TextField, { fullWidth: true, ...inputProps, ...params, required: required, error: error, helperText: helperText, endAdornment: React.createElement(DateTimeEndAdornment, { isClearable: internalIsClearable, onClear: handleClear, onOpen: handleOpen, OpenPickerIcon: OpenPickerIcon, disabled: disabled }) }));
}, [
disabled,
error,
handleClear,
handleOpen,
helperText,
inputProps,
required,
internalIsClearable,
mergedComponents.OpenPickerIcon
]);
const localeUsed = useMemo(() => adapterLocale ?? localeMap[format] ?? localeMap.ro, [format, adapterLocale]);
const commonProps = { renderInput, open, onClose: handleClose, value, onChange: handleChange, disabled };
const renderPicker = () => {
switch (showPicker) {
case 'dateTime':
return (React.createElement(DateTimePicker, { components: mergedComponents, ...commonProps, ...rest }));
case 'time':
return (React.createElement(TimePicker, { components: mergedComponents, ...commonProps, ...rest }));
default:
return (React.createElement(DatePicker, { components: mergedComponents, ...commonProps, ...rest }));
}
};
return (React.createElement(LocalizationProvider, { dateAdapter: dateAdapter, adapterLocale: localeUsed }, renderPicker()));
};
DateTime.propTypes = {
/**
* @default AdapterDateFns
* DateIO adapter class function
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
dateAdapter: PropTypes.func,
/**
* The adapterLocale object/string from the engine you use for displaying the date
*/
adapterLocale: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
/**
* Choose the type of picker you want displayed by the component
* @default 'date'
*/
showPicker: PropTypes.oneOf(['date', 'dateTime', 'time']),
/**
* The components used for each slot. Either a string to use a HTML element or a component.
*/
components: PropTypes.shape({
LeftArrowButton: PropTypes.any,
LeftArrowIcon: PropTypes.any,
OpenPickerIcon: PropTypes.any,
RightArrowButton: PropTypes.any,
RightArrowIcon: PropTypes.any,
SwitchViewButton: PropTypes.any,
SwitchViewIcon: PropTypes.any
}),
/**
* Properties that will be passed to the rendered input. This is a TextField.
*/
inputProps: PropTypes.object,
/**
* A small sample of ISO format names that will be used to display the date.
* @default 'ro'
*/
format: PropTypes.oneOf(['de', 'en-US', 'fr', 'ro', 'ru']),
/**
* @default null
* Value of the picker
*/
value: PropTypes.any,
/**
* Callback fired when the value (the selected date) changes @DateIOType.
*/
onChange: PropTypes.func,
/**
* Dedicated button for clearing the value
*/
isClearable: PropTypes.bool,
/**
* @default false
* Control the popup or dialog open state.
*/
open: PropTypes.bool,
/**
* Callback fired when the popup requests to be closed. Use in controlled mode (see open).
*/
onClose: PropTypes.func,
/**
* If true, the picker and text field are disabled.
*/
disabled: PropTypes.bool,
/**
* If true, the label is displayed in an error state.
*/
error: PropTypes.bool,
/**
* The helper text content.
*/
helperText: PropTypes.node
};
export default DateTime;
//# sourceMappingURL=DateTime.js.map