Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/design review #52

Merged
merged 11 commits into from
Apr 19, 2023
7 changes: 6 additions & 1 deletion example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ const App = () => {
return (
<ThemeProvider>
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Navigator
screenOptions={{
contentStyle: { backgroundColor: '#FFF' },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

neutral[50]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think i tried to use theme there, but it returns an error as i try to use it outside ThemeProvider

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We definitely should use the ThemeProvider then !

}}
initialRouteName="Home"
>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Buttons" component={ButtonsPage} />
<Stack.Screen name="Dialog" component={DialogPage} />
Expand Down
83 changes: 80 additions & 3 deletions example/src/Buttons/ButtonsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,95 @@
import React from 'react';
import { StyleSheet } from 'react-native';
import { StyleSheet, View } from 'react-native';
import { Button, Screen } from 'smartway-react-native-ui';

export const ButtonsPage = () => {
return (
<Screen style={styles.container}>
<Button mode="text">Text button</Button>
<Button mode="filled">Filled button</Button>
<View style={styles.buttonContainer}>
<Button style={styles.button} mode="filled">
Filled
</Button>
<Button style={styles.button} status="primary" mode="filled">
Filled
</Button>
<Button style={styles.button} status="information" mode="filled">
Filled
</Button>
<Button style={styles.button} status="success" mode="filled">
Filled
</Button>
<Button style={styles.button} status="warning" mode="filled">
Filled
</Button>
<Button style={styles.button} status="error" mode="filled">
Filled
</Button>
<Button style={styles.button} disabled mode="filled">
Filled
</Button>
</View>
<View style={styles.buttonContainer}>
<Button style={styles.button} mode="text">
Text
</Button>
<Button style={styles.button} status="primary" mode="text">
Text
</Button>
<Button style={styles.button} status="information" mode="text">
Text
</Button>
<Button style={styles.button} status="success" mode="text">
Text
</Button>
<Button style={styles.button} status="warning" mode="text">
Text
</Button>
<Button style={styles.button} status="error" mode="text">
Text
</Button>
<Button style={styles.button} disabled mode="text">
Text
</Button>
</View>
<View style={styles.buttonContainer}>
<Button style={styles.outlinedButton} mode="outlined">
Outlined
</Button>
<Button style={styles.outlinedButton} status="primary" mode="outlined">
Outlined
</Button>
<Button style={styles.outlinedButton} status="information" mode="outlined">
Outlined
</Button>
<Button style={styles.outlinedButton} status="success" mode="outlined">
Outlined
</Button>
<Button style={styles.outlinedButton} status="warning" mode="outlined">
Outlined
</Button>
<Button style={styles.outlinedButton} status="error" mode="outlined">
Outlined
</Button>
<Button style={styles.outlinedButton} disabled mode="outlined">
Outlined
</Button>
</View>
</Screen>
);
};

const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'center',
},
buttonContainer: {
alignItems: 'center',
},
button: {
margin: 6,
},
outlinedButton: {
margin: 5,
},
});
41 changes: 23 additions & 18 deletions example/src/Dialog/DialogPage.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
import React, { useState } from 'react';
import { StyleSheet } from 'react-native';
import { StatusBar, StyleSheet } from 'react-native';
import { Button, Dialog, Screen } from 'smartway-react-native-ui';

export const DialogPage = () => {
const [modalVisible, setModalVisible] = useState<boolean>(false);

const showModal = () => {
setModalVisible(true);
};

const hideModal = () => {
setModalVisible(false);
};
const [singleOptionDialog, setSingleOptionDialog] = useState<boolean>(false);
const [twoOptionsDialog, setTwoOptionsDialog] = useState<boolean>(false);

return (
<Screen style={styles.container}>
<Button mode="text" onClick={showModal}>
Click me
<StatusBar backgroundColor={'transparent'} />
<Button mode="text" onClick={() => setSingleOptionDialog(true)}>
single option
</Button>
<Button mode="text" onClick={() => setTwoOptionsDialog(true)}>
two options
</Button>
<Dialog
visible={modalVisible}
visible={singleOptionDialog}
title={'Titre du dialog'}
content={'Contenu texte du dialog pour expliquer l’action à faire '}
confirmButtonLabel={'Valider'}
onConfirm={() => setSingleOptionDialog(false)}
onDismiss={() => setSingleOptionDialog(false)}
/>
<Dialog
visible={twoOptionsDialog}
title={'Titre du dialog'}
content={'Contenu texte'}
content={'Contenu texte du dialog pour expliquer l’action à faire '}
dismissButtonLabel={'Annuler'}
confirmButtonLabel={'Ok'}
onDismiss={hideModal}
onConfirm={hideModal}
></Dialog>
confirmButtonLabel={'Valider'}
onDismiss={() => setTwoOptionsDialog(false)}
onConfirm={() => setTwoOptionsDialog(false)}
/>
</Screen>
);
};
Expand Down
4 changes: 4 additions & 0 deletions src/components/Screen.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { SafeAreaView, ViewStyle, StatusBar, StyleSheet } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useTheme } from '../styles/themes';

