diff --git a/app/app/ExternalLinkProvider.tsx b/app/app/ExternalLinkProvider.tsx index a3720ff..38c58e6 100644 --- a/app/app/ExternalLinkProvider.tsx +++ b/app/app/ExternalLinkProvider.tsx @@ -42,30 +42,30 @@ export function ExternalLinkProvider(props: PropsWithChildren): JSX.Element { ( )} - handleIndicatorStyle={tailwind('bg-stone-100')} - backgroundStyle={tailwind('bg-stone-800')} + handleIndicatorStyle={tailwind('bg-zinc-200')} + backgroundStyle={tailwind('bg-zinc-900')} > - + - - + + - - {url} + + {url} - + You're about to navigate to an external website. Please proceed with caution and avoid sharing sensitive information. @@ -77,8 +77,8 @@ export function ExternalLinkProvider(props: PropsWithChildren): JSX.Element { close(); }} > - - Continue + + Continue diff --git a/app/app/_layout.tsx b/app/app/_layout.tsx index b3067f1..54ec0c2 100644 --- a/app/app/_layout.tsx +++ b/app/app/_layout.tsx @@ -27,7 +27,7 @@ function WebContainer(): JSX.Element { const tailwind = useTailwind(); if (Platform.OS === 'web') { return ( - + @@ -59,8 +59,13 @@ function AppContainer(): JSX.Element | null { - - + + + + + + + diff --git a/app/app/about/design.e2e.ts b/app/app/about/design.e2e.ts new file mode 100644 index 0000000..d1effe0 --- /dev/null +++ b/app/app/about/design.e2e.ts @@ -0,0 +1,8 @@ +import { expect, test } from '@playwright/test'; + +test('should go to Settings -> Design System ', async ({ page, baseURL }) => { + await page.goto('/'); + await page.getByTestId('/tabs/settings').click(); + await page.getByTestId('/about/design').click(); + await expect(page).toHaveURL(`${baseURL}/about/design`); +}); diff --git a/app/app/keychain/settings/about/design.tsx b/app/app/about/design.tsx similarity index 65% rename from app/app/keychain/settings/about/design.tsx rename to app/app/about/design.tsx index 841ff3f..3fd46c7 100644 --- a/app/app/keychain/settings/about/design.tsx +++ b/app/app/about/design.tsx @@ -1,38 +1,46 @@ -import { Stack } from 'expo-router'; +import { Stack, useRouter } from 'expo-router'; import { ComponentProps, ReactNode } from 'react'; import { SafeAreaView, ScrollView, Switch, Text, TouchableOpacity, View, ViewStyle } from 'react-native'; import { StyleProp } from 'react-native/Libraries/StyleSheet/StyleSheet'; import { useTailwind } from 'tailwind-rn'; -import { useHaptic } from '../../../HapticFeedback'; -import { IconSet } from '../../../IconSet'; +import { useHaptic } from '../HapticFeedback'; +import { IconSet } from '../IconSet'; export default function DesignSystemPage(): JSX.Element { const tailwind = useTailwind(); const haptic = useHaptic(); + const router = useRouter(); return ( <> ( + { + await haptic.selectionAsync(); + router.back(); + }} + > + + + ), }} /> - +
- + A collection of open source rules, principles, and constraints that govern how we design and build Levain Keychain. It is a living document that will grow and evolve as we add more features and functionality to Keychain. As a design system, it provides a common language and vocabulary to build cohesive, accessible, responsive, and efficient experiences. - + Utilizing a utility-first approach, we build complex components from a constrained set of primitive utilities. @@ -40,59 +48,59 @@ export default function DesignSystemPage(): JSX.Element {
- - Primary - stone-200 + + Primary + zinc-200 - Accent + Accent teal-500 - - Background - stone-900 + + Background + zinc-900
- Heading 1 - text-2xl font-bold text-stone-200 + Heading 1 + text-2xl font-bold text-zinc-200 - Heading 2 - text-lg font-bold text-stone-200 + Heading 2 + text-lg font-bold text-zinc-200 - Body - text-base text-stone-200 + Body + text-base text-zinc-200 - Caption - text-sm text-stone-200 + Caption + text-sm text-zinc-200
- 24 - - - - + 24 + + + + - 16 - - - - - + 16 + + + + +
@@ -103,8 +111,8 @@ export default function DesignSystemPage(): JSX.Element { await haptic.selectionAsync(); }} > - - Primary + + Primary @@ -115,8 +123,8 @@ export default function DesignSystemPage(): JSX.Element { await haptic.selectionAsync(); }} > - - Secondary + + Secondary @@ -124,7 +132,7 @@ export default function DesignSystemPage(): JSX.Element {
{ await haptic.setEnabled(value); }} @@ -150,7 +158,7 @@ export default function DesignSystemPage(): JSX.Element { />
-
+
{(() => { function ListViewItem(props: { title: string; @@ -163,13 +171,13 @@ export default function DesignSystemPage(): JSX.Element { await haptic.selectionAsync(); }} > - + {props.title} - + @@ -179,11 +187,11 @@ export default function DesignSystemPage(): JSX.Element { return ( - - + + - SECTION + SECTION ); @@ -200,9 +208,9 @@ function Section(props: { title: string; children?: ReactNode; innerStyle?: Styl return ( - - - {props.title} + + + {props.title} {props.children} @@ -215,7 +223,7 @@ function Code(props: { children: string }): JSX.Element { return ( - {props.children} + {props.children} ); } diff --git a/app/app/about/licenses.tsx b/app/app/about/licenses.tsx new file mode 100644 index 0000000..1aa7f9c --- /dev/null +++ b/app/app/about/licenses.tsx @@ -0,0 +1,36 @@ +import { Stack, useRouter } from 'expo-router'; +import { Text, TouchableOpacity, View } from 'react-native'; +import { useTailwind } from 'tailwind-rn'; + +import { useHaptic } from '../HapticFeedback'; +import { IconSet } from '../IconSet'; + +export default function LicensesPage(): JSX.Element { + const tailwind = useTailwind(); + const haptic = useHaptic(); + const router = useRouter(); + + return ( + <> + ( + { + await haptic.selectionAsync(); + router.back(); + }} + > + + + ), + }} + /> + + Licenses + + + ); +} diff --git a/app/app/api/settings.tsx b/app/app/api/settings.tsx new file mode 100644 index 0000000..d5f2b9b --- /dev/null +++ b/app/app/api/settings.tsx @@ -0,0 +1,35 @@ +import { Stack, useRouter } from 'expo-router'; +import { TouchableOpacity, View } from 'react-native'; +import { useTailwind } from 'tailwind-rn'; + +import { useHaptic } from '../HapticFeedback'; +import { IconSet } from '../IconSet'; + +export default function ApiSettingsPage(): JSX.Element { + const tailwind = useTailwind(); + const haptic = useHaptic(); + const router = useRouter(); + + return ( + <> + ( + { + await haptic.selectionAsync(); + router.back(); + }} + > + + + ), + }} + /> + + + ); +} diff --git a/app/app/index.e2e.ts b/app/app/index.e2e.ts index 9c40f4c..86d1815 100644 --- a/app/app/index.e2e.ts +++ b/app/app/index.e2e.ts @@ -3,7 +3,6 @@ import { expect, test } from '@playwright/test'; test.describe('Index', async () => { test('should go to /', async ({ page, baseURL }) => { await page.goto('/'); - await expect(page).toHaveURL(`${baseURL}/keychain/keys`); - await expect(page.getByTestId('KeysPage.Keys')).toContainText('Keys'); + await expect(page).toHaveURL(`${baseURL}/tabs`); }); }); diff --git a/app/app/index.tsx b/app/app/index.tsx index 3853b6f..52974bd 100644 --- a/app/app/index.tsx +++ b/app/app/index.tsx @@ -1,5 +1,5 @@ import { Redirect } from 'expo-router'; export default function App(): JSX.Element { - return ; + return ; } diff --git a/app/app/keychain/index.tsx b/app/app/keychain/index.tsx deleted file mode 100644 index 6818959..0000000 --- a/app/app/keychain/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { Redirect } from 'expo-router'; - -export default function Keychain(): JSX.Element { - return ; -} diff --git a/app/app/keychain/keys/_layout.tsx b/app/app/keychain/keys/_layout.tsx deleted file mode 100644 index ed09309..0000000 --- a/app/app/keychain/keys/_layout.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { Stack } from 'expo-router'; - -export default function Layout(): JSX.Element { - return ; -} diff --git a/app/app/keychain/scan/_layout.tsx b/app/app/keychain/scan/_layout.tsx deleted file mode 100644 index ed09309..0000000 --- a/app/app/keychain/scan/_layout.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { Stack } from 'expo-router'; - -export default function Layout(): JSX.Element { - return ; -} diff --git a/app/app/keychain/settings/_layout.tsx b/app/app/keychain/settings/_layout.tsx deleted file mode 100644 index 0eab574..0000000 --- a/app/app/keychain/settings/_layout.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Stack } from 'expo-router'; -import { useTailwind } from 'tailwind-rn'; - -export default function SettingLayout(): JSX.Element { - const tailwind = useTailwind(); - - return ( - - ); -} diff --git a/app/app/keychain/settings/about/design.e2e.ts b/app/app/keychain/settings/about/design.e2e.ts deleted file mode 100644 index b8787d2..0000000 --- a/app/app/keychain/settings/about/design.e2e.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { expect, test } from '@playwright/test'; - -test('should go to Settings -> Design System ', async ({ page, baseURL }) => { - await page.goto('/'); - await page.getByTestId('/keychain/settings').click(); - await page.getByTestId('/keychain/settings/about/design').click(); - await expect(page).toHaveURL(`${baseURL}/keychain/settings/about/design`); -}); diff --git a/app/app/keychain/settings/about/licenses.tsx b/app/app/keychain/settings/about/licenses.tsx deleted file mode 100644 index 6fdaacf..0000000 --- a/app/app/keychain/settings/about/licenses.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { Stack } from 'expo-router'; -import { Text, View } from 'react-native'; -import { useTailwind } from 'tailwind-rn'; - -export default function LicensesPage(): JSX.Element { - const tailwind = useTailwind(); - - return ( - <> - - - - Settings - licenses.tsx - - - - ); -} diff --git a/app/app/keychain/settings/app/api.tsx b/app/app/keychain/settings/app/api.tsx deleted file mode 100644 index 66da403..0000000 --- a/app/app/keychain/settings/app/api.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { Stack } from 'expo-router'; -import { Text, View } from 'react-native'; -import { useTailwind } from 'tailwind-rn'; - -export default function ApiSigningPage(): JSX.Element { - const tailwind = useTailwind(); - - return ( - <> - - - - Settings - api.tsx - - - - ); -} diff --git a/app/app/keychain/settings/app/keys.tsx b/app/app/keychain/settings/app/keys.tsx deleted file mode 100644 index 57f85fa..0000000 --- a/app/app/keychain/settings/app/keys.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { Stack } from 'expo-router'; -import { Text, View } from 'react-native'; -import { useTailwind } from 'tailwind-rn'; - -export default function KeyStoragePage(): JSX.Element { - const tailwind = useTailwind(); - - return ( - <> - - - - Settings - keys.tsx - - - - ); -} diff --git a/app/app/keychain/settings/app/scan.tsx b/app/app/keychain/settings/app/scan.tsx deleted file mode 100644 index 8215f65..0000000 --- a/app/app/keychain/settings/app/scan.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { Stack } from 'expo-router'; -import { Text, View } from 'react-native'; -import { useTailwind } from 'tailwind-rn'; - -export default function ScanSigningPage(): JSX.Element { - const tailwind = useTailwind(); - - return ( - <> - - - - Settings - scan.tsx - - - - ); -} diff --git a/app/app/keys/settings.tsx b/app/app/keys/settings.tsx new file mode 100644 index 0000000..ef98695 --- /dev/null +++ b/app/app/keys/settings.tsx @@ -0,0 +1,34 @@ +import { Stack, useRouter } from 'expo-router'; +import { TouchableOpacity, View } from 'react-native'; +import { useTailwind } from 'tailwind-rn'; + +import { useHaptic } from '../HapticFeedback'; +import { IconSet } from '../IconSet'; + +export default function KeySettingsPage(): JSX.Element { + const tailwind = useTailwind(); + const haptic = useHaptic(); + const router = useRouter(); + + return ( + <> + ( + { + await haptic.selectionAsync(); + router.back(); + }} + > + + + ), + }} + /> + + + ); +} diff --git a/app/app/scan/settings.tsx b/app/app/scan/settings.tsx new file mode 100644 index 0000000..1519cca --- /dev/null +++ b/app/app/scan/settings.tsx @@ -0,0 +1,34 @@ +import { Stack, useRouter } from 'expo-router'; +import { TouchableOpacity, View } from 'react-native'; +import { useTailwind } from 'tailwind-rn'; + +import { useHaptic } from '../HapticFeedback'; +import { IconSet } from '../IconSet'; + +export default function ScanSettingsPage(): JSX.Element { + const tailwind = useTailwind(); + const haptic = useHaptic(); + const router = useRouter(); + + return ( + <> + ( + { + await haptic.selectionAsync(); + router.back(); + }} + > + + + ), + }} + /> + + + ); +} diff --git a/app/app/keychain/api/_layout.tsx b/app/app/sign/_layout.tsx similarity index 100% rename from app/app/keychain/api/_layout.tsx rename to app/app/sign/_layout.tsx diff --git a/app/app/sign/index.tsx b/app/app/sign/index.tsx new file mode 100644 index 0000000..00ebe72 --- /dev/null +++ b/app/app/sign/index.tsx @@ -0,0 +1,14 @@ +import { Text, View } from 'react-native'; +import { useTailwind } from 'tailwind-rn'; + +export default function SignPage(): JSX.Element { + const tailwind = useTailwind(); + + return ( + <> + + Sign + + + ); +} diff --git a/app/app/signing/_layout.tsx b/app/app/signing/_layout.tsx deleted file mode 100644 index ed09309..0000000 --- a/app/app/signing/_layout.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { Stack } from 'expo-router'; - -export default function Layout(): JSX.Element { - return ; -} diff --git a/app/app/signing/index.tsx b/app/app/signing/index.tsx deleted file mode 100644 index 2317c9d..0000000 --- a/app/app/signing/index.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Link } from 'expo-router'; -import { Text, View } from 'react-native'; -import { useTailwind } from 'tailwind-rn'; - -export default function ApprovalPage(): JSX.Element { - const tailwind = useTailwind(); - - return ( - <> - - KeyChain — Approval - - - - Sitemap - - - - - ); -} diff --git a/app/app/keychain/_layout.tsx b/app/app/tabs/_layout.tsx similarity index 71% rename from app/app/keychain/_layout.tsx rename to app/app/tabs/_layout.tsx index ad6f807..f14015f 100644 --- a/app/app/keychain/_layout.tsx +++ b/app/app/tabs/_layout.tsx @@ -20,7 +20,7 @@ export default function TabsLayout(): JSX.Element { tabPress: () => haptic.selectionAsync(), }), options: { - tabBarTestID: `/keychain/${props.route}`, + tabBarTestID: `/tabs/${props.route}`, title: props.title, tabBarIcon: ({ color }) => , }, @@ -29,20 +29,21 @@ export default function TabsLayout(): JSX.Element { return ( - - + - - + + ); } diff --git a/app/app/keychain/api/index.tsx b/app/app/tabs/api.tsx similarity index 91% rename from app/app/keychain/api/index.tsx rename to app/app/tabs/api.tsx index 0f9fce9..55e8c0e 100644 --- a/app/app/keychain/api/index.tsx +++ b/app/app/tabs/api.tsx @@ -8,8 +8,8 @@ export default function ApiPage(): JSX.Element { return ( <> - - KeyChain — API + + API ); diff --git a/app/app/keychain/keys/index.tsx b/app/app/tabs/index.tsx similarity index 65% rename from app/app/keychain/keys/index.tsx rename to app/app/tabs/index.tsx index a2deb40..0f5904e 100644 --- a/app/app/keychain/keys/index.tsx +++ b/app/app/tabs/index.tsx @@ -1,4 +1,3 @@ -import { Stack } from 'expo-router'; import { Text, View } from 'react-native'; import { useTailwind } from 'tailwind-rn'; @@ -6,11 +5,8 @@ export default function KeysPage(): JSX.Element { const tailwind = useTailwind(); return ( <> - - - - KeyChain — Keys - + + Keys ); diff --git a/app/app/keychain/scan/index.tsx b/app/app/tabs/scan.tsx similarity index 72% rename from app/app/keychain/scan/index.tsx rename to app/app/tabs/scan.tsx index 49242bf..5a67368 100644 --- a/app/app/keychain/scan/index.tsx +++ b/app/app/tabs/scan.tsx @@ -1,4 +1,3 @@ -import { Stack } from 'expo-router'; import { Text, View } from 'react-native'; import { useTailwind } from 'tailwind-rn'; @@ -7,9 +6,8 @@ export default function ScanPage(): JSX.Element { return ( <> - - - KeyChain — Scan + + Scan ); diff --git a/app/app/keychain/settings/index.tsx b/app/app/tabs/settings.tsx similarity index 83% rename from app/app/keychain/settings/index.tsx rename to app/app/tabs/settings.tsx index 0924e12..03e699a 100644 --- a/app/app/keychain/settings/index.tsx +++ b/app/app/tabs/settings.tsx @@ -3,18 +3,22 @@ import { Stack, useRouter } from 'expo-router'; import { Platform, SectionList, Switch, Text, TouchableOpacity, View } from 'react-native'; import { useTailwind } from 'tailwind-rn'; -import { useExternalLink } from '../../ExternalLinkProvider'; -import { useHaptic } from '../../HapticFeedback'; -import { IconSet } from '../../IconSet'; +import { useExternalLink } from '../ExternalLinkProvider'; +import { useHaptic } from '../HapticFeedback'; +import { IconSet } from '../IconSet'; export default function SettingPage(): JSX.Element { const tailwind = useTailwind(); return ( <> - + ( - {section.title} + {section.title} )} renderItem={({ item }) => { switch (item.type) { @@ -129,8 +133,8 @@ export default function SettingPage(): JSX.Element { }} keyExtractor={(item) => item.type + item.props.title} ItemSeparatorComponent={() => ( - - + + )} /> @@ -160,7 +164,7 @@ function SettingRowVersion(props: RowProps): JSX.Element { })(); return ( - + @@ -177,14 +181,14 @@ function SettingRowHaptic(props: RowProps): JSX.Element { const haptic = useHaptic(); return ( - + {props.title} - + {props.title} @@ -234,13 +238,13 @@ function SettingRowSelect(props: RowProps): JSX.Element { }} testID={props.to} > - + {props.title} - +