{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "primitives-effects-effect",
  "title": "Effect",
  "description": "An effect that allows you to animate elements on first view or load.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "@unlumen-ui/primitives-animate-slot",
    "@unlumen-ui/hooks-use-is-in-view"
  ],
  "files": [
    {
      "path": "registry/primitives/effects/effect/index.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { motion, type HTMLMotionProps, type Variant } from \"motion/react\";\n\nimport {\n  useIsInView,\n  type UseIsInViewOptions,\n} from \"@/hooks/use-is-in-view\";\nimport { Slot, type WithAsChild } from \"@/components/unlumen-ui/primitives/animate/slot\";\n\ntype SlideDirection = \"up\" | \"down\" | \"left\" | \"right\";\n\ntype Slide = {\n  direction?: SlideDirection;\n  offset?: number;\n};\n\ntype Fade = { initialOpacity?: number; opacity?: number };\n\ntype Zoom = {\n  initialScale?: number;\n  scale?: number;\n};\n\ntype Blur = {\n  initialBlur?: number;\n  blur?: number;\n};\n\ntype EffectProps = WithAsChild<\n  {\n    children?: React.ReactNode;\n    delay?: number;\n    blur?: Blur | boolean;\n    slide?: Slide | boolean;\n    fade?: Fade | boolean;\n    zoom?: Zoom | boolean;\n    ref?: React.Ref<HTMLElement>;\n  } & UseIsInViewOptions &\n    HTMLMotionProps<\"div\">\n>;\n\nconst DEFAULT_SLIDE_DIRECTION: SlideDirection = \"up\";\nconst DEFAULT_SLIDE_OFFSET: number = 100;\nconst DEFAULT_FADE_INITIAL_OPACITY: number = 0;\nconst DEFAULT_FADE_OPACITY: number = 1;\nconst DEFAULT_ZOOM_INITIAL_SCALE: number = 0.5;\nconst DEFAULT_ZOOM_SCALE: number = 1;\nconst DEFAULT_BLUR_INITIAL_BLUR: number = 10;\nconst DEFAULT_BLUR_BLUR: number = 0;\n\nfunction Effect({\n  ref,\n  transition = { type: \"spring\", stiffness: 200, damping: 20 },\n  delay = 0,\n  inView = false,\n  inViewMargin = \"0px\",\n  inViewOnce = true,\n  blur = false,\n  slide = false,\n  fade = false,\n  zoom = false,\n  asChild = false,\n  ...props\n}: EffectProps) {\n  const { ref: localRef, isInView } = useIsInView(\n    ref as React.Ref<HTMLElement>,\n    {\n      inView,\n      inViewOnce,\n      inViewMargin,\n    },\n  );\n\n  const hiddenVariant: Variant = {};\n  const visibleVariant: Variant = {};\n\n  if (slide) {\n    const offset =\n      typeof slide === \"boolean\"\n        ? DEFAULT_SLIDE_OFFSET\n        : (slide.offset ?? DEFAULT_SLIDE_OFFSET);\n    const direction =\n      typeof slide === \"boolean\"\n        ? DEFAULT_SLIDE_DIRECTION\n        : (slide.direction ?? DEFAULT_SLIDE_DIRECTION);\n    const axis = direction === \"up\" || direction === \"down\" ? \"y\" : \"x\";\n    hiddenVariant[axis] =\n      direction === \"right\" || direction === \"down\" ? -offset : offset;\n    visibleVariant[axis] = 0;\n  }\n\n  if (fade) {\n    hiddenVariant.opacity =\n      typeof fade === \"boolean\"\n        ? DEFAULT_FADE_INITIAL_OPACITY\n        : (fade.initialOpacity ?? DEFAULT_FADE_INITIAL_OPACITY);\n    visibleVariant.opacity =\n      typeof fade === \"boolean\"\n        ? DEFAULT_FADE_OPACITY\n        : (fade.opacity ?? DEFAULT_FADE_OPACITY);\n  }\n\n  if (zoom) {\n    hiddenVariant.scale =\n      typeof zoom === \"boolean\"\n        ? DEFAULT_ZOOM_INITIAL_SCALE\n        : (zoom.initialScale ?? DEFAULT_ZOOM_INITIAL_SCALE);\n    visibleVariant.scale =\n      typeof zoom === \"boolean\"\n        ? DEFAULT_ZOOM_SCALE\n        : (zoom.scale ?? DEFAULT_ZOOM_SCALE);\n  }\n\n  if (blur) {\n    hiddenVariant.filter =\n      typeof blur === \"boolean\"\n        ? `blur(${DEFAULT_BLUR_INITIAL_BLUR}px)`\n        : `blur(${blur.initialBlur ?? DEFAULT_BLUR_INITIAL_BLUR}px)`;\n    visibleVariant.filter =\n      typeof blur === \"boolean\"\n        ? `blur(${DEFAULT_BLUR_BLUR}px)`\n        : `blur(${blur.blur ?? DEFAULT_BLUR_BLUR}px)`;\n  }\n\n  const Component = asChild ? Slot : motion.div;\n\n  return (\n    <Component\n      ref={localRef as React.Ref<HTMLDivElement>}\n      initial=\"hidden\"\n      animate={isInView ? \"visible\" : \"hidden\"}\n      exit=\"hidden\"\n      variants={{\n        hidden: hiddenVariant,\n        visible: visibleVariant,\n      }}\n      transition={{\n        ...transition,\n        delay: (transition?.delay ?? 0) + delay / 1000,\n      }}\n      {...props}\n    />\n  );\n}\n\ntype EffectsProps = Omit<EffectProps, \"children\"> & {\n  children: React.ReactElement | React.ReactElement[];\n  holdDelay?: number;\n};\n\nfunction Effects({\n  children,\n  delay = 0,\n  holdDelay = 0,\n  ...props\n}: EffectsProps) {\n  const array = React.Children.toArray(children) as React.ReactElement[];\n\n  return (\n    <>\n      {array.map((child, index) => (\n        <Effect\n          key={child.key ?? index}\n          delay={delay + index * holdDelay}\n          {...props}\n        >\n          {child}\n        </Effect>\n      ))}\n    </>\n  );\n}\n\nexport {\n  Effect,\n  Effects,\n  type EffectProps,\n  type EffectsProps,\n  type SlideDirection,\n  type Slide,\n  type Fade,\n  type Zoom,\n};\n",
      "type": "registry:ui",
      "target": "components/unlumen-ui/primitives/effects/effect.tsx"
    }
  ],
  "type": "registry:ui"
}