Commit 17d884c6 authored by John Lee's avatar John Lee Committed by Commit Bot

WebUI Tab Strip: Keep new tab button fixed at the end of tab strip

This CL updates the New Tab button to have fixed positioning. This
CL also updates the scroll animation so that it takes the edge of
the New Tab button as the right-most boundary, instead of the
edge of the viewport.

Bug: 1032650
Change-Id: If656545b5d4b4a50197a5f0d94baeb26b6f7df09
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1977841Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Commit-Queue: John Lee <johntlee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726986}
parent 1e828d08
......@@ -18,6 +18,9 @@
display: flex;
min-width: fit-content;
overflow: hidden;
padding-inline-end: calc(
var(--tabstrip-new-tab-button-width) +
var(--tabstrip-new-tab-button-margin));
}
#pinnedTabs {
......@@ -47,8 +50,7 @@
}
#newTabButton {
--new-tab-button-margin: 24px;
--cr-icon-button-size: 50px;
--cr-icon-button-size: var(--tabstrip-new-tab-button-width);
--cr-icon-button-icon-size: 32px;
--cr-icon-button-fill-color: var(--tabstrip-tab-text-color);
--cr-icon-button-margin-end: var(--new-tab-button-margin);
......@@ -57,19 +59,17 @@
border-radius: 50%;
box-shadow: 0 1px 3px 0 rgba(var(--google-grey-800-rgb), .3),
0 4px 8px 3px rgba(var(--google-grey-800-rgb), .15);
height: 50px;
position: sticky;
right: var(--new-tab-button-margin);
height: var(--tabstrip-new-tab-button-width);
margin: 0;
position: fixed;
right: var(--tabstrip-new-tab-button-margin);
top: 50%;
transform: translateY(-50%);
width: 50px;
width: var(--tabstrip-new-tab-button-width);
}
:host-context([dir='rtl']) #newTabButton {
/* TODO(crbug.com/1015605): Sticky positioning does not work with RTL. */
--cr-icon-button-margin-end: 0;
left: var(--new-tab-button-margin);
position: fixed;
left: var(--tabstrip-new-tab-button-margin);
right: auto;
}
......
......@@ -40,6 +40,8 @@ export function setScrollAnimationEnabledForTesting(enabled) {
*/
const LayoutVariable = {
VIEWPORT_WIDTH: '--tabstrip-viewport-width',
NEW_TAB_BUTTON_MARGIN: '--tabstrip-new-tab-button-margin',
NEW_TAB_BUTTON_WIDTH: '--tabstrip-new-tab-button-width',
TAB_WIDTH: '--tabstrip-tab-thumbnail-width',
};
......@@ -595,21 +597,30 @@ class TabListElement extends CustomElement {
const tabElementLeft =
isRTL() ? tabElementRect.right - tabElementWidth : tabElementRect.left;
const newTabButtonSpace =
this.getLayoutVariable_(LayoutVariable.NEW_TAB_BUTTON_WIDTH) +
this.getLayoutVariable_(LayoutVariable.NEW_TAB_BUTTON_MARGIN);
const leftBoundary =
isRTL() ? SCROLL_PADDING + newTabButtonSpace : SCROLL_PADDING;
let scrollBy = 0;
if (tabElementLeft === SCROLL_PADDING) {
if (tabElementLeft === leftBoundary) {
// Perfectly aligned to the left.
return;
} else if (tabElementLeft < SCROLL_PADDING) {
// If the element's left is to the left of the visible screen, scroll
// such that the element's left edge is aligned with the screen's edge.
scrollBy = tabElementLeft - SCROLL_PADDING;
} else if (tabElementLeft < leftBoundary) {
// If the element's left is to the left of the left boundary, scroll
// such that the element's left edge is aligned with the left boundary.
scrollBy = tabElementLeft - leftBoundary;
} else {
const tabElementRight = tabElementLeft + tabElementWidth;
const viewportWidth =
this.getLayoutVariable_(LayoutVariable.VIEWPORT_WIDTH);
if (tabElementRight + SCROLL_PADDING > viewportWidth) {
scrollBy = (tabElementRight + SCROLL_PADDING) - viewportWidth;
const rightBoundary = isRTL() ?
this.getLayoutVariable_(LayoutVariable.VIEWPORT_WIDTH) -
SCROLL_PADDING :
this.getLayoutVariable_(LayoutVariable.VIEWPORT_WIDTH) -
SCROLL_PADDING - newTabButtonSpace;
if (tabElementRight > rightBoundary) {
scrollBy = (tabElementRight) - rightBoundary;
} else {
// Perfectly aligned to the right.
return;
......
......@@ -32,7 +32,17 @@
</style>
</head>
<body>
<tabstrip-tab-list role="tablist"></tabstrip-tab-list>
<!--
The CSS variables defined inside of TabList's style tag are also
made available through TabList's class object in JavaScript.
-->
<tabstrip-tab-list
role="tablist"
style="
--tabstrip-new-tab-button-margin: 24px;
--tabstrip-new-tab-button-width: 50px;
">
</tabstrip-tab-list>
<script src="tab_list.js" type="module"></script>
</body>
</html>
......@@ -485,11 +485,17 @@ suite('TabList', () => {
test('scrolls to active tabs', async () => {
await tabList.animationPromises;
const newTabButtonMargin = 15;
const newTabButtonWidth = 50;
const scrollPadding = 32;
const tabWidth = 200;
const viewportWidth = 300;
// Mock the width of each tab element.
tabList.style.setProperty(
'--tabstrip-new-tab-button-margin', `${newTabButtonMargin}px`);
tabList.style.setProperty(
'--tabstrip-new-tab-button-width', `${newTabButtonWidth}px`);
tabList.style.setProperty(
'--tabstrip-tab-thumbnail-width', `${tabWidth}px`);
tabList.style.setProperty('--tabstrip-tab-spacing', '0px');
......@@ -516,7 +522,8 @@ suite('TabList', () => {
let activeTab = getUnpinnedTabs()[1];
assertEquals(
tabList.scrollLeft + tabList.offsetWidth,
activeTab.offsetLeft + activeTab.offsetWidth + scrollPadding);
activeTab.offsetLeft + activeTab.offsetWidth + scrollPadding +
newTabButtonMargin + newTabButtonWidth);
// The 1st tab should be now off-screen to the left, so activating it should
// scroll so that the element's left edge is aligned with the screen's
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment