Skip to content

Commit

Permalink
feat: mobile button comp (#924)
Browse files Browse the repository at this point in the history
Co-authored-by: Alder Whiteford <[email protected]>
Co-authored-by: Alder Whiteford <[email protected]>
  • Loading branch information
3 people authored May 29, 2024
1 parent b308e6c commit ca88501
Show file tree
Hide file tree
Showing 20 changed files with 484 additions and 111 deletions.
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

0 comments on commit ca88501

Please sign in to comment.