@fountain-ui/core 2.0.0-beta.23 → 2.0.0-beta.24

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.
Files changed (31) hide show
  1. package/build/commonjs/hooks/useCollapsibleAppBar.js +2 -4
  2. package/build/commonjs/hooks/useCollapsibleAppBar.js.map +1 -1
  3. package/build/commonjs/hooks/useSyncAnimatedValue.js +2 -1
  4. package/build/commonjs/hooks/useSyncAnimatedValue.js.map +1 -1
  5. package/build/commonjs/store/MockStore.js +1 -1
  6. package/build/commonjs/store/MockStore.js.map +1 -1
  7. package/build/commonjs/store/SimpleStore.js +7 -5
  8. package/build/commonjs/store/SimpleStore.js.map +1 -1
  9. package/build/commonjs/store/index.js.map +1 -1
  10. package/build/commonjs/store/types.js.map +1 -1
  11. package/build/module/hooks/useCollapsibleAppBar.js +3 -5
  12. package/build/module/hooks/useCollapsibleAppBar.js.map +1 -1
  13. package/build/module/hooks/useSyncAnimatedValue.js +2 -1
  14. package/build/module/hooks/useSyncAnimatedValue.js.map +1 -1
  15. package/build/module/store/MockStore.js +1 -1
  16. package/build/module/store/MockStore.js.map +1 -1
  17. package/build/module/store/SimpleStore.js +7 -5
  18. package/build/module/store/SimpleStore.js.map +1 -1
  19. package/build/module/store/index.js.map +1 -1
  20. package/build/module/store/types.js.map +1 -1
  21. package/build/typescript/store/MockStore.d.ts +2 -2
  22. package/build/typescript/store/SimpleStore.d.ts +2 -2
  23. package/build/typescript/store/index.d.ts +1 -1
  24. package/build/typescript/store/types.d.ts +2 -1
  25. package/package.json +2 -2
  26. package/src/hooks/useCollapsibleAppBar.ts +3 -3
  27. package/src/hooks/useSyncAnimatedValue.ts +2 -1
  28. package/src/store/MockStore.ts +2 -2
  29. package/src/store/SimpleStore.ts +8 -5
  30. package/src/store/index.ts +1 -1
  31. package/src/store/types.ts +3 -1
@@ -83,8 +83,7 @@ function useCollapsibleAppBar() {
83
83
  ]);
84
84
  const indexRef = (0, _react.useRef)(0);
85
85
  const offsetsRef = (0, _react.useRef)([]);
