Skip to content

Commit ce4c575

Browse files
authored
Tabs, TabPanel: refactoring codebase and tests (DevExpress#30153)
1 parent 988d7c1 commit ce4c575

File tree

10 files changed

+254
-295
lines changed

10 files changed

+254
-295
lines changed

packages/devextreme/js/__internal/ui/tab_panel/tab_panel.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,30 @@ import supportUtils from '@ts/core/utils/m_support';
1818
import type { OptionChanged } from '@ts/core/widget/types';
1919
import MultiView from '@ts/ui/m_multi_view';
2020
import type { TabsProperties } from '@ts/ui/tabs/tabs';
21-
import Tabs from '@ts/ui/tabs/tabs';
21+
import Tabs, {
22+
TABS_ITEM_TEXT_CLASS,
23+
TABS_ITEM_TEXT_SPAN_CLASS,
24+
TABS_ITEM_TEXT_SPAN_PSEUDO_CLASS,
25+
} from '@ts/ui/tabs/tabs';
2226

2327
// eslint-disable-next-line import/no-named-default
2428
import { default as TabPanelItem } from './item';
2529

2630
export const TABPANEL_CLASS = 'dx-tabpanel';
2731
const TABPANEL_TABS_CLASS = 'dx-tabpanel-tabs';
28-
const TABPANEL_TABS_ITEM_CLASS = 'dx-tabpanel-tab';
29-
const TABPANEL_CONTAINER_CLASS = 'dx-tabpanel-container';
30-
const TABS_ITEM_TEXT_CLASS = 'dx-tab-text';
31-
const DISABLED_FOCUSED_TAB_CLASS = 'dx-disabled-focused-tab';
32-
const TABS_ITEM_TEXT_SPAN_CLASS = 'dx-tab-text-span';
33-
const TABS_ITEM_TEXT_SPAN_PSEUDO_CLASS = 'dx-tab-text-span-pseudo';
34-
35-
const TABPANEL_TABS_POSITION_CLASS: Record<Position, string> = {
32+
export const TABPANEL_TABS_ITEM_CLASS = 'dx-tabpanel-tab';
33+
export const TABPANEL_CONTAINER_CLASS = 'dx-tabpanel-container';
34+
35+
export const DISABLED_FOCUSED_TAB_CLASS = 'dx-disabled-focused-tab';
36+
37+
export const TABPANEL_TABS_POSITION_CLASS: Record<Position, string> = {
3638
top: 'dx-tabpanel-tabs-position-top',
3739
right: 'dx-tabpanel-tabs-position-right',
3840
bottom: 'dx-tabpanel-tabs-position-bottom',
3941
left: 'dx-tabpanel-tabs-position-left',
4042
};
4143

42-
const TABS_POSITION: Record<Position, Position> = {
44+
export const TABS_POSITION: Record<Position, Position> = {
4345
top: 'top',
4446
right: 'right',
4547
bottom: 'bottom',
@@ -53,7 +55,7 @@ const TABS_INDICATOR_POSITION_BY_TABS_POSITION: Record<Position, Position> = {
5355
left: 'right',
5456
};
5557

56-
const TABS_ORIENTATION: Record<Orientation, Orientation> = {
58+
export const TABS_ORIENTATION: Record<Orientation, Orientation> = {
5759
horizontal: 'horizontal',
5860
vertical: 'vertical',
5961
};
@@ -212,7 +214,7 @@ class TabPanel extends MultiView<TabPanelProperties> {
212214
super._initTemplates();
213215

214216
this._templateManager.addDefaultTemplates({
215-
title: new BindableTemplate(($container, data) => {
217+
title: new BindableTemplate(($container: dxElementWrapper, data: Item) => {
216218
this._prepareTabsItemTemplate(data, $container);
217219

218220
const $tabItem = $('<div>').addClass(TABS_ITEM_TEXT_CLASS);

packages/devextreme/js/__internal/ui/tabs/item.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import $ from '@js/core/renderer';
22
import type { Item } from '@js/ui/tabs';
33
import CollectionItem from '@ts/ui/collection/item';
44

5-
const TABS_ITEM_BADGE_CLASS = 'dx-tabs-item-badge';
5+
export const TABS_ITEM_BADGE_CLASS = 'dx-tabs-item-badge';
66
const BADGE_CLASS = 'dx-badge';
77

88
class TabsItem extends CollectionItem<Item> {

packages/devextreme/js/__internal/ui/tabs/tabs.ts

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { DefaultOptionsRule, Position } from '@js/common';
22
import eventsEngine from '@js/common/core/events/core/events_engine';
33
import holdEvent from '@js/common/core/events/hold';
44
import pointerEvents from '@js/common/core/events/pointer';
5-
import { addNamespace } from '@js/common/core/events/utils/index';
5+
import { addNamespace } from '@js/common/core/events/utils';
66
import registerComponent from '@js/core/component_registrator';
77
import devices from '@js/core/devices';
88
import type { dxElementWrapper } from '@js/core/renderer';
@@ -35,49 +35,49 @@ import TabsItem from './item';
3535

3636
// STYLE tabs
3737

38-
const TABS_CLASS = 'dx-tabs';
39-
const TABS_WRAPPER_CLASS = 'dx-tabs-wrapper';
40-
const TABS_STRETCHED_CLASS = 'dx-tabs-stretched';
41-
const TABS_SCROLLABLE_CLASS = 'dx-tabs-scrollable';
42-
const TABS_NAV_BUTTONS_CLASS = 'dx-tabs-nav-buttons';
38+
export const TABS_CLASS = 'dx-tabs';
39+
export const TABS_WRAPPER_CLASS = 'dx-tabs-wrapper';
40+
export const TABS_STRETCHED_CLASS = 'dx-tabs-stretched';
41+
export const TABS_SCROLLABLE_CLASS = 'dx-tabs-scrollable';
42+
export const TABS_NAV_BUTTONS_CLASS = 'dx-tabs-nav-buttons';
4343
const OVERFLOW_HIDDEN_CLASS = 'dx-overflow-hidden';
4444

45-
const TABS_ITEM_CLASS = 'dx-tab';
46-
const TABS_ITEM_SELECTED_CLASS = 'dx-tab-selected';
47-
const TABS_SCROLLING_ENABLED_CLASS = 'dx-tabs-scrolling-enabled';
45+
export const TABS_ITEM_CLASS = 'dx-tab';
46+
export const TABS_ITEM_SELECTED_CLASS = 'dx-tab-selected';
47+
export const TABS_SCROLLING_ENABLED_CLASS = 'dx-tabs-scrolling-enabled';
4848

49-
const TABS_NAV_BUTTON_CLASS = 'dx-tabs-nav-button';
50-
const TABS_LEFT_NAV_BUTTON_CLASS = 'dx-tabs-nav-button-left';
51-
const TABS_RIGHT_NAV_BUTTON_CLASS = 'dx-tabs-nav-button-right';
49+
export const TABS_NAV_BUTTON_CLASS = 'dx-tabs-nav-button';
50+
export const TABS_LEFT_NAV_BUTTON_CLASS = 'dx-tabs-nav-button-left';
51+
export const TABS_RIGHT_NAV_BUTTON_CLASS = 'dx-tabs-nav-button-right';
5252

53-
const TABS_ITEM_TEXT_CLASS = 'dx-tab-text';
54-
const TABS_ITEM_TEXT_SPAN_CLASS = 'dx-tab-text-span';
55-
const TABS_ITEM_TEXT_SPAN_PSEUDO_CLASS = 'dx-tab-text-span-pseudo';
53+
export const TABS_ITEM_TEXT_CLASS = 'dx-tab-text';
54+
export const TABS_ITEM_TEXT_SPAN_CLASS = 'dx-tab-text-span';
55+
export const TABS_ITEM_TEXT_SPAN_PSEUDO_CLASS = 'dx-tab-text-span-pseudo';
5656

5757
const STATE_DISABLED_CLASS = 'dx-state-disabled';
58-
const FOCUSED_DISABLED_NEXT_TAB_CLASS = 'dx-focused-disabled-next-tab';
59-
const FOCUSED_DISABLED_PREV_TAB_CLASS = 'dx-focused-disabled-prev-tab';
58+
export const FOCUSED_DISABLED_NEXT_TAB_CLASS = 'dx-focused-disabled-next-tab';
59+
export const FOCUSED_DISABLED_PREV_TAB_CLASS = 'dx-focused-disabled-prev-tab';
6060

61-
const TABS_ORIENTATION_CLASS = {
61+
export const TABS_ORIENTATION_CLASS = {
6262
vertical: 'dx-tabs-vertical',
6363
horizontal: 'dx-tabs-horizontal',
6464
};
6565

66-
const INDICATOR_POSITION_CLASS: Record<Position, string> = {
66+
export const TABS_INDICATOR_POSITION_CLASS: Record<Position, string> = {
6767
top: 'dx-tab-indicator-position-top',
6868
right: 'dx-tab-indicator-position-right',
6969
bottom: 'dx-tab-indicator-position-bottom',
7070
left: 'dx-tab-indicator-position-left',
7171
};
7272

73-
const TABS_ICON_POSITION_CLASS: Record<TabsIconPosition, string> = {
73+
export const TABS_ICON_POSITION_CLASS: Record<TabsIconPosition, string> = {
7474
top: 'dx-tabs-icon-position-top',
7575
end: 'dx-tabs-icon-position-end',
7676
bottom: 'dx-tabs-icon-position-bottom',
7777
start: 'dx-tabs-icon-position-start',
7878
};
7979

80-
const TABS_STYLING_MODE_CLASS: Record<TabsStyle, string> = {
80+
export const TABS_STYLING_MODE_CLASS: Record<TabsStyle, string> = {
8181
primary: 'dx-tabs-styling-mode-primary',
8282
secondary: 'dx-tabs-styling-mode-secondary',
8383
};
@@ -271,7 +271,7 @@ class Tabs extends CollectionWidget<TabsProperties> {
271271
super._initTemplates();
272272

273273
this._templateManager.addDefaultTemplates({
274-
item: new BindableTemplate(($container, data) => {
274+
item: new BindableTemplate(($container: dxElementWrapper, data: Item) => {
275275
this._prepareDefaultItemTemplate(data, $container);
276276

277277
const $iconElement = getImageContainer(data.icon);
@@ -357,11 +357,10 @@ class Tabs extends CollectionWidget<TabsProperties> {
357357

358358
_isItemsSizeExceeded(): boolean {
359359
const isVertical = this._isVertical();
360-
const isItemsSizeExceeded = isVertical
360+
361+
return isVertical
361362
? this._isItemsHeightExceeded()
362363
: this._isItemsWidthExceeded();
363-
364-
return isItemsSizeExceeded;
365364
}
366365

367366
_isItemsWidthExceeded(): boolean {
@@ -373,18 +372,15 @@ class Tabs extends CollectionWidget<TabsProperties> {
373372
return false;
374373
}
375374

376-
const isItemsWidthExceeded = tabItemTotalWidth > elementWidth - 1;
377-
378-
return isItemsWidthExceeded;
375+
return tabItemTotalWidth > elementWidth - 1;
379376
}
380377

381378
_isItemsHeightExceeded(): boolean {
382379
const $visibleItems = this._getVisibleItems();
383380
const itemsHeight = this._getSummaryItemsSize('height', $visibleItems, true);
384381
const elementHeight = getHeight(this.$element());
385-
const isItemsHeightExceeded = itemsHeight - 1 > elementHeight;
386382

387-
return isItemsHeightExceeded;
383+
return itemsHeight - 1 > elementHeight;
388384
}
389385

390386
_needStretchItems(): boolean {
@@ -399,9 +395,8 @@ class Tabs extends CollectionWidget<TabsProperties> {
399395

400396
const maxTabItemWidth = Math.max.apply(null, itemsWidth);
401397
const requireWidth = elementWidth / $visibleItems.length;
402-
const needStretchItems = maxTabItemWidth > requireWidth + 1;
403398

404-
return needStretchItems;
399+
return maxTabItemWidth > requireWidth + 1;
405400
}
406401

407402
_cleanNavButtons(): void {
@@ -478,11 +473,10 @@ class Tabs extends CollectionWidget<TabsProperties> {
478473

479474
_getScrollableDirection(): Orientation {
480475
const isVertical = this._isVertical();
481-
const scrollableDirection = isVertical
476+
477+
return isVertical
482478
? SCROLLABLE_DIRECTION.vertical
483479
: SCROLLABLE_DIRECTION.horizontal;
484-
485-
return scrollableDirection;
486480
}
487481

488482
_updateScrollable(): void {
@@ -676,7 +670,7 @@ class Tabs extends CollectionWidget<TabsProperties> {
676670
}
677671

678672
_getIndicatorPositionClass(indicatorPosition: Position): string {
679-
return INDICATOR_POSITION_CLASS[indicatorPosition];
673+
return TABS_INDICATOR_POSITION_CLASS[indicatorPosition];
680674
}
681675

682676
_getIndicatorPosition(): Position {
@@ -698,7 +692,7 @@ class Tabs extends CollectionWidget<TabsProperties> {
698692
_toggleIndicatorPositionClass(indicatorPosition: Position): void {
699693
const newClass = this._getIndicatorPositionClass(indicatorPosition);
700694

701-
this._toggleElementClasses(INDICATOR_POSITION_CLASS, newClass);
695+
this._toggleElementClasses(TABS_INDICATOR_POSITION_CLASS, newClass);
702696
}
703697

704698
_toggleScrollingEnabledClass(scrollingEnabled: boolean | undefined): void {

packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.API.option_tabs.tests.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import $ from 'jquery';
22
import 'ui/form';
3+
import { TABS_ITEM_CLASS } from '__internal/ui/tabs/tabs';
4+
import { TABS_ITEM_BADGE_CLASS } from '__internal/ui/tabs/item';
5+
import { TABPANEL_CLASS } from '__internal/ui/tab_panel/tab_panel';
36

47
import 'generic_light.css!';
58

@@ -29,8 +32,8 @@ class FormTestWrapper {
2932
this._form.on('contentReady', this._contentReadyStub);
3033
}
3134

32-
_getTabsTextsElements() {
33-
return this._form.$element().find('.dx-tab-content .dx-tab-text');
35+
_getTabsElements() {
36+
return this._form.$element().find(`.${TABS_ITEM_CLASS}`);
3437
}
3538

3639
_getMultiViewItemsElements() {
@@ -46,7 +49,7 @@ class FormTestWrapper {
4649
}
4750

4851
selectTab(tabIndex) {
49-
$('.dx-tabpanel').dxTabPanel('instance').option('selectedIndex', tabIndex);
52+
$(`.${TABPANEL_CLASS}`).dxTabPanel('instance').option('selectedIndex', tabIndex);
5053
}
5154

5255
checkFormsReRender() {
@@ -55,16 +58,16 @@ class FormTestWrapper {
5558
}
5659

5760
checkTabBadge(tabIndex, expectedText) {
58-
assert.equal($('.dx-tabs-item-badge').eq(tabIndex).text(), expectedText, `${tabIndex} tab badge`);
61+
assert.equal($(`.${TABS_ITEM_BADGE_CLASS}`).eq(tabIndex).text(), expectedText, `${tabIndex} tab badge`);
5962
}
6063

6164
checkTabDisabled(tabIndex, expectedValue) {
62-
const $tabItems = $('.dx-tab');
65+
const $tabItems = $(`.${TABS_ITEM_CLASS}`);
6366
assert.equal($tabItems.eq(tabIndex).hasClass('dx-state-disabled'), expectedValue, `${tabIndex} tab disabled`);
6467
}
6568

6669
checkTabIcon(tabIndex, expectedIcon) {
67-
const $icon = $('.dx-tab .dx-icon').eq(tabIndex);
70+
const $icon = $(`.${TABS_ITEM_CLASS} .dx-icon`).eq(tabIndex);
6871
assert.ok($icon.hasClass(`dx-icon-${expectedIcon}`), `${tabIndex} tab icon`);
6972
}
7073

@@ -79,12 +82,12 @@ class FormTestWrapper {
7982
}
8083

8184
checkTabTitle(tabIndex, expectedText) {
82-
const $title = this._getTabsTextsElements().eq(tabIndex);
85+
const $title = this._getTabsElements().eq(tabIndex);
8386
assert.strictEqual($title.text(), `${expectedText}${expectedText}`, `${tabIndex} tab title`);
8487
}
8588

8689
checkTabsElements(expectedTabsCount) {
87-
const $tabs = this._getTabsTextsElements();
90+
const $tabs = this._getTabsElements();
8891
assert.equal($tabs.length, expectedTabsCount, 'count of tabs elements');
8992

9093
const $multiViewItems = this._getMultiViewItemsElements();

0 commit comments

Comments
 (0)