ColorPickerInput: Fixed color picker disappearing on input blur (#102241)
* ColorPickerInput: Fixed color picker disappearing on input blur * Updates per feedback around targeting method * Updated per feedback - testid vs id
This commit is contained in:
@@ -12,6 +12,24 @@ describe('ColorPickerInput', () => {
|
||||
expect(screen.getByTestId('color-popover')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should hide color popover on blur', async () => {
|
||||
render(<ColorPickerInput onChange={noop} />);
|
||||
expect(screen.queryByTestId('color-popover')).not.toBeInTheDocument();
|
||||
await userEvent.click(screen.getByRole('textbox'));
|
||||
expect(screen.getByTestId('color-popover')).toBeInTheDocument();
|
||||
await userEvent.click(document.body);
|
||||
expect(screen.queryByTestId('color-popover')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not hide color popover on blur if clicked inside the color picker', async () => {
|
||||
render(<ColorPickerInput onChange={noop} />);
|
||||
expect(screen.queryByTestId('color-popover')).not.toBeInTheDocument();
|
||||
await userEvent.click(screen.getByRole('textbox'));
|
||||
expect(screen.getByTestId('color-popover')).toBeInTheDocument();
|
||||
await userEvent.click(screen.getAllByRole('slider')[0]);
|
||||
expect(screen.queryByTestId('color-popover')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should pass correct color to onChange callback', async () => {
|
||||
const mockOnChange = jest.fn();
|
||||
render(<ColorPickerInput onChange={mockOnChange} />);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { useState, forwardRef } from 'react';
|
||||
import { useState, forwardRef, FocusEvent } from 'react';
|
||||
import { RgbaStringColorPicker } from 'react-colorful';
|
||||
import { useThrottleFn } from 'react-use';
|
||||
|
||||
@@ -48,6 +48,14 @@ export const ColorPickerInput = forwardRef<HTMLInputElement, ColorPickerInputPro
|
||||
[currentColor]
|
||||
);
|
||||
|
||||
const handleBlur = (evt: FocusEvent<HTMLInputElement>) => {
|
||||
// Unless the user clicked inside the color picker, close it on blur
|
||||
const isClickInPopover = document.querySelector('[data-testid="color-popover"]')?.contains(evt.relatedTarget);
|
||||
if (!isClickInPopover) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ClickOutsideWrapper onClick={() => setIsOpen(false)}>
|
||||
<div className={styles.wrapper}>
|
||||
@@ -66,7 +74,7 @@ export const ColorPickerInput = forwardRef<HTMLInputElement, ColorPickerInputPro
|
||||
onChange={setColor}
|
||||
buttonAriaLabel="Open color picker"
|
||||
onClick={() => setIsOpen(true)}
|
||||
onBlur={() => setIsOpen(false)}
|
||||
onBlur={(e) => handleBlur(e)}
|
||||
ref={ref}
|
||||
isClearable
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user