Build out header, WIP

This commit is contained in:
Eric Bailey
2024-12-01 17:13:52 -06:00
parent 8cd6763811
commit 40eb45baad
6 changed files with 125 additions and 68 deletions
+1
View File
@@ -20,6 +20,7 @@ export * from '#/alf/types'
export * from '#/alf/util/flatten'
export * from '#/alf/util/platform'
export * from '#/alf/util/themeSelector'
export * from '#/alf/util/useGutterStyles'
export type Alf = {
themeName: ThemeName
+21
View File
@@ -0,0 +1,21 @@
import React from 'react'
import {atoms as a, useBreakpoints, ViewStyleProp} from '#/alf'
export function useGutterStyles({
top,
bottom,
}: {
top?: boolean
bottom?: boolean
} = {}) {
const {gtMobile} = useBreakpoints()
return React.useMemo<ViewStyleProp['style']>(() => {
return [
a.px_lg,
top && a.pt_md,
bottom && a.pb_md,
gtMobile && [a.px_xl, top && a.pt_lg, bottom && a.pb_lg],
]
}, [gtMobile, top, bottom])
}
+89 -15
View File
@@ -7,11 +7,18 @@ import {
} from 'react-native-keyboard-controller'
import Animated, {AnimatedScrollViewProps} from 'react-native-reanimated'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native'
import {NavigationProp} from '#/lib/routes/types'
import {isWeb} from '#/platform/detection'
import {ViewHeader} from '#/view/com/util/ViewHeader'
import {CenteredView} from '#/view/com/util/Views'
import {atoms as a, useBreakpoints, useTheme, ViewStyleProp} from '#/alf'
import {atoms as a, useBreakpoints, useGutterStyles,useTheme} from '#/alf'
import {Button, ButtonIcon} from '#/components/Button'
import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron'
import {Text} from '#/components/Typography'
// Every screen should have a Layout component wrapping it.
// This component provides a default padding for the top of the screen.
@@ -190,28 +197,95 @@ export const Center = React.forwardRef(function LayoutContent(
)
})
export function Gutter({
export function HeaderNew({children}: {children: React.ReactNode}) {
const t = useTheme()
const gutter = useGutterStyles({top: true, bottom: true})
return (
<View style={[a.w_full, a.border_b, t.atoms.border_contrast_low]}>
<View style={[a.flex_row, a.align_start, gutter, {gap: 9}]}>
{children}
</View>
</View>
)
}
HeaderNew.BackButton = function HeaderBackButton() {
const {_} = useLingui()
const navigation = useNavigation<NavigationProp>()
const onPressBack = React.useCallback(() => {
if (navigation.canGoBack()) {
navigation.goBack()
} else {
navigation.navigate('Home')
}
}, [navigation])
return (
<Button
label={_(msg`Go back`)}
size="small"
variant="solid"
color="secondary"
shape="round"
onPress={onPressBack}
style={[{marginLeft: -3}]}>
<ButtonIcon icon={ChevronLeft} />
</Button>
)
}
HeaderNew.Content = function HeaderContent({
children,
top,
bottom,
style,
}: ViewStyleProp & {
right,
}: {
children: React.ReactNode
right?: React.ReactNode
}) {
return (
<View style={[a.flex_row, a.align_start, a.gap_xs]}>
<View style={[a.flex_1]}>{children}</View>
{right && <View style={[a.gap_xs, a.flex_1]}>{right}</View>}
</View>
)
}
HeaderNew.TitleText = function HeaderTitleText({
children,
}: {
children: React.ReactNode
top?: boolean
bottom?: boolean
}) {
const {gtMobile} = useBreakpoints()
return (
<View
<Text
style={[
a.px_lg,
top && a.pt_lg,
bottom && a.pb_lg,
gtMobile && [a.px_xl, top && a.pt_xl, bottom && a.pb_xl],
style,
a.text_xl,
a.font_heavy,
a.leading_tight,
{paddingTop: 6},
gtMobile && [
a.text_3xl,
{
paddingTop: 2,
},
],
]}>
{children}
</View>
</Text>
)
}
HeaderNew.SubtitleText = function HeaderSubtitleText({
children,
}: {
children: React.ReactNode
}) {
const t = useTheme()
return (
<Text style={[a.text_sm, a.leading_tight, t.atoms.text_contrast_medium]}>
{children}
</Text>
)
}
+7 -1
View File
@@ -38,8 +38,14 @@ export function AccountSettingsScreen({}: Props) {
return (
<Layout.Screen>
<Layout.Header title={_(msg`Account`)} />
<Layout.Content>
<Layout.HeaderNew>
<Layout.HeaderNew.BackButton />
<Layout.HeaderNew.Content>
<Layout.HeaderNew.TitleText>Account</Layout.HeaderNew.TitleText>
</Layout.HeaderNew.Content>
</Layout.HeaderNew>
<SettingsList.Container>
<SettingsList.Item>
<SettingsList.ItemIcon icon={EnvelopeIcon} />
@@ -2,7 +2,7 @@ import React, {useContext, useMemo} from 'react'
import {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native'
import {HITSLOP_10} from '#/lib/constants'
import {atoms as a, useTheme, ViewStyleProp} from '#/alf'
import {atoms as a, useGutterStyles,useTheme, ViewStyleProp} from '#/alf'
import * as Button from '#/components/Button'
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRightIcon} from '#/components/icons/Chevron'
import {Link, LinkProps} from '#/components/Link'
@@ -80,6 +80,7 @@ export function Item({
iconInset?: boolean
style?: StyleProp<ViewStyle>
}) {
const gutter = useGutterStyles()
const context = useContext(ItemContext)
const childContext = useMemo(() => {
if (typeof destructive !== 'boolean') return context
@@ -88,7 +89,7 @@ export function Item({
return (
<View
style={[
a.px_xl,
gutter,
a.py_sm,
a.align_center,
a.gap_md,
+4 -50
View File
@@ -1,9 +1,6 @@
import React from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {StyleSheet, View} from 'react-native'
import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {
@@ -14,9 +11,9 @@ import {
import {usePalette} from '#/lib/hooks/usePalette'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {getCurrentRoute, isStateAtTabRoot, isTab} from '#/lib/routes/helpers'
import {getCurrentRoute, isTab} from '#/lib/routes/helpers'
import {makeProfileLink} from '#/lib/routes/links'
import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
import {CommonNavigatorParams} from '#/lib/routes/types'
import {isInvalidHandle} from '#/lib/strings/handles'
import {emitSoftReset} from '#/state/events'
import {useFetchHandle} from '#/state/queries/handle'
@@ -101,47 +98,6 @@ function ProfileCard() {
)
}
const HIDDEN_BACK_BNT_ROUTES = ['StarterPackWizard', 'StarterPackEdit']
function BackBtn() {
const {isTablet} = useWebMediaQueries()
const pal = usePalette('default')
const navigation = useNavigation<NavigationProp>()
const {_} = useLingui()
const shouldShow = useNavigationState(
state =>
!isStateAtTabRoot(state) &&
!HIDDEN_BACK_BNT_ROUTES.includes(getCurrentRoute(state).name),
)
const onPressBack = React.useCallback(() => {
if (navigation.canGoBack()) {
navigation.goBack()
} else {
navigation.navigate('Home')
}
}, [navigation])
if (!shouldShow || isTablet) {
return <></>
}
return (
<TouchableOpacity
testID="viewHeaderBackOrMenuBtn"
onPress={onPressBack}
style={styles.backBtn}
accessibilityRole="button"
accessibilityLabel={_(msg`Go back`)}
accessibilityHint="">
<FontAwesomeIcon
size={24}
icon="angle-left"
style={pal.text as FontAwesomeIconStyle}
/>
</TouchableOpacity>
)
}
interface NavItemProps {
count?: string
href: string
@@ -381,8 +337,6 @@ export function DesktopLeftNav() {
{hasSession && (
<>
<BackBtn />
<NavItem
href="/"
icon={