Skip to content

Commit

Permalink
feat(menu): menu component in carbon web components
Browse files Browse the repository at this point in the history
  • Loading branch information
sangeethababu9223 committed Mar 19, 2024
1 parent e770dd5 commit 1b74b89
Show file tree
Hide file tree
Showing 14 changed files with 707 additions and 2 deletions.
Binary file not shown.
Binary file not shown.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@
"through2": "^3.0.0"
},
"dependencies": {
"@babel/runtime": "^7.16.3"
"@babel/runtime": "^7.16.3",
"@lit/context": "^1.1.0"
},
"resolutions": {
"kind-of": ">=6.0.3",
Expand Down
15 changes: 15 additions & 0 deletions packages/carbon-web-components/src/components/menu/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @license
*
* Copyright IBM Corp. 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import './menu';
import './menu-item';
import './menu-item-divider';
import './menu-item-group';
import './menu-item-radio-group';
import './menu-item-selectable';
25 changes: 25 additions & 0 deletions packages/carbon-web-components/src/components/menu/menu-context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* @license
*
* Copyright IBM Corp. 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
import { createContext } from '@lit/context';

type StateType = {
isRoot: boolean;
mode: 'full' | 'basic';
hasIcons: boolean;
size: 'xs' | 'sm' | 'md' | 'lg' | null;
items: any[];
requestCloseRoot: (e: Pick<KeyboardEvent, 'type'>) => void;
};

type MenuContextProps = {
state: StateType;
};
const menuContext = createContext<MenuContextProps>('menucontext');

export { menuContext, MenuContextProps };
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @license
*
* Copyright IBM Corp. 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import { LitElement, html } from 'lit';
import { prefix } from '../../globals/settings';
import HostListenerMixin from '../../globals/mixins/host-listener';
import { carbonElement as customElement } from '../../globals/decorators/carbon-element';

@customElement(`${prefix}-menu-item`)
class CDMenuItemDivider extends HostListenerMixin(LitElement) {
render() {
return html`
<li class="${prefix}--menu-item-divider" role="separator"></li>
`;
}
}
export default CDMenuItemDivider;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @license
*
* Copyright IBM Corp. 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import { LitElement, html } from 'lit';
import { property } from 'lit/decorators.js';
import { prefix } from '../../globals/settings';
import HostListenerMixin from '../../globals/mixins/host-listener';
import { carbonElement as customElement } from '../../globals/decorators/carbon-element';

@customElement(`${prefix}-menu-item-group`)
class CDSMenuItemGroup extends HostListenerMixin(LitElement) {
/**
* A required label titling the MenuItem. Will be rendered as its text content.
*/
@property({ type: String })
label;

render() {
const { label } = this;
return html`
<li class="${prefix}--menu-item-group" role="none">
<ul role="group" aria-label="${label}">
<slot></slot>
</ul>
</li>
`;
}
}
export default CDSMenuItemGroup;
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* @license
*
* Copyright IBM Corp. 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import { LitElement, html } from 'lit';
import { property } from 'lit/decorators.js';
import { prefix } from '../../globals/settings';
import HostListenerMixin from '../../globals/mixins/host-listener';
import { carbonElement as customElement } from '../../globals/decorators/carbon-element';
import Checkmark16 from '@carbon/icons/lib/checkmark/16';
import { ChangeEventHandler } from 'react';

const defaultItemToString = (item) => item.toString();

@customElement(`${prefix}-menu-item-radio-group`)
class CDSMenuItemRadioGroup extends HostListenerMixin(LitElement) {
/**
* A required label titling the MenuItem. Will be rendered as its text content.
*/
@property({ type: String })
label;

/**
* Provide the options for this radio group. Can be of any type, as long as you provide an appropriate props.itemToString function.
*/
items;

/**
* Provide a function to convert an item to the string that will be rendered. Defaults to item.toString().
*/
itemToString?: (item) => string;

selection;

/**
* Provide an optional function to be called when the MenuItem is clicked.
*/
onChange?: (event: ChangeEventHandler) => void;

_handleClick(item, e) {
const { onChange } = this;
this.selection = item;
if (onChange) {
onChange(e);
}
}
render() {
// if (context.state.mode === 'basic') {
// warning(
// false,
// 'MenuItemRadioGroup is not supported when the menu is in "basic" mode.'
// );
// }
const {
label,
items,
selection,
itemToString = defaultItemToString,
_handleClick: handleClick,
} = this;
return html`
<li class="${prefix}--menu-item-radio-group" role="none">
<ul role="group" aria-label="${label}">
${items.map((item, i) => {
html`
<cds-menu-item
key="${i}"
label="${itemToString(item)}"
role="menuitemradio"
aria-checked="${item === selection}"
renderIcon="${item === selection
? Checkmark16({
part: 'selected-icon',
class: `${prefix}--list-box__menu-item__selected-icon`,
})
: undefined}"
@click="${(e) => {
handleClick(item, e);
}}">
</cds-menu-item>
`;
})}
</ul>
</li>
`;
}
}
export default CDSMenuItemRadioGroup;
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* @license
*
* Copyright IBM Corp. 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import { LitElement, html } from 'lit';
import { property } from 'lit/decorators.js';
import { prefix } from '../../globals/settings';
import HostListenerMixin from '../../globals/mixins/host-listener';
import { carbonElement as customElement } from '../../globals/decorators/carbon-element';
import Checkmark16 from '@carbon/icons/lib/checkmark/16';
import { ChangeEventHandler } from 'react';

@customElement(`${prefix}-menu-item-selectable`)
class CDSMenuItemSelectable extends HostListenerMixin(LitElement) {
/**
* A required label titling the MenuItem. Will be rendered as its text content.
*/

@property({ type: String })
label;
/**
* Indicates whether th eitem is checked or not.
*/
@property({ type: Boolean })
checked;
/**
* checks whether th eitem is selected or not.
*/
@property({ type: Boolean })
selected;
/**
* Provide an optional function to be called when the MenuItem is clicked.
*/
onChange?: (event: ChangeEventHandler) => void;

_handleClick(e) {
const { onChange } = this;
this.checked = !this.checked;
if (onChange) {
onChange(e);
}
}

firstUpdated() {
this.checked = this.selected;
}

render() {
const { label, checked, _handleClick: handleClick } = this;
// if (context.state.mode === 'basic') {
// warning(
// false,
// 'MenuItemSelectable is not supported when the menu is in "basic" mode.'
// );
// }

return html`
<cds-menu-item
label="${label}"
class="${prefix}--menu-item-selectable--selected"
role="menuitemcheckbox"
aria-checked="${checked}"
renderIcon="${checked
? Checkmark16({
part: 'selected-icon',
class: `${prefix}--list-box__menu-item__selected-icon`,
})
: undefined}
"
@click="${handleClick}">
</cds-menu-item>
`;
}
}
export default CDSMenuItemSelectable;
Loading

0 comments on commit 1b74b89

Please sign in to comment.