Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/devextreme/js/__internal/ui/menu/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ class Menu extends MenuBase<MenuProperties> {
selectByClick,
expandEvent: 'click',
_supportItemUrl: true,
showItemStubs: false,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ const ITEM_URL_CLASS = 'dx-item-url';
const CHECK_BOX_CLASS = 'dx-checkbox';
const CHECK_BOX_ICON_CLASS = 'dx-checkbox-icon';
const ROOT_NODE_CLASS = `${WIDGET_CLASS}-root-node`;
const EXPANDER_ICON_STUB_CLASS = `${WIDGET_CLASS}-expander-icon-stub`;
export const EXPANDER_ICON_STUB_CLASS = `${WIDGET_CLASS}-expander-icon-stub`;

type TreeViewItem = Item & {
url?: string;
Expand All @@ -95,6 +95,8 @@ export interface TreeViewBaseProperties extends Properties<TreeViewNode>, Omit<
deferRendering?: boolean;

_supportItemUrl?: boolean;

showItemStubs?: boolean;
}

class TreeViewBase extends HierarchicalCollectionWidget<TreeViewBaseProperties, TreeViewNode> {
Expand Down Expand Up @@ -275,6 +277,7 @@ class TreeViewBase extends HierarchicalCollectionWidget<TreeViewBaseProperties,
createChildren: null,
onSelectAllValueChanged: null,
_supportItemUrl: false,
showItemStubs: true,
};

// eslint-disable-next-line @typescript-eslint/no-unsafe-return
Expand Down Expand Up @@ -416,6 +419,7 @@ class TreeViewBase extends HierarchicalCollectionWidget<TreeViewBaseProperties,
case 'virtualModeEnabled':
case 'selectByClick':
case '_supportItemUrl':
case 'showItemStubs':
break;
case 'selectionMode':
this._initDataAdapter();
Expand Down Expand Up @@ -909,9 +913,12 @@ class TreeViewBase extends HierarchicalCollectionWidget<TreeViewBaseProperties,
_renderChildren($node: dxElementWrapper, node: TreeViewNode): void {
if (!this._hasChildren(node)) {
this._addLeafClass($node);
$('<div>')
.addClass(EXPANDER_ICON_STUB_CLASS)
.appendTo(this._getItem($node));
const { showItemStubs } = this.option();
if (showItemStubs) {
$('<div>')
.addClass(EXPANDER_ICON_STUB_CLASS)
.appendTo(this._getItem($node));
}
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { shouldSkipOnMobile } from '../../helpers/device.js';
import 'generic_light.css!';
import { implementationsMap, getHeight, getWidth, getOuterHeight } from 'core/utils/size';
import ariaAccessibilityTestHelper from '../../helpers/ariaAccessibilityTestHelper.js';
import { EXPANDER_ICON_STUB_CLASS } from '__internal/ui/tree_view/tree_view.base';

QUnit.testStart(function() {
const markup =
Expand Down Expand Up @@ -257,7 +258,7 @@ QUnit.module('Menu rendering', {
assert.equal(root.length, 1, 'just root level');
});

QUnit.test('Don\'t create submenu on rendering', function(assert) {
QUnit.test('Do not create submenu on rendering', function(assert) {
const menu = createMenu({ items: [{ text: 'item1', items: [{}] }] });
const $rootMenuItem = $(menu.element).find('.' + DX_MENU_ITEM_CLASS).eq(0);

Expand Down Expand Up @@ -1608,7 +1609,7 @@ QUnit.module('Menu tests', {
assert.strictEqual(submenu.option('visible'), true, 'submenu still opened');
});

QUnit.test('Don\'t hide submenu when cancel is true', function(assert) {
QUnit.test('Do not hide submenu when cancel is true', function(assert) {
let i = 0;

const options = {
Expand Down Expand Up @@ -2371,7 +2372,7 @@ QUnit.module('Menu tests', {
assert.ok(submenu.option('visible'), 'submenu shown');
});

QUnit.test('Menu should show after it\'s submenu has been selected', function(assert) {
QUnit.test('Menu should show after its submenu has been selected', function(assert) {
const menu = createMenu({
items: [{ text: 'Item 1', items: [{ text: 'item 11' }] }, { text: 'Item 2' }],
showFirstSubmenuMode: { name: 'onClick', delay: 0 }
Expand Down Expand Up @@ -2470,7 +2471,7 @@ QUnit.module('Menu tests', {
assert.ok(submenu.isOverlayVisible(), 'submenu is still visible');
});

QUnit.test('click should not be blocked on menu\'s item', function(assert) {
QUnit.test('click should not be blocked on menu item', function(assert) {
const menu = createMenu({
items: [{ text: 'Item 1' }]
});
Expand Down Expand Up @@ -2641,7 +2642,7 @@ QUnit.module('keyboard navigation', {
assert.equal(this.instance.option('selectedItem').text, 'item3', 'correct item is selected');
});

QUnit.test('don\'t select an item when space pressed and selectionMode is none', function(assert) {
QUnit.test('do not select an item when space pressed and selectionMode is none', function(assert) {
this.instance.option('selectionMode', 'none');

this.keyboard
Expand Down Expand Up @@ -2891,7 +2892,7 @@ QUnit.module('keyboard navigation', {
[{ icon: 'imageCssClass', items: [{ name: 'item_1_1' }] }],
[{ text: 'item1', icon: 'imageCssClass', items: [{ name: 'item_1_1' }] }],
].forEach(items => {
checkStyleHelper.testInChromeOnDesktopActiveWindow('root item text should be visible after focusing when it\'s opened (T1227670)', function(assert) {
checkStyleHelper.testInChromeOnDesktopActiveWindow('root item text should be visible after focusing when it is opened (T1227670)', function(assert) {
this.instance.option('items', items);

const $rootMenuItem = $(this.instance.itemElements().eq(0));
Expand Down Expand Up @@ -3339,6 +3340,17 @@ QUnit.module('adaptivity: render', {
offset.restore();
}
});

QUnit.test('menu should not show stub elements next to treeview items if adaptivityEnabled is set to true (T1302958)', function(assert) {
new Menu(this.$element, {
items: this.items,
adaptivityEnabled: true
});

const $stubElements = $.find(`.${EXPANDER_ICON_STUB_CLASS}`);

assert.strictEqual($stubElements.length, 0, 'stub elements are not rendered');
});
});

QUnit.module('adaptivity: transfer options', {
Expand Down Expand Up @@ -3576,7 +3588,7 @@ QUnit.module('adaptivity: transfer options', {
assert.strictEqual(treeview.option('animationEnabled'), false, 'animation has been changed to disabled');
});

QUnit.test('Data of tree view doesn\'t load twice when uses the custom store', function(assert) {
QUnit.test('Data of tree view does not load twice when uses the custom store', function(assert) {
const that = this;
let dataLoadCounter = 0;
const clock = sinon.useFakeTimers();
Expand Down Expand Up @@ -3849,7 +3861,7 @@ QUnit.module('adaptivity: behavior', {
assert.ok($treeview.is(':visible'), 'treeview is visible');
});

QUnit.test('Menu should toggle it\'s view between adaptive and non adaptive if container size changed', function(assert) {
QUnit.test('Menu should toggle its view between adaptive and non adaptive if container size changed', function(assert) {
new Menu(this.$element, {
items: this.items,
adaptivityEnabled: true
Expand All @@ -3862,7 +3874,7 @@ QUnit.module('adaptivity: behavior', {
assert.ok(this.$element.find('.' + DX_ADAPTIVE_HAMBURGER_BUTTON_CLASS).is(':hidden'), 'hamburger button is hidden');
});

QUnit.test('Menu should toggle it\'s view between adaptive and non adaptive if width is not enough', function(assert) {
QUnit.test('Menu should toggle its view between adaptive and non adaptive if width is not enough', function(assert) {
new Menu(this.$element, {
items: this.items,
width: 500,
Expand All @@ -3872,7 +3884,7 @@ QUnit.module('adaptivity: behavior', {
assert.ok(this.$element.find('.' + DX_ADAPTIVE_HAMBURGER_BUTTON_CLASS).is(':hidden'), 'hamburger button is hidden');
});

QUnit.test('Menu should toggle it\'s view between adaptive and non adaptive if widget size changed', function(assert) {
QUnit.test('Menu should toggle its view between adaptive and non adaptive if widget size changed', function(assert) {
const menu = new Menu(this.$element, {
items: this.items,
adaptivityEnabled: true
Expand All @@ -3883,7 +3895,7 @@ QUnit.module('adaptivity: behavior', {
assert.ok(this.$element.find('.' + DX_ADAPTIVE_HAMBURGER_BUTTON_CLASS).is(':hidden'), 'hamburger button is hidden');
});

QUnit.test('Menu should toggle it\'s view between adaptive and non adaptive on visibilityChanged event', function(assert) {
QUnit.test('Menu should toggle its view between adaptive and non adaptive on visibilityChanged event', function(assert) {
$('#qunit-fixture').width(500);

const menu = new Menu(this.$element, {
Expand Down Expand Up @@ -4023,11 +4035,11 @@ QUnit.module('adaptivity: behavior', {

$($item2).trigger('dxclick');
assert.ok(getOuterHeight($overlayContent) > height, 'overlay should be enlarged');
assert.equal(overlayPositioned.callCount, 2, 'overlay\'s position should be recalculated');
assert.equal(overlayPositioned.callCount, 2, 'overlay position should be recalculated');

$($item2).trigger('dxclick');
assert.equal(getOuterHeight($overlayContent), height, 'overlay should be shrinked');
assert.equal(overlayPositioned.callCount, 3, 'overlay\'s position should be recalculated');
assert.equal(overlayPositioned.callCount, 3, 'overlay position should be recalculated');
});

QUnit.test('Adaptive width limit should contain only root items', function(assert) {
Expand Down Expand Up @@ -4195,7 +4207,7 @@ function createMenuForHoverStay(options) {
}

function transferActionTest(eventName, expectedArgs, triggerFunc) {
QUnit.test(eventName + ' action should be transferred to the treeview when \'on\' binding is used', function(assert) {
QUnit.test(eventName + ' action should be transferred to the treeview when on binding is used', function(assert) {
const handler = sinon.spy();

const menu = new Menu(this.$element, {
Expand All @@ -4206,15 +4218,15 @@ function transferActionTest(eventName, expectedArgs, triggerFunc) {

menu.on(eventName, handler);
triggerFunc(treeView);
assert.equal(handler.callCount, 1, 'handler for \'on\' was called once');
assert.equal(handler.callCount, 1, 'handler for on was called once');
$.each(expectedArgs, function(_, argument) {
assert.ok(handler.getCall(0).args[0], argument + ' is exist in parameters');
});

handler.resetHistory();
menu.off(eventName);
triggerFunc(treeView);
assert.equal(handler.callCount, 0, 'handler for \'on\' was not executed after unsubscribe');
assert.equal(handler.callCount, 0, 'handler for on was not executed after unsubscribe');
});

QUnit.test(eventName + ' action should be transferred to the treeview when option is used', function(assert) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ QUnit.testStart(function() {
});

import 'ui/tree_view';
import { EXPANDER_ICON_STUB_CLASS } from '__internal/ui/tree_view/tree_view.base';

const WIDGET_CLASS = 'dx-treeview';
const NODE_CONTAINER_CLASS = 'dx-treeview-node-container';
Expand Down Expand Up @@ -467,7 +468,7 @@ QUnit.module('markup', {
assert.equal($firstItem.text(), 'Item 1');
});

QUnit.test('scroll direction by default is \'vertical\'', function(assert) {
QUnit.test('scroll direction by default is vertical', function(assert) {
const treeView = initTree({
items: this.treeItems,
}).dxTreeView('instance');
Expand Down Expand Up @@ -562,7 +563,7 @@ QUnit.module('markup', {
});
});

QUnit.test('Render \'selectAll\' item', function(assert) {
QUnit.test('Render selectAll item', function(assert) {
const $treeView = initTree({
showCheckBoxesMode: 'selectAll',
dataSource: this.treeItems
Expand All @@ -572,7 +573,7 @@ QUnit.module('markup', {
assert.equal($selectAll.length, 1);
});

QUnit.test('On initialization \'selectAll\' item should be selected if all items are selected', function(assert) {
QUnit.test('On initialization selectAll item should be selected if all items are selected', function(assert) {
const data = [{ id: 1, text: 'item 1', selected: true }, { id: 2, text: 'item 2', selected: true }];
const $treeView = initTree({
showCheckBoxesMode: 'selectAll',
Expand All @@ -583,7 +584,7 @@ QUnit.module('markup', {
assert.ok($selectAll.hasClass('dx-checkbox-checked'));
});

QUnit.test('On initialization \'selectAll\' item should be unselected if all items are unselected', function(assert) {
QUnit.test('On initialization selectAll item should be unselected if all items are unselected', function(assert) {
const data = [{ id: 1, text: 'item 1' }, { id: 2, text: 'item 2' }];
const $treeView = initTree({
showCheckBoxesMode: 'selectAll',
Expand All @@ -595,7 +596,7 @@ QUnit.module('markup', {
assert.notOk($selectAll.hasClass('dx-checkbox-checked'));
});

QUnit.test('On initialization \'selectAll\' item should have intermediate state if at least one item is selected', function(assert) {
QUnit.test('On initialization selectAll item should have intermediate state if at least one item is selected', function(assert) {
const data = [{ id: 1, text: 'item 1', selected: true }, { id: 2, text: 'item 2' }];
const $treeView = initTree({
showCheckBoxesMode: 'selectAll',
Expand All @@ -606,7 +607,7 @@ QUnit.module('markup', {
assert.ok($selectAll.hasClass('dx-checkbox-indeterminate'));
});

QUnit.test('On initialization \'selectAll\' item should have intermediate state if at least one item is selected (ierarchical)', function(assert) {
QUnit.test('On initialization selectAll item should have intermediate state if at least one item is selected (ierarchical)', function(assert) {
const data = [{
id: '1',
expanded: true,
Expand Down Expand Up @@ -635,5 +636,15 @@ QUnit.module('markup', {

assert.strictEqual($icon.attr('alt'), 'dxTreeView item icon');
});

QUnit.test('TreeView should show stub elements next to items', function(assert) {
const $treeView = initTree({
items: [{ text: 'Item text', icon: 'some_icon.jpg' }]
});

const $stubElements = $treeView.find(`.${EXPANDER_ICON_STUB_CLASS}`);

assert.strictEqual($stubElements.length > 0, true, 'stub elements are rendered');
});
});

Loading