Skip to content

Commit

Permalink
Merge pull request #20 from grupadotnet/8693cgf0c
Browse files Browse the repository at this point in the history
8693cgf0c - tłumaczenia w aplikacji, konfiguracja testów, dodanie kilku kolorów z figmy, poprawa Primary Button
  • Loading branch information
wiktorrudzki authored Apr 1, 2024
2 parents 4ac0724 + 8285e93 commit aa2645c
Show file tree
Hide file tree
Showing 22 changed files with 1,902 additions and 1,568 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ yarn-error.*

# typescript
*.tsbuildinfo

# react-native
%ProgramData%
20 changes: 20 additions & 0 deletions App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import i18next from 'i18next';
import commonEN from 'public/locales/en/common.json';
import commonPL from 'public/locales/pl/common.json';
import { initReactI18next } from 'react-i18next';

import { ThemeProvider } from '@/hooks';
import { Components, Home } from '@/screens';
Expand All @@ -8,6 +12,22 @@ import { RootStackParamList } from '@/types/param';
const Stack = createNativeStackNavigator<RootStackParamList>();

const App = () => {
i18next.use(initReactI18next).init({
compatibilityJSON: 'v3',
fallbackLng: 'pl',
interpolation: {
escapeValue: false, // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
},
resources: {
pl: {
common: commonPL,
},
en: {
common: commonEN,
},
},
});

return (
<NavigationContainer>
<ThemeProvider>
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@ If you are new to _react-hook-form_ library then we recommend you create your fo

![2 step](./readme/sort_import_2.png)

## Translations

### Structure

![translations structure](./readme/translations_structure.png)

### To add a new translation file

- create file in `/public/locales/pl` and every other language folder
- import it to the typescript declaration file and add it to the resources as shown below - `/src/types/i18next.d.ts`: ![translations declatarion file](./readme/translations_declaration_file.png)

### Recommended way of translationing

- `Import { t } from 'i18-next';`
- `const { t } = useTranslation('common');`, where `common` is the name of the file from which we want to get a translation (namespace)
- use translated text in the app - `t('Hello', {ns: 'common'})` - where `Hello` is the translated text and common is the name of the file (if we have imported only one namepsace then it can be skipped)

## Start development

- Clone repository
Expand Down
13 changes: 13 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Config } from 'jest';

export default async (): Promise<Config> => {
return {
preset: '@testing-library/react-native',
// testEnvironment: 'node',
moduleDirectories: ['node_modules', '<rootDir>/'],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
setupFiles: ['./jest.setup.ts'],
};
};
3 changes: 3 additions & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
jest.mock('@react-native-async-storage/async-storage', () =>
require('@react-native-async-storage/async-storage/jest/async-storage-mock'),
);
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
"@react-navigation/native-stack": "^6.9.17",
"expo": "~49.0.15",
"expo-status-bar": "~1.6.0",
"i18next": "^23.10.1",
"i18next-browser-languagedetector": "^7.2.0",
"react": "18.2.0",
"react-hook-form": "^7.48.2",
"react-native": "0.72.6",
"react-i18next": "^14.1.0",
"react-native": "0.72.10",
"react-native-safe-area-context": "4.6.3",
"react-native-screens": "~3.22.0",
"yarn": "^1.22.21",
Expand All @@ -43,10 +46,8 @@
"react-dom": "18.2.0",
"react-native-web": "~0.19.6",
"react-test-renderer": "^18.2.0",
"ts-node": "^10.9.2",
"typescript": "^5.1.3"
},
"jest": {
"preset": "@testing-library/react-native"
},
"private": true
}
3 changes: 3 additions & 0 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"Hello": "Hello"
}
3 changes: 3 additions & 0 deletions public/locales/pl/common.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"Hello": "Witamy"
}
Binary file added readme/translations_declaration_file.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added readme/translations_structure.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 6 additions & 5 deletions src/components/Button/PrimaryButton.test.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { fireEvent, render, screen } from '@testing-library/react-native';
import { fireEvent, screen } from '@testing-library/react-native';

import PrimaryButton from './PrimaryButton';
import { PrimaryButton } from '@/components/Button';
import renderWithTheme from '@/tests/renderWithTheme';

const onPress = jest.fn();

