'use strict';

//
// Animates an element using keyframes. Returns a promise that resolves after the animation completes or gets canceled.
//
function animateTo(el, keyframes, options) {
  return new Promise(resolve => {
    if ((options === null || options === void 0 ? void 0 : options.duration) === Infinity) {
      throw new Error('Promise-based animations must be finite.');
    }
    if (!(el === null || el === void 0 ? void 0 : el.animate)) {
      return;
    }
    const animation = el.animate(keyframes, {
      ...options,
      duration: prefersReducedMotion() ? 0 : options.duration,
    });
    animation.addEventListener('cancel', resolve, { once: true });
    animation.addEventListener('finish', resolve, { once: true });
  });
}
//
// Tells if the user has enabled the "reduced motion" setting in their browser or OS.
//
function prefersReducedMotion() {
  const query = window.matchMedia('(prefers-reduced-motion: reduce)');
  return query.matches;
}
//
// Stops all active animations on the target element. Returns a promise that resolves after all animations are canceled.
//
function stopAnimations(el) {
  var _a;
  return Promise.all((((_a = el === null || el === void 0 ? void 0 : el.getAnimations) === null || _a === void 0 ? void 0 : _a.call(el)) || []).map(animation => {
    return new Promise(resolve => {
      const handleAnimationEvent = requestAnimationFrame(resolve);
      animation.addEventListener('cancel', () => handleAnimationEvent, { once: true });
      animation.addEventListener('finish', () => handleAnimationEvent, { once: true });
      animation.cancel();
    });
  }));
}
// We can't animate `height: auto`, but we can calculate the height and shim keyframes by replacing it with the
// element's scrollHeight before the animation.
function shimKeyframesHeightAuto(keyframes, calculatedHeight) {
  return keyframes.map(keyframe => ({
    ...keyframe,
    height: keyframe.height === 'auto' ? `${calculatedHeight}px` : keyframe.height,
  }));
}

const defaultAnimationRegistry = new Map();
const customAnimationRegistry = new WeakMap();
function ensureAnimation(animation) {
  return animation !== null && animation !== void 0 ? animation : { keyframes: [], options: { duration: 0 } };
}
//
// Sets a default animation. Components should use the `name.animation` for primary animations and `name.part.animation`
// for secondary animations, e.g. `dialog.show` and `dialog.overlay.show`. For modifiers, use `drawer.showTop`.
//
function setDefaultAnimation(animationName, animation) {
  defaultAnimationRegistry.set(animationName, ensureAnimation(animation));
}
//
// Gets an element's animation. Falls back to the default if no animation is found.
//
function getAnimation(el, animationName) {
  const customAnimation = customAnimationRegistry.get(el);
  // Check for a custom animation
  if (customAnimation === null || customAnimation === void 0 ? void 0 : customAnimation[animationName]) {
    return customAnimation[animationName];
  }
  // Check for a default animation
  const defaultAnimation = defaultAnimationRegistry.get(animationName);
  if (defaultAnimation) {
    return defaultAnimation;
  }
  // Fall back to an empty animation
  return {
    keyframes: [],
    options: { duration: 0 },
  };
}

exports.animateTo = animateTo;
exports.getAnimation = getAnimation;
exports.setDefaultAnimation = setDefaultAnimation;
exports.shimKeyframesHeightAuto = shimKeyframesHeightAuto;
exports.stopAnimations = stopAnimations;
