feat: Typst → LaTeX import, and fix export button visibility
Build and Deploy Verso / deploy (push) Successful in 1m14s

Typst → LaTeX import:
- CLSI ConversionManager: add 'typst' to CONVERSION_CONFIGS
  (pandoc input.typ --from typst --to latex --standalone → zip archive)
- Web controller: allow 'typst' as a valid importDocument conversion type
- Frontend modal: add .typ file config to ImportDocumentModal
- New project button modal: add 'import_typst' variant + switch case
- New project button: show "Import Typst file" when enablePandocConversions
  is true (no split test gate — Verso has no SaaS split test infra)
- Locales: add choose_typst_file and import_typst_file keys (18 locales)

Export button fix:
- Remove featureFlag="export-typst" from ExportProjectWithConversionButton
  so the button shows whenever enablePandocConversions is true, without
  needing an unconfigured split test to return 'enabled'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
claude
2026-06-17 08:54:54 +00:00
parent 15ffaefb87
commit 9d11683920
24 changed files with 88 additions and 16 deletions
@@ -16,6 +16,10 @@ const CONVERSION_CONFIGS = {
inputFilename: 'input.md',
pandocArgs: ['--from', 'markdown'],
},
typst: {
inputFilename: 'input.typ',
pandocArgs: ['--from', 'typst'],
},
}
const PDF_TO_JPEG_CONFIGS = {
@@ -196,7 +196,7 @@ async function importDocument(req, res, next) {
const userId = SessionManager.getLoggedInUserId(req.session)
const { path } = req.file
const conversionType = req.query.type
if (!['docx', 'markdown'].includes(conversionType)) {
if (!['docx', 'markdown', 'typst'].includes(conversionType)) {
return res.status(400).json({
success: false,
error: req.i18n.translate('invalid_import_type'),
@@ -96,7 +96,6 @@ export const ToolbarProjectTitle = () => {
menuBarId="export-as-html"
/>
<ExportProjectWithConversionButton
featureFlag="export-typst"
conversionType="typst"
label={t('export_as_typst')}
menuBarId="export-as-typst"
@@ -67,6 +67,7 @@ function NewProjectButton({
const markdownImportEnabled =
useFeatureFlag('import-markdown') &&
getMeta('ol-ExposedSettings').enablePandocConversions
const typstImportEnabled = getMeta('ol-ExposedSettings').enablePandocConversions
const { selectedTagId, tags } = useProjectListContext()
const isLibraryEnabled = isSplitTestEnabled('overleaf-library')
const initialTags =
@@ -302,6 +303,21 @@ function NewProjectButton({
</DropdownItem>
</li>
)}
{typstImportEnabled && (
<li role="none">
<DropdownItem
onClick={e =>
handleModalMenuClick(e, {
modalVariant: 'import_typst',
dropdownMenuEvent: 'import-typst',
})
}
trailingIcon={<MaterialIcon type="fiber_new" />}
>
{t('import_typst_file')}
</DropdownItem>
</li>
)}
<li role="none">
{ImportProjectFromGithubMenu && (
<ImportProjectFromGithubMenu
@@ -19,7 +19,7 @@ function ImportDocumentModal({
onHide,
openProject,
}: {
type: 'docx' | 'markdown'
type: 'docx' | 'markdown' | 'typst'
onHide: () => void
openProject: (id: string, convertedFrom?: string) => void
}) {
@@ -39,6 +39,12 @@ function ImportDocumentModal({
browseLabel: 'Select .md file',
dragLabel: '%{browseFiles} or \n\n Drag .md file',
},
typst: {
allowedFileTypes: ['.typ'],
title: t('choose_typst_file'),
browseLabel: 'Select .typ file',
dragLabel: '%{browseFiles} or \n\n Drag .typ file',
},
}),
[t]
)
@@ -21,6 +21,7 @@ export type NewProjectButtonModalVariant =
| 'import_from_github'
| 'import_docx'
| 'import_markdown'
| 'import_typst'
type NewProjectButtonModalProps = {
modal: Nullable<NewProjectButtonModalVariant>
@@ -128,6 +129,16 @@ function NewProjectButtonModal({
/>
</Suspense>
)
case 'import_typst':
return (
<Suspense fallback={<FullSizeLoadingSpinner delay={500} />}>
<ImportDocumentModal
type="typst"
onHide={onHide}
openProject={openProject}
/>
</Suspense>
)
case 'import_from_github':
return <ImportProjectFromGithubModalWrapper onHide={onHide} />
default:
+3 -1
View File
@@ -340,5 +340,7 @@
"top_bottom_split_view": "Horní/dolní rozdělené zobrazení",
"your_subscriptions": "Vaše předplatná",
"editor_settings": "Nastavení editoru",
"export_as_typst": "Exportovat jako Typst"
"export_as_typst": "Exportovat jako Typst",
"choose_typst_file": "Vyberte soubor Typst",
"import_typst_file": "Importovat soubor Typst"
}
+3 -1
View File
@@ -2168,5 +2168,7 @@
"top_bottom_split_view": "Øverste/nedre delt visning",
"zotero_sync_description": "Via Zotero-integrationen kan du importere dine referencer fra Zotero ind i dine __appName__-projekter.",
"editor_settings": "Editorindstillinger",
"export_as_typst": "Eksportér som Typst"
"export_as_typst": "Eksportér som Typst",
"choose_typst_file": "Vælg Typst-fil",
"import_typst_file": "Importér Typst-fil"
}
+2
View File
@@ -403,6 +403,7 @@
"choose_from_group_members": "Wählen Sie aus Gruppenmitgliedern",
"choose_how_you_search_your_references": "Wählen Sie, wie Sie nach Ihren Referenzen suchen",
"choose_markdown_file": "Wählen Sie Markdown-Datei",
"choose_typst_file": "Typst-Datei auswählen",
"choose_which_experiments": "Wählen Sie aus, welche Experimente Sie ausprobieren möchten.",
"choose_word_document": "Wählen Sie Word-Dokument",
"choose_your_plan": "Wähle deinen Kontotyp",
@@ -1246,6 +1247,7 @@
"import_from_github": "Von GitHub importieren",
"import_idp_metadata": "IdP-Metadaten importieren",
"import_markdown_file": "Markdown-Datei importieren",
"import_typst_file": "Typst-Datei importieren",
"import_to_sharelatex": "In __appName__ importieren",
"import_word_document": "Word-Dokument importieren",
"important_message": "Wichtige Nachricht",
+2
View File
@@ -393,6 +393,7 @@
"choose_from_group_members": "Choose from group members",
"choose_how_you_search_your_references": "Choose how you search your references",
"choose_markdown_file": "Choose Markdown file",
"choose_typst_file": "Choose Typst file",
"choose_which_experiments": "Choose which experiments youd like to try.",
"choose_word_document": "Choose Word document",
"choose_your_plan": "Choose your plan",
@@ -1229,6 +1230,7 @@
"import_from_github": "Import from GitHub",
"import_idp_metadata": "Import IdP metadata",
"import_markdown_file": "Import Markdown file",
"import_typst_file": "Import Typst file",
"import_to_sharelatex": "Import to __appName__",
"import_word_document": "Import Word document",
"important_message": "Important message",
+2
View File
@@ -394,6 +394,7 @@
"choose_from_group_members": "Elija entre los miembros del grupo",
"choose_how_you_search_your_references": "Elige cómo buscas tus referencias",
"choose_markdown_file": "Elija el archivo Markdown",
"choose_typst_file": "Elegir archivo Typst",
"choose_which_experiments": "Elija qué experimentos le gustaría probar.",
"choose_word_document": "Elija un documento de Word",
"choose_your_plan": "Elige tu plan",
@@ -1230,6 +1231,7 @@
"import_from_github": "Importar desde GitHub",
"import_idp_metadata": "Importar metadatos de IdP",
"import_markdown_file": "Importar archivo Markdown",
"import_typst_file": "Importar archivo Typst",
"import_to_sharelatex": "Importa a __appName__",
"import_word_document": "Importar documento de Word",
"important_message": "Mensaje importante",
+3 -1
View File
@@ -346,5 +346,7 @@
"top_bottom_split_view": "Ylä/alakerros jaettu näkymä",
"zh-CN": "Kiina",
"editor_settings": "Editorin asetukset",
"export_as_typst": "Vie Typst-muotoon"
"export_as_typst": "Vie Typst-muotoon",
"choose_typst_file": "Valitse Typst-tiedosto",
"import_typst_file": "Tuo Typst-tiedosto"
}
+2
View File
@@ -394,6 +394,7 @@
"choose_from_group_members": "Choisissez parmi les membres du groupe",
"choose_how_you_search_your_references": "Choisissez comment vous recherchez vos références",
"choose_markdown_file": "Choisissez le fichier Markdown",
"choose_typst_file": "Choisir un fichier Typst",
"choose_which_experiments": "Choisissez les expériences que vous souhaitez essayer.",
"choose_word_document": "Choisissez un document Word",
"choose_your_plan": "Choisir votre offre",
@@ -1232,6 +1233,7 @@
"import_from_github": "Importer depuis GitHub",
"import_idp_metadata": "Importer les métadonnées IdP",
"import_markdown_file": "Importer le fichier Markdown",
"import_typst_file": "Importer un fichier Typst",
"import_to_sharelatex": "Importer dans __appName__",
"import_word_document": "Importer un document Word",
"important_message": "Message important",
+2
View File
@@ -393,6 +393,7 @@
"choose_from_group_members": "Scegli tra i membri del gruppo",
"choose_how_you_search_your_references": "Scegli come cercare i tuoi riferimenti",
"choose_markdown_file": "Scegli il file Markdown",
"choose_typst_file": "Scegli file Typst",
"choose_which_experiments": "Scegli quali esperimenti desideri provare.",
"choose_word_document": "Scegli il documento Word",
"choose_your_plan": "Scegli il tuo piano",
@@ -1229,6 +1230,7 @@
"import_from_github": "Importa da GitHub",
"import_idp_metadata": "Importa metadati IdP",
"import_markdown_file": "Importa il file Markdown",
"import_typst_file": "Importa file Typst",
"import_to_sharelatex": "Importa in __appName__",
"import_word_document": "Importa documento Word",
"important_message": "Messaggio importante",
+3 -1
View File
@@ -490,5 +490,7 @@
"top_bottom_split_view": "上下分割ビュー",
"zotero_sync_description": "Zoteroを統合すると、Zoteroから__appName__プロジェクトにリファレンスをインポートすることができます。",
"editor_settings": "エディタ設定",
"export_as_typst": "Typstとしてエクスポート"
"export_as_typst": "Typstとしてエクスポート",
"choose_typst_file": "Typstファイルを選択",
"import_typst_file": "Typstファイルをインポート"
}
+3 -1
View File
@@ -551,5 +551,7 @@
"top_bottom_split_view": "상하 분할 보기",
"zh-CN": "中國語",
"editor_settings": "편집기 설정",
"export_as_typst": "Typst로 내보내기"
"export_as_typst": "Typst로 내보내기",
"choose_typst_file": "Typst 파일 선택",
"import_typst_file": "Typst 파일 가져오기"
}
+3 -1
View File
@@ -561,5 +561,7 @@
"top_bottom_split_view": "Boven/onder gesplitst",
"zotero_reference_loading_error_forbidden": "Kon referenties niet laden vanaf Zotero, gelieve je account opnieuw te koppelen en nogmaals te proberen",
"editor_settings": "Editor-instellingen",
"export_as_typst": "Exporteren als Typst"
"export_as_typst": "Exporteren als Typst",
"choose_typst_file": "Kies Typst-bestand",
"import_typst_file": "Typst-bestand importeren"
}
+3 -1
View File
@@ -392,5 +392,7 @@
"top_bottom_split_view": "Øvre/nedre delt visning",
"zh-CN": "Kinesisk",
"editor_settings": "Redaktørinnstillinger",
"export_as_typst": "Eksporter som Typst"
"export_as_typst": "Eksporter som Typst",
"choose_typst_file": "Velg Typst-fil",
"import_typst_file": "Importer Typst-fil"
}
+3 -1
View File
@@ -231,5 +231,7 @@
"top_bottom_split_view": "Widok podzielony góra/dół",
"your_subscriptions": "Twoje subskrypcje",
"editor_settings": "Ustawienia edytora",
"export_as_typst": "Eksportuj jako Typst"
"export_as_typst": "Eksportuj jako Typst",
"choose_typst_file": "Wybierz plik Typst",
"import_typst_file": "Importuj plik Typst"
}
+3 -1
View File
@@ -661,5 +661,7 @@
"top_bottom_split_view": "Divisão superior/inferior",
"zotero_sync_description": "A integração Zotero permite você importar as referências do zotero para seus projetos no __appName__.",
"editor_settings": "Configurações do editor",
"export_as_typst": "Exportar como Typst"
"export_as_typst": "Exportar como Typst",
"choose_typst_file": "Escolher arquivo Typst",
"import_typst_file": "Importar arquivo Typst"
}
+3 -1
View File
@@ -466,5 +466,7 @@
"top_bottom_split_view": "Разделить сверху/снизу",
"zh-CN": "Китайский",
"editor_settings": "Настройки редактора",
"export_as_typst": "Экспорт в Typst"
"export_as_typst": "Экспорт в Typst",
"choose_typst_file": "Выберите файл Typst",
"import_typst_file": "Импорт файла Typst"
}
+3 -1
View File
@@ -938,5 +938,7 @@
"top_bottom_split_view": "Övre/nedre delad vy",
"zotero_sync_description": "Med Zotero integrering kan du importera dina referenser direkt från Zotero till ditt __appName__ projekt.",
"editor_settings": "Editorinställningar",
"export_as_typst": "Exportera som Typst"
"export_as_typst": "Exportera som Typst",
"choose_typst_file": "Välj Typst-fil",
"import_typst_file": "Importera Typst-fil"
}
+3 -1
View File
@@ -378,5 +378,7 @@
"top_bottom_split_view": "Yukarı/aşağı bölünmüş görünüm",
"zh-CN": "Çince",
"editor_settings": "Düzenleyici ayarları",
"export_as_typst": "Typst olarak dışa aktar"
"export_as_typst": "Typst olarak dışa aktar",
"choose_typst_file": "Typst dosyası seç",
"import_typst_file": "Typst dosyasını içe aktar"
}
+3 -1
View File
@@ -2534,5 +2534,7 @@
"zotero_sync_description": "集成 Zotero 后,您可以将 Zotero 的参考文献导入__appName__项目。",
"zotero_upgrade_prompt_content": "关联您的 Zotero 帐户,即可直接在项目中搜索并添加 Zotero 中的参考文献——它们将自动添加到您的 .bib 文件中。或者,您也可以将它们作为文件导入到您的 __appName__ 项目中。",
"zotero_upgrade_prompt_title": "引用自 Zotero",
"export_as_typst": "导出为 Typst"
"export_as_typst": "导出为 Typst",
"choose_typst_file": "选择 Typst 文件",
"import_typst_file": "导入 Typst 文件"
}