Timeline
abui/timelineFreeBlock
A Gantt-chart style timeline with draggable time slots.
Live preview
live · rendered by the registry
Rendered by abui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://abui.io/r/timeline.jsonSource
1"use client"23import * as React from "react"4import { useState, useRef, useEffect, createContext, useContext, useMemo } from "react"5import { Slot } from "@radix-ui/react-slot"6import {7 DndContext,8 DragOverlay,9 useSensor,10 useSensors,11 PointerSensor,12 closestCenter,13 useDraggable,14 useDroppable,15} from "@dnd-kit/core"16import tunnel from "tunnel-rat"17import { cn } from "@/lib/utils"1819/* ============================================================================20 * TYPES & INTERFACES21 * ========================================================================== */2223export interface TimelineSlotData {24 id: string25 rowId: string26 startTime: string // "14:30"27 duration: number // minutes28 [key: string]: any // Additional custom data29}3031export interface TimelineRowData {32 id: string33 label: string34 [key: string]: any // Additional custom data35}3637export interface TimelineConfig {38 startHour: number39 endHour: number40 snapIntervalMinutes?: number41 columnWidth?: number42}4344/* ============================================================================45 * CONTEXT46 * ========================================================================== */4748type TimelineContextValue = {49 // Configuration50 config: TimelineConfig51 pixelsPerMinute: number52 timelineWidth: number5354 // Refs55 timelineRef: React.RefObject<HTMLDivElement | null>56 columnRef: React.RefObject<HTMLDivElement | null>5758 // Tunnel for drag preview59 dragPreviewTunnel: ReturnType<typeof tunnel>6061 // Callbacks62 onSlotPositionChange?: (slotId: string, newTime: string, newRowId: string) => Promise<boolean>63 onValidateDrop?: (slotId: string, newTime: string, newRowId: string) => boolean64 onSlotClick?: (slotId: string) => void65}6667const TimelineContext = createContext<TimelineContextValue | null>(null)6869function useTimeline() {70 const context = useContext(TimelineContext)71 if (!context) {72 throw new Error("Timeline components must be used within TimelineProvider")73 }74 return context75}7677/* ============================================================================78 * UTILITIES79 * ========================================================================== */8081export const timeToMinutes = (time: string): number => {82 const [hours, minutes] = time.split(":").map(Number)83 return hours * 60 + minutes84}8586export const minutesToTime = (minutes: number): string => {87 const hours = Math.floor(minutes / 60)88 const mins = minutes % 6089// … truncated
What it pulls in
npm packages
Files it writes
More from abui
All 20 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Chartanimated-chart | abui | Blocks | Free | 1 dep | |
| Availabilityavailability | abui | Blocks | Free | 1 dep | |
| Calendar Yearcalendar-year | abui | Blocks | Free | 1 dep | |
| Scroll Reveal Content Ascroll-reveal-content-a | abui | Blocks | Free | 1 dep |
