MynaUI
No results found.
Theme
Toggle Theme (Dark)
Documentation
Getting Started
Design System
Changelog
Icons
Elements
Accordion
Alert
Alert Dialog
Avatar
Avatar Groups
Badge
Breadcrumb
Button
Button Groups
Calendar
Combobox
Command
Context Menu
Data Table
Dialog
Drawer
Dropdown Menu
Menubar
Pagination
Popover
Progress
Rating
Sheet
Skeleton
Spinner
Table
Tabs
Toast
Toggle and Toggle Group
Tooltip
Forms
Checkbox
Date Picker
Input
Input OTP
Radio
Select
Slider
Switch
Textarea
Marketing
404
Banners
Blog List
Blog Post
Call to Action
Cookies
FAQ
Features
Footer
Gallery
Header
Hero
Newsletters
Statistics
Testimonial Logos
Application
App Headers
App Sheets
Application Dialogs
Card Headers
Cards
Chat
Code Block
Containers
Dividers
Empty States
Forgot Password
Login
Notifications
Registration
Section Headers
Documentation
  • Getting Started
  • Copybook
  • Design System
  • Icons
  • Changelog
  • Figma
  • Request Components
  • Request Icons
Elements
  • Accordion
  • Alert
  • Alert Dialog
  • Avatar
  • Avatar Groups
  • Badge
  • Breadcrumb
  • Button
  • Button Groups
  • Calendar
  • Combobox
  • Command
  • Context Menu
  • Data Table
  • Dialog
  • Drawer
  • Dropdown Menu
  • Menubar
  • Pagination
  • Popover
  • Progress
  • Rating
  • Sheet
  • Skeleton
  • Spinner
  • Table
  • Tabs
  • Toast
  • Toggle and Toggle Group
  • Tooltip
Forms
  • Checkbox
  • Date Picker
  • Input
  • Input OTP
  • Radio
  • Select
  • Slider
  • Switch
  • Textarea
Marketing
  • 404
  • Banners
  • Blog List
  • Blog Post
  • Call to Action
  • Cookies
  • FAQ
  • Features
  • Footer
  • Gallery
  • Header
  • Hero
  • Newsletters
  • Statistics
  • Testimonial Logos
Application
  • App Headers
  • App Sheets
  • Application Dialogs
  • Card Headers
  • Cards
  • Chat
  • Code Block
  • Containers
  • Dividers
  • Empty States
  • Forgot Password
  • Login
  • Notifications
  • Registration
  • Section Headers
Newsletter

Get the latest news and updates from MynaUI

Subscribe for Updates

Gallery

Responsive image and video galleries with slideshow navigation.

import {
  Carousel,
  CarouselContent,
  CarouselItem,
  CarouselNext,
  CarouselPrevious,
} from "@/components/ui/carousel"

const slides = [
  { src: "/images/gradients/lilac.webp", alt: "Soft blue and indigo gradient", caption: "Blue hour" },
  { src: "/images/gradients/coral.webp", alt: "Soft coral and amber gradient", caption: "First light" },
  { src: "/images/gradients/aurora.webp", alt: "Soft violet and pink gradient", caption: "Night bloom" },
]

