chore(): sync

This commit is contained in:
Liam DeBeasi
2024-01-25 12:35:32 -05:00
110 changed files with 1819 additions and 585 deletions

View File

@ -776,8 +776,27 @@ export class Select implements ComponentInterface {
* We ensure the target isn't this element in case the select is slotted
* in, for example, an item. This would prevent the select from ever
* being opened since the element itself has slot="start"/"end".
*
* Clicking a slotted element also causes a click
* on the <label> element (since it wraps the slots).
* Clicking <label> dispatches another click event on
* the native form control that then bubbles up to this
* listener. This additional event targets the host
* element, so the select overlay is opened.
*
* When the slotted elements are clicked (and therefore
* the ancestor <label> element) we want to prevent the label
* from dispatching another click event.
*
* Do not call stopPropagation() because this will cause
* click handlers on the slotted elements to never fire in React.
* When developers do onClick in React a native "click" listener
* is added on the root element, not the slotted element. When that
* native click listener fires, React then dispatches the synthetic
* click event on the slotted element. However, if stopPropagation
* is called then the native click event will never bubble up
* to the root element.
*/
ev.stopPropagation();
ev.preventDefault();
}
};

View File

@ -69,3 +69,31 @@ describe('ion-select', () => {
expect(slotEl).toBe(null);
});
});
describe('select: slot interactivity', () => {
test('should not prevent click handlers from firing', async () => {
// https://github.com/ionic-team/ionic-framework/issues/28818
const divSpy = jest.fn();
const buttonSpy = jest.fn();
const page = await newSpecPage({
components: [Select],
template: () => (
<div onClick={divSpy}>
<ion-select label="Label Prop Text">
<button slot="end" onClick={buttonSpy}>
Button
</button>
</ion-select>
</div>
),
});
const button = page.body.querySelector('button')!;
await button.click();
expect(buttonSpy).toHaveBeenCalled();
expect(divSpy).toHaveBeenCalled();
});
});