|
1 | 1 | <script lang="ts">
|
2 |
| - import { forcefocus } from '@sveltejs/site-kit/actions'; |
3 |
| - import { tick } from 'svelte'; |
4 | 2 | import RunesInfo from './RunesInfo.svelte';
|
5 | 3 | import Migrate from './Migrate.svelte';
|
6 | 4 | import type { Workspace, File } from 'editor';
|
|
14 | 12 |
|
15 | 13 | let { runes, onchange, workspace, can_migrate }: Props = $props();
|
16 | 14 |
|
17 |
| - let editing_name: string | null = $state(null); |
18 |
| - let input_value = $state(''); |
| 15 | + let input_value = $state(workspace.current.name); |
19 | 16 |
|
20 |
| - function select_file(filename: string) { |
21 |
| - if (workspace.current.name !== filename) { |
22 |
| - editing_name = null; |
23 |
| - workspace.select(filename); |
24 |
| - } |
25 |
| - } |
26 |
| -
|
27 |
| - function edit_tab(file: File) { |
28 |
| - if (workspace.current.name === file.name) { |
29 |
| - editing_name = file.name; |
30 |
| - input_value = file.name; |
31 |
| - } |
32 |
| - } |
33 |
| -
|
34 |
| - async function close_edit() { |
35 |
| - if (input_value === editing_name) { |
| 17 | + async function close_edit(file: File) { |
| 18 | + if (input_value === file.name) { |
36 | 19 | // nothing to do
|
37 |
| - editing_name = null; |
38 | 20 | return;
|
39 | 21 | }
|
40 | 22 |
|
41 |
| - const edited_file = (workspace.files as File[]).find((val) => val.name === editing_name); |
42 |
| - if (!edited_file) return; // TODO can this happen? |
| 23 | + const deconflicted = deconflict(input_value, file); |
43 | 24 |
|
44 |
| - const deconflicted = deconflict(input_value, edited_file); |
45 |
| -
|
46 |
| - workspace.rename(edited_file, deconflicted); |
| 25 | + workspace.rename(file, deconflicted); |
47 | 26 | workspace.focus();
|
48 |
| -
|
49 |
| - editing_name = null; |
50 | 27 | }
|
51 | 28 |
|
52 | 29 | function deconflict(name: string, file?: File) {
|
|
81 | 58 | text: true
|
82 | 59 | });
|
83 | 60 |
|
84 |
| - editing_name = file.name; |
85 | 61 | input_value = file.name;
|
86 |
| -
|
87 | 62 | onchange();
|
88 | 63 | }
|
89 | 64 |
|
|
97 | 72 | <div class="file-tabs">
|
98 | 73 | {#each workspace.files as File[] as file, index (file.name)}
|
99 | 74 | <div
|
100 |
| - id={file.name} |
101 | 75 | class="button"
|
102 | 76 | role="button"
|
103 | 77 | tabindex="0"
|
104 |
| - class:active={file.name === workspace.current.name} |
105 |
| - class:draggable={file.name !== editing_name && index !== 0} |
| 78 | + class:active={file === workspace.current} |
| 79 | + class:draggable={file !== workspace.current && index !== 0} |
106 | 80 | class:drag-over={file === dragover}
|
107 |
| - onclick={() => select_file(file.name)} |
108 |
| - onkeyup={(e) => e.key === ' ' && select_file(file.name)} |
109 |
| - draggable={file.name !== editing_name} |
| 81 | + onclick={() => { |
| 82 | + workspace.select(file.name); |
| 83 | + input_value = file.name; |
| 84 | + }} |
| 85 | + onkeyup={(e) => e.key === ' ' && workspace.select(file.name)} |
| 86 | + draggable={file !== workspace.current} |
110 | 87 | ondragstart={() => (dragging = file)}
|
111 | 88 | ondragover={(e) => (e.preventDefault(), (dragover = file))}
|
112 | 89 | ondragleave={(e) => (e.preventDefault(), (dragover = null))}
|
|
120 | 97 | >
|
121 | 98 | <i class="drag-handle"></i>
|
122 | 99 |
|
123 |
| - {#if file.name === 'App.svelte'} |
124 |
| - <div class="uneditable"> |
125 |
| - App.svelte{#if workspace.modified[file.name]}*{/if} |
126 |
| - </div> |
127 |
| - {:else if file.name === editing_name} |
128 |
| - <span class="input-sizer"> |
129 |
| - <span style="color: transparent">{input_value}</span> |
130 |
| - </span> |
| 100 | + <span class:editable={file.name !== 'App.svelte'}> |
| 101 | + {(file === workspace.current && file.name !== 'App.svelte' ? input_value : file.name) + |
| 102 | + (workspace.modified[file.name] ? '*' : '')} |
| 103 | + </span> |
131 | 104 |
|
| 105 | + {#if file === workspace.current && file.name !== 'App.svelte'} |
132 | 106 | <!-- svelte-ignore a11y_autofocus -->
|
133 | 107 | <input
|
134 |
| - use:forcefocus |
135 | 108 | spellcheck={false}
|
136 | 109 | bind:value={input_value}
|
137 | 110 | onfocus={async (event) => {
|
138 | 111 | const input = event.currentTarget;
|
139 |
| - await tick(); |
140 |
| - input.select(); |
| 112 | + setTimeout(() => { |
| 113 | + input.select(); |
| 114 | + }); |
141 | 115 | }}
|
142 |
| - onblur={close_edit} |
| 116 | + onblur={() => close_edit(file)} |
143 | 117 | onkeydown={(e) => {
|
144 | 118 | if (e.key === 'Enter') {
|
145 | 119 | e.preventDefault();
|
146 | 120 | e.currentTarget.blur();
|
147 | 121 | }
|
148 | 122 | }}
|
149 | 123 | />
|
150 |
| - {:else} |
151 |
| - <div |
152 |
| - class="editable" |
153 |
| - title="edit component name" |
154 |
| - onclick={() => edit_tab(file)} |
155 |
| - onkeyup={(e) => e.key === ' ' && edit_tab(file)} |
156 |
| - > |
157 |
| - {file.name}{#if workspace.modified[file.name]}*{/if} |
158 |
| - </div> |
159 | 124 |
|
160 | 125 | <span
|
161 | 126 | class="remove"
|
|
264 | 229 | position: absolute;
|
265 | 230 | width: 100%;
|
266 | 231 | border: none;
|
267 |
| - color: var(--sk-fg-accent); |
268 | 232 | outline: none;
|
269 |
| - background-color: transparent; |
| 233 | + background-color: inherit; |
| 234 | + color: inherit; |
270 | 235 | top: 0;
|
271 | 236 | left: 0;
|
272 | 237 | height: 100%;
|
|
275 | 240 | justify-content: center;
|
276 | 241 | font-family: var(--sk-font-family-ui);
|
277 | 242 | font: var(--sk-font-ui-small); /* TODO can we just inherit */
|
278 |
| - padding: 0 1rem 1px 2em; |
| 243 | + padding: 0 1rem 0 2em; |
279 | 244 | box-sizing: border-box;
|
280 |
| - } |
281 | 245 |
|
282 |
| - .duplicate { |
283 |
| - color: var(--sk-fg-accent); |
| 246 | + &:focus { |
| 247 | + color: var(--sk-fg-accent); |
| 248 | + } |
284 | 249 | }
|
285 | 250 |
|
286 | 251 | .remove {
|
|
0 commit comments