creativetimofficial--ui
27 行
6.5 KiB
JSON
27 行
6.5 KiB
JSON
{
|
|
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
"name": "ecommerce-sections-01",
|
|
"description": "Runway video spotlight with product cards",
|
|
"registryDependencies": [
|
|
"badge",
|
|
"button",
|
|
"card"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "creative-tim/blocks/ecommerce-sections-01/page.tsx",
|
|
"content": "\"use client\"\n\nimport { useEffect, useRef, useState } from \"react\"\nimport { Pause, Play, ShoppingBag, Shuffle } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\nconst PRODUCTS = [\n {\n id: \"card-1\",\n media: {\n src: \"https://images.unsplash.com/photo-1595777457583-95e059d581b8?q=80&w=400&h=400&auto=format&fit=crop\",\n alt: \"Satin Wrap Dress product thumbnail\",\n },\n eyebrow: \"Maison Aurore\",\n title: \"Satin Wrap Dress\",\n description: \"Fluid silhouette with tie waist and soft sheen.\",\n price: \"$215.00\",\n },\n {\n id: \"card-2\",\n media: {\n src: \"https://images.unsplash.com/photo-1591369822096-ffd140ec948f?q=80&w=400&h=400&auto=format&fit=crop\",\n alt: \"Structured Blazer product thumbnail\",\n },\n eyebrow: \"Atelier No. 9\",\n title: \"Structured Blazer\",\n description: \"Sharp shoulders, single-breasted, polished finish.\",\n price: \"$329.00\",\n },\n {\n id: \"card-3\",\n media: {\n src: \"https://images.unsplash.com/photo-1543163521-1bf539c55dd2?q=80&w=400&h=400&auto=format&fit=crop\",\n alt: \"Chunky Chelsea Boots product thumbnail\",\n },\n eyebrow: \"Linea Forte\",\n title: \"Chunky Chelsea Boots\",\n description: \"Elevated lug sole with elastic side panels.\",\n price: \"From $180.00\",\n },\n]\n\nexport default function EcommerceSectionsBlock() {\n const [isPlaying, setIsPlaying] = useState(true)\n const playerRef = useRef<any>(null)\n const [playerReady, setPlayerReady] = useState(false)\n\n useEffect(() => {\n const tag = document.createElement(\"script\")\n tag.src = \"https://www.youtube.com/iframe_api\"\n const firstScriptTag = document.getElementsByTagName(\"script\")[0]\n firstScriptTag.parentNode?.insertBefore(tag, firstScriptTag)\n ;(window as any).onYouTubeIframeAPIReady = () => {\n playerRef.current = new (window as any).YT.Player(\"youtube-player\", {\n videoId: \"YCIuEU2y8XI\",\n playerVars: {\n autoplay: 1,\n mute: 1,\n loop: 1,\n playlist: \"YCIuEU2y8XI\",\n controls: 0,\n showinfo: 0,\n modestbranding: 1,\n playsinline: 1,\n },\n events: {\n onReady: () => {\n setPlayerReady(true)\n },\n },\n })\n }\n\n return () => {\n if (playerRef.current) {\n playerRef.current.destroy()\n }\n }\n }, [])\n\n const togglePlay = () => {\n if (playerRef.current && playerReady) {\n if (isPlaying) {\n playerRef.current.pauseVideo()\n } else {\n playerRef.current.playVideo()\n }\n setIsPlaying(!isPlaying)\n }\n }\n\n return (\n <section className=\"relative w-full overflow-hidden rounded-xl\">\n <div className=\"relative aspect-[16/9] w-full lg:aspect-[16/9]\">\n <div\n id=\"youtube-player\"\n className=\"absolute inset-0 h-full w-full rounded-xl\"\n style={{\n pointerEvents: \"none\",\n }}\n />\n\n <div className=\"absolute inset-0 bg-gradient-to-t from-black/80 via-black/30 to-transparent\" />\n\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"absolute top-4 left-4 rounded-full bg-black/50 text-white backdrop-blur-sm hover:bg-black/70 hover:text-white lg:top-6 lg:left-6\"\n onClick={togglePlay}\n >\n {isPlaying ? (\n <Pause className=\"h-4 w-4\" />\n ) : (\n <Play className=\"h-4 w-4\" />\n )}\n </Button>\n\n <div className=\"absolute inset-x-0 bottom-0 space-y-6 p-4 lg:p-8\">\n <div className=\"mx-auto grid max-w-6xl gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {PRODUCTS.map((product) => (\n <div\n key={product.id}\n className=\"flex items-center gap-4 rounded-2xl bg-white p-4 shadow-lg dark:bg-white/95\"\n >\n <div className=\"h-16 w-16 flex-shrink-0 overflow-hidden rounded-lg\">\n <img\n src={product.media.src}\n alt={product.media.alt}\n className=\"h-full w-full object-cover\"\n />\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-xs font-medium tracking-wide text-gray-500 uppercase\">\n {product.eyebrow}\n </p>\n <h3 className=\"truncate font-semibold text-gray-900\">\n {product.title}\n </h3>\n <p className=\"font-semibold text-gray-900\">{product.price}</p>\n </div>\n\n <div className=\"flex flex-shrink-0 items-center gap-2\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-gray-600 hover:text-gray-900\"\n >\n <ShoppingBag className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-gray-600 hover:text-gray-900\"\n >\n <Shuffle className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n ))}\n </div>\n\n <div className=\"flex justify-center\">\n <Button\n variant=\"outline\"\n size=\"lg\"\n className=\"rounded-full border-white/80 bg-white/10 px-8 text-white backdrop-blur-sm hover:bg-white/20 hover:text-white\"\n >\n VIEW ALL PRODUCTS\n </Button>\n </div>\n </div>\n </div>\n </section>\n )\n}\n",
|
|
"type": "registry:page",
|
|
"target": "app/ecommerce-sections/page.tsx"
|
|
}
|
|
],
|
|
"meta": {
|
|
"iframeHeight": "900px",
|
|
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-center md:py-20 justify-center min-w-0",
|
|
"mobile": "component"
|
|
},
|
|
"categories": [
|
|
"ecommerce"
|
|
],
|
|
"type": "registry:block"
|
|
} |