@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.
- package/build/commonjs/hooks/useCollapsibleAppBar.js +2 -4
- package/build/commonjs/hooks/useCollapsibleAppBar.js.map +1 -1
- package/build/commonjs/hooks/useSyncAnimatedValue.js +2 -1
- package/build/commonjs/hooks/useSyncAnimatedValue.js.map +1 -1
- package/build/commonjs/store/MockStore.js +1 -1
- package/build/commonjs/store/MockStore.js.map +1 -1
- package/build/commonjs/store/SimpleStore.js +7 -5
- package/build/commonjs/store/SimpleStore.js.map +1 -1
- package/build/commonjs/store/index.js.map +1 -1
- package/build/commonjs/store/types.js.map +1 -1
- package/build/module/hooks/useCollapsibleAppBar.js +3 -5
- package/build/module/hooks/useCollapsibleAppBar.js.map +1 -1
- package/build/module/hooks/useSyncAnimatedValue.js +2 -1
- package/build/module/hooks/useSyncAnimatedValue.js.map +1 -1
- package/build/module/store/MockStore.js +1 -1
- package/build/module/store/MockStore.js.map +1 -1
- package/build/module/store/SimpleStore.js +7 -5
- package/build/module/store/SimpleStore.js.map +1 -1
- package/build/module/store/index.js.map +1 -1
- package/build/module/store/types.js.map +1 -1
- package/build/typescript/store/MockStore.d.ts +2 -2
- package/build/typescript/store/SimpleStore.d.ts +2 -2
- package/build/typescript/store/index.d.ts +1 -1
- package/build/typescript/store/types.d.ts +2 -1
- package/package.json +2 -2
- package/src/hooks/useCollapsibleAppBar.ts +3 -3
- package/src/hooks/useSyncAnimatedValue.ts +2 -1
- package/src/store/MockStore.ts +2 -2
- package/src/store/SimpleStore.ts +8 -5
- package/src/store/index.ts +1 -1
- 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,
|
|
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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["MockStore","dispatch","
|
|
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(
|
|
24
|
-
//
|
|
25
|
-
|
|
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 =
|
|
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(
|
|
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(
|
|
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: (
|
|
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,
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"names":["MockStore","dispatch","
|
|
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(
|
|
17
|
-
//
|
|
18
|
-
|
|
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 =
|
|
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(
|
|
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(
|
|
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: (
|
|
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(
|
|
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(
|
|
6
|
+
dispatch(action: DispatchAction<S>): void;
|
|
7
7
|
getState(): S;
|
|
8
8
|
subscribe(listener: (state: S) => void): StoreSubscription;
|
|
9
9
|
removeAllListeners(): void;
|
|
@@ -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: (
|
|
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.
|
|
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": "
|
|
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);
|
package/src/store/MockStore.ts
CHANGED
|
@@ -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(
|
|
5
|
+
dispatch(action: DispatchAction<S>): void {
|
|
6
6
|
// do nothing
|
|
7
7
|
}
|
|
8
8
|
|
package/src/store/SimpleStore.ts
CHANGED
|
@@ -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(
|
|
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,
|
|
22
|
+
if (refEqual(this.state, nextState)) {
|
|
20
23
|
return;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
this.state =
|
|
26
|
+
this.state = nextState;
|
|
24
27
|
for (const id in this.listeners) {
|
|
25
28
|
const listener = this.listeners[id];
|
|
26
|
-
listener?.(
|
|
29
|
+
listener?.(nextState);
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
|
package/src/store/index.ts
CHANGED
package/src/store/types.ts
CHANGED
|
@@ -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: (
|
|
8
|
+
dispatch: (action: DispatchAction<S>) => void;
|
|
7
9
|
getState: () => S;
|
|
8
10
|
subscribe: (listener: (state: S) => void) => StoreSubscription;
|
|
9
11
|
removeAllListeners: () => void;
|