diff options
Diffstat (limited to 'src/view/com/util')
-rw-r--r-- | src/view/com/util/TabBar.tsx | 75 | ||||
-rw-r--r-- | src/view/com/util/pager/Pager.tsx (renamed from src/view/com/util/Pager.tsx) | 4 | ||||
-rw-r--r-- | src/view/com/util/pager/Pager.web.tsx | 65 |
3 files changed, 117 insertions, 27 deletions
diff --git a/src/view/com/util/TabBar.tsx b/src/view/com/util/TabBar.tsx index dd8fdcb56..4b67b8a80 100644 --- a/src/view/com/util/TabBar.tsx +++ b/src/view/com/util/TabBar.tsx @@ -7,6 +7,7 @@ import { } from 'react-native' import {Text} from './text/Text' import {usePalette} from 'lib/hooks/usePalette' +import {isDesktopWeb} from 'platform/detection' interface Layout { x: number @@ -46,8 +47,9 @@ export function TabBar({ const indicatorStyle = { backgroundColor: indicatorColor || pal.colors.link, - bottom: indicatorPosition === 'bottom' ? -1 : undefined, - top: indicatorPosition === 'top' ? -1 : undefined, + bottom: + indicatorPosition === 'bottom' ? (isDesktopWeb ? 0 : -1) : undefined, + top: indicatorPosition === 'top' ? (isDesktopWeb ? 0 : -1) : undefined, transform: [ { translateX: panX.interpolate({ @@ -112,26 +114,49 @@ export function TabBar({ ) } -const styles = StyleSheet.create({ - outer: { - flexDirection: 'row', - paddingHorizontal: 14, - }, - itemTop: { - paddingTop: 10, - paddingBottom: 10, - marginRight: 24, - }, - itemBottom: { - paddingTop: 8, - paddingBottom: 12, - marginRight: 24, - }, - indicator: { - position: 'absolute', - left: 0, - width: 1, - height: 3, - borderRadius: 4, - }, -}) +const styles = isDesktopWeb + ? StyleSheet.create({ + outer: { + flexDirection: 'row', + paddingHorizontal: 18, + }, + itemTop: { + paddingTop: 16, + paddingBottom: 14, + marginRight: 24, + }, + itemBottom: { + paddingTop: 14, + paddingBottom: 16, + marginRight: 24, + }, + indicator: { + position: 'absolute', + left: 0, + width: 1, + height: 3, + }, + }) + : StyleSheet.create({ + outer: { + flexDirection: 'row', + paddingHorizontal: 14, + }, + itemTop: { + paddingTop: 10, + paddingBottom: 10, + marginRight: 24, + }, + itemBottom: { + paddingTop: 8, + paddingBottom: 12, + marginRight: 24, + }, + indicator: { + position: 'absolute', + left: 0, + width: 1, + height: 3, + borderRadius: 4, + }, + }) diff --git a/src/view/com/util/Pager.tsx b/src/view/com/util/pager/Pager.tsx index d71cb7f7f..416828a27 100644 --- a/src/view/com/util/Pager.tsx +++ b/src/view/com/util/pager/Pager.tsx @@ -19,7 +19,7 @@ interface Props { tabBarPosition?: 'top' | 'bottom' initialPage?: number renderTabBar: RenderTabBarFn - onPageSelected?: (e: PageSelectedEvent) => void + onPageSelected?: (index: number) => void } export const Pager = ({ children, @@ -36,7 +36,7 @@ export const Pager = ({ const onPageSelectedInner = React.useCallback( (e: PageSelectedEvent) => { setSelectedPage(e.nativeEvent.position) - onPageSelected?.(e) + onPageSelected?.(e.nativeEvent.position) }, [setSelectedPage, onPageSelected], ) diff --git a/src/view/com/util/pager/Pager.web.tsx b/src/view/com/util/pager/Pager.web.tsx new file mode 100644 index 000000000..d50100de9 --- /dev/null +++ b/src/view/com/util/pager/Pager.web.tsx @@ -0,0 +1,65 @@ +import React from 'react' +import {Animated, View} from 'react-native' +import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' +import {s} from 'lib/styles' + +export interface RenderTabBarFnProps { + selectedPage: number + position: Animated.Value + offset: Animated.Value + onSelect?: (index: number) => void +} +export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element + +interface Props { + tabBarPosition?: 'top' | 'bottom' + initialPage?: number + renderTabBar: RenderTabBarFn + onPageSelected?: (index: number) => void +} +export const Pager = ({ + children, + tabBarPosition = 'top', + initialPage = 0, + renderTabBar, + onPageSelected, +}: React.PropsWithChildren<Props>) => { + const [selectedPage, setSelectedPage] = React.useState(initialPage) + const position = useAnimatedValue(0) + const offset = useAnimatedValue(0) + + const onTabBarSelect = React.useCallback( + (index: number) => { + setSelectedPage(index) + onPageSelected?.(index) + Animated.timing(position, { + toValue: index, + duration: 200, + useNativeDriver: true, + }).start() + }, + [setSelectedPage, onPageSelected, position], + ) + + return ( + <View> + {tabBarPosition === 'top' && + renderTabBar({ + selectedPage, + position, + offset, + onSelect: onTabBarSelect, + })} + {children.map((child, i) => ( + <View style={selectedPage === i ? undefined : s.hidden}>{child}</View> + ))} + {tabBarPosition === 'bottom' && + renderTabBar({ + selectedPage, + position, + offset, + onSelect: onTabBarSelect, + })} + </View> + ) +} |