{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "primitives-animate-scroll-progress",
  "title": "Scroll Progress",
  "description": "A scroll progress component that allows you to track the progress of a scrollable element.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "@odysseyui/primitives-animate-slot",
    "@odysseyui/lib-get-strict-context",
    "@odysseyui/hooks-use-motion-value-state"
  ],
  "files": [
    {
      "path": "registry/primitives/animate/scroll-progress/index.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport {\n  motion,\n  useScroll,\n  useSpring,\n  type MotionValue,\n  type HTMLMotionProps,\n  type SpringOptions,\n} from 'motion/react';\n\nimport { Slot, type WithAsChild } from '@/components/odyssey/primitives/animate/slot';\nimport { getStrictContext } from '@/lib/get-strict-context';\nimport { useMotionValueState } from '@/hooks/use-motion-value-state';\n\ntype ScrollProgressDirection = 'horizontal' | 'vertical';\n\ntype ScrollProgressContextType = {\n  containerRef: React.RefObject<HTMLDivElement | null>;\n  progress: MotionValue<number>;\n  scale: MotionValue<number>;\n  direction: ScrollProgressDirection;\n  global: boolean;\n};\n\nconst [LocalScrollProgressProvider, useScrollProgress] =\n  getStrictContext<ScrollProgressContextType>('ScrollProgressContext');\n\ntype ScrollProgressProviderProps = {\n  children: React.ReactNode;\n  global?: boolean;\n  transition?: SpringOptions;\n  direction?: ScrollProgressDirection;\n};\n\nfunction ScrollProgressProvider({\n  global = false,\n  transition = { stiffness: 250, damping: 40, bounce: 0 },\n  direction = 'vertical',\n  ...props\n}: ScrollProgressProviderProps) {\n  const containerRef = React.useRef<HTMLDivElement | null>(null);\n\n  const { scrollYProgress, scrollXProgress } = useScroll(\n    global ? undefined : { container: containerRef },\n  );\n\n  const progress = direction === 'vertical' ? scrollYProgress : scrollXProgress;\n  const scale = useSpring(progress, transition);\n\n  return (\n    <LocalScrollProgressProvider\n      value={{\n        containerRef,\n        progress,\n        scale,\n        direction,\n        global,\n      }}\n      {...props}\n    />\n  );\n}\n\ntype ScrollProgressMode = 'width' | 'height' | 'scaleY' | 'scaleX';\n\ntype ScrollProgressProps = WithAsChild<\n  HTMLMotionProps<'div'> & {\n    mode?: ScrollProgressMode;\n  }\n>;\n\nfunction ScrollProgress({\n  style,\n  mode = 'width',\n  asChild = false,\n  ...props\n}: ScrollProgressProps) {\n  const { scale, direction, global } = useScrollProgress();\n  const scaleValue = useMotionValueState(scale);\n\n  const Component = asChild ? Slot : motion.div;\n\n  return (\n    <Component\n      data-slot=\"scroll-progress\"\n      data-direction={direction}\n      data-mode={mode}\n      data-global={global}\n      style={{\n        ...(mode === 'width' || mode === 'height'\n          ? {\n              [mode]: scaleValue * 100 + '%',\n            }\n          : {\n              [mode]: scale,\n            }),\n        ...style,\n      }}\n      {...props}\n    />\n  );\n}\n\ntype ScrollProgressContainerProps = WithAsChild<HTMLMotionProps<'div'>>;\n\nfunction ScrollProgressContainer({\n  ref,\n  asChild = false,\n  ...props\n}: ScrollProgressContainerProps) {\n  const { containerRef, direction } = useScrollProgress();\n\n  React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);\n\n  const Component = asChild ? Slot : motion.div;\n\n  return (\n    <Component\n      ref={containerRef}\n      data-slot=\"scroll-progress-container\"\n      data-direction={direction}\n      data-global={global}\n      {...props}\n    />\n  );\n}\n\nexport {\n  ScrollProgressProvider,\n  ScrollProgress,\n  ScrollProgressContainer,\n  useScrollProgress,\n  type ScrollProgressProviderProps,\n  type ScrollProgressProps,\n  type ScrollProgressContainerProps,\n  type ScrollProgressDirection,\n  type ScrollProgressMode,\n  type ScrollProgressContextType,\n};\n",
      "type": "registry:ui",
      "target": "components/odysseyui/primitives/animate/scroll-progress.tsx"
    }
  ],
  "type": "registry:ui"
}