Move components to sdk for future use (#1243)

* move components to sdk and refactor a way from tamagui

* linting

* reverting since this is just a local issue for me

* lint

* simple

* yarn

* yolo

* run yarn nice

* fix pipelines

* fix tests

* fix mock

* add fonts to mobile sdk

* more feedback

---------

Co-authored-by: Justin Hernandez <justin.hernandez@self.xyz>
This commit is contained in:
Aaron DeRuvo
2025-10-11 01:52:41 +02:00
committed by GitHub
parent 1ca2e8a32c
commit 6bdc4ae1d2
90 changed files with 875 additions and 573 deletions

View File

@@ -8,8 +8,8 @@ import { XStack, YStack } from 'tamagui';
import type { Country3LetterCode } from '@selfxyz/common/constants';
import { countryCodes } from '@selfxyz/common/constants';
import type { SelfAppDisclosureConfig } from '@selfxyz/common/utils';
import { BodyText } from '@selfxyz/mobile-sdk-alpha/components';
import { BodyText } from '@/components/typography/BodyText';
import CheckMark from '@/images/icons/checkmark.svg';
import { slate200, slate500 } from '@/utils/colors';
@@ -115,7 +115,7 @@ const DisclosureItem: React.FC<DisclosureItemProps> = ({
paddingHorizontal={10}
>
<CheckMark width={22} />
<BodyText textBreakStrategy="balanced" color={slate500}>
<BodyText textBreakStrategy="balanced" style={{ color: slate500 }}>
{text}
</BodyText>
</XStack>

View File

@@ -6,7 +6,8 @@ import React, { useState } from 'react';
import { Alert, Modal, StyleSheet, Text, TextInput, View } from 'react-native';
import { Button, XStack, YStack } from 'tamagui';
import { Caption } from '@/components/typography/Caption';
import { Caption } from '@selfxyz/mobile-sdk-alpha/components';
import { black, slate400, white, zinc800, zinc900 } from '@/utils/colors';
import { advercase, dinot } from '@/utils/fonts';

View File

@@ -6,10 +6,13 @@ import React, { useCallback } from 'react';
import { Modal, StyleSheet } from 'react-native';
import { styled, View, XStack, YStack } from 'tamagui';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import {
Description,
PrimaryButton,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import ModalClose from '@/images/icons/modal_close.svg';
import LogoInversed from '@/images/logo_inversed.svg';
import { white } from '@/utils/colors';
@@ -112,7 +115,9 @@ const FeedbackModalScreen: React.FC<FeedbackModalScreenProps> = ({
)}
</XStack>
<YStack gap={20}>
<Title textAlign="left">{modalParams.titleText}</Title>
<Title style={{ textAlign: 'left' }}>
{modalParams.titleText}
</Title>
<Description style={styles.description}>
{modalParams.bodyText}
</Description>

View File

@@ -61,10 +61,12 @@ export const AadhaarNavBar = (props: NativeStackHeaderProps) => {
/>
<NavBar.Title
fontSize={16}
color={black}
fontWeight="600"
fontFamily={dinot}
style={{
fontSize: 16,
color: black,
fontWeight: '600',
fontFamily: dinot,
}}
>
AADHAAR REGISTRATION
</NavBar.Title>

View File

@@ -3,13 +3,14 @@
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React, { useMemo } from 'react';
import type { TextProps } from 'react-native';
import type { SystemBarStyle } from 'react-native-edge-to-edge';
import { SystemBars } from 'react-native-edge-to-edge';
import type { TextProps, ViewProps, XStackProps } from 'tamagui';
import type { ViewProps, XStackProps } from 'tamagui';
import { Button, View, XStack } from 'tamagui';
import { ChevronLeft, X } from '@tamagui/lucide-icons';
import { Title } from '@/components/typography/Title';
import { Title } from '@selfxyz/mobile-sdk-alpha/components';
interface NavBarProps extends XStackProps {
children: React.ReactNode;

View File

@@ -32,7 +32,7 @@ export const DocumentFlowNavBar = ({
justifyContent="space-between"
>
<NavBar.LeftAction component="back" onPress={() => navigation.goBack()} />
<NavBar.Title fontFamily={titleFontFamily} fontSize={fontSize}>
<NavBar.Title style={{ fontFamily: titleFontFamily, fontSize: fontSize }}>
{title}
</NavBar.Title>
<NavBar.RightAction

View File

@@ -100,7 +100,7 @@ export const HomeNavBar = (props: NativeStackHeaderProps) => {
</XStack>
}
/>
<NavBar.Title size="large" color={black}>
<NavBar.Title style={{ fontSize: 24, color: black }}>
{props.options.title}
</NavBar.Title>
<NavBar.RightAction

View File

@@ -41,7 +41,7 @@ export const IdDetailsNavBar = (props: NativeStackHeaderProps) => {
</Button>
}
/>
<NavBar.Title size="large" color={black}>
<NavBar.Title style={{ fontSize: 24, color: black }}>
{props.options.title}
</NavBar.Title>
<NavBar.RightAction

View File

@@ -5,7 +5,8 @@
import React from 'react';
import { Text, View } from 'tamagui';
import { Caption } from '@/components/typography/Caption';
import { Caption } from '@selfxyz/mobile-sdk-alpha/components';
import { slate500 } from '@/utils/colors';
export interface TipProps {
@@ -39,7 +40,7 @@ function Tip({ title, body, icon }: TipProps) {
</View>
)}
<View flex={1}>
<Caption size="large" color={slate500}>
<Caption size="large" style={{ color: slate500 }}>
<Text fontWeight={'bold'}>
{title}
{': '}

View File

@@ -1,114 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React from 'react';
import type {
GestureResponderEvent,
LayoutChangeEvent,
ViewStyle,
} from 'react-native';
import { Platform, StyleSheet } from 'react-native';
import type { ViewProps } from 'tamagui';
import { Button, Text } from 'tamagui';
import { pressedStyle } from '@/components/buttons/pressedStyle';
import analytics from '@/utils/analytics';
import { dinot } from '@/utils/fonts';
export interface ButtonProps extends ViewProps {
children: React.ReactNode;
animatedComponent?: React.ReactNode;
trackEvent?: string;
onLayout?: (event: LayoutChangeEvent) => void;
}
interface AbstractButtonProps extends ButtonProps {
bgColor: string;
borderColor?: string;
borderWidth?: number;
color: string;
onPress?: ((e: GestureResponderEvent) => void) | null | undefined;
}
const { trackEvent: analyticsTrackEvent } = analytics();
/*
Base Button component that can be used to create different types of buttons
use PrimaryButton and SecondaryButton instead of this component or create a new button component
@dev If the button isnt filling the space check that its parent is 100% width
*/
export default function AbstractButton({
children,
bgColor,
color,
borderColor,
borderWidth = 4,
style,
animatedComponent,
trackEvent,
onPress,
...props
}: AbstractButtonProps) {
const hasBorder = borderColor ? true : false;
const handlePress = (e: GestureResponderEvent) => {
if (trackEvent) {
// attempt to remove event category from click event
const parsedEvent = trackEvent?.split(':')?.[1]?.trim();
if (parsedEvent) {
trackEvent = parsedEvent;
}
analyticsTrackEvent(`Click: ${trackEvent}`);
}
if (onPress) {
onPress(e);
}
};
return (
<Button
unstyled
{...props}
onPress={handlePress}
style={[
styles.container,
{ backgroundColor: bgColor },
hasBorder
? {
borderWidth: borderWidth,
borderColor: borderColor,
padding: 20 - borderWidth, // Adjust padding to maintain total size
}
: Platform.select({ web: { borderWidth: 0 }, default: {} }),
style as ViewStyle,
]}
pressStyle={!animatedComponent ? pressedStyle : {}}
>
{animatedComponent}
<Text style={[styles.text, { color: color }]}>{children}</Text>
</Button>
);
}
const styles = StyleSheet.create({
container: {
position: 'relative',
justifyContent: 'center',
flexDirection: 'row',
flexGrow: 0,
flexShrink: 0,
width: '100%',
display: 'flex',
alignItems: 'center',
rowGap: 12,
padding: 20,
borderRadius: 5,
},
text: {
fontFamily: dinot,
textAlign: 'center',
fontSize: 18,
},
});

View File

@@ -1,273 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React, { useEffect } from 'react';
import { ActivityIndicator, View } from 'react-native';
import { assign, createMachine } from 'xstate';
import { useMachine } from '@xstate/react';
import { ProofEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { HeldPrimaryButton } from '@/components/buttons/PrimaryButtonLongHold';
import Description from '@/components/typography/Description';
import { black } from '@/utils/colors';
interface HeldPrimaryButtonProveScreenProps {
onVerify: () => void;
selectedAppSessionId: string | undefined | null;
hasScrolledToBottom: boolean;
isReadyToProve: boolean;
}
interface ButtonContext {
selectedAppSessionId: string | undefined | null;
hasScrolledToBottom: boolean;
isReadyToProve: boolean;
onVerify: () => void;
}
type ButtonEvent =
| {
type: 'PROPS_UPDATED';
selectedAppSessionId: string | undefined | null;
hasScrolledToBottom: boolean;
isReadyToProve: boolean;
}
| { type: 'VERIFY' };
const buttonMachine = createMachine(
{
id: 'proveButton',
types: {} as {
context: ButtonContext;
events: ButtonEvent;
actions: { type: 'callOnVerify' } | { type: 'updateContext' };
},
initial: 'waitingForSession',
context: ({ input }: { input: { onVerify: () => void } }) => ({
selectedAppSessionId: null as string | undefined | null,
hasScrolledToBottom: false,
isReadyToProve: false,
onVerify: input.onVerify,
}),
on: {
PROPS_UPDATED: {
actions: 'updateContext',
},
},
states: {
waitingForSession: {
always: {
target: 'needsScroll',
guard: ({ context }) => !!context.selectedAppSessionId,
},
},
needsScroll: {
always: [
{
target: 'waitingForSession',
guard: ({ context }) => !context.selectedAppSessionId,
},
{
target: 'preparing',
guard: ({ context }) => context.hasScrolledToBottom,
},
],
},
preparing: {
always: [
{
target: 'waitingForSession',
guard: ({ context }) => !context.selectedAppSessionId,
},
{
target: 'needsScroll',
guard: ({ context }) => !context.hasScrolledToBottom,
},
{
target: 'ready',
guard: ({ context }) => context.isReadyToProve,
},
],
after: {
500: { target: 'preparing2' },
},
},
preparing2: {
always: [
{
target: 'waitingForSession',
guard: ({ context }) => !context.selectedAppSessionId,
},
{
target: 'needsScroll',
guard: ({ context }) => !context.hasScrolledToBottom,
},
{
target: 'ready',
guard: ({ context }) => context.isReadyToProve,
},
],
after: {
500: { target: 'preparing3' },
},
},
preparing3: {
always: [
{
target: 'waitingForSession',
guard: ({ context }) => !context.selectedAppSessionId,
},
{
target: 'needsScroll',
guard: ({ context }) => !context.hasScrolledToBottom,
},
{
target: 'ready',
guard: ({ context }) => context.isReadyToProve,
},
],
},
ready: {
on: {
VERIFY: 'verifying',
},
always: [
{
target: 'waitingForSession',
guard: ({ context }) => !context.selectedAppSessionId,
},
{
target: 'needsScroll',
guard: ({ context }) => !context.hasScrolledToBottom,
},
{
target: 'preparing',
guard: ({ context }) => !context.isReadyToProve,
},
],
},
verifying: {
entry: 'callOnVerify',
// Remove always transitions checking hasScrolledToBottom and isReadyToProve
// Keep the button visually verifying until the component unmounts or session changes
always: {
target: 'waitingForSession',
guard: ({ context }) => !context.selectedAppSessionId,
},
},
},
},
{
actions: {
updateContext: assign(({ context, event }) => {
if (event.type === 'PROPS_UPDATED') {
if (
context.selectedAppSessionId !== event.selectedAppSessionId ||
context.hasScrolledToBottom !== event.hasScrolledToBottom ||
context.isReadyToProve !== event.isReadyToProve
) {
return {
selectedAppSessionId: event.selectedAppSessionId,
hasScrolledToBottom: event.hasScrolledToBottom,
isReadyToProve: event.isReadyToProve,
};
}
}
return context;
}),
callOnVerify: ({ context }) => {
context.onVerify();
},
},
},
);
export const HeldPrimaryButtonProveScreen: React.FC<
HeldPrimaryButtonProveScreenProps
> = ({
onVerify,
selectedAppSessionId,
hasScrolledToBottom,
isReadyToProve,
}) => {
const [state, send] = useMachine(buttonMachine, {
input: { onVerify },
});
useEffect(() => {
send({
type: 'PROPS_UPDATED',
selectedAppSessionId,
hasScrolledToBottom,
isReadyToProve,
});
}, [selectedAppSessionId, hasScrolledToBottom, isReadyToProve, send]);
const isDisabled = !state.matches('ready');
const renderButtonContent = () => {
if (state.matches('waitingForSession')) {
return (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<ActivityIndicator color={black} style={{ marginRight: 8 }} />
<Description color={black}>Waiting for app...</Description>
</View>
);
}
if (state.matches('needsScroll')) {
return 'Please read all disclosures';
}
if (state.matches('preparing')) {
return (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<ActivityIndicator color={black} style={{ marginRight: 8 }} />
<Description color={black}>Accessing to Keychain data</Description>
</View>
);
}
if (state.matches('preparing2')) {
return (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<ActivityIndicator color={black} style={{ marginRight: 8 }} />
<Description color={black}>Parsing passport data</Description>
</View>
);
}
if (state.matches('preparing3')) {
return (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<ActivityIndicator color={black} style={{ marginRight: 8 }} />
<Description color={black}>Preparing for verification</Description>
</View>
);
}
if (state.matches('ready')) {
return 'Hold to verify';
}
if (state.matches('verifying')) {
return (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<ActivityIndicator color={black} style={{ marginRight: 8 }} />
<Description color={black}>Generating proof</Description>
</View>
);
}
return null;
};
return (
<HeldPrimaryButton
trackEvent={ProofEvents.PROOF_VERIFY_LONG_PRESS}
onLongPress={() => {
if (state.matches('ready')) {
send({ type: 'VERIFY' });
}
}}
disabled={isDisabled}
>
{renderButtonContent()}
</HeldPrimaryButton>
);
};

View File

@@ -1,32 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React from 'react';
import type { ButtonProps } from '@/components/buttons/AbstractButton';
import AbstractButton from '@/components/buttons/AbstractButton';
import { amber50, black, slate300, white } from '@/utils/colors';
import { normalizeBorderWidth } from '@/utils/styleUtils';
export function PrimaryButton({ children, ...props }: ButtonProps) {
const { borderWidth, ...restProps } = props;
const isDisabled = restProps.disabled;
const bgColor = isDisabled ? white : black;
const color = isDisabled ? slate300 : amber50;
const borderColor = isDisabled ? slate300 : undefined;
const numericBorderWidth = normalizeBorderWidth(borderWidth);
return (
<AbstractButton
{...restProps}
borderWidth={numericBorderWidth}
borderColor={borderColor}
bgColor={bgColor}
color={color}
>
{children}
</AbstractButton>
);
}

View File

@@ -1,15 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import type { ButtonProps } from '@/components/buttons/AbstractButton';
export interface HeldPrimaryButtonProps extends ButtonProps {
onLongPress: () => void;
}
export type RGBA = `rgba(${number}, ${number}, ${number}, ${number})`; // time in ms
//slate400 to slate800 but in rgb
export const ACTION_TIMER = 600;
export const COLORS: RGBA[] = ['rgba(30, 41, 59, 0.3)', 'rgba(30, 41, 59, 1)'];

View File

@@ -1,113 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React, { useEffect, useState } from 'react';
import type { LayoutChangeEvent } from 'react-native';
import { Animated, StyleSheet, useAnimatedValue } from 'react-native';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import type { HeldPrimaryButtonProps } from '@/components/buttons/PrimaryButtonLongHold.shared';
import {
ACTION_TIMER,
COLORS,
} from '@/components/buttons/PrimaryButtonLongHold.shared';
export function HeldPrimaryButton({
children,
onLongPress,
...props
}: HeldPrimaryButtonProps) {
const [hasTriggered, setHasTriggered] = useState(false);
const [size, setSize] = useState({ width: 0, height: 0 });
// React Native animation setup
const animation = useAnimatedValue(0);
const onPressIn = () => {
setHasTriggered(false);
Animated.timing(animation, {
toValue: 1,
duration: ACTION_TIMER,
useNativeDriver: true,
}).start();
};
const onPressOut = () => {
if (!hasTriggered) {
Animated.timing(animation, {
toValue: 0,
duration: ACTION_TIMER,
useNativeDriver: true,
}).start();
}
};
const getButtonSize = (e: LayoutChangeEvent) => {
const width = e.nativeEvent.layout.width - 1;
const height = e.nativeEvent.layout.height - 1;
setSize({ width, height });
};
useEffect(() => {
// Mobile: Use React Native animation listener
animation.addListener(({ value }) => {
if (value >= 0.95 && !hasTriggered) {
setHasTriggered(true);
onLongPress();
}
});
return () => {
animation.removeAllListeners();
};
}, [animation, hasTriggered, onLongPress]);
const renderAnimatedComponent = () => {
// Mobile: Use React Native Animated.View
const scaleX = animation.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
});
const bgColor = animation.interpolate({
inputRange: [0, 1],
outputRange: COLORS,
});
return (
<Animated.View
style={[
styles.fill,
size,
{
transform: [{ scaleX }],
backgroundColor: bgColor,
height: size.height,
},
]}
/>
);
};
return (
<PrimaryButton
{...props}
onPressIn={onPressIn}
onPressOut={onPressOut}
onLayout={getButtonSize}
animatedComponent={renderAnimatedComponent()}
>
{children}
</PrimaryButton>
);
}
const styles = StyleSheet.create({
fill: {
transformOrigin: 'left',
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
borderRadius: 4,
},
});

View File

@@ -1,92 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React, { useEffect, useState } from 'react';
import type { LayoutChangeEvent } from 'react-native';
// Tamagui imports for web
import { AnimatePresence, YStack } from 'tamagui';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import type { HeldPrimaryButtonProps } from '@/components/buttons/PrimaryButtonLongHold.shared';
import {
ACTION_TIMER,
COLORS,
} from '@/components/buttons/PrimaryButtonLongHold.shared';
export function HeldPrimaryButton({
children,
onLongPress,
...props
}: HeldPrimaryButtonProps) {
const [hasTriggered, setHasTriggered] = useState(false);
const [size, setSize] = useState({ width: 0, height: 0 });
const [isPressed, setIsPressed] = useState(false);
const onPressIn = () => {
setHasTriggered(false);
setIsPressed(true);
};
const onPressOut = () => {
setIsPressed(false);
};
const getButtonSize = (e: LayoutChangeEvent) => {
const width = e.nativeEvent.layout.width - 1;
const height = e.nativeEvent.layout.height - 1;
setSize({ width, height });
};
useEffect(() => {
// Web: Use setTimeout to trigger onLongPress
let timeoutId: NodeJS.Timeout;
if (isPressed && !hasTriggered) {
timeoutId = setTimeout(() => {
if (isPressed && !hasTriggered) {
setHasTriggered(true);
onLongPress();
}
}, ACTION_TIMER);
}
return () => {
if (timeoutId) clearTimeout(timeoutId);
};
}, [hasTriggered, onLongPress, isPressed]);
const renderAnimatedComponent = () => {
// Web: Use Tamagui AnimatePresence with CSS transitions
return (
<AnimatePresence>
{isPressed && (
<YStack
key="fill"
position="absolute"
top={0}
left={0}
bottom={0}
borderRadius={4}
backgroundColor={COLORS[1]}
width="100%"
height={size.height}
enterStyle={{ width: 0 }}
exitStyle={{ width: 0 }}
animation="quick"
/>
)}
</AnimatePresence>
);
};
return (
<PrimaryButton
{...props}
onPressIn={onPressIn}
onPressOut={onPressOut}
onLayout={getButtonSize}
animatedComponent={renderAnimatedComponent()}
>
{children}
</PrimaryButton>
);
}

View File

@@ -1,32 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React from 'react';
import type { ButtonProps } from '@/components/buttons/AbstractButton';
import AbstractButton from '@/components/buttons/AbstractButton';
import { slate200, slate300, slate500, white } from '@/utils/colors';
import { normalizeBorderWidth } from '@/utils/styleUtils';
export function SecondaryButton({ children, ...props }: ButtonProps) {
const { borderWidth, ...restProps } = props;
const isDisabled = restProps.disabled;
const bgColor = isDisabled ? white : slate200;
const color = isDisabled ? slate300 : slate500;
const borderColor = isDisabled ? slate200 : undefined;
const numericBorderWidth = normalizeBorderWidth(borderWidth);
return (
<AbstractButton
{...restProps}
borderWidth={numericBorderWidth}
bgColor={bgColor}
color={color}
borderColor={borderColor}
>
{children}
</AbstractButton>
);
}

View File

@@ -1,5 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
export const pressedStyle = { transform: [{ scale: 0.99 }], opacity: 0.85 };

View File

@@ -1,78 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React from 'react';
import { View } from 'react-native';
import * as CountryFlags from 'react-native-svg-circle-country-flags';
import { alpha3ToAlpha2 } from '@selfxyz/common/constants/countries';
import { slate300 } from '@/utils/colors';
type CountryFlagComponent = React.ComponentType<{
width: number;
height: number;
}>;
type CountryFlagsRecord = Record<string, CountryFlagComponent>;
interface RoundFlagProps {
countryCode: string;
size: number;
}
const findFlagComponent = (formattedCode: string) => {
const patterns = [
formattedCode,
formattedCode.toLowerCase(),
formattedCode.charAt(0).toUpperCase() +
formattedCode.charAt(1).toLowerCase(),
];
for (const pattern of patterns) {
const component = (CountryFlags as unknown as CountryFlagsRecord)[pattern];
if (component) {
return component;
}
}
return null;
};
const getCountryFlag = (countryCode: string): CountryFlagComponent | null => {
try {
const normalizedCountryCode = countryCode === 'D<<' ? 'DEU' : countryCode;
const iso2 = alpha3ToAlpha2(normalizedCountryCode);
if (!iso2) {
return null;
}
const formattedCode = iso2.toUpperCase();
return findFlagComponent(formattedCode);
} catch (error) {
console.error('Error getting country flag:', error);
return null;
}
};
export const RoundFlag: React.FC<RoundFlagProps> = ({ countryCode, size }) => {
const CountryFlagComponent = getCountryFlag(countryCode);
if (!CountryFlagComponent) {
return (
<View
style={{
width: size,
height: size,
backgroundColor: slate300,
}}
/>
);
}
return (
<View style={{ alignItems: 'center' }}>
<CountryFlagComponent width={size} height={size} />
</View>
);
};

View File

@@ -142,7 +142,7 @@ const IdCardLayout: FC<IdCardLayoutAttributes> = ({
</Text>
<Text
fontSize={fontSize.small}
color={'#9193A2'}
color={slate400}
fontFamily={dinot}
>
Verified{' '}

View File

@@ -1,34 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React from 'react';
import type { TextProps } from 'react-native';
import { StyleSheet, Text } from 'react-native';
import { slate400 } from '@/utils/colors';
import { dinot } from '@/utils/fonts';
type AdditionalProps = TextProps;
const Additional = ({ children, style, ...props }: AdditionalProps) => {
return (
<Text {...props} style={[styles.additional, style]}>
{children}
</Text>
);
};
export default Additional;
const styles = StyleSheet.create({
additional: {
fontSize: 14,
lineHeight: 18,
textAlign: 'center',
color: slate400,
marginTop: 10,
fontFamily: dinot,
textTransform: 'none',
},
});

View File

@@ -1,11 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import { styled, Text } from 'tamagui';
import { dinot } from '@/utils/fonts';
export const BodyText = styled(Text, {
fontFamily: dinot,
});

View File

@@ -1,23 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import { styled } from 'tamagui';
import { BodyText } from '@/components/typography/BodyText';
import { slate400 } from '@/utils/colors';
export const Caption = styled(BodyText, {
fontSize: 15,
color: slate400,
variants: {
size: {
small: {
fontSize: 14,
},
large: {
fontSize: 16,
},
},
},
});

View File

@@ -1,31 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React from 'react';
import type { TextProps } from 'react-native';
import { StyleSheet, Text } from 'react-native';
import { slate700 } from '@/utils/colors';
import { dinot } from '@/utils/fonts';
type CautionProps = TextProps;
const Caution = ({ children, style, ...props }: CautionProps) => {
return (
<Text {...props} style={[styles.Caution, style]}>
{children}
</Text>
);
};
export default Caution;
const styles = StyleSheet.create({
Caution: {
fontFamily: dinot,
color: slate700,
fontSize: 18,
fontWeight: '500',
},
});

View File

@@ -1,37 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React from 'react';
import { StyleSheet } from 'react-native';
import type { TextProps } from 'tamagui';
import { Text } from 'tamagui';
import { slate500 } from '@/utils/colors';
import { dinot } from '@/utils/fonts';
type DescriptionProps = TextProps;
const Description = ({ children, style, ...props }: DescriptionProps) => {
return (
<Text
{...props}
textBreakStrategy="balanced"
style={[styles.description, style]}
>
{children}
</Text>
);
};
export default Description;
const styles = StyleSheet.create({
description: {
color: slate500,
fontSize: 18,
lineHeight: 23,
textAlign: 'center',
fontFamily: dinot,
},
});

View File

@@ -1,17 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import { styled, Text } from 'tamagui';
import { dinot } from '@/utils/fonts';
export const SubHeader = styled(Text, {
fontFamily: dinot,
lineHeight: 18,
fontSize: 15,
fontWeight: '500',
letterSpacing: 0.6,
textTransform: 'uppercase',
textAlign: 'center',
});

View File

@@ -1,29 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import type { StyleProp, TextStyle } from 'react-native';
import { styled, Text } from 'tamagui';
import { advercase } from '@/utils/fonts';
export const Title = styled(
Text,
{
fontSize: 28,
lineHeight: 35,
fontFamily: advercase,
variants: {
size: {
large: {
fontSize: 38,
lineHeight: 47,
},
},
},
},
{
acceptsClassName: true,
style: (props: { style?: StyleProp<TextStyle> }) => props.style,
},
);

View File

@@ -1,14 +0,0 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import { StyleSheet } from 'react-native';
import { black } from '@/utils/colors';
export const typography = StyleSheet.create({
strong: {
fontWeight: 'bold',
color: black,
},
});

View File

@@ -7,9 +7,12 @@ import React from 'react';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { ScrollView, YStack } from 'tamagui';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import { Title } from '@/components/typography/Title';
import {
PrimaryButton,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import { white } from '@/utils/colors';
@@ -50,7 +53,10 @@ export default function SimpleScrolledTitleLayout({
</YStack>
)}
{secondaryButtonText && onSecondaryButtonPress && (
<SecondaryButton onPress={onSecondaryButtonPress} marginBottom={12}>
<SecondaryButton
onPress={onSecondaryButtonPress}
style={{ marginBottom: 12 }}
>
{secondaryButtonText}
</SecondaryButton>
)}

View File

@@ -9,13 +9,15 @@ import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { isUserRegisteredWithAlternativeCSCA } from '@selfxyz/common/utils/passports/validate';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import {
Caption,
Description,
PrimaryButton,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { BackupEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import { Caption } from '@/components/typography/Caption';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import Keyboard from '@/images/icons/keyboard.svg';
import RestoreAccountSvg from '@/images/icons/restore_account.svg';

View File

@@ -5,12 +5,14 @@
import React from 'react';
import { View, YStack } from 'tamagui';
import {
Description,
PrimaryButton,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { BackupEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import RestoreAccountSvg from '@/images/icons/restore_account.svg';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';

View File

@@ -8,10 +8,12 @@ import {
hasAnyValidRegisteredDocument,
useSelfClient,
} from '@selfxyz/mobile-sdk-alpha';
import {
Description,
PrimaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import analytics from '@/utils/analytics';
@@ -41,13 +43,15 @@ const DocumentDataNotFoundScreen: React.FC = () => {
return (
<ExpandableBottomLayout.Layout backgroundColor={black}>
<ExpandableBottomLayout.TopSection backgroundColor={black}>
<Title textAlign="center" style={{ color: white }}>
<Title style={{ textAlign: 'center', color: white }}>
Are you new here?
</Title>
<Description
marginTop={8}
textAlign="center"
style={{ color: slate200 }}
style={{
marginTop: 8,
textAlign: 'center',
color: slate200,
}}
>
It seems like you need to go through the registration flow first.
</Description>

View File

@@ -12,10 +12,12 @@ import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { isUserRegisteredWithAlternativeCSCA } from '@selfxyz/common/utils/passports/validate';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import {
Description,
SecondaryButton,
} from '@selfxyz/mobile-sdk-alpha/components';
import { BackupEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import Description from '@/components/typography/Description';
import Paste from '@/images/icons/paste.svg';
import type { RootStackParamList } from '@/navigation';
import { useAuth } from '@/providers/authProvider';
@@ -115,7 +117,7 @@ const RecoverWithPhraseScreen: React.FC = () => {
paddingBottom="$2.5"
style={styles.layout}
>
<Description color={slate300}>
<Description style={{ color: slate300 }}>
Your recovery phrase has 24 words. Enter the words in the correct order,
separated by spaces.
</Description>

View File

@@ -9,14 +9,16 @@ import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import {
Caption,
Description,
PrimaryButton,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { BackupEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import BackupDocumentationLink from '@/components/BackupDocumentationLink';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import { Caption } from '@/components/typography/Caption';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import { useModal } from '@/hooks/useModal';
import Cloud from '@/images/icons/logo_cloud_backup.svg';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';

View File

@@ -13,8 +13,8 @@ import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { Bug, FileText } from '@tamagui/lucide-icons';
import { pressedStyle } from '@/components/buttons/pressedStyle';
import { BodyText } from '@/components/typography/BodyText';
import { BodyText, pressedStyle } from '@selfxyz/mobile-sdk-alpha/components';
import {
appStoreUrl,
gitHubUrl,
@@ -119,7 +119,7 @@ const MenuButton: React.FC<MenuButtonProps> = ({ children, Icon, onPress }) => (
hitSlop={4}
>
<Icon height={24} width={21} color={white} />
<BodyText color={white} fontSize={18} lineHeight={23}>
<BodyText style={{ color: white, fontSize: 18, lineHeight: 23 }}>
{children}
</BodyText>
</Button>
@@ -262,14 +262,16 @@ ${deviceInfo.map(([k, v]) => `${k}=${v}`).join('; ')}
pressStyle={pressedStyle}
onPress={goToStore}
>
<BodyText color={white}>Leave an app store review</BodyText>
<BodyText style={{ color: white }}>
Leave an app store review
</BodyText>
</Button>
<XStack gap={32}>
{social.map(([Icon, href], i) => (
<SocialButton key={i} Icon={Icon} href={href} />
))}
</XStack>
<BodyText color={amber500} fontSize={15}>
<BodyText style={{ color: amber500, fontSize: 15 }}>
SELF
</BodyText>
{/* Dont remove if not viewing on ios */}

View File

@@ -4,8 +4,9 @@
import React, { useCallback } from 'react';
import { Description } from '@selfxyz/mobile-sdk-alpha/components';
import Mnemonic from '@/components/Mnemonic';
import Description from '@/components/typography/Description';
import useMnemonic from '@/hooks/useMnemonic';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';

View File

@@ -6,9 +6,12 @@ import React from 'react';
import { YStack } from 'tamagui';
import { useNavigation } from '@react-navigation/native';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import {
Description,
PrimaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import { black, white } from '@/utils/colors';
import { confirmTap } from '@/utils/haptic';

View File

@@ -8,11 +8,13 @@ import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Anchor, Text, YStack } from 'tamagui';
import {
AbstractButton,
BodyText,
Caption,
} from '@selfxyz/mobile-sdk-alpha/components';
import { AppEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import AbstractButton from '@/components/buttons/AbstractButton';
import { BodyText } from '@/components/typography/BodyText';
import { Caption } from '@/components/typography/Caption';
import { privacyUrl, termsUrl } from '@/consts/links';
import useConnectionModal from '@/hooks/useConnectionModal';
import useHapticNavigation from '@/hooks/useHapticNavigation';
@@ -64,11 +66,13 @@ const LaunchScreen: React.FC = () => {
Take control of your digital identity
</Text>
<BodyText
color={slate300}
fontSize={16}
textAlign="center"
marginHorizontal={40}
marginBottom={40}
style={{
color: slate300,
fontSize: 16,
textAlign: 'center',
marginHorizontal: 40,
marginBottom: 40,
}}
>
Self is the easiest way to verify your identity safely wherever you
are.

View File

@@ -7,10 +7,13 @@ import { styled, View, XStack, YStack } from 'tamagui';
import type { StaticScreenProps } from '@react-navigation/native';
import { useNavigation } from '@react-navigation/native';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import {
Description,
PrimaryButton,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import ModalClose from '@/images/icons/modal_close.svg';
import LogoInversed from '@/images/logo_inversed.svg';
import { white } from '@/utils/colors';
@@ -112,9 +115,11 @@ const ModalScreen: React.FC<ModalScreenProps> = ({ route: { params } }) => {
{params?.preventDismiss ? null : <ModalClose onPress={onClose} />}
</XStack>
<YStack gap={20}>
<Title textAlign="left">{params?.titleText}</Title>
<Title style={{ textAlign: 'left' }}>
{params?.titleText as React.ReactNode}
</Title>
<Description style={{ textAlign: 'left' }}>
{params?.bodyText}
{params?.bodyText as React.ReactNode}
</Description>
</YStack>
<YStack gap={12}>

View File

@@ -29,11 +29,10 @@ import {
signatureAlgorithmToStrictSignatureAlgorithm,
useSelfClient,
} from '@selfxyz/mobile-sdk-alpha';
import { Caption, PrimaryButton } from '@selfxyz/mobile-sdk-alpha/components';
import { MockDataEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import ButtonsContainer from '@/components/ButtonsContainer';
import { Caption } from '@/components/typography/Caption';
import { useMockDataForm } from '@/hooks/useMockDataForm';
import SelfDevCard from '@/images/card-dev.svg';
import IdIcon from '@/images/icons/id_icon.svg';
@@ -88,7 +87,7 @@ const MockDocumentTitleCard = () => {
<Text fontFamily={dinot} fontWeight={500} fontSize="$6" color={white}>
Generate mock document data
</Text>
<Caption fontFamily={dinot} fontSize="$5" color={zinc400}>
<Caption style={{ fontFamily: dinot, fontSize: 20, color: zinc400 }}>
Configure data parameters to generate a mock document for testing
purposes on the Self Protocol.
</Caption>

View File

@@ -14,13 +14,15 @@ import { countryCodes } from '@selfxyz/common/constants';
import { getCountryISO2 } from '@selfxyz/common/constants/countries';
import type { IdDocInput } from '@selfxyz/common/utils';
import { genMockIdDocAndInitDataParsing } from '@selfxyz/common/utils/passports';
import {
BodyText,
Description,
PrimaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { MockDataEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import ButtonsContainer from '@/components/ButtonsContainer';
import { BodyText } from '@/components/typography/BodyText';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import type { RootStackParamList } from '@/navigation';
import { storePassportData } from '@/providers/passportDataProvider';
import useUserStore from '@/stores/userStore';
@@ -196,7 +198,7 @@ const CreateMockScreenDeepLink: React.FC = () => {
>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<ActivityIndicator color={black} style={{ marginRight: 8 }} />
<Description color={black} fontWeight="bold">
<Description style={{ color: black, fontWeight: 'bold' }}>
Onboarding your Developer ID
</Description>
</View>

View File

@@ -8,12 +8,14 @@ import type { RouteProp } from '@react-navigation/native';
import { useNavigation, useRoute } from '@react-navigation/native';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import {
BodyText,
PrimaryButton,
SecondaryButton,
} from '@selfxyz/mobile-sdk-alpha/components';
import { AadhaarEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { getErrorMessages } from '@selfxyz/mobile-sdk-alpha/onboarding/import-aadhaar';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import { BodyText } from '@/components/typography/BodyText';
import WarningIcon from '@/images/warning.svg';
import { useSafeAreaInsets } from '@/mocks/react-native-safe-area-context';
import { black, slate100, slate200, slate500, white } from '@/utils/colors';
@@ -58,14 +60,16 @@ const AadhaarUploadErrorScreen: React.FC = () => {
borderBlockWidth={1}
borderBlockColor={slate200}
>
<BodyText fontSize={19} textAlign="center" color={black}>
<BodyText style={{ fontSize: 19, textAlign: 'center', color: black }}>
{title}
</BodyText>
<BodyText
marginTop={6}
fontSize={17}
textAlign="center"
color={slate500}
style={{
marginTop: 6,
fontSize: 17,
textAlign: 'center',
color: slate500,
}}
>
{description}
</BodyText>

View File

@@ -10,11 +10,10 @@ import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { BodyText, PrimaryButton } from '@selfxyz/mobile-sdk-alpha/components';
import { AadhaarEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { useAadhaar } from '@selfxyz/mobile-sdk-alpha/onboarding/import-aadhaar';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { BodyText } from '@/components/typography/BodyText';
import { useModal } from '@/hooks/useModal';
import AadhaarImage from '@/images/512w.png';
import { useSafeAreaInsets } from '@/mocks/react-native-safe-area-context';
@@ -170,17 +169,23 @@ const AadhaarUploadScreen: React.FC = () => {
borderBlockWidth={1}
borderBlockColor={slate200}
>
<BodyText fontWeight="bold" fontSize={18} textAlign="center">
<BodyText
style={{ fontWeight: 'bold', fontSize: 18, textAlign: 'center' }}
>
Generate a QR code from the mAadaar app
</BodyText>
<BodyText fontSize={16} textAlign="center" color={slate500}>
<BodyText
style={{ fontSize: 16, textAlign: 'center', color: slate500 }}
>
Save the QR code to your photo library and upload it here.
</BodyText>
<BodyText
fontSize={12}
textAlign="center"
color={slate400}
marginTop={20}
style={{
fontSize: 12,
textAlign: 'center',
color: slate400,
marginTop: 20,
}}
>
SELF DOES NOT STORE THIS INFORMATION.
</BodyText>

View File

@@ -8,10 +8,9 @@ import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { BodyText, PrimaryButton } from '@selfxyz/mobile-sdk-alpha/components';
import { AadhaarEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { BodyText } from '@/components/typography/BodyText';
import BlueCheckIcon from '@/images/blue_check.svg';
import { useSafeAreaInsets } from '@/mocks/react-native-safe-area-context';
import type { RootStackParamList } from '@/navigation';
@@ -45,14 +44,16 @@ const AadhaarUploadedSuccessScreen: React.FC = () => {
borderBlockWidth={1}
borderBlockColor={slate200}
>
<BodyText fontSize={19} textAlign="center" color={black}>
<BodyText style={{ fontSize: 19, textAlign: 'center', color: black }}>
QR code upload successful
</BodyText>
<BodyText
marginTop={6}
fontSize={17}
textAlign="center"
color={slate500}
style={{
marginTop: 6,
fontSize: 17,
textAlign: 'center',
color: slate500,
}}
>
You are ready to register your Aadhaar card with Self.
</BodyText>

View File

@@ -10,9 +10,9 @@ import { useFocusEffect } from '@react-navigation/native';
import type { PassportMetadata } from '@selfxyz/common/types';
import type { AadhaarData } from '@selfxyz/common/utils/types';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { Caption } from '@selfxyz/mobile-sdk-alpha/components';
import { DocumentEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { Caption } from '@/components/typography/Caption';
import { usePassport } from '@/providers/passportDataProvider';
import { black, slate200, white } from '@/utils/colors';
import { extraYPadding } from '@/utils/constants';
@@ -63,10 +63,8 @@ const InfoRow: React.FC<{
}> = ({ label, value }) => (
<YStack>
<XStack paddingVertical="$4" justifyContent="space-between">
<Caption size="large">{label}</Caption>
<Caption color={black} size="large">
{value}
</Caption>
<Caption style={{ fontSize: 16 }}>{label}</Caption>
<Caption style={{ color: black, fontSize: 16 }}>{value}</Caption>
</XStack>
<Separator borderColor={slate200} />
</YStack>

View File

@@ -15,10 +15,12 @@ import type {
DocumentMetadata,
} from '@selfxyz/common/utils/types';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import {
PrimaryButton,
SecondaryButton,
} from '@selfxyz/mobile-sdk-alpha/components';
import { DocumentEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import ButtonsContainer from '@/components/ButtonsContainer';
import type { RootStackParamList } from '@/navigation';
import { usePassport } from '@/providers/passportDataProvider';

View File

@@ -11,6 +11,12 @@ import {
hasAnyValidRegisteredDocument,
useSelfClient,
} from '@selfxyz/mobile-sdk-alpha';
import {
Additional,
Description,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { PassportEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import {
mrzReadInstructions,
@@ -18,12 +24,8 @@ import {
} from '@selfxyz/mobile-sdk-alpha/onboarding/read-mrz';
import passportScanAnimation from '@/assets/animations/passport_scan.json';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import { DelayedLottieView } from '@/components/DelayedLottieView';
import { PassportCamera } from '@/components/native/PassportCamera';
import Additional from '@/components/typography/Additional';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import Scan from '@/images/icons/passport_camera_scan.svg';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';

View File

@@ -4,9 +4,10 @@
import React, { useEffect } from 'react';
import { Caption } from '@selfxyz/mobile-sdk-alpha/components';
import type { TipProps } from '@/components/Tips';
import Tips from '@/components/Tips';
import { Caption } from '@/components/typography/Caption';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import Activity from '@/images/icons/activity.svg';
import PassportCameraBulb from '@/images/icons/passport_camera_bulb.svg';
@@ -60,12 +61,12 @@ const DocumentCameraTroubleScreen: React.FC = () => {
title="Having trouble scanning your ID?"
onDismiss={go}
header={
<Caption size="large" color={slate500} marginBottom={18}>
<Caption style={{ fontSize: 16, color: slate500, marginBottom: 18 }}>
Here are a few tips that might help:
</Caption>
}
footer={
<Caption size="large" color={slate500}>
<Caption size="large" style={{ color: slate500 }}>
Following these steps should help your phone's camera capture the ID
page quickly and clearly!
</Caption>

View File

@@ -9,13 +9,15 @@ import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import {
BodyText,
Description,
PrimaryButton,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import ButtonsContainer from '@/components/ButtonsContainer';
import { BodyText } from '@/components/typography/BodyText';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import type { RootStackParamList } from '@/navigation';
import { white } from '@/utils/colors';
@@ -173,7 +175,9 @@ const DocumentNFCMethodSelectionScreen: React.FC = () => {
maxLength={6}
/>
{error ? (
<Description color="red">{error}</Description>
<Description style={{ color: 'red' }}>
{error}
</Description>
) : null}
</YStack>
)}

View File

@@ -36,15 +36,17 @@ import {
hasAnyValidRegisteredDocument,
useSelfClient,
} from '@selfxyz/mobile-sdk-alpha';
import {
BodyText,
PrimaryButton,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { PassportEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import passportVerifyAnimation from '@/assets/animations/passport_verify.json';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import ButtonsContainer from '@/components/ButtonsContainer';
import TextsContainer from '@/components/TextsContainer';
import { BodyText } from '@/components/typography/BodyText';
import { Title } from '@/components/typography/Title';
import { useFeedbackAutoHide } from '@/hooks/useFeedbackAutoHide';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import NFC_IMAGE from '@/images/nfc.png';
@@ -546,7 +548,7 @@ const DocumentNFCScanScreen: React.FC = () => {
<>
<TextsContainer>
<Title children="Ready to scan" />
<BodyText textAlign="center">
<BodyText style={{ textAlign: 'center' }}>
{nfcMessage && nfcMessage.trim().length > 0 ? (
nfcMessage
) : (
@@ -588,24 +590,22 @@ const DocumentNFCScanScreen: React.FC = () => {
</GestureDetector>
{isNfcEnabled ? (
<>
<Title style={styles.title} marginTop="$2">
<Title style={[styles.title, { marginTop: 8 }]}>
Find the RFID chip in your ID
</Title>
<BodyText
style={styles.bodyText}
marginTop="$2"
marginBottom="$2"
style={[styles.bodyText, { marginTop: 8, marginBottom: 8 }]}
>
Place your phone against the chip and keep it still until
the sensor reads it.
</BodyText>
<BodyText style={styles.disclaimer} marginTop="$2">
<BodyText style={[styles.disclaimer, { marginTop: 16 }]}>
SELF DOES NOT STORE THIS INFORMATION.
</BodyText>
</>
) : (
<>
<BodyText style={styles.disclaimer} marginTop="$2">
<BodyText style={[styles.disclaimer, { marginTop: 16 }]}>
{dialogMessage}
</BodyText>
</>

View File

@@ -9,13 +9,15 @@ import {
hasAnyValidRegisteredDocument,
useSelfClient,
} from '@selfxyz/mobile-sdk-alpha';
import {
BodyText,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { PassportEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import ButtonsContainer from '@/components/ButtonsContainer';
import TextsContainer from '@/components/TextsContainer';
import { BodyText } from '@/components/typography/BodyText';
import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import NFC_IMAGE from '@/images/nfc.png';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
@@ -48,7 +50,7 @@ const DocumentNFCScanScreen: React.FC = () => {
<>
<TextsContainer>
<Title children="Ready to scan" />
<BodyText textAlign="center">TODO implement</BodyText>
<BodyText style={{ textAlign: 'center' }}>TODO implement</BodyText>
</TextsContainer>
<Image
height="$8"

View File

@@ -7,10 +7,10 @@ import { View } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import { YStack } from 'tamagui';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import { Caption, SecondaryButton } from '@selfxyz/mobile-sdk-alpha/components';
import type { TipProps } from '@/components/Tips';
import Tips from '@/components/Tips';
import { Caption } from '@/components/typography/Caption';
import { useFeedbackAutoHide } from '@/hooks/useFeedbackAutoHide';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import SimpleScrolledTitleLayout from '@/layouts/SimpleScrolledTitleLayout';
@@ -80,7 +80,7 @@ const DocumentNFCTroubleScreen: React.FC = () => {
origin: 'passport/nfc-trouble',
})
}
marginBottom={0}
style={{ marginBottom: 0 }}
>
Report Issue
</SecondaryButton>
@@ -95,13 +95,13 @@ const DocumentNFCTroubleScreen: React.FC = () => {
>
<GestureDetector gesture={devModeTap}>
<View collapsable={false}>
<Caption size="large" color={slate500}>
<Caption size="large" style={{ color: slate500 }}>
Here are some tips to help you successfully scan the RFID chip:
</Caption>
</View>
</GestureDetector>
<Tips items={tips} />
<Caption size="large" color={slate500}>
<Caption size="large" style={{ color: slate500 }}>
These steps should help improve the success rate of reading the RFID
chip in your passport. If the issue persists, double-check that your
device supports NFC and that your passport's RFID is functioning

View File

@@ -8,6 +8,11 @@ import { usePreventRemove } from '@react-navigation/native';
import type { DocumentCategory } from '@selfxyz/common/utils/types';
import { loadSelectedDocument, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import {
Description,
PrimaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import {
PassportEvents,
ProofEvents,
@@ -15,10 +20,7 @@ import {
import { getPreRegistrationDescription } from '@selfxyz/mobile-sdk-alpha/onboarding/confirm-identification';
import successAnimation from '@/assets/animations/loading/success.json';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { DelayedLottieView } from '@/components/DelayedLottieView';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import { styles } from '@/screens/verification/ProofRequestStatusScreen';
@@ -144,8 +146,8 @@ const ConfirmBelongingScreen: React.FC<ConfirmBelongingScreenProps> = () => {
paddingBottom={20}
backgroundColor={white}
>
<Title textAlign="center">Confirm your identity</Title>
<Description textAlign="center" paddingBottom={20}>
<Title style={{ textAlign: 'center' }}>Confirm your identity</Title>
<Description style={{ textAlign: 'center', paddingBottom: 20 }}>
{getPreRegistrationDescription()}
</Description>
<PrimaryButton

View File

@@ -12,10 +12,9 @@ import {
useCountries,
useSelfClient,
} from '@selfxyz/mobile-sdk-alpha';
import { BodyText, RoundFlag } from '@selfxyz/mobile-sdk-alpha/components';
import { RoundFlag } from '@/components/flag/RoundFlag';
import { DocumentFlowNavBar } from '@/components/NavBar/DocumentFlowNavBar';
import { BodyText } from '@/components/typography/BodyText';
import { black, slate100, slate500 } from '@/utils/colors';
import { advercase, dinot } from '@/utils/fonts';
import { buttonTap } from '@/utils/haptic';
@@ -45,7 +44,7 @@ const CountryItem = memo<{
>
<XStack alignItems="center" gap={16}>
<RoundFlag countryCode={countryCode} size={FLAG_SIZE} />
<BodyText fontSize={16} color={black} flex={1}>
<BodyText style={{ fontSize: 16, color: black, flex: 1 }}>
{countryName}
</BodyText>
</XStack>
@@ -126,10 +125,10 @@ const CountryPickerScreen: React.FC = () => {
<DocumentFlowNavBar title="GETTING STARTED" />
<YStack flex={1} paddingTop="$4" paddingHorizontal="$4">
<YStack marginTop="$4" marginBottom="$6">
<BodyText fontSize={29} fontFamily={advercase}>
<BodyText style={{ fontSize: 29, fontFamily: advercase }}>
Select the country that issued your ID
</BodyText>
<BodyText fontSize={16} color={slate500} marginTop="$3">
<BodyText style={{ fontSize: 16, color: slate500, marginTop: 20 }}>
Self has support for over 300 ID types. You can select the type of
ID in the next step
</BodyText>
@@ -141,11 +140,13 @@ const CountryPickerScreen: React.FC = () => {
{showSuggestion && (
<YStack marginBottom="$2">
<BodyText
fontSize={16}
color={black}
fontFamily={dinot}
letterSpacing={0.8}
marginBottom="$1"
style={{
fontSize: 16,
color: black,
fontFamily: dinot,
letterSpacing: 0.8,
marginBottom: 8,
}}
>
SUGGESTION
</BodyText>
@@ -156,11 +157,13 @@ const CountryPickerScreen: React.FC = () => {
onSelect={onPressCountry}
/>
<BodyText
fontSize={16}
color={black}
fontFamily={dinot}
letterSpacing={0.8}
marginTop="$4"
style={{
fontSize: 16,
color: black,
fontFamily: dinot,
letterSpacing: 0.8,
marginTop: 20,
}}
>
SELECT AN ISSUING COUNTRY
</BodyText>

View File

@@ -8,16 +8,18 @@ import { StyleSheet } from 'react-native';
import { SystemBars } from 'react-native-edge-to-edge';
import { useNavigation } from '@react-navigation/native';
import {
Additional,
Description,
PrimaryButton,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { PassportEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import passportOnboardingAnimation from '@/assets/animations/passport_onboarding.json';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import ButtonsContainer from '@/components/ButtonsContainer';
import TextsContainer from '@/components/TextsContainer';
import Additional from '@/components/typography/Additional';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import { black, slate100, white } from '@/utils/colors';

View File

@@ -9,14 +9,13 @@ import type { RouteProp } from '@react-navigation/native';
import { useRoute } from '@react-navigation/native';
import { SdkEvents, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { BodyText, RoundFlag } from '@selfxyz/mobile-sdk-alpha/components';
import AadhaarLogo from '@selfxyz/mobile-sdk-alpha/svgs/icons/aadhaar.svg';
import EPassportLogoRounded from '@selfxyz/mobile-sdk-alpha/svgs/icons/epassport_rounded.svg';
import PlusIcon from '@selfxyz/mobile-sdk-alpha/svgs/icons/plus.svg';
import SelfLogo from '@selfxyz/mobile-sdk-alpha/svgs/logo.svg';
import { RoundFlag } from '@/components/flag/RoundFlag';
import { DocumentFlowNavBar } from '@/components/NavBar/DocumentFlowNavBar';
import { BodyText } from '@/components/typography/BodyText';
import type { RootStackParamList } from '@/navigation';
import { black, slate100, slate300, slate400, white } from '@/utils/colors';
import { extraYPadding } from '@/utils/constants';
@@ -132,10 +131,12 @@ const IDPickerScreen: React.FC = () => {
</YStack>
</XStack>
<BodyText
marginTop="$6"
fontSize={29}
fontFamily={advercase}
textAlign="center"
style={{
marginTop: 48,
fontSize: 29,
fontFamily: advercase,
textAlign: 'center',
}}
>
Select an ID type
</BodyText>
@@ -156,10 +157,18 @@ const IDPickerScreen: React.FC = () => {
<XStack alignItems="center" gap={'$3'} flex={1}>
{getDocumentLogo(docType)}
<YStack gap={'$1'}>
<BodyText fontSize={24} fontFamily={dinot} color={black}>
<BodyText
style={{ fontSize: 24, fontFamily: dinot, color: black }}
>
{getDocumentName(docType)}
</BodyText>
<BodyText fontSize={14} fontFamily={dinot} color="#9193A2">
<BodyText
style={{
fontSize: 14,
fontFamily: dinot,
color: slate400,
}}
>
{getDocumentDescription(docType)}
</BodyText>
</YStack>
@@ -167,10 +176,12 @@ const IDPickerScreen: React.FC = () => {
</XStack>
))}
<BodyText
fontSize={18}
fontFamily={dinot}
color={slate400}
textAlign="center"
style={{
fontSize: 18,
fontFamily: dinot,
color: slate400,
textAlign: 'center',
}}
>
Be sure your document is ready to scan
</BodyText>

View File

@@ -14,7 +14,8 @@ import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { CheckSquare2, Wallet, XCircle } from '@tamagui/lucide-icons';
import { BodyText } from '@/components/typography/BodyText';
import { BodyText } from '@selfxyz/mobile-sdk-alpha/components';
import type { RootStackParamList } from '@/navigation';
import { useProofHistoryStore } from '@/stores/proofHistoryStore';
import type { ProofHistory } from '@/stores/proofTypes';
@@ -231,14 +232,18 @@ export const ProofHistoryList: React.FC<ProofHistoryListProps> = ({
/>
)}
<YStack flex={1}>
<BodyText fontSize={20} color={black} fontWeight="500">
<BodyText
style={{ fontSize: 20, color: black, fontWeight: '500' }}
>
{item.appName}
</BodyText>
<BodyText
fontFamily={plexMono}
color={slate400}
gap={2}
fontSize={14}
style={{
fontFamily: plexMono,
color: slate400,
gap: 2,
fontSize: 14,
}}
>
{formatDate(item.timestamp)}
</BodyText>

View File

@@ -15,7 +15,8 @@ import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { CheckSquare2, Wallet, XCircle } from '@tamagui/lucide-icons';
import { BodyText } from '@/components/typography/BodyText';
import { BodyText } from '@selfxyz/mobile-sdk-alpha/components';
import type { RootStackParamList } from '@/navigation';
import { useProofHistoryStore } from '@/stores/proofHistoryStore';
import type { ProofHistory } from '@/stores/proofTypes';
@@ -238,10 +239,12 @@ const ProofHistoryScreen: React.FC = () => {
/>
)}
<YStack flex={1}>
<BodyText fontSize={20} color={black} fontWeight="500">
<BodyText
style={{ fontSize: 20, color: black, fontWeight: '500' }}
>
{item.appName}
</BodyText>
<BodyText color={slate300} gap={2} fontSize={14}>
<BodyText style={{ color: slate300, fontSize: 14 }}>
{formatDate(item.timestamp)}
</BodyText>
</YStack>

View File

@@ -7,13 +7,15 @@ import { YStack } from 'tamagui';
import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import {
Description,
PrimaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { BackupEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import proofSuccessAnimation from '@/assets/animations/proof_success.json';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { DelayedLottieView } from '@/components/DelayedLottieView';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import type { RootStackParamList } from '@/navigation';
import { styles } from '@/screens/verification/ProofRequestStatusScreen';

View File

@@ -8,13 +8,15 @@ import { YStack } from 'tamagui';
import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import {
Caution,
PrimaryButton,
SubHeader,
} from '@selfxyz/mobile-sdk-alpha/components';
import { AppEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import warningAnimation from '@/assets/animations/warning.json';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { DelayedLottieView } from '@/components/DelayedLottieView';
import Caution from '@/components/typography/Caution';
import { SubHeader } from '@/components/typography/SubHeader';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import type { RootStackParamList } from '@/navigation';
import { useSettingStore } from '@/stores/settingStore';

View File

@@ -4,12 +4,15 @@
import React, { useCallback, useState } from 'react';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import {
Caption,
Description,
PrimaryButton,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import Mnemonic from '@/components/Mnemonic';
import { Caption } from '@/components/typography/Caption';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import useMnemonic from '@/hooks/useMnemonic';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
@@ -42,10 +45,10 @@ const SaveRecoveryPhraseScreen: React.FC = () => {
justifyContent="space-between"
gap={10}
>
<Title paddingTop={20} textAlign="center">
<Title style={{ paddingTop: 20, textAlign: 'center' }}>
Save your recovery phrase
</Title>
<Description paddingBottom={10}>
<Description style={{ paddingBottom: 10 }}>
This phrase is the only way to recover your account. Keep it secret,
keep it safe.
</Description>
@@ -56,7 +59,7 @@ const SaveRecoveryPhraseScreen: React.FC = () => {
backgroundColor={white}
>
<Mnemonic words={mnemonic} onRevealWords={onRevealWords} />
<Caption color={slate400}>
<Caption style={{ color: slate400 }}>
You can reveal your recovery phrase in settings.
</Caption>
<PrimaryButton onPress={onCloudBackupPress}>

View File

@@ -12,13 +12,15 @@ import {
hasAnyValidRegisteredDocument,
useSelfClient,
} from '@selfxyz/mobile-sdk-alpha';
import {
BodyText,
PrimaryButton,
RoundFlag,
SecondaryButton,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { PassportEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { SecondaryButton } from '@/components/buttons/SecondaryButton';
import { RoundFlag } from '@/components/flag/RoundFlag';
import { BodyText } from '@/components/typography/BodyText';
import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import analytics from '@/utils/analytics';
@@ -135,30 +137,36 @@ const ComingSoonScreen: React.FC<ComingSoonScreenProps> = ({ route }) => {
)}
</XStack>
<Title
fontSize={32}
textAlign="center"
color={black}
marginBottom={16}
style={{
fontSize: 32,
textAlign: 'center',
color: black,
marginBottom: 16,
}}
>
Coming Soon
</Title>
<BodyText
fontSize={17}
textAlign="center"
color={black}
marginBottom={10}
paddingHorizontal={10}
style={{
fontSize: 17,
textAlign: 'center',
color: black,
marginBottom: 10,
paddingHorizontal: 10,
}}
>
{documentTypeText
? `We're working to roll out support for ${documentTypeText} in ${countryName}.`
: `We're working to roll out support in ${countryName}.`}
</BodyText>
<BodyText
fontSize={17}
textAlign="center"
color={slate500}
marginBottom={40}
paddingHorizontal={10}
style={{
fontSize: 17,
textAlign: 'center',
color: slate500,
marginBottom: 40,
paddingHorizontal: 10,
}}
>
Sign up for live updates.
</BodyText>

View File

@@ -11,16 +11,18 @@ import { ScrollView, Spinner } from 'tamagui';
import { useIsFocused } from '@react-navigation/native';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import {
BodyText,
Description,
PrimaryButton,
Title,
typography,
} from '@selfxyz/mobile-sdk-alpha/components';
import { ProofEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import loadingAnimation from '@/assets/animations/loading/misc.json';
import failAnimation from '@/assets/animations/proof_failed.json';
import succesAnimation from '@/assets/animations/proof_success.json';
import { PrimaryButton } from '@/components/buttons/PrimaryButton';
import { BodyText } from '@/components/typography/BodyText';
import Description from '@/components/typography/Description';
import { typography } from '@/components/typography/styles';
import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import { useProofHistoryStore } from '@/stores/proofHistoryStore';

View File

@@ -24,13 +24,15 @@ import { Eye, EyeOff } from '@tamagui/lucide-icons';
import type { SelfAppDisclosureConfig } from '@selfxyz/common/utils/appType';
import { formatEndpoint } from '@selfxyz/common/utils/scope';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import {
BodyText,
Caption,
HeldPrimaryButtonProveScreen,
} from '@selfxyz/mobile-sdk-alpha/components';
import { ProofEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import miscAnimation from '@/assets/animations/loading/misc.json';
import { HeldPrimaryButtonProveScreen } from '@/components/buttons/HeldPrimaryButtonProveScreen';
import Disclosures from '@/components/Disclosures';
import { BodyText } from '@/components/typography/BodyText';
import { Caption } from '@/components/typography/Caption';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import type { RootStackParamList } from '@/navigation';
import {
@@ -238,10 +240,14 @@ const ProveScreen: React.FC = () => {
objectFit="contain"
/>
)}
<BodyText fontSize={12} color={slate300} marginBottom={20}>
<BodyText
style={{ fontSize: 12, color: slate300, marginBottom: 20 }}
>
{url}
</BodyText>
<BodyText fontSize={24} color={slate300} textAlign="center">
<BodyText
style={{ fontSize: 24, color: slate300, textAlign: 'center' }}
>
<Text color={white}>{selectedApp.appName}</Text> is requesting
that you prove the following information:
</BodyText>
@@ -267,10 +273,12 @@ const ProveScreen: React.FC = () => {
{formattedUserId && (
<View marginTop={20} paddingHorizontal={20}>
<BodyText
fontSize={16}
color={black}
fontWeight="600"
marginBottom={10}
style={{
fontSize: 16,
color: black,
fontWeight: '600',
marginBottom: 10,
}}
>
{selectedApp?.userIdType === 'hex'
? 'Connected Wallet'
@@ -294,15 +302,16 @@ const ProveScreen: React.FC = () => {
marginRight={selectedApp?.userIdType === 'hex' ? 12 : 0}
>
<BodyText
fontSize={14}
color={black}
lineHeight={20}
fontFamily={
showFullAddress && selectedApp?.userIdType === 'hex'
? 'monospace'
: 'normal'
}
flexWrap={showFullAddress ? 'wrap' : 'nowrap'}
style={{
fontSize: 14,
color: black,
lineHeight: 20,
...(showFullAddress &&
selectedApp?.userIdType === 'hex'
? { fontFamily: 'monospace' }
: {}),
flexWrap: showFullAddress ? 'wrap' : 'nowrap',
}}
>
{selectedApp?.userIdType === 'hex' && showFullAddress
? selectedApp.userId
@@ -321,10 +330,12 @@ const ProveScreen: React.FC = () => {
</XStack>
{selectedApp?.userIdType === 'hex' && (
<BodyText
fontSize={12}
color={black}
opacity={0.6}
marginTop={4}
style={{
fontSize: 12,
color: black,
opacity: 0.6,
marginTop: 4,
}}
>
{showFullAddress
? 'Tap to hide address'
@@ -340,10 +351,12 @@ const ProveScreen: React.FC = () => {
{selectedApp?.userDefinedData && (
<View marginTop={20} paddingHorizontal={20}>
<BodyText
fontSize={16}
color={black}
fontWeight="600"
marginBottom={10}
style={{
fontSize: 16,
color: black,
fontWeight: '600',
marginBottom: 10,
}}
>
Additional Information:
</BodyText>
@@ -353,7 +366,9 @@ const ProveScreen: React.FC = () => {
borderRadius={8}
marginBottom={10}
>
<BodyText fontSize={14} color={black} lineHeight={20}>
<BodyText
style={{ fontSize: 14, color: black, lineHeight: 20 }}
>
{selectedApp.userDefinedData}
</BodyText>
</View>
@@ -362,12 +377,14 @@ const ProveScreen: React.FC = () => {
<View marginTop={20}>
<Caption
textAlign="center"
size="small"
marginBottom={20}
marginTop={10}
borderRadius={4}
paddingBottom={20}
style={{
textAlign: 'center',
fontSize: 12,
marginBottom: 20,
marginTop: 10,
borderRadius: 4,
paddingBottom: 20,
}}
>
Self will confirm that these details are accurate and none of your
confidential info will be revealed to {selectedApp?.appName}

View File

@@ -4,9 +4,10 @@
import React, { useEffect } from 'react';
import { Caption } from '@selfxyz/mobile-sdk-alpha/components';
import type { TipProps } from '@/components/Tips';
import Tips from '@/components/Tips';
import { Caption } from '@/components/typography/Caption';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import SimpleScrolledTitleLayout from '@/layouts/SimpleScrolledTitleLayout';
import { flushAllAnalytics } from '@/utils/analytics';
@@ -55,7 +56,7 @@ const QRCodeTrouble: React.FC = () => {
title="Having trouble scanning the QR code?"
onDismiss={go}
>
<Caption size="large" color={slate500}>
<Caption size="large" style={{ color: slate500 }}>
Here are some tips to help you successfully scan the QR code:
</Caption>
<Tips items={tips} />

View File

@@ -14,14 +14,16 @@ import {
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import {
Additional,
Description,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { ProofEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import qrScanAnimation from '@/assets/animations/qr_scan.json';
import type { QRCodeScannerViewProps } from '@/components/native/QRCodeScanner';
import { QRCodeScannerView } from '@/components/native/QRCodeScanner';
import Additional from '@/components/typography/Additional';
import Description from '@/components/typography/Description';
import { Title } from '@/components/typography/Title';
import useConnectionModal from '@/hooks/useConnectionModal';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import QRScan from '@/images/icons/qr_code.svg';