Refine input

This commit is contained in:
Zhiyuan Zheng 2021-05-10 23:41:48 +02:00
parent 7da8297b46
commit c0dfc30dec
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
5 changed files with 105 additions and 57 deletions

View File

@ -9,7 +9,14 @@ import React, {
useRef,
useState
} from 'react'
import { Platform, StyleSheet, Text, TextInput, View } from 'react-native'
import {
Platform,
StyleSheet,
Text,
TextInput,
TextInputProps,
View
} from 'react-native'
import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'
import {
ComponentEmojis,
@ -23,7 +30,6 @@ export interface Props {
title?: string
maxLength?: number
multiline?: boolean
emoji?: boolean
@ -32,16 +38,28 @@ export interface Props {
setValue:
| Dispatch<SetStateAction<string | undefined>>
| Dispatch<SetStateAction<string>>
options?: Omit<
TextInputProps,
| 'autoFocus'
| 'onFocus'
| 'onBlur'
| 'style'
| 'onChangeText'
| 'onSelectionChange'
| 'keyboardAppearance'
| 'textAlignVertical'
>
}
const Input: React.FC<Props> = ({
autoFocus = true,
title,
maxLength,
multiline = false,
emoji = false,
value,
setValue
setValue,
options
}) => {
const { mode, theme } = useTheme()
@ -90,7 +108,15 @@ const Input: React.FC<Props> = ({
setValue={setValue}
selectionRange={selectionRange}
>
<View style={[styles.base, { borderColor: theme.border }]}>
<View
style={[
styles.base,
{
borderColor: theme.border,
flexDirection: multiline ? 'column' : 'row'
}
]}
>
<EmojisContext.Consumer>
{({ emojisDispatch }) => (
<TextInput
@ -113,11 +139,13 @@ const Input: React.FC<Props> = ({
onChangeText={setValue}
onSelectionChange={onSelectionChange}
value={value}
maxLength={maxLength}
{...(multiline && {
multiline,
numberOfLines: Platform.OS === 'android' ? 5 : undefined
})}
keyboardAppearance={mode}
textAlignVertical='top'
{...options}
/>
)}
</EmojisContext.Consumer>
@ -128,12 +156,14 @@ const Input: React.FC<Props> = ({
{title}
</Animated.Text>
) : null}
{maxLength && value?.length ? (
<Text style={[styles.maxLength, { color: theme.secondary }]}>
{value?.length} / {maxLength}
</Text>
) : null}
{inputFocused ? <EmojisButton /> : null}
<View style={{ flexDirection: 'row' }}>
{options?.maxLength && value?.length ? (
<Text style={[styles.maxLength, { color: theme.secondary }]}>
{value?.length} / {options.maxLength}
</Text>
) : null}
{inputFocused ? <EmojisButton /> : null}
</View>
</View>
<EmojisList />
</ComponentEmojis>
@ -142,7 +172,6 @@ const Input: React.FC<Props> = ({
const styles = StyleSheet.create({
base: {
flexDirection: 'row',
alignItems: 'flex-end',
borderWidth: 1,
marginVertical: StyleConstants.Spacing.S,
@ -156,7 +185,8 @@ const styles = StyleSheet.create({
fontSize: StyleConstants.Font.Size.M
},
maxLength: {
...StyleConstants.FontStyle.S
...StyleConstants.FontStyle.S,
paddingLeft: StyleConstants.Spacing.XS
}
})

View File

@ -26,10 +26,7 @@ const TabMeProfile: React.FC<StackScreenProps<
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
<Stack.Navigator
screenOptions={{
headerHideShadow: true,
headerTopInsetEnabled: false
}}
screenOptions={{ headerHideShadow: true, headerTopInsetEnabled: false }}
>
<Stack.Screen
name='Tab-Me-Profile-Root'

View File

@ -113,48 +113,51 @@ const ScreenMeProfileFields: React.FC<StackScreenProps<
return (
<ScrollView style={styles.base} keyboardShouldPersistTaps='handled'>
{Array.from(Array(4).keys()).map(index => (
<View key={index} style={styles.group}>
<Text style={[styles.headline, { color: theme.primaryDefault }]}>
{t('me.profile.fields.group', { index: index + 1 })}
</Text>
<Input
title={t('me.profile.fields.label')}
autoFocus={false}
maxLength={255}
value={newFields[index].name}
setValue={(v: any) =>
setNewFields(
newFields.map((field, i) =>
i === index ? { ...field, name: v } : field
<View style={{ marginBottom: StyleConstants.Spacing.L * 2 }}>
{Array.from(Array(4).keys()).map(index => (
<View key={index} style={styles.group}>
<Text style={[styles.headline, { color: theme.primaryDefault }]}>
{t('me.profile.fields.group', { index: index + 1 })}
</Text>
<Input
title={t('me.profile.fields.label')}
autoFocus={false}
options={{ maxLength: 255 }}
value={newFields[index].name}
setValue={(v: any) =>
setNewFields(
newFields.map((field, i) =>
i === index ? { ...field, name: v } : field
)
)
)
}
emoji
/>
<Input
title={t('me.profile.fields.content')}
autoFocus={false}
maxLength={255}
value={newFields[index].value}
setValue={(v: any) =>
setNewFields(
newFields.map((field, i) =>
i === index ? { ...field, value: v } : field
}
emoji
/>
<Input
title={t('me.profile.fields.content')}
autoFocus={false}
options={{ maxLength: 255 }}
value={newFields[index].value}
setValue={(v: any) =>
setNewFields(
newFields.map((field, i) =>
i === index ? { ...field, value: v } : field
)
)
)
}
emoji
/>
</View>
))}
}
emoji
/>
</View>
))}
</View>
</ScrollView>
)
}
const styles = StyleSheet.create({
base: {
padding: StyleConstants.Spacing.Global.PagePadding
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
marginBottom: StyleConstants.Spacing.L
},
group: {
marginBottom: StyleConstants.Spacing.M

View File

@ -95,14 +95,24 @@ const ScreenMeProfileName: React.FC<StackScreenProps<
return (
<ScrollView style={styles.base} keyboardShouldPersistTaps='handled'>
<Input value={displayName} setValue={setDisplayName} emoji />
<Input
value={displayName}
setValue={setDisplayName}
emoji
options={{
maxLength: 30,
autoCapitalize: 'none',
autoCompleteType: 'username',
autoCorrect: false
}}
/>
</ScrollView>
)
}
const styles = StyleSheet.create({
base: {
padding: StyleConstants.Spacing.Global.PagePadding
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding
}
})

View File

@ -7,7 +7,7 @@ import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { RefObject, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Alert, StyleSheet } from 'react-native'
import { Alert, StyleSheet, View } from 'react-native'
import FlashMessage from 'react-native-flash-message'
import { ScrollView } from 'react-native-gesture-handler'
@ -95,14 +95,22 @@ const ScreenMeProfileNote: React.FC<StackScreenProps<
return (
<ScrollView style={styles.base} keyboardShouldPersistTaps='handled'>
<Input value={newNote} setValue={setNewNote} multiline emoji />
<View style={{ marginBottom: StyleConstants.Spacing.XL * 2 }}>
<Input
value={newNote}
setValue={setNewNote}
multiline
emoji
options={{ maxLength: 500 }}
/>
</View>
</ScrollView>
)
}
const styles = StyleSheet.create({
base: {
padding: StyleConstants.Spacing.Global.PagePadding
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding
}
})