/** * Copyright Aquera Inc 2026 * * This source code is licensed under the BSD-3-Clause license found in the * LICENSE file in the root directory of this source tree. */ import { html, CSSResultArray, TemplateResult, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { styles } from './nile-context-menu-item.css'; import NileElement from '../internal/nile-element'; //Data passed to an item's `onSelect` callback. Matches the `nile-context-menu:select` event detail. export interface NileContextMenuItemSelectDetail { id: string; value: string; name: string; target: Element | null; originalEvent: Event | null; } export type NileContextMenuItemSelectHandler = ( detail: NileContextMenuItemSelectDetail ) => void; /** * Nile context-menu item. A clickable entry inside `nile-context-menu`. * * @tag nile-context-menu-item * * @slot - Default slot for the visible label. * @slot icon - Optional leading icon (e.g. a ``). */ @customElement('nile-context-menu-item') export class NileContextMenuItem extends NileElement { public static get styles(): CSSResultArray { return [styles]; } @property({ attribute: true, type: String, reflect: true }) value = ''; @property({ attribute: true, type: Boolean, reflect: true }) disabled = false; @property({ attribute: true, type: Boolean, reflect: true }) open = false; public onSelect?: NileContextMenuItemSelectHandler; @state() private _hasSubmenu = false; @state() private _hasIcon = false; @state() private _submenuExpanded = false; public setSubmenuExpanded(expanded: boolean): void { this._submenuExpanded = expanded; } public override focus(options?: FocusOptions): void { const inner = this.shadowRoot?.querySelector('.item') as HTMLElement | null; inner?.focus(options); } public get hasSubmenu(): boolean { return this._hasSubmenu; } private _onSlotChange = (e: Event): void => { const slot = e.target as HTMLSlotElement; const nodes = slot.assignedElements({ flatten: true }); this._hasSubmenu = nodes.some( n => n.tagName.toLowerCase() === 'nile-context-submenu' ); }; private _onIconSlotChange = (e: Event): void => { const slot = e.target as HTMLSlotElement; this._hasIcon = slot.assignedNodes({ flatten: true }).some( n => n.nodeType === Node.ELEMENT_NODE || (n.textContent ?? '').trim() !== '' ); }; public render(): TemplateResult { return html` `; } } export default NileContextMenuItem; declare global { interface HTMLElementTagNameMap { 'nile-context-menu-item': NileContextMenuItem; } }