Skip to content

Commit 0e69210

Browse files
committed
allow pasting at the root
1 parent 3eead5f commit 0e69210

File tree

4 files changed

+60
-38
lines changed

4 files changed

+60
-38
lines changed

packages/svelte-file-tree/src/lib/components/Tree.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script
22
lang="ts"
3-
generics="TFile extends FileNode, TFolder extends FolderNode<TFile | TFolder> = DefaultTFolder<TFile>"
3+
generics="TFile extends FileNode = FileNode, TFolder extends FolderNode<TFile | TFolder> = DefaultTFolder<TFile>"
44
>
55
import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
66
import { DEV } from "esm-env";

packages/svelte-file-tree/src/lib/components/TreeItem.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script
22
lang="ts"
3-
generics="TFile extends FileNode, TFolder extends FolderNode<TFile | TFolder> = DefaultTFolder<TFile>"
3+
generics="TFile extends FileNode = FileNode, TFolder extends FolderNode<TFile | TFolder> = DefaultTFolder<TFile>"
44
>
55
import {
66
draggable,

sites/preview/src/lib/components/Tree.svelte

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,61 @@
22
import { Tree, type FolderNode } from "svelte-file-tree";
33
import { flip } from "svelte/animate";
44
import { SvelteSet } from "svelte/reactivity";
5+
import { isControlOrMeta } from "$lib/helpers.js";
56
import TreeItem from "./TreeItem.svelte";
67
import type { TreeProps } from "./types.js";
78
89
const { root }: TreeProps = $props();
910
1011
const expandedIds = new SvelteSet<string>();
1112
let dropDestination: FolderNode | undefined = $state.raw();
13+
14+
let tree: Tree | null = $state.raw(null);
1215
</script>
1316

14-
<Tree
15-
{root}
16-
{expandedIds}
17-
class={[
18-
"min-h-svh p-8",
19-
{
20-
"before:pointer-events-none before:absolute before:inset-2 before:border-2 before:border-red-500":
21-
dropDestination === root,
22-
},
23-
]}
24-
onChildrenChange={(args) => {
25-
if (args.operation === "insert") {
26-
args.children.sort((a, b) => a.name.localeCompare(b.name));
27-
}
28-
}}
29-
onDropDestinationChange={(args) => {
30-
dropDestination = args.dropDestination;
31-
}}
32-
>
33-
{#snippet children({ items })}
34-
{#each items.filter((item) => item.visible) as item (item.node.id)}
35-
<div animate:flip={{ duration: 300 }}>
36-
<TreeItem
37-
{item}
38-
{dropDestination}
39-
onExpand={() => {
40-
expandedIds.add(item.node.id);
41-
}}
42-
onCollapse={() => {
43-
expandedIds.delete(item.node.id);
44-
}}
45-
/>
46-
</div>
47-
{/each}
48-
{/snippet}
49-
</Tree>
17+
<div class="flex min-h-svh p-2">
18+
<Tree
19+
{root}
20+
{expandedIds}
21+
bind:this={tree}
22+
tabindex={0}
23+
class={[
24+
"relative grow p-6 focus-visible:outline-2 focus-visible:outline-current",
25+
{
26+
"before:pointer-events-none before:absolute before:inset-0 before:border-2 before:border-red-500":
27+
dropDestination === root,
28+
},
29+
]}
30+
onChildrenChange={(args) => {
31+
if (args.operation === "insert") {
32+
args.children.sort((a, b) => a.name.localeCompare(b.name));
33+
}
34+
}}
35+
onDropDestinationChange={(args) => {
36+
dropDestination = args.dropDestination;
37+
}}
38+
onkeydown={(event) => {
39+
if (event.key === "v" && isControlOrMeta(event)) {
40+
event.preventDefault();
41+
tree!.paste(root);
42+
}
43+
}}
44+
>
45+
{#snippet children({ items })}
46+
{#each items.filter((item) => item.visible) as item (item.node.id)}
47+
<div animate:flip={{ duration: 300 }}>
48+
<TreeItem
49+
{item}
50+
{dropDestination}
51+
onExpand={() => {
52+
expandedIds.add(item.node.id);
53+
}}
54+
onCollapse={() => {
55+
expandedIds.delete(item.node.id);
56+
}}
57+
/>
58+
</div>
59+
{/each}
60+
{/snippet}
61+
</Tree>
62+
</div>

sites/preview/src/lib/helpers.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @link https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform#examples
3+
*/
4+
export function isControlOrMeta(event: KeyboardEvent | MouseEvent) {
5+
if (navigator.platform.startsWith("Mac") || navigator.platform === "iPhone") {
6+
return event.metaKey;
7+
}
8+
return event.ctrlKey;
9+
}

0 commit comments

Comments
 (0)