Skip to content

Commit 5c639cc

Browse files
docs: custom item data for context menu and menu bar (#4158)
Co-authored-by: Russell J.T. Dyer <[email protected]>
1 parent 4a3fb95 commit 5c639cc

File tree

8 files changed

+385
-24
lines changed

8 files changed

+385
-24
lines changed

articles/components/context-menu/index.adoc

+58-23
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ tab-title: Usage
33
layout: tabbed-page
44
title: Context Menu
55
page-title: Context Menu component | Vaadin components
6-
description: Context Menu is a component that you can attach to any component to display a context menu.
6+
description: Context Menu is a component that can be attached to any component to display a context menu.
77
meta-description: Implement and configure context menus for better user interaction in your Vaadin applications.
88
page-links:
99
- 'API: https://cdn.vaadin.com/vaadin-web-components/{moduleNpmVersion:@vaadin/context-menu}/#/elements/vaadin-context-menu[TypeScript] / https://vaadin.com/api/platform/{moduleMavenVersion:com.vaadin:vaadin}/com/vaadin/flow/component/contextmenu/ContextMenu.html[Java]'
@@ -16,11 +16,11 @@ page-links:
1616
// tag::description[]
1717
Context Menu is a component that you can attach to any component to display a context menu.
1818
// end::description[]
19-
The menu appears on right (default) or left click. On a touch device, a long press opens the context menu.
19+
The menu appears on the right by default, or with a left click. On a touch device, a long press opens the context menu.
2020

2121
// tag::example-instructions[]
2222
[IMPORTANT]
23-
Open the Context Menu by right-clicking (mouse) or long-pressing (touch) a Grid row.
23+
Open the Context Menu by right-clicking (i.e., with a mouse), or by long-pressing (i.e., on a touch screen), a Grid row.
2424
// end::example-instructions[]
2525

2626
[.example]
@@ -52,10 +52,10 @@ include::{root}/frontend/demo/component/contextmenu/react/context-menu-basic.tsx
5252
endif::[]
5353
--
5454

55+
5556
== Dividers
5657

57-
You can use dividers to separate and group related content.
58-
Use dividers sparingly to avoid creating unnecessary visual clutter.
58+
You can use dividers to separate and group related content. Use dividers sparingly to avoid creating unnecessary visual clutter.
5959

6060
include::index.adoc[tag=example-instructions]
6161

@@ -84,6 +84,7 @@ include::{root}/frontend/demo/component/contextmenu/react/context-menu-dividers.
8484
endif::[]
8585
--
8686

87+
8788
== Checkable Menu Items
8889

8990
Checkable Menu Items can be used to toggle a setting on and off.
@@ -117,10 +118,10 @@ include::{root}/frontend/demo/component/contextmenu/react/context-menu-checkable
117118
endif::[]
118119
--
119120

121+
120122
== Hierarchical Menu
121123

122-
Context Menu, like Menu Bar, supports multi-level sub-menus.
123-
You can use a hierarchical menu to organize a large set of options and group related items.
124+
Context Menu, like Menu Bar, supports multi-level sub-menus. You can use a hierarchical menu to organize a large set of options and group related items.
124125

125126
include::index.adoc[tag=example-instructions]
126127

@@ -153,6 +154,7 @@ include::{root}/frontend/demo/component/contextmenu/react/context-menu-hierarchi
153154
endif::[]
154155
--
155156

157+
156158
== Custom Items
157159

158160
You can customize the items to include more than a single line of text.
@@ -193,6 +195,7 @@ include::{root}/frontend/demo/component/contextmenu/react/context-menu-presentat
193195
endif::[]
194196
--
195197

198+
196199
== Styling Menu Items
197200

198201
Individual menu items can be styled by [since:com.vaadin:[email protected]]#applying custom class names# to them, and writing CSS style blocks targeting those class names.
@@ -222,9 +225,10 @@ include::{root}/frontend/demo/component/contextmenu/react/context-menu-classname
222225
endif::[]
223226
--
224227

225-
.Use theme names instead of class names in V24.2 and older
228+
.Theme Names, Not Class Names
226229
[NOTE]
227-
In versions prior to 24.3, theme names must be used instead (`theme` property / `addThemeNames` Java method). The CSS syntax for targeting a theme name is `[theme~="custom-theme"]`
230+
In versions prior to 24.3, theme names must be used instead (i.e., `theme` property / `addThemeNames` Java method). The CSS syntax for targeting a theme name is `[theme~="custom-theme"]`
231+
228232

229233
== Disabled Menu Items
230234

@@ -265,10 +269,11 @@ include::{root}/frontend/demo/component/contextmenu/react/context-menu-disabled.
265269
endif::[]
266270
--
267271

272+
268273
[role="since:com.vaadin:[email protected]"]
269274
=== Disable on Click (Flow)
270275

271-
To prevent duplicate clicks while the server is processing a request, call the `setDisableOnClick(true)` method on a menu item instance to immediately disable that menu item on the client-side when its clicked.
276+
To prevent duplicate clicks while the server is processing a request, call the `setDisableOnClick(true)` method on a menu item instance to disable immediately that menu item on the client-side when it's clicked.
272277

273278
[.example]
274279
--
@@ -282,9 +287,10 @@ endif::[]
282287

283288
--
284289

290+
285291
== Left-Click
286292

287-
You can use left-click to open Context Menu in situations where left-click doesn't have any other function, for example a Grid without selection support.
293+
You can use left-click to open Context Menu in situations where left-click doesn't have any other function (e.g., a Grid without selection support).
288294

289295
[IMPORTANT]
290296
Open the Context Menu by clicking a Grid row.
@@ -318,14 +324,43 @@ include::{root}/frontend/demo/component/contextmenu/react/context-menu-left-clic
318324
endif::[]
319325
--
320326

327+
328+
[role="since:com.vaadin:[email protected]"]
329+
== Custom Item Data
330+
331+
Context Menu allows you to associate custom data with menu items. This can be useful for storing additional information about the item, such as an item type or a value. The data can then be used to trigger actions when an item is selected.
332+
333+
[.example]
334+
--
335+
ifdef::lit[]
336+
[source,typescript]
337+
----
338+
include::{root}/frontend/demo/component/contextmenu/context-menu-custom-item-data.ts[render,tags=snippet,indent=0,group=Lit]
339+
----
340+
endif::[]
341+
342+
ifdef::flow[]
343+
[source,java]
344+
----
345+
include::{root}/src/main/java/com/vaadin/demo/component/contextmenu/ContextMenuCustomItemData.java[render,tags=snippet,indent=0,group=Flow]
346+
----
347+
endif::[]
348+
349+
ifdef::react[]
350+
[source,tsx]
351+
----
352+
include::{root}/frontend/demo/component/contextmenu/react/context-menu-custom-item-data.tsx[render,tags=snippet,indent=0,group=React]
353+
----
354+
endif::[]
355+
--
356+
357+
321358
== Best Practices
322359

323-
Context Menu is used to provide shortcuts to the user.
324-
You shouldn't use it as the only or primary means to complete a task.
325-
The primary way should be accessible elsewhere in the UI.
360+
Context Menu is used to provide shortcuts to the user. You shouldn't use it as the only or primary means to complete a task. The primary way should be accessible elsewhere in the UI.
326361

327362
[IMPORTANT]
328-
Open the Context Menu by right-clicking (desktop) or long-pressing (mobile) a Grid row, or use the Menu Bar in the last column.
363+
Open the Context Menu by right-clicking (i.e., for desktops) or long-pressing (i.e., for mobile devices) a Grid row, or use the Menu Bar in the last column.
329364

330365
[.example]
331366
--
@@ -356,26 +391,26 @@ include::{root}/frontend/demo/component/contextmenu/react/context-menu-best-prac
356391
endif::[]
357392
--
358393

359-
=== Context Menu vs Menu Bar
360394

361-
You should use Context Menu when there is no dedicated button for opening an overlay menu, such as right-clicking a grid row.
362-
When there is a dedicated element/component, such as an <<../menu-bar#,overflow menu>>, use Menu Bar.
395+
=== Context Menu vs. Menu Bar
396+
397+
You should use Context Menu when there is no dedicated button for opening an overlay menu, such as right-clicking a grid row. When there is a dedicated element or component, such as an <<../menu-bar#,overflow menu>>, use Menu Bar.
398+
363399

364400
=== Icons
365401

366-
Use icons when applicable to help improve recognition.
367-
It's recommended to use commonly recognized icons to avoid confusion.
368-
Use icons consistently throughout a list of options.
402+
Use icons when applicable to help improve recognition. It's recommended to use commonly recognized icons to avoid confusion. Use icons consistently throughout a list of options.
403+
369404

370405
=== Labelling
371406

372-
Suffix a menu item with ... when the associated action won't be executed, but instead reveal some UI, like a dialog, for completing the action.
407+
Suffix a menu item with "..." when the associated action won't be executed, but instead reveal some UI, like a dialog, for completing the action.
373408

374409

375410
== Related Components
376411

377412
|===
378-
|Component |Usage recommendations
413+
|Component |Usage Recommendations
379414

380415
|<<../menu-bar#,Menu Bar>>
381416
|Component for displaying a horizontal menu with multi-level sub-menus.

articles/components/menu-bar/index.adoc

+30-1
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,36 @@ endif::[]
615615
ifdef::react[]
616616
[source,tsx]
617617
----
618-
include::{root}/frontend/demo/component/menubar/react/menu-bar-internationalization.tsx[render,tags=snippet,indent=0,group=React]
618+
include::{root}/frontend/demo/component/menubar/react/menu-bar-internationalization.tsx[tags=snippet,indent=0,group=React]
619+
----
620+
endif::[]
621+
--
622+
623+
[role="since:com.vaadin:[email protected]"]
624+
== Custom Item Data
625+
626+
Menu Bar allows you to associate custom data with menu items. This can be useful for storing additional information about the item, such as an item type or a value. The data can then be used to trigger actions when an item is selected.
627+
628+
[.example]
629+
--
630+
ifdef::lit[]
631+
[source,typescript]
632+
----
633+
include::{root}/frontend/demo/component/menubar/menu-bar-custom-item-data.ts[render,tags=snippet,indent=0,group=Lit]
634+
----
635+
endif::[]
636+
637+
ifdef::flow[]
638+
[source,java]
639+
----
640+
include::{root}/src/main/java/com/vaadin/demo/component/menubar/MenuBarCustomItemData.java[render,tags=snippet,indent=0,group=Flow]
641+
----
642+
endif::[]
643+
644+
ifdef::react[]
645+
[source,tsx]
646+
----
647+
include::{root}/frontend/demo/component/menubar/react/menu-bar-custom-item-data.tsx[render,tags=snippet,indent=0,group=React]
619648
----
620649
endif::[]
621650
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import 'Frontend/demo/init'; // hidden-source-line
2+
import '@vaadin/context-menu';
3+
import { html, LitElement } from 'lit';
4+
import { customElement, state } from 'lit/decorators.js';
5+
import type { ContextMenuItem, ContextMenuItemSelectedEvent } from '@vaadin/context-menu';
6+
import { applyTheme } from 'Frontend/generated/theme';
7+
8+
@customElement('context-menu-custom-item-data')
9+
export class Example extends LitElement {
10+
protected override createRenderRoot() {
11+
const root = super.createRenderRoot();
12+
// Apply custom theme (only supported if your app uses one)
13+
applyTheme(root);
14+
return root;
15+
}
16+
17+
// tag::snippet[]
18+
@state()
19+
private items: Array<ContextMenuItem<{ value: string }>> = [
20+
{
21+
text: 'Copy as plain text',
22+
value:
23+
'Context Menu\n\nContext Menu is a component that you can attach to any component to display a context menu.',
24+
},
25+
{
26+
text: 'Copy as HTML',
27+
value:
28+
'<h1>Context Menu</h1><p>Context Menu is a component that you can attach to any component to display a context menu.</p>',
29+
},
30+
{
31+
text: 'Copy as Markdown',
32+
value:
33+
'# Context Menu\n\nContext Menu is a component that you can attach to any component to display a context menu.',
34+
},
35+
];
36+
37+
protected override render() {
38+
return html`
39+
<vaadin-context-menu .items="${this.items}" @item-selected="${this.itemSelected}">
40+
<h1>Context Menu</h1>
41+
<p>
42+
Context Menu is a component that you can attach to any component to display a context
43+
menu.
44+
</p>
45+
</vaadin-context-menu>
46+
`;
47+
}
48+
49+
itemSelected(e: ContextMenuItemSelectedEvent<ContextMenuItem<{ value?: string }>>) {
50+
const value = e.detail.value.value;
51+
if (value) {
52+
navigator.clipboard.writeText(value);
53+
}
54+
}
55+
56+
// end::snippet[]
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { reactExample } from 'Frontend/demo/react-example'; // hidden-source-line
2+
import React from 'react';
3+
import { ContextMenu, type ContextMenuItem } from '@vaadin/react-components';
4+
5+
function Example() {
6+
// tag::snippet[]
7+
const items: Array<ContextMenuItem<{ value: string }>> = [
8+
{
9+
text: 'Copy as plain text',
10+
value:
11+
'Context Menu\n\nContext Menu is a component that you can attach to any component to display a context menu.',
12+
},
13+
{
14+
text: 'Copy as HTML',
15+
value:
16+
'<h1>Context Menu</h1><p>Context Menu is a component that you can attach to any component to display a context menu.</p>',
17+
},
18+
{
19+
text: 'Copy as Markdown',
20+
value:
21+
'# Context Menu\n\nContext Menu is a component that you can attach to any component to display a context menu.',
22+
},
23+
];
24+
25+
return (
26+
<ContextMenu
27+
items={items}
28+
onItemSelected={(event) => {
29+
const value = event.detail.value.value;
30+
if (value) {
31+
navigator.clipboard.writeText(value);
32+
}
33+
}}
34+
>
35+
<h1>Context Menu</h1>
36+
<p>
37+
Context Menu is a component that you can attach to any component to display a context menu.
38+
</p>
39+
</ContextMenu>
40+
);
41+
// end::snippet[]
42+
}
43+
44+
export default reactExample(Example); // hidden-source-line
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import 'Frontend/demo/init'; // hidden-source-line
2+
import '@vaadin/menu-bar';
3+
import { html, LitElement } from 'lit';
4+
import { customElement, state } from 'lit/decorators.js';
5+
import type { MenuBarItem, MenuBarItemSelectedEvent } from '@vaadin/menu-bar';
6+
import { applyTheme } from 'Frontend/generated/theme';
7+
8+
@customElement('menu-bar-custom-item-data')
9+
export class Example extends LitElement {
10+
protected override createRenderRoot() {
11+
const root = super.createRenderRoot();
12+
// Apply custom theme (only supported if your app uses one)
13+
applyTheme(root);
14+
return root;
15+
}
16+
17+
// tag::snippet[]
18+
@state()
19+
private items: Array<MenuBarItem<{ value?: string }>> = [
20+
{
21+
text: 'Copy',
22+
children: [
23+
{
24+
text: 'Copy as plain text',
25+
value:
26+
'Menu Bar\n\nMenu Bar is a horizontal button bar with hierarchical drop-down menus.',
27+
},
28+
{
29+
text: 'Copy as HTML',
30+
value:
31+
'<h1>Menu Bar</h1><p>Menu Bar is a horizontal button bar with hierarchical drop-down menus.</p>',
32+
},
33+
{
34+
text: 'Copy as Markdown',
35+
value:
36+
'# Menu Bar\n\nMenu Bar is a horizontal button bar with hierarchical drop-down menus.',
37+
},
38+
],
39+
},
40+
];
41+
42+
protected override render() {
43+
return html`
44+
<vaadin-menu-bar
45+
.items="${this.items}"
46+
@item-selected="${this.itemSelected}"
47+
></vaadin-menu-bar>
48+
`;
49+
}
50+
51+
itemSelected(e: MenuBarItemSelectedEvent<MenuBarItem<{ value?: string }>>) {
52+
const value = e.detail.value.value;
53+
if (value) {
54+
navigator.clipboard.writeText(value);
55+
}
56+
}
57+
// end::snippet[]
58+
}

0 commit comments

Comments
 (0)