Skip to content

Commit

Permalink
refactor: use requestAnimationFrame to replace readTask (#10432)
Browse files Browse the repository at this point in the history
**Related Issue:** #10348

## Summary

We've been using `readTask` in a few places to ensure proper timing for
DOM reads w/o triggering layout thrashing. Looking at [the
implementation](https://github.com/ionic-team/stencil/blob/7ede77a873486b5cf47f0b26571f852675f67dd6/src/client/client-task-queue.ts#L23),
we might be able to get close or similar behavior by using
`requestAnimationFrame`.
  • Loading branch information
jcfranco authored Oct 1, 2024
1 parent bcdd5ac commit fe792d3
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
State,
VNode,
Watch,
readTask,
} from "@stencil/core";
import { focusElementInGroup, slotChangeGetAssignedElements } from "../../utils/dom";
import { Position, Scale } from "../interfaces";
Expand Down Expand Up @@ -356,7 +355,7 @@ export class Stepper implements LocalizedComponent, T9nComponent {

@Watch("currentActivePosition")
handlePositionChange(): void {
readTask((): void => {
requestAnimationFrame((): void => {
this.determineActiveStepper();
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
Host,
Listen,
Prop,
readTask,
State,
VNode,
Watch,
Expand Down Expand Up @@ -262,7 +261,7 @@ export class TabNav implements LocalizedComponent, T9nComponent {
return;
}

readTask(() => {
requestAnimationFrame(() => {
const isLTR = this.effectiveDir === "ltr";
const tabTitleContainer = this.tabTitleContainerEl;
const containerBounds = tabTitleContainer.getBoundingClientRect();
Expand Down Expand Up @@ -487,7 +486,7 @@ export class TabNav implements LocalizedComponent, T9nComponent {
}

private scrollToTabTitles = (direction: "forward" | "backward"): void => {
readTask(() => {
requestAnimationFrame(() => {
const tabTitleContainer = this.tabTitleContainerEl;
const containerBounds = tabTitleContainer.getBoundingClientRect();
const tabTitles = Array.from(this.el.querySelectorAll("calcite-tab-title"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ describe("openCloseComponent", () => {
let dispatchTransitionEvent: TransitionEventDispatcher;

beforeEach(() => {
jest.spyOn(openCloseComponent, "internalReadTask").mockImplementation((task) => task(1337));
jest.spyOn(global, "requestAnimationFrame").mockImplementation((cb) => {
cb(0);
return 0;
});
dispatchTransitionEvent = createTransitionEventDispatcher();
});

Expand Down
8 changes: 1 addition & 7 deletions packages/calcite-components/src/utils/openCloseComponent.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { readTask } from "@stencil/core";
import { whenTransitionDone } from "./dom";

/**
* Exported for testing purposes only
*/
export const internalReadTask = readTask;

/**
* Defines interface for components with open/close public emitter.
* All implementations of this interface must handle the following events: `beforeOpen`, `open`, `beforeClose`, `close`.
Expand Down Expand Up @@ -86,7 +80,7 @@ function isOpen(component: OpenCloseComponent): boolean {
* @param component - OpenCloseComponent uses `open` prop to emit (before)open/close.
*/
export function onToggleOpenCloseComponent(component: OpenCloseComponent): void {
internalReadTask((): void => {
requestAnimationFrame((): void => {
if (!component.transitionEl) {
return;
}
Expand Down

0 comments on commit fe792d3

Please sign in to comment.