feat(action): add buttonType and menu properties to support menu patterns (WIP)#14237
Draft
feat(action): add buttonType and menu properties to support menu patterns (WIP)#14237
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds initial support for menu-enabled calcite-action variants to prototype overflow/menu/split-button patterns that will later integrate with calcite-action-group overflow behavior (Issue #11126).
Changes:
- Introduces
button-typeandopenstate tocalcite-action, plus a newmenuslot rendered via an internalcalcite-popover. - Adds split/overflow/menu-specific rendering and styling (secondary split trigger, chevron, open/active visuals).
- Updates Storybook stories and adds E2E coverage for the new variants and styling states.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/components/src/components/action/resources.ts | Adds CSS class keys, menu slot constant, menu IDs, and icon constants used by new variants. |
| packages/components/src/components/action/action.tsx | Implements buttonType, open, menu slot handling, split rendering, and popover-backed menu behavior. |
| packages/components/src/components/action/action.stories.ts | Adds stories/examples for overflow/split/menu variants and open-state matrices. |
| packages/components/src/components/action/action.scss | Adds styling for split button layout and menu/overflow open states and menu container styles. |
| packages/components/src/components/action/action.e2e.ts | Adds E2E assertions for overflow text visibility, split hit targets, and open-state styling behavior. |
| packages/components/src/components/action/action.browser.e2e.tsx | Extends default/reflect tests for the new buttonType and open props. |
Comments suppressed due to low confidence (2)
packages/components/src/components/action/action.tsx:510
- A
menuIdis generated and applied to the menu container, but neither the primary trigger nor the split secondary trigger associates itself to that menu viaaria-controls/ariaControlsElements. For accessibility parity withcalcite-action-menu(which setsaria-controlson its trigger), include the menu element in the trigger’sariaControlsElements(whensupportsMenu && hasSlottedMenu) and setaria-controlson the split secondary button as well.
const internalControlsElements = indicator && indicatorRef.value ? [indicatorRef.value] : [];
const ariaControlsElements = [
...(this.aria?.controlsElements ?? []),
...internalControlsElements,
];
packages/components/src/components/action/action.tsx:533
- When
dragHandleis true, the component renders a<span role="button">but does not wireonClick(or key handlers) tohandleClick()/toggleOpen(). This meansbuttonType="menu"|"overflow"triggers won’t open andtype="submit"|"reset"behavior won’t run in the drag-handle rendering path. If drag handles should still be operable as actions, add the same click/keyboard handling used by the<button>path; otherwise consider guarding against menu/button types whendragHandleis enabled.
if (this.dragHandle) {
return (
// Needs to be a span because of https://github.com/SortableJS/Sortable/issues/1486 & https://bugzilla.mozilla.org/show_bug.cgi?id=568313
<span
ariaBusy={loading}
ariaControlsElements={ariaControlsElements}
ariaDescribedByElements={this.aria?.describedByElements}
ariaExpanded={this.getMenuTriggerAriaExpanded()}
ariaHasPopup={this.getMenuTriggerAriaHasPopup()}
ariaLabel={ariaLabel}
ariaLabelledByElements={this.aria?.labelledByElements}
ariaOwnsElements={this.aria?.ownsElements}
ariaPressed={this.aria?.pressed}
class={buttonClasses}
id={buttonId}
ref={ref}
role="button"
tabIndex={this.disabled ? undefined : 0}
>
{buttonContent}
</span>
);
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…//github.com/Esri/calcite-design-system into ashetland/11126-action-components-prototypes
… improve keyboard/focus handling
Comment on lines
+128
to
+163
| private toggleOpen = (value = !this.menuOpen): void => { | ||
| if (!this.supportsMenu || !this.hasSlottedMenu) { | ||
| return; | ||
| } | ||
|
|
||
| this.menuOpen = value; | ||
|
|
||
| // Emit event to close other action menus when opening | ||
| if (value) { | ||
| document.dispatchEvent( | ||
| new CustomEvent<{ menuElement: HTMLElement }>(ACTION_MENU_OPEN_EVENT, { | ||
| detail: { menuElement: this.el }, | ||
| }), | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
| private setPopoverEl = (el: Popover["el"]): void => { | ||
| if (!el) { | ||
| return; | ||
| } | ||
|
|
||
| el.open = this.menuOpen; | ||
| }; | ||
|
|
||
| private handlePopoverOpen = (event: CustomEvent<void>): void => { | ||
| event.stopPropagation(); | ||
| this.menuOpen = true; | ||
| this.menuButtonEl?.focus(); | ||
| // Emit event to close other action menus when opening | ||
| document.dispatchEvent( | ||
| new CustomEvent<{ menuElement: HTMLElement }>(ACTION_MENU_OPEN_EVENT, { | ||
| detail: { menuElement: this.el }, | ||
| }), | ||
| ); | ||
| }; |
Contributor
Author
There was a problem hiding this comment.
Follow up on this after concept is proven. There could be a cleaner way to do this.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related Issue: #11126
Summary
WIP prototyping of the following:
All final naming of props and slots TBD.
Action:
button-type="menu" | "overflow" | "split" | "undefined" (default)prop toactionto support these patternsmenu-actionsslot for these buttonTypes for configuration of menu button patternsmenu-flip-placements,menu-open, andmenu-placementprops matchingaction-menutooltipslot matchingaction-menu