Skip to content

Commit cc3548a

Browse files
Rich-HarrisRich Harris
and
Rich Harris
authored
Filetree overhaul (sveltejs#244)
* flatten DOM * fix blur * tidy up * fix arrow * remove scope.depth * remove depth property * various tweaks * simplification * add file icon * keyboard nav * toggle expanded state with arrow keys * prevent duplicates * improve input styles * tweaks * fix * fix --------- Co-authored-by: Rich Harris <git@rich-harris.dev>
1 parent 2176fb3 commit cc3548a

File tree

32 files changed

+280
-281
lines changed

32 files changed

+280
-281
lines changed

content/tutorial/01-svelte/01-introduction/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Introduction",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/01-svelte/02-reactivity/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Reactivity",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/01-svelte/03-props/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Props",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/01-svelte/04-logic/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Logic",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/01-svelte/05-events/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Events",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/01-svelte/06-bindings/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Bindings",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/01-svelte/07-lifecycle/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Lifecycle",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/01-svelte/08-stores/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Stores",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/01-svelte/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Welcome to Svelte",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/02-sveltekit/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Introduction to SvelteKit",
33
"scope": {
44
"prefix": "/",
5-
"depth": 0,
65
"name": "project"
76
},
87
"focus": "/src/routes/+page.svelte"

content/tutorial/03-advanced-svelte/01-motion/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Motion",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/02-transitions/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Transitions",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/03-animations/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Animations",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/04-actions/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Actions",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/05-bindings/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Advanced bindings",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/06-classes/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Classes",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/07-composition/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Component composition",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/08-context/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Context API",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/09-special-elements/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Special elements",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/10-module-context/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Module context",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/11-special-tags/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Debugging",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/12-next-steps/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Next steps",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/03-advanced-svelte/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Advanced Svelte",
33
"scope": {
44
"prefix": "/src/lib/",
5-
"depth": 2,
65
"name": "src"
76
},
87
"focus": "/src/lib/App.svelte"

content/tutorial/04-advanced-sveltekit/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"title": "Advanced SvelteKit",
33
"scope": {
44
"prefix": "/",
5-
"depth": 0,
65
"name": "project"
76
},
87
"focus": "/src/routes/+page.svelte"

src/lib/icons/file.svg

Lines changed: 3 additions & 0 deletions
Loading

src/lib/types/index.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ export interface Adapter extends AdapterInternal {
3232

3333
export interface Scope {
3434
prefix: string;
35-
depth: number;
3635
name: string;
3736
}
3837

src/routes/tutorial/[slug]/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
pos={$mobile ? (selected_view === 1 ? '100%' : '0%') : '50%'}
7272
>
7373
<section slot="a">
74-
<SplitPane type="horizontal" min="80px" max="300px" pos="200px">
74+
<SplitPane type="horizontal" min="120px" max="300px" pos="200px">
7575
<section class="navigator" slot="a">
7676
<Filetree readonly={mobile} />
7777

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
<script>
22
import * as context from './context.js';
33
import Item from './Item.svelte';
4+
import file_icon from '$lib/icons/file.svg';
45
import { selected, solution, state } from '../state.js';
56
67
/** @type {import('$lib/types').FileStub} */
78
export let file;
89
10+
/** @type {number} */
11+
export let depth;
12+
913
const { rename, remove, readonly } = context.get();
1014
1115
let renaming = false;
@@ -33,40 +37,22 @@
3337
: [];
3438
</script>
3539

36-
<div class="row" class:selected={file.name === $selected?.name}>
37-
<Item
38-
can_rename={can_remove}
39-
{renaming}
40-
basename={file.basename}
41-
{actions}
42-
on:click={() => state.select_file(file.name)}
43-
on:edit={() => {
44-
renaming = true;
45-
}}
46-
on:rename={(e) => {
47-
rename(file, e.detail.basename);
48-
}}
49-
on:cancel={() => {
50-
renaming = false;
51-
}}
52-
/>
53-
</div>
54-
55-
<style>
56-
.selected {
57-
color: var(--prime) !important;
58-
}
59-
60-
.selected::after {
61-
content: '';
62-
position: absolute;
63-
width: 1rem;
64-
height: 1rem;
65-
top: 0.1rem;
66-
right: calc(-2.6rem - 2px);
67-
background-color: var(--sk-back-3);
68-
border: 1px solid var(--sk-back-4);
69-
transform: translate(0, 0.2rem) rotate(45deg);
70-
z-index: 2;
71-
}
72-
</style>
40+
<Item
41+
{depth}
42+
can_rename={can_remove}
43+
{renaming}
44+
basename={file.basename}
45+
icon={file_icon}
46+
selected={file.name === $selected?.name}
47+
{actions}
48+
on:click={() => state.select_file(file.name)}
49+
on:edit={() => {
50+
renaming = true;
51+
}}
52+
on:rename={(e) => {
53+
rename(file, e.detail.basename);
54+
}}
55+
on:cancel={() => {
56+
renaming = false;
57+
}}
58+
/>

src/routes/tutorial/[slug]/filetree/Filetree.svelte

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
return;
2323
}
2424
25+
const existing = $state.stubs.find((stub) => stub.name === name);
26+
if (existing) {
27+
modal_text = `A ${existing.type} already exists with this name`;
28+
return;
29+
}
30+
2531
const basename = /** @type {string} */ (name.split('/').pop());
2632
2733
/** @type {import('$lib/types').Stub} */
@@ -135,19 +141,31 @@
135141
}
136142
</script>
137143

