Skip to content

Commit 8e6a969

Browse files
Toolbar: The overflow menu shouldn’t close immediately when a template is used to define a nested dropdown item (T1298858) (#30380)
1 parent 600d859 commit 8e6a969

File tree

4 files changed

+38
-31
lines changed

4 files changed

+38
-31
lines changed

packages/devextreme/js/__internal/ui/toolbar/internal/m_toolbar.menu.list.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import type { ToolbarItemComponent } from '@js/common';
12
import $ from '@js/core/renderer';
23
import { each } from '@js/core/utils/iterator';
4+
import type { Item } from '@js/ui/toolbar';
35
import { ListBase } from '@ts/ui/list/m_list.base';
46

57
const TOOLBAR_MENU_ACTION_CLASS = 'dx-toolbar-menu-action';
@@ -10,6 +12,7 @@ const TOOLBAR_MENU_CUSTOM_CLASS = 'dx-toolbar-menu-custom';
1012
const TOOLBAR_MENU_LAST_SECTION_CLASS = 'dx-toolbar-menu-last-section';
1113
const SCROLLVIEW_CONTENT_CLASS = 'dx-scrollview-content';
1214

15+
type ActionableComponents = Extract<ToolbarItemComponent, 'dxButton' | 'dxButtonGroup'>;
1316
export default class ToolbarMenuList extends ListBase {
1417
_activeStateUnit?: string;
1518

@@ -80,15 +83,16 @@ export default class ToolbarMenuList extends ListBase {
8083
return itemElement;
8184
}
8285

83-
_getItemCssClasses(item): string[] {
86+
_getItemCssClasses(item: Item): string[] {
8487
const cssClasses: string[] = [];
8588
const actionableComponents = this._getActionableComponents();
8689

8790
if (this._getItemTemplateName({ itemData: item })) {
8891
cssClasses.push(TOOLBAR_MENU_CUSTOM_CLASS);
8992
}
9093

91-
if (!item.widget || actionableComponents.includes(item.widget)) {
94+
if ((!item.location && !item.widget)
95+
|| actionableComponents.some((component) => component === item.widget)) {
9296
cssClasses.push(TOOLBAR_MENU_ACTION_CLASS);
9397
}
9498

@@ -100,11 +104,15 @@ export default class ToolbarMenuList extends ListBase {
100104
cssClasses.push(TOOLBAR_HIDDEN_BUTTON_GROUP_CLASS);
101105
}
102106

103-
cssClasses.push(item.cssClass);
107+
if (item.cssClass) {
108+
cssClasses.push(item.cssClass);
109+
}
110+
104111
return cssClasses;
105112
}
106113

107-
_getActionableComponents() {
114+
// eslint-disable-next-line class-methods-use-this
115+
_getActionableComponents(): ActionableComponents[] {
108116
return ['dxButton', 'dxButtonGroup'];
109117
}
110118

packages/devextreme/js/__internal/ui/toolbar/m_toolbar.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class Toolbar extends ToolbarBase {
151151
}
152152

153153
_isMenuItem(itemData): boolean {
154-
return itemData.location === 'menu' || itemData.locateInMenu === 'always';
154+
return itemData.locateInMenu === 'always';
155155
}
156156

157157
_isToolbarItem(itemData): boolean {

packages/devextreme/js/__internal/ui/toolbar/strategy/m_toolbar.singleline.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export class SingleLineStrategy {
173173
// @ts-expect-error
174174
const itemOverflow = overflowGetter(item, { functionsAsIs: true });
175175

176-
if (itemVisible !== false && (itemOverflow === 'auto' || itemOverflow === 'always') || item.location === 'menu') {
176+
if (itemVisible !== false && (itemOverflow === 'auto' || itemOverflow === 'always')) {
177177
result = true;
178178
}
179179
});

packages/devextreme/testing/tests/DevExpress.ui.widgets/toolbar.tests.js

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -587,8 +587,14 @@ QUnit.module('toolbar with menu', moduleConfig, () => {
587587
widget: 'dxDropDownButton',
588588
options: { items: ['item'] },
589589
},
590+
{
591+
locateInMenu: 'always',
592+
location: 'after',
593+
widget: 'dxDropDownButton',
594+
options: { items: ['item'] },
595+
}
590596
].forEach(({ widget, options }) => {
591-
QUnit.test(`click on editor component (${widget}) inside the toolbar menu should not close it (T1287462)`, function(assert) {
597+
QUnit.test(`click on editor component (${widget}) inside the toolbar menu should not close it (T1287462, T1298858)`, function(assert) {
592598
this.instance.option('items', [{
593599
locateInMenu: 'always',
594600
widget,
@@ -1263,6 +1269,23 @@ QUnit.module('adaptivity', moduleConfig, () => {
12631269
assert.ok($sections.eq(2).hasClass('dx-toolbar-menu-last-section'), 'border for last section is removed');
12641270
});
12651271

1272+
QUnit.test('menu shouldn\'t be closed after click on editors', function(assert) {
1273+
const $beforeItem = $('<div>').width(150);
1274+
1275+
this.instance.option({
1276+
items: [
1277+
{ location: 'before', locateInMenu: 'auto', template: () => $beforeItem },
1278+
],
1279+
width: 100
1280+
});
1281+
1282+
this.overflowMenu.click();
1283+
1284+
$($beforeItem).trigger('dxclick');
1285+
1286+
assert.ok(this.overflowMenu.instance().option('opened'), 'dropdown isn\'t closed');
1287+
});
1288+
12661289
QUnit.test('menu should be closed after click on button or menu items', function(assert) {
12671290
this.instance.option({
12681291
items: [
@@ -1568,30 +1591,6 @@ QUnit.module('adaptivity', moduleConfig, () => {
15681591
});
15691592

15701593
QUnit.module('default template', moduleConfig, () => {
1571-
QUnit.test('T430159 menu should be closed after click on item if location is defined', function(assert) {
1572-
const onClickActionStub = sinon.stub();
1573-
1574-
this.instance.option({
1575-
items: [
1576-
{
1577-
location: 'center',
1578-
text: '123',
1579-
locateInMenu: 'always',
1580-
onClick: onClickActionStub
1581-
}
1582-
],
1583-
width: 100
1584-
});
1585-
1586-
this.overflowMenu.click();
1587-
1588-
const $menuItem = $(`.${TOOLBAR_MENU_SECTION_CLASS} .${LIST_ITEM_CLASS}`).eq(0);
1589-
$menuItem.trigger('dxclick');
1590-
1591-
assert.strictEqual(this.instance.option('overflowMenuVisible'), false, 'dropdown is closed');
1592-
assert.strictEqual(onClickActionStub.callCount, 1, 'onClick was fired');
1593-
});
1594-
15951594
['single', 'multiple'].forEach(selectionMode => {
15961595
QUnit.test(`Click on buttonGroup item inside menu (T977105). selectionMode: ${selectionMode}`, function(assert) {
15971596
const onClickActionStub = sinon.stub();

0 commit comments

Comments
 (0)