From 61d818cdfb14bd6070df2c1757a3d9e0fa0cec1d Mon Sep 17 00:00:00 2001 From: Urjit Chakraborty <135136842+urjitc@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:59:08 -0400 Subject: [PATCH 1/4] fix(workspaces): polish mobile home header --- src/components/AppShell.tsx | 2 +- src/features/workspaces/components/WorkspaceHomePage.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/AppShell.tsx b/src/components/AppShell.tsx index a15a79ab..607ae973 100644 --- a/src/components/AppShell.tsx +++ b/src/components/AppShell.tsx @@ -25,7 +25,7 @@ export default function AppShell({ data-app-shell className="flex h-screen flex-col overflow-hidden bg-background text-foreground" > -
+
-
+
+
+ } + content={content} + /> + + {chatPanel && isChatOpen ? ( +
{chatPanel}
+ ) : null} + + ); +} diff --git a/src/features/workspaces/components/WorkspacePdfViewer.tsx b/src/features/workspaces/components/WorkspacePdfViewer.tsx index f8b4c84e..1cdff671 100644 --- a/src/features/workspaces/components/WorkspacePdfViewer.tsx +++ b/src/features/workspaces/components/WorkspacePdfViewer.tsx @@ -37,7 +37,7 @@ import { import { TilingLayer, TilingPluginPackage } from "@embedpdf/plugin-tiling/react"; import { Viewport, ViewportPluginPackage } from "@embedpdf/plugin-viewport/react"; import { ZoomGestureWrapper, ZoomMode, ZoomPluginPackage } from "@embedpdf/plugin-zoom/react"; -import { type ReactNode, useEffect, useState } from "react"; +import { type ReactNode, useCallback, useEffect, useState } from "react"; import { Spinner } from "#/components/ui/spinner"; import { WorkspaceCaptureShortcuts, @@ -52,6 +52,7 @@ import { type WorkspacePdfCaptureResult, } from "#/features/workspaces/components/WorkspacePdfCapture"; import { WorkspacePdfPageControl } from "#/features/workspaces/components/WorkspacePdfPageControl"; +import { useWorkspaceViewCapabilities } from "#/features/workspaces/components/workspace-view-policy"; import { createCaptureAttachmentFile } from "#/features/workspaces/components/workspace-region-capture"; import { stageCaptureAttachmentToComposerWithFeedback } from "#/features/workspaces/composer/workspace-composer-actions"; import type { WorkspaceItem } from "#/features/workspaces/model/types"; @@ -105,12 +106,22 @@ export default function WorkspacePdfViewer({ const fileUrl = getWorkspaceFileContentUrl(workspaceId, item.id); const { engine, error, isLoading } = useEngineContext(); const [isCaptureActive, setIsCaptureActive] = useState(false); + const enableFileCapture = useWorkspaceViewCapabilities().fileCapture; + const captureActive = enableFileCapture && isCaptureActive; + const exitCapture = useCallback(() => { + setIsCaptureActive(false); + }, []); + const toggleCapture = useCallback(() => { + setIsCaptureActive((current) => !current); + }, []); useFileItemToolbar({ - capture: { - isActive: isCaptureActive, - onToggle: () => setIsCaptureActive((current) => !current), - }, + capture: enableFileCapture + ? { + isActive: captureActive, + onToggle: toggleCapture, + } + : undefined, fileName: item.name, fileUrl, slotId: toolbarSlotId ?? item.id, @@ -133,10 +144,11 @@ export default function WorkspacePdfViewer({ documentId={item.id} fileName={item.name} fileUrl={fileUrl} - isCaptureActive={isCaptureActive} + isCaptureActive={captureActive} itemId={item.id} - onCaptureModeExit={() => setIsCaptureActive(false)} - onCaptureModeToggle={() => setIsCaptureActive((current) => !current)} + onCaptureModeExit={exitCapture} + onCaptureModeToggle={toggleCapture} + enableFileCapture={enableFileCapture} workspaceId={workspaceId} /> ) : ( @@ -145,7 +157,7 @@ export default function WorkspacePdfViewer({ } )} - + {enableFileCapture ? : null} ); } @@ -153,6 +165,7 @@ export default function WorkspacePdfViewer({ function WorkspacePdfDocumentLoader({ activeDocumentId, documentId, + enableFileCapture, fileName, fileUrl, isCaptureActive, @@ -163,6 +176,7 @@ function WorkspacePdfDocumentLoader({ }: { activeDocumentId: string | null; documentId: string; + enableFileCapture: boolean; fileName: string; fileUrl: string; isCaptureActive: boolean; @@ -245,6 +259,7 @@ function WorkspacePdfDocumentLoader({ itemId={itemId} onCaptureModeExit={onCaptureModeExit} onCaptureModeToggle={onCaptureModeToggle} + enableFileCapture={enableFileCapture} workspaceId={workspaceId} {...props} /> @@ -256,6 +271,7 @@ function WorkspacePdfDocumentLoader({ function WorkspacePdfDocumentContent({ documentId, documentState, + enableFileCapture, fileName, fileUrl, isCaptureActive, @@ -269,6 +285,7 @@ function WorkspacePdfDocumentContent({ }: { documentId: string; documentState: DocumentState; + enableFileCapture: boolean; fileName: string; fileUrl: string; isCaptureActive: boolean; @@ -318,12 +335,16 @@ function WorkspacePdfDocumentContent({ workspaceId={workspaceId} /> - - + {enableFileCapture ? ( + <> + + + + ) : null} )} @@ -358,6 +380,7 @@ function WorkspacePdfDocumentContent({ function WorkspacePdfPage({ documentId, documentState, + enableFileCapture, isCaptureActive, itemId, onCapture, @@ -368,6 +391,7 @@ function WorkspacePdfPage({ }: { documentId: string; documentState: DocumentState; + enableFileCapture: boolean; isCaptureActive: boolean; itemId: string; onCapture: (capture: WorkspacePdfCaptureResult) => void; @@ -416,7 +440,7 @@ function WorkspacePdfPage({ documentId={documentId} pageIndex={pageLayout.pageIndex} /> - {page ? ( + {enableFileCapture && page ? ( void }) { return (
-
+ -
+
); } @@ -107,7 +112,7 @@ function WorkspaceRootDropEmptyState() { Drop your files here - Or click New to get started + Click anywhere here to upload files ); diff --git a/src/features/workspaces/components/WorkspaceUploadClickTarget.tsx b/src/features/workspaces/components/WorkspaceUploadClickTarget.tsx new file mode 100644 index 00000000..a1143bbd --- /dev/null +++ b/src/features/workspaces/components/WorkspaceUploadClickTarget.tsx @@ -0,0 +1,42 @@ +import type { KeyboardEvent, ReactNode } from "react"; + +import { cn } from "#/lib/utils"; + +interface WorkspaceUploadClickTargetProps { + "aria-label": string; + children: ReactNode; + className?: string; + onUploadFiles: () => void; +} + +export function WorkspaceUploadClickTarget({ + "aria-label": ariaLabel, + children, + className, + onUploadFiles, +}: WorkspaceUploadClickTargetProps) { + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key !== "Enter" && event.key !== " ") { + return; + } + + event.preventDefault(); + onUploadFiles(); + }; + + return ( +
+ {children} +
+ ); +} diff --git a/src/features/workspaces/components/ai-chat/AiChatPanelToolbar.tsx b/src/features/workspaces/components/ai-chat/AiChatPanelToolbar.tsx index 97a4b81b..3bc22f92 100644 --- a/src/features/workspaces/components/ai-chat/AiChatPanelToolbar.tsx +++ b/src/features/workspaces/components/ai-chat/AiChatPanelToolbar.tsx @@ -142,6 +142,7 @@ export default function AiChatPanelToolbar({ {isMaximized ? : } diff --git a/src/features/workspaces/components/workspace-view-policy.tsx b/src/features/workspaces/components/workspace-view-policy.tsx new file mode 100644 index 00000000..54f77030 --- /dev/null +++ b/src/features/workspaces/components/workspace-view-policy.tsx @@ -0,0 +1,74 @@ +import { createContext, type ReactNode, use, useSyncExternalStore } from "react"; + +const WORKSPACE_DESKTOP_MEDIA_QUERY = "(min-width: 640px)"; + +export type WorkspaceViewportMode = "desktop" | "mobile"; + +export interface WorkspaceViewCapabilities { + contextMenus: boolean; + fileCapture: boolean; +} + +const desktopWorkspaceViewCapabilities: WorkspaceViewCapabilities = { + contextMenus: true, + fileCapture: true, +}; + +const mobileWorkspaceViewCapabilities: WorkspaceViewCapabilities = { + contextMenus: false, + fileCapture: false, +}; + +const WorkspaceViewCapabilitiesContext = createContext( + desktopWorkspaceViewCapabilities, +); + +function subscribeToWorkspaceViewportChange(onChange: () => void) { + const media = window.matchMedia(WORKSPACE_DESKTOP_MEDIA_QUERY); + + media.addEventListener("change", onChange); + + return () => media.removeEventListener("change", onChange); +} + +function getWorkspaceViewportSnapshot(): WorkspaceViewportMode { + return window.matchMedia(WORKSPACE_DESKTOP_MEDIA_QUERY).matches ? "desktop" : "mobile"; +} + +function getWorkspaceViewportServerSnapshot(): WorkspaceViewportMode { + return "desktop"; +} + +export function useWorkspaceViewPolicy() { + const viewportMode = useSyncExternalStore( + subscribeToWorkspaceViewportChange, + getWorkspaceViewportSnapshot, + getWorkspaceViewportServerSnapshot, + ); + + return { + capabilities: + viewportMode === "desktop" + ? desktopWorkspaceViewCapabilities + : mobileWorkspaceViewCapabilities, + viewportMode, + }; +} + +export function WorkspaceViewCapabilitiesProvider({ + capabilities, + children, +}: { + capabilities: WorkspaceViewCapabilities; + children: ReactNode; +}) { + return ( + + {children} + + ); +} + +export function useWorkspaceViewCapabilities() { + return use(WorkspaceViewCapabilitiesContext); +} From 67088ea060648c730d2f185b8bc2310300fa4853 Mon Sep 17 00:00:00 2001 From: Urjit Chakraborty <135136842+urjitc@users.noreply.github.com> Date: Tue, 30 Jun 2026 19:00:01 -0400 Subject: [PATCH 3/4] fix(workspaces): improve mobile item rows --- .../components/WorkspaceItemCard.tsx | 74 +++++++++++++------ .../WorkspaceItemPreviewSurface.tsx | 42 ++++++++--- .../components/workspace-item-card-chrome.ts | 18 +++-- .../components/workspace-item-card-footer.tsx | 4 +- .../workspace-item-card-preview-controls.tsx | 4 +- .../workspace-item-card-preview-stage.tsx | 30 +------- 6 files changed, 99 insertions(+), 73 deletions(-) diff --git a/src/features/workspaces/components/WorkspaceItemCard.tsx b/src/features/workspaces/components/WorkspaceItemCard.tsx index c8f1d16a..9f393f8e 100644 --- a/src/features/workspaces/components/WorkspaceItemCard.tsx +++ b/src/features/workspaces/components/WorkspaceItemCard.tsx @@ -12,11 +12,14 @@ import { workspaceItemCardHoverClass, workspaceItemCardSelectedClass, workspaceItemCardUnselectedHoverClass, + workspaceItemPreviewControlsLayerClass, } from "#/features/workspaces/components/workspace-item-card-chrome"; import { WorkspaceItemCardFooter } from "#/features/workspaces/components/workspace-item-card-footer"; +import { WorkspaceItemCardPreviewControls } from "#/features/workspaces/components/workspace-item-card-preview-controls"; import { WorkspaceItemCardPreviewStage } from "#/features/workspaces/components/workspace-item-card-preview-stage"; import { useWorkspaceMutationAccess } from "#/features/workspaces/components/workspace-mutation-access"; import { workspaceItemSortablePlugins } from "#/features/workspaces/components/workspace-sortable-plugins"; +import { useWorkspaceViewCapabilities } from "#/features/workspaces/components/workspace-view-policy"; import { createWorkspaceItemDragData, getWorkspaceDragSource, @@ -58,6 +61,7 @@ export default function WorkspaceItemCard({ onElementChange, }: WorkspaceItemCardProps) { const { capabilities, itemSortableDisabled } = useWorkspaceMutationAccess(); + const viewCapabilities = useWorkspaceViewCapabilities(); const { canMutateContent } = capabilities; const isFolder = item.type === "folder"; const row = isFolder ? "folder" : "item"; @@ -206,14 +210,17 @@ export default function WorkspaceItemCard({ aria-label={`Open ${item.name}`} onClick={handleOpen} /> - + +
+ +
{showFolderDropAffordance ? (
) : null} - + - {canMutateContent ? ( - - ) : ( - {item.name} - )} + {isFolder ? ( meta ? ( @@ -251,6 +251,10 @@ export default function WorkspaceItemCard({ ); + if (!viewCapabilities.contextMenus) { + return card; + } + return ( @@ -263,3 +267,31 @@ export default function WorkspaceItemCard({ ); } + +function WorkspaceItemCardTitle({ + canRename, + itemName, + onRenameClick, +}: { + canRename: boolean; + itemName: string; + onRenameClick: (event: MouseEvent) => void; +}) { + if (!canRename) { + return {itemName}; + } + + return ( + <> + {itemName} + + + ); +} diff --git a/src/features/workspaces/components/WorkspaceItemPreviewSurface.tsx b/src/features/workspaces/components/WorkspaceItemPreviewSurface.tsx index 0486bc65..c71c12db 100644 --- a/src/features/workspaces/components/WorkspaceItemPreviewSurface.tsx +++ b/src/features/workspaces/components/WorkspaceItemPreviewSurface.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { type ReactNode, useState } from "react"; import { workspaceItemDocumentPreviewPanelClass, @@ -32,17 +32,18 @@ export default function WorkspaceItemPreviewSurface({ item }: WorkspaceItemPrevi function WorkspaceItemDocumentPreview({ item }: { item: WorkspaceItem }) { const previewText = getWorkspaceDocumentPreviewText(item); + const desktopPreview = previewText ? ( +
+

{previewText}

+
+ ) : ( + + ); return ( -
- {previewText ? ( -
-

{previewText}

-
- ) : ( - - )} -
+ + {desktopPreview} + ); } @@ -65,7 +66,7 @@ function WorkspaceItemFilePreview({ item }: { item: WorkspaceItem }) { if (showImage) { return ( -
+ setFailedPreviewUrl(previewUrl)} /> -
+ ); } return ; } +function WorkspaceItemMobileIconDesktopPreview({ + children, + item, +}: { + children: ReactNode; + item: WorkspaceItem; +}) { + return ( + <> +
+ +
+
{children}
+ + ); +} + /** Icon-only preview for folders and types without a custom thumbnail yet. */ function WorkspaceItemIconPreview({ item }: { item: WorkspaceItem }) { const { Icon, iconClassName } = getWorkspaceItemDisplay(item); diff --git a/src/features/workspaces/components/workspace-item-card-chrome.ts b/src/features/workspaces/components/workspace-item-card-chrome.ts index de04f11b..da9288ad 100644 --- a/src/features/workspaces/components/workspace-item-card-chrome.ts +++ b/src/features/workspaces/components/workspace-item-card-chrome.ts @@ -1,19 +1,19 @@ /** Shared layout + appearance tokens for workspace item cards. */ export const workspaceItemPreviewControlClass = - "relative z-20 rounded-[4px] border border-border/80 bg-card/95 text-muted-foreground shadow-none backdrop-blur-md transition-[background-color,border-color,color,opacity] hover:border-foreground/30 hover:bg-secondary hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/50 dark:border-white/15 dark:bg-card/90 dark:text-muted-foreground dark:hover:border-white/35 dark:hover:bg-secondary dark:hover:text-foreground/95 data-popup-open:border-foreground/30 data-popup-open:bg-secondary data-popup-open:text-foreground dark:data-popup-open:border-white/35 dark:data-popup-open:bg-secondary dark:data-popup-open:text-foreground/95"; + "relative z-20 size-9 rounded-[6px] border border-border/80 bg-card/95 text-muted-foreground shadow-none backdrop-blur-md transition-[background-color,border-color,color,opacity] hover:border-foreground/30 hover:bg-secondary hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/50 dark:border-white/15 dark:bg-card/90 dark:text-muted-foreground dark:hover:border-white/35 dark:hover:bg-secondary dark:hover:text-foreground/95 data-popup-open:border-foreground/30 data-popup-open:bg-secondary data-popup-open:text-foreground dark:data-popup-open:border-white/35 dark:data-popup-open:bg-secondary dark:data-popup-open:text-foreground/95 sm:size-6 sm:rounded-[4px]"; export const workspaceItemPreviewControlOverlayClass = - "pointer-events-none opacity-0 transition-opacity group-hover/item:pointer-events-auto group-hover/item:opacity-100 data-popup-open:pointer-events-auto data-popup-open:opacity-100"; + "pointer-events-auto opacity-100 transition-opacity sm:pointer-events-none sm:opacity-0 sm:group-hover/item:pointer-events-auto sm:group-hover/item:opacity-100 sm:data-popup-open:pointer-events-auto sm:data-popup-open:opacity-100"; export const workspaceItemPreviewControlSelectedClass = "pointer-events-auto border-info bg-info text-white opacity-100 dark:border-info dark:bg-info dark:text-white"; export const workspaceItemPreviewControlRowClass = - "relative z-10 flex h-10 items-center justify-between px-2"; + "relative z-10 flex items-center justify-end gap-2 sm:h-10 sm:justify-between sm:gap-1 sm:px-2"; export const workspaceItemCardBaseClass = - "workspace-item-card group/item relative flex h-full min-h-44 cursor-pointer flex-col gap-0 overflow-hidden py-0 transition-[background-color,box-shadow] active:cursor-grabbing"; + "workspace-item-card group/item relative flex h-full min-h-20 cursor-pointer flex-row gap-0 overflow-hidden py-0 transition-[background-color,box-shadow] active:cursor-grabbing sm:min-h-44 sm:flex-col"; export const workspaceItemCardHoverClass = "hover:bg-secondary dark:hover:bg-accent/75"; @@ -23,18 +23,20 @@ export const workspaceItemCardUnselectedHoverClass = export const workspaceItemCardSelectedClass = "data-[selected=true]:ring-2 data-[selected=true]:ring-info"; -export const workspaceItemGridClass = "grid grid-cols-[repeat(auto-fill,minmax(13rem,1fr))] gap-5"; +export const workspaceItemGridClass = + "grid grid-cols-1 gap-3 sm:grid-cols-[repeat(auto-fill,minmax(13rem,1fr))] sm:gap-5"; export const workspaceItemPreviewStageClass = - "pointer-events-none relative z-10 min-h-20 flex-1 overflow-hidden bg-muted"; + "pointer-events-none relative z-10 w-14 shrink-0 overflow-hidden bg-muted sm:min-h-20 sm:w-auto sm:flex-1"; export const workspaceItemPreviewContentLayerClass = "absolute inset-0"; -export const workspaceItemPreviewControlsLayerClass = "absolute inset-x-0 top-0 z-20"; +export const workspaceItemPreviewControlsLayerClass = + "pointer-events-none absolute top-1/2 right-2 z-20 -translate-y-1/2 sm:inset-x-0 sm:top-0 sm:translate-y-0"; export const workspaceItemDocumentPreviewPanelClass = "size-full overflow-hidden p-3"; export const workspaceItemDocumentPreviewTextClass = "size-full overflow-hidden break-words whitespace-pre-line text-[11px] leading-[1.45] text-muted-foreground/70 line-clamp-[11]"; -export const workspaceItemPreviewIconClass = "size-10"; +export const workspaceItemPreviewIconClass = "size-8 sm:size-10"; diff --git a/src/features/workspaces/components/workspace-item-card-footer.tsx b/src/features/workspaces/components/workspace-item-card-footer.tsx index 25a6aa0a..df8ae5cf 100644 --- a/src/features/workspaces/components/workspace-item-card-footer.tsx +++ b/src/features/workspaces/components/workspace-item-card-footer.tsx @@ -14,9 +14,9 @@ export function WorkspaceItemCardFooter({ item }: WorkspaceItemCardFooterProps) return ( +
} content={content} /> + {chatPanel && isChatOpen ? (
{chatPanel}
diff --git a/src/features/workspaces/components/WorkspacePdfViewer.tsx b/src/features/workspaces/components/WorkspacePdfViewer.tsx index 1cdff671..5540bd5f 100644 --- a/src/features/workspaces/components/WorkspacePdfViewer.tsx +++ b/src/features/workspaces/components/WorkspacePdfViewer.tsx @@ -106,7 +106,9 @@ export default function WorkspacePdfViewer({ const fileUrl = getWorkspaceFileContentUrl(workspaceId, item.id); const { engine, error, isLoading } = useEngineContext(); const [isCaptureActive, setIsCaptureActive] = useState(false); - const enableFileCapture = useWorkspaceViewCapabilities().fileCapture; + const viewCapabilities = useWorkspaceViewCapabilities(); + const enableFileCapture = viewCapabilities.fileCapture; + const enableSelectionMenu = viewCapabilities.contextMenus; const captureActive = enableFileCapture && isCaptureActive; const exitCapture = useCallback(() => { setIsCaptureActive(false); @@ -149,6 +151,7 @@ export default function WorkspacePdfViewer({ onCaptureModeExit={exitCapture} onCaptureModeToggle={toggleCapture} enableFileCapture={enableFileCapture} + enableSelectionMenu={enableSelectionMenu} workspaceId={workspaceId} /> ) : ( @@ -166,6 +169,7 @@ function WorkspacePdfDocumentLoader({ activeDocumentId, documentId, enableFileCapture, + enableSelectionMenu, fileName, fileUrl, isCaptureActive, @@ -177,6 +181,7 @@ function WorkspacePdfDocumentLoader({ activeDocumentId: string | null; documentId: string; enableFileCapture: boolean; + enableSelectionMenu: boolean; fileName: string; fileUrl: string; isCaptureActive: boolean; @@ -260,6 +265,7 @@ function WorkspacePdfDocumentLoader({ onCaptureModeExit={onCaptureModeExit} onCaptureModeToggle={onCaptureModeToggle} enableFileCapture={enableFileCapture} + enableSelectionMenu={enableSelectionMenu} workspaceId={workspaceId} {...props} /> @@ -272,6 +278,7 @@ function WorkspacePdfDocumentContent({ documentId, documentState, enableFileCapture, + enableSelectionMenu, fileName, fileUrl, isCaptureActive, @@ -286,6 +293,7 @@ function WorkspacePdfDocumentContent({ documentId: string; documentState: DocumentState; enableFileCapture: boolean; + enableSelectionMenu: boolean; fileName: string; fileUrl: string; isCaptureActive: boolean; @@ -367,6 +375,7 @@ function WorkspacePdfDocumentContent({ renderCapability={renderCapability} selectionPoint={selectionPoint} enableFileCapture={enableFileCapture} + enableSelectionMenu={enableSelectionMenu} workspaceId={workspaceId} /> )} @@ -381,6 +390,7 @@ function WorkspacePdfPage({ documentId, documentState, enableFileCapture, + enableSelectionMenu, isCaptureActive, itemId, onCapture, @@ -392,6 +402,7 @@ function WorkspacePdfPage({ documentId: string; documentState: DocumentState; enableFileCapture: boolean; + enableSelectionMenu: boolean; isCaptureActive: boolean; itemId: string; onCapture: (capture: WorkspacePdfCaptureResult) => void; @@ -422,15 +433,19 @@ function WorkspacePdfPage({ ( - - )} + selectionMenu={ + enableSelectionMenu + ? (props) => ( + + ) + : undefined + } textStyle={{ background: "var(--selection)", }} diff --git a/src/features/workspaces/components/WorkspaceUploadClickTarget.tsx b/src/features/workspaces/components/WorkspaceUploadClickTarget.tsx index a1143bbd..9c561fe2 100644 --- a/src/features/workspaces/components/WorkspaceUploadClickTarget.tsx +++ b/src/features/workspaces/components/WorkspaceUploadClickTarget.tsx @@ -1,4 +1,4 @@ -import type { KeyboardEvent, ReactNode } from "react"; +import type { ReactNode } from "react"; import { cn } from "#/lib/utils"; @@ -15,28 +15,15 @@ export function WorkspaceUploadClickTarget({ className, onUploadFiles, }: WorkspaceUploadClickTargetProps) { - const handleKeyDown = (event: KeyboardEvent) => { - if (event.key !== "Enter" && event.key !== " ") { - return; - } - - event.preventDefault(); - onUploadFiles(); - }; - return ( -
- {children} +
+
); }