refactor: improve UI components for folder and document management

This commit is contained in:
Anish Sarkar 2026-03-27 23:11:13 +05:30
parent 17091edb77
commit ddccba0df8
5 changed files with 56 additions and 30 deletions

View file

@ -1,6 +1,5 @@
"use client"; "use client";
import { FolderPlus } from "lucide-react";
import { useCallback, useEffect, useRef, useState } from "react"; import { useCallback, useEffect, useRef, useState } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { import {
@ -52,22 +51,25 @@ export function CreateFolderDialog({
return ( return (
<Dialog open={open} onOpenChange={onOpenChange}> <Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-sm"> <DialogContent className="select-none max-w-[90vw] sm:max-w-sm p-4 sm:p-5 data-[state=open]:animate-none data-[state=closed]:animate-none">
<DialogHeader> <DialogHeader className="space-y-2 pb-2">
<DialogTitle className="flex items-center gap-2"> <div className="flex items-center gap-2 sm:gap-3">
<FolderPlus className="size-5 text-muted-foreground" /> <div className="flex-1 min-w-0">
{isSubfolder ? "New subfolder" : "New folder"} <DialogTitle className="text-base sm:text-lg">
</DialogTitle> {isSubfolder ? "New subfolder" : "New folder"}
<DialogDescription> </DialogTitle>
{isSubfolder <DialogDescription className="text-xs sm:text-sm mt-0.5">
? `Create a new folder inside "${parentFolderName}".` {isSubfolder
: "Create a new folder at the root level."} ? `Create a new folder inside "${parentFolderName}".`
</DialogDescription> : "Create a new folder at the root level."}
</DialogDescription>
</div>
</div>
</DialogHeader> </DialogHeader>
<form onSubmit={handleSubmit} className="flex flex-col gap-4"> <form onSubmit={handleSubmit} className="flex flex-col gap-3 sm:gap-4">
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<Label htmlFor="folder-name">Folder name</Label> <Label htmlFor="folder-name" className="text-sm">Folder name</Label>
<Input <Input
ref={inputRef} ref={inputRef}
id="folder-name" id="folder-name"
@ -76,14 +78,24 @@ export function CreateFolderDialog({
onChange={(e) => setName(e.target.value)} onChange={(e) => setName(e.target.value)}
maxLength={255} maxLength={255}
autoComplete="off" autoComplete="off"
className="text-sm h-9 sm:h-10"
/> />
</div> </div>
<DialogFooter> <DialogFooter className="flex-row justify-end gap-2 pt-2 sm:pt-3">
<Button type="button" variant="outline" onClick={() => onOpenChange(false)}> <Button
type="button"
variant="secondary"
onClick={() => onOpenChange(false)}
className="h-8 sm:h-9 text-xs sm:text-sm"
>
Cancel Cancel
</Button> </Button>
<Button type="submit" disabled={!name.trim()}> <Button
type="submit"
disabled={!name.trim()}
className="h-8 sm:h-9 text-xs sm:text-sm"
>
Create Create
</Button> </Button>
</DialogFooter> </DialogFooter>

View file

@ -84,7 +84,7 @@ export const DocumentNode = React.memo(function DocumentNode({
role="button" role="button"
tabIndex={0} tabIndex={0}
className={cn( className={cn(
"group flex h-8 items-center gap-1.5 rounded-md px-1 text-sm hover:bg-accent/50 cursor-pointer select-none", "group flex h-8 items-center gap-2.5 rounded-md px-1 text-sm hover:bg-accent/50 cursor-pointer select-none",
isMentioned && "bg-accent/30", isMentioned && "bg-accent/30",
isDragging && "opacity-40" isDragging && "opacity-40"
)} )}
@ -137,7 +137,7 @@ export const DocumentNode = React.memo(function DocumentNode({
<MoreHorizontal className="h-3.5 w-3.5" /> <MoreHorizontal className="h-3.5 w-3.5" />
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-44"> <DropdownMenuContent align="end" className="w-40">
<DropdownMenuItem onClick={() => onPreview(doc)}> <DropdownMenuItem onClick={() => onPreview(doc)}>
<Eye className="mr-2 h-4 w-4" /> <Eye className="mr-2 h-4 w-4" />
Open Open
@ -166,7 +166,7 @@ export const DocumentNode = React.memo(function DocumentNode({
</div> </div>
</ContextMenuTrigger> </ContextMenuTrigger>
<ContextMenuContent className="w-44"> <ContextMenuContent className="w-40">
<ContextMenuItem onClick={() => onPreview(doc)}> <ContextMenuItem onClick={() => onPreview(doc)}>
<Eye className="mr-2 h-4 w-4" /> <Eye className="mr-2 h-4 w-4" />
Open Open

View file

@ -285,7 +285,7 @@ export const FolderNode = React.memo(function FolderNode({
<MoreHorizontal className="h-3.5 w-3.5" /> <MoreHorizontal className="h-3.5 w-3.5" />
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-48"> <DropdownMenuContent align="end" className="w-40">
<DropdownMenuItem <DropdownMenuItem
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
@ -331,7 +331,7 @@ export const FolderNode = React.memo(function FolderNode({
</ContextMenuTrigger> </ContextMenuTrigger>
{!isRenaming && ( {!isRenaming && (
<ContextMenuContent className="w-48"> <ContextMenuContent className="w-40">
<ContextMenuItem onClick={() => onCreateSubfolder(folder.id)}> <ContextMenuItem onClick={() => onCreateSubfolder(folder.id)}>
<FolderPlus className="mr-2 h-4 w-4" /> <FolderPlus className="mr-2 h-4 w-4" />
New subfolder New subfolder

View file

@ -124,10 +124,18 @@ export function FolderPickerDialog({
return ( return (
<Dialog open={open} onOpenChange={onOpenChange}> <Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-sm"> <DialogContent className="select-none max-w-[90vw] sm:max-w-sm p-4 sm:p-5 data-[state=open]:animate-none data-[state=closed]:animate-none">
<DialogHeader> <DialogHeader className="space-y-2 pb-2">
<DialogTitle>{title}</DialogTitle> <div className="flex items-center gap-2 sm:gap-3">
{description && <DialogDescription>{description}</DialogDescription>} <div className="flex-1 min-w-0">
<DialogTitle className="text-base sm:text-lg">{title}</DialogTitle>
{description && (
<DialogDescription className="text-xs sm:text-sm mt-0.5">
{description}
</DialogDescription>
)}
</div>
</div>
</DialogHeader> </DialogHeader>
<div className="max-h-[300px] overflow-y-auto rounded-md border p-1"> <div className="max-h-[300px] overflow-y-auto rounded-md border p-1">
@ -147,11 +155,17 @@ export function FolderPickerDialog({
{renderPickerLevel(null, 1)} {renderPickerLevel(null, 1)}
</div> </div>
<DialogFooter> <DialogFooter className="flex-row justify-end gap-2 pt-2 sm:pt-3">
<Button variant="outline" onClick={() => onOpenChange(false)}> <Button
variant="secondary"
onClick={() => onOpenChange(false)}
className="h-8 sm:h-9 text-xs sm:text-sm"
>
Cancel Cancel
</Button> </Button>
<Button onClick={handleConfirm}>Move here</Button> <Button onClick={handleConfirm} className="h-8 sm:h-9 text-xs sm:text-sm">
Move here
</Button>
</DialogFooter> </DialogFooter>
</DialogContent> </DialogContent>
</Dialog> </Dialog>

View file

@ -617,7 +617,7 @@ export function DocumentsSidebar({
open={folderPickerOpen} open={folderPickerOpen}
onOpenChange={setFolderPickerOpen} onOpenChange={setFolderPickerOpen}
folders={treeFolders} folders={treeFolders}
title={folderPickerTarget?.type === "folder" ? "Move folder to..." : "Move document to..."} title={folderPickerTarget?.type === "folder" ? "Move folder to" : "Move document to"}
description="Select a destination folder, or choose Root to move to the top level." description="Select a destination folder, or choose Root to move to the top level."
disabledFolderIds={folderPickerTarget?.disabledIds} disabledFolderIds={folderPickerTarget?.disabledIds}
onSelect={handleFolderPickerSelect} onSelect={handleFolderPickerSelect}