diff --git a/packages/menu-bar/src/vaadin-menu-bar-mixin.d.ts b/packages/menu-bar/src/vaadin-menu-bar-mixin.d.ts index a870609c436..65ad1dfc318 100644 --- a/packages/menu-bar/src/vaadin-menu-bar-mixin.d.ts +++ b/packages/menu-bar/src/vaadin-menu-bar-mixin.d.ts @@ -11,7 +11,7 @@ import type { KeyboardMixinClass } from '@vaadin/a11y-base/src/keyboard-mixin.js import type { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js'; import type { ResizeMixinClass } from '@vaadin/component-base/src/resize-mixin.js'; -export interface MenuBarItem { +export type MenuBarItem = { /** * Text to be set as the menu button component's textContent. */ @@ -37,40 +37,40 @@ export interface MenuBarItem { /** * Array of submenu items. */ - children?: SubMenuItem[]; + children?: Array>; /** * Class/classes to be set to the class attribute of the button. */ className?: string; -} +} & TItemData; -export interface SubMenuItem { +export type SubMenuItem = { text?: string; component?: HTMLElement | string; disabled?: boolean; theme?: string[] | string; checked?: boolean; className?: string; - children?: SubMenuItem[]; -} + children?: Array>; +} & TItemData; export interface MenuBarI18n { moreOptions: string; } -export declare function MenuBarMixin>( +export declare function MenuBarMixin, TItem extends MenuBarItem = MenuBarItem>( base: T, ): Constructor & Constructor & Constructor & Constructor & Constructor & - Constructor & + Constructor> & Constructor & T; -export declare class MenuBarMixinClass { +export declare class MenuBarMixinClass { /** * Defines a hierarchical structure, where root level items represent menu bar buttons, * and `children` property configures a submenu with items to be opened below @@ -118,7 +118,7 @@ export declare class MenuBarMixinClass { * window.Vaadin.featureFlags.accessibleDisabledButtons = true; * ``` */ - items: MenuBarItem[]; + items: TItem[]; /** * The object used to localize this component. @@ -183,3 +183,11 @@ export declare class MenuBarMixinClass { protected _hasOverflow: boolean; } + +export declare interface MenuBarMixinClass + extends ControllerMixinClass, + DisabledMixinClass, + FocusMixinClass, + KeyboardDirectionMixinClass, + KeyboardMixinClass, + ResizeMixinClass {} diff --git a/packages/menu-bar/src/vaadin-menu-bar.d.ts b/packages/menu-bar/src/vaadin-menu-bar.d.ts index fad4cfd6b94..7137aa1a38e 100644 --- a/packages/menu-bar/src/vaadin-menu-bar.d.ts +++ b/packages/menu-bar/src/vaadin-menu-bar.d.ts @@ -3,23 +3,25 @@ * Copyright (c) 2019 - 2025 Vaadin Ltd. * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ */ -import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js'; -import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js'; -import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; -import { type MenuBarItem, MenuBarMixin } from './vaadin-menu-bar-mixin.js'; +import type { DisabledMixinClass } from '@vaadin/a11y-base/src/disabled-mixin.js'; +import type { ElementMixinClass } from '@vaadin/component-base/src/element-mixin.js'; +import type { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; +import type { MenuBarItem, MenuBarMixinClass } from './vaadin-menu-bar-mixin.js'; export { MenuBarItem, MenuBarI18n, SubMenuItem } from './vaadin-menu-bar-mixin.js'; /** * Fired when a submenu item or menu bar button without children is clicked. */ -export type MenuBarItemSelectedEvent = CustomEvent<{ value: MenuBarItem }>; +export type MenuBarItemSelectedEvent = CustomEvent<{ value: TItem }>; -export interface MenuBarCustomEventMap { - 'item-selected': MenuBarItemSelectedEvent; +export interface MenuBarCustomEventMap { + 'item-selected': MenuBarItemSelectedEvent; } -export interface MenuBarEventMap extends HTMLElementEventMap, MenuBarCustomEventMap {} +export interface MenuBarEventMap + extends HTMLElementEventMap, + MenuBarCustomEventMap {} /** * `` is a Web Component providing a set of horizontally stacked buttons offering @@ -77,20 +79,26 @@ export interface MenuBarEventMap extends HTMLElementEventMap, MenuBarCustomEvent * * @fires {CustomEvent} item-selected - Fired when a submenu item or menu bar button without children is clicked. */ -declare class MenuBar extends MenuBarMixin(DisabledMixin(ElementMixin(ThemableMixin(HTMLElement)))) { - addEventListener( +declare class MenuBar extends HTMLElement { + addEventListener>( type: K, - listener: (this: MenuBar, ev: MenuBarEventMap[K]) => void, + listener: (this: MenuBar, ev: MenuBarEventMap[K]) => void, options?: AddEventListenerOptions | boolean, ): void; - removeEventListener( + removeEventListener>( type: K, - listener: (this: MenuBar, ev: MenuBarEventMap[K]) => void, + listener: (this: MenuBar, ev: MenuBarEventMap[K]) => void, options?: EventListenerOptions | boolean, ): void; } +interface MenuBar + extends MenuBarMixinClass, + DisabledMixinClass, + ElementMixinClass, + ThemableMixinClass {} + declare global { interface HTMLElementTagNameMap { 'vaadin-menu-bar': MenuBar; diff --git a/packages/menu-bar/test/typings/menu-bar.types.ts b/packages/menu-bar/test/typings/menu-bar.types.ts index 07e8f4aca73..d4969966988 100644 --- a/packages/menu-bar/test/typings/menu-bar.types.ts +++ b/packages/menu-bar/test/typings/menu-bar.types.ts @@ -9,7 +9,7 @@ import type { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-th import type { MenuBarItem } from '../../src/vaadin-menu-bar-item.js'; import type { MenuBarListBox } from '../../src/vaadin-menu-bar-list-box.js'; import type { MenuBarMixinClass } from '../../src/vaadin-menu-bar-mixin.js'; -import type { MenuBarItem as MenuItem, MenuBarItemSelectedEvent } from '../../vaadin-menu-bar.js'; +import type { MenuBar, MenuBarItem as MenuItem, MenuBarItemSelectedEvent } from '../../vaadin-menu-bar.js'; const menu = document.createElement('vaadin-menu-bar'); @@ -39,6 +39,22 @@ assertType(menuItem.theme); assertType(menuItem.children); assertType(menuItem.component); +// Custom item data +interface ItemData { + type: 'copy' | 'cut' | 'paste'; + value: string; +} + +const narrowedMenu = menu as MenuBar>; + +assertType(narrowedMenu.items[0]); +assertType(narrowedMenu.items[0].children![0]); +assertType(narrowedMenu.items[0].children![0].children![0]); + +narrowedMenu.addEventListener('item-selected', (event) => { + assertType(event.detail.value); +}); + // Item const item = document.createElement('vaadin-menu-bar-item');