v4.6 -1 (#459)
This commit is contained in:
99
projects/app/src/components/common/Textarea/TagTextarea.tsx
Normal file
99
projects/app/src/components/common/Textarea/TagTextarea.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import React, { useCallback, useRef, useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
BoxProps,
|
||||
Flex,
|
||||
Input,
|
||||
Tag,
|
||||
TagCloseButton,
|
||||
TagLabel,
|
||||
useTheme
|
||||
} from '@chakra-ui/react';
|
||||
import { useToast } from '@/web/common/hooks/useToast';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type Props = BoxProps & { defaultValues: string[]; onUpdate: (e: string[]) => void };
|
||||
|
||||
const TagTextarea = ({ defaultValues, onUpdate, ...props }: Props) => {
|
||||
const theme = useTheme();
|
||||
const InputRef = useRef<HTMLInputElement>(null);
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const [focus, setFocus] = useState(false);
|
||||
const [tags, setTags] = useState<string[]>(defaultValues);
|
||||
|
||||
const onUpdateValue = useCallback(
|
||||
(value?: string) => {
|
||||
setFocus(false);
|
||||
if (!value || !InputRef.current?.value) {
|
||||
return;
|
||||
}
|
||||
if (tags.includes(value)) {
|
||||
toast({
|
||||
status: 'warning',
|
||||
title: t('common.input.Repeat Value')
|
||||
});
|
||||
}
|
||||
setTags([...tags, value]);
|
||||
onUpdate([...tags, value]);
|
||||
InputRef.current.value = '';
|
||||
},
|
||||
[onUpdate, t, tags, toast]
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
w={'100%'}
|
||||
minH={'200px'}
|
||||
borderRadius={'md'}
|
||||
border={theme.borders.base}
|
||||
p={2}
|
||||
fontSize={'sm'}
|
||||
bg={'myWhite.600'}
|
||||
{...(focus && {
|
||||
boxShadow: '0px 0px 4px #A8DBFF',
|
||||
borderColor: 'myBlue.600'
|
||||
})}
|
||||
{...props}
|
||||
onClick={() => {
|
||||
if (!focus) {
|
||||
InputRef.current?.focus();
|
||||
setFocus(true);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Flex alignItems={'center'} gap={2} flexWrap={'wrap'}>
|
||||
{tags.map((tag, i) => (
|
||||
<Tag key={tag} colorScheme="blue" onClick={(e) => e.stopPropagation()}>
|
||||
<TagLabel>{tag}</TagLabel>
|
||||
<TagCloseButton
|
||||
onClick={() => {
|
||||
const val = tags.filter((_, index) => index !== i);
|
||||
setTags(val);
|
||||
onUpdate(val);
|
||||
}}
|
||||
/>
|
||||
</Tag>
|
||||
))}
|
||||
<Input
|
||||
ref={InputRef}
|
||||
variant={'unstyled'}
|
||||
display={'inline-block'}
|
||||
w="auto"
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value;
|
||||
onUpdateValue(value);
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
onUpdateValue(InputRef.current?.value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default TagTextarea;
|
||||
Reference in New Issue
Block a user