refactor some inputs

This commit is contained in:
ammarahm-ed
2020-12-17 15:42:55 +05:00
parent 7b34157d45
commit 4aaedbed13
3 changed files with 255 additions and 335 deletions

View File

@@ -23,6 +23,7 @@ import {GetPremium} from '../ActionSheetComponent/GetPremium';
import DialogButtons from '../Dialog/dialog-buttons'; import DialogButtons from '../Dialog/dialog-buttons';
import DialogHeader from '../Dialog/dialog-header'; import DialogHeader from '../Dialog/dialog-header';
import {updateEvent} from '../DialogManager/recievers'; import {updateEvent} from '../DialogManager/recievers';
import Input from '../Input';
import {Toast} from '../Toast'; import {Toast} from '../Toast';
import Paragraph from '../Typography/Paragraph'; import Paragraph from '../Typography/Paragraph';
@@ -129,7 +130,7 @@ export class AddNotebookDialog extends React.Component {
let edit = this.props.toEdit; let edit = this.props.toEdit;
if (!this.title || this.title?.trim().length === 0) if (!this.title || this.title?.trim().length === 0)
return ToastEvent.show('Title is required', 'error', 'local'); return ToastEvent.show('Notebook title is required', 'error', 'local');
let id = edit && edit.id ? edit.id : null; let id = edit && edit.id ? edit.id : null;
@@ -282,136 +283,60 @@ export class AddNotebookDialog extends React.Component {
} }
/> />
<TextInput <Input
ref={(ref) => (this.titleRef = ref)} fwdRef={(ref) => (this.titleRef = ref)}
testID={notesnook.ids.dialogs.notebook.inputs.title} testID={notesnook.ids.dialogs.notebook.inputs.title}
style={[
styles.input,
{
borderColor: titleFocused ? colors.accent : colors.nav,
color: colors.pri,
fontSize: SIZE.md,
},
]}
numberOfLines={1}
multiline={false}
onFocus={() => {
this.setState({
titleFocused: true,
});
}}
onBlur={() => {
this.setState({
titleFocused: false,
});
}}
defaultValue={toEdit ? toEdit.title : null}
onChangeText={(value) => { onChangeText={(value) => {
this.title = value; this.title = value;
}} }}
onSubmitEditing={() => { placeholder="Title"
onSubmit={() => {
this.descriptionRef.focus(); this.descriptionRef.focus();
}} }}
placeholder="Title" defaultValue={toEdit ? toEdit.title : null}
placeholderTextColor={colors.icon}
/> />
<TextInput
ref={(ref) => (this.descriptionRef = ref)} <Input
testID={notesnook.ids.dialogs.notebook.inputs.description} fwdRef={(ref) => (this.descriptionRef = ref)}
style={[ testID={notesnook.ids.dialogs.notebook.inputs.title}
styles.input, onChangeText={(value) => {
{ this.description = value;
borderColor: descFocused ? colors.accent : colors.nav, this.currentInputValue = value;
minHeight: 45, if (this.prevItem !== null) {
color: colors.pri, refs[this.prevIndex].setNativeProps({
}, text: this.prevIndex + 1 + '. ' + value,
]} style: {
maxLength={150} borderBottomColor: colors.accent,
onFocus={() => { },
this.setState({ });
descFocused: true, }
});
}} }}
onBlur={() => { placeholder="Describe your notebook."
this.setState({ onSubmit={() => {
descFocused: false, this.topicInputRef.focus();
});
}} }}
defaultValue={toEdit ? toEdit.description : null} defaultValue={toEdit ? toEdit.title : null}
/>
<Input
fwdRef={(ref) => (this.topicInputRef = ref)}
testID={notesnook.ids.dialogs.notebook.inputs.title}
onChangeText={(value) => { onChangeText={(value) => {
this.description = value; this.description = value;
}} }}
onSubmitEditing={() => {
this.topicInputRef.focus();
}}
placeholder="Describe your notebook." placeholder="Describe your notebook."
placeholderTextColor={colors.icon} onSubmit={() => {
this.onSubmit();
}}
button={{
icon: this.state.editTopic ? 'check' : 'plus',
onPress: this.onSubmit,
color: topicInputFocused ? colors.accent : colors.icon,
}}
placeholder="Add a topic"
defaultValue={toEdit ? toEdit.title : null}
/> />
<View style={styles.topicContainer}>
<TextInput
ref={(ref) => (this.topicInputRef = ref)}
testID={notesnook.ids.dialogs.notebook.inputs.topic}
onChangeText={(value) => {
this.currentInputValue = value;
if (this.prevItem !== null) {
refs[this.prevIndex].setNativeProps({
text: this.prevIndex + 1 + '. ' + value,
style: {
borderBottomColor: colors.accent,
},
});
}
}}
blurOnSubmit={false}
onFocus={() => {
this.setState({
topicInputFocused: true,
});
}}
onBlur={() => {
this.onSubmit(false);
this.setState({
topicInputFocused: false,
editTopic: false,
});
}}
onSubmitEditing={this.onSubmit}
style={[
styles.input,
{
borderColor: topicInputFocused
? colors.accent
: colors.nav,
color: colors.pri,
width: '100%',
maxWidth: '100%',
marginTop: 5,
paddingRight: '15%',
},
]}
placeholder="Add a topic"
placeholderTextColor={colors.icon}
/>
<TouchableOpacity
onPress={this.onSubmit}
testID={notesnook.ids.dialogs.notebook.buttons.add}
style={[
styles.addBtn,
{
borderColor: topicInputFocused
? colors.accent
: colors.nav,
},
]}>
<Icon
name={this.state.editTopic ? 'check' : 'plus'}
size={SIZE.lg}
color={topicInputFocused ? colors.accent : colors.icon}
/>
</TouchableOpacity>
</View>
<FlatList <FlatList
data={topics} data={topics}
ref={(ref) => (this.listRef = ref)} ref={(ref) => (this.listRef = ref)}

