-
Notifications
You must be signed in to change notification settings - Fork 89
refactor(dom): consolidate transition/animation waiting utils #9341
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
97795d8
6ed8688
8252739
265a426
d0fb904
c2b0c09
ebea3ed
44360a4
048ab62
31c2893
23fdee5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -661,11 +661,41 @@ export function isBefore(a: HTMLElement, b: HTMLElement): boolean { | |
| * @param animationName The name of the animation to watch for completion. | ||
| */ | ||
| export async function whenAnimationDone(targetEl: HTMLElement, animationName: string): Promise<void> { | ||
| const { animationDuration: allDurations, animationName: allNames } = getComputedStyle(targetEl); | ||
| return whenTransitionOrAnimationDone(targetEl, animationName, "animation"); | ||
| } | ||
|
|
||
| /** | ||
| * This util helps determine when a transition has completed. | ||
| * | ||
| * @param targetEl The element to watch for the transition to complete. | ||
| * @param transitionProp The name of the transition to watch for completion. | ||
| */ | ||
| export async function whenTransitionDone(targetEl: HTMLElement, transitionProp: string): Promise<void> { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't we just use
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can tweak the name and doc to better explain its usage. |
||
| return whenTransitionOrAnimationDone(targetEl, transitionProp, "transition"); | ||
| } | ||
|
|
||
| type TransitionOrAnimation = "transition" | "animation"; | ||
| type TransitionOrAnimationEvent = TransitionEvent | AnimationEvent; | ||
|
|
||
| /** | ||
| * This util helps determine when a transition has completed. | ||
| * | ||
| * @param targetEl The element to watch for the transition or animation to complete. | ||
| * @param transitionPropOrAnimationName The transition or animation property to watch for completion. | ||
| * @param type The type of property to watch for completion. Defaults to "transition". | ||
| */ | ||
| export async function whenTransitionOrAnimationDone( | ||
| targetEl: HTMLElement, | ||
| transitionPropOrAnimationName: string, | ||
| type: TransitionOrAnimation, | ||
| ): Promise<void> { | ||
| const style = window.getComputedStyle(targetEl); | ||
| const allDurations = type === "transition" ? style.transitionDuration : style.animationDuration; | ||
| const allProps = type === "transition" ? style.transitionProperty : style.animationName; | ||
|
|
||
| const allDurationsArray = allDurations.split(","); | ||
| const allPropsArray = allNames.split(","); | ||
| const propIndex = allPropsArray.indexOf(animationName); | ||
| const allPropsArray = allProps.split(","); | ||
| const propIndex = allPropsArray.indexOf(transitionPropOrAnimationName); | ||
| const duration = | ||
| allDurationsArray[propIndex] ?? | ||
| /* Safari will have a single duration value for the shorthand prop when multiple, separate names/props are defined, | ||
|
|
@@ -676,12 +706,12 @@ export async function whenAnimationDone(targetEl: HTMLElement, animationName: st | |
| return Promise.resolve(); | ||
| } | ||
|
|
||
| const startEvent = "animationstart"; | ||
| const endEvent = "animationend"; | ||
| const cancelEvent = "animationcancel"; | ||
| const startEvent = type === "transition" ? "transitionstart" : "animationstart"; | ||
| const endEvent = type === "transition" ? "transitionend" : "animationend"; | ||
| const cancelEvent = type === "transition" ? "transitioncancel" : "animationcancel"; | ||
|
|
||
| return new Promise<void>((resolve) => { | ||
| const fallbackTimeoutId = setTimeout( | ||
| const fallbackTimeoutId = window.setTimeout( | ||
| (): void => { | ||
| targetEl.removeEventListener(startEvent, onStart); | ||
| targetEl.removeEventListener(endEvent, onEndOrCancel); | ||
|
|
@@ -695,19 +725,27 @@ export async function whenAnimationDone(targetEl: HTMLElement, animationName: st | |
| targetEl.addEventListener(endEvent, onEndOrCancel); | ||
| targetEl.addEventListener(cancelEvent, onEndOrCancel); | ||
|
|
||
| function onStart(event: AnimationEvent): void { | ||
| if (event.animationName === animationName && event.target === targetEl) { | ||
| clearTimeout(fallbackTimeoutId); | ||
| function onStart(event: TransitionOrAnimationEvent): void { | ||
| if (event.target === targetEl && getTransitionOrAnimationName(event) === transitionPropOrAnimationName) { | ||
| window.clearTimeout(fallbackTimeoutId); | ||
| targetEl.removeEventListener(startEvent, onStart); | ||
| } | ||
| } | ||
|
|
||
| function onEndOrCancel(event: AnimationEvent): void { | ||
| if (event.animationName === animationName && event.target === targetEl) { | ||
| function onEndOrCancel(event: TransitionOrAnimationEvent): void { | ||
| if (event.target === targetEl && getTransitionOrAnimationName(event) === transitionPropOrAnimationName) { | ||
| targetEl.removeEventListener(endEvent, onEndOrCancel); | ||
| targetEl.removeEventListener(cancelEvent, onEndOrCancel); | ||
| resolve(); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| function isTransitionEvent(event: TransitionOrAnimationEvent): event is TransitionEvent { | ||
| return "propertyName" in event; | ||
| } | ||
|
|
||
| function getTransitionOrAnimationName(event: TransitionOrAnimationEvent): string { | ||
| return isTransitionEvent(event) ? event.propertyName : event.animationName; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.