Skip to content

Commit aef37ed

Browse files
authored
Tabs: add resize observer to reload scrollable on internal item size changes (#30168)
1 parent 0027116 commit aef37ed

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import registerComponent from '@js/core/component_registrator';
77
import devices from '@js/core/devices';
88
import type { dxElementWrapper } from '@js/core/renderer';
99
import $ from '@js/core/renderer';
10+
import resizeObserverSingleton from '@js/core/resize_observer';
1011
import { BindableTemplate } from '@js/core/templates/bindable_template';
1112
import { getImageContainer } from '@js/core/utils/icon';
1213
import { each } from '@js/core/utils/iterator';
@@ -306,6 +307,8 @@ class Tabs extends CollectionWidget<TabsProperties> {
306307
}
307308

308309
this.$element().addClass(OVERFLOW_HIDDEN_CLASS);
310+
311+
this._attachResizeObserverSubscription();
309312
}
310313

311314
_postProcessRenderItems(): void {
@@ -633,6 +636,11 @@ class Tabs extends CollectionWidget<TabsProperties> {
633636
}
634637
}
635638

639+
_attachResizeObserverSubscription(): void {
640+
resizeObserverSingleton.unobserve(this.$element().get(0));
641+
resizeObserverSingleton.observe(this.$element().get(0), () => { this._dimensionChanged(); });
642+
}
643+
636644
_dimensionChanged(): void {
637645
this._renderScrolling();
638646
}
@@ -657,6 +665,7 @@ class Tabs extends CollectionWidget<TabsProperties> {
657665
}
658666

659667
_clean(): void {
668+
resizeObserverSingleton.unobserve(this.$element().get(0));
660669
this._cleanScrolling();
661670
super._clean();
662671
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import pointerMock from '../../helpers/pointerMock.js';
1111
import { TestAsyncTabsWrapper, TestTabsWrapper } from '../../helpers/wrappers/tabsWrappers.js';
1212
import { getScrollLeftMax } from '__internal/ui/scroll_view/utils/get_scroll_left_max';
1313
import keyboardMock from '../../helpers/keyboardMock.js';
14+
import devices from '__internal/core/m_devices';
15+
import { compare as compareVersions } from 'core/utils/version';
16+
import resizeObserverSingleton from 'core/resize_observer';
1417
import {
1518
TABS_ITEM_CLASS,
1619
TABS_ITEM_SELECTED_CLASS,
@@ -405,6 +408,18 @@ QUnit.module('General', () => {
405408
assert.strictEqual($element.find(`.${TABS_NAV_BUTTON_CLASS}`).length, 2, 'nav buttons was rendered');
406409
assert.strictEqual($element.find(`.${TABS_SCROLLABLE_CLASS}`).length, 1, 'scrollable was rendered');
407410
});
411+
412+
QUnit.test('resize observer should be attached to the tabs', function(assert) {
413+
const observeSpy = sinon.spy(resizeObserverSingleton, 'observe');
414+
415+
$('#tabs').dxTabs({
416+
items: [{ text: 'item 1' }],
417+
});
418+
419+
assert.strictEqual(observeSpy.callCount, 1, 'resize observer is connected');
420+
421+
observeSpy.restore();
422+
});
408423
});
409424

410425
QUnit.module('Tab select action', () => {

packages/devextreme/testing/tests/DevExpress.ui.widgets/tabs.width.tests.js

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,27 @@ QUnit.module('Width', () => {
114114
break;
115115
case 'container':
116116
this.setContainerWidth(width);
117-
this.tabs.repaint();
118117
break;
119118
case 'resizeBrowser':
120119
this.setContainerWidth(width);
121120
triggerResizeEvent(this.$container);
122121
break;
123122
}
124123
}
124+
125+
delayedCheckIfRequired(fn) {
126+
const done = this.assert.async();
127+
const resizeTimeout = 40;
128+
if(this.setWidthApproach === 'container') {
129+
setTimeout(() => {
130+
fn();
131+
done();
132+
}, resizeTimeout);
133+
} else {
134+
fn();
135+
done();
136+
}
137+
}
125138
}
126139

127140
[true, false, undefined].forEach((scrollingEnabled) => {
@@ -130,44 +143,44 @@ QUnit.module('Width', () => {
130143

131144
QUnit.test('Show fixed tabs, resize to show stretched tabs' + config, function(assert) {
132145
const helper = new TabsWidthTestHelper(assert, scrollingEnabled, setWidthApproach);
133-
helper.createFixedTabs(400);
146+
helper.createFixedTabs();
134147
helper.setWidth(200);
135-
helper.checkStretchedTabs();
148+
helper.delayedCheckIfRequired(() => helper.checkStretchedTabs());
136149
});
137150

138151
QUnit.test('Show fixed tabs, resize to show navigation buttons' + config, function(assert) {
139152
const helper = new TabsWidthTestHelper(assert, scrollingEnabled, setWidthApproach);
140-
helper.createFixedTabs(400);
153+
helper.createFixedTabs();
141154
helper.setWidth(100);
142-
helper.checkNavigationButtonsTabs();
155+
helper.delayedCheckIfRequired(() => helper.checkNavigationButtonsTabs());
143156
});
144157

145158
QUnit.test('Show stretched tabs, resize to show navigation buttons' + config, function(assert) {
146159
const helper = new TabsWidthTestHelper(assert, scrollingEnabled, setWidthApproach);
147160
helper.createStretchedTabs();
148161
helper.setWidth(100);
149-
helper.checkNavigationButtonsTabs();
162+
helper.delayedCheckIfRequired(() => helper.checkNavigationButtonsTabs());
150163
});
151164

152165
QUnit.test('Show stretched tabs, resize to show fixed tabs' + config, function(assert) {
153166
const helper = new TabsWidthTestHelper(assert, scrollingEnabled, setWidthApproach);
154167
helper.createStretchedTabs();
155168
helper.setWidth(400);
156-
helper.checkFixedTabs();
169+
helper.delayedCheckIfRequired(() => helper.checkFixedTabs());
157170
});
158171

159172
QUnit.test('Show navigation buttons, resize to show stretched tabs' + config, function(assert) {
160173
const helper = new TabsWidthTestHelper(assert, scrollingEnabled, setWidthApproach);
161174
helper.createNavigationButtonsTabs();
162175
helper.setWidth(200);
163-
helper.checkStretchedTabs();
176+
helper.delayedCheckIfRequired(() => helper.checkStretchedTabs());
164177
});
165178

166179
QUnit.test('Show navigation buttons, resize to show fixed tabs' + config, function(assert) {
167180
const helper = new TabsWidthTestHelper(assert, scrollingEnabled, setWidthApproach);
168181
helper.createFixedTabs();
169182
helper.setWidth(400);
170-
helper.checkFixedTabs();
183+
helper.delayedCheckIfRequired(() => helper.checkFixedTabs());
171184
});
172185
});
173186
});

0 commit comments

Comments
 (0)