{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"fysk-hooks","type":"registry:hook","description":"Global hooks for Fysk components.","registryDependencies":["https://fysk.dev/r/fysk-provider.json"],"files":[{"path":"fysk/useFyskAnimation.ts","type":"registry:hook","content":"\"use client\";\r\nimport {\r\n  useFyskConfig,\r\n  defaultAnimationConfig,\r\n  type FyskAnimationConfig,\r\n} from \"@/components/fysk-provider\";\r\nimport React from \"react\";\r\n\r\n/**\r\n * Hook to access animation configuration and utilities.\r\n * Provides pre-computed transition objects for consistent animations across components.\r\n */\r\nexport function useFyskAnimation() {\r\n  const { animations } = useFyskConfig();\r\n\r\n  // Merge user config with defaults\r\n  const config: FyskAnimationConfig = React.useMemo(\r\n    () => ({\r\n      ...defaultAnimationConfig,\r\n      ...animations,\r\n      durations: {\r\n        ...defaultAnimationConfig.durations,\r\n        ...animations?.durations,\r\n      },\r\n      easings: { ...defaultAnimationConfig.easings, ...animations?.easings },\r\n      effects: { ...defaultAnimationConfig.effects, ...animations?.effects },\r\n    }),\r\n    [animations],\r\n  );\r\n\r\n  // Check if animations are enabled and motion is available\r\n  const isEnabled = config.enabled && !!config.motion;\r\n\r\n  // Pre-computed transition objects based on config\r\n  const transitions = React.useMemo(() => {\r\n    if (!isEnabled) return null;\r\n\r\n    const { durations, easings } = config;\r\n\r\n    return {\r\n      layout: {\r\n        duration: durations.layout,\r\n        ease: easings.layout,\r\n      },\r\n      enter: {\r\n        duration: durations.normal,\r\n        ease: easings.enter,\r\n      },\r\n      exit: {\r\n        duration: durations.fast,\r\n        ease: easings.exit,\r\n      },\r\n      hover: {\r\n        duration: durations.instant,\r\n        ease: easings.hover,\r\n      },\r\n      content: {\r\n        duration: durations.normal,\r\n        ease: easings.enter,\r\n        layout: {\r\n          duration: durations.slow,\r\n          ease: easings.layout,\r\n        },\r\n      },\r\n      linear: {\r\n        duration: durations.normal,\r\n        ease: easings.linear,\r\n        repeat: Infinity,\r\n      },\r\n      layoutEnter: {\r\n        layout: { duration: durations.layout, ease: easings.layout },\r\n        opacity: { duration: durations.normal, ease: easings.enter },\r\n      },\r\n    };\r\n  }, [isEnabled, config]);\r\n\r\n  // Pre-computed animation variants based on config\r\n  const variants = React.useMemo(() => {\r\n    if (!isEnabled) return null;\r\n\r\n    const { effects, durations, easings } = config;\r\n\r\n    const buildHiddenState = () => {\r\n      const state: Record<string, any> = { opacity: 0 };\r\n      if (effects.blur) state.filter = `blur(${effects.blurAmount}px)`;\r\n      if (effects.scale) state.scale = effects.scaleAmount;\r\n      if (effects.slide) state.y = effects.slideDistance;\r\n      return state;\r\n    };\r\n\r\n    const buildVisibleState = () => {\r\n      const state: Record<string, any> = { opacity: 1 };\r\n      if (effects.blur) state.filter = \"blur(0px)\";\r\n      if (effects.scale) state.scale = 1;\r\n      if (effects.slide) state.y = 0;\r\n      return state;\r\n    };\r\n\r\n    const buildExitState = () => {\r\n      const state: Record<string, any> = { opacity: 0 };\r\n      if (effects.blur) state.filter = `blur(${effects.blurAmount}px)`;\r\n      if (effects.scale) state.scale = effects.scaleAmount;\r\n      if (effects.slide) state.y = -effects.slideDistance;\r\n      return state;\r\n    };\r\n\r\n    return {\r\n      fadeSlide: {\r\n        initial: buildHiddenState(),\r\n        animate: buildVisibleState(),\r\n        exit: buildExitState(),\r\n        transition: { duration: durations.normal, ease: easings.enter },\r\n      },\r\n      fade: {\r\n        initial: { opacity: 0 },\r\n        animate: { opacity: 1 },\r\n        exit: { opacity: 0 },\r\n        transition: { duration: durations.fast, ease: easings.enter },\r\n      },\r\n      iconPop: {\r\n        initial: { scale: 0.5, rotate: -10 },\r\n        animate: { scale: 1, rotate: 0 },\r\n        transition: { duration: durations.normal, ease: easings.enter },\r\n      },\r\n      overlay: {\r\n        initial: { opacity: 0 },\r\n        animate: { opacity: 1 },\r\n        exit: { opacity: 0 },\r\n        transition: { duration: durations.fast, ease: easings.enter },\r\n      },\r\n      slideUp: {\r\n        initial: { opacity: 0, y: 20 },\r\n        animate: { opacity: 1, y: 0 },\r\n        exit: { opacity: 0, y: 10 },\r\n        transition: { duration: durations.normal, ease: easings.enter },\r\n      },\r\n      scaleIn: {\r\n        initial: { opacity: 0, scale: 0.95 },\r\n        animate: { opacity: 1, scale: 1 },\r\n        exit: { opacity: 0, scale: 0.95 },\r\n        transition: { duration: durations.normal, ease: easings.enter },\r\n      },\r\n    };\r\n  }, [isEnabled, config]);\r\n\r\n  const AnimatePresence = config.AnimatePresence || React.Fragment;\r\n\r\n  return {\r\n    isEnabled,\r\n    motion: isEnabled ? config.motion : null,\r\n    AnimatePresence,\r\n    config,\r\n    transitions,\r\n    variants,\r\n  };\r\n}\r\n"}]}