Skip to content

Commit

Permalink
fix: don't capture non-left mouse clicks on combobox
Browse files Browse the repository at this point in the history
Right-clicking on a combobox input or menu option should
not behave like a left click. this commit skips the
custom mouse down handling if not left-click.
  • Loading branch information
mike-mike-mike-mike-mike committed Jan 26, 2024
1 parent beeb640 commit 319627a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 5 deletions.
56 changes: 54 additions & 2 deletions src/components/Combobox/Combobox.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,31 @@ describe('<Combobox />', () => {
sinon.assert.calledWith(mockOnChange, OPTIONS[1].value);
});

it('should select an option with left-click only', () => {
const mockOnChange = sinon.spy();
const combobox = render(<Combobox options={OPTIONS} onChange={mockOnChange} />);
const input = combobox.getByTestId('react-gears-combobox-input');

fireEvent.focus(input);
assert.strictEqual(
combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'),
'false'
);

const option = combobox.getByText('D-O');
fireEvent.mouseDown(option, { button: 2 });
assert.strictEqual(
combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'),
'false'
);

fireEvent.mouseDown(option);
assert.strictEqual(
combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'),
'true'
);
});

it('should deselect option on backspace', () => {
let value;
const mockOnChange = (v) => {
Expand Down Expand Up @@ -265,7 +290,7 @@ describe('<Combobox />', () => {
);
});

it('should open options if input is clicked', async () => {
it('should open options if input is left-clicked', async () => {
const combobox = render(<Combobox options={OPTIONS} value={3} />);

assert.equal(
Expand All @@ -274,8 +299,14 @@ describe('<Combobox />', () => {
);

const input = combobox.getByTestId('react-gears-combobox-input');
fireEvent.mouseDown(input);

fireEvent.mouseDown(input, { button: 2 });
assert.equal(
combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'),
'true'
);

fireEvent.mouseDown(input);
assert.equal(
combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'),
'false'
Expand Down Expand Up @@ -309,6 +340,27 @@ describe('<Combobox />', () => {
);
});

it('should open options with dropdown toggle left-click only', () => {
const combobox = render(<Combobox options={OPTIONS} />);
const caret = combobox.getByTestId('react-gears-combobox-button');
assert.equal(
combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'),
'true'
);

fireEvent.mouseDown(caret, { button: 2 });
assert.equal(
combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'),
'true'
);

fireEvent.mouseDown(caret);
assert.equal(
combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'),
'false'
);
});

describe('default filterOptions ', () => {
it('should filter by input (case insensitive)', () => {
const combobox = render(<Combobox options={OPTIONS} />);
Expand Down
23 changes: 20 additions & 3 deletions src/components/Combobox/Combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ function Combobox<T>({
setFocusedOptionIndex(visibleIndex);
}}
onMouseDown={(ev) => {
if (ev.button !== 0) {
return;
}

ev.preventDefault();
ev.stopPropagation();
selectOption(option.value);
Expand Down Expand Up @@ -311,6 +315,10 @@ function Combobox<T>({
data-testid="react-gears-combobox-dropdownitem-create-new-option"
disabled={!isValidNewOption(inputValue)}
onMouseDown={(ev) => {
if (ev.button !== 0) {
return;
}

ev.preventDefault();
ev.stopPropagation();
createOption();
Expand Down Expand Up @@ -389,17 +397,22 @@ function Combobox<T>({
onChange(undefined);
}
}}
onMouseDown={(e) => {
onMouseDown={(ev) => {
if (ev.button !== 0) {
ev.preventDefault();
return;
}

if (!multi && selected) {
inputElement!.current!.setSelectionRange(0, 0);

if ((selected as Option<T>).label === inputValue) {
e.preventDefault();
ev.preventDefault();
}
}

// @ts-ignore
e.target.focus();
ev.target.focus();
}}
onKeyDown={handleOptionsKeyboardNav}
onKeyPress={clearSelectedPreview}
Expand All @@ -415,6 +428,10 @@ function Combobox<T>({
disabled={disabled}
active={open}
onMouseDown={(ev: React.MouseEvent<HTMLButtonElement>) => {
if (ev.button !== 0) {
return;
}

ev.stopPropagation();
setOpen(!open);
}}
Expand Down

0 comments on commit 319627a

Please sign in to comment.