parent
00cef5d672
commit
887fd6e2a5
@ -1,7 +1,7 @@ |
||||
# remix-ui-drag-n-drop |
||||
# drag-n-drop |
||||
|
||||
This library was generated with [Nx](https://nx.dev). |
||||
|
||||
## Running unit tests |
||||
|
||||
Run `nx test remix-ui-drag-n-drop` to execute the unit tests via [Jest](https://jestjs.io). |
||||
Run `nx test drag-n-drop` to execute the unit tests via [Jest](https://jestjs.io). |
||||
|
@ -1,2 +1,2 @@ |
||||
|
||||
export * from './lib/remix-ui-drag-n-drop'; |
||||
export * from './lib/drag-n-drop'; |
||||
|
@ -0,0 +1,8 @@ |
||||
import { createContext } from "react"; |
||||
import { MoveContextType } from "../types"; |
||||
|
||||
export const MoveContext = createContext<MoveContextType>({ |
||||
dragged: "", |
||||
moveFile: () => {}, |
||||
currentlyMoved: () => {} |
||||
}) |
@ -0,0 +1,85 @@ |
||||
import { extractParentFromKey } from "@remix-ui/helper" |
||||
import React, { useContext, useRef, useState } from "react" |
||||
import { MoveContext } from "./context/moveContext" |
||||
import { DraggableType, DragType } from "./types" |
||||
|
||||
export const Drag = (props: DragType) => { |
||||
const [dragged, setDragged] = useState<string>("") |
||||
|
||||
return ( |
||||
<MoveContext.Provider |
||||
value={{ |
||||
dragged: dragged, |
||||
moveFile: props.onFileMoved, |
||||
currentlyMoved: (path) => { |
||||
setDragged(() => path) |
||||
}, |
||||
}} |
||||
> |
||||
{props.children} |
||||
</MoveContext.Provider> |
||||
) |
||||
} |
||||
|
||||
export const Draggable = (props: DraggableType) => { |
||||
const dragRef = useRef<HTMLSpanElement>(null), |
||||
file = props.file, |
||||
context = useContext(MoveContext) |
||||
|
||||
const handleDrop = (event: React.DragEvent<HTMLSpanElement>) => { |
||||
event.preventDefault() |
||||
|
||||
if (file.isDirectory) { |
||||
context.moveFile(file.path, context.dragged) |
||||
} else { |
||||
const path = extractParentFromKey(file.path) || '/' |
||||
|
||||
context.moveFile(path, context.dragged) |
||||
} |
||||
} |
||||
|
||||
const handleDragover = (event: React.DragEvent<HTMLSpanElement>) => { |
||||
//Checks if the folder is opened
|
||||
event.preventDefault() |
||||
if (file.isDirectory && !props.expandedPath.includes(file.path)) { |
||||
props.handleClickFolder(file.path, file.type) |
||||
} |
||||
} |
||||
|
||||
const handleDrag = () => { |
||||
if (context.dragged !== file.path) { |
||||
context.currentlyMoved(file.path) |
||||
} |
||||
} |
||||
|
||||
if (props.isDraggable) { |
||||
return <>{props.children}</> |
||||
} |
||||
|
||||
return ( |
||||
<> |
||||
{ |
||||
props.isDraggable ? props.children : |
||||
<span |
||||
ref={dragRef} |
||||
draggable |
||||
onDrop={(event) => { |
||||
handleDrop(event) |
||||
}} |
||||
onDragStart={() => { |
||||
if (file) { |
||||
handleDrag() |
||||
} |
||||
}} |
||||
onDragOver={(event) => { |
||||
if (file) { |
||||
handleDragover(event) |
||||
} |
||||
}} |
||||
> |
||||
{props.children} |
||||
</span> |
||||
} |
||||
</> |
||||
) |
||||
} |
@ -1,112 +0,0 @@ |
||||
import React, { |
||||
createContext, |
||||
ReactNode, |
||||
useContext, |
||||
useRef, |
||||
useState, |
||||
} from "react"; |
||||
|
||||
|
||||
export interface FileType { |
||||
path: string, |
||||
name: string, |
||||
isDirectory: boolean, |
||||
type: 'folder' | 'file' | 'gist', |
||||
child?: File[] |
||||
} |
||||
|
||||
interface MoveContextType { |
||||
dragged: string; |
||||
isDraggable?: boolean; |
||||
moveFile: (dest: string, dragged: string) => void; |
||||
currentlyMoved: (path: string) => void; |
||||
} |
||||
interface DraggableType { |
||||
children: ReactNode; |
||||
file: FileType; |
||||
isDraggable?: boolean; |
||||
expandedPath: string[]; |
||||
handleClickFolder: (path: string, type: string) => void; |
||||
} |
||||
|
||||
interface DragType { |
||||
children: ReactNode; |
||||
onFileMoved: (dest: string, dragged: string) => void; |
||||
} |
||||
|
||||
export const MoveContext = createContext<MoveContextType>({ |
||||
dragged: "", |
||||
moveFile: () => {}, |
||||
currentlyMoved: () => {}, |
||||
}); |
||||
|
||||
export const Drag = (props: DragType) => { |
||||
const [dragged, setDragged] = useState<string>(""); |
||||
|
||||
return ( |
||||
<MoveContext.Provider |
||||
value={{ |
||||
dragged: dragged, |
||||
moveFile: props.onFileMoved, |
||||
currentlyMoved: (path) => { |
||||
setDragged(() => path); |
||||
}, |
||||
}} |
||||
> |
||||
{props.children} |
||||
</MoveContext.Provider> |
||||
); |
||||
}; |
||||
|
||||
export const Draggable = (props: DraggableType) => { |
||||
const dragRef = useRef<HTMLSpanElement | null>(null), |
||||
file = props.file, |
||||
context = useContext(MoveContext); |
||||
|
||||
const handleDrop = (event: React.DragEvent<HTMLSpanElement>) => { |
||||
event.preventDefault(); |
||||
|
||||
if (file.isDirectory) { |
||||
context.moveFile(file.path, context.dragged); |
||||
} |
||||
}; |
||||
|
||||
const handleDragover = (event: React.DragEvent<HTMLSpanElement>) => { |
||||
//Checks if the folder is opened
|
||||
event.preventDefault(); |
||||
if (file.isDirectory && !props.expandedPath.includes(file.path)) { |
||||
props.handleClickFolder(file.path, file.type); |
||||
} |
||||
}; |
||||
const handleDrag = () => { |
||||
if (context.dragged !== file.path) { |
||||
context.currentlyMoved(file.path); |
||||
} |
||||
}; |
||||
|
||||
if (props.isDraggable) { |
||||
return <>{props.children}</>; |
||||
} |
||||
|
||||
return ( |
||||
<span |
||||
ref={dragRef} |
||||
draggable |
||||
onDrop={(event) => { |
||||
handleDrop(event); |
||||
}} |
||||
onDragStart={() => { |
||||
if (file) { |
||||
handleDrag(); |
||||
} |
||||
}} |
||||
onDragOver={(event) => { |
||||
if (file && file.isDirectory) { |
||||
handleDragover(event); |
||||
} |
||||
}} |
||||
> |
||||
{props.children} |
||||
</span> |
||||
); |
||||
}; |
@ -0,0 +1,29 @@ |
||||
import { ReactNode } from "react" |
||||
|
||||
export interface FileType { |
||||
path: string, |
||||
name: string, |
||||
isDirectory: boolean, |
||||
type: 'folder' | 'file' | 'gist', |
||||
child?: File[] |
||||
} |
||||
|
||||
export interface MoveContextType { |
||||
dragged: string |
||||
isDraggable?: boolean |
||||
moveFile: (dest: string, dragged: string) => void |
||||
currentlyMoved: (path: string) => void |
||||
} |
||||
|
||||
export interface DraggableType { |
||||
children: ReactNode |
||||
file: FileType |
||||
isDraggable?: boolean |
||||
expandedPath: string[] |
||||
handleClickFolder: (path: string, type: string) => void |
||||
} |
||||
|
||||
export interface DragType { |
||||
children: ReactNode |
||||
onFileMoved: (dest: string, dragged: string) => void |
||||
} |
Loading…
Reference in new issue