@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
429 lines (428 loc) • 16.7 kB
JavaScript
;
"use client";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
require("core-js/modules/es.string.replace.js");
require("core-js/modules/web.dom-collections.iterator.js");
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _dateFns = require("date-fns");
var _DatePickerCalc = require("./DatePickerCalc");
var _Button = _interopRequireDefault(require("../button/Button"));
var _DatePickerContext = _interopRequireDefault(require("./DatePickerContext"));
var _DatePickerCalendarNavigator = require("./DatePickerCalendarNavigator");
var _DateFormatUtils = require("../date-format/DateFormatUtils");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const defaultProps = {
hideNavigation: false,
hideDays: false,
onlyMonth: false,
hideNextMonthWeek: false,
noAutoFocus: false,
rtl: false,
resetDate: true
};
const arrowKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
const keysToHandle = ['Enter', 'Space', ...arrowKeys];
function DatePickerCalendar(restOfProps) {
const props = _objectSpread(_objectSpread({}, defaultProps), restOfProps);
const {
updateDates,
setHasClickedCalendarDay,
startDate,
endDate,
maxDate,
minDate,
startMonth,
endMonth,
hoverDate,
setHoverDate,
setSubmittedDates,
props: {
onDaysRender,
yearNavigation
},
translation: {
DatePicker: {
firstDay: defaultFirstDayOfWeek,
selectedMonth
}
}
} = (0, _react.useContext)(_DatePickerContext.default);
const {
id,
nr,
rtl,
month,
isRange,
firstDayOfWeek = defaultFirstDayOfWeek,
hideNavigation,
locale,
hideDays,
onSelect,
onKeyDown,
resetDate,
noAutoFocus,
hideNextMonthWeek,
onlyMonth
} = props;
const tableRef = (0, _react.useRef)();
const days = (0, _react.useRef)({});
const cache = (0, _react.useRef)({});
(0, _react.useEffect)(() => {
if (!noAutoFocus && nr === 0) {
if (tableRef.current) {
tableRef.current.focus({
preventScroll: true
});
}
}
}, [noAutoFocus, nr]);
(0, _react.useEffect)(() => {
setSubmittedDates({
startDate,
endDate
});
}, []);
const onMouseLeaveHandler = (0, _react.useCallback)(() => {
setHoverDate(undefined);
}, [setHoverDate]);
const callOnSelect = (0, _react.useCallback)(event => {
onSelect === null || onSelect === void 0 ? void 0 : onSelect(event);
}, [onSelect]);
const getDays = (0, _react.useCallback)(month => {
let daysFromCalendar = (0, _DatePickerCalc.getCalendar)(month || new Date(), (0, _DatePickerCalc.dayOffset)(firstDayOfWeek), {
onlyMonth,
hideNextMonthWeek
}).map(date => (0, _DatePickerCalc.makeDayObject)(date, {
startDate,
endDate,
hoverDate,
minDate,
maxDate,
month
}));
if (onDaysRender) {
const changedDays = onDaysRender(daysFromCalendar, nr);
if (Array.isArray(changedDays)) {
daysFromCalendar = changedDays;
}
}
days.current[(0, _dateFns.format)(month, 'yyyy-MM')] = daysFromCalendar;
return daysFromCalendar;
}, [endDate, firstDayOfWeek, hideNextMonthWeek, hoverDate, maxDate, minDate, nr, onDaysRender, onlyMonth, startDate]);
const keyNavCalc = (0, _react.useCallback)((date, keyCode) => {
if (!arrowKeys.includes(keyCode)) {
return date;
}
const dateHandler = /(ArrowLeft|ArrowRight)/g.test(keyCode) ? _dateFns.addDays : _dateFns.addWeeks;
const shiftAmount = /(ArrowLeft|ArrowUp)/g.test(keyCode) ? -1 : 1;
return dateHandler(date, shiftAmount);
}, []);
const findValid = (0, _react.useCallback)((date, keyCode) => {
if (!onDaysRender || !days.current) {
return date;
}
const month = (0, _dateFns.format)(date, 'yyyy-MM');
if (!days.current[month]) {
getDays(date);
}
if (Array.isArray(days.current[month])) {
const foundDate = days.current[month].find(cur => (0, _dateFns.isSameDay)(cur.date, date));
if (foundDate !== null && foundDate !== void 0 && foundDate.date && (foundDate.isDisabled || foundDate.isSelectable === false || foundDate.isInactive)) {
const nextDate = keyNavCalc(foundDate.date, keyCode);
return findValid(nextDate, keyCode);
}
if (foundDate !== null && foundDate !== void 0 && foundDate.date) {
return foundDate.date;
}
}
return date;
}, [onDaysRender, getDays, keyNavCalc]);
const hasReachedEnd = (0, _react.useCallback)(date => (0, _DatePickerCalc.isDisabled)(date, minDate, maxDate), [minDate, maxDate]);
const onKeyDownHandler = (0, _react.useCallback)(event => {
const pressedKey = event.code;
if (typeof onKeyDown === 'function') {
return onKeyDown(event, tableRef, nr);
}
if (!keysToHandle.includes(pressedKey)) {
return;
}
event.preventDefault();
event.persist();
const currentDates = {
startDate,
endDate,
startMonth,
endMonth
};
const dateType = !isRange || nr === 0 ? 'start' : 'end';
const currentDate = currentDates[`${dateType}Date`];
let newDate = currentDate ? keyNavCalc(currentDate, pressedKey) : currentDates[`${dateType}Month`] || (isRange && nr === 1 ? (0, _dateFns.addMonths)(new Date(), 1) : new Date());
if (newDate === currentDate && (pressedKey === 'Enter' || pressedKey === 'Space')) {
return callOnSelect({
event,
nr,
hidePicker: true
});
}
const dates = {};
const currentMonth = currentDates[`${dateType}Month`];
if (currentMonth && !currentDate || currentMonth && Math.abs((0, _dateFns.differenceInMonths)(newDate, currentMonth)) > 1) {
newDate = !isRange ? currentMonth : nr === 0 ? (0, _dateFns.setDate)(currentMonth, 1) : (0, _dateFns.lastDayOfMonth)(currentMonth);
} else if (currentMonth && !(0, _dateFns.isSameMonth)(currentDate, currentMonth)) {
dates[`${dateType}Month`] = newDate;
}
newDate = findValid(newDate, pressedKey);
if (hasReachedEnd(newDate)) {
return;
}
dates[`${dateType}Date`] = newDate;
if (!isRange) {
dates.endDate = newDate;
} else {
if (!startDate) {
dates.startDate = newDate;
}
if (!endDate) {
dates.endDate = newDate;
}
}
if (onlyMonth || hideNavigation) {
if (!(0, _dateFns.isSameMonth)(dates.startDate, startDate) || !(0, _dateFns.isSameMonth)(dates.endDate, startDate)) {
return;
}
}
updateDates(dates, () => {
callOnSelect(_objectSpread({
event,
nr,
hidePicker: false
}, dates));
});
if (tableRef && tableRef.current) {
tableRef.current.focus({
preventScroll: true
});
}
}, [callOnSelect, findValid, hasReachedEnd, onKeyDown, startDate, endDate, updateDates, hideNavigation, isRange, keyNavCalc, nr, onlyMonth, endMonth, startMonth]);
const cacheKey = (0, _react.useMemo)(() => {
return [nr, month, firstDayOfWeek, onlyMonth, hideNextMonthWeek, startDate, endDate, hoverDate, maxDate, minDate].join('|');
}, [nr, month, firstDayOfWeek, onlyMonth, hideNextMonthWeek, startDate, endDate, hoverDate, maxDate, minDate]);
const weekDays = (0, _react.useMemo)(() => {
if (cache.current[cacheKey]) {
return cache.current[cacheKey];
}
let count = 0;
const days = getDays(month).reduce((acc, cur, i) => {
acc[count] = acc[count] || [];
acc[count].push(cur);
if (i % 7 === 6) {
count++;
}
return acc;
}, {});
cache.current[cacheKey] = Object.values(days);
return cache.current[cacheKey];
}, [cacheKey, getDays, month]);
return _react.default.createElement("div", {
className: 'dnb-date-picker__calendar' + (rtl ? " rtl" : ""),
lang: locale
}, !hideNavigation && !onlyMonth && _react.default.createElement("div", {
className: "dnb-date-picker__header"
}, _react.default.createElement(_DatePickerCalendarNavigator.DatePickerCalendarNav, {
type: yearNavigation ? 'month' : 'both',
id: id,
nr: nr,
date: month,
locale: locale
}), yearNavigation && _react.default.createElement(_DatePickerCalendarNavigator.DatePickerCalendarNav, {
type: "year",
id: id,
nr: nr,
date: month,
locale: locale
})), onlyMonth && _react.default.createElement("div", {
className: "dnb-date-picker__header dnb-date-picker__header--only-month-label"
}, _react.default.createElement("label", {
id: `${id}--title`,
className: "dnb-date-picker__header__title dnb-no-focus",
title: selectedMonth.replace(/%s/, (0, _DateFormatUtils.formatDate)(month, {
locale,
options: {
month: 'long'
}
})),
tabIndex: -1
}, (0, _DateFormatUtils.formatDate)(month, {
locale,
options: {
month: 'long'
}
}))), _react.default.createElement("table", {
role: "grid",
className: "dnb-no-focus",
tabIndex: 0,
"aria-labelledby": `${id}--title`,
onKeyDown: onKeyDownHandler,
onMouseLeave: onMouseLeaveHandler,
ref: tableRef
}, !hideDays && !onlyMonth && _react.default.createElement("thead", {
"aria-hidden": true
}, _react.default.createElement("tr", {
role: "row",
className: "dnb-date-picker__labels"
}, (0, _DatePickerCalc.getWeek)((0, _DatePickerCalc.dayOffset)(firstDayOfWeek)).map((day, i) => _react.default.createElement("th", {
key: i,
role: "columnheader",
scope: "col",
className: "dnb-date-picker__labels__day",
"aria-label": (0, _DateFormatUtils.formatDate)(day, {
locale,
options: {
weekday: 'long'
}
})
}, (0, _DateFormatUtils.formatDate)(day, {
locale,
options: {
weekday: 'short'
}
}).substring(0, 2))))), _react.default.createElement("tbody", null, weekDays.map((week, i) => {
return _react.default.createElement("tr", {
key: 'week' + i,
role: "row",
className: "dnb-date-picker__days"
}, week.map((day, i) => {
const title = (0, _DateFormatUtils.formatDate)(day.date, {
locale,
options: {
weekday: 'long',
day: 'numeric',
month: 'long',
year: 'numeric'
}
});
const handleAsDisabled = day.isLastMonth || day.isNextMonth || day.isDisabled || day.isInactive;
const dateType = day.isStartDate ? 'start' : day.isEndDate ? 'end' : undefined;
const isSelectedDate = nr === 0 ? day.isStartDate : day.isEndDate;
const paramsCell = _objectSpread(_objectSpread({
tabIndex: -1
}, dateType && {
id: `${id}--button-${dateType}`
}), isSelectedDate && {
['aria-selected']: true
});
const paramsButton = _objectSpread({}, isSelectedDate && {
['aria-current']: 'date'
});
return _react.default.createElement("td", _extends({
key: 'day' + i,
role: "gridcell",
className: (0, _classnames.default)("dnb-date-picker__day dnb-no-focus", buildDayClassNames(day))
}, paramsCell), _react.default.createElement(_Button.default, _extends({
size: "medium",
variant: "secondary",
text: day.date.getDate(),
bounding: true,
disabled: handleAsDisabled,
tabIndex: handleAsDisabled ? 0 : -1,
"aria-disabled": handleAsDisabled,
"aria-label": title
}, paramsButton, {
on_click: handleAsDisabled ? undefined : _ref => {
let {
event
} = _ref;
return onSelectRange({
day,
isRange,
startDate,
endDate,
resetDate,
event,
setHasClickedCalendarDay,
onSelect: state => {
updateDates(state, dates => callOnSelect(_objectSpread(_objectSpread({}, dates), {}, {
event,
nr,
hidePicker: !isRange
})));
}
});
},
onMouseOver: handleAsDisabled ? undefined : () => onHoverDay({
day,
hoverDate,
setHoverDate
}),
onFocus: handleAsDisabled ? undefined : () => onHoverDay({
day,
hoverDate,
setHoverDate
})
})));
}));
}))));
}
var _default = exports.default = DatePickerCalendar;
function onSelectRange(_ref2) {
let {
day,
isRange,
startDate,
endDate,
onSelect,
resetDate,
event,
setHasClickedCalendarDay
} = _ref2;
event.persist();
if (!isRange) {
return onSelect({
startDate: (0, _dateFns.startOfDay)(day.date),
endDate: (0, _dateFns.startOfDay)(day.date),
event
});
}
setHasClickedCalendarDay(true);
if (!startDate || resetDate && startDate && endDate) {
return onSelect({
startDate: (0, _dateFns.startOfDay)(day.date),
endDate: undefined,
event
});
}
const daysToStartDate = Math.abs((0, _dateFns.differenceInCalendarDays)(startDate, day.date));
const daysToEndDate = Math.abs((0, _dateFns.differenceInCalendarDays)(endDate, day.date));
const range = (0, _DatePickerCalc.toRange)(endDate && !resetDate && daysToStartDate < daysToEndDate ? endDate : startDate, day.date);
return onSelect({
startDate: (0, _dateFns.startOfDay)(range.startDate),
endDate: (0, _dateFns.startOfDay)(range.endDate),
event
});
}
function onHoverDay(_ref3) {
let {
day,
hoverDate,
setHoverDate
} = _ref3;
if (!(0, _dateFns.isSameDay)(day.date, hoverDate)) {
setHoverDate === null || setHoverDate === void 0 ? void 0 : setHoverDate(day.date);
}
}
function buildDayClassNames(day) {
return (0, _classnames.default)(day.className, day.isStartDate && 'dnb-date-picker__day--start-date', day.isEndDate && 'dnb-date-picker__day--end-date', day.isPreview && 'dnb-date-picker__day--preview', day.isWithinSelection && 'dnb-date-picker__day--within-selection', day.isSelectable && 'dnb-date-picker__day--selectable', day.isInactive && 'dnb-date-picker__day--inactive', day.isDisabled && 'dnb-date-picker__day--disabled', day.isToday && 'dnb-date-picker__day--today');
}
//# sourceMappingURL=DatePickerCalendar.js.map