---
title: "파일과 다른 앱"
description: "브라우저 자체의 드래그 앤 드롭을 라이브러리의 드래그로. 다른 앱의 파일, 링크, 텍스트를 드롭 대상과 자리를 만들어 주는 리스트로, 페이지 밖으로 드래그하는 항목, 그리고 앱의 창 사이에서."
canonical_url: "https://zizigy.github.io/vue-dnd-kit/ko/docs/guides/native"
---

> Index of every page on this site: [llms.txt](https://zizigy.github.io/vue-dnd-kit/llms.txt)

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

<example height="34rem" hint="다른 앱에서 이미지, 링크, 텍스트를 놓아 보세요. 카드를 밖으로 끌어내거나, 두 번째 창에서 연 이 페이지로 드래그하세요" name="moodboard">



</example>

## 페이지 밖에서

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

```ts [Board.vue]
const { items } = makeSortableList(grid, {
  items: cards,
  group: 'moodboard',
  strategy: 'grid',
  external: { files: 'image/*', links: true, text: true },
  createItem: fromOutside,
});
```

<table>
<thead>
  <tr>
    <th>
      <code>
        external
      </code>
    </th>
    
    <th>
      받는 것
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        files
      </code>
    </td>
    
    <td>
      파일. <code>
        true
      </code>
      
      는 모든 파일, <code>
        <input accept>
      </code>
      
      와 같은 방식의 MIME 타입과 확장자(<code>
        'image/*, .md'
      </code>
      
      ), 또는 파일마다 묻는 함수. 폴더는 절대 받지 않습니다.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        multiple
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
      
      : 한 번에 파일 하나. 여러 파일의 드래그는 거부됩니다.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        links
      </code>
    </td>
    
    <td>
      링크(<code>
        text/uri-list
      </code>
      
      ). 다른 탭의 주소, 페이지의 링크.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        text
      </code>
    </td>
    
    <td>
      일반 텍스트. 다른 앱에서 선택한 내용.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        types
      </code>
    </td>
    
    <td>
      그 밖의 MIME 타입. 다른 앱이 제공하는 그대로 적습니다.
    </td>
  </tr>
</tbody>
</table>

`makeDroppable`도 같은 옵션을 받습니다. 아바타 이미지를 받는 영역은
[드래그 앤 드롭](https://zizigy.github.io/docs/guides/drag-and-drop#files-from-the-computer)에 있습니다.

### 드래그가 담고 있는 것

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

<table>
<thead>
  <tr>
    <th>
      
    </th>
    
    <th>
      드래그하는 동안
    </th>
    
    <th>
      드롭할 때
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        types
      </code>
    </td>
    
    <td>
      제공하는 MIME 타입: <code>
        Files
      </code>
      
      , <code>
        text/uri-list
      </code>
      
      …
    </td>
    
    <td>
      같음
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fileTypes
      </code>
    </td>
    
    <td>
      파일마다 MIME 타입 하나
    </td>
    
    <td>
      같음
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        files
      </code>
    </td>
    
    <td>
      비어 있음
    </td>
    
    <td>
      대상이 받는 파일(<code>
        File
      </code>
      
      로)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        urls
      </code>
      
      , <code>
        text
      </code>
      
      , <code>
        html
      </code>
    </td>
    
    <td>
      비어 있음
    </td>
    
    <td>
      링크, 텍스트, HTML
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        getData(type)
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      제공하는 모든 타입의 데이터
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ready
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
  </tr>
</tbody>
</table>

### 리스트로

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

```ts [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`를 쓰면 항목의 마우스 드래그가 브라우저 자체의 드래그가 되므로, 페이지를 떠날 수 있습니다.
데스크톱으로, 에디터로, 채팅으로, 다른 탭으로.

```ts [Tile.vue]
makeSortableItem(el, {
  item: () => props.card,
  native: { data: () => toOutside(props.card) },
});
```

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

- 드래그하는 동안 다른 창은 이미 항목을 가지고 있습니다. 그 창의 리스트가 항목을 들어갈 자리에
보여 줍니다.
- 드롭하면 항목이 그쪽으로 들어가고, 이쪽에서는 리스트를 떠납니다(드롭이 이동이었기 때문입니다).
대신 복사하려면 <kbd value="Ctrl">



</kbd>

(Mac에서는 <kbd value="Option">



</kbd>

)을 누르고 있으세요.
- `createItem`이 있는 리스트는 이런 항목에 대해서도 호출됩니다. 이때 `active.external.group`이
설정되고, 항목은 `active.items[].item`에 있습니다. 그 항목들을 반환하거나, 그 창의 key를 가진
복사본을 반환하세요. `createItem`이 없으면 항목이 그대로 들어갑니다.
- 항목은 JSON으로 전달됩니다. 날짜는 문자열이 되고, 함수는 빠집니다.

## 제한

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

API는 [makeDroppable](https://zizigy.github.io/docs/api/make-droppable#from-outside-the-page)과
[makeDraggable](https://zizigy.github.io/docs/api/make-draggable#out-of-the-page)에 있습니다.

## Sitemap

See the full [sitemap](https://zizigy.github.io/vue-dnd-kit/sitemap.md) for all pages.
