{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"card-3d","type":"registry:ui","title":"Card3D","description":"Interactive 3D perspective card with depth effects on child elements","author":"fancy-ui <https://fancy-ui.rama.app>","categories":["cards"],"registryDependencies":["https://fancy-ui.rama.app/r/internals-dom.json","https://fancy-ui.rama.app/r/utils.json"],"files":[{"path":"react/src/components/card-3d/CardBody.tsx","content":"\"use client\";\n\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../../utils\";\n\nexport interface CardBodyProps {\n\t/** Additional CSS classes. */\n\tclassName?: string;\n\t/** The card's layers — typically `<CardItem>`s. */\n\tchildren?: ReactNode;\n}\n\nexport function CardBody({ className = \"\", children }: CardBodyProps) {\n\treturn (\n\t\t<div className={cn(\"h-96 w-96\", className)} style={{ transformStyle: \"preserve-3d\" }}>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n","type":"registry:ui","target":"@ui/fancy/components/card-3d/CardBody.tsx"},{"path":"react/src/components/card-3d/CardContainer.tsx","content":"\"use client\";\n\nimport { useMemo, useRef, useState } from \"react\";\nimport type { MouseEvent, ReactNode } from \"react\";\n\nimport { cn } from \"../../utils\";\nimport { createInternalContext } from \"../../internals/dom/context\";\n\n/** What a `<CardItem>` reads from its enclosing `<CardContainer>`. */\nexport interface Card3DContextValue {\n\t/** Whether the pointer is currently over the container. */\n\tisMouseEntered: boolean;\n}\n\nconst Card3DContext = createInternalContext<Card3DContextValue>(\"Card3DContext\");\n\n/** Provider half of the container/item link. Rendered by `<CardContainer>`. */\nexport const Card3DProvider = Card3DContext.Provider;\n\n/** Reads the container's hover state. Throws outside a `<CardContainer>`. */\nexport const useCard3D = Card3DContext.useRequired;\n\nexport interface CardContainerProps {\n\t/** Additional CSS classes for the tilting 3d container. */\n\tclassName?: string;\n\t/** Additional CSS classes for the outer perspective wrapper. */\n\tcontainerClass?: string;\n\t/** The card content — typically a `<CardBody>` holding `<CardItem>`s. */\n\tchildren?: ReactNode;\n}\n\nexport function CardContainer({\n\tclassName = \"\",\n\tcontainerClass = \"\",\n\tchildren,\n}: CardContainerProps) {\n\tconst containerRef = useRef<HTMLDivElement | null>(null);\n\tconst [isMouseEntered, setIsMouseEntered] = useState(false);\n\n\tconst contextValue = useMemo<Card3DContextValue>(() => ({ isMouseEntered }), [isMouseEntered]);\n\n\tfunction handleMouseMove(e: MouseEvent<HTMLDivElement>) {\n\t\tconst container = containerRef.current;\n\t\tif (!container) return;\n\t\tconst { left, top, width, height } = container.getBoundingClientRect();\n\t\tconst x = (e.clientX - left - width / 2) / 25;\n\t\tconst y = (e.clientY - top - height / 2) / 25;\n\t\tcontainer.style.transform = `rotateY(${x}deg) rotateX(${y}deg)`;\n\t}\n\n\tfunction handleMouseEnter() {\n\t\tsetIsMouseEntered(true);\n\t}\n\n\tfunction handleMouseLeave() {\n\t\tconst container = containerRef.current;\n\t\tif (!container) return;\n\t\tsetIsMouseEntered(false);\n\t\tcontainer.style.transform = `rotateY(0deg) rotateX(0deg)`;\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"flex items-center justify-center p-2\", containerClass)}\n\t\t\tstyle={{ perspective: \"1000px\" }}\n\t\t>\n\t\t\t<div\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"relative flex items-center justify-center ease-linear motion-safe:transition-all motion-safe:duration-200\",\n\t\t\t\t\tclassName\n\t\t\t\t)}\n\t\t\t\tstyle={{ transformStyle: \"preserve-3d\" }}\n\t\t\t\tonMouseEnter={handleMouseEnter}\n\t\t\t\tonMouseMove={handleMouseMove}\n\t\t\t\tonMouseLeave={handleMouseLeave}\n\t\t\t>\n\t\t\t\t<Card3DProvider value={contextValue}>{children}</Card3DProvider>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","type":"registry:ui","target":"@ui/fancy/components/card-3d/CardContainer.tsx"},{"path":"react/src/components/card-3d/CardItem.tsx","content":"\"use client\";\n\nimport { createElement } from \"react\";\nimport type { ElementType, ReactNode } from \"react\";\n\nimport { cn } from \"../../utils\";\nimport { useCard3D } from \"./CardContainer\";\n\nexport interface CardItemProps {\n\t/** Element to render. */\n\tas?: ElementType;\n\t/** Additional CSS classes. */\n\tclassName?: string;\n\t/** X offset, in pixels, applied while the container is hovered. */\n\ttranslateX?: number | string;\n\t/** Y offset, in pixels, applied while the container is hovered. */\n\ttranslateY?: number | string;\n\t/** Z offset, in pixels, applied while the container is hovered. */\n\ttranslateZ?: number | string;\n\t/** X rotation, in degrees, applied while the container is hovered. */\n\trotateX?: number | string;\n\t/** Y rotation, in degrees, applied while the container is hovered. */\n\trotateY?: number | string;\n\t/** Z rotation, in degrees, applied while the container is hovered. */\n\trotateZ?: number | string;\n\t/** The layer's content. */\n\tchildren?: ReactNode;\n}\n\nexport function CardItem({\n\tas = \"div\",\n\tclassName = \"\",\n\ttranslateX = 0,\n\ttranslateY = 0,\n\ttranslateZ = 0,\n\trotateX = 0,\n\trotateY = 0,\n\trotateZ = 0,\n\tchildren,\n}: CardItemProps) {\n\tconst { isMouseEntered } = useCard3D();\n\n\tconst transform = isMouseEntered\n\t\t? `translateX(${translateX}px) translateY(${translateY}px) translateZ(${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) rotateZ(${rotateZ}deg)`\n\t\t: `translateX(0px) translateY(0px) translateZ(0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg)`;\n\n\treturn createElement(\n\t\tas,\n\t\t{\n\t\t\tclassName: cn(\"w-fit motion-safe:transition motion-safe:duration-500 ease-in-out\", className),\n\t\t\tstyle: { transform },\n\t\t},\n\t\tchildren\n\t);\n}\n","type":"registry:ui","target":"@ui/fancy/components/card-3d/CardItem.tsx"},{"path":"react/src/components/card-3d/index.ts","content":"\"use client\";\n\nexport { CardContainer } from \"./CardContainer\";\nexport type { CardContainerProps } from \"./CardContainer\";\nexport { CardBody } from \"./CardBody\";\nexport type { CardBodyProps } from \"./CardBody\";\nexport { CardItem } from \"./CardItem\";\nexport type { CardItemProps } from \"./CardItem\";\n","type":"registry:ui","target":"@ui/fancy/components/card-3d/index.ts"}],"meta":{"license":"MIT","package":"fancy-ui-react","version":"0.7.0","source":"https://fancy-ui.rama.app/docs/components/card-3d?framework=react"}}