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

feat: mobile button comp #924

Merged
merged 14 commits into from
May 29, 2024
Merged
2 changes: 1 addition & 1 deletion frontend/mobile/app/(app)/(tabs)/discover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Box, Tag } from '@/app/(design-system)';
const DiscoverPage = () => {
return (
<Box flex={1} alignItems="center" justifyContent="center" padding="m">
<Tag variant="darkRed">Discover</Tag>
<Tag>Tag</Tag>
</Box>
);
};
Expand Down
2 changes: 1 addition & 1 deletion frontend/mobile/app/(app)/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { StyleSheet, Text, View } from 'react-native';
const HomePage = () => {
return (
<View style={styles.container}>
<Text style={styles.title}>Home</Text>
<Text style={styles.title}>Home Page</Text>
</View>
);
};
Expand Down
5 changes: 5 additions & 0 deletions frontend/mobile/app/(auth)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import React from 'react';
import { Text, View } from 'react-native';

import { Button } from '../(design-system)/components/Button/Button';

const Welcome = () => {
return (
<View>
<Text>Welcome</Text>
<Button variant="standardButton" color="blue">
Hello
</Button>
</View>
);
};
Expand Down
12 changes: 0 additions & 12 deletions frontend/mobile/app/(design-system)/Colors.ts

This file was deleted.

37 changes: 0 additions & 37 deletions frontend/mobile/app/(design-system)/Tag/Tag.tsx

This file was deleted.

42 changes: 0 additions & 42 deletions frontend/mobile/app/(design-system)/Tag/TagVariants.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { PropsWithChildren } from 'react';
import { ViewProps } from 'react-native-svg/lib/typescript/fabric/utils';
import { ViewProps } from 'react-native';

import { BoxProps, createBox } from '@shopify/restyle';

import { Theme } from './theme';
import { Theme } from '../../theme';

type Props = ViewProps & PropsWithChildren & BoxProps<Theme>;

Expand Down
142 changes: 142 additions & 0 deletions frontend/mobile/app/(design-system)/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import React from 'react';
import { GestureResponderEvent, TouchableOpacity } from 'react-native';

import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
import { BoxProps, createBox } from '@shopify/restyle';

import { Text } from '@/app/(design-system)/components/Text/Text';
import {
SACColors,
defaultColor,
textColorVariants
} from '@/app/(design-system)/shared/colors';
import { Theme, createStyles } from '@/app/(design-system)/theme';

import { ComponentSizes } from '../../shared/types';
import { Icon } from '../Icon/Icon';

interface BaseButtonProps {
onPress?: (event: GestureResponderEvent) => void;
disabled?: boolean;
children?: React.ReactNode;
color?: SACColors;
}

interface StandardButtonProps {
variant: 'standardButton';
size?: ComponentSizes;
}

interface IconButtonProps {
variant: 'iconButton';
icon: IconDefinition;
iconColor?: SACColors;
iconPosition?: 'left' | 'right';
justify?: 'center' | 'space-between' | 'flex-end' | 'flex-start';
size?: ComponentSizes;
}

type VariantButtonProps = StandardButtonProps | IconButtonProps;
type ButtonProps = BaseButtonProps & VariantButtonProps & BoxProps<Theme>;

const BaseButton = createBox<Theme, ButtonProps>(TouchableOpacity);

const StandardButton: React.FC<
BaseButtonProps & StandardButtonProps & BoxProps<Theme>
> = ({
children,
onPress,
disabled = false,
color = defaultColor,
size = 'full',
...rest
}) => {
return (
<BaseButton
backgroundColor={disabled ? 'disabled' : color}
disabled={disabled}
onPress={disabled ? undefined : onPress}
{...styles.standardButton}
{...buttonSizeStyles[size]}
{...rest}
>
<Text color={textColorVariants[color]}>{children}</Text>
</BaseButton>
);
};

