Skip to content

Commit

Permalink
feat: onboarding screens in storybook (#126)
Browse files Browse the repository at this point in the history
Signed-off-by: Timo Glastra <[email protected]>
  • Loading branch information
TimoGlastra authored Jul 25, 2024
1 parent e6ee115 commit 4ffd02f
Show file tree
Hide file tree
Showing 36 changed files with 1,891 additions and 1,693 deletions.
Binary file added apps/funke/assets/german-issuer-image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion apps/funke/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
},
"devDependencies": {
"@babel/core": "^7.24.4",
"@tamagui/babel-plugin": "^1.91.4",
"@tamagui/babel-plugin": "^1.104.2",
"typescript": "*"
}
}
16 changes: 12 additions & 4 deletions apps/funke/tamagui.config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// don't import from here, that's handled already
// instead this is just setting types for this folder
import { radius, size, space, zIndex } from '@tamagui/themes'

import { configInput, fontOpenSans, fontRaleway, hexColors } from '@package/ui/src/config/tamagui.config'
import { createTamagui, createTokens } from 'tamagui'

export const tokensInput = {
color: hexColors,
radius,
radius: {
...radius,
button: 16,
},
size,
zIndex,
space,
Expand Down Expand Up @@ -45,9 +46,16 @@ const config = createTamagui({
fonts: {
default: fontOpenSans,
heading: fontRaleway,
// Somehow adding body font gives build errors?!
// body: fontOpenSans,
},
themes: {
light: tokens.color,
light: {
...tokens.color,

// Button
buttonHeight: 53,
},
},
})

Expand Down
2 changes: 1 addition & 1 deletion apps/paradym/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
},
"devDependencies": {
"@babel/core": "^7.24.4",
"@tamagui/babel-plugin": "^1.91.4",
"@tamagui/babel-plugin": "^1.104.2",
"typescript": "*"
}
}
3 changes: 0 additions & 3 deletions apps/paradym/tamagui.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// don't import from here, that's handled already
// instead this is just setting types for this folder

import { config } from '@package/ui'

type Conf = typeof config
Expand Down
3 changes: 2 additions & 1 deletion apps/storybook/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { Preview } from '@storybook/react'
import withThemeProvider from './withThemeProvider'
import 'react-device-frameset/styles/marvel-devices.min.css'
import { withDeviceFrameOnWeb } from './withDeviceFrameOnWeb'