View File

@@ -1,5 +1,4 @@
import React, {createRef} from 'react'; import React, {createRef} from 'react';
import {TextInput} from 'react-native-gesture-handler';
import {Actions} from '../../provider/Actions'; import {Actions} from '../../provider/Actions';
import { import {
eSendEvent, eSendEvent,
@@ -13,12 +12,12 @@ import {
eOnNewTopicAdded, eOnNewTopicAdded,
eOpenAddTopicDialog, eOpenAddTopicDialog,
} from '../../utils/Events'; } from '../../utils/Events';
import {SIZE, WEIGHT} from '../../utils/SizeUtils';
import BaseDialog from '../Dialog/base-dialog'; import BaseDialog from '../Dialog/base-dialog';
import DialogButtons from '../Dialog/dialog-buttons'; import DialogButtons from '../Dialog/dialog-buttons';
import DialogContainer from '../Dialog/dialog-container'; import DialogContainer from '../Dialog/dialog-container';
import DialogHeader from '../Dialog/dialog-header'; import DialogHeader from '../Dialog/dialog-header';
import {updateEvent} from '../DialogManager/recievers'; import {updateEvent} from '../DialogManager/recievers';
import Input from '../Input';
import {Toast} from '../Toast'; import {Toast} from '../Toast';
export class AddTopicDialog extends React.Component { export class AddTopicDialog extends React.Component {
@@ -75,7 +74,7 @@ export class AddTopicDialog extends React.Component {
}; };
render() { render() {
const {visible, titleFocused} = this.state; const {visible} = this.state;
const {colors, toEdit} = this.props; const {colors, toEdit} = this.props;
if (!visible) return null; if (!visible) return null;
return ( return (
@@ -93,34 +92,15 @@ export class AddTopicDialog extends React.Component {
paragraph={'Add a new topic to ' + this.notebook.title} paragraph={'Add a new topic to ' + this.notebook.title}
/> />
<TextInput <Input
ref={this.titleRef} fwdRef={this.titleRef}
style={{
paddingTop: 10,
paddingBottom: 5,
borderBottomWidth: 1,
borderColor: titleFocused ? colors.accent : colors.nav,
paddingHorizontal: 0,
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
color: colors.pri,
}}
onFocus={() => {
this.setState({
titleFocused: true,
});
}}
onBlur={() => {
this.setState({
titleFocused: true,
});
}}
defaultValue={toEdit ? toEdit.title : null}
onChangeText={(value) => { onChangeText={(value) => {
this.title = value; this.title = value;
}} }}
blurOnSubmit={false}
defaultValue={toEdit ? toEdit.title : null}
placeholder="Enter title of topic" placeholder="Enter title of topic"
placeholderTextColor={colors.icon} onSubmit={this.addNewTopic}
/> />
<DialogButtons <DialogButtons

View File

@@ -1,200 +1,215 @@
import React, {useState} from 'react';
import React, { useState } from 'react'; import {View} from 'react-native';
import { View } from 'react-native'; import {TextInput} from 'react-native-gesture-handler';
import { TextInput } from 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import { useTracked } from '../../provider/index'; import {useTracked} from '../../provider/index';
import { import {
validateEmail, validateEmail,
validatePass, validatePass,
validateUsername validateUsername,
} from '../../services/Validation'; } from '../../services/Validation';
import { getElevation } from '../../utils'; import {getElevation} from '../../utils';
import { SIZE, WEIGHT } from '../../utils/SizeUtils'; import {SIZE, WEIGHT} from '../../utils/SizeUtils';
import Paragraph from '../Typography/Paragraph'; import Paragraph from '../Typography/Paragraph';
const Input = ({ const Input = ({
fwdRef, fwdRef,
validationType, validationType,
loading, loading,
autoCapitalize, autoCapitalize,
onChangeText, onChangeText,
onSubmit, onSubmit,
blurOnSubmit, blurOnSubmit,
placeholder, placeholder,
onErrorCheck, onErrorCheck,
errorMessage, errorMessage,
secureTextEntry, secureTextEntry,
customColor, customColor,
customValidator, customValidator,
marginBottom = 10, marginBottom = 10,
}) => { button,
const [state] = useTracked(); testID,
const colors = state.colors; defaultValue
const [error, setError] = useState(false); }) => {
const [value, setValue] = useState(null); const [state] = useTracked();
const [focus, setFocus] = useState(false); const colors = state.colors;
const [secureEntry, setSecureEntry] = useState(true); const [error, setError] = useState(false);
const [showError, setShowError] = useState(false); const [value, setValue] = useState(null);
const color = error const [focus, setFocus] = useState(false);
? colors.red const [secureEntry, setSecureEntry] = useState(true);
: focus const [showError, setShowError] = useState(false);
? customColor || colors.accent const color = error
: colors.nav; ? colors.red
: focus
const validate = () => { ? customColor || colors.accent
if (!validationType) return; : colors.nav;
if (!value || value?.length === 0) {
setError(false); const validate = () => {
onErrorCheck(false); if (!validationType) return;
return; if (!value || value?.length === 0) {
} setError(false);
let isError = false; onErrorCheck(false);
switch (validationType) { return;
case 'password': }
isError = validatePass(value); let isError = false;
break; switch (validationType) {
case 'email': case 'password':
isError = validateEmail(value); isError = validatePass(value);
break; break;
case 'username': case 'email':
isError = validateUsername(value); isError = validateEmail(value);
break; break;
case 'confirmPassword': case 'username':
isError = value === customValidator(); isError = validateUsername(value);
break; break;
} case 'confirmPassword':
console.log('isError', isError, error); isError = value === customValidator();
setError(!isError); break;
onErrorCheck(!isError); }
}; console.log('isError', isError, error);
setError(!isError);
const onChange = (value) => { onErrorCheck(!isError);
onChangeText(value);
setValue(value);
if (error) {
validate();
}
};
const onBlur = () => {
setFocus(false);
validate();
};
const onFocus = () => {
setFocus(true);
};
const style = {
borderBottomWidth: 1,
borderColor: color,
paddingHorizontal: 0,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-end',
height: 50,
marginBottom: marginBottom,
};
const textStyle = {
paddingHorizontal: 0,
fontSize: SIZE.md,
fontFamily: WEIGHT.regular,
color: colors.pri,
paddingVertical: 0,
paddingBottom: 2.5,
flexGrow: 1,
height: 35,
};
return (
<>
<View style={style}>
<TextInput
ref={fwdRef}
editable={!loading}
defaultValue={value}
autoCapitalize={autoCapitalize}
onChangeText={onChange}
onBlur={onBlur}
onFocus={onFocus}
onSubmitEditing={onSubmit}
blurOnSubmit={blurOnSubmit}
style={textStyle}
secureTextEntry={secureTextEntry && secureEntry}
placeholder={placeholder}
placeholderTextColor={colors.icon}
/>
<View
style={{
flexDirection: 'row',
justifyContent: 'center',
height: 35,
alignItems: 'center',
}}>
{secureTextEntry && (
<Icon
name="eye"
size={20}
onPress={() => {
setSecureEntry(!secureEntry);
}}
style={{
width: 25,
marginLeft: 5,
}}
color={secureEntry ? colors.icon : colors.accent}
/>
)}
{error && (
<Icon
name="alert-circle-outline"
onPress={() => {
setShowError(!showError);
}}
size={20}
style={{
width: 25,
marginLeft: 5,
}}
color={colors.errorText}
/>
)}
</View>
{error && showError && errorMessage ? (
<View
style={{
position: 'absolute',
backgroundColor: colors.nav,
paddingVertical: 3,
paddingHorizontal: 5,
borderRadius: 2.5,
...getElevation(2),
top: 0,
}}>
<Paragraph
size={SIZE.xs}
style={{
textAlign: 'right',
textAlignVertical: 'bottom',
}}>
<Icon
name="alert-circle-outline"
size={SIZE.xs}
color={colors.errorText}
/>{' '}
{errorMessage}
</Paragraph>
</View>
) : null}
</View>
</>
);
}; };
export default Input const onChange = (value) => {
onChangeText(value);
setValue(value);
if (error) {
validate();
}
};
const onBlur = () => {
setFocus(false);
validate();
};
const onFocus = () => {
setFocus(true);
};
const style = {
borderBottomWidth: 1,
borderColor: color,
paddingHorizontal: 0,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-end',
height: 50,
marginBottom: marginBottom,
};
const textStyle = {
paddingHorizontal: 0,
fontSize: SIZE.md,
fontFamily: WEIGHT.regular,
color: colors.pri,
paddingVertical: 0,
paddingBottom: 2.5,
flexGrow: 1,
height: 35,
};
return (
<>
<View style={style}>
<TextInput
ref={fwdRef}
testID={testID}
editable={!loading}
defaultValue={defaultValue}
autoCapitalize={autoCapitalize}
onChangeText={onChange}
onBlur={onBlur}
onFocus={onFocus}
onSubmitEditing={onSubmit}
blurOnSubmit={blurOnSubmit}
style={textStyle}
secureTextEntry={secureTextEntry && secureEntry}
placeholder={placeholder}
placeholderTextColor={colors.icon}
/>
<View
style={{
flexDirection: 'row',
justifyContent: 'center',
height: 35,
alignItems: 'center',
}}>
{secureTextEntry && (
<Icon
name="eye"
size={20}
onPress={() => {
setSecureEntry(!secureEntry);
}}
style={{
width: 25,
marginLeft: 5,
}}
color={secureEntry ? colors.icon : colors.accent}
/>
)}
{button && (
<Icon
name={button.icon}
size={20}
onPress={button.onPress}
style={{
width: 25,
marginLeft: 5,
}}
color={button.color}
/>
)}
{error && (
<Icon
name="alert-circle-outline"
onPress={() => {
setShowError(!showError);
}}
size={20}
style={{
width: 25,
marginLeft: 5,
}}
color={colors.errorText}
/>
)}
</View>
{error && showError && errorMessage ? (
<View
style={{
position: 'absolute',
backgroundColor: colors.nav,
paddingVertical: 3,
paddingHorizontal: 5,
borderRadius: 2.5,
...getElevation(2),
top: 0,
}}>
<Paragraph
size={SIZE.xs}
style={{
textAlign: 'right',
textAlignVertical: 'bottom',
}}>
<Icon
name="alert-circle-outline"
size={SIZE.xs}
color={colors.errorText}
/>{' '}
{errorMessage}
</Paragraph>
</View>
) : null}
</View>
</>
);
};
export default Input;