Build out header, WIP
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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={
|
||||
|
||||
Reference in New Issue
Block a user