react-native-paper-dates
Version:
Performant Date Picker for React Native Paper
361 lines (360 loc) • 14.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.getHorizontalMonthOffset = getHorizontalMonthOffset;
exports.getIndexFromHorizontalOffset = getIndexFromHorizontalOffset;
exports.getIndexFromVerticalOffset = getIndexFromVerticalOffset;
exports.getMonthHeight = getMonthHeight;
exports.getVerticalMonthsOffset = getVerticalMonthsOffset;
exports.weekSize = exports.weekMargin = exports.monthHeaderSingleMarginTop = exports.monthHeaderSingleMarginBottom = exports.monthHeaderSingleHeight = exports.montHeaderHeight = void 0;
var _reactNative = require("react-native");
var _reactNativePaper = require("react-native-paper");
var _Day = _interopRequireWildcard(require("./Day"));
var _dateUtils = require("./dateUtils");
var _CalendarHeader = require("./CalendarHeader");
var _DayNames = require("./DayNames");
var _utils = require("../shared/utils");
var _react = require("react");
var _styles = require("../shared/styles");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function Month(props) {
const {
locale,
mode,
index,
onPressYear,
selectingYear,
onPressDate,
primaryColor,
selectColor,
roundness,
validRange,
disableWeekDays,
scrollMode,
startDate,
endDate,
date,
dates,
startWeekOnMonday,
startYear,
endYear
} = props;
const isHorizontal = scrollMode === 'horizontal';
const theme = (0, _reactNativePaper.useTheme)();
const textColorOnPrimary = (0, _utils.useTextColorOnPrimary)();
const realIndex = (0, _dateUtils.getRealIndex)(index, startYear, endYear);
const {
isDisabled,
isWithinValidRange
} = (0, _dateUtils.useRangeChecker)(validRange);
const {
monthName,
month,
year
} = (0, _react.useMemo)(() => {
const md = (0, _dateUtils.addMonths)(new Date(), realIndex);
const y = md.getFullYear();
const m = md.getMonth();
const formatter = new Intl.DateTimeFormat(locale, {
month: 'long'
});
return {
monthName: formatter.format(md),
month: m,
year: y
};
}, [realIndex, locale]);
const grid = (0, _react.useMemo)(() => {
const today = new Date();
const daysInMonth = (0, _dateUtils.getDaysInMonth)({
year,
month
});
const dayOfWeek = (0, _dateUtils.getFirstDayOfMonth)({
year,
month,
startWeekOnMonday
});
const emptyDays = dayOfWeek;
return monthGrid(index, startWeekOnMonday, startYear, endYear).map(({
days,
weekGrid
}) => {
return {
weekIndex: weekGrid,
generatedDays: days.map((_, dayIndex) => {
const isFirstWeek = weekGrid === 0;
const realDayIndex = emptyDays - dayIndex;
const beforeWeekDay = isFirstWeek && realDayIndex > 0;
const dayOfMonth = weekGrid * 7 + dayIndex - emptyDays + 1;
const afterWeekDay = dayOfMonth > daysInMonth;
const day = new Date(year, month, dayOfMonth);
const isToday = (0, _dateUtils.areDatesOnSameDay)(day, today);
let inRange = false;
let disabled = isDisabled(day);
let selected = false;
let leftCrop = dayOfMonth === 1;
let rightCrop = dayOfMonth === daysInMonth;
const isFirstDayOfMonth = dayOfMonth === 1;
const isLastDayOfMonth = dayOfMonth === daysInMonth;
if (mode === 'range') {
const selectedStartDay = (0, _dateUtils.areDatesOnSameDay)(day, startDate);
const selectedEndDay = (0, _dateUtils.areDatesOnSameDay)(day, endDate);
selected = selectedStartDay || selectedEndDay;
inRange = (0, _dateUtils.isDateBetween)(day, {
startDate,
endDate
});
if (selectedStartDay) {
leftCrop = true;
}
if (selectedEndDay) {
rightCrop = true;
}
if (dayIndex === 0 && !selectedStartDay) {
leftCrop = false;
}
if (dayIndex === 6 && !selectedEndDay) {
rightCrop = false;
}
if (isFirstDayOfMonth && selectedEndDay || isLastDayOfMonth && selectedStartDay) {
inRange = false;
}
} else if (mode === 'multiple') {
const safeDates = dates || [];
selected = safeDates.some(d => (0, _dateUtils.areDatesOnSameDay)(day, d));
const yesterday = new Date(year, month, dayOfMonth - 1);
const tomorrow = new Date(year, month, dayOfMonth + 1);
const yesterdaySelected = safeDates.some(d => (0, _dateUtils.areDatesOnSameDay)(d, yesterday));
const tomorrowSelected = safeDates.some(d => (0, _dateUtils.areDatesOnSameDay)(d, tomorrow));
if (selected) {
if (tomorrowSelected && yesterdaySelected) {
inRange = true;
}
if (tomorrowSelected && !yesterdaySelected) {
inRange = true;
leftCrop = true;
}
if (yesterdaySelected && !tomorrowSelected) {
inRange = true;
rightCrop = true;
}
if (isFirstDayOfMonth && !tomorrowSelected) {
inRange = false;
}
if (isLastDayOfMonth && !yesterdaySelected) {
inRange = false;
}
if (inRange && !leftCrop && !rightCrop) {
selected = false;
}
}
} else if (mode === 'single') {
selected = (0, _dateUtils.areDatesOnSameDay)(day, date);
}
const isWithinOptionalValidRange = isWithinValidRange(day);
if (inRange && !disabled) {
disabled = false;
}
if (!isWithinOptionalValidRange) {
disabled = true;
}
return {
beforeWeekDay,
afterWeekDay,
year,
month,
dayOfMonth,
dayIndex,
mode,
selected,
inRange,
leftCrop,
rightCrop,
isToday,
disabled
};
})
};
});
}, [year, month, index, isDisabled, mode, isWithinValidRange, startDate, endDate, dates, date, startWeekOnMonday, startYear, endYear]);
let textFont = theme?.isV3 ? theme.fonts.titleSmall : theme.fonts.medium;
const iconColor = theme.isV3 ? theme.colors.onSurfaceVariant : theme.colors.onSurface;
const iconSourceV3 = selectingYear ? 'menu-up' : 'menu-down';
const iconSourceV2 = selectingYear ? 'chevron-up' : 'chevron-down';
const iconSource = theme.isV3 ? iconSourceV3 : iconSourceV2;
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: {
height: getMonthHeight(scrollMode, index, startWeekOnMonday, startYear, endYear)
},
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.monthHeader, isHorizontal ? {
marginTop: monthHeaderSingleMarginTop,
marginBottom: monthHeaderSingleMarginBottom
} : null],
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativePaper.TouchableRipple, {
disabled: !isHorizontal,
onPress: isHorizontal ? () => onPressYear(year) : undefined,
accessibilityRole: "button",
accessibilityLabel: `${monthName} ${year}`,
style: [styles.yearButton, {
borderRadius: roundness
}],
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [styles.yearButtonInner, {
borderRadius: roundness
}],
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativePaper.Text, {
maxFontSizeMultiplier: 1.5,
style: [styles.monthLabel, {
...textFont,
color: theme.isV3 ? theme.colors.onSurfaceVariant : theme.colors.onSurface
}],
selectable: false,
children: [monthName, " ", year]
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.iconWrapper, isHorizontal ? _styles.sharedStyles.opacity1 : _styles.sharedStyles.opacity0],
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativePaper.Icon, {
size: 24,
color: iconColor,
source: iconSource
})
})]
})
})
}), grid.map(({
weekIndex,
generatedDays
}) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: styles.week,
children: generatedDays.filter(gd => (0, _dateUtils.showWeekDay)(gd.dayIndex, disableWeekDays)).map(gd => gd.beforeWeekDay || gd.afterWeekDay ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Day.EmptyDay, {}, gd.dayIndex) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Day.default, {
theme: theme,
day: gd.dayOfMonth,
month: gd.month,
year: gd.year,
selected: gd.selected,
inRange: gd.inRange,
leftCrop: gd.leftCrop,
rightCrop: gd.rightCrop,
onPressDate: onPressDate,
isToday: gd.isToday,
selectColor: selectColor,
primaryColor: primaryColor,
disabled: gd.disabled,
textColorOnPrimary: textColorOnPrimary
}, gd.dayIndex))
}, weekIndex))]
});
}
const weekMargin = exports.weekMargin = 6;
const weekSize = exports.weekSize = _dateUtils.daySize + weekMargin;
const montHeaderHeight = exports.montHeaderHeight = 56;
const monthHeaderSingleMarginTop = exports.monthHeaderSingleMarginTop = 4;
const monthHeaderSingleMarginBottom = exports.monthHeaderSingleMarginBottom = 8 + 44 + 12;
const monthHeaderSingleHeight = exports.monthHeaderSingleHeight = monthHeaderSingleMarginTop + monthHeaderSingleMarginBottom;
const styles = _reactNative.StyleSheet.create({
iconWrapper: {
padding: 8
},
monthHeader: {
height: montHeaderHeight,
justifyContent: 'center',
overflow: 'hidden'
},
monthLabel: {
fontSize: 14,
opacity: 0.7
},
week: {
flexDirection: 'row',
marginBottom: weekMargin,
height: _dateUtils.daySize
},
yearButton: {
alignSelf: 'flex-start',
marginLeft: 6
},
yearButtonInner: {
paddingLeft: 16,
flexDirection: 'row',
alignItems: 'center'
}
});
const monthGrid = (index, startWeekOnMonday, startYear, endYear) => {
return Array((0, _dateUtils.getGridCount)(index, startWeekOnMonday, startYear, endYear)).fill(null).map((_, weekGrid) => {
const days = Array(7).fill(null);
return {
weekGrid,
days
};
});
};
function getIndexCount(index, startYear, endYear) {
const dynamicStartAtIndex = (0, _dateUtils.getStartAtIndex)(startYear, endYear);
if (index > dynamicStartAtIndex) {
return index - dynamicStartAtIndex;
}
return -(dynamicStartAtIndex - index);
}
function weeksOffset(index, startWeekOnMonday, startYear, endYear) {
const dynamicStartAtIndex = (0, _dateUtils.getStartAtIndex)(startYear, endYear);
const dynamicGridCounts = (0, _dateUtils.createGridCounts)((0, _dateUtils.getTotalMonths)(startYear, endYear));
if (index === dynamicStartAtIndex) {
return 0;
}
let off = 0;
if (index > dynamicStartAtIndex) {
for (let i = 0; i < index - dynamicStartAtIndex; i++) {
const cIndex = dynamicStartAtIndex + i;
off += dynamicGridCounts[cIndex] || (0, _dateUtils.getGridCount)(cIndex, startWeekOnMonday, startYear, endYear);
}
} else {
for (let i = 0; i < dynamicStartAtIndex - index; i++) {
const cIndex = dynamicStartAtIndex - i - 1;
off -= dynamicGridCounts[cIndex] || (0, _dateUtils.getGridCount)(cIndex, startWeekOnMonday, startYear, endYear);
}
}
return off;
}
function getIndexFromHorizontalOffset(offset, width, startYear, endYear) {
const dynamicStartAtIndex = (0, _dateUtils.getStartAtIndex)(startYear, endYear);
return dynamicStartAtIndex + Math.floor(offset / width);
}
function getIndexFromVerticalOffset(offset, startWeekOnMonday, startYear, endYear) {
const dynamicStartAtIndex = (0, _dateUtils.getStartAtIndex)(startYear, endYear);
const dynamicBeginOffset = _dateUtils.estimatedMonthHeight * dynamicStartAtIndex;
let estimatedIndex = dynamicStartAtIndex + Math.ceil(offset / _dateUtils.estimatedMonthHeight);
const realOffset = getVerticalMonthsOffset(estimatedIndex, startWeekOnMonday, startYear, endYear);
const difference = (realOffset - dynamicBeginOffset - offset) / _dateUtils.estimatedMonthHeight;
if (difference >= 1 || difference <= -1) {
estimatedIndex -= Math.floor(difference);
}
return estimatedIndex;
}
function getHorizontalMonthOffset(index, width) {
if (index < 0) {
return 0;
}
return width * index;
}
function getVerticalMonthsOffset(index, startWeekOnMonday, startYear, endYear) {
const count = getIndexCount(index, startYear, endYear);
const ob = weeksOffset(index, startWeekOnMonday, startYear, endYear);
const monthsHeight = weekSize * ob;
const c = monthsHeight + count * (_DayNames.dayNamesHeight + montHeaderHeight);
const dynamicBeginOffset = _dateUtils.estimatedMonthHeight * (0, _dateUtils.getStartAtIndex)(startYear, endYear);
return (c || 0) + dynamicBeginOffset;
}
function getMonthHeight(scrollMode, index, startWeekOnMonday, startYear, endYear) {
const calendarHeight = (0, _CalendarHeader.getCalendarHeaderHeight)(scrollMode);
const gc = (0, _dateUtils.getGridCount)(index, startWeekOnMonday, startYear, endYear);
const currentMonthHeight = weekSize * gc;
const extraHeight = scrollMode === 'horizontal' ? monthHeaderSingleHeight : montHeaderHeight;
const c = calendarHeight + currentMonthHeight + extraHeight;
return c || 0;
}
var _default = exports.default = /*#__PURE__*/(0, _react.memo)(Month);
//# sourceMappingURL=Month.js.map