diff --git a/.changeset/go-and-gruvbox.md b/.changeset/go-and-gruvbox.md new file mode 100644 index 0000000..8ed13db --- /dev/null +++ b/.changeset/go-and-gruvbox.md @@ -0,0 +1,5 @@ +--- +"@tanstack/highlight": minor +--- + +Add an isolated Go language definition with the `golang` alias and isolated Gruvbox Dark and Light themes. Existing selective language bundles and the core are unchanged. diff --git a/README.md b/README.md index 7a5f833..b5b10f9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,21 @@ +
+ + + + TanStack Highlight + +
+ # TanStack Highlight Tiny, synchronous syntax highlighting for blogs and documentation. @@ -172,11 +190,11 @@ const css = createThemeCss({ For TanStack Markdown, set `codeBlockSelector` to its `pre.tm-code` wrapper and `lineNumbersSelector` to `.tm-code--line-numbers`. See the [Markdown pipeline guide](docs/guides/markdown-pipelines.md#tanstack-markdown). -Available themes: Aurora X, Dracula, GitHub Dark, GitHub Light, Monokai, Nord, One Dark Pro, Solarized Dark, and Solarized Light. +Available themes: Aurora X, Dracula, GitHub Dark, GitHub Light, Gruvbox Dark, Gruvbox Light, Monokai, Nord, One Dark Pro, Solarized Dark, and Solarized Light. ## Languages -`apache`, `css`, `diff`, `dockerfile`, `ejs`, `env`, `html`, `http`, `js`, `json`, `jsx`, `markdown`, `mermaid`, `nginx`, `plaintext`, `python`, `scheme`, `shell`, `sql`, `svelte`, `toml`, `ts`, `tsrx`, `tsx`, `vue`, and `yaml`. +`apache`, `css`, `diff`, `dockerfile`, `ejs`, `env`, `go`, `html`, `http`, `js`, `json`, `jsx`, `markdown`, `mermaid`, `nginx`, `plaintext`, `python`, `scheme`, `shell`, `sql`, `svelte`, `toml`, `ts`, `tsrx`, `tsx`, `vue`, and `yaml`. Each language is available from `@tanstack/highlight/languages/`. The aggregate `@tanstack/highlight/languages` entry can tree-shake, while direct subpaths make isolation explicit. Importing only core helpers from the root entry also removes unused language registrations in a compatible bundler. @@ -199,7 +217,7 @@ Local browser bundles, minified with esbuild and compressed independently. KB us | Core + TSX | 9.46 KB | 4.03 KB | 3.66 KB | | Octane MDX + TypeScript | 13.21 KB | 5.37 KB | 4.90 KB | | Nine-language docs set | 15.39 KB | 5.97 KB | 5.44 KB | -| All 26 languages | 22.59 KB | 8.29 KB | 7.49 KB | +| All 27 languages | 23.93 KB | 8.66 KB | 7.78 KB | On 80 real JavaScript/TypeScript/JSX/TSX TanStack docs fixtures repeated across 5,040 blocks, using the median of three runs after warmup: diff --git a/docs/guides/performance.md b/docs/guides/performance.md index d4b54c9..29b9710 100644 --- a/docs/guides/performance.md +++ b/docs/guides/performance.md @@ -16,7 +16,7 @@ CI measures selective browser bundles and highlighting performance on real docum | TSX | TSX | 4.03 KB | 4.1 KB | | Octane | TypeScript plus Octane MDX adapter | 5.37 KB | 5.5 KB | | Docs | CSS, HTML, JS, JSON, JSX, Markdown, Shell, TS, TSX | 5.97 KB | 6.1 KB | -| All | All 26 definitions | 8.29 KB | 8.3 KB | +| All | All 27 definitions | 8.66 KB | 8.9 KB | KB uses 1,000 bytes. Core helpers imported from the root tree-shake to the same engine size. The standalone theme helper is 695 gzip bytes. diff --git a/docs/guides/themes.md b/docs/guides/themes.md index 921ea92..6fb0334 100644 --- a/docs/guides/themes.md +++ b/docs/guides/themes.md @@ -154,6 +154,8 @@ The defaults remain `pre.th-code` and `.th-code--line-numbers`. Token classes st | Dracula | `draculaTheme` | Dark | `themes/dracula` | | GitHub Dark | `githubDarkTheme` | Dark | `themes/github-dark` | | GitHub Light | `githubLightTheme` | Light | `themes/github-light` | +| Gruvbox Dark | `gruvboxDarkTheme` | Dark | `themes/gruvbox-dark` | +| Gruvbox Light | `gruvboxLightTheme` | Light | `themes/gruvbox-light` | | Monokai | `monokaiTheme` | Dark | `themes/monokai` | | Nord | `nordTheme` | Dark | `themes/nord` | | One Dark Pro | `oneDarkProTheme` | Dark | `themes/one-dark-pro` | diff --git a/docs/language-support.md b/docs/language-support.md index f7de9bc..35b2b29 100644 --- a/docs/language-support.md +++ b/docs/language-support.md @@ -16,6 +16,7 @@ Every language is an isolated definition imported from `@tanstack/highlight/lang | Dockerfile | `dockerfile` | `docker` | Common directives, variables, commands | | EJS | `ejs` | - | HTML plus optional JavaScript delegation | | Env | `env` | `dotenv` | Properties, values, comments | +| Go | `go` | `golang` | Raw strings, runes, comments, declarations | | HTML | `html` | `htm`, `xml`, `angular-html` | Optional JavaScript/TypeScript and CSS delegation | | HTTP | `http` | - | Methods, headers, protocol, paths | | JavaScript | `js` | `javascript`, `mjs`, `cjs`, `js-vue` | Templates, interpolation, regex literals | diff --git a/docs/reference/default-entry.md b/docs/reference/default-entry.md index 101ea22..6f6f756 100644 --- a/docs/reference/default-entry.md +++ b/docs/reference/default-entry.md @@ -43,7 +43,7 @@ Returns the canonical registered language name for a name or alias. Names are tr function listLanguages(): Array ``` -Returns the 26 canonical language names registered in `defaultHighlighter`. +Returns the 27 canonical language names registered in `defaultHighlighter`. ### `tokenize` diff --git a/docs/reference/languages.md b/docs/reference/languages.md index 2de8bee..3089e6b 100644 --- a/docs/reference/languages.md +++ b/docs/reference/languages.md @@ -27,6 +27,7 @@ const highlighter = createHighlighter({ | `dockerfile` | `@tanstack/highlight/languages/dockerfile` | `docker` | | `ejs` | `@tanstack/highlight/languages/ejs` | None | | `env` | `@tanstack/highlight/languages/env` | `dotenv` | +| `go` | `@tanstack/highlight/languages/go` | `golang` | | `html` | `@tanstack/highlight/languages/html` | `htm`, `xml`, `angular-html` | | `http` | `@tanstack/highlight/languages/http` | None | | `js` | `@tanstack/highlight/languages/js` | `javascript`, `mjs`, `cjs`, `js-vue` | @@ -48,6 +49,6 @@ const highlighter = createHighlighter({ | `vue` | `@tanstack/highlight/languages/vue` | None | | `yaml` | `@tanstack/highlight/languages/yaml` | `yml` | -`@tanstack/highlight/languages` re-exports `apache`, `css`, `diff`, `dockerfile`, `ejs`, `env`, `html`, `http`, `js`, `json`, `jsx`, `markdown`, `mermaid`, `nginx`, `plaintext`, `python`, `scheme`, `shell`, `sql`, `svelte`, `toml`, `ts`, `tsrx`, `tsx`, `vue`, and `yaml`. The barrel is convenient but individual subpaths make bundle intent explicit. +`@tanstack/highlight/languages` re-exports `apache`, `css`, `diff`, `dockerfile`, `ejs`, `env`, `go`, `html`, `http`, `js`, `json`, `jsx`, `markdown`, `mermaid`, `nginx`, `plaintext`, `python`, `scheme`, `shell`, `sql`, `svelte`, `toml`, `ts`, `tsrx`, `tsx`, `vue`, and `yaml`. The barrel is convenient but individual subpaths make bundle intent explicit. See the [language support matrix](../language-support) for the context-aware behavior and current scope of each registration. diff --git a/docs/reference/themes.md b/docs/reference/themes.md index 522638e..f2fac98 100644 --- a/docs/reference/themes.md +++ b/docs/reference/themes.md @@ -12,6 +12,8 @@ Bundled themes are isolated objects. Importing one theme does not include anothe | `draculaTheme` | `@tanstack/highlight/themes/dracula` | Dark | | `githubDarkTheme` | `@tanstack/highlight/themes/github-dark` | Dark | | `githubLightTheme` | `@tanstack/highlight/themes/github-light` | Light | +| `gruvboxDarkTheme` | `@tanstack/highlight/themes/gruvbox-dark` | Dark | +| `gruvboxLightTheme` | `@tanstack/highlight/themes/gruvbox-light` | Light | | `monokaiTheme` | `@tanstack/highlight/themes/monokai` | Dark | | `nordTheme` | `@tanstack/highlight/themes/nord` | Dark | | `oneDarkProTheme` | `@tanstack/highlight/themes/one-dark-pro` | Dark | diff --git a/docs/test-strategy.md b/docs/test-strategy.md index 36bd38b..9ebfb69 100644 --- a/docs/test-strategy.md +++ b/docs/test-strategy.md @@ -27,7 +27,7 @@ The suite protects the package's actual product boundary: valid code commonly pu | TSX | TSX | 4.1 KB | | Octane | TypeScript plus Octane MDX adapter | 5.5 KB | | Docs | CSS, HTML, JS, JSON, JSX, Markdown, Shell, TS, TSX | 6.1 KB | -| All | All 26 definitions | 8.3 KB | +| All | All 27 definitions | 8.9 KB | The selective profiles are the primary product metric. The all-language profile protects the convenience entry from unbounded growth. Bundle graphs reject unexpected language or theme code. Package tests repeat isolation checks through public exports after building. diff --git a/scripts/language-utils.mjs b/scripts/language-utils.mjs index c31105c..451eb1e 100644 --- a/scripts/language-utils.mjs +++ b/scripts/language-utils.mjs @@ -8,6 +8,7 @@ export const supportedLanguages = [ 'dockerfile', 'ejs', 'env', + 'go', 'html', 'http', 'js', @@ -39,6 +40,7 @@ const aliases = { cmd: 'shell', console: 'shell', dotenv: 'env', + golang: 'go', htm: 'html', javascript: 'js', 'js-vue': 'js', diff --git a/scripts/measure-size.mjs b/scripts/measure-size.mjs index b848ba1..57738c8 100644 --- a/scripts/measure-size.mjs +++ b/scripts/measure-size.mjs @@ -77,7 +77,7 @@ const profiles = { globalThis.highlighter = defaultHighlighter `, languages: 'all', - limits: { minified: 23_000, gzip: 8_300, brotli: 7_500 }, + limits: { minified: 24_500, gzip: 8_900, brotli: 8_000 }, }, reactAdapter: { source: `export * from './src/react.ts'`, diff --git a/skills/configure-selective-highlighting/references/languages.md b/skills/configure-selective-highlighting/references/languages.md index 657ba15..769972c 100644 --- a/skills/configure-selective-highlighting/references/languages.md +++ b/skills/configure-selective-highlighting/references/languages.md @@ -10,6 +10,7 @@ Import only the definitions the application registers. | Dockerfile | `dockerfile` | `@tanstack/highlight/languages/dockerfile` | `docker` | | EJS | `ejs` | `@tanstack/highlight/languages/ejs` | - | | Env | `env` | `@tanstack/highlight/languages/env` | `dotenv` | +| Go | `go` | `@tanstack/highlight/languages/go` | `golang` | | HTML | `html` | `@tanstack/highlight/languages/html` | `htm`, `xml`, `angular-html` | | HTTP | `http` | `@tanstack/highlight/languages/http` | - | | JavaScript | `js` | `@tanstack/highlight/languages/js` | `javascript`, `mjs`, `cjs`, `js-vue` | diff --git a/skills/theme-and-annotate-code/references/themes-and-tokens.md b/skills/theme-and-annotate-code/references/themes-and-tokens.md index 43d9c75..ba9a955 100644 --- a/skills/theme-and-annotate-code/references/themes-and-tokens.md +++ b/skills/theme-and-annotate-code/references/themes-and-tokens.md @@ -8,6 +8,8 @@ | Dracula | `draculaTheme` | dark | `@tanstack/highlight/themes/dracula` | | GitHub Dark | `githubDarkTheme` | dark | `@tanstack/highlight/themes/github-dark` | | GitHub Light | `githubLightTheme` | light | `@tanstack/highlight/themes/github-light` | +| Gruvbox Dark | `gruvboxDarkTheme` | dark | `@tanstack/highlight/themes/gruvbox-dark` | +| Gruvbox Light | `gruvboxLightTheme` | light | `@tanstack/highlight/themes/gruvbox-light` | | Monokai | `monokaiTheme` | dark | `@tanstack/highlight/themes/monokai` | | Nord | `nordTheme` | dark | `@tanstack/highlight/themes/nord` | | One Dark Pro | `oneDarkProTheme` | dark | `@tanstack/highlight/themes/one-dark-pro` | diff --git a/src/index.ts b/src/index.ts index 0fe2930..9de48a2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ import { diff } from './languages/diff.js' import { dockerfile } from './languages/dockerfile.js' import { ejs } from './languages/ejs.js' import { env } from './languages/env.js' +import { go } from './languages/go.js' import { html } from './languages/html.js' import { http } from './languages/http.js' import { js } from './languages/js.js' @@ -39,6 +40,7 @@ export type HighlightLanguage = | 'dockerfile' | 'ejs' | 'env' + | 'go' | 'html' | 'http' | 'js' @@ -107,6 +109,7 @@ export const allLanguages = [ dockerfile, ejs, env, + go, html, http, js, diff --git a/src/languages/go.ts b/src/languages/go.ts new file mode 100644 index 0000000..c899748 --- /dev/null +++ b/src/languages/go.ts @@ -0,0 +1,40 @@ +import { defineLanguage } from '../core.js' +import { patternTokenizer } from '../internal/patterns.js' + +export const go = defineLanguage({ + name: 'go', + aliases: ['golang'], + tokenize: patternTokenizer([ + { + className: (match) => + match[0].startsWith('/') ? 'comment' : 'string', + regex: + /\/\/[^\n]*|\/\*[\s\S]*?\*\/|`[\s\S]*?`|"(?:\\.|[^"\\\n])*"|'(?:\\.|[^'\\\n])*'/g, + }, + { + className: 'keyword', + regex: + /\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go|goto|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/g, + }, + { className: 'literal', regex: /\b(?:false|iota|nil|true)\b/g }, + { className: 'type', regex: /\btype\s+([A-Za-z_]\w*)/g, group: 1 }, + { + className: 'type', + regex: + /\b(?:any|bool|byte|comparable|complex64|complex128|error|float32|float64|int|int8|int16|int32|int64|rune|string|uint|uint8|uint16|uint32|uint64|uintptr)\b/g, + }, + { className: 'function', regex: /\b[A-Za-z_]\w*(?=\s*\()/g }, + { + className: 'number', + regex: + /(?:^|[^\w.])((?:0[bB]_?[01](?:_?[01])*|0[oO]_?[0-7](?:_?[0-7])*|0[xX](?:(?:_?[\da-fA-F](?:_?[\da-fA-F])*(?:\.(?:[\da-fA-F](?:_?[\da-fA-F])*)?)?|\.[\da-fA-F](?:_?[\da-fA-F])*)[pP][+-]?\d(?:_?\d)*|_?[\da-fA-F](?:_?[\da-fA-F])*)|\d(?:_?\d)*\.(?:\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|\d(?:_?\d)*[eE][+-]?\d(?:_?\d)*|\.\d(?:_?\d)*(?:[eE][+-]?\d(?:_?\d)*)?|\d(?:_?\d)*)(?:i)?)(?![\w.])/g, + group: 1, + }, + { className: 'property', regex: /\.\s*([A-Za-z_]\w*)/g, group: 1 }, + { + className: 'operator', + regex: + /\.\.\.|<<=?|>>=?|&\^=?|:=|<-|\+\+|--|==|!=|<=|>=|&&|\|\||[+\-*/%&|^!<>=~]=?/g, + }, + ]), +}) diff --git a/src/languages/index.ts b/src/languages/index.ts index ef279c9..50c2791 100644 --- a/src/languages/index.ts +++ b/src/languages/index.ts @@ -4,6 +4,7 @@ export { diff } from './diff.js' export { dockerfile } from './dockerfile.js' export { ejs } from './ejs.js' export { env } from './env.js' +export { go } from './go.js' export { html } from './html.js' export { http } from './http.js' export { js } from './js.js' diff --git a/src/themes/gruvbox-dark.ts b/src/themes/gruvbox-dark.ts new file mode 100644 index 0000000..d1518a4 --- /dev/null +++ b/src/themes/gruvbox-dark.ts @@ -0,0 +1,33 @@ +import type { HighlightTheme } from '../theme.js' + +export const gruvboxDarkTheme = { + background: '#282828', + foreground: '#ebdbb2', + name: 'gruvbox-dark', + type: 'dark', + tokens: { + attr: '#8ec07c', + 'code-inline': '#8ec07c', + command: '#b8bb26', + comment: '#928374', + deleted: '#fb4934', + function: '#b8bb26', + heading: '#b8bb26', + inserted: '#b8bb26', + keyword: '#fb4934', + link: '#d3869b', + literal: '#d3869b', + meta: '#928374', + number: '#d3869b', + operator: '#ebdbb2', + property: '#8ec07c', + selector: '#fe8019', + string: '#b8bb26', + tag: '#8ec07c', + token: '#ebdbb2', + type: '#fabd2f', + variable: '#83a598', + }, +} as const satisfies HighlightTheme + +export default gruvboxDarkTheme diff --git a/src/themes/gruvbox-light.ts b/src/themes/gruvbox-light.ts new file mode 100644 index 0000000..b1e404c --- /dev/null +++ b/src/themes/gruvbox-light.ts @@ -0,0 +1,33 @@ +import type { HighlightTheme } from '../theme.js' + +export const gruvboxLightTheme = { + background: '#fbf1c7', + foreground: '#3c3836', + name: 'gruvbox-light', + type: 'light', + tokens: { + attr: '#427b58', + 'code-inline': '#427b58', + command: '#79740e', + comment: '#928374', + deleted: '#9d0006', + function: '#79740e', + heading: '#79740e', + inserted: '#79740e', + keyword: '#9d0006', + link: '#8f3f71', + literal: '#8f3f71', + meta: '#928374', + number: '#8f3f71', + operator: '#3c3836', + property: '#427b58', + selector: '#af3a03', + string: '#79740e', + tag: '#427b58', + token: '#3c3836', + type: '#b57614', + variable: '#076678', + }, +} as const satisfies HighlightTheme + +export default gruvboxLightTheme diff --git a/test/fixtures.ts b/test/fixtures.ts index f2ebe9b..a3ead0d 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -29,6 +29,35 @@ export function Counter() @{ 'th-number', ], }, + { + lang: 'golang', + normalized: 'go', + code: `package main + +import "fmt" + +type Greeter struct { + Name string +} + +func (g Greeter) Greet() { + count := 2 + url := \`https://go.dev\` + initial := 'G' + fmt.Println(url, initial, g.Name, count, true) // greet +}`, + expectedClasses: [ + 'th-keyword', + 'th-string', + 'th-type', + 'th-function', + 'th-property', + 'th-number', + 'th-literal', + 'th-comment', + 'th-operator', + ], + }, { lang: 'tsx', normalized: 'tsx', diff --git a/test/highlight.contract.test.ts b/test/highlight.contract.test.ts index 49137b9..a8bd809 100644 --- a/test/highlight.contract.test.ts +++ b/test/highlight.contract.test.ts @@ -28,11 +28,17 @@ describe('language inventory', () => { it('lists the normalized support targets once', () => { const languages = listLanguages() + const fixtureLanguages = new Set( + languageFixtures.map((fixture) => fixture.normalized), + ) expect(new Set(languages).size).toBe(languages.length) for (const fixture of languageFixtures) { expect(languages).toContain(fixture.normalized) } + for (const language of languages) { + expect(fixtureLanguages, `missing representative fixture for ${language}`).toContain(language) + } }) }) @@ -82,6 +88,7 @@ describe('output contract', () => { it('keeps comment markers inside strings and quotes inside comments', () => { const cases = [ ['ts', `const url = "https://example.com" // "comment"`], + ['go', `url := "https://go.dev" // "comment"`], ['python', `value = "# not a comment" # "comment"`], ['shell', `echo "# not a comment" # "comment"`], ['yaml', `url: "https://example.com/#hash" # "comment"`], diff --git a/test/real-doc-fixtures.test.ts b/test/real-doc-fixtures.test.ts index f8480de..74242e4 100644 --- a/test/real-doc-fixtures.test.ts +++ b/test/real-doc-fixtures.test.ts @@ -11,12 +11,14 @@ type DocFixture = { } const fixtures = fixtureData.fixtures as Array +const languagesWithoutRealDocFixtures = new Set(['go']) describe('real TanStack docs fixtures', () => { - it('covers every normalized language target with sampled docs code', () => { + it('covers normalized language targets available in TanStack docs', () => { const fixtureLanguages = new Set(fixtures.map((fixture) => fixture.lang)) for (const language of listLanguages()) { + if (languagesWithoutRealDocFixtures.has(language)) continue expect(fixtureLanguages, `missing real docs fixture for ${language}`).toContain(language) } }) @@ -53,8 +55,9 @@ describe('real TanStack docs fixtures', () => { } } + const fixtureLanguages = new Set(fixtures.map((fixture) => fixture.lang)) for (const language of listLanguages()) { - if (language === 'plaintext') continue + if (language === 'plaintext' || !fixtureLanguages.has(language)) continue expect(highlightedLanguages, `${language} should highlight at least one real docs fixture`).toContain(language) } }) diff --git a/test/regressions.test.ts b/test/regressions.test.ts index 6671856..a8549a6 100644 --- a/test/regressions.test.ts +++ b/test/regressions.test.ts @@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest' import { createHighlighter } from '../src/core' import { css } from '../src/languages/css' import { dockerfile } from '../src/languages/dockerfile' +import { go } from '../src/languages/go' import { html } from '../src/languages/html' import { http } from '../src/languages/http' import { js } from '../src/languages/js' @@ -19,6 +20,7 @@ const highlighter = createHighlighter({ languages: [ css, dockerfile, + go, html, http, js, @@ -305,6 +307,46 @@ export function View() @{

