문서/가이드

파일과 다른 앱

브라우저 자체의 드래그 앤 드롭을 라이브러리의 드래그로. 다른 앱의 파일, 링크, 텍스트를 드롭 대상과 자리를 만들어 주는 리스트로, 페이지 밖으로 드래그하는 항목, 그리고 앱의 창 사이에서.

이 페이지 편집

이 페이지는 AI가 번역했으며 부정확한 내용이 있을 수 있습니다. 영어 원문 읽기

라이브러리의 드래그는 페이지 안에서 일어납니다. 브라우저에는 페이지의 경계를 넘는 자체 드래그 앤 드롭이 있습니다. 데스크톱의 파일, 다른 탭의 링크, 다른 앱의 텍스트, 그리고 그 모든 곳으로 끌어내는 여러분의 항목이 그렇습니다. 라이브러리는 이런 드래그도 프로바이더의 드래그로 실행합니다. 대상이 강조되고, 리스트가 자리를 만들고, 이벤트와 스크린 리더 문구도 평소와 같습니다.

Live

데모 불러오는 중…

<script setup lang="ts">
import { DnDProvider } from '@vue-dnd-kit/core';
import Board from './Board.vue';
</script>

<template>
  <DnDProvider>
    <Board />
  </DnDProvider>
</template>

페이지 밖에서

대상은 external로 이런 드래그를 받으며, 무엇을 받는지 지정합니다. 이 옵션이 없는 대상은 이런 드래그를 무시합니다.

Board.vue
const { items } = makeSortableList(grid, {
  items: cards,
  group: 'moodboard',
  strategy: 'grid',
  external: { files: 'image/*', links: true, text: true },
  createItem: fromOutside,
});
external받는 것
files파일. true는 모든 파일, <input accept>와 같은 방식의 MIME 타입과 확장자('image/*, .md'), 또는 파일마다 묻는 함수. 폴더는 절대 받지 않습니다.
multiplefalse: 한 번에 파일 하나. 여러 파일의 드래그는 거부됩니다.
links링크(text/uri-list). 다른 탭의 주소, 페이지의 링크.
text일반 텍스트. 다른 앱에서 선택한 내용.
types그 밖의 MIME 타입. 다른 앱이 제공하는 그대로 적습니다.

makeDroppable도 같은 옵션을 받습니다. 아바타 이미지를 받는 영역은 드래그 앤 드롭에 있습니다.

드래그가 담고 있는 것

브라우저는 드롭될 때까지 드래그의 데이터를 내주지 않습니다. 드래그하는 동안 페이지는 어떤 종류의 데이터가 담겨 있는지만 알 수 있습니다. active.external과 e.external이 알려진 것을 알려 줍니다.

드래그하는 동안드롭할 때
types제공하는 MIME 타입: Files, text/uri-list…같음
fileTypes파일마다 MIME 타입 하나같음
files비어 있음대상이 받는 파일(File로)
urls, text, html비어 있음링크, 텍스트, HTML
getData(type)''제공하는 모든 타입의 데이터
readyfalsetrue

리스트로

리스트는 일반 draggable과 마찬가지로 createItem으로 자리를 만듭니다. createItem은 두 번 호출됩니다. 드래그하는 동안에는 어디로 갈지 보여 주는 항목을 위해, 드롭할 때는 데이터와 함께 실제로 들어갈 것을 위해서입니다. 항목 배열을 반환하면 모두 그 자리에 삽입됩니다. 이미지마다 카드 하나입니다.

cards.ts
export const fromOutside = (active: Active): Card | Card[] | undefined => {
  const { external } = active;
  if (!external) return undefined;
  // While it is held: a tile that says what is coming.
  if (!external.ready) return { id: 'incoming', kind: 'incoming', label: incoming(external) };
  // At the drop: a card each.
  if (external.files.length) {
    return external.files.map((file) => ({ id: uid(), kind: 'image', src: URL.createObjectURL(file), name: file.name }));
  }
  if (external.urls.length) return external.urls.map((url) => ({ id: uid(), kind: 'link', url, title: host(url) }));
  const text = external.text.trim();
  return text ? { id: uid(), kind: 'note', text } : undefined;
};
  • 들어오는 중인 타일은 다른 행과 똑같은 리스트의 한 행입니다. 리스트가 그것을 렌더링하고, 주변 행은 미끄러지듯 비켜나며, onDrop은 실제 항목을 받습니다.
  • 트리도 이런 드래그를 받지만, 한 번에 노드 하나입니다. 파일마다 자식이 하나씩 있는 폴더 노드라면 여러 파일을 담을 수 있습니다.
  • 드롭 이벤트에는 데이터가 담긴 e.external이 있습니다. 리스트의 onDrop에서도, 모니터에서도 마찬가지입니다.

