Update primary color palette (#497)
This commit is contained in:
parent
b5c165714b
commit
d948b99719
9 changed files with 180 additions and 111 deletions
|
|
@ -30,9 +30,9 @@
|
|||
--card-foreground: 240 10% 3.9%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 240 10% 3.9%;
|
||||
--primary: 240 5.9% 10%;
|
||||
--primary: 217 100% 45%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
--secondary: 240 4.8% 95.9%;
|
||||
--secondary: 213 100% 96%;
|
||||
--secondary-foreground: 240 5.9% 10%;
|
||||
--muted: 240 4.8% 95.9%;
|
||||
--muted-foreground: 240 3.8% 46.1%;
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
--accent-foreground: 240 5.9% 10%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 240 5.9% 90%;
|
||||
--border: 214 32% 91%;
|
||||
--input: 240 5.9% 90%;
|
||||
--ring: 240 10% 3.9%;
|
||||
--chart-1: 12 76% 61%;
|
||||
|
|
@ -65,8 +65,8 @@
|
|||
--card-foreground: 0 0% 98%;
|
||||
--popover: 240 10% 3.9%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 240 5.9% 10%;
|
||||
--primary: 208.69 100% 24.18%;
|
||||
--primary-foreground: 207 100% 96%;
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 240 3.7% 15.9%;
|
||||
|
|
@ -142,5 +142,5 @@
|
|||
}
|
||||
|
||||
.suggestion-highlight {
|
||||
@apply bg-blue-100 hover:bg-blue-200 dark:hover:bg-blue-400/50 dark:text-blue-50 dark:bg-blue-400/40;
|
||||
@apply bg-blue-200 hover:bg-blue-300 dark:hover:bg-blue-400/50 dark:text-blue-50 dark:bg-blue-500/40;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import { MultimodalInput } from './multimodal-input';
|
|||
import { Toolbar } from './toolbar';
|
||||
import { useScrollToBottom } from './use-scroll-to-bottom';
|
||||
import { VersionFooter } from './version-footer';
|
||||
import { Button } from '../ui/button';
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';
|
||||
export interface UICanvas {
|
||||
title: string;
|
||||
|
|
@ -254,10 +255,10 @@ export function Canvas({
|
|||
{!isMobile && (
|
||||
<motion.div
|
||||
className="relative w-[400px] bg-muted dark:bg-background h-dvh shrink-0"
|
||||
initial={{ opacity: 0, x: windowWidth - 420, scale: 1 }}
|
||||
initial={{ opacity: 0, x: 10, scale: 1 }}
|
||||
animate={{
|
||||
opacity: 1,
|
||||
x: windowWidth - 400,
|
||||
x: 0,
|
||||
scale: 1,
|
||||
transition: {
|
||||
delay: 0.2,
|
||||
|
|
@ -268,7 +269,7 @@ export function Canvas({
|
|||
}}
|
||||
exit={{
|
||||
opacity: 0,
|
||||
x: windowWidth - 420,
|
||||
x: 0,
|
||||
scale: 0.95,
|
||||
transition: { delay: 0 },
|
||||
}}
|
||||
|
|
@ -370,7 +371,7 @@ export function Canvas({
|
|||
}
|
||||
: {
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
x: 400,
|
||||
y: 0,
|
||||
height: windowHeight,
|
||||
width: windowWidth ? windowWidth - 400 : 'calc(100dvw-400px)',
|
||||
|
|
@ -396,8 +397,9 @@ export function Canvas({
|
|||
>
|
||||
<div className="p-2 flex flex-row justify-between items-start">
|
||||
<div className="flex flex-row gap-4 items-start">
|
||||
<div
|
||||
className="cursor-pointer hover:bg-muted dark:hover:bg-zinc-700 p-2 rounded-lg text-muted-foreground"
|
||||
<Button
|
||||
variant="outline"
|
||||
className="h-fit p-2 dark:hover:bg-zinc-700"
|
||||
onClick={() => {
|
||||
setCanvas((currentCanvas) => ({
|
||||
...currentCanvas,
|
||||
|
|
@ -406,9 +408,9 @@ export function Canvas({
|
|||
}}
|
||||
>
|
||||
<CrossIcon size={18} />
|
||||
</div>
|
||||
</Button>
|
||||
|
||||
<div className="flex flex-col pt-1">
|
||||
<div className="flex flex-col">
|
||||
<div className="font-medium">
|
||||
{document?.title ?? canvas.title}
|
||||
</div>
|
||||
|
|
@ -433,58 +435,63 @@ export function Canvas({
|
|||
|
||||
<div className="flex flex-row gap-1">
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<div
|
||||
className="cursor-pointer hover:bg-muted p-2 rounded-lg text-muted-foreground dark:hover:bg-zinc-700"
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="p-2 h-fit dark:hover:bg-zinc-700"
|
||||
onClick={() => {
|
||||
copyToClipboard(canvas.content);
|
||||
toast.success('Copied to clipboard!');
|
||||
}}
|
||||
>
|
||||
<CopyIcon size={18} />
|
||||
</div>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Copy to clipboard</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<div
|
||||
className="cursor-pointer hover:bg-muted p-2 rounded-lg text-muted-foreground dark:hover:bg-zinc-700"
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="p-2 h-fit dark:hover:bg-zinc-700 !pointer-events-auto"
|
||||
onClick={() => {
|
||||
handleVersionChange('prev');
|
||||
}}
|
||||
disabled={currentVersionIndex === 0}
|
||||
>
|
||||
<UndoIcon size={18} />
|
||||
</div>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>View Previous version</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<div
|
||||
className="cursor-pointer hover:bg-muted p-2 rounded-lg text-muted-foreground dark:hover:bg-zinc-700"
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="p-2 h-fit dark:hover:bg-zinc-700 !pointer-events-auto"
|
||||
onClick={() => {
|
||||
handleVersionChange('next');
|
||||
}}
|
||||
disabled={isCurrentVersion}
|
||||
>
|
||||
<RedoIcon size={18} />
|
||||
</div>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>View Next version</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<div
|
||||
className={cx(
|
||||
'cursor-pointer hover:bg-muted p-2 rounded-lg text-muted-foreground dark:hover:bg-zinc-700',
|
||||
{ 'bg-muted dark:bg-zinc-700': mode === 'diff' }
|
||||
)}
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className={cx('p-2 h-fit dark:hover:bg-zinc-700', {
|
||||
'bg-muted': mode === 'diff',
|
||||
})}
|
||||
onClick={() => {
|
||||
handleVersionChange('toggle');
|
||||
}}
|
||||
>
|
||||
<DeltaIcon size={18} />
|
||||
</div>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>View changes</TooltipContent>
|
||||
</Tooltip>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export function ChatHeader({ selectedModelId }: { selectedModelId: string }) {
|
|||
className="order-1 md:order-2"
|
||||
/>
|
||||
<Button
|
||||
className="hidden md:flex py-1.5 px-2 h-fit md:h-[34px] order-4 md:ml-auto"
|
||||
className="bg-zinc-900 dark:bg-zinc-100 hover:bg-zinc-800 dark:hover:bg-zinc-200 text-zinc-50 dark:text-zinc-900 hidden md:flex py-1.5 px-2 h-fit md:h-[34px] order-4 md:ml-auto"
|
||||
asChild
|
||||
>
|
||||
<Link
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export function DocumentToolResult({
|
|||
}: DocumentToolResultProps) {
|
||||
return (
|
||||
<div
|
||||
className="cursor-pointer border py-2 px-3 rounded-xl w-fit flex flex-row gap-3 items-start"
|
||||
className="bg-background cursor-pointer border py-2 px-3 rounded-xl w-fit flex flex-row gap-3 items-start"
|
||||
onClick={(event) => {
|
||||
const rect = event.currentTarget.getBoundingClientRect();
|
||||
|
||||
|
|
|
|||
|
|
@ -836,3 +836,22 @@ export const SparklesIcon = ({ size = 16 }: { size?: number }) => (
|
|||
></path>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const CheckCirclFillIcon = ({ size = 16 }: { size?: number }) => {
|
||||
return (
|
||||
<svg
|
||||
height={size}
|
||||
strokeLinejoin="round"
|
||||
viewBox="0 0 16 16"
|
||||
width={size}
|
||||
style={{ color: 'currentcolor' }}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8ZM11.5303 6.53033L12.0607 6L11 4.93934L10.4697 5.46967L6.5 9.43934L5.53033 8.46967L5 7.93934L3.93934 9L4.46967 9.53033L5.96967 11.0303C6.26256 11.3232 6.73744 11.3232 7.03033 11.0303L11.5303 6.53033Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -32,19 +32,14 @@ export const PreviewMessage = ({
|
|||
}) => {
|
||||
return (
|
||||
<motion.div
|
||||
className="w-full mx-auto max-w-3xl px-4 group/message "
|
||||
className="w-full mx-auto max-w-3xl px-4 group/message"
|
||||
initial={{ y: 5, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
data-role={message.role}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
'flex gap-4 group-data-[role=user]/message:px-3 w-full group-data-[role=user]/message:w-fit group-data-[role=user]/message:ml-auto group-data-[role=user]/message:max-w-2xl group-data-[role=user]/message:py-2 rounded-xl',
|
||||
{
|
||||
'group-data-[role=user]/message:bg-muted': !canvas,
|
||||
'group-data-[role=user]/message:bg-zinc-300 dark:group-data-[role=user]/message:bg-zinc-800':
|
||||
canvas,
|
||||
}
|
||||
'group-data-[role=user]/message:bg-primary group-data-[role=user]/message:text-primary-foreground flex gap-4 group-data-[role=user]/message:px-3 w-full group-data-[role=user]/message:w-fit group-data-[role=user]/message:ml-auto group-data-[role=user]/message:max-w-2xl group-data-[role=user]/message:py-2 rounded-xl'
|
||||
)}
|
||||
>
|
||||
{message.role === 'assistant' && (
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
'use client';
|
||||
|
||||
import { Check, ChevronDown } from 'lucide-react';
|
||||
import { startTransition, useMemo, useOptimistic, useState } from 'react';
|
||||
|
||||
import { models } from '@/ai/models';
|
||||
|
|
@ -14,7 +13,7 @@ import {
|
|||
} from '@/components/ui/dropdown-menu';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
import { ChevronDownIcon } from './icons';
|
||||
import { CheckCirclFillIcon, ChevronDownIcon } from './icons';
|
||||
|
||||
export function ModelSelector({
|
||||
selectedModelId,
|
||||
|
|
@ -57,7 +56,7 @@ export function ModelSelector({
|
|||
saveModelId(model.id);
|
||||
});
|
||||
}}
|
||||
className="gap-4 group/item"
|
||||
className="gap-4 group/item flex flex-row justify-between items-center"
|
||||
data-active={model.id === optimisticModelId}
|
||||
>
|
||||
<div className="flex flex-col gap-1 items-start">
|
||||
|
|
@ -68,7 +67,9 @@ export function ModelSelector({
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Check className="size-4 ml-auto opacity-0 group-data-[active=true]/item:opacity-100" />
|
||||
<div className="text-primary dark:text-primary-foreground opacity-0 group-data-[active=true]/item:opacity-100">
|
||||
<CheckCirclFillIcon />
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ const suggestedActions = [
|
|||
{
|
||||
title: 'Help me draft an essay',
|
||||
label: 'about Silicon Valley',
|
||||
action: 'Help me draft an essay about Silicon Valley',
|
||||
action: 'Help me draft a short essay about Silicon Valley',
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -283,7 +283,7 @@ export function MultimodalInput({
|
|||
|
||||
{isLoading ? (
|
||||
<Button
|
||||
className="rounded-full p-1.5 h-fit absolute bottom-2 right-2 m-0.5"
|
||||
className="rounded-full p-1.5 h-fit absolute bottom-2 right-2 m-0.5 border dark:border-zinc-600"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
stop();
|
||||
|
|
@ -294,7 +294,7 @@ export function MultimodalInput({
|
|||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
className="rounded-full p-1.5 h-fit absolute bottom-2 right-2 m-0.5"
|
||||
className="rounded-full p-1.5 h-fit absolute bottom-2 right-2 m-0.5 border dark:border-zinc-600"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
submitForm();
|
||||
|
|
@ -306,7 +306,7 @@ export function MultimodalInput({
|
|||
)}
|
||||
|
||||
<Button
|
||||
className="rounded-full p-1.5 h-fit absolute bottom-2 right-10 m-0.5 dark:border-zinc-700"
|
||||
className="rounded-full p-1.5 h-fit absolute bottom-2 right-11 m-0.5 dark:border-zinc-700"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
fileInputRef.current?.click();
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import {
|
|||
StopIcon,
|
||||
SummarizeIcon,
|
||||
} from './icons';
|
||||
import { Button } from '../ui/button';
|
||||
|
||||
type ToolProps = {
|
||||
type: 'final-polish' | 'request-suggestions' | 'adjust-reading-level';
|
||||
|
|
@ -61,29 +62,7 @@ const Tool = ({
|
|||
}
|
||||
}, [selectedTool, type]);
|
||||
|
||||
return (
|
||||
<Tooltip open={isHovered && !isAnimating}>
|
||||
<TooltipTrigger>
|
||||
<motion.div
|
||||
className={cx('p-3 rounded-full', {
|
||||
'bg-foreground !text-background': selectedTool === type,
|
||||
})}
|
||||
onHoverStart={() => {
|
||||
setIsHovered(true);
|
||||
}}
|
||||
onHoverEnd={() => {
|
||||
if (selectedTool !== type) setIsHovered(false);
|
||||
}}
|
||||
initial={{ scale: 1, opacity: 0 }}
|
||||
animate={{ opacity: 1, transition: { delay: 0.1 } }}
|
||||
whileHover={{ scale: 1.1 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
exit={{
|
||||
scale: 0.9,
|
||||
opacity: 0,
|
||||
transition: { duration: 0.1 },
|
||||
}}
|
||||
onClick={() => {
|
||||
const handleSelect = () => {
|
||||
if (!isToolbarVisible && setIsToolbarVisible) {
|
||||
setIsToolbarVisible(true);
|
||||
return;
|
||||
|
|
@ -116,6 +95,37 @@ const Tool = ({
|
|||
setSelectedTool(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Tooltip open={isHovered && !isAnimating}>
|
||||
<TooltipTrigger asChild>
|
||||
<motion.div
|
||||
className={cx('p-3 rounded-full', {
|
||||
'bg-primary !text-primary-foreground': selectedTool === type,
|
||||
})}
|
||||
onHoverStart={() => {
|
||||
setIsHovered(true);
|
||||
}}
|
||||
onHoverEnd={() => {
|
||||
if (selectedTool !== type) setIsHovered(false);
|
||||
}}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
handleSelect();
|
||||
}
|
||||
}}
|
||||
initial={{ scale: 1, opacity: 0 }}
|
||||
animate={{ opacity: 1, transition: { delay: 0.1 } }}
|
||||
whileHover={{ scale: 1.1 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
exit={{
|
||||
scale: 0.9,
|
||||
opacity: 0,
|
||||
transition: { duration: 0.1 },
|
||||
}}
|
||||
onClick={() => {
|
||||
handleSelect();
|
||||
}}
|
||||
>
|
||||
{selectedTool === type ? <ArrowUpIcon /> : icon}
|
||||
|
|
@ -192,7 +202,7 @@ const ReadingLevelSelector = ({
|
|||
className={cx(
|
||||
'absolute bg-background p-3 border rounded-full flex flex-row items-center',
|
||||
{
|
||||
'bg-foreground text-background': currentLevel !== 2,
|
||||
'bg-primary text-primary-foreground': currentLevel !== 2,
|
||||
'bg-background text-foreground': currentLevel === 2,
|
||||
}
|
||||
)}
|
||||
|
|
@ -241,37 +251,31 @@ const ReadingLevelSelector = ({
|
|||
);
|
||||
};
|
||||
|
||||
export const Toolbar = ({
|
||||
export const Tools = ({
|
||||
isToolbarVisible,
|
||||
setIsToolbarVisible,
|
||||
selectedTool,
|
||||
setSelectedTool,
|
||||
append,
|
||||
isLoading,
|
||||
stop,
|
||||
setMessages,
|
||||
isAnimating,
|
||||
setIsToolbarVisible,
|
||||
}: {
|
||||
isToolbarVisible: boolean;
|
||||
setIsToolbarVisible: Dispatch<SetStateAction<boolean>>;
|
||||
isLoading: boolean;
|
||||
selectedTool: string | null;
|
||||
setSelectedTool: Dispatch<SetStateAction<string | null>>;
|
||||
append: (
|
||||
message: Message | CreateMessage,
|
||||
chatRequestOptions?: ChatRequestOptions
|
||||
) => Promise<string | null | undefined>;
|
||||
stop: () => void;
|
||||
setMessages: Dispatch<SetStateAction<Message[]>>;
|
||||
isAnimating: boolean;
|
||||
setIsToolbarVisible: Dispatch<SetStateAction<boolean>>;
|
||||
}) => {
|
||||
const toolbarRef = useRef<HTMLDivElement>(null);
|
||||
const timeoutRef = useRef<NodeJS.Timeout>();
|
||||
|
||||
const [selectedTool, setSelectedTool] = useState<string | null>(null);
|
||||
const [isAnimating, setIsAnimating] = useState(false);
|
||||
|
||||
useOnClickOutside(toolbarRef, () => {
|
||||
setIsToolbarVisible(false);
|
||||
setSelectedTool(null);
|
||||
});
|
||||
|
||||
const Tools = (
|
||||
<>
|
||||
return (
|
||||
<motion.div
|
||||
className="flex flex-col"
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.95 }}
|
||||
>
|
||||
<AnimatePresence>
|
||||
{isToolbarVisible && (
|
||||
<>
|
||||
|
|
@ -309,8 +313,38 @@ export const Toolbar = ({
|
|||
append={append}
|
||||
isAnimating={isAnimating}
|
||||
/>
|
||||
</>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Toolbar = ({
|
||||
isToolbarVisible,
|
||||
setIsToolbarVisible,
|
||||
append,
|
||||
isLoading,
|
||||
stop,
|
||||
setMessages,
|
||||
}: {
|
||||
isToolbarVisible: boolean;
|
||||
setIsToolbarVisible: Dispatch<SetStateAction<boolean>>;
|
||||
isLoading: boolean;
|
||||
append: (
|
||||
message: Message | CreateMessage,
|
||||
chatRequestOptions?: ChatRequestOptions
|
||||
) => Promise<string | null | undefined>;
|
||||
stop: () => void;
|
||||
setMessages: Dispatch<SetStateAction<Message[]>>;
|
||||
}) => {
|
||||
const toolbarRef = useRef<HTMLDivElement>(null);
|
||||
const timeoutRef = useRef<NodeJS.Timeout>();
|
||||
|
||||
const [selectedTool, setSelectedTool] = useState<string | null>(null);
|
||||
const [isAnimating, setIsAnimating] = useState(false);
|
||||
|
||||
useOnClickOutside(toolbarRef, () => {
|
||||
setIsToolbarVisible(false);
|
||||
setSelectedTool(null);
|
||||
});
|
||||
|
||||
const startCloseTimer = () => {
|
||||
if (timeoutRef.current) {
|
||||
|
|
@ -389,7 +423,11 @@ export const Toolbar = ({
|
|||
ref={toolbarRef}
|
||||
>
|
||||
{isLoading ? (
|
||||
<div
|
||||
<motion.div
|
||||
key="stop-icon"
|
||||
initial={{ scale: 1 }}
|
||||
animate={{ scale: 1.4 }}
|
||||
exit={{ scale: 1 }}
|
||||
className="p-3"
|
||||
onClick={() => {
|
||||
stop();
|
||||
|
|
@ -397,15 +435,24 @@ export const Toolbar = ({
|
|||
}}
|
||||
>
|
||||
<StopIcon />
|
||||
</div>
|
||||
</motion.div>
|
||||
) : selectedTool === 'adjust-reading-level' ? (
|
||||
<ReadingLevelSelector
|
||||
key="reading-level-selector"
|
||||
append={append}
|
||||
setSelectedTool={setSelectedTool}
|
||||
isAnimating={isAnimating}
|
||||
/>
|
||||
) : (
|
||||
Tools
|
||||
<Tools
|
||||
key="tools"
|
||||
append={append}
|
||||
isAnimating={isAnimating}
|
||||
isToolbarVisible={isToolbarVisible}
|
||||
selectedTool={selectedTool}
|
||||
setIsToolbarVisible={setIsToolbarVisible}
|
||||
setSelectedTool={setSelectedTool}
|
||||
/>
|
||||
)}
|
||||
</motion.div>
|
||||
</TooltipProvider>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue