fix(frontend): improve folder picker with sticky create button and drawer flow (#7985)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Guilhem
2026-02-17 16:32:25 +00:00
committed by GitHub
parent 4b55f549a5
commit 548830bbaa
2 changed files with 63 additions and 10 deletions
@@ -1,12 +1,18 @@
<script lang="ts">
import { FolderService } from '$lib/gen'
import { workspaceStore, userStore } from '$lib/stores'
import { Eye } from 'lucide-svelte'
import { Eye, PlusIcon } from 'lucide-svelte'
import { Button, Drawer, DrawerContent } from './common'
import FolderEditor from './FolderEditor.svelte'
import Select from './select/Select.svelte'
import TextInput from './text_input/TextInput.svelte'
import Label from './Label.svelte'
import { tick } from 'svelte'
let folders: { name: string; write: boolean }[] = $state([])
let filterText: string = $state('')
let selectOpen: boolean = $state(false)
let nameInput: TextInput | undefined = $state()
let newFolder: Drawer | null = $state(null)
let viewFolder: Drawer | null = $state(null)
let newFolderName: string = $state('')
@@ -57,10 +63,12 @@
)
}
async function openCreateFolder(name: string) {
newFolderName = name
await addFolder()
async function openCreateFolder() {
newFolderName = filterText
folderCreated = undefined
newFolder?.openDrawer()
await tick()
nameInput?.focus()
}
async function addFolder() {
@@ -82,12 +90,25 @@
}))
)
let noMatchingItems = $derived(
filterText &&
!selectItems.some((item) => item.label.toLowerCase().includes(filterText.toLowerCase()))
)
function handleSelectKeydown(e: KeyboardEvent) {
if (e.key === 'Enter' && selectOpen && noMatchingItems) {
e.preventDefault()
selectOpen = false
openCreateFolder()
}
}
loadFolders()
</script>
<Drawer bind:this={newFolder} name="newFolder" offset={drawerOffset}>
<DrawerContent
title="Folder {folderCreated ?? ''}"
title={folderCreated ? `Folder ${folderCreated}` : 'Create folder'}
on:close={() => {
newFolder?.closeDrawer()
folderCreated = undefined
@@ -95,6 +116,25 @@
>
{#if folderCreated}
<FolderEditor name={folderCreated} />
{:else}
<div class="flex flex-col gap-4">
<Label label="Folder name">
<TextInput
bind:this={nameInput}
bind:value={newFolderName}
inputProps={{
placeholder: 'folder_name',
onkeydown: (e: KeyboardEvent) => {
if (e.key === 'Enter' && newFolderName) {
e.preventDefault()
addFolder()
}
}
}}
/>
</Label>
<Button variant="accent" disabled={!newFolderName} on:click={addFolder}>Create</Button>
</div>
{/if}
</DrawerContent>
</Drawer>
@@ -105,16 +145,30 @@
</DrawerContent>
</Drawer>
<div class="flex flex-row items-center gap-1 w-full">
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="flex flex-row items-center gap-1 w-full" onkeydown={handleSelectKeydown}>
<Select
bind:value={folderName}
bind:filterText
bind:open={selectOpen}
items={selectItems}
disabled={disabled || disableEditing}
{size}
placeholder="Select folder"
createText="Create folder"
onCreateItem={openCreateFolder}
/>
>
{#snippet bottomSnippet({ close })}
<button
class="sticky py-2 px-4 w-full text-left text-xs font-semibold text-medium hover:bg-surface-hover flex items-center justify-center gap-2 border-t border-border-light {noMatchingItems ? 'bg-surface-hover' : ''}"
onclick={() => {
close()
openCreateFolder()
}}
>
<PlusIcon class="inline" size={16} />
Create folder
</button>
{/snippet}
</Select>
<Button
title="View folder"
variant="subtle"
-1
View File
@@ -406,7 +406,6 @@
{#if !hideUser}
<div class="block">
<ToggleButtonGroup
class="mt-0.5"
bind:selected={meta.ownerKind}
on:selected={(e) => {
setDirty()