Commit d96ee053 authored by John Lee's avatar John Lee Committed by Commit Bot

WebUI Tab Strip: Reorganize spacing for tabs

This CL sets overflow of the tabs container to hidden so that when the
last tab animates out and its max-width goes to 0, the container's
width also shrinks.

Moving the gap internally to TabElement makes more sense in terms of
consistency since it's also included internally in the animation of
slideIn and slideOut. Also, previously, having 16px margin on all tabs
except the last tab caused the 16px to snap into place when the last
tab slides out and a new tab becomes the last-child.

Change-Id: Ia0bec1c6c86ab0aa2bfd769fc488429419ff9613
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1924619
Commit-Queue: John Lee <johntlee@chromium.org>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#718310}
parent 84056e94
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
--tabstrip-tab-transition-duration: 250ms; --tabstrip-tab-transition-duration: 250ms;
height: var(--tabstrip-tab-height); height: var(--tabstrip-tab-height);
padding-inline-end: var(--tabstrip-tab-spacing);
position: relative; position: relative;
transform-origin: top left; transform-origin: top left;
width: var(--tabstrip-tab-width); width: var(--tabstrip-tab-width);
......
...@@ -37,11 +37,11 @@ function getAccessibleTitle(tab) { ...@@ -37,11 +37,11 @@ function getAccessibleTitle(tab) {
} }
/** /**
* TODO(crbug.com/1025390): margin-inline-end cannot be animated yet. * TODO(crbug.com/1025390): padding-inline-end cannot be animated yet.
* @return {string} * @return {string}
*/ */
function getMarginInlineEndProperty() { function getPaddingInlineEndProperty() {
return isRTL() ? 'marginLeft' : 'marginRight'; return isRTL() ? 'paddingLeft' : 'paddingRight';
} }
export class TabElement extends CustomElement { export class TabElement extends CustomElement {
...@@ -254,19 +254,19 @@ export class TabElement extends CustomElement { ...@@ -254,19 +254,19 @@ export class TabElement extends CustomElement {
* @return {!Promise} * @return {!Promise}
*/ */
slideIn() { slideIn() {
const marginInlineEnd = getMarginInlineEndProperty(); const paddingInlineEnd = getPaddingInlineEndProperty();
const startState = { const startState = {
maxWidth: 0, maxWidth: 0,
transform: `scale(0)`, transform: `scale(0)`,
}; };
startState[marginInlineEnd] = 0; startState[paddingInlineEnd] = 0;
const finishState = { const finishState = {
maxWidth: `var(--tabstrip-tab-width)`, maxWidth: `var(--tabstrip-tab-width)`,
transform: `scale(1)`, transform: `scale(1)`,
}; };
finishState[marginInlineEnd] = 'var(--tabstrip-tab-margin-inline-end)'; finishState[paddingInlineEnd] = 'var(--tabstrip-tab-spacing)';
return new Promise(resolve => { return new Promise(resolve => {
const animation = this.animate([startState, finishState], { const animation = this.animate([startState, finishState], {
...@@ -317,8 +317,8 @@ export class TabElement extends CustomElement { ...@@ -317,8 +317,8 @@ export class TabElement extends CustomElement {
const widthAnimationKeyframes = { const widthAnimationKeyframes = {
maxWidth: ['var(--tabstrip-tab-width)', 0], maxWidth: ['var(--tabstrip-tab-width)', 0],
}; };
widthAnimationKeyframes[getMarginInlineEndProperty()] = widthAnimationKeyframes[getPaddingInlineEndProperty()] =
['var(--tabstrip-tab-margin-inline-end)', 0]; ['var(--tabstrip-tab-spacing)', 0];
const widthAnimation = this.animate(widthAnimationKeyframes, { const widthAnimation = this.animate(widthAnimationKeyframes, {
delay: 97.5, delay: 97.5,
duration: 300, duration: 300,
......
...@@ -3,13 +3,12 @@ ...@@ -3,13 +3,12 @@
--tabstrip-tab-height: calc(var(--tabstrip-tab-title-height) + --tabstrip-tab-height: calc(var(--tabstrip-tab-title-height) +
var(--tabstrip-tab-thumbnail-height)); var(--tabstrip-tab-thumbnail-height));
--tabstrip-tab-width: var(--tabstrip-tab-thumbnail-width); --tabstrip-tab-width: var(--tabstrip-tab-thumbnail-width);
--tabstrip-tab-margin-inline-end: 16px; --tabstrip-tab-spacing: 16px;
background: var(--tabstrip-background-color); background: var(--tabstrip-background-color);
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
min-width: fit-content; min-width: fit-content;
padding: 16px;
width: 100%; width: 100%;
} }
...@@ -24,7 +23,8 @@ ...@@ -24,7 +23,8 @@
grid-auto-flow: column; grid-auto-flow: column;
grid-gap: 10px; grid-gap: 10px;
grid-template-rows: repeat(4, var(--tabstrip-pinned-tab-size)); grid-template-rows: repeat(4, var(--tabstrip-pinned-tab-size));
margin-inline-end: var(--tabstrip-tab-margin-inline-end); padding: var(--tabstrip-tab-spacing);
padding-inline-end: 0;
} }
#pinnedTabsContainer:empty { #pinnedTabsContainer:empty {
...@@ -33,14 +33,9 @@ ...@@ -33,14 +33,9 @@
#tabsContainer { #tabsContainer {
display: flex; display: flex;
} overflow: hidden;
padding: var(--tabstrip-tab-spacing);
#tabsContainer tabstrip-tab { padding-inline-end: 0;
margin-inline-end: var(--tabstrip-tab-margin-inline-end);
}
#tabsContainer tabstrip-tab:last-child {
--tabstrip-tab-margin-inline-end: 0;
} }
#demoOptions { #demoOptions {
......
...@@ -53,34 +53,34 @@ suite('Tab', function() { ...@@ -53,34 +53,34 @@ suite('Tab', function() {
test('slideIn animates in the element', async () => { test('slideIn animates in the element', async () => {
document.documentElement.dir = 'ltr'; document.documentElement.dir = 'ltr';
tabElement.style.marginRight = '100px'; tabElement.style.paddingRight = '100px';
const tabElementStyle = window.getComputedStyle(tabElement); const tabElementStyle = window.getComputedStyle(tabElement);
const animationPromise = tabElement.slideIn(); const animationPromise = tabElement.slideIn();
// Before animation completes. // Before animation completes.
assertEquals('0px', tabElementStyle.marginRight); assertEquals('0px', tabElementStyle.paddingRight);
assertEquals('0px', tabElementStyle.maxWidth); assertEquals('0px', tabElementStyle.maxWidth);
assertEquals('matrix(0, 0, 0, 0, 0, 0)', tabElementStyle.transform); assertEquals('matrix(0, 0, 0, 0, 0, 0)', tabElementStyle.transform);
await animationPromise; await animationPromise;
// After animation completes. // After animation completes.
assertEquals('100px', tabElementStyle.marginRight); assertEquals('100px', tabElementStyle.paddingRight);
assertEquals('none', tabElementStyle.maxWidth); assertEquals('none', tabElementStyle.maxWidth);
assertEquals('matrix(1, 0, 0, 1, 0, 0)', tabElementStyle.transform); assertEquals('matrix(1, 0, 0, 1, 0, 0)', tabElementStyle.transform);
}); });
test('slideIn animations right to left for RTL languages', async () => { test('slideIn animations right to left for RTL languages', async () => {
document.documentElement.dir = 'rtl'; document.documentElement.dir = 'rtl';
tabElement.style.marginLeft = '100px'; tabElement.style.paddingLeft = '100px';
const tabElementStyle = window.getComputedStyle(tabElement); const tabElementStyle = window.getComputedStyle(tabElement);
const animationPromise = tabElement.slideIn(); const animationPromise = tabElement.slideIn();
// Before animation completes. // Before animation completes.
assertEquals('0px', tabElementStyle.marginLeft); assertEquals('0px', tabElementStyle.paddingLeft);
assertEquals('0px', tabElementStyle.maxWidth); assertEquals('0px', tabElementStyle.maxWidth);
assertEquals('matrix(0, 0, 0, 0, 0, 0)', tabElementStyle.transform); assertEquals('matrix(0, 0, 0, 0, 0, 0)', tabElementStyle.transform);
await animationPromise; await animationPromise;
// After animation completes. // After animation completes.
assertEquals('100px', tabElementStyle.marginLeft); assertEquals('100px', tabElementStyle.paddingLeft);
assertEquals('none', tabElementStyle.maxWidth); assertEquals('none', tabElementStyle.maxWidth);
assertEquals('matrix(1, 0, 0, 1, 0, 0)', tabElementStyle.transform); assertEquals('matrix(1, 0, 0, 1, 0, 0)', tabElementStyle.transform);
}); });
......
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