const navigationItems = [
{ icon: 'house', name: 'Home' },
{ icon: 'person', name: 'Profile' },
{ icon: 'checkmark-circle-filled', name: 'Check-In' },
{ icon: 'people', name: 'Groups' },
{ icon: 'calendar', name: 'Events' },
{ icon: 'search', name: 'Search' },
]
function Item({
icon,
name,
type,
index,
onAdd,
onRemove,
hoverEnabled = true,
...restProps
}) {
const { hover, hoverProps } = hooks.useHover()
return (
<Card
axis="horizontal"
alignment="center"
marginBottom={1}
padding={1}
spacing={1}
elevation={1}
borderColor="transparent"
hover={hoverEnabled ? { borderColor: 'blue-5' } : {}}
{...hoverProps}
{...restProps}
>
<Icon name={icon} color="grey-7" />
<Text grow={1}>{name}</Text>
<Button
title={type === 'remove' ? 'Remove' : 'Add'}
icon={{
name: `${type}-circle-filled`,
color: type === 'remove' ? 'error' : 'success',
}}
variant="naked"
opacity={hover && hoverEnabled ? 1 : 0}
transform={`scale(${hover && hoverEnabled ? 1 : 0.9})`}
transition="all 280ms ease-out"
onClick={() => (type === 'remove' ? onRemove() : onAdd({ icon, name }))}
/>
</Card>
)
}
function App() {
const [activeNavigationItems, setActiveNavigationItems] = React.useState(
navigationItems.slice(1, 3)
)
const filteredNavigationItems = navigationItems.filter((item) =>
activeNavigationItems.every((activeItem) => activeItem.name !== item.name)
)
return (
<DragDrop.Provider>
<GridView width="100%" columns="1fr 240px">
<StackView padding={6} spacing={2}>
<DragDrop.Droppable
droppableId="navigation"
onDrop={(event) => {
if (event.source.droppableId === 'static') {
setActiveNavigationItems(
utils.insertAtIndex({
list: activeNavigationItems,
index: event.destination.index,
value: filteredNavigationItems[event.source.index],
})
)
} else {
setActiveNavigationItems(
utils.reorderArray({
list: activeNavigationItems,
startIndex: event.source.index,
endIndex: event.destination.index,
})
)
}
}}
>
{(provided, snapshot) => (
<Card
innerRef={provided.innerRef}
subdued
minWidth={32}
paddingTop={1}
paddingHorizontal={1}
>
{activeNavigationItems.map((item, index) => (
<DragDrop.Draggable
key={item.name}
draggableId={item.name}
index={index}
>
{(provided, snapshot) => (
<Item
type="remove"
innerRef={provided.innerRef}
onRemove={() => {
setActiveNavigationItems((activeNavigationItems) => {
const nextItems = [...activeNavigationItems]
nextItems.splice(index, 1)
return nextItems
})
}}
{...provided.draggableProps}
{...provided.dragHandleProps}
{...item}
/>
)}
</DragDrop.Draggable>
))}
{provided.placeholder}
</Card>
)}
</DragDrop.Droppable>
</StackView>
<StackView padding={3} spacing={1} backgroundColor="grey-1">
<DragDrop.Droppable
droppableId="static"
onDragStart={console.log}
onDragEnd={console.log}
sourceOnly
>
{(provided) => (
<StackView innerRef={provided.innerRef}>
{filteredNavigationItems.map((item, index) => (
<DragDrop.Draggable
key={item.name}
draggableId={item.name}
index={index}
placeholder={() => (
<Item type="add" opacity={0.65} {...item} />
)}
>
{(provided, snapshot) => (
<Item
type="add"
innerRef={provided.innerRef}
onAdd={(item) =>
setActiveNavigationItems((activeNavigationItems) => [
...activeNavigationItems,
item,
])
}
{...provided.draggableProps}
{...provided.dragHandleProps}
{...item}
/>
)}
</DragDrop.Draggable>
))}
{provided.placeholder}
</StackView>
)}
</DragDrop.Droppable>
</StackView>
</GridView>
</DragDrop.Provider>
)
}
render(<App />)