Files
Verso/services/web/frontend/js/features/settings/components/compiler-settings/compiler-setting.tsx
T
claudeandClaude Opus 4.8 4fc86ebd3d
Build and Deploy Verso / deploy (push) Successful in 9m48s
Editor: qmd/typst autocomplete, format column, compiler gating, Verso loader
- Add a Typst language (stream highlighting + completions) for .typ, and
  Quarto completions (code chunks, callouts, cross-refs) for .qmd/markdown.
- Project dashboard: new Format column (Quarto/Typst/LaTeX) from the cheap
  project compiler field, surfaced through the projects list API.
- Compiler dropdown: grey out engines that don't match the root file's
  extension (.qmd->Quarto, .typ->Typst, .tex->LaTeX engines).
- Replace the Overleaf fill loader with an animated Verso logo: the four
  quadrant circles drift on their own orbits while colour warms up with load
  progress; reused on the token-access screen too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 07:47:31 +00:00

76 lines
2.8 KiB
TypeScript

import { useMemo, useState } from 'react'
import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context'
import DropdownSetting from '../dropdown-setting'
import type { Option } from '../dropdown-setting'
import { useTranslation } from 'react-i18next'
import { usePermissionsContext } from '@/features/ide-react/context/permissions-context'
import { ProjectCompiler } from '@ol-types/project-settings'
import { useSetCompilationSettingWithEvent } from '@/features/editor-left-menu/hooks/use-set-compilation-setting'
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
// Which compiler engines make sense for a given root-file extension. CLSI
// dispatches the real engine from this extension (.qmd → Quarto, .typ → Typst,
// .tex → latexmk), so offering, say, XeLaTeX for a .qmd root is meaningless.
const ENGINES_BY_EXTENSION: Record<string, ProjectCompiler[]> = {
tex: ['pdflatex', 'latex', 'xelatex', 'lualatex'],
qmd: ['quarto'],
rmd: ['quarto'],
typ: ['typst'],
}
function getCompilerOptions(): Option<ProjectCompiler>[] {
return [
{ value: 'quarto', label: 'Quarto' },
{ value: 'typst', label: 'Typst' },
{ value: 'pdflatex', label: 'pdfLaTeX' },
{ value: 'latex', label: 'LaTeX' },
{ value: 'xelatex', label: 'XeLaTeX' },
{ value: 'lualatex', label: 'LuaLaTeX' },
]
}
export default function CompilerSetting() {
const { compiler, setCompiler, rootDocId } = useProjectSettingsContext()
const [compilerOptions] = useState(() => getCompilerOptions())
const { t } = useTranslation()
const { write } = usePermissionsContext()
const { docs } = useFileTreeData()
const changeCompiler = useSetCompilationSettingWithEvent(
'compiler',
setCompiler
)
// Disable the engines that don't apply to the current root file's extension.
// The currently-selected engine is always left enabled so it keeps showing.
const options = useMemo(() => {
const rootDoc = rootDocId
? docs?.find(doc => doc.doc.id === rootDocId)
: undefined
const extension = rootDoc?.doc.name.split('.').pop()?.toLowerCase()
const allowed = extension ? ENGINES_BY_EXTENSION[extension] : undefined
if (!allowed) {
// Unknown / no root file: don't restrict anything.
return compilerOptions
}
return compilerOptions.map(option => ({
...option,
disabled: !allowed.includes(option.value) && option.value !== compiler,
}))
}, [compilerOptions, docs, rootDocId, compiler])
return (
<DropdownSetting
id="compiler"
label={t('compiler')}
description={t('the_latex_engine_used_for_compiling')}
disabled={!write}
options={options}
onChange={changeCompiler}
value={compiler}
translateOptions="no"
/>
)
}