Skip to content

Commit

Permalink
impl Drag&Drop
Browse files Browse the repository at this point in the history
  • Loading branch information
yuta4j1 committed Nov 30, 2023
1 parent 5006059 commit ba30b78
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Routing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import FileUploadPage from './components/FileUploadPage'
import Fetcher from './components/Fetcher'
import GridPage from './components/grid'
import AnimationPage from './components/animation'
import DragAndDropPage from './components/dd'

const location = new ReactLocation()

Expand All @@ -28,6 +29,7 @@ const Routing = () => {
{ path: '/data_fetch', element: <Fetcher /> },
{ path: '/grid', element: <GridPage /> },
{ path: '/animation', element: <AnimationPage /> },
{ path: '/dd', element: <DragAndDropPage /> },
]}
>
<Header>
Expand All @@ -52,6 +54,9 @@ const Routing = () => {
<Link to="/animation" activeOptions={{ exact: true }}>
Animation
</Link>
<Link to="/dd" activeOptions={{ exact: true }}>
Drag&Drop
</Link>
</Header>
<hr />
<Outlet />
Expand Down
41 changes: 41 additions & 0 deletions src/components/dd/DraggableCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react'
import styled from 'styled-components'

const CardContainer = styled.div`
padding: 12px;
color: black;
background: #fff;
border-radius: 8px;
height: 80px;
cursor: grab;
&:active {
cursor: grabbing;
}
`

export const DraggableCard: React.FC<{
id: string
text: string
dropHandler: (droppedId: string, selfId: string) => void
}> = ({ id, text, dropHandler }) => {
return (
<CardContainer
draggable="true"
onDragEnter={e => {
e.preventDefault()
}}
onDragOver={e => {
e.preventDefault()
}}
onDragStart={e => {
e.dataTransfer.setData('text/plain', id)
}}
onDrop={e => {
const droppedCardId = e.dataTransfer.getData('text/plain')
dropHandler(droppedCardId, id)
}}
>
{text}
</CardContainer>
)
}
3 changes: 3 additions & 0 deletions src/components/dd/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { DragAndDropPage } from './page'

export default DragAndDropPage
97 changes: 97 additions & 0 deletions src/components/dd/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { useState } from 'react'
import styled from 'styled-components'
import { DraggableCard } from './DraggableCard'

const PageContainer = styled.div`
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
`

const BoardContainer = styled.div`
display: flex;
justify-content: center;
border: 1px solid;
padding: 24px;
border-radius: 12px;
gap: 24px;
`

const ColumnContainer = styled.div`
display: flex;
flex-direction: column;
gap: 12px;
padding: 12px;
background: #e0ebeb;
width: 300px;
min-height: 500px;
border-radius: 16px;
`

type CardProps = { id: string; text: string }

type ColumnWithCards = {
[columnKey: string]: CardProps[]
}

const initialState: ColumnWithCards = {
a: [
{ id: '1', text: 'hogehogefuga' },
{ id: '2', text: 'testtest' },
],
b: [
{ id: '3', text: 'aaaaadiuads' },
{ id: '4', text: 'jsdjaidsiad' },
],
}

const visitData = (
targetId: string,
columnWithCards: ColumnWithCards
): CardProps | undefined => {
for (const columnKey of Object.keys(columnWithCards)) {
for (const card of columnWithCards[columnKey]) {
if (card.id === targetId) {
return card
}
}
}
}

export const DragAndDropPage = () => {
const [columnWithCards, setColumnWithCards] =
useState<ColumnWithCards>(initialState)

const swapCard = (droppedId: string, selfId: string): void => {
const newDatas = Object.keys(columnWithCards).reduce((acc, curr) => {
const cards = columnWithCards[curr]
let newCards = cards.map(v => {
if (v.id === droppedId) {
return visitData(selfId, columnWithCards) ?? { id: '0', text: 'a' }
} else if (v.id === selfId) {
return visitData(droppedId, columnWithCards) ?? { id: '0', text: 'a' }
} else {
return v
}
})
acc[curr] = newCards
return acc
}, {} as ColumnWithCards)
setColumnWithCards(newDatas)
}

return (
<PageContainer>
<BoardContainer>
{Object.keys(columnWithCards).map(v => (
<ColumnContainer key={v}>
{columnWithCards[v].map(card => (
<DraggableCard key={card.id} {...card} dropHandler={swapCard} />
))}
</ColumnContainer>
))}
</BoardContainer>
</PageContainer>
)
}

0 comments on commit ba30b78

Please sign in to comment.