138-
<div class="filetree">
144+
<ul
145+
class="filetree"
146+
on:keydown={(e) => {
147+
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
148+
e.preventDefault();
149+
const lis = Array.from(e.currentTarget.querySelectorAll('li'));
150+
const focused = lis.findIndex((li) => li.contains(e.target));
151+
152+
const d = e.key === 'ArrowUp' ? -1 : +1;
153+
154+
lis[focused + d]?.querySelector('button')?.focus();
155+
}
156+
}}
157+
>
139158
<Folder
140159
prefix={$scope.prefix}
141-
depth={$scope.depth}
160+
depth={0}
142161
directory={{
143162
type: 'directory',
144163
name: '',
145164
basename: $scope.name
146165
}}
147166
files={$stubs.filter((stub) => !hidden.has(stub.basename))}
148-
expanded
149167
/>
150-
</div>
168+
</ul>
151169

152170
{#if modal_text}
153171
<Modal on:close={() => (modal_text = '')}>
@@ -165,8 +183,10 @@
165183
flex: 1;
166184
overflow-y: auto;
167185
overflow-x: hidden;
168-
padding: 2rem;
186+
padding: 1rem 0rem;
187+
margin: 0;
169188
background: var(--sk-back-1);
189+
list-style: none;
170190
}
171191
172192
.filetree::before {
@@ -179,34 +199,6 @@
179199
border-right: 1px solid var(--sk-back-4);
180200
}
181201
182-
.filetree :global(.row) {
183-
--bg: var(--sk-back-1);
184-
--inset: calc((var(--depth) * 1.2rem) + 1.5rem);
185-
position: relative;
186-
width: calc(100% - 1px);
187-
padding: 0 0 0 var(--inset);
188-
height: 1.4em;
189-
z-index: 1;
190-
background: var(--bg);
191-
color: var(--sk-text-2);
192-
}
193-
194-
.filetree :global(.row:hover) {
195-
--bg: var(--sk-back-3);
196-
}
197-
198-
.filetree :global(button),
199-
.filetree :global(input) {
200-
background-size: 1.2rem 1.2rem;
201-
background-position: 0 45%;
202-
background-repeat: no-repeat;
203-
}
204-
205-
.filetree :global(:focus-visible) {
206-
outline: none;
207-
border: 2px solid var(--sk-theme-3) !important;
208-
}
209-
210202
.modal-contents p {
211203
white-space: pre-line;
212204
}

0 commit comments

Comments
 (0)