context-menupackage.src.vaadin-context-menu.d.ts Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vaadin-webcomponents Show documentation
Show all versions of vaadin-webcomponents Show documentation
Mvnpm composite: Vaadin webcomponents
The newest version!
/**
* @license
* Copyright (c) 2016 - 2024 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
import { ContextMenuMixin } from './vaadin-context-menu-mixin.js';
import { ContextMenuItem } from './vaadin-contextmenu-items-mixin.js';
export { ContextMenuItem };
export interface ContextMenuRendererContext {
target: HTMLElement;
detail?: { sourceEvent: Event };
}
export type ContextMenuRenderer = (
root: HTMLElement,
contextMenu: ContextMenu,
context: ContextMenuRendererContext,
) => void;
/**
* Fired when the `opened` property changes.
*/
export type ContextMenuOpenedChangedEvent = CustomEvent<{ value: boolean }>;
/**
* Fired when an item is selected when the context menu is populated using the `items` API.
*/
export type ContextMenuItemSelectedEvent = CustomEvent<{ value: ContextMenuItem }>;
export interface ContextMenuCustomEventMap {
'opened-changed': ContextMenuOpenedChangedEvent;
'item-selected': ContextMenuItemSelectedEvent;
'close-all-menus': Event;
'items-outside-click': Event;
}
export interface ContextMenuEventMap extends HTMLElementEventMap, ContextMenuCustomEventMap {}
/**
* `` is a Web Component for creating context menus.
*
* ### Items
*
* Items is a higher level convenience API for defining a (hierarchical) menu structure for the component.
* If a menu item has a non-empty `children` set, a sub-menu with the child items is opened
* next to the parent menu on mouseover, tap or a right arrow keypress.
*
* When an item is selected, `` dispatches an "item-selected" event
* with the selected item as `event.detail.value` property.
* If item does not have `keepOpen` property the menu will be closed.
*
* ```javascript
* contextMenu.items = [
* { text: 'Menu Item 1', theme: 'primary', className: 'first', children:
* [
* { text: 'Menu Item 1-1', checked: true, keepOpen: true },
* { text: 'Menu Item 1-2' }
* ]
* },
* { component: 'hr' },
* { text: 'Menu Item 2', children:
* [
* { text: 'Menu Item 2-1' },
* { text: 'Menu Item 2-2', disabled: true }
* ]
* },
* { text: 'Menu Item 3', disabled: true, className: 'last' }
* ];
*
* contextMenu.addEventListener('item-selected', e => {
* const item = e.detail.value;
* console.log(`${item.text} selected`);
* });
* ```
*
* **NOTE:** when the `items` array is defined, the renderer cannot be used.
*
* ### Rendering
*
* The content of the menu can be populated by using the renderer callback function.
*
* The renderer function provides `root`, `contextMenu`, `model` arguments when applicable.
* Generate DOM content by using `model` object properties if needed, append it to the `root`
* element and control the state of the host element by accessing `contextMenu`. Before generating
* new content, the renderer function should check if there is already content in `root` for reusing it.
*
* ```html
*
* This paragraph has a context menu.
*
* ```
* ```js
* const contextMenu = document.querySelector('#contextMenu');
* contextMenu.renderer = (root, contextMenu, context) => {
* let listBox = root.firstElementChild;
* if (!listBox) {
* listBox = document.createElement('vaadin-list-box');
* root.appendChild(listBox);
* }
*
* let item = listBox.querySelector('vaadin-item');
* if (!item) {
* item = document.createElement('vaadin-item');
* listBox.appendChild(item);
* }
* item.textContent = 'Content of the selector: ' + context.target.textContent;
* };
* ```
*
* You can access the menu context inside the renderer using
* `context.target` and `context.detail`.
*
* Renderer is called on the opening of the context-menu and each time the related context is updated.
* DOM generated during the renderer call can be reused
* in the next renderer call and will be provided with the `root` argument.
* On first call it will be empty.
*
* ### `vaadin-contextmenu` Gesture Event
*
* `vaadin-contextmenu` is a gesture event (a custom event),
* which is dispatched after either `contextmenu` or long touch events.
* This enables support for both mouse and touch environments in a uniform way.
*
* `` opens the menu overlay on the `vaadin-contextmenu`
* event by default.
*
* ### Menu Listener
*
* By default, the `` element listens for the menu opening
* event on itself. In case if you do not want to wrap the target, you can listen for
* events on an element outside the `` by setting the
* `listenOn` property:
*
* ```html
*
*
*
* ```
* ```javascript
* const contextMenu = document.querySelector('#contextMenu');
* contextMenu.listenOn = document.querySelector('#menuListener');
* ```
*
* ### Filtering Menu Targets
*
* By default, the listener element and all its descendants open the context
* menu. You can filter the menu targets to a smaller set of elements inside
* the listener element by setting the `selector` property.
*
* In the following example, only the elements matching `.has-menu` will open the context menu:
*
* ```html
*
* This paragraph does not open the context menu
*
* ```
*
* ### Menu Context
*
* You can use the following properties in the renderer function:
*
* - `target` is the menu opening event target, which is the element that
* the user has called the context menu for
* - `detail` is the menu opening event detail
*
* In the following example, the menu item text is composed with the contents
* of the element that opened the menu:
*
* ```html
*
*
*
* - Foo
* - Bar
* - Baz
*
*
* ```
* ```js
* const contextMenu = document.querySelector('#contextMenu');
* contextMenu.renderer = (root, contextMenu, context) => {
* let listBox = root.firstElementChild;
* if (!listBox) {
* listBox = document.createElement('vaadin-list-box');
* root.appendChild(listBox);
* }
*
* let item = listBox.querySelector('vaadin-item');
* if (!item) {
* item = document.createElement('vaadin-item');
* listBox.appendChild(item);
* }
* item.textContent = 'The menu target: ' + context.target.textContent;
* };
* ```
*
* ### Styling
*
* `` uses `` internal
* themable component as the actual visible context menu overlay.
*
* See [``](#/elements/vaadin-overlay)
* documentation for `` stylable parts.
*
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
*
* ### Internal components
*
* When using `items` API, in addition ``, the following
* internal components are themable:
*
* - `` - has the same API as [``](#/elements/vaadin-item).
* - `` - has the same API as [``](#/elements/vaadin-list-box).
*
* The `` sub-menu elements have the following additional state attributes
* on top of the built-in `` state attributes:
*
* Attribute | Description
* ---------- |-------------
* `expanded` | Expanded parent item.
*
* Note: the `theme` attribute value set on `` is
* propagated to the internal components listed above.
*
* @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
* @fires {CustomEvent} item-selected - Fired when an item is selected when the context menu is populated using the `items` API.
*/
declare class ContextMenu extends ContextMenuMixin(OverlayClassMixin(ElementMixin(ThemePropertyMixin(HTMLElement)))) {
addEventListener(
type: K,
listener: (this: ContextMenu, ev: ContextMenuEventMap[K]) => void,
options?: AddEventListenerOptions | boolean,
): void;
removeEventListener(
type: K,
listener: (this: ContextMenu, ev: ContextMenuEventMap[K]) => void,
options?: EventListenerOptions | boolean,
): void;
}
declare global {
interface HTMLElementTagNameMap {
'vaadin-context-menu': ContextMenu;
}
}
export { ContextMenu };