diff options
Diffstat (limited to 'app_expo/components/button')
-rw-r--r-- | app_expo/components/button/button.presets.ts | 58 | ||||
-rw-r--r-- | app_expo/components/button/button.props.ts | 35 | ||||
-rw-r--r-- | app_expo/components/button/button.story.tsx | 33 | ||||
-rw-r--r-- | app_expo/components/button/button.tsx | 36 |
4 files changed, 162 insertions, 0 deletions
diff --git a/app_expo/components/button/button.presets.ts b/app_expo/components/button/button.presets.ts new file mode 100644 index 0000000..bc0ad3f --- /dev/null +++ b/app_expo/components/button/button.presets.ts @@ -0,0 +1,58 @@ +import { ViewStyle, TextStyle } from 'react-native' +import { color, spacing } from '../../theme' + +/** + * All text will start off looking like this. + */ +const BASE_VIEW: ViewStyle = { + paddingVertical: spacing[2], + paddingHorizontal: spacing[2], + borderRadius: 4, + justifyContent: 'center', + alignItems: 'center', +} + +const BASE_TEXT: TextStyle = { + paddingHorizontal: spacing[3], +} + +/** + * All the variations of text styling within the app. + * + * You want to customize these to whatever you need in your app. + */ +export const viewPresets: Record<string, ViewStyle> = { + /** + * A smaller piece of secondard information. + */ + primary: { ...BASE_VIEW, backgroundColor: color.palette.orange } as ViewStyle, + + /** + * A button without extras. + */ + link: { + ...BASE_VIEW, + paddingHorizontal: 0, + paddingVertical: 0, + alignItems: 'flex-start', + } as ViewStyle, +} + +export const textPresets: Record<ButtonPresetNames, TextStyle> = { + primary: { + ...BASE_TEXT, + fontSize: 9, + color: color.palette.white, + } as TextStyle, + link: { + ...BASE_TEXT, + color: color.text, + paddingHorizontal: 0, + paddingVertical: 0, + } as TextStyle, +} + +/** + * A list of preset names. + */ +export type ButtonPresetNames = keyof typeof viewPresets diff --git a/app_expo/components/button/button.props.ts b/app_expo/components/button/button.props.ts new file mode 100644 index 0000000..810e0aa --- /dev/null +++ b/app_expo/components/button/button.props.ts @@ -0,0 +1,35 @@ +import { StyleProp, TextStyle, TouchableOpacityProps, ViewStyle } from 'react-native' +import { ButtonPresetNames } from './button.presets' +import { TxKeyPath } from '../../i18n' + +export interface ButtonProps extends TouchableOpacityProps { + /** + * Text which is looked up via i18n. + */ + tx?: TxKeyPath + + /** + * The text to display if not using `tx` or nested components. + */ + text?: string + + /** + * An optional style override useful for padding & margin. + */ + style?: StyleProp<ViewStyle> + + /** + * An optional style override useful for the button text. + */ + textStyle?: StyleProp<TextStyle> + + /** + * One of the different types of text presets. + */ + preset?: ButtonPresetNames + + /** + * One of the different types of text presets. + */ + children?: React.ReactNode +} diff --git a/app_expo/components/button/button.story.tsx b/app_expo/components/button/button.story.tsx new file mode 100644 index 0000000..54dc2a9 --- /dev/null +++ b/app_expo/components/button/button.story.tsx @@ -0,0 +1,33 @@ +import * as React from 'react' +import { ViewStyle, TextStyle, Alert } from 'react-native' +import { storiesOf } from '@storybook/react-native' +import { StoryScreen, Story, UseCase } from '../../../storybook/views' +import { Button } from './button' + +declare let module + +const buttonStyleArray: ViewStyle[] = [{ paddingVertical: 100 }, { borderRadius: 0 }] + +const buttonTextStyleArray: TextStyle[] = [{ fontSize: 20 }, { color: '#a511dc' }] + +storiesOf('Button', module) + .addDecorator((fn) => <StoryScreen>{fn()}</StoryScreen>) + .add('Style Presets', () => ( + <Story> + <UseCase text="Primary" usage="The primary button."> + <Button text="Click It" preset="primary" onPress={() => Alert.alert('pressed')} /> + </UseCase> + <UseCase text="Disabled" usage="The disabled behaviour of the primary button."> + <Button text="Click It" preset="primary" onPress={() => Alert.alert('pressed')} disabled /> + </UseCase> + <UseCase text="Array Style" usage="Button with array style"> + <Button + text="Click It" + preset="primary" + onPress={() => Alert.alert('pressed')} + style={buttonStyleArray} + textStyle={buttonTextStyleArray} + /> + </UseCase> + </Story> + )) diff --git a/app_expo/components/button/button.tsx b/app_expo/components/button/button.tsx new file mode 100644 index 0000000..03b8f85 --- /dev/null +++ b/app_expo/components/button/button.tsx @@ -0,0 +1,36 @@ +import * as React from 'react' +import { TouchableOpacity } from 'react-native' +import { Text } from '../text/text' +import { viewPresets, textPresets } from './button.presets' +import { ButtonProps } from './button.props' + +/** + * For your text displaying needs. + * + * This component is a HOC over the built-in React Native one. + */ +export function Button(props: ButtonProps) { + // grab the props + const { + preset = 'primary', + tx, + text, + style: styleOverride, + textStyle: textStyleOverride, + children, + ...rest + } = props + + const viewStyle = viewPresets[preset] || viewPresets.primary + const viewStyles = [viewStyle, styleOverride] + const textStyle = textPresets[preset] || textPresets.primary + const textStyles = [textStyle, textStyleOverride] + + const content = children || <Text tx={tx} text={text} style={textStyles} /> + + return ( + <TouchableOpacity style={viewStyles} {...rest}> + {content} + </TouchableOpacity> + ) +} |