Skip to content

Draggable Card

The Draggable Card component provides a powerful way to display and interact with cards, featuring drag and drop functionality. Built using dnd-kit, it offers a comprehensive solution for complex drag and drop interactions.

Variations

With actions

This example shows how to add interactive elements like close buttons to your draggable cards:

Grip outside

The draggable card supports placing the grip handle outside the card container using gripPosition="outside". This creates a cleaner card appearance with the drag handle positioned to the left of the card.

Sticky headers

Use the sticky and header props on DraggableCardList for the common pattern of a pinned header above a draggable list inside a scrollable drawer. These props wrap the list in a StickyListSection internally.

Contained mode

Use contained when the DraggableCardList is nested inside form input wrappers or other intermediate elements, but the drawer body is still the scroll container. Set --cn-sticky-container-padding on an ancestor to control how far the header bleeds horizontally.

Installation

import { DraggableCard, DraggableCardList, CardData } from '@harnessio/ui/components'
// Define your cards
const [cards, setCards] = useState<CardData[]>([
{
id: '1',
title: 'First Card',
description: 'This is the first card description',
disableDragAndDrop: false // Optional: disable dragging for this card
},
{
id: '2',
title: 'Second Card',
description: 'This is the second card description'
}
])
// Use the DraggableCardList to render and manage the cards
return (
<DraggableCardList
cards={cards}
setCards={setCards}
/>
)

Both title and description accept React components, not just strings, so you can render richer content:

const [cards, setCards] = useState<CardData[]>([
{
id: '1',
title: (
<div className="flex items-center justify-between w-full">
<span>Card with Custom Title</span>
<IconV2 name="settings" size="sm" />
</div>
),
description: (
<div className="space-y-cn-xs">
<p>This card has a custom description component</p>
<Button>Action Button</Button>
</div>
)
}
])