summaryrefslogtreecommitdiff
path: root/app_expo/components/text
diff options
context:
space:
mode:
authorKirill Rogovoy <[email protected]>2021-07-20 21:24:52 +0300
committerKirill Rogovoy <[email protected]>2021-07-20 21:24:52 +0300
commit5f4611d65e40eae3ca6191a15f68d69ea5a1c4cb (patch)
tree273dfc086444533d86d580961c92ba8d14781a67 /app_expo/components/text
parentf0bf4e7afdcd8b02a62be45ab3e7d047ed865a79 (diff)
WIP
Diffstat (limited to 'app_expo/components/text')
-rw-r--r--app_expo/components/text/text.presets.ts48
-rw-r--r--app_expo/components/text/text.props.ts37
-rw-r--r--app_expo/components/text/text.story.tsx92
-rw-r--r--app_expo/components/text/text.tsx28
4 files changed, 205 insertions, 0 deletions
diff --git a/app_expo/components/text/text.presets.ts b/app_expo/components/text/text.presets.ts
new file mode 100644
index 0000000..4693417
--- /dev/null
+++ b/app_expo/components/text/text.presets.ts
@@ -0,0 +1,48 @@
+import { TextStyle } from 'react-native'
+import { color, typography } from '../../theme'
+
+/**
+ * All text will start off looking like this.
+ */
+const BASE: TextStyle = {
+ fontFamily: typography.primary,
+ color: color.text,
+ fontSize: 15,
+}
+
+/**
+ * All the variations of text styling within the app.
+ *
+ * You want to customize these to whatever you need in your app.
+ */
+export const presets = {
+ /**
+ * The default text styles.
+ */
+ default: BASE,
+
+ /**
+ * A bold version of the default text.
+ */
+ bold: { ...BASE, fontWeight: 'bold' } as TextStyle,
+
+ /**
+ * Large headers.
+ */
+ header: { ...BASE, fontSize: 24, fontWeight: 'bold' } as TextStyle,
+
+ /**
+ * Field labels that appear on forms above the inputs.
+ */
+ fieldLabel: { ...BASE, fontSize: 13, color: color.dim } as TextStyle,
+
+ /**
+ * A smaller piece of secondard information.
+ */
+ secondary: { ...BASE, fontSize: 9, color: color.dim } as TextStyle,
+}
+
+/**
+ * A list of preset names.
+ */
+export type TextPresets = keyof typeof presets
diff --git a/app_expo/components/text/text.props.ts b/app_expo/components/text/text.props.ts
new file mode 100644
index 0000000..79ee12c
--- /dev/null
+++ b/app_expo/components/text/text.props.ts
@@ -0,0 +1,37 @@
+import { StyleProp, TextProps as TextProperties, TextStyle } from 'react-native'
+import i18n from 'i18n-js'
+import { TextPresets } from './text.presets'
+import { TxKeyPath } from '../../i18n'
+
+export interface TextProps extends TextProperties {
+ /**
+ * Children components.
+ */
+ children?: React.ReactNode
+
+ /**
+ * Text which is looked up via i18n.
+ */
+ tx?: TxKeyPath
+
+ /**
+ * Optional options to pass to i18n. Useful for interpolation
+ * as well as explicitly setting locale or translation fallbacks.
+ */
+ txOptions?: i18n.TranslateOptions
+
+ /**
+ * The text to display if not using `tx` or nested components.
+ */
+ text?: string
+
+ /**
+ * An optional style override useful for padding & margin.
+ */
+ style?: StyleProp<TextStyle>
+
+ /**
+ * One of the different types of text presets.
+ */
+ preset?: TextPresets
+}
diff --git a/app_expo/components/text/text.story.tsx b/app_expo/components/text/text.story.tsx
new file mode 100644
index 0000000..edfe24d
--- /dev/null
+++ b/app_expo/components/text/text.story.tsx
@@ -0,0 +1,92 @@
+/* eslint-disable react-native/no-inline-styles */
+/* eslint-disable react-native/no-color-literals */
+
+import * as React from 'react'
+import { View, ViewStyle } from 'react-native'
+import { storiesOf } from '@storybook/react-native'
+import { StoryScreen, Story, UseCase } from '../../../storybook/views'
+import { color } from '../../theme'
+import { Text } from './text'
+
+declare let module
+
+const VIEWSTYLE = {
+ flex: 1,
+ backgroundColor: color.storybookDarkBg,
+}
+const viewStyleArray: ViewStyle[] = [VIEWSTYLE, { backgroundColor: '#7fff00' }]
+
+storiesOf('Text', module)
+ .addDecorator((fn) => <StoryScreen>{fn()}</StoryScreen>)
+ .add('Style Presets', () => (
+ <Story>
+ <UseCase text="default" usage="Used for normal body text.">
+ <View style={VIEWSTYLE}>
+ <Text>Hello!</Text>
+ <Text style={{ paddingTop: 10 }}>
+ Check out{'\n'}
+ my{'\n'}
+ line height
+ </Text>
+ <Text style={{ paddingTop: 10 }}>The quick brown fox jumped over the slow lazy dog.</Text>
+ <Text>$123,456,789.00</Text>
+ </View>
+ </UseCase>
+ <UseCase text="bold" usage="Used for bolded body text.">
+ <View style={VIEWSTYLE}>
+ <Text preset="bold">Osnap! I'm puffy.</Text>
+ </View>
+ </UseCase>
+ <UseCase text="header" usage="Used for major section headers.">
+ <View style={VIEWSTYLE}>
+ <Text preset="header">Behold!</Text>
+ </View>
+ </UseCase>
+ </Story>
+ ))
+ .add('Passing Content', () => (
+ <Story>
+ <UseCase
+ text="text"
+ usage="Used when you want to pass a value but don't want to open a child."
+ >
+ <View style={VIEWSTYLE}>
+ <Text text="Heyo!" />
+ </View>
+ </UseCase>
+ <UseCase text="tx" usage="Used for looking up i18n keys.">
+ <View style={VIEWSTYLE}>
+ <Text tx="common.ok" />
+ <Text tx="common.cancel" />
+ </View>
+ </UseCase>
+ <UseCase
+ text="children"
+ usage="Used like you would normally use a React Native <Text> component."
+ >
+ <View style={VIEWSTYLE}>
+ <Text>Passing strings as children.</Text>
+ </View>
+ </UseCase>
+ <UseCase text="nested children" usage="You can embed them and change styles too.">
+ <View style={VIEWSTYLE}>
+ <Text>
+ {' '}
+ Hello <Text preset="bold">bolded</Text> World.
+ </Text>
+ </View>
+ </UseCase>
+ </Story>
+ ))
+ .add('Styling', () => (
+ <Story>
+ <UseCase text="Style array" usage="Text with style array">
+ <View style={viewStyleArray}>
+ <Text>
+ {' '}
+ Hello <Text preset="bold">bolded</Text> World.
+ </Text>
+ </View>
+ </UseCase>
+ </Story>
+ ))
diff --git a/app_expo/components/text/text.tsx b/app_expo/components/text/text.tsx
new file mode 100644
index 0000000..d9ffc8c
--- /dev/null
+++ b/app_expo/components/text/text.tsx
@@ -0,0 +1,28 @@
+import * as React from 'react'
+import { Text as ReactNativeText } from 'react-native'
+import { presets } from './text.presets'
+import { TextProps } from './text.props'
+import { translate } from '../../i18n'
+
+/**
+ * For your text displaying needs.
+ *
+ * This component is a HOC over the built-in React Native one.
+ */
+export function Text(props: TextProps) {
+ // grab the props
+ const { preset = 'default', tx, txOptions, text, children, style: styleOverride, ...rest } = props
+
+ // figure out which content to use
+ const i18nText = tx && translate(tx, txOptions)
+ const content = i18nText || text || children
+
+ const style = presets[preset] || presets.default
+ const styles = [style, styleOverride]
+
+ return (
+ <ReactNativeText {...rest} style={styles}>
+ {content}
+ </ReactNativeText>
+ )
+}