Skip to content

Commit 9700c29

Browse files
author
Norisz Fay
committed
Revert "Bug 2047788 - Animate the widgets row height when toggling show more/less r=thecount" for causing lint failure @ Widgets.jsx
This reverts commit 18e838c.
1 parent df0da7a commit 9700c29

7 files changed

Lines changed: 4 additions & 224 deletions

File tree

browser/extensions/newtab/content-src/components/Widgets/Widgets.jsx

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
33
* You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
import React, { useContext, useEffect, useLayoutEffect, useRef } from "react";
5+
import React, { useContext, useEffect, useRef } from "react";
66
import { useDispatch, useSelector, batch } from "react-redux";
77
import { BaseContext } from "content-src/lib/BaseContext";
88
// Bug 2034542: these per-widget imports can be removed once the non-Nova render
@@ -50,9 +50,6 @@ const PREF_WIDGETS_FEEDBACK_ENABLED = "widgets.feedback.enabled";
5050
const PREF_WIDGETS_HIDE_ALL_TOAST_ENABLED = "widgets.hideAllToast.enabled";
5151
const WIDGETS_FEEDBACK_URL =
5252
"https://support.mozilla.org/kb/firefox-new-tab-widgets";
53-
// Safety net in case transitionend never fires. Keep this above the CSS
54-
// height transition duration (--widget-size-transition-duration, 180ms).
55-
const ROW_TOGGLE_HEIGHT_ANIMATION_FALLBACK_MS = 300;
5653

