{"version":3,"file":"animatedIcon.mjs","names":[],"sources":["../../../../package/common/animatedIcon/animatedIcon.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { CSSProperties } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport type { IconDefinition } from '@fortawesome/fontawesome-svg-core';\nimport type { AnimatedIconProps } from './animatedIcon.types';\n\nimport styles from './animatedIcon.module.pcss';\n\nfunction iconKey(icon: IconDefinition) {\n  return `${icon.prefix}:${icon.iconName}`;\n}\n\n// A full turn per step, not Fab's original 225° — 225° only looked right there because the\n// resting \"open\" icon (a \"+\") happens to look identical rotated 45° (it's 4-fold symmetric).\n// For arbitrary icon pairs a shared rotation has to land on a multiple of 360° every time, or\n// the new icon ends up sitting sideways.\nconst SPIN_DEGREES_PER_STEP = 360;\n\nfunction AnimatedIcon({\n  icon,\n  duration = 200,\n  spin = false,\n  className,\n  style,\n  onClick,\n  onMouseEnter,\n  onMouseLeave,\n  classNames,\n  styles: slotStyles,\n  ...rest\n}: AnimatedIconProps) {\n  // Two permanently-mounted layers, ping-ponging which one is the visible (\"front\") icon,\n  // instead of conditionally mounting/unmounting an \"outgoing\" layer. That's what lets this use\n  // a real CSS `transition` (which retargets smoothly from wherever it currently is) rather than\n  // a keyframe `animation` (which, once started on a freshly-mounted element, plays to\n  // completion regardless of what happens mid-flight): tap the toggle again before a transition\n  // finishes and it reverses smoothly from its current position — the same thing that already\n  // let Fab's own hand-rolled icon rotation cancel cleanly.\n  const [slots, setSlots] = useState<[IconDefinition, IconDefinition]>([icon, icon]);\n  const [activeIndex, setActiveIndex] = useState<0 | 1>(0);\n  const [spinStep, setSpinStep] = useState(0);\n\n  // Adjusting state during render (not in an effect) on a prop change: the documented React\n  // pattern for reacting to a prop that changed since the last render, without an extra tick.\n  if (iconKey(icon) !== iconKey(slots[activeIndex])) {\n    const nextIndex = activeIndex === 0 ? 1 : 0;\n    const nextSlots: [IconDefinition, IconDefinition] = [...slots];\n    nextSlots[nextIndex] = icon;\n    setSlots(nextSlots);\n    setActiveIndex(nextIndex);\n    if (spin) setSpinStep((step) => step + 1);\n  }\n\n  return (\n    <span\n      {...rest}\n      className={cx(styles.animatedIcon, { [styles.animatedIconSpin]: spin }, classNames?.root, className)}\n      style={\n        {\n          ...style,\n          ...slotStyles?.root,\n          '--animated-icon-duration': `${duration}ms`,\n          '--animated-icon-spin-rotation': `${spinStep * SPIN_DEGREES_PER_STEP}deg`,\n        } as CSSProperties & Record<'--animated-icon-duration' | '--animated-icon-spin-rotation', string>\n      }\n      onClick={onClick}\n      onMouseEnter={onMouseEnter}\n      onMouseLeave={onMouseLeave}\n    >\n      <FontAwesomeIcon\n        icon={slots[0]}\n        className={cx(\n          styles.animatedIconLayer,\n          { [styles.animatedIconLayerFront]: activeIndex === 0 },\n          classNames?.icon,\n        )}\n        style={slotStyles?.icon as CSSProperties & Record<`--fa-font-${string}`, string>}\n      />\n      <FontAwesomeIcon\n        icon={slots[1]}\n        className={cx(\n          styles.animatedIconLayer,\n          { [styles.animatedIconLayerFront]: activeIndex === 1 },\n          classNames?.icon,\n        )}\n        style={slotStyles?.icon as CSSProperties & Record<`--fa-font-${string}`, string>}\n      />\n    </span>\n  );\n}\n\nexport default AnimatedIcon;\n"],"mappings":"oOASA,SAAS,EAAQ,EAAsB,CACrC,MAAO,GAAG,EAAK,OAAO,GAAG,EAAK,UAChC,CAMA,IAAM,EAAwB,IAE9B,SAAS,EAAa,CACpB,OACA,WAAW,IACX,OAAO,GACP,YACA,QACA,UACA,eACA,eACA,aACA,OAAQ,EACR,GAAG,GACiB,CAQpB,GAAM,CAAC,EAAO,GAAY,EAA2C,CAAC,EAAM,CAAI,CAAC,EAC3E,CAAC,EAAa,GAAkB,EAAgB,CAAC,EACjD,CAAC,EAAU,GAAe,EAAS,CAAC,EAI1C,GAAI,EAAQ,CAAI,IAAM,EAAQ,EAAM,EAAY,EAAG,CACjD,IAAM,EAAY,MAAgB,GAC5B,EAA8C,CAAC,GAAG,CAAK,EAC7D,EAAU,GAAa,EACvB,EAAS,CAAS,EAClB,EAAe,CAAS,EACpB,GAAM,EAAa,GAAS,EAAO,CAAC,CAC1C,CAEA,OACE,EAAC,OAAD,CACE,GAAI,EACJ,UAAW,EAAG,EAAO,aAAc,EAAG,EAAO,kBAAmB,CAAK,EAAG,GAAY,KAAM,CAAS,EACnG,MACE,CACE,GAAG,EACH,GAAG,GAAY,KACf,2BAA4B,GAAG,EAAS,IACxC,gCAAiC,GAAG,EAAW,EAAsB,IACvE,EAEO,UACK,eACA,eAbhB,SAAA,CAeE,EAAC,EAAD,CACE,KAAM,EAAM,GACZ,UAAW,EACT,EAAO,kBACP,EAAG,EAAO,wBAAyB,IAAgB,CAAE,EACrD,GAAY,IACd,EACA,MAAO,GAAY,IACpB,CAAA,EACD,EAAC,EAAD,CACE,KAAM,EAAM,GACZ,UAAW,EACT,EAAO,kBACP,EAAG,EAAO,wBAAyB,IAAgB,CAAE,EACrD,GAAY,IACd,EACA,MAAO,GAAY,IACpB,CAAA,CACG,GAEV"}