| 1733 | 1733 | |
| 1734 | 1734 | /** |
| 1735 | 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 | 1737 | * @param {HTMLElement} control - The control element to listen for animation end event |
| 1738 | 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 | 1741 | export function runAfterAnimation(control, callback, timeout = 500) { |
| 1741 | 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 | 1747 | } else { |
| 1748 | 1748 | callback(control); |
| 1749 | 1749 | } |