Carousel Composer
ilinxa/carousel-composerFreeBlock
Multi-item media post composer — drag in photos and videos, reorder them on a rail, and edit each through a shared editor panel.
Install it
npx shadcn@latest add https://ui.ilinxa.com/r/carousel-composer.jsonSource
1"use client";23import {4 forwardRef,5 useEffect,6 useImperativeHandle,7 useMemo,8 useRef,9 useState,10} from "react";11import {12 DndContext,13 KeyboardSensor,14 PointerSensor,15 closestCenter,16 useSensor,17 useSensors,18 type Announcements,19 type DragEndEvent,20} from "@dnd-kit/core";21import { arrayMove, sortableKeyboardCoordinates } from "@dnd-kit/sortable";22import { AlertCircle, X } from "lucide-react";23import { cn } from "@/lib/utils";24import {25 DEFAULT_CAROUSEL_LABELS,26 type CarouselComposerHandle,27 type CarouselComposerProps,28} from "./types";29import { useCarouselState } from "./hooks/use-carousel-state";30import { filesToItems } from "./lib/file-intake";31import { clampSources } from "./lib/clamp-sources";32import { aspectToCss, resolveAspect } from "./lib/aspect";33import { MediaDropzone } from "./parts/media-dropzone";34import { PreviewRail } from "./parts/preview-rail";35import { MainPreview } from "./parts/main-preview";36import { EditPanel } from "./parts/edit-panel";3738/**39 * carousel-composer — a multi-item media composer (Instagram-feed-post40 * semantics): drag-drop / browse one-or-more mixed photo+video files into an41 * ordered, reorderable rail with a main preview, and edit any item through a42 * single shared `media-editor` instance (loaded serially, never N at once).43 * Composes media-editor without modifying it.44 */45function CarouselComposerImpl(46 props: CarouselComposerProps,47 ref: React.Ref<CarouselComposerHandle>,48) {49 const {50 value,51 defaultValue,52 onChange,53 maxItems = 10,54 maxFileSizeMb = 50,55 accept,56 sources,57 aspect = "auto",58 editorProps,59 labels: labelOverrides,60 className,61 revokeOnUnmount,62 onItemAdd,63 onItemRemove,64 onReorder,65 onSelect,66 onEditOpen,67 onEditApply,68 onEditCancel,69 onValidationError,70 onMaxItemsExceeded,71 } = props;7273 const labels = useMemo(74 () => ({ ...DEFAULT_CAROUSEL_LABELS, ...labelOverrides }),75 [labelOverrides],76 );77 const acceptKinds = useMemo(78 () => accept ?? ["image" as const, "video" as const],79 [accept],80 );81 // v0.1: "library" is clamped out — intake is upload-only (drop / browse).82 const uploadEnabled = useMemo(83 () => clampSources(sources).includes("upload"),84 [sources],85 );8687 const [ingesting, setIngesting] = useState(false);88 const [errors, setErrors] = useState<string[]>([]);89 const [announce, setAnnounce] = useState("");9091// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from ilinxa
All 184 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Account Switcheraccount-switcher | ilinxa | Blocks | Free | 1 dep · 10 files | |
| Account Switcher (deprecated alias)account-switcher-01 | ilinxa | Blocks | Free | no deps | |
| Account Switcher — fixturesaccount-switcher-fixtures | ilinxa | Blocks | Free | no deps | |
| App Sidebarapp-sidebar | ilinxa | Blocks | Free | 1 dep · 37 files | |
| App Sidebar — fixturesapp-sidebar-fixtures | ilinxa | Blocks | Free | no deps | |
| Rich Text Editor (deprecated alias)article-body-01 | ilinxa | Blocks | Free | no deps | |
| Article Metaarticle-meta | ilinxa | Blocks | Free | 1 dep · 4 files | |
| Article Meta (deprecated alias)article-meta-01 | ilinxa | Blocks | Free | no deps |
