shoelace/src/components/menu-item/menu-item.ts

110 wiersze
2.9 KiB
TypeScript
Czysty Zwykły widok Historia

import { LitElement, html, unsafeCSS } from 'lit';
2021-05-27 21:00:43 +00:00
import { customElement, property, query, state } from 'lit/decorators.js';
2021-03-06 17:01:39 +00:00
import { classMap } from 'lit-html/directives/class-map';
2021-03-15 11:56:15 +00:00
import { ifDefined } from 'lit-html/directives/if-defined';
import styles from 'sass:./menu-item.scss';
2020-07-15 21:30:37 +00:00
/**
2020-07-17 10:09:10 +00:00
* @since 2.0
2020-07-15 21:30:37 +00:00
* @status stable
*
2021-02-26 14:09:13 +00:00
* @dependency sl-icon
*
* @slot default The menu item's label.
* @slot prefix Used to prepend an icon or similar element to the menu item.
* @slot suffix Used to append an icon or similar element to the menu item.
2020-07-15 21:30:37 +00:00
*
* @csspart base The component's base wrapper.
* @csspart checked-icon The container that wraps the checked icon.
* @csspart prefix The prefix container.
* @csspart label The menu item label.
* @csspart suffix The suffix container.
2020-07-15 21:30:37 +00:00
*/
2021-03-18 13:04:23 +00:00
@customElement('sl-menu-item')
2021-03-09 00:14:32 +00:00
export default class SlMenuItem extends LitElement {
2021-03-06 17:01:39 +00:00
static styles = unsafeCSS(styles);
2020-07-15 21:30:37 +00:00
2021-03-06 17:01:39 +00:00
@query('.menu-item') menuItem: HTMLElement;
@state() private hasFocus = false;
2020-10-22 17:41:09 +00:00
2021-02-26 14:09:13 +00:00
/** Draws the item in a checked state. */
2021-03-06 17:01:39 +00:00
@property({ type: Boolean, reflect: true }) checked = false;
2020-07-15 21:30:37 +00:00
2020-12-30 18:32:42 +00:00
/** A unique value to store in the menu item. This can be used as a way to identify menu items when selected. */
2021-03-06 17:01:39 +00:00
@property() value = '';
2020-07-15 21:30:37 +00:00
2021-02-26 14:09:13 +00:00
/** Draws the menu item in a disabled state. */
2021-03-06 17:01:39 +00:00
@property({ type: Boolean, reflect: true }) disabled = false;
2020-10-22 17:41:09 +00:00
/** Sets focus on the button. */
focus(options?: FocusOptions) {
2021-01-07 15:13:08 +00:00
this.menuItem.focus(options);
2020-10-22 17:41:09 +00:00
}
2020-10-22 17:41:09 +00:00
/** Removes focus from the button. */
blur() {
2020-10-22 17:41:09 +00:00
this.menuItem.blur();
}
handleBlur() {
this.hasFocus = false;
}
handleFocus() {
this.hasFocus = true;
}
2020-12-11 22:09:28 +00:00
handleMouseEnter() {
this.focus();
2020-10-22 17:41:09 +00:00
}
2020-12-11 22:09:28 +00:00
handleMouseLeave() {
this.blur();
2020-10-22 17:41:09 +00:00
}
2020-07-15 21:30:37 +00:00
render() {
2021-02-26 14:09:13 +00:00
return html`
2020-07-15 21:30:37 +00:00
<div
part="base"
2021-02-26 14:09:13 +00:00
class=${classMap({
2020-07-15 21:30:37 +00:00
'menu-item': true,
'menu-item--checked': this.checked,
2020-10-22 17:41:09 +00:00
'menu-item--disabled': this.disabled,
'menu-item--focused': this.hasFocus
2021-02-26 14:09:13 +00:00
})}
2020-07-15 21:30:37 +00:00
role="menuitem"
2021-02-26 14:09:13 +00:00
aria-disabled=${this.disabled ? 'true' : 'false'}
aria-checked=${this.checked ? 'true' : 'false'}
2021-03-15 11:56:15 +00:00
tabindex=${ifDefined(!this.disabled ? '0' : undefined)}
2021-03-06 17:01:39 +00:00
@focus=${this.handleFocus}
@blur=${this.handleBlur}
@mouseenter=${this.handleMouseEnter}
@mouseleave=${this.handleMouseLeave}
2020-07-15 21:30:37 +00:00
>
<span part="checked-icon" class="menu-item__check">
<sl-icon name="check" library="system" aria-hidden="true"></sl-icon>
2020-07-15 21:30:37 +00:00
</span>
<span part="prefix" class="menu-item__prefix">
2021-03-06 17:01:39 +00:00
<slot name="prefix"></slot>
2020-07-15 21:30:37 +00:00
</span>
<span part="label" class="menu-item__label">
2021-03-06 17:01:39 +00:00
<slot></slot>
2020-07-15 21:30:37 +00:00
</span>
<span part="suffix" class="menu-item__suffix">
2021-03-06 17:01:39 +00:00
<slot name="suffix"></slot>
2020-07-15 21:30:37 +00:00
</span>
</div>
2021-02-26 14:09:13 +00:00
`;
2020-07-15 21:30:37 +00:00
}
}
2021-03-12 14:09:08 +00:00
declare global {
interface HTMLElementTagNameMap {
'sl-menu-item': SlMenuItem;
}
}