Kanban
A Kanban board is a visual representation of work processes used to manage and optimize workflow.
- Beta
Buy Pro
- 0.35.5 (latest)
Import
The Kanban board is composed of several key primitives:
Kanban
: The canvas or workspace that provides context.KanbanColumn
: Columns represent different stages or phases in your workflow.KanbanColumnHeader
: The header of a column.KanbanColumnBody
: The body of a column.KanbanColumnDragHandle
: Handle to allow sorting of columns.KanbanCard
: A card represents an individual work item or task.KanbanDragOverlay
: A drag overlay that can be used to provide visual feedback.KanbanTrash
: Allows cards to be dropped and removed.useKanbanContext
: A hook to access the Kanban context.
import {Kanban,KanbanColumn,KanbanColumnHeader,KanbanColumnHandle,KanbanCard,KanbanTrash,useKanbanContext,} from '@saas-ui-pro/kanban'
Usage
These Kanban primitives can be used to build advanced workflows that allows items to be moved over different stages.
Basic
This is a basic example showing a simple Kanban board with 3 columns.
import { Card, CardBody } from '@chakra-ui/react'import {Kanban,KanbanColumn,KanbanColumnHeader,KanbanColumnBody,KanbanColumnHandle,KanbanCard,KanbanDragOverlay,} from '@saas-ui-pro/kanban'const columnDefs: Record<string, { title: string }> = {todo: {title: 'Todo',},doing: {title: 'Doing',},done: {title: 'Done',},}export default function Basic() {return (<Kanban defaultItems={kanbanItems}>{({ columns, items, activeId }) => {return (<>{columns.map((columnId) => (<KanbanColumn id={columnId} minWidth="200px"><KanbanColumnHeader>{columnDefs[columnId]?.title} ({items[columnId]?.length})</KanbanColumnHeader><KanbanColumnBody>{items[columnId].map((itemId) => {return (<KanbanCard id={itemId}><Card minHeight="80px" w="full" fontSize="sm"><CardBody>{itemId}</CardBody></Card></KanbanCard>)})}</KanbanColumnBody></KanbanColumn>))}<KanbanDragOverlay>{activeId ? (<KanbanCard id={activeId}><CardminHeight="80px"w="full"fontSize="sm"cursor="grabbing"><CardBody>{activeId}</CardBody></Card></KanbanCard>) : null}</KanbanDragOverlay></>)}}</Kanban>)}
Controlled
You can control the items by passing the items
and onChange
props to the Kanban
component.
import { Card, CardBody } from '@chakra-ui/react'import {Kanban,KanbanColumn,KanbanColumnHeader,KanbanColumnBody,KanbanColumnHandle,KanbanCard,KanbanDragOverlay,} from '@saas-ui-pro/kanban'const columnDefs: Record<string, { title: string }> = {todo: {title: 'Todo',},doing: {title: 'Doing',},done: {title: 'Done',},}export default function Controlled() {const [items, setItems] = React.useState(kanbanItems)return (<Kanban items={items} onChange={setItems}>{({ columns, items, activeId }) => {return (<>{columns.map((columnId) => (<KanbanColumn id={columnId} minWidth="200px"><KanbanColumnHeader>{columnDefs[columnId]?.title} ({items[columnId]?.length})</KanbanColumnHeader><KanbanColumnBody>{items[columnId].map((itemId) => {return (<KanbanCard id={itemId}><Card minHeight="80px" w="full" fontSize="sm"><CardBody>{itemId}</CardBody></Card></KanbanCard>)})}</KanbanColumnBody></KanbanColumn>))}<KanbanDragOverlay>{activeId ? (<KanbanCard id={activeId}><CardminHeight="80px"w="full"fontSize="sm"cursor="grabbing"><CardBody>{activeId}</CardBody></Card></KanbanCard>) : null}</KanbanDragOverlay></>)}}</Kanban>)}
Draggable columns
You can make columns draggable by using the KanbanColumnDragHandle
component.
import { Card, CardBody, Spacer } from '@chakra-ui/react'import {Kanban,KanbanColumn,KanbanColumnProps,KanbanColumnHeader,KanbanColumnBody,KanbanColumnDragHandle,KanbanCard,KanbanCardProps,KanbanDragOverlay,useKanbanContext,} from '@saas-ui-pro/kanban'const columnDefs: Record<string, { title: string }> = {todo: {title: 'Todo',},doing: {title: 'Doing',},done: {title: 'Done',},}function DraggableBoardColumn({children,id,style,...props}: KanbanColumnProps & {id: string | number,}) {const { items } = useKanbanContext()return (<KanbanColumn id={id} minWidth="200px" {...props}><KanbanColumnHeader>{columnDefs[id]?.title} ({items[id]?.length})<Spacer /><KanbanColumnDragHandle /></KanbanColumnHeader><KanbanColumnBody>{children}</KanbanColumnBody></KanbanColumn>)}function BoardCard({ id, ...rest }: Omit<KanbanCardProps, 'children'>) {return (<KanbanCard id={id} {...rest}><Card minHeight="100px" w="full" fontSize="sm"><CardBody>{id}</CardBody></Card></KanbanCard>)}export default function DraggableColumns() {return (<Kanban defaultItems={kanbanItems}>{({ columns, items, isSortingColumn, activeId }) => {function renderSortableItemDragOverlay(id: string | number) {return <BoardCard id={id} cursor="grabbing" />}function renderColumnDragOverlay(columnId: string | number) {return (<KanbanColumn id={columnId} minWidth="200px">{items[columnId].map((itemId) => (<BoardCard id={itemId} key={itemId} />))}</KanbanColumn>)}return (<>{columns.map((columnId) => (<DraggableBoardColumn key={columnId} id={columnId}>{items[columnId].map((itemId) => {return (<BoardCardisDisabled={isSortingColumn}key={itemId}id={itemId}/>)})}</DraggableBoardColumn>))}<KanbanDragOverlay>{activeId? columns.includes(activeId)? renderColumnDragOverlay(activeId): renderSortableItemDragOverlay(activeId): null}</KanbanDragOverlay></>)}}</Kanban>)}
Toggle columns
You can toggle column visibility by using useState.
import { Button, Card, CardBody } from '@chakra-ui/react'import {Kanban,KanbanColumn,KanbanColumnHeader,KanbanColumnBody,KanbanColumnHandle,KanbanCard,KanbanDragOverlay,} from '@saas-ui-pro/kanban'const columnDefs: Record<string, { title: string }> = {todo: {title: 'Todo',},doing: {title: 'Doing',},done: {title: 'Done',},}export default function ToggleColumn() {const [visibleColumns, setVisibleColumns] = React.useState({todo: true,doing: true,done: false,})const showColumn = (columnId) => {setVisibleColumns((prev) => ({...prev,[columnId]: true,}))}const hideColumn = (columnId) => {setVisibleColumns((prev) => ({...prev,[columnId]: false,}))}const hiddenColumns = Object.keys(visibleColumns).filter((columnId) => !visibleColumns[columnId])return (<Kanban defaultItems={kanbanItems}>{({ columns, items, isSortingColumn, activeId }) => {return (<>{columns.map((columnId) => {if (!visibleColumns[columnId]) {return null}return (<KanbanColumn id={columnId} minWidth="200px"><KanbanColumnHeader py="1">{columnDefs[columnId]?.title} ({items[columnId]?.length})<Button onClick={() => hideColumn(columnId)} size="xs">Hide</Button></KanbanColumnHeader><KanbanColumnBody>{items[columnId].map((itemId) => {return (<KanbanCard id={itemId}><Card minHeight="80px" w="full" fontSize="sm"><CardBody>{itemId}</CardBody></Card></KanbanCard>)})}</KanbanColumnBody></KanbanColumn>)})}<Stack pt="10">{hiddenColumns.map((col) => (<Button onClick={() => showColumn(col)}>Show {col}</Button>))}</Stack><KanbanDragOverlay>{activeId ? (<KanbanCard id={activeId}><CardminHeight="80px"w="full"fontSize="sm"cursor="grabbing"><CardBody>{activeId}</CardBody></Card></KanbanCard>) : null}</KanbanDragOverlay></>)}}</Kanban>)}
Removing items
You can remove items by dragging them into the KanbanTrash
component.
import { Button, Card, CardBody } from '@chakra-ui/react'import {Kanban,KanbanColumn,KanbanColumnHeader,KanbanColumnBody,KanbanColumnHandle,KanbanCard,KanbanDragOverlay,KanbanTrash,} from '@saas-ui-pro/kanban'const columnDefs: Record<string, { title: string }> = {todo: {title: 'Todo',},doing: {title: 'Doing',},done: {title: 'Done',},}export default function Trash() {return (<Kanban defaultItems={kanbanItems}>{({ columns, items, isSortingColumn, activeId }) => {return (<>{columns.map((columnId) => (<KanbanColumn id={columnId} minWidth="200px"><KanbanColumnHeader>{columnDefs[columnId]?.title} ({items[columnId]?.length})</KanbanColumnHeader><KanbanColumnBody>{items[columnId].map((itemId) => {return (<KanbanCard id={itemId}><Card minHeight="80px" w="full" fontSize="sm"><CardBody>{itemId}</CardBody></Card></KanbanCard>)})}</KanbanColumnBody></KanbanColumn>))}<KanbanTrash mt="8"><Card height="300px"><CardBody>Drag items here to remove them.</CardBody></Card></KanbanTrash><KanbanDragOverlay>{activeId ? (<KanbanCard id={activeId}><CardminHeight="80px"w="full"fontSize="sm"cursor="grabbing"><CardBody>{activeId}</CardBody></Card></KanbanCard>) : null}</KanbanDragOverlay></>)}}</Kanban>)}
Add event listeners
The Kanban
component provides several event listeners that can be used to listen to drag events.
onCardDragEnd
: Called when a card drag ends.onColumnDragEnd
: Called when a column drag ends.
import { Button, Card, CardBody } from '@chakra-ui/react'import {Kanban,KanbanColumn,KanbanColumnHeader,KanbanColumnBody,KanbanColumnHandle,KanbanCard,KanbanDragOverlay,KanbanTrash,} from '@saas-ui-pro/kanban'const columnDefs: Record<string, { title: string }> = {todo: {title: 'Todo',},doing: {title: 'Doing',},done: {title: 'Done',},}export default function EventListeners() {const onCardDragEnd: OnCardDragEndHandler = React.useCallback((args) => {console.log(args)}, [])const onColumnDragEnd: OnColumnDragEndHandler = React.useCallback((args) => {console.log(args)}, [])return (<KanbandefaultItems={kanbanItems}onCardDragEnd={onCardDragEnd}onColumnDragEnd={onColumnDragEnd}>{({ columns, items, isSortingColumn, activeId }) => {return (<>{columns.map((columnId) => (<KanbanColumn id={columnId} minWidth="200px"><KanbanColumnHeader>{columnDefs[columnId]?.title} ({items[columnId]?.length})</KanbanColumnHeader><KanbanColumnBody>{items[columnId].map((itemId) => {return (<KanbanCard id={itemId}><Card minHeight="80px" w="full" fontSize="sm"><CardBody>{itemId}</CardBody></Card></KanbanCard>)})}</KanbanColumnBody></KanbanColumn>))}<KanbanDragOverlay>{activeId ? (<KanbanCard id={activeId}><CardminHeight="80px"w="full"fontSize="sm"cursor="grabbing"><CardBody>{activeId}</CardBody></Card></KanbanCard>) : null}</KanbanDragOverlay></>)}}</Kanban>)}
Was this helpful?