export default function GallerySlideshow() {
  return (
    <section className="mx-auto max-w-5xl">
      <div className="mb-6 flex items-end justify-between gap-6">
        <div>
          <p className="text-sm font-medium text-muted-foreground">Journal 04</p>
          <h2 className="mt-1 text-2xl font-semibold tracking-tight">Scenes from the road</h2>
        </div>
        <p className="hidden max-w-xs text-sm text-muted-foreground md:block">
          A visual diary from twelve days moving west.
        </p>
      </div>
      <Carousel opts={{ loop: true }} className="px-10 md:px-12">
        <CarouselContent>
          {slides.map((slide, index) => (
            <CarouselItem key={slide.src}>
              <figure className="relative aspect-[16/9] overflow-hidden rounded-lg bg-muted">
                <img src={slide.src} alt={slide.alt} className="size-full object-cover" />
                <figcaption className="absolute inset-x-0 bottom-0 bg-gradient-to-t from-foreground/70 to-transparent p-5 pt-16 text-sm text-background">
                  {String(index + 1).padStart(2, "0")} — {slide.caption}
                </figcaption>
              </figure>
            </CarouselItem>
          ))}
        </CarouselContent>
        <CarouselPrevious className="left-0" />
        <CarouselNext className="right-0" />
      </Carousel>
    </section>
  )
}
const images = [
  { src: "/images/gradients/lilac.webp", alt: "Blue and indigo gradient", className: "md:col-span-2 md:row-span-2" },
  { src: "/images/gradients/coral.webp", alt: "Coral and amber gradient", className: "" },
  { src: "/images/gradients/aurora.webp", alt: "Violet and pink gradient", className: "" },
  { src: "/images/gradients/ember.webp", alt: "Orange and red gradient", className: "md:col-span-2" },
]

export default function ImageGallery() {
  return (
    <section className="mx-auto max-w-6xl">
      <div className="mb-8 max-w-xl">
        <p className="text-sm font-medium text-muted-foreground">Selected work</p>
        <h2 className="mt-2 text-3xl font-semibold tracking-tight">A study in light and motion</h2>
      </div>
      <div className="grid auto-rows-[14rem] grid-cols-1 gap-3 md:grid-cols-4">
        {images.map((image) => (
          <figure
            key={image.src}
            className={`group relative overflow-hidden rounded-lg bg-muted ${image.className}`}
          >
            <img
              src={image.src}
              alt={image.alt}
              loading="lazy"
              className="size-full object-cover transition-transform duration-500 group-hover:scale-105"
            />
            <figcaption className="sr-only">{image.alt}</figcaption>
          </figure>
        ))}
      </div>
    </section>
  )
}
const media = [
  { src: "/images/gradients/lilac.webp", alt: "Blue hour study", type: "Image", duration: "" },
  {
    src: "https://videos.pexels.com/video-files/2715412/2715412-hd_1920_1080_30fps.mp4",
    poster: "/images/gradients/ember.webp",
    alt: "Sparks moving through smoke",
    type: "Film",
    duration: "01:42",
  },
  { src: "/images/gradients/aurora.webp", alt: "Night bloom study", type: "Image", duration: "" },
]

export default function MixedMediaGallery() {
  return (
    <section className="mx-auto max-w-6xl">
      <div className="mb-6 flex items-end justify-between gap-4">
        <div>
          <p className="text-sm text-muted-foreground">Campaign archive</p>
          <h2 className="mt-1 text-2xl font-semibold tracking-tight">Still & moving</h2>
        </div>
        <a href="#" className="text-sm font-medium underline-offset-4 hover:underline">View all work</a>
      </div>
      <div className="grid gap-6 md:grid-cols-3">
        {media.map((item) => (
          <article key={item.src} className="group">
            <div className="relative aspect-[4/5] overflow-hidden rounded-lg bg-muted">
              {item.type === "Film" ? (
                <video
                  src={item.src}
                  poster={item.poster}
                  autoPlay
                  muted
                  loop
                  playsInline
                  controls
                  aria-label={item.alt}
                  className="size-full object-cover transition-transform duration-500 group-hover:scale-105"
                />
              ) : (
                <img
                  src={item.src}
                  alt={item.alt}
                  className="size-full object-cover transition-transform duration-500 group-hover:scale-105"
                />
              )}
            </div>
            <div className="mt-3 flex items-center justify-between gap-4 text-sm">
              <p className="font-medium">{item.alt}</p>
              <p className="text-muted-foreground">{item.duration || item.type}</p>
            </div>
          </article>
        ))}
      </div>
    </section>
  )
}

Not affiliated with Figma, TailwindCSS or shadcn/ui.