diff --git a/package-lock.json b/package-lock.json index b83fb86d..4a403917 100644 --- a/package-lock.json +++ b/package-lock.json @@ -75,6 +75,7 @@ "devDependencies": { "@playwright/test": "^1.50.0", "@stylistic/eslint-plugin-ts": "^2.8.0", + "@tailwindcss/typography": "^0.5.16", "@types/cookie": "^0.3.3", "@types/debug": "^4.1.5", "@types/diff": "^7.0.1", @@ -168,7 +169,7 @@ "pump": "^1.0.1", "rcedit": "^1.1.0", "rimraf": "^2.7.1", - "scope-tailwind": "^1.0.6", + "scope-tailwind": "^1.0.9", "sinon": "^12.0.1", "sinon-test": "^3.1.3", "source-map": "0.6.1", @@ -3598,6 +3599,36 @@ "node": ">=10" } }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz", + "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.castarray": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" + } + }, + "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@thisismanta/pessimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@thisismanta/pessimist/-/pessimist-1.2.0.tgz", @@ -14039,6 +14070,13 @@ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY= sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true }, + "node_modules/lodash.castarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", + "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.clone": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", @@ -14057,6 +14095,13 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -18820,9 +18865,9 @@ "dev": true }, "node_modules/scope-tailwind": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/scope-tailwind/-/scope-tailwind-1.0.6.tgz", - "integrity": "sha512-tkISLsaesYKKXL9YrLsRWFOD/FhrRVGKeinjgTuFtEidryLzwlBB3G17ArmHWHYcfdMp00XwnRMcGFkF8wwG6w==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/scope-tailwind/-/scope-tailwind-1.0.9.tgz", + "integrity": "sha512-sxtAKxJq143lYK/RCE36YGq13ficBZ9/9Z0TZa78k0AEiKNT5nH4kfhD8YAfEXR/qPR+G7tl9KL4UoHh+Cs93g==", "dev": true, "license": "AGPL-3.0-only", "dependencies": { diff --git a/package.json b/package.json index 91cf98d0..52387a3e 100644 --- a/package.json +++ b/package.json @@ -136,6 +136,7 @@ "devDependencies": { "@playwright/test": "^1.50.0", "@stylistic/eslint-plugin-ts": "^2.8.0", + "@tailwindcss/typography": "^0.5.16", "@types/cookie": "^0.3.3", "@types/debug": "^4.1.5", "@types/diff": "^7.0.1", @@ -229,7 +230,7 @@ "pump": "^1.0.1", "rcedit": "^1.1.0", "rimraf": "^2.7.1", - "scope-tailwind": "^1.0.6", + "scope-tailwind": "^1.0.9", "sinon": "^12.0.1", "sinon-test": "^3.1.3", "source-map": "0.6.1", diff --git a/src/vs/workbench/contrib/void/browser/react/build.js b/src/vs/workbench/contrib/void/browser/react/build.js index ab4ea921..26b5bc37 100755 --- a/src/vs/workbench/contrib/void/browser/react/build.js +++ b/src/vs/workbench/contrib/void/browser/react/build.js @@ -74,7 +74,7 @@ function saveStylesFile() { } catch (err) { console.error('[scope-tailwind] Error saving styles.css:', err); } - }, 3000); + }, 4000); } const args = process.argv.slice(2); diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx index 65786cfe..b4f6232c 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx @@ -14,10 +14,6 @@ export type ChatMessageLocation = { messageIdx: number; } - -const cn = (className: string) => className?.split(' ').map(c => c ? `void-${c}` : '').join(' ') - - type ApplyBoxLocation = ChatMessageLocation & { tokenIdx: string } const getApplyBoxId = ({ threadId, messageIdx, tokenIdx }: ApplyBoxLocation) => { @@ -26,6 +22,7 @@ const getApplyBoxId = ({ threadId, messageIdx, tokenIdx }: ApplyBoxLocation) => + // all classnames must go in tailwind.config.js/safelist export const noSpaceStyles = { blockquote: 'pl-4 border-l-4 border-void-bg-2 italic', @@ -88,31 +85,17 @@ const defaultStyles = { text: '', } - - -type TokenClasses = typeof defaultStyles - -const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, classes }: { token: Token | string, nested?: boolean, chatMessageLocationForApply?: ChatMessageLocation, tokenIdx: string, classes?: TokenClasses }): JSX.Element => { - +const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx }: { token: Token | string, nested?: boolean, chatMessageLocationForApply?: ChatMessageLocation, tokenIdx: string }): JSX.Element => { // deal with built-in tokens first (assume marked token) const t = token as MarkedToken - if(t.raw.trim() ===''){ + if (t.raw.trim() === '') { return <>>; } - // compute the className - const defaultClassName = defaultStyles[t.type] - const classNameOverride = classes?.[t.type] - const _className = classNameOverride ?? defaultClassName - let className: string = '' - if (typeof defaultClassName === 'string') { - className = _className as string - } - if (t.type === "space") { - return {t.raw} + return {t.raw} } if (t.type === "code") { @@ -123,7 +106,7 @@ const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, cla tokenIdx: tokenIdx, }) : null - return
| + | {cell.raw} | ))} @@ -160,13 +137,9 @@ const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, cla
|---|---|
| + | {cell.raw} | ))} @@ -176,20 +149,54 @@ const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, cla
| + // {cell.raw} + // | + // ))} + //
|---|
| + // {cell.raw} + // | + // ))} + //
{t.text}+ return
{t.text}} if (t.type === 'list_item') { -
+ return
{contents}
} if (t.type === "html") { return ( -+
{t.raw}
) } if (t.type === "text" || t.type === "escape") { - return {t.raw} + return {t.raw} } if (t.type === "def") { @@ -269,10 +257,10 @@ const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, cla if (t.type === "link") { return ( { window.open(t.href) }} href={t.href} title={t.title ?? undefined} + className='underline cursor-pointer hover:brightness-90 transition-all duration-200' > {t.text} @@ -284,52 +272,50 @@ const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, cla src={t.href} alt={t.text} title={t.title ?? undefined} - className={cn(className)} + /> } if (t.type === "strong") { - return {t.text} + return {t.text} } if (t.type === "em") { - return {t.text} + return {t.text} } // inline code if (t.type === "codespan") { return ( -
+
{t.text}
)
}
if (t.type === "br") {
- return
+ return
}
// strikethrough
if (t.type === "del") {
- return {t.text}
+ return {t.text}
}
// default
return (
- Unknown type:
- {t.type}
- {t.raw}
+ Unknown token rendered...
)
}
-export const ChatMarkdownRender = ({ string, nested = false, classes, chatMessageLocationForApply }: { string: string, nested?: boolean, classes?: TokenClasses, chatMessageLocationForApply?: ChatMessageLocation }) => {
+export const ChatMarkdownRender = ({ string, nested = false, chatMessageLocationForApply }: { string: string, nested?: boolean, chatMessageLocationForApply?: ChatMessageLocation }) => {
const tokens = marked.lexer(string); // https://marked.js.org/using_pro#renderer
return (
<>
{tokens.map((token, index) => (
-
+
))}
>
)
diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx
index 839a6679..dd49d08a 100644
--- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx
+++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx
@@ -2,11 +2,6 @@
* Copyright 2025 Glass Devtools, Inc. All rights reserved.
* Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information.
*--------------------------------------------------------------------------------------*/
-import React, { useEffect, useState } from 'react'
-import { mountFnGenerator } from '../util/mountFnGenerator.js'
-
-// import { SidebarSettings } from './SidebarSettings.js';
-
import { useIsDark, useSidebarState } from '../util/services.js';
// import { SidebarThreadSelector } from './SidebarThreadSelector.js';
@@ -20,9 +15,9 @@ export const Sidebar = ({ className }: { className: string }) => {
const sidebarState = useSidebarState()
const { currentTab: tab } = sidebarState
- // const isDark = useIsDark()
+ const isDark = useIsDark()
return
{
colorThemeState = themeService.getColorTheme().type
disposables.push(
- themeService.onDidColorThemeChange(theme => {
- colorThemeState = theme.theme.type
+ themeService.onDidColorThemeChange(({ theme }) => {
+ colorThemeState = theme.type
colorThemeStateListeners.forEach(l => l(colorThemeState))
})
)
diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx
index 1ebbefc9..79c8fdb8 100644
--- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx
+++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx
@@ -15,7 +15,7 @@ import { isWindows, isLinux, isMacintosh } from '../../../../../../../base/commo
import { URI } from '../../../../../../../base/common/uri.js'
import { env } from '../../../../../../../base/common/process.js'
import { ModelDropdown } from './ModelDropdown.js'
-import { ChatMarkdownRender, noSpaceStyles } from '../markdown/ChatMarkdownRender.js'
+import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js'
import { WarningBox } from './WarningBox.js'
import { os } from '../../../../common/helpers/systemInfo.js'
@@ -293,7 +293,7 @@ const ProviderSetting = ({ providerName, settingName }: { providerName: Provider
isPasswordField={isPasswordField}
/>
{subTextMd === undefined ? null :
-
+
}
@@ -412,12 +412,12 @@ export const FeaturesTab = () => {
{/* {`Instructions:`}
*/}
{/* {`Void can access any model that you host locally. We automatically detect your local models by default.`}
*/}
{`Void can access any model that you host locally. We automatically detect your local models by default.`}
-
-
-
-
-
-
+
+
+
+
+
+
{/* TODO we should create UI for downloading models without user going into terminal */}
diff --git a/src/vs/workbench/contrib/void/browser/react/tailwind.config.js b/src/vs/workbench/contrib/void/browser/react/tailwind.config.js
index 228b2847..be4f9a13 100644
--- a/src/vs/workbench/contrib/void/browser/react/tailwind.config.js
+++ b/src/vs/workbench/contrib/void/browser/react/tailwind.config.js
@@ -9,6 +9,29 @@ module.exports = {
content: ['./src2/**/*.{jsx,tsx}'], // uses these files to decide how to transform the css file
theme: {
extend: {
+ typography: {
+ DEFAULT: {
+ css: {
+ '--tw-prose-body': 'var(--void-fg-1)',
+ '--tw-prose-headings': 'var(--void-fg-1)',
+ '--tw-prose-lead': 'var(--void-fg-2)',
+ '--tw-prose-links': 'var(--void-link-color)',
+ '--tw-prose-bold': 'var(--void-fg-1)',
+ '--tw-prose-counters': 'var(--void-fg-3)',
+ '--tw-prose-bullets': 'var(--void-fg-3)',
+ '--tw-prose-hr': 'var(--void-border-4)',
+ '--tw-prose-quotes': 'var(--void-fg-1)',
+ '--tw-prose-quote-borders': 'var(--void-border-2)',
+ '--tw-prose-captions': 'var(--void-fg-3)',
+ '--tw-prose-code': 'var(--void-fg-0)',
+ '--tw-prose-pre-code': 'var(--void-fg-0)',
+ '--tw-prose-pre-bg': 'var(--void-bg-1)',
+ '--tw-prose-th-borders': 'var(--void-border-4)',
+ '--tw-prose-td-borders': 'var(--void-border-4)',
+ },
+ },
+
+ },
fontSize: {
xs: '10px',
sm: '11px',
@@ -27,27 +50,29 @@ module.exports = {
// common colors to use, ordered light to dark
colors: {
- 'void-bg-1': 'var(--vscode-input-background)',
- 'void-bg-1-alt': 'var(--vscode-badge-background)',
- 'void-bg-2': 'var(--vscode-sideBar-background)',
- 'void-bg-2-alt': 'color-mix(in srgb, var(--vscode-sideBar-background) 30%, var(--vscode-editor-background) 70%)',
- 'void-bg-3': 'var(--vscode-editor-background)',
+ 'void-bg-1': 'var(--void-bg-1)',
+ 'void-bg-1-alt': 'var(--void-bg-1-alt)',
+ 'void-bg-2': 'var(--void-bg-2)',
+ 'void-bg-2-alt': 'var(--void-bg-2-alt)',
+ 'void-bg-3': 'var(--void-bg-3)',
- 'void-fg-1': 'var(--vscode-editor-foreground)',
- 'void-fg-2': 'var(--vscode-input-foreground)',
- 'void-fg-3': 'var(--vscode-input-placeholderForeground)',
+ 'void-fg-0': 'var(--void-fg-0)',
+ 'void-fg-1': 'var(--void-fg-1)',
+ 'void-fg-2': 'var(--void-fg-2)',
+ 'void-fg-3': 'var(--void-fg-3)',
// 'void-fg-4': 'var(--vscode-tab-inactiveForeground)',
- 'void-fg-4': 'var(--vscode-list-deemphasizedForeground)',
+ 'void-fg-4': 'var(--void-fg-4)',
+ 'void-warning': 'var(--void-warning)',
- 'void-warning': 'var(--vscode-charts-yellow)',
-
- 'void-border-1': 'var(--vscode-commandCenter-activeBorder)',
- 'void-border-2': 'var(--vscode-commandCenter-border)',
- 'void-border-3': 'var(--vscode-commandCenter-inactiveBorder)',
- 'void-border-4': 'var(--vscode-editorGroup-border)',
+ 'void-border-1': 'var(--void-border-1)',
+ 'void-border-2': 'var(--void-border-2)',
+ 'void-border-3': 'var(--void-border-3)',
+ 'void-border-4': 'var(--void-border-4)',
+ 'void-ring-color': 'var(--void-ring-color)',
+ 'void-link-color': 'var(--void-link-color)',
vscode: {
// see: https://code.visualstudio.com/api/extension-guides/webview#theming-webview-content
@@ -166,83 +191,9 @@ module.exports = {
},
},
},
- plugins: [],
- prefix: 'void-',
- safelist: [
- // Background colors
- 'void-bg-void-bg-1',
-
- // Borders
- 'void-border-b',
- 'void-border-l-4',
- 'void-border-t',
- 'void-border-void-bg-2',
-
- // Typography
- 'void-text-2xl',
- 'void-text-3xl',
- 'void-text-4xl',
- 'void-text-base',
- 'void-text-lg',
- 'void-text-xl',
- 'void-text-gray-600',
- 'void-font-medium',
- 'void-font-mono',
- 'void-font-semibold',
- 'void-italic',
- 'void-line-through',
- 'void-underline',
-
- // Spacing
- 'void-mt-1',
- 'void-mt-2',
- 'void-mt-4',
- 'void-mt-6',
- 'void-mb-1',
- 'void-mb-2',
- 'void-mb-4',
- 'void-mx-1',
- 'void-mx-2',
- 'void-mx-4',
- 'void-my-1',
- 'void-my-2',
- 'void-my-4',
- 'void-my-6',
- 'void-pb-1',
- 'void-pb-2',
- 'void-pb-4',
- 'void-pl-1',
- 'void-pl-2',
- 'void-pl-4',
- 'void-px-1',
- 'void-px-2',
- 'void-px-4',
-
- // Sizing and layout
- 'void-h-auto',
- 'void-max-w-full',
- 'void-overflow-x-auto',
-
- // Lists
- 'void-list-inside',
- 'void-list-decimal',
- 'void-list-disc',
-
- // Effects and decoration
- 'void-cursor-pointer',
- 'void-ring-8',
- 'void-ring-[#123456]',
- 'void-rounded',
- 'void-rounded-sm',
-
- // misc
- 'void-break-all',
- 'void-bg-void-bg-1',
- 'void-px-1',
- 'void-rounded-sm',
- 'void-font-mono',
- 'void-font-medium',
- 'void-break-all'
- ]
+ plugins: [
+ require('@tailwindcss/typography')
+ ],
+ prefix: 'void-'
}