{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"book","type":"registry:ui","title":"Book","description":"3D book component with cover, spine, and back face that opens on hover","author":"fancy-ui <https://fancy-ui.rama.app>","categories":["cards"],"registryDependencies":["https://fancy-ui.rama.app/r/utils.json"],"files":[{"path":"react/src/components/book/Book.tsx","content":"\"use client\";\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../../utils\";\nimport {\n\tBOOK_RADIUS_MAP as radiusMap,\n\tBOOK_SIZE_MAP as sizeMap,\n\tBOOK_COLOR_MAP as colorMap,\n\tBOOK_SHADOW_SIZE_MAP as shadowSizeMap,\n\ttype BookRadius,\n\ttype BookSize,\n\ttype BookColor,\n\ttype BookShadowSize,\n} from \"./index\";\n\nexport interface BookProps extends Omit<HTMLAttributes<HTMLDivElement>, \"className\" | \"color\"> {\n\tclassName?: string;\n\tduration?: number;\n\tcolor?: BookColor;\n\tisStatic?: boolean;\n\tsize?: BookSize;\n\tradius?: BookRadius;\n\tshadowSize?: BookShadowSize;\n\tchildren?: ReactNode;\n}\n\nexport function Book({\n\tclassName = \"\",\n\tduration = 1000,\n\tcolor = \"zinc\",\n\tisStatic = false,\n\tsize = \"md\",\n\tradius = \"md\",\n\tshadowSize = \"lg\",\n\tchildren,\n\t...rest\n}: BookProps) {\n\tconst computedGradient = colorMap[color] || colorMap.zinc;\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"group z-10 w-min [--shadowColor:#bbb] [perspective:800px] dark:[--shadowColor:#111]\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\t{...rest}\n\t\t>\n\t\t\t<div\n\t\t\t\tstyle={{ width: sizeMap[size].width, transition: `transform ${duration}ms ease` }}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"relative aspect-[3/4] [transform-style:preserve-3d]\",\n\t\t\t\t\tisStatic\n\t\t\t\t\t\t? \"[transform:rotateY(-30deg)]\"\n\t\t\t\t\t\t: \"[transform:rotateY(0deg)] group-hover:[transform:rotateY(-30deg)]\",\n\t\t\t\t\tradiusMap[radius]\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{/* Front face */}\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"absolute inset-y-0 left-0 flex size-full flex-col justify-end overflow-hidden bg-gradient-to-tr p-6 text-white\",\n\t\t\t\t\t\tcomputedGradient.from,\n\t\t\t\t\t\tcomputedGradient.to,\n\t\t\t\t\t\tradiusMap[radius]\n\t\t\t\t\t)}\n\t\t\t\t\tstyle={{ transform: \"translateZ(25px)\", boxShadow: \"5px 5px 20px var(--shadowColor)\" }}\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"absolute top-0 left-0 h-full\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tminWidth: \"8.2%\",\n\t\t\t\t\t\t\tbackground:\n\t\t\t\t\t\t\t\t\"linear-gradient(90deg, hsla(0, 0%, 100%, 0), hsla(0, 0%, 100%, 0) 12%, hsla(0, 0%, 100%, .25) 29.25%, hsla(0, 0%, 100%, 0) 50.5%, hsla(0, 0%, 100%, 0) 75.25%, hsla(0, 0%, 100%, .25) 91%, hsla(0, 0%, 100%, 0)), linear-gradient(90deg, rgba(0, 0, 0, .03), rgba(0, 0, 0, .1) 12%, transparent 30%, rgba(0, 0, 0, .02) 50%, rgba(0, 0, 0, .2) 73.5%, rgba(0, 0, 0, .5) 75.25%, rgba(0, 0, 0, .15) 85.25%, transparent)\",\n\t\t\t\t\t\t\topacity: 0.2,\n\t\t\t\t\t\t}}\n\t\t\t\t\t></div>\n\t\t\t\t\t<div className=\"pl-1\">{children}</div>\n\t\t\t\t</div>\n\n\t\t\t\t{/* Spine */}\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"absolute left-0 bg-white\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\ttop: \"3px\",\n\t\t\t\t\t\tbottom: \"3px\",\n\t\t\t\t\t\twidth: \"48px\",\n\t\t\t\t\t\ttransform: `translateX(${sizeMap[size].spineTranslation}) rotateY(90deg)`,\n\t\t\t\t\t\tbackground: \"linear-gradient(90deg, rgba(255,255,255,1) 50%, rgba(249,249,249,1) 50%)\",\n\t\t\t\t\t}}\n\t\t\t\t></div>\n\n\t\t\t\t{/* Back face */}\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"absolute inset-y-0 left-0 flex size-full flex-col justify-end overflow-hidden bg-gradient-to-tr p-6 text-white\",\n\t\t\t\t\t\tcomputedGradient.from,\n\t\t\t\t\t\tcomputedGradient.to,\n\t\t\t\t\t\tradiusMap[radius]\n\t\t\t\t\t)}\n\t\t\t\t\tstyle={{ transform: \"translateZ(-25px)\", boxShadow: shadowSizeMap[shadowSize] }}\n\t\t\t\t></div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","type":"registry:ui","target":"@ui/fancy/components/book/Book.tsx"},{"path":"react/src/components/book/BookDescription.tsx","content":"\"use client\";\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../../utils\";\n\nexport interface BookDescriptionProps extends Omit<HTMLAttributes<HTMLParagraphElement>, \"className\"> {\n\tclassName?: string;\n\tchildren?: ReactNode;\n}\n\nexport function BookDescription({ className = \"\", children, ...rest }: BookDescriptionProps) {\n\treturn (\n\t\t<p className={cn(\"text-xs/relaxed select-none\", className)} {...rest}>\n\t\t\t{children}\n\t\t</p>\n\t);\n}\n","type":"registry:ui","target":"@ui/fancy/components/book/BookDescription.tsx"},{"path":"react/src/components/book/BookHeader.tsx","content":"\"use client\";\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../../utils\";\n\nexport interface BookHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, \"className\"> {\n\tclassName?: string;\n\tchildren?: ReactNode;\n}\n\nexport function BookHeader({ className = \"\", children, ...rest }: BookHeaderProps) {\n\treturn (\n\t\t<div className={cn(\"flex flex-wrap gap-2\", className)} {...rest}>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n","type":"registry:ui","target":"@ui/fancy/components/book/BookHeader.tsx"},{"path":"react/src/components/book/BookTitle.tsx","content":"\"use client\";\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../../utils\";\n\nexport interface BookTitleProps extends Omit<HTMLAttributes<HTMLHeadingElement>, \"className\"> {\n\tclassName?: string;\n\tchildren?: ReactNode;\n}\n\nexport function BookTitle({ className = \"\", children, ...rest }: BookTitleProps) {\n\treturn (\n\t\t<h1 className={cn(\"mt-3 mb-1 font-bold text-balance select-none\", className)} {...rest}>\n\t\t\t{children}\n\t\t</h1>\n\t);\n}\n","type":"registry:ui","target":"@ui/fancy/components/book/BookTitle.tsx"},{"path":"react/src/components/book/index.ts","content":"export const BOOK_RADIUS_MAP = {\n\tsm: \"rounded-sm\",\n\tmd: \"rounded-md\",\n\tlg: \"rounded-lg\",\n\txl: \"rounded-xl\",\n} as const;\n\nexport const BOOK_SIZE_MAP = {\n\tsm: { width: \"180px\", spineTranslation: \"152px\" },\n\tmd: { width: \"220px\", spineTranslation: \"192px\" },\n\tlg: { width: \"260px\", spineTranslation: \"232px\" },\n\txl: { width: \"300px\", spineTranslation: \"272px\" },\n} as const;\n\nexport const BOOK_SHADOW_SIZE_MAP = {\n\tsm: \"-5px 0 15px 5px var(--shadowColor)\",\n\tmd: \"-7px 0 25px 7px var(--shadowColor)\",\n\tlg: \"-10px 0 35px 10px var(--shadowColor)\",\n\txl: \"-12px 0 45px 12px var(--shadowColor)\",\n} as const;\n\nexport const BOOK_COLOR_MAP = {\n\tslate: { from: \"from-slate-900\", to: \"to-slate-700\" },\n\tgray: { from: \"from-gray-900\", to: \"to-gray-700\" },\n\tzinc: { from: \"from-zinc-900\", to: \"to-zinc-700\" },\n\tneutral: { from: \"from-neutral-900\", to: \"to-neutral-700\" },\n\tstone: { from: \"from-stone-900\", to: \"to-stone-700\" },\n\tred: { from: \"from-red-900\", to: \"to-red-700\" },\n\torange: { from: \"from-orange-900\", to: \"to-orange-700\" },\n\tamber: { from: \"from-amber-900\", to: \"to-amber-700\" },\n\tyellow: { from: \"from-yellow-900\", to: \"to-yellow-700\" },\n\tlime: { from: \"from-lime-900\", to: \"to-lime-700\" },\n\tgreen: { from: \"from-green-900\", to: \"to-green-700\" },\n\temerald: { from: \"from-emerald-900\", to: \"to-emerald-700\" },\n\tteal: { from: \"from-teal-900\", to: \"to-teal-700\" },\n\tcyan: { from: \"from-cyan-900\", to: \"to-cyan-700\" },\n\tsky: { from: \"from-sky-900\", to: \"to-sky-700\" },\n\tblue: { from: \"from-blue-900\", to: \"to-blue-700\" },\n\tindigo: { from: \"from-indigo-900\", to: \"to-indigo-700\" },\n\tviolet: { from: \"from-violet-900\", to: \"to-violet-700\" },\n\tpurple: { from: \"from-purple-900\", to: \"to-purple-700\" },\n\tfuchsia: { from: \"from-fuchsia-900\", to: \"to-fuchsia-700\" },\n\tpink: { from: \"from-pink-900\", to: \"to-pink-700\" },\n\trose: { from: \"from-rose-900\", to: \"to-rose-700\" },\n} as const;\n\nexport type BookColor = keyof typeof BOOK_COLOR_MAP;\nexport type BookSize = keyof typeof BOOK_SIZE_MAP;\nexport type BookRadius = keyof typeof BOOK_RADIUS_MAP;\nexport type BookShadowSize = keyof typeof BOOK_SHADOW_SIZE_MAP;\n\nexport { Book } from \"./Book\";\nexport type { BookProps } from \"./Book\";\nexport { BookHeader } from \"./BookHeader\";\nexport type { BookHeaderProps } from \"./BookHeader\";\nexport { BookTitle } from \"./BookTitle\";\nexport type { BookTitleProps } from \"./BookTitle\";\nexport { BookDescription } from \"./BookDescription\";\nexport type { BookDescriptionProps } from \"./BookDescription\";\n","type":"registry:ui","target":"@ui/fancy/components/book/index.ts"}],"meta":{"license":"MIT","package":"fancy-ui-react","version":"0.7.0","source":"https://fancy-ui.rama.app/docs/components/book?framework=react"}}