5754
// resets timer to default values (exported for testing)
5855
// In practice, this logic runs inside a useEffect when
@@ -296,52 +293,6 @@ function Widgets() {
296293
// track previous timerEnabled state to detect when it becomes disabled
297294
const prevTimerEnabledRef = useRef(timerEnabled);
298295

299-
const rowToggleFromHeightRef = useRef(null);
300-
301-
useLayoutEffect(() => {
302-
const fromHeight = rowToggleFromHeightRef.current;
303-
rowToggleFromHeightRef.current = null;
304-
const container = widgetsContainerRef.current;
305-
if (fromHeight === null || !container) {
306-
return undefined;
307-
}
308-
const toHeight = container.getBoundingClientRect().height;
309-
if (fromHeight === toHeight) {
310-
return undefined;
311-
}
312-
container.style.height = `${fromHeight}px`;
313-
container.classList.add("is-animating-height");
314-
// Commit the start height before transitioning to the target.
315-
void container.offsetHeight;
316-
container.style.height = `${toHeight}px`;
317-
318-
let fallbackTimer;
319-
// Invoked from transitionend/transitioncancel (with an event), from the
320-
// fallback timer, or as the effect cleanup (no event). Ignore events
321-
// bubbling up from child widgets; the container only transitions height,
322-
// so its own events need no propertyName check.
323-
const finishRowHeightAnimation = e => {
324-
if (e && e.target !== container) {
325-
return;
326-
}
327-
globalThis.clearTimeout(fallbackTimer);
328-
container.style.height = "";
329-
container.classList.remove("is-animating-height");
330-
container.removeEventListener("transitionend", finishRowHeightAnimation);
331-
container.removeEventListener(
332-
"transitioncancel",
333-
finishRowHeightAnimation
334-
);
335-
};
336-
container.addEventListener("transitionend", finishRowHeightAnimation);
337-
container.addEventListener("transitioncancel", finishRowHeightAnimation);
338-
fallbackTimer = globalThis.setTimeout(
339-
finishRowHeightAnimation,
340-
ROW_TOGGLE_HEIGHT_ANIMATION_FALLBACK_MS
341-
);
342-
return finishRowHeightAnimation;
343-
}, [rowExpanded]);
344-
345296
// Reset timer when it becomes disabled
346297
useEffect(() => {
347298
const wasTimerEnabled = prevTimerEnabledRef.current;
@@ -481,13 +432,6 @@ function Widgets() {
481432

482433
function toggleRowExpanded() {
483434
const next = !rowExpanded;
484-
const container = widgetsContainerRef.current;
485-
const prefersReducedMotion = globalThis.matchMedia?.(
486-
"(prefers-reduced-motion: reduce)"
487-
)?.matches;
488-
if (container && !prefersReducedMotion) {
489-
rowToggleFromHeightRef.current = container.getBoundingClientRect().height;
490-
}
491435
batch(() => {
492436
dispatch(ac.SetPref(PREF_WIDGETS_ROW_EXPANDED, next));
493437
dispatch(

browser/extensions/newtab/content-src/components/Widgets/_Widgets.scss

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -189,19 +189,6 @@
189189
grid-template-columns: repeat(auto-fill, var(--col-width));
190190
grid-auto-rows: var(--row-height);
191191
gap: var(--space-medium);
192-
193-
@include widget-size-transition-tokens;
194-
}
195-
196-
.nova-enabled &.is-animating-height {
197-
overflow: hidden;
198-
transition: height var(--widget-size-transition-duration) var(--widget-size-transition-easing);
199-
}
200-
201-
@media (prefers-reduced-motion: reduce) {
202-
.nova-enabled &.is-animating-height {
203-
transition: none;
204-
}
205192
}
206193

207194
// Classic layout (when Nova is disabled)

browser/extensions/newtab/content-src/styles/_mixins.scss

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,17 +181,11 @@ $side-col-width-px: $col-width-px * 2;
181181
}
182182
}
183183

184-
// Shared size-change transition tokens. Included by widget-base-style (each
185-
// widget card) and by the Nova widgets-container so the row-height animation
186-
// stays in sync with per-widget resize timing.
187-
@mixin widget-size-transition-tokens {
184+
// Baseline styles for all widgets
185+
@mixin widget-base-style {
188186
--widget-size-transition-duration: 180ms;
189187
--widget-size-transition-easing: ease;
190-
}
191188

192-
// Baseline styles for all widgets
193-
@mixin widget-base-style {
194-
@include widget-size-transition-tokens;
195189
@include newtab-card-style;
196190

197191
padding: var(--space-medium);

browser/extensions/newtab/css/activity-stream.css

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5094,17 +5094,6 @@ dialog:dir(rtl)::after {
50945094
grid-template-columns: repeat(auto-fill, var(--col-width));
50955095
grid-auto-rows: var(--row-height);
50965096
gap: var(--space-medium);
5097-
--widget-size-transition-duration: 180ms;
5098-
--widget-size-transition-easing: ease;
5099-
}
5100-
.nova-enabled .widgets-container.is-animating-height {
5101-
overflow: hidden;
5102-
transition: height var(--widget-size-transition-duration) var(--widget-size-transition-easing);
5103-
}
5104-
@media (prefers-reduced-motion: reduce) {
5105-
.nova-enabled .widgets-container.is-animating-height {
5106-
transition: none;
5107-
}
51085097
}
51095098
.classic-enabled .widgets-container {
51105099
--widgets-card-width: var(--newtab-card-grid-layout-width);

browser/extensions/newtab/css/nova/activity-stream.css

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4775,17 +4775,6 @@ button.arrow-button:dir(rtl) {
47754775
grid-template-columns: repeat(auto-fill, var(--col-width));
47764776
grid-auto-rows: var(--row-height);
47774777
gap: var(--space-medium);
4778-
--widget-size-transition-duration: 180ms;
4779-
--widget-size-transition-easing: ease;
4780-
}
4781-
.nova-enabled .widgets-container.is-animating-height {
4782-
overflow: hidden;
4783-
transition: height var(--widget-size-transition-duration) var(--widget-size-transition-easing);
4784-
}
4785-
@media (prefers-reduced-motion: reduce) {
4786-
.nova-enabled .widgets-container.is-animating-height {
4787-
transition: none;
4788-
}
47894778
}
47904779
.classic-enabled .widgets-container {
47914780
--widgets-card-width: var(--newtab-card-grid-layout-width);

browser/extensions/newtab/data/content/activity-stream.bundle.js

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -23937,9 +23937,6 @@ const PREF_WIDGETS_ROW_EXPANDED = "widgets.row.expanded";
2393723937
const PREF_WIDGETS_FEEDBACK_ENABLED = "widgets.feedback.enabled";
2393823938
const PREF_WIDGETS_HIDE_ALL_TOAST_ENABLED = "widgets.hideAllToast.enabled";
2393923939
const WIDGETS_FEEDBACK_URL = "https://support.mozilla.org/kb/firefox-new-tab-widgets";
23940-
// Safety net in case transitionend never fires. Keep this above the CSS
23941-
// height transition duration (--widget-size-transition-duration, 180ms).
23942-
const ROW_TOGGLE_HEIGHT_ANIMATION_FALLBACK_MS = 300;
2394323940

2394423941
// resets timer to default values (exported for testing)
2394523942
// In practice, this logic runs inside a useEffect when
@@ -24114,43 +24111,6 @@ function Widgets() {
2411424111

2411524112
// track previous timerEnabled state to detect when it becomes disabled
2411624113
const prevTimerEnabledRef = (0,external_React_namespaceObject.useRef)(timerEnabled);
24117-
const rowToggleFromHeightRef = (0,external_React_namespaceObject.useRef)(null);
24118-
(0,external_React_namespaceObject.useLayoutEffect)(() => {
24119-
const fromHeight = rowToggleFromHeightRef.current;
24120-
rowToggleFromHeightRef.current = null;
24121-
const container = widgetsContainerRef.current;
24122-
if (fromHeight === null || !container) {
24123-
return undefined;
24124-
}
24125-
const toHeight = container.getBoundingClientRect().height;
24126-
if (fromHeight === toHeight) {
24127-
return undefined;
24128-
}
24129-
container.style.height = `${fromHeight}px`;
24130-
container.classList.add("is-animating-height");
24131-
// Commit the start height before transitioning to the target.
24132-
void container.offsetHeight;
24133-
container.style.height = `${toHeight}px`;
24134-
let fallbackTimer;
24135-
// Invoked from transitionend/transitioncancel (with an event), from the
24136-
// fallback timer, or as the effect cleanup (no event). Ignore events
24137-
// bubbling up from child widgets; the container only transitions height,
24138-
// so its own events need no propertyName check.
24139-
const finishRowHeightAnimation = e => {
24140-
if (e && e.target !== container) {
24141-
return;
24142-
}
24143-
globalThis.clearTimeout(fallbackTimer);
24144-
container.style.height = "";
24145-
container.classList.remove("is-animating-height");
24146-
container.removeEventListener("transitionend", finishRowHeightAnimation);
24147-
container.removeEventListener("transitioncancel", finishRowHeightAnimation);
24148-
};
24149-
container.addEventListener("transitionend", finishRowHeightAnimation);
24150-
container.addEventListener("transitioncancel", finishRowHeightAnimation);
24151-
fallbackTimer = globalThis.setTimeout(finishRowHeightAnimation, ROW_TOGGLE_HEIGHT_ANIMATION_FALLBACK_MS);
24152-
return finishRowHeightAnimation;
24153-
}, [rowExpanded]);
2415424114

2415524115
// Reset timer when it becomes disabled
2415624116
(0,external_React_namespaceObject.useEffect)(() => {
@@ -24275,11 +24235,6 @@ function Widgets() {
2427524235
}
2427624236
function toggleRowExpanded() {
2427724237
const next = !rowExpanded;
24278-
const container = widgetsContainerRef.current;
24279-
const prefersReducedMotion = globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;
24280-
if (container && !prefersReducedMotion) {
24281-
rowToggleFromHeightRef.current = container.getBoundingClientRect().height;
24282-
}
2428324238
(0,external_ReactRedux_namespaceObject.batch)(() => {
2428424239
dispatch(actionCreators.SetPref(PREF_WIDGETS_ROW_EXPANDED, next));
2428524240
dispatch(actionCreators.OnlyToMain({

browser/extensions/newtab/test/jest/content-src/components/Widgets/Widgets.test.jsx

Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { render, fireEvent, act } from "@testing-library/react";
1+
import { render, fireEvent } from "@testing-library/react";
22
import { WrapWithProvider } from "test/jest/test-utils";
33
import { Provider } from "react-redux";
44
import { createStore, combineReducers } from "redux";
@@ -281,28 +281,6 @@ describe("<Widgets> row toggle", () => {
281281
});
282282
}
283283

284-
function startRowHeightAnimation() {
285-
const { container, store } = renderWidgets(novaStateWith(false));
286-
const widgetsContainer = container.querySelector("#widgets-container");
287-
jest
288-
.spyOn(widgetsContainer, "getBoundingClientRect")
289-
.mockReturnValueOnce({ height: 40 })
290-
.mockReturnValueOnce({ height: 80 });
291-
292-
// The click captures the pre-toggle height; the pref change round-trips
293-
// from the main process as PREF_CHANGED, flipping rowExpanded and running
294-
// the height animation effect.
295-
fireEvent.click(container.querySelector(".widgets-row-toggle"));
296-
act(() => {
297-
store.dispatch({
298-
type: at.PREF_CHANGED,
299-
data: { name: "widgets.row.expanded", value: true },
300-
});
301-
});
302-
303-
return widgetsContainer;
304-
}
305-
306284
it("renders the toggle button when nova is enabled", () => {
307285
const { container } = renderWidgets(novaStateWith(false));
308286
expect(container.querySelector(".widgets-row-toggle")).toBeInTheDocument();
@@ -344,62 +322,6 @@ describe("<Widgets> row toggle", () => {
344322
})
345323
);
346324
});
347-
348-
it("clears row height animation if transitionend does not fire", () => {
349-
jest.useFakeTimers();
350-
try {
351-
const widgetsContainer = startRowHeightAnimation();
352-
353-
expect(widgetsContainer).toHaveClass("is-animating-height");
354-
expect(widgetsContainer.style.height).toBe("80px");
355-
356-
act(() => {
357-
jest.runOnlyPendingTimers();
358-
});
359-
360-
expect(widgetsContainer).not.toHaveClass("is-animating-height");
361-
expect(widgetsContainer.style.height).toBe("");
362-
} finally {
363-
jest.useRealTimers();
364-
}
365-
});
366-
367-
it("clears row height animation on transitionend", () => {
368-
const widgetsContainer = startRowHeightAnimation();
369-
370-
expect(widgetsContainer).toHaveClass("is-animating-height");
371-
expect(widgetsContainer.style.height).toBe("80px");
372-
373-
fireEvent.transitionEnd(widgetsContainer, { propertyName: "height" });
374-
375-
expect(widgetsContainer).not.toHaveClass("is-animating-height");
376-
expect(widgetsContainer.style.height).toBe("");
377-
});
378-
379-
it("skips the row height animation under prefers-reduced-motion", () => {
380-
const originalMatchMedia = globalThis.matchMedia;
381-
globalThis.matchMedia = () => ({ matches: true });
382-
try {
383-
const { container, store } = renderWidgets(novaStateWith(false));
384-
const widgetsContainer = container.querySelector("#widgets-container");
385-
const rectSpy = jest.spyOn(widgetsContainer, "getBoundingClientRect");
386-
387-
fireEvent.click(container.querySelector(".widgets-row-toggle"));
388-
act(() => {
389-
store.dispatch({
390-
type: at.PREF_CHANGED,
391-
data: { name: "widgets.row.expanded", value: true },
392-
});
393-
});
394-
395-
// The container is never measured, so the FLIP animation never starts.
396-
expect(rectSpy).not.toHaveBeenCalled();
397-
expect(widgetsContainer).not.toHaveClass("is-animating-height");
398-
expect(widgetsContainer.style.height).toBe("");
399-
} finally {
400-
globalThis.matchMedia = originalMatchMedia;
401-
}
402-
});
403325
});
404326

405327
describe("<Widgets> maximize toggle", () => {

0 commit comments

Comments
 (0)