generated from nhcarrigan/template
feat: add create and delete file/folder functionality to editor
- Add Tauri backend commands: create_file, create_directory, delete_file, delete_directory - Add editor store functions for create/delete with auto-refresh - Add FileContextMenu component with right-click support - Add InputDialog component for file/folder name input - Add ConfirmDialog component for delete confirmation - Add Ctrl+N keyboard shortcut for new file - Update keyboard shortcuts modal with new shortcuts - Auto-close tabs when their files are deleted - Auto-refresh file tree after create/delete operations
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
title: string;
|
||||
placeholder?: string;
|
||||
confirmText?: string;
|
||||
cancelText?: string;
|
||||
onConfirm: (value: string) => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
let {
|
||||
title,
|
||||
placeholder = "",
|
||||
confirmText = "Create",
|
||||
cancelText = "Cancel",
|
||||
onConfirm,
|
||||
onCancel,
|
||||
}: Props = $props();
|
||||
|
||||
let inputValue = $state("");
|
||||
let inputElement: HTMLInputElement | undefined = $state();
|
||||
|
||||
$effect(() => {
|
||||
if (inputElement) {
|
||||
inputElement.focus();
|
||||
}
|
||||
});
|
||||
|
||||
function handleSubmit() {
|
||||
const trimmed = inputValue.trim();
|
||||
if (trimmed) {
|
||||
onConfirm(trimmed);
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeydown(event: KeyboardEvent) {
|
||||
if (event.key === "Escape") {
|
||||
onCancel();
|
||||
} else if (event.key === "Enter") {
|
||||
handleSubmit();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window onkeydown={handleKeydown} />
|
||||
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50" onclick={onCancel}>
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div
|
||||
class="mx-4 w-full max-w-md rounded-lg border border-gray-700 bg-gray-800 p-6 shadow-xl"
|
||||
onclick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<h2 class="mb-4 text-lg font-semibold text-gray-100">{title}</h2>
|
||||
|
||||
<input
|
||||
bind:this={inputElement}
|
||||
bind:value={inputValue}
|
||||
type="text"
|
||||
{placeholder}
|
||||
class="mb-6 w-full rounded-md border border-gray-600 bg-gray-700 px-3 py-2 text-sm text-gray-100 placeholder-gray-400 focus:border-pink-500 focus:outline-none focus:ring-1 focus:ring-pink-500"
|
||||
/>
|
||||
|
||||
<div class="flex justify-end gap-3">
|
||||
<button
|
||||
class="rounded-md border border-gray-600 bg-gray-700 px-4 py-2 text-sm text-gray-200 hover:bg-gray-600"
|
||||
onclick={onCancel}
|
||||
>
|
||||
{cancelText}
|
||||
</button>
|
||||
<button
|
||||
class="rounded-md bg-pink-600 px-4 py-2 text-sm text-white hover:bg-pink-700 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
onclick={handleSubmit}
|
||||
disabled={!inputValue.trim()}
|
||||
>
|
||||
{confirmText}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user