Skip to content

Commit a99e0b9

Browse files
feat(menu-button): new web-component for parity (#19156)
* feat(menu-button): new web-component for parity * fix(floating-controller): flip * fix(story): space * fix(mdx): update * fix(menu-button): cleanup * fix(menu-button): update docs * Apply suggestions from code review Co-authored-by: kennylam <[email protected]> * Update packages/web-components/src/components/menu-button/menu-button.mdx Co-authored-by: kennylam <[email protected]> * chore(format): menu-button * fix(styles): menu-button * fix(danger): add action and divider --------- Co-authored-by: kennylam <[email protected]>
1 parent 6794203 commit a99e0b9

File tree

15 files changed

+681
-47
lines changed

15 files changed

+681
-47
lines changed

packages/web-components/src/components/button/button.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,12 @@ class CDSButton extends HostListenerMixin(FocusMixin(LitElement)) {
221221
@property({ reflect: true })
222222
size = 'lg';
223223

224+
/**
225+
* Specify the tabIndex of the button.
226+
*/
227+
@property({ type: Number, attribute: 'tab-index', reflect: true })
228+
tabIndex = 0;
229+
224230
/**
225231
* The link target, if this button is rendered as `<a>`.
226232
*/
@@ -272,6 +278,7 @@ class CDSButton extends HostListenerMixin(FocusMixin(LitElement)) {
272278
ping,
273279
rel,
274280
size,
281+
tabIndex,
275282
target,
276283
tooltipAlignment,
277284
tooltipPosition,
@@ -329,6 +336,7 @@ class CDSButton extends HostListenerMixin(FocusMixin(LitElement)) {
329336
rel="${ifDefined(rel)}"
330337
target="${ifDefined(target)}"
331338
type="${ifDefined(type)}"
339+
tabindex="${tabIndex}"
332340
aria-describedby="badge-indicator">
333341
<slot @slotchange="${handleSlotChange}"></slot>
334342
<slot name="icon" @slotchange="${handleSlotChange}"></slot>
@@ -364,6 +372,7 @@ class CDSButton extends HostListenerMixin(FocusMixin(LitElement)) {
364372
class="${classes}"
365373
?autofocus="${autofocus}"
366374
?disabled="${disabled}"
375+
tabindex="${tabIndex}"
367376
type="${ifDefined(type)}"
368377
aria-label="${ifDefined(tooltipText)}"
369378
aria-describedby="badge-indicator">
@@ -388,6 +397,7 @@ class CDSButton extends HostListenerMixin(FocusMixin(LitElement)) {
388397
class="${classes}"
389398
?autofocus="${autofocus}"
390399
?disabled="${disabled}"
400+
tabindex="${tabIndex}"
391401
type="${ifDefined(type)}"
392402
aria-describedby="badge-indicator">
393403
${isDanger
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Copyright IBM Corp. 2025, 2025
3+
*
4+
* This source code is licensed under the Apache-2.0 license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
/**
9+
* Menu button size.
10+
*/
11+
export enum MENU_BUTTON_SIZE {
12+
/**
13+
* Small size.
14+
*/
15+
SMALL = 'sm',
16+
17+
/**
18+
* Medium size.
19+
*/
20+
MEDIUM = 'md',
21+
22+
/**
23+
* Large size.
24+
*/
25+
LARGE = 'lg',
26+
}
27+
/**
28+
* menu button kind
29+
*/
30+
export enum MENU_BUTTON_KIND {
31+
/**
32+
* primary kind
33+
*/
34+
PRIMARY = 'primary',
35+
/**
36+
* tertiary kind
37+
*/
38+
TERTIARY = 'tertiary',
39+
/**
40+
* ghost kind
41+
*/
42+
GHOST = 'ghost',
43+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
## Live demo
2+
3+
<StorybookDemo
4+
tall
5+
url="https://www.ibm.com/standards/carbon/carbon-web-components"
6+
variants={[
7+
{
8+
label: 'Default',
9+
variant: 'components-menu-button--default',
10+
},
11+
]}
12+
/>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* Copyright IBM Corp. 2025, 2025
3+
*
4+
* This source code is licensed under the Apache-2.0 license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import './menu-button';
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { ArgTypes, Canvas, Markdown, Meta } from '@storybook/blocks';
2+
import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn';
3+
import * as MenuButtonStories from './menu-button.stories';
4+
5+
<Meta of={MenuButtonStories} />
6+
7+
# MenuButton
8+
9+
[Source code](https://github.com/carbon-design-system/carbon/tree/main/packages/web-components/src/components/menu-button)
10+
&nbsp;|&nbsp;
11+
12+
## Table of Contents
13+
14+
- [Overview](#overview)
15+
- [With Danger](#with-danger)
16+
- [With Dividers](#with-dividers)
17+
- [With icons](#with-icons)
18+
- [Menu Alignment](#menu-alignment)
19+
- [Experimental Auto Align](#experimental-auto-align)
20+
- [Component API](#component-api)
21+
- [CDN](#cdn)
22+
- [Feedback](#feedback)
23+
24+
## Overview
25+
26+
A `cds-menu-button` can be used to group a set of actions that are related. These
27+
actions must be `cds-menu-item` passed as child elements. The trigger buttons's label is
28+
passed as `label`.
29+
30+
<Canvas of={MenuButtonStories.Default} />
31+
32+
#### With Danger
33+
34+
<Canvas of={MenuButtonStories.withDanger} />
35+
36+
#### With Dividers
37+
38+
<Canvas of={MenuButtonStories.withDividers} />
39+
40+
#### With Icons
41+
42+
<Canvas of={MenuButtonStories.withIcons} />
43+
44+
## Menu Alignment
45+
46+
The `menu-alignment` attribute enables you to define the placement of the menu in
47+
relation to the menu button. For instance, setting `menu-alignment="top"` on the
48+
menu button will render the menu above the button.
49+
50+
If it seems your specified `menu-alignment` isn't working, it's because we
51+
prioritize ensuring the menu remains visible. We calculate the optimal position
52+
to display the menu in case the provided `menu-alignment` obscures it.
53+
54+
We encourage you to play around in the Storybook Default stories to better
55+
understand the `menu-alignment` attribute.
56+
57+
<Canvas of={MenuButtonStories.withMenuAlignment} />
58+
59+
## Experimental Auto Align
60+
61+
<Canvas of={MenuButtonStories.ExperimentalAutoAlign} />
62+
63+
## Component API
64+
65+
<ArgTypes of="cds-menu-button" />
66+
<Markdown>{`${cdnJs({ components: ['menu-button'] })}`}</Markdown>
67+
68+
## Feedback
69+
70+
Help us improve this component by providing feedback, asking questions on Slack,
71+
or updating this file on
72+
[GitHub](https://github.com/carbon-design-system/carbon/edit/main/packages/web-components/src/components/menu-button/menu-button.mdx).
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//
2+
// Copyright IBM Corp. 2025, 2025
3+
//
4+
// This source code is licensed under the Apache-2.0 license found in the
5+
// LICENSE file in the root directory of this source tree.
6+
//
7+
$css--plex: true !default;
8+
@use '@carbon/styles/scss/config' as *;
9+
@use '@carbon/styles/scss/motion' as *;
10+
@use '@carbon/styles/scss/components/menu-button/index' as *;
11+
12+
:host(#{$prefix}-menu-button) {
13+
@extend .#{$prefix}--menu-button__container;
14+
}
15+
16+
:host(#{$prefix}-menu-button) #{$prefix}-button:not([kind='ghost']) {
17+
min-inline-size: 12rem;
18+
}
19+
20+
:host(#{$prefix}-menu-button) #{$prefix}-button svg {
21+
transition: transform $duration-fast-02 motion(standard, productive);
22+
}
23+
24+
:host(#{$prefix}-menu-button[_open]) #{$prefix}-button svg {
25+
transform: rotate(180deg);
26+
}

0 commit comments

Comments
 (0)