@fountain-ui/lab 2.0.0-beta.16 → 2.0.0-beta.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/commonjs/Carousel/Carousel.js +5 -7
- package/build/commonjs/Carousel/Carousel.js.map +1 -1
- package/build/commonjs/Carousel/CarouselProps.js.map +1 -1
- package/build/commonjs/Carousel/components/ItemView.js +2 -2
- package/build/commonjs/Carousel/components/ItemView.js.map +1 -1
- package/build/commonjs/Carousel/hooks/useIndexController.js +19 -13
- package/build/commonjs/Carousel/hooks/useIndexController.js.map +1 -1
- package/build/commonjs/Carousel/hooks/useItemVisibilityStore.js +3 -3
- package/build/commonjs/Carousel/hooks/useItemVisibilityStore.js.map +1 -1
- package/build/commonjs/Carousel/types.js.map +1 -1
- package/build/module/Carousel/Carousel.js +6 -8
- package/build/module/Carousel/Carousel.js.map +1 -1
- package/build/module/Carousel/CarouselProps.js.map +1 -1
- package/build/module/Carousel/components/ItemView.js +2 -2
- package/build/module/Carousel/components/ItemView.js.map +1 -1
- package/build/module/Carousel/hooks/useIndexController.js +19 -14
- package/build/module/Carousel/hooks/useIndexController.js.map +1 -1
- package/build/module/Carousel/hooks/useItemVisibilityStore.js +3 -3
- package/build/module/Carousel/hooks/useItemVisibilityStore.js.map +1 -1
- package/build/module/Carousel/types.js.map +1 -1
- package/build/typescript/Carousel/CarouselProps.d.ts +2 -2
- package/build/typescript/Carousel/hooks/useIndexController.d.ts +3 -1
- package/build/typescript/Carousel/hooks/useItemVisibilityStore.d.ts +2 -5
- package/build/typescript/Carousel/types.d.ts +6 -0
- package/package.json +2 -2
- package/src/Carousel/Carousel.tsx +6 -9
- package/src/Carousel/CarouselProps.ts +9 -2
- package/src/Carousel/components/ItemView.tsx +2 -2
- package/src/Carousel/hooks/useIndexController.tsx +26 -15
- package/src/Carousel/hooks/useItemVisibilityStore.ts +5 -9
- package/src/Carousel/types.ts +8 -0
|
@@ -35,7 +35,7 @@ const Carousel = /*#__PURE__*/(0, _react.forwardRef)(function Carousel(props, re
|
|
|
35
35
|
itemHeight,
|
|
36
36
|
itemWidth,
|
|
37
37
|
loop = false,
|
|
38
|
-
onIndexChange
|
|
38
|
+
onIndexChange,
|
|
39
39
|
renderItem,
|
|
40
40
|
scrollEnabled = true,
|
|
41
41
|
style,
|
|
@@ -48,20 +48,18 @@ const Carousel = /*#__PURE__*/(0, _react.forwardRef)(function Carousel(props, re
|
|
|
48
48
|
|
|
49
49
|
const globalInterpolation = _reactNative.Animated.add(offsetX, translateX);
|
|
50
50
|
|
|
51
|
-
const [itemVisibilityStore,
|
|
51
|
+
const [itemVisibilityStore, onPositionChange] = (0, _hooks.useItemVisibilityStore)({
|
|
52
52
|
initialIndex,
|
|
53
53
|
numberOfData: data.length,
|
|
54
54
|
windowSize
|
|
55
55
|
});
|
|
56
|
-
const handleIndexChange = (0, _react.useCallback)(newIndex => {
|
|
57
|
-
onIndexChange(newIndex);
|
|
58
|
-
onIndexChangeProp === null || onIndexChangeProp === void 0 ? void 0 : onIndexChangeProp(newIndex);
|
|
59
|
-
}, [onIndexChange, onIndexChangeProp]);
|
|
60
56
|
const indexController = (0, _hooks.useIndexController)({
|
|
61
57
|
initialIndex,
|
|
62
58
|
itemWidth,
|
|
59
|
+
numberOfData: data.length,
|
|
63
60
|
numberOfOriginalData: originalData.length,
|
|
64
|
-
onIndexChange
|
|
61
|
+
onIndexChange,
|
|
62
|
+
onPositionChange
|
|
65
63
|
});
|
|
66
64
|
const {
|
|
67
65
|
getCurrentIndex
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Carousel","forwardRef","props","ref","autoplay","autoplayInterval","createItemStyle","createDefaultItemStyle","createScrollAnimation","createDefaultScrollAnimation","data","originalData","disableSmartAutoplay","initialIndex","itemHeight","itemWidth","loop","onIndexChange","
|
|
1
|
+
{"version":3,"names":["Carousel","forwardRef","props","ref","autoplay","autoplayInterval","createItemStyle","createDefaultItemStyle","createScrollAnimation","createDefaultScrollAnimation","data","originalData","disableSmartAutoplay","initialIndex","itemHeight","itemWidth","loop","onIndexChange","renderItem","scrollEnabled","style","windowSize","useLoopedData","initialTx","offsetX","useRef","Animated","Value","current","translateX","globalInterpolation","add","itemVisibilityStore","onPositionChange","useItemVisibilityStore","numberOfData","length","indexController","useIndexController","numberOfOriginalData","getCurrentIndex","interruptAnimation","startPagingAnimation","usePagingAnimation","autoplayController","useAutoplayController","enabled","intervalMillis","useImperativeHandle","next","direction","prev","scrollTo","option","contextValue","useMemo","Math","max","visible","resume","pause","memo"],"sources":["Carousel.tsx"],"sourcesContent":["import React, { forwardRef, memo, useImperativeHandle, useMemo, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport ViewabilityTrackerView from '../ViewabilityTrackerView';\nimport type CarouselProps from './CarouselProps';\nimport type { CarouselInstance } from './types';\nimport {\n useAutoplayController,\n useIndexController,\n useItemVisibilityStore,\n useLoopedData,\n usePagingAnimation,\n} from './hooks';\nimport { createDefaultItemStyle, createDefaultScrollAnimation } from './animation';\nimport { InternalContext, RootView, ScrollViewGesture } from './components';\n\nconst Carousel = forwardRef<CarouselInstance, CarouselProps>(function Carousel(props, ref) {\n const {\n autoplay = false,\n autoplayInterval = 3000,\n createItemStyle = createDefaultItemStyle,\n createScrollAnimation = createDefaultScrollAnimation,\n data: originalData,\n disableSmartAutoplay = false,\n initialIndex = 0,\n itemHeight,\n itemWidth,\n loop = false,\n onIndexChange,\n renderItem,\n scrollEnabled = true,\n style,\n windowSize = 5,\n } = props;\n\n const data = useLoopedData(originalData, loop);\n\n const initialTx = itemWidth * initialIndex;\n const offsetX = useRef(new Animated.Value(initialTx)).current;\n const translateX = useRef(new Animated.Value(0)).current;\n const globalInterpolation = Animated.add(offsetX, translateX);\n\n const [itemVisibilityStore, onPositionChange] = useItemVisibilityStore({\n initialIndex,\n numberOfData: data.length,\n windowSize,\n });\n\n const indexController = useIndexController({\n initialIndex,\n itemWidth,\n numberOfData: data.length,\n numberOfOriginalData: originalData.length,\n onIndexChange,\n onPositionChange,\n });\n\n const { getCurrentIndex } = indexController;\n\n const {\n interruptAnimation,\n startPagingAnimation,\n } = usePagingAnimation({\n createScrollAnimation,\n itemWidth,\n indexController,\n loop,\n numberOfData: data.length,\n offsetX,\n translateX,\n });\n\n const autoplayController = useAutoplayController({\n enabled: autoplay,\n intervalMillis: autoplayInterval,\n startPagingAnimation,\n });\n\n useImperativeHandle(\n ref,\n () => ({\n getCurrentIndex,\n next: () => startPagingAnimation('directional', { direction: 'next' }),\n prev: () => startPagingAnimation('directional', { direction: 'prev' }),\n scrollTo: (option) => startPagingAnimation('index', option),\n }),\n [startPagingAnimation, getCurrentIndex],\n );\n\n const contextValue = useMemo(() => ({\n createItemStyle,\n data,\n globalInterpolation,\n itemHeight,\n itemWidth,\n itemVisibilityStore,\n loop,\n }), [\n createItemStyle,\n data,\n globalInterpolation,\n itemHeight,\n itemWidth,\n itemVisibilityStore,\n loop,\n ]);\n\n return (\n <InternalContext.Provider value={contextValue}>\n <ViewabilityTrackerView\n enabled={autoplay && !disableSmartAutoplay}\n measurementIntervalMillis={Math.max(3000, autoplayInterval)}\n onViewabilityChange={({ visible }) => {\n if (visible) {\n autoplayController.resume();\n } else {\n autoplayController.pause();\n }\n }}\n >\n <ScrollViewGesture\n autoplayController={autoplayController}\n interruptAnimation={interruptAnimation}\n translateX={translateX}\n scrollEnabled={scrollEnabled}\n startPagingAnimation={startPagingAnimation}\n >\n <RootView\n data={data}\n itemHeight={itemHeight}\n originalData={originalData}\n renderItem={renderItem}\n style={style}\n />\n </ScrollViewGesture>\n </ViewabilityTrackerView>\n </InternalContext.Provider>\n );\n});\n\nexport default memo(Carousel);\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AAGA;;AAOA;;AACA;;;;;;;;AAEA,MAAMA,QAAQ,gBAAG,IAAAC,iBAAA,EAA4C,SAASD,QAAT,CAAkBE,KAAlB,EAAyBC,GAAzB,EAA8B;EACvF,MAAM;IACFC,QAAQ,GAAG,KADT;IAEFC,gBAAgB,GAAG,IAFjB;IAGFC,eAAe,GAAGC,iCAHhB;IAIFC,qBAAqB,GAAGC,uCAJtB;IAKFC,IAAI,EAAEC,YALJ;IAMFC,oBAAoB,GAAG,KANrB;IAOFC,YAAY,GAAG,CAPb;IAQFC,UARE;IASFC,SATE;IAUFC,IAAI,GAAG,KAVL;IAWFC,aAXE;IAYFC,UAZE;IAaFC,aAAa,GAAG,IAbd;IAcFC,KAdE;IAeFC,UAAU,GAAG;EAfX,IAgBFnB,KAhBJ;EAkBA,MAAMQ,IAAI,GAAG,IAAAY,oBAAA,EAAcX,YAAd,EAA4BK,IAA5B,CAAb;EAEA,MAAMO,SAAS,GAAGR,SAAS,GAAGF,YAA9B;EACA,MAAMW,OAAO,GAAG,IAAAC,aAAA,EAAO,IAAIC,qBAAA,CAASC,KAAb,CAAmBJ,SAAnB,CAAP,EAAsCK,OAAtD;EACA,MAAMC,UAAU,GAAG,IAAAJ,aAAA,EAAO,IAAIC,qBAAA,CAASC,KAAb,CAAmB,CAAnB,CAAP,EAA8BC,OAAjD;;EACA,MAAME,mBAAmB,GAAGJ,qBAAA,CAASK,GAAT,CAAaP,OAAb,EAAsBK,UAAtB,CAA5B;;EAEA,MAAM,CAACG,mBAAD,EAAsBC,gBAAtB,IAA0C,IAAAC,6BAAA,EAAuB;IACnErB,YADmE;IAEnEsB,YAAY,EAAEzB,IAAI,CAAC0B,MAFgD;IAGnEf;EAHmE,CAAvB,CAAhD;EAMA,MAAMgB,eAAe,GAAG,IAAAC,yBAAA,EAAmB;IACvCzB,YADuC;IAEvCE,SAFuC;IAGvCoB,YAAY,EAAEzB,IAAI,CAAC0B,MAHoB;IAIvCG,oBAAoB,EAAE5B,YAAY,CAACyB,MAJI;IAKvCnB,aALuC;IAMvCgB;EANuC,CAAnB,CAAxB;EASA,MAAM;IAAEO;EAAF,IAAsBH,eAA5B;EAEA,MAAM;IACFI,kBADE;IAEFC;EAFE,IAGF,IAAAC,yBAAA,EAAmB;IACnBnC,qBADmB;IAEnBO,SAFmB;IAGnBsB,eAHmB;IAInBrB,IAJmB;IAKnBmB,YAAY,EAAEzB,IAAI,CAAC0B,MALA;IAMnBZ,OANmB;IAOnBK;EAPmB,CAAnB,CAHJ;EAaA,MAAMe,kBAAkB,GAAG,IAAAC,4BAAA,EAAsB;IAC7CC,OAAO,EAAE1C,QADoC;IAE7C2C,cAAc,EAAE1C,gBAF6B;IAG7CqC;EAH6C,CAAtB,CAA3B;EAMA,IAAAM,0BAAA,EACI7C,GADJ,EAEI,OAAO;IACHqC,eADG;IAEHS,IAAI,EAAE,MAAMP,oBAAoB,CAAC,aAAD,EAAgB;MAAEQ,SAAS,EAAE;IAAb,CAAhB,CAF7B;IAGHC,IAAI,EAAE,MAAMT,oBAAoB,CAAC,aAAD,EAAgB;MAAEQ,SAAS,EAAE;IAAb,CAAhB,CAH7B;IAIHE,QAAQ,EAAGC,MAAD,IAAYX,oBAAoB,CAAC,OAAD,EAAUW,MAAV;EAJvC,CAAP,CAFJ,EAQI,CAACX,oBAAD,EAAuBF,eAAvB,CARJ;EAWA,MAAMc,YAAY,GAAG,IAAAC,cAAA,EAAQ,OAAO;IAChCjD,eADgC;IAEhCI,IAFgC;IAGhCoB,mBAHgC;IAIhChB,UAJgC;IAKhCC,SALgC;IAMhCiB,mBANgC;IAOhChB;EAPgC,CAAP,CAAR,EAQjB,CACAV,eADA,EAEAI,IAFA,EAGAoB,mBAHA,EAIAhB,UAJA,EAKAC,SALA,EAMAiB,mBANA,EAOAhB,IAPA,CARiB,CAArB;EAkBA,oBACI,6BAAC,2BAAD,CAAiB,QAAjB;IAA0B,KAAK,EAAEsC;EAAjC,gBACI,6BAAC,+BAAD;IACI,OAAO,EAAElD,QAAQ,IAAI,CAACQ,oBAD1B;IAEI,yBAAyB,EAAE4C,IAAI,CAACC,GAAL,CAAS,IAAT,EAAepD,gBAAf,CAF/B;IAGI,mBAAmB,EAAE,QAAiB;MAAA,IAAhB;QAAEqD;MAAF,CAAgB;;MAClC,IAAIA,OAAJ,EAAa;QACTd,kBAAkB,CAACe,MAAnB;MACH,CAFD,MAEO;QACHf,kBAAkB,CAACgB,KAAnB;MACH;IACJ;EATL,gBAWI,6BAAC,6BAAD;IACI,kBAAkB,EAAEhB,kBADxB;IAEI,kBAAkB,EAAEH,kBAFxB;IAGI,UAAU,EAAEZ,UAHhB;IAII,aAAa,EAAEV,aAJnB;IAKI,oBAAoB,EAAEuB;EAL1B,gBAOI,6BAAC,oBAAD;IACI,IAAI,EAAEhC,IADV;IAEI,UAAU,EAAEI,UAFhB;IAGI,YAAY,EAAEH,YAHlB;IAII,UAAU,EAAEO,UAJhB;IAKI,KAAK,EAAEE;EALX,EAPJ,CAXJ,CADJ,CADJ;AA+BH,CA1HgB,CAAjB;;4BA4He,IAAAyC,WAAA,EAAK7D,QAAL,C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["CarouselProps.ts"],"sourcesContent":["import type { RefObject } from 'react';\nimport type { ComponentProps } from '@fountain-ui/core';\nimport type {
|
|
1
|
+
{"version":3,"names":[],"sources":["CarouselProps.ts"],"sourcesContent":["import type { RefObject } from 'react';\nimport type { ComponentProps } from '@fountain-ui/core';\nimport type {\n CarouselInstance,\n CreateItemStyle,\n CreateScrollAnimation,\n ItemHeight,\n OnIndexChange,\n RenderItem,\n} from './types';\n\nexport default interface CarouselProps<ItemT = any> extends ComponentProps<{\n ref?: RefObject<CarouselInstance>;\n\n /**\n * If `true`, enable autoplay.\n * @default false\n */\n autoplay?: boolean;\n\n /**\n * Delay in ms until navigating to the next item.\n * @default 3000\n */\n autoplayInterval?: number;\n\n /**\n * The item style creator function.\n * @default createDefaultItemStyle\n */\n createItemStyle?: CreateItemStyle;\n\n /**\n * The scroll animation creator function.\n * @default createDefaultScrollAnimation\n */\n createScrollAnimation?: CreateScrollAnimation;\n\n /**\n * Data for render items.\n */\n data: ReadonlyArray<ItemT>;\n\n /**\n * If `true`, carousel will detect its own viewability and control autoplay automatically.\n * @default false\n */\n disableSmartAutoplay?: boolean;\n\n /**\n * Index of initial item that should be selected.\n * @default 0\n */\n initialIndex?: number;\n\n /**\n * The item height.\n * For a performance reason, always consider to provide a number value.\n */\n itemHeight: ItemHeight;\n\n /**\n * The item width.\n */\n itemWidth: number;\n\n /**\n * Enable infinite loop mode.\n * @default false\n */\n loop?: boolean;\n\n /**\n * Callback fired when an index is changed.\n */\n onIndexChange?: OnIndexChange;\n\n /**\n * Takes an item from data and renders it into the list.\n */\n renderItem: RenderItem<ItemT>;\n\n /**\n * Whether to enable scroll gesture.\n * @default true\n */\n scrollEnabled?: boolean;\n\n /**\n * The maximum number of items that can respond to pan gesture events.\n * Due to the nature of the `active` item, it accepts only odd number. (e.g. 1, 3, 5...)\n * 0 means all items will respond to pan gesture events.\n * @default 5\n */\n windowSize?: number;\n}> {}\n"],"mappings":""}
|
|
@@ -35,7 +35,7 @@ function ItemView(props) {
|
|
|
35
35
|
} = (0, _react.useContext)(_InternalContext.default);
|
|
36
36
|
const [visible, setVisible] = (0, _react.useState)(false);
|
|
37
37
|
const interpolation = (0, _useItemInterpolation.default)(index);
|
|
38
|
-
const itemStyle = (0, _react.useMemo)(() => createItemStyle(interpolation, itemWidth), [createItemStyle, interpolation]);
|
|
38
|
+
const itemStyle = (0, _react.useMemo)(() => createItemStyle(interpolation, itemWidth), [createItemStyle, interpolation, itemWidth]);
|
|
39
39
|
(0, _react.useEffect)(() => {
|
|
40
40
|
return itemVisibilityStore.subscribe(ranges => {
|
|
41
41
|
const nextVisible = ranges.some(_ref => {
|
|
@@ -44,7 +44,7 @@ function ItemView(props) {
|
|
|
44
44
|
});
|
|
45
45
|
setVisible(nextVisible);
|
|
46
46
|
});
|
|
47
|
-
}, [itemVisibilityStore]);
|
|
47
|
+
}, [index, itemVisibilityStore]);
|
|
48
48
|
return /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, {
|
|
49
49
|
children: visible ? children(interpolation) : null,
|
|
50
50
|
onLayout: onLayout,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ItemView","props","children","index","onLayout","createItemStyle","itemHeight","itemWidth","itemVisibilityStore","useContext","InternalContext","visible","setVisible","useState","interpolation","useItemInterpolation","itemStyle","useMemo","useEffect","subscribe","ranges","nextVisible","some","from","to","width","height","undefined","styles","absolute","StyleSheet","create","position"],"sources":["ItemView.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React, { useContext, useEffect, useMemo, useState } from 'react';\nimport type { ViewProps } from 'react-native';\nimport { Animated } from 'react-native';\nimport { StyleSheet } from '@fountain-ui/core';\nimport useItemInterpolation from './useItemInterpolation';\nimport InternalContext from './InternalContext';\n\nexport interface ItemViewProps {\n children: (interpolation: Animated.AnimatedInterpolation) => ReactElement | null;\n index: number;\n onLayout?: ViewProps['onLayout'];\n}\n\nexport default function ItemView(props: ItemViewProps) {\n const {\n children,\n index,\n onLayout,\n } = props;\n\n const {\n createItemStyle,\n itemHeight,\n itemWidth,\n itemVisibilityStore,\n } = useContext(InternalContext);\n\n const [visible, setVisible] = useState(false);\n\n const interpolation = useItemInterpolation(index);\n\n const itemStyle = useMemo(\n () => createItemStyle(interpolation, itemWidth),\n [createItemStyle, interpolation],\n );\n\n useEffect(() => {\n return itemVisibilityStore.subscribe(ranges => {\n const nextVisible = ranges.some(([from, to]) => index >= from && index <= to);\n setVisible(nextVisible);\n });\n }, [itemVisibilityStore]);\n\n return (\n <Animated.View\n children={visible ? children(interpolation) : null}\n onLayout={onLayout}\n style={[\n {\n width: itemWidth,\n height: itemHeight !== 'auto' ? itemHeight : undefined,\n },\n styles.absolute,\n // @ts-ignore\n itemStyle,\n ]}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n absolute: {\n position: 'absolute',\n },\n});\n"],"mappings":";;;;;;;AACA;;AAEA;;AACA;;AACA;;AACA;;;;;;;;AAQe,SAASA,QAAT,CAAkBC,KAAlB,EAAwC;EACnD,MAAM;IACFC,QADE;IAEFC,KAFE;IAGFC;EAHE,IAIFH,KAJJ;EAMA,MAAM;IACFI,eADE;IAEFC,UAFE;IAGFC,SAHE;IAIFC;EAJE,IAKF,IAAAC,iBAAA,EAAWC,wBAAX,CALJ;EAOA,MAAM,CAACC,OAAD,EAAUC,UAAV,IAAwB,IAAAC,eAAA,EAAS,KAAT,CAA9B;EAEA,MAAMC,aAAa,GAAG,IAAAC,6BAAA,EAAqBZ,KAArB,CAAtB;EAEA,MAAMa,SAAS,GAAG,IAAAC,cAAA,EACd,MAAMZ,eAAe,CAACS,aAAD,EAAgBP,SAAhB,CADP,EAEd,CAACF,eAAD,EAAkBS,aAAlB,CAFc,CAAlB;EAKA,
|
|
1
|
+
{"version":3,"names":["ItemView","props","children","index","onLayout","createItemStyle","itemHeight","itemWidth","itemVisibilityStore","useContext","InternalContext","visible","setVisible","useState","interpolation","useItemInterpolation","itemStyle","useMemo","useEffect","subscribe","ranges","nextVisible","some","from","to","width","height","undefined","styles","absolute","StyleSheet","create","position"],"sources":["ItemView.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React, { useContext, useEffect, useMemo, useState } from 'react';\nimport type { ViewProps } from 'react-native';\nimport { Animated } from 'react-native';\nimport { StyleSheet } from '@fountain-ui/core';\nimport useItemInterpolation from './useItemInterpolation';\nimport InternalContext from './InternalContext';\n\nexport interface ItemViewProps {\n children: (interpolation: Animated.AnimatedInterpolation) => ReactElement | null;\n index: number;\n onLayout?: ViewProps['onLayout'];\n}\n\nexport default function ItemView(props: ItemViewProps) {\n const {\n children,\n index,\n onLayout,\n } = props;\n\n const {\n createItemStyle,\n itemHeight,\n itemWidth,\n itemVisibilityStore,\n } = useContext(InternalContext);\n\n const [visible, setVisible] = useState(false);\n\n const interpolation = useItemInterpolation(index);\n\n const itemStyle = useMemo(\n () => createItemStyle(interpolation, itemWidth),\n [createItemStyle, interpolation, itemWidth],\n );\n\n useEffect(() => {\n return itemVisibilityStore.subscribe(ranges => {\n const nextVisible = ranges.some(([from, to]) => index >= from && index <= to);\n setVisible(nextVisible);\n });\n }, [index, itemVisibilityStore]);\n\n return (\n <Animated.View\n children={visible ? children(interpolation) : null}\n onLayout={onLayout}\n style={[\n {\n width: itemWidth,\n height: itemHeight !== 'auto' ? itemHeight : undefined,\n },\n styles.absolute,\n // @ts-ignore\n itemStyle,\n ]}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n absolute: {\n position: 'absolute',\n },\n});\n"],"mappings":";;;;;;;AACA;;AAEA;;AACA;;AACA;;AACA;;;;;;;;AAQe,SAASA,QAAT,CAAkBC,KAAlB,EAAwC;EACnD,MAAM;IACFC,QADE;IAEFC,KAFE;IAGFC;EAHE,IAIFH,KAJJ;EAMA,MAAM;IACFI,eADE;IAEFC,UAFE;IAGFC,SAHE;IAIFC;EAJE,IAKF,IAAAC,iBAAA,EAAWC,wBAAX,CALJ;EAOA,MAAM,CAACC,OAAD,EAAUC,UAAV,IAAwB,IAAAC,eAAA,EAAS,KAAT,CAA9B;EAEA,MAAMC,aAAa,GAAG,IAAAC,6BAAA,EAAqBZ,KAArB,CAAtB;EAEA,MAAMa,SAAS,GAAG,IAAAC,cAAA,EACd,MAAMZ,eAAe,CAACS,aAAD,EAAgBP,SAAhB,CADP,EAEd,CAACF,eAAD,EAAkBS,aAAlB,EAAiCP,SAAjC,CAFc,CAAlB;EAKA,IAAAW,gBAAA,EAAU,MAAM;IACZ,OAAOV,mBAAmB,CAACW,SAApB,CAA8BC,MAAM,IAAI;MAC3C,MAAMC,WAAW,GAAGD,MAAM,CAACE,IAAP,CAAY;QAAA,IAAC,CAACC,IAAD,EAAOC,EAAP,CAAD;QAAA,OAAgBrB,KAAK,IAAIoB,IAAT,IAAiBpB,KAAK,IAAIqB,EAA1C;MAAA,CAAZ,CAApB;MACAZ,UAAU,CAACS,WAAD,CAAV;IACH,CAHM,CAAP;EAIH,CALD,EAKG,CAAClB,KAAD,EAAQK,mBAAR,CALH;EAOA,oBACI,6BAAC,qBAAD,CAAU,IAAV;IACI,QAAQ,EAAEG,OAAO,GAAGT,QAAQ,CAACY,aAAD,CAAX,GAA6B,IADlD;IAEI,QAAQ,EAAEV,QAFd;IAGI,KAAK,EAAE,CACH;MACIqB,KAAK,EAAElB,SADX;MAEImB,MAAM,EAAEpB,UAAU,KAAK,MAAf,GAAwBA,UAAxB,GAAqCqB;IAFjD,CADG,EAKHC,MAAM,CAACC,QALJ,EAMH;IACAb,SAPG;EAHX,EADJ;AAeH;;AAAA;;AAED,MAAMY,MAAM,GAAGE,gBAAA,CAAWC,MAAX,CAAkB;EAC7BF,QAAQ,EAAE;IACNG,QAAQ,EAAE;EADJ;AADmB,CAAlB,CAAf"}
|
|
@@ -7,37 +7,43 @@ exports.default = useIndexController;
|
|
|
7
7
|
|
|
8
8
|
var _react = require("react");
|
|
9
9
|
|
|
10
|
+
var _core = require("@fountain-ui/core");
|
|
11
|
+
|
|
10
12
|
var _utils = require("@fountain-ui/utils");
|
|
11
13
|
|
|
12
14
|
function useIndexController(params) {
|
|
13
15
|
const {
|
|
14
16
|
initialIndex,
|
|
15
17
|
itemWidth,
|
|
18
|
+
numberOfData,
|
|
16
19
|
numberOfOriginalData,
|
|
17
|
-
onIndexChange
|
|
20
|
+
onIndexChange,
|
|
21
|
+
onPositionChange
|
|
18
22
|
} = params;
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const getCurrentIndex = (0, _react.useCallback)(() => currentIndexRef.current, []);
|
|
23
|
+
const currentIndex = (0, _core.useImperativeState)(initialIndex);
|
|
24
|
+
const currentPosition = (0, _core.useImperativeState)(initialIndex);
|
|
22
25
|
const notifyAnimationState = (0, _react.useCallback)(state => {
|
|
23
26
|
if (state === 'finished' || state === 'interrupted') {
|
|
24
|
-
if (
|
|
25
|
-
onIndexChange === null || onIndexChange === void 0 ? void 0 : onIndexChange(
|
|
27
|
+
if (currentIndex.hasChanged()) {
|
|
28
|
+
onIndexChange === null || onIndexChange === void 0 ? void 0 : onIndexChange(currentIndex.get());
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (currentPosition.hasChanged()) {
|
|
32
|
+
onPositionChange === null || onPositionChange === void 0 ? void 0 : onPositionChange(currentPosition.get());
|
|
26
33
|
}
|
|
27
34
|
}
|
|
28
|
-
}, [
|
|
35
|
+
}, [onIndexChange, onPositionChange]);
|
|
29
36
|
const notifyOffsetHasChanged = (0, _react.useCallback)(offset => {
|
|
30
37
|
const roundedOffset = Math.round(offset / itemWidth) * itemWidth; // To prevent floating point problem, make sure index is integer type.
|
|
31
38
|
|
|
32
39
|
const nextIndex = Math.floor((0, _utils.mod)(-roundedOffset / itemWidth, numberOfOriginalData));
|
|
40
|
+
currentIndex.set(nextIndex); // To prevent floating point problem, make sure index is integer type.
|
|
33
41
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
}, [itemWidth, numberOfOriginalData]);
|
|
42
|
+
const nextPosition = Math.floor((0, _utils.mod)(-roundedOffset / itemWidth, numberOfData));
|
|
43
|
+
currentPosition.set(nextPosition);
|
|
44
|
+
}, [itemWidth, numberOfData, numberOfOriginalData]);
|
|
39
45
|
return {
|
|
40
|
-
getCurrentIndex,
|
|
46
|
+
getCurrentIndex: currentIndex.get,
|
|
41
47
|
lastIndex: numberOfOriginalData - 1,
|
|
42
48
|
notifyAnimationState,
|
|
43
49
|
notifyOffsetHasChanged
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useIndexController","params","initialIndex","itemWidth","numberOfOriginalData","onIndexChange","
|
|
1
|
+
{"version":3,"names":["useIndexController","params","initialIndex","itemWidth","numberOfData","numberOfOriginalData","onIndexChange","onPositionChange","currentIndex","useImperativeState","currentPosition","notifyAnimationState","useCallback","state","hasChanged","get","notifyOffsetHasChanged","offset","roundedOffset","Math","round","nextIndex","floor","mod","set","nextPosition","getCurrentIndex","lastIndex"],"sources":["useIndexController.tsx"],"sourcesContent":["import { useCallback } from 'react';\nimport { useImperativeState } from '@fountain-ui/core';\nimport { mod } from '@fountain-ui/utils';\nimport type { AnimationState, IndexController } from '../types';\n\nexport interface UseIndexControllerParameters {\n initialIndex: number;\n itemWidth: number;\n numberOfData: number;\n numberOfOriginalData: number;\n onIndexChange?: (itemIndex: number) => void;\n onPositionChange?: (position: number) => void;\n}\n\nexport default function useIndexController(params: UseIndexControllerParameters): IndexController {\n const {\n initialIndex,\n itemWidth,\n numberOfData,\n numberOfOriginalData,\n onIndexChange,\n onPositionChange,\n } = params;\n\n const currentIndex = useImperativeState(initialIndex);\n const currentPosition = useImperativeState(initialIndex);\n\n const notifyAnimationState = useCallback((state: AnimationState) => {\n if (state === 'finished' || state === 'interrupted') {\n if (currentIndex.hasChanged()) {\n onIndexChange?.(currentIndex.get());\n }\n\n if (currentPosition.hasChanged()) {\n onPositionChange?.(currentPosition.get());\n }\n }\n }, [\n onIndexChange,\n onPositionChange,\n ]);\n\n const notifyOffsetHasChanged = useCallback((offset: number) => {\n const roundedOffset = Math.round(offset / itemWidth) * itemWidth;\n\n // To prevent floating point problem, make sure index is integer type.\n const nextIndex = Math.floor(mod((-roundedOffset / itemWidth), numberOfOriginalData));\n currentIndex.set(nextIndex);\n\n // To prevent floating point problem, make sure index is integer type.\n const nextPosition = Math.floor(mod((-roundedOffset / itemWidth), numberOfData));\n currentPosition.set(nextPosition);\n }, [\n itemWidth,\n numberOfData,\n numberOfOriginalData,\n ]);\n\n return {\n getCurrentIndex: currentIndex.get,\n lastIndex: numberOfOriginalData - 1,\n notifyAnimationState,\n notifyOffsetHasChanged,\n };\n};\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AAYe,SAASA,kBAAT,CAA4BC,MAA5B,EAAmF;EAC9F,MAAM;IACFC,YADE;IAEFC,SAFE;IAGFC,YAHE;IAIFC,oBAJE;IAKFC,aALE;IAMFC;EANE,IAOFN,MAPJ;EASA,MAAMO,YAAY,GAAG,IAAAC,wBAAA,EAAmBP,YAAnB,CAArB;EACA,MAAMQ,eAAe,GAAG,IAAAD,wBAAA,EAAmBP,YAAnB,CAAxB;EAEA,MAAMS,oBAAoB,GAAG,IAAAC,kBAAA,EAAaC,KAAD,IAA2B;IAChE,IAAIA,KAAK,KAAK,UAAV,IAAwBA,KAAK,KAAK,aAAtC,EAAqD;MACjD,IAAIL,YAAY,CAACM,UAAb,EAAJ,EAA+B;QAC3BR,aAAa,SAAb,IAAAA,aAAa,WAAb,YAAAA,aAAa,CAAGE,YAAY,CAACO,GAAb,EAAH,CAAb;MACH;;MAED,IAAIL,eAAe,CAACI,UAAhB,EAAJ,EAAkC;QAC9BP,gBAAgB,SAAhB,IAAAA,gBAAgB,WAAhB,YAAAA,gBAAgB,CAAGG,eAAe,CAACK,GAAhB,EAAH,CAAhB;MACH;IACJ;EACJ,CAV4B,EAU1B,CACCT,aADD,EAECC,gBAFD,CAV0B,CAA7B;EAeA,MAAMS,sBAAsB,GAAG,IAAAJ,kBAAA,EAAaK,MAAD,IAAoB;IAC3D,MAAMC,aAAa,GAAGC,IAAI,CAACC,KAAL,CAAWH,MAAM,GAAGd,SAApB,IAAiCA,SAAvD,CAD2D,CAG3D;;IACA,MAAMkB,SAAS,GAAGF,IAAI,CAACG,KAAL,CAAW,IAAAC,UAAA,EAAK,CAACL,aAAD,GAAiBf,SAAtB,EAAkCE,oBAAlC,CAAX,CAAlB;IACAG,YAAY,CAACgB,GAAb,CAAiBH,SAAjB,EAL2D,CAO3D;;IACA,MAAMI,YAAY,GAAGN,IAAI,CAACG,KAAL,CAAW,IAAAC,UAAA,EAAK,CAACL,aAAD,GAAiBf,SAAtB,EAAkCC,YAAlC,CAAX,CAArB;IACAM,eAAe,CAACc,GAAhB,CAAoBC,YAApB;EACH,CAV8B,EAU5B,CACCtB,SADD,EAECC,YAFD,EAGCC,oBAHD,CAV4B,CAA/B;EAgBA,OAAO;IACHqB,eAAe,EAAElB,YAAY,CAACO,GAD3B;IAEHY,SAAS,EAAEtB,oBAAoB,GAAG,CAF/B;IAGHM,oBAHG;IAIHK;EAJG,CAAP;AAMH;;AAAA"}
|
|
@@ -79,8 +79,8 @@ function useItemVisibilityStore(params) {
|
|
|
79
79
|
return makeVisibleIndexRanges(numberOfData, windowSize, initialIndex);
|
|
80
80
|
});
|
|
81
81
|
const store = (0, _react.useRef)(new SimpleItemVisibilityStore(initialRange)).current;
|
|
82
|
-
const
|
|
83
|
-
const newRanges = makeVisibleIndexRanges(numberOfData, windowSize,
|
|
82
|
+
const onPositionChange = (0, _react.useCallback)(position => {
|
|
83
|
+
const newRanges = makeVisibleIndexRanges(numberOfData, windowSize, position);
|
|
84
84
|
store.dispatch(newRanges);
|
|
85
85
|
}, [numberOfData, windowSize]);
|
|
86
86
|
(0, _react.useEffect)(() => {
|
|
@@ -88,7 +88,7 @@ function useItemVisibilityStore(params) {
|
|
|
88
88
|
store.removeAllListeners();
|
|
89
89
|
};
|
|
90
90
|
}, []);
|
|
91
|
-
return [store,
|
|
91
|
+
return [store, onPositionChange];
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["SimpleItemVisibilityStore","constructor","initialValue","store","subscribe","listener","listeners","push","index","indexOf","splice","dispatch","ranges","id","removeAllListeners","length","normalize","windowSize","numberOfData","makeVisibleIndexRanges","ws","firstIndex","lastIndex","halfNumberOfAdjacent","Math","floor","leftSide","rightSide","leftRanges","mod","rightRanges","useItemVisibilityStore","params","initialIndex","initialRange","useState","useRef","current","
|
|
1
|
+
{"version":3,"names":["SimpleItemVisibilityStore","constructor","initialValue","store","subscribe","listener","listeners","push","index","indexOf","splice","dispatch","ranges","id","removeAllListeners","length","normalize","windowSize","numberOfData","makeVisibleIndexRanges","ws","firstIndex","lastIndex","halfNumberOfAdjacent","Math","floor","leftSide","rightSide","leftRanges","mod","rightRanges","useItemVisibilityStore","params","initialIndex","initialRange","useState","useRef","current","onPositionChange","useCallback","position","newRanges","useEffect"],"sources":["useItemVisibilityStore.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport { mod } from '@fountain-ui/utils';\nimport type { ItemVisibilityStore, OnPositionChange, VisibleIndexRanges } from '../types';\n\nexport interface Parameters {\n initialIndex: number;\n numberOfData: number;\n windowSize: number;\n}\n\nclass SimpleItemVisibilityStore implements ItemVisibilityStore {\n\n private store: VisibleIndexRanges;\n\n constructor(initialValue: VisibleIndexRanges) {\n this.store = initialValue;\n }\n\n private listeners: Array<(ranges: VisibleIndexRanges) => void> = [];\n\n subscribe(listener: (ranges: VisibleIndexRanges) => void) {\n this.listeners.push(listener);\n\n listener(this.store);\n\n return () => {\n const index = this.listeners.indexOf(listener);\n this.listeners.splice(index, 1);\n };\n }\n\n dispatch(ranges: VisibleIndexRanges): void {\n this.store = ranges;\n for (const id in this.listeners) {\n const listener = this.listeners[id];\n listener?.(ranges);\n }\n }\n\n removeAllListeners(): void {\n this.listeners.splice(0, this.listeners.length);\n }\n\n}\n\nfunction normalize(windowSize: number, numberOfData: number): number {\n if (windowSize <= 0) {\n return numberOfData;\n }\n if (windowSize > 0 && windowSize % 2 === 0) {\n return windowSize + 1;\n }\n return windowSize;\n}\n\nfunction makeVisibleIndexRanges(numberOfData: number, windowSize: number, index: number): VisibleIndexRanges {\n const ws = normalize(windowSize, numberOfData);\n\n const firstIndex = 0;\n const lastIndex = numberOfData - 1;\n const halfNumberOfAdjacent = Math.floor(ws / 2);\n\n const leftSide = index - halfNumberOfAdjacent;\n const rightSide = index + halfNumberOfAdjacent;\n\n const leftRanges = leftSide >= 0\n ? [[leftSide, index]]\n : [[firstIndex, index], [mod(leftSide, numberOfData), lastIndex]];\n\n const rightRanges = rightSide < numberOfData\n ? [[index, rightSide]]\n : [[index, lastIndex], [firstIndex, mod(rightSide, numberOfData)]];\n\n // @ts-ignore\n return [\n ...leftRanges,\n ...rightRanges,\n ];\n}\n\nexport default function useItemVisibilityStore(params: Parameters): [ItemVisibilityStore, OnPositionChange] {\n const {\n initialIndex,\n numberOfData,\n windowSize,\n } = params;\n\n const [initialRange] = useState(() => {\n return makeVisibleIndexRanges(numberOfData, windowSize, initialIndex);\n });\n\n const store = useRef(new SimpleItemVisibilityStore(initialRange)).current;\n\n const onPositionChange: OnPositionChange = useCallback((position) => {\n const newRanges = makeVisibleIndexRanges(numberOfData, windowSize, position);\n\n store.dispatch(newRanges);\n }, [numberOfData, windowSize]);\n\n useEffect(() => {\n return () => {\n store.removeAllListeners();\n };\n }, []);\n\n return [store, onPositionChange];\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["directions","animationStates"],"sources":["types.ts"],"sourcesContent":["import type { ReactElement } from 'react';\nimport type { Animated, ViewProps } from 'react-native';\n\nconst directions = ['next', 'prev', 'stay'] as const;\n\nexport type PagingDirection = (typeof directions)[number];\n\nconst animationStates = ['started', 'finished', 'interrupted'] as const;\n\nexport type AnimationState = (typeof animationStates)[number];\n\nexport type ItemHeight = number | 'auto';\n\nexport interface RenderItem<T> {\n (info: { item: T, index: number, interpolation: Animated.AnimatedInterpolation }): ReactElement | null;\n}\n\nexport interface CreateScrollAnimation {\n (aValue: Animated.AnimatedValue, toValue: number): Animated.CompositeAnimation;\n}\n\nexport interface CreateItemStyle {\n (itemInterpolation: Animated.AnimatedInterpolation, itemWidth: number): Animated.AnimatedProps<ViewProps['style']>;\n}\n\nexport interface GetCurrentIndex {\n (): number;\n}\n\nexport interface IndexController {\n getCurrentIndex: GetCurrentIndex;\n lastIndex: number;\n notifyAnimationState: (state: AnimationState) => void;\n notifyOffsetHasChanged: (offset: number) => void;\n}\n\nexport type PagingAnimationType = 'directional' | 'index';\n\nexport interface BasePagingAnimationConfig {\n animated?: boolean;\n}\n\nexport interface DirectionalPagingAnimationConfig extends BasePagingAnimationConfig {\n direction: PagingDirection;\n isOriginatedFromGesture?: boolean;\n}\n\nexport interface IndexPagingAnimationConfig extends BasePagingAnimationConfig {\n index: number;\n}\n\nexport type PagingAnimationConfig = DirectionalPagingAnimationConfig | IndexPagingAnimationConfig;\n\nexport interface StartPagingAnimation {\n (type: PagingAnimationType, config: PagingAnimationConfig): void;\n}\n\nexport type VisibleIndexRanges = Array<[number, number]>;\n\nexport interface StoreSubscription {\n (): void;\n}\n\nexport interface ItemVisibilityStore {\n dispatch: (ranges: VisibleIndexRanges) => void;\n subscribe: (listener: (ranges: VisibleIndexRanges) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n\nexport interface AutoplayController {\n pause: () => void;\n resume: () => void;\n}\n\nexport interface ScrollToOption {\n index: number;\n animated?: boolean;\n}\n\nexport interface CarouselInstance {\n /**\n * Get current visible item index.\n */\n getCurrentIndex: GetCurrentIndex;\n\n /**\n * Scroll to next visible item.\n */\n next: () => void;\n\n /**\n * Scroll to previous visible item.\n */\n prev: () => void;\n\n /**\n * Scroll to desired indexed item.\n * Invalid index is ignored.\n */\n scrollTo: (option: ScrollToOption) => void;\n}\n"],"mappings":";;;;;AAGA,MAAMA,UAAU,GAAG,CAAC,MAAD,EAAS,MAAT,EAAiB,MAAjB,CAAnB;AAIA,MAAMC,eAAe,GAAG,CAAC,SAAD,EAAY,UAAZ,EAAwB,aAAxB,CAAxB"}
|
|
1
|
+
{"version":3,"names":["directions","animationStates"],"sources":["types.ts"],"sourcesContent":["import type { ReactElement } from 'react';\nimport type { Animated, ViewProps } from 'react-native';\n\nconst directions = ['next', 'prev', 'stay'] as const;\n\nexport type PagingDirection = (typeof directions)[number];\n\nconst animationStates = ['started', 'finished', 'interrupted'] as const;\n\nexport type AnimationState = (typeof animationStates)[number];\n\nexport type ItemHeight = number | 'auto';\n\nexport interface RenderItem<T> {\n (info: { item: T, index: number, interpolation: Animated.AnimatedInterpolation }): ReactElement | null;\n}\n\nexport interface CreateScrollAnimation {\n (aValue: Animated.AnimatedValue, toValue: number): Animated.CompositeAnimation;\n}\n\nexport interface CreateItemStyle {\n (itemInterpolation: Animated.AnimatedInterpolation, itemWidth: number): Animated.AnimatedProps<ViewProps['style']>;\n}\n\nexport interface GetCurrentIndex {\n (): number;\n}\n\nexport interface OnIndexChange {\n (itemIndex: number): void;\n}\n\nexport interface OnPositionChange {\n (position: number): void;\n}\n\nexport interface IndexController {\n getCurrentIndex: GetCurrentIndex;\n lastIndex: number;\n notifyAnimationState: (state: AnimationState) => void;\n notifyOffsetHasChanged: (offset: number) => void;\n}\n\nexport type PagingAnimationType = 'directional' | 'index';\n\nexport interface BasePagingAnimationConfig {\n animated?: boolean;\n}\n\nexport interface DirectionalPagingAnimationConfig extends BasePagingAnimationConfig {\n direction: PagingDirection;\n isOriginatedFromGesture?: boolean;\n}\n\nexport interface IndexPagingAnimationConfig extends BasePagingAnimationConfig {\n index: number;\n}\n\nexport type PagingAnimationConfig = DirectionalPagingAnimationConfig | IndexPagingAnimationConfig;\n\nexport interface StartPagingAnimation {\n (type: PagingAnimationType, config: PagingAnimationConfig): void;\n}\n\nexport type VisibleIndexRanges = Array<[number, number]>;\n\nexport interface StoreSubscription {\n (): void;\n}\n\nexport interface ItemVisibilityStore {\n dispatch: (ranges: VisibleIndexRanges) => void;\n subscribe: (listener: (ranges: VisibleIndexRanges) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n\nexport interface AutoplayController {\n pause: () => void;\n resume: () => void;\n}\n\nexport interface ScrollToOption {\n index: number;\n animated?: boolean;\n}\n\nexport interface CarouselInstance {\n /**\n * Get current visible item index.\n */\n getCurrentIndex: GetCurrentIndex;\n\n /**\n * Scroll to next visible item.\n */\n next: () => void;\n\n /**\n * Scroll to previous visible item.\n */\n prev: () => void;\n\n /**\n * Scroll to desired indexed item.\n * Invalid index is ignored.\n */\n scrollTo: (option: ScrollToOption) => void;\n}\n"],"mappings":";;;;;AAGA,MAAMA,UAAU,GAAG,CAAC,MAAD,EAAS,MAAT,EAAiB,MAAjB,CAAnB;AAIA,MAAMC,eAAe,GAAG,CAAC,SAAD,EAAY,UAAZ,EAAwB,aAAxB,CAAxB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, memo,
|
|
1
|
+
import React, { forwardRef, memo, useImperativeHandle, useMemo, useRef } from 'react';
|
|
2
2
|
import { Animated } from 'react-native';
|
|
3
3
|
import ViewabilityTrackerView from '../ViewabilityTrackerView';
|
|
4
4
|
import { useAutoplayController, useIndexController, useItemVisibilityStore, useLoopedData, usePagingAnimation } from './hooks';
|
|
@@ -16,7 +16,7 @@ const Carousel = /*#__PURE__*/forwardRef(function Carousel(props, ref) {
|
|
|
16
16
|
itemHeight,
|
|
17
17
|
itemWidth,
|
|
18
18
|
loop = false,
|
|
19
|
-
onIndexChange
|
|
19
|
+
onIndexChange,
|
|
20
20
|
renderItem,
|
|
21
21
|
scrollEnabled = true,
|
|
22
22
|
style,
|
|
@@ -27,20 +27,18 @@ const Carousel = /*#__PURE__*/forwardRef(function Carousel(props, ref) {
|
|
|
27
27
|
const offsetX = useRef(new Animated.Value(initialTx)).current;
|
|
28
28
|
const translateX = useRef(new Animated.Value(0)).current;
|
|
29
29
|
const globalInterpolation = Animated.add(offsetX, translateX);
|
|
30
|
-
const [itemVisibilityStore,
|
|
30
|
+
const [itemVisibilityStore, onPositionChange] = useItemVisibilityStore({
|
|
31
31
|
initialIndex,
|
|
32
32
|
numberOfData: data.length,
|
|
33
33
|
windowSize
|
|
34
34
|
});
|
|
35
|
-
const handleIndexChange = useCallback(newIndex => {
|
|
36
|
-
onIndexChange(newIndex);
|
|
37
|
-
onIndexChangeProp === null || onIndexChangeProp === void 0 ? void 0 : onIndexChangeProp(newIndex);
|
|
38
|
-
}, [onIndexChange, onIndexChangeProp]);
|
|
39
35
|
const indexController = useIndexController({
|
|
40
36
|
initialIndex,
|
|
41
37
|
itemWidth,
|
|
38
|
+
numberOfData: data.length,
|
|
42
39
|
numberOfOriginalData: originalData.length,
|
|
43
|
-
onIndexChange
|
|
40
|
+
onIndexChange,
|
|
41
|
+
onPositionChange
|
|
44
42
|
});
|
|
45
43
|
const {
|
|
46
44
|
getCurrentIndex
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","forwardRef","memo","
|
|
1
|
+
{"version":3,"names":["React","forwardRef","memo","useImperativeHandle","useMemo","useRef","Animated","ViewabilityTrackerView","useAutoplayController","useIndexController","useItemVisibilityStore","useLoopedData","usePagingAnimation","createDefaultItemStyle","createDefaultScrollAnimation","InternalContext","RootView","ScrollViewGesture","Carousel","props","ref","autoplay","autoplayInterval","createItemStyle","createScrollAnimation","data","originalData","disableSmartAutoplay","initialIndex","itemHeight","itemWidth","loop","onIndexChange","renderItem","scrollEnabled","style","windowSize","initialTx","offsetX","Value","current","translateX","globalInterpolation","add","itemVisibilityStore","onPositionChange","numberOfData","length","indexController","numberOfOriginalData","getCurrentIndex","interruptAnimation","startPagingAnimation","autoplayController","enabled","intervalMillis","next","direction","prev","scrollTo","option","contextValue","Math","max","visible","resume","pause"],"sources":["Carousel.tsx"],"sourcesContent":["import React, { forwardRef, memo, useImperativeHandle, useMemo, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport ViewabilityTrackerView from '../ViewabilityTrackerView';\nimport type CarouselProps from './CarouselProps';\nimport type { CarouselInstance } from './types';\nimport {\n useAutoplayController,\n useIndexController,\n useItemVisibilityStore,\n useLoopedData,\n usePagingAnimation,\n} from './hooks';\nimport { createDefaultItemStyle, createDefaultScrollAnimation } from './animation';\nimport { InternalContext, RootView, ScrollViewGesture } from './components';\n\nconst Carousel = forwardRef<CarouselInstance, CarouselProps>(function Carousel(props, ref) {\n const {\n autoplay = false,\n autoplayInterval = 3000,\n createItemStyle = createDefaultItemStyle,\n createScrollAnimation = createDefaultScrollAnimation,\n data: originalData,\n disableSmartAutoplay = false,\n initialIndex = 0,\n itemHeight,\n itemWidth,\n loop = false,\n onIndexChange,\n renderItem,\n scrollEnabled = true,\n style,\n windowSize = 5,\n } = props;\n\n const data = useLoopedData(originalData, loop);\n\n const initialTx = itemWidth * initialIndex;\n const offsetX = useRef(new Animated.Value(initialTx)).current;\n const translateX = useRef(new Animated.Value(0)).current;\n const globalInterpolation = Animated.add(offsetX, translateX);\n\n const [itemVisibilityStore, onPositionChange] = useItemVisibilityStore({\n initialIndex,\n numberOfData: data.length,\n windowSize,\n });\n\n const indexController = useIndexController({\n initialIndex,\n itemWidth,\n numberOfData: data.length,\n numberOfOriginalData: originalData.length,\n onIndexChange,\n onPositionChange,\n });\n\n const { getCurrentIndex } = indexController;\n\n const {\n interruptAnimation,\n startPagingAnimation,\n } = usePagingAnimation({\n createScrollAnimation,\n itemWidth,\n indexController,\n loop,\n numberOfData: data.length,\n offsetX,\n translateX,\n });\n\n const autoplayController = useAutoplayController({\n enabled: autoplay,\n intervalMillis: autoplayInterval,\n startPagingAnimation,\n });\n\n useImperativeHandle(\n ref,\n () => ({\n getCurrentIndex,\n next: () => startPagingAnimation('directional', { direction: 'next' }),\n prev: () => startPagingAnimation('directional', { direction: 'prev' }),\n scrollTo: (option) => startPagingAnimation('index', option),\n }),\n [startPagingAnimation, getCurrentIndex],\n );\n\n const contextValue = useMemo(() => ({\n createItemStyle,\n data,\n globalInterpolation,\n itemHeight,\n itemWidth,\n itemVisibilityStore,\n loop,\n }), [\n createItemStyle,\n data,\n globalInterpolation,\n itemHeight,\n itemWidth,\n itemVisibilityStore,\n loop,\n ]);\n\n return (\n <InternalContext.Provider value={contextValue}>\n <ViewabilityTrackerView\n enabled={autoplay && !disableSmartAutoplay}\n measurementIntervalMillis={Math.max(3000, autoplayInterval)}\n onViewabilityChange={({ visible }) => {\n if (visible) {\n autoplayController.resume();\n } else {\n autoplayController.pause();\n }\n }}\n >\n <ScrollViewGesture\n autoplayController={autoplayController}\n interruptAnimation={interruptAnimation}\n translateX={translateX}\n scrollEnabled={scrollEnabled}\n startPagingAnimation={startPagingAnimation}\n >\n <RootView\n data={data}\n itemHeight={itemHeight}\n originalData={originalData}\n renderItem={renderItem}\n style={style}\n />\n </ScrollViewGesture>\n </ViewabilityTrackerView>\n </InternalContext.Provider>\n );\n});\n\nexport default memo(Carousel);\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["CarouselProps.ts"],"sourcesContent":["import type { RefObject } from 'react';\nimport type { ComponentProps } from '@fountain-ui/core';\nimport type {
|
|
1
|
+
{"version":3,"names":[],"sources":["CarouselProps.ts"],"sourcesContent":["import type { RefObject } from 'react';\nimport type { ComponentProps } from '@fountain-ui/core';\nimport type {\n CarouselInstance,\n CreateItemStyle,\n CreateScrollAnimation,\n ItemHeight,\n OnIndexChange,\n RenderItem,\n} from './types';\n\nexport default interface CarouselProps<ItemT = any> extends ComponentProps<{\n ref?: RefObject<CarouselInstance>;\n\n /**\n * If `true`, enable autoplay.\n * @default false\n */\n autoplay?: boolean;\n\n /**\n * Delay in ms until navigating to the next item.\n * @default 3000\n */\n autoplayInterval?: number;\n\n /**\n * The item style creator function.\n * @default createDefaultItemStyle\n */\n createItemStyle?: CreateItemStyle;\n\n /**\n * The scroll animation creator function.\n * @default createDefaultScrollAnimation\n */\n createScrollAnimation?: CreateScrollAnimation;\n\n /**\n * Data for render items.\n */\n data: ReadonlyArray<ItemT>;\n\n /**\n * If `true`, carousel will detect its own viewability and control autoplay automatically.\n * @default false\n */\n disableSmartAutoplay?: boolean;\n\n /**\n * Index of initial item that should be selected.\n * @default 0\n */\n initialIndex?: number;\n\n /**\n * The item height.\n * For a performance reason, always consider to provide a number value.\n */\n itemHeight: ItemHeight;\n\n /**\n * The item width.\n */\n itemWidth: number;\n\n /**\n * Enable infinite loop mode.\n * @default false\n */\n loop?: boolean;\n\n /**\n * Callback fired when an index is changed.\n */\n onIndexChange?: OnIndexChange;\n\n /**\n * Takes an item from data and renders it into the list.\n */\n renderItem: RenderItem<ItemT>;\n\n /**\n * Whether to enable scroll gesture.\n * @default true\n */\n scrollEnabled?: boolean;\n\n /**\n * The maximum number of items that can respond to pan gesture events.\n * Due to the nature of the `active` item, it accepts only odd number. (e.g. 1, 3, 5...)\n * 0 means all items will respond to pan gesture events.\n * @default 5\n */\n windowSize?: number;\n}> {}\n"],"mappings":""}
|
|
@@ -17,7 +17,7 @@ export default function ItemView(props) {
|
|
|
17
17
|
} = useContext(InternalContext);
|
|
18
18
|
const [visible, setVisible] = useState(false);
|
|
19
19
|
const interpolation = useItemInterpolation(index);
|
|
20
|
-
const itemStyle = useMemo(() => createItemStyle(interpolation, itemWidth), [createItemStyle, interpolation]);
|
|
20
|
+
const itemStyle = useMemo(() => createItemStyle(interpolation, itemWidth), [createItemStyle, interpolation, itemWidth]);
|
|
21
21
|
useEffect(() => {
|
|
22
22
|
return itemVisibilityStore.subscribe(ranges => {
|
|
23
23
|
const nextVisible = ranges.some(_ref => {
|
|
@@ -26,7 +26,7 @@ export default function ItemView(props) {
|
|
|
26
26
|
});
|
|
27
27
|
setVisible(nextVisible);
|
|
28
28
|
});
|
|
29
|
-
}, [itemVisibilityStore]);
|
|
29
|
+
}, [index, itemVisibilityStore]);
|
|
30
30
|
return /*#__PURE__*/React.createElement(Animated.View, {
|
|
31
31
|
children: visible ? children(interpolation) : null,
|
|
32
32
|
onLayout: onLayout,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useContext","useEffect","useMemo","useState","Animated","StyleSheet","useItemInterpolation","InternalContext","ItemView","props","children","index","onLayout","createItemStyle","itemHeight","itemWidth","itemVisibilityStore","visible","setVisible","interpolation","itemStyle","subscribe","ranges","nextVisible","some","from","to","width","height","undefined","styles","absolute","create","position"],"sources":["ItemView.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React, { useContext, useEffect, useMemo, useState } from 'react';\nimport type { ViewProps } from 'react-native';\nimport { Animated } from 'react-native';\nimport { StyleSheet } from '@fountain-ui/core';\nimport useItemInterpolation from './useItemInterpolation';\nimport InternalContext from './InternalContext';\n\nexport interface ItemViewProps {\n children: (interpolation: Animated.AnimatedInterpolation) => ReactElement | null;\n index: number;\n onLayout?: ViewProps['onLayout'];\n}\n\nexport default function ItemView(props: ItemViewProps) {\n const {\n children,\n index,\n onLayout,\n } = props;\n\n const {\n createItemStyle,\n itemHeight,\n itemWidth,\n itemVisibilityStore,\n } = useContext(InternalContext);\n\n const [visible, setVisible] = useState(false);\n\n const interpolation = useItemInterpolation(index);\n\n const itemStyle = useMemo(\n () => createItemStyle(interpolation, itemWidth),\n [createItemStyle, interpolation],\n );\n\n useEffect(() => {\n return itemVisibilityStore.subscribe(ranges => {\n const nextVisible = ranges.some(([from, to]) => index >= from && index <= to);\n setVisible(nextVisible);\n });\n }, [itemVisibilityStore]);\n\n return (\n <Animated.View\n children={visible ? children(interpolation) : null}\n onLayout={onLayout}\n style={[\n {\n width: itemWidth,\n height: itemHeight !== 'auto' ? itemHeight : undefined,\n },\n styles.absolute,\n // @ts-ignore\n itemStyle,\n ]}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n absolute: {\n position: 'absolute',\n },\n});\n"],"mappings":"AACA,OAAOA,KAAP,IAAgBC,UAAhB,EAA4BC,SAA5B,EAAuCC,OAAvC,EAAgDC,QAAhD,QAAgE,OAAhE;AAEA,SAASC,QAAT,QAAyB,cAAzB;AACA,SAASC,UAAT,QAA2B,mBAA3B;AACA,OAAOC,oBAAP,MAAiC,wBAAjC;AACA,OAAOC,eAAP,MAA4B,mBAA5B;AAQA,eAAe,SAASC,QAAT,CAAkBC,KAAlB,EAAwC;EACnD,MAAM;IACFC,QADE;IAEFC,KAFE;IAGFC;EAHE,IAIFH,KAJJ;EAMA,MAAM;IACFI,eADE;IAEFC,UAFE;IAGFC,SAHE;IAIFC;EAJE,IAKFhB,UAAU,CAACO,eAAD,CALd;EAOA,MAAM,CAACU,OAAD,EAAUC,UAAV,IAAwBf,QAAQ,CAAC,KAAD,CAAtC;EAEA,MAAMgB,aAAa,GAAGb,oBAAoB,CAACK,KAAD,CAA1C;EAEA,MAAMS,SAAS,GAAGlB,OAAO,CACrB,MAAMW,eAAe,CAACM,aAAD,EAAgBJ,SAAhB,CADA,EAErB,CAACF,eAAD,EAAkBM,aAAlB,CAFqB,CAAzB;
|
|
1
|
+
{"version":3,"names":["React","useContext","useEffect","useMemo","useState","Animated","StyleSheet","useItemInterpolation","InternalContext","ItemView","props","children","index","onLayout","createItemStyle","itemHeight","itemWidth","itemVisibilityStore","visible","setVisible","interpolation","itemStyle","subscribe","ranges","nextVisible","some","from","to","width","height","undefined","styles","absolute","create","position"],"sources":["ItemView.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React, { useContext, useEffect, useMemo, useState } from 'react';\nimport type { ViewProps } from 'react-native';\nimport { Animated } from 'react-native';\nimport { StyleSheet } from '@fountain-ui/core';\nimport useItemInterpolation from './useItemInterpolation';\nimport InternalContext from './InternalContext';\n\nexport interface ItemViewProps {\n children: (interpolation: Animated.AnimatedInterpolation) => ReactElement | null;\n index: number;\n onLayout?: ViewProps['onLayout'];\n}\n\nexport default function ItemView(props: ItemViewProps) {\n const {\n children,\n index,\n onLayout,\n } = props;\n\n const {\n createItemStyle,\n itemHeight,\n itemWidth,\n itemVisibilityStore,\n } = useContext(InternalContext);\n\n const [visible, setVisible] = useState(false);\n\n const interpolation = useItemInterpolation(index);\n\n const itemStyle = useMemo(\n () => createItemStyle(interpolation, itemWidth),\n [createItemStyle, interpolation, itemWidth],\n );\n\n useEffect(() => {\n return itemVisibilityStore.subscribe(ranges => {\n const nextVisible = ranges.some(([from, to]) => index >= from && index <= to);\n setVisible(nextVisible);\n });\n }, [index, itemVisibilityStore]);\n\n return (\n <Animated.View\n children={visible ? children(interpolation) : null}\n onLayout={onLayout}\n style={[\n {\n width: itemWidth,\n height: itemHeight !== 'auto' ? itemHeight : undefined,\n },\n styles.absolute,\n // @ts-ignore\n itemStyle,\n ]}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n absolute: {\n position: 'absolute',\n },\n});\n"],"mappings":"AACA,OAAOA,KAAP,IAAgBC,UAAhB,EAA4BC,SAA5B,EAAuCC,OAAvC,EAAgDC,QAAhD,QAAgE,OAAhE;AAEA,SAASC,QAAT,QAAyB,cAAzB;AACA,SAASC,UAAT,QAA2B,mBAA3B;AACA,OAAOC,oBAAP,MAAiC,wBAAjC;AACA,OAAOC,eAAP,MAA4B,mBAA5B;AAQA,eAAe,SAASC,QAAT,CAAkBC,KAAlB,EAAwC;EACnD,MAAM;IACFC,QADE;IAEFC,KAFE;IAGFC;EAHE,IAIFH,KAJJ;EAMA,MAAM;IACFI,eADE;IAEFC,UAFE;IAGFC,SAHE;IAIFC;EAJE,IAKFhB,UAAU,CAACO,eAAD,CALd;EAOA,MAAM,CAACU,OAAD,EAAUC,UAAV,IAAwBf,QAAQ,CAAC,KAAD,CAAtC;EAEA,MAAMgB,aAAa,GAAGb,oBAAoB,CAACK,KAAD,CAA1C;EAEA,MAAMS,SAAS,GAAGlB,OAAO,CACrB,MAAMW,eAAe,CAACM,aAAD,EAAgBJ,SAAhB,CADA,EAErB,CAACF,eAAD,EAAkBM,aAAlB,EAAiCJ,SAAjC,CAFqB,CAAzB;EAKAd,SAAS,CAAC,MAAM;IACZ,OAAOe,mBAAmB,CAACK,SAApB,CAA8BC,MAAM,IAAI;MAC3C,MAAMC,WAAW,GAAGD,MAAM,CAACE,IAAP,CAAY;QAAA,IAAC,CAACC,IAAD,EAAOC,EAAP,CAAD;QAAA,OAAgBf,KAAK,IAAIc,IAAT,IAAiBd,KAAK,IAAIe,EAA1C;MAAA,CAAZ,CAApB;MACAR,UAAU,CAACK,WAAD,CAAV;IACH,CAHM,CAAP;EAIH,CALQ,EAKN,CAACZ,KAAD,EAAQK,mBAAR,CALM,CAAT;EAOA,oBACI,oBAAC,QAAD,CAAU,IAAV;IACI,QAAQ,EAAEC,OAAO,GAAGP,QAAQ,CAACS,aAAD,CAAX,GAA6B,IADlD;IAEI,QAAQ,EAAEP,QAFd;IAGI,KAAK,EAAE,CACH;MACIe,KAAK,EAAEZ,SADX;MAEIa,MAAM,EAAEd,UAAU,KAAK,MAAf,GAAwBA,UAAxB,GAAqCe;IAFjD,CADG,EAKHC,MAAM,CAACC,QALJ,EAMH;IACAX,SAPG;EAHX,EADJ;AAeH;AAAA;AAED,MAAMU,MAAM,GAAGzB,UAAU,CAAC2B,MAAX,CAAkB;EAC7BD,QAAQ,EAAE;IACNE,QAAQ,EAAE;EADJ;AADmB,CAAlB,CAAf"}
|
|
@@ -1,34 +1,39 @@
|
|
|
1
|
-
import { useCallback
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { useImperativeState } from '@fountain-ui/core';
|
|
2
3
|
import { mod } from '@fountain-ui/utils';
|
|
3
4
|
export default function useIndexController(params) {
|
|
4
5
|
const {
|
|
5
6
|
initialIndex,
|
|
6
7
|
itemWidth,
|
|
8
|
+
numberOfData,
|
|
7
9
|
numberOfOriginalData,
|
|
8
|
-
onIndexChange
|
|
10
|
+
onIndexChange,
|
|
11
|
+
onPositionChange
|
|
9
12
|
} = params;
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const getCurrentIndex = useCallback(() => currentIndexRef.current, []);
|
|
13
|
+
const currentIndex = useImperativeState(initialIndex);
|
|
14
|
+
const currentPosition = useImperativeState(initialIndex);
|
|
13
15
|
const notifyAnimationState = useCallback(state => {
|
|
14
16
|
if (state === 'finished' || state === 'interrupted') {
|
|
15
|
-
if (
|
|
16
|
-
onIndexChange === null || onIndexChange === void 0 ? void 0 : onIndexChange(
|
|
17
|
+
if (currentIndex.hasChanged()) {
|
|
18
|
+
onIndexChange === null || onIndexChange === void 0 ? void 0 : onIndexChange(currentIndex.get());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (currentPosition.hasChanged()) {
|
|
22
|
+
onPositionChange === null || onPositionChange === void 0 ? void 0 : onPositionChange(currentPosition.get());
|
|
17
23
|
}
|
|
18
24
|
}
|
|
19
|
-
}, [
|
|
25
|
+
}, [onIndexChange, onPositionChange]);
|
|
20
26
|
const notifyOffsetHasChanged = useCallback(offset => {
|
|
21
27
|
const roundedOffset = Math.round(offset / itemWidth) * itemWidth; // To prevent floating point problem, make sure index is integer type.
|
|
22
28
|
|
|
23
29
|
const nextIndex = Math.floor(mod(-roundedOffset / itemWidth, numberOfOriginalData));
|
|
30
|
+
currentIndex.set(nextIndex); // To prevent floating point problem, make sure index is integer type.
|
|
24
31
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
}, [itemWidth, numberOfOriginalData]);
|
|
32
|
+
const nextPosition = Math.floor(mod(-roundedOffset / itemWidth, numberOfData));
|
|
33
|
+
currentPosition.set(nextPosition);
|
|
34
|
+
}, [itemWidth, numberOfData, numberOfOriginalData]);
|
|
30
35
|
return {
|
|
31
|
-
getCurrentIndex,
|
|
36
|
+
getCurrentIndex: currentIndex.get,
|
|
32
37
|
lastIndex: numberOfOriginalData - 1,
|
|
33
38
|
notifyAnimationState,
|
|
34
39
|
notifyOffsetHasChanged
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","
|
|
1
|
+
{"version":3,"names":["useCallback","useImperativeState","mod","useIndexController","params","initialIndex","itemWidth","numberOfData","numberOfOriginalData","onIndexChange","onPositionChange","currentIndex","currentPosition","notifyAnimationState","state","hasChanged","get","notifyOffsetHasChanged","offset","roundedOffset","Math","round","nextIndex","floor","set","nextPosition","getCurrentIndex","lastIndex"],"sources":["useIndexController.tsx"],"sourcesContent":["import { useCallback } from 'react';\nimport { useImperativeState } from '@fountain-ui/core';\nimport { mod } from '@fountain-ui/utils';\nimport type { AnimationState, IndexController } from '../types';\n\nexport interface UseIndexControllerParameters {\n initialIndex: number;\n itemWidth: number;\n numberOfData: number;\n numberOfOriginalData: number;\n onIndexChange?: (itemIndex: number) => void;\n onPositionChange?: (position: number) => void;\n}\n\nexport default function useIndexController(params: UseIndexControllerParameters): IndexController {\n const {\n initialIndex,\n itemWidth,\n numberOfData,\n numberOfOriginalData,\n onIndexChange,\n onPositionChange,\n } = params;\n\n const currentIndex = useImperativeState(initialIndex);\n const currentPosition = useImperativeState(initialIndex);\n\n const notifyAnimationState = useCallback((state: AnimationState) => {\n if (state === 'finished' || state === 'interrupted') {\n if (currentIndex.hasChanged()) {\n onIndexChange?.(currentIndex.get());\n }\n\n if (currentPosition.hasChanged()) {\n onPositionChange?.(currentPosition.get());\n }\n }\n }, [\n onIndexChange,\n onPositionChange,\n ]);\n\n const notifyOffsetHasChanged = useCallback((offset: number) => {\n const roundedOffset = Math.round(offset / itemWidth) * itemWidth;\n\n // To prevent floating point problem, make sure index is integer type.\n const nextIndex = Math.floor(mod((-roundedOffset / itemWidth), numberOfOriginalData));\n currentIndex.set(nextIndex);\n\n // To prevent floating point problem, make sure index is integer type.\n const nextPosition = Math.floor(mod((-roundedOffset / itemWidth), numberOfData));\n currentPosition.set(nextPosition);\n }, [\n itemWidth,\n numberOfData,\n numberOfOriginalData,\n ]);\n\n return {\n getCurrentIndex: currentIndex.get,\n lastIndex: numberOfOriginalData - 1,\n notifyAnimationState,\n notifyOffsetHasChanged,\n };\n};\n"],"mappings":"AAAA,SAASA,WAAT,QAA4B,OAA5B;AACA,SAASC,kBAAT,QAAmC,mBAAnC;AACA,SAASC,GAAT,QAAoB,oBAApB;AAYA,eAAe,SAASC,kBAAT,CAA4BC,MAA5B,EAAmF;EAC9F,MAAM;IACFC,YADE;IAEFC,SAFE;IAGFC,YAHE;IAIFC,oBAJE;IAKFC,aALE;IAMFC;EANE,IAOFN,MAPJ;EASA,MAAMO,YAAY,GAAGV,kBAAkB,CAACI,YAAD,CAAvC;EACA,MAAMO,eAAe,GAAGX,kBAAkB,CAACI,YAAD,CAA1C;EAEA,MAAMQ,oBAAoB,GAAGb,WAAW,CAAEc,KAAD,IAA2B;IAChE,IAAIA,KAAK,KAAK,UAAV,IAAwBA,KAAK,KAAK,aAAtC,EAAqD;MACjD,IAAIH,YAAY,CAACI,UAAb,EAAJ,EAA+B;QAC3BN,aAAa,SAAb,IAAAA,aAAa,WAAb,YAAAA,aAAa,CAAGE,YAAY,CAACK,GAAb,EAAH,CAAb;MACH;;MAED,IAAIJ,eAAe,CAACG,UAAhB,EAAJ,EAAkC;QAC9BL,gBAAgB,SAAhB,IAAAA,gBAAgB,WAAhB,YAAAA,gBAAgB,CAAGE,eAAe,CAACI,GAAhB,EAAH,CAAhB;MACH;IACJ;EACJ,CAVuC,EAUrC,CACCP,aADD,EAECC,gBAFD,CAVqC,CAAxC;EAeA,MAAMO,sBAAsB,GAAGjB,WAAW,CAAEkB,MAAD,IAAoB;IAC3D,MAAMC,aAAa,GAAGC,IAAI,CAACC,KAAL,CAAWH,MAAM,GAAGZ,SAApB,IAAiCA,SAAvD,CAD2D,CAG3D;;IACA,MAAMgB,SAAS,GAAGF,IAAI,CAACG,KAAL,CAAWrB,GAAG,CAAE,CAACiB,aAAD,GAAiBb,SAAnB,EAA+BE,oBAA/B,CAAd,CAAlB;IACAG,YAAY,CAACa,GAAb,CAAiBF,SAAjB,EAL2D,CAO3D;;IACA,MAAMG,YAAY,GAAGL,IAAI,CAACG,KAAL,CAAWrB,GAAG,CAAE,CAACiB,aAAD,GAAiBb,SAAnB,EAA+BC,YAA/B,CAAd,CAArB;IACAK,eAAe,CAACY,GAAhB,CAAoBC,YAApB;EACH,CAVyC,EAUvC,CACCnB,SADD,EAECC,YAFD,EAGCC,oBAHD,CAVuC,CAA1C;EAgBA,OAAO;IACHkB,eAAe,EAAEf,YAAY,CAACK,GAD3B;IAEHW,SAAS,EAAEnB,oBAAoB,GAAG,CAF/B;IAGHK,oBAHG;IAIHI;EAJG,CAAP;AAMH;AAAA"}
|
|
@@ -71,8 +71,8 @@ export default function useItemVisibilityStore(params) {
|
|
|
71
71
|
return makeVisibleIndexRanges(numberOfData, windowSize, initialIndex);
|
|
72
72
|
});
|
|
73
73
|
const store = useRef(new SimpleItemVisibilityStore(initialRange)).current;
|
|
74
|
-
const
|
|
75
|
-
const newRanges = makeVisibleIndexRanges(numberOfData, windowSize,
|
|
74
|
+
const onPositionChange = useCallback(position => {
|
|
75
|
+
const newRanges = makeVisibleIndexRanges(numberOfData, windowSize, position);
|
|
76
76
|
store.dispatch(newRanges);
|
|
77
77
|
}, [numberOfData, windowSize]);
|
|
78
78
|
useEffect(() => {
|
|
@@ -80,7 +80,7 @@ export default function useItemVisibilityStore(params) {
|
|
|
80
80
|
store.removeAllListeners();
|
|
81
81
|
};
|
|
82
82
|
}, []);
|
|
83
|
-
return [store,
|
|
83
|
+
return [store, onPositionChange];
|
|
84
84
|
}
|
|
85
85
|
;
|
|
86
86
|
//# sourceMappingURL=useItemVisibilityStore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useRef","useState","mod","SimpleItemVisibilityStore","constructor","initialValue","store","subscribe","listener","listeners","push","index","indexOf","splice","dispatch","ranges","id","removeAllListeners","length","normalize","windowSize","numberOfData","makeVisibleIndexRanges","ws","firstIndex","lastIndex","halfNumberOfAdjacent","Math","floor","leftSide","rightSide","leftRanges","rightRanges","useItemVisibilityStore","params","initialIndex","initialRange","current","
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useRef","useState","mod","SimpleItemVisibilityStore","constructor","initialValue","store","subscribe","listener","listeners","push","index","indexOf","splice","dispatch","ranges","id","removeAllListeners","length","normalize","windowSize","numberOfData","makeVisibleIndexRanges","ws","firstIndex","lastIndex","halfNumberOfAdjacent","Math","floor","leftSide","rightSide","leftRanges","rightRanges","useItemVisibilityStore","params","initialIndex","initialRange","current","onPositionChange","position","newRanges"],"sources":["useItemVisibilityStore.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport { mod } from '@fountain-ui/utils';\nimport type { ItemVisibilityStore, OnPositionChange, VisibleIndexRanges } from '../types';\n\nexport interface Parameters {\n initialIndex: number;\n numberOfData: number;\n windowSize: number;\n}\n\nclass SimpleItemVisibilityStore implements ItemVisibilityStore {\n\n private store: VisibleIndexRanges;\n\n constructor(initialValue: VisibleIndexRanges) {\n this.store = initialValue;\n }\n\n private listeners: Array<(ranges: VisibleIndexRanges) => void> = [];\n\n subscribe(listener: (ranges: VisibleIndexRanges) => void) {\n this.listeners.push(listener);\n\n listener(this.store);\n\n return () => {\n const index = this.listeners.indexOf(listener);\n this.listeners.splice(index, 1);\n };\n }\n\n dispatch(ranges: VisibleIndexRanges): void {\n this.store = ranges;\n for (const id in this.listeners) {\n const listener = this.listeners[id];\n listener?.(ranges);\n }\n }\n\n removeAllListeners(): void {\n this.listeners.splice(0, this.listeners.length);\n }\n\n}\n\nfunction normalize(windowSize: number, numberOfData: number): number {\n if (windowSize <= 0) {\n return numberOfData;\n }\n if (windowSize > 0 && windowSize % 2 === 0) {\n return windowSize + 1;\n }\n return windowSize;\n}\n\nfunction makeVisibleIndexRanges(numberOfData: number, windowSize: number, index: number): VisibleIndexRanges {\n const ws = normalize(windowSize, numberOfData);\n\n const firstIndex = 0;\n const lastIndex = numberOfData - 1;\n const halfNumberOfAdjacent = Math.floor(ws / 2);\n\n const leftSide = index - halfNumberOfAdjacent;\n const rightSide = index + halfNumberOfAdjacent;\n\n const leftRanges = leftSide >= 0\n ? [[leftSide, index]]\n : [[firstIndex, index], [mod(leftSide, numberOfData), lastIndex]];\n\n const rightRanges = rightSide < numberOfData\n ? [[index, rightSide]]\n : [[index, lastIndex], [firstIndex, mod(rightSide, numberOfData)]];\n\n // @ts-ignore\n return [\n ...leftRanges,\n ...rightRanges,\n ];\n}\n\nexport default function useItemVisibilityStore(params: Parameters): [ItemVisibilityStore, OnPositionChange] {\n const {\n initialIndex,\n numberOfData,\n windowSize,\n } = params;\n\n const [initialRange] = useState(() => {\n return makeVisibleIndexRanges(numberOfData, windowSize, initialIndex);\n });\n\n const store = useRef(new SimpleItemVisibilityStore(initialRange)).current;\n\n const onPositionChange: OnPositionChange = useCallback((position) => {\n const newRanges = makeVisibleIndexRanges(numberOfData, windowSize, position);\n\n store.dispatch(newRanges);\n }, [numberOfData, windowSize]);\n\n useEffect(() => {\n return () => {\n store.removeAllListeners();\n };\n }, []);\n\n return [store, onPositionChange];\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["directions","animationStates"],"sources":["types.ts"],"sourcesContent":["import type { ReactElement } from 'react';\nimport type { Animated, ViewProps } from 'react-native';\n\nconst directions = ['next', 'prev', 'stay'] as const;\n\nexport type PagingDirection = (typeof directions)[number];\n\nconst animationStates = ['started', 'finished', 'interrupted'] as const;\n\nexport type AnimationState = (typeof animationStates)[number];\n\nexport type ItemHeight = number | 'auto';\n\nexport interface RenderItem<T> {\n (info: { item: T, index: number, interpolation: Animated.AnimatedInterpolation }): ReactElement | null;\n}\n\nexport interface CreateScrollAnimation {\n (aValue: Animated.AnimatedValue, toValue: number): Animated.CompositeAnimation;\n}\n\nexport interface CreateItemStyle {\n (itemInterpolation: Animated.AnimatedInterpolation, itemWidth: number): Animated.AnimatedProps<ViewProps['style']>;\n}\n\nexport interface GetCurrentIndex {\n (): number;\n}\n\nexport interface IndexController {\n getCurrentIndex: GetCurrentIndex;\n lastIndex: number;\n notifyAnimationState: (state: AnimationState) => void;\n notifyOffsetHasChanged: (offset: number) => void;\n}\n\nexport type PagingAnimationType = 'directional' | 'index';\n\nexport interface BasePagingAnimationConfig {\n animated?: boolean;\n}\n\nexport interface DirectionalPagingAnimationConfig extends BasePagingAnimationConfig {\n direction: PagingDirection;\n isOriginatedFromGesture?: boolean;\n}\n\nexport interface IndexPagingAnimationConfig extends BasePagingAnimationConfig {\n index: number;\n}\n\nexport type PagingAnimationConfig = DirectionalPagingAnimationConfig | IndexPagingAnimationConfig;\n\nexport interface StartPagingAnimation {\n (type: PagingAnimationType, config: PagingAnimationConfig): void;\n}\n\nexport type VisibleIndexRanges = Array<[number, number]>;\n\nexport interface StoreSubscription {\n (): void;\n}\n\nexport interface ItemVisibilityStore {\n dispatch: (ranges: VisibleIndexRanges) => void;\n subscribe: (listener: (ranges: VisibleIndexRanges) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n\nexport interface AutoplayController {\n pause: () => void;\n resume: () => void;\n}\n\nexport interface ScrollToOption {\n index: number;\n animated?: boolean;\n}\n\nexport interface CarouselInstance {\n /**\n * Get current visible item index.\n */\n getCurrentIndex: GetCurrentIndex;\n\n /**\n * Scroll to next visible item.\n */\n next: () => void;\n\n /**\n * Scroll to previous visible item.\n */\n prev: () => void;\n\n /**\n * Scroll to desired indexed item.\n * Invalid index is ignored.\n */\n scrollTo: (option: ScrollToOption) => void;\n}\n"],"mappings":"AAGA,MAAMA,UAAU,GAAG,CAAC,MAAD,EAAS,MAAT,EAAiB,MAAjB,CAAnB;AAIA,MAAMC,eAAe,GAAG,CAAC,SAAD,EAAY,UAAZ,EAAwB,aAAxB,CAAxB"}
|
|
1
|
+
{"version":3,"names":["directions","animationStates"],"sources":["types.ts"],"sourcesContent":["import type { ReactElement } from 'react';\nimport type { Animated, ViewProps } from 'react-native';\n\nconst directions = ['next', 'prev', 'stay'] as const;\n\nexport type PagingDirection = (typeof directions)[number];\n\nconst animationStates = ['started', 'finished', 'interrupted'] as const;\n\nexport type AnimationState = (typeof animationStates)[number];\n\nexport type ItemHeight = number | 'auto';\n\nexport interface RenderItem<T> {\n (info: { item: T, index: number, interpolation: Animated.AnimatedInterpolation }): ReactElement | null;\n}\n\nexport interface CreateScrollAnimation {\n (aValue: Animated.AnimatedValue, toValue: number): Animated.CompositeAnimation;\n}\n\nexport interface CreateItemStyle {\n (itemInterpolation: Animated.AnimatedInterpolation, itemWidth: number): Animated.AnimatedProps<ViewProps['style']>;\n}\n\nexport interface GetCurrentIndex {\n (): number;\n}\n\nexport interface OnIndexChange {\n (itemIndex: number): void;\n}\n\nexport interface OnPositionChange {\n (position: number): void;\n}\n\nexport interface IndexController {\n getCurrentIndex: GetCurrentIndex;\n lastIndex: number;\n notifyAnimationState: (state: AnimationState) => void;\n notifyOffsetHasChanged: (offset: number) => void;\n}\n\nexport type PagingAnimationType = 'directional' | 'index';\n\nexport interface BasePagingAnimationConfig {\n animated?: boolean;\n}\n\nexport interface DirectionalPagingAnimationConfig extends BasePagingAnimationConfig {\n direction: PagingDirection;\n isOriginatedFromGesture?: boolean;\n}\n\nexport interface IndexPagingAnimationConfig extends BasePagingAnimationConfig {\n index: number;\n}\n\nexport type PagingAnimationConfig = DirectionalPagingAnimationConfig | IndexPagingAnimationConfig;\n\nexport interface StartPagingAnimation {\n (type: PagingAnimationType, config: PagingAnimationConfig): void;\n}\n\nexport type VisibleIndexRanges = Array<[number, number]>;\n\nexport interface StoreSubscription {\n (): void;\n}\n\nexport interface ItemVisibilityStore {\n dispatch: (ranges: VisibleIndexRanges) => void;\n subscribe: (listener: (ranges: VisibleIndexRanges) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n\nexport interface AutoplayController {\n pause: () => void;\n resume: () => void;\n}\n\nexport interface ScrollToOption {\n index: number;\n animated?: boolean;\n}\n\nexport interface CarouselInstance {\n /**\n * Get current visible item index.\n */\n getCurrentIndex: GetCurrentIndex;\n\n /**\n * Scroll to next visible item.\n */\n next: () => void;\n\n /**\n * Scroll to previous visible item.\n */\n prev: () => void;\n\n /**\n * Scroll to desired indexed item.\n * Invalid index is ignored.\n */\n scrollTo: (option: ScrollToOption) => void;\n}\n"],"mappings":"AAGA,MAAMA,UAAU,GAAG,CAAC,MAAD,EAAS,MAAT,EAAiB,MAAjB,CAAnB;AAIA,MAAMC,eAAe,GAAG,CAAC,SAAD,EAAY,UAAZ,EAAwB,aAAxB,CAAxB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RefObject } from 'react';
|
|
2
2
|
import type { ComponentProps } from '@fountain-ui/core';
|
|
3
|
-
import type { CarouselInstance, CreateItemStyle, CreateScrollAnimation, ItemHeight, RenderItem } from './types';
|
|
3
|
+
import type { CarouselInstance, CreateItemStyle, CreateScrollAnimation, ItemHeight, OnIndexChange, RenderItem } from './types';
|
|
4
4
|
export default interface CarouselProps<ItemT = any> extends ComponentProps<{
|
|
5
5
|
ref?: RefObject<CarouselInstance>;
|
|
6
6
|
/**
|
|
@@ -54,7 +54,7 @@ export default interface CarouselProps<ItemT = any> extends ComponentProps<{
|
|
|
54
54
|
/**
|
|
55
55
|
* Callback fired when an index is changed.
|
|
56
56
|
*/
|
|
57
|
-
onIndexChange?:
|
|
57
|
+
onIndexChange?: OnIndexChange;
|
|
58
58
|
/**
|
|
59
59
|
* Takes an item from data and renders it into the list.
|
|
60
60
|
*/
|
|
@@ -2,7 +2,9 @@ import type { IndexController } from '../types';
|
|
|
2
2
|
export interface UseIndexControllerParameters {
|
|
3
3
|
initialIndex: number;
|
|
4
4
|
itemWidth: number;
|
|
5
|
+
numberOfData: number;
|
|
5
6
|
numberOfOriginalData: number;
|
|
6
|
-
onIndexChange?: (
|
|
7
|
+
onIndexChange?: (itemIndex: number) => void;
|
|
8
|
+
onPositionChange?: (position: number) => void;
|
|
7
9
|
}
|
|
8
10
|
export default function useIndexController(params: UseIndexControllerParameters): IndexController;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type { ItemVisibilityStore } from '../types';
|
|
1
|
+
import type { ItemVisibilityStore, OnPositionChange } from '../types';
|
|
2
2
|
export interface Parameters {
|
|
3
3
|
initialIndex: number;
|
|
4
4
|
numberOfData: number;
|
|
5
5
|
windowSize: number;
|
|
6
6
|
}
|
|
7
|
-
export
|
|
8
|
-
(newIndex: number): void;
|
|
9
|
-
}
|
|
10
|
-
export default function useItemVisibilityStore(params: Parameters): [ItemVisibilityStore, OnIndexChange];
|
|
7
|
+
export default function useItemVisibilityStore(params: Parameters): [ItemVisibilityStore, OnPositionChange];
|
|
@@ -21,6 +21,12 @@ export interface CreateItemStyle {
|
|
|
21
21
|
export interface GetCurrentIndex {
|
|
22
22
|
(): number;
|
|
23
23
|
}
|
|
24
|
+
export interface OnIndexChange {
|
|
25
|
+
(itemIndex: number): void;
|
|
26
|
+
}
|
|
27
|
+
export interface OnPositionChange {
|
|
28
|
+
(position: number): void;
|
|
29
|
+
}
|
|
24
30
|
export interface IndexController {
|
|
25
31
|
getCurrentIndex: GetCurrentIndex;
|
|
26
32
|
lastIndex: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fountain-ui/lab",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.17",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Fountain-UI Team",
|
|
6
6
|
"description": "Incubator for Fountain-UI React components.",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "973591c61fab2561cea9f30d03e802a24817b5f8"
|
|
74
74
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, memo,
|
|
1
|
+
import React, { forwardRef, memo, useImperativeHandle, useMemo, useRef } from 'react';
|
|
2
2
|
import { Animated } from 'react-native';
|
|
3
3
|
import ViewabilityTrackerView from '../ViewabilityTrackerView';
|
|
4
4
|
import type CarouselProps from './CarouselProps';
|
|
@@ -25,7 +25,7 @@ const Carousel = forwardRef<CarouselInstance, CarouselProps>(function Carousel(p
|
|
|
25
25
|
itemHeight,
|
|
26
26
|
itemWidth,
|
|
27
27
|
loop = false,
|
|
28
|
-
onIndexChange
|
|
28
|
+
onIndexChange,
|
|
29
29
|
renderItem,
|
|
30
30
|
scrollEnabled = true,
|
|
31
31
|
style,
|
|
@@ -39,22 +39,19 @@ const Carousel = forwardRef<CarouselInstance, CarouselProps>(function Carousel(p
|
|
|
39
39
|
const translateX = useRef(new Animated.Value(0)).current;
|
|
40
40
|
const globalInterpolation = Animated.add(offsetX, translateX);
|
|
41
41
|
|
|
42
|
-
const [itemVisibilityStore,
|
|
42
|
+
const [itemVisibilityStore, onPositionChange] = useItemVisibilityStore({
|
|
43
43
|
initialIndex,
|
|
44
44
|
numberOfData: data.length,
|
|
45
45
|
windowSize,
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
const handleIndexChange = useCallback((newIndex: number) => {
|
|
49
|
-
onIndexChange(newIndex);
|
|
50
|
-
onIndexChangeProp?.(newIndex);
|
|
51
|
-
}, [onIndexChange, onIndexChangeProp]);
|
|
52
|
-
|
|
53
48
|
const indexController = useIndexController({
|
|
54
49
|
initialIndex,
|
|
55
50
|
itemWidth,
|
|
51
|
+
numberOfData: data.length,
|
|
56
52
|
numberOfOriginalData: originalData.length,
|
|
57
|
-
onIndexChange
|
|
53
|
+
onIndexChange,
|
|
54
|
+
onPositionChange,
|
|
58
55
|
});
|
|
59
56
|
|
|
60
57
|
const { getCurrentIndex } = indexController;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { RefObject } from 'react';
|
|
2
2
|
import type { ComponentProps } from '@fountain-ui/core';
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
CarouselInstance,
|
|
5
|
+
CreateItemStyle,
|
|
6
|
+
CreateScrollAnimation,
|
|
7
|
+
ItemHeight,
|
|
8
|
+
OnIndexChange,
|
|
9
|
+
RenderItem,
|
|
10
|
+
} from './types';
|
|
4
11
|
|
|
5
12
|
export default interface CarouselProps<ItemT = any> extends ComponentProps<{
|
|
6
13
|
ref?: RefObject<CarouselInstance>;
|
|
@@ -66,7 +73,7 @@ export default interface CarouselProps<ItemT = any> extends ComponentProps<{
|
|
|
66
73
|
/**
|
|
67
74
|
* Callback fired when an index is changed.
|
|
68
75
|
*/
|
|
69
|
-
onIndexChange?:
|
|
76
|
+
onIndexChange?: OnIndexChange;
|
|
70
77
|
|
|
71
78
|
/**
|
|
72
79
|
* Takes an item from data and renders it into the list.
|
|
@@ -32,7 +32,7 @@ export default function ItemView(props: ItemViewProps) {
|
|
|
32
32
|
|
|
33
33
|
const itemStyle = useMemo(
|
|
34
34
|
() => createItemStyle(interpolation, itemWidth),
|
|
35
|
-
[createItemStyle, interpolation],
|
|
35
|
+
[createItemStyle, interpolation, itemWidth],
|
|
36
36
|
);
|
|
37
37
|
|
|
38
38
|
useEffect(() => {
|
|
@@ -40,7 +40,7 @@ export default function ItemView(props: ItemViewProps) {
|
|
|
40
40
|
const nextVisible = ranges.some(([from, to]) => index >= from && index <= to);
|
|
41
41
|
setVisible(nextVisible);
|
|
42
42
|
});
|
|
43
|
-
}, [itemVisibilityStore]);
|
|
43
|
+
}, [index, itemVisibilityStore]);
|
|
44
44
|
|
|
45
45
|
return (
|
|
46
46
|
<Animated.View
|
|
@@ -1,36 +1,43 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { useImperativeState } from '@fountain-ui/core';
|
|
2
3
|
import { mod } from '@fountain-ui/utils';
|
|
3
4
|
import type { AnimationState, IndexController } from '../types';
|
|
4
5
|
|
|
5
6
|
export interface UseIndexControllerParameters {
|
|
6
7
|
initialIndex: number;
|
|
7
8
|
itemWidth: number;
|
|
9
|
+
numberOfData: number;
|
|
8
10
|
numberOfOriginalData: number;
|
|
9
|
-
onIndexChange?: (
|
|
11
|
+
onIndexChange?: (itemIndex: number) => void;
|
|
12
|
+
onPositionChange?: (position: number) => void;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
export default function useIndexController(params: UseIndexControllerParameters): IndexController {
|
|
13
16
|
const {
|
|
14
17
|
initialIndex,
|
|
15
18
|
itemWidth,
|
|
19
|
+
numberOfData,
|
|
16
20
|
numberOfOriginalData,
|
|
17
21
|
onIndexChange,
|
|
22
|
+
onPositionChange,
|
|
18
23
|
} = params;
|
|
19
24
|
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const getCurrentIndex = useCallback(() => currentIndexRef.current, []);
|
|
25
|
+
const currentIndex = useImperativeState(initialIndex);
|
|
26
|
+
const currentPosition = useImperativeState(initialIndex);
|
|
24
27
|
|
|
25
28
|
const notifyAnimationState = useCallback((state: AnimationState) => {
|
|
26
29
|
if (state === 'finished' || state === 'interrupted') {
|
|
27
|
-
if (
|
|
28
|
-
onIndexChange?.(
|
|
30
|
+
if (currentIndex.hasChanged()) {
|
|
31
|
+
onIndexChange?.(currentIndex.get());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (currentPosition.hasChanged()) {
|
|
35
|
+
onPositionChange?.(currentPosition.get());
|
|
29
36
|
}
|
|
30
37
|
}
|
|
31
38
|
}, [
|
|
32
|
-
getCurrentIndex,
|
|
33
39
|
onIndexChange,
|
|
40
|
+
onPositionChange,
|
|
34
41
|
]);
|
|
35
42
|
|
|
36
43
|
const notifyOffsetHasChanged = useCallback((offset: number) => {
|
|
@@ -38,15 +45,19 @@ export default function useIndexController(params: UseIndexControllerParameters)
|
|
|
38
45
|
|
|
39
46
|
// To prevent floating point problem, make sure index is integer type.
|
|
40
47
|
const nextIndex = Math.floor(mod((-roundedOffset / itemWidth), numberOfOriginalData));
|
|
48
|
+
currentIndex.set(nextIndex);
|
|
41
49
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
// To prevent floating point problem, make sure index is integer type.
|
|
51
|
+
const nextPosition = Math.floor(mod((-roundedOffset / itemWidth), numberOfData));
|
|
52
|
+
currentPosition.set(nextPosition);
|
|
53
|
+
}, [
|
|
54
|
+
itemWidth,
|
|
55
|
+
numberOfData,
|
|
56
|
+
numberOfOriginalData,
|
|
57
|
+
]);
|
|
47
58
|
|
|
48
59
|
return {
|
|
49
|
-
getCurrentIndex,
|
|
60
|
+
getCurrentIndex: currentIndex.get,
|
|
50
61
|
lastIndex: numberOfOriginalData - 1,
|
|
51
62
|
notifyAnimationState,
|
|
52
63
|
notifyOffsetHasChanged,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { mod } from '@fountain-ui/utils';
|
|
3
|
-
import type { ItemVisibilityStore, VisibleIndexRanges } from '../types';
|
|
3
|
+
import type { ItemVisibilityStore, OnPositionChange, VisibleIndexRanges } from '../types';
|
|
4
4
|
|
|
5
5
|
export interface Parameters {
|
|
6
6
|
initialIndex: number;
|
|
@@ -8,10 +8,6 @@ export interface Parameters {
|
|
|
8
8
|
windowSize: number;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export interface OnIndexChange {
|
|
12
|
-
(newIndex: number): void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
11
|
class SimpleItemVisibilityStore implements ItemVisibilityStore {
|
|
16
12
|
|
|
17
13
|
private store: VisibleIndexRanges;
|
|
@@ -82,7 +78,7 @@ function makeVisibleIndexRanges(numberOfData: number, windowSize: number, index:
|
|
|
82
78
|
];
|
|
83
79
|
}
|
|
84
80
|
|
|
85
|
-
export default function useItemVisibilityStore(params: Parameters): [ItemVisibilityStore,
|
|
81
|
+
export default function useItemVisibilityStore(params: Parameters): [ItemVisibilityStore, OnPositionChange] {
|
|
86
82
|
const {
|
|
87
83
|
initialIndex,
|
|
88
84
|
numberOfData,
|
|
@@ -95,8 +91,8 @@ export default function useItemVisibilityStore(params: Parameters): [ItemVisibil
|
|
|
95
91
|
|
|
96
92
|
const store = useRef(new SimpleItemVisibilityStore(initialRange)).current;
|
|
97
93
|
|
|
98
|
-
const
|
|
99
|
-
const newRanges = makeVisibleIndexRanges(numberOfData, windowSize,
|
|
94
|
+
const onPositionChange: OnPositionChange = useCallback((position) => {
|
|
95
|
+
const newRanges = makeVisibleIndexRanges(numberOfData, windowSize, position);
|
|
100
96
|
|
|
101
97
|
store.dispatch(newRanges);
|
|
102
98
|
}, [numberOfData, windowSize]);
|
|
@@ -107,5 +103,5 @@ export default function useItemVisibilityStore(params: Parameters): [ItemVisibil
|
|
|
107
103
|
};
|
|
108
104
|
}, []);
|
|
109
105
|
|
|
110
|
-
return [store,
|
|
106
|
+
return [store, onPositionChange];
|
|
111
107
|
};
|
package/src/Carousel/types.ts
CHANGED
|
@@ -27,6 +27,14 @@ export interface GetCurrentIndex {
|
|
|
27
27
|
(): number;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
export interface OnIndexChange {
|
|
31
|
+
(itemIndex: number): void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface OnPositionChange {
|
|
35
|
+
(position: number): void;
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
export interface IndexController {
|
|
31
39
|
getCurrentIndex: GetCurrentIndex;
|
|
32
40
|
lastIndex: number;
|