AI-Generated forms in seconds.
KickStart your next FormKit form in seconds. Generate from a prompt, image, or text attachment. Copy & paste as Vue components or FormKit schema.
Introduction
FormKit’s Drag and Drop is a small library for adding data-first drag and drop sorting and transferring of elements in your app. It’s simple, flexible, framework agnostic, and clocks in at only ~4Kb gzipped. Drag and Drop works with React, Solid, Vue, Svelte, or any JavaScript application.
Getting Started
Install
Drag and Drop is published as @formkit/drag-and-drop
on npm. Click to copy the install command for your package manager of choice:
- npm install @formkit/drag-and-drop
- pnpm add @formkit/drag-and-drop
- yarn add @formkit/drag-and-drop
- bun install @formkit/drag-and-drop
Usage
Drag and drop ships two main functions: dragAndDrop
and useDragAndDrop
. These can be imported for your framework of choice by using the subpath import @formkit/drag-and-drop/{react/vue}
. A native JavaScript version of the dragAndDrop
function is also available at @formkit/drag-and-drop
.
useDragAndDrop
The useDragAndDrop
hook is the most convenient way to add Drag and Drop to your app. Call this function with an initial array of values. It returns a tuple containing a a template ref and a reactive array of values. The template ref should be assigned to the parent DOM element of the items you wish to make draggable. The reactive array of values should be used in your template to render the draggable elements.
// React:const [parentRef, values, setValues] = useDragAndDrop(
['Item 1', 'Item2', 'Item3']
)
// Vue:const [parentRef, values] = useDragAndDrop(
['Item 1', 'Item2', 'Item3']
)
dragAndDrop
The dragAndDrop
hook allows you to define your own ref and list state. This is useful if you need to integrate with a pre-existing app without changing your component structure.
// React:dragAndDrop({
parent: parentRef,
state: [values, setValues]
})
// Vue:dragAndDrop({
parent: parentRef,
values: valueRef
})
Features
Drag and drop ships out of the box with the ability to sort and transfer individual items between lists. Further customization is also available via first-party plugins, and of course you can always write your own.
Sortability
Using useDragAndDrop
or dragAndDrop
automatically makes a lists sortable. Dragging items within your list will automatically change your list’s state to reflect the new order (which in turn allows the framework to re-render to the correct order).
- React
- Vue
- Native
import React from "react";
import { function useDragAndDrop<E extends HTMLElement, T = unknown>(list: T[], options?: Partial<ParentConfig<T>>): [RefObject<E>, T[], Dispatch<SetStateAction<T[]>>, (config: Partial<ParentConfig<T>>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop } from "@formkit/drag-and-drop/react";
export function function myComponent(): React.JSX.Element
myComponent() {
const [const parent: React.RefObject<HTMLUListElement>
parent, const tapes: string[]
tapes] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>([
"Depeche Mode",
"Duran Duran",
"Pet Shop Boys",
"Kraftwerk",
"Tears for Fears",
"Spandau Ballet",
]);
return (
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const parent: React.RefObject<HTMLUListElement>
parent}>
{const tapes: string[]
tapes.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((tape: string
tape) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<HTMLLIElement>.className?: string | undefined
className="cassette" data-label: string
data-label={tape: string
tape} React.Attributes.key?: React.Key | null | undefined
key={tape: string
tape}>
{tape: string
tape}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
);
}
import React from "react";
import { function useDragAndDrop<E extends HTMLElement, T = unknown>(list: T[], options?: Partial<ParentConfig<T>>): [RefObject<E>, T[], Dispatch<SetStateAction<T[]>>, (config: Partial<ParentConfig<T>>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop } from "@formkit/drag-and-drop/react";
export function function myComponent(): React.JSX.Element
myComponent() {
const [const parent: React.RefObject<HTMLUListElement>
parent, const tapes: string[]
tapes] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>([
"Depeche Mode",
"Duran Duran",
"Pet Shop Boys",
"Kraftwerk",
"Tears for Fears",
"Spandau Ballet",
]);
return (
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const parent: React.RefObject<HTMLUListElement>
parent}>
{const tapes: string[]
tapes.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((tape: string
tape) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<HTMLLIElement>.className?: string | undefined
className="cassette" data-label: string
data-label={tape: string
tape} React.Attributes.key?: React.Key | null | undefined
key={tape: string
tape}>
{tape: string
tape}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
);
}
- Depeche Mode
- Duran Duran
- Pet Shop Boys
- Kraftwerk
- Tears for Fears
- Spandau Ballet
If there is a direct descendant of the parent that should not become draggable, set the draggable
property of the parent config. draggable
is a callback function that lets you determine whether or not a given element should be draggable.
Draggable
- React
- Vue
- Native
import React from "react";
import { function useDragAndDrop<E extends HTMLElement, T = unknown>(list: T[], options?: Partial<ParentConfig<T>>): [RefObject<E>, T[], Dispatch<SetStateAction<T[]>>, (config: Partial<ParentConfig<T>>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop } from "@formkit/drag-and-drop/react";
export function function myComponent(): React.JSX.Element
myComponent() {
const [const parent: React.RefObject<HTMLUListElement>
parent, const tapes: string[]
tapes] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>(
[
"Depeche Mode",
"Duran Duran",
"Pet Shop Boys",
"Kraftwerk",
"Tears for Fears",
"Spandau Ballet",
],
{
draggable?: ((child: HTMLElement) => boolean) | undefined
A function that returns whether a given node is draggable.draggable: (el: HTMLElement
el) => {
return el: HTMLElement
el.Element.id: string
Returns the value of element's id content attribute. Can be set to change it.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/id)id !== "no-drag";
},
}
);
return (
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const parent: React.RefObject<HTMLUListElement>
parent}>
{const tapes: string[]
tapes.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((tape: string
tape) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<HTMLLIElement>.className?: string | undefined
className="cassette" data-label: string
data-label={tape: string
tape} React.Attributes.key?: React.Key | null | undefined
key={tape: string
tape}>
{tape: string
tape}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
<JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.id?: string | undefined
id="no-drag">I am NOT draggable</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
);
}
import React from "react";
import { function useDragAndDrop<E extends HTMLElement, T = unknown>(list: T[], options?: Partial<ParentConfig<T>>): [RefObject<E>, T[], Dispatch<SetStateAction<T[]>>, (config: Partial<ParentConfig<T>>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop } from "@formkit/drag-and-drop/react";
export function function myComponent(): React.JSX.Element
myComponent() {
const [const parent: React.RefObject<HTMLUListElement>
parent, const tapes: string[]
tapes] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>(
[
"Depeche Mode",
"Duran Duran",
"Pet Shop Boys",
"Kraftwerk",
"Tears for Fears",
"Spandau Ballet",
],
{
draggable?: ((child: HTMLElement) => boolean) | undefined
A function that returns whether a given node is draggable.draggable: (el: HTMLElement
el) => {
return el: HTMLElement
el.Element.id: string
Returns the value of element's id content attribute. Can be set to change it.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/id)id !== "no-drag";
},
}
);
return (
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const parent: React.RefObject<HTMLUListElement>
parent}>
{const tapes: string[]
tapes.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((tape: string
tape) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<HTMLLIElement>.className?: string | undefined
className="cassette" data-label: string
data-label={tape: string
tape} React.Attributes.key?: React.Key | null | undefined
key={tape: string
tape}>
{tape: string
tape}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
<JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.id?: string | undefined
id="no-drag">I am NOT draggable</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
);
}
- Depeche Mode
- Duran Duran
- Pet Shop Boys
- Kraftwerk
- Tears for Fears
- Spandau Ballet
- I am NOT draggable
Transferability
If the intention is to transfer values between lists, simply set the group
property in the configuration to the same value for each list.
- React
- Vue
- Native
import React from "react";
import { function useDragAndDrop<E extends HTMLElement, T = unknown>(list: T[], options?: Partial<ParentConfig<T>>): [RefObject<E>, T[], Dispatch<SetStateAction<T[]>>, (config: Partial<ParentConfig<T>>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop } from "@formkit/drag-and-drop/react";
export function function myComponent(): React.JSX.Element
myComponent() {
const const todoItems: string[]
todoItems = [
"Schedule perm",
"Rewind VHS tapes",
"Make change for the arcade",
"Get disposable camera developed",
"Learn C++",
"Return Nintendo Power Glove",
];
const const doneItems: string[]
doneItems = ["Pickup new mix-tape from Beth"];
const [const todoList: React.RefObject<HTMLUListElement>
todoList, const todos: string[]
todos] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>(
const todoItems: string[]
todoItems,
{ group?: string | undefined
The group that the parent belongs to. This is used for allowing multiple
parents to transfer nodes between each other.group: "todoList" }
);
const [const doneList: React.RefObject<HTMLUListElement>
doneList, const dones: string[]
dones] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>(
const doneItems: string[]
doneItems,
{ group?: string | undefined
The group that the parent belongs to. This is used for allowing multiple
parents to transfer nodes between each other.group: "todoList" }
);
return (
<JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="kanban-board">
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const todoList: React.RefObject<HTMLUListElement>
todoList}>
{const todos: string[]
todos.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((todo: string
todo) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<T>.className?: string | undefined
className="kanban-item" React.Attributes.key?: React.Key | null | undefined
key={todo: string
todo}>
{todo: string
todo}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const doneList: React.RefObject<HTMLUListElement>
doneList}>
{const dones: string[]
dones.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((done: string
done) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<T>.className?: string | undefined
className="kanban-item" React.Attributes.key?: React.Key | null | undefined
key={done: string
done}>
{done: string
done}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
);
}
import React from "react";
import { function useDragAndDrop<E extends HTMLElement, T = unknown>(list: T[], options?: Partial<ParentConfig<T>>): [RefObject<E>, T[], Dispatch<SetStateAction<T[]>>, (config: Partial<ParentConfig<T>>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop } from "@formkit/drag-and-drop/react";
export function function myComponent(): React.JSX.Element
myComponent() {
const const todoItems: string[]
todoItems = [
"Schedule perm",
"Rewind VHS tapes",
"Make change for the arcade",
"Get disposable camera developed",
"Learn C++",
"Return Nintendo Power Glove",
];
const const doneItems: string[]
doneItems = ["Pickup new mix-tape from Beth"];
const [const todoList: React.RefObject<HTMLUListElement>
todoList, const todos: string[]
todos] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>(
const todoItems: string[]
todoItems,
{ group?: string | undefined
The group that the parent belongs to. This is used for allowing multiple
parents to transfer nodes between each other.group: "todoList" }
);
const [const doneList: React.RefObject<HTMLUListElement>
doneList, const dones: string[]
dones] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>(
const doneItems: string[]
doneItems,
{ group?: string | undefined
The group that the parent belongs to. This is used for allowing multiple
parents to transfer nodes between each other.group: "todoList" }
);
return (
<JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="kanban-board">
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const todoList: React.RefObject<HTMLUListElement>
todoList}>
{const todos: string[]
todos.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((todo: string
todo) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<T>.className?: string | undefined
className="kanban-item" React.Attributes.key?: React.Key | null | undefined
key={todo: string
todo}>
{todo: string
todo}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const doneList: React.RefObject<HTMLUListElement>
doneList}>
{const dones: string[]
dones.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((done: string
done) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<T>.className?: string | undefined
className="kanban-item" React.Attributes.key?: React.Key | null | undefined
key={done: string
done}>
{done: string
done}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
);
}
ToDos
- Schedule perm
- Rewind VHS tapes
- Make change for the arcade
- Get disposable camera developed
- Learn C++
- Return Nintendo Power Glove
Complete
- Pickup new mix-tape from Beth
Disable sort
If you would like to prevent sorting within a given list, but still allow transfer, set the sortable
property to false
in the configuration.
- React
- Vue
- Native
import React from "react";
import { function useDragAndDrop<E extends HTMLElement, T = unknown>(list: T[], options?: Partial<ParentConfig<T>>): [RefObject<E>, T[], Dispatch<SetStateAction<T[]>>, (config: Partial<ParentConfig<T>>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop } from "@formkit/drag-and-drop/react";
export function function myComponent(): React.JSX.Element
myComponent() {
const const todoItems: string[]
todoItems = ["Schedule perm", "Rewind VHS tapes", "Make change for the arcade", "Get disposable camera developed", "Learn C++", "Return Nintendo Power Glove"];
const const doneItems: string[]
doneItems = ["Pickup new mix-tape from Beth"];
const [const todoList: React.RefObject<HTMLUListElement>
todoList, const todos: string[]
todos] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>(
const todoItems: string[]
todoItems,
{
group?: string | undefined
The group that the parent belongs to. This is used for allowing multiple
parents to transfer nodes between each other.group: "todoList",
sortable?: boolean | undefined
Flag for whether or not to allow sorting within a given parent.sortable: false
}
);
const [const doneList: React.RefObject<HTMLUListElement>
doneList, const dones: string[]
dones] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>(
const doneItems: string[]
doneItems,
{
group?: string | undefined
The group that the parent belongs to. This is used for allowing multiple
parents to transfer nodes between each other.group: "todoList",
sortable?: boolean | undefined
Flag for whether or not to allow sorting within a given parent.sortable: false
}
);
return (
<JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="kanban-board">
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const todoList: React.RefObject<HTMLUListElement>
todoList}>
{const todos: string[]
todos.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((todo: string
todo) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<T>.className?: string | undefined
className="kanban-item" React.Attributes.key?: React.Key | null | undefined
key={todo: string
todo}>
{todo: string
todo}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const doneList: React.RefObject<HTMLUListElement>
doneList}>
{const dones: string[]
dones.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((done: string
done) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<T>.className?: string | undefined
className="kanban-item" React.Attributes.key?: React.Key | null | undefined
key={done: string
done}>
{done: string
done}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
);
}
import React from "react";
import { function useDragAndDrop<E extends HTMLElement, T = unknown>(list: T[], options?: Partial<ParentConfig<T>>): [RefObject<E>, T[], Dispatch<SetStateAction<T[]>>, (config: Partial<ParentConfig<T>>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop } from "@formkit/drag-and-drop/react";
export function function myComponent(): React.JSX.Element
myComponent() {
const const todoItems: string[]
todoItems = ["Schedule perm", "Rewind VHS tapes", "Make change for the arcade", "Get disposable camera developed", "Learn C++", "Return Nintendo Power Glove"];
const const doneItems: string[]
doneItems = ["Pickup new mix-tape from Beth"];
const [const todoList: React.RefObject<HTMLUListElement>
todoList, const todos: string[]
todos] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>(
const todoItems: string[]
todoItems,
{
group?: string | undefined
The group that the parent belongs to. This is used for allowing multiple
parents to transfer nodes between each other.group: "todoList",
sortable?: boolean | undefined
Flag for whether or not to allow sorting within a given parent.sortable: false
}
);
const [const doneList: React.RefObject<HTMLUListElement>
doneList, const dones: string[]
dones] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>(
const doneItems: string[]
doneItems,
{
group?: string | undefined
The group that the parent belongs to. This is used for allowing multiple
parents to transfer nodes between each other.group: "todoList",
sortable?: boolean | undefined
Flag for whether or not to allow sorting within a given parent.sortable: false
}
);
return (
<JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="kanban-board">
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const todoList: React.RefObject<HTMLUListElement>
todoList}>
{const todos: string[]
todos.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((todo: string
todo) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<T>.className?: string | undefined
className="kanban-item" React.Attributes.key?: React.Key | null | undefined
key={todo: string
todo}>
{todo: string
todo}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const doneList: React.RefObject<HTMLUListElement>
doneList}>
{const dones: string[]
dones.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((done: string
done) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.HTMLAttributes<T>.className?: string | undefined
className="kanban-item" React.Attributes.key?: React.Key | null | undefined
key={done: string
done}>
{done: string
done}
</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
);
}
ToDos
- Schedule perm
- Rewind VHS tapes
- Make change for the arcade
- Get disposable camera developed
- Learn C++
- Return Nintendo Power Glove
Complete
- Pickup new mix-tape from Beth
Accepts
For a more nuanced transfer experience, define the accepts
property in the configuration. This property is a callback function that lets you determine whether or not a given element can be transferred into the given list.
- React
- Vue
- Native
import React from "react";
import type { interface ParentConfig<T>
The configuration object for a given parent.ParentConfig } from "@formkit/drag-and-drop";
import { function useDragAndDrop<E extends HTMLElement, T = unknown>(list: T[], options?: Partial<ParentConfig<T>>): [RefObject<E>, T[], Dispatch<SetStateAction<T[]>>, (config: Partial<ParentConfig<T>>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop } from "@formkit/drag-and-drop/react";
export default function function myComponent(): React.JSX.Element
myComponent() {
const [const source: React.RefObject<HTMLUListElement>
source, const items1: string[]
items1] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLUListElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop<HTMLUListElement, string>(
["dungeon_master.exe", "map_1.dat", "map_2.dat", "character1.txt", "character2.txt", "shell32.dll", "README.txt",],
{
draggable?: ((child: HTMLElement) => boolean) | undefined
A function that returns whether a given node is draggable.draggable: (el: HTMLElement
el) => {
return el: HTMLElement
el.Element.id: string
Returns the value of element's id content attribute. Can be set to change it.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/id)id !== "no-drag";
},
}
);
const const config1: Partial<ParentConfig<string>>
config1: type Partial<T> = { [P in keyof T]?: T[P] | undefined; }
Make all properties in T optionalPartial<interface ParentConfig<T>
The configuration object for a given parent.ParentConfig<string>> = {};
const config1: Partial<ParentConfig<string>>
config1.accepts?: ((targetParentData: ParentRecord<string>, initialParentData: ParentRecord<string>, lastParentData: ParentRecord<string>, state: DragState<...>) => boolean) | undefined
A function that returns whether a given parent accepts a given node.accepts = (_parent: ParentRecord<string>
_parent, lastParent: ParentRecord<string>
lastParent) => {
if (lastParent: ParentRecord<string>
lastParent.ParentRecord<string>.el: HTMLElement
el === const target2: React.RefObject<HTMLElement>
target2.React.RefObject<HTMLElement>.current: HTMLElement | null
The current value of the ref.current) {
return false;
}
return const items2: string[]
items2.Array<string>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length < 3;
};
const const config2: Partial<ParentConfig<string>>
config2: type Partial<T> = { [P in keyof T]?: T[P] | undefined; }
Make all properties in T optionalPartial<interface ParentConfig<T>
The configuration object for a given parent.ParentConfig<string>> = {};
const config2: Partial<ParentConfig<string>>
config2.accepts?: ((targetParentData: ParentRecord<string>, initialParentData: ParentRecord<string>, lastParentData: ParentRecord<string>, state: DragState<...>) => boolean) | undefined
A function that returns whether a given parent accepts a given node.accepts = (_parent: ParentRecord<string>
_parent, lastParent: ParentRecord<string>
lastParent) => {
if (lastParent: ParentRecord<string>
lastParent.ParentRecord<string>.el: HTMLElement
el === const target1: React.RefObject<HTMLElement>
target1.React.RefObject<HTMLElement>.current: HTMLElement | null
The current value of the ref.current) {
return false;
}
return const items3: string[]
items3.Array<string>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length < 5;
};
const [const target1: React.RefObject<HTMLElement>
target1, const items2: string[]
items2] = useDragAndDrop<HTMLElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop(["knight.bmp", "dragon.bmp"], const config1: Partial<ParentConfig<string>>
config1);
const [const target2: React.RefObject<HTMLElement>
target2, const items3: string[]
items3] = useDragAndDrop<HTMLElement, string>(list: string[], options?: Partial<ParentConfig<string>> | undefined): [React.RefObject<HTMLElement>, string[], React.Dispatch<...>, (config: Partial<...>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop(["brick.bmp", "moss.bmp"], const config2: Partial<ParentConfig<string>>
config2);
return (
<JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref={const source: React.RefObject<HTMLUListElement>
source}>
{const items1: string[]
items1.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((item: string
item) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.Attributes.key?: React.Key | null | undefined
key={item: string
item}>{item: string
item}</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref="target1">
{const items2: string[]
items2.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((item: string
item) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.Attributes.key?: React.Key | null | undefined
key={item: string
item}>{item: string
item}</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
<JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul React.RefAttributes<HTMLUListElement>.ref?: React.LegacyRef<HTMLUListElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set `ref.current` to `null`
(or call the ref with `null` if you passed a callback ref).ref="target2">
{const items3: string[]
items3.Array<string>.map<React.JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((item: string
item) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li React.Attributes.key?: React.Key | null | undefined
key={item: string
item}>{item: string
item}</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>
))}
</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>
</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
);
}
import React from "react";
import type { interface ParentConfig<T>
The configuration object for a given parent.ParentConfig } from "@formkit/drag-and-drop";
import { function useDragAndDrop<E extends HTMLElement, T = unknown>(list: T[], options?: Partial<ParentConfig<T>>): [RefObject<E>, T[], Dispatch<SetStateAction<T[]>>, (config: Partial<ParentConfig<T>>) => void]
Hook for adding drag and drop/sortable support to a list of items.useDragAndDrop } from "@formkit/drag-and-drop/react";
export default function function myComponent(): React.JSX.Element
myComponent() {
const [const source: React.RefObject<HTMLUListElement>
source, const items1: string[]
items1] = useDragAndDrop<HTMLUListElement, string>(list: string[], options?: Partial<ParentConfig<string