describe('PrimaryButton component tests', () => {
it('properly renders button with provided title', () => {
render(<PrimaryButton title="test" onPress={onPress} />);
it('properly renders button with provided text', () => {
renderWithTheme(<PrimaryButton text="test" onPress={onPress} />);

expect(screen.getByText('test')).toBeDefined();
});
it('calls provieded onPress method', () => {
render(<PrimaryButton title="test" onPress={onPress} />);
renderWithTheme(<PrimaryButton text="test" onPress={onPress} />);

fireEvent(screen.getByText('test'), 'press');

Expand Down
26 changes: 17 additions & 9 deletions src/components/Button/PrimaryButton.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
import React from 'react';
import { Pressable, StyleSheet, Text } from 'react-native';

interface Param {
title: string;
onPress: any;
}
import { useTheme } from '@/hooks';

type Props = React.ComponentProps<typeof Pressable> & {
text: string;
onPress: () => void;
};

const PrimaryButton = ({ text, onPress, ...passThroughProps }: Props) => {
const { themedStyles } = useTheme();

const PrimaryButton = (param: Param) => {
return (
<Pressable style={styles.button} onPress={param.onPress}>
<Text style={styles.text}>{param.title}</Text>
<Pressable
{...passThroughProps}
style={{ ...styles.button, backgroundColor: themedStyles.button }}
onPress={onPress}
>
<Text style={{ ...styles.text, color: themedStyles.buttonText }}>
{text}
</Text>
</Pressable>
);
};
Expand All @@ -20,14 +30,12 @@ const styles = StyleSheet.create({
button: {
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#5964AB',
width: 291,
height: 44,
borderRadius: 10,
},

text: {
color: '#FFFFFF',
fontSize: 12,
lineHeight: 15,
fontWeight: '500',
Expand Down
File renamed without changes.
File renamed without changes.
5 changes: 2 additions & 3 deletions src/hooks/useTheme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import React, { useContext, useEffect, useState } from 'react';
import { useColorScheme } from 'react-native';
import { darkColors, lightColors } from 'style';

import { isTypeOfTheme, Theme, THEMES } from '@/types/theme';
import { Colors, isTypeOfTheme, Theme, THEMES } from '@/types/theme';

type Props = {
children: React.ReactNode;
};

type Context = {
theme: Theme;
themedStyles: Record<string, string>;
themedStyles: Record<Colors, string>;
switchTheme: () => void;
};

Expand Down Expand Up @@ -45,7 +45,6 @@ export const ThemeProvider = ({ children }: Props) => {

useEffect(() => {
// Load saved theme from storage
console.log('xd');
const getTheme = async () => {
try {
const savedTheme = await AsyncStorage.getItem('theme');
Expand Down
11 changes: 7 additions & 4 deletions src/screens/Components.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { StyleSheet, Text, View } from 'react-native';
import { globalStyles } from 'style';

import { SwitchTheme } from '@/components';
import { PrimaryButton } from '@/components/Button';
import { SwitchTheme } from '@/components/Theme';
import { RootStackParamList } from '@/types/param';

type Props = NativeStackScreenProps<RootStackParamList, 'Components'>;

const Home = ({ navigation }: Props) => {
const { t } = useTranslation('common');

return (
<View style={styles.container}>
<Text>Components screen</Text>
<Text>{t('Hello')}</Text>
<PrimaryButton
title="Wróć do Home Screen"
text="Wróć do Home Screen"
onPress={() => navigation.navigate('Home')}
/>
<SwitchTheme />
<PrimaryButton title="primary button" onPress={() => {}} />
<PrimaryButton text="primary button" onPress={() => {}} />
</View>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/screens/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const Home = ({ navigation }: Props) => {
return (
<View style={styles.container}>
<PrimaryButton
title="Idź do Components Screen"
text="Idź do Components Screen"
onPress={() => navigation.navigate('Components')}
/>
</View>
Expand Down
9 changes: 9 additions & 0 deletions src/tests/renderWithTheme.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { render } from '@testing-library/react-native';
import React from 'react';

import { ThemeProvider } from '@/hooks';

const renderWithTheme = (component: React.ReactNode) =>
render(<ThemeProvider>{component}</ThemeProvider>);

export default renderWithTheme;
12 changes: 12 additions & 0 deletions src/types/i18next.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'i18next';

import common from 'public/locales/pl/common.json';

declare module 'i18next' {
interface CustomTypeOptions {
defaultNS: 'common';
resources: {
common: typeof common;
};
}
}
3 changes: 3 additions & 0 deletions src/types/theme.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { lightColors } from 'style';

export const THEMES = ['light', 'dark'] as const;
export type Theme = (typeof THEMES)[number];
export type Colors = keyof typeof lightColors;

export const isTypeOfTheme = (value: any): value is Theme =>
THEMES.includes(value);
15 changes: 13 additions & 2 deletions style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,20 @@ export const globalStyles = StyleSheet.create({
});

export const darkColors = {
primary: 'blue',
button: '#5964AB',
buttonText: '#FFF',
buttonActive: '#1F1F1F',
background: '#2F2F2F',
text: '#FFF',
};

export const lightColors = {
primary: 'green',
button: '#5964AB',
buttonText: '#FFF',
stroke: '#BDC1DD',
icon: '#A7AAC0',
iconBackground: '#EDEEF4',
buttonSettings: '#F5F5F5',
buttonSettingsActive: '#E4E4E4',
text: '#000',
};
Loading

0 comments on commit aa2645c

Please sign in to comment.