@apptane/react-ui-calendar
Version:
Calendar component in Apptane React UI framework
113 lines (104 loc) • 9.8 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
const _excluded = ["colorMode", "appearance", "panes", "selected", "rangeStart", "rangeEnd", "notBefore", "notAfter", "weekStartsOnSunday", "onClick"];
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
import { IconButton } from "@apptane/react-ui-button";
import { Pane } from "@apptane/react-ui-pane";
import { useVisualAppearance } from "@apptane/react-ui-theme";
import { Text } from "@apptane/react-ui-typography";
import { css } from "@emotion/react";
import { useEffect, useState } from "react";
import { addMonths, format, isAfter, isBefore, startOfMonth } from "date-fns";
import { CalendarPropTypes } from "./Calendar.types.js";
import { CalendarMonth } from "./CalendarMonth.js";
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
import { jsxs as _jsxs } from "@emotion/react/jsx-runtime";
const StyleEmpty = size => /*#__PURE__*/css("height:", size, "px;width:", size, "px;" + (process.env.NODE_ENV === "production" ? "" : ";label:StyleEmpty;"), process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9DYWxlbmRhci50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBVXdDIiwiZmlsZSI6Ii4uL3NyYy9DYWxlbmRhci50c3giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJY29uQnV0dG9uIH0gZnJvbSBcIkBhcHB0YW5lL3JlYWN0LXVpLWJ1dHRvblwiO1xuaW1wb3J0IHsgUGFuZSB9IGZyb20gXCJAYXBwdGFuZS9yZWFjdC11aS1wYW5lXCI7XG5pbXBvcnQgeyB1c2VWaXN1YWxBcHBlYXJhbmNlIH0gZnJvbSBcIkBhcHB0YW5lL3JlYWN0LXVpLXRoZW1lXCI7XG5pbXBvcnQgeyBUZXh0IH0gZnJvbSBcIkBhcHB0YW5lL3JlYWN0LXVpLXR5cG9ncmFwaHlcIjtcbmltcG9ydCB7IGNzcyB9IGZyb20gXCJAZW1vdGlvbi9yZWFjdFwiO1xuaW1wb3J0IHsgdXNlRWZmZWN0LCB1c2VTdGF0ZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgYWRkTW9udGhzLCBmb3JtYXQsIGlzQWZ0ZXIsIGlzQmVmb3JlLCBzdGFydE9mTW9udGggfSBmcm9tIFwiZGF0ZS1mbnNcIjtcbmltcG9ydCB7IENhbGVuZGFyUHJvcHMsIENhbGVuZGFyUHJvcFR5cGVzIH0gZnJvbSBcIi4vQ2FsZW5kYXIudHlwZXMuanNcIjtcbmltcG9ydCB7IENhbGVuZGFyTW9udGggfSBmcm9tIFwiLi9DYWxlbmRhck1vbnRoLmpzXCI7XG5cbmNvbnN0IFN0eWxlRW1wdHkgPSAoc2l6ZTogbnVtYmVyKSA9PiBjc3NgXG4gIGhlaWdodDogJHtzaXplfXB4O1xuICB3aWR0aDogJHtzaXplfXB4O1xuYDtcblxuLyoqXG4gKiBgQ2FsZW5kYXJgIGNvbXBvbmVudCDigJQgc3VwcG9ydHMgb25lIG9yIG1vcmUgbW9udGggcGFuZXMsIGRhdGUgcmFuZ2VzLCBzZWxlY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDYWxlbmRhcih7XG4gIGNvbG9yTW9kZSxcbiAgYXBwZWFyYW5jZSxcbiAgcGFuZXMsXG4gIHNlbGVjdGVkLFxuICByYW5nZVN0YXJ0LFxuICByYW5nZUVuZCxcbiAgbm90QmVmb3JlLFxuICBub3RBZnRlcixcbiAgd2Vla1N0YXJ0c09uU3VuZGF5LFxuICBvbkNsaWNrLFxuICAuLi5vdGhlclxufTogQ2FsZW5kYXJQcm9wcykge1xuICBjb25zdCBbdmlzdWFsQXBwZWFyYW5jZSwgdGhlbWVdID0gdXNlVmlzdWFsQXBwZWFyYW5jZShcImNhbGVuZGFyXCIsIGNvbG9yTW9kZSwgYXBwZWFyYW5jZSk7XG4gIGNvbnN0IHZpc3VhbFN0eWxlID0gdGhlbWUuY29tcG9uZW50cy5jYWxlbmRhci5zdHlsZTtcbiAgY29uc3QgaGVhZGVyU2l6ZSA9IHRoZW1lLmNvbXBvbmVudHMuYnV0dG9uLnNpemVzLnNtYWxsO1xuXG4gIGNvbnN0IFtjdXJyZW50LCBzZXRDdXJyZW50XSA9IHVzZVN0YXRlPERhdGU+KCgpID0+IHN0YXJ0T2ZNb250aChzZWxlY3RlZCA/PyBuZXcgRGF0ZSgpKSk7XG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHNlbGVjdGVkICE9IG51bGwpIHtcbiAgICAgIHNldEN1cnJlbnQoc3RhcnRPZk1vbnRoKHNlbGVjdGVkKSk7XG4gICAgfVxuICB9LCBbc2VsZWN0ZWRdKTtcblxuICBjb25zdCBjb3VudCA9IE1hdGgubWF4KDEsIHBhbmVzID8/IDEpO1xuICBjb25zdCBvZmZzZXQgPSBNYXRoLmZsb29yKChjb3VudCAtIDEpIC8gMik7XG5cbiAgY29uc3QgbW9udGhQcm9wcyA9IHtcbiAgICBjb2xvck1vZGUsXG4gICAgcmFuZ2VTdGFydCxcbiAgICByYW5nZUVuZCxcbiAgICBub3RCZWZvcmUsXG4gICAgbm90QWZ0ZXIsXG4gICAgd2Vla1N0YXJ0c09uU3VuZGF5LFxuICAgIG9uQ2xpY2ssXG4gICAgc2VsZWN0ZWQsXG4gIH07XG5cbiAgY29uc3QgYmxvY2tzOiBSZWFjdC5SZWFjdE5vZGVbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcbiAgICBjb25zdCBkID0gaSAtIG9mZnNldCA9PT0gMCA/IGN1cnJlbnQgOiBhZGRNb250aHMoY3VycmVudCwgaSAtIG9mZnNldCk7XG4gICAgY29uc3QgeWVhciA9IGQuZ2V0RnVsbFllYXIoKTtcbiAgICBjb25zdCBtb250aCA9IGQuZ2V0TW9udGgoKTtcblxuICAgIGJsb2Nrcy5wdXNoKFxuICAgICAgPFBhbmUga2V5PXtgJHt5ZWFyfS0ke21vbnRofWB9IG9yaWVudGF0aW9uPVwidmVydGljYWxcIiBtYXJnaW5MZWZ0PXtpID4gMCA/IHZpc3VhbFN0eWxlLnNwYWNpbmcgOiB1bmRlZmluZWR9PlxuICAgICAgICA8UGFuZSBvcmllbnRhdGlvbj1cImhvcml6b250YWxcIiBob3Jpem9udGFsQWxpZ25tZW50PVwic3BhY2UtYmV0d2VlblwiIHZlcnRpY2FsQWxpZ25tZW50PVwibWlkZGxlXCI+XG4gICAgICAgICAge2kgPT09IDAgPyAoXG4gICAgICAgICAgICA8SWNvbkJ1dHRvblxuICAgICAgICAgICAgICBpY29uTmFtZT1cImk6YXJyb3ctcmlnaHRcIlxuICAgICAgICAgICAgICBjb2xvck1vZGU9e2NvbG9yTW9kZX1cbiAgICAgICAgICAgICAgYXBwZWFyYW5jZT1cIm1pbmltYWxcIlxuICAgICAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgICBkaXNhYmxlZD17bm90QmVmb3JlICE9IG51bGwgJiYgaXNCZWZvcmUoYWRkTW9udGhzKGN1cnJlbnQsIC1vZmZzZXQpLCBub3RCZWZvcmUpfVxuICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBzZXRDdXJyZW50KGFkZE1vbnRocyhjdXJyZW50LCAtMSkpfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPGRpdiBjc3M9e1N0eWxlRW1wdHkoaGVhZGVyU2l6ZSl9IC8+XG4gICAgICAgICAgKX1cbiAgICAgICAgICA8VGV4dCB7Li4udmlzdWFsU3R5bGUuZm9udC5oZWFkZXJ9IGNvbG9yPXt2aXN1YWxBcHBlYXJhbmNlLnRleHQuaGVhZGVyfT5cbiAgICAgICAgICAgIHtmb3JtYXQoZCwgXCJNTU1NLCB5eXl5XCIpfVxuICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICB7aSA9PT0gY291bnQgLSAxID8gKFxuICAgICAgICAgICAgPEljb25CdXR0b25cbiAgICAgICAgICAgICAgaWNvbk5hbWU9XCJpOmFycm93LWxlZnRcIlxuICAgICAgICAgICAgICBjb2xvck1vZGU9e2NvbG9yTW9kZX1cbiAgICAgICAgICAgICAgYXBwZWFyYW5jZT1cIm1pbmltYWxcIlxuICAgICAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgICBkaXNhYmxlZD17bm90QWZ0ZXIgIT0gbnVsbCAmJiBpc0FmdGVyKGFkZE1vbnRocyhjdXJyZW50LCBjb3VudCAtIG9mZnNldCksIG5vdEFmdGVyKX1cbiAgICAgICAgICAgICAgb25DbGljaz17KCkgPT4gc2V0Q3VycmVudChhZGRNb250aHMoY3VycmVudCwgMSkpfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPGRpdiBjc3M9e1N0eWxlRW1wdHkoaGVhZGVyU2l6ZSl9IC8+XG4gICAgICAgICAgKX1cbiAgICAgICAgPC9QYW5lPlxuICAgICAgICA8Q2FsZW5kYXJNb250aCB7Li4ubW9udGhQcm9wc30geWVhcj17eWVhcn0gbW9udGg9e21vbnRofSAvPlxuICAgICAgPC9QYW5lPlxuICAgICk7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIDxQYW5lIHsuLi5vdGhlcn0gb3JpZW50YXRpb249XCJob3Jpem9udGFsXCI+XG4gICAgICB7YmxvY2tzfVxuICAgIDwvUGFuZT5cbiAgKTtcbn1cblxuQ2FsZW5kYXIuZGlzcGxheU5hbWUgPSBcIkNhbGVuZGFyXCI7XG5DYWxlbmRhci5wcm9wVHlwZXMgPSBDYWxlbmRhclByb3BUeXBlcztcblxuZXhwb3J0IGRlZmF1bHQgQ2FsZW5kYXI7XG4iXX0= */");
/**
* `Calendar` component — supports one or more month panes, date ranges, selection.
*/
export function Calendar(_ref) {
let {
colorMode,
appearance,
panes,
selected,
rangeStart,
rangeEnd,
notBefore,
notAfter,
weekStartsOnSunday,
onClick
} = _ref,
other = _objectWithoutProperties(_ref, _excluded);
const [visualAppearance, theme] = useVisualAppearance("calendar", colorMode, appearance);
const visualStyle = theme.components.calendar.style;
const headerSize = theme.components.button.sizes.small;
const [current, setCurrent] = useState(() => startOfMonth(selected !== null && selected !== void 0 ? selected : new Date()));
useEffect(() => {
if (selected != null) {
setCurrent(startOfMonth(selected));
}
}, [selected]);
const count = Math.max(1, panes !== null && panes !== void 0 ? panes : 1);
const offset = Math.floor((count - 1) / 2);
const monthProps = {
colorMode,
rangeStart,
rangeEnd,
notBefore,
notAfter,
weekStartsOnSunday,
onClick,
selected
};
const blocks = [];
for (let i = 0; i < count; ++i) {
const d = i - offset === 0 ? current : addMonths(current, i - offset);
const year = d.getFullYear();
const month = d.getMonth();
blocks.push(_jsxs(Pane, {
orientation: "vertical",
marginLeft: i > 0 ? visualStyle.spacing : undefined,
children: [_jsxs(Pane, {
orientation: "horizontal",
horizontalAlignment: "space-between",
verticalAlignment: "middle",
children: [i === 0 ? _jsx(IconButton, {
iconName: "i:arrow-right",
colorMode: colorMode,
appearance: "minimal",
size: "small",
disabled: notBefore != null && isBefore(addMonths(current, -offset), notBefore),
onClick: () => setCurrent(addMonths(current, -1))
}) : _jsx("div", {
css: StyleEmpty(headerSize)
}), _jsx(Text, _objectSpread(_objectSpread({}, visualStyle.font.header), {}, {
color: visualAppearance.text.header,
children: format(d, "MMMM, yyyy")
})), i === count - 1 ? _jsx(IconButton, {
iconName: "i:arrow-left",
colorMode: colorMode,
appearance: "minimal",
size: "small",
disabled: notAfter != null && isAfter(addMonths(current, count - offset), notAfter),
onClick: () => setCurrent(addMonths(current, 1))
}) : _jsx("div", {
css: StyleEmpty(headerSize)
})]
}), _jsx(CalendarMonth, _objectSpread(_objectSpread({}, monthProps), {}, {
year: year,
month: month
}))]
}, "".concat(year, "-").concat(month)));
}
return _jsx(Pane, _objectSpread(_objectSpread({}, other), {}, {
orientation: "horizontal",
children: blocks
}));
}
Calendar.displayName = "Calendar";
Calendar.propTypes = CalendarPropTypes;
export default Calendar;
//# sourceMappingURL=Calendar.js.map