UNPKG

react-native-slider-intro

Version:

A simple and full customizable React Native package which implements a unique slider.

217 lines (216 loc) 7.72 kB
"use strict"; import React, { createContext, useLayoutEffect, useMemo, useState } from 'react'; import { Animated, Dimensions, Easing, useAnimatedValue } from 'react-native'; import { ButtonType } from '../types/Button.types'; import { jsx as _jsx } from "react/jsx-runtime"; const defaultSlideState = { active: 0, previous: 0, slideToValue: 0, dotWidthToValue: 0, expectOpacityOfNext: 1, expectOpacityOfDone: 0, expectOpacityOfSkip: 1 }; const deviceMaxWidth = Dimensions.get('window').width; export const SliderContext = /*#__PURE__*/createContext({ data: [], children: null, navigationBarBottom: 0, navigationBarHeight: 70, animateSlideSpeed: 15, navContainerMaxSizePercent: 0.5, dotWidth: 12, fixDotOpacity: 0.35, fixDotBackgroundColor: 'grey', animatedDotBackgroundColor: 'white', animateDotSpeed: 8, animateDotBouncing: 2, showLeftButton: true, leftButtonType: ButtonType.Skip, columnButtonStyle: false, limitToSlide: deviceMaxWidth * 0.35, renderSkipButton: () => null, renderNextButton: () => null, renderDoneButton: () => null, skipLabel: ButtonType.Skip, nextLabel: ButtonType.Next, doneLabel: ButtonType.Done, onDone: () => {}, onSkip: () => {}, numberOfSlides: 1, navContainerMaxSize: 0, dotMaxPossibleWidth: 0, buttonsMaxSize: 0, slidesMaxWidth: 0, slide: defaultSlideState, setDefaultState: () => {}, animations: Object.create(null), goToNewSlide: () => {}, isLastSlide: false }); const SliderProvider = props => { const { data = [], children = null, animateSlideSpeed = 15, navContainerMaxSizePercent = 0.5, dotWidth = 12, animateDotSpeed = 8, animateDotBouncing = 2, onDone = () => {}, isCustomRender } = props; const numberOfSlides = isCustomRender ? props?.numberOfSlides ?? 1 : data?.length ?? 1; const slidesMaxWidth = (numberOfSlides - 1) * deviceMaxWidth; const navContainerMaxSize = deviceMaxWidth * navContainerMaxSizePercent; const buttonsMaxSize = (deviceMaxWidth - navContainerMaxSize) / 2 - 1; const dotMaxPossibleWidth = navContainerMaxSize / (numberOfSlides - 1) + 9; const _moveSlideTranslateX = useAnimatedValue(0); const _slideDotScaleX = useAnimatedValue(1); const _slideDotTranslateX = useAnimatedValue(0); const _opacityOfNextButton = useAnimatedValue(0); const _opacityOfDoneButton = useAnimatedValue(0); const _opacityOfSkipButton = useAnimatedValue(0); const sliderState = useState(defaultSlideState); const [slide, setSlide] = sliderState; const { active, slideToValue, dotWidthToValue, expectOpacityOfNext, expectOpacityOfDone, expectOpacityOfSkip } = slide; const slideAnimation = useMemo(() => Animated.spring(_moveSlideTranslateX, { toValue: slideToValue, speed: animateSlideSpeed, bounciness: animateDotBouncing, useNativeDriver: true }), [slideToValue, animateSlideSpeed, animateDotBouncing, _moveSlideTranslateX]); const dotAnimation = useMemo(() => Animated.spring(_slideDotScaleX, { toValue: 1, speed: animateDotSpeed, bounciness: animateDotBouncing, useNativeDriver: true }), [_slideDotScaleX, animateDotBouncing, animateDotSpeed]); const dotWidthAnimation = useMemo(() => Animated.spring(_slideDotTranslateX, { toValue: dotWidthToValue, speed: animateDotSpeed, bounciness: animateDotBouncing, useNativeDriver: true }), [dotWidthToValue, animateDotSpeed, animateDotBouncing, _slideDotTranslateX]); const nextOpacityAnimation = useMemo(() => Animated.timing(_opacityOfNextButton, { toValue: expectOpacityOfNext, duration: animateDotSpeed, easing: Easing.inOut(Easing.ease), useNativeDriver: true }), [expectOpacityOfNext, animateDotSpeed, _opacityOfNextButton]); const doneOpacityAnimation = useMemo(() => Animated.timing(_opacityOfDoneButton, { toValue: expectOpacityOfDone, duration: animateDotSpeed, easing: Easing.inOut(Easing.ease), useNativeDriver: true }), [expectOpacityOfDone, animateDotSpeed, _opacityOfDoneButton]); const skipOpacityAnimation = useMemo(() => Animated.timing(_opacityOfSkipButton, { toValue: expectOpacityOfSkip, duration: animateDotSpeed, easing: Easing.inOut(Easing.ease), useNativeDriver: true }), [expectOpacityOfSkip, animateDotSpeed, _opacityOfSkipButton]); useLayoutEffect(() => { const animationGroup = Animated.parallel([slideAnimation, dotAnimation, dotWidthAnimation, nextOpacityAnimation, doneOpacityAnimation, skipOpacityAnimation]); animationGroup.start(); return () => animationGroup.stop(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [slide]); const goToNewSlide = newSlide => { if (newSlide < 0) { return; } if (newSlide > numberOfSlides - 1) { setSlide(defaultSlideState); onDone(); return; } let opacityOfNext = 0; let opacityOfDone = 0; let opacityOfSkip = 0; let expectedMarginLeft = 0; let expectedMarginLeftDot = newSlide * (navContainerMaxSize - numberOfSlides * dotWidth) / (numberOfSlides - 1) + newSlide * dotWidth; if (newSlide === numberOfSlides - 1) { opacityOfNext = 0; opacityOfDone = 1; opacityOfSkip = 0; } else { opacityOfNext = 1; opacityOfDone = 0; opacityOfSkip = 1; } if (newSlide > active) { expectedMarginLeft = -(newSlide * deviceMaxWidth); } else if (newSlide < active) { expectedMarginLeft = -(newSlide * deviceMaxWidth); } else { expectedMarginLeft = slideToValue; } setSlide({ active: newSlide, previous: active, dotWidthToValue: expectedMarginLeftDot, slideToValue: expectedMarginLeft, expectOpacityOfNext: opacityOfNext, expectOpacityOfDone: opacityOfDone, expectOpacityOfSkip: opacityOfSkip }); }; const contextValue = { data: props?.data ?? [], children: props?.children ?? null, navigationBarBottom: props?.navigationBarBottom ?? 0, navigationBarHeight: props?.navigationBarHeight ?? 70, animateSlideSpeed: props?.animateSlideSpeed ?? 15, navContainerMaxSizePercent: props?.navContainerMaxSizePercent ?? 0.5, dotWidth: props?.dotWidth ?? 12, fixDotOpacity: props?.fixDotOpacity ?? 0.35, fixDotBackgroundColor: props?.fixDotBackgroundColor ?? 'grey', animatedDotBackgroundColor: props?.animatedDotBackgroundColor ?? 'white', animateDotSpeed: props?.animateDotSpeed ?? 8, animateDotBouncing: props?.animateDotBouncing ?? 2, showLeftButton: props?.showLeftButton ?? true, leftButtonType: props?.leftButtonType ?? ButtonType.Skip, columnButtonStyle: !!props?.columnButtonStyle, limitToSlide: props?.limitToSlide ?? deviceMaxWidth * 0.35, renderSkipButton: props?.renderSkipButton, renderNextButton: props?.renderNextButton, renderDoneButton: props?.renderDoneButton, onDone: props?.onDone, onSkip: props?.onSkip, skipLabel: props?.skipLabel ?? ButtonType.Skip, doneLabel: props?.doneLabel ?? ButtonType.Done, nextLabel: props?.nextLabel ?? ButtonType.Next, slide, setDefaultState: () => setSlide(defaultSlideState), isLastSlide: active + 1 === numberOfSlides, goToNewSlide, animations: { _moveSlideTranslateX, _slideDotScaleX, _slideDotTranslateX, _opacityOfNextButton, _opacityOfDoneButton, _opacityOfSkipButton }, slidesMaxWidth, navContainerMaxSize, buttonsMaxSize, dotMaxPossibleWidth, numberOfSlides }; return /*#__PURE__*/_jsx(SliderContext.Provider, { value: contextValue, children: children }); }; export default SliderProvider; //# sourceMappingURL=SliderProvider.js.map