{ "$schema": "https://ui.shadcn.com/schema/registry.json", "name": "ikui", "homepage": "https://ik-ui.pages.dev", "author": "wudi ", "items": [ { "name": "chart", "type": "registry:component", "title": "Chart", "description": "Recharts-based chart primitives (container, tooltip, legend) with theme-aware colors. Compose bar, area, line, pie, radar, and radial charts from a single config.", "files": [ { "path": "registry/ikui/chart.tsx", "type": "registry:component" } ], "dependencies": ["recharts"], "registryDependencies": [], "category": "display" }, { "name": "spark-chart", "type": "registry:component", "title": "Spark Chart", "description": "Dependency-free interactive line chart with a cursor-tracked tooltip, snap-to-point hover, reveal effect, and built-in X-axis labels.", "files": [ { "path": "registry/ikui/spark-chart.tsx", "type": "registry:component" } ], "dependencies": [], "registryDependencies": [], "category": "display" }, { "name": "qr-code", "type": "registry:component", "title": "QR Code", "description": "QR code generator with rounded finder patterns and dot-style data modules.", "files": [ { "path": "registry/ikui/qr-code.tsx", "type": "registry:component" } ], "dependencies": ["qrcode", "lucide-react"], "registryDependencies": [], "category": "display" }, { "name": "copy-button", "type": "registry:component", "title": "Copy Button", "description": "A copy-to-clipboard button with blur transition effect.", "files": [ { "path": "registry/ikui/copy-button.tsx", "type": "registry:component" } ], "dependencies": ["lucide-react"], "registryDependencies": [], "category": "button" }, { "name": "cascader", "type": "registry:component", "title": "Cascader", "description": "A column-based cascading dropdown for selecting a path through hierarchical data (region \u2192 city \u2192 district, category trees). Desktop popover / mobile drawer, keyboard navigable, controlled or uncontrolled, with clear and custom display rendering.", "files": [ { "path": "registry/ikui/cascader.tsx", "type": "registry:component" } ], "dependencies": ["lucide-react"], "registryDependencies": ["popover", "drawer", "use-mobile"], "category": "form" }, { "name": "password-input", "type": "registry:component", "title": "Password Input", "description": "A password field with a trailing show/hide toggle, composed from the input-group primitive. Spreads native input props (name, value, onChange, placeholder).", "files": [ { "path": "registry/ikui/password-input.tsx", "type": "registry:component" } ], "dependencies": ["lucide-react"], "registryDependencies": ["input-group"], "category": "form" }, { "name": "tree", "type": "registry:component", "title": "Tree", "description": "A data-driven hierarchical tree view of folders and leaves with selection, expand/collapse, per-node icons, an actions slot, and a custom renderItem. Self-managed expand state, animated open/close, ARIA roving-tabindex keyboard navigation, and native drag-and-drop to reorder or re-parent nodes via onDocumentDrag. Controlled or uncontrolled selection reported through onSelectChange.", "files": [ { "path": "registry/ikui/tree.tsx", "type": "registry:component" } ], "dependencies": ["lucide-react"], "registryDependencies": [], "category": "display" }, { "name": "date-range-picker", "type": "registry:component", "title": "Date Range Picker", "description": "A popover date range picker with a quick-preset side panel (Today, Last 7 days, This month, …), a two-month calendar with live hover-range preview, min/max clamping, and a clearable trigger. Controlled or uncontrolled, with configurable presets and date-fns locale.", "files": [ { "path": "registry/ikui/date-range-picker.tsx", "type": "registry:component" } ], "dependencies": ["date-fns", "react-day-picker", "lucide-react"], "registryDependencies": ["calendar", "popover", "button"], "category": "form" }, { "name": "heatmap-calendar", "type": "registry:component", "title": "Heatmap Calendar", "description": "A GitHub-style contribution heatmap. Buckets dated values into color levels across a weeks × weekdays grid, with month/weekday axis labels, a Less→More legend, a shared hover tooltip, and custom palettes. Driven purely by data — no card or title scaffolding.", "files": [ { "path": "registry/ikui/heatmap-calendar.tsx", "type": "registry:component" } ], "dependencies": ["date-fns"], "registryDependencies": ["tooltip"], "category": "display" }, { "name": "audio-waveform", "type": "registry:component", "title": "Audio Waveform", "description": "A static, width-explicit waveform for timelines. Decodes audio (URL / Blob / AudioBuffer) into normalized peaks \u2014 or takes precomputed peaks \u2014 and renders mirrored canvas bars at any pixel width, with optional played-progress coloring. Backs the waveform-player.", "files": [ { "path": "registry/ikui/audio-waveform.tsx", "type": "registry:component" } ], "dependencies": [], "registryDependencies": [], "category": "audio" }, { "name": "waveform-player", "type": "registry:component", "title": "Waveform Player", "description": "A compact audio player built on audio-waveform: play/pause, elapsed and total time, played-progress coloring, and click/drag-to-seek on the waveform.", "files": [ { "path": "registry/ikui/waveform-player.tsx", "type": "registry:component" } ], "dependencies": ["lucide-react"], "registryDependencies": ["button", "@ikui/audio-waveform"], "category": "audio" }, { "name": "video-thumbnail-cache", "type": "registry:lib", "title": "Video Thumbnail Cache", "description": "Decode video frames via mediabunny on demand and cache them as ImageBitmaps. Backs the thumbnail-strip and segmented-timeline-strip components.", "files": [ { "path": "registry/ikui/video-thumbnail-cache.ts", "type": "registry:lib" } ], "dependencies": ["mediabunny"], "registryDependencies": [], "category": "video" }, { "name": "thumbnail-strip", "type": "registry:component", "title": "Thumbnail Strip", "description": "A viewport-virtualized canvas strip rendering video thumbnails along a horizontal timeline. Pairs with video-thumbnail-cache for the frame decoding.", "files": [ { "path": "registry/ikui/thumbnail-strip.tsx", "type": "registry:component" } ], "dependencies": [], "registryDependencies": ["@ikui/video-thumbnail-cache"], "category": "video" }, { "name": "segmented-timeline-strip", "type": "registry:component", "title": "Segmented Timeline Strip", "description": "Multi-clip timeline overview built by composing one thumbnail-strip per segment with DOM chrome (active border, dim mask, label, playhead, total duration badge) and click-to-seek.", "files": [ { "path": "registry/ikui/segmented-timeline-strip.tsx", "type": "registry:component" } ], "dependencies": [], "registryDependencies": [ "@ikui/thumbnail-strip", "@ikui/video-thumbnail-cache" ], "category": "video" }, { "name": "timeline-ruler", "type": "registry:component", "title": "Timeline Ruler", "description": "A pure, zoom-aware, horizontally-scrollable time ruler: adaptive tick density and MM:SS / frame labels, with viewport virtualization. Just the scale \u2014 playhead, seeking, and tracks are left to the consumer.", "files": [ { "path": "registry/ikui/timeline-ruler.tsx", "type": "registry:component" } ], "dependencies": [], "registryDependencies": [], "category": "timeline" }, { "name": "timeline-element", "type": "registry:component", "title": "Timeline Element", "description": "A positioned, trimmable timeline clip: places itself on a track by time (startTime/duration \u00d7 pixelsPerSecond \u00d7 zoom, the same basis as timeline-ruler) and renders any content inside \u2014 an audio waveform, a thumbnail strip, a label. Selectable, with left/right trim handles that emit the new geometry. The track, playhead, and seeking are left to the consumer.", "files": [ { "path": "registry/ikui/timeline-element.tsx", "type": "registry:component" } ], "dependencies": [], "registryDependencies": [], "category": "timeline" }, { "name": "timeline-playhead", "type": "registry:component", "title": "Timeline Playhead", "description": "A draggable timeline playhead: a vertical line with a top knob, positioned by time (currentTime \u00d7 pixelsPerSecond \u00d7 zoom, the same basis as timeline-ruler) and scrubbable. Drag it to seek; it scrolls with the tracks it sits over. Spans whatever container it is placed in. The playback clock and click-to-seek on the tracks are left to the consumer.", "files": [ { "path": "registry/ikui/timeline-playhead.tsx", "type": "registry:component" } ], "dependencies": [], "registryDependencies": [], "category": "timeline" }, { "name": "audio-trimmer", "type": "registry:block", "title": "Audio Trimmer", "description": "A business composition built from the timeline primitives: trim an audio clip with the timeline-element handles, then play back only the trimmed [startTime, startTime + duration] window. The playhead follows playback, the waveform colors in as it plays, and an In / Out / length readout tracks the selection.", "files": [ { "path": "registry/ikui/blocks/audio-trimmer.tsx", "type": "registry:block" } ], "dependencies": ["lucide-react", "mediabunny"], "registryDependencies": [ "@ikui/timeline-ruler", "@ikui/timeline-element", "@ikui/timeline-playhead", "@ikui/audio-waveform", "button", "card", "slider", "scroll-area", "skeleton" ], "category": "blocks", "categories": ["audio"] }, { "name": "video-trimmer", "type": "registry:block", "title": "Video Trimmer", "description": "A business composition built from the timeline primitives: trim a video clip with the timeline-element handles over a thumbnail strip, then play back only the trimmed [startTime, startTime + duration] window in the preview. The playhead follows playback, the frames outside the selection dim, and an In / Out / length readout tracks the selection. Export cuts the window to an MP4 via mediabunny.", "files": [ { "path": "registry/ikui/blocks/video-trimmer.tsx", "type": "registry:block" } ], "dependencies": ["lucide-react", "mediabunny"], "registryDependencies": [ "@ikui/timeline-ruler", "@ikui/timeline-element", "@ikui/timeline-playhead", "@ikui/thumbnail-strip", "button", "card", "slider", "scroll-area", "skeleton" ], "category": "blocks", "categories": ["video"], "meta": { "iframeHeight": 640 } }, { "name": "media-compressor", "type": "registry:block", "title": "Media Compressor", "description": "A business composition over mediabunny's Conversion: load an audio or video file, pick a quality preset and (for video) a target resolution, then re-encode to a smaller MP4 \u2014 video as H.264 + AAC, audio-only as AAC. A before/after readout shows the original size, the compressed size, and the percentage saved; the result auto-downloads.", "files": [ { "path": "registry/ikui/blocks/media-compressor.tsx", "type": "registry:block" } ], "dependencies": ["lucide-react", "mediabunny"], "registryDependencies": [ "@ikui/waveform-player", "button", "card", "select", "skeleton" ], "category": "blocks", "categories": ["video", "audio"], "meta": { "iframeHeight": 560 } }, { "name": "image-compare", "type": "registry:component", "title": "Image Compare", "description": "A before/after image comparison slider. Drag (or hover) to reveal one image over another, horizontally or vertically, with optional labels, a custom handle, and a loading skeleton. Responsive out of the box.", "files": [ { "path": "registry/ikui/image-compare.tsx", "type": "registry:component" } ], "dependencies": ["lucide-react"], "registryDependencies": [], "category": "image" }, { "name": "image-crop", "type": "registry:component", "title": "Image Crop", "description": "A responsive, pointer- and keyboard-driven image cropping tool. Draw, drag, and 8-way resize a crop over any image or video, with fixed aspect ratios, circular crops, min/max bounds, rule-of-thirds guides, and percent/pixel crop callbacks. Self-contained Tailwind styling, zero dependencies.", "files": [ { "path": "registry/ikui/image-crop.tsx", "type": "registry:component" } ], "dependencies": [], "registryDependencies": [], "category": "image" }, { "name": "image-grid", "type": "registry:component", "title": "Image Grid", "description": "An adaptive photo grid that lays out 1 to 9 images in WeChat-moments style: 1\u20138 use hand-tuned collage layouts on a 6\u00d76 grid (every cell stays a healthy size) and 9 fills a uniform 3\u00d73 grid, with the container always staying square. Responsive, dependency-free, with optional keyboard-accessible per-cell click and custom rendering for lightbox integration.", "files": [ { "path": "registry/ikui/image-grid.tsx", "type": "registry:component" } ], "dependencies": [], "registryDependencies": [], "category": "image" }, { "name": "image-cropper", "type": "registry:block", "title": "Image Cropper", "description": "A business composition built on the image-crop primitive: load an image and frame a crop inline, with the selection rendered live as a real image in the preview beside it \u2014 that preview is the cropped result. Switch to a circular avatar crop, rotate the source in 90\u00b0 steps, or lock the box to an aspect-ratio preset; the output is validated against min/max source-pixel bounds (the readout turns red until it fits) and downloads at full resolution.", "files": [ { "path": "registry/ikui/blocks/image-cropper.tsx", "type": "registry:block" } ], "dependencies": ["lucide-react"], "registryDependencies": ["@ikui/image-crop", "button", "card"], "category": "blocks", "categories": ["image"], "meta": { "iframeHeight": 580 } }, { "name": "image-editor", "type": "registry:block", "title": "Image Editor", "description": "A full single-image editor built on fabric.js, wrapped in ikui's Base UI toolbar. Annotate with text, shapes, arrows, and image overlays; free-draw; pixelate a region for a privacy mosaic; tune brightness, contrast, and saturation; apply filter presets; crop (via the image-crop primitive) and resize; rotate, flip, undo, and redo; then export to PNG or JPEG. The fabric canvas is created from a lazily-imported module inside an effect, so the browser-only library never runs during SSR.", "files": [ { "path": "registry/ikui/blocks/image-editor.tsx", "type": "registry:block" } ], "dependencies": [ "fabric", "lucide-react", "@dnd-kit/core", "@dnd-kit/sortable", "@dnd-kit/utilities" ], "registryDependencies": [ "@ikui/image-crop", "alert-dialog", "button", "card", "dropdown-menu", "field", "popover", "resizable", "select", "slider", "toggle-group" ], "category": "blocks", "categories": ["image"], "meta": { "iframeHeight": 700 } }, { "name": "particle-image", "type": "registry:component", "title": "Particle Image", "description": "Turn any image into an interactive particle field that scatters from the pointer and settles back toward its origin.", "files": [ { "path": "registry/ikui/particle-image.tsx", "type": "registry:component" } ], "dependencies": [], "registryDependencies": [], "category": "image" }, { "name": "storyboard-timeline", "type": "registry:block", "title": "Storyboard Timeline", "description": "A business composition built from the timeline primitives: lays out a mix of video and image shots end-to-end on a single absolute time axis, each shot wrapped in its own card (header label, duration, type tag) over a shared timeline-ruler, with a draggable timeline-playhead that follows playback across shots. Videos play in the preview and are driven by the media clock; image stills advance on an rAF clock for their set duration. Zoom widens the strips and ruler while the timeline scrolls; the preview swaps source at shot boundaries.", "files": [ { "path": "registry/ikui/blocks/storyboard-timeline.tsx", "type": "registry:block" } ], "dependencies": ["lucide-react"], "registryDependencies": [ "@ikui/timeline-ruler", "@ikui/timeline-playhead", "@ikui/thumbnail-strip", "@ikui/video-thumbnail-cache", "button", "card", "slider", "scroll-area", "skeleton" ], "category": "blocks", "categories": ["video"], "meta": { "iframeHeight": 560 } }, { "name": "video-frame-extractor", "type": "registry:block", "title": "Video Frame Extractor", "description": "A business composition over mediabunny's VideoSampleSink: load a video, then grab the still under the playhead at native resolution. A ruler aligned to the real duration sits above a continuous filmstrip carrying a playhead that tracks playback; the `