ComponentsInteractive Image Selector

Interactive Image Selector

Select images by clicking on them, delete selected images using the trash icon, and reset the gallery with the refresh button. Inspired by the smooth and intuitive photo gallery experience of iPhones, this interface features seamless animations for an engaging user experience.

Gallery item 1
Gallery item 2
Gallery item 3
Gallery item 4
Gallery item 5
Gallery item 6

Code

1

Install with shadcn

Terminal

npx shadcn@latest add @smoothui/interactive-image-selector

Or install the demo

Terminal

npx shadcn@latest add @smoothui/interactive-image-selector-demo

How to use

Demo.tsx

"use client"

import React, { useState } from "react"

import InteractiveImageSelector, {
  ImageData,
} from "@/components/smoothui/ui/InteractiveImageSelector"

const demoImages: ImageData[] = [
  {
    id: 1,
    src: "https://res.cloudinary.com/dyzxnud9z/image/upload/w_300,ar_1:1,c_fill,g_auto/v1758270763/smoothui/womanorange.webp",
  },
  {
    id: 2,
    src: "https://res.cloudinary.com/dyzxnud9z/image/upload/w_300,ar_1:1,c_fill,g_auto/v1758209962/smoothui/girl-nature.webp",
  },
  {
    id: 3,
    src: "https://res.cloudinary.com/dyzxnud9z/image/upload/w_300,ar_1:1,c_fill,g_auto/v1758271088/smoothui/metrowoman.webp",
  },
  {
    id: 4,
    src: "https://res.cloudinary.com/dyzxnud9z/image/upload/w_300,ar_1:1,c_fill,g_auto/v1758271134/smoothui/designerworking.webp",
  },
  {
    id: 5,
    src: "https://res.cloudinary.com/dyzxnud9z/image/upload/w_300,ar_1:1,c_fill,g_auto/v1758271305/smoothui/girlglass.webp",
  },
  {
    id: 6,
    src: "https://res.cloudinary.com/dyzxnud9z/image/upload/w_300,ar_1:1,c_fill,g_auto/v1758271369/smoothui/manup.webp",
  },
]

const InteractiveImageSelectorDemo = () => {
  const [selected, setSelected] = useState<number[]>([])
  const [images, setImages] = useState<ImageData[]>(demoImages)

  return (
    <InteractiveImageSelector
      images={images}
      selectedImages={selected}
      onChange={setSelected}
      onDelete={(deleted) =>
        setImages((imgs) => imgs.filter((img) => !deleted.includes(img.id)))
      }
      onShare={(selected) => alert(`Share images: ${selected.join(", ")}`)}
      selectable={false}
    />
  )
}

export default InteractiveImageSelectorDemo

Props

PropTypeDefault
images?
ImageData[]
-
selectedImages?
number[]
-
onChange?
(selected: number[]) => void
-
onDelete?
(deleted: number[]) => void
-
onShare?
(selected: number[]) => void
-
className?
string
-
title?
string
-
selectable?
boolean
-