86
-
87
- const onScrollViewChanged = nextIndex => {
86
+ const onScrollViewChanged = (0, _react.useCallback)(nextIndex => {
88
87
  const prevIndex = indexRef.current;
89
88
 
90
89
  if (prevIndex === nextIndex) {
@@ -101,8 +100,7 @@ function useCollapsibleAppBar() {
101
100
  if (translateY.value < 0 && savedOffsetY < appBarHeight) {
102
101
  translateY.value = (0, _reactNativeReanimated.withTiming)(0, ANIMATION_CONFIG);
103
102
  }
104
- };
105
-
103
+ }, [appBarHeight]);
106
104
  const scrollHandler = (0, _reactNativeReanimated.useAnimatedScrollHandler)({
107
105
  onBeginDrag: () => {
108
106
  if (keyboardDismissMode === 'on-drag') {
@@ -1 +1 @@
1
- {"version":3,"names":["defaultOptions","keyboardDismissMode","ANIMATION_CONFIG","duration","SUPPORTS_DRAG_DETECTION","Platform","OS","useCollapsibleAppBar","userOptions","styles","useAppbarStyles","safeAreaInsets","useSafeAreaInsets","appBarHeight","onAppBarLayout","useHeight","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","useDerivedValue","translateY","useSharedValue","lastTranslateY","lastOffsetY","overlapped","elevationStyle","useElevationStyle","animatedStyle","useAnimatedStyle","transform","value","boxShadow","elevation","shadowColor","shadowOffset","shadowRadius","shadowOpacity","indexRef","useRef","offsetsRef","onScrollViewChanged","nextIndex","prevIndex","current","savedOffsetY","withTiming","scrollHandler","useAnimatedScrollHandler","onBeginDrag","runOnJS","Keyboard","dismiss","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","ty","maxTy","dy","Math","min","max","onEndDrag","onMomentumEnd","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useCollapsibleAppBar.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { Falsy, Keyboard, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport {\n runOnJS,\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { useHeight } from '../internal/hooks';\nimport useElevationStyle from './useElevationStyle';\nimport useAppbarStyles from './useAppbarStyles';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n keyboardDismissMode?: 'none' | 'on-drag';\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n scrollContentInsets: ContentInsets;\n}\n\nconst defaultOptions: Required<Options> = {\n keyboardDismissMode: 'none',\n};\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = { duration: 100 };\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\n\nexport default function useCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { keyboardDismissMode }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => -collapsibleToolbarHeight, [collapsibleToolbarHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n\n const elevationStyle = useElevationStyle(4);\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n if (Platform.OS === 'web') {\n return {\n transform,\n boxShadow: overlapped.value ? elevationStyle?.boxShadow : 0,\n };\n }\n if (Platform.OS === 'android') {\n return {\n transform,\n elevation: overlapped.value ? elevationStyle?.elevation : 0,\n };\n }\n if (Platform.OS === 'ios') {\n return {\n transform,\n shadowColor: elevationStyle?.shadowColor,\n shadowOffset: elevationStyle?.shadowOffset,\n shadowRadius: elevationStyle?.shadowRadius,\n shadowOpacity: overlapped.value ? elevationStyle?.shadowOpacity : 0,\n };\n }\n return {};\n }, [\n /**\n * FIXME: Consider add `elevationStyle` to dependencies.\n */\n ]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = (nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n };\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n if (keyboardDismissMode === 'on-drag') {\n runOnJS(Keyboard.dismiss)();\n }\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n if (offsetY > -maxTy) {\n if (ty === 0) {\n translateY.value = withTiming(Math.min(Math.max(-offsetY, maxTy), 0), ANIMATION_CONFIG);\n }\n } else {\n if (ty === maxTy) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n }\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, ANIMATION_CONFIG);\n },\n }, [keyboardDismissMode, appBarHeight]);\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n scrollContentInsets: { top: hasCollapsible ? appBarHeight : 0 },\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["defaultOptions","keyboardDismissMode","ANIMATION_CONFIG","duration","SUPPORTS_DRAG_DETECTION","Platform","OS","useCollapsibleAppBar","userOptions","styles","useAppbarStyles","safeAreaInsets","useSafeAreaInsets","appBarHeight","onAppBarLayout","useHeight","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","useDerivedValue","translateY","useSharedValue","lastTranslateY","lastOffsetY","overlapped","elevationStyle","useElevationStyle","animatedStyle","useAnimatedStyle","transform","value","boxShadow","elevation","shadowColor","shadowOffset","shadowRadius","shadowOpacity","indexRef","useRef","offsetsRef","onScrollViewChanged","useCallback","nextIndex","prevIndex","current","savedOffsetY","withTiming","scrollHandler","useAnimatedScrollHandler","onBeginDrag","runOnJS","Keyboard","dismiss","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","ty","maxTy","dy","Math","min","max","onEndDrag","onMomentumEnd","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useCollapsibleAppBar.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { Falsy, Keyboard, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport {\n runOnJS,\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { useHeight } from '../internal/hooks';\nimport useElevationStyle from './useElevationStyle';\nimport useAppbarStyles from './useAppbarStyles';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n keyboardDismissMode?: 'none' | 'on-drag';\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n scrollContentInsets: ContentInsets;\n}\n\nconst defaultOptions: Required<Options> = {\n keyboardDismissMode: 'none',\n};\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = { duration: 100 };\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\n\nexport default function useCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { keyboardDismissMode }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => -collapsibleToolbarHeight, [collapsibleToolbarHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n\n const elevationStyle = useElevationStyle(4);\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n if (Platform.OS === 'web') {\n return {\n transform,\n boxShadow: overlapped.value ? elevationStyle?.boxShadow : 0,\n };\n }\n if (Platform.OS === 'android') {\n return {\n transform,\n elevation: overlapped.value ? elevationStyle?.elevation : 0,\n };\n }\n if (Platform.OS === 'ios') {\n return {\n transform,\n shadowColor: elevationStyle?.shadowColor,\n shadowOffset: elevationStyle?.shadowOffset,\n shadowRadius: elevationStyle?.shadowRadius,\n shadowOpacity: overlapped.value ? elevationStyle?.shadowOpacity : 0,\n };\n }\n return {};\n }, [\n /**\n * FIXME: Consider add `elevationStyle` to dependencies.\n */\n ]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = useCallback((nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n }, [appBarHeight]);\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n if (keyboardDismissMode === 'on-drag') {\n runOnJS(Keyboard.dismiss)();\n }\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n if (offsetY > -maxTy) {\n if (ty === 0) {\n translateY.value = withTiming(Math.min(Math.max(-offsetY, maxTy), 0), ANIMATION_CONFIG);\n }\n } else {\n if (ty === maxTy) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n }\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, ANIMATION_CONFIG);\n },\n }, [keyboardDismissMode, appBarHeight]);\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n scrollContentInsets: { top: hasCollapsible ? appBarHeight : 0 },\n };\n};\n"],"mappings":";;;;;;;AAAA;;AACA;;AAEA;;AAQA;;AACA;;AACA;;AACA;;;;AA8BA,MAAMA,cAAiC,GAAG;EACtCC,mBAAmB,EAAE;AADiB,CAA1C;AAIA,MAAMC,gBAA4C,GAAG;EAAEC,QAAQ,EAAE;AAAZ,CAArD;AAEA,MAAMC,uBAAuB,GAAGC,qBAAA,CAASC,EAAT,KAAgB,KAAhD;;AAEe,SAASC,oBAAT,GAAwF;EAAA,IAA1DC,WAA0D,uEAAnCR,cAAmC;EACnG,MAAM;IAAEC;EAAF,IAA6C,EAC/C,GAAGD,cAD4C;IAE/C,GAAGQ;EAF4C,CAAnD;EAKA,MAAMC,MAAM,GAAG,IAAAC,wBAAA,GAAf;EAEA,MAAMC,cAAc,GAAG,IAAAC,6CAAA,GAAvB;EAEA,MAAM,CAACC,YAAD,EAAeC,cAAf,IAAiC,IAAAC,gBAAA,GAAvC;EACA,MAAM,CAACC,wBAAD,EAA2BC,0BAA3B,IAAyD,IAAAF,gBAAA,GAA/D;EAEA,MAAMG,aAAa,GAAG,IAAAC,sCAAA,EAAgB,MAAM,CAACH,wBAAvB,EAAiD,CAACA,wBAAD,CAAjD,CAAtB;EAEA,MAAMI,UAAU,GAAG,IAAAC,qCAAA,EAAuB,CAAvB,CAAnB;EACA,MAAMC,cAAc,GAAG,IAAAD,qCAAA,EAAuB,CAAvB,CAAvB;EACA,MAAME,WAAW,GAAG,IAAAF,qCAAA,EAAuB,CAAvB,CAApB;EACA,MAAMG,UAAU,GAAG,IAAAH,qCAAA,EAAwB,KAAxB,CAAnB;EAEA,MAAMI,cAAc,GAAG,IAAAC,0BAAA,EAAkB,CAAlB,CAAvB;EACA,MAAMC,aAAa,GAAG,IAAAC,uCAAA,EAAiB,MAAM;IACzC,MAAMC,SAAS,GAAG,CAAC;MAAET,UAAU,EAAEA,UAAU,CAACU;IAAzB,CAAD,CAAlB;;IAEA,IAAIzB,qBAAA,CAASC,EAAT,KAAgB,KAApB,EAA2B;MACvB,OAAO;QACHuB,SADG;QAEHE,SAAS,EAAEP,UAAU,CAACM,KAAX,GAAmBL,cAAnB,aAAmBA,cAAnB,uBAAmBA,cAAc,CAAEM,SAAnC,GAA+C;MAFvD,CAAP;IAIH;;IACD,IAAI1B,qBAAA,CAASC,EAAT,KAAgB,SAApB,EAA+B;MAC3B,OAAO;QACHuB,SADG;QAEHG,SAAS,EAAER,UAAU,CAACM,KAAX,GAAmBL,cAAnB,aAAmBA,cAAnB,uBAAmBA,cAAc,CAAEO,SAAnC,GAA+C;MAFvD,CAAP;IAIH;;IACD,IAAI3B,qBAAA,CAASC,EAAT,KAAgB,KAApB,EAA2B;MACvB,OAAO;QACHuB,SADG;QAEHI,WAAW,EAAER,cAAF,aAAEA,cAAF,uBAAEA,cAAc,CAAEQ,WAF1B;QAGHC,YAAY,EAAET,cAAF,aAAEA,cAAF,uBAAEA,cAAc,CAAES,YAH3B;QAIHC,YAAY,EAAEV,cAAF,aAAEA,cAAF,uBAAEA,cAAc,CAAEU,YAJ3B;QAKHC,aAAa,EAAEZ,UAAU,CAACM,KAAX,GAAmBL,cAAnB,aAAmBA,cAAnB,uBAAmBA,cAAc,CAAEW,aAAnC,GAAmD;MAL/D,CAAP;IAOH;;IACD,OAAO,EAAP;EACH,CAzBqB,EAyBnB;IACC;AACR;AACA;EAHO,CAzBmB,CAAtB;EA+BA,MAAMC,QAAQ,GAAG,IAAAC,aAAA,EAAe,CAAf,CAAjB;EACA,MAAMC,UAAU,GAAG,IAAAD,aAAA,EAAsB,EAAtB,CAAnB;EAEA,MAAME,mBAAmB,GAAG,IAAAC,kBAAA,EAAaC,SAAD,IAAuB;IAC3D,MAAMC,SAAS,GAAGN,QAAQ,CAACO,OAA3B;;IACA,IAAID,SAAS,KAAKD,SAAlB,EAA6B;MACzB;IACH;;IAEDH,UAAU,CAACK,OAAX,CAAmBD,SAAnB,IAAgCpB,WAAW,CAACO,KAA5C;IAEA,MAAMe,YAAY,GAAGN,UAAU,CAACK,OAAX,CAAmBF,SAAnB,KAAiC,CAAtD;IACAnB,WAAW,CAACO,KAAZ,GAAoBe,YAApB;IAEAR,QAAQ,CAACO,OAAT,GAAmBF,SAAnB,CAX2D,CAa3D;;IACAlB,UAAU,CAACM,KAAX,GAAmBe,YAAY,GAAG,CAAlC,CAd2D,CAgB3D;;IACA,IAAIzB,UAAU,CAACU,KAAX,GAAmB,CAAnB,IAAwBe,YAAY,GAAGhC,YAA3C,EAAyD;MACrDO,UAAU,CAACU,KAAX,GAAmB,IAAAgB,iCAAA,EAAW,CAAX,EAAc5C,gBAAd,CAAnB;IACH;EACJ,CApB2B,EAoBzB,CAACW,YAAD,CApByB,CAA5B;EAsBA,MAAMkC,aAAa,GAAG,IAAAC,+CAAA,EAAyB;IAC3CC,WAAW,EAAE,MAAM;MACf,IAAIhD,mBAAmB,KAAK,SAA5B,EAAuC;QACnC,IAAAiD,8BAAA,EAAQC,qBAAA,CAASC,OAAjB;MACH;;MACD9B,cAAc,CAACQ,KAAf,GAAuBV,UAAU,CAACU,KAAlC;IACH,CAN0C;IAO3CuB,eAAe,EAAE,MAAM;MACnB/B,cAAc,CAACQ,KAAf,GAAuBV,UAAU,CAACU,KAAlC;IACH,CAT0C;IAU3CwB,QAAQ,EAAGC,KAAD,IAAW;MACjB,MAAMC,OAAO,GAAGD,KAAK,CAACE,aAAN,CAAoBC,CAApC;MAEA,MAAMC,EAAE,GAAGvC,UAAU,CAACU,KAAtB;MACA,MAAM8B,KAAK,GAAG1C,aAAa,CAACY,KAA5B;;MAEA,IAAI1B,uBAAJ,EAA6B;QACzB,MAAMyD,EAAE,GAAGL,OAAO,GAAGjC,WAAW,CAACO,KAAjC;QAEAV,UAAU,CAACU,KAAX,GAAmB0B,OAAO,IAAI,CAAX,GAAe,CAAf,GAAmBM,IAAI,CAACC,GAAL,CAASD,IAAI,CAACE,GAAL,CAAS1C,cAAc,CAACQ,KAAf,GAAuB+B,EAAhC,EAAoCD,KAApC,CAAT,EAAqD,CAArD,CAAtC;QAEApC,UAAU,CAACM,KAAX,GAAmB0B,OAAO,GAAGpC,UAAU,CAACU,KAArB,GAA6B,CAAhD;MACH,CAND,MAMO;QACH,IAAI0B,OAAO,GAAG,CAACI,KAAf,EAAsB;UAClB,IAAID,EAAE,KAAK,CAAX,EAAc;YACVvC,UAAU,CAACU,KAAX,GAAmB,IAAAgB,iCAAA,EAAWgB,IAAI,CAACC,GAAL,CAASD,IAAI,CAACE,GAAL,CAAS,CAACR,OAAV,EAAmBI,KAAnB,CAAT,EAAoC,CAApC,CAAX,EAAmD1D,gBAAnD,CAAnB;UACH;QACJ,CAJD,MAIO;UACH,IAAIyD,EAAE,KAAKC,KAAX,EAAkB;YACdxC,UAAU,CAACU,KAAX,GAAmB,IAAAgB,iCAAA,EAAW,CAAX,EAAc5C,gBAAd,CAAnB;UACH;QACJ;;QAEDsB,UAAU,CAACM,KAAX,GAAmB0B,OAAO,GAAG,CAA7B;QAEAjC,WAAW,CAACO,KAAZ,GAAoB0B,OAApB;MACH;IACJ,CArC0C;IAsC3CS,SAAS,EAAGV,KAAD,IAAW;MAClBhC,WAAW,CAACO,KAAZ,GAAoByB,KAAK,CAACE,aAAN,CAAoBC,CAAxC;IACH,CAxC0C;IAyC3CQ,aAAa,EAAGX,KAAD,IAAW;MACtB,MAAMC,OAAO,GAAGD,KAAK,CAACE,aAAN,CAAoBC,CAApC;MAEAnC,WAAW,CAACO,KAAZ,GAAoB0B,OAApB;MAEA,MAAMG,EAAE,GAAGvC,UAAU,CAACU,KAAtB;MACA,MAAM8B,KAAK,GAAG1C,aAAa,CAACY,KAA5B,CANsB,CAQtB;;MACA,IAAI6B,EAAE,IAAIC,KAAN,IAAeD,EAAE,IAAI,CAAzB,EAA4B;QACxB;MACH;;MAED,MAAMQ,SAAS,GAAGP,KAAK,GAAG,GAA1B;MAEA,MAAMQ,cAAc,GAAIT,EAAE,GAAGQ,SAAL,IAAkBX,OAAO,GAAG3C,YAA7B,GAA6C,CAA7C,GAAiD+C,KAAxE;MAEApC,UAAU,CAACM,KAAX,GAAmB0B,OAAO,GAAGY,cAAV,GAA2B,CAA9C;MAEAhD,UAAU,CAACU,KAAX,GAAmB,IAAAgB,iCAAA,EAAWsB,cAAX,EAA2BlE,gBAA3B,CAAnB;IACH;EA7D0C,CAAzB,EA8DnB,CAACD,mBAAD,EAAsBY,YAAtB,CA9DmB,CAAtB;EAgEA,MAAMwD,cAAc,GAAGrD,wBAAwB,GAAG,CAAlD;EAEA,MAAMsD,WAAW,GAAG,CAChB3C,aADgB,EAEhB;IAAE4C,UAAU,EAAE5D,cAAc,CAAC6D;EAA7B,CAFgB,EAGhBH,cAAc,GAAG5D,MAAM,CAACgE,QAAV,GAAqBC,SAHnB,CAApB;EAMA,OAAO;IACHJ,WADG;IAEHxD,cAFG;IAGHG,0BAHG;IAIHqC,QAAQ,EAAEP,aAJP;IAKHP,mBALG;IAMHmC,mBAAmB,EAAE;MAAEH,GAAG,EAAEH,cAAc,GAAGxD,YAAH,GAAkB;IAAvC;EANlB,CAAP;AAQH;;AAAA"}
@@ -11,9 +11,10 @@ var _reactNative = require("react-native");
11
11
 
12
12
  function useSyncAnimatedValue(config) {
13
13
  const {
14
- initialValue,
14
+ initialValue: maybeInitialValue,
15
15
  shouldSyncAlways = false
16
16
  } = config;
17
+ const initialValue = maybeInitialValue ?? 0;
17
18
  const animatedValue = (0, _react.useRef)(new _reactNative.Animated.Value(initialValue)).current;
18
19
  const indexRef = (0, _react.useRef)(initialValue);
19
20
  (0, _react.useEffect)(() => {
@@ -1 +1 @@
1
- {"version":3,"names":["useSyncAnimatedValue","config","initialValue","shouldSyncAlways","animatedValue","useRef","Animated","Value","current","indexRef","useEffect","maybeId","addListener","newValue","value","undefined","removeListener","getCurrentValue"],"sources":["useSyncAnimatedValue.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport type { SyncAnimatedValue } from '../types';\n\nexport interface SyncAnimatedValueConfig {\n initialValue: number;\n shouldSyncAlways?: boolean;\n}\n\nexport default function useSyncAnimatedValue(config: SyncAnimatedValueConfig): SyncAnimatedValue {\n const {\n initialValue,\n shouldSyncAlways = false,\n } = config;\n\n const animatedValue = useRef(new Animated.Value(initialValue)).current;\n\n const indexRef = useRef<number>(initialValue);\n\n useEffect(() => {\n const maybeId = shouldSyncAlways ? animatedValue.addListener((newValue) => {\n indexRef.current = newValue.value;\n }) : undefined;\n\n return () => {\n if (maybeId != null) {\n animatedValue.removeListener(maybeId);\n }\n };\n }, [shouldSyncAlways]);\n\n return {\n animatedValue,\n initialValue,\n getCurrentValue: () => indexRef.current,\n };\n};\n"],"mappings":";;;;;;;AAAA;;AACA;;AAQe,SAASA,oBAAT,CAA8BC,MAA9B,EAAkF;EAC7F,MAAM;IACFC,YADE;IAEFC,gBAAgB,GAAG;EAFjB,IAGFF,MAHJ;EAKA,MAAMG,aAAa,GAAG,IAAAC,aAAA,EAAO,IAAIC,qBAAA,CAASC,KAAb,CAAmBL,YAAnB,CAAP,EAAyCM,OAA/D;EAEA,MAAMC,QAAQ,GAAG,IAAAJ,aAAA,EAAeH,YAAf,CAAjB;EAEA,IAAAQ,gBAAA,EAAU,MAAM;IACZ,MAAMC,OAAO,GAAGR,gBAAgB,GAAGC,aAAa,CAACQ,WAAd,CAA2BC,QAAD,IAAc;MACvEJ,QAAQ,CAACD,OAAT,GAAmBK,QAAQ,CAACC,KAA5B;IACH,CAFkC,CAAH,GAE3BC,SAFL;IAIA,OAAO,MAAM;MACT,IAAIJ,OAAO,IAAI,IAAf,EAAqB;QACjBP,aAAa,CAACY,cAAd,CAA6BL,OAA7B;MACH;IACJ,CAJD;EAKH,CAVD,EAUG,CAACR,gBAAD,CAVH;EAYA,OAAO;IACHC,aADG;IAEHF,YAFG;IAGHe,eAAe,EAAE,MAAMR,QAAQ,CAACD;EAH7B,CAAP;AAKH;;AAAA"}
1
+ {"version":3,"names":["useSyncAnimatedValue","config","initialValue","maybeInitialValue","shouldSyncAlways","animatedValue","useRef","Animated","Value","current","indexRef","useEffect","maybeId","addListener","newValue","value","undefined","removeListener","getCurrentValue"],"sources":["useSyncAnimatedValue.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport type { SyncAnimatedValue } from '../types';\n\nexport interface SyncAnimatedValueConfig {\n initialValue: number;\n shouldSyncAlways?: boolean;\n}\n\nexport default function useSyncAnimatedValue(config: SyncAnimatedValueConfig): SyncAnimatedValue {\n const {\n initialValue: maybeInitialValue,\n shouldSyncAlways = false,\n } = config;\n\n const initialValue = maybeInitialValue ?? 0;\n const animatedValue = useRef(new Animated.Value(initialValue)).current;\n\n const indexRef = useRef<number>(initialValue);\n\n useEffect(() => {\n const maybeId = shouldSyncAlways ? animatedValue.addListener((newValue) => {\n indexRef.current = newValue.value;\n }) : undefined;\n\n return () => {\n if (maybeId != null) {\n animatedValue.removeListener(maybeId);\n }\n };\n }, [shouldSyncAlways]);\n\n return {\n animatedValue,\n initialValue,\n getCurrentValue: () => indexRef.current,\n };\n};\n"],"mappings":";;;;;;;AAAA;;AACA;;AAQe,SAASA,oBAAT,CAA8BC,MAA9B,EAAkF;EAC7F,MAAM;IACFC,YAAY,EAAEC,iBADZ;IAEFC,gBAAgB,GAAG;EAFjB,IAGFH,MAHJ;EAKA,MAAMC,YAAY,GAAGC,iBAAiB,IAAI,CAA1C;EACA,MAAME,aAAa,GAAG,IAAAC,aAAA,EAAO,IAAIC,qBAAA,CAASC,KAAb,CAAmBN,YAAnB,CAAP,EAAyCO,OAA/D;EAEA,MAAMC,QAAQ,GAAG,IAAAJ,aAAA,EAAeJ,YAAf,CAAjB;EAEA,IAAAS,gBAAA,EAAU,MAAM;IACZ,MAAMC,OAAO,GAAGR,gBAAgB,GAAGC,aAAa,CAACQ,WAAd,CAA2BC,QAAD,IAAc;MACvEJ,QAAQ,CAACD,OAAT,GAAmBK,QAAQ,CAACC,KAA5B;IACH,CAFkC,CAAH,GAE3BC,SAFL;IAIA,OAAO,MAAM;MACT,IAAIJ,OAAO,IAAI,IAAf,EAAqB;QACjBP,aAAa,CAACY,cAAd,CAA6BL,OAA7B;MACH;IACJ,CAJD;EAKH,CAVD,EAUG,CAACR,gBAAD,CAVH;EAYA,OAAO;IACHC,aADG;IAEHH,YAFG;IAGHgB,eAAe,EAAE,MAAMR,QAAQ,CAACD;EAH7B,CAAP;AAKH;;AAAA"}
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
 
8
8
  class MockStore {
9
- dispatch(state) {// do nothing
9
+ dispatch(action) {// do nothing
10
10
  }
11
11
 
12
12
  getState() {
@@ -1 +1 @@
1
- {"version":3,"names":["MockStore","dispatch","state","getState","Error","removeAllListeners","subscribe","listener"],"sources":["MockStore.ts"],"sourcesContent":["import { MonoStore, StoreSubscription } from './types';\n\nexport default class MockStore<S> implements MonoStore<S> {\n\n dispatch(state: S): void {\n // do nothing\n }\n\n getState(): S {\n throw new Error('stub!');\n }\n\n removeAllListeners(): void {\n // do nothing\n }\n\n subscribe(listener: (state: S) => void): StoreSubscription {\n return () => void 0;\n }\n\n};\n"],"mappings":";;;;;;;AAEe,MAAMA,SAAN,CAA2C;EAEtDC,QAAQ,CAACC,KAAD,EAAiB,CACrB;EACH;;EAEDC,QAAQ,GAAM;IACV,MAAM,IAAIC,KAAJ,CAAU,OAAV,CAAN;EACH;;EAEDC,kBAAkB,GAAS,CACvB;EACH;;EAEDC,SAAS,CAACC,QAAD,EAAkD;IACvD,OAAO,MAAM,KAAK,CAAlB;EACH;;AAhBqD;;;AAkBzD"}
1
+ {"version":3,"names":["MockStore","dispatch","action","getState","Error","removeAllListeners","subscribe","listener"],"sources":["MockStore.ts"],"sourcesContent":["import { MonoStore, StoreSubscription, DispatchAction } from './types';\n\nexport default class MockStore<S> implements MonoStore<S> {\n\n dispatch(action: DispatchAction<S>): void {\n // do nothing\n }\n\n getState(): S {\n throw new Error('stub!');\n }\n\n removeAllListeners(): void {\n // do nothing\n }\n\n subscribe(listener: (state: S) => void): StoreSubscription {\n return () => void 0;\n }\n\n};\n"],"mappings":";;;;;;;AAEe,MAAMA,SAAN,CAA2C;EAEtDC,QAAQ,CAACC,MAAD,EAAkC,CACtC;EACH;;EAEDC,QAAQ,GAAM;IACV,MAAM,IAAIC,KAAJ,CAAU,OAAV,CAAN;EACH;;EAEDC,kBAAkB,GAAS,CACvB;EACH;;EAEDC,SAAS,CAACC,QAAD,EAAkD;IACvD,OAAO,MAAM,KAAK,CAAlB;EACH;;AAhBqD;;;AAkBzD"}
@@ -20,17 +20,19 @@ class SimpleStore {
20
20
  this.state = initialState;
21
21
  }
22
22
 
23
- dispatch(state) {
24
- // Do not dispatch if state ref is equal
25
- if (refEqual(this.state, state)) {
23
+ dispatch(action) {
24
+ // @ts-ignore
25
+ const nextState = typeof action === 'function' ? action(this.state) : action; // Do not dispatch if state ref is equal
26
+
27
+ if (refEqual(this.state, nextState)) {
26
28
  return;
27
29
  }
28
30
 
29
- this.state = state;
31
+ this.state = nextState;
30
32
 
31
33
  for (const id in this.listeners) {
32
34
  const listener = this.listeners[id];
33
- listener === null || listener === void 0 ? void 0 : listener(state);
35
+ listener === null || listener === void 0 ? void 0 : listener(nextState);
34
36
  }
35
37
  }
36
38
 
@@ -1 +1 @@
1
- {"version":3,"names":["refEqual","a","b","SimpleStore","constructor","initialState","state","dispatch","id","listeners","listener","getState","subscribe","push","index","indexOf","splice","removeAllListeners","length"],"sources":["SimpleStore.ts"],"sourcesContent":["import { MonoStore, StoreSubscription } from './types';\n\nfunction refEqual(a: any, b: any): boolean {\n return a === b;\n}\n\nexport default class SimpleStore<S> implements MonoStore<S> {\n\n private state: S;\n\n private listeners: Array<(state: S) => void> = [];\n\n constructor(initialState: S) {\n this.state = initialState;\n }\n\n dispatch(state: S): void {\n // Do not dispatch if state ref is equal\n if (refEqual(this.state, state)) {\n return;\n }\n\n this.state = state;\n for (const id in this.listeners) {\n const listener = this.listeners[id];\n listener?.(state);\n }\n }\n\n getState(): S {\n return this.state;\n }\n\n subscribe(listener: (state: S) => void): StoreSubscription {\n this.listeners.push(listener);\n\n return () => {\n const index = this.listeners.indexOf(listener);\n this.listeners.splice(index, 1);\n };\n }\n\n removeAllListeners(): void {\n this.listeners.splice(0, this.listeners.length);\n }\n\n};\n"],"mappings":";;;;;;;;;AAEA,SAASA,QAAT,CAAkBC,CAAlB,EAA0BC,CAA1B,EAA2C;EACvC,OAAOD,CAAC,KAAKC,CAAb;AACH;;AAEc,MAAMC,WAAN,CAA6C;EAMxDC,WAAW,CAACC,YAAD,EAAkB;IAAA;;IAAA,mCAFkB,EAElB;;IACzB,KAAKC,KAAL,GAAaD,YAAb;EACH;;EAEDE,QAAQ,CAACD,KAAD,EAAiB;IACrB;IACA,IAAIN,QAAQ,CAAC,KAAKM,KAAN,EAAaA,KAAb,CAAZ,EAAiC;MAC7B;IACH;;IAED,KAAKA,KAAL,GAAaA,KAAb;;IACA,KAAK,MAAME,EAAX,IAAiB,KAAKC,SAAtB,EAAiC;MAC7B,MAAMC,QAAQ,GAAG,KAAKD,SAAL,CAAeD,EAAf,CAAjB;MACAE,QAAQ,SAAR,IAAAA,QAAQ,WAAR,YAAAA,QAAQ,CAAGJ,KAAH,CAAR;IACH;EACJ;;EAEDK,QAAQ,GAAM;IACV,OAAO,KAAKL,KAAZ;EACH;;EAEDM,SAAS,CAACF,QAAD,EAAkD;IACvD,KAAKD,SAAL,CAAeI,IAAf,CAAoBH,QAApB;IAEA,OAAO,MAAM;MACT,MAAMI,KAAK,GAAG,KAAKL,SAAL,CAAeM,OAAf,CAAuBL,QAAvB,CAAd;MACA,KAAKD,SAAL,CAAeO,MAAf,CAAsBF,KAAtB,EAA6B,CAA7B;IACH,CAHD;EAIH;;EAEDG,kBAAkB,GAAS;IACvB,KAAKR,SAAL,CAAeO,MAAf,CAAsB,CAAtB,EAAyB,KAAKP,SAAL,CAAeS,MAAxC;EACH;;AAtCuD;;;AAwC3D"}
1
+ {"version":3,"names":["refEqual","a","b","SimpleStore","constructor","initialState","state","dispatch","action","nextState","id","listeners","listener","getState","subscribe","push","index","indexOf","splice","removeAllListeners","length"],"sources":["SimpleStore.ts"],"sourcesContent":["import type { DispatchAction, MonoStore, StoreSubscription } from './types';\n\nfunction refEqual(a: any, b: any): boolean {\n return a === b;\n}\n\nexport default class SimpleStore<S> implements MonoStore<S> {\n\n private state: S;\n\n private listeners: Array<(state: S) => void> = [];\n\n constructor(initialState: S) {\n this.state = initialState;\n }\n\n dispatch(action: DispatchAction<S>): void {\n // @ts-ignore\n const nextState = typeof action === 'function' ? action(this.state) : action;\n\n // Do not dispatch if state ref is equal\n if (refEqual(this.state, nextState)) {\n return;\n }\n\n this.state = nextState;\n for (const id in this.listeners) {\n const listener = this.listeners[id];\n listener?.(nextState);\n }\n }\n\n getState(): S {\n return this.state;\n }\n\n subscribe(listener: (state: S) => void): StoreSubscription {\n this.listeners.push(listener);\n\n return () => {\n const index = this.listeners.indexOf(listener);\n this.listeners.splice(index, 1);\n };\n }\n\n removeAllListeners(): void {\n this.listeners.splice(0, this.listeners.length);\n }\n\n};\n"],"mappings":";;;;;;;;;AAEA,SAASA,QAAT,CAAkBC,CAAlB,EAA0BC,CAA1B,EAA2C;EACvC,OAAOD,CAAC,KAAKC,CAAb;AACH;;AAEc,MAAMC,WAAN,CAA6C;EAMxDC,WAAW,CAACC,YAAD,EAAkB;IAAA;;IAAA,mCAFkB,EAElB;;IACzB,KAAKC,KAAL,GAAaD,YAAb;EACH;;EAEDE,QAAQ,CAACC,MAAD,EAAkC;IACtC;IACA,MAAMC,SAAS,GAAG,OAAOD,MAAP,KAAkB,UAAlB,GAA+BA,MAAM,CAAC,KAAKF,KAAN,CAArC,GAAoDE,MAAtE,CAFsC,CAItC;;IACA,IAAIR,QAAQ,CAAC,KAAKM,KAAN,EAAaG,SAAb,CAAZ,EAAqC;MACjC;IACH;;IAED,KAAKH,KAAL,GAAaG,SAAb;;IACA,KAAK,MAAMC,EAAX,IAAiB,KAAKC,SAAtB,EAAiC;MAC7B,MAAMC,QAAQ,GAAG,KAAKD,SAAL,CAAeD,EAAf,CAAjB;MACAE,QAAQ,SAAR,IAAAA,QAAQ,WAAR,YAAAA,QAAQ,CAAGH,SAAH,CAAR;IACH;EACJ;;EAEDI,QAAQ,GAAM;IACV,OAAO,KAAKP,KAAZ;EACH;;EAEDQ,SAAS,CAACF,QAAD,EAAkD;IACvD,KAAKD,SAAL,CAAeI,IAAf,CAAoBH,QAApB;IAEA,OAAO,MAAM;MACT,MAAMI,KAAK,GAAG,KAAKL,SAAL,CAAeM,OAAf,CAAuBL,QAAvB,CAAd;MACA,KAAKD,SAAL,CAAeO,MAAf,CAAsBF,KAAtB,EAA6B,CAA7B;IACH,CAHD;EAIH;;EAEDG,kBAAkB,GAAS;IACvB,KAAKR,SAAL,CAAeO,MAAf,CAAsB,CAAtB,EAAyB,KAAKP,SAAL,CAAeS,MAAxC;EACH;;AAzCuD;;;AA2C3D"}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export { default as SimpleStore } from './SimpleStore';\nexport { default as MockStore } from './MockStore';\nexport type { MonoStore } from './types';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;;AACA"}
1
+ {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export { default as SimpleStore } from './SimpleStore';\nexport { default as MockStore } from './MockStore';\nexport type { MonoStore, DispatchAction } from './types';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;;AACA"}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["export interface StoreSubscription {\n (): void;\n}\n\nexport interface MonoStore<S> {\n dispatch: (state: S) => void;\n getState: () => S;\n subscribe: (listener: (state: S) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["export interface StoreSubscription {\n (): void;\n}\n\nexport type DispatchAction<State> = State | ((prevState: State) => State);\n\nexport interface MonoStore<S> {\n dispatch: (action: DispatchAction<S>) => void;\n getState: () => S;\n subscribe: (listener: (state: S) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n"],"mappings":""}
@@ -1,4 +1,4 @@
1
- import { useRef } from 'react';
1
+ import { useCallback, useRef } from 'react';
2
2
  import { Keyboard, Platform } from 'react-native';
3
3
  import { runOnJS, useAnimatedScrollHandler, useAnimatedStyle, useDerivedValue, useSharedValue, withTiming } from 'react-native-reanimated';
4
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
@@ -66,8 +66,7 @@ export default function useCollapsibleAppBar() {
66
66
  ]);
67
67
  const indexRef = useRef(0);
68
68
  const offsetsRef = useRef([]);
69
-
70
- const onScrollViewChanged = nextIndex => {
69
+ const onScrollViewChanged = useCallback(nextIndex => {
71
70
  const prevIndex = indexRef.current;
72
71
 
73
72
  if (prevIndex === nextIndex) {
@@ -84,8 +83,7 @@ export default function useCollapsibleAppBar() {
84
83
  if (translateY.value < 0 && savedOffsetY < appBarHeight) {
85
84
  translateY.value = withTiming(0, ANIMATION_CONFIG);
86
85
  }
87
- };
88
-
86
+ }, [appBarHeight]);
89
87
  const scrollHandler = useAnimatedScrollHandler({
90
88
  onBeginDrag: () => {
91
89
  if (keyboardDismissMode === 'on-drag') {
@@ -1 +1 @@
1
- {"version":3,"names":["useRef","Keyboard","Platform","runOnJS","useAnimatedScrollHandler","useAnimatedStyle","useDerivedValue","useSharedValue","withTiming","useSafeAreaInsets","useHeight","useElevationStyle","useAppbarStyles","defaultOptions","keyboardDismissMode","ANIMATION_CONFIG","duration","SUPPORTS_DRAG_DETECTION","OS","useCollapsibleAppBar","userOptions","styles","safeAreaInsets","appBarHeight","onAppBarLayout","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","translateY","lastTranslateY","lastOffsetY","overlapped","elevationStyle","animatedStyle","transform","value","boxShadow","elevation","shadowColor","shadowOffset","shadowRadius","shadowOpacity","indexRef","offsetsRef","onScrollViewChanged","nextIndex","prevIndex","current","savedOffsetY","scrollHandler","onBeginDrag","dismiss","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","ty","maxTy","dy","Math","min","max","onEndDrag","onMomentumEnd","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useCollapsibleAppBar.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { Falsy, Keyboard, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport {\n runOnJS,\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { useHeight } from '../internal/hooks';\nimport useElevationStyle from './useElevationStyle';\nimport useAppbarStyles from './useAppbarStyles';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n keyboardDismissMode?: 'none' | 'on-drag';\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n scrollContentInsets: ContentInsets;\n}\n\nconst defaultOptions: Required<Options> = {\n keyboardDismissMode: 'none',\n};\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = { duration: 100 };\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\n\nexport default function useCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { keyboardDismissMode }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => -collapsibleToolbarHeight, [collapsibleToolbarHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n\n const elevationStyle = useElevationStyle(4);\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n if (Platform.OS === 'web') {\n return {\n transform,\n boxShadow: overlapped.value ? elevationStyle?.boxShadow : 0,\n };\n }\n if (Platform.OS === 'android') {\n return {\n transform,\n elevation: overlapped.value ? elevationStyle?.elevation : 0,\n };\n }\n if (Platform.OS === 'ios') {\n return {\n transform,\n shadowColor: elevationStyle?.shadowColor,\n shadowOffset: elevationStyle?.shadowOffset,\n shadowRadius: elevationStyle?.shadowRadius,\n shadowOpacity: overlapped.value ? elevationStyle?.shadowOpacity : 0,\n };\n }\n return {};\n }, [\n /**\n * FIXME: Consider add `elevationStyle` to dependencies.\n */\n ]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = (nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n };\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n if (keyboardDismissMode === 'on-drag') {\n runOnJS(Keyboard.dismiss)();\n }\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n if (offsetY > -maxTy) {\n if (ty === 0) {\n translateY.value = withTiming(Math.min(Math.max(-offsetY, maxTy), 0), ANIMATION_CONFIG);\n }\n } else {\n if (ty === maxTy) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n }\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, ANIMATION_CONFIG);\n },\n }, [keyboardDismissMode, appBarHeight]);\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n scrollContentInsets: { top: hasCollapsible ? appBarHeight : 0 },\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["useCallback","useRef","Keyboard","Platform","runOnJS","useAnimatedScrollHandler","useAnimatedStyle","useDerivedValue","useSharedValue","withTiming","useSafeAreaInsets","useHeight","useElevationStyle","useAppbarStyles","defaultOptions","keyboardDismissMode","ANIMATION_CONFIG","duration","SUPPORTS_DRAG_DETECTION","OS","useCollapsibleAppBar","userOptions","styles","safeAreaInsets","appBarHeight","onAppBarLayout","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","translateY","lastTranslateY","lastOffsetY","overlapped","elevationStyle","animatedStyle","transform","value","boxShadow","elevation","shadowColor","shadowOffset","shadowRadius","shadowOpacity","indexRef","offsetsRef","onScrollViewChanged","nextIndex","prevIndex","current","savedOffsetY","scrollHandler","onBeginDrag","dismiss","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","ty","maxTy","dy","Math","min","max","onEndDrag","onMomentumEnd","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useCollapsibleAppBar.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { Falsy, Keyboard, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport {\n runOnJS,\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { useHeight } from '../internal/hooks';\nimport useElevationStyle from './useElevationStyle';\nimport useAppbarStyles from './useAppbarStyles';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n keyboardDismissMode?: 'none' | 'on-drag';\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n scrollContentInsets: ContentInsets;\n}\n\nconst defaultOptions: Required<Options> = {\n keyboardDismissMode: 'none',\n};\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = { duration: 100 };\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\n\nexport default function useCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { keyboardDismissMode }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => -collapsibleToolbarHeight, [collapsibleToolbarHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n\n const elevationStyle = useElevationStyle(4);\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n if (Platform.OS === 'web') {\n return {\n transform,\n boxShadow: overlapped.value ? elevationStyle?.boxShadow : 0,\n };\n }\n if (Platform.OS === 'android') {\n return {\n transform,\n elevation: overlapped.value ? elevationStyle?.elevation : 0,\n };\n }\n if (Platform.OS === 'ios') {\n return {\n transform,\n shadowColor: elevationStyle?.shadowColor,\n shadowOffset: elevationStyle?.shadowOffset,\n shadowRadius: elevationStyle?.shadowRadius,\n shadowOpacity: overlapped.value ? elevationStyle?.shadowOpacity : 0,\n };\n }\n return {};\n }, [\n /**\n * FIXME: Consider add `elevationStyle` to dependencies.\n */\n ]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = useCallback((nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n }, [appBarHeight]);\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n if (keyboardDismissMode === 'on-drag') {\n runOnJS(Keyboard.dismiss)();\n }\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n if (offsetY > -maxTy) {\n if (ty === 0) {\n translateY.value = withTiming(Math.min(Math.max(-offsetY, maxTy), 0), ANIMATION_CONFIG);\n }\n } else {\n if (ty === maxTy) {\n translateY.value = withTiming(0, ANIMATION_CONFIG);\n }\n }\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, ANIMATION_CONFIG);\n },\n }, [keyboardDismissMode, appBarHeight]);\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n scrollContentInsets: { top: hasCollapsible ? appBarHeight : 0 },\n };\n};\n"],"mappings":"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"}
@@ -2,9 +2,10 @@ import { useEffect, useRef } from 'react';
2
2
  import { Animated } from 'react-native';
3
3
  export default function useSyncAnimatedValue(config) {
4
4
  const {
5
- initialValue,
5
+ initialValue: maybeInitialValue,
6
6
  shouldSyncAlways = false
7
7
  } = config;
8
+ const initialValue = maybeInitialValue ?? 0;
8
9
  const animatedValue = useRef(new Animated.Value(initialValue)).current;
9
10
  const indexRef = useRef(initialValue);
10
11
  useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"names":["useEffect","useRef","Animated","useSyncAnimatedValue","config","initialValue","shouldSyncAlways","animatedValue","Value","current","indexRef","maybeId","addListener","newValue","value","undefined","removeListener","getCurrentValue"],"sources":["useSyncAnimatedValue.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport type { SyncAnimatedValue } from '../types';\n\nexport interface SyncAnimatedValueConfig {\n initialValue: number;\n shouldSyncAlways?: boolean;\n}\n\nexport default function useSyncAnimatedValue(config: SyncAnimatedValueConfig): SyncAnimatedValue {\n const {\n initialValue,\n shouldSyncAlways = false,\n } = config;\n\n const animatedValue = useRef(new Animated.Value(initialValue)).current;\n\n const indexRef = useRef<number>(initialValue);\n\n useEffect(() => {\n const maybeId = shouldSyncAlways ? animatedValue.addListener((newValue) => {\n indexRef.current = newValue.value;\n }) : undefined;\n\n return () => {\n if (maybeId != null) {\n animatedValue.removeListener(maybeId);\n }\n };\n }, [shouldSyncAlways]);\n\n return {\n animatedValue,\n initialValue,\n getCurrentValue: () => indexRef.current,\n };\n};\n"],"mappings":"AAAA,SAASA,SAAT,EAAoBC,MAApB,QAAkC,OAAlC;AACA,SAASC,QAAT,QAAyB,cAAzB;AAQA,eAAe,SAASC,oBAAT,CAA8BC,MAA9B,EAAkF;EAC7F,MAAM;IACFC,YADE;IAEFC,gBAAgB,GAAG;EAFjB,IAGFF,MAHJ;EAKA,MAAMG,aAAa,GAAGN,MAAM,CAAC,IAAIC,QAAQ,CAACM,KAAb,CAAmBH,YAAnB,CAAD,CAAN,CAAyCI,OAA/D;EAEA,MAAMC,QAAQ,GAAGT,MAAM,CAASI,YAAT,CAAvB;EAEAL,SAAS,CAAC,MAAM;IACZ,MAAMW,OAAO,GAAGL,gBAAgB,GAAGC,aAAa,CAACK,WAAd,CAA2BC,QAAD,IAAc;MACvEH,QAAQ,CAACD,OAAT,GAAmBI,QAAQ,CAACC,KAA5B;IACH,CAFkC,CAAH,GAE3BC,SAFL;IAIA,OAAO,MAAM;MACT,IAAIJ,OAAO,IAAI,IAAf,EAAqB;QACjBJ,aAAa,CAACS,cAAd,CAA6BL,OAA7B;MACH;IACJ,CAJD;EAKH,CAVQ,EAUN,CAACL,gBAAD,CAVM,CAAT;EAYA,OAAO;IACHC,aADG;IAEHF,YAFG;IAGHY,eAAe,EAAE,MAAMP,QAAQ,CAACD;EAH7B,CAAP;AAKH;AAAA"}
1
+ {"version":3,"names":["useEffect","useRef","Animated","useSyncAnimatedValue","config","initialValue","maybeInitialValue","shouldSyncAlways","animatedValue","Value","current","indexRef","maybeId","addListener","newValue","value","undefined","removeListener","getCurrentValue"],"sources":["useSyncAnimatedValue.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport type { SyncAnimatedValue } from '../types';\n\nexport interface SyncAnimatedValueConfig {\n initialValue: number;\n shouldSyncAlways?: boolean;\n}\n\nexport default function useSyncAnimatedValue(config: SyncAnimatedValueConfig): SyncAnimatedValue {\n const {\n initialValue: maybeInitialValue,\n shouldSyncAlways = false,\n } = config;\n\n const initialValue = maybeInitialValue ?? 0;\n const animatedValue = useRef(new Animated.Value(initialValue)).current;\n\n const indexRef = useRef<number>(initialValue);\n\n useEffect(() => {\n const maybeId = shouldSyncAlways ? animatedValue.addListener((newValue) => {\n indexRef.current = newValue.value;\n }) : undefined;\n\n return () => {\n if (maybeId != null) {\n animatedValue.removeListener(maybeId);\n }\n };\n }, [shouldSyncAlways]);\n\n return {\n animatedValue,\n initialValue,\n getCurrentValue: () => indexRef.current,\n };\n};\n"],"mappings":"AAAA,SAASA,SAAT,EAAoBC,MAApB,QAAkC,OAAlC;AACA,SAASC,QAAT,QAAyB,cAAzB;AAQA,eAAe,SAASC,oBAAT,CAA8BC,MAA9B,EAAkF;EAC7F,MAAM;IACFC,YAAY,EAAEC,iBADZ;IAEFC,gBAAgB,GAAG;EAFjB,IAGFH,MAHJ;EAKA,MAAMC,YAAY,GAAGC,iBAAiB,IAAI,CAA1C;EACA,MAAME,aAAa,GAAGP,MAAM,CAAC,IAAIC,QAAQ,CAACO,KAAb,CAAmBJ,YAAnB,CAAD,CAAN,CAAyCK,OAA/D;EAEA,MAAMC,QAAQ,GAAGV,MAAM,CAASI,YAAT,CAAvB;EAEAL,SAAS,CAAC,MAAM;IACZ,MAAMY,OAAO,GAAGL,gBAAgB,GAAGC,aAAa,CAACK,WAAd,CAA2BC,QAAD,IAAc;MACvEH,QAAQ,CAACD,OAAT,GAAmBI,QAAQ,CAACC,KAA5B;IACH,CAFkC,CAAH,GAE3BC,SAFL;IAIA,OAAO,MAAM;MACT,IAAIJ,OAAO,IAAI,IAAf,EAAqB;QACjBJ,aAAa,CAACS,cAAd,CAA6BL,OAA7B;MACH;IACJ,CAJD;EAKH,CAVQ,EAUN,CAACL,gBAAD,CAVM,CAAT;EAYA,OAAO;IACHC,aADG;IAEHH,YAFG;IAGHa,eAAe,EAAE,MAAMP,QAAQ,CAACD;EAH7B,CAAP;AAKH;AAAA"}
@@ -1,5 +1,5 @@
1
1
  export default class MockStore {
2
- dispatch(state) {// do nothing
2
+ dispatch(action) {// do nothing
3
3
  }
4
4
 
5
5
  getState() {
@@ -1 +1 @@
1
- {"version":3,"names":["MockStore","dispatch","state","getState","Error","removeAllListeners","subscribe","listener"],"sources":["MockStore.ts"],"sourcesContent":["import { MonoStore, StoreSubscription } from './types';\n\nexport default class MockStore<S> implements MonoStore<S> {\n\n dispatch(state: S): void {\n // do nothing\n }\n\n getState(): S {\n throw new Error('stub!');\n }\n\n removeAllListeners(): void {\n // do nothing\n }\n\n subscribe(listener: (state: S) => void): StoreSubscription {\n return () => void 0;\n }\n\n};\n"],"mappings":"AAEA,eAAe,MAAMA,SAAN,CAA2C;EAEtDC,QAAQ,CAACC,KAAD,EAAiB,CACrB;EACH;;EAEDC,QAAQ,GAAM;IACV,MAAM,IAAIC,KAAJ,CAAU,OAAV,CAAN;EACH;;EAEDC,kBAAkB,GAAS,CACvB;EACH;;EAEDC,SAAS,CAACC,QAAD,EAAkD;IACvD,OAAO,MAAM,KAAK,CAAlB;EACH;;AAhBqD;AAkBzD"}
1
+ {"version":3,"names":["MockStore","dispatch","action","getState","Error","removeAllListeners","subscribe","listener"],"sources":["MockStore.ts"],"sourcesContent":["import { MonoStore, StoreSubscription, DispatchAction } from './types';\n\nexport default class MockStore<S> implements MonoStore<S> {\n\n dispatch(action: DispatchAction<S>): void {\n // do nothing\n }\n\n getState(): S {\n throw new Error('stub!');\n }\n\n removeAllListeners(): void {\n // do nothing\n }\n\n subscribe(listener: (state: S) => void): StoreSubscription {\n return () => void 0;\n }\n\n};\n"],"mappings":"AAEA,eAAe,MAAMA,SAAN,CAA2C;EAEtDC,QAAQ,CAACC,MAAD,EAAkC,CACtC;EACH;;EAEDC,QAAQ,GAAM;IACV,MAAM,IAAIC,KAAJ,CAAU,OAAV,CAAN;EACH;;EAEDC,kBAAkB,GAAS,CACvB;EACH;;EAEDC,SAAS,CAACC,QAAD,EAAkD;IACvD,OAAO,MAAM,KAAK,CAAlB;EACH;;AAhBqD;AAkBzD"}
@@ -13,17 +13,19 @@ export default class SimpleStore {
13
13
  this.state = initialState;
14
14
  }
15
15
 
16
- dispatch(state) {
17
- // Do not dispatch if state ref is equal
18
- if (refEqual(this.state, state)) {
16
+ dispatch(action) {
17
+ // @ts-ignore
18
+ const nextState = typeof action === 'function' ? action(this.state) : action; // Do not dispatch if state ref is equal
19
+
20
+ if (refEqual(this.state, nextState)) {
19
21
  return;
20
22
  }
21
23
 
22
- this.state = state;
24
+ this.state = nextState;
23
25
 
24
26
  for (const id in this.listeners) {
25
27
  const listener = this.listeners[id];
26
- listener === null || listener === void 0 ? void 0 : listener(state);
28
+ listener === null || listener === void 0 ? void 0 : listener(nextState);
27
29
  }
28
30
  }
29
31
 
@@ -1 +1 @@
1
- {"version":3,"names":["refEqual","a","b","SimpleStore","constructor","initialState","state","dispatch","id","listeners","listener","getState","subscribe","push","index","indexOf","splice","removeAllListeners","length"],"sources":["SimpleStore.ts"],"sourcesContent":["import { MonoStore, StoreSubscription } from './types';\n\nfunction refEqual(a: any, b: any): boolean {\n return a === b;\n}\n\nexport default class SimpleStore<S> implements MonoStore<S> {\n\n private state: S;\n\n private listeners: Array<(state: S) => void> = [];\n\n constructor(initialState: S) {\n this.state = initialState;\n }\n\n dispatch(state: S): void {\n // Do not dispatch if state ref is equal\n if (refEqual(this.state, state)) {\n return;\n }\n\n this.state = state;\n for (const id in this.listeners) {\n const listener = this.listeners[id];\n listener?.(state);\n }\n }\n\n getState(): S {\n return this.state;\n }\n\n subscribe(listener: (state: S) => void): StoreSubscription {\n this.listeners.push(listener);\n\n return () => {\n const index = this.listeners.indexOf(listener);\n this.listeners.splice(index, 1);\n };\n }\n\n removeAllListeners(): void {\n this.listeners.splice(0, this.listeners.length);\n }\n\n};\n"],"mappings":";;AAEA,SAASA,QAAT,CAAkBC,CAAlB,EAA0BC,CAA1B,EAA2C;EACvC,OAAOD,CAAC,KAAKC,CAAb;AACH;;AAED,eAAe,MAAMC,WAAN,CAA6C;EAMxDC,WAAW,CAACC,YAAD,EAAkB;IAAA;;IAAA,mCAFkB,EAElB;;IACzB,KAAKC,KAAL,GAAaD,YAAb;EACH;;EAEDE,QAAQ,CAACD,KAAD,EAAiB;IACrB;IACA,IAAIN,QAAQ,CAAC,KAAKM,KAAN,EAAaA,KAAb,CAAZ,EAAiC;MAC7B;IACH;;IAED,KAAKA,KAAL,GAAaA,KAAb;;IACA,KAAK,MAAME,EAAX,IAAiB,KAAKC,SAAtB,EAAiC;MAC7B,MAAMC,QAAQ,GAAG,KAAKD,SAAL,CAAeD,EAAf,CAAjB;MACAE,QAAQ,SAAR,IAAAA,QAAQ,WAAR,YAAAA,QAAQ,CAAGJ,KAAH,CAAR;IACH;EACJ;;EAEDK,QAAQ,GAAM;IACV,OAAO,KAAKL,KAAZ;EACH;;EAEDM,SAAS,CAACF,QAAD,EAAkD;IACvD,KAAKD,SAAL,CAAeI,IAAf,CAAoBH,QAApB;IAEA,OAAO,MAAM;MACT,MAAMI,KAAK,GAAG,KAAKL,SAAL,CAAeM,OAAf,CAAuBL,QAAvB,CAAd;MACA,KAAKD,SAAL,CAAeO,MAAf,CAAsBF,KAAtB,EAA6B,CAA7B;IACH,CAHD;EAIH;;EAEDG,kBAAkB,GAAS;IACvB,KAAKR,SAAL,CAAeO,MAAf,CAAsB,CAAtB,EAAyB,KAAKP,SAAL,CAAeS,MAAxC;EACH;;AAtCuD;AAwC3D"}
1
+ {"version":3,"names":["refEqual","a","b","SimpleStore","constructor","initialState","state","dispatch","action","nextState","id","listeners","listener","getState","subscribe","push","index","indexOf","splice","removeAllListeners","length"],"sources":["SimpleStore.ts"],"sourcesContent":["import type { DispatchAction, MonoStore, StoreSubscription } from './types';\n\nfunction refEqual(a: any, b: any): boolean {\n return a === b;\n}\n\nexport default class SimpleStore<S> implements MonoStore<S> {\n\n private state: S;\n\n private listeners: Array<(state: S) => void> = [];\n\n constructor(initialState: S) {\n this.state = initialState;\n }\n\n dispatch(action: DispatchAction<S>): void {\n // @ts-ignore\n const nextState = typeof action === 'function' ? action(this.state) : action;\n\n // Do not dispatch if state ref is equal\n if (refEqual(this.state, nextState)) {\n return;\n }\n\n this.state = nextState;\n for (const id in this.listeners) {\n const listener = this.listeners[id];\n listener?.(nextState);\n }\n }\n\n getState(): S {\n return this.state;\n }\n\n subscribe(listener: (state: S) => void): StoreSubscription {\n this.listeners.push(listener);\n\n return () => {\n const index = this.listeners.indexOf(listener);\n this.listeners.splice(index, 1);\n };\n }\n\n removeAllListeners(): void {\n this.listeners.splice(0, this.listeners.length);\n }\n\n};\n"],"mappings":";;AAEA,SAASA,QAAT,CAAkBC,CAAlB,EAA0BC,CAA1B,EAA2C;EACvC,OAAOD,CAAC,KAAKC,CAAb;AACH;;AAED,eAAe,MAAMC,WAAN,CAA6C;EAMxDC,WAAW,CAACC,YAAD,EAAkB;IAAA;;IAAA,mCAFkB,EAElB;;IACzB,KAAKC,KAAL,GAAaD,YAAb;EACH;;EAEDE,QAAQ,CAACC,MAAD,EAAkC;IACtC;IACA,MAAMC,SAAS,GAAG,OAAOD,MAAP,KAAkB,UAAlB,GAA+BA,MAAM,CAAC,KAAKF,KAAN,CAArC,GAAoDE,MAAtE,CAFsC,CAItC;;IACA,IAAIR,QAAQ,CAAC,KAAKM,KAAN,EAAaG,SAAb,CAAZ,EAAqC;MACjC;IACH;;IAED,KAAKH,KAAL,GAAaG,SAAb;;IACA,KAAK,MAAMC,EAAX,IAAiB,KAAKC,SAAtB,EAAiC;MAC7B,MAAMC,QAAQ,GAAG,KAAKD,SAAL,CAAeD,EAAf,CAAjB;MACAE,QAAQ,SAAR,IAAAA,QAAQ,WAAR,YAAAA,QAAQ,CAAGH,SAAH,CAAR;IACH;EACJ;;EAEDI,QAAQ,GAAM;IACV,OAAO,KAAKP,KAAZ;EACH;;EAEDQ,SAAS,CAACF,QAAD,EAAkD;IACvD,KAAKD,SAAL,CAAeI,IAAf,CAAoBH,QAApB;IAEA,OAAO,MAAM;MACT,MAAMI,KAAK,GAAG,KAAKL,SAAL,CAAeM,OAAf,CAAuBL,QAAvB,CAAd;MACA,KAAKD,SAAL,CAAeO,MAAf,CAAsBF,KAAtB,EAA6B,CAA7B;IACH,CAHD;EAIH;;EAEDG,kBAAkB,GAAS;IACvB,KAAKR,SAAL,CAAeO,MAAf,CAAsB,CAAtB,EAAyB,KAAKP,SAAL,CAAeS,MAAxC;EACH;;AAzCuD;AA2C3D"}
@@ -1 +1 @@
1
- {"version":3,"names":["default","SimpleStore","MockStore"],"sources":["index.ts"],"sourcesContent":["export { default as SimpleStore } from './SimpleStore';\nexport { default as MockStore } from './MockStore';\nexport type { MonoStore } from './types';\n"],"mappings":"AAAA,SAASA,OAAO,IAAIC,WAApB,QAAuC,eAAvC;AACA,SAASD,OAAO,IAAIE,SAApB,QAAqC,aAArC"}
1
+ {"version":3,"names":["default","SimpleStore","MockStore"],"sources":["index.ts"],"sourcesContent":["export { default as SimpleStore } from './SimpleStore';\nexport { default as MockStore } from './MockStore';\nexport type { MonoStore, DispatchAction } from './types';\n"],"mappings":"AAAA,SAASA,OAAO,IAAIC,WAApB,QAAuC,eAAvC;AACA,SAASD,OAAO,IAAIE,SAApB,QAAqC,aAArC"}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["export interface StoreSubscription {\n (): void;\n}\n\nexport interface MonoStore<S> {\n dispatch: (state: S) => void;\n getState: () => S;\n subscribe: (listener: (state: S) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["export interface StoreSubscription {\n (): void;\n}\n\nexport type DispatchAction<State> = State | ((prevState: State) => State);\n\nexport interface MonoStore<S> {\n dispatch: (action: DispatchAction<S>) => void;\n getState: () => S;\n subscribe: (listener: (state: S) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n"],"mappings":""}
@@ -1,6 +1,6 @@
1
- import { MonoStore, StoreSubscription } from './types';
1
+ import { MonoStore, StoreSubscription, DispatchAction } from './types';
2
2
  export default class MockStore<S> implements MonoStore<S> {
3
- dispatch(state: S): void;
3
+ dispatch(action: DispatchAction<S>): void;
4
4
  getState(): S;
5
5
  removeAllListeners(): void;
6
6
  subscribe(listener: (state: S) => void): StoreSubscription;
@@ -1,9 +1,9 @@
1
- import { MonoStore, StoreSubscription } from './types';
1
+ import type { DispatchAction, MonoStore, StoreSubscription } from './types';
2
2
  export default class SimpleStore<S> implements MonoStore<S> {
3
3
  private state;
4
4
  private listeners;
5
5
  constructor(initialState: S);
6
- dispatch(state: S): void;
6
+ dispatch(action: DispatchAction<S>): void;
7
7
  getState(): S;
8
8
  subscribe(listener: (state: S) => void): StoreSubscription;
9
9
  removeAllListeners(): void;
@@ -1,3 +1,3 @@
1
1
  export { default as SimpleStore } from './SimpleStore';
2
2
  export { default as MockStore } from './MockStore';
3
- export type { MonoStore } from './types';
3
+ export type { MonoStore, DispatchAction } from './types';
@@ -1,8 +1,9 @@
1
1
  export interface StoreSubscription {
2
2
  (): void;
3
3
  }
4
+ export declare type DispatchAction<State> = State | ((prevState: State) => State);
4
5
  export interface MonoStore<S> {
5
- dispatch: (state: S) => void;
6
+ dispatch: (action: DispatchAction<S>) => void;
6
7
  getState: () => S;
7
8
  subscribe: (listener: (state: S) => void) => StoreSubscription;
8
9
  removeAllListeners: () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fountain-ui/core",
3
- "version": "2.0.0-beta.23",
3
+ "version": "2.0.0-beta.24",
4
4
  "author": "Fountain-UI Team",
5
5
  "description": "React components that implement Tappytoon's Fountain Design.",
6
6
  "license": "MIT",
@@ -67,5 +67,5 @@
67
67
  "publishConfig": {
68
68
  "access": "public"
69
69
  },
70
- "gitHead": "8b3569226ab4fc9c5812084f850461c9beffe496"
70
+ "gitHead": "fecf3188c95df22fd559194feb24b8662872852b"
71
71
  }
@@ -1,4 +1,4 @@
1
- import { useRef } from 'react';
1
+ import { useCallback, useRef } from 'react';
2
2
  import { Falsy, Keyboard, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';
3
3
  import type { WithTimingConfig } from 'react-native-reanimated';
4
4
  import {
@@ -105,7 +105,7 @@ export default function useCollapsibleAppBar(userOptions: Options = defaultOptio
105
105
  const indexRef = useRef<number>(0);
106
106
  const offsetsRef = useRef<Array<number>>([]);
107
107
 
108
- const onScrollViewChanged = (nextIndex: number) => {
108
+ const onScrollViewChanged = useCallback((nextIndex: number) => {
109
109
  const prevIndex = indexRef.current;
110
110
  if (prevIndex === nextIndex) {
111
111
  return;
@@ -125,7 +125,7 @@ export default function useCollapsibleAppBar(userOptions: Options = defaultOptio
125
125
  if (translateY.value < 0 && savedOffsetY < appBarHeight) {
126
126
  translateY.value = withTiming(0, ANIMATION_CONFIG);
127
127
  }
128
- };
128
+ }, [appBarHeight]);
129
129
 
130
130
  const scrollHandler = useAnimatedScrollHandler({
131
131
  onBeginDrag: () => {
@@ -9,10 +9,11 @@ export interface SyncAnimatedValueConfig {
9
9
 
10
10
  export default function useSyncAnimatedValue(config: SyncAnimatedValueConfig): SyncAnimatedValue {
11
11
  const {
12
- initialValue,
12
+ initialValue: maybeInitialValue,
13
13
  shouldSyncAlways = false,
14
14
  } = config;
15
15
 
16
+ const initialValue = maybeInitialValue ?? 0;
16
17
  const animatedValue = useRef(new Animated.Value(initialValue)).current;
17
18
 
18
19
  const indexRef = useRef<number>(initialValue);
@@ -1,8 +1,8 @@
1
- import { MonoStore, StoreSubscription } from './types';
1
+ import { MonoStore, StoreSubscription, DispatchAction } from './types';
2
2
 
3
3
  export default class MockStore<S> implements MonoStore<S> {
4
4
 
5
- dispatch(state: S): void {
5
+ dispatch(action: DispatchAction<S>): void {
6
6
  // do nothing
7
7
  }
8
8
 
@@ -1,4 +1,4 @@
1
- import { MonoStore, StoreSubscription } from './types';
1
+ import type { DispatchAction, MonoStore, StoreSubscription } from './types';
2
2
 
3
3
  function refEqual(a: any, b: any): boolean {
4
4
  return a === b;
@@ -14,16 +14,19 @@ export default class SimpleStore<S> implements MonoStore<S> {
14
14
  this.state = initialState;
15
15
  }
16
16
 
17
- dispatch(state: S): void {
17
+ dispatch(action: DispatchAction<S>): void {
18
+ // @ts-ignore
19
+ const nextState = typeof action === 'function' ? action(this.state) : action;
20
+
18
21
  // Do not dispatch if state ref is equal
19
- if (refEqual(this.state, state)) {
22
+ if (refEqual(this.state, nextState)) {
20
23
  return;
21
24
  }
22
25
 
23
- this.state = state;
26
+ this.state = nextState;
24
27
  for (const id in this.listeners) {
25
28
  const listener = this.listeners[id];
26
- listener?.(state);
29
+ listener?.(nextState);
27
30
  }
28
31
  }
29
32
 
@@ -1,3 +1,3 @@
1
1
  export { default as SimpleStore } from './SimpleStore';
2
2
  export { default as MockStore } from './MockStore';
3
- export type { MonoStore } from './types';
3
+ export type { MonoStore, DispatchAction } from './types';
@@ -2,8 +2,10 @@ export interface StoreSubscription {
2
2
  (): void;
3
3
  }
4
4
 
5
+ export type DispatchAction<State> = State | ((prevState: State) => State);
6
+
5
7
  export interface MonoStore<S> {
6
- dispatch: (state: S) => void;
8
+ dispatch: (action: DispatchAction<S>) => void;
7
9
  getState: () => S;
8
10
  subscribe: (listener: (state: S) => void) => StoreSubscription;
9
11
  removeAllListeners: () => void;