comparison
kibo-ui-registry/comparisonFreeComponent
A slider-based component for comparing two items in an overlay.
Live preview
live · rendered by the registry
Rendered by Kibo UI Registry on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://www.kibo-ui.com/r/comparison.jsonSource
1"use client";23import { GripVerticalIcon } from "lucide-react";4import {5 type MotionValue,6 motion,7 useMotionValue,8 useSpring,9 useTransform,10} from "motion/react";11import {12 type ComponentProps,13 createContext,14 type HTMLAttributes,15 type MouseEventHandler,16 type ReactNode,17 type TouchEventHandler,18 useContext,19 useState,20} from "react";21import { cn } from "@/lib/utils";2223type ImageComparisonContextType = {24 sliderPosition: number;25 setSliderPosition: (pos: number) => void;26 motionSliderPosition: MotionValue<number>;27 mode: "hover" | "drag";28};2930const ImageComparisonContext = createContext<31 ImageComparisonContextType | undefined32>(undefined);3334const useImageComparisonContext = () => {35 const context = useContext(ImageComparisonContext);3637 if (!context) {38 throw new Error(39 "useImageComparisonContext must be used within a ImageComparison"40 );41 }4243 return context;44};4546export type ComparisonProps = HTMLAttributes<HTMLDivElement> & {47 mode?: "hover" | "drag";48 onDragStart?: () => void;49 onDragEnd?: () => void;50};5152export const Comparison = ({53 className,54 mode = "drag",55 onDragStart,56 onDragEnd,57 ...props58}: ComparisonProps) => {59 const [isDragging, setIsDragging] = useState(false);60 const motionValue = useMotionValue(50);61 const motionSliderPosition = useSpring(motionValue, {62 bounce: 0,63 duration: 0,64 });65 const [sliderPosition, setSliderPosition] = useState(50);6667 const handleDrag = (domRect: DOMRect, clientX: number) => {68 if (!isDragging && mode === "drag") {69 return;70 }7172 const x = clientX - domRect.left;73 const percentage = Math.min(Math.max((x / domRect.width) * 100, 0), 100);74 motionValue.set(percentage);75 setSliderPosition(percentage);76 };7778 const handleMouseDrag: MouseEventHandler<HTMLDivElement> = (event) => {79 if (!event) {80 return;81 }8283 const containerRect = event.currentTarget.getBoundingClientRect();8485 handleDrag(containerRect, event.clientX);86 };8788 const handleTouchDrag: TouchEventHandler<HTMLDivElement> = (event) => {89 if (!event) {90 return;91 }9293 const containerRect = event.currentTarget.getBoundingClientRect();94 const touches = Array.from(event.touches);9596 handleDrag(containerRect, touches.at(0)?.clientX ?? 0);97 };9899 const handleDragStart = () => {100 if (mode === "drag") {101 setIsDragging(true);102 onDragStart?.();103 }104 };105106 const handleDragEnd = () => {107 if (mode === "drag") {108// … truncated
What it pulls in
npm packages
Files it writes
More from Kibo UI Registry
All 41 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| announcementannouncement | Kibo UI Registry | Components | Free | no deps | |
| avatar-stackavatar-stack | Kibo UI Registry | Components | Free | no deps | |
| bannerbanner | Kibo UI Registry | Components | Free | 2 deps | |
| calendarcalendar | Kibo UI Registry | Components | Free | 3 deps | |
| choiceboxchoicebox | Kibo UI Registry | Components | Free | 2 deps | |
| code-blockcode-block | Kibo UI Registry | Components | Free | 5 deps · 2 files | |
| color-pickercolor-picker | Kibo UI Registry | Components | Free | 3 deps | |
| comboboxcombobox | Kibo UI Registry | Components | Free | 2 deps |
