From 38de760ca5dfbf1595c65c04d8e1751cfc395797 Mon Sep 17 00:00:00 2001 From: Alessio Gravili Date: Thu, 21 Nov 2024 16:53:29 -0700 Subject: [PATCH] feat(richtext-lexical): allow customizing maxActiveItems for toolbar groups (#9417) Previously, they were hardcoded to 1. This is useful for lexical toolbar groups where multiple items can be active at the same time. --- .../src/features/align/server/i18n.ts | 6 +++ .../src/features/blockquote/server/i18n.ts | 3 ++ .../src/features/blocks/server/i18n.ts | 9 +++++ .../src/features/heading/server/i18n.ts | 3 ++ .../features/horizontalRule/server/i18n.ts | 3 ++ .../src/features/indent/server/i18n.ts | 4 ++ .../src/features/link/server/i18n.ts | 4 ++ .../features/lists/checklist/server/i18n.ts | 3 ++ .../features/lists/orderedList/server/i18n.ts | 3 ++ .../lists/unorderedList/server/i18n.ts | 3 ++ .../src/features/paragraph/server/i18n.ts | 4 ++ .../src/features/relationship/server/i18n.ts | 3 ++ .../toolbars/fixed/client/Toolbar/index.tsx | 19 ++++++++-- .../toolbars/inline/client/Toolbar/index.tsx | 4 +- .../src/features/toolbars/types.ts | 9 +++++ .../src/features/upload/server/i18n.ts | 3 ++ packages/richtext-lexical/src/i18n.ts | 38 +++++++++++++++++++ 17 files changed, 115 insertions(+), 6 deletions(-) diff --git a/packages/richtext-lexical/src/features/align/server/i18n.ts b/packages/richtext-lexical/src/features/align/server/i18n.ts index fddd74b5d8a..3fce160de3b 100644 --- a/packages/richtext-lexical/src/features/align/server/i18n.ts +++ b/packages/richtext-lexical/src/features/align/server/i18n.ts @@ -25,6 +25,12 @@ export const i18n: Partial = { alignLeftLabel: 'Zarovnat vlevo', alignRightLabel: 'Zarovnat vpravo', }, + da: { + alignCenterLabel: 'Centrer teksten', + alignJustifyLabel: 'Justér til begge sider', + alignLeftLabel: 'Justér til venstre', + alignRightLabel: 'Juster til højre', + }, de: { alignCenterLabel: 'Zentrieren', alignJustifyLabel: 'Blocksatz', diff --git a/packages/richtext-lexical/src/features/blockquote/server/i18n.ts b/packages/richtext-lexical/src/features/blockquote/server/i18n.ts index 8b634a5e568..56a44b71118 100644 --- a/packages/richtext-lexical/src/features/blockquote/server/i18n.ts +++ b/packages/richtext-lexical/src/features/blockquote/server/i18n.ts @@ -13,6 +13,9 @@ export const i18n: Partial = { cs: { label: 'Citace', }, + da: { + label: 'Blokering', + }, de: { label: 'Blockzitat', }, diff --git a/packages/richtext-lexical/src/features/blocks/server/i18n.ts b/packages/richtext-lexical/src/features/blocks/server/i18n.ts index 4884f32dee1..2720003e588 100644 --- a/packages/richtext-lexical/src/features/blocks/server/i18n.ts +++ b/packages/richtext-lexical/src/features/blocks/server/i18n.ts @@ -37,6 +37,15 @@ export const i18n: Partial = { }, label: 'Bloky', }, + da: { + inlineBlocks: { + create: 'Opret {{label}}', + edit: 'Rediger {{label}}', + label: 'Indlejrede blokke', + remove: 'Fjern {{label}}', + }, + label: 'Blokke', + }, de: { inlineBlocks: { create: 'Erstelle {{label}}', diff --git a/packages/richtext-lexical/src/features/heading/server/i18n.ts b/packages/richtext-lexical/src/features/heading/server/i18n.ts index bb4d23942c4..8cefa5c662b 100644 --- a/packages/richtext-lexical/src/features/heading/server/i18n.ts +++ b/packages/richtext-lexical/src/features/heading/server/i18n.ts @@ -13,6 +13,9 @@ export const i18n: Partial = { cs: { label: 'Nadpis {{headingLevel}}', }, + da: { + label: 'Overskrift {{overskriftNiveau}}', + }, de: { label: 'Überschrift {{headingLevel}}', }, diff --git a/packages/richtext-lexical/src/features/horizontalRule/server/i18n.ts b/packages/richtext-lexical/src/features/horizontalRule/server/i18n.ts index ab7cbcc3276..6ff8e0a5140 100644 --- a/packages/richtext-lexical/src/features/horizontalRule/server/i18n.ts +++ b/packages/richtext-lexical/src/features/horizontalRule/server/i18n.ts @@ -13,6 +13,9 @@ export const i18n: Partial = { cs: { label: 'Vodorovný pravítko', }, + da: { + label: 'Horisontal Regel', + }, de: { label: 'Trennlinie', }, diff --git a/packages/richtext-lexical/src/features/indent/server/i18n.ts b/packages/richtext-lexical/src/features/indent/server/i18n.ts index 717e52fefeb..e9e4035ed6f 100644 --- a/packages/richtext-lexical/src/features/indent/server/i18n.ts +++ b/packages/richtext-lexical/src/features/indent/server/i18n.ts @@ -17,6 +17,10 @@ export const i18n: Partial = { decreaseLabel: 'Zmenšit odsazení', increaseLabel: 'Zvětšit odsazení', }, + da: { + decreaseLabel: 'Reducer Indrykning', + increaseLabel: 'Forøg indrykning', + }, de: { decreaseLabel: 'Einzug verkleinern', increaseLabel: 'Einzug erhöhen', diff --git a/packages/richtext-lexical/src/features/link/server/i18n.ts b/packages/richtext-lexical/src/features/link/server/i18n.ts index 8b88702b100..d78047e6406 100644 --- a/packages/richtext-lexical/src/features/link/server/i18n.ts +++ b/packages/richtext-lexical/src/features/link/server/i18n.ts @@ -17,6 +17,10 @@ export const i18n: Partial = { label: 'Odkaz', loadingWithEllipsis: 'Načítání...', }, + da: { + label: 'Link', + loadingWithEllipsis: 'Indlæser...', + }, de: { label: 'Verknüpfung', loadingWithEllipsis: 'Laden...', diff --git a/packages/richtext-lexical/src/features/lists/checklist/server/i18n.ts b/packages/richtext-lexical/src/features/lists/checklist/server/i18n.ts index 35bb015ca80..9dc5cdbcefd 100644 --- a/packages/richtext-lexical/src/features/lists/checklist/server/i18n.ts +++ b/packages/richtext-lexical/src/features/lists/checklist/server/i18n.ts @@ -13,6 +13,9 @@ export const i18n: Partial = { cs: { label: 'Seznam kontrol', }, + da: { + label: 'Tjekliste', + }, de: { label: 'Checkliste', }, diff --git a/packages/richtext-lexical/src/features/lists/orderedList/server/i18n.ts b/packages/richtext-lexical/src/features/lists/orderedList/server/i18n.ts index a7d0ae48f45..c3f9e22796a 100644 --- a/packages/richtext-lexical/src/features/lists/orderedList/server/i18n.ts +++ b/packages/richtext-lexical/src/features/lists/orderedList/server/i18n.ts @@ -13,6 +13,9 @@ export const i18n: Partial = { cs: { label: 'Seřazený seznam', }, + da: { + label: 'Ordnet Liste', + }, de: { label: 'Geordnete Liste', }, diff --git a/packages/richtext-lexical/src/features/lists/unorderedList/server/i18n.ts b/packages/richtext-lexical/src/features/lists/unorderedList/server/i18n.ts index 4294dc8a709..33a18dfe698 100644 --- a/packages/richtext-lexical/src/features/lists/unorderedList/server/i18n.ts +++ b/packages/richtext-lexical/src/features/lists/unorderedList/server/i18n.ts @@ -13,6 +13,9 @@ export const i18n: Partial = { cs: { label: 'Neuspořádaný seznam', }, + da: { + label: 'Usorteret Liste', + }, de: { label: 'Ungeordnete Liste', }, diff --git a/packages/richtext-lexical/src/features/paragraph/server/i18n.ts b/packages/richtext-lexical/src/features/paragraph/server/i18n.ts index 92bd12d2f09..ee0f9d8b582 100644 --- a/packages/richtext-lexical/src/features/paragraph/server/i18n.ts +++ b/packages/richtext-lexical/src/features/paragraph/server/i18n.ts @@ -17,6 +17,10 @@ export const i18n: Partial = { label: 'Odstavec', label2: 'Normální text', }, + da: { + label: 'Afsnit', + label2: 'Normal tekst', + }, de: { label: 'Paragraph', label2: 'Normaler Text', diff --git a/packages/richtext-lexical/src/features/relationship/server/i18n.ts b/packages/richtext-lexical/src/features/relationship/server/i18n.ts index f72593a827a..dcd4764dfbf 100644 --- a/packages/richtext-lexical/src/features/relationship/server/i18n.ts +++ b/packages/richtext-lexical/src/features/relationship/server/i18n.ts @@ -13,6 +13,9 @@ export const i18n: Partial = { cs: { label: 'Vztah', }, + da: { + label: 'Forhold', + }, de: { label: 'Beziehung', }, diff --git a/packages/richtext-lexical/src/features/toolbars/fixed/client/Toolbar/index.tsx b/packages/richtext-lexical/src/features/toolbars/fixed/client/Toolbar/index.tsx index a2e5b670002..8eb44f4511b 100644 --- a/packages/richtext-lexical/src/features/toolbars/fixed/client/Toolbar/index.tsx +++ b/packages/richtext-lexical/src/features/toolbars/fixed/client/Toolbar/index.tsx @@ -98,8 +98,19 @@ function ToolbarGroupComponent({ if (label.length > 25) { label = label.substring(0, 25) + '...' } - setDropdownLabel(label) - setDropdownIcon(() => item.ChildComponent) + if (activeItems.length === 1) { + setDropdownLabel(label) + setDropdownIcon(() => item.ChildComponent) + } else { + setDropdownLabel( + i18n.t('lexical:general:toolbarItemsActive', { count: activeItems.length }), + ) + if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) { + setDropdownIcon(() => group.ChildComponent!) + } else { + setDropdownIcon(undefined) + } + } }, [group, i18n, featureClientSchemaMap, schemaPath], ) @@ -115,7 +126,7 @@ function ToolbarGroupComponent({ Icon={DropdownIcon} itemsContainerClassNames={['fixed-toolbar__dropdown-items']} label={dropdownLabel} - maxActiveItems={1} + maxActiveItems={group.maxActiveItems ?? 1} onActiveChange={onActiveChange} /> ) : ( @@ -125,7 +136,7 @@ function ToolbarGroupComponent({ group={group} itemsContainerClassNames={['fixed-toolbar__dropdown-items']} label={dropdownLabel} - maxActiveItems={1} + maxActiveItems={group.maxActiveItems ?? 1} onActiveChange={onActiveChange} /> ) diff --git a/packages/richtext-lexical/src/features/toolbars/inline/client/Toolbar/index.tsx b/packages/richtext-lexical/src/features/toolbars/inline/client/Toolbar/index.tsx index 59a834b7942..c160cf77656 100644 --- a/packages/richtext-lexical/src/features/toolbars/inline/client/Toolbar/index.tsx +++ b/packages/richtext-lexical/src/features/toolbars/inline/client/Toolbar/index.tsx @@ -102,7 +102,7 @@ function ToolbarGroupComponent({ editor={editor} group={group} Icon={DropdownIcon} - maxActiveItems={1} + maxActiveItems={group.maxActiveItems ?? 1} onActiveChange={onActiveChange} /> ) : ( @@ -110,7 +110,7 @@ function ToolbarGroupComponent({ anchorElem={anchorElem} editor={editor} group={group} - maxActiveItems={1} + maxActiveItems={group.maxActiveItems ?? 1} onActiveChange={onActiveChange} /> ) diff --git a/packages/richtext-lexical/src/features/toolbars/types.ts b/packages/richtext-lexical/src/features/toolbars/types.ts index 393647bc378..600049ee622 100644 --- a/packages/richtext-lexical/src/features/toolbars/types.ts +++ b/packages/richtext-lexical/src/features/toolbars/types.ts @@ -32,6 +32,15 @@ export type ToolbarDropdownGroup = { * Each toolbar group needs to have a unique key. Groups with the same keys will have their items merged together. */ key: string + /** + * The maximum number of active items that can be selected at once. + * Increasing this will hurt performance, as more nodes need to be checked for their active state. + * + * E.g. if this is 1, we can stop checking nodes once we find an active node. + * + * @default 1 + */ + maxActiveItems?: number /** * Determines where the toolbar group will be. */ diff --git a/packages/richtext-lexical/src/features/upload/server/i18n.ts b/packages/richtext-lexical/src/features/upload/server/i18n.ts index a167bbdd274..d6da11dcad6 100644 --- a/packages/richtext-lexical/src/features/upload/server/i18n.ts +++ b/packages/richtext-lexical/src/features/upload/server/i18n.ts @@ -13,6 +13,9 @@ export const i18n: Partial = { cs: { label: 'Nahrát', }, + da: { + label: 'Upload', + }, de: { label: 'Datei', }, diff --git a/packages/richtext-lexical/src/i18n.ts b/packages/richtext-lexical/src/i18n.ts index d3024961690..b273e4a8adb 100644 --- a/packages/richtext-lexical/src/i18n.ts +++ b/packages/richtext-lexical/src/i18n.ts @@ -5,160 +5,198 @@ export const i18n: Partial = { placeholder: "ابدأ بالكتابة، أو اضغط على '/' للأوامر ...", slashMenuBasicGroupLabel: 'أساسي', slashMenuListGroupLabel: 'قوائم', + toolbarItemsActive: '{{count}} نشط', }, az: { placeholder: "Yazmağa başlayın və ya əmrlər üçün '/' düyməsini basın...", slashMenuBasicGroupLabel: 'Əsas', slashMenuListGroupLabel: 'Siyahılar', + toolbarItemsActive: '{{count}} aktiv', }, bg: { placeholder: "Започнете да пишете или натиснете '/' за команди...", slashMenuBasicGroupLabel: 'Основен', slashMenuListGroupLabel: 'Списъци', + toolbarItemsActive: '{{count}} активни', }, cs: { placeholder: "Začněte psát nebo stiskněte '/' pro příkazy...", slashMenuBasicGroupLabel: 'Základní', slashMenuListGroupLabel: 'Seznamy', + toolbarItemsActive: '{{count}} aktivní', + }, + da: { + placeholder: "Begynd at skrive, eller tryk på '/' for kommandoer...", + slashMenuBasicGroupLabel: 'Grundlæggende', + slashMenuListGroupLabel: 'Lister', + toolbarItemsActive: '{{count}} aktive', }, de: { placeholder: "Beginne zu tippen oder drücke '/' für Befehle...", slashMenuBasicGroupLabel: 'Basis', slashMenuListGroupLabel: 'Listen', + toolbarItemsActive: '{{count}} aktiv', }, en: { placeholder: "Start typing, or press '/' for commands...", slashMenuBasicGroupLabel: 'Basic', slashMenuListGroupLabel: 'Lists', + toolbarItemsActive: '{{count}} active', }, es: { placeholder: "Comience a escribir, o presione '/' para comandos...", slashMenuBasicGroupLabel: 'Básico', slashMenuListGroupLabel: 'Listas', + toolbarItemsActive: '{{count}} activo', }, fa: { placeholder: "شروع به تایپ کنید، یا برای دستورات '/' را فشار دهید ...", slashMenuBasicGroupLabel: 'پایه', slashMenuListGroupLabel: 'لیست ها', + toolbarItemsActive: '{{count}} فعال', }, fr: { placeholder: "Commencez à taper, ou appuyez sur '/' pour les commandes...", slashMenuBasicGroupLabel: 'De base', slashMenuListGroupLabel: 'Listes', + toolbarItemsActive: '{{count}} actif', }, he: { placeholder: "התחיל להקליד, או לחץ על '/' עבור פקודות ...", slashMenuBasicGroupLabel: 'בסיסי', slashMenuListGroupLabel: 'רשימות', + toolbarItemsActive: '{{count}} פעיל', }, hr: { placeholder: "Počnite tipkati, ili pritisnite '/' za naredbe...", slashMenuBasicGroupLabel: 'Osnovno', slashMenuListGroupLabel: 'Popisi', + toolbarItemsActive: '{{count}} aktivno', }, hu: { placeholder: "Kezdje el gépelni, vagy nyomja meg a '/' billentyűt a parancsokhoz...", slashMenuBasicGroupLabel: 'Alapvető', slashMenuListGroupLabel: 'Listák', + toolbarItemsActive: '{{count}} aktív', }, it: { placeholder: "Inizia a digitare, oppure premi '/' per i comandi...", slashMenuBasicGroupLabel: 'Base', slashMenuListGroupLabel: 'Elenchi', + toolbarItemsActive: '{{count}} attivo', }, ja: { placeholder: "入力を開始するか、コマンドのために'/'を押してください…", slashMenuBasicGroupLabel: '基本的な', slashMenuListGroupLabel: 'リスト', + toolbarItemsActive: '{{count}} アクティブ', }, ko: { placeholder: "타이핑을 시작하거나, 명령어를 입력하려면 '/'를 누르세요...", slashMenuBasicGroupLabel: '기본적인', slashMenuListGroupLabel: '목록', + toolbarItemsActive: '{{count}} 활성화된', }, my: { placeholder: "Mula menaip, atau tekan '/' untuk arahan...", slashMenuBasicGroupLabel: 'အခြေခံ', slashMenuListGroupLabel: 'Senarai', + toolbarItemsActive: '{{count}} aktif', }, nb: { placeholder: "Begynn å skrive, eller trykk '/' for kommandoer...", slashMenuBasicGroupLabel: 'Grunnleggende', slashMenuListGroupLabel: 'Lister', + toolbarItemsActive: '{{count}} aktiv', }, nl: { placeholder: "Begin met typen, of druk op '/' voor opdrachten...", slashMenuBasicGroupLabel: 'Basis', slashMenuListGroupLabel: 'Lijsten', + toolbarItemsActive: '{{count}} actief', }, pl: { placeholder: "Rozpocznij pisanie lub naciśnij '/' dla poleceń...", slashMenuBasicGroupLabel: 'Podstawowy', slashMenuListGroupLabel: 'Listy', + toolbarItemsActive: '{{count}} aktywny', }, pt: { placeholder: "Comece a digitar, ou pressione '/' para comandos...", slashMenuBasicGroupLabel: 'Básico', slashMenuListGroupLabel: 'Listas', + toolbarItemsActive: '{{count}} ativo', }, ro: { placeholder: "Începeți să tastați sau apăsați '/' pentru comenzi...", slashMenuBasicGroupLabel: 'De bază', slashMenuListGroupLabel: 'Liste', + toolbarItemsActive: '{{count}} activ', }, rs: { placeholder: "Počnite da kucate, ili pritisnite '/' za komande...", slashMenuBasicGroupLabel: 'Osnovno', slashMenuListGroupLabel: 'Liste', + toolbarItemsActive: '{{count}} aktivno', }, 'rs-latin': { placeholder: "Počnite da kucate, ili pritisnite '/' za komande...", slashMenuBasicGroupLabel: 'Osnovno', slashMenuListGroupLabel: 'Liste', + toolbarItemsActive: '{{count}} aktivan', }, ru: { placeholder: "Начните печатать или нажмите '/' для команд...", slashMenuBasicGroupLabel: 'Базовый', slashMenuListGroupLabel: 'Списки', + toolbarItemsActive: '{{count}} активных', }, sk: { placeholder: "Začnite písať alebo stlačte '/' pre príkazy...", slashMenuBasicGroupLabel: 'Základný', slashMenuListGroupLabel: 'Zoznamy', + toolbarItemsActive: '{{count}} aktívne', }, sv: { placeholder: "Börja skriva, eller tryck på '/' för kommandon...", slashMenuBasicGroupLabel: 'Grundläggande', slashMenuListGroupLabel: 'Listor', + toolbarItemsActive: '{{count}} aktiv', }, th: { placeholder: "เริ่มพิมพ์หรือกด '/' สำหรับคำสั่ง...", slashMenuBasicGroupLabel: 'พื้นฐาน', slashMenuListGroupLabel: 'รายการ', + toolbarItemsActive: '{{count}} ที่ใช้งานอยู่', }, tr: { placeholder: "Yazmaya başlayın veya komutlar için '/' tuşuna basın...", slashMenuBasicGroupLabel: 'Temel', slashMenuListGroupLabel: 'Listeler', + toolbarItemsActive: '{{count}} aktif', }, uk: { placeholder: "Почніть друкувати, або натисніть '/' для команд...", slashMenuBasicGroupLabel: 'Базовий', slashMenuListGroupLabel: 'Списки', + toolbarItemsActive: '{{count}} активний', }, vi: { placeholder: "Bắt đầu gõ, hoặc nhấn '/' để gọi lệnh...", slashMenuBasicGroupLabel: 'Cơ bản', slashMenuListGroupLabel: 'Danh sách', + toolbarItemsActive: '{{count}} đang hoạt động', }, zh: { placeholder: "开始输入,或按'/'进行命令...", slashMenuBasicGroupLabel: '基础', slashMenuListGroupLabel: '列表', + toolbarItemsActive: '{{count}} 活跃', }, 'zh-TW': { placeholder: "開始輸入,或按'/'以使用命令...", slashMenuBasicGroupLabel: '基本的', slashMenuListGroupLabel: '清單', + toolbarItemsActive: '{{count}} 活躍中', }, }