Skip to content

Commit

Permalink
[Select] Fix custom options menu not opening on Avatar click (mui#34648)
Browse files Browse the repository at this point in the history
  • Loading branch information
shivam1646 authored and Daniel Rabe committed Nov 29, 2022
1 parent eff666b commit 85581e5
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 3 deletions.
13 changes: 13 additions & 0 deletions docs/data/joy/components/select/select-pt.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ Use the `startDecorator` and/or `endDecorator` props to add supporting icons or

{{"demo": "SelectDecorators.js"}}

If you have interactive elements as the select's decorators, call `stopPropagation()` from the mouse down event to prevent the popup from being opened.

```jsx
<IconButton
onMouseDown={(event) => {
// don't open the popup when clicking on this button
event.stopPropagation();
}}
onClick={() => {
// click handler goes here
}
>...</IconButton>
```
### Indicator
To change the default indicator, use the `indicator` prop with either any React element (including string) or `null` as value (to remove the indicator completely).
Expand Down
13 changes: 13 additions & 0 deletions docs/data/joy/components/select/select-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ Use the `startDecorator` and/or `endDecorator` props to add supporting icons or

{{"demo": "SelectDecorators.js"}}

If you have interactive elements as the select's decorators, call `stopPropagation()` from the mouse down event to prevent the popup from being opened.

```jsx
<IconButton
onMouseDown={(event) => {
// don't open the popup when clicking on this button
event.stopPropagation();
}}
onClick={() => {
// click handler goes here
}
>...</IconButton>
```
### Indicator
To change the default indicator, use the `indicator` prop with either any React element (including string) or `null` as value (to remove the indicator completely).
Expand Down
14 changes: 14 additions & 0 deletions docs/data/joy/components/select/select.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ Use the `startDecorator` and/or `endDecorator` props to add supporting icons or

{{"demo": "SelectDecorators.js"}}

If you have interactive elements as the select's decorators, call `stopPropagation()` from the mouse down event to prevent the popup from being opened.

```jsx
<IconButton
onMouseDown={(event) => {
// don't open the popup when clicking on this button
event.stopPropagation();
}}
onClick={() => {
// click handler goes here
}
>...</IconButton>
```
### Indicator
To change the default indicator, use the `indicator` prop with either any React element (including string) or `null` as value (to remove the indicator completely).
Expand Down
42 changes: 42 additions & 0 deletions packages/mui-joy/src/Select/Select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -593,4 +593,46 @@ describe('Joy <Select />', () => {
expect(isEventHandled).to.equal(true);
});
});

it('should show dropdown if the children of the select button is clicked', () => {
const { getByTestId, getByRole } = render(
<Select defaultValue="1">
<Option value="1">
<span data-testid="test-element" />
Eric
</Option>
</Select>,
);
// Fire Click of the avatar
act(() => {
getByTestId('test-element').click();
});

expect(getByRole('button', { hidden: true })).to.have.attribute('aria-expanded', 'true');
});

it('should not show dropdown if stop propagation is handled', () => {
const handleClick = spy();
const { getByTestId, getByRole } = render(
<Select
defaultValue="1"
startDecorator={
<div
data-testid="test-element"
onMouseDown={(event) => event.stopPropagation()}
onClick={handleClick}
/>
}
>
<Option value="1">Eric</Option>
</Select>,
);
// Fire Click of the avatar
act(() => {
getByTestId('test-element').click();
});

expect(getByRole('button', { hidden: true })).to.have.attribute('aria-expanded', 'false');
expect(handleClick.callCount).to.equal(1);
});
});
9 changes: 6 additions & 3 deletions packages/mui-joy/src/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ const SelectStartDecorator = styled('span', {
'--Button-margin': '0 0 0 calc(var(--Select-decorator-childOffset) * -1)',
'--IconButton-margin': '0 0 0 calc(var(--Select-decorator-childOffset) * -1)',
'--Icon-margin': '0 0 0 calc(var(--Select-paddingInline) / -4)',
pointerEvents: 'none', // to make the input focused when click on the element because start element usually is an icon
display: 'inherit',
alignItems: 'center',
marginInlineEnd: 'var(--Select-gap)',
Expand Down Expand Up @@ -436,12 +435,16 @@ const Select = React.forwardRef(function Select<TValue extends {}>(
elementType: SelectRoot,
getSlotProps: (handlers) => ({
onMouseDown: (event: React.MouseEvent<HTMLDivElement>) => {
if (!listboxOpen && event.target !== buttonRef.current && !event.isPropagationStopped()) {
if (
!listboxOpen &&
!buttonRef.current?.contains(event.target as Node) &&
!event.isPropagationStopped()
) {
// show the popup if user click outside of the button element.
// the close action is already handled by blur event.
handleOpenChange(true);
}
handlers.onClick?.(event);
handlers.onMouseDown?.(event);
},
}),
externalSlotProps: componentsProps.root,
Expand Down

0 comments on commit 85581e5

Please sign in to comment.