feat(components): add reusable full-screen panel components

Add new full-screen panel components to support the UI refactoring:

- FullScreenPanel: Reusable full-screen layout component with header,
  content area, and optional footer. Provides consistent layout for
  settings, prompts, and other full-screen views.

- PromptFormPanel: Dedicated panel for creating and editing prompts
  with markdown preview support. Features real-time validation and
  integrated save/cancel actions.

- AgentsPanel: Panel component for managing agent configurations.
  Provides a consistent interface for agent CRUD operations.

- RepoManagerPanel: Full-featured repository manager panel for Skills.
  Supports repository listing, addition, deletion, and configuration
  management with integrated validation.

These components establish the foundation for the upcoming settings
page migration from dialog-based to full-screen layout.
This commit is contained in:
YoVinchen
2025-11-21 09:27:20 +08:00
parent 74969ae968
commit d802b7bf61
4 changed files with 440 additions and 0 deletions
+60
View File
@@ -0,0 +1,60 @@
import React from "react";
import { createPortal } from "react-dom";
import { ArrowLeft } from "lucide-react";
import { Button } from "@/components/ui/button";
interface FullScreenPanelProps {
isOpen: boolean;
title: string;
onClose: () => void;
children: React.ReactNode;
footer?: React.ReactNode;
}
/**
* Reusable full-screen panel component
* Handles portal rendering, header with back button, and footer
* Uses solid theme colors without transparency
*/
export const FullScreenPanel: React.FC<FullScreenPanelProps> = ({
isOpen,
title,
onClose,
children,
footer,
}) => {
if (!isOpen) return null;
return createPortal(
<div className="fixed inset-0 z-[60] flex flex-col" style={{ backgroundColor: 'hsl(var(--background))' }}>
{/* Header */}
<div className="flex-shrink-0 px-6 py-4 flex items-center gap-4" style={{ backgroundColor: 'hsl(var(--background))' }}>
<Button
type="button"
variant="ghost"
size="icon"
onClick={onClose}
className="hover:bg-black/5 dark:hover:bg-white/5"
>
<ArrowLeft className="h-5 w-5" />
</Button>
<h2 className="text-lg font-semibold text-foreground">
{title}
</h2>
</div>
{/* Content */}
<div className="flex-1 overflow-y-auto px-6 py-6 space-y-6 max-w-5xl mx-auto w-full">
{children}
</div>
{/* Footer */}
{footer && (
<div className="flex-shrink-0 px-6 py-4 flex items-center justify-end gap-3" style={{ backgroundColor: 'hsl(var(--background))' }}>
{footer}
</div>
)}
</div>,
document.body
);
};