Skip to content

Commit 0398082

Browse files
author
abdel-17
committed
highlight dragged items
1 parent 4812b93 commit 0398082

22 files changed

+940
-1047
lines changed

eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export default tseslint.config(
4242
},
4343
],
4444
"@typescript-eslint/consistent-type-definitions": "off",
45+
"@typescript-eslint/unbound-method": "off",
4546
},
4647
},
4748
{

packages/svelte-file-tree/package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"directory": "packages/svelte-file-tree"
3636
},
3737
"peerDependencies": {
38-
"svelte": "^5.0.0"
38+
"svelte": "^5.20.0"
3939
},
4040
"devDependencies": {
4141
"@sveltejs/kit": "^2.17.1",
@@ -47,14 +47,13 @@
4747
"prettier": "^3.5.0",
4848
"prettier-plugin-svelte": "^3.3.3",
4949
"publint": "^0.3.4",
50-
"svelte": "5.19.9",
50+
"svelte": "5.20.5",
5151
"svelte-check": "^4.1.4",
5252
"vite": "^6.1.0",
5353
"vitest": "3.0.5",
5454
"vitest-browser-svelte": "^0.1.0"
5555
},
5656
"dependencies": {
57-
"esm-env": "^1.2.2",
58-
"runed": "^0.23.2"
57+
"esm-env": "^1.2.2"
5958
}
6059
}
Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,92 @@
1-
<script lang="ts">
1+
<script lang="ts" module>
22
import type { FileTreeNode, FolderNode } from "$lib/tree.svelte.js";
3+
import { DEV } from "esm-env";
4+
import { getContext, hasContext, setContext } from "svelte";
35
import TreeItemProvider from "./TreeItemProvider.svelte";
4-
import { TreeContext } from "./context.js";
5-
import { createTreeState } from "./state.svelte.js";
6-
import type { TreeItemSnippetProps, TreeProps } from "./types.js";
6+
import { TreeContext } from "./state.svelte.js";
7+
import type { TreeItemProviderContext, TreeProps } from "./types.js";
8+
9+
const CONTEXT_KEY = Symbol("Tree");
10+
11+
export function getTreeContext(): TreeContext {
12+
if (DEV && !hasContext(CONTEXT_KEY)) {
13+
throw new Error("No parent <Tree> found");
14+
}
15+
return getContext(CONTEXT_KEY);
16+
}
17+
</script>
718

