Commit a0073857 by tungnq

IMPORTANT: Đã hoàn thiện componet email chip input

- Nhấn vào button arrow để xem tất cả
- Nhấn vào TouchOpacity toàn dòng thì sẽ hiển thị text input cho người dùng nhập
parent 3c5a84e8
...@@ -48,6 +48,7 @@ const images = { ...@@ -48,6 +48,7 @@ const images = {
//Icon other //Icon other
icBack: require('./icon/icon_png/back.png'), icBack: require('./icon/icon_png/back.png'),
icBack2: require('./icon/back.png'),
icNext: require('./icon/icon_png/arrow_next.png'), icNext: require('./icon/icon_png/arrow_next.png'),
icCancel: require('./images/iconCancel.png'), icCancel: require('./images/iconCancel.png'),
icMale: require('./icon/icon_png/male.png'), icMale: require('./icon/icon_png/male.png'),
......
// FEATURE: Component EmailChipInput để nhập và hiển thị danh sách email dạng chip
import React, {useRef, useState} from 'react'; import React, {useRef, useState} from 'react';
import {View, TextInput, TouchableOpacity, Image} from 'react-native'; import {View, TextInput, TouchableOpacity, Image} from 'react-native';
import Chip from './chip'; import Chip from './chip';
import {BACKSPACE, DELIMITERS} from '../../config/constants'; import {BACKSPACE, DELIMITERS} from '../../config/constants';
import {isValidEmail} from '../../config/Functions'; import {isValidEmail} from '../../config/Functions';
import styles from './styles';
import {Text} from 'react-native'; import {Text} from 'react-native';
import R from '../../assets/R'; import R from '../../assets/R';
...@@ -75,17 +73,21 @@ export const EmailChipInput = ({ ...@@ -75,17 +73,21 @@ export const EmailChipInput = ({
autoFocus = false, autoFocus = false,
blurOnSubmit = true, blurOnSubmit = true,
keyboardType = 'email-address', keyboardType = 'email-address',
widthContainerInput= '100%', widthContainerInput = '100%',
}) => { }) => {
// STATE: Refs và state management
const ref = useRef(null); const ref = useRef(null);
const [emails, setEmails] = useState(entries); const [emails, setEmails] = useState(entries);
const [value, setValue] = useState(''); const [value, setValue] = useState('');
const [isExpanded, setIsExpanded] = useState(false); // Quản lý chế độ hiển thị chip const [isExpanded, setIsExpanded] = useState(false);
const [showInput, setShowInput] = useState(false);
const onBlur = () => {
if (!value) {
setShowInput(false);
}
};
// FUNCTIONALITY: Xử lý nhấn vào chip để edit
const handleOnPressChip = index => { const handleOnPressChip = index => {
// NOTE: Đưa email từ chip về input để chỉnh sửa
setValue(emails[index]); setValue(emails[index]);
setEmails(emails.filter((_, i) => i !== index)); setEmails(emails.filter((_, i) => i !== index));
...@@ -129,7 +131,7 @@ export const EmailChipInput = ({ ...@@ -129,7 +131,7 @@ export const EmailChipInput = ({
}; };
// FUNCTIONALITY: Xử lý blur/submit để finalize email // FUNCTIONALITY: Xử lý blur/submit để finalize email
const onBlur = () => { const handleBlur = () => {
// VALIDATION: Nếu email không hợp lệ hoặc rỗng, chỉ submit danh sách hiện tại // VALIDATION: Nếu email không hợp lệ hoặc rỗng, chỉ submit danh sách hiện tại
if (!isValidEmail(value)) { if (!isValidEmail(value)) {
return onSubmit(emails); return onSubmit(emails);
...@@ -150,7 +152,7 @@ export const EmailChipInput = ({ ...@@ -150,7 +152,7 @@ export const EmailChipInput = ({
// FUNCTIONALITY: Render chip theo chế độ hiển thị // FUNCTIONALITY: Render chip theo chế độ hiển thị
const renderChips = () => { const renderChips = () => {
if (emails.length === 0) return null; if (emails.length === 0) return null;
// Nếu chỉ có 1 chip hoặc đang ở chế độ mở rộng, hiển thị tất cả // Nếu chỉ có 1 chip hoặc đang ở chế độ mở rộng, hiển thị tất cả
if (emails.length === 1 || isExpanded) { if (emails.length === 1 || isExpanded) {
return emails.map((email, index) => ( return emails.map((email, index) => (
...@@ -166,7 +168,7 @@ export const EmailChipInput = ({ ...@@ -166,7 +168,7 @@ export const EmailChipInput = ({
/> />
)); ));
} }
// Chế độ thu gọn: chỉ hiển thị chip đầu + text số lượng // Chế độ thu gọn: chỉ hiển thị chip đầu + text số lượng
return ( return (
<> <>
...@@ -180,13 +182,14 @@ export const EmailChipInput = ({ ...@@ -180,13 +182,14 @@ export const EmailChipInput = ({
chipTextStyle={chipTextStyle} chipTextStyle={chipTextStyle}
marginHorizontal={5} marginHorizontal={5}
/> />
<Text style={{ <Text
fontSize: 12, style={{
color: R.colors.gray, fontSize: 12,
fontFamily: R.fonts.fontMedium, color: R.colors.gray,
marginLeft: 5, fontFamily: R.fonts.fontMedium,
alignSelf: 'center' marginLeft: 5,
}}> alignSelf: 'center',
}}>
+{emails.length - 1} more +{emails.length - 1} more
</Text> </Text>
</> </>
...@@ -201,66 +204,89 @@ export const EmailChipInput = ({ ...@@ -201,66 +204,89 @@ export const EmailChipInput = ({
flexDirection: 'row', flexDirection: 'row',
flexWrap: emails.length > 0 ? 'wrap' : 'nowrap', flexWrap: emails.length > 0 ? 'wrap' : 'nowrap',
alignItems: 'center', alignItems: 'center',
} },
]}> ]}>
{/* FEATURE: Render danh sách email chips */} {/* FEATURE: Render danh sách email chips */}
<Text <TouchableOpacity
style={{ onPress={() => setShowInput(true)}
fontSize: 12, style={{
color: R.colors.black, flexDirection: 'row',
fontFamily:R.fonts.fontMedium, flexWrap: emails.length > 0 ? 'wrap' : 'nowrap',
fontWeight:'600', alignItems: 'center',
}} }}>
>{title}</Text> <Text
{renderChips()} style={{
fontSize: 12,
color: R.colors.black,
fontFamily: R.fonts.fontMedium,
fontWeight: '600',
}}>
{title}
</Text>
{renderChips()}
</TouchableOpacity>
{/* FEATURE: Nút toggle thu gọn/phóng to */} {/* FEATURE: Nút toggle thu gọn/phóng to */}
{emails.length > 1 && ( {emails.length > 1 && (
<View style={{ position: 'absolute', right: 0, top: 5}}> <View style={{position: 'absolute', right: -3, top: 0}}>
<TouchableOpacity <TouchableOpacity
onPress={toggleExpanded} onPress={toggleExpanded}
> style={{
<Image backgroundColor: R.colors.blue4,
source={isExpanded ? R.images.icDrop : R.images.icDrop} borderRadius: 15,
style={{ padding: 3,
width: 30, }}>
height: 20, <Image
tintColor: R.colors.black source={isExpanded ? R.images.icBack2 : R.images.icDrop}
style={{
width: 25,
height: 25,
tintColor: R.colors.black,
}} }}
/> />
</TouchableOpacity> </TouchableOpacity>
</View> </View>
)} )}
{/* FEATURE: Input để nhập email mới */} {showInput && (
<View style={[{width: widthContainerInput}, inputContainerStyle]}> <View
<TextInput style={[
value={value} {width: '100%', height: 35, widthContainerInput},
ref={ref} inputContainerStyle,
onChangeText={onTextChange} ]}>
onKeyPress={onKeyPress} <TextInput
onSubmitEditing={onBlur} value={value}
onBlur={onBlur} ref={ref}
blurOnSubmit={blurOnSubmit} onChangeText={onTextChange}
keyboardType={keyboardType} onKeyPress={onKeyPress}
clearButtonMode={clearButtonMode} onSubmitEditing={handleBlur}
autoCorrect={autoCorrect} onBlur={onBlur}
autoFocus={autoFocus} blurOnSubmit={blurOnSubmit}
placeholder={placeholder} keyboardType={keyboardType}
autoCapitalize={autoCapitalize} clearButtonMode={clearButtonMode}
keyboardAppearance={keyboardAppearance} autoCorrect={autoCorrect}
placeholderTextColor={placeholderTextColor} autoFocus={autoFocus}
style={[{ placeholder={placeholder}
fontSize: 12, autoCapitalize={autoCapitalize}
color: R.colors.black, keyboardAppearance={keyboardAppearance}
fontFamily:R.fonts.fontMedium, placeholderTextColor={placeholderTextColor}
fontWeight:'600', style={[
borderBottomWidth:1, {
borderColor:R.colors.grayBorderInputTextHeader fontSize: 12,
}, inputStyle]} color: R.colors.black,
{...TextInputProps} fontFamily: R.fonts.fontMedium,
/> fontWeight: '600',
</View> padding: 0,
height: '100%',
paddingHorizontal: 0,
textAlignVertical: 'center',
},
inputStyle,
]}
{...TextInputProps}
/>
</View>
)}
</View> </View>
</View> </View>
); );
......
...@@ -39,8 +39,13 @@ const renderHeader = () => { ...@@ -39,8 +39,13 @@ const renderHeader = () => {
onSubmit={handleChange} onSubmit={handleChange}
chipContainerStyle={{ backgroundColor: R.colors.blue4}} chipContainerStyle={{ backgroundColor: R.colors.blue4}}
chipTextStyle={{ color:R.colors.black }} chipTextStyle={{ color:R.colors.black }}
containerStyle={{
borderBottomWidth:1,
borderColor: R.colors.blue4,
borderRadius: 5,
}}
chipImage={ chipImage={
<Image source={R.images.icCancel} style={styles.iconClose} tintColor={R.colors.blue}/> <Image source={R.images.icCancel} style={styles.iconClose} tintColor={R.colors.black}/>
} }
/> />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment