diff --git a/.vscode/styles.code-snippets b/.vscode/styles.code-snippets index 69cb2b20ee..2ac627e2c5 100644 --- a/.vscode/styles.code-snippets +++ b/.vscode/styles.code-snippets @@ -10,7 +10,7 @@ "prepareStyle() with Props": { "prefix": "@prepareStyle_props", "body": [ - "interface ${1/(.)/${1:/upcase}/}StyleProps {${3}}", + "type ${1/(.)/${1:/upcase}/}StyleProps = {${3}}", "", "const ${1}Style = prepareStyle${2}<${1/(.)/${1:/upcase}/}StyleProps>((utils, {${4}}) => ({${0}}));" ] @@ -18,7 +18,7 @@ "prepareNativeStyle() with Props": { "prefix": "@prepareNativeStyle_props", "body": [ - "interface ${1/(.)/${1:/upcase}/}StyleProps {${3}}", + "type ${1/(.)/${1:/upcase}/}StyleProps = {${3}}", "", "const ${1}Style = prepareNativeStyle${2}<${1/(.)/${1:/upcase}/}StyleProps>((utils, {${4}}) => ({${0}}));" ] @@ -29,14 +29,14 @@ }, "useStyles() for React Native": { "prefix": "@useStyles_native", - "body": "const { applyNativeStyle } = useStyles${0}();" + "body": "const { applyStyle } = useNativeStyles${0}();" }, "applyStyle()": { "prefix": "@applyStyle", "body": "className={applyStyle(${0})}" }, - "applyNativeStyle()": { - "prefix": "@applyNativeStyle", - "body": "style={applyNativeStyle(${0})}" + "applyStyle() for React Native": { + "prefix": "@applyStyle", + "body": "style={applyStyle(${0})}" } } diff --git a/package.json b/package.json index 00de585584..cfe330a10e 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,8 @@ "@types/react-native": "0.67.6", "typescript": "4.5.5", "react-native": "0.68.0", - "prettier": "2.5.1" + "prettier": "2.5.1", + "type-fest": "2.12.2" }, "devDependencies": { "@babel/cli": "^7.13.14", diff --git a/packages/atoms/jest.config.js b/packages/atoms/jest.config.js new file mode 100644 index 0000000000..aadfd322e9 --- /dev/null +++ b/packages/atoms/jest.config.js @@ -0,0 +1,3 @@ +export default { + preset: '../../jest.config.base.js', +}; diff --git a/packages/atoms/package.json b/packages/atoms/package.json new file mode 100644 index 0000000000..bd650d4cf9 --- /dev/null +++ b/packages/atoms/package.json @@ -0,0 +1,21 @@ +{ + "name": "@trezor/atoms", + "version": "1.0.0", + "private": true, + "license": "See LICENSE.md in repo root", + "sideEffects": false, + "type": "module", + "main": "src/index", + "scripts": { + "lint": "eslint '**/*.{ts,tsx,js}'", + "test:unit": "jest", + "type-check": "tsc --build" + }, + "dependencies": { + "@mobily/ts-belt": "^3.11.0", + "@trezor/styles": "*", + "@trezor/theme": "*", + "react-native": "*", + "type-fest": "^2.12.2" + } +} diff --git a/packages/atoms/src/Box.tsx b/packages/atoms/src/Box.tsx new file mode 100644 index 0000000000..cba9ec8c39 --- /dev/null +++ b/packages/atoms/src/Box.tsx @@ -0,0 +1,62 @@ +import { D, pipe } from '@mobily/ts-belt'; +import { NativeStyleObject, prepareNativeStyle, useNativeStyles } from '@trezor/styles'; +import { Spacing } from '@trezor/theme'; +import React from 'react'; +import { View, ViewProps, ViewStyle } from 'react-native'; + +const layoutStylePropsKeys = [ + 'flex', + 'flexDirection', + 'justifyContent', + 'alignItems', + 'alignContent', + 'alignSelf', +] as const; + +const spacingStylePropsKeys = [ + 'marginHorizontal', + 'marginVertical', + 'marginTop', + 'marginRight', + 'marginBottom', + 'marginLeft', + + 'paddingHorizontal', + 'paddingVertical', + 'paddingTop', + 'paddingRight', + 'paddingBottom', + 'paddingLeft', +] as const; + +type SpacingStyleProps = Partial>; +type LayoutStyleProps = Partial>; + +export interface BoxProps extends Omit, LayoutStyleProps, SpacingStyleProps { + style?: NativeStyleObject; +} + +type BoxStyleProps = Record & LayoutStyleProps; + +const boxStyle = prepareNativeStyle((_utils, { ...styles }) => ({ + ...styles, +})); + +export const Box = ({ style, ...props }: BoxProps) => { + const { applyStyle, utils } = useNativeStyles(); + + const layoutStyles = D.selectKeys(props, [...layoutStylePropsKeys]); + const spacingStyles = pipe( + props, + D.selectKeys([...spacingStylePropsKeys]), + D.map(spacing => (spacing ? utils.spacings[spacing] : 0)), + ); + const otherProps = D.deleteKeys(props, [...layoutStylePropsKeys, ...spacingStylePropsKeys]); + + return ( + + ); +}; diff --git a/packages/atoms/src/Button.tsx b/packages/atoms/src/Button.tsx new file mode 100644 index 0000000000..7b535c11c3 --- /dev/null +++ b/packages/atoms/src/Button.tsx @@ -0,0 +1,78 @@ +import React from 'react'; +import { NativeStyleObject, prepareNativeStyle, useNativeStyles } from '@trezor/styles'; +import { Pressable, PressableProps } from 'react-native'; +import { Text } from './Text'; +import { Color } from '@trezor/theme'; + +type ButtonSize = 'sm' | 'md' | 'lg'; +type ButtonColorScheme = 'primary' | 'gray'; + +export interface ButtonProps extends Omit { + size: ButtonSize; + colorScheme: ButtonColorScheme; + style?: NativeStyleObject; +} + +type ButtonStyleProps = { + size: ButtonSize; + colorScheme: ButtonColorScheme; +}; + +const buttonStyle = prepareNativeStyle((utils, { size, colorScheme }) => { + const buttonSizeStyles: Record = { + sm: { + height: 36, + paddingVertical: utils.spacings.sm, + paddingHorizontal: 12, + borderRadius: utils.borders.radii.basic, + }, + md: { + height: 44, + paddingVertical: 10, + paddingHorizontal: utils.spacings.md, + borderRadius: utils.borders.radii.basic, + }, + lg: { + height: 58, + paddingVertical: 17, + paddingHorizontal: utils.spacings.md, + borderRadius: utils.borders.radii.large, + }, + }; + + const buttonColorSchemeStyles: Record = { + primary: { + backgroundColor: utils.colors.green, + }, + gray: { + backgroundColor: utils.colors.gray300, + }, + }; + + return { + flexDirection: 'row', + ...buttonSizeStyles[size], + ...buttonColorSchemeStyles[colorScheme], + }; +}); + +const buttonColorSchemeFontColor: Record = { + primary: 'white', + gray: 'gray700', +}; + +export const Button = ({ size, style, colorScheme, children, ...props }: ButtonProps) => { + const { applyStyle } = useNativeStyles(); + + return ( + + + {children} + + + ); +}; diff --git a/packages/atoms/src/Text.tsx b/packages/atoms/src/Text.tsx new file mode 100644 index 0000000000..75c1647748 --- /dev/null +++ b/packages/atoms/src/Text.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { Text as RNText, TextProps as RNTextProps, TextStyle } from 'react-native'; +import { useNativeStyles, prepareNativeStyle, NativeStyleObject } from '@trezor/styles'; +import { Color, TypographyStyle } from '@trezor/theme'; + +interface TextProps extends Omit { + variant?: TypographyStyle; + color?: Color; + align?: TextStyle['textAlign']; + style?: NativeStyleObject; +} + +type TextStyleProps = { + variant: TypographyStyle; + color: Color; + align: TextStyle['textAlign']; +}; + +const textStyle = prepareNativeStyle((utils, { variant, color, align }) => ({ + ...utils.typography[variant], + color: utils.colors[color], + textAlign: align, +})); + +export const Text = ({ + variant = 'body', + color = 'black', + align = 'left', + style, + ...otherProps +}: TextProps) => { + const { applyStyle } = useNativeStyles(); + + return ( + + ); +}; diff --git a/packages/atoms/src/index.ts b/packages/atoms/src/index.ts new file mode 100644 index 0000000000..6929ec936d --- /dev/null +++ b/packages/atoms/src/index.ts @@ -0,0 +1,3 @@ +export * from './Text'; +export * from './Box'; +export * from './Button'; diff --git a/packages/atoms/tsconfig.json b/packages/atoms/tsconfig.json new file mode 100644 index 0000000000..c3ec5f5d2a --- /dev/null +++ b/packages/atoms/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { "outDir": "libDev" }, + "references": [ + { "path": "../styles" }, + { "path": "../theme" } + ] +} diff --git a/packages/styles/package.json b/packages/styles/package.json index 4927e0da11..ea25d2c1ac 100644 --- a/packages/styles/package.json +++ b/packages/styles/package.json @@ -12,7 +12,7 @@ "test:unit": "jest" }, "dependencies": { - "@mobily/ts-belt": "^3.10.0", + "@mobily/ts-belt": "^3.11.0", "@trezor/theme": "*", "@types/react-native": "*", "css-in-js-utils": "^3.1.0", diff --git a/packages/suite-native/README.md b/packages/suite-native/README.md index 4377ac67bd..1427a23a08 100644 --- a/packages/suite-native/README.md +++ b/packages/suite-native/README.md @@ -36,3 +36,8 @@ Best way how to debug app is download [Flipper](https://fbflipper.com). ## Dependencies, version locks 1. `simple-plist` - some internal dependency of RN want to use version `1.3.0`, but in this version is some error that dependabot doesn't like. Error is not valid for us, but adding `1.3.1` to dev dependencies will fix this warning. + +## Updating fonts + +1. Place updated fonts to `packages/theme/fonts` +2. Run `yarn react-native link` diff --git a/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-Bold.otf b/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-Bold.otf new file mode 100644 index 0000000000..725499ec84 Binary files /dev/null and b/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-Bold.otf differ diff --git a/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-DemiBold.otf b/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-DemiBold.otf new file mode 100644 index 0000000000..ad60e7e90e Binary files /dev/null and b/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-DemiBold.otf differ diff --git a/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-Medium.otf b/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-Medium.otf new file mode 100644 index 0000000000..f637264f43 Binary files /dev/null and b/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-Medium.otf differ diff --git a/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-Regular.otf b/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-Regular.otf new file mode 100644 index 0000000000..36747efff9 Binary files /dev/null and b/packages/suite-native/android/app/src/main/assets/fonts/TTSatoshi-Regular.otf differ diff --git a/packages/suite-native/ios/TrezorSuite.xcodeproj/project.pbxproj b/packages/suite-native/ios/TrezorSuite.xcodeproj/project.pbxproj index c427109081..da8e939240 100644 --- a/packages/suite-native/ios/TrezorSuite.xcodeproj/project.pbxproj +++ b/packages/suite-native/ios/TrezorSuite.xcodeproj/project.pbxproj @@ -14,6 +14,10 @@ 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 7699B88040F8A987B510C191 /* libPods-TrezorSuite-TrezorSuiteTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-TrezorSuite-TrezorSuiteTests.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; + E603FAB37886431ABE0590DC /* TTSatoshi-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 92AC1F3110C34E2F8264BEAE /* TTSatoshi-Bold.otf */; }; + AE19C8EA249F4BC29A82736A /* TTSatoshi-DemiBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8BCDC7530653430F8480AEF1 /* TTSatoshi-DemiBold.otf */; }; + 5EA58567F7C34D4BB4135E94 /* TTSatoshi-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = A0E40F5120CB4E82AF6C1CA0 /* TTSatoshi-Medium.otf */; }; + B4528AB09CC346C49EB6347E /* TTSatoshi-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 69A6D83EFA4747F2BABDFD0A /* TTSatoshi-Regular.otf */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -44,6 +48,10 @@ 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = TrezorSuite/LaunchScreen.storyboard; sourceTree = ""; }; 89C6BE57DB24E9ADA2F236DE /* Pods-TrezorSuite-TrezorSuiteTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrezorSuite-TrezorSuiteTests.release.xcconfig"; path = "Target Support Files/Pods-TrezorSuite-TrezorSuiteTests/Pods-TrezorSuite-TrezorSuiteTests.release.xcconfig"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; + 92AC1F3110C34E2F8264BEAE /* TTSatoshi-Bold.otf */ = {isa = PBXFileReference; name = "TTSatoshi-Bold.otf"; path = "../../theme/fonts/TTSatoshi-Bold.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 8BCDC7530653430F8480AEF1 /* TTSatoshi-DemiBold.otf */ = {isa = PBXFileReference; name = "TTSatoshi-DemiBold.otf"; path = "../../theme/fonts/TTSatoshi-DemiBold.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + A0E40F5120CB4E82AF6C1CA0 /* TTSatoshi-Medium.otf */ = {isa = PBXFileReference; name = "TTSatoshi-Medium.otf"; path = "../../theme/fonts/TTSatoshi-Medium.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 69A6D83EFA4747F2BABDFD0A /* TTSatoshi-Regular.otf */ = {isa = PBXFileReference; name = "TTSatoshi-Regular.otf"; path = "../../theme/fonts/TTSatoshi-Regular.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -122,6 +130,7 @@ 83CBBA001A601CBA00E9B192 /* Products */, 2D16E6871FA4F8E400B85C8A /* Frameworks */, BBD78D7AC51CEA395F1C20DB /* Pods */, + 80736439959D441D9BCFB197 /* Resources */, ); indentWidth = 2; sourceTree = ""; @@ -148,6 +157,18 @@ path = Pods; sourceTree = ""; }; + 80736439959D441D9BCFB197 /* Resources */ = { + isa = "PBXGroup"; + children = ( + 92AC1F3110C34E2F8264BEAE /* TTSatoshi-Bold.otf */, + 8BCDC7530653430F8480AEF1 /* TTSatoshi-DemiBold.otf */, + A0E40F5120CB4E82AF6C1CA0 /* TTSatoshi-Medium.otf */, + 69A6D83EFA4747F2BABDFD0A /* TTSatoshi-Regular.otf */, + ); + name = Resources; + sourceTree = ""; + path = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -244,6 +265,10 @@ files = ( 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, + E603FAB37886431ABE0590DC /* TTSatoshi-Bold.otf in Resources */, + AE19C8EA249F4BC29A82736A /* TTSatoshi-DemiBold.otf in Resources */, + 5EA58567F7C34D4BB4135E94 /* TTSatoshi-Medium.otf in Resources */, + B4528AB09CC346C49EB6347E /* TTSatoshi-Regular.otf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/packages/suite-native/ios/TrezorSuite/Info.plist b/packages/suite-native/ios/TrezorSuite/Info.plist index 036e136265..4c4e18a60a 100644 --- a/packages/suite-native/ios/TrezorSuite/Info.plist +++ b/packages/suite-native/ios/TrezorSuite/Info.plist @@ -36,7 +36,7 @@ NSLocationWhenInUseUsageDescription - + UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities @@ -51,5 +51,12 @@ UIViewControllerBasedStatusBarAppearance + UIAppFonts + + TTSatoshi-Bold.otf + TTSatoshi-DemiBold.otf + TTSatoshi-Medium.otf + TTSatoshi-Regular.otf + diff --git a/packages/suite-native/package.json b/packages/suite-native/package.json index ce81b4d545..79a0f8427e 100644 --- a/packages/suite-native/package.json +++ b/packages/suite-native/package.json @@ -14,7 +14,10 @@ "pods": "npx pod-install" }, "dependencies": { + "@trezor/atoms": "*", "@trezor/transport-native": "*", + "@trezor/styles": "*", + "@trezor/theme": "*", "node-libs-browser": "^2.2.1", "react": "17.0.2", "react-native": "0.68.0", diff --git a/packages/suite-native/react-native.config.js b/packages/suite-native/react-native.config.js new file mode 100644 index 0000000000..8a1f4a359f --- /dev/null +++ b/packages/suite-native/react-native.config.js @@ -0,0 +1,7 @@ +module.exports = { + project: { + ios: {}, + android: {}, + }, + assets: ['../theme/fonts/'], +}; diff --git a/packages/suite-native/src/App.tsx b/packages/suite-native/src/App.tsx index 98fc4c74bf..f0a2df4033 100644 --- a/packages/suite-native/src/App.tsx +++ b/packages/suite-native/src/App.tsx @@ -1,124 +1,18 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { - Button, - SafeAreaView, - ScrollView, - StatusBar, - StyleSheet, - Text, - View, - useColorScheme, -} from 'react-native'; +import React from 'react'; -import { Colors, Header } from 'react-native/Libraries/NewAppScreen'; -import TrezorConnect from 'trezor-connect'; +import { StylesProvider, createRenderer } from '@trezor/styles'; +import { prepareNativeTheme } from '@trezor/theme'; -const styles = StyleSheet.create({ - sectionContainer: { - marginTop: 32, - paddingHorizontal: 24, - }, - sectionTitle: { - fontSize: 24, - fontWeight: '600', - }, - sectionDescription: { - marginTop: 8, - fontSize: 18, - fontWeight: '400', - }, - highlight: { - fontWeight: '700', - }, -}); +import { Home } from './screens/Home'; -const Section = ({ children, title }: any) => { - const isDarkMode = useColorScheme() === 'dark'; - return ( - - - {title} - - - {children} - - - ); -}; - -const connectOptions = { - transportReconnect: true, - debug: true, - manifest: { - email: 'info@trezor.io', - appUrl: '@trezor/suite', - }, -}; +const renderer = createRenderer(); export const App = () => { - const isDarkMode = useColorScheme() === 'dark'; - const [connectStatus, setConnectStatus] = useState(''); - const [deviceState, setDeviceState] = useState(''); - - const backgroundStyle = { - backgroundColor: isDarkMode ? Colors.darker : Colors.lighter, - }; - - const getFeatures = useCallback(() => { - console.log('getting features'); - TrezorConnect.getDeviceState() - .then(state => { - setDeviceState(JSON.stringify(state)); - console.log(state); - }) - .catch(error => { - console.log(`get device state failed ${JSON.stringify(error)}`); - }); - }, []); - - useEffect(() => { - TrezorConnect.init(connectOptions) - .then(result => { - setConnectStatus('Init OK'); - console.log(result); - getFeatures(); - }) - .catch(error => { - setConnectStatus(`Init failed ${JSON.stringify(error.code)}`); - }); - }, [getFeatures]); + const theme = prepareNativeTheme({ colorVariant: 'standard' }); return ( - - - -
- -
{connectStatus}
-
-
-
- - + + + ); }; diff --git a/packages/suite-native/src/screens/Home.tsx b/packages/suite-native/src/screens/Home.tsx new file mode 100644 index 0000000000..11503ae130 --- /dev/null +++ b/packages/suite-native/src/screens/Home.tsx @@ -0,0 +1,110 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { Platform, SafeAreaView, ScrollView, StatusBar, useColorScheme, View } from 'react-native'; + +import { Text, Box, Button } from '@trezor/atoms'; +import { prepareNativeStyle, useNativeStyles } from '@trezor/styles'; +import TrezorConnect from 'trezor-connect'; + +const backgroundStyle = prepareNativeStyle<{ isDarkMode: boolean }>( + ({ colors, spacings }, { isDarkMode }) => ({ + backgroundColor: isDarkMode ? colors.black : colors.white, + padding: spacings.lg, + marginTop: 0, + }), +); + +const connectOptions = { + transportReconnect: true, + debug: true, + manifest: { + email: 'info@trezor.io', + appUrl: '@trezor/suite', + }, +}; + +export const Home = () => { + const isDarkMode = useColorScheme() === 'dark'; + const [connectStatus, setConnectStatus] = useState(''); + const [deviceState, setDeviceState] = useState(''); + const { applyStyle } = useNativeStyles(); + + const getFeatures = useCallback(() => { + console.log('getting features'); + TrezorConnect.getDeviceState() + .then(state => { + setDeviceState(`${Math.random()} ${JSON.stringify(state)}`); + }) + .catch(error => { + console.log(`get device state failed ${JSON.stringify(error)}}`); + setDeviceState(`${Math.random()}`); + }); + }, []); + + useEffect(() => { + // prevent errors spam on iOS + if (Platform.OS === 'android') { + TrezorConnect.init(connectOptions) + .then(result => { + setConnectStatus('Init OK'); + console.log(result); + getFeatures(); + }) + .catch(error => { + setConnectStatus(`Init failed ${JSON.stringify(error.code)}`); + }); + } + }, [getFeatures]); + console.log('rerender Home'); + + return ( + + + + + + Title Large + + + Title Medium + + + Title Small + + + Highlight + + + Body + + + Callout + + + Hint + + + Label + + + + + + + Connect status: + {connectStatus} + + + + Device features: {deviceState} + + + + ); +}; diff --git a/packages/suite-native/tsconfig.json b/packages/suite-native/tsconfig.json index 8533757c21..ad95d2280d 100644 --- a/packages/suite-native/tsconfig.json +++ b/packages/suite-native/tsconfig.json @@ -2,7 +2,10 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "libDev" }, "references": [ - { "path": "../transport-native" } + { "path": "../atoms" }, + { "path": "../transport-native" }, + { "path": "../styles" }, + { "path": "../theme" } ], "include": [".", "**.json"] } diff --git a/packages/theme/README.md b/packages/theme/README.md index b5584afce8..175bc3e3c2 100644 --- a/packages/theme/README.md +++ b/packages/theme/README.md @@ -7,6 +7,10 @@ You can find Figma files for this theme here: - [colors](https://www.figma.com/file/YIFzn2vuwktwV4GzZClrYx/%5Bs2.0%5D-Trezor-Colors?node-id=0%3A1) - [font, borders, shadows...](https://www.figma.com/file/Z6AGVUmKQzLNtDozFamW7f/s2-Mobile?node-id=37%3A757) +# Fonts for React Native app + +If you want to update fonts, place new fonts to `./fonts` folder in this package and then follow guide in [suite-native README](../suite-native/README.md). + ### Older themes For older themes (v1, v1.5) you can check `@trezor/components` package. diff --git a/packages/theme/fonts/TTSatoshi-Bold.otf b/packages/theme/fonts/TTSatoshi-Bold.otf new file mode 100644 index 0000000000..725499ec84 Binary files /dev/null and b/packages/theme/fonts/TTSatoshi-Bold.otf differ diff --git a/packages/theme/fonts/TTSatoshi-DemiBold.otf b/packages/theme/fonts/TTSatoshi-DemiBold.otf new file mode 100644 index 0000000000..ad60e7e90e Binary files /dev/null and b/packages/theme/fonts/TTSatoshi-DemiBold.otf differ diff --git a/packages/theme/fonts/TTSatoshi-Medium.otf b/packages/theme/fonts/TTSatoshi-Medium.otf new file mode 100644 index 0000000000..f637264f43 Binary files /dev/null and b/packages/theme/fonts/TTSatoshi-Medium.otf differ diff --git a/packages/theme/fonts/TTSatoshi-Regular.otf b/packages/theme/fonts/TTSatoshi-Regular.otf new file mode 100644 index 0000000000..36747efff9 Binary files /dev/null and b/packages/theme/fonts/TTSatoshi-Regular.otf differ diff --git a/packages/theme/src/borders.ts b/packages/theme/src/borders.ts index 15bbaf9350..c726865ef9 100644 --- a/packages/theme/src/borders.ts +++ b/packages/theme/src/borders.ts @@ -20,7 +20,8 @@ export const nativeBorders = { lg: 2, }, radii: { - basic: 5, + basic: 8, + large: 16, round: '50%', }, } as const; diff --git a/packages/theme/src/colors.ts b/packages/theme/src/colors.ts index a518db0473..31ed0a7cc3 100644 --- a/packages/theme/src/colors.ts +++ b/packages/theme/src/colors.ts @@ -28,7 +28,7 @@ export type Color = keyof typeof defaultColorVariant; export type Colors = Record; -export const colorVariants: Record = { +export const colorVariants = { standard: { ...defaultColorVariant, }, diff --git a/packages/theme/src/fontFamilies.ts b/packages/theme/src/fontFamilies.ts index f979998b3c..588a7af76a 100644 --- a/packages/theme/src/fontFamilies.ts +++ b/packages/theme/src/fontFamilies.ts @@ -5,7 +5,7 @@ export const fontFamilies = { export type FontFamilies = typeof fontFamilies; export const nativeFontFamilies: Record = { - base: 'TT Satoshi', + base: 'TTSatoshi-Regular', } as const; export type NativeFontFamilies = typeof nativeFontFamilies; diff --git a/packages/theme/src/fontWeights.ts b/packages/theme/src/fontWeights.ts new file mode 100644 index 0000000000..f177a75c84 --- /dev/null +++ b/packages/theme/src/fontWeights.ts @@ -0,0 +1,8 @@ +// RN require font weight to be string +export const fontWeights = { + medium: '500', + semiBold: '600', +} as const; + +export type FontWeight = keyof typeof fontWeights; +export type FontWeightValue = typeof fontWeights[FontWeight]; diff --git a/packages/theme/src/index.ts b/packages/theme/src/index.ts index 98c7c1e11f..185425d71b 100644 --- a/packages/theme/src/index.ts +++ b/packages/theme/src/index.ts @@ -2,6 +2,7 @@ export * from './borders'; export * from './boxShadows'; export * from './colors'; export * from './fontFamilies'; +export * from './fontWeights'; export * from './typography'; export * from './sizes'; export * from './spacings'; diff --git a/packages/theme/src/spacings.ts b/packages/theme/src/spacings.ts index 9c31118300..80dad8b3d5 100644 --- a/packages/theme/src/spacings.ts +++ b/packages/theme/src/spacings.ts @@ -8,7 +8,7 @@ export const spacings = { export type Spacings = typeof spacings; export type Spacing = keyof typeof spacings; -export const nativeSpacings: Record = { +export const nativeSpacings = { sm: 8, md: 16, lg: 24, diff --git a/packages/theme/src/typography.ts b/packages/theme/src/typography.ts index e35b4514bf..9f9ee99e96 100644 --- a/packages/theme/src/typography.ts +++ b/packages/theme/src/typography.ts @@ -1,29 +1,22 @@ import { nativeFontFamilies } from './fontFamilies'; - -export const fontWeights = { - medium: 400, - demi: 600, -} as const; - -export type FontWeight = keyof typeof fontWeights; -export type FontWeightValue = typeof fontWeights[FontWeight]; +import { fontWeights, FontWeightValue } from './fontWeights'; // we need unit-less typography base because RN is unit-less, we can easily add units later // for web we need string instead of object because styled-components syntax export const typographyStylesBase = { - largeTitle: { + titleLarge: { fontSize: 48, lineHeight: 53, fontWeight: fontWeights.medium, letterSpacing: 0.4, }, - mediumTitle: { + titleMedium: { fontSize: 34, lineHeight: 37, fontWeight: fontWeights.medium, letterSpacing: -1.4, }, - smallTitle: { + titleSmall: { fontSize: 22, lineHeight: 26, fontWeight: fontWeights.medium, @@ -32,7 +25,7 @@ export const typographyStylesBase = { highlight: { fontSize: 16, lineHeight: 24, - fontWeight: fontWeights.demi, + fontWeight: fontWeights.semiBold, letterSpacing: -0.4, }, body: { @@ -44,7 +37,7 @@ export const typographyStylesBase = { callout: { fontSize: 14, lineHeight: 21, - fontWeight: fontWeights.demi, + fontWeight: fontWeights.semiBold, letterSpacing: -0.3, }, hint: { diff --git a/yarn.lock b/yarn.lock index 8d26a2a5e6..e300f06c6a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2813,10 +2813,10 @@ resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== -"@mobily/ts-belt@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@mobily/ts-belt/-/ts-belt-3.10.0.tgz#bf264493420e47a6f95e592056de9957513d990a" - integrity sha512-F3XLU3zMDzJOf9KlKgnNOz5rdAtMG/UBxEDU4UNA4ewKFRd5DsbIIJmeAifLudNwcXmoIgtZ39KwVjPaL/CjgA== +"@mobily/ts-belt@^3.11.0": + version "3.11.0" + resolved "https://registry.yarnpkg.com/@mobily/ts-belt/-/ts-belt-3.11.0.tgz#5ba18b8116d699d05fae10c29e248d6c99afe817" + integrity sha512-nEtjcTi9k02dU90VnZAUA7V5umP7kVBZJYZc1N7cXQidb3HICXcBi5B2UxyxZ7leO++TWd1y2fItfxIwWS8h4A== "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" @@ -20016,7 +20016,7 @@ react-native-web@^0.14.9: prop-types "^15.6.0" react-timer-mixin "^0.13.4" -react-native@0.66.4, react-native@0.68.0: +react-native@*, react-native@0.66.4, react-native@0.68.0: version "0.68.0" resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.68.0.tgz#00204818c7fa5a9802ee73f3905a6d9b1c945a31" integrity sha512-Qi8KpG9rqiU0hVp05GKkuRe8iAVhblYMwpnwG3wkBi99Z/X8iZ0jD1b1UW0/y6oesmCyGQAxpsB36imU8zg1AQ== @@ -23478,50 +23478,10 @@ type-detect@4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" - integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== - -type-fest@^0.18.0: - version "0.18.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" - integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" - integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - -type-fest@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" - integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -type-fest@^1.0.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" - integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== +type-fest@2.12.2, type-fest@^0.13.1, type-fest@^0.18.0, type-fest@^0.20.2, type-fest@^0.21.3, type-fest@^0.3.0, type-fest@^0.6.0, type-fest@^0.7.1, type-fest@^0.8.1, type-fest@^1.0.2, type-fest@^2.12.2: + version "2.12.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.12.2.tgz#80a53614e6b9b475eb9077472fb7498dc7aa51d0" + integrity sha512-qt6ylCGpLjZ7AaODxbpyBZSs9fCI9SkL3Z9q2oxMBQhs/uyY+VD8jHA8ULCGmWQJlBgqvO3EJeAngOHD8zQCrQ== type-is@^1.6.16, type-is@~1.6.18: version "1.6.18"