| 1733 | | 1733 | |
| 1734 | /** | 1734 | /** |
| 1735 | * Run an action once an animation on a control ends. If the control has no animation, the action will be executed immediately. | 1735 | * Run an action once an animation on a control ends. If the control has no animation, the action will be executed immediately. |
| 1736 | * | 1736 | * The action will be executed after the animation ends or after the timeout, whichever comes first. |
| 1737 | * @param {HTMLElement} control - The control element to listen for animation end event | 1737 | * @param {HTMLElement} control - The control element to listen for animation end event |
| 1738 | * @param {(control:*?) => void} callback - The callback function to be executed when the animation ends | 1738 | * @param {(control:*?) => void} callback - The callback function to be executed when the animation ends |
| | 1739 | * @param {number} [timeout=500] - The timeout in milliseconds to wait for the animation to end before executing the callback |
| 1739 | */ | 1740 | */ |
| 1740 | export function runAfterAnimation(control, callback) { | 1741 | export function runAfterAnimation(control, callback, timeout = 500) { |
| 1741 | if (hasAnimation(control)) { | 1742 | if (hasAnimation(control)) { |
| 1742 | const onAnimationEnd = () => { | 1743 | Promise.race([ |
| 1743 | control.removeEventListener('animationend', onAnimationEnd); | 1744 | new Promise((r) => setTimeout(r, timeout)), // Fallback timeout |
| 1744 | callback(control); | 1745 | new Promise((r) => control.addEventListener('animationend', r, { once: true })), |
| 1745 | }; | 1746 | ]).finally(() => callback(control)); |
| 1746 | control.addEventListener('animationend', onAnimationEnd); | | |
| 1747 | } else { | 1747 | } else { |
| 1748 | callback(control); | 1748 | callback(control); |
| 1749 | } | 1749 | } |