UNPKG

@amaui/ui-react

Version:
314 lines (313 loc) 21.9 kB
"use strict"; 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 }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = __importDefault(require("react")); const utils_1 = require("@amaui/utils"); const style_react_1 = require("@amaui/style-react"); const date_1 = require("@amaui/date"); const IconMaterialScheduleW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialScheduleW100")); const IconMaterialWbSunnyW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialWbSunnyW100")); const IconMaterialWbTwilightW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialWbTwilightW100")); const IconMaterialCounter7W100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialCounter7W100")); const IconMaterialCalendarMonthW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialCalendarMonthW100")); const IconMaterialDeleteW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialDeleteW100")); const Menu_1 = __importDefault(require("../Menu")); const Calendar_1 = __importDefault(require("../Calendar")); const Line_1 = __importDefault(require("../Line")); const Tooltip_1 = __importDefault(require("../Tooltip")); const IconButton_1 = __importDefault(require("../IconButton")); const Button_1 = __importDefault(require("../Button")); const ListItem_1 = __importDefault(require("../ListItem")); const PaginationItem_1 = __importDefault(require("../PaginationItem")); const TimePicker_1 = __importDefault(require("../TimePicker")); const Type_1 = __importDefault(require("../Type")); const utils_2 = require("../utils"); const useStyle = (0, style_react_1.style)(theme => ({ root: {}, weekday: { cursor: 'pointer' }, dayValue: { '&:hover': { boxShadow: 'inset 0px 0px 0px 1px currentColor' } }, dayValueRepeating: { background: theme.palette.background.secondary.quaternary }, calendar: { boxShadow: '0px 4px 32px 0px rgba(0, 0, 0, 0.04)', '& .amaui-Calendar-header': { paddingTop: '0px' }, '& .amaui-Calendar-calendars': { paddingBottom: '4px' } }, calendarShortcuts: { padding: '14px 16px 2px' }, end: { padding: '0 12px 12px', '& .amaui-ListItem-root': { minHeight: '24px !important', padding: '0 8px', borderRadius: theme.methods.shape.radius.value(0.5, 'px') } }, minorMenu: { '& .amaui-List-root': { width: '100%' } }, repeatEndMenu: { '& .amaui-List-root': { width: '100%' } }, menuMore: { width: '100%', padding: '12px', borderRadius: theme.methods.shape.radius.value(0.5, 'px'), '& .amaui-TextField-input-wrapper': { paddingBlock: '12px', height: '40px' }, '& .amaui-TextField-icon-end': { paddingBlock: '8px' } }, item: { '& .amaui-ListItem-root': { minHeight: '30px !important' }, '&.amaui-Surface-root': { background: 'transparent' } }, iconInactive: { opacity: '0', pointerEvents: 'none' }, menuFooter: { marginTop: '8px' } }), { name: 'amaui-CalendarMenu' }); const CalendarMenu = react_1.default.forwardRef((props_, ref) => { var _a; const theme = (0, style_react_1.useAmauiTheme)(); const props = react_1.default.useMemo(() => { var _a, _b, _c, _d, _e, _f, _g, _h; return (Object.assign(Object.assign(Object.assign({}, (_d = (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.all) === null || _c === void 0 ? void 0 : _c.props) === null || _d === void 0 ? void 0 : _d.default), (_h = (_g = (_f = (_e = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _e === void 0 ? void 0 : _e.elements) === null || _f === void 0 ? void 0 : _f.amauiCalendarAvailability) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h.default), props_)); }, [props_]); const Line = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Line) || Line_1.default; }, [theme]); const Menu = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Menu) || Menu_1.default; }, [theme]); const Calendar = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Calendar) || Calendar_1.default; }, [theme]); const Tooltip = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Tooltip) || Tooltip_1.default; }, [theme]); const IconButton = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.IconButton) || IconButton_1.default; }, [theme]); const Button = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Button) || Button_1.default; }, [theme]); const ListItem = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.ListItem) || ListItem_1.default; }, [theme]); const PaginationItem = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.PaginationItem) || PaginationItem_1.default; }, [theme]); const TimePicker = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.TimePicker) || TimePicker_1.default; }, [theme]); const Type = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Type) || Type_1.default; }, [theme]); const { value, dateProperty = 'ends_at', menuOpen: menuOpen_, menuOpenDefault, timeMenuOpen: timeMenuOpen_, timeMenuOpenDefault, onChange: onChange_, onRemove: onRemove_, closeOnChange = true, startBottom, endBottom, noRemove, children, className } = props, other = __rest(props, ["value", "dateProperty", "menuOpen", "menuOpenDefault", "timeMenuOpen", "timeMenuOpenDefault", "onChange", "onRemove", "closeOnChange", "startBottom", "endBottom", "noRemove", "children", "className"]); const { classes } = useStyle(); const [menuOpen, setMenuOpen] = react_1.default.useState(menuOpenDefault !== undefined ? menuOpenDefault : menuOpen_ !== undefined ? menuOpen_ : false); const [timeMenuOpen, setTimeMenuOpen] = react_1.default.useState(timeMenuOpenDefault !== undefined ? timeMenuOpenDefault : timeMenuOpen_ !== undefined ? timeMenuOpen_ : false); const refs = { value: react_1.default.useRef(value), dateProperty: react_1.default.useRef(dateProperty), time: react_1.default.useRef(undefined), repeat: react_1.default.useRef(undefined), repeatEnd: react_1.default.useRef(undefined), onChange: react_1.default.useRef(onChange_), repeatCount: react_1.default.useRef({}) }; refs.dateProperty.current = dateProperty; refs.value.current = value; refs.onChange.current = onChange_; const onChange = react_1.default.useCallback(async (...args) => { if ((0, utils_1.is)('function', onChange_)) onChange_(...args); }, [onChange_]); react_1.default.useEffect(() => { if (menuOpen !== menuOpen_ && menuOpen_ !== undefined) setMenuOpen(menuOpen_); }, [menuOpen_]); react_1.default.useEffect(() => { if (timeMenuOpen !== timeMenuOpen_ && timeMenuOpen_ !== undefined) setTimeMenuOpen(timeMenuOpen_); }, [timeMenuOpen_]); const onMenuOpen = react_1.default.useCallback(() => { setMenuOpen(true); }, []); const onMenuClose = react_1.default.useCallback(() => { setMenuOpen(false); }, []); const onTimeMenuOpen = react_1.default.useCallback(() => { setTimeMenuOpen(true); }, []); const onTimeMenuClose = react_1.default.useCallback(() => { setTimeMenuOpen(false); }, []); const onChangeDate = react_1.default.useCallback((valueNew) => { if (closeOnChange) onMenuClose(); onChange(refs.dateProperty.current, valueNew === null || valueNew === void 0 ? void 0 : valueNew.milliseconds); }, [closeOnChange, onChange]); const onChangeTime = react_1.default.useCallback((valueNew) => { onTimeMenuClose(); onChange(refs.dateProperty.current, valueNew === null || valueNew === void 0 ? void 0 : valueNew.milliseconds); }, [onTimeMenuClose, closeOnChange, onChange]); const onRemove = react_1.default.useCallback(() => { if ((0, utils_1.is)('function', onRemove_)) onRemove_(value); }, [value, onRemove_]); react_1.default.useEffect(() => { // reset refs.repeatCount.current = {}; }, [(0, utils_1.hash)(value)]); const iconProps = { size: 'regular' }; const shortcuts = [ { name: 'Today', onClick: () => onChangeDate(new date_1.AmauiDate()), icon: (0, jsx_runtime_1.jsx)(IconMaterialWbSunnyW100_1.default, Object.assign({}, iconProps)) }, { name: 'Tomorrow', onClick: () => onChangeDate((0, date_1.add)(1, 'day')), icon: (0, jsx_runtime_1.jsx)(IconMaterialWbTwilightW100_1.default, Object.assign({}, iconProps)) }, { name: '7 days', onClick: () => onChangeDate((0, date_1.add)(7, 'day')), icon: (0, jsx_runtime_1.jsx)(IconMaterialCounter7W100_1.default, Object.assign({}, iconProps)) }, { name: '1 month', onClick: () => onChangeDate((0, date_1.add)(1, 'month')), icon: (0, jsx_runtime_1.jsx)(IconMaterialCalendarMonthW100_1.default, Object.assign({}, iconProps)) } ]; const onClear = react_1.default.useCallback((event) => { onChange(refs.dateProperty.current, null); }, [onChange]); const date = react_1.default.useMemo(() => new date_1.AmauiDate((value === null || value === void 0 ? void 0 : value[dateProperty]) || undefined), [value, dateProperty]); const repeats = (day) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s; if (!((_a = value === null || value === void 0 ? void 0 : value.repeat) === null || _a === void 0 ? void 0 : _a.active)) return; let unit = (_b = value === null || value === void 0 ? void 0 : value.repeat) === null || _b === void 0 ? void 0 : _b.unit; let valueRepeat = (_c = value === null || value === void 0 ? void 0 : value.repeat) === null || _c === void 0 ? void 0 : _c.value; if (unit === 'day') unit = 'days'; if (unit === 'week') { unit = 'days'; valueRepeat *= 7; } if (unit === 'month') unit = 'months'; let difference = (0, date_1.diff)(day, date, unit); let repeating = false; if (['day', 'week'].includes((_d = value === null || value === void 0 ? void 0 : value.repeat) === null || _d === void 0 ? void 0 : _d.unit)) { if ((value === null || value === void 0 ? void 0 : value.repeat.unit) === 'week' && !!((_f = (_e = value === null || value === void 0 ? void 0 : value.repeat) === null || _e === void 0 ? void 0 : _e.weekdays) === null || _f === void 0 ? void 0 : _f.length)) { difference = (0, date_1.diff)(day, date.dayWeek === 0 ? (0, date_1.add)(-1, 'week', date) : date, 'weeks'); if (day.dayWeek === 0) difference -= 1; const modulus = difference % ((_g = value === null || value === void 0 ? void 0 : value.repeat) === null || _g === void 0 ? void 0 : _g.value); repeating = (0, date_1.is)(day, 'after or same', date) && !modulus && ((_h = value === null || value === void 0 ? void 0 : value.repeat.weekdays) === null || _h === void 0 ? void 0 : _h.includes(day.dayWeek)); } else { const modulus = difference % valueRepeat; repeating = (0, date_1.is)(day, 'after or same', date) && !modulus; } } if (['month'].includes((_j = value === null || value === void 0 ? void 0 : value.repeat) === null || _j === void 0 ? void 0 : _j.unit)) { const modulus = difference % valueRepeat; const monthDate = (0, date_1.add)(difference, 'month', date); repeating = (monthDate.year === day.year && monthDate.dayYear === day.dayYear) && !modulus; } if (['year'].includes((_k = value === null || value === void 0 ? void 0 : value.repeat) === null || _k === void 0 ? void 0 : _k.unit)) { const modulus = difference % valueRepeat; const yearDate = (0, date_1.add)(difference, 'year', date); repeating = (0, date_1.is)(day, 'after', date) && (yearDate.year === day.year && yearDate.dayYear === day.dayYear) && !modulus; } if (((_l = value === null || value === void 0 ? void 0 : value.repeat) === null || _l === void 0 ? void 0 : _l.skip_weekends) && [0, 6].includes(day.dayWeek)) repeating = false; if (repeating) { const formated = (0, date_1.format)(day, utils_2.formats.date); if ((_o = (_m = value === null || value === void 0 ? void 0 : value.repeat) === null || _m === void 0 ? void 0 : _m.ends) === null || _o === void 0 ? void 0 : _o.active) { // date if ((value === null || value === void 0 ? void 0 : value.repeat.ends.version) === 'date') { const endsDate = new date_1.AmauiDate(value === null || value === void 0 ? void 0 : value.repeat.ends.value); repeating = repeating && ((day.year < endsDate.year) || (day.year === endsDate.year && ((day.month < endsDate.month) || (day.month === endsDate.month && day.dayYear <= endsDate.dayYear)))); } } if (repeating) { if (!refs.repeatCount.current[value === null || value === void 0 ? void 0 : value.id]) refs.repeatCount.current[value === null || value === void 0 ? void 0 : value.id] = []; if (!refs.repeatCount.current[value === null || value === void 0 ? void 0 : value.id].includes(formated)) refs.repeatCount.current[value === null || value === void 0 ? void 0 : value.id].push(formated); } if ((_q = (_p = value === null || value === void 0 ? void 0 : value.repeat) === null || _p === void 0 ? void 0 : _p.ends) === null || _q === void 0 ? void 0 : _q.active) { const indexRepeated = (_r = refs.repeatCount.current[value === null || value === void 0 ? void 0 : value.id]) === null || _r === void 0 ? void 0 : _r.indexOf(formated); // count if ((value === null || value === void 0 ? void 0 : value.repeat.ends.version) === 'count') repeating = repeating && (value === null || value === void 0 ? void 0 : value.repeat.ends.value) >= ((indexRepeated === -1 ? 0 : indexRepeated) + 1); } repeating = !((_s = value === null || value === void 0 ? void 0 : value.repeat.ends) === null || _s === void 0 ? void 0 : _s.active) || repeating; } return repeating; }; const onContextMenu = react_1.default.useCallback((event) => { event.stopPropagation(); }, []); const palette = theme.palette.color.primary; return ((0, jsx_runtime_1.jsx)(Menu, Object.assign({ open: menuOpen, onOpen: onMenuOpen, onClose: onMenuClose, onContextMenu: onContextMenu, name: ((0, jsx_runtime_1.jsx)(Calendar, { tonal: true, color: 'themed', calendarDefault: date, start: ((0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 1, direction: 'row', align: 'center', justify: 'center', className: classes.calendarShortcuts }, { children: shortcuts.map((item, index) => ((0, jsx_runtime_1.jsx)(Tooltip, Object.assign({ name: item.name }, { children: (0, jsx_runtime_1.jsx)(IconButton, Object.assign({ onClick: () => { item.onClick(); onMenuClose(); }, size: 'small' }, { children: item.icon })) }), index))) }))), value: (value === null || value === void 0 ? void 0 : value[dateProperty]) ? date : null, onChange: onChangeDate, onContextMenu: onContextMenu, size: 'small', end: ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 0.5, fullWidth: true, className: classes.end }, { children: [startBottom, (value === null || value === void 0 ? void 0 : value[dateProperty]) && ((0, jsx_runtime_1.jsx)(Menu, Object.assign({ open: timeMenuOpen, onOpen: onTimeMenuOpen, onClose: onTimeMenuClose, name: () => ((0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 1, align: 'center', fullWidth: true }, { children: (0, jsx_runtime_1.jsx)(TimePicker, { value: date, onChange: onChangeTime, clear: false, MainProps: { elevation: theme.palette.light ? 8 : 0 }, static: true }) }))), className: (0, style_react_1.classNames)([ classes.timeMenu, 'amaui-time' ]), style: { width: (_a = refs.time.current) === null || _a === void 0 ? void 0 : _a.clientWidth } }, { children: (0, jsx_runtime_1.jsx)(ListItem, { ref: refs.time, start: ((0, jsx_runtime_1.jsx)(IconMaterialScheduleW100_1.default, Object.assign({}, iconProps))), primary: ((0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'b2', color: 'inherit' }, { children: (0, date_1.format)(date, 'HH:mm') }))), startAlign: 'center', size: 'small', button: true, Component: 'div', className: classes.item }) }))), endBottom, (0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 0.4, direction: 'row', align: 'center', justify: 'space-between', fullWidth: true, className: classes.menuFooter }, { children: [(0, jsx_runtime_1.jsx)(Button, Object.assign({ onClick: onClear, version: 'text', size: 'small', disabled: !(value === null || value === void 0 ? void 0 : value[dateProperty]) }, { children: "Clear" })), !noRemove && ((0, jsx_runtime_1.jsx)(Tooltip, Object.assign({ name: 'Remove' }, { children: (0, jsx_runtime_1.jsx)(IconButton, Object.assign({ size: 'small', onClick: onRemove }, { children: (0, jsx_runtime_1.jsx)(IconMaterialDeleteW100_1.default, Object.assign({}, iconProps)) })) })))] }))] }))), CalendarMonthProps: { renderDay: (dayAmauiDate, propsDay, day, outside) => { const repeating = repeats(dayAmauiDate); return ((0, jsx_runtime_1.jsx)(PaginationItem, Object.assign({ tonal: true, color: 'inherit', size: 'small', InteractionProps: { background: false }, TypeProps: { version: 'b3', priority: !day.selected ? !day.weekend ? 'primary' : 'secondary' : undefined }, "aria-label": (0, date_1.format)(dayAmauiDate, 'DD-MM-YYYY'), className: (0, style_react_1.classNames)([ classes.dayValue, repeating && classes.dayValueRepeating ]), style: Object.assign(Object.assign({}, (day.today ? { boxShadow: `inset 0px 0px 0px 1px ${palette[40]}` } : undefined)), (day.selected ? { color: theme.methods.palette.color.value(undefined, 90, true, palette), backgroundColor: theme.methods.palette.color.value(undefined, 40, true, palette) } : undefined)) }, propsDay, { children: day.value }))); }, noTransition: true }, className: (0, style_react_1.classNames)([ 'amaui-ObjectCalendar-root', classes.calendar ]) })), ClickListenerProps: { contextMenu: false }, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('CalendarMenu', theme) && [ 'amaui-CalendarMenu-root' ], className, classes.root ]) }, other, { children: children }))); }); CalendarMenu.displayName = 'amaui-CalendarMenu'; exports.default = CalendarMenu;