type Props = {
Expand All @@ -11,11 +12,13 @@ type Props = {

export const Screen = ({ children, style, testID, statusBarColor }: Props) => {
const theme = useTheme();
const insets = useSafeAreaInsets();

const styles = StyleSheet.create({
screen: {
flex: 1,
backgroundColor: theme.sw.colors.neutral[50],
marginTop: insets.top,
paddingLeft: theme.sw.spacing.m,
paddingRight: theme.sw.spacing.m,
...style,
Expand All @@ -25,6 +28,7 @@ export const Screen = ({ children, style, testID, statusBarColor }: Props) => {
return (
<SafeAreaView style={styles.screen} testID={testID}>
<StatusBar
translucent
backgroundColor={statusBarColor ? statusBarColor : theme.sw.colors.neutral[50]}
barStyle="dark-content"
/>
Expand Down
1 change: 1 addition & 0 deletions src/components/appBar/AppBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export const AppBar = ({
body: {
paddingRight: theme.sw.spacing.m,
color: disabled ? theme.sw.colors.neutral[500] : theme.sw.colors.neutral[800],
lineHeight: 26,
},
});

Expand Down
10 changes: 10 additions & 0 deletions src/components/buttons/BaseButtonProps.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import type { ReactNode } from 'react';
import type { TextStyle, ViewStyle } from 'react-native';

type ButtonStatus =
| 'default'
| 'primary'
| 'information'
| 'success'
| 'warning'
| 'error'
| 'neutral';
export interface BaseButtonProps {
children?: ReactNode;
style?: ViewStyle;
labelStyle?: TextStyle;
onClick?: () => void;
testID?: string;
disabled?: boolean;
status?: ButtonStatus;
}
44 changes: 40 additions & 4 deletions src/components/buttons/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { TextButton } from './TextButton';
import { Button as BaseButton } from 'react-native-paper';
import { FilledButton } from './FilledButton';
import type { BaseButtonProps } from './BaseButtonProps';
import { OutlinedButton } from './OutlinedButton';

interface ButtonProps extends BaseButtonProps {
mode?: 'text' | 'filled';
mode?: 'filled' | 'outlined' | 'text';
}

export const Button = ({
Expand All @@ -14,23 +15,58 @@ export const Button = ({
style,
labelStyle,
onClick,
status = 'primary',
disabled,
testID,
}: ButtonProps) => {
if (mode === 'text') {
return (
<TextButton style={style} labelStyle={labelStyle} onClick={onClick} testID={testID}>
<TextButton
status={status}
style={style}
labelStyle={labelStyle}
onClick={onClick}
testID={testID}
disabled={disabled}
>
{children}
</TextButton>
);
} else if (mode === 'filled') {
return (
<FilledButton style={style} labelStyle={labelStyle} onClick={onClick} testID={testID}>
<FilledButton
status={status}
style={style}
labelStyle={labelStyle}
onClick={onClick}
testID={testID}
disabled={disabled}
>
{children}
</FilledButton>
);
} else if (mode === 'outlined') {
return (
<OutlinedButton
status={status}
style={style}
labelStyle={labelStyle}
onClick={onClick}
testID={testID}
disabled={disabled}
>
{children}
</OutlinedButton>
);
} else {
return (
<BaseButton style={style} labelStyle={labelStyle} onPress={onClick} testID={testID}>
<BaseButton
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about it I think it's not a good idea to fallback to the default react-native-paper's Button component if no mode props has been provided.
I cannot tell what it looks like quickly because it is not in the design system.

Would you mind to provide a default value to the mode props instead ? Like filled ?

style={style}
disabled={disabled}
labelStyle={labelStyle}
onPress={onClick}
testID={testID}
>
{children}
</BaseButton>
);
Expand Down
70 changes: 51 additions & 19 deletions src/components/buttons/FilledButton.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,64 @@
import React from 'react';
import type { TextStyle, ViewStyle } from 'react-native';
import { StyleSheet, ViewStyle } from 'react-native';
import { Button as BaseButton } from 'react-native-paper';
import { useTheme } from '../../styles/themes';
import type { BaseButtonProps } from './BaseButtonProps';

export const FilledButton = ({ children, style, labelStyle, onClick, testID }: BaseButtonProps) => {
export const FilledButton = ({
children,
style,
labelStyle,
onClick,
testID,
disabled,
status,
}: BaseButtonProps) => {
const theme = useTheme();
const buttonStyle: ViewStyle = {
borderRadius: 8,
backgroundColor: theme.sw.colors.primary[400],
...style,
};

const _labelStyle: TextStyle = {
fontFamily: 'PublicSans-Regular',
fontSize: 16,
lineHeight: 19,
color: theme.sw.colors.neutral[50],
paddingVertical: theme.sw.spacing.s,
paddingHorizontal: theme.sw.spacing.l,
// Overrides default margin of Paper component
marginVertical: 0,
marginHorizontal: 0,
...labelStyle,
const getbackgroundColor = (): ViewStyle['backgroundColor'] => {
switch (status) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move this function in it's own file (like utils), so that we can reuse it in the 3 button variants ?

Something like getColor(status) -> string so it could be reused without being concerned wether we want to set the background color, the text color or the border color ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated :)

case 'primary':
return theme.sw.colors.primary[400];
case 'information':
return theme.sw.colors.information[400];
case 'success':
return theme.sw.colors.success[400];
case 'warning':
return theme.sw.colors.warning[400];
case 'error':
return theme.sw.colors.error[400];
default:
return theme.sw.colors.neutral[700];
}
};

const styles = StyleSheet.create({
button: {
borderRadius: 8,
backgroundColor: disabled ? '#919EAB3D' : getbackgroundColor(),
...style,
},
label: {
fontFamily: 'PublicSans-Regular',
fontSize: 16,
lineHeight: 26,
color: disabled ? theme.sw.colors.neutral[500] : theme.sw.colors.neutral[50],
paddingVertical: theme.sw.spacing.s,
paddingHorizontal: theme.sw.spacing.l,
fontWeight: 'bold',
marginVertical: 0,
marginHorizontal: 0,
...labelStyle,
},
});

return (
<BaseButton style={buttonStyle} labelStyle={_labelStyle} onPress={onClick} testID={testID}>
<BaseButton
style={styles.button}
labelStyle={styles.label}
onPress={onClick}
testID={testID}
>
{children}
</BaseButton>
);
Expand Down
Loading