Problem
Several container components fire click/press events on behalf of their children (e.g., List fires item-click, Menu fires item-click), but the child elements themselves have no public click event. This means framework consumers (React, Angular, Vue) using wrappers like createReactComponent cannot attach onClick handlers directly on child elements — they must listen on the parent and match the clicked item from the event detail.
For example, React consumers expect to write:
<ListItemStandard onClick={() => handleClick()}>Product A</ListItemStandard>
But currently must write:
<List onItemClick={(e) => { if (e.detail.item === targetRef) handleClick(); }}>
<ListItemStandard>Product A</ListItemStandard>
</List>
Prior Art
This pattern has already been implemented for:
TableRow — fires own click + Table keeps row-click (#13303)
TableRowActionBase — fires own click + Table keeps row-action-click
SideNavigationSelectableItemBase — fires own click + SideNavigation keeps item-click
Button, Link, Icon, CardHeader, Tag, Avatar — all suppress the native click and fire a semantic CustomEvent("click") covering mouse + keyboard
The pattern: intercept the native DOM click on the child via stopImmediatePropagation, fire a CustomEvent("click") via fireDecoratorEvent, then call the parent's handler for backward compatibility.
Candidates
High impact
| Child Component |
Parent Component |
Parent Event |
Mechanism |
ListItemBase (all variants) |
List |
item-click |
Private _press event → List re-fires |
MenuItem |
Menu |
item-click |
Via inner List's item-click |
TreeItemBase / TreeItem |
Tree |
item-click |
Via inner List's item-click |
NotificationListItem |
NotificationList |
item-click |
Private _press → inner List → parent |
UserMenuItem |
UserMenu |
item-click |
Via inner List's item-click |
Note: ListItemBase is the foundation. Adding a semantic click there would cascade to MenuItem, TreeItem, NotificationListItem, and all other ListItem variants.
Medium impact
| Child Component |
Parent Component |
Parent Event |
Mechanism |
Tab |
TabContainer |
tab-select |
Pure DOM delegation, no child event |
BreadcrumbsItem |
Breadcrumbs |
item-click |
Internal Link click, parent maps to item |
SegmentedButtonItem |
SegmentedButton |
selection-change |
Pure DOM delegation, no child event |
WizardTab |
Wizard |
step-change |
Private selection-change-requested |
Low impact
| Child Component |
Parent Component |
Parent Event |
ColorPaletteItem |
ColorPalette |
item-click |
Implementation approach
For each candidate:
- Declare
click in the base class eventDetails (to preserve JSX type compatibility in the hierarchy)
- Add
@eventStrict("click", { bubbles: true }) on the concrete child class
- Intercept the native click in the constructor (
this.addEventListener("click", ...)) — suppress via stopImmediatePropagation, fire fireDecoratorEvent("click")
- Keep the existing parent-level event (
item-click, tab-select, etc.) for backward compatibility
Suggested order
ListItemBase — highest impact, cascades to Menu, Tree, NotificationList
Tab — commonly requested by framework consumers
BreadcrumbsItem / SegmentedButtonItem — smaller scope, straightforward
Problem
Several container components fire click/press events on behalf of their children (e.g.,
Listfiresitem-click,Menufiresitem-click), but the child elements themselves have no publicclickevent. This means framework consumers (React, Angular, Vue) using wrappers likecreateReactComponentcannot attachonClickhandlers directly on child elements — they must listen on the parent and match the clicked item from the event detail.For example, React consumers expect to write:
But currently must write:
Prior Art
This pattern has already been implemented for:
TableRow— fires ownclick+ Table keepsrow-click(#13303)TableRowActionBase— fires ownclick+ Table keepsrow-action-clickSideNavigationSelectableItemBase— fires ownclick+ SideNavigation keepsitem-clickButton,Link,Icon,CardHeader,Tag,Avatar— all suppress the native click and fire a semanticCustomEvent("click")covering mouse + keyboardThe pattern: intercept the native DOM click on the child via
stopImmediatePropagation, fire aCustomEvent("click")viafireDecoratorEvent, then call the parent's handler for backward compatibility.Candidates
High impact
ListItemBase(all variants)Listitem-click_pressevent → List re-firesMenuItemMenuitem-clickitem-clickTreeItemBase/TreeItemTreeitem-clickitem-clickNotificationListItemNotificationListitem-click_press→ inner List → parentUserMenuItemUserMenuitem-clickitem-clickNote:
ListItemBaseis the foundation. Adding a semanticclickthere would cascade to MenuItem, TreeItem, NotificationListItem, and all other ListItem variants.Medium impact
TabTabContainertab-selectBreadcrumbsItemBreadcrumbsitem-clickSegmentedButtonItemSegmentedButtonselection-changeWizardTabWizardstep-changeselection-change-requestedLow impact
ColorPaletteItemColorPaletteitem-clickImplementation approach
For each candidate:
clickin the base classeventDetails(to preserve JSX type compatibility in the hierarchy)@eventStrict("click", { bubbles: true })on the concrete child classthis.addEventListener("click", ...)) — suppress viastopImmediatePropagation, firefireDecoratorEvent("click")item-click,tab-select, etc.) for backward compatibilitySuggested order
ListItemBase— highest impact, cascades to Menu, Tree, NotificationListTab— commonly requested by framework consumersBreadcrumbsItem/SegmentedButtonItem— smaller scope, straightforward