diff --git a/apps/web/package.json b/apps/web/package.json index e6ce41bb..db88f2dc 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -85,6 +85,7 @@ "lodash": "^4.17.21", "lucide-react": "^0.474.0", "next": "14.2.25", + "next-themes": "^0.4.6", "nuqs": "^2.4.1", "pdf-parse": "^1.1.1", "react": "^18", diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index 16d270ee..8bb41da6 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -3,6 +3,7 @@ import "./globals.css"; import { Inter } from "next/font/google"; import { cn } from "@/lib/utils"; import { NuqsAdapter } from "nuqs/adapters/next/app"; +import { ThemeProvider } from "@/components/ui/theme-providers"; const inter = Inter({ subsets: ["latin"], @@ -19,9 +20,16 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - + - {children} + + {children} + ); diff --git a/apps/web/src/components/artifacts/CodeRenderer.tsx b/apps/web/src/components/artifacts/CodeRenderer.tsx index f0220d33..9dba102b 100644 --- a/apps/web/src/components/artifacts/CodeRenderer.tsx +++ b/apps/web/src/components/artifacts/CodeRenderer.tsx @@ -19,6 +19,7 @@ import { cn } from "@/lib/utils"; import { CopyText } from "./components/CopyText"; import { getArtifactContent } from "@opencanvas/shared/utils/artifacts"; import { useGraphContext } from "@/contexts/GraphContext"; +import { useTheme } from "next-themes"; export interface CodeRendererProps { editorRef: MutableRefObject; @@ -60,6 +61,7 @@ const getLanguageExtension = (language: string) => { export function CodeRendererComponent(props: Readonly) { const { graphData } = useGraphContext(); + const { resolvedTheme } = useTheme(); const { artifact, isStreaming, @@ -112,6 +114,7 @@ export function CodeRendererComponent(props: Readonly) { )} { return text.replaceAll("\\\n", "\n"); @@ -44,9 +45,9 @@ function ViewRawText({ onClick={() => setIsRawView((p) => !p)} > {isRawView ? ( - + ) : ( - + )} @@ -73,6 +74,7 @@ export function TextRendererComponent(props: TextRendererProps) { } = graphData; const [rawMarkdown, setRawMarkdown] = useState(""); + const { resolvedTheme } = useTheme(); const [isRawView, setIsRawView] = useState(false); const [manuallyUpdatingArtifact, setManuallyUpdatingArtifact] = useState(false); @@ -278,7 +280,7 @@ export function TextRendererComponent(props: TextRendererProps) { } `} (isComposition.current = true)} diff --git a/apps/web/src/components/artifacts/actions_toolbar/code/index.tsx b/apps/web/src/components/artifacts/actions_toolbar/code/index.tsx index 574d79d5..950d4ae9 100644 --- a/apps/web/src/components/artifacts/actions_toolbar/code/index.tsx +++ b/apps/web/src/components/artifacts/actions_toolbar/code/index.tsx @@ -157,7 +157,7 @@ export function CodeToolBar(props: CodeToolbarProps) { } variant="outline" className={cn( - "transition-colors w-[48px] h-[48px] p-0 rounded-xl", + "transition-colors w-[48px] h-[48px] p-0 rounded-xl dark:text-gray-300", props.isTextSelected ? "cursor-default opacity-50 text-gray-400 hover:bg-background" : "cursor-pointer" @@ -169,7 +169,7 @@ export function CodeToolBar(props: CodeToolbarProps) { "w-[26px] h-[26px]", props.isTextSelected ? "text-gray-400" - : "hover:text-gray-900 transition-colors" + : "hover:text-gray-900 dark:hover:text-gray-400 transition-colors" )} /> diff --git a/apps/web/src/components/artifacts/actions_toolbar/custom/index.tsx b/apps/web/src/components/artifacts/actions_toolbar/custom/index.tsx index 3fdabd76..4533a5cf 100644 --- a/apps/web/src/components/artifacts/actions_toolbar/custom/index.tsx +++ b/apps/web/src/components/artifacts/actions_toolbar/custom/index.tsx @@ -193,10 +193,10 @@ export function CustomQuickActions(props: CustomQuickActionsProps) { > diff --git a/apps/web/src/components/artifacts/actions_toolbar/text/index.tsx b/apps/web/src/components/artifacts/actions_toolbar/text/index.tsx index 1e277747..c7aa644c 100644 --- a/apps/web/src/components/artifacts/actions_toolbar/text/index.tsx +++ b/apps/web/src/components/artifacts/actions_toolbar/text/index.tsx @@ -109,7 +109,7 @@ export function ActionsToolbar(props: ActionsToolbarProps) {
diff --git a/apps/web/src/components/artifacts/components/CopyText.tsx b/apps/web/src/components/artifacts/components/CopyText.tsx index e27022e5..c9e3a5fa 100644 --- a/apps/web/src/components/artifacts/components/CopyText.tsx +++ b/apps/web/src/components/artifacts/components/CopyText.tsx @@ -46,7 +46,7 @@ export function CopyText(props: CopyTextProps) { } }} > - + ); diff --git a/apps/web/src/components/artifacts/header/artifact-title.tsx b/apps/web/src/components/artifacts/header/artifact-title.tsx index 2703affa..f4c45cef 100644 --- a/apps/web/src/components/artifacts/header/artifact-title.tsx +++ b/apps/web/src/components/artifacts/header/artifact-title.tsx @@ -9,7 +9,7 @@ interface ArtifactTitleProps { export function ArtifactTitle(props: ArtifactTitleProps) { return (
-

+

{props.title}

diff --git a/apps/web/src/components/artifacts/header/index.tsx b/apps/web/src/components/artifacts/header/index.tsx index 2fae7e1e..4e43ad12 100644 --- a/apps/web/src/components/artifacts/header/index.tsx +++ b/apps/web/src/components/artifacts/header/index.tsx @@ -31,7 +31,7 @@ export function ArtifactHeader(props: ArtifactHeaderProps) { delayDuration={400} onClick={() => props.setChatCollapsed(false)} > - + )}
diff --git a/apps/web/src/components/assistant-ui/attachment.tsx b/apps/web/src/components/assistant-ui/attachment.tsx index b236c608..db8ceeb0 100644 --- a/apps/web/src/components/assistant-ui/attachment.tsx +++ b/apps/web/src/components/assistant-ui/attachment.tsx @@ -205,7 +205,7 @@ export const ComposerAddAttachment: FC<{ className?: string }> = ({ tooltip="Add Attachment" variant="ghost" > - + ); diff --git a/apps/web/src/components/canvas/canvas.tsx b/apps/web/src/components/canvas/canvas.tsx index 237c0fac..3885e3e6 100644 --- a/apps/web/src/components/canvas/canvas.tsx +++ b/apps/web/src/components/canvas/canvas.tsx @@ -146,7 +146,7 @@ export function CanvasComponent() { defaultSize={25} minSize={15} maxSize={50} - className="transition-all duration-700 h-screen mr-auto bg-gray-50/70 shadow-inner-right" + className="transition-all duration-700 h-screen mr-auto bg-gray-50/70 dark:bg-gray-950 shadow-inner-right" id="chat-panel-main" order={1} > diff --git a/apps/web/src/components/chat-interface/composer-actions-popout.tsx b/apps/web/src/components/chat-interface/composer-actions-popout.tsx index 8fa17434..9930011a 100644 --- a/apps/web/src/components/chat-interface/composer-actions-popout.tsx +++ b/apps/web/src/components/chat-interface/composer-actions-popout.tsx @@ -83,7 +83,7 @@ export function ComposerActionsPopOut(props: ComposerActionsPopOutProps) { }} > {searchEnabled && ( setSearchEnabled((p) => !p)} > - + )} {!isDefaultSelected && ( @@ -136,7 +136,7 @@ export function ComposerActionsPopOut(props: ComposerActionsPopOutProps) { className="size-7 flex-shrink-0 hover:bg-blue-100 transition-colors ease-in-out" onClick={() => setSearchEnabled((p) => !p)} > - + )} {isDefaultSelected && ( diff --git a/apps/web/src/components/chat-interface/composer.tsx b/apps/web/src/components/chat-interface/composer.tsx index 3e0db2dc..9ac825ba 100644 --- a/apps/web/src/components/chat-interface/composer.tsx +++ b/apps/web/src/components/chat-interface/composer.tsx @@ -74,7 +74,7 @@ export const Composer: FC = (props: ComposerProps) => { return ( - +
diff --git a/apps/web/src/components/chat-interface/model-selector/index.tsx b/apps/web/src/components/chat-interface/model-selector/index.tsx index 609482ea..9d3ae1a6 100644 --- a/apps/web/src/components/chat-interface/model-selector/index.tsx +++ b/apps/web/src/components/chat-interface/model-selector/index.tsx @@ -99,13 +99,13 @@ function CommandModelItem({ /> ) : ( )} @@ -223,7 +223,7 @@ export default function ModelSelector({ return (
@@ -232,7 +232,7 @@ export default function ModelSelector({ src={LLMIcon} width={14} height={14} - className="mr-2" + className="mr-2 " /> {selectedModelLabel} diff --git a/apps/web/src/components/chat-interface/thread-history.tsx b/apps/web/src/components/chat-interface/thread-history.tsx index 1b7f46a1..3d490622 100644 --- a/apps/web/src/components/chat-interface/thread-history.tsx +++ b/apps/web/src/components/chat-interface/thread-history.tsx @@ -254,7 +254,7 @@ export function ThreadHistoryComponent(props: ThreadHistoryProps) { aria-describedby={undefined} > - + Chat History diff --git a/apps/web/src/components/chat-interface/thread.tsx b/apps/web/src/components/chat-interface/thread.tsx index 539a4748..e8c7c0d1 100644 --- a/apps/web/src/components/chat-interface/thread.tsx +++ b/apps/web/src/components/chat-interface/thread.tsx @@ -17,6 +17,7 @@ import { ThreadWelcome } from "./welcome"; import { useUserContext } from "@/contexts/UserContext"; import { useThreadContext } from "@/contexts/ThreadProvider"; import { useAssistantContext } from "@/contexts/AssistantContext"; +import { ModeToggle } from "../ui/toggle-theme"; const ThreadScrollToBottom: FC = () => { return ( @@ -93,11 +94,13 @@ export const Thread: FC = (props: ThreadProps) => { return (
-
+
- Open Canvas + + Open Canvas + {!hasChatStarted && ( = (props: ThreadProps) => { /> )}
- {hasChatStarted ? ( -
- props.setChatCollapsed(true)} - > - - - - - -
- ) : ( -
- -
- )} +
+ + {hasChatStarted ? ( +
+ props.setChatCollapsed(true)} + > + + + + + +
+ ) : ( +
+ +
+ )} +
{!hasChatStarted && ( diff --git a/apps/web/src/components/chat-interface/welcome.tsx b/apps/web/src/components/chat-interface/welcome.tsx index f4b2f316..bf3eb067 100644 --- a/apps/web/src/components/chat-interface/welcome.tsx +++ b/apps/web/src/components/chat-interface/welcome.tsx @@ -80,7 +80,7 @@ const QuickStartPrompts = ({ searchEnabled }: QuickStartPromptsProps) => { key={`quick-start-prompt-${index}`} onClick={() => handleClick(prompt)} variant="outline" - className="min-h-[60px] w-full flex items-center justify-center p-6 whitespace-normal text-gray-500 hover:text-gray-700 transition-colors ease-in rounded-2xl" + className="min-h-[60px] w-full flex items-center justify-center p-6 whitespace-normal text-gray-500 dark:text-gray-300 hover:text-gray-700 transition-colors ease-in rounded-2xl" >

{prompt} @@ -100,11 +100,13 @@ const QuickStartButtons = (props: QuickStartButtonsProps) => { return (

-

Start with a blank canvas

+

+ Start with a blank canvas +

-

or with a message

+

+ or with a message +

{props.composer}
diff --git a/apps/web/src/components/reflections-dialog/ReflectionsDialog.tsx b/apps/web/src/components/reflections-dialog/ReflectionsDialog.tsx index afadea76..5d653ccf 100644 --- a/apps/web/src/components/reflections-dialog/ReflectionsDialog.tsx +++ b/apps/web/src/components/reflections-dialog/ReflectionsDialog.tsx @@ -107,7 +107,7 @@ export function ReflectionsDialog(props: ReflectionsDialogProps) { className="w-fit h-fit p-2" onClick={() => setOpen(true)} > - + diff --git a/apps/web/src/components/ui/programming-lang-dropdown.tsx b/apps/web/src/components/ui/programming-lang-dropdown.tsx index 6a176b89..94951f92 100644 --- a/apps/web/src/components/ui/programming-lang-dropdown.tsx +++ b/apps/web/src/components/ui/programming-lang-dropdown.tsx @@ -116,7 +116,7 @@ export const ProgrammingLanguagesDropdown = ({ + + + setTheme("light")}> + Light + + setTheme("dark")}> + Dark + + setTheme("system")}> + System + + + + ); +} diff --git a/yarn.lock b/yarn.lock index 79e86540..d0eca191 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7602,6 +7602,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +next-themes@^0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.4.6.tgz#8d7e92d03b8fea6582892a50a928c9b23502e8b6" + integrity sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA== + next@14.2.25: version "14.2.25" resolved "https://registry.yarnpkg.com/next/-/next-14.2.25.tgz#0657551fde6a97f697cf9870e9ccbdaa465c6008"