Add account creation

This commit is contained in:
Paul Frazee 2022-09-27 14:24:47 -05:00
parent c89ec94b17
commit ef4b9cf8d9
17 changed files with 727 additions and 272 deletions

View file

@ -0,0 +1,155 @@
import React, {useRef} from 'react'
import {
StyleProp,
StyleSheet,
Text,
TextStyle,
TouchableOpacity,
TouchableWithoutFeedback,
View,
ViewStyle,
} from 'react-native'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import RootSiblings from 'react-native-root-siblings'
import {colors} from '../../lib/styles'
interface PickerItem {
value: string
label: string
}
interface PickerOpts {
style?: StyleProp<ViewStyle>
labelStyle?: StyleProp<TextStyle>
iconStyle?: FontAwesomeIconStyle
items: PickerItem[]
value: string
onChange: (value: string) => void
enabled?: boolean
}
const MENU_WIDTH = 200
export function Picker({
style,
labelStyle,
iconStyle,
items,
value,
onChange,
enabled,
}: PickerOpts) {
const ref = useRef<View>(null)
const valueLabel = items.find(item => item.value === value)?.label || value
const onPress = () => {
if (!enabled) {
return
}
ref.current?.measure(
(
_x: number,
_y: number,
width: number,
height: number,
pageX: number,
pageY: number,
) => {
createDropdownMenu(pageX, pageY + height, MENU_WIDTH, items, onChange)
},
)
}
return (
<TouchableWithoutFeedback onPress={onPress}>
<View style={[styles.outer, style]} ref={ref}>
<View style={styles.label}>
<Text style={labelStyle}>{valueLabel}</Text>
</View>
<FontAwesomeIcon icon="angle-down" style={[styles.icon, iconStyle]} />
</View>
</TouchableWithoutFeedback>
)
}
function createDropdownMenu(
x: number,
y: number,
width: number,
items: PickerItem[],
onChange: (value: string) => void,
): RootSiblings {
const onPressItem = (index: number) => {
sibling.destroy()
onChange(items[index].value)
}
const onOuterPress = () => sibling.destroy()
const sibling = new RootSiblings(
(
<>
<TouchableWithoutFeedback onPress={onOuterPress}>
<View style={styles.bg} />
</TouchableWithoutFeedback>
<View style={[styles.menu, {left: x, top: y, width}]}>
{items.map((item, index) => (
<TouchableOpacity
key={index}
style={[styles.menuItem, index !== 0 && styles.menuItemBorder]}
onPress={() => onPressItem(index)}>
<Text style={styles.menuItemLabel}>{item.label}</Text>
</TouchableOpacity>
))}
</View>
</>
),
)
return sibling
}
const styles = StyleSheet.create({
outer: {
flexDirection: 'row',
alignItems: 'center',
},
label: {
marginRight: 5,
},
icon: {},
bg: {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
backgroundColor: '#000',
opacity: 0.1,
},
menu: {
position: 'absolute',
backgroundColor: '#fff',
borderRadius: 14,
opacity: 1,
paddingVertical: 6,
},
menuItem: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 6,
paddingLeft: 15,
paddingRight: 30,
},
menuItemBorder: {
borderTopWidth: 1,
borderTopColor: colors.gray2,
marginTop: 4,
paddingTop: 12,
},
menuItemIcon: {
marginLeft: 6,
marginRight: 8,
},
menuItemLabel: {
fontSize: 15,
},
})