Svelte DNDアクションを使用したSveletによるドラッグアンドドロップ


TLDRは:このポストを使用すると、驚くほどドラッグ&ドロップ機能をあなたのsvelteアプリにsvelte-dnd-action . 場合は常にトレッロのクローンをsvelteを使用して(ちょうどトレロのより良いアニメーションで)を構築したい場合は、適切な場所に来ている.

ドラッグアンドドロップについて
あなたは(または基本的な)ドラッグアンドドロップの相互作用を持っているアプリを実装しようとした場合は、それは驚くほど難しいことを知っているだろう.確かに、ブラウザはa built in drag and drop API . そこにマイナーな問題があります-それはそれが見て、感じになると、その顔に平らに落ちる.
私を信じないで?svelte-sortable-list ブラウザのドラッグアンドドロップAPIを使用して、可能な限り多くのアニメーションを追加するために(Svelteの助けを借りて)上記と超えて行くライブラリです.見事な努力にもかかわらず、それは私が生産に出荷できる何かではない.ドラッグされた要素だけでなく、他のすべての要素は、ドロップイベントが発生するまで、元の場所にとどまる.それは非常に静的で古くなった感じyou can try it for yourself ). 豊かなハリスが言うように:“我々はより良い行うことができます”.
開発者は、ヘビー級と複雑な、しかし、強力なを楽しんでいる.react-beautiful-dnd . Svelte開発者(少なくともあなたの真に)は、残っていた.
svelte-dnd-action それを修正することを目的とする新しいライブラリです.

どのように、Svelte DNDアクションは働きますか?
その名の通り、図書館はSvelte's actions mechanism 任意のリストコンテナをドラッグアンドドロップ(DND)ゾーンにするには.これは、ホスト名(= ==コード)に依存します.また、使用してアニメーションの一部を支援するホストに依存してSvelte's built-in flip animation .
簡単な例を見てみましょう
次の3つの項目を持つリストが表示されます
<style>
    div {
        height: 1.5em;
        width: 10em;
        text-align: center;
        border: 1px solid black;
        margin: 0.2em;
        padding: 0.3em;
    }
</style>
<script>
    let items = [
        {id:1, title: 'I'},
        {id:2, title: 'Am'},
        {id:3, title: 'Yoda'}
    ];
</script>
<section>
    {#each items as item(item.id)}
        <div>
            {item.title}    
        </div>
    {/each}
</section>
さて、ドラッグアンドドロップを使って並べ替えをしたいとしましょう.
Svelte DNDアクションをミックスに追加しましょう.
<style>
    div {
        height: 1.5em;
        width: 10em;
        text-align: center;
        border: 1px solid black;
        margin: 0.2em;
        padding: 0.3em;
    }
</style>
<script>
    import {dndzone} from 'svelte-dnd-action';
    function handleSort(e) {
        items = e.detail.items;
    }
    let items = [
        {id:1, title: 'I'},
        {id:2, title: 'Am'},
        {id:3, title: 'Yoda'}
    ];
</script>
<section use:dndzone={{items}} on:consider={handleSort} on:finalize={handleSort}>
    {#each items as item(item.id)}
        <div>
            {item.title}    
        </div>
    {/each}
</section>
Play with this example in the REPL
簡単、右?
私たちはアイテムをdndzone アクションと我々のリストを更新するときに我々はconsider or finalize イベント.両者の違いはconsider 仲介された状態(アイテムが「部屋を作る」)とfinalize 要素が破棄されたときに送出されます.つの間の区別は、たとえば、サーバー内の新しいリストを保存するかどうかを判断するときに便利です.
通知する重要なことは、リスト内の各項目がid また、我々はまた、キーのキーとして渡すプロパティ#each ブロック.svelte-dnd-action の存在に依存するid プロパティは、あなたがそれを持っていることを確認します.
これはきちんとしています、しかし、まだアニメーションがありません.すべてをうまくアニメーション化するためには、追加する必要がありますflip ミックスとフリップ期間を渡すにはdndzone パラメータとして:
<style>
    div {
        height: 1.5em;
        width: 10em;
        text-align: center;
        border: 1px solid black;
        margin: 0.2em;
        padding: 0.3em;
    }
</style>
<script>
    import {dndzone} from 'svelte-dnd-action';
    import {flip} from 'svelte/animate';
    const flipDurationMs = 200;
    function handleSort(e) {
        items = e.detail.items;
    }
    let items = [
        {id:1, title: 'I'},
        {id:2, title: 'Am'},
        {id:3, title: 'Yoda'}
    ];
</script>
<section use:dndzone={{items, flipDurationMs}} on:consider={handleSort} on:finalize={handleSort}>
    {#each items as item(item.id)}
        <div animate:flip={{duration:flipDurationMs}}>
            {item.title}    
        </div>
    {/each}
</section>
Play with this example in the REPL
ビオラ、それはアニメーション!

ゾーンタイプ
デフォルトではdnd-zone 複数のリストコンテナでは、1つのリストから要素を取得し、別のリストにドロップできます.それはかなりクールですが、時々何がどこに行くことができるかを制御する必要があります.
この必要に対処するためにsvelte-dnd-action オプションを受け入れるtype パラメータ
See it in action in the REPL .
この例では、トップの2つのリストの間に項目を移動できます.あなたはトップリストと下のリストの間にアイテムを移動することはできません“ダーク”(幸いにも、ヨダとルーク安全です).あなたはまだ前に、各リスト内の項目をシャッフルすることができます.
型を使用する一つの便利な方法は入れ子になったdndゾーンのためです.たとえば、トレイルのようなボードを構築している場合は、各列をすることができますdndzone (したがって、項目は一つのカラムから別のカラムに移動することができます)、そしてカラムを保持するコンテナもdndzone の型.このようにして、列はそれらが保持する項目と独立して再注文できます.

他に何ができるか
実際には、このライブラリを行うことができますかなりのビットがあります.
水平方向と垂直方向のリストが含まれているより複雑な例を見るには、ボード(上で説明したように入れ子にされたゾーン)とデモ自動スクロール機能はthis REPL .
それは今日の人々のためのすべてです.幸せなドラッグアンドドロップ.
OCTの3月20日:ライブラリは完全に同様にアクセス可能です.もっと読むことができます.