Skip to content

Instantly share code, notes, and snippets.

@kreddos
Last active August 30, 2021 10:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kreddos/2464a969df3b632e82fc4646365c37d7 to your computer and use it in GitHub Desktop.
Save kreddos/2464a969df3b632e82fc4646365c37d7 to your computer and use it in GitHub Desktop.
interface BaseCard {
_id: string;
}
interface DndListProps<T extends BaseCard = BaseCard> {
data: Array<T>;
onChange: (newData: Array<T>) => void;
renderItemContent: (props: T, drag?: ConnectDragSource) => React.ReactElement;
}
export const DndList = <T extends BaseCard>({
data,
onChange,
renderItemContent,
}: React.PropsWithChildren<DndListProps<T>>) => {
const [cards, setCards] = useState(data);
useEffect(() => {
setCards(data);
}, [data]);
const findCard = useCallback(
(id: string) => {
const card = cards.filter((c) => `${c._id}` === id)[0];
return {
card,
index: cards.indexOf(card),
};
},
[cards]
);
const moveCard = useCallback(
(id: string, atIndex: number) => {
const { card, index } = findCard(id);
setCards(
update(cards, {
$splice: [
[index, 1],
[atIndex, 0, card],
],
})
);
},
[findCard, cards, setCards]
);
const onSave = () => {
onChange(cards);
};
const [, drop] = useDrop(() => ({ accept: "cards" }));
return (
<Grid ref={drop} container spacing={2}>
{cards.map((card, index) => {
return (
<ListItem
key={card._id}
card={card}
moveCard={moveCard}
findCard={findCard}
onSave={onSave}
renderItem={renderItemContent}
/>
);
})}
</Grid>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment