commit 31c24821e92c07cea737caa27a5b824471cc1480
parent a2f8e4956a53ad331ea1d4a91170861ec134bc51
Author: Irene Ni <ini@mozilla.com>
Date: Fri, 7 Nov 2025 19:56:18 +0000
Bug 1994428 - Make New Tab Customize button hover animation smoother. r=home-newtab-reviewers,reemhamz
Differential Revision: https://phabricator.services.mozilla.com/D270915
Diffstat:
4 files changed, 25 insertions(+), 46 deletions(-)
diff --git a/browser/extensions/newtab/content-src/components/CustomizeMenu/CustomizeMenu.jsx b/browser/extensions/newtab/content-src/components/CustomizeMenu/CustomizeMenu.jsx
@@ -52,13 +52,13 @@ export class _CustomizeMenu extends React.PureComponent {
}}
ref={c => (this.openButton = c)}
>
+ <label data-l10n-id="newtab-customize-panel-icon-button-label" />
<div>
<img
role="presentation"
src="chrome://global/skin/icons/edit-outline.svg"
/>
</div>
- <label data-l10n-id="newtab-customize-panel-icon-button-label" />
</button>
</CSSTransition>
<CSSTransition
diff --git a/browser/extensions/newtab/content-src/components/CustomizeMenu/_CustomizeMenu.scss b/browser/extensions/newtab/content-src/components/CustomizeMenu/_CustomizeMenu.scss
@@ -9,12 +9,6 @@
}
.personalize-button {
- // Throw these values for the button animation into variables
- // so they're not recalculated all the time
- --button-collapsed-width: calc(var(--size-item-small) + var(--size-item-medium));
- --button-full-width: calc(2 * var(--button-collapsed-width));
- --label-shift-by-value: calc(-1 * var(--space-small));
-
border: 0;
border-radius: var(--border-radius-small);
background-color: var(--button-background-color, rgba(21, 20, 26, 7%));
@@ -26,9 +20,7 @@
display: flex;
align-items: center;
overflow: hidden;
- width: var(--button-collapsed-width);
- min-width: var(--button-collapsed-width);
- transition: all 0.5s ease-in-out;
+ transition: background-color 0.3s ease;
.lightWallpaper &,
.darkWallpaper & {
@@ -78,29 +70,26 @@
}
> label {
- margin-inline-start: 0;
+ margin-inline-end: 0;
opacity: 0;
- transform: translateX(var(--label-shift-by-value));
white-space: nowrap;
+ overflow: hidden;
+ max-width: 0;
transition:
- opacity 0.5s ease-in-out,
- margin 0.5s ease-in-out,
- transform 0.5s ease-in-out;
+ opacity 0.3s ease,
+ margin 0.3s ease,
+ max-width 0.3s ease;
}
}
.personalize-button:hover,
-.personalize-button:focus {
- width: fit-content;
- // Animate the appearance of the button label on the min-width,
- // as we need to cater for localised strings
- min-width: var(--button-full-width);
-
+.personalize-button:focus-visible {
> label {
opacity: 1;
- transform: translateX(0);
- margin-inline-start: var(--space-small);
- transition-duration: 0.2s;
+ margin-inline-end: var(--space-medium);
+ // CSS animations can only transition between fixed values;
+ // 30ch is enough to accommodate longest localized string (Bulgarian: 15ch)
+ max-width: 30ch;
}
}
diff --git a/browser/extensions/newtab/css/activity-stream.css b/browser/extensions/newtab/css/activity-stream.css
@@ -1995,9 +1995,6 @@ main section {
}
.personalize-button {
- --button-collapsed-width: calc(var(--size-item-small) + var(--size-item-medium));
- --button-full-width: calc(2 * var(--button-collapsed-width));
- --label-shift-by-value: calc(-1 * var(--space-small));
border: 0;
border-radius: var(--border-radius-small);
background-color: var(--button-background-color, rgba(21, 20, 26, 0.07));
@@ -2009,9 +2006,7 @@ main section {
display: flex;
align-items: center;
overflow: hidden;
- width: var(--button-collapsed-width);
- min-width: var(--button-collapsed-width);
- transition: all 0.5s ease-in-out;
+ transition: background-color 0.3s ease;
}
.lightWallpaper .personalize-button, .darkWallpaper .personalize-button {
background-color: var(--newtab-weather-background-color);
@@ -2054,24 +2049,19 @@ main section {
width: 100%;
}
.personalize-button > label {
- margin-inline-start: 0;
+ margin-inline-end: 0;
opacity: 0;
- transform: translateX(var(--label-shift-by-value));
white-space: nowrap;
- transition: opacity 0.5s ease-in-out, margin 0.5s ease-in-out, transform 0.5s ease-in-out;
+ overflow: hidden;
+ max-width: 0;
+ transition: opacity 0.3s ease, margin 0.3s ease, max-width 0.3s ease;
}
-.personalize-button:hover,
-.personalize-button:focus {
- width: fit-content;
- min-width: var(--button-full-width);
-}
.personalize-button:hover > label,
-.personalize-button:focus > label {
+.personalize-button:focus-visible > label {
opacity: 1;
- transform: translateX(0);
- margin-inline-start: var(--space-small);
- transition-duration: 0.2s;
+ margin-inline-end: var(--space-medium);
+ max-width: 30ch;
}
.customize-menu {
diff --git a/browser/extensions/newtab/data/content/activity-stream.bundle.js b/browser/extensions/newtab/data/content/activity-stream.bundle.js
@@ -15104,12 +15104,12 @@ class _CustomizeMenu extends (external_React_default()).PureComponent {
}
},
ref: c => this.openButton = c
- }, /*#__PURE__*/external_React_default().createElement("div", null, /*#__PURE__*/external_React_default().createElement("img", {
+ }, /*#__PURE__*/external_React_default().createElement("label", {
+ "data-l10n-id": "newtab-customize-panel-icon-button-label"
+ }), /*#__PURE__*/external_React_default().createElement("div", null, /*#__PURE__*/external_React_default().createElement("img", {
role: "presentation",
src: "chrome://global/skin/icons/edit-outline.svg"
- })), /*#__PURE__*/external_React_default().createElement("label", {
- "data-l10n-id": "newtab-customize-panel-icon-button-label"
- }))), /*#__PURE__*/external_React_default().createElement(external_ReactTransitionGroup_namespaceObject.CSSTransition, {
+ })))), /*#__PURE__*/external_React_default().createElement(external_ReactTransitionGroup_namespaceObject.CSSTransition, {
timeout: 250,
classNames: "customize-animate",
in: this.props.showing,