react-tagsinput
react-tagsinput copied to clipboard
Can't remove a tag when input filed has overflow
Hello, first of all, thank you for this library and for maintaining it.
I am having an issue with removing a tag when I have a dense populated input field. The bug happens only when I try to delete tags on top of the overflow.
I recorded a quick video to better explain it: TagBug.webm
Does anyone know why this is happening? and If there is a quick solution? One solution that came in mind was to control the onRemove method on the tag, but it seems like this method isn't exposed?
Thanks in advance!
Can you post some example code and which browser and React version you are using?
Can you post some example code and which browser and React version you are using?
Version: React: "^16.12.0" Browsers: Google Chrome Version 107.0.5304.107 (Official Build) (64-bit)
import React, {
Fragment,
useRef,
useState,
useEffect,
forwardRef,
} from 'react';
import PropTypes from 'prop-types';
import { randomId } from '@igloosoftware/iglue';
import TagsInput from '@incoqnito.io/react-tagsinput';
import '@incoqnito.io/react-tagsinput/react-tagsinput.css';
import classNames from 'classnames';
import styles from './TagBox.scss';
import FormInputMessage, { ALLOWED_MESSAGE_TYPES } from '../../atoms/FormInputMessage';
const TagBox = forwardRef((props, forwardedRef) => {
const [tags, setTags] = useState(props.tags);
const tagsInput = useRef(null);
// In case a ref is passed to TagBox (eg. AddModal.js)
// set that ref to point to the correct element
useEffect(() => {
if (!forwardedRef) {
return;
}
forwardedRef.current = tagsInput.current;
}, []); // eslint-disable-line react-hooks/exhaustive-deps
const {
error,
border,
message,
onChange,
messageId,
inputProps,
...rest
} = props;
const inputMessageId = useRef(messageId || randomId());
const handleChange = (newTags) => {
setTags(newTags);
if (typeof onChange === 'function') {
onChange(newTags);
}
};
let wrapperClass = classNames('react-tagsinput',
{
[styles['react-tagsinput--error']]: error,
[styles['react-tagsinput-noborder']]: !border,
'react-tagsinput-placeholder': !tags.length,
});
let newInputProps = Object.assign({}, inputProps);
if (tags.length) {
newInputProps.placeholder = '';
}
const isDescribedBy = [
...(message ? [inputMessageId.current] : []),
].filter(Boolean).join(' ');
return <Fragment>
<TagsInput
{...rest}
ref={tagsInput}
value={tags}
onChange={handleChange}
className={wrapperClass}
inputProps={newInputProps}
focusedClassName={styles['react-tagsinput--focused']}
tagProps={{
className: `${styles['react-tagsinput-tag']}`,
classNameRemove: `${styles['react-tagsinput-remove']}`,
'aria-describedby': isDescribedBy.length ? isDescribedBy : undefined,
}} />
{message &&
<FormInputMessage
id={inputMessageId.current}
type={error ? ALLOWED_MESSAGE_TYPES.ERROR : ALLOWED_MESSAGE_TYPES.INFO}
message={message} />
}
</Fragment>;
});
TagBox.displayName = 'TagBox';
TagBox.propTypes = {
tags: PropTypes.array,
error: PropTypes.bool,
border: PropTypes.bool,
message: PropTypes.string,
onChange: PropTypes.func,
validate: PropTypes.func,
addOnBlur: PropTypes.bool,
messageId: PropTypes.string,
inputProps: PropTypes.object,
onlyUnique: PropTypes.bool,
};
TagBox.defaultProps = {
tags: [],
error: false,
border: false,
onChange: null,
addOnBlur: false,
onlyUnique: false,
inputProps: {
title: '',
className: 'react-tagsinput-input',
placeholder: '',
},
};
export default TagBox;