You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
9.1 KiB

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DatePicker = void 0;
const react_1 = __importStar(require("react"));
const react_datepicker_1 = __importDefault(require("react-datepicker"));
const styled_components_1 = __importDefault(require("styled-components"));
const react_text_mask_1 = __importDefault(require("react-text-mask"));
const createAutoCorrectedDatePipe_1 = __importDefault(require("text-mask-addons/dist/createAutoCorrectedDatePipe"));
const datepicker_styles_1 = __importDefault(require("../../utils/datepicker.styles"));
const icon_1 = require("../../atoms/icon");
const box_1 = require("../../atoms/box/box");
const css_class_1 = require("../../utils/css-class");
const DatePickerIcon = styled_components_1.default(icon_1.Icon) `
position: absolute;
background: ${({ theme }) => theme.colors.primary100};
color: ${({ theme }) => theme.colors.white};
right: 0;
top: 0;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
height: 100%;
min-width: 34px;
width: auto;
`;
const StyledDatePicker = styled_components_1.default(box_1.Box) `
${datepicker_styles_1.default};
position: relative;
& .react-datepicker-wrapper {
width: 100%;
box-sizing: border-box;
border: ${({ theme }) => `1px solid ${theme.colors.grey40}`};
padding: 4px 8px;
font-size: 14px;
line-height: 24px;
}
& .react-datepicker-wrapper input {
border: none;
width: 100%;
height: 100%;
background: transparent;
color: ${({ theme }) => theme.colors.grey80};
&:focus-visible {
outline: none;
}
}
& .react-datepicker {
border-radius: 0;
padding: ${({ theme }) => theme.space.default};
font-family: ${({ theme }) => theme.font};
z-index: 101;
&:focus-visible {
outline: none;
}
}
& .react-datepicker__navigation--next {
border-left-color: ${({ theme }) => theme.colors.primary60};
top: 16px;
}
& .react-datepicker__navigation--next:hover {
border-left-color: ${({ theme }) => theme.colors.primary100};
}
& .react-datepicker__navigation--previous {
border-right-color: ${({ theme }) => theme.colors.primary60};
top: 16px;
}
& .react-datepicker__navigation--previous:hover {
border-right-color: ${({ theme }) => theme.colors.primary100};
}
& .react-datepicker__navigation {
outline: none;
}
& .react-datepicker__year-read-view--down-arrow {
top: 5px;
}
& .react-datepicker__header {
background: ${({ theme }) => theme.colors.white};
font-size: ${({ theme }) => theme.fontSizes.default};
border: none;
}
& .react-datepicker__current-month {
font-weight: normal;
padding-bottom: ${({ theme }) => theme.space.lg};
}
& .react-datepicker__month {
margin-top: 0;
}
& .react-datepicker__day-name {
color: ${({ theme }) => theme.colors.primary60};
}
& .react-datepicker__day--outside-month {
color: ${({ theme }) => theme.colors.grey40};
}
& .react-datepicker__day--today.react-datepicker__day--keyboard-selected {
color: ${({ theme }) => theme.colors.white};
}
& .react-datepicker__day--selected {
color: ${({ theme }) => theme.colors.white};
}
& .react-datepicker__day--keyboard-selected:not(.react-datepicker__day--today) {
background: none;
color: ${({ theme }) => theme.colors.grey100};
}
& .react-datepicker__day:hover,
& .react-datepicker__day {
border-radius: 15px;
}
& .react-datepicker__day--selected {
background: ${({ theme }) => theme.colors.primary100};
border-radius: 15px;
color: ${({ theme }) => theme.colors.white};
}
`;
const parseDateSafely = (newDate) => {
const timestamp = Date.parse(newDate);
if (!Number.isNaN(timestamp)) {
return new Date(timestamp);
}
return null;
};
// https://github.com/text-mask/text-mask/issues/951
const convertDateFnsFormatToDatePipeFormat = (format) => {
const tokens = format.split('');
return tokens.map((char) => {
if (char === 'M')
return 'm';
if (char === 'm')
return 'M';
return char;
}).join('');
};
const defaultDateProps = {
date: {
format: 'yyyy/MM/dd',
placeholder: 'YYYY/MM/DD',
inputMask: [/\d/, /\d/, /\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/],
},
datetime: {
format: 'yyyy/MM/dd HH:mm',
placeholder: 'YYYY/MM/DD HH:mm',
inputMask: [/\d/, /\d/, /\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, ' ', /\d/, /\d/, ':', /\d/, /\d/],
},
};
const parseCustomMask = (mask) => mask.map((el) => {
if (typeof el === 'string')
return el;
if (el.raw)
return el.raw;
if (!el.regex)
throw new Error('Invalid input mask');
return new RegExp(el.regex);
});
const getDateInputProps = (propertyType = 'datetime', props) => {
const { dateFormat, placeholderText, inputMask } = props;
const defaultProps = defaultDateProps[propertyType];
const format = dateFormat !== null && dateFormat !== void 0 ? dateFormat : defaultProps.format;
const placeholder = placeholderText !== null && placeholderText !== void 0 ? placeholderText : defaultProps.placeholder;
const mask = (inputMask === null || inputMask === void 0 ? void 0 : inputMask.mask) ? parseCustomMask(inputMask.mask)
: defaultProps.inputMask;
const dateFormatPipe = createAutoCorrectedDatePipe_1.default(convertDateFnsFormatToDatePipeFormat(format));
return { format, dateFormatPipe, placeholder, parsedMask: mask };
};
/**
* @classdesc
*
* <img src="components/date-picker.png" />
*
*
* Component responsible for showing dates. It is a wrapper to
* [react datepicker]{@link https://reactdatepicker.com/}.
*
* ### Usage
*
* ```javascript
* import { DatePicker, DatePickerProps } from '@adminjs/design-system'
* ```
*
* @component
* @subcategory Molecules
* @see https://reactdatepicker.com/
* @see {@link https://storybook.adminjs.co/?path=/story/designsystem-molecules-datepicker--default Storybook}
* @see DatePickerProps
* @hideconstructor
*
* @example
* return (
* <Box width={1/2} height="300px">
* <DatePicker onChange={(date) => console.log(date)}/>
* </Box>
* )
* @section design-system
*/
const DatePicker = (props) => {
const { value, onChange, disabled, propertyType, inputMask = {}, placeholderText, dateFormat } = props, other = __rest(props, ["value", "onChange", "disabled", "propertyType", "inputMask", "placeholderText", "dateFormat"]);
const _a = inputMask, { mask: _mask } = _a, otherInputMaskProps = __rest(_a, ["mask"]);
const handleChange = (newDate) => {
var _a, _b;
onChange(((_b = (_a = parseDateSafely(newDate)) === null || _a === void 0 ? void 0 : _a.toISOString) === null || _b === void 0 ? void 0 : _b.call(_a)) || '');
};
const dateValue = react_1.useMemo(() => parseDateSafely(value), [value]);
const { dateFormatPipe, format, parsedMask, placeholder } = getDateInputProps(propertyType, { dateFormat, inputMask, placeholderText });
return (react_1.default.createElement(StyledDatePicker, { className: css_class_1.cssClass('DatePicker') },
react_1.default.createElement(react_datepicker_1.default, Object.assign({ customInput: (react_1.default.createElement(react_text_mask_1.default, Object.assign({ pipe: dateFormatPipe, mask: parsedMask, keepCharPositions: true, guide: true, placeholder: placeholder, disabled: disabled }, otherInputMaskProps))), selected: dateValue, onChange: handleChange, showTimeInput: propertyType === 'datetime', dateFormat: format, disabled: disabled }, other)),
react_1.default.createElement(DatePickerIcon, { icon: "Calendar", color: "white" })));
};
exports.DatePicker = DatePicker;
exports.default = DatePicker;