-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import type { Action } from 'svelte/action' | ||
import type { SvelteComponent } from 'svelte/internal' | ||
import { get, readable, readonly, writable } from 'svelte/store' | ||
|
||
export type DragConfig = { | ||
onDragStart?: (e: DragEvent) => void | ||
onDragEnd?: (e: DragEvent) => void | ||
preview?: SvelteComponent | string | ||
} | ||
|
||
// TODO: Add keyboard support | ||
// TODO: Add drag image support (rendered component) | ||
export const useDrag = (config?: DragConfig) => { | ||
const { onDragStart, onDragEnd } = { ...config } | ||
|
||
const dragging$ = writable(false) | ||
const data$ = writable<string>('') | ||
|
||
const draggableAttrs = readable({ | ||
draggable: true, | ||
}) | ||
|
||
const onDragStartHandler = async (event: DragEvent) => { | ||
dragging$.set(true) | ||
event.dataTransfer?.setData('text/plain', get(data$)) | ||
onDragStart?.(event) | ||
} | ||
|
||
const onDragEndHandler = (event: DragEvent) => { | ||
dragging$.set(false) | ||
onDragEnd?.(event) | ||
} | ||
|
||
const drag: Action = (node, data: string = '') => { | ||
data$.set(data) | ||
|
||
node.addEventListener('dragstart', onDragStartHandler) | ||
node.addEventListener('dragend', onDragEndHandler) | ||
|
||
return { | ||
update(data: string) { | ||
data$.set(data) | ||
}, | ||
destroy() { | ||
dragging$.set(false) | ||
node.removeEventListener('dragstart', onDragStartHandler) | ||
node.removeEventListener('dragend', onDragEndHandler) | ||
}, | ||
} | ||
} | ||
|
||
return { | ||
dragging: readonly(dragging$), | ||
draggableAttrs, | ||
drag, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import type { Action } from 'svelte/action' | ||
import { readonly, writable } from 'svelte/store' | ||
|
||
export type DropConfig = { | ||
accept?: string[] | ||
onDrop?: (e: DragEvent) => void | ||
} | ||
|
||
// TODO: Add keyboard support | ||
export const useDrop = (config?: DropConfig) => { | ||
const { onDrop } = { ...config } | ||
|
||
const hovering$ = writable(false) | ||
|
||
const onDragOverHandler = (e: DragEvent) => { | ||
e.preventDefault() | ||
hovering$.set(true) | ||
} | ||
|
||
const onDragLeaveHandler = (e: DragEvent) => { | ||
e.preventDefault() | ||
hovering$.set(false) | ||
} | ||
|
||
const onDropHandler = (e: DragEvent) => { | ||
e.preventDefault() | ||
hovering$.set(false) | ||
onDrop?.(e) | ||
} | ||
|
||
const drop: Action = (node) => { | ||
node.addEventListener('dragover', onDragOverHandler) | ||
node.addEventListener('dragleave', onDragLeaveHandler) | ||
node.addEventListener('drop', onDropHandler) | ||
|
||
return { | ||
destroy() { | ||
node.removeEventListener('dragover', onDragOverHandler) | ||
node.removeEventListener('dragleave', onDragLeaveHandler) | ||
node.removeEventListener('drop', onDropHandler) | ||
}, | ||
} | ||
} | ||
|
||
return { | ||
hovering: readonly(hovering$), | ||
drop, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<script lang="ts"> | ||
import Page from './example/+page.svelte' | ||
import PageSource from './example/+page.svelte?raw' | ||
import ProductSource from './example/Product.svelte?raw' | ||
import BasketSource from './example/Basket.svelte?raw' | ||
import Snippet from '../../Snippet.svelte' | ||
</script> | ||
|
||
<h1>Drag and Drop</h1> | ||
|
||
<p>The Drag and Drop interactions allows data transfer between components.</p> | ||
|
||
<h2>Example</h2> | ||
|
||
<div> | ||
<Page /> | ||
</div> | ||
|
||
<h2>Sources</h2> | ||
|
||
<p>Page</p> | ||
<Snippet code={PageSource} /> | ||
|
||
<p>Product</p> | ||
<Snippet code={ProductSource} /> | ||
|
||
<p>Basket</p> | ||
<Snippet code={BasketSource} /> |
15 changes: 15 additions & 0 deletions
15
src/routes/(docs)/interaction/drag-and-drop/example/+page.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<script lang="ts"> | ||
import Basket from './Basket.svelte' | ||
import Product from './Product.svelte' | ||
const products = ['🧀', '🧴', '🪥', '🥑', '🥖', '☕', '🍺', '🍅', '🐟'] | ||
</script> | ||
|
||
<div class="mb-4 flex w-fit gap-2 rounded"> | ||
{#each products as value} | ||
<Product {value} /> | ||
{/each} | ||
</div> | ||
|
||
<p class="mb-2 text-xs opacity-50">Drag a product into your basket</p> | ||
<Basket items={['🥑', '🐟']} /> |
28 changes: 28 additions & 0 deletions
28
src/routes/(docs)/interaction/drag-and-drop/example/Basket.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<script lang="ts"> | ||
import { useDrop } from '$lib' | ||
export let items: string[] = [] | ||
const { drop, hovering } = useDrop({ | ||
onDrop: (event) => { | ||
const item = event.dataTransfer.getData('text/plain') | ||
items = [...items, item] | ||
}, | ||
}) | ||
</script> | ||
|
||
<div | ||
use:drop | ||
class="mb-2 flex min-h-[3rem] max-w-md flex-wrap gap-2 rounded-md border-2 border-transparent bg-amber-50 p-2 shadow dark:bg-amber-950" | ||
class:is-hovering={$hovering} | ||
> | ||
{#each items as item} | ||
<div class="select-none p-1">{item}</div> | ||
{/each} | ||
</div> | ||
|
||
<style lang="postcss"> | ||
.is-hovering { | ||
@apply border-dashed border-amber-500 transition-colors; | ||
} | ||
</style> |
22 changes: 22 additions & 0 deletions
22
src/routes/(docs)/interaction/drag-and-drop/example/Product.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<script lang="ts"> | ||
import { useDrag } from '$lib' | ||
export let value: string | ||
const { dragging, drag, draggableAttrs } = useDrag() | ||
</script> | ||
|
||
<button | ||
use:drag={value} | ||
{...$draggableAttrs} | ||
class="rounded border-2 border-transparent p-2 transition-colors transition-opacity hover:bg-neutral-200 dark:hover:bg-neutral-700" | ||
class:is-dragging={$dragging} | ||
> | ||
{value} | ||
</button> | ||
|
||
<style lang="postcss"> | ||
.is-dragging { | ||
@apply border-amber-500 opacity-50; | ||
} | ||
</style> |