19+
<script lang="ts">
20+
const defaultId = $props.id();
821
let {
922
tree,
1023
item,
1124
pasteOperation = $bindable(),
12-
id = crypto.randomUUID(),
25+
id = defaultId,
1326
element = $bindable(null),
1427
generateCopyId = () => crypto.randomUUID(),
15-
onRenameItem = ({ target, name }) => {
16-
target.name = name;
28+
onRenameItem = (args) => {
29+
args.target.name = args.name;
1730
return true;
1831
},
1932
onRenameError,
20-
onMoveItems = ({ updates }) => {
21-
for (const { target, children } of updates) {
33+
onMoveItems = (args) => {
34+
for (const { target, children } of args.updates) {
2235
target.children = children;
2336
}
2437
return true;
2538
},
2639
onMoveError,
27-
onInsertItems = ({ target, start, inserted }) => {
28-
target.children.splice(start, 0, ...inserted);
40+
onInsertItems = (args) => {
41+
args.target.children.splice(args.start, 0, ...args.inserted);
2942
return true;
3043
},
3144
onNameConflict = () => "cancel",
32-
onDeleteItems = ({ updates }) => {
33-
for (const { target, children } of updates) {
45+
onDeleteItems = (args) => {
46+
for (const { target, children } of args.updates) {
3447
target.children = children;
3548
}
3649
return true;
3750
},
38-
...attributes
51+
...rest
3952
}: TreeProps = $props();
4053
41-
const treeState = createTreeState({
54+
const treeContext = new TreeContext({
4255
tree: () => tree,
4356
pasteOperation: () => pasteOperation,
4457
setPasteOperation: (value) => {
4558
pasteOperation = value;
4659
},
47-
treeId: () => id,
60+
id: () => id,
4861
generateCopyId: () => generateCopyId(),
49-
onRenameItem: (event) => onRenameItem(event),
50-
onRenameError: (event) => onRenameError?.(event),
51-
onMoveItems: (event) => onMoveItems(event),
52-
onMoveError: (event) => onMoveError?.(event),
53-
onInsertItems: (event) => onInsertItems(event),
54-
onNameConflict: (event) => onNameConflict(event),
55-
onDeleteItems: (event) => onDeleteItems(event),
62+
onRenameItem: (args) => onRenameItem(args),
63+
onRenameError: (args) => onRenameError?.(args),
64+
onMoveItems: (args) => onMoveItems(args),
65+
onMoveError: (args) => onMoveError?.(args),
66+
onInsertItems: (args) => onInsertItems(args),
67+
onNameConflict: (args) => onNameConflict(args),
68+
onDeleteItems: (args) => onDeleteItems(args),
5669
});
57-
58-
TreeContext.set({ treeState });
70+
setContext(CONTEXT_KEY, treeContext);
5971
</script>
6072

6173
{#snippet items(
6274
nodes: Array<FileTreeNode> = tree.children,
63-
depth: number = 0,
64-
parent?: TreeItemSnippetProps<FolderNode>,
75+
parent?: TreeItemProviderContext<FolderNode>,
6576
)}
6677
{#each nodes as node, index (node.id)}
67-
{@const props = { node, index, depth, parent }}
68-
<TreeItemProvider {node} {index} {depth} {parent}>
69-
{@render item(props)}
70-
</TreeItemProvider>
78+
<TreeItemProvider {node} {index} {parent}>
79+
{#snippet children(context)}
80+
{@render item(context)}
7181

72-
{#if node.type === "folder" && node.expanded}
73-
{@render items(node.children, depth + 1, props as TreeItemSnippetProps<FolderNode>)}
74-
{/if}
82+
{#if node.type === "folder" && node.expanded}
83+
{@render items(node.children, context as TreeItemProviderContext<FolderNode>)}
84+
{/if}
85+
{/snippet}
86+
</TreeItemProvider>
7587
{/each}
7688
{/snippet}
7789

78-
<div bind:this={element} {...attributes} {id} role="tree" aria-multiselectable="true">
90+
<div bind:this={element} {...rest} {id} role="tree" aria-multiselectable="true">
7991
{@render items()}
8092
</div>
Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,42 @@
1-
<script lang="ts">
1+
<script lang="ts" module>
22
import type { FileTreeNode, FolderNode } from "$lib/tree.svelte.js";
3-
import type { Snippet } from "svelte";
4-
import { TreeItemProviderContext } from "./context.js";
5-
import type { TreeItemPosition } from "./state.svelte.js";
3+
import { DEV } from "esm-env";
4+
import { getContext, hasContext, setContext, type Snippet } from "svelte";
5+
import { getTreeContext } from "./Tree.svelte";
6+
import { TreeItemProviderContext } from "./state.svelte.js";
7+
8+
const CONTEXT_KEY = Symbol("TreeItemProvider");
9+
10+
export function getTreeItemProviderContext(): TreeItemProviderContext {
11+
if (DEV && !hasContext(CONTEXT_KEY)) {
12+
throw new Error("No parent <Tree> found");
13+
}
14+
return getContext(CONTEXT_KEY);
15+
}
16+
</script>
17+
18+
<script lang="ts">
19+
const treeContext = getTreeContext();
620
721
const {
822
node,
923
index,
10-
depth,
1124
parent,
1225
children,
1326
}: {
1427
node: FileTreeNode;
1528
index: number;
16-
depth: number;
17-
parent: TreeItemPosition<FolderNode> | undefined;
18-
children: Snippet;
29+
parent: TreeItemProviderContext<FolderNode> | undefined;
30+
children: Snippet<[context: TreeItemProviderContext]>;
1931
} = $props();
2032
21-
TreeItemProviderContext.set({
33+
const itemProviderContext = new TreeItemProviderContext({
34+
treeContext,
2235
node: () => node,
2336
index: () => index,
24-
depth: () => depth,
2537
parent: () => parent,
2638
});
39+
setContext(CONTEXT_KEY, itemProviderContext);
2740
</script>
2841

29-
{@render children()}
42+
{@render children(itemProviderContext)}

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

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)