@chakra-ui/react#TagCloseButton TypeScript Examples

The following examples show how to use @chakra-ui/react#TagCloseButton. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ReactSelectCustomization.tsx    From ke with MIT License 6 votes vote down vote up
export function MultiValue<OptionType>(props: MultiValueProps<OptionType>): JSX.Element {
  const { children, className, cx, getStyles, innerProps, isDisabled, removeProps, data, selectProps } = props

  const { multiValueContainer, multiValueLabel, multiValueRemove } = useStyles()

  const externalClassName = (selectProps as ExtendedProps).componentsClasses?.MultiValue

  return (
    <ClassNames>
      {({ css, cx: emotionCx }) => (
        <Tag data={data} sx={multiValueContainer} {...innerProps} className={classNames(className, externalClassName)}>
          <TagLabel sx={multiValueLabel} className={className}>
            {children}
          </TagLabel>
          <TagCloseButton
            className={emotionCx(
              css(getStyles('multiValueRemove', props)),
              cx(
                {
                  'multi-value__remove': true,
                },
                className
              )
            )}
            isDisabled={isDisabled}
            {...removeProps}
            sx={multiValueRemove}
          />
        </Tag>
      )}
    </ClassNames>
  )
}
Example #2
Source File: SelectedFoodItem.tsx    From calories-in with MIT License 6 votes vote down vote up
function SelectedFoodItem({ food, onUnselect }: Props) {
  return (
    <Fade in={true}>
      <Tag
        size="md"
        borderRadius="full"
        variant="outline"
        colorScheme="teal"
        maxWidth="250px"
      >
        <TagLabel>{food.name}</TagLabel>
        <TagCloseButton onClick={() => onUnselect(food)} />
      </Tag>
    </Fade>
  )
}
Example #3
Source File: ContactDialog.tsx    From bluebubbles-server with Apache License 2.0 4 votes vote down vote up
ContactDialog = ({
    onCancel,
    onDelete,
    onCreate,
    onUpdate,
    onClose,
    onAddressAdd,
    onAddressDelete,
    isOpen,
    modalRef,
    existingContact,
}: ContactDialogProps): JSX.Element => {
    const [firstName, setFirstName] = useState('');
    const [lastName, setLastName] = useState('');
    const [displayName, setDisplayName] = useState('');
    const [currentAddress, setCurrentAddress] = useState('');
    const [hasEdited, setHasEdited] = useBoolean(false);
    const [phones, setPhones] = useState([] as ContactAddress[]);
    const [emails, setEmails] = useState([] as ContactAddress[]);
    const [firstNameError, setFirstNameError] = useState('');
    const isNameValid = (firstNameError ?? '').length > 0;

    useEffect(() => {
        if (!existingContact) return;
        if (existingContact.firstName) setFirstName(existingContact.firstName);
        if (existingContact.lastName) setLastName(existingContact.lastName);
        if (existingContact.displayName) setDisplayName(existingContact.displayName);
        if (existingContact.phoneNumbers) setPhones(existingContact.phoneNumbers);
        if (existingContact.emails) setEmails(existingContact.emails);
    }, [existingContact]);

    const addAddress = (address: string) => {
        const existsPhone = phones.map((e: ContactAddress) => e.address).includes(address);
        const existsEmail = emails.map((e: ContactAddress) => e.address).includes(address);
        if (existsPhone || existsEmail) {
            return showErrorToast({
                id: 'contacts',
                description: 'Address already exists!'
            });
        }

        if (address.includes('@')) {
            setEmails([{ address }, ...emails]);
        } else {
            setPhones([{ address }, ...phones]);
        }

        if (onAddressAdd && existingContact) {
            onAddressAdd(existingContact.id, address);
        }
    };

    const removeAddress = (address: string, addressId: number | null) => {
        if (address.includes('@')) {
            setEmails(emails.filter((e: NodeJS.Dict<any>) => e.address !== address));
        } else {
            setPhones(phones.filter((e: NodeJS.Dict<any>) => e.address !== address));
        }

        if (onAddressDelete && addressId) {
            onAddressDelete(addressId);
        }
    };

    const _onClose = () => {
        setPhones([]);
        setEmails([]);
        setFirstName('');
        setLastName('');
        setDisplayName('');
        setCurrentAddress('');
        setHasEdited.off();

        if (onClose) onClose();
    };

    return (
        <AlertDialog
            isOpen={isOpen}
            leastDestructiveRef={modalRef}
            onClose={() => onClose()}
        >
            <AlertDialogOverlay>
                <AlertDialogContent>
                    <AlertDialogHeader fontSize='lg' fontWeight='bold'>
                        {(existingContact) ? 'Edit Contact' : 'Add a new Contact'}
                    </AlertDialogHeader>

                    <AlertDialogBody>
                        <Text>Add a custom contact to the server's database</Text>
                        <FormControl isInvalid={isNameValid} mt={5}>
                            <FormLabel htmlFor='firstName'>First Name</FormLabel>
                            <Input
                                id='firstName'
                                type='text'
                                value={firstName}
                                placeholder='Tim'
                                onChange={(e) => {
                                    setFirstNameError('');
                                    setFirstName(e.target.value);
                                    if (!hasEdited) {
                                        setDisplayName(`${e.target.value} ${lastName}`.trim());
                                    }
                                }}
                            />
                            {isNameValid ? (
                                <FormErrorMessage>{firstNameError}</FormErrorMessage>
                            ) : null}
                        </FormControl>
                        <FormControl mt={5}>
                            <FormLabel htmlFor='lastName'>Last Name</FormLabel>
                            <Input
                                id='lastName'
                                type='text'
                                value={lastName}
                                placeholder='Apple'
                                onChange={(e) => {
                                    setLastName(e.target.value);
                                    if (!hasEdited) {
                                        setDisplayName(`${firstName} ${e.target.value}`.trim());
                                    }
                                }}
                            />
                        </FormControl>
                        <FormControl mt={5}>
                            <FormLabel htmlFor='lastName'>Display Name</FormLabel>
                            <Input
                                id='displayName'
                                type='text'
                                value={displayName}
                                placeholder='Tim Apple'
                                onChange={(e) => {
                                    setHasEdited.on();
                                    setDisplayName(e.target.value);
                                }}
                            />
                        </FormControl>
                        <FormControl mt={5}>
                            <FormLabel htmlFor='address'>Addresses</FormLabel>
                            <HStack>
                                <Input
                                    id='address'
                                    type='text'
                                    value={currentAddress}
                                    placeholder='Add Address'
                                    onChange={(e) => {
                                        setCurrentAddress(e.target.value);
                                    }}
                                />
                                <IconButton
                                    onClick={() => {
                                        if (!currentAddress || currentAddress.length === 0) return;
                                        addAddress(currentAddress);
                                        setCurrentAddress('');
                                    }}
                                    aria-label='Add'
                                    icon={<AiOutlinePlus />}
                                />
                            </HStack>
                            <Flex flexDirection="row" alignItems="center" justifyContent="flex-start" flexWrap="wrap" mt={2}>
                                {[...phones, ...emails].map(((e: ContactAddress) => {
                                    return (
                                        <Tag
                                            mt={1}
                                            mx={1}
                                            size={'md'}
                                            key={e.address}
                                            borderRadius='full'
                                            variant='solid'
                                        >
                                            <TagLabel>{e.address}</TagLabel>
                                            <TagCloseButton
                                                onClick={() => {
                                                    removeAddress(e.address, (e.id) ? e.id : null);
                                                }}
                                            />
                                        </Tag>
                                    );
                                }))}
                            </Flex>
                        </FormControl>
                    </AlertDialogBody>

                    <AlertDialogFooter>
                        <Button
                            ref={modalRef as React.LegacyRef<HTMLButtonElement> | undefined}
                            onClick={() => {
                                if (!existingContact && onCancel) onCancel();
                                if (existingContact && onUpdate) {
                                    existingContact.firstName = firstName;
                                    existingContact.lastName = lastName;
                                    existingContact.displayName = displayName;
                                    onUpdate(existingContact);
                                }
                                _onClose();
                            }}
                        >
                            {(existingContact) ? 'Save & Close' : 'Cancel'}
                        </Button>
                        {(existingContact) ? (
                            <Button
                                ml={3}
                                bg='red'
                                ref={modalRef as React.LegacyRef<HTMLButtonElement> | undefined}
                                onClick={() => {
                                    if (onDelete) {
                                        onDelete(Number.parseInt(existingContact.id));
                                    }

                                    _onClose();
                                }}
                            >
                                Delete
                            </Button>
                        ) : null}
                        {(!existingContact) ? (
                            <Button
                                ml={3}
                                bg='brand.primary'
                                ref={modalRef as React.LegacyRef<HTMLButtonElement> | undefined}
                                onClick={() => {
                                    if (firstName.length === 0) {
                                        setFirstNameError('Please enter a first name for the contact!');
                                        return;
                                    }

                                    if (onCreate) {
                                        onCreate({
                                            firstName,
                                            lastName,
                                            phoneNumbers: phones,
                                            emails: emails,
                                            displayName,
                                            birthday: '',
                                            avatar: '',
                                            id: '',
                                            sourceType: 'db'
                                        });
                                    }

                                    _onClose();
                                }}
                            >
                                Create
                            </Button>
                        ) : null}
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialogOverlay>
        </AlertDialog>
    );
}
Example #4
Source File: ChipInput.tsx    From ke with MIT License 4 votes vote down vote up
ChipInput = forwardRef<HTMLInputElement, ChipInputProps>((props, ref): JSX.Element => {
  const {
    value: inputValue,
    onChange,
    placeholder,
    submitKeys = ['Enter', 'Tab'],
    validator = () => true,
    errorText = 'Invalid value',
    chipClassName,
    inputClassName,
  } = props
  const [chips, setChips] = usePropState<string[]>(inputValue)
  const [value, setValue] = useState<string>('')
  const [error, setError] = useState<string>('')
  // TODO: Исправить
  // eslint-disable-next-line react-hooks/rules-of-hooks
  const inputRef = (ref as RefObject<HTMLInputElement>) ?? useRef<HTMLInputElement>(null)

  const isValid = useCallback(
    (val: string): boolean => {
      if (!validator(val)) {
        setError(errorText)
        return false
      }
      setError('')
      return true
    },
    [errorText, validator]
  )

  const deleteChip = useCallback(
    (index: number): void => {
      const newChips = chips.filter((_, chipIndex) => chipIndex !== index)
      setChips(newChips)
      onChange(newChips)
    },
    [onChange, chips, setChips]
  )

  const finishInput = useCallback((): void => {
    const trimmedValue = value.trim()
    if (trimmedValue && isValid(trimmedValue)) {
      const newChips = [...chips, trimmedValue]
      setChips(newChips)
      onChange(newChips)
      setValue('')
      setError('')
    }
  }, [onChange, chips, setChips, isValid, value])

  const handleKeyDown = useCallback(
    (e: KeyboardEvent<HTMLInputElement>): void => {
      if (submitKeys.includes(e.key)) {
        e.preventDefault()
        finishInput()
      }
      if (e.key === 'Backspace') {
        if (!value && chips.length > 0) {
          e.preventDefault()
          deleteChip(chips.length - 1)
        }
      }
    },
    [chips.length, deleteChip, finishInput, submitKeys, value]
  )

  const { container, input, chip, chipLabel } = useMultiStyleConfig('ChipInput', props)

  return (
    <>
      <Flex __css={container} onClick={() => inputRef?.current?.focus?.()}>
        {chips.map((chipValue: string, index: number) => {
          const key = index
          return (
            <Tag key={key} minWidth={undefined} minHeight={undefined} sx={chip} className={chipClassName}>
              <TagLabel sx={chipLabel} width="100%">
                {chipValue}
              </TagLabel>
              <TagCloseButton onClick={() => deleteChip(key)} />
            </Tag>
          )
        })}
        <Input
          variant="unstyled"
          sx={input}
          value={value}
          onChange={(e: ChangeEvent<HTMLInputElement>): void => setValue(e.target.value)}
          placeholder={placeholder}
          onKeyDown={handleKeyDown}
          isInvalid={!!error}
          ref={inputRef}
          width="auto"
          height="2rem"
          borderRadius="0px"
          onBlur={finishInput}
          className={inputClassName}
        />
      </Flex>
      {error && (
        <Text className="error" fontSize="0.7rem" color="red.400">
          {error}
        </Text>
      )}
    </>
  )
})