react-native-paper-dates
Version:
Performant Date Picker for React Native Paper
209 lines (207 loc) • 7.32 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.useDebouncedCallback = useDebouncedCallback;
var _reactNative = require("react-native");
var _Month = require("./Month");
var _dateUtils = require("./dateUtils");
var _utils = require("../shared/utils");
var _SwiperUtils = require("./SwiperUtils");
var _AutoSizer = _interopRequireDefault(require("./AutoSizer"));
var _react = require("react");
var _styles = require("../shared/styles");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? _react.useLayoutEffect : _react.useEffect;
function Swiper({
scrollMode,
renderItem,
renderHeader,
renderFooter,
selectedYear,
initialIndex,
startWeekOnMonday,
startYear,
endYear
}) {
const isHorizontal = scrollMode === 'horizontal';
const [index, setIndex] = (0, _react.useState)(initialIndex);
const onPrev = (0, _react.useCallback)(() => {
setIndex(prev => {
const newIndex = prev - 1;
// Check if the new index is within allowed range
if ((0, _SwiperUtils.isIndexWithinRange)(newIndex, startYear, endYear)) {
return newIndex;
}
return prev; // Don't change if outside range
});
}, [setIndex, startYear, endYear]);
const onNext = (0, _react.useCallback)(() => {
setIndex(prev => {
const newIndex = prev + 1;
// Check if the new index is within allowed range
if ((0, _SwiperUtils.isIndexWithinRange)(newIndex, startYear, endYear)) {
return newIndex;
}
return prev; // Don't change if outside range
});
}, [setIndex, startYear, endYear]);
const renderProps = {
index,
onPrev,
onNext
};
const indexRef = (0, _utils.useLatest)(index);
(0, _SwiperUtils.useYearChange)(newIndex => {
if (newIndex && (0, _SwiperUtils.isIndexWithinRange)(newIndex, startYear, endYear)) {
setIndex(newIndex);
}
}, {
selectedYear,
currentIndexRef: indexRef,
startYear,
endYear
});
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [renderHeader && renderHeader(renderProps), isHorizontal ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: _styles.sharedStyles.root,
children: renderItem({
index,
onPrev,
onNext
})
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_AutoSizer.default, {
children: ({
width,
height
}) => /*#__PURE__*/(0, _jsxRuntime.jsx)(VerticalScroller, {
width: width,
height: height,
initialIndex: initialIndex,
estimatedHeight: _dateUtils.estimatedMonthHeight,
renderItem: renderItem,
startWeekOnMonday: startWeekOnMonday,
startYear: startYear,
endYear: endYear
})
}), renderFooter && renderFooter(renderProps)]
});
}
const visibleArray = i => {
return [i - 2, i - 1, i, i + 1, i + 2];
};
function VerticalScroller({
width,
height,
initialIndex,
estimatedHeight,
renderItem,
startWeekOnMonday,
startYear,
endYear
}) {
// Provide default values for startYear and endYear
const effectiveStartYear = startYear || 1800;
const effectiveEndYear = endYear || 2200;
// Ensure initial index is within allowed range
const constrainedInitialIndex = (0, _SwiperUtils.isIndexWithinRange)(initialIndex, effectiveStartYear, effectiveEndYear) ? initialIndex : Math.max(Math.min(initialIndex, (0, _SwiperUtils.getMaxIndex)(effectiveEndYear)), (0, _SwiperUtils.getMinIndex)(effectiveStartYear));
const [visibleIndexes, setVisibleIndexes] = (0, _react.useState)(() => visibleArray(constrainedInitialIndex));
const idx = (0, _react.useRef)(constrainedInitialIndex);
const parentRef = (0, _react.useRef)(null);
useIsomorphicLayoutEffect(() => {
const element = parentRef.current;
if (!element) {
return;
}
const top = (0, _Month.getVerticalMonthsOffset)(idx.current, startWeekOnMonday, effectiveStartYear, effectiveEndYear) - _Month.montHeaderHeight;
element.scrollTo({
top
});
}, [parentRef, idx]);
const setVisibleIndexesThrottled = useDebouncedCallback(setVisibleIndexes);
const onScroll = (0, _react.useCallback)(e => {
const top = e.currentTarget?.scrollTop;
if (top === 0) {
return;
}
const dynamicBeginOffset = (0, _dateUtils.getBeginOffset)(effectiveStartYear, effectiveEndYear);
const offset = top - dynamicBeginOffset;
const index = (0, _Month.getIndexFromVerticalOffset)(offset, startWeekOnMonday, effectiveStartYear, effectiveEndYear);
// Check if the new index is within allowed range
if (!(0, _SwiperUtils.isIndexWithinRange)(index, effectiveStartYear, effectiveEndYear)) {
return;
}
if (idx.current !== index) {
idx.current = index;
setVisibleIndexesThrottled(visibleArray(index));
}
}, [setVisibleIndexesThrottled, startWeekOnMonday, effectiveStartYear, effectiveEndYear]);
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
ref: parentRef
// eslint-disable-next-line react-native/no-inline-styles
,
style: {
height,
width,
overflow: 'auto'
},
onScroll: onScroll,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
// eslint-disable-next-line react-native/no-inline-styles
style: {
height: estimatedHeight * (0, _dateUtils.getTotalMonths)(effectiveStartYear, effectiveEndYear),
position: 'relative'
},
children: [0, 1, 2, 3, 4].map(vi => {
const monthIndex = visibleIndexes[vi];
if (monthIndex === undefined) {
return null;
}
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
// eslint-disable-next-line react-native/no-inline-styles
style: {
willChange: 'transform',
transform: `translateY(${(0, _Month.getVerticalMonthsOffset)(monthIndex, startWeekOnMonday, effectiveStartYear, effectiveEndYear)}px)`,
left: 0,
right: 0,
position: 'absolute',
height: (0, _Month.getMonthHeight)('vertical', monthIndex, startWeekOnMonday, effectiveStartYear, effectiveEndYear)
},
children: renderItem({
index: monthIndex,
onPrev: empty,
onNext: empty
})
}, vi);
}).filter(item => item !== null)
})
});
}
const empty = () => null;
function useDebouncedCallback(callback) {
const mounted = (0, _react.useRef)(true);
const timerId = (0, _react.useRef)(null);
const latest = (0, _utils.useLatest)(callback);
(0, _react.useEffect)(() => {
return () => {
mounted.current = false;
if (timerId.current) {
window.cancelAnimationFrame(timerId.current);
}
};
}, [mounted, timerId]);
return (0, _react.useCallback)(args => {
if (timerId.current) {
window.cancelAnimationFrame(timerId.current);
}
timerId.current = window.requestAnimationFrame(function () {
if (mounted.current) {
latest.current(args);
}
});
}, [mounted, timerId, latest]);
}
var _default = exports.default = /*#__PURE__*/(0, _react.memo)(Swiper);
//# sourceMappingURL=Swiper.js.map