mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	Refine input
This commit is contained in:
		| @@ -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,13 +156,15 @@ const Input: React.FC<Props> = ({ | ||||
|             {title} | ||||
|           </Animated.Text> | ||||
|         ) : null} | ||||
|         {maxLength && value?.length ? ( | ||||
|         <View style={{ flexDirection: 'row' }}> | ||||
|           {options?.maxLength && value?.length ? ( | ||||
|             <Text style={[styles.maxLength, { color: theme.secondary }]}> | ||||
|             {value?.length} / {maxLength} | ||||
|               {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 | ||||
|   } | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -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' | ||||
|   | ||||
| @@ -113,6 +113,7 @@ const ScreenMeProfileFields: React.FC<StackScreenProps< | ||||
|  | ||||
|   return ( | ||||
|     <ScrollView style={styles.base} keyboardShouldPersistTaps='handled'> | ||||
|       <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 }]}> | ||||
| @@ -121,7 +122,7 @@ const ScreenMeProfileFields: React.FC<StackScreenProps< | ||||
|             <Input | ||||
|               title={t('me.profile.fields.label')} | ||||
|               autoFocus={false} | ||||
|             maxLength={255} | ||||
|               options={{ maxLength: 255 }} | ||||
|               value={newFields[index].name} | ||||
|               setValue={(v: any) => | ||||
|                 setNewFields( | ||||
| @@ -135,7 +136,7 @@ const ScreenMeProfileFields: React.FC<StackScreenProps< | ||||
|             <Input | ||||
|               title={t('me.profile.fields.content')} | ||||
|               autoFocus={false} | ||||
|             maxLength={255} | ||||
|               options={{ maxLength: 255 }} | ||||
|               value={newFields[index].value} | ||||
|               setValue={(v: any) => | ||||
|                 setNewFields( | ||||
| @@ -148,13 +149,15 @@ const ScreenMeProfileFields: React.FC<StackScreenProps< | ||||
|             /> | ||||
|           </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 | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
| }) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user