const preview: Preview = {
decorators: [withThemeProvider],
decorators: [withThemeProvider, withDeviceFrameOnWeb],
parameters: {
backgrounds: {
default: 'grey',
Expand Down
27 changes: 5 additions & 22 deletions apps/storybook/.storybook/withDeviceFrameOnWeb.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,14 @@
import type { Decorator } from '@storybook/react'
import React, { type NamedExoticComponent, useEffect, useState } from 'react'
import React from 'react'
import { DeviceFrameset } from 'react-device-frameset'
import { Platform } from 'react-native'

// TODO: register by default and allow to configure through parameters to disable device set per component
import type { DeviceFramesetProps } from 'react-device-frameset'

const withDeviceFrameOnWeb: Decorator = (Story, context) => {
if (Platform.OS !== 'web') return <Story {...context} />

const [DeviceFrameset, setDeviceFrameset] = useState<NamedExoticComponent<DeviceFramesetProps>>()
useEffect(() => {
if (DeviceFrameset) return
// @ts-ignore
import('react-device-frameset').then((component) => setDeviceFrameset(component.DeviceFrameset))
}, [DeviceFrameset])

if (!DeviceFrameset) return <></>
if (Platform.OS !== 'web' || context.parameters.deviceFrame !== true) return <Story />

return (
<DeviceFrameset
device="iPhone 8"
color="silver"
style={{
paddingTop: 20,
}}
>
<Story {...context} />
<DeviceFrameset device="iPhone 8" color="silver">
<Story />
</DeviceFrameset>
)
}
Expand Down
18 changes: 12 additions & 6 deletions apps/storybook/.storybook/withThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import { TamaguiProvider } from '@package/ui'
import type { Decorator } from '@storybook/react'
import React from 'react'
import { useColorScheme } from 'react-native'

// TODO: make custom decorator that allows changing this from within the storybook UI. But
// requires quite some boilerplate
// You can change the theme used in the storybook
import funkeConfig from '../../funke/tamagui.config'
import paradymConfig from '../../paradym/tamagui.config'

const configs = {
funke: funkeConfig,
paradym: paradymConfig,
}

const withThemeProvider: Decorator = (Story, context) => {
const scheme = useColorScheme()
const configName = context.parameters.theme ?? 'funke'

const config = configs[configName]
if (!config)
throw new Error(`Theme with name ${configName} does not exist. Valid themes are ${Object.keys(configs).join(', ')}`)

return (
<TamaguiProvider config={funkeConfig} defaultTheme={scheme === 'dark' ? 'dark' : 'light'}>
<TamaguiProvider config={config} defaultTheme="light">
<Story {...context} />
</TamaguiProvider>
)
Expand Down
39 changes: 0 additions & 39 deletions apps/storybook/components/FirstLaunchScreen.stories.tsx

This file was deleted.

81 changes: 81 additions & 0 deletions apps/storybook/components/funke/BiometricsModal.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Button, Heading, Paragraph, Stack, YStack } from '@package/ui'
import { useArgs } from '@storybook/addons'
import type { Meta, StoryObj } from '@storybook/react'
import React from 'react'
import { Path, Svg } from 'react-native-svg'
import { Sheet, View, useTheme } from 'tamagui'

interface BiometricsModalProps {
onAcceptBiometrics: () => void
open: boolean
onOpenChange: (open: boolean) => void
}

const FingerprintIcon = () => {
const theme = useTheme()
return (
<Svg width="75" height="84" viewBox="0 0 75 84" fill="none">
<Path
d="M0.646218 31.6878C0.298996 31.41 0.108718 31.0976 0.0753847 30.7503C0.0392736 30.4031 0.125385 30.0212 0.333718 29.6045C4.70872 23.8406 10.0907 19.3087 16.4795 16.0087C22.8684 12.7114 29.674 11.0628 36.8962 11.0628C44.2573 11.0628 51.1837 12.642 57.6754 15.8003C64.1698 18.9614 69.5698 23.4934 73.8754 29.3962C74.292 29.8823 74.4143 30.3156 74.2421 30.6962C74.067 31.0795 73.8059 31.41 73.4587 31.6878C73.1115 31.8962 72.7295 32.0003 72.3129 32.0003C71.8962 32.0003 71.5143 31.7573 71.1671 31.2712C67.2782 25.7156 62.2962 21.4962 56.2212 18.6128C50.1434 15.7323 43.7018 14.292 36.8962 14.292C30.1601 14.292 23.824 15.767 17.8879 18.717C11.949 21.6698 7.00038 25.8545 3.04205 31.2712C2.69483 31.7573 2.29483 32.0184 1.84205 32.0545C1.39205 32.0878 0.993441 31.9656 0.646218 31.6878ZM48.7712 83.1462C41.7573 81.3406 35.9934 77.7809 31.4795 72.467C26.9657 67.1559 24.7087 60.6809 24.7087 53.042C24.7087 49.7087 25.924 46.9128 28.3545 44.6545C30.7851 42.3989 33.7018 41.2712 37.1045 41.2712C40.5073 41.2712 43.4073 42.3989 45.8046 44.6545C48.199 46.9128 49.3962 49.7087 49.3962 53.042C49.3962 55.4725 50.299 57.5212 52.1045 59.1878C53.9101 60.8545 56.0629 61.6878 58.5629 61.6878C61.0629 61.6878 63.1976 60.8545 64.967 59.1878C66.7393 57.5212 67.6254 55.4725 67.6254 53.042C67.6254 44.8475 64.6045 37.9559 58.5629 32.367C52.5212 26.7753 45.3337 23.9795 37.0004 23.9795C28.5976 23.9795 21.4101 26.792 15.4379 32.417C9.46566 38.042 6.47955 44.917 6.47955 53.042C6.47955 54.7087 6.66983 56.8101 7.05038 59.3462C7.43372 61.8795 8.21566 64.8128 9.39622 68.1462C9.53511 68.6323 9.51844 69.0489 9.34622 69.3962C9.17122 69.7434 8.87538 70.0212 8.45872 70.2295C7.97261 70.4378 7.53927 70.4559 7.15872 70.2837C6.77538 70.1087 6.51427 69.7781 6.37538 69.292C5.26427 66.4448 4.46566 63.7017 3.97955 61.0628C3.49344 58.4239 3.25039 55.7503 3.25039 53.042C3.25039 43.9448 6.56705 36.3059 13.2004 30.1253C19.8309 23.9448 27.7296 20.8545 36.8962 20.8545C46.2018 20.8545 54.1879 23.9448 60.8545 30.1253C67.5212 36.3059 70.8545 43.9448 70.8545 53.042C70.8545 56.3753 69.6573 59.1712 67.2629 61.4295C64.8657 63.6851 61.9657 64.8128 58.5629 64.8128C55.2295 64.8128 52.3309 63.6851 49.8671 61.4295C47.4004 59.1712 46.167 56.3753 46.167 53.042C46.167 50.6114 45.2809 48.5628 43.5087 46.8962C41.7393 45.2295 39.6045 44.3962 37.1045 44.3962C34.6045 44.3962 32.4518 45.2295 30.6462 46.8962C28.8407 48.5628 27.9379 50.6114 27.9379 53.042C27.9379 59.917 29.9865 65.6642 34.0837 70.2837C38.1809 74.9003 43.3893 78.1114 49.7087 79.917C50.1948 80.1253 50.5254 80.4031 50.7004 80.7503C50.8726 81.0975 50.8893 81.4795 50.7504 81.8962C50.6115 82.3128 50.3851 82.6601 50.0712 82.9378C49.7601 83.2156 49.3268 83.2851 48.7712 83.1462ZM13.5629 10.0212C13.2157 10.2295 12.8337 10.2642 12.4171 10.1253C12.0004 9.98644 11.7226 9.74338 11.5837 9.39616C11.3754 8.97949 11.3059 8.57949 11.3754 8.19616C11.4448 7.8156 11.6879 7.52116 12.1046 7.31283C15.924 5.16005 19.9518 3.54477 24.1879 2.46699C28.424 1.39199 32.7295 0.854492 37.1045 0.854492C41.4795 0.854492 45.7504 1.39199 49.917 2.46699C54.0837 3.54477 58.1115 5.0906 62.0004 7.10449C62.5559 7.38227 62.8865 7.72949 62.9921 8.14616C63.0948 8.56283 63.042 8.94477 62.8337 9.29199C62.6948 9.70866 62.417 10.0031 62.0004 10.1753C61.5837 10.3503 61.167 10.2989 60.7504 10.0212C57.1393 8.00727 53.3379 6.51421 49.3462 5.54199C45.3518 4.56977 41.2712 4.08366 37.1045 4.08366C32.9379 4.08366 28.8934 4.60449 24.9712 5.64616C21.0462 6.68783 17.2434 8.14616 13.5629 10.0212ZM26.5837 81.8962C22.6948 77.6601 19.6393 73.285 17.4171 68.7712C15.1948 64.2573 14.0837 59.0142 14.0837 53.042C14.0837 46.8614 16.3407 41.6531 20.8545 37.417C25.3684 33.1809 30.7851 31.0628 37.1045 31.0628C43.424 31.0628 48.8587 33.1809 53.4087 37.417C57.9559 41.6531 60.2295 46.8614 60.2295 53.042C60.2295 53.5281 60.0726 53.9101 59.7587 54.1878C59.4476 54.4656 59.049 54.6045 58.5629 54.6045C58.2157 54.6045 57.8684 54.4656 57.5212 54.1878C57.174 53.9101 57.0004 53.5281 57.0004 53.042C57.0004 47.6948 55.0393 43.2156 51.117 39.6045C47.192 35.9934 42.5212 34.1878 37.1045 34.1878C31.6879 34.1878 27.0351 35.9934 23.1462 39.6045C19.2573 43.2156 17.3129 47.6948 17.3129 53.042C17.3129 58.8059 18.3032 63.6503 20.2837 67.5753C22.2615 71.4976 25.1254 75.5073 28.8754 79.6045C29.292 80.0212 29.4657 80.4378 29.3962 80.8545C29.3268 81.2712 29.1532 81.6184 28.8754 81.8962C28.5976 82.1739 28.2504 82.3309 27.8337 82.367C27.417 82.4003 27.0004 82.2434 26.5837 81.8962ZM57.7295 74.6045C51.7573 74.6045 46.5323 72.5559 42.0546 68.4587C37.574 64.3614 35.3337 59.2225 35.3337 53.042C35.3337 52.6253 35.4726 52.2601 35.7504 51.9462C36.0282 51.6351 36.4101 51.4795 36.8962 51.4795C37.3823 51.4795 37.7809 51.6351 38.092 51.9462C38.4059 52.2601 38.5629 52.6253 38.5629 53.042C38.5629 58.3892 40.4726 62.7809 44.292 66.217C48.1115 69.6559 52.5907 71.3753 57.7295 71.3753C58.424 71.3753 59.1532 71.3406 59.917 71.2712C60.6809 71.2017 61.4448 71.0976 62.2087 70.9587C62.6254 70.8892 62.9893 70.9587 63.3004 71.167C63.6143 71.3753 63.8407 71.7225 63.9795 72.2087C64.1184 72.6253 64.0323 72.9892 63.7212 73.3003C63.4073 73.6142 63.042 73.8406 62.6254 73.9795C61.8615 74.1878 61.0282 74.3448 60.1254 74.4503C59.2226 74.5531 58.424 74.6045 57.7295 74.6045Z"
fill={theme['primary-500'].val}
/>
</Svg>
)
}

const BiometricsModal = ({ onAcceptBiometrics, open, onOpenChange }: BiometricsModalProps) => {
return (
<Sheet
open={open}
onOpenChange={onOpenChange}
// FIXME: hardcoded for good fit in storybook, but this probably won't work on mobile...
snapPoints={[520]}
snapPointsMode="constant"
disableDrag
dismissOnOverlayPress={false}
>
<Sheet.Overlay bc="#00000033" animation="quick" enterStyle={{ opacity: 0 }} exitStyle={{ opacity: 0 }} />
<Sheet.Frame borderRadius="$8" maxHeight={360} width="90%" alignSelf="center">
<YStack flex-1 justifyContent="space-between" overflow="hidden">
<Stack backgroundColor="$primary-100" height={175} justifyContent="center" alignItems="center">
<FingerprintIcon />
</Stack>
<YStack p="$2" px="$4" gap="$3" height={100}>
<Heading variant="h2">Biometrics is required</Heading>
<Paragraph variant="text">
Securing with your biometrics is required for receiving your digital identity
</Paragraph>
</YStack>
<Button.Solid onPress={onAcceptBiometrics} mx="$4" mb="$4">
Activate Biometrics
</Button.Solid>
</YStack>
</Sheet.Frame>
</Sheet>
)
}

const meta = {
title: 'Funke/Biometrics Modal',
component: BiometricsModal,
args: {
open: true,
},
parameters: {
deviceFrame: true,
},
render: (args) => {
const [_, updateArgs] = useArgs()
return (
<View height={800}>
<BiometricsModal {...args} onOpenChange={(open) => updateArgs({ open })} />
</View>
)
},
} satisfies Meta<typeof BiometricsModal>

export default meta

type Story = StoryObj<typeof meta>

export const Screen: Story = {}
41 changes: 13 additions & 28 deletions apps/storybook/components/funke/FirstLaunchScreen.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Button, Heading, HeroIcon, Page, Separator, XStack, YStack } from '@package/ui'
import { Button, Heading, HeroIcons, Page, Separator, XStack, YStack } from '@package/ui'
import type { Meta, StoryObj } from '@storybook/react'
import React from 'react'
import { LinearGradient } from 'tamagui/linear-gradient'
import { withDeviceFrameOnWeb } from '../../.storybook/withDeviceFrameOnWeb'

const FirstLaunchScreen = () => {
return (
Expand All @@ -12,42 +11,26 @@ const FirstLaunchScreen = () => {
flex={1}
width="100%"
height="100%"
colors={['#EFF3F6', '#FFFFFF']}
colors={['$grey-100', '$white']}
start={[0.5, 0]}
end={[0.5, 1]}
/>
<YStack p="$4" gap="$4" flex-1 justifyContent="space-between">
{/* This stack keeps the */}
{/* This stack ensures the right spacing */}
<YStack flex={3} />
<YStack gap="$2">
{/* todo: grey-5 */}
<Heading variant="h1" color="#282C37">
Ausweis Wallet
</Heading>
{/* todo: 1 is a bit too small, maybe just hardcode */}
<Separator borderWidth="$1" borderRadius="$1" borderColor="$primary-500" width="$3" />
{/* todo: grey-4 */}
<Heading variant="h1" color="#656974">
<Heading variant="title">Ausweis Wallet</Heading>
<Separator borderWidth={3} borderRadius={3} borderColor="$primary-500" width="$4" />
<Heading variant="title" secondary>
Your digital Identity
</Heading>
</YStack>
<YStack flex-1 />
{/* TODO: button height is higher in Funke app, need to set different default */}
<XStack gap="$2" my="$2" height={55} display="flex" alignContent="stretch" alignItems="stretch">
{/* todo: grey-1 */}
<Button.Outline
p="$0"
width={55}
height="100%"
backgroundColor="#EFF3F6"
borderWidth="$0.25"
borderColor="#D7DCE080"
borderRadius="$6"
>
<HeroIcon.GlobeAlt />
<XStack gap="$2" my="$2">
<Button.Outline p="$0" width="$buttonHeight">
<HeroIcons.GlobeAlt size={24} />
</Button.Outline>
{/* todo: grey-5 */}
<Button.Solid height="100%" flexGrow={1} backgroundColor="#282C37" onPress={() => {}} borderRadius="$6">
<Button.Solid flexGrow={1} onPress={() => {}}>
Get Started
</Button.Solid>
</XStack>
Expand All @@ -58,8 +41,10 @@ const FirstLaunchScreen = () => {

const meta = {
title: 'Funke/First Launch Screen',
decorators: [withDeviceFrameOnWeb],
component: FirstLaunchScreen,
parameters: {
deviceFrame: true,
},
} satisfies Meta<typeof FirstLaunchScreen>

export default meta
Expand Down
52 changes: 52 additions & 0 deletions apps/storybook/components/funke/IdCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { HeroIcons, Image, Paragraph, Stack, XStack, YStack } from '@package/ui'
import { StyleSheet } from 'react-native'
import { Circle } from 'tamagui'
import { LinearGradient } from 'tamagui/linear-gradient'

export interface IdCardProps {
icon: keyof typeof iconMapping
issuerImage: string
userName?: string
}

const iconMapping = {
locked: <HeroIcons.LockClosed color="$white" />,
loading: <HeroIcons.ArrowPath color="$white" />,
complete: <HeroIcons.ShieldCheck color="$white" />,
} as const

export function IdCard({ icon, issuerImage, userName }: IdCardProps) {
return (
<YStack gap="$6" p="$5" borderRadius="$8" overflow="hidden" borderColor="rgba(216, 218, 200, 1)">
<LinearGradient
colors={['#EFE7DA', '#EDEEE6', '#E9EDEE', '#D4D6C0']}
start={[0.98, 0.02]}
end={[0.28, 1.0]}
locations={[0.0207, 0.3341, 0.5887, 1.0]}
style={StyleSheet.absoluteFillObject}
/>
<LinearGradient
colors={['rgba(255, 255, 255, 0.2)', 'rgba(255, 255, 255, 0.2)']}
start={[0, 0]}
end={[1, 0]}
style={StyleSheet.absoluteFillObject}
/>
<XStack justifyContent="space-between">
<YStack gap="$1">
<Paragraph secondary>Personalausweis</Paragraph>
<Paragraph size="$6" fontWeight="$regular">
{userName ?? '********'}
</Paragraph>
</YStack>
<Stack>
<Image src={issuerImage} width={75} height={75} resizeMode="contain" />
</Stack>
</XStack>
<XStack justifyContent="flex-end">
<Circle size="$3" backgroundColor="$grey-700" opacity={0.4}>
{iconMapping[icon]}
</Circle>
</XStack>
</YStack>
)
}
Loading

0 comments on commit 4ffd02f

Please sign in to comment.