UNPKG

react-native-paper-dates

Version:
203 lines (201 loc) 6.75 kB
"use strict"; import { View } from 'react-native'; import { getIndexFromVerticalOffset, getMonthHeight, getVerticalMonthsOffset, montHeaderHeight } from './Month'; import { getBeginOffset, estimatedMonthHeight, getTotalMonths } from './dateUtils'; import { useLatest } from '../shared/utils'; import { useYearChange, isIndexWithinRange, getMinIndex, getMaxIndex } from './SwiperUtils'; import AutoSizer from './AutoSizer'; import { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'; import { sharedStyles } from '../shared/styles'; import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect; function Swiper({ scrollMode, renderItem, renderHeader, renderFooter, selectedYear, initialIndex, startWeekOnMonday, startYear, endYear }) { const isHorizontal = scrollMode === 'horizontal'; const [index, setIndex] = useState(initialIndex); const onPrev = useCallback(() => { setIndex(prev => { const newIndex = prev - 1; // Check if the new index is within allowed range if (isIndexWithinRange(newIndex, startYear, endYear)) { return newIndex; } return prev; // Don't change if outside range }); }, [setIndex, startYear, endYear]); const onNext = useCallback(() => { setIndex(prev => { const newIndex = prev + 1; // Check if the new index is within allowed range if (isIndexWithinRange(newIndex, startYear, endYear)) { return newIndex; } return prev; // Don't change if outside range }); }, [setIndex, startYear, endYear]); const renderProps = { index, onPrev, onNext }; const indexRef = useLatest(index); useYearChange(newIndex => { if (newIndex && isIndexWithinRange(newIndex, startYear, endYear)) { setIndex(newIndex); } }, { selectedYear, currentIndexRef: indexRef, startYear, endYear }); return /*#__PURE__*/_jsxs(_Fragment, { children: [renderHeader && renderHeader(renderProps), isHorizontal ? /*#__PURE__*/_jsx(View, { style: sharedStyles.root, children: renderItem({ index, onPrev, onNext }) }) : /*#__PURE__*/_jsx(AutoSizer, { children: ({ width, height }) => /*#__PURE__*/_jsx(VerticalScroller, { width: width, height: height, initialIndex: initialIndex, estimatedHeight: 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 = isIndexWithinRange(initialIndex, effectiveStartYear, effectiveEndYear) ? initialIndex : Math.max(Math.min(initialIndex, getMaxIndex(effectiveEndYear)), getMinIndex(effectiveStartYear)); const [visibleIndexes, setVisibleIndexes] = useState(() => visibleArray(constrainedInitialIndex)); const idx = useRef(constrainedInitialIndex); const parentRef = useRef(null); useIsomorphicLayoutEffect(() => { const element = parentRef.current; if (!element) { return; } const top = getVerticalMonthsOffset(idx.current, startWeekOnMonday, effectiveStartYear, effectiveEndYear) - montHeaderHeight; element.scrollTo({ top }); }, [parentRef, idx]); const setVisibleIndexesThrottled = useDebouncedCallback(setVisibleIndexes); const onScroll = useCallback(e => { const top = e.currentTarget?.scrollTop; if (top === 0) { return; } const dynamicBeginOffset = getBeginOffset(effectiveStartYear, effectiveEndYear); const offset = top - dynamicBeginOffset; const index = getIndexFromVerticalOffset(offset, startWeekOnMonday, effectiveStartYear, effectiveEndYear); // Check if the new index is within allowed range if (!isIndexWithinRange(index, effectiveStartYear, effectiveEndYear)) { return; } if (idx.current !== index) { idx.current = index; setVisibleIndexesThrottled(visibleArray(index)); } }, [setVisibleIndexesThrottled, startWeekOnMonday, effectiveStartYear, effectiveEndYear]); return /*#__PURE__*/_jsx("div", { ref: parentRef // eslint-disable-next-line react-native/no-inline-styles , style: { height, width, overflow: 'auto' }, onScroll: onScroll, children: /*#__PURE__*/_jsx("div", { // eslint-disable-next-line react-native/no-inline-styles style: { height: estimatedHeight * getTotalMonths(effectiveStartYear, effectiveEndYear), position: 'relative' }, children: [0, 1, 2, 3, 4].map(vi => { const monthIndex = visibleIndexes[vi]; if (monthIndex === undefined) { return null; } return /*#__PURE__*/_jsx("div", { // eslint-disable-next-line react-native/no-inline-styles style: { willChange: 'transform', transform: `translateY(${getVerticalMonthsOffset(monthIndex, startWeekOnMonday, effectiveStartYear, effectiveEndYear)}px)`, left: 0, right: 0, position: 'absolute', height: getMonthHeight('vertical', monthIndex, startWeekOnMonday, effectiveStartYear, effectiveEndYear) }, children: renderItem({ index: monthIndex, onPrev: empty, onNext: empty }) }, vi); }).filter(item => item !== null) }) }); } const empty = () => null; export function useDebouncedCallback(callback) { const mounted = useRef(true); const timerId = useRef(null); const latest = useLatest(callback); useEffect(() => { return () => { mounted.current = false; if (timerId.current) { window.cancelAnimationFrame(timerId.current); } }; }, [mounted, timerId]); return useCallback(args => { if (timerId.current) { window.cancelAnimationFrame(timerId.current); } timerId.current = window.requestAnimationFrame(function () { if (mounted.current) { latest.current(args); } }); }, [mounted, timerId, latest]); } export default /*#__PURE__*/memo(Swiper); //# sourceMappingURL=Swiper.js.map