Add a design system (#34)
* Add theming system * Add standard Button control and update RadioButtons * Unify radiobutton with design system * Update debug screen to have multiple views * Add ToggleButton * Update error controls to use design system * Add typography to <Text> element * Move DropdownButton into the design system * Clean out old code * Move Text into design system * Add 'inverted' color palette * Move LoadingPlaceholder into the design system
This commit is contained in:
parent
cc63660982
commit
7e31645e9a
78 changed files with 1431 additions and 375 deletions
76
src/view/com/util/error/ErrorMessage.tsx
Normal file
76
src/view/com/util/error/ErrorMessage.tsx
Normal file
|
@ -0,0 +1,76 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
StyleProp,
|
||||
View,
|
||||
ViewStyle,
|
||||
} from 'react-native'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {Text} from '../text/Text'
|
||||
import {colors} from '../../../lib/styles'
|
||||
import {useTheme} from '../../../lib/ThemeContext'
|
||||
import {usePalette} from '../../../lib/hooks/usePalette'
|
||||
|
||||
export function ErrorMessage({
|
||||
message,
|
||||
numberOfLines,
|
||||
style,
|
||||
onPressTryAgain,
|
||||
}: {
|
||||
message: string
|
||||
numberOfLines?: number
|
||||
style?: StyleProp<ViewStyle>
|
||||
onPressTryAgain?: () => void
|
||||
}) {
|
||||
const theme = useTheme()
|
||||
const pal = usePalette('error')
|
||||
return (
|
||||
<View style={[styles.outer, pal.view, style]}>
|
||||
<View
|
||||
style={[styles.errorIcon, {backgroundColor: theme.palette.error.icon}]}>
|
||||
<FontAwesomeIcon icon="exclamation" style={pal.text} size={16} />
|
||||
</View>
|
||||
<Text
|
||||
type="body2"
|
||||
style={[styles.message, pal.text]}
|
||||
numberOfLines={numberOfLines}>
|
||||
{message}
|
||||
</Text>
|
||||
{onPressTryAgain && (
|
||||
<TouchableOpacity style={styles.btn} onPress={onPressTryAgain}>
|
||||
<FontAwesomeIcon
|
||||
icon="arrows-rotate"
|
||||
style={{color: theme.palette.error.icon}}
|
||||
size={18}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
outer: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 8,
|
||||
},
|
||||
errorIcon: {
|
||||
borderRadius: 12,
|
||||
width: 24,
|
||||
height: 24,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginRight: 8,
|
||||
},
|
||||
message: {
|
||||
flex: 1,
|
||||
paddingRight: 10,
|
||||
},
|
||||
btn: {
|
||||
paddingHorizontal: 4,
|
||||
paddingVertical: 4,
|
||||
},
|
||||
})
|
113
src/view/com/util/error/ErrorScreen.tsx
Normal file
113
src/view/com/util/error/ErrorScreen.tsx
Normal file
|
@ -0,0 +1,113 @@
|
|||
import React from 'react'
|
||||
import {StyleSheet, TouchableOpacity, View} from 'react-native'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {Text} from '../text/Text'
|
||||
import {colors} from '../../../lib/styles'
|
||||
import {useTheme} from '../../../lib/ThemeContext'
|
||||
import {usePalette} from '../../../lib/hooks/usePalette'
|
||||
|
||||
export function ErrorScreen({
|
||||
title,
|
||||
message,
|
||||
details,
|
||||
onPressTryAgain,
|
||||
}: {
|
||||
title: string
|
||||
message: string
|
||||
details?: string
|
||||
onPressTryAgain?: () => void
|
||||
}) {
|
||||
const theme = useTheme()
|
||||
const pal = usePalette('error')
|
||||
return (
|
||||
<View style={[styles.outer, pal.view]}>
|
||||
<View style={styles.errorIconContainer}>
|
||||
<View
|
||||
style={[
|
||||
styles.errorIcon,
|
||||
{backgroundColor: theme.palette.error.icon},
|
||||
]}>
|
||||
<FontAwesomeIcon
|
||||
icon="exclamation"
|
||||
style={{color: colors.white}}
|
||||
size={24}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<Text type="h3" style={[styles.title, pal.text]}>
|
||||
{title}
|
||||
</Text>
|
||||
<Text style={[styles.message, pal.textLight]}>{message}</Text>
|
||||
{details && (
|
||||
<Text
|
||||
type="body2"
|
||||
style={[
|
||||
styles.details,
|
||||
pal.textInverted,
|
||||
{backgroundColor: theme.palette.default.background},
|
||||
]}>
|
||||
{details}
|
||||
</Text>
|
||||
)}
|
||||
{onPressTryAgain && (
|
||||
<View style={styles.btnContainer}>
|
||||
<TouchableOpacity
|
||||
style={[styles.btn, {backgroundColor: theme.palette.error.icon}]}
|
||||
onPress={onPressTryAgain}>
|
||||
<FontAwesomeIcon icon="arrows-rotate" style={pal.text} size={16} />
|
||||
<Text type="button" style={[styles.btnText, pal.text]}>
|
||||
Try again
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
outer: {
|
||||
flex: 1,
|
||||
paddingVertical: 30,
|
||||
paddingHorizontal: 14,
|
||||
},
|
||||
title: {
|
||||
textAlign: 'center',
|
||||
marginBottom: 10,
|
||||
},
|
||||
message: {
|
||||
textAlign: 'center',
|
||||
marginBottom: 20,
|
||||
},
|
||||
details: {
|
||||
textAlign: 'center',
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 14,
|
||||
overflow: 'hidden',
|
||||
marginBottom: 20,
|
||||
},
|
||||
btnContainer: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
btn: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 10,
|
||||
},
|
||||
btnText: {
|
||||
marginLeft: 5,
|
||||
},
|
||||
errorIconContainer: {
|
||||
alignItems: 'center',
|
||||
marginBottom: 10,
|
||||
},
|
||||
errorIcon: {
|
||||
borderRadius: 30,
|
||||
width: 50,
|
||||
height: 50,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginRight: 5,
|
||||
},
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue