UNPKG

react-native-animated-pagination-dot

Version:
136 lines (127 loc) 3.95 kB
/** * * Created by rouge on 11/09/2019. * Converted to Typescript on 14/07/2020. * Converted to Functional component. on 21/09/2021 */ import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import { ScrollView, View, StyleSheet } from 'react-native'; import Dot from './component/Dot'; import EmptyDot, { defaultEmptyDotSize } from './component/EmptyDot'; import usePrevious from 'react-use/lib/usePrevious'; const ONE_EMPTY_DOT_SIZE = defaultEmptyDotSize * defaultEmptyDotSize; const DotContainer = props => { const refScrollView = useRef(null); const prevPage = usePrevious(props.curPage); const getSizeRatio = useCallback(() => { if (!props.sizeRatio) return 1.0; return Math.max(1.0, props.sizeRatio); }, [props.sizeRatio]); const scrollTo = useCallback((index, animated = true) => { if (!refScrollView.current) return; const sizeRatio = getSizeRatio(); const FIRST_EMPTY_DOT_SPACE = ONE_EMPTY_DOT_SIZE * 2; const MOVE_DISTANCE = ONE_EMPTY_DOT_SIZE * sizeRatio; const moveTo = Math.max(0, FIRST_EMPTY_DOT_SPACE + (index - 4) * MOVE_DISTANCE); if (props.vertical) { refScrollView.current.scrollTo({ x: 0, y: moveTo, animated }); return; } refScrollView.current.scrollTo({ x: moveTo, y: 0, animated }); }, [getSizeRatio, props.vertical]); const getContainerStyle = useCallback(() => { const { vertical } = props; const sizeRatio = getSizeRatio(); const containerSize = 84 * sizeRatio; return { alignItems: 'center', flexDirection: vertical ? 'column' : 'row', maxHeight: vertical ? containerSize : undefined, maxWidth: vertical ? undefined : containerSize }; }, [getSizeRatio, props]); useEffect(() => { if (props.maxPage > 4 && prevPage !== props.curPage) scrollTo(props.curPage); }, [prevPage, props.curPage, props.maxPage, scrollTo]); const { curPage, maxPage, activeDotColor, inactiveDotColor } = props; const list = useMemo(() => [...Array(maxPage).keys()], [maxPage]); let normalizedPage = curPage; if (curPage < 0) { normalizedPage = 0; } if (curPage > maxPage - 1) { normalizedPage = maxPage - 1; } const sizeRatio = getSizeRatio(); const container = getContainerStyle(); if (maxPage < 5) { return /*#__PURE__*/React.createElement(View, { style: container }, list.map(i => { return /*#__PURE__*/React.createElement(Dot, { key: i, idx: i, sizeRatio: sizeRatio, curPage: normalizedPage, maxPage: maxPage, activeColor: activeDotColor, inactiveColor: inactiveDotColor }); })); } return /*#__PURE__*/React.createElement(View, { style: container, onLayout: () => { // scroll to right index on initial render scrollTo(props.curPage, false); } }, /*#__PURE__*/React.createElement(ScrollView, { ref: refScrollView, contentContainerStyle: styles.scrollViewContainer, bounces: false, horizontal: !props.vertical, scrollEnabled: false, showsVerticalScrollIndicator: false, showsHorizontalScrollIndicator: false }, /*#__PURE__*/React.createElement(EmptyDot, { sizeRatio: sizeRatio }), /*#__PURE__*/React.createElement(EmptyDot, { sizeRatio: sizeRatio }), list.map(i => { return /*#__PURE__*/React.createElement(Dot, { sizeRatio: sizeRatio, key: i, idx: i, curPage: normalizedPage, maxPage: maxPage, activeColor: activeDotColor, inactiveColor: inactiveDotColor }); }), /*#__PURE__*/React.createElement(EmptyDot, { sizeRatio: sizeRatio }), /*#__PURE__*/React.createElement(EmptyDot, { sizeRatio: sizeRatio }))); }; const styles = StyleSheet.create({ scrollViewContainer: { alignItems: 'center' } }); export default DotContainer; //# sourceMappingURL=index.js.map