Template
Improve chat navigation, model selection, and streaming
This commit is contained in:
@@ -8,7 +8,7 @@ import {
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { type LucideIcon, XIcon } from "lucide-react";
|
||||
import { type RemixiconComponentType, RiCloseLine } from "@remixicon/react";
|
||||
import type { ComponentProps, HTMLAttributes } from "react";
|
||||
|
||||
export type ArtifactProps = HTMLAttributes<HTMLDivElement>;
|
||||
@@ -57,7 +57,7 @@ export const ArtifactClose = ({
|
||||
variant={variant}
|
||||
{...props}
|
||||
>
|
||||
{children ?? <XIcon className="size-4" />}
|
||||
{children ?? <RiCloseLine className="size-4" />}
|
||||
<span className="sr-only">Close</span>
|
||||
</Button>
|
||||
);
|
||||
@@ -92,7 +92,7 @@ export const ArtifactActions = ({
|
||||
export type ArtifactActionProps = ComponentProps<typeof Button> & {
|
||||
tooltip?: string;
|
||||
label?: string;
|
||||
icon?: LucideIcon;
|
||||
icon?: RemixiconComponentType;
|
||||
};
|
||||
|
||||
export const ArtifactAction = ({
|
||||
|
||||
@@ -9,11 +9,11 @@ import {
|
||||
} from "@/components/ui/collapsible";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
BrainIcon,
|
||||
ChevronDownIcon,
|
||||
DotIcon,
|
||||
type LucideIcon,
|
||||
} from "lucide-react";
|
||||
RiBrainLine,
|
||||
RiArrowDownSLine,
|
||||
RiCircleFill,
|
||||
type RemixiconComponentType,
|
||||
} from "@remixicon/react";
|
||||
import type { ComponentProps, ReactNode } from "react";
|
||||
import { createContext, memo, useContext, useMemo } from "react";
|
||||
|
||||
@@ -92,11 +92,11 @@ export const ChainOfThoughtHeader = memo(
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<BrainIcon className="size-4" />
|
||||
<RiBrainLine className="size-4" />
|
||||
<span className="flex-1 text-left">
|
||||
{children ?? "Chain of Thought"}
|
||||
</span>
|
||||
<ChevronDownIcon
|
||||
<RiArrowDownSLine
|
||||
className={cn(
|
||||
"size-4 transition-transform",
|
||||
isOpen ? "rotate-180" : "rotate-0"
|
||||
@@ -109,7 +109,7 @@ export const ChainOfThoughtHeader = memo(
|
||||
);
|
||||
|
||||
export type ChainOfThoughtStepProps = ComponentProps<"div"> & {
|
||||
icon?: LucideIcon;
|
||||
icon?: RemixiconComponentType;
|
||||
label: ReactNode;
|
||||
description?: ReactNode;
|
||||
status?: "complete" | "active" | "pending";
|
||||
@@ -118,7 +118,7 @@ export type ChainOfThoughtStepProps = ComponentProps<"div"> & {
|
||||
export const ChainOfThoughtStep = memo(
|
||||
({
|
||||
className,
|
||||
icon: Icon = DotIcon,
|
||||
icon: Icon = RiCircleFill,
|
||||
label,
|
||||
description,
|
||||
status = "complete",
|
||||
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { BookmarkIcon, type LucideProps } from "lucide-react";
|
||||
import type { ComponentProps, HTMLAttributes } from "react";
|
||||
import { RiBookmarkLine } from "@remixicon/react";
|
||||
import type { ComponentProps, HTMLAttributes, ReactNode } from "react";
|
||||
|
||||
export type CheckpointProps = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
@@ -27,7 +27,9 @@ export const Checkpoint = ({
|
||||
</div>
|
||||
);
|
||||
|
||||
export type CheckpointIconProps = LucideProps;
|
||||
export type CheckpointIconProps = Omit<ComponentProps<typeof RiBookmarkLine>, "children"> & {
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
export const CheckpointIcon = ({
|
||||
className,
|
||||
@@ -35,7 +37,7 @@ export const CheckpointIcon = ({
|
||||
...props
|
||||
}: CheckpointIconProps) =>
|
||||
children ?? (
|
||||
<BookmarkIcon className={cn("size-4 shrink-0", className)} {...props} />
|
||||
<RiBookmarkLine className={cn("size-4 shrink-0", className)} {...props} />
|
||||
);
|
||||
|
||||
export type CheckpointTriggerProps = ComponentProps<typeof Button> & {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { CheckIcon, CopyIcon } from "lucide-react";
|
||||
import { RiCheckLine, RiFileCopyLine } from "@remixicon/react";
|
||||
import {
|
||||
type ComponentProps,
|
||||
createContext,
|
||||
@@ -162,7 +162,7 @@ export const CodeBlockCopyButton = ({
|
||||
}
|
||||
};
|
||||
|
||||
const Icon = isCopied ? CheckIcon : CopyIcon;
|
||||
const Icon = isCopied ? RiCheckLine : RiFileCopyLine;
|
||||
|
||||
return (
|
||||
<Button
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ArrowDownIcon } from "lucide-react";
|
||||
import { RiArrowDownLine } from "@remixicon/react";
|
||||
import type { ComponentProps } from "react";
|
||||
import { useCallback } from "react";
|
||||
import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
||||
@@ -93,7 +93,7 @@ export const ConversationScrollButton = ({
|
||||
variant="outline"
|
||||
{...props}
|
||||
>
|
||||
<ArrowDownIcon className="size-4" />
|
||||
<RiArrowDownLine className="size-4" />
|
||||
</Button>
|
||||
)
|
||||
);
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
HoverCardTrigger,
|
||||
} from "@/components/ui/hover-card";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react";
|
||||
import { RiArrowLeftLine, RiArrowRightLine } from "@remixicon/react";
|
||||
import {
|
||||
type ComponentProps,
|
||||
createContext,
|
||||
@@ -206,7 +206,7 @@ export const InlineCitationCarouselPrev = ({
|
||||
type="button"
|
||||
{...props}
|
||||
>
|
||||
<ArrowLeftIcon className="size-4 text-muted-foreground" />
|
||||
<RiArrowLeftLine className="size-4 text-muted-foreground" />
|
||||
</button>
|
||||
);
|
||||
};
|
||||
@@ -233,7 +233,7 @@ export const InlineCitationCarouselNext = ({
|
||||
type="button"
|
||||
{...props}
|
||||
>
|
||||
<ArrowRightIcon className="size-4 text-muted-foreground" />
|
||||
<RiArrowRightLine className="size-4 text-muted-foreground" />
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,11 +14,11 @@ import {
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { FileUIPart, UIMessage } from "ai";
|
||||
import {
|
||||
ChevronLeftIcon,
|
||||
ChevronRightIcon,
|
||||
PaperclipIcon,
|
||||
XIcon,
|
||||
} from "lucide-react";
|
||||
RiArrowLeftSLine,
|
||||
RiArrowRightSLine,
|
||||
RiAttachment2,
|
||||
RiCloseLine,
|
||||
} from "@remixicon/react";
|
||||
import type { ComponentProps, HTMLAttributes, ReactElement, ReactNode } from "react";
|
||||
import {
|
||||
Children,
|
||||
@@ -267,7 +267,7 @@ export const MessageBranchPrevious = ({
|
||||
variant="ghost"
|
||||
{...props}
|
||||
>
|
||||
{children ?? <ChevronLeftIcon size={14} />}
|
||||
{children ?? <RiArrowLeftSLine size={14} />}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
@@ -291,7 +291,7 @@ export const MessageBranchNext = ({
|
||||
variant="ghost"
|
||||
{...props}
|
||||
>
|
||||
{children ?? <ChevronRightIcon size={14} />}
|
||||
{children ?? <RiArrowRightSLine size={14} />}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
@@ -338,8 +338,7 @@ export const MessageResponse = memo(
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
(prevProps, nextProps) => prevProps.children === nextProps.children
|
||||
)
|
||||
);
|
||||
|
||||
MessageResponse.displayName = "MessageResponse";
|
||||
@@ -390,7 +389,7 @@ export function MessageAttachment({
|
||||
type="button"
|
||||
variant="ghost"
|
||||
>
|
||||
<XIcon />
|
||||
<RiCloseLine />
|
||||
<span className="sr-only">Remove</span>
|
||||
</Button>
|
||||
)}
|
||||
@@ -400,7 +399,7 @@ export function MessageAttachment({
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div className="flex size-full shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground">
|
||||
<PaperclipIcon className="size-4" />
|
||||
<RiAttachment2 className="size-4" />
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
@@ -418,7 +417,7 @@ export function MessageAttachment({
|
||||
type="button"
|
||||
variant="ghost"
|
||||
>
|
||||
<XIcon />
|
||||
<RiCloseLine />
|
||||
<span className="sr-only">Remove</span>
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -11,10 +11,10 @@ import {
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
ChevronDownIcon,
|
||||
ExternalLinkIcon,
|
||||
MessageCircleIcon,
|
||||
} from "lucide-react";
|
||||
RiArrowDownSLine,
|
||||
RiExternalLinkLine,
|
||||
RiChat3Line,
|
||||
} from "@remixicon/react";
|
||||
import { type ComponentProps, createContext, useContext } from "react";
|
||||
|
||||
const providers = {
|
||||
@@ -140,7 +140,7 @@ const providers = {
|
||||
`https://t3.chat/new?${new URLSearchParams({
|
||||
q,
|
||||
})}`,
|
||||
icon: <MessageCircleIcon />,
|
||||
icon: <RiChat3Line />,
|
||||
},
|
||||
v0: {
|
||||
title: "Open in v0",
|
||||
@@ -238,7 +238,7 @@ export const OpenInTrigger = ({ children, ...props }: OpenInTriggerProps) => (
|
||||
{children ?? (
|
||||
<Button type="button" variant="outline">
|
||||
Open in chat
|
||||
<ChevronDownIcon className="size-4" />
|
||||
<RiArrowDownSLine className="size-4" />
|
||||
</Button>
|
||||
)}
|
||||
</DropdownMenuTrigger>
|
||||
@@ -258,7 +258,7 @@ export const OpenInChatGPT = (props: OpenInChatGPTProps) => {
|
||||
>
|
||||
<span className="shrink-0">{providers.chatgpt.icon}</span>
|
||||
<span className="flex-1">{providers.chatgpt.title}</span>
|
||||
<ExternalLinkIcon className="size-4 shrink-0" />
|
||||
<RiExternalLinkLine className="size-4 shrink-0" />
|
||||
</a>
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
@@ -278,7 +278,7 @@ export const OpenInClaude = (props: OpenInClaudeProps) => {
|
||||
>
|
||||
<span className="shrink-0">{providers.claude.icon}</span>
|
||||
<span className="flex-1">{providers.claude.title}</span>
|
||||
<ExternalLinkIcon className="size-4 shrink-0" />
|
||||
<RiExternalLinkLine className="size-4 shrink-0" />
|
||||
</a>
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
@@ -298,7 +298,7 @@ export const OpenInT3 = (props: OpenInT3Props) => {
|
||||
>
|
||||
<span className="shrink-0">{providers.t3.icon}</span>
|
||||
<span className="flex-1">{providers.t3.title}</span>
|
||||
<ExternalLinkIcon className="size-4 shrink-0" />
|
||||
<RiExternalLinkLine className="size-4 shrink-0" />
|
||||
</a>
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
@@ -318,7 +318,7 @@ export const OpenInScira = (props: OpenInSciraProps) => {
|
||||
>
|
||||
<span className="shrink-0">{providers.scira.icon}</span>
|
||||
<span className="flex-1">{providers.scira.title}</span>
|
||||
<ExternalLinkIcon className="size-4 shrink-0" />
|
||||
<RiExternalLinkLine className="size-4 shrink-0" />
|
||||
</a>
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
@@ -338,7 +338,7 @@ export const OpenInv0 = (props: OpenInv0Props) => {
|
||||
>
|
||||
<span className="shrink-0">{providers.v0.icon}</span>
|
||||
<span className="flex-1">{providers.v0.title}</span>
|
||||
<ExternalLinkIcon className="size-4 shrink-0" />
|
||||
<RiExternalLinkLine className="size-4 shrink-0" />
|
||||
</a>
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
@@ -358,7 +358,7 @@ export const OpenInCursor = (props: OpenInCursorProps) => {
|
||||
>
|
||||
<span className="shrink-0">{providers.cursor.icon}</span>
|
||||
<span className="flex-1">{providers.cursor.title}</span>
|
||||
<ExternalLinkIcon className="size-4 shrink-0" />
|
||||
<RiExternalLinkLine className="size-4 shrink-0" />
|
||||
</a>
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
CollapsibleTrigger,
|
||||
} from "@/components/ui/collapsible";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ChevronsUpDownIcon } from "lucide-react";
|
||||
import { RiExpandUpDownLine } from "@remixicon/react";
|
||||
import type { ComponentProps } from "react";
|
||||
import { createContext, useContext } from "react";
|
||||
import { Shimmer } from "./shimmer";
|
||||
@@ -135,7 +135,7 @@ export const PlanTrigger = ({ className, ...props }: PlanTriggerProps) => (
|
||||
variant="ghost"
|
||||
{...props}
|
||||
>
|
||||
<ChevronsUpDownIcon className="size-4" />
|
||||
<RiExpandUpDownLine className="size-4" />
|
||||
<span className="sr-only">Toggle plan</span>
|
||||
</Button>
|
||||
</CollapsibleTrigger>
|
||||
|
||||
@@ -37,14 +37,14 @@ import {
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ChatStatus, FileUIPart } from "ai";
|
||||
import {
|
||||
CornerDownLeftIcon,
|
||||
ImageIcon,
|
||||
MicIcon,
|
||||
PaperclipIcon,
|
||||
PlusIcon,
|
||||
SquareIcon,
|
||||
XIcon,
|
||||
} from "lucide-react";
|
||||
RiCornerDownLeftLine,
|
||||
RiImageLine,
|
||||
RiMicLine,
|
||||
RiAttachment2,
|
||||
RiAddLine,
|
||||
RiStopFill,
|
||||
RiCloseLine,
|
||||
} from "@remixicon/react";
|
||||
import { Loader } from "@/components/ai-elements/loader";
|
||||
import { nanoid } from "nanoid";
|
||||
import {
|
||||
@@ -319,7 +319,7 @@ export function PromptInputAttachment({
|
||||
/>
|
||||
) : (
|
||||
<div className="flex size-5 items-center justify-center text-muted-foreground">
|
||||
<PaperclipIcon className="size-3" />
|
||||
<RiAttachment2 className="size-3" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -333,7 +333,7 @@ export function PromptInputAttachment({
|
||||
type="button"
|
||||
variant="ghost"
|
||||
>
|
||||
<XIcon />
|
||||
<RiCloseLine />
|
||||
<span className="sr-only">Remove</span>
|
||||
</Button>
|
||||
</div>
|
||||
@@ -421,7 +421,7 @@ export const PromptInputActionAddAttachments = ({
|
||||
attachments.openFileDialog();
|
||||
}}
|
||||
>
|
||||
<ImageIcon className="mr-2 size-4" /> {label}
|
||||
<RiImageLine className="mr-2 size-4" /> {label}
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
};
|
||||
@@ -989,7 +989,7 @@ export const PromptInputActionMenuTrigger = ({
|
||||
}: PromptInputActionMenuTriggerProps) => (
|
||||
<DropdownMenuTrigger asChild>
|
||||
<PromptInputButton className={className} {...props}>
|
||||
{children ?? <PlusIcon className="size-4" />}
|
||||
{children ?? <RiAddLine className="size-4" />}
|
||||
</PromptInputButton>
|
||||
</DropdownMenuTrigger>
|
||||
);
|
||||
@@ -1029,14 +1029,14 @@ export const PromptInputSubmit = ({
|
||||
children,
|
||||
...props
|
||||
}: PromptInputSubmitProps) => {
|
||||
let Icon = <CornerDownLeftIcon className="size-4" />;
|
||||
let Icon = <RiCornerDownLeftLine className="size-4" />;
|
||||
|
||||
if (status === "submitted") {
|
||||
Icon = <Loader size={16} />;
|
||||
} else if (status === "streaming") {
|
||||
Icon = <SquareIcon className="size-4" />;
|
||||
Icon = <RiStopFill className="size-4" />;
|
||||
} else if (status === "error") {
|
||||
Icon = <XIcon className="size-4" />;
|
||||
Icon = <RiCloseLine className="size-4" />;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -1208,7 +1208,7 @@ export const PromptInputSpeechButton = ({
|
||||
onClick={toggleListening}
|
||||
{...props}
|
||||
>
|
||||
<MicIcon className="size-4" />
|
||||
<RiMicLine className="size-4" />
|
||||
</PromptInputButton>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from "@/components/ui/collapsible";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ChevronDownIcon, PaperclipIcon } from "lucide-react";
|
||||
import { RiArrowDownSLine, RiAttachment2 } from "@remixicon/react";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
export type QueueMessagePart = {
|
||||
@@ -174,7 +174,7 @@ export const QueueItemFile = ({
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<PaperclipIcon size={12} />
|
||||
<RiAttachment2 size={12} />
|
||||
<span className="max-w-[100px] truncate">{children}</span>
|
||||
</span>
|
||||
);
|
||||
@@ -241,7 +241,7 @@ export const QueueSectionLabel = ({
|
||||
...props
|
||||
}: QueueSectionLabelProps) => (
|
||||
<span className={cn("flex items-center gap-2", className)} {...props}>
|
||||
<ChevronDownIcon className="group-data-[state=closed]:-rotate-90 size-4 transition-transform" />
|
||||
<RiArrowDownSLine className="group-data-[state=closed]:-rotate-90 size-4 transition-transform" />
|
||||
{icon}
|
||||
<span>
|
||||
{count} {label}
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
CollapsibleTrigger,
|
||||
} from "@/components/ui/collapsible";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { BrainIcon, ChevronDownIcon } from "lucide-react";
|
||||
import { RiBrainLine, RiArrowDownSLine } from "@remixicon/react";
|
||||
import type { ComponentProps, ReactNode } from "react";
|
||||
import { createContext, memo, useContext, useEffect, useState } from "react";
|
||||
import { Streamdown } from "streamdown";
|
||||
@@ -139,9 +139,9 @@ export const ReasoningTrigger = memo(
|
||||
>
|
||||
{children ?? (
|
||||
<>
|
||||
<BrainIcon className="size-4" />
|
||||
<RiBrainLine className="size-4" />
|
||||
{getThinkingMessage(isStreaming, duration)}
|
||||
<ChevronDownIcon
|
||||
<RiArrowDownSLine
|
||||
className={cn(
|
||||
"size-4 transition-transform",
|
||||
isOpen ? "rotate-180" : "rotate-0"
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
TabsTrigger,
|
||||
} from "@/components/ui/tabs";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ChevronDownIcon, Code } from "lucide-react";
|
||||
import { RiArrowDownSLine, RiCodeLine } from "@remixicon/react";
|
||||
|
||||
import { getStatusBadge } from "./tool";
|
||||
|
||||
@@ -52,11 +52,11 @@ export const SandboxHeader = ({
|
||||
{...props}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<Code className="size-4 text-muted-foreground" />
|
||||
<RiCodeLine className="size-4 text-muted-foreground" />
|
||||
<span className="font-medium text-sm">{title}</span>
|
||||
{getStatusBadge(state)}
|
||||
</div>
|
||||
<ChevronDownIcon className="size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
|
||||
<RiArrowDownSLine className="size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
|
||||
</CollapsibleTrigger>
|
||||
);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
CollapsibleTrigger,
|
||||
} from "@/components/ui/collapsible";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { BookIcon, ChevronDownIcon } from "lucide-react";
|
||||
import { RiBookOpenLine, RiArrowDownSLine } from "@remixicon/react";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
export type SourcesProps = ComponentProps<"div">;
|
||||
@@ -35,7 +35,7 @@ export const SourcesTrigger = ({
|
||||
{children ?? (
|
||||
<>
|
||||
<p className="font-medium">Used {count} sources</p>
|
||||
<ChevronDownIcon className="h-4 w-4" />
|
||||
<RiArrowDownSLine className="h-4 w-4" />
|
||||
</>
|
||||
)}
|
||||
</CollapsibleTrigger>
|
||||
@@ -69,7 +69,7 @@ export const Source = ({ href, title, children, ...props }: SourceProps) => (
|
||||
>
|
||||
{children ?? (
|
||||
<>
|
||||
<BookIcon className="h-4 w-4" />
|
||||
<RiBookOpenLine className="h-4 w-4" />
|
||||
<span className="block font-medium">{title}</span>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
CollapsibleTrigger,
|
||||
} from "@/components/ui/collapsible";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ChevronDownIcon, SearchIcon } from "lucide-react";
|
||||
import { RiArrowDownSLine, RiSearchLine } from "@remixicon/react";
|
||||
import type { ComponentProps, ReactNode } from "react";
|
||||
|
||||
export type TaskItemFileProps = ComponentProps<"div">;
|
||||
@@ -60,9 +60,9 @@ export const TaskTrigger = ({
|
||||
<CollapsibleTrigger asChild className={cn("group", className)} {...props}>
|
||||
{children ?? (
|
||||
<div className="flex w-full cursor-pointer items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground">
|
||||
{icon ?? <SearchIcon className="size-4" />}
|
||||
{icon ?? <RiSearchLine className="size-4" />}
|
||||
<p className="text-sm">{title}</p>
|
||||
<ChevronDownIcon className="size-4 transition-transform group-data-[state=open]:rotate-180" />
|
||||
<RiArrowDownSLine className="size-4 transition-transform group-data-[state=open]:rotate-180" />
|
||||
</div>
|
||||
)}
|
||||
</CollapsibleTrigger>
|
||||
|
||||
@@ -9,13 +9,13 @@ import {
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ToolUIPart } from "ai";
|
||||
import {
|
||||
CheckCircleIcon,
|
||||
ChevronDownIcon,
|
||||
CircleIcon,
|
||||
ClockIcon,
|
||||
WrenchIcon,
|
||||
XCircleIcon,
|
||||
} from "lucide-react";
|
||||
RiCheckboxCircleLine,
|
||||
RiArrowDownSLine,
|
||||
RiCircleLine,
|
||||
RiTimeLine,
|
||||
RiToolsLine,
|
||||
RiCloseCircleLine,
|
||||
} from "@remixicon/react";
|
||||
import type { ComponentProps, ReactNode } from "react";
|
||||
import { isValidElement } from "react";
|
||||
import { CodeBlock } from "./code-block";
|
||||
@@ -48,13 +48,13 @@ export const getStatusBadge = (status: ToolUIPart["state"]) => {
|
||||
};
|
||||
|
||||
const icons: Record<ToolUIPart["state"], ReactNode> = {
|
||||
"input-streaming": <CircleIcon className="size-4" />,
|
||||
"input-available": <ClockIcon className="size-4 animate-pulse" />,
|
||||
"approval-requested": <ClockIcon className="size-4 text-yellow-600" />,
|
||||
"approval-responded": <CheckCircleIcon className="size-4 text-blue-600" />,
|
||||
"output-available": <CheckCircleIcon className="size-4 text-green-600" />,
|
||||
"output-error": <XCircleIcon className="size-4 text-red-600" />,
|
||||
"output-denied": <XCircleIcon className="size-4 text-orange-600" />,
|
||||
"input-streaming": <RiCircleLine className="size-4" />,
|
||||
"input-available": <RiTimeLine className="size-4 animate-pulse" />,
|
||||
"approval-requested": <RiTimeLine className="size-4 text-yellow-600" />,
|
||||
"approval-responded": <RiCheckboxCircleLine className="size-4 text-blue-600" />,
|
||||
"output-available": <RiCheckboxCircleLine className="size-4 text-green-600" />,
|
||||
"output-error": <RiCloseCircleLine className="size-4 text-red-600" />,
|
||||
"output-denied": <RiCloseCircleLine className="size-4 text-orange-600" />,
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -80,13 +80,13 @@ export const ToolHeader = ({
|
||||
{...props}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<WrenchIcon className="size-4 text-muted-foreground" />
|
||||
<RiToolsLine className="size-4 text-muted-foreground" />
|
||||
<span className="font-medium text-sm">
|
||||
{title ?? type.split("-").slice(1).join("-")}
|
||||
</span>
|
||||
{getStatusBadge(state)}
|
||||
</div>
|
||||
<ChevronDownIcon className="size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
|
||||
<RiArrowDownSLine className="size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
|
||||
</CollapsibleTrigger>
|
||||
);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ChevronDownIcon } from "lucide-react";
|
||||
import { RiArrowDownSLine } from "@remixicon/react";
|
||||
import type { ComponentProps, ReactNode } from "react";
|
||||
import { createContext, useContext, useEffect, useState } from "react";
|
||||
|
||||
@@ -220,7 +220,7 @@ export const WebPreviewConsole = ({
|
||||
variant="ghost"
|
||||
>
|
||||
Console
|
||||
<ChevronDownIcon
|
||||
<RiArrowDownSLine
|
||||
className={cn(
|
||||
"h-4 w-4 transition-transform duration-200",
|
||||
consoleOpen && "rotate-180"
|
||||
|
||||
Reference in New Issue
Block a user