@amaui/ui-react
Version:
UI for React
314 lines (313 loc) • 21.9 kB
JavaScript
"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;