From a41b4c2482b8134ca8a7daca168af4ecc6cc8492 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Wed, 20 May 2026 13:11:06 +0900 Subject: feat: markdown rendering, daisyUI 5 compliance fixes, garden/luxury themes --- bun.lock | 9 +++ packages/frontend/package.json | 3 + packages/frontend/src/App.svelte | 2 +- packages/frontend/src/app.css | 78 +++++++++++++++++++- .../frontend/src/lib/components/ChatInput.svelte | 2 +- .../frontend/src/lib/components/ChatMessage.svelte | 14 ++-- .../frontend/src/lib/components/ChatPanel.svelte | 9 +-- packages/frontend/src/lib/components/Header.svelte | 4 +- .../src/lib/components/MarkdownRenderer.svelte | 58 +++++++++++++++ .../src/lib/components/ThemeSwitcher.svelte | 73 ++++++++----------- .../src/lib/components/ToolCallDisplay.svelte | 82 +++++++++++----------- 11 files changed, 229 insertions(+), 105 deletions(-) create mode 100644 packages/frontend/src/lib/components/MarkdownRenderer.svelte diff --git a/bun.lock b/bun.lock index 2440fe3..44cf8c2 100644 --- a/bun.lock +++ b/bun.lock @@ -39,6 +39,9 @@ "name": "@dispatch/frontend", "version": "0.0.1", "dependencies": { + "highlight.js": "^11.11.1", + "marked": "^18.0.4", + "marked-highlight": "^2.2.4", "svelte": "^5.0.0", }, "devDependencies": { @@ -324,6 +327,8 @@ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + "highlight.js": ["highlight.js@11.11.1", "", {}, "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w=="], + "hono": ["hono@4.12.19", "", {}, "sha512-xa3eYXYXx68XTT4hZ7dRzsXBhaq85ToSrlUJNoR0gwz/1Ap/CNwX47wfvV7pc/xWhjKVVkLT7zBJy8chhNguqQ=="], "is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="], @@ -368,6 +373,10 @@ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "marked": ["marked@18.0.4", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-c/BTaKzg0G6ezQx97DAkYU7k0HM6ys0FqYeKBL6hlBByZwy+ycA1+f0vDdjMHKKeEjdgkx0GOv9Il6D+85cOqA=="], + + "marked-highlight": ["marked-highlight@2.2.4", "", { "peerDependencies": { "marked": ">=4 <19" } }, "sha512-PZxisNMJDduSjc0q6uvjsnqqHCXc9s0eyzxDO9sB1eNGJnd/H1/Fu+z6g/liC1dfJdFW4SftMwMlLvsBhUPrqQ=="], + "mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="], "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], diff --git a/packages/frontend/package.json b/packages/frontend/package.json index acb23ad..2b68692 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -12,6 +12,9 @@ "typecheck": "svelte-check --tsconfig ./tsconfig.json" }, "dependencies": { + "highlight.js": "^11.11.1", + "marked": "^18.0.4", + "marked-highlight": "^2.2.4", "svelte": "^5.0.0" }, "devDependencies": { diff --git a/packages/frontend/src/App.svelte b/packages/frontend/src/App.svelte index c8e3803..b980abf 100644 --- a/packages/frontend/src/App.svelte +++ b/packages/frontend/src/App.svelte @@ -26,7 +26,7 @@ onMount(() => { }); -
+
diff --git a/packages/frontend/src/app.css b/packages/frontend/src/app.css index 5602e1f..a9ee1b6 100644 --- a/packages/frontend/src/app.css +++ b/packages/frontend/src/app.css @@ -1,4 +1,80 @@ @import "tailwindcss"; +@import "highlight.js/styles/atom-one-dark.min.css"; @plugin "daisyui" { - themes: light, dark, dracula, night, nord, sunset, cyberpunk, forest, cmyk, coffee, caramellatte; + themes: light, dark, dracula, night, nord, sunset, cyberpunk, forest, cmyk, coffee, caramellatte, garden, luxury; +} + +.markdown-body { + & p { + margin-block: 0.5em; + &:first-child { margin-block-start: 0; } + &:last-child { margin-block-end: 0; } + } + & h1, & h2, & h3, & h4, & h5, & h6 { + font-weight: 600; + line-height: 1.25; + margin-block: 0.75em 0.25em; + &:first-child { margin-block-start: 0; } + } + & h1 { font-size: 1.4em; } + & h2 { font-size: 1.2em; } + & h3 { font-size: 1.1em; } + & ul, & ol { + padding-inline-start: 1.5em; + margin-block: 0.5em; + } + & ul { list-style-type: disc; } + & ol { list-style-type: decimal; } + & li { margin-block: 0.15em; } + & pre { + overflow-x: auto; + border-radius: var(--radius-box); + margin-block: 0.5em; + background-color: oklch(var(--color-neutral)); + color: oklch(var(--color-neutral-content)); + } + & pre code { + display: block; + padding: 0.75em 1em; + font-size: 0.8125em; + line-height: 1.5; + } + & :not(pre) > code { + font-size: 0.875em; + padding: 0.15em 0.4em; + border-radius: var(--radius-selector); + background-color: oklch(var(--color-base-content) / 0.1); + } + & blockquote { + border-inline-start: 3px solid oklch(var(--color-base-content) / 0.2); + padding-inline-start: 0.75em; + margin-block: 0.5em; + opacity: 0.8; + } + & a { + color: oklch(var(--color-primary)); + text-decoration: underline; + &:hover { opacity: 0.8; } + } + & strong { font-weight: 600; } + & table { + width: 100%; + border-collapse: collapse; + margin-block: 0.5em; + font-size: 0.875em; + } + & th, & td { + border: 1px solid oklch(var(--color-base-content) / 0.15); + padding: 0.4em 0.75em; + text-align: start; + } + & th { + font-weight: 600; + background-color: oklch(var(--color-base-200)); + } + & hr { + border: none; + border-top: 1px solid oklch(var(--color-base-content) / 0.2); + margin-block: 0.75em; + } } diff --git a/packages/frontend/src/lib/components/ChatInput.svelte b/packages/frontend/src/lib/components/ChatInput.svelte index b929923..92c78b9 100644 --- a/packages/frontend/src/lib/components/ChatInput.svelte +++ b/packages/frontend/src/lib/components/ChatInput.svelte @@ -30,7 +30,7 @@ function submit() { bind:value={inputValue} type="text" placeholder={isDisabled ? "Agent is running..." : "Type a message..."} - class="input input-bordered flex-1" + class="input flex-1" disabled={isDisabled} onkeydown={handleKeydown} /> diff --git a/packages/frontend/src/lib/components/ChatMessage.svelte b/packages/frontend/src/lib/components/ChatMessage.svelte index 5212790..1b92de3 100644 --- a/packages/frontend/src/lib/components/ChatMessage.svelte +++ b/packages/frontend/src/lib/components/ChatMessage.svelte @@ -1,5 +1,6 @@