diff options
Diffstat (limited to 'src/screens/Onboarding/Layout.tsx')
-rw-r--r-- | src/screens/Onboarding/Layout.tsx | 126 |
1 files changed, 76 insertions, 50 deletions
diff --git a/src/screens/Onboarding/Layout.tsx b/src/screens/Onboarding/Layout.tsx index 16c37358f..6394d9c96 100644 --- a/src/screens/Onboarding/Layout.tsx +++ b/src/screens/Onboarding/Layout.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, {useState} from 'react' import {ScrollView, View} from 'react-native' import {useSafeAreaInsets} from 'react-native-safe-area-context' import {msg} from '@lingui/macro' @@ -11,20 +11,23 @@ import { atoms as a, flatten, native, - TextStyleProp, + type TextStyleProp, + tokens, useBreakpoints, useTheme, web, } from '#/alf' import {leading} from '#/alf/typography' import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron' +import {ArrowLeft_Stroke2_Corner0_Rounded as ArrowLeft} from '#/components/icons/Arrow' +import {HEADER_SLOT_SIZE} from '#/components/Layout' import {createPortalGroup} from '#/components/Portal' import {P, Text} from '#/components/Typography' -const COL_WIDTH = 420 +const ONBOARDING_COL_WIDTH = 420 export const OnboardingControls = createPortalGroup() +export const OnboardingHeaderSlot = createPortalGroup() export function Layout({children}: React.PropsWithChildren<{}>) { const {_} = useLingui() @@ -46,6 +49,8 @@ export function Layout({children}: React.PropsWithChildren<{}>) { const paddingTop = gtMobile ? a.py_5xl : a.py_lg const dialogLabel = _(msg`Set up your account`) + const [footerHeight, setFooterHeight] = useState(0) + return ( <View aria-modal @@ -62,45 +67,67 @@ export function Layout({children}: React.PropsWithChildren<{}>) { t.atoms.bg, ]}> {__DEV__ && ( - <View style={[a.absolute, a.p_xl, a.z_10, {right: 0, top: insets.top}]}> - <Button - variant="ghost" - color="negative" - size="small" - onPress={() => onboardDispatch({type: 'skip'})} - // DEV ONLY - label="Clear onboarding state"> - <ButtonText>Clear</ButtonText> - </Button> - </View> + <Button + variant="ghost" + color="negative" + size="tiny" + onPress={() => onboardDispatch({type: 'skip'})} + // DEV ONLY + label="Clear onboarding state" + style={[ + a.absolute, + a.z_10, + { + left: '50%', + top: insets.top + 2, + transform: [{translateX: '-50%'}], + }, + ]}> + <ButtonText>[DEV] Clear</ButtonText> + </Button> )} - {!gtMobile && state.hasPrev && ( + {!gtMobile && ( <View + pointerEvents="box-none" style={[ web(a.fixed), native(a.absolute), + a.left_0, + a.right_0, a.flex_row, a.w_full, a.justify_center, a.z_20, a.px_xl, - { - top: paddingTop.paddingTop + insets.top - 1, - }, + {top: paddingTop.paddingTop + insets.top - 1}, ]}> - <View style={[a.w_full, a.align_start, {maxWidth: COL_WIDTH}]}> - <Button - key={state.activeStep} // remove focus state on nav - variant="ghost" - color="secondary" - size="small" - shape="round" - label={_(msg`Go back to previous step`)} - style={[a.absolute]} - onPress={() => dispatch({type: 'prev'})}> - <ButtonIcon icon={ChevronLeft} /> - </Button> + <View + pointerEvents="box-none" + style={[ + a.w_full, + a.align_start, + a.flex_row, + a.justify_between, + {maxWidth: ONBOARDING_COL_WIDTH}, + ]}> + {state.hasPrev ? ( + <Button + key={state.activeStep} // remove focus state on nav + color="secondary" + variant="ghost" + shape="square" + size="small" + label={_(msg`Go back to previous step`)} + onPress={() => dispatch({type: 'prev'})} + style={[a.bg_transparent]}> + <ButtonIcon icon={ArrowLeft} size="lg" /> + </Button> + ) : ( + <View /> + )} + + <OnboardingHeaderSlot.Outlet /> </View> </View> )} @@ -109,22 +136,24 @@ export function Layout({children}: React.PropsWithChildren<{}>) { ref={scrollview} style={[a.h_full, a.w_full, {paddingTop: insets.top}]} contentContainerStyle={{borderWidth: 0}} - // @ts-ignore web only --prf + scrollIndicatorInsets={{bottom: footerHeight - insets.bottom}} + // @ts-expect-error web only --prf dataSet={{'stable-gutters': 1}}> <View style={[a.flex_row, a.justify_center, gtMobile ? a.px_5xl : a.px_xl]}> - <View style={[a.flex_1, {maxWidth: COL_WIDTH}]}> + <View style={[a.flex_1, {maxWidth: ONBOARDING_COL_WIDTH}]}> <View style={[a.w_full, a.align_center, paddingTop]}> <View style={[ a.flex_row, a.gap_sm, a.w_full, - {paddingTop: 17, maxWidth: '60%'}, + a.align_center, + {height: HEADER_SLOT_SIZE, maxWidth: '60%'}, ]}> {Array(state.totalSteps) .fill(0) - .map((_, i) => ( + .map((__, i) => ( <View key={i} style={[ @@ -144,19 +173,16 @@ export function Layout({children}: React.PropsWithChildren<{}>) { </View> </View> - <View - style={[a.w_full, a.mb_5xl, {paddingTop: gtMobile ? 20 : 40}]}> - {children} - </View> + <View style={[a.w_full, a.mb_5xl, a.pt_md]}>{children}</View> - <View style={{height: 400}} /> + <View style={{height: 100 + footerHeight}} /> </View> </View> </ScrollView> <View + onLayout={evt => setFooterHeight(evt.nativeEvent.layout.height)} style={[ - // @ts-ignore web only -prf isWeb ? a.fixed : a.absolute, {bottom: 0, left: 0, right: 0}, t.atoms.bg, @@ -167,30 +193,30 @@ export function Layout({children}: React.PropsWithChildren<{}>) { isWeb ? a.py_2xl : { - paddingTop: a.pt_lg.paddingTop, - paddingBottom: insets.bottom + 10, + paddingTop: tokens.space.md, + paddingBottom: insets.bottom + tokens.space.md, }, ]}> <View style={[ a.w_full, - {maxWidth: COL_WIDTH}, - gtMobile && [a.flex_row, a.justify_between], + {maxWidth: ONBOARDING_COL_WIDTH}, + gtMobile && [a.flex_row, a.justify_between, a.align_center], ]}> {gtMobile && (state.hasPrev ? ( <Button key={state.activeStep} // remove focus state on nav - variant="solid" color="secondary" - size="large" - shape="round" + variant="ghost" + shape="square" + size="small" label={_(msg`Go back to previous step`)} onPress={() => dispatch({type: 'prev'})}> - <ButtonIcon icon={ChevronLeft} /> + <ButtonIcon icon={ArrowLeft} size="lg" /> </Button> ) : ( - <View style={{height: 54}} /> + <View style={{height: 33}} /> ))} <OnboardingControls.Outlet /> </View> |