const IconButton: React.FC<
BaseButtonProps & IconButtonProps & BoxProps<Theme>
> = ({
children,
onPress,
disabled = false,
color,
icon,
iconColor = 'white',
iconPosition = 'left',
justify = 'center',
size = 'full',
...rest
}) => {
const buttonIcon = <Icon size={size} icon={icon} color={iconColor} />;

return (
<BaseButton
backgroundColor={disabled ? 'disabled' : color}
justifyContent={justify}
disabled={disabled}
onPress={disabled ? undefined : onPress}
{...styles.iconButton}
{...buttonSizeStyles[size]}
{...rest}
>
{iconPosition === 'left' && buttonIcon}
<Text color={textColorVariants[color ?? 'black']}>{children}</Text>
{iconPosition === 'right' && buttonIcon}
</BaseButton>
);
};

export const Button: React.FC<ButtonProps> = (props) => {
if (props.variant === 'standardButton') {
return <StandardButton {...props} />;
}
if (props.variant === 'iconButton') {
return <IconButton {...props} />;
}
return null;
};

const styles = createStyles({
standardButton: {
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 'l',
paddingVertical: 'm',
borderRadius: 'base'
},
iconButton: {
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 'l',
paddingVertical: 'm',
borderRadius: 'base',
flexDirection: 'row',
gap: 's'
}
});

const buttonSizeStyles = createStyles({
small: {
minWidth: 80,
paddingVertical: 'xs',
paddingHorizontal: 'm'
},
medium: {
minWidth: 115
},
full: {
minWidth: '100%'
}
});
34 changes: 34 additions & 0 deletions frontend/mobile/app/(design-system)/components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';

import { SACColors } from '../../shared/colors';
import { ComponentSizes } from '../../shared/types';
import { createStyles } from '../../theme';

type IconProps = {
icon: IconDefinition;
size?: ComponentSizes;
color?: SACColors;
};

export const Icon: React.FC<IconProps> = ({ icon, size = 'medium', color }) => {
return (
<FontAwesomeIcon
icon={icon}
size={styles[size].fontSize}
color={color}
/>
);
};

const styles = createStyles({
small: {
fontSize: 16
},
medium: {
fontSize: 24
},
full: {
fontSize: 24
}
});
51 changes: 51 additions & 0 deletions frontend/mobile/app/(design-system)/components/Tag/Tag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';

import { faXmark } from '@fortawesome/free-solid-svg-icons';

import { SACColors, defaultColor } from '../../shared/colors';
import { Button } from '../Button/Button';

type TagProps = {
children: React.ReactNode;
onPress?: () => void;
color?: SACColors;
state?: 'selected' | 'unselected' | 'remove';
};

export const Tag: React.FC<TagProps> = ({
children,
color = defaultColor,
state = 'selected',
onPress
}) => {
if (state === 'selected' || state === 'unselected') {
return (
<Button
variant="standardButton"
color={state === 'selected' ? color : 'white'}
size={'small'}
borderRadius={'full'}
onPress={onPress}
>
{children}
</Button>
);
}
if (state === 'remove') {
return (
<Button
variant="iconButton"
color={color}
icon={faXmark}
iconColor={'white'}
iconPosition={'right'}
size={'small'}
borderRadius={'full'}
onPress={onPress}
>
{children}
</Button>
);
}
return null;
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createText } from '@shopify/restyle';

import { Theme } from '../theme';
import { Theme } from '../../theme';

export const Text = createText<Theme>();
10 changes: 5 additions & 5 deletions frontend/mobile/app/(design-system)/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export * from './Text/Text';
export * from './Box';
export * from './components/Text/Text';
export * from './components/Box/Box';
export * from './theme';
export * from './Colors';
export * from './Spacing';
export * from './Tag/Tag';
export * from './shared/colors';
export * from './shared/spacing';
export * from './components/Tag/Tag';
4 changes: 4 additions & 0 deletions frontend/mobile/app/(design-system)/shared/border.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const Border = {
base: 8,
full: 999
};
Loading
Loading