Skip to content

Commit 5be3965

Browse files
Kateryna ProkopenkoDevtools-frontend LUCI CQ
authored andcommitted
[DevToolsUIKit] Add code examples for context menu
Bug: 414331596 Change-Id: Ieee446091624bdc2e9e8dc8978c4e930289e60e3 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6822160 Auto-Submit: Kateryna Prokopenko <[email protected]> Reviewed-by: Victor Porof <[email protected]> Commit-Queue: Victor Porof <[email protected]>
1 parent 4d5d009 commit 5be3965

File tree

7 files changed

+181
-1
lines changed

7 files changed

+181
-1
lines changed

docs/styleguide/ux/components.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ element.addEventListener('contextmenu', (event: MouseEvent) => {
407407
// Disabled item
408408
contextMenu.defaultSection().appendItem('Disabled item', () => {
409409
console.log('Will not be printed');
410-
}, { jslogContext: 'disbaled-item',
410+
}, { jslogContext: 'disabled-item',
411411
disabled: true });
412412

413413
// Experimental item

front_end/ui/components/docs/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ group("docs") {
1919
"./computed_style_property",
2020
"./computed_style_trace",
2121
"./console_insight",
22+
"./context_menu",
2223
"./elements_breadcrumbs",
2324
"./expandable_list",
2425
"./icon_button",
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright 2025 The Chromium Authors. All rights reserved.
2+
# Use of this source code is governed by a BSD-style license that can be
3+
# found in the LICENSE file.
4+
5+
import("../../../../../scripts/build/ninja/copy.gni")
6+
import("../../../../../scripts/build/typescript/typescript.gni")
7+
8+
ts_library("ts") {
9+
testonly = true
10+
sources = [ "basic.ts" ]
11+
12+
deps = [
13+
"../../../../testing",
14+
"../../../legacy:bundle",
15+
]
16+
}
17+
18+
copy_to_gen("context_menu") {
19+
testonly = true
20+
sources = [ "basic.html" ]
21+
22+
deps = [ ":ts" ]
23+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!--
2+
Copyright 2025 The Chromium Authors. All rights reserved.
3+
Use of this source code is governed by a BSD-style license that can be
4+
found in the LICENSE file.
5+
-->
6+
<!DOCTYPE html>
7+
<html>
8+
<head>
9+
<meta charset="UTF-8" />
10+
<meta name="viewport" content="width=device-width" />
11+
<title>Context menu example</title>
12+
<style>
13+
body {
14+
overflow: auto !important; /* stylelint-disable-line declaration-no-important */
15+
}
16+
17+
div:not(.vbox) {
18+
width: 500px;
19+
padding: 25px;
20+
display: flex;
21+
align-items: center;
22+
flex-wrap: wrap;
23+
gap: 10px;
24+
background-color: var(--sys-color-neutral-container);
25+
border-radius: var(--sys-shape-corner-medium);
26+
text-align: center;
27+
28+
p {
29+
vertical-align: middle;
30+
}
31+
}
32+
</style>
33+
</head>
34+
<body>
35+
<header>DevTools menu button (lit-html)</header>
36+
<div id="menu-button"></div>
37+
<header>Various simple menu items (imperative API)</header>
38+
<div id="simple-items"><p>Right-click here</p></div>
39+
<header>Custom sections (imperative API)</header>
40+
<div id="custom-section"><p>Right-click here</p></div>
41+
<header>Sub menu (imperative API)</header>
42+
<div id="sub-menu"><p>Right-click here</p></div>
43+
<script type="module" src="./basic.js"></script>
44+
</body>
45+
</html>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright 2021 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import * as FrontendHelpers from '../../../../testing/EnvironmentHelpers.js';
6+
import * as UI from '../../../legacy/legacy.js';
7+
import * as Lit from '../../../lit/lit.js';
8+
import * as ComponentHelpers from '../../helpers/helpers.js';
9+
10+
const {html} = Lit;
11+
12+
await ComponentHelpers.ComponentServerSetup.setup();
13+
await FrontendHelpers.initializeGlobalVars();
14+
15+
{
16+
const menuButtonSection = document.querySelector('#menu-button') as HTMLElement;
17+
Lit.render(
18+
html`
19+
<devtools-menu-button
20+
icon-name="bin"
21+
.populateMenuCall=${(menu: UI.ContextMenu.ContextMenu) => {
22+
menu.defaultSection().appendItem('Item', () => {
23+
alert('Item clicked');
24+
}, {jslogContext: 'item'});
25+
}}
26+
jslogContext="my-menu-button"
27+
></devtools-menu-button>
28+
`,
29+
menuButtonSection);
30+
}
31+
32+
{
33+
let checked = true;
34+
const simpleItemMenuSection = document.querySelector('#simple-items');
35+
simpleItemMenuSection?.addEventListener('contextmenu', onSimpleMenu.bind(this));
36+
37+
function onSimpleMenu(event: Event) {
38+
const simpleMenu = new UI.ContextMenu.ContextMenu(event);
39+
40+
// Regular item
41+
simpleMenu.defaultSection().appendItem('Regular item', () => {
42+
alert('Regular item clicked ');
43+
}, {jslogContext: 'regular-item'});
44+
45+
// Disabled item
46+
simpleMenu.defaultSection().appendItem('Disabled item', () => {
47+
alert('Will not be printed');
48+
}, {jslogContext: 'disabled-item', disabled: true});
49+
50+
// Experimental item
51+
simpleMenu.defaultSection().appendItem('Experimental item', () => {
52+
alert('Experimental item clicked');
53+
}, {jslogContext: 'experimental-item', isPreviewFeature: true});
54+
55+
// Separator
56+
simpleMenu.defaultSection().appendSeparator();
57+
58+
// Checkbox item
59+
simpleMenu.defaultSection().appendCheckboxItem('Checkbox item', () => {
60+
alert('Checkbox item clicked');
61+
checked = !checked;
62+
}, {checked, jslogContext: 'checkbox-item'});
63+
64+
void simpleMenu.show();
65+
}
66+
}
67+
68+
{
69+
const customSectionMenuSection = document.querySelector('#custom-section');
70+
customSectionMenuSection?.addEventListener('contextmenu', onCustomSectionMenu.bind(this));
71+
72+
function onCustomSectionMenu(event: Event) {
73+
const customSectionMenu = new UI.ContextMenu.ContextMenu(event);
74+
75+
// First custom section
76+
const customSection = customSectionMenu.section('Custom section');
77+
customSection.appendItem('Section inner item 1', () => {/* ... */}, {jslogContext: 'my-inner-item-1'});
78+
customSection.appendItem('Section inner item 2', () => {/* ... */}, {jslogContext: 'my-inner-item-2'});
79+
80+
// Second custom section
81+
const customSection2 = customSectionMenu.section('Custom section 2');
82+
customSection2.appendItem('Section inner item 1', () => {/* ... */}, {jslogContext: 'my-inner-item-3'});
83+
84+
void customSectionMenu.show();
85+
}
86+
}
87+
88+
{
89+
const subMenuSection = document.querySelector('#sub-menu');
90+
subMenuSection?.addEventListener('contextmenu', onCustomSectionMenu.bind(this));
91+
92+
function onCustomSectionMenu(event: Event) {
93+
const subMenuMenu = new UI.ContextMenu.ContextMenu(event);
94+
95+
const subMenu =
96+
subMenuMenu.defaultSection().appendSubMenuItem('Item to open sub menu', /* disabled */ false, 'my-sub-menu');
97+
subMenu.defaultSection().appendItem('Sub menu inner item 1', () => {/* ... */}, {jslogContext: 'my-inner-item-1'});
98+
subMenu.defaultSection().appendItem('Sub menu inner item 2', () => {/* ... */}, {jslogContext: 'my-inner-item-2'});
99+
100+
void subMenuMenu.show();
101+
}
102+
}

front_end/ui/legacy/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ devtools_entrypoint("bundle") {
147147
"../components/copy_to_clipboard:*",
148148
"../components/data_grid:*",
149149
"../components/docs/combo_box/*",
150+
"../components/docs/context_menu/*",
150151
"../components/docs/performance_panel/*",
151152
"../components/docs/radio_button/*",
152153
"../components/docs/slider/*",

front_end/ui/visual_logging/KnownContextValues.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,7 @@ export const knownContextValues = new Set([
699699
'changes',
700700
'changes.changes',
701701
'changes.reveal-source',
702+
'checkbox-item',
702703
'checked',
703704
'chevron-left',
704705
'chevron-right',
@@ -1254,6 +1255,7 @@ export const knownContextValues = new Set([
12541255
'disable-recorder-import-warning',
12551256
'disable-self-xss-warning',
12561257
'disabled',
1258+
'disabled-item',
12571259
'disallowed-select-descendants-details',
12581260
'disconnect-from-network',
12591261
'display',
@@ -1482,6 +1484,7 @@ export const knownContextValues = new Set([
14821484
'expand',
14831485
'expand-recursively',
14841486
'experimental-cookie-features',
1487+
'experimental-item',
14851488
'experiments',
14861489
'experiments-filter',
14871490
'expires',
@@ -1921,6 +1924,7 @@ export const knownContextValues = new Set([
19211924
'issues.filter-network-requests-by-raw-cookie',
19221925
'issues.unhide-all-hiddes',
19231926
'it',
1927+
'item',
19241928
'item-1',
19251929
'item-2',
19261930
'item-tolerance',
@@ -2510,6 +2514,9 @@ export const knownContextValues = new Set([
25102514
'mr',
25112515
'ms',
25122516
'my',
2517+
'my-inner-item-1',
2518+
'my-inner-item-2',
2519+
'my-inner-item-3',
25132520
'name',
25142521
'navigate',
25152522
'navigate-to-selector-source',
@@ -2951,6 +2958,7 @@ export const knownContextValues = new Set([
29512958
'refresh-watch-expressions',
29522959
'regular-breakpoint',
29532960
'regular-expression',
2961+
'regular-item',
29542962
'reject-percentage',
29552963
'release-note',
29562964
'release-notes',

0 commit comments

Comments
 (0)