{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "bell-snooze",
  "type": "registry:component",
  "title": "bell-snooze",
  "description": "Animated bell-snooze icon for Vue",
  "author": "Aniket Pawar <pawaraniket508@gmail.com>",
  "registryDependencies": [],
  "dependencies": [
    "motion-v"
  ],
  "files": [
    {
      "path": "src/icons/bell-snooze.vue",
      "type": "registry:component",
      "target": "~/src/components/heroicons-animated/bell-snooze.vue",
      "content": "<template>\n  <div\n    :class=\"props.class\"\n    @mouseenter=\"handleMouseEnter\"\n    @mouseleave=\"handleMouseLeave\"\n    v-bind=\"$attrs\"\n  >\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      :width=\"props.size\"\n      :height=\"props.size\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      :stroke=\"props.color\"\n      :stroke-width=\"props.strokeWidth\"\n      stroke-linecap=\"round\"\n      stroke-linejoin=\"round\"\n    >\n      <g ref=\"bellGroupRef\">\n        <path\n          d=\"M14.8569 17.0817C16.7514 16.857 18.5783 16.4116 20.3111 15.7719C18.8743 14.177 17.9998 12.0656 17.9998 9.75V9.04919C17.9999 9.03281 18 9.01641 18 9C18 5.68629 15.3137 3 12 3C8.68629 3 6 5.68629 6 9L5.9998 9.75C5.9998 12.0656 5.12527 14.177 3.68848 15.7719C5.4214 16.4116 7.24843 16.857 9.14314 17.0818M14.8569 17.0817C13.92 17.1928 12.9666 17.25 11.9998 17.25C11.0332 17.25 10.0799 17.1929 9.14314 17.0818M14.8569 17.0817C14.9498 17.3711 15 17.6797 15 18C15 19.6569 13.6569 21 12 21C10.3431 21 9 19.6569 9 18C9 17.6797 9.05019 17.3712 9.14314 17.0818\"\n        />\n      </g>\n      <path ref=\"snoozeRef\" d=\"M10.5 8.25H13.5L10.5 12.75H13.5\" />\n    </svg>\n  </div>\n</template>\n\n<script lang=\"ts\">\n  export default {\n    name: \"BellSnoozeIcon\",\n  };\n</script>\n\n<script setup lang=\"ts\">\n  import { useMotion } from \"../motion\";\n  import { ref } from \"vue\";\n\n  export interface Props {\n    size?: number;\n    class?: string;\n    color?: string;\n    strokeWidth?: number | string;\n  }\n\n  const props = withDefaults(defineProps<Props>(), {\n    size: 28,\n    color: \"currentColor\",\n    strokeWidth: 1.5,\n  });\n\n  const bellVariants = {\n    normal: {\n      rotate: 0,\n      scale: 1,\n    },\n    animate: {\n      rotate: [0, -8, -8, 0],\n      scale: [1, 0.97, 0.97, 1],\n      transition: {\n        duration: 0.8,\n        ease: \"easeInOut\",\n      },\n    },\n  };\n\n  const snoozeVariants = {\n    normal: {\n      opacity: 1,\n      y: 0,\n      scale: 1,\n    },\n    animate: {\n      opacity: [1, 1, 0.6, 1],\n      y: [0, -1, -2, 0],\n      scale: [1, 1.1, 1.15, 1],\n      transition: {\n        duration: 0.8,\n        ease: \"easeInOut\",\n      },\n    },\n  };\n\n  const bellGroupRef = ref<SVGGElement>();\n  const snoozeRef = ref<SVGPathElement>();\n\n  const bellMotion = useMotion(bellGroupRef, {\n    initial: bellVariants.normal,\n    enter: bellVariants.normal,\n  });\n\n  const snoozeMotion = useMotion(snoozeRef, {\n    initial: snoozeVariants.normal,\n    enter: snoozeVariants.normal,\n  });\n\n  let isControlled = false;\n\n  const startAnimation = () => {\n    bellMotion.apply(bellVariants.animate);\n    snoozeMotion.apply(snoozeVariants.animate);\n  };\n\n  const stopAnimation = () => {\n    bellMotion.apply(bellVariants.normal);\n    snoozeMotion.apply(snoozeVariants.normal);\n  };\n\n  const handleMouseEnter = () => {\n    if (!isControlled) {\n      startAnimation();\n    }\n  };\n\n  const handleMouseLeave = () => {\n    if (!isControlled) {\n      stopAnimation();\n    }\n  };\n\n  const setControlled = (value: boolean) => {\n    isControlled = value;\n  };\n\n  defineExpose({\n    startAnimation,\n    stopAnimation,\n    setControlled,\n  });\n</script>\n"
    },
    {
      "path": "src/motion.ts",
      "type": "registry:component",
      "target": "~/src/components/motion.ts",
      "content": "import { animate } from \"motion-v\";\nimport { isRef, watch, type Ref } from \"vue\";\n\ntype MotionElement = Element | SVGElement;\ntype MotionTarget =\n  | MotionElement\n  | Ref<MotionElement | null | undefined>\n  | null\n  | undefined;\n\ntype MotionTransition = Record<string, unknown>;\ntype MotionValues = Record<string, unknown>;\n\nexport interface MotionVariant extends MotionValues {\n  transition?: MotionTransition;\n}\n\nexport interface UseMotionOptions {\n  initial?: MotionVariant;\n  enter?: MotionVariant;\n}\n\ninterface MotionControls {\n  stop?: () => void;\n}\n\nexport interface MotionInstance {\n  apply: (variant: MotionVariant) => void;\n  stop: () => void;\n}\n\nconst isDomElement = (value: unknown): value is MotionElement => {\n  if (typeof window === \"undefined\") {\n    return false;\n  }\n  return value instanceof Element;\n};\n\nconst resolveElement = (target: MotionTarget): MotionElement | null => {\n  const element = isRef(target) ? target.value : target;\n  if (!element) {\n    return null;\n  }\n  return isDomElement(element) ? element : null;\n};\n\nconst takeTransformOrigin = (value: unknown): string | null => {\n  if (typeof value === \"string\") {\n    return value;\n  }\n  if (Array.isArray(value) && value.length > 0) {\n    // biome-ignore lint/style/useAtIndex: ES2020 lib target for package type-check does not include Array.prototype.at.\n    const lastValue = value[value.length - 1];\n    if (typeof lastValue === \"string\") {\n      return lastValue;\n    }\n  }\n  return null;\n};\n\nconst extractAnimatableValues = (\n  element: MotionElement,\n  values: MotionValues\n): MotionValues => {\n  const animatableValues: MotionValues = { ...values };\n  const transformOrigin = takeTransformOrigin(values.transformOrigin);\n\n  if (transformOrigin && \"style\" in element) {\n    element.style.transformOrigin = transformOrigin;\n    animatableValues.transformOrigin = undefined;\n  }\n\n  return animatableValues;\n};\n\nconst runAnimation = (\n  element: MotionElement,\n  controlsRef: { current: MotionControls | null },\n  variant: MotionVariant,\n  instant = false\n): void => {\n  if (typeof window === \"undefined\") {\n    return;\n  }\n\n  const { transition, ...values } = variant;\n  const animatableValues = extractAnimatableValues(element, values);\n\n  if (Object.keys(animatableValues).length === 0) {\n    return;\n  }\n\n  controlsRef.current?.stop?.();\n\n  const animationOptions = instant\n    ? ({ duration: 0 } as MotionTransition)\n    : (transition ?? {});\n\n  controlsRef.current = animate(\n    element,\n    animatableValues as Record<string, unknown>,\n    animationOptions\n  ) as MotionControls;\n};\n\nexport const useMotion = (\n  target: MotionTarget,\n  options: UseMotionOptions = {}\n): MotionInstance => {\n  const controlsRef: { current: MotionControls | null } = { current: null };\n\n  const initialize = (element: MotionElement): void => {\n    if (options.initial) {\n      runAnimation(element, controlsRef, options.initial, true);\n      return;\n    }\n    if (options.enter) {\n      runAnimation(element, controlsRef, options.enter, true);\n    }\n  };\n\n  const resolvedAtSetup = resolveElement(target);\n  if (resolvedAtSetup) {\n    initialize(resolvedAtSetup);\n  }\n\n  if (isRef(target)) {\n    watch(\n      () => target.value,\n      (element) => {\n        if (isDomElement(element)) {\n          initialize(element);\n        }\n      },\n      { immediate: true }\n    );\n  }\n\n  const apply = (variant: MotionVariant): void => {\n    if (typeof window === \"undefined\") {\n      return;\n    }\n    const element = resolveElement(target);\n    if (!element) {\n      return;\n    }\n    runAnimation(element, controlsRef, variant);\n  };\n\n  return {\n    apply,\n    stop: () => {\n      controlsRef.current?.stop?.();\n    },\n  };\n};\n"
    }
  ]
}