UNPKG

17.9 kBTypeScriptView Raw
1import { CommandRegistry } from '@lumino/commands';
2import { ReadonlyJSONObject } from '@lumino/coreutils';
3import { Message } from '@lumino/messaging';
4import { ISignal } from '@lumino/signaling';
5import { ElementARIAAttrs, ElementDataset, h, VirtualElement } from '@lumino/virtualdom';
6import { Widget } from './widget';
7/**
8 * A widget which displays items as a canonical menu.
9 */
10export declare class Menu extends Widget {
11 /**
12 * Construct a new menu.
13 *
14 * @param options - The options for initializing the menu.
15 */
16 constructor(options: Menu.IOptions);
17 /**
18 * Dispose of the resources held by the menu.
19 */
20 dispose(): void;
21 /**
22 * A signal emitted just before the menu is closed.
23 *
24 * #### Notes
25 * This signal is emitted when the menu receives a `'close-request'`
26 * message, just before it removes itself from the DOM.
27 *
28 * This signal is not emitted if the menu is already detached from
29 * the DOM when it receives the `'close-request'` message.
30 */
31 get aboutToClose(): ISignal<this, void>;
32 /**
33 * A signal emitted when a new menu is requested by the user.
34 *
35 * #### Notes
36 * This signal is emitted whenever the user presses the right or left
37 * arrow keys, and a submenu cannot be opened or closed in response.
38 *
39 * This signal is useful when implementing menu bars in order to open
40 * the next or previous menu in response to a user key press.
41 *
42 * This signal is only emitted for the root menu in a hierarchy.
43 */
44 get menuRequested(): ISignal<this, 'next' | 'previous'>;
45 /**
46 * The command registry used by the menu.
47 */
48 readonly commands: CommandRegistry;
49 /**
50 * The renderer used by the menu.
51 */
52 readonly renderer: Menu.IRenderer;
53 /**
54 * The parent menu of the menu.
55 *
56 * #### Notes
57 * This is `null` unless the menu is an open submenu.
58 */
59 get parentMenu(): Menu | null;
60 /**
61 * The child menu of the menu.
62 *
63 * #### Notes
64 * This is `null` unless the menu has an open submenu.
65 */
66 get childMenu(): Menu | null;
67 /**
68 * The root menu of the menu hierarchy.
69 */
70 get rootMenu(): Menu;
71 /**
72 * The leaf menu of the menu hierarchy.
73 */
74 get leafMenu(): Menu;
75 /**
76 * The menu content node.
77 *
78 * #### Notes
79 * This is the node which holds the menu item nodes.
80 *
81 * Modifying this node directly can lead to undefined behavior.
82 */
83 get contentNode(): HTMLUListElement;
84 /**
85 * Get the currently active menu item.
86 */
87 get activeItem(): Menu.IItem | null;
88 /**
89 * Set the currently active menu item.
90 *
91 * #### Notes
92 * If the item cannot be activated, the item will be set to `null`.
93 */
94 set activeItem(value: Menu.IItem | null);
95 /**
96 * Get the index of the currently active menu item.
97 *
98 * #### Notes
99 * This will be `-1` if no menu item is active.
100 */
101 get activeIndex(): number;
102 /**
103 * Set the index of the currently active menu item.
104 *
105 * #### Notes
106 * If the item cannot be activated, the index will be set to `-1`.
107 */
108 set activeIndex(value: number);
109 /**
110 * A read-only array of the menu items in the menu.
111 */
112 get items(): ReadonlyArray<Menu.IItem>;
113 /**
114 * Activate the next selectable item in the menu.
115 *
116 * #### Notes
117 * If no item is selectable, the index will be set to `-1`.
118 */
119 activateNextItem(): void;
120 /**
121 * Activate the previous selectable item in the menu.
122 *
123 * #### Notes
124 * If no item is selectable, the index will be set to `-1`.
125 */
126 activatePreviousItem(): void;
127 /**
128 * Trigger the active menu item.
129 *
130 * #### Notes
131 * If the active item is a submenu, it will be opened and the first
132 * item will be activated.
133 *
134 * If the active item is a command, the command will be executed.
135 *
136 * If the menu is not attached, this is a no-op.
137 *
138 * If there is no active item, this is a no-op.
139 */
140 triggerActiveItem(): void;
141 /**
142 * Add a menu item to the end of the menu.
143 *
144 * @param options - The options for creating the menu item.
145 *
146 * @returns The menu item added to the menu.
147 */
148 addItem(options: Menu.IItemOptions): Menu.IItem;
149 /**
150 * Insert a menu item into the menu at the specified index.
151 *
152 * @param index - The index at which to insert the item.
153 *
154 * @param options - The options for creating the menu item.
155 *
156 * @returns The menu item added to the menu.
157 *
158 * #### Notes
159 * The index will be clamped to the bounds of the items.
160 */
161 insertItem(index: number, options: Menu.IItemOptions): Menu.IItem;
162 /**
163 * Remove an item from the menu.
164 *
165 * @param item - The item to remove from the menu.
166 *
167 * #### Notes
168 * This is a no-op if the item is not in the menu.
169 */
170 removeItem(item: Menu.IItem): void;
171 /**
172 * Remove the item at a given index from the menu.
173 *
174 * @param index - The index of the item to remove.
175 *
176 * #### Notes
177 * This is a no-op if the index is out of range.
178 */
179 removeItemAt(index: number): void;
180 /**
181 * Remove all menu items from the menu.
182 */
183 clearItems(): void;
184 /**
185 * Open the menu at the specified location.
186 *
187 * @param x - The client X coordinate of the menu location.
188 *
189 * @param y - The client Y coordinate of the menu location.
190 *
191 * @param options - The additional options for opening the menu.
192 *
193 * #### Notes
194 * The menu will be opened at the given location unless it will not
195 * fully fit on the screen. If it will not fit, it will be adjusted
196 * to fit naturally on the screen.
197 *
198 * This is a no-op if the menu is already attached to the DOM.
199 */
200 open(x: number, y: number, options?: Menu.IOpenOptions): void;
201 /**
202 * Handle the DOM events for the menu.
203 *
204 * @param event - The DOM event sent to the menu.
205 *
206 * #### Notes
207 * This method implements the DOM `EventListener` interface and is
208 * called in response to events on the menu's DOM nodes. It should
209 * not be called directly by user code.
210 */
211 handleEvent(event: Event): void;
212 /**
213 * A message handler invoked on a `'before-attach'` message.
214 */
215 protected onBeforeAttach(msg: Message): void;
216 /**
217 * A message handler invoked on an `'after-detach'` message.
218 */
219 protected onAfterDetach(msg: Message): void;
220 /**
221 * A message handler invoked on an `'activate-request'` message.
222 */
223 protected onActivateRequest(msg: Message): void;
224 /**
225 * A message handler invoked on an `'update-request'` message.
226 */
227 protected onUpdateRequest(msg: Message): void;
228 /**
229 * A message handler invoked on a `'close-request'` message.
230 */
231 protected onCloseRequest(msg: Message): void;
232 /**
233 * Handle the `'keydown'` event for the menu.
234 *
235 * #### Notes
236 * This listener is attached to the menu node.
237 */
238 private _evtKeyDown;
239 /**
240 * Handle the `'mouseup'` event for the menu.
241 *
242 * #### Notes
243 * This listener is attached to the menu node.
244 */
245 private _evtMouseUp;
246 /**
247 * Handle the `'mousemove'` event for the menu.
248 *
249 * #### Notes
250 * This listener is attached to the menu node.
251 */
252 private _evtMouseMove;
253 /**
254 * Handle the `'mouseenter'` event for the menu.
255 *
256 * #### Notes
257 * This listener is attached to the menu node.
258 */
259 private _evtMouseEnter;
260 /**
261 * Handle the `'mouseleave'` event for the menu.
262 *
263 * #### Notes
264 * This listener is attached to the menu node.
265 */
266 private _evtMouseLeave;
267 /**
268 * Handle the `'mousedown'` event for the menu.
269 *
270 * #### Notes
271 * This listener is attached to the document node.
272 */
273 private _evtMouseDown;
274 /**
275 * Open the child menu at the active index immediately.
276 *
277 * If a different child menu is already open, it will be closed,
278 * even if the active item is not a valid submenu.
279 */
280 private _openChildMenu;
281 /**
282 * Close the child menu immediately.
283 *
284 * This is a no-op if a child menu is not open.
285 */
286 private _closeChildMenu;
287 /**
288 * Start the open timer, unless it is already pending.
289 */
290 private _startOpenTimer;
291 /**
292 * Start the close timer, unless it is already pending.
293 */
294 private _startCloseTimer;
295 /**
296 * Cancel the open timer, if the timer is pending.
297 */
298 private _cancelOpenTimer;
299 /**
300 * Cancel the close timer, if the timer is pending.
301 */
302 private _cancelCloseTimer;
303 /**
304 * Save window data used for menu positioning in transient cache.
305 *
306 * In order to avoid layout trashing it is recommended to invoke this
307 * method immediately prior to opening the menu and any DOM modifications
308 * (like closing previously visible menu, or adding a class to menu widget).
309 *
310 * The transient cache will be released upon `open()` call.
311 */
312 static saveWindowData(): void;
313 private _childIndex;
314 private _activeIndex;
315 private _openTimerID;
316 private _closeTimerID;
317 private _items;
318 private _childMenu;
319 private _parentMenu;
320 private _aboutToClose;
321 private _menuRequested;
322}
323/**
324 * The namespace for the `Menu` class statics.
325 */
326export declare namespace Menu {
327 /**
328 * An options object for creating a menu.
329 */
330 interface IOptions {
331 /**
332 * The command registry for use with the menu.
333 */
334 commands: CommandRegistry;
335 /**
336 * A custom renderer for use with the menu.
337 *
338 * The default is a shared renderer instance.
339 */
340 renderer?: IRenderer;
341 }
342 /**
343 * An options object for the `open` method on a menu.
344 */
345 interface IOpenOptions {
346 /**
347 * Whether to force the X position of the menu.
348 *
349 * Setting to `true` will disable the logic which repositions the
350 * X coordinate of the menu if it will not fit entirely on screen.
351 *
352 * The default is `false`.
353 */
354 forceX?: boolean;
355 /**
356 * Whether to force the Y position of the menu.
357 *
358 * Setting to `true` will disable the logic which repositions the
359 * Y coordinate of the menu if it will not fit entirely on screen.
360 *
361 * The default is `false`.
362 */
363 forceY?: boolean;
364 }
365 /**
366 * A type alias for a menu item type.
367 */
368 type ItemType = 'command' | 'submenu' | 'separator';
369 /**
370 * An options object for creating a menu item.
371 */
372 interface IItemOptions {
373 /**
374 * The type of the menu item.
375 *
376 * The default value is `'command'`.
377 */
378 type?: ItemType;
379 /**
380 * The command to execute when the item is triggered.
381 *
382 * The default value is an empty string.
383 */
384 command?: string;
385 /**
386 * The arguments for the command.
387 *
388 * The default value is an empty object.
389 */
390 args?: ReadonlyJSONObject;
391 /**
392 * The submenu for a `'submenu'` type item.
393 *
394 * The default value is `null`.
395 */
396 submenu?: Menu | null;
397 }
398 /**
399 * An object which represents a menu item.
400 *
401 * #### Notes
402 * Item objects are created automatically by a menu.
403 */
404 interface IItem {
405 /**
406 * The type of the menu item.
407 */
408 readonly type: ItemType;
409 /**
410 * The command to execute when the item is triggered.
411 */
412 readonly command: string;
413 /**
414 * The arguments for the command.
415 */
416 readonly args: ReadonlyJSONObject;
417 /**
418 * The submenu for a `'submenu'` type item.
419 */
420 readonly submenu: Menu | null;
421 /**
422 * The display label for the menu item.
423 */
424 readonly label: string;
425 /**
426 * The mnemonic index for the menu item.
427 */
428 readonly mnemonic: number;
429 /**
430 * The icon renderer for the menu item.
431 */
432 readonly icon: VirtualElement.IRenderer | undefined;
433 /**
434 * The icon class for the menu item.
435 */
436 readonly iconClass: string;
437 /**
438 * The icon label for the menu item.
439 */
440 readonly iconLabel: string;
441 /**
442 * The display caption for the menu item.
443 */
444 readonly caption: string;
445 /**
446 * The extra class name for the menu item.
447 */
448 readonly className: string;
449 /**
450 * The dataset for the menu item.
451 */
452 readonly dataset: CommandRegistry.Dataset;
453 /**
454 * Whether the menu item is enabled.
455 */
456 readonly isEnabled: boolean;
457 /**
458 * Whether the menu item is toggled.
459 */
460 readonly isToggled: boolean;
461 /**
462 * Whether the menu item is visible.
463 */
464 readonly isVisible: boolean;
465 /**
466 * The key binding for the menu item.
467 */
468 readonly keyBinding: CommandRegistry.IKeyBinding | null;
469 }
470 /**
471 * An object which holds the data to render a menu item.
472 */
473 interface IRenderData {
474 /**
475 * The item to be rendered.
476 */
477 readonly item: IItem;
478 /**
479 * Whether the item is the active item.
480 */
481 readonly active: boolean;
482 /**
483 * Whether the item should be collapsed.
484 */
485 readonly collapsed: boolean;
486 /**
487 * Handler for when element is in focus.
488 */
489 readonly onfocus?: () => void;
490 }
491 /**
492 * A renderer for use with a menu.
493 */
494 interface IRenderer {
495 /**
496 * Render the virtual element for a menu item.
497 *
498 * @param data - The data to use for rendering the item.
499 *
500 * @returns A virtual element representing the item.
501 */
502 renderItem(data: IRenderData): VirtualElement;
503 }
504 /**
505 * The default implementation of `IRenderer`.
506 *
507 * #### Notes
508 * Subclasses are free to reimplement rendering methods as needed.
509 */
510 class Renderer implements IRenderer {
511 /**
512 * Render the virtual element for a menu item.
513 *
514 * @param data - The data to use for rendering the item.
515 *
516 * @returns A virtual element representing the item.
517 */
518 renderItem(data: IRenderData): VirtualElement;
519 /**
520 * Render the icon element for a menu item.
521 *
522 * @param data - The data to use for rendering the icon.
523 *
524 * @returns A virtual element representing the item icon.
525 */
526 renderIcon(data: IRenderData): VirtualElement;
527 /**
528 * Render the label element for a menu item.
529 *
530 * @param data - The data to use for rendering the label.
531 *
532 * @returns A virtual element representing the item label.
533 */
534 renderLabel(data: IRenderData): VirtualElement;
535 /**
536 * Render the shortcut element for a menu item.
537 *
538 * @param data - The data to use for rendering the shortcut.
539 *
540 * @returns A virtual element representing the item shortcut.
541 */
542 renderShortcut(data: IRenderData): VirtualElement;
543 /**
544 * Render the submenu icon element for a menu item.
545 *
546 * @param data - The data to use for rendering the submenu icon.
547 *
548 * @returns A virtual element representing the submenu icon.
549 */
550 renderSubmenu(data: IRenderData): VirtualElement;
551 /**
552 * Create the class name for the menu item.
553 *
554 * @param data - The data to use for the class name.
555 *
556 * @returns The full class name for the menu item.
557 */
558 createItemClass(data: IRenderData): string;
559 /**
560 * Create the dataset for the menu item.
561 *
562 * @param data - The data to use for creating the dataset.
563 *
564 * @returns The dataset for the menu item.
565 */
566 createItemDataset(data: IRenderData): ElementDataset;
567 /**
568 * Create the class name for the menu item icon.
569 *
570 * @param data - The data to use for the class name.
571 *
572 * @returns The full class name for the item icon.
573 */
574 createIconClass(data: IRenderData): string;
575 /**
576 * Create the aria attributes for menu item.
577 *
578 * @param data - The data to use for the aria attributes.
579 *
580 * @returns The aria attributes object for the item.
581 */
582 createItemARIA(data: IRenderData): ElementARIAAttrs;
583 /**
584 * Create the render content for the label node.
585 *
586 * @param data - The data to use for the label content.
587 *
588 * @returns The content to add to the label node.
589 */
590 formatLabel(data: IRenderData): h.Child;
591 /**
592 * Create the render content for the shortcut node.
593 *
594 * @param data - The data to use for the shortcut content.
595 *
596 * @returns The content to add to the shortcut node.
597 */
598 formatShortcut(data: IRenderData): h.Child;
599 }
600 /**
601 * The default `Renderer` instance.
602 */
603 const defaultRenderer: Renderer;
604}