Ready

}`, }) describe('docs language regressions', () => { + it('handles Go raw strings, runes, and numeric forms', () => { + const numbers = [ + '0b1010', + '0o755', + '0x1.fp2', + '1.', + '1.e2', + '1.e2i', + '.5', + '.5i', + '.5e2', + '.5e2i', + '1e2', + '1e2i', + '0x1.p2', + '0x.8p2', + '0x_1p2', + '0x1.p2i', + '1_000.5e-2i', + ] + const result = highlighter.tokenize( + [ + 'raw := `https://go.dev/a//b`', + "runeValue := '\\n'", + `values := []complex128{${numbers.join(', ')}}`, + '// done', + ].join('\n'), + { lang: 'go' }, + ) + + expect(exactClassesFor(result, '`https://go.dev/a//b`')).toEqual(['string']) + expect(exactClassesFor(result, "'\\n'")).toEqual(['string']) + expect(exactClassesFor(result, 'complex128')).toEqual(['type']) + for (const number of numbers) { + expect(exactClassesFor(result, number), number).toEqual(['number']) + } + expect(exactClassesFor(result, '// done')).toEqual(['comment']) + expect(reconstruct(result)).toBe(result.code) + }) + it('keeps Python triple strings together and highlights literals and numbers', () => { const result = highlighter.tokenize( 'text = """hello\nworld"""\nempty = None\nenabled = True\ncount = 42', diff --git a/test/themes.test.ts b/test/themes.test.ts index c2a9b49..5c963b8 100644 --- a/test/themes.test.ts +++ b/test/themes.test.ts @@ -9,6 +9,8 @@ import { auroraXTheme } from '../src/themes/aurora-x' import { draculaTheme } from '../src/themes/dracula' import { githubDarkTheme } from '../src/themes/github-dark' import { githubLightTheme } from '../src/themes/github-light' +import { gruvboxDarkTheme } from '../src/themes/gruvbox-dark' +import { gruvboxLightTheme } from '../src/themes/gruvbox-light' import { monokaiTheme } from '../src/themes/monokai' import { nordTheme } from '../src/themes/nord' import { oneDarkProTheme } from '../src/themes/one-dark-pro' @@ -20,6 +22,8 @@ const themes = [ draculaTheme, githubDarkTheme, githubLightTheme, + gruvboxDarkTheme, + gruvboxLightTheme, monokaiTheme, nordTheme, oneDarkProTheme, @@ -40,6 +44,11 @@ describe('themes', () => { } }) + it('ships Gruvbox with the medium contrast backgrounds', () => { + expect(gruvboxDarkTheme.background).toBe('#282828') + expect(gruvboxLightTheme.background).toBe('#fbf1c7') + }) + it('composes only the themes the caller passes', () => { const css = createThemeCss({ dark: draculaTheme,