From 3ba363cfe1ea1f96b8e263f29aa84079fae18fbb Mon Sep 17 00:00:00 2001 From: Mahmood Khalil Date: Sun, 8 Nov 2026 15:55:37 +0000 Subject: [PATCH] fix(labs): split button clicks on the menu icon and touch targets The leading slot's 48dp touch target is an absolutely positioned ::before. The slot has display: contents, so the touch target sized itself against the viewport. It covered the page around the split button and took clicks meant for nearby content. The menu icon is the trailing slot's ::after, and it painted over the slotted button, so clicking the chevron did nothing. The container now positions the touch targets, and the icon lets pointer events through. A click on a slot's touch target outside the slotted button now activates that button. --- .../splitbutton/split-button-element.ts | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/labs/gb/components/splitbutton/split-button-element.ts b/labs/gb/components/splitbutton/split-button-element.ts index c4184f55f4..815b186793 100644 --- a/labs/gb/components/splitbutton/split-button-element.ts +++ b/labs/gb/components/splitbutton/split-button-element.ts @@ -52,6 +52,15 @@ export class SplitButtonElement extends LitElement { } .split-btn { flex: 1; + /* Contains the slots' touch targets (::before, absolute). The leading + slot is display: contents, so without this its touch target sizes + against the viewport and covers the page. */ + position: relative; + } + /* The menu icon is the trailing slot's ::after, painted over the + slotted button: clicks pass through to the button. */ + [name='trailing']::after { + pointer-events: none; } [name='leading'] { display: contents; @@ -90,7 +99,8 @@ export class SplitButtonElement extends LitElement { part="leading-btn" class="${button(buttonConfig)}" @focusin=${this.updateSlotFocusVisible} - @focusout=${this.updateSlotFocusVisible}> + @focusout=${this.updateSlotFocusVisible} + @click=${this.forwardSlotClick}> `; } + /** + * A click on a slot's own box (its 48dp touch target, outside the slotted + * button) activates that slot's button, as a tap on the touch target of a + * button does. + */ + private forwardSlotClick(event: MouseEvent) { + const slot = event.currentTarget as HTMLSlotElement; + if (event.target !== slot) return; + const target = slot + .assignedElements() + .find((el): el is HTMLButtonElement => el.matches('button')); + if (!target || target.disabled) return; + event.stopPropagation(); + target.click(); + } + private updateSlotFocusVisible(event: Event) { const slot = event.currentTarget as HTMLSlotElement; const hasFocusVisible = slot