From 4b59a79baadaab17bed42de9c01381912375e995 Mon Sep 17 00:00:00 2001 From: Dominic Elm Date: Thu, 8 Aug 2024 15:56:36 +0200 Subject: [PATCH] feat: implement light and dark theme (#30) --- .../bolt/app/components/chat/Artifact.tsx | 101 ++++--- .../bolt/app/components/chat/BaseChat.tsx | 42 +-- .../bolt/app/components/chat/Chat.client.tsx | 38 ++- .../app/components/chat/Markdown.module.scss | 61 ++-- .../app/components/chat/Messages.client.tsx | 44 ++- .../app/components/chat/SendButton.client.tsx | 2 +- .../bolt/app/components/chat/UserMessage.tsx | 2 +- .../editor/codemirror/CodeMirrorEditor.tsx | 1 + .../components/editor/codemirror/cm-theme.ts | 40 ++- .../editor/codemirror/themes/vscode-dark.ts | 76 ----- .../bolt/app/components/header/Header.tsx | 17 +- .../app/components/sidebar/HistoryItem.tsx | 10 +- .../app/components/sidebar/Menu.client.tsx | 39 +-- .../bolt/app/components/ui/IconButton.tsx | 5 +- .../bolt/app/components/ui/PanelHeader.tsx | 7 +- .../app/components/ui/PanelHeaderButton.tsx | 2 +- packages/bolt/app/components/ui/Slider.tsx | 10 +- .../bolt/app/components/ui/ThemeSwitch.tsx | 29 ++ .../app/components/workbench/EditorPanel.tsx | 83 +++--- .../app/components/workbench/FileTree.tsx | 27 +- .../bolt/app/components/workbench/Preview.tsx | 10 +- .../components/workbench/Workbench.client.tsx | 18 +- .../workbench/terminal/Terminal.tsx | 2 +- packages/bolt/app/root.tsx | 2 +- packages/bolt/app/styles/components/code.scss | 9 + .../components/editor.scss} | 88 +++--- .../bolt/app/styles/components/toast.scss | 17 ++ packages/bolt/app/styles/index.scss | 3 + packages/bolt/app/styles/variables.scss | 180 +++++++++--- packages/bolt/app/styles/z-index.scss | 8 + packages/bolt/icons/logo-text.svg | 1 + packages/bolt/package.json | 1 + packages/bolt/public/logo_text.svg | 1 - packages/bolt/uno.config.ts | 275 +++++++++++++----- pnpm-lock.yaml | 27 ++ 35 files changed, 799 insertions(+), 479 deletions(-) delete mode 100644 packages/bolt/app/components/editor/codemirror/themes/vscode-dark.ts create mode 100644 packages/bolt/app/components/ui/ThemeSwitch.tsx create mode 100644 packages/bolt/app/styles/components/code.scss rename packages/bolt/app/{components/editor/codemirror/styles.css => styles/components/editor.scss} (57%) create mode 100644 packages/bolt/app/styles/components/toast.scss create mode 100644 packages/bolt/icons/logo-text.svg delete mode 100644 packages/bolt/public/logo_text.svg diff --git a/packages/bolt/app/components/chat/Artifact.tsx b/packages/bolt/app/components/chat/Artifact.tsx index c7fda83..9de52dd 100644 --- a/packages/bolt/app/components/chat/Artifact.tsx +++ b/packages/bolt/app/components/chat/Artifact.tsx @@ -4,7 +4,6 @@ import { computed } from 'nanostores'; import { memo, useEffect, useRef, useState } from 'react'; import { createHighlighter, type BundledLanguage, type BundledTheme, type HighlighterGeneric } from 'shiki'; import type { ActionState } from '~/lib/runtime/action-runner'; -import { chatStore } from '~/lib/stores/chat'; import { workbenchStore } from '~/lib/stores/workbench'; import { classNames } from '~/utils/classNames'; import { cubicEasingFn } from '~/utils/easings'; @@ -29,7 +28,6 @@ export const Artifact = memo(({ messageId }: ArtifactProps) => { const userToggledActions = useRef(false); const [showActions, setShowActions] = useState(false); - const chat = useStore(chatStore); const artifacts = useStore(workbenchStore.artifacts); const artifact = artifacts[messageId]; @@ -51,27 +49,21 @@ export const Artifact = memo(({ messageId }: ArtifactProps) => { }, [actions]); return ( -
+
+
{actions.length && ( { animate={{ width: 'auto' }} exit={{ width: 0 }} transition={{ duration: 0.15, ease: cubicEasingFn }} - className="hover:bg-gray-200" + className="bg-bolt-elements-artifacts-background hover:bg-bolt-elements-artifacts-backgroundHover" onClick={toggleActions} >
@@ -98,7 +90,8 @@ export const Artifact = memo(({ messageId }: ArtifactProps) => { exit={{ height: '0px' }} transition={{ duration: 0.15 }} > -
+
+
@@ -108,29 +101,6 @@ export const Artifact = memo(({ messageId }: ArtifactProps) => { ); }); -function getTextColor(status: ActionState['status']) { - switch (status) { - case 'pending': { - return 'text-gray-500'; - } - case 'running': { - return 'text-gray-1000'; - } - case 'complete': { - return 'text-positive-600'; - } - case 'aborted': { - return 'text-gray-600'; - } - case 'failed': { - return 'text-negative-600'; - } - default: { - return undefined; - } - } -} - interface ShellCodeBlockProps { classsName?: string; code: string; @@ -140,7 +110,12 @@ function ShellCodeBlock({ classsName, code }: ShellCodeBlockProps) { return (
); } @@ -160,6 +135,7 @@ const ActionList = memo(({ actions }: ActionListProps) => {
    {actions.map((action, index) => { const { status, type, content } = action; + const isLast = index === actions.length - 1; return ( { ease: cubicEasingFn, }} > -
    -
    +
    +
    {status === 'running' ? (
    ) : status === 'pending' ? (
    ) : status === 'complete' ? ( -
    +
    ) : status === 'failed' || status === 'aborted' ? ( -
    +
    ) : null}
    {type === 'file' ? (
    - Create {action.filePath} + Create{' '} + + {action.filePath} +
    ) : type === 'shell' ? (
    @@ -194,7 +173,14 @@ const ActionList = memo(({ actions }: ActionListProps) => {
    ) : null}
    - {type === 'shell' && } + {type === 'shell' && ( + + )} ); })} @@ -202,3 +188,26 @@ const ActionList = memo(({ actions }: ActionListProps) => { ); }); + +function getIconColor(status: ActionState['status']) { + switch (status) { + case 'pending': { + return 'text-bolt-elements-textTertiary'; + } + case 'running': { + return 'text-bolt-elements-loader-progress'; + } + case 'complete': { + return 'text-bolt-elements-icon-success'; + } + case 'aborted': { + return 'text-bolt-elements-textSecondary'; + } + case 'failed': { + return 'text-bolt-elements-icon-error'; + } + default: { + return undefined; + } + } +} diff --git a/packages/bolt/app/components/chat/BaseChat.tsx b/packages/bolt/app/components/chat/BaseChat.tsx index 5bbb77e..c732065 100644 --- a/packages/bolt/app/components/chat/BaseChat.tsx +++ b/packages/bolt/app/components/chat/BaseChat.tsx @@ -32,7 +32,7 @@ const EXAMPLE_PROMPTS = [ { text: 'How do I center a div?' }, ]; -const TEXTAREA_MIN_HEIGHT = 72; +const TEXTAREA_MIN_HEIGHT = 76; export const BaseChat = React.forwardRef( ( @@ -56,14 +56,18 @@ export const BaseChat = React.forwardRef( const TEXTAREA_MAX_HEIGHT = chatStarted ? 400 : 200; return ( -
    +
    {() => }
    {!chatStarted && (
    -

    Where ideas begin

    -

    Bring ideas to life in seconds or get help on existing projects.

    +

    + Where ideas begin +

    +

    + Bring ideas to life in seconds or get help on existing projects. +

    )}
    ( return chatStarted ? ( @@ -90,12 +94,12 @@ export const BaseChat = React.forwardRef( >