From 09c3dce0836d3b8b39767d851e9778a21d9e0cf9 Mon Sep 17 00:00:00 2001 From: MT-Fire <798521692@qq.com> Date: Sat, 28 Mar 2026 23:19:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20=E5=90=8C=E6=AD=A5=20ai-eleme?= =?UTF-8?q?nts=20=E4=B8=8E=20ui=20=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/ai-elements/artifact.tsx | 19 +- .../ai-elements/chain-of-thought.tsx | 8 +- .../src/components/ai-elements/checkpoint.tsx | 5 +- .../src/components/ai-elements/code-block.tsx | 13 +- .../src/components/ai-elements/context.tsx | 10 +- .../src/components/ai-elements/controls.tsx | 6 +- .../components/ai-elements/conversation.tsx | 4 +- frontend/src/components/ai-elements/edge.tsx | 10 +- frontend/src/components/ai-elements/image.tsx | 2 +- .../src/components/ai-elements/loader.tsx | 2 +- .../src/components/ai-elements/message.tsx | 15 +- frontend/src/components/ai-elements/node.tsx | 6 +- frontend/src/components/ai-elements/panel.tsx | 4 +- .../components/ai-elements/prompt-input.tsx | 231 ++++++------------ frontend/src/components/ai-elements/queue.tsx | 32 +-- .../src/components/ai-elements/reasoning.tsx | 27 +- .../src/components/ai-elements/shimmer.tsx | 8 +- .../src/components/ai-elements/sources.tsx | 6 +- .../src/components/ai-elements/suggestion.tsx | 7 +- frontend/src/components/ai-elements/task.tsx | 12 +- .../src/components/ai-elements/toolbar.tsx | 4 +- .../components/ai-elements/web-preview.tsx | 16 +- frontend/src/components/ui/alert.tsx | 22 +- frontend/src/components/ui/aurora-text.tsx | 26 +- frontend/src/components/ui/avatar.tsx | 20 +- frontend/src/components/ui/badge.tsx | 18 +- frontend/src/components/ui/breadcrumb.tsx | 30 +-- frontend/src/components/ui/button-group.tsx | 28 +-- frontend/src/components/ui/button.tsx | 2 +- frontend/src/components/ui/card.tsx | 30 +-- frontend/src/components/ui/carousel.tsx | 136 +++++------ frontend/src/components/ui/command.tsx | 52 ++-- frontend/src/components/ui/dialog.tsx | 40 +-- frontend/src/components/ui/dropdown-menu.tsx | 74 +++--- frontend/src/components/ui/empty.tsx | 30 +-- frontend/src/components/ui/hover-card.tsx | 18 +- frontend/src/components/ui/input-group.tsx | 10 +- frontend/src/components/ui/item.tsx | 52 ++-- frontend/src/components/ui/magic-bento.css | 4 +- frontend/src/components/ui/progress.tsx | 14 +- frontend/src/components/ui/resizable.tsx | 2 +- frontend/src/components/ui/scroll-area.tsx | 16 +- frontend/src/components/ui/separator.tsx | 14 +- frontend/src/components/ui/sheet.tsx | 38 +-- frontend/src/components/ui/shine-border.tsx | 16 +- frontend/src/components/ui/sidebar.tsx | 5 +- frontend/src/components/ui/skeleton.tsx | 6 +- frontend/src/components/ui/sonner.tsx | 26 +- frontend/src/components/ui/spotlight-card.css | 8 +- frontend/src/components/ui/switch.tsx | 16 +- frontend/src/components/ui/tabs.tsx | 28 +-- frontend/src/components/ui/toggle-group.tsx | 4 +- frontend/src/components/ui/toggle.tsx | 18 +- frontend/src/components/ui/tooltip.tsx | 2 +- .../src/components/workspace/input-box.tsx | 18 +- frontend/src/components/workspace/welcome.tsx | 6 +- 56 files changed, 591 insertions(+), 685 deletions(-) diff --git a/frontend/src/components/ai-elements/artifact.tsx b/frontend/src/components/ai-elements/artifact.tsx index 96db33d8..550dfa11 100644 --- a/frontend/src/components/ai-elements/artifact.tsx +++ b/frontend/src/components/ai-elements/artifact.tsx @@ -16,7 +16,7 @@ export type ArtifactProps = HTMLAttributes; export const Artifact = ({ className, ...props }: ArtifactProps) => (
(
); @@ -63,7 +66,7 @@ export type ArtifactTitleProps = HTMLAttributes; export const ArtifactTitle = ({ className, ...props }: ArtifactTitleProps) => (
); @@ -90,7 +93,6 @@ export type ArtifactActionProps = ComponentProps & { tooltip?: string; label?: string; icon?: LucideIcon; - asChild?: boolean; }; export const ArtifactAction = ({ @@ -101,7 +103,6 @@ export const ArtifactAction = ({ className, size = "sm", variant = "ghost", - asChild = false, ...props }: ArtifactActionProps) => { const button = ( @@ -113,7 +114,6 @@ export const ArtifactAction = ({ size={size} type="button" variant={variant} - asChild={asChild} {...props} > {Icon ? : children} @@ -143,7 +143,8 @@ export const ArtifactContent = ({ className, ...props }: ArtifactContentProps) => ( -
-
-
+
); diff --git a/frontend/src/components/ai-elements/chain-of-thought.tsx b/frontend/src/components/ai-elements/chain-of-thought.tsx index a8891821..cd3a6b7a 100644 --- a/frontend/src/components/ai-elements/chain-of-thought.tsx +++ b/frontend/src/components/ai-elements/chain-of-thought.tsx @@ -147,11 +147,7 @@ export const ChainOfThoughtStep = memo( {...props} >
- {isValidElement(Icon) ? ( - Icon - ) : ( - - )} + {isValidElement(Icon) ? Icon : }
@@ -206,7 +202,7 @@ export const ChainOfThoughtContent = memo( (
{children} diff --git a/frontend/src/components/ai-elements/code-block.tsx b/frontend/src/components/ai-elements/code-block.tsx index 0f227cc2..c0460238 100644 --- a/frontend/src/components/ai-elements/code-block.tsx +++ b/frontend/src/components/ai-elements/code-block.tsx @@ -1,7 +1,7 @@ "use client"; import { Button } from "@/components/ui/button"; -import { cn, copyToClipboard } from "@/lib/utils"; +import { cn } from "@/lib/utils"; import { CheckIcon, CopyIcon } from "lucide-react"; import { type ComponentProps, @@ -146,9 +146,14 @@ export const CodeBlockCopyButton = ({ const [isCopied, setIsCopied] = useState(false); const { code } = useContext(CodeBlockContext); - const handleCopy = async () => { + const copyToClipboard = async () => { + if (typeof window === "undefined" || !navigator?.clipboard?.writeText) { + onError?.(new Error("Clipboard API not available")); + return; + } + try { - await copyToClipboard(code); + await navigator.clipboard.writeText(code); setIsCopied(true); onCopy?.(); setTimeout(() => setIsCopied(false), timeout); @@ -162,7 +167,7 @@ export const CodeBlockCopyButton = ({ return ( )} @@ -388,7 +384,7 @@ export function MessageAttachment({ {onRemove && ( )} diff --git a/frontend/src/components/ai-elements/node.tsx b/frontend/src/components/ai-elements/node.tsx index f329a8b3..75ac59a1 100644 --- a/frontend/src/components/ai-elements/node.tsx +++ b/frontend/src/components/ai-elements/node.tsx @@ -22,7 +22,7 @@ export const Node = ({ handles, className, ...props }: NodeProps) => ( @@ -36,7 +36,7 @@ export type NodeHeaderProps = ComponentProps; export const NodeHeader = ({ className, ...props }: NodeHeaderProps) => ( ); @@ -65,7 +65,7 @@ export type NodeFooterProps = ComponentProps; export const NodeFooter = ({ className, ...props }: NodeFooterProps) => ( ); diff --git a/frontend/src/components/ai-elements/panel.tsx b/frontend/src/components/ai-elements/panel.tsx index a0b8c1d7..059cb7ac 100644 --- a/frontend/src/components/ai-elements/panel.tsx +++ b/frontend/src/components/ai-elements/panel.tsx @@ -7,8 +7,8 @@ type PanelProps = ComponentProps; export const Panel = ({ className, ...props }: PanelProps) => ( diff --git a/frontend/src/components/ai-elements/prompt-input.tsx b/frontend/src/components/ai-elements/prompt-input.tsx index c3b5f30a..a094def4 100644 --- a/frontend/src/components/ai-elements/prompt-input.tsx +++ b/frontend/src/components/ai-elements/prompt-input.tsx @@ -35,7 +35,6 @@ import { SelectValue, } from "@/components/ui/select"; import { cn } from "@/lib/utils"; -import { Tooltip } from "../workspace/tooltip"; import type { ChatStatus, FileUIPart } from "ai"; import { ArrowUpIcon, @@ -71,7 +70,6 @@ import { useRef, useState, } from "react"; -import { useI18n } from "@/core/i18n/hooks"; // ============================================================================ // Provider Context & Types @@ -290,7 +288,6 @@ export function PromptInputAttachment({ ...props }: PromptInputAttachmentProps) { const attachments = usePromptInputAttachments(); - const { t } = useI18n(); const filename = data.filename || ""; @@ -298,112 +295,81 @@ export function PromptInputAttachment({ data.mediaType?.startsWith("image/") && data.url ? "image" : "file"; const isImage = mediaType === "image"; - const truncateFilename = (name: string, maxLen: number = 10) => { - if (name.length <= maxLen) return name; - const ext = name.slice(name.lastIndexOf(".")); - const baseName = name.slice(0, name.lastIndexOf(".")); - const truncated = baseName.slice(0, maxLen - ext.length - 3); - return truncated + "..." + ext; - }; + const attachmentLabel = filename || (isImage ? "Image" : "Attachment"); return ( -
- {isImage ? ( - <> - {filename - {/* 悬浮遮罩层 */} -
- {/* 眼睛图标 - 居中 */} - - - - - {/* 删除按钮 - 右上角 */} - + + Remove +
- - ) : ( - <> -
- - - {truncateFilename(filename)} - + + {attachmentLabel} +
+ + +
+ {isImage && ( +
+ {filename +
+ )} +
+
+

+ {filename || (isImage ? "Image" : "Attachment")} +

+ {data.mediaType && ( +

+ {data.mediaType} +

+ )} +
- {/* 关闭按钮 - 右上角 */} - - - )} -
+
+ + ); } @@ -427,14 +393,13 @@ export function PromptInputAttachments({ return (
{attachments.files.map((file) => ( - {children(file)} + +
{children(file)}
+
))}
); @@ -492,13 +457,10 @@ export type PromptInputProps = Omit< message: PromptInputMessage, event: FormEvent, ) => void | Promise; - // className for InputGroup (passes through to inner InputGroup component) - inputGroupClassName?: string; }; export const PromptInput = ({ className, - inputGroupClassName, accept, disabled, multiple, @@ -832,7 +794,7 @@ export const PromptInput = ({ ref={formRef} {...props} > - {children} + {children} ); @@ -1065,63 +1027,32 @@ export type PromptInputSubmitProps = ComponentProps & { export const PromptInputSubmit = ({ className, variant = "default", - size = "sm", + size = "icon-sm", status, - disabled, children, ...props }: PromptInputSubmitProps) => { - const controller = useOptionalPromptInputController(); - const { t } = useI18n(); - - // 判断是否有内容可发送 - const hasContent = controller - ? controller.textInput.value.trim().length > 0 || - controller.attachments.files.length > 0 - : false; - - // 正在 streaming 时不允许发送 - // const isStreaming = status === "streaming" || status === "submitted"; - - // const isDisabled = disabled || !hasContent || isStreaming; - let Icon = ; - let text: string = "发送"; - if (status === "submitted") { Icon = ; - text = "生成中..."; } else if (status === "streaming") { Icon = ; - text = "停止"; } else if (status === "error") { Icon = ; - text = "错误"; } return ( - - - {/* {children ?? Icon} */} - {text} - - + + {children ?? Icon} + ); }; diff --git a/frontend/src/components/ai-elements/queue.tsx b/frontend/src/components/ai-elements/queue.tsx index a9c5a74e..0c91d130 100644 --- a/frontend/src/components/ai-elements/queue.tsx +++ b/frontend/src/components/ai-elements/queue.tsx @@ -36,8 +36,8 @@ export type QueueItemProps = ComponentProps<"li">; export const QueueItem = ({ className, ...props }: QueueItemProps) => (
  • @@ -58,7 +58,7 @@ export const QueueItemIndicator = ({ completed ? "border-muted-foreground/20 bg-muted-foreground/10" : "border-muted-foreground/50", - className, + className )} {...props} /> @@ -79,7 +79,7 @@ export const QueueItemContent = ({ completed ? "text-muted-foreground/50 line-through" : "text-muted-foreground", - className, + className )} {...props} /> @@ -100,7 +100,7 @@ export const QueueItemDescription = ({ completed ? "text-muted-foreground/40 line-through" : "text-muted-foreground", - className, + className )} {...props} /> @@ -126,8 +126,8 @@ export const QueueItemAction = ({ }: QueueItemActionProps) => ( ); diff --git a/frontend/src/components/ai-elements/task.tsx b/frontend/src/components/ai-elements/task.tsx index 6f635914..eeb802c6 100644 --- a/frontend/src/components/ai-elements/task.tsx +++ b/frontend/src/components/ai-elements/task.tsx @@ -18,8 +18,8 @@ export const TaskItemFile = ({ }: TaskItemFileProps) => (
    @@ -57,7 +57,7 @@ export const TaskTrigger = ({ }: TaskTriggerProps) => ( {children ?? ( -
    +

    {title}

    @@ -75,12 +75,12 @@ export const TaskContent = ({ }: TaskContentProps) => ( -
    +
    {children}
    diff --git a/frontend/src/components/ai-elements/toolbar.tsx b/frontend/src/components/ai-elements/toolbar.tsx index 1152a59d..b55aa889 100644 --- a/frontend/src/components/ai-elements/toolbar.tsx +++ b/frontend/src/components/ai-elements/toolbar.tsx @@ -7,8 +7,8 @@ type ToolbarProps = ComponentProps; export const Toolbar = ({ className, ...props }: ToolbarProps) => (
    @@ -107,7 +107,7 @@ export const WebPreviewNavigationButton = ({ @@ -231,7 +231,7 @@ export const WebPreviewConsole = ({
    @@ -244,7 +244,7 @@ export const WebPreviewConsole = ({ "text-xs", log.level === "error" && "text-destructive", log.level === "warn" && "text-yellow-600", - log.level === "log" && "text-foreground", + log.level === "log" && "text-foreground" )} key={`${log.timestamp.getTime()}-${index}`} > diff --git a/frontend/src/components/ui/alert.tsx b/frontend/src/components/ui/alert.tsx index aa7de24d..14213546 100644 --- a/frontend/src/components/ui/alert.tsx +++ b/frontend/src/components/ui/alert.tsx @@ -1,7 +1,7 @@ -import * as React from "react"; -import { cva, type VariantProps } from "class-variance-authority"; +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" const alertVariants = cva( "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", @@ -16,8 +16,8 @@ const alertVariants = cva( defaultVariants: { variant: "default", }, - }, -); + } +) function Alert({ className, @@ -31,7 +31,7 @@ function Alert({ className={cn(alertVariants({ variant }), className)} {...props} /> - ); + ) } function AlertTitle({ className, ...props }: React.ComponentProps<"div">) { @@ -40,11 +40,11 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) { data-slot="alert-title" className={cn( "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight", - className, + className )} {...props} /> - ); + ) } function AlertDescription({ @@ -56,11 +56,11 @@ function AlertDescription({ data-slot="alert-description" className={cn( "text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed", - className, + className )} {...props} /> - ); + ) } -export { Alert, AlertTitle, AlertDescription }; +export { Alert, AlertTitle, AlertDescription } diff --git a/frontend/src/components/ui/aurora-text.tsx b/frontend/src/components/ui/aurora-text.tsx index eb32cce2..85857c1a 100644 --- a/frontend/src/components/ui/aurora-text.tsx +++ b/frontend/src/components/ui/aurora-text.tsx @@ -1,13 +1,12 @@ -"use client"; +"use client" -import React, { memo } from "react"; +import React, { memo } from "react" interface AuroraTextProps { - children: React.ReactNode; - className?: string; - colors?: string[]; - speed?: number; - style?: React.CSSProperties; + children: React.ReactNode + className?: string + colors?: string[] + speed?: number } export const AuroraText = memo( @@ -16,7 +15,6 @@ export const AuroraText = memo( className = "", colors = ["#FF0080", "#7928CA", "#0070F3", "#38bdf8"], speed = 1, - style, }: AuroraTextProps) => { const gradientStyle = { backgroundImage: `linear-gradient(135deg, ${colors.join(", ")}, ${ @@ -25,10 +23,10 @@ export const AuroraText = memo( WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent", animationDuration: `${10 / speed}s`, - }; + } return ( - + {children} - ); - }, -); + ) + } +) -AuroraText.displayName = "AuroraText"; +AuroraText.displayName = "AuroraText" diff --git a/frontend/src/components/ui/avatar.tsx b/frontend/src/components/ui/avatar.tsx index c4475c2e..71e428b4 100644 --- a/frontend/src/components/ui/avatar.tsx +++ b/frontend/src/components/ui/avatar.tsx @@ -1,9 +1,9 @@ -"use client"; +"use client" -import * as React from "react"; -import * as AvatarPrimitive from "@radix-ui/react-avatar"; +import * as React from "react" +import * as AvatarPrimitive from "@radix-ui/react-avatar" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" function Avatar({ className, @@ -14,11 +14,11 @@ function Avatar({ data-slot="avatar" className={cn( "relative flex size-8 shrink-0 overflow-hidden rounded-full", - className, + className )} {...props} /> - ); + ) } function AvatarImage({ @@ -31,7 +31,7 @@ function AvatarImage({ className={cn("aspect-square size-full", className)} {...props} /> - ); + ) } function AvatarFallback({ @@ -43,11 +43,11 @@ function AvatarFallback({ data-slot="avatar-fallback" className={cn( "bg-muted flex size-full items-center justify-center rounded-full", - className, + className )} {...props} /> - ); + ) } -export { Avatar, AvatarImage, AvatarFallback }; +export { Avatar, AvatarImage, AvatarFallback } diff --git a/frontend/src/components/ui/badge.tsx b/frontend/src/components/ui/badge.tsx index 55f8352b..fd3a406b 100644 --- a/frontend/src/components/ui/badge.tsx +++ b/frontend/src/components/ui/badge.tsx @@ -1,8 +1,8 @@ -import * as React from "react"; -import { Slot } from "@radix-ui/react-slot"; -import { cva, type VariantProps } from "class-variance-authority"; +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" const badgeVariants = cva( "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden", @@ -22,8 +22,8 @@ const badgeVariants = cva( defaultVariants: { variant: "default", }, - }, -); + } +) function Badge({ className, @@ -32,7 +32,7 @@ function Badge({ ...props }: React.ComponentProps<"span"> & VariantProps & { asChild?: boolean }) { - const Comp = asChild ? Slot : "span"; + const Comp = asChild ? Slot : "span" return ( - ); + ) } -export { Badge, badgeVariants }; +export { Badge, badgeVariants } diff --git a/frontend/src/components/ui/breadcrumb.tsx b/frontend/src/components/ui/breadcrumb.tsx index f63ae19a..eb88f321 100644 --- a/frontend/src/components/ui/breadcrumb.tsx +++ b/frontend/src/components/ui/breadcrumb.tsx @@ -1,11 +1,11 @@ -import * as React from "react"; -import { Slot } from "@radix-ui/react-slot"; -import { ChevronRight, MoreHorizontal } from "lucide-react"; +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { ChevronRight, MoreHorizontal } from "lucide-react" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" function Breadcrumb({ ...props }: React.ComponentProps<"nav">) { - return
  • - ); + ) } function BreadcrumbEllipsis({ @@ -95,7 +95,7 @@ function BreadcrumbEllipsis({ More - ); + ) } export { @@ -106,4 +106,4 @@ export { BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis, -}; +} diff --git a/frontend/src/components/ui/button-group.tsx b/frontend/src/components/ui/button-group.tsx index 043802ed..8600af03 100644 --- a/frontend/src/components/ui/button-group.tsx +++ b/frontend/src/components/ui/button-group.tsx @@ -1,8 +1,8 @@ -import { Slot } from "@radix-ui/react-slot"; -import { cva, type VariantProps } from "class-variance-authority"; +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@/lib/utils"; -import { Separator } from "@/components/ui/separator"; +import { cn } from "@/lib/utils" +import { Separator } from "@/components/ui/separator" const buttonGroupVariants = cva( "flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2", @@ -18,8 +18,8 @@ const buttonGroupVariants = cva( defaultVariants: { orientation: "horizontal", }, - }, -); + } +) function ButtonGroup({ className, @@ -34,7 +34,7 @@ function ButtonGroup({ className={cn(buttonGroupVariants({ orientation }), className)} {...props} /> - ); + ) } function ButtonGroupText({ @@ -42,19 +42,19 @@ function ButtonGroupText({ asChild = false, ...props }: React.ComponentProps<"div"> & { - asChild?: boolean; + asChild?: boolean }) { - const Comp = asChild ? Slot : "div"; + const Comp = asChild ? Slot : "div" return ( - ); + ) } function ButtonGroupSeparator({ @@ -68,11 +68,11 @@ function ButtonGroupSeparator({ orientation={orientation} className={cn( "bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto", - className, + className )} {...props} /> - ); + ) } export { @@ -80,4 +80,4 @@ export { ButtonGroupSeparator, ButtonGroupText, buttonGroupVariants, -}; +} diff --git a/frontend/src/components/ui/button.tsx b/frontend/src/components/ui/button.tsx index f11b51b9..f332e0d9 100644 --- a/frontend/src/components/ui/button.tsx +++ b/frontend/src/components/ui/button.tsx @@ -18,7 +18,7 @@ const buttonVariants = cva( secondary: "cursor-pointer bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: - "cursor-pointer bg-transparent hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + "cursor-pointer hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", link: "cursor-pointer text-primary underline-offset-4 hover:underline", }, size: { diff --git a/frontend/src/components/ui/card.tsx b/frontend/src/components/ui/card.tsx index 48ae7eb2..681ad980 100644 --- a/frontend/src/components/ui/card.tsx +++ b/frontend/src/components/ui/card.tsx @@ -1,18 +1,18 @@ -import * as React from "react"; +import * as React from "react" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" function Card({ className, ...props }: React.ComponentProps<"div">) { return (
    - ); + ) } function CardHeader({ className, ...props }: React.ComponentProps<"div">) { @@ -20,12 +20,12 @@ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
    - ); + ) } function CardTitle({ className, ...props }: React.ComponentProps<"div">) { @@ -35,7 +35,7 @@ function CardTitle({ className, ...props }: React.ComponentProps<"div">) { className={cn("leading-none font-semibold", className)} {...props} /> - ); + ) } function CardDescription({ className, ...props }: React.ComponentProps<"div">) { @@ -45,7 +45,7 @@ function CardDescription({ className, ...props }: React.ComponentProps<"div">) { className={cn("text-muted-foreground text-sm", className)} {...props} /> - ); + ) } function CardAction({ className, ...props }: React.ComponentProps<"div">) { @@ -54,11 +54,11 @@ function CardAction({ className, ...props }: React.ComponentProps<"div">) { data-slot="card-action" className={cn( "col-start-2 row-span-2 row-start-1 self-start justify-self-end", - className, + className )} {...props} /> - ); + ) } function CardContent({ className, ...props }: React.ComponentProps<"div">) { @@ -68,7 +68,7 @@ function CardContent({ className, ...props }: React.ComponentProps<"div">) { className={cn("px-6", className)} {...props} /> - ); + ) } function CardFooter({ className, ...props }: React.ComponentProps<"div">) { @@ -78,7 +78,7 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) { className={cn("flex items-center px-6 [.border-t]:pt-6", className)} {...props} /> - ); + ) } export { @@ -89,4 +89,4 @@ export { CardAction, CardDescription, CardContent, -}; +} diff --git a/frontend/src/components/ui/carousel.tsx b/frontend/src/components/ui/carousel.tsx index dc1985af..0e05a77e 100644 --- a/frontend/src/components/ui/carousel.tsx +++ b/frontend/src/components/ui/carousel.tsx @@ -1,45 +1,45 @@ -"use client"; +"use client" -import * as React from "react"; +import * as React from "react" import useEmblaCarousel, { type UseEmblaCarouselType, -} from "embla-carousel-react"; -import { ArrowLeft, ArrowRight } from "lucide-react"; +} from "embla-carousel-react" +import { ArrowLeft, ArrowRight } from "lucide-react" -import { cn } from "@/lib/utils"; -import { Button } from "@/components/ui/button"; +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" -type CarouselApi = UseEmblaCarouselType[1]; -type UseCarouselParameters = Parameters; -type CarouselOptions = UseCarouselParameters[0]; -type CarouselPlugin = UseCarouselParameters[1]; +type CarouselApi = UseEmblaCarouselType[1] +type UseCarouselParameters = Parameters +type CarouselOptions = UseCarouselParameters[0] +type CarouselPlugin = UseCarouselParameters[1] type CarouselProps = { - opts?: CarouselOptions; - plugins?: CarouselPlugin; - orientation?: "horizontal" | "vertical"; - setApi?: (api: CarouselApi) => void; -}; + opts?: CarouselOptions + plugins?: CarouselPlugin + orientation?: "horizontal" | "vertical" + setApi?: (api: CarouselApi) => void +} type CarouselContextProps = { - carouselRef: ReturnType[0]; - api: ReturnType[1]; - scrollPrev: () => void; - scrollNext: () => void; - canScrollPrev: boolean; - canScrollNext: boolean; -} & CarouselProps; + carouselRef: ReturnType[0] + api: ReturnType[1] + scrollPrev: () => void + scrollNext: () => void + canScrollPrev: boolean + canScrollNext: boolean +} & CarouselProps -const CarouselContext = React.createContext(null); +const CarouselContext = React.createContext(null) function useCarousel() { - const context = React.useContext(CarouselContext); + const context = React.useContext(CarouselContext) if (!context) { - throw new Error("useCarousel must be used within a "); + throw new Error("useCarousel must be used within a ") } - return context; + return context } function Carousel({ @@ -56,53 +56,53 @@ function Carousel({ ...opts, axis: orientation === "horizontal" ? "x" : "y", }, - plugins, - ); - const [canScrollPrev, setCanScrollPrev] = React.useState(false); - const [canScrollNext, setCanScrollNext] = React.useState(false); + plugins + ) + const [canScrollPrev, setCanScrollPrev] = React.useState(false) + const [canScrollNext, setCanScrollNext] = React.useState(false) const onSelect = React.useCallback((api: CarouselApi) => { - if (!api) return; - setCanScrollPrev(api.canScrollPrev()); - setCanScrollNext(api.canScrollNext()); - }, []); + if (!api) return + setCanScrollPrev(api.canScrollPrev()) + setCanScrollNext(api.canScrollNext()) + }, []) const scrollPrev = React.useCallback(() => { - api?.scrollPrev(); - }, [api]); + api?.scrollPrev() + }, [api]) const scrollNext = React.useCallback(() => { - api?.scrollNext(); - }, [api]); + api?.scrollNext() + }, [api]) const handleKeyDown = React.useCallback( (event: React.KeyboardEvent) => { if (event.key === "ArrowLeft") { - event.preventDefault(); - scrollPrev(); + event.preventDefault() + scrollPrev() } else if (event.key === "ArrowRight") { - event.preventDefault(); - scrollNext(); + event.preventDefault() + scrollNext() } }, - [scrollPrev, scrollNext], - ); + [scrollPrev, scrollNext] + ) React.useEffect(() => { - if (!api || !setApi) return; - setApi(api); - }, [api, setApi]); + if (!api || !setApi) return + setApi(api) + }, [api, setApi]) React.useEffect(() => { - if (!api) return; - onSelect(api); - api.on("reInit", onSelect); - api.on("select", onSelect); + if (!api) return + onSelect(api) + api.on("reInit", onSelect) + api.on("select", onSelect) return () => { - api?.off("select", onSelect); - }; - }, [api, onSelect]); + api?.off("select", onSelect) + } + }, [api, onSelect]) return ( - ); + ) } function CarouselContent({ className, ...props }: React.ComponentProps<"div">) { - const { carouselRef, orientation } = useCarousel(); + const { carouselRef, orientation } = useCarousel() return (
    ) { className={cn( "flex", orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col", - className, + className )} {...props} />
    - ); + ) } function CarouselItem({ className, ...props }: React.ComponentProps<"div">) { - const { orientation } = useCarousel(); + const { orientation } = useCarousel() return (
    ) { className={cn( "min-w-0 shrink-0 grow-0 basis-full", orientation === "horizontal" ? "pl-4" : "pt-4", - className, + className )} {...props} /> - ); + ) } function CarouselPrevious({ @@ -177,7 +177,7 @@ function CarouselPrevious({ size = "icon", ...props }: React.ComponentProps) { - const { orientation, scrollPrev, canScrollPrev } = useCarousel(); + const { orientation, scrollPrev, canScrollPrev } = useCarousel() return ( - ); + ) } function CarouselNext({ @@ -207,7 +207,7 @@ function CarouselNext({ size = "icon", ...props }: React.ComponentProps) { - const { orientation, scrollNext, canScrollNext } = useCarousel(); + const { orientation, scrollNext, canScrollNext } = useCarousel() return ( - ); + ) } export { @@ -238,4 +238,4 @@ export { CarouselItem, CarouselPrevious, CarouselNext, -}; +} diff --git a/frontend/src/components/ui/command.tsx b/frontend/src/components/ui/command.tsx index ee7450af..8cb4ca7a 100644 --- a/frontend/src/components/ui/command.tsx +++ b/frontend/src/components/ui/command.tsx @@ -1,17 +1,17 @@ -"use client"; +"use client" -import * as React from "react"; -import { Command as CommandPrimitive } from "cmdk"; -import { SearchIcon } from "lucide-react"; +import * as React from "react" +import { Command as CommandPrimitive } from "cmdk" +import { SearchIcon } from "lucide-react" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, -} from "@/components/ui/dialog"; +} from "@/components/ui/dialog" function Command({ className, @@ -22,11 +22,11 @@ function Command({ data-slot="command" className={cn( "bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md", - className, + className )} {...props} /> - ); + ) } function CommandDialog({ @@ -37,10 +37,10 @@ function CommandDialog({ showCloseButton = true, ...props }: React.ComponentProps & { - title?: string; - description?: string; - className?: string; - showCloseButton?: boolean; + title?: string + description?: string + className?: string + showCloseButton?: boolean }) { return ( @@ -57,7 +57,7 @@ function CommandDialog({ - ); + ) } function CommandInput({ @@ -74,12 +74,12 @@ function CommandInput({ data-slot="command-input" className={cn( "placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50", - className, + className )} {...props} />
    - ); + ) } function CommandList({ @@ -91,11 +91,11 @@ function CommandList({ data-slot="command-list" className={cn( "max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto", - className, + className )} {...props} /> - ); + ) } function CommandEmpty({ @@ -107,7 +107,7 @@ function CommandEmpty({ className="py-6 text-center text-sm" {...props} /> - ); + ) } function CommandGroup({ @@ -119,11 +119,11 @@ function CommandGroup({ data-slot="command-group" className={cn( "text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium", - className, + className )} {...props} /> - ); + ) } function CommandSeparator({ @@ -136,7 +136,7 @@ function CommandSeparator({ className={cn("bg-border -mx-1 h-px", className)} {...props} /> - ); + ) } function CommandItem({ @@ -148,11 +148,11 @@ function CommandItem({ data-slot="command-item" className={cn( "data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", - className, + className )} {...props} /> - ); + ) } function CommandShortcut({ @@ -164,11 +164,11 @@ function CommandShortcut({ data-slot="command-shortcut" className={cn( "text-muted-foreground ml-auto text-xs tracking-widest", - className, + className )} {...props} /> - ); + ) } export { @@ -181,4 +181,4 @@ export { CommandItem, CommandShortcut, CommandSeparator, -}; +} diff --git a/frontend/src/components/ui/dialog.tsx b/frontend/src/components/ui/dialog.tsx index bad9f2de..a6f1cfbd 100644 --- a/frontend/src/components/ui/dialog.tsx +++ b/frontend/src/components/ui/dialog.tsx @@ -1,33 +1,33 @@ -"use client"; +"use client" -import * as React from "react"; -import * as DialogPrimitive from "@radix-ui/react-dialog"; -import { XIcon } from "lucide-react"; +import * as React from "react" +import * as DialogPrimitive from "@radix-ui/react-dialog" +import { XIcon } from "lucide-react" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" function Dialog({ ...props }: React.ComponentProps) { - return ; + return } function DialogTrigger({ ...props }: React.ComponentProps) { - return ; + return } function DialogPortal({ ...props }: React.ComponentProps) { - return ; + return } function DialogClose({ ...props }: React.ComponentProps) { - return ; + return } function DialogOverlay({ @@ -39,11 +39,11 @@ function DialogOverlay({ data-slot="dialog-overlay" className={cn( "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50", - className, + className )} {...props} /> - ); + ) } function DialogContent({ @@ -52,7 +52,7 @@ function DialogContent({ showCloseButton = true, ...props }: React.ComponentProps & { - showCloseButton?: boolean; + showCloseButton?: boolean }) { return ( @@ -61,7 +61,7 @@ function DialogContent({ data-slot="dialog-content" className={cn( "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg", - className, + className )} {...props} > @@ -77,7 +77,7 @@ function DialogContent({ )} - ); + ) } function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { @@ -87,7 +87,7 @@ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { className={cn("flex flex-col gap-2 text-center sm:text-left", className)} {...props} /> - ); + ) } function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { @@ -96,11 +96,11 @@ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { data-slot="dialog-footer" className={cn( "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", - className, + className )} {...props} /> - ); + ) } function DialogTitle({ @@ -113,7 +113,7 @@ function DialogTitle({ className={cn("text-lg leading-none font-semibold", className)} {...props} /> - ); + ) } function DialogDescription({ @@ -126,7 +126,7 @@ function DialogDescription({ className={cn("text-muted-foreground text-sm", className)} {...props} /> - ); + ) } export { @@ -140,4 +140,4 @@ export { DialogPortal, DialogTitle, DialogTrigger, -}; +} diff --git a/frontend/src/components/ui/dropdown-menu.tsx b/frontend/src/components/ui/dropdown-menu.tsx index 1270e58f..bbe6fb01 100644 --- a/frontend/src/components/ui/dropdown-menu.tsx +++ b/frontend/src/components/ui/dropdown-menu.tsx @@ -1,15 +1,15 @@ -"use client"; +"use client" -import * as React from "react"; -import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"; -import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"; +import * as React from "react" +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" function DropdownMenu({ ...props }: React.ComponentProps) { - return ; + return } function DropdownMenuPortal({ @@ -17,20 +17,18 @@ function DropdownMenuPortal({ }: React.ComponentProps) { return ( - ); + ) } function DropdownMenuTrigger({ - className, ...props }: React.ComponentProps) { return ( - ); + ) } function DropdownMenuContent({ @@ -44,13 +42,13 @@ function DropdownMenuContent({ data-slot="dropdown-menu-content" sideOffset={sideOffset} className={cn( - "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-[20px] border p-[20px] shadow-md", - className, + "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md", + className )} {...props} /> - ); + ) } function DropdownMenuGroup({ @@ -58,7 +56,7 @@ function DropdownMenuGroup({ }: React.ComponentProps) { return ( - ); + ) } function DropdownMenuItem({ @@ -67,8 +65,8 @@ function DropdownMenuItem({ variant = "default", ...props }: React.ComponentProps & { - inset?: boolean; - variant?: "default" | "destructive"; + inset?: boolean + variant?: "default" | "destructive" }) { return ( - ); + ) } function DropdownMenuCheckboxItem({ @@ -95,7 +93,7 @@ function DropdownMenuCheckboxItem({ data-slot="dropdown-menu-checkbox-item" className={cn( "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", - className, + className )} checked={checked} {...props} @@ -107,7 +105,7 @@ function DropdownMenuCheckboxItem({ {children} - ); + ) } function DropdownMenuRadioGroup({ @@ -118,7 +116,7 @@ function DropdownMenuRadioGroup({ data-slot="dropdown-menu-radio-group" {...props} /> - ); + ) } function DropdownMenuRadioItem({ @@ -130,8 +128,8 @@ function DropdownMenuRadioItem({ @@ -142,7 +140,7 @@ function DropdownMenuRadioItem({ {children} - ); + ) } function DropdownMenuLabel({ @@ -150,7 +148,7 @@ function DropdownMenuLabel({ inset, ...props }: React.ComponentProps & { - inset?: boolean; + inset?: boolean }) { return ( - ); + ) } function DropdownMenuSeparator({ @@ -175,7 +173,7 @@ function DropdownMenuSeparator({ className={cn("bg-border -mx-1 my-1 h-px", className)} {...props} /> - ); + ) } function DropdownMenuShortcut({ @@ -187,17 +185,17 @@ function DropdownMenuShortcut({ data-slot="dropdown-menu-shortcut" className={cn( "text-muted-foreground ml-auto text-xs tracking-widest", - className, + className )} {...props} /> - ); + ) } function DropdownMenuSub({ ...props }: React.ComponentProps) { - return ; + return } function DropdownMenuSubTrigger({ @@ -206,7 +204,7 @@ function DropdownMenuSubTrigger({ children, ...props }: React.ComponentProps & { - inset?: boolean; + inset?: boolean }) { return ( {children} - ); + ) } function DropdownMenuSubContent({ @@ -232,12 +230,12 @@ function DropdownMenuSubContent({ - ); + ) } export { @@ -256,4 +254,4 @@ export { DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, -}; +} diff --git a/frontend/src/components/ui/empty.tsx b/frontend/src/components/ui/empty.tsx index e4a0754c..df91e9d8 100644 --- a/frontend/src/components/ui/empty.tsx +++ b/frontend/src/components/ui/empty.tsx @@ -1,6 +1,6 @@ -import { cva, type VariantProps } from "class-variance-authority"; +import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" function Empty({ className, ...props }: React.ComponentProps<"div">) { return ( @@ -8,11 +8,11 @@ function Empty({ className, ...props }: React.ComponentProps<"div">) { data-slot="empty" className={cn( "flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12", - className, + className )} {...props} /> - ); + ) } function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) { @@ -21,11 +21,11 @@ function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) { data-slot="empty-header" className={cn( "flex max-w-sm flex-col items-center gap-2 text-center", - className, + className )} {...props} /> - ); + ) } const emptyMediaVariants = cva( @@ -40,8 +40,8 @@ const emptyMediaVariants = cva( defaultVariants: { variant: "default", }, - }, -); + } +) function EmptyMedia({ className, @@ -55,7 +55,7 @@ function EmptyMedia({ className={cn(emptyMediaVariants({ variant, className }))} {...props} /> - ); + ) } function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) { @@ -65,7 +65,7 @@ function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) { className={cn("text-lg font-medium tracking-tight", className)} {...props} /> - ); + ) } function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) { @@ -74,11 +74,11 @@ function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) { data-slot="empty-description" className={cn( "text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4", - className, + className )} {...props} /> - ); + ) } function EmptyContent({ className, ...props }: React.ComponentProps<"div">) { @@ -87,11 +87,11 @@ function EmptyContent({ className, ...props }: React.ComponentProps<"div">) { data-slot="empty-content" className={cn( "flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance", - className, + className )} {...props} /> - ); + ) } export { @@ -101,4 +101,4 @@ export { EmptyDescription, EmptyContent, EmptyMedia, -}; +} diff --git a/frontend/src/components/ui/hover-card.tsx b/frontend/src/components/ui/hover-card.tsx index f574b4ad..e7541864 100644 --- a/frontend/src/components/ui/hover-card.tsx +++ b/frontend/src/components/ui/hover-card.tsx @@ -1,14 +1,14 @@ -"use client"; +"use client" -import * as React from "react"; -import * as HoverCardPrimitive from "@radix-ui/react-hover-card"; +import * as React from "react" +import * as HoverCardPrimitive from "@radix-ui/react-hover-card" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" function HoverCard({ ...props }: React.ComponentProps) { - return ; + return } function HoverCardTrigger({ @@ -16,7 +16,7 @@ function HoverCardTrigger({ }: React.ComponentProps) { return ( - ); + ) } function HoverCardContent({ @@ -33,12 +33,12 @@ function HoverCardContent({ sideOffset={sideOffset} className={cn( "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden", - className, + className )} {...props} /> - ); + ) } -export { HoverCard, HoverCardTrigger, HoverCardContent }; +export { HoverCard, HoverCardTrigger, HoverCardContent } diff --git a/frontend/src/components/ui/input-group.tsx b/frontend/src/components/ui/input-group.tsx index 392738be..e35f75b2 100644 --- a/frontend/src/components/ui/input-group.tsx +++ b/frontend/src/components/ui/input-group.tsx @@ -14,20 +14,20 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) { data-slot="input-group" role="group" className={cn( - "group/input-group dark:bg-background/80 relative flex w-full max-w-[720px] items-center overflow-hidden rounded-md bg-[#FBFAFC] transition-[color,box-shadow] outline-none", + "group/input-group border-input/50 dark:bg-background/80 relative flex w-full items-center rounded-md border bg-white/80 shadow-xs transition-[color,box-shadow] outline-none", "h-9 min-w-0 has-[>textarea]:h-auto", // Variants based on alignment. "has-[>[data-align=inline-start]]:[&>input]:pl-2", "has-[>[data-align=inline-end]]:[&>input]:pr-2", "has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3", - "has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3", + "has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3", // Focus state. - "has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]", + "has-[[data-slot=input-group-control]:focus-visible]:border-input has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]", // Error state. - "has-[[data-slot][aria-invalid=true]]:ring-destructive/20 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40", + "has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40", className, )} @@ -152,7 +152,7 @@ function InputGroupTextarea({