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 = {
//Icon other
icBack: require('./icon/icon_png/back.png'),
icBack2: require('./icon/back.png'),
icNext: require('./icon/icon_png/arrow_next.png'),
icCancel: require('./images/iconCancel.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 {View, TextInput, TouchableOpacity, Image} from 'react-native';
import Chip from './chip';
import {BACKSPACE, DELIMITERS} from '../../config/constants';
import {isValidEmail} from '../../config/Functions';
import styles from './styles';
import {Text} from 'react-native';
import R from '../../assets/R';
......@@ -75,17 +73,21 @@ export const EmailChipInput = ({
autoFocus = false,
blurOnSubmit = true,
keyboardType = 'email-address',
widthContainerInput= '100%',
widthContainerInput = '100%',
}) => {
// STATE: Refs và state management
const ref = useRef(null);
const [emails, setEmails] = useState(entries);
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 => {
// NOTE: Đưa email từ chip về input để chỉnh sửa
setValue(emails[index]);
setEmails(emails.filter((_, i) => i !== index));
......@@ -129,7 +131,7 @@ export const EmailChipInput = ({
};
// 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
if (!isValidEmail(value)) {
return onSubmit(emails);
......@@ -150,7 +152,7 @@ export const EmailChipInput = ({
// FUNCTIONALITY: Render chip theo chế độ hiển thị
const renderChips = () => {
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ả
if (emails.length === 1 || isExpanded) {
return emails.map((email, index) => (
......@@ -166,7 +168,7 @@ export const EmailChipInput = ({
/>
));
}
// Chế độ thu gọn: chỉ hiển thị chip đầu + text số lượng
return (
<>
......@@ -180,13 +182,14 @@ export const EmailChipInput = ({
chipTextStyle={chipTextStyle}
marginHorizontal={5}
/>
<Text style={{
fontSize: 12,
color: R.colors.gray,
fontFamily: R.fonts.fontMedium,
marginLeft: 5,
alignSelf: 'center'
}}>
<Text
style={{
fontSize: 12,
color: R.colors.gray,
fontFamily: R.fonts.fontMedium,
marginLeft: 5,
alignSelf: 'center',
}}>
+{emails.length - 1} more
</Text>
</>
......@@ -201,66 +204,89 @@ export const EmailChipInput = ({
flexDirection: 'row',
flexWrap: emails.length > 0 ? 'wrap' : 'nowrap',
alignItems: 'center',
}
},
]}>
{/* FEATURE: Render danh sách email chips */}
<Text
style={{
fontSize: 12,
color: R.colors.black,
fontFamily:R.fonts.fontMedium,
fontWeight:'600',
}}
>{title}</Text>
{renderChips()}
<TouchableOpacity
onPress={() => setShowInput(true)}
style={{
flexDirection: 'row',
flexWrap: emails.length > 0 ? 'wrap' : 'nowrap',
alignItems: 'center',
}}>
<Text
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 */}
{emails.length > 1 && (
<View style={{ position: 'absolute', right: 0, top: 5}}>
<View style={{position: 'absolute', right: -3, top: 0}}>
<TouchableOpacity
onPress={toggleExpanded}
>
<Image
source={isExpanded ? R.images.icDrop : R.images.icDrop}
style={{
width: 30,
height: 20,
tintColor: R.colors.black
style={{
backgroundColor: R.colors.blue4,
borderRadius: 15,
padding: 3,
}}>
<Image
source={isExpanded ? R.images.icBack2 : R.images.icDrop}
style={{
width: 25,
height: 25,
tintColor: R.colors.black,
}}
/>
</TouchableOpacity>
</View>
)}
{/* FEATURE: Input để nhập email mới */}
<View style={[{width: widthContainerInput}, inputContainerStyle]}>
<TextInput
value={value}
ref={ref}
onChangeText={onTextChange}
onKeyPress={onKeyPress}
onSubmitEditing={onBlur}
onBlur={onBlur}
blurOnSubmit={blurOnSubmit}
keyboardType={keyboardType}
clearButtonMode={clearButtonMode}
autoCorrect={autoCorrect}
autoFocus={autoFocus}
placeholder={placeholder}
autoCapitalize={autoCapitalize}
keyboardAppearance={keyboardAppearance}
placeholderTextColor={placeholderTextColor}
style={[{
fontSize: 12,
color: R.colors.black,
fontFamily:R.fonts.fontMedium,
fontWeight:'600',
borderBottomWidth:1,
borderColor:R.colors.grayBorderInputTextHeader
}, inputStyle]}
{...TextInputProps}
/>
</View>
{showInput && (
<View
style={[
{width: '100%', height: 35, widthContainerInput},
inputContainerStyle,
]}>
<TextInput
value={value}
ref={ref}
onChangeText={onTextChange}
onKeyPress={onKeyPress}
onSubmitEditing={handleBlur}
onBlur={onBlur}
blurOnSubmit={blurOnSubmit}
keyboardType={keyboardType}
clearButtonMode={clearButtonMode}
autoCorrect={autoCorrect}
autoFocus={autoFocus}
placeholder={placeholder}
autoCapitalize={autoCapitalize}
keyboardAppearance={keyboardAppearance}
placeholderTextColor={placeholderTextColor}
style={[
{
fontSize: 12,
color: R.colors.black,
fontFamily: R.fonts.fontMedium,
fontWeight: '600',
padding: 0,
height: '100%',
paddingHorizontal: 0,
textAlignVertical: 'center',
},
inputStyle,
]}
{...TextInputProps}
/>
</View>
)}
</View>
</View>
);
......
......@@ -39,8 +39,13 @@ const renderHeader = () => {
onSubmit={handleChange}
chipContainerStyle={{ backgroundColor: R.colors.blue4}}
chipTextStyle={{ color:R.colors.black }}
containerStyle={{
borderBottomWidth:1,
borderColor: R.colors.blue4,
borderRadius: 5,
}}
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