Image
tool-ui/imageFreeBlock
Display images with metadata and attribution.
See it running
Open the demo on tool-ui
www.tool-ui.com/components/imageInstall it
npx shadcn@latest add https://www.tool-ui.com/r/image.jsonSource
1"use client";23import * as React from "react";4import { cn } from "./_adapter";56import {7 RATIO_CLASS_MAP,8 getFitClass,9 openSafeNavigationHref,10 resolveSafeNavigationHref,11 sanitizeHref,12} from "../shared/media";13import type { SerializableImage, Source } from "./schema";1415const FALLBACK_LOCALE = "en-US";1617export interface ImageProps extends SerializableImage {18 className?: string;19 onNavigate?: (href: string, image: SerializableImage) => void;20}2122export function Image(props: ImageProps) {23 const { className, onNavigate, ...serializable } = props;2425 const {26 id,27 src,28 alt,29 title,30 href: rawHref,31 domain,32 ratio = "auto",33 fit = "cover",34 source,35 locale: providedLocale,36 } = serializable;3738 const locale = providedLocale ?? FALLBACK_LOCALE;39 const sanitizedHref = sanitizeHref(rawHref);40 const resolvedSourceUrl = sanitizeHref(source?.url);4142 const imageData: SerializableImage = {43 ...serializable,44 href: sanitizedHref,45 source: source ? { ...source, url: resolvedSourceUrl } : undefined,46 locale,47 };4849 const sourceLabel = source?.label ?? domain;50 const fallbackInitial = (sourceLabel ?? "").trim().charAt(0).toUpperCase();51 const hasSource = Boolean(sourceLabel || source?.iconUrl);5253 const handleSourceClick = (event: React.MouseEvent<HTMLButtonElement>) => {54 event.preventDefault();55 event.stopPropagation();56 const targetUrl = resolveSafeNavigationHref(57 resolvedSourceUrl,58 source?.url,59 sanitizedHref,60 src,61 );62 if (!targetUrl) return;63 if (onNavigate) {64 onNavigate(targetUrl, imageData);65 } else {66 openSafeNavigationHref(targetUrl);67 }68 };6970 const handleImageClick = () => {71 if (!sanitizedHref) return;72 if (onNavigate) {73 onNavigate(sanitizedHref, imageData);74 } else {75 openSafeNavigationHref(sanitizedHref);76 }77 };7879 const hasMetadata = title || hasSource;8081 return (82 <article83 className={cn("relative w-full max-w-md min-w-80", className)}84 lang={locale}85 data-tool-ui-id={id}86 data-slot="image"87 >88 <div89 className={cn(90 "group @container relative isolate flex w-full min-w-0 flex-col overflow-hidden rounded-xl",91 "border-border bg-card border text-sm shadow-xs",92 )}93 >94 <>95 <div96 className={cn(97 "bg-muted group relative w-full overflow-hidden",98// … truncated
What it pulls in
npm packages
Files it writes
More from tool-ui
All 27 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Approval Cardapproval-card | tool-ui | Blocks | Free | 2 deps · 11 files | |
| Audioaudio | tool-ui | Blocks | Free | 2 deps · 9 files | |
| Chartchart | tool-ui | Blocks | Free | 2 deps · 8 files | |
| Citationcitation | tool-ui | Blocks | Free | 2 deps · 15 files | |
| Code Blockcode-block | tool-ui | Blocks | Free | 3 deps · 11 files | |
| Code Diffcode-diff | tool-ui | Blocks | Free | 3 deps · 10 files | |
| Data Tabledata-table | tool-ui | Blocks | Free | 1 dep · 17 files | |
| Geo Mapgeo-map | tool-ui | Blocks | Free | 4 deps · 12 files |
