This component no longer exists. It was in deso-ui’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-06 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
Post Image
deso-ui/post-imageRemovedBlock
A component for displaying images in a post, with support for bento grids and carousels.
Install it
npx shadcn@latest add https://ui.deso.com/r/post-image.jsonSource
1'use client';23import * as React from 'react';4import {5 Carousel,6 CarouselContent,7 CarouselItem,8 CarouselNext,9 CarouselPrevious,10 type CarouselApi,11} from '@/components/ui/carousel';12import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogClose } from '@/components/ui/dialog';13import { cn } from '@/lib/utils/deso';14import { PostEngagement } from './post-engagement';15import { Button } from '../ui/button';16import { Blurhash } from 'react-blurhash';17import { Lock } from 'lucide-react';1819export interface PostImageActions {20 likes: { count: number; active: boolean };21 reposts: { count: number; active: boolean };22 diamonds: { count: number; value: string; active: boolean };23 comments: { count: number };24 views?: { count: number };25 onLike: () => void;26 onRepost: () => void;27 onDiamond: () => void;28 onComment: () => void;29}3031export interface PostImageProps {32 images: string[];33 variant?: 'default' | 'carousel' | 'bento' | 'blurred' | 'unlockable';34 className?: string;35 onImageClick?: (index: number) => void;36 withModal?: boolean;37 withModalActions?: PostImageActions;38 blurhash?: string;39 onUnlock?: () => void;40}4142export function PostImage({43 images,44 variant,45 className,46 onImageClick,47 withModal = true,48 withModalActions,49 blurhash,50 onUnlock,51}: PostImageProps) {52 const [modalOpen, setModalOpen] = React.useState(false);53 const [selectedIndex, setSelectedIndex] = React.useState(0);54 const [api, setApi] = React.useState<CarouselApi>();55 const [current, setCurrent] = React.useState(0);56 const [isUnlocked, setIsUnlocked] = React.useState(variant !== 'unlockable');5758 if (!images || images.length === 0) {59 return null;60 }6162 const handleUnlockClick = () => {63 onUnlock?.();64 setIsUnlocked(true);65 };6667 const handleImageClick = (index: number) => {68 onImageClick?.(index);69 if (withModal) {70 setSelectedIndex(index);71 setModalOpen(true);72 }73 };7475 React.useEffect(() => {76 if (!api) return;77 setCurrent(api.selectedScrollSnap());78 api.on('select', () => setCurrent(api.selectedScrollSnap()));79 }, [api]);8081 const imageCount = images.length;8283 const ImageOrBlurComponent = ({84 src,85 index,86 className: imgClassName,87 }: {88 src: string;89 index: number;90 className?: string;91 }) => {92 if (isUnlocked) {93 return (94 <img95 src={src}96 alt={`Post image ${index + 1}`}97 className={cn(98// … truncated
