Skip to content

Commit

Permalink
Improves the MultiEmailIput component interactions. (#2359)
Browse files Browse the repository at this point in the history
* Set the value of the props menuIsOpen from the local state and the local state will be set to true only when the input has some content.

* Cleaned up the paste event handler to gracefully handle the email creation based on the pasted content.

* Sets the isMenuOpen to false once an email change is handled.

* Added test case to verify the functionality.
  • Loading branch information
deepakjosp authored Oct 26, 2024
1 parent bf1f004 commit eb90348
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 11 deletions.
28 changes: 18 additions & 10 deletions src/components/MultiEmailInput/constants.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,25 @@ const SelectContainer = props => (
/>
);

const Input = props => (
<components.Input
{...props}
data-cy="email-select-input-field"
onPaste={e => {
const clipboardData = e.clipboardData.getData("Text");
const Input = props => {
const handlePaste = event => {
const { handleEmailChange } = props.selectProps;

setTimeout(() => props.selectProps.handleEmailChange(clipboardData));
}}
/>
);
const text = event.clipboardData.getData("Text");
if (!EMAIL_REGEX.test(text)) return;

event?.preventDefault();
setTimeout(() => handleEmailChange(text));
};

return (
<components.Input
{...props}
data-cy="email-select-input-field"
onPaste={handlePaste}
/>
);
};

export const EMAIL_REGEX = new RegExp(
"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$",
Expand Down
8 changes: 7 additions & 1 deletion src/components/MultiEmailInput/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const MultiEmailInput = forwardRef(
const [inputValue, setInputValue] = useState("");
const [isFocused, setIsFocused] = useState(false);
const [duplicateEmails, setDuplicateEmails] = useState([]);
const [isMenuOpen, setIsMenuOpen] = useState(false);

const isCounterVisible =
!!counter &&
Expand All @@ -73,6 +74,7 @@ const MultiEmailInput = forwardRef(
onChange(uniqueEmails);
setDuplicateEmails(duplicates);
setInputValue("");
setIsMenuOpen(false);
};

const handleKeyDown = event => {
Expand Down Expand Up @@ -169,6 +171,7 @@ const MultiEmailInput = forwardRef(
classNamePrefix="neeto-ui-react-select"
components={CUSTOM_COMPONENTS}
isDisabled={disabled}
menuIsOpen={isMenuOpen}
className={classnames(
"neeto-ui-react-select__container neeto-ui-react-select__container--medium neeto-ui-email-input__select",
{ "neeto-ui-react-select__container--error": !!error }
Expand All @@ -182,8 +185,11 @@ const MultiEmailInput = forwardRef(
}}
onBlur={handleBlur}
onFocus={() => setIsFocused(true)}
onInputChange={inputValue => setInputValue(inputValue)}
onKeyDown={handleKeyDown}
onInputChange={inputValue => {
setIsMenuOpen(Boolean(inputValue));
setInputValue(inputValue);
}}
{...{
handleEmailChange,
inputValue,
Expand Down
22 changes: 22 additions & 0 deletions tests/MultiEmailInput.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,26 @@ describe("MultiEmailInput", () => {
{ label: "[email protected]", valid: true, value: "[email protected]" },
]);
});

it("should not render the menu when clicked on the input field", async () => {
const onChange = jest.fn();
const selectedEmails = SAMPLE_EMAILS.slice(0, 2);
const { container } = render(
<MultiEmailInput
{...{ onChange }}
options={SAMPLE_EMAILS}
value={selectedEmails}
/>
);
const emailInput = screen.getByRole("combobox");
await userEvent.click(emailInput);
expect(
container.querySelector(".neeto-ui-react-select__menu")
).not.toBeInTheDocument();

await userEvent.type(emailInput, "test");
await expect(
container.querySelector(".neeto-ui-react-select__menu")
).toBeInTheDocument();
});
});

0 comments on commit eb90348

Please sign in to comment.