페이지 밖으로

native를 쓰면 항목의 마우스 드래그가 브라우저 자체의 드래그가 되므로, 페이지를 떠날 수 있습니다. 데스크톱으로, 에디터로, 채팅으로, 다른 탭으로.

Tile.vue
makeSortableItem(el, {
  item: () => props.card,
  native: { data: () => toOutside(props.card) },
});
cards.ts
case 'link':
  return { 'text/uri-list': card.url, 'text/plain': card.url };
case 'note':
  return { 'text/plain': card.text };
  • data는 항목을 MIME 타입과 텍스트로 다른 앱에 건넵니다. text/plain, text/uri-list, text/html. 드래그가 시작될 때 읽습니다. 이것이 없으면 native: true는 label을 텍스트로 담습니다.
  • 페이지 위에서는 다른 드래그와 똑같이 동작합니다. 대상, 자리를 만드는 리스트, 드롭. 오버레이 대신 브라우저가 드래그되는 이미지를 그리고, 요소는 제자리에 남습니다(overlay: false여도 transform은 null로 유지됩니다).
  • 항목의 터치 드래그와 키보드 드래그는 라이브러리의 드래그로 남습니다. 브라우저에는 이를 위한 자체 드래그가 없습니다.
  • effect(effectAllowed)는 드롭되는 곳이 무엇을 할 수 있는지 정합니다. 기본값은 'copyMove'입니다. 다른 곳에 드롭하면 드래그는 droppedOutside가 'move', 'copy', 'link' 중 하나인 상태로 끝나며, 이는 onDragEnd에서 받습니다. 이동이면 항목이 리스트에서 빠지고, 복사면 그대로 남습니다.

makeDraggable도 같은 방식으로 native를 받습니다.

창 사이에서

native가 있는 항목은 자기 자신도 담아 갑니다. 여러분 앱의 다른 창에 있는 같은 그룹의 리스트는 그 항목을 자기 리스트 중 하나에서 온 것처럼 받아들입니다. 무드보드를 두 번째 창에서 열고 카드를 건너편으로 드래그해 보세요.

  • 드래그하는 동안 다른 창은 이미 항목을 가지고 있습니다. 그 창의 리스트가 항목을 들어갈 자리에 보여 줍니다.
  • 드롭하면 항목이 그쪽으로 들어가고, 이쪽에서는 리스트를 떠납니다(드롭이 이동이었기 때문입니다). 대신 복사하려면 Ctrl(Mac에서는 Option)을 누르고 있으세요.
  • createItem이 있는 리스트는 이런 항목에 대해서도 호출됩니다. 이때 active.external.group이 설정되고, 항목은 active.items[].item에 있습니다. 그 항목들을 반환하거나, 그 창의 key를 가진 복사본을 반환하세요. createItem이 없으면 항목이 그대로 들어갑니다.
  • 항목은 JSON으로 전달됩니다. 날짜는 문자열이 되고, 함수는 빠집니다.

제한

  • 데이터는 드롭할 때만 오며, 그 전에는 절대 오지 않습니다. 드래그하는 동안 보여 줄 항목은 데이터 없이 설계하세요.
  • 파일 드래그는 마우스와 트랙패드 사용자를 위한 것입니다. 영역 옆에 <input type="file">도 함께 두세요.
  • 페이지 밖에서 오는 드래그는 페이지의 프로바이더 하나만 받습니다. 그런 드래그를 받을 대상이 있는 첫 번째 프로바이더입니다.
  • Firefox에서는 드래그 도중 다른 리스트로 옮겨진 뒤 다른 창에 드롭된 항목이 그 드롭을 알지 못합니다. 이쪽에서는 원래 있던 곳에 그대로 남습니다.
  • JSON이 16 KB를 넘는 항목도 다른 창으로 가지만, 그 창은 드롭할 때에야 항목을 보여 줍니다.

API는 makeDroppable과 makeDraggable에 있습니다.