Kanban Board
shadcn-kanban-board/kanbanFreeComponent
A Kanban board component with customizable circle colors.
Install it
npx shadcn@latest add https://shadcn-kanban-board.com/r/kanban.jsonSource
1/* eslint-disable @typescript-eslint/no-unsafe-member-access */2/* eslint-disable unicorn/no-null */3import type {4 ChangeEvent,5 ComponentProps,6 KeyboardEvent,7 RefObject,8} from 'react';9import {10 createContext,11 useCallback,12 useContext,13 useEffect,14 useId,15 useImperativeHandle,16 useMemo,17 useRef,18 useState,19} from 'react';20import { createPortal } from 'react-dom';2122import { Button, buttonVariants } from '~/components/ui/button';23import { Skeleton } from '~/components/ui/skeleton';24import { Textarea } from '~/components/ui/textarea';25import {26 Tooltip,27 TooltipContent,28 TooltipProvider,29 TooltipTrigger,30} from '~/components/ui/tooltip';31import { cn } from '~/lib/utils';3233/*34Accessibility35*/3637export type KanbanBoardDndMonitorEventHandler = {38 onDragStart?: (activeId: string) => void;39 onDragMove?: (activeId: string, overId?: string) => void;40 onDragOver?: (activeId: string, overId?: string) => void;41 onDragEnd?: (activeId: string, overId?: string) => void;42 onDragCancel?: (activeId: string) => void;43};4445export type KanbanBoardDndEventType = keyof KanbanBoardDndMonitorEventHandler;4647export type KanbanBoardDndMonitorContextValue = {48 activeIdRef: RefObject<string>;49 draggableDescribedById: string;50 registerMonitor: (monitor: KanbanBoardDndMonitorEventHandler) => void;51 unregisterMonitor: (monitor: KanbanBoardDndMonitorEventHandler) => void;52 triggerEvent: (53 eventType: KanbanBoardDndEventType,54 activeId: string,55 overId?: string,56 ) => void;57};5859export const KanbanBoardContext = createContext<60 KanbanBoardDndMonitorContextValue | undefined61>(undefined);6263function useDndMonitor(monitor: KanbanBoardDndMonitorEventHandler) {64 const context = useContext(KanbanBoardContext);65 if (!context) {66 throw new Error('useDndMonitor must be used within a DndMonitorProvider');67 }6869 const { registerMonitor, unregisterMonitor } = context;7071 useEffect(() => {72 registerMonitor(monitor);73 return () => {74 unregisterMonitor(monitor);75 };76 }, [monitor, registerMonitor, unregisterMonitor]);77}7879export function useDndEvents() {80 const context = useContext(KanbanBoardContext);8182 if (!context) {83 throw new Error('useDndEvents must be used within a DndMonitorProvider');84 }8586 const { activeIdRef, draggableDescribedById, triggerEvent } = context;8788 const onDragStart = useCallback(89 (activeId: string) => {90 activeIdRef.current = activeId;91 triggerEvent('onDragStart', activeId);92 },93// … truncated
What it pulls in
Other registry items
