Skip to content

Commit ec2c935

Browse files
authored
fix: consider decimal values of scrollLeft and scrollTop (#5732) (#5743)
1 parent aabe6a4 commit ec2c935

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

packages/tabs/src/vaadin-tabs.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,17 @@ class Tabs extends ResizeMixin(ElementMixin(ListMixin(ThemableMixin(PolymerEleme
249249
: this.__getNormalizedScrollLeft(this._scrollerElement);
250250
const scrollSize = this._vertical ? this._scrollerElement.scrollHeight : this._scrollerElement.scrollWidth;
251251

252-
let overflow = scrollPosition > 0 ? 'start' : '';
253-
overflow += scrollPosition + this._scrollOffset < scrollSize ? ' end' : '';
252+
// Note that we are not comparing floored scrollPosition to be greater than zero here, which would make a natural
253+
// sense, but to be greater than one intentionally. There is a known bug in Chromium browsers on Linux/Mac
254+
// (https://bugs.chromium.org/p/chromium/issues/detail?id=1123301), which returns invalid value of scrollLeft when
255+
// text direction is RTL. The value is off by one pixel in that case. Comparing scrollPosition to be greater than
256+
// one on the following line is a workaround for that bug. Comparing scrollPosition to be greater than one means,
257+
// that the left overflow and left arrow will be displayed "one pixel" later than normal. In other words, if the tab
258+
// scroller element is scrolled just by 1px, the overflow is not yet showing.
259+
let overflow = Math.floor(scrollPosition) > 1 ? 'start' : '';
260+
if (Math.ceil(scrollPosition) < Math.ceil(scrollSize - this._scrollOffset)) {
261+
overflow += ' end';
262+
}
254263

255264
if (this.__direction === 1) {
256265
overflow = overflow.replace(/start|end/gi, (matched) => {

packages/tabs/test/tabs.test.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ describe('tabs', () => {
3131
<vaadin-tabs>
3232
<vaadin-tab>Foo</vaadin-tab>
3333
<vaadin-tab>Bar</vaadin-tab>
34+
<vaadin-tab>Some</vaadin-tab>
3435
<span></span>
3536
<vaadin-tab disabled>Baz</vaadin-tab>
3637
<vaadin-tab>
@@ -59,7 +60,7 @@ describe('tabs', () => {
5960

6061
describe('items', () => {
6162
it('should only add vaadin-tab components to items', () => {
62-
expect(tabs.items.length).to.equal(4);
63+
expect(tabs.items.length).to.equal(5);
6364
tabs.items.forEach((item) => {
6465
expect(item.tagName.toLowerCase()).to.equal('vaadin-tab');
6566
});
@@ -114,6 +115,10 @@ describe('tabs', () => {
114115
await nextFrame();
115116
});
116117

118+
afterEach(() => {
119+
document.body.style.zoom = '';
120+
});
121+
117122
it(`when orientation=${orientation} should have overflow="end" if scroll is at the beginning`, () => {
118123
expect(tabs.getAttribute('overflow')).to.be.equal('end');
119124
});
@@ -127,18 +132,24 @@ describe('tabs', () => {
127132
tabs._scroll(horizontalRtl ? -2 : 2);
128133
});
129134

130-
// TODO: passes locally but fails in GitHub Actions due to 1px difference.
131-
const chrome = /HeadlessChrome/.test(navigator.userAgent);
132-
(horizontalRtl && chrome ? it.skip : it)(
133-
`when orientation=${orientation} should have overflow="start" if scroll is at the end`,
134-
(done) => {
135+
it(`when orientation=${orientation} should have overflow="start" if scroll is at the end`, (done) => {
136+
listenOnce(tabs._scrollerElement, 'scroll', () => {
137+
expect(tabs.getAttribute('overflow')).to.be.equal('start');
138+
done();
139+
});
140+
tabs._scroll(horizontalRtl ? -200 : 200);
141+
});
142+
143+
[1.25, 1.33, 1.5, 1.75].forEach((zoomLevel) => {
144+
it(`when orientation=${orientation} should have overflow="start" if scroll is at the end on page zoomed to ${zoomLevel}`, (done) => {
145+
document.body.style.zoom = zoomLevel;
135146
listenOnce(tabs._scrollerElement, 'scroll', () => {
136147
expect(tabs.getAttribute('overflow')).to.be.equal('start');
137148
done();
138149
});
139150
tabs._scroll(horizontalRtl ? -200 : 200);
140-
},
141-
);
151+
});
152+
});
142153

143154
it(`when orientation=${orientation} should not have overflow="start" when over-scrolling`, () => {
144155
const scroll = tabs._scrollerElement;

0 commit comments

Comments
 (0)