Implement drag & drop w/o persistence

This commit is contained in:
ekzyis 2024-07-05 04:59:32 +02:00
parent b96757b366
commit eb2f4b980f
2 changed files with 56 additions and 4 deletions

View File

@ -5,10 +5,44 @@ import { WalletCard } from '@/components/wallet-card'
import { WALLETS as WALLETS_QUERY } from '@/fragments/wallet'
import Link from 'next/link'
import { WALLET_DEFS } from '@/components/wallet'
import { useState } from 'react'
export const getServerSideProps = getGetServerSideProps({ query: WALLETS_QUERY, authRequired: true })
export default function Wallet ({ ssrData }) {
const [wallets, setWallets] = useState(WALLET_DEFS)
const [sourceIndex, setSourceIndex] = useState()
const [targetIndex, setTargetIndex] = useState()
const onDragStart = (i) => (e) => {
// e.dataTransfer.dropEffect = 'move'
// We can only use the DataTransfer API inside the drop event
// see https://html.spec.whatwg.org/multipage/dnd.html#security-risks-in-the-drag-and-drop-model
// e.dataTransfer.setData('text/plain', name)
// That's why we use React state instead
setSourceIndex(i)
}
const onDragEnter = (i) => (e) => {
setTargetIndex(i)
}
const onDragEnd = (e) => {
setSourceIndex(null)
setTargetIndex(null)
if (sourceIndex === targetIndex) return
setWallets(wallets => {
const copy = [...wallets]
const [source] = copy.splice(sourceIndex, 1)
const newTargetIndex = sourceIndex < targetIndex ? targetIndex - 1 : targetIndex
const append = sourceIndex < targetIndex
copy.splice(newTargetIndex + (append ? 1 : 0), 0, source)
return copy
})
}
return (
<Layout>
<div className='py-5 w-100'>
@ -19,10 +53,19 @@ export default function Wallet ({ ssrData }) {
wallet logs
</Link>
</div>
<div className={styles.walletGrid}>
{WALLET_DEFS.map((def, i) =>
<WalletCard key={i} name={def.name} {...def.card} />
)}
<div className={styles.walletGrid} onDragEnd={onDragEnd}>
{wallets
.map((def, i) =>
<div
key={def.name}
draggable
onDragStart={onDragStart(i)}
onDragEnter={onDragEnter(i)}
className={`${sourceIndex === i ? styles.drag : ''} ${targetIndex === i ? styles.drop : ''}`}
>
<WalletCard name={def.name} {...def.card} />
</div>
)}
</div>
</div>
</Layout>

View File

@ -7,9 +7,18 @@
margin-top: 3rem;
}
.drag {
opacity: 33%;
}
.drop {
box-shadow: 0 0 10px var(--bs-info);
}
.card {
width: 160px;
height: 180px;
cursor: move;
}
.badge {