fix markdown stylings with prose

This commit is contained in:
Mathew Pareles 2025-03-05 22:03:01 -08:00
parent ead1d9229f
commit cc6a231b3c
9 changed files with 207 additions and 205 deletions

53
package-lock.json generated
View file

@ -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": {

View file

@ -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",

View file

@ -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);

View file

@ -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 <span className={cn(className)}>{t.raw}</span>
return <span>{t.raw}</span>
}
if (t.type === "code") {
@ -123,7 +106,7 @@ const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, cla
tokenIdx: tokenIdx,
}) : null
return <div className={cn(className)}>
return <div>
<BlockCode
initValue={t.text}
language={t.lang === undefined ? undefined : nameToVscodeLanguage[t.lang]}
@ -134,25 +117,19 @@ const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, cla
if (t.type === "heading") {
const HeadingTag = `h${t.depth}` as keyof typeof defaultStyles.heading
const HeadingTag = `h${t.depth}` as keyof JSX.IntrinsicElements
const className = classes?.heading[HeadingTag] ?? defaultStyles.heading[HeadingTag]
return <HeadingTag className={cn(className)}>{t.text}</HeadingTag>
return <HeadingTag>{t.text}</HeadingTag>
}
if (t.type === "table") {
return (
<div className={cn(className)}>
<table className={"min-w-full border border-void-bg-2"}>
<div>
<table>
<thead>
<tr className="bg-void-bg-1">
<tr>
{t.header.map((cell: any, index: number) => (
<th
key={index}
className="px-4 py-2 border border-void-bg-2 font-semibold"
style={{ textAlign: t.align[index] || "left" }}
>
<th key={index}>
{cell.raw}
</th>
))}
@ -160,13 +137,9 @@ const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, cla
</thead>
<tbody>
{t.rows.map((row: any[], rowIndex: number) => (
<tr key={rowIndex} className={rowIndex % 2 === 0 ? 'bg-white' : 'bg-void-bg-1'}>
<tr key={rowIndex}>
{row.map((cell: any, cellIndex: number) => (
<td
key={cellIndex}
className={"px-4 py-2 border border-void-bg-2"}
style={{ textAlign: t.align[cellIndex] || "left" }}
>
<td key={cellIndex} >
{cell.raw}
</td>
))}
@ -176,20 +149,54 @@ const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, cla
</table>
</div>
)
// return (
// <div>
// <table className={"min-w-full border border-void-bg-2"}>
// <thead>
// <tr className="bg-void-bg-1">
// {t.header.map((cell: any, index: number) => (
// <th
// key={index}
// className="px-4 py-2 border border-void-bg-2 font-semibold"
// style={{ textAlign: t.align[index] || "left" }}
// >
// {cell.raw}
// </th>
// ))}
// </tr>
// </thead>
// <tbody>
// {t.rows.map((row: any[], rowIndex: number) => (
// <tr key={rowIndex} className={rowIndex % 2 === 0 ? 'bg-white' : 'bg-void-bg-1'}>
// {row.map((cell: any, cellIndex: number) => (
// <td
// key={cellIndex}
// className={"px-4 py-2 border border-void-bg-2"}
// style={{ textAlign: t.align[cellIndex] || "left" }}
// >
// {cell.raw}
// </td>
// ))}
// </tr>
// ))}
// </tbody>
// </table>
// </div>
// )
}
if (t.type === "hr") {
return <hr className={cn(className)} />
return <hr />
}
if (t.type === "blockquote") {
return <blockquote className={cn(className)}>{t.text}</blockquote>
return <blockquote>{t.text}</blockquote>
}
if (t.type === 'list_item') {
<li className={cn(className)}>
<span className="ml-1">
!!!!!!!!!!!!!
return <li>
<input type="checkbox" checked={t.checked} readOnly />
<span>
<ChatMarkdownRender chatMessageLocationForApply={chatMessageLocationForApply} string={t.text} nested={true} />
</span>
</li>
@ -198,68 +205,49 @@ const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, cla
if (t.type === "list") {
const ListTag = t.ordered ? "ol" : "ul"
const itemClassName = classes?.['list_item'] ?? defaultStyles['list_item']
return (
<ListTag
start={t.start ? t.start : undefined}
className={`${cn(className)} ${t.ordered ? "list-decimal" : "list-disc"}`}
>
<ListTag start={t.start ? t.start : undefined}>
{t.items.map((item, index) => (
<li key={index} className={cn(itemClassName)}>
<li key={index}>
{item.task && (
<input type="checkbox" checked={item.checked} readOnly className="mr-2 form-checkbox" />
<input type="checkbox" checked={item.checked} readOnly />
)}
<span className="ml-1">
<span>
<ChatMarkdownRender chatMessageLocationForApply={chatMessageLocationForApply} string={item.text} nested={true} />
</span>
</li>
))}
</ListTag>
)
// attempt at indentation
// return (
// <ListTag
// start={t.start ? t.start : undefined}
// className={`${className} ${t.ordered ? "list-decimal" : "list-disc"}`}
// >
// {t.items.map((item, index) => (
// <li key={index} className={`itemClassName`}>
// {item.task && (
// <input type="checkbox" className='mr-2 form-checkbox' checked={item.checked} readOnly />
// )}
// <span className-='inline-block pr-2'>
// <ChatMarkdownRender chatMessageLocation={chatMessageLocation} string={item.text} nested={true} />
// </span>
// </li>
// ))}
// </ListTag>
// )
}
if (t.type === "paragraph") {
const contents = <>
{t.tokens.map((token, index) => (
<RenderToken key={index} token={token} tokenIdx={`${tokenIdx ? `${tokenIdx}-` : ''}${index}`} classes={classes} /> // assign a unique tokenId to nested components
<RenderToken key={index}
token={token}
tokenIdx={`${tokenIdx ? `${tokenIdx}-` : ''}${index}`} // assign a unique tokenId to nested components
/>
))}
</>
if (nested) return contents
return <p className={cn(className)}>
return <p>
{contents}
</p>
}
if (t.type === "html") {
return (
<p className={cn(className)}>
<p>
{t.raw}
</p>
)
}
if (t.type === "text" || t.type === "escape") {
return <span className={cn(className)}>{t.raw}</span>
return <span>{t.raw}</span>
}
if (t.type === "def") {
@ -269,10 +257,10 @@ const RenderToken = ({ token, nested, chatMessageLocationForApply, tokenIdx, cla
if (t.type === "link") {
return (
<a
className={cn(className)}
onClick={() => { window.open(t.href) }}
href={t.href}
title={t.title ?? undefined}
className='underline cursor-pointer hover:brightness-90 transition-all duration-200'
>
{t.text}
</a>
@ -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 <strong className={cn(className)}>{t.text}</strong>
return <strong>{t.text}</strong>
}
if (t.type === "em") {
return <em className={cn(className)}>{t.text}</em>
return <em>{t.text}</em>
}
// inline code
if (t.type === "codespan") {
return (
<code className={cn(className)}>
<code className="font-mono font-semibold rounded-sm bg-void-bg-1 px-1">
{t.text}
</code>
)
}
if (t.type === "br") {
return <br className={cn(className)} />
return <br />
}
// strikethrough
if (t.type === "del") {
return <del className={cn(className)}>{t.text}</del>
return <del>{t.text}</del>
}
// default
return (
<div className="bg-orange-50 rounded-sm overflow-hidden p-2">
<span className="text-sm text-orange-500">Unknown type:</span>
{t.type}
{t.raw}
<span className="text-sm text-orange-500">Unknown token rendered...</span>
</div>
)
}
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) => (
<RenderToken key={index} token={token} nested={nested} classes={classes} chatMessageLocationForApply={chatMessageLocationForApply} tokenIdx={index + ''} />
<RenderToken key={index} token={token} nested={nested} chatMessageLocationForApply={chatMessageLocationForApply} tokenIdx={index + ''} />
))}
</>
)

View file

@ -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 <div
className={`@@void-scope`} // ${isDark ? 'dark' : ''}
className={`@@void-scope ${isDark ? 'dark' : ''}`}
style={{ width: '100%', height: '100%' }}
>
<div

View file

@ -7,6 +7,30 @@
@tailwind components;
@tailwind utilities;
& {
--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-fg-0: color-mix(in srgb, var(--vscode-tab-activeForeground) 90%, black 10%);
--void-fg-1: var(--vscode-editor-foreground);
--void-fg-2: var(--vscode-input-foreground);
--void-fg-3: var(--vscode-input-placeholderForeground);
/* --void-fg-4: var(--vscode-tab-inactiveForeground); */
--void-fg-4: var(--vscode-list-deemphasizedForeground);
--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-ring-color: #007FD4;
--void-link-color: #007FD4;
}
.select-child-restyle select {
text-overflow: ellipsis;

View file

@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------*/
import React, { useState, useEffect, useCallback } from 'react'
import { ThreadStreamState,IChatThreadService, ThreadsState } from '../../../chatThreadService.js'
import { RefreshableProviderName, SettingsOfProvider } from '../../../../../../../workbench/contrib/void/common/voidSettingsTypes.js'
import { IDisposable } from '../../../../../../../base/common/lifecycle.js'
import { VoidSidebarState } from '../../../sidebarStateService.js'
@ -45,6 +44,7 @@ import { IConfigurationService } from '../../../../../../../platform/configurati
import { IPathService } from '../../../../../../../workbench/services/path/common/pathService.js'
import { IMetricsService } from '../../../../../../../workbench/contrib/void/common/metricsService.js'
import { URI } from '../../../../../../../base/common/uri.js'
import { IChatThreadService, ThreadsState, ThreadStreamState } from '../../../chatThreadService.js'
@ -171,8 +171,8 @@ export const _registerServices = (accessor: ServicesAccessor) => {
colorThemeState = themeService.getColorTheme().type
disposables.push(
themeService.onDidColorThemeChange(theme => {
colorThemeState = theme.theme.type
themeService.onDidColorThemeChange(({ theme }) => {
colorThemeState = theme.type
colorThemeStateListeners.forEach(l => l(colorThemeState))
})
)

View file

@ -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 : <div className='py-1 px-3 opacity-50 text-sm'>
<ChatMarkdownRender classes={noSpaceStyles} string={subTextMd} />
<ChatMarkdownRender string={subTextMd} />
</div>}
</div>
@ -412,12 +412,12 @@ export const FeaturesTab = () => {
{/* <h3 className={`opacity-50 mb-2`}>{`Instructions:`}</h3> */}
{/* <h3 className={`mb-2`}>{`Void can access any model that you host locally. We automatically detect your local models by default.`}</h3> */}
<h3 className={`text-void-fg-3 mb-2`}>{`Void can access any model that you host locally. We automatically detect your local models by default.`}</h3>
<div className='pl-4 opacity-50'>
<span className={`text-sm mb-2`}><ChatMarkdownRender classes={noSpaceStyles} string={`1. Download [Ollama](https://ollama.com/download).`} /></span>
<span className={`text-sm mb-2`}><ChatMarkdownRender classes={noSpaceStyles} string={`2. Open your terminal.`} /></span>
<span className={`text-sm mb-2 select-text`}><ChatMarkdownRender classes={noSpaceStyles} string={`3. Run \`ollama run llama3.1:8b\`. This installs Meta's llama3.1 model which is best for chat and inline edits. Requires 5GB of memory.`} /></span>
<span className={`text-sm mb-2 select-text`}><ChatMarkdownRender classes={noSpaceStyles} string={`4. Run \`ollama run qwen2.5-coder:1.5b\`. This installs a faster autocomplete model. Requires 1GB of memory.`} /></span>
<span className={`text-sm mb-2`}><ChatMarkdownRender classes={noSpaceStyles} string={`Void automatically detects locally running models and enables them.`} /></span>
<div className='pl-4 prose-ol:list-decimal opacity-80'>
<span className={`text-sm mb-2`}><ChatMarkdownRender string={`1. Download [Ollama](https://ollama.com/download).`} /></span>
<span className={`text-sm mb-2`}><ChatMarkdownRender string={`2. Open your terminal.`} /></span>
<span className={`text-sm mb-2 select-text`}><ChatMarkdownRender string={`3. Run \`ollama run llama3.1:8b\`. This installs Meta's llama3.1 model which is best for chat and inline edits. Requires 5GB of memory.`} /></span>
<span className={`text-sm mb-2 select-text`}><ChatMarkdownRender string={`4. Run \`ollama run qwen2.5-coder:1.5b\`. This installs a faster autocomplete model. Requires 1GB of memory.`} /></span>
<span className={`text-sm mb-2`}><ChatMarkdownRender string={`Void automatically detects locally running models and enables them.`} /></span>
{/* TODO we should create UI for downloading models without user going into terminal */}
</div>

View file

@ -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-'
}