{ "name": "circular-gallery", "type": "registry:ui", "registryDependencies": [], "dependencies": [], "devDependencies": [], "tailwind": {}, "cssVars": { "light": {}, "dark": {} }, "files": [ { "path": "circular-gallery.tsx", "content": "'use client';\n\nimport * as React from 'react';\nimport { cn } from '@/lib/utils';\nimport './circular-gallery.css';\n\nexport interface CircularGalleryItemProps {\n id: string;\n imageSrc: string;\n title: string;\n}\n\nexport interface CircularGalleryProps extends Omit<\n React.HTMLAttributes,\n 'title'\n> {\n items: CircularGalleryItemProps[];\n title?: React.ReactNode;\n radius?: string;\n}\n\nexport const CircularGallery = React.forwardRef<\n HTMLElement,\n CircularGalleryProps\n>(({ className, items, title, radius = '40vmin', ...props }, ref) => {\n return (\n \n {items.map((item, index) => (\n \n \n {/* eslint-disable-next-line @next/next/no-img-element */}\n {item.title}\n \n \n ))}\n {title &&

{title}

}\n \n );\n});\nCircularGallery.displayName = 'CircularGallery';\n", "type": "registry:ui" }, { "path": "circular-gallery.tsx", "content": "'use client';\n\nimport * as React from 'react';\nimport { cn } from '@/lib/utils';\nimport './circular-gallery.css';\n\nexport interface CircularGalleryItemProps {\n id: string;\n imageSrc: string;\n title: string;\n}\n\nexport interface CircularGalleryProps extends Omit<\n React.HTMLAttributes,\n 'title'\n> {\n items: CircularGalleryItemProps[];\n title?: React.ReactNode;\n radius?: string;\n}\n\nexport const CircularGallery = React.forwardRef<\n HTMLElement,\n CircularGalleryProps\n>(({ className, items, title, radius = '40vmin', ...props }, ref) => {\n return (\n \n {items.map((item, index) => (\n \n \n {/* eslint-disable-next-line @next/next/no-img-element */}\n {item.title}\n \n \n ))}\n {title &&

{title}

}\n \n );\n});\nCircularGallery.displayName = 'CircularGallery';\n", "type": "registry:ui" }, { "path": "circular-gallery.css", "content": "@reference \"../../app/globals.css\";\n\n@property --rotation {\n syntax: '';\n inherits: true;\n initial-value: 0;\n}\n\n.circular-gallery-wrapper {\n --card-trans-duration: 1000ms;\n --card-trans-easing: linear(\n 0,\n 0.01 0.8%,\n 0.038 1.6%,\n 0.154 3.4%,\n 0.781 9.7%,\n 1.01 12.5%,\n 1.089 13.8%,\n 1.153 15.2%,\n 1.195 16.6%,\n 1.219 18%,\n 1.224 19.7%,\n 1.208 21.6%,\n 1.172 23.6%,\n 1.057 28.6%,\n 1.007 31.2%,\n 0.969 34.1%,\n 0.951 37.1%,\n 0.953 40.9%,\n 0.998 50.4%,\n 1.011 56%,\n 0.998 74.7%,\n 1\n );\n --card-width: clamp(40px, 7vw, 120px);\n --card-border-radius: 1vw;\n --radius: 40vmin;\n --arc-size: 0.95; /* essentially the distance between cards */\n --arc-center: 0.275; /* start at bottom to last card will be at the top */\n --arc-start: calc(var(--arc-center) - var(--arc-size) / 2);\n --arc-shift-delta: 0.0075;\n --clr-lines: rgba(255 255 255 / 0.25);\n\n anchor-name: --center;\n position: absolute;\n inset: 0;\n margin: auto;\n width: var(--radius);\n height: var(--radius);\n aspect-ratio: 1;\n transform: rotate(var(--rotation));\n transition: transform 700ms linear;\n display: grid;\n place-content: center;\n}\n\n.circular-gallery-wrapper h1 {\n margin: 0;\n text-align: center;\n font-size: clamp(1.2rem, 3.5vw + 0.045rem, 3rem);\n color: white;\n}\n\n.circular-gallery-wrapper > div {\n --card-i: var(--i);\n /* var(--cards) is injected dynamically by React */\n --arc-step: calc(var(--arc-size) / (var(--cards) - 1));\n --arc-shift: calc(var(--arc-shift-delta) * var(--d, 1));\n --card-offset-distance: calc(\n (\n var(--arc-start) + (var(--card-i) - 1) * var(--arc-step) +\n var(--arc-shift)\n ) *\n 100%\n );\n\n &:has(a:hover),\n &:target {\n --title-opacity: 1;\n }\n\n &:target {\n --zindex: 2;\n --center-opacity: 1;\n --center-scale: 1;\n --image-outline-color: var(--clr-lines);\n }\n\n &::before,\n &::after {\n content: '';\n position: fixed;\n position-anchor: --center;\n transform: rotate(calc(var(--rotation) * -1));\n transition-timing-function: ease-in-out;\n }\n\n /* large image in center of wrapper */\n &::before {\n position-area: span-all;\n width: calc(var(--radius));\n aspect-ratio: 1;\n border-radius: 9in;\n background: var(--bg-img);\n box-sizing: border-box;\n outline: 10px solid var(--clr-lines);\n outline-offset: -10px;\n background-size: cover;\n background-repeat: no-repeat;\n background-attachment: fixed;\n opacity: var(--center-opacity, 0);\n scale: var(--center-scale, 0);\n pointer-events: none;\n transition-property: scale, opacity;\n transition-duration: 300ms, 150ms;\n }\n\n /* image title - over thumb */\n &::after {\n content: attr(data-title);\n position-anchor: --card;\n position-area: center span-all;\n z-index: 2;\n pointer-events: none;\n opacity: var(--title-opacity, 0);\n transition-property: opacity, transform;\n transition-duration: 150ms;\n border: 1px solid rgb(255 255 255 / 0.75);\n background: rgb(0 0 0 / 0.25);\n color: white;\n backdrop-filter: blur(3px);\n padding: 0.25em 1em;\n border-radius: 5px;\n font-size: clamp(0.6rem, 1vw + 0.045rem, 0.85rem);\n @starting-style {\n opacity: 0;\n }\n }\n\n /* links with images are placed in a circle */\n a {\n position: absolute;\n display: block;\n width: var(--card-width);\n aspect-ratio: 4/6;\n border-radius: var(--card-border-radius);\n border: 2px solid transparent;\n offset-path: circle(var(--radius) at 50% 50%);\n offset-distance: var(--card-offset-distance);\n offset-rotate: auto;\n offset-anchor: 50% 0%;\n transition: offset var(--card-trans-duration) var(--card-trans-easing);\n z-index: var(--zindex, 1);\n anchor-name: --card;\n }\n\n a img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n border-radius: inherit;\n outline: 5px solid var(--image-outline-color, transparent);\n outline-offset: -5px;\n transition: outline 300ms ease-in-out;\n }\n}\n\n/* ============================================================\n FORWARD siblings (clockwise / +)\n ============================================================ */\n/* +1 */\n.circular-gallery-wrapper:has(> *:hover) > *:hover + *,\n.circular-gallery-wrapper:has(> :last-child:hover) > :nth-child(1) {\n --d: 3;\n}\n\n/* +2 */\n.circular-gallery-wrapper:has(> *:hover) > *:hover + * + *,\n.circular-gallery-wrapper:has(> :last-child:hover) > :nth-child(2),\n.circular-gallery-wrapper:has(> :nth-last-child(2):hover) > :nth-child(1) {\n --d: 2;\n}\n\n/* +3 */\n.circular-gallery-wrapper:has(> *:hover) > *:hover + * + * + *,\n.circular-gallery-wrapper:has(> :last-child:hover) > :nth-child(3),\n.circular-gallery-wrapper:has(> :nth-last-child(2):hover) > :nth-child(2),\n.circular-gallery-wrapper:has(> :nth-last-child(3):hover) > :nth-child(1) {\n --d: 1;\n}\n\n/* +4 */\n.circular-gallery-wrapper:has(> *:hover) > *:hover + * + * + * + *,\n.circular-gallery-wrapper:has(> :last-child:hover) > :nth-child(4),\n.circular-gallery-wrapper:has(> :nth-last-child(2):hover) > :nth-child(3),\n.circular-gallery-wrapper:has(> :nth-last-child(3):hover) > :nth-child(2),\n.circular-gallery-wrapper:has(> :nth-last-child(4):hover) > :nth-child(1) {\n --d: 0.5;\n}\n\n/* ============================================================\n BACKWARD siblings (counter-clockwise / −)\n ============================================================ */\n/* −1 */\n.circular-gallery-wrapper *:has(+ *:hover),\n.circular-gallery-wrapper:has(> :nth-child(1):hover) :nth-last-child(1) {\n --d: -3;\n}\n\n/* −2 */\n.circular-gallery-wrapper *:has(+ * + *:hover),\n.circular-gallery-wrapper:has(> :nth-child(1):hover) :nth-last-child(2),\n.circular-gallery-wrapper:has(> :nth-child(2):hover) :nth-last-child(1) {\n --d: -2;\n}\n\n/* −3 */\n.circular-gallery-wrapper *:has(+ * + * + *:hover),\n.circular-gallery-wrapper:has(> :nth-child(1):hover) :nth-last-child(3),\n.circular-gallery-wrapper:has(> :nth-child(2):hover) :nth-last-child(2),\n.circular-gallery-wrapper:has(> :nth-child(3):hover) :nth-last-child(1) {\n --d: -1;\n}\n\n/* −4 */\n.circular-gallery-wrapper *:has(+ * + * + * + *:hover),\n.circular-gallery-wrapper:has(> :nth-child(1):hover) :nth-last-child(4),\n.circular-gallery-wrapper:has(> :nth-child(2):hover) :nth-last-child(3),\n.circular-gallery-wrapper:has(> :nth-child(3):hover) :nth-last-child(2),\n.circular-gallery-wrapper:has(> :nth-child(4):hover) :nth-last-child(1) {\n --d: -0.5;\n}\n", "type": "registry:ui" } ] }