From 93e4c1207da2d8bce9a2391497d0d26b692e9342 Mon Sep 17 00:00:00 2001
From: Drew Johnson
Date: Mon, 21 Apr 2025 20:21:47 -0400
Subject: [PATCH 01/13] Adding H4/H5 blocks
---
.../HeadingBlockContent.ts | 102 ++++++------------
packages/core/src/editor/Block.css | 12 +++
packages/core/src/editor/editor.css | 2 +
3 files changed, 44 insertions(+), 72 deletions(-)
diff --git a/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts b/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts
index 2b95fbf5ab..a0b070623a 100644
--- a/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts
+++ b/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts
@@ -10,9 +10,11 @@ import {
import { createDefaultBlockDOMOutputSpec } from "../defaultBlockHelpers.js";
import { defaultProps } from "../defaultProps.js";
+const HEADING_LEVELS = [1, 2, 3, 4, 5] as const;
+
export const headingPropSchema = {
...defaultProps,
- level: { default: 1, values: [1, 2, 3] as const },
+ level: { default: 1, values: HEADING_LEVELS },
} satisfies PropSchema;
const HeadingBlockContent = createStronglyTypedTiptapNode({
@@ -26,7 +28,7 @@ const HeadingBlockContent = createStronglyTypedTiptapNode({
addInputRules() {
return [
- ...[1, 2, 3].map((level) => {
+ ...HEADING_LEVELS.map((level) => {
// Creates a heading of appropriate level when starting with "#", "##", or "###".
return new InputRule({
find: new RegExp(`^(#{${level}})\\s$`),
@@ -58,84 +60,40 @@ const HeadingBlockContent = createStronglyTypedTiptapNode({
},
addKeyboardShortcuts() {
- return {
- "Mod-Alt-1": () => {
- const blockInfo = getBlockInfoFromSelection(this.editor.state);
- if (
- !blockInfo.isBlockContainer ||
- blockInfo.blockContent.node.type.spec.content !== "inline*"
- ) {
- return true;
- }
-
- // call updateBlockCommand
- return this.editor.commands.command(
- updateBlockCommand(blockInfo.bnBlock.beforePos, {
- type: "heading",
- props: {
- level: 1 as any,
- },
- })
- );
- },
- "Mod-Alt-2": () => {
- const blockInfo = getBlockInfoFromSelection(this.editor.state);
- if (
- !blockInfo.isBlockContainer ||
- blockInfo.blockContent.node.type.spec.content !== "inline*"
- ) {
- return true;
- }
-
- return this.editor.commands.command(
- updateBlockCommand(blockInfo.bnBlock.beforePos, {
- type: "heading",
- props: {
- level: 2 as any,
- },
- })
- );
- },
- "Mod-Alt-3": () => {
- const blockInfo = getBlockInfoFromSelection(this.editor.state);
- if (
- !blockInfo.isBlockContainer ||
- blockInfo.blockContent.node.type.spec.content !== "inline*"
- ) {
- return true;
- }
+ return Object.fromEntries(
+ HEADING_LEVELS.map((level) => [
+ `Mod-Alt-${level}`,
+ () => {
+ const blockInfo = getBlockInfoFromSelection(this.editor.state);
+ if (
+ !blockInfo.isBlockContainer ||
+ blockInfo.blockContent.node.type.spec.content !== "inline*"
+ ) {
+ return true;
+ }
- return this.editor.commands.command(
- updateBlockCommand(blockInfo.bnBlock.beforePos, {
- type: "heading",
- props: {
- level: 3 as any,
- },
- })
- );
- },
- };
+ return this.editor.commands.command(
+ updateBlockCommand(blockInfo.bnBlock.beforePos, {
+ type: "heading",
+ props: {
+ level: level as any,
+ },
+ })
+ );
+ },
+ ])
+ );
},
parseHTML() {
return [
{
tag: "div[data-content-type=" + this.name + "]",
},
- {
- tag: "h1",
- attrs: { level: 1 },
+ ...HEADING_LEVELS.map((level) => ({
+ tag: `h${level}`,
+ attrs: { level },
node: "heading",
- },
- {
- tag: "h2",
- attrs: { level: 2 },
- node: "heading",
- },
- {
- tag: "h3",
- attrs: { level: 3 },
- node: "heading",
- },
+ })),
];
},
diff --git a/packages/core/src/editor/Block.css b/packages/core/src/editor/Block.css
index 2bff2395b4..69844b5a39 100644
--- a/packages/core/src/editor/Block.css
+++ b/packages/core/src/editor/Block.css
@@ -127,6 +127,12 @@ NESTED BLOCKS
[data-content-type="heading"][data-level="3"] {
--level: 1.3em;
}
+[data-content-type="heading"][data-level="4"] {
+ --level: 1em;
+}
+[data-content-type="heading"][data-level="5"] {
+ --level: 0.8em;
+}
[data-prev-level="1"] {
--prev-level: 3em;
@@ -137,6 +143,12 @@ NESTED BLOCKS
[data-prev-level="3"] {
--prev-level: 1.3em;
}
+[data-prev-level="4"] {
+ --prev-level: 1em;
+}
+[data-prev-level="5"] {
+ --prev-level: 0.9em;
+}
.bn-block-outer[data-prev-type="heading"] > .bn-block > .bn-block-content {
font-size: var(--prev-level);
diff --git a/packages/core/src/editor/editor.css b/packages/core/src/editor/editor.css
index 0f5c486337..76bfd253a1 100644
--- a/packages/core/src/editor/editor.css
+++ b/packages/core/src/editor/editor.css
@@ -44,6 +44,8 @@ Tippy popups that are appended to document.body directly
.bn-default-styles h1,
.bn-default-styles h2,
.bn-default-styles h3,
+.bn-default-styles h4,
+.bn-default-styles h5,
.bn-default-styles li {
margin: 0;
padding: 0;
From 4c893f5d70d9fe3ebefaafce8ba539fe8cfee458 Mon Sep 17 00:00:00 2001
From: Drew Johnson
Date: Mon, 21 Apr 2025 20:22:04 -0400
Subject: [PATCH 02/13] Adding translations for h4/h5
---
packages/core/src/i18n/locales/ar.ts | 12 ++++++++++++
packages/core/src/i18n/locales/de.ts | 12 ++++++++++++
packages/core/src/i18n/locales/en.ts | 12 ++++++++++++
packages/core/src/i18n/locales/es.ts | 12 ++++++++++++
packages/core/src/i18n/locales/fr.ts | 12 ++++++++++++
packages/core/src/i18n/locales/hr.ts | 12 ++++++++++++
packages/core/src/i18n/locales/is.ts | 12 ++++++++++++
packages/core/src/i18n/locales/it.ts | 12 ++++++++++++
packages/core/src/i18n/locales/ja.ts | 12 ++++++++++++
packages/core/src/i18n/locales/ko.ts | 12 ++++++++++++
packages/core/src/i18n/locales/nl.ts | 12 ++++++++++++
packages/core/src/i18n/locales/no.ts | 12 ++++++++++++
packages/core/src/i18n/locales/pl.ts | 12 ++++++++++++
packages/core/src/i18n/locales/pt.ts | 12 ++++++++++++
packages/core/src/i18n/locales/ru.ts | 12 ++++++++++++
packages/core/src/i18n/locales/uk.ts | 12 ++++++++++++
packages/core/src/i18n/locales/vi.ts | 12 ++++++++++++
packages/core/src/i18n/locales/zh.ts | 12 ++++++++++++
18 files changed, 216 insertions(+)
diff --git a/packages/core/src/i18n/locales/ar.ts b/packages/core/src/i18n/locales/ar.ts
index eff1bbed30..ecc9bf9887 100644
--- a/packages/core/src/i18n/locales/ar.ts
+++ b/packages/core/src/i18n/locales/ar.ts
@@ -20,6 +20,18 @@ export const ar: Dictionary = {
aliases: ["ع3", "عنوان3", "عنوان فرعي"],
group: "العناوين",
},
+ heading_4: {
+ title: "عنوان 4",
+ subtext: "عنوان فرعي ثانوي صغير",
+ aliases: ["ع4", "عنوان4", "عنوان فرعي صغير"],
+ group: "العناوين",
+ },
+ heading_5: {
+ title: "عنوان 5",
+ subtext: "أدنى مستوى للعناوين",
+ aliases: ["ع5", "عنوان5", "العنوان الفرعي الأدنى"],
+ group: "العناوين",
+ },
quote: {
title: "اقتباس",
subtext: "اقتباس أو مقتطف",
diff --git a/packages/core/src/i18n/locales/de.ts b/packages/core/src/i18n/locales/de.ts
index 6d66713e2d..d2208f6d86 100644
--- a/packages/core/src/i18n/locales/de.ts
+++ b/packages/core/src/i18n/locales/de.ts
@@ -20,6 +20,18 @@ export const de: Dictionary = {
aliases: ["h3", "überschrift3", "unterüberschrift"],
group: "Überschriften",
},
+ heading_4: {
+ title: "Überschrift 4",
+ subtext: "Überschrift für kleinere Unterabschnitte",
+ aliases: ["h4", "überschrift4", "unterüberschrift4"],
+ group: "Überschriften",
+ },
+ heading_5: {
+ title: "Überschrift 5",
+ subtext: "Überschrift auf der untersten Ebene",
+ aliases: ["h5", "überschrift5", "unterüberschrift5"],
+ group: "Überschriften",
+ },
quote: {
title: "Zitat",
subtext: "Zitat oder Auszug",
diff --git a/packages/core/src/i18n/locales/en.ts b/packages/core/src/i18n/locales/en.ts
index c705fae419..d2fc8dc637 100644
--- a/packages/core/src/i18n/locales/en.ts
+++ b/packages/core/src/i18n/locales/en.ts
@@ -18,6 +18,18 @@ export const en = {
aliases: ["h3", "heading3", "subheading"],
group: "Headings",
},
+ heading_4: {
+ title: "Heading 4",
+ subtext: "Minor subsection heading",
+ aliases: ["h4", "heading4", "subheading4"],
+ group: "Headings",
+ },
+ heading_5: {
+ title: "Heading 5",
+ subtext: "Lowest‑level heading",
+ aliases: ["h5", "heading5", "subheading5"],
+ group: "Headings",
+ },
quote: {
title: "Quote",
subtext: "Quote or excerpt",
diff --git a/packages/core/src/i18n/locales/es.ts b/packages/core/src/i18n/locales/es.ts
index 4f23dc027c..aa93ab3509 100644
--- a/packages/core/src/i18n/locales/es.ts
+++ b/packages/core/src/i18n/locales/es.ts
@@ -20,6 +20,18 @@ export const es: Dictionary = {
aliases: ["h3", "encabezado3", "subencabezado"],
group: "Encabezados",
},
+ heading_4: {
+ title: "Encabezado 4",
+ subtext: "Encabezado de subsección menor",
+ aliases: ["h4", "encabezado4", "subencabezado4"],
+ group: "Encabezados",
+ },
+ heading_5: {
+ title: "Encabezado 5",
+ subtext: "Encabezado de nivel más bajo",
+ aliases: ["h5", "encabezado5", "subencabezado5"],
+ group: "Encabezados",
+ },
quote: {
title: "Cita",
subtext: "Cita o extracto",
diff --git a/packages/core/src/i18n/locales/fr.ts b/packages/core/src/i18n/locales/fr.ts
index ba24ee8599..a5d6d927b4 100644
--- a/packages/core/src/i18n/locales/fr.ts
+++ b/packages/core/src/i18n/locales/fr.ts
@@ -21,6 +21,18 @@ export const fr: Dictionary = {
aliases: ["h3", "titre3", "sous-titre"],
group: "Titres",
},
+ heading_4: {
+ title: "Titre 4",
+ subtext: "Titre de sous‑section mineure",
+ aliases: ["h4", "titre4", "sous‑titre4"],
+ group: "Titres",
+ },
+ heading_5: {
+ title: "Titre 5",
+ subtext: "Titre de niveau le plus bas",
+ aliases: ["h5", "titre5", "sous‑titre5"],
+ group: "Titres",
+ },
quote: {
title: "Citation",
subtext: "Citation ou extrait",
diff --git a/packages/core/src/i18n/locales/hr.ts b/packages/core/src/i18n/locales/hr.ts
index d099696d8f..43c607f4f8 100644
--- a/packages/core/src/i18n/locales/hr.ts
+++ b/packages/core/src/i18n/locales/hr.ts
@@ -20,6 +20,18 @@ export const hr: Dictionary = {
aliases: ["h3", "naslov3", "podnaslov"],
group: "Naslovi",
},
+ heading_4: {
+ title: "Naslov 4",
+ subtext: "Manji naslov podpoglavlja",
+ aliases: ["h4", "naslov4", "podnaslov4"],
+ group: "Naslovi",
+ },
+ heading_5: {
+ title: "Naslov 5",
+ subtext: "Naslov najniže razine",
+ aliases: ["h5", "naslov5", "podnaslov5"],
+ group: "Naslovi",
+ },
quote: {
title: "Citat",
subtext: "Citat ili izvadak",
diff --git a/packages/core/src/i18n/locales/is.ts b/packages/core/src/i18n/locales/is.ts
index f307171012..1c62786f99 100644
--- a/packages/core/src/i18n/locales/is.ts
+++ b/packages/core/src/i18n/locales/is.ts
@@ -20,6 +20,18 @@ export const is: Dictionary = {
aliases: ["h3", "fyrirsogn3", "undirfyrirsogn"],
group: "Fyrirsagnir",
},
+ heading_4: {
+ title: "Fyrirsögn 4",
+ subtext: "Titill fyrir minni undirhluta",
+ aliases: ["h4", "fyrirsogn4", "undirfyrirsogn4"],
+ group: "Fyrirsagnir",
+ },
+ heading_5: {
+ title: "Fyrirsögn 5",
+ subtext: "Titill á lægsta stigi",
+ aliases: ["h5", "fyrirsogn5", "undirfyrirsogn5"],
+ group: "Fyrirsagnir",
+ },
quote: {
title: "Tilvitnun",
subtext: "Tilvitnun eða útdráttur",
diff --git a/packages/core/src/i18n/locales/it.ts b/packages/core/src/i18n/locales/it.ts
index 5554317ddf..a98d9f7aaf 100644
--- a/packages/core/src/i18n/locales/it.ts
+++ b/packages/core/src/i18n/locales/it.ts
@@ -20,6 +20,18 @@ export const it: Dictionary = {
aliases: ["h3", "intestazione3", "sottotitolo"],
group: "Intestazioni",
},
+ heading_4: {
+ title: "Intestazione 4",
+ subtext: "Intestazione di sottosezione minore",
+ aliases: ["h4", "intestazione4", "sottotitolo4"],
+ group: "Intestazioni",
+ },
+ heading_5: {
+ title: "Intestazione 5",
+ subtext: "Intestazione di livello più basso",
+ aliases: ["h5", "intestazione5", "sottotitolo5"],
+ group: "Intestazioni",
+ },
quote: {
title: "Citazione",
subtext: "Citazione o estratto",
diff --git a/packages/core/src/i18n/locales/ja.ts b/packages/core/src/i18n/locales/ja.ts
index 0d359a07c6..c5fd7229a4 100644
--- a/packages/core/src/i18n/locales/ja.ts
+++ b/packages/core/src/i18n/locales/ja.ts
@@ -20,6 +20,18 @@ export const ja: Dictionary = {
aliases: ["h3", "見出し3", "subheading", "小見出し"],
group: "見出し",
},
+ heading_4: {
+ title: "見出し4",
+ subtext: "小さなサブセクションの見出しに使用",
+ aliases: ["h4", "見出し4", "subheading4", "小見出し4"],
+ group: "見出し",
+ },
+ heading_5: {
+ title: "見出し5",
+ subtext: "最下位レベルの見出しに使用",
+ aliases: ["h5", "見出し5", "subheading5", "小見出し5"],
+ group: "見出し",
+ },
quote: {
title: "引用",
subtext: "引用または抜粋",
diff --git a/packages/core/src/i18n/locales/ko.ts b/packages/core/src/i18n/locales/ko.ts
index f647d9d018..a31a75a78c 100644
--- a/packages/core/src/i18n/locales/ko.ts
+++ b/packages/core/src/i18n/locales/ko.ts
@@ -20,6 +20,18 @@ export const ko: Dictionary = {
aliases: ["h3", "제목3", "subheading"],
group: "제목",
},
+ heading_4: {
+ title: "제목4",
+ subtext: "하위 소단락 제목",
+ aliases: ["h4", "제목4", "소제목4"],
+ group: "제목",
+ },
+ heading_5: {
+ title: "제목5",
+ subtext: "가장 하위 수준 제목",
+ aliases: ["h5", "제목5", "소제목5"],
+ group: "제목",
+ },
quote: {
title: "인용",
subtext: "인용문 또는 발췌",
diff --git a/packages/core/src/i18n/locales/nl.ts b/packages/core/src/i18n/locales/nl.ts
index 9e6f8d34bd..aceb12fdee 100644
--- a/packages/core/src/i18n/locales/nl.ts
+++ b/packages/core/src/i18n/locales/nl.ts
@@ -20,6 +20,18 @@ export const nl: Dictionary = {
aliases: ["h3", "kop3", "subkop"],
group: "Koppen",
},
+ heading_4: {
+ title: "Kop 4",
+ subtext: "Gebruikt voor kleinere subsecties",
+ aliases: ["h4", "kop4", "subkop4"],
+ group: "Koppen",
+ },
+ heading_5: {
+ title: "Kop 5",
+ subtext: "Gebruikt voor de laagste niveau koppen",
+ aliases: ["h5", "kop5", "subkop5"],
+ group: "Koppen",
+ },
quote: {
title: "Citaat",
subtext: "Citaat of uittreksel",
diff --git a/packages/core/src/i18n/locales/no.ts b/packages/core/src/i18n/locales/no.ts
index 5eddd8705d..f201028cb7 100644
--- a/packages/core/src/i18n/locales/no.ts
+++ b/packages/core/src/i18n/locales/no.ts
@@ -20,6 +20,18 @@ export const no: Dictionary = {
aliases: ["h3", "overskrift3", "underoverskrift"],
group: "Overskrifter",
},
+ heading_4: {
+ title: "Overskrift 4",
+ subtext: "Underoverskrift for mindre underseksjoner",
+ aliases: ["h4", "overskrift4", "underoverskrift4"],
+ group: "Overskrifter",
+ },
+ heading_5: {
+ title: "Overskrift 5",
+ subtext: "Overskrift på laveste nivå",
+ aliases: ["h5", "overskrift5", "underoverskrift5"],
+ group: "Overskrifter",
+ },
quote: {
title: "Sitat",
subtext: "Sitat eller utdrag",
diff --git a/packages/core/src/i18n/locales/pl.ts b/packages/core/src/i18n/locales/pl.ts
index 490de484e8..24639da252 100644
--- a/packages/core/src/i18n/locales/pl.ts
+++ b/packages/core/src/i18n/locales/pl.ts
@@ -20,6 +20,18 @@ export const pl: Dictionary = {
aliases: ["h3", "naglowek3", "podnaglowek"],
group: "Nagłówki",
},
+ heading_4: {
+ title: "Nagłówek 4",
+ subtext: "Nagłówek mniejszej podsekcji",
+ aliases: ["h4", "naglowek4", "podnaglowek4"],
+ group: "Nagłówki",
+ },
+ heading_5: {
+ title: "Nagłówek 5",
+ subtext: "Nagłówek najniższego poziomu",
+ aliases: ["h5", "naglowek5", "podnaglowek5"],
+ group: "Nagłówki",
+ },
quote: {
title: "Cytat",
subtext: "Cytat lub fragment",
diff --git a/packages/core/src/i18n/locales/pt.ts b/packages/core/src/i18n/locales/pt.ts
index 1272700eb2..0cb558ceb4 100644
--- a/packages/core/src/i18n/locales/pt.ts
+++ b/packages/core/src/i18n/locales/pt.ts
@@ -20,6 +20,18 @@ export const pt: Dictionary = {
aliases: ["h3", "titulo3", "subtitulo"],
group: "Títulos",
},
+ heading_4: {
+ title: "Título 4",
+ subtext: "Usado para subseções menores",
+ aliases: ["h4", "titulo4", "subtitulo4"],
+ group: "Títulos",
+ },
+ heading_5: {
+ title: "Título 5",
+ subtext: "Usado para títulos de nível mais baixo",
+ aliases: ["h5", "titulo5", "subtitulo5"],
+ group: "Títulos",
+ },
quote: {
title: "Citação",
subtext: "Citação ou trecho",
diff --git a/packages/core/src/i18n/locales/ru.ts b/packages/core/src/i18n/locales/ru.ts
index 045980cf50..11b91fe661 100644
--- a/packages/core/src/i18n/locales/ru.ts
+++ b/packages/core/src/i18n/locales/ru.ts
@@ -20,6 +20,18 @@ export const ru: Dictionary = {
aliases: ["h3", "heading3", "subheading", "заголовок3", "подзаголовок"],
group: "Заголовки",
},
+ heading_4: {
+ title: "Заголовок 4 уровня",
+ subtext: "Используется для более мелких подразделов",
+ aliases: ["h4", "heading4", "subheading4", "заголовок4", "подзаголовок4"],
+ group: "Заголовки",
+ },
+ heading_5: {
+ title: "Заголовок 5 уровня",
+ subtext: "Используется для заголовков самого низкого уровня",
+ aliases: ["h5", "heading5", "subheading5", "заголовок5", "подзаголовок5"],
+ group: "Заголовки",
+ },
quote: {
title: "Цитата",
subtext: "Цитата или отрывок",
diff --git a/packages/core/src/i18n/locales/uk.ts b/packages/core/src/i18n/locales/uk.ts
index 5592d752c1..8a990ee6ff 100644
--- a/packages/core/src/i18n/locales/uk.ts
+++ b/packages/core/src/i18n/locales/uk.ts
@@ -20,6 +20,18 @@ export const uk: Dictionary = {
aliases: ["h3", "heading3", "subheading", "заголовок3"],
group: "Заголовки",
},
+ heading_4: {
+ title: "Заголовок 4",
+ subtext: "Використовується для менших підрозділів",
+ aliases: ["h4", "heading4", "subheading4", "заголовок4"],
+ group: "Заголовки",
+ },
+ heading_5: {
+ title: "Заголовок 5",
+ subtext: "Використовується для заголовків найнижчого рівня",
+ aliases: ["h5", "heading5", "subheading5", "заголовок5"],
+ group: "Заголовки",
+ },
quote: {
title: "Цитата",
subtext: "Цитата або уривок",
diff --git a/packages/core/src/i18n/locales/vi.ts b/packages/core/src/i18n/locales/vi.ts
index afe16fd2cd..afcb3d20cf 100644
--- a/packages/core/src/i18n/locales/vi.ts
+++ b/packages/core/src/i18n/locales/vi.ts
@@ -20,6 +20,18 @@ export const vi: Dictionary = {
aliases: ["h3", "tieude3", "tieudephu"],
group: "Tiêu đề",
},
+ heading_4: {
+ title: "Tiêu đề H4",
+ subtext: "Sử dụng cho tiêu đề phụ nhỏ hơn",
+ aliases: ["h4", "tieude4", "tieudephu4"],
+ group: "Tiêu đề",
+ },
+ heading_5: {
+ title: "Tiêu đề H5",
+ subtext: "Sử dụng cho tiêu đề cấp thấp nhất",
+ aliases: ["h5", "tieude5", "tieudephu5"],
+ group: "Tiêu đề",
+ },
quote: {
title: "Trích dẫn",
subtext: "Trích dẫn hoặc đoạn trích",
diff --git a/packages/core/src/i18n/locales/zh.ts b/packages/core/src/i18n/locales/zh.ts
index fff54c314c..84f36c5808 100644
--- a/packages/core/src/i18n/locales/zh.ts
+++ b/packages/core/src/i18n/locales/zh.ts
@@ -20,6 +20,18 @@ export const zh: Dictionary = {
aliases: ["h3", "heading3", "subheading", "标题", "三级标题"],
group: "标题",
},
+ heading_4: {
+ title: "四级标题",
+ subtext: "用于较小的子节标题",
+ aliases: ["h4", "heading4", "subheading4", "四级标题"],
+ group: "标题",
+ },
+ heading_5: {
+ title: "五级标题",
+ subtext: "用于最低层级的标题",
+ aliases: ["h5", "heading5", "subheading5", "五级标题"],
+ group: "标题",
+ },
quote: {
title: "引用",
subtext: "引用或摘录",
From 285c6001e1465d3d7de4a8739af65f8e0d99df59 Mon Sep 17 00:00:00 2001
From: Drew Johnson
Date: Mon, 21 Apr 2025 20:22:08 -0400
Subject: [PATCH 03/13] Styles
---
.../DefaultSelects/BlockTypeSelect.tsx | 22 ++++++++
.../getDefaultReactSlashMenuItems.tsx | 8 ++-
packages/shadcn/src/tailwindStyles.css | 50 +++++++++----------
3 files changed, 53 insertions(+), 27 deletions(-)
diff --git a/packages/react/src/components/FormattingToolbar/DefaultSelects/BlockTypeSelect.tsx b/packages/react/src/components/FormattingToolbar/DefaultSelects/BlockTypeSelect.tsx
index c37e27b967..111f1c5d94 100644
--- a/packages/react/src/components/FormattingToolbar/DefaultSelects/BlockTypeSelect.tsx
+++ b/packages/react/src/components/FormattingToolbar/DefaultSelects/BlockTypeSelect.tsx
@@ -11,6 +11,8 @@ import {
RiH1,
RiH2,
RiH3,
+ RiH4,
+ RiH5,
RiListCheck3,
RiListOrdered,
RiListUnordered,
@@ -76,6 +78,26 @@ export const blockTypeSelectItems = (
"level" in block.props &&
block.props.level === 3,
},
+ {
+ name: dict.slash_menu.heading_4.title,
+ type: "heading",
+ props: { level: 4 },
+ icon: RiH4,
+ isSelected: (block) =>
+ block.type === "heading" &&
+ "level" in block.props &&
+ block.props.level === 4,
+ },
+ {
+ name: dict.slash_menu.heading_5.title,
+ type: "heading",
+ props: { level: 5 },
+ icon: RiH5,
+ isSelected: (block) =>
+ block.type === "heading" &&
+ "level" in block.props &&
+ block.props.level === 5,
+ },
{
name: dict.slash_menu.quote.title,
type: "quote",
diff --git a/packages/react/src/components/SuggestionMenu/getDefaultReactSlashMenuItems.tsx b/packages/react/src/components/SuggestionMenu/getDefaultReactSlashMenuItems.tsx
index 9e970a2dac..979e82f984 100644
--- a/packages/react/src/components/SuggestionMenu/getDefaultReactSlashMenuItems.tsx
+++ b/packages/react/src/components/SuggestionMenu/getDefaultReactSlashMenuItems.tsx
@@ -6,21 +6,23 @@ import {
StyleSchema,
} from "@blocknote/core";
import {
+ RiCodeBlock,
RiEmotionFill,
RiFile2Line,
RiFilmLine,
RiH1,
RiH2,
RiH3,
+ RiH4,
+ RiH5,
RiImage2Fill,
RiListCheck3,
RiListOrdered,
RiListUnordered,
+ RiQuoteText,
RiTable2,
RiText,
RiVolumeUpFill,
- RiCodeBlock,
- RiQuoteText,
} from "react-icons/ri";
import { DefaultReactSuggestionItem } from "./types.js";
@@ -28,6 +30,8 @@ const icons = {
heading: RiH1,
heading_2: RiH2,
heading_3: RiH3,
+ heading_4: RiH4,
+ heading_5: RiH5,
quote: RiQuoteText,
numbered_list: RiListOrdered,
bullet_list: RiListUnordered,
diff --git a/packages/shadcn/src/tailwindStyles.css b/packages/shadcn/src/tailwindStyles.css
index 16d69c0337..71a0d4544b 100644
--- a/packages/shadcn/src/tailwindStyles.css
+++ b/packages/shadcn/src/tailwindStyles.css
@@ -37,22 +37,22 @@
-moz-tab-size: 4; /* 3 */
tab-size: 4; /* 3 */
font-family: theme(
- "fontFamily.sans",
- ui-sans-serif,
- system-ui,
- sans-serif,
- "Apple Color Emoji",
- "Segoe UI Emoji",
- "Segoe UI Symbol",
- "Noto Color Emoji"
+ "fontFamily.sans",
+ ui-sans-serif,
+ system-ui,
+ sans-serif,
+ "Apple Color Emoji",
+ "Segoe UI Emoji",
+ "Segoe UI Symbol",
+ "Noto Color Emoji"
); /* 4 */
font-feature-settings: theme(
- "fontFamily.sans[1].fontFeatureSettings",
- normal
+ "fontFamily.sans[1].fontFeatureSettings",
+ normal
); /* 5 */
font-variation-settings: theme(
- "fontFamily.sans[1].fontVariationSettings",
- normal
+ "fontFamily.sans[1].fontVariationSettings",
+ normal
); /* 6 */
-webkit-tap-highlight-color: transparent; /* 7 */
}
@@ -131,23 +131,23 @@
samp,
pre {
font-family: theme(
- "fontFamily.mono",
- ui-monospace,
- SFMono-Regular,
- Menlo,
- Monaco,
- Consolas,
- "Liberation Mono",
- "Courier New",
- monospace
+ "fontFamily.mono",
+ ui-monospace,
+ SFMono-Regular,
+ Menlo,
+ Monaco,
+ Consolas,
+ "Liberation Mono",
+ "Courier New",
+ monospace
); /* 1 */
font-feature-settings: theme(
- "fontFamily.mono[1].fontFeatureSettings",
- normal
+ "fontFamily.mono[1].fontFeatureSettings",
+ normal
); /* 2 */
font-variation-settings: theme(
- "fontFamily.mono[1].fontVariationSettings",
- normal
+ "fontFamily.mono[1].fontVariationSettings",
+ normal
); /* 3 */
font-size: 1em; /* 4 */
}
From 75c144e25265ef4e8fb7b5d303215ba9ea6bbc2c Mon Sep 17 00:00:00 2001
From: Drew Johnson
Date: Mon, 21 Apr 2025 20:30:14 -0400
Subject: [PATCH 04/13] Font size and test
---
packages/core/src/editor/Block.css | 2 +-
.../formatConversion/parse/parseTestInstances.ts | 12 ++++++++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/packages/core/src/editor/Block.css b/packages/core/src/editor/Block.css
index 69844b5a39..a9f7938966 100644
--- a/packages/core/src/editor/Block.css
+++ b/packages/core/src/editor/Block.css
@@ -131,7 +131,7 @@ NESTED BLOCKS
--level: 1em;
}
[data-content-type="heading"][data-level="5"] {
- --level: 0.8em;
+ --level: 0.9em;
}
[data-prev-level="1"] {
diff --git a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts
index 1953d1ca75..f5d0744bdf 100644
--- a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts
+++ b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts
@@ -22,6 +22,8 @@ export const parseTestInstancesHTML: TestInstance<
content: `Heading 1
Heading 2
Heading 3
+Heading 4
+Heading 5
Paragraph
Image Caption
None Bold Italic Underline Strikethrough All
`,
@@ -286,6 +288,8 @@ export const parseTestInstancesHTML: TestInstance<
Heading 1
Heading 2
Heading 3
+ Heading 4
+ Heading 5
Paragraph
Image Caption
Bold Italic Underline Strikethrough All
@@ -352,6 +356,8 @@ export const parseTestInstancesHTML: TestInstance<
content: `Heading 1
Heading 2
Heading 3
+Heading 4
+Heading 5
Paragraph 1
Nested Paragraph 1
Nested Paragraph 2
@@ -413,6 +419,8 @@ With Hard Break
Heading 1
Heading 2
Heading 3
+Heading 4
+Heading 5
Paragraph 1
Paragraph 2
Paragraph 3
@@ -564,6 +572,10 @@ Paragraph
### Heading 3
+#### Heading 4
+
+##### Heading 5
+
Paragraph
P**ara***grap*h
From a9691730233b1a9ee52a62cf52630de1ef888f1a Mon Sep 17 00:00:00 2001
From: Drew Johnson
Date: Mon, 21 Apr 2025 20:51:15 -0400
Subject: [PATCH 05/13] Update snapshot tests
---
.../__snapshots__/html/basicBlockTypes.json | 42 +++++++++-
.../__snapshots__/html/deepNestedContent.json | 44 ++++++++++-
.../parse/__snapshots__/html/googleDocs.json | 76 ++++++++++++++-----
.../parse/__snapshots__/html/notion.json | 70 ++++++++++++-----
.../parse/__snapshots__/markdown/complex.json | 66 ++++++++++++----
5 files changed, 241 insertions(+), 57 deletions(-)
diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/basicBlockTypes.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/basicBlockTypes.json
index 1a9bd562f2..e11339eae9 100644
--- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/basicBlockTypes.json
+++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/basicBlockTypes.json
@@ -58,11 +58,47 @@
"content": [
{
"styles": {},
- "text": "Paragraph",
+ "text": "Heading 4",
"type": "text",
},
],
"id": "4",
+ "props": {
+ "backgroundColor": "default",
+ "level": 4,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Heading 5",
+ "type": "text",
+ },
+ ],
+ "id": "5",
+ "props": {
+ "backgroundColor": "default",
+ "level": 5,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Paragraph",
+ "type": "text",
+ },
+ ],
+ "id": "6",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -73,7 +109,7 @@
{
"children": [],
"content": undefined,
- "id": "5",
+ "id": "7",
"props": {
"backgroundColor": "default",
"caption": "Image Caption",
@@ -132,7 +168,7 @@
"type": "text",
},
],
- "id": "6",
+ "id": "8",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json
index 959dbbcd5a..fac0b83650 100644
--- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json
+++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json
@@ -126,11 +126,47 @@
"content": [
{
"styles": {},
- "text": "Paragraph",
+ "text": "Heading 4",
"type": "text",
},
],
"id": "8",
+ "props": {
+ "backgroundColor": "default",
+ "level": 4,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Heading 5",
+ "type": "text",
+ },
+ ],
+ "id": "9",
+ "props": {
+ "backgroundColor": "default",
+ "level": 5,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Paragraph",
+ "type": "text",
+ },
+ ],
+ "id": "10",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -141,7 +177,7 @@
{
"children": [],
"content": undefined,
- "id": "9",
+ "id": "11",
"props": {
"backgroundColor": "default",
"caption": "Image Caption",
@@ -215,7 +251,7 @@
"type": "text",
},
],
- "id": "10",
+ "id": "12",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -232,7 +268,7 @@
"type": "text",
},
],
- "id": "11",
+ "id": "13",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/googleDocs.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/googleDocs.json
index 5a7912dcd1..a5e2dc0b18 100644
--- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/googleDocs.json
+++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/googleDocs.json
@@ -59,6 +59,46 @@
},
"type": "heading",
},
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {
+ "bold": true,
+ },
+ "text": "Heading 4",
+ "type": "text",
+ },
+ ],
+ "id": "4",
+ "props": {
+ "backgroundColor": "default",
+ "level": 4,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {
+ "bold": true,
+ },
+ "text": "Heading 5",
+ "type": "text",
+ },
+ ],
+ "id": "5",
+ "props": {
+ "backgroundColor": "default",
+ "level": 5,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
{
"children": [],
"content": [
@@ -68,7 +108,7 @@
"type": "text",
},
],
- "id": "4",
+ "id": "6",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -85,7 +125,7 @@
"type": "text",
},
],
- "id": "5",
+ "id": "7",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -102,7 +142,7 @@
"type": "text",
},
],
- "id": "6",
+ "id": "8",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -120,7 +160,7 @@ Hard Break",
"type": "text",
},
],
- "id": "7",
+ "id": "9",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -177,7 +217,7 @@ Hard Break",
"type": "text",
},
],
- "id": "8",
+ "id": "10",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -198,7 +238,7 @@ Hard Break",
"type": "text",
},
],
- "id": "11",
+ "id": "13",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -215,7 +255,7 @@ Hard Break",
"type": "text",
},
],
- "id": "12",
+ "id": "14",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -231,7 +271,7 @@ Hard Break",
"type": "text",
},
],
- "id": "10",
+ "id": "12",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -248,7 +288,7 @@ Hard Break",
"type": "text",
},
],
- "id": "13",
+ "id": "15",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -264,7 +304,7 @@ Hard Break",
"type": "text",
},
],
- "id": "9",
+ "id": "11",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -281,7 +321,7 @@ Hard Break",
"type": "text",
},
],
- "id": "14",
+ "id": "16",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -298,7 +338,7 @@ Hard Break",
"type": "text",
},
],
- "id": "15",
+ "id": "17",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -315,7 +355,7 @@ Hard Break",
"type": "text",
},
],
- "id": "16",
+ "id": "18",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -326,7 +366,7 @@ Hard Break",
{
"children": [],
"content": undefined,
- "id": "17",
+ "id": "19",
"props": {
"backgroundColor": "default",
"caption": "",
@@ -348,7 +388,7 @@ Hard Break",
"type": "text",
},
],
- "id": "18",
+ "id": "20",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -535,7 +575,7 @@ Hard Break",
],
"type": "tableContent",
},
- "id": "19",
+ "id": "21",
"props": {
"textColor": "default",
},
@@ -550,7 +590,7 @@ Hard Break",
"type": "text",
},
],
- "id": "20",
+ "id": "22",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -568,7 +608,7 @@ Hard Break",
"type": "text",
},
],
- "id": "21",
+ "id": "23",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/notion.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/notion.json
index b1eb97dd2d..84a9766da6 100644
--- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/notion.json
+++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/notion.json
@@ -58,11 +58,47 @@
"content": [
{
"styles": {},
- "text": "Paragraph 1",
+ "text": "Heading 4",
"type": "text",
},
],
"id": "4",
+ "props": {
+ "backgroundColor": "default",
+ "level": 4,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Heading 5",
+ "type": "text",
+ },
+ ],
+ "id": "5",
+ "props": {
+ "backgroundColor": "default",
+ "level": 5,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Paragraph 1",
+ "type": "text",
+ },
+ ],
+ "id": "6",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -79,7 +115,7 @@
"type": "text",
},
],
- "id": "5",
+ "id": "7",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -96,7 +132,7 @@
"type": "text",
},
],
- "id": "6",
+ "id": "8",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -113,7 +149,7 @@
"type": "text",
},
],
- "id": "7",
+ "id": "9",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -170,7 +206,7 @@
"type": "text",
},
],
- "id": "8",
+ "id": "10",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -191,7 +227,7 @@
"type": "text",
},
],
- "id": "11",
+ "id": "13",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -208,7 +244,7 @@
"type": "text",
},
],
- "id": "12",
+ "id": "14",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -224,7 +260,7 @@
"type": "text",
},
],
- "id": "10",
+ "id": "12",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -241,7 +277,7 @@
"type": "text",
},
],
- "id": "13",
+ "id": "15",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -257,7 +293,7 @@
"type": "text",
},
],
- "id": "9",
+ "id": "11",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -274,7 +310,7 @@
"type": "text",
},
],
- "id": "14",
+ "id": "16",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -291,7 +327,7 @@
"type": "text",
},
],
- "id": "15",
+ "id": "17",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -308,7 +344,7 @@
"type": "text",
},
],
- "id": "16",
+ "id": "18",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -325,7 +361,7 @@
"type": "text",
},
],
- "id": "17",
+ "id": "19",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -353,7 +389,7 @@
"type": "link",
},
],
- "id": "18",
+ "id": "20",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -540,7 +576,7 @@
],
"type": "tableContent",
},
- "id": "19",
+ "id": "21",
"props": {
"textColor": "default",
},
@@ -555,7 +591,7 @@
"type": "text",
},
],
- "id": "20",
+ "id": "22",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/markdown/complex.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/markdown/complex.json
index 81ac21d79a..3db20d42bd 100644
--- a/tests/src/unit/core/formatConversion/parse/__snapshots__/markdown/complex.json
+++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/markdown/complex.json
@@ -58,11 +58,47 @@
"content": [
{
"styles": {},
- "text": "Paragraph",
+ "text": "Heading 4",
"type": "text",
},
],
"id": "4",
+ "props": {
+ "backgroundColor": "default",
+ "level": 4,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Heading 5",
+ "type": "text",
+ },
+ ],
+ "id": "5",
+ "props": {
+ "backgroundColor": "default",
+ "level": 5,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Paragraph",
+ "type": "text",
+ },
+ ],
+ "id": "6",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -98,7 +134,7 @@
"type": "text",
},
],
- "id": "5",
+ "id": "7",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -134,7 +170,7 @@
"type": "text",
},
],
- "id": "6",
+ "id": "8",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -151,7 +187,7 @@
"type": "text",
},
],
- "id": "7",
+ "id": "9",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -172,7 +208,7 @@
"type": "text",
},
],
- "id": "10",
+ "id": "12",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -188,7 +224,7 @@
"type": "text",
},
],
- "id": "9",
+ "id": "11",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -207,7 +243,7 @@
"type": "text",
},
],
- "id": "12",
+ "id": "14",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -224,7 +260,7 @@
"type": "text",
},
],
- "id": "13",
+ "id": "15",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -243,7 +279,7 @@
"type": "text",
},
],
- "id": "15",
+ "id": "17",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -259,7 +295,7 @@
"type": "text",
},
],
- "id": "14",
+ "id": "16",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -276,7 +312,7 @@
"type": "text",
},
],
- "id": "16",
+ "id": "18",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -292,7 +328,7 @@
"type": "text",
},
],
- "id": "11",
+ "id": "13",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -309,7 +345,7 @@
"type": "text",
},
],
- "id": "17",
+ "id": "19",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -325,7 +361,7 @@
"type": "text",
},
],
- "id": "8",
+ "id": "10",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -342,7 +378,7 @@
"type": "text",
},
],
- "id": "18",
+ "id": "20",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
From 86da278913875aa2e2c6213c9110aed112f02e1d Mon Sep 17 00:00:00 2001
From: Drew Johnson
Date: Wed, 23 Apr 2025 13:35:55 -0400
Subject: [PATCH 06/13] locales and other h6 support updates
---
.../blocks/HeadingBlockContent/HeadingBlockContent.ts | 2 +-
packages/core/src/editor/Block.css | 6 ++++++
packages/core/src/editor/editor.css | 1 +
packages/core/src/i18n/locales/ar.ts | 8 +++++++-
packages/core/src/i18n/locales/de.ts | 8 +++++++-
packages/core/src/i18n/locales/en.ts | 8 +++++++-
packages/core/src/i18n/locales/es.ts | 8 +++++++-
packages/core/src/i18n/locales/fr.ts | 8 +++++++-
packages/core/src/i18n/locales/hr.ts | 8 +++++++-
packages/core/src/i18n/locales/is.ts | 8 +++++++-
packages/core/src/i18n/locales/it.ts | 8 +++++++-
packages/core/src/i18n/locales/ja.ts | 8 +++++++-
packages/core/src/i18n/locales/ko.ts | 8 +++++++-
packages/core/src/i18n/locales/nl.ts | 8 +++++++-
packages/core/src/i18n/locales/no.ts | 8 +++++++-
packages/core/src/i18n/locales/pl.ts | 8 +++++++-
packages/core/src/i18n/locales/pt.ts | 8 +++++++-
packages/core/src/i18n/locales/ru.ts | 8 +++++++-
packages/core/src/i18n/locales/uk.ts | 8 +++++++-
packages/core/src/i18n/locales/vi.ts | 8 +++++++-
packages/core/src/i18n/locales/zh.ts | 8 +++++++-
.../DefaultSelects/BlockTypeSelect.tsx | 11 +++++++++++
22 files changed, 145 insertions(+), 19 deletions(-)
diff --git a/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts b/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts
index a0b070623a..248c292a76 100644
--- a/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts
+++ b/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts
@@ -10,7 +10,7 @@ import {
import { createDefaultBlockDOMOutputSpec } from "../defaultBlockHelpers.js";
import { defaultProps } from "../defaultProps.js";
-const HEADING_LEVELS = [1, 2, 3, 4, 5] as const;
+const HEADING_LEVELS = [1, 2, 3, 4, 5, 6] as const;
export const headingPropSchema = {
...defaultProps,
diff --git a/packages/core/src/editor/Block.css b/packages/core/src/editor/Block.css
index a9f7938966..5f0dfa942a 100644
--- a/packages/core/src/editor/Block.css
+++ b/packages/core/src/editor/Block.css
@@ -133,6 +133,9 @@ NESTED BLOCKS
[data-content-type="heading"][data-level="5"] {
--level: 0.9em;
}
+[data-content-type="heading"][data-level="6"] {
+ --level: 0.8em;
+}
[data-prev-level="1"] {
--prev-level: 3em;
@@ -149,6 +152,9 @@ NESTED BLOCKS
[data-prev-level="5"] {
--prev-level: 0.9em;
}
+[data-prev-level="6"] {
+ --prev-level: 0.8em;
+}
.bn-block-outer[data-prev-type="heading"] > .bn-block > .bn-block-content {
font-size: var(--prev-level);
diff --git a/packages/core/src/editor/editor.css b/packages/core/src/editor/editor.css
index 76bfd253a1..6e6bc34f61 100644
--- a/packages/core/src/editor/editor.css
+++ b/packages/core/src/editor/editor.css
@@ -46,6 +46,7 @@ Tippy popups that are appended to document.body directly
.bn-default-styles h3,
.bn-default-styles h4,
.bn-default-styles h5,
+.bn-default-styles h6,
.bn-default-styles li {
margin: 0;
padding: 0;
diff --git a/packages/core/src/i18n/locales/ar.ts b/packages/core/src/i18n/locales/ar.ts
index ecc9bf9887..6c08718d72 100644
--- a/packages/core/src/i18n/locales/ar.ts
+++ b/packages/core/src/i18n/locales/ar.ts
@@ -28,8 +28,14 @@ export const ar: Dictionary = {
},
heading_5: {
title: "عنوان 5",
+ subtext: "عنوان فرعي صغير",
+ aliases: ["ع5", "عنوان5", "عنوان فرعي صغير"],
+ group: "العناوين",
+ },
+ heading_6: {
+ title: "عنوان 6",
subtext: "أدنى مستوى للعناوين",
- aliases: ["ع5", "عنوان5", "العنوان الفرعي الأدنى"],
+ aliases: ["ع6", "عنوان6", "العنوان الفرعي الأدنى"],
group: "العناوين",
},
quote: {
diff --git a/packages/core/src/i18n/locales/de.ts b/packages/core/src/i18n/locales/de.ts
index d2208f6d86..cb0506ff4d 100644
--- a/packages/core/src/i18n/locales/de.ts
+++ b/packages/core/src/i18n/locales/de.ts
@@ -28,10 +28,16 @@ export const de: Dictionary = {
},
heading_5: {
title: "Überschrift 5",
- subtext: "Überschrift auf der untersten Ebene",
+ subtext: "Überschrift für tiefere Unterabschnitte",
aliases: ["h5", "überschrift5", "unterüberschrift5"],
group: "Überschriften",
},
+ heading_6: {
+ title: "Überschrift 6",
+ subtext: "Überschrift auf der untersten Ebene",
+ aliases: ["h6", "überschrift6", "unterüberschrift6"],
+ group: "Überschriften",
+ },
quote: {
title: "Zitat",
subtext: "Zitat oder Auszug",
diff --git a/packages/core/src/i18n/locales/en.ts b/packages/core/src/i18n/locales/en.ts
index d2fc8dc637..3b6a96aa84 100644
--- a/packages/core/src/i18n/locales/en.ts
+++ b/packages/core/src/i18n/locales/en.ts
@@ -26,10 +26,16 @@ export const en = {
},
heading_5: {
title: "Heading 5",
- subtext: "Lowest‑level heading",
+ subtext: "Small subsection heading",
aliases: ["h5", "heading5", "subheading5"],
group: "Headings",
},
+ heading_6: {
+ title: "Heading 6",
+ subtext: "Lowest-level heading",
+ aliases: ["h6", "heading6", "subheading6"],
+ group: "Headings",
+ },
quote: {
title: "Quote",
subtext: "Quote or excerpt",
diff --git a/packages/core/src/i18n/locales/es.ts b/packages/core/src/i18n/locales/es.ts
index aa93ab3509..b9756bf85f 100644
--- a/packages/core/src/i18n/locales/es.ts
+++ b/packages/core/src/i18n/locales/es.ts
@@ -28,10 +28,16 @@ export const es: Dictionary = {
},
heading_5: {
title: "Encabezado 5",
- subtext: "Encabezado de nivel más bajo",
+ subtext: "Encabezado de subsección pequeña",
aliases: ["h5", "encabezado5", "subencabezado5"],
group: "Encabezados",
},
+ heading_6: {
+ title: "Encabezado 6",
+ subtext: "Encabezado de nivel más bajo",
+ aliases: ["h6", "encabezado6", "subencabezado6"],
+ group: "Encabezados",
+ },
quote: {
title: "Cita",
subtext: "Cita o extracto",
diff --git a/packages/core/src/i18n/locales/fr.ts b/packages/core/src/i18n/locales/fr.ts
index a5d6d927b4..3722260746 100644
--- a/packages/core/src/i18n/locales/fr.ts
+++ b/packages/core/src/i18n/locales/fr.ts
@@ -29,8 +29,14 @@ export const fr: Dictionary = {
},
heading_5: {
title: "Titre 5",
+ subtext: "Titre de sous-section mineure",
+ aliases: ["h5", "titre5", "sous-titre5"],
+ group: "Titres",
+ },
+ heading_6: {
+ title: "Titre 6",
subtext: "Titre de niveau le plus bas",
- aliases: ["h5", "titre5", "sous‑titre5"],
+ aliases: ["h6", "titre6", "sous-titre6"],
group: "Titres",
},
quote: {
diff --git a/packages/core/src/i18n/locales/hr.ts b/packages/core/src/i18n/locales/hr.ts
index 43c607f4f8..a71ae02ab6 100644
--- a/packages/core/src/i18n/locales/hr.ts
+++ b/packages/core/src/i18n/locales/hr.ts
@@ -28,10 +28,16 @@ export const hr: Dictionary = {
},
heading_5: {
title: "Naslov 5",
- subtext: "Naslov najniže razine",
+ subtext: "Mali naslov podpoglavlja",
aliases: ["h5", "naslov5", "podnaslov5"],
group: "Naslovi",
},
+ heading_6: {
+ title: "Naslov 6",
+ subtext: "Naslov najniže razine",
+ aliases: ["h6", "naslov6", "podnaslov6"],
+ group: "Naslovi",
+ },
quote: {
title: "Citat",
subtext: "Citat ili izvadak",
diff --git a/packages/core/src/i18n/locales/is.ts b/packages/core/src/i18n/locales/is.ts
index 1c62786f99..b185cd42e1 100644
--- a/packages/core/src/i18n/locales/is.ts
+++ b/packages/core/src/i18n/locales/is.ts
@@ -28,10 +28,16 @@ export const is: Dictionary = {
},
heading_5: {
title: "Fyrirsögn 5",
- subtext: "Titill á lægsta stigi",
+ subtext: "Titill fyrir litla undirkafla",
aliases: ["h5", "fyrirsogn5", "undirfyrirsogn5"],
group: "Fyrirsagnir",
},
+ heading_6: {
+ title: "Fyrirsögn 6",
+ subtext: "Titill á lægsta stigi",
+ aliases: ["h6", "fyrirsogn6", "undirfyrirsogn6"],
+ group: "Fyrirsagnir",
+ },
quote: {
title: "Tilvitnun",
subtext: "Tilvitnun eða útdráttur",
diff --git a/packages/core/src/i18n/locales/it.ts b/packages/core/src/i18n/locales/it.ts
index a98d9f7aaf..7771d3744e 100644
--- a/packages/core/src/i18n/locales/it.ts
+++ b/packages/core/src/i18n/locales/it.ts
@@ -28,10 +28,16 @@ export const it: Dictionary = {
},
heading_5: {
title: "Intestazione 5",
- subtext: "Intestazione di livello più basso",
+ subtext: "Intestazione di sottosezione minore",
aliases: ["h5", "intestazione5", "sottotitolo5"],
group: "Intestazioni",
},
+ heading_6: {
+ title: "Intestazione 6",
+ subtext: "Intestazione di livello più basso",
+ aliases: ["h6", "intestazione6", "sottotitolo6"],
+ group: "Intestazioni",
+ },
quote: {
title: "Citazione",
subtext: "Citazione o estratto",
diff --git a/packages/core/src/i18n/locales/ja.ts b/packages/core/src/i18n/locales/ja.ts
index c5fd7229a4..e969c6ea1e 100644
--- a/packages/core/src/i18n/locales/ja.ts
+++ b/packages/core/src/i18n/locales/ja.ts
@@ -28,10 +28,16 @@ export const ja: Dictionary = {
},
heading_5: {
title: "見出し5",
- subtext: "最下位レベルの見出しに使用",
+ subtext: "小さなサブセクションの見出しに使用",
aliases: ["h5", "見出し5", "subheading5", "小見出し5"],
group: "見出し",
},
+ heading_6: {
+ title: "見出し6",
+ subtext: "最下位レベルの見出しに使用",
+ aliases: ["h6", "見出し6", "subheading6", "小見出し6"],
+ group: "見出し",
+ },
quote: {
title: "引用",
subtext: "引用または抜粋",
diff --git a/packages/core/src/i18n/locales/ko.ts b/packages/core/src/i18n/locales/ko.ts
index a31a75a78c..754de605ed 100644
--- a/packages/core/src/i18n/locales/ko.ts
+++ b/packages/core/src/i18n/locales/ko.ts
@@ -28,10 +28,16 @@ export const ko: Dictionary = {
},
heading_5: {
title: "제목5",
- subtext: "가장 하위 수준 제목",
+ subtext: "작은 하위 섹션 제목",
aliases: ["h5", "제목5", "소제목5"],
group: "제목",
},
+ heading_6: {
+ title: "제목6",
+ subtext: "가장 하위 수준 제목",
+ aliases: ["h6", "제목6", "소제목6"],
+ group: "제목",
+ },
quote: {
title: "인용",
subtext: "인용문 또는 발췌",
diff --git a/packages/core/src/i18n/locales/nl.ts b/packages/core/src/i18n/locales/nl.ts
index aceb12fdee..9f03ed2c87 100644
--- a/packages/core/src/i18n/locales/nl.ts
+++ b/packages/core/src/i18n/locales/nl.ts
@@ -28,10 +28,16 @@ export const nl: Dictionary = {
},
heading_5: {
title: "Kop 5",
- subtext: "Gebruikt voor de laagste niveau koppen",
+ subtext: "Gebruikt voor kleinere subsecties",
aliases: ["h5", "kop5", "subkop5"],
group: "Koppen",
},
+ heading_6: {
+ title: "Kop 6",
+ subtext: "Gebruikt voor koppen op het laagste niveau",
+ aliases: ["h6", "kop6", "subkop6"],
+ group: "Koppen",
+ },
quote: {
title: "Citaat",
subtext: "Citaat of uittreksel",
diff --git a/packages/core/src/i18n/locales/no.ts b/packages/core/src/i18n/locales/no.ts
index f201028cb7..aac7ed66d0 100644
--- a/packages/core/src/i18n/locales/no.ts
+++ b/packages/core/src/i18n/locales/no.ts
@@ -28,10 +28,16 @@ export const no: Dictionary = {
},
heading_5: {
title: "Overskrift 5",
- subtext: "Overskrift på laveste nivå",
+ subtext: "Overskrift for mindre underseksjoner",
aliases: ["h5", "overskrift5", "underoverskrift5"],
group: "Overskrifter",
},
+ heading_6: {
+ title: "Overskrift 6",
+ subtext: "Overskrift på laveste nivå",
+ aliases: ["h6", "overskrift6", "underoverskrift6"],
+ group: "Overskrifter",
+ },
quote: {
title: "Sitat",
subtext: "Sitat eller utdrag",
diff --git a/packages/core/src/i18n/locales/pl.ts b/packages/core/src/i18n/locales/pl.ts
index 24639da252..65ddb9a01c 100644
--- a/packages/core/src/i18n/locales/pl.ts
+++ b/packages/core/src/i18n/locales/pl.ts
@@ -28,10 +28,16 @@ export const pl: Dictionary = {
},
heading_5: {
title: "Nagłówek 5",
- subtext: "Nagłówek najniższego poziomu",
+ subtext: "Nagłówek mniejszej podsekcji",
aliases: ["h5", "naglowek5", "podnaglowek5"],
group: "Nagłówki",
},
+ heading_6: {
+ title: "Nagłówek 6",
+ subtext: "Nagłówek najniższego poziomu",
+ aliases: ["h6", "naglowek6", "podnaglowek6"],
+ group: "Nagłówki",
+ },
quote: {
title: "Cytat",
subtext: "Cytat lub fragment",
diff --git a/packages/core/src/i18n/locales/pt.ts b/packages/core/src/i18n/locales/pt.ts
index 0cb558ceb4..849eaa976e 100644
--- a/packages/core/src/i18n/locales/pt.ts
+++ b/packages/core/src/i18n/locales/pt.ts
@@ -28,10 +28,16 @@ export const pt: Dictionary = {
},
heading_5: {
title: "Título 5",
- subtext: "Usado para títulos de nível mais baixo",
+ subtext: "Usado para títulos de subseções pequenas",
aliases: ["h5", "titulo5", "subtitulo5"],
group: "Títulos",
},
+ heading_6: {
+ title: "Título 6",
+ subtext: "Usado para títulos de nível mais baixo",
+ aliases: ["h6", "titulo6", "subtitulo6"],
+ group: "Títulos",
+ },
quote: {
title: "Citação",
subtext: "Citação ou trecho",
diff --git a/packages/core/src/i18n/locales/ru.ts b/packages/core/src/i18n/locales/ru.ts
index 11b91fe661..5772dc80d0 100644
--- a/packages/core/src/i18n/locales/ru.ts
+++ b/packages/core/src/i18n/locales/ru.ts
@@ -28,10 +28,16 @@ export const ru: Dictionary = {
},
heading_5: {
title: "Заголовок 5 уровня",
- subtext: "Используется для заголовков самого низкого уровня",
+ subtext: "Используется для заголовков небольших подразделов",
aliases: ["h5", "heading5", "subheading5", "заголовок5", "подзаголовок5"],
group: "Заголовки",
},
+ heading_6: {
+ title: "Заголовок 6 уровня",
+ subtext: "Используется для заголовков самого низкого уровня",
+ aliases: ["h6", "heading6", "subheading6", "заголовок6", "подзаголовок6"],
+ group: "Заголовки",
+ },
quote: {
title: "Цитата",
subtext: "Цитата или отрывок",
diff --git a/packages/core/src/i18n/locales/uk.ts b/packages/core/src/i18n/locales/uk.ts
index 8a990ee6ff..e6344ac653 100644
--- a/packages/core/src/i18n/locales/uk.ts
+++ b/packages/core/src/i18n/locales/uk.ts
@@ -28,8 +28,14 @@ export const uk: Dictionary = {
},
heading_5: {
title: "Заголовок 5",
+ subtext: "Використовується для заголовків менших підрозділів",
+ aliases: ["h5", "heading5", "subheading5", "заголовок5", "підзаголовок5"],
+ group: "Заголовки",
+ },
+ heading_6: {
+ title: "Заголовок 6",
subtext: "Використовується для заголовків найнижчого рівня",
- aliases: ["h5", "heading5", "subheading5", "заголовок5"],
+ aliases: ["h6", "heading6", "subheading6", "заголовок6", "підзаголовок6"],
group: "Заголовки",
},
quote: {
diff --git a/packages/core/src/i18n/locales/vi.ts b/packages/core/src/i18n/locales/vi.ts
index afcb3d20cf..9a69b20780 100644
--- a/packages/core/src/i18n/locales/vi.ts
+++ b/packages/core/src/i18n/locales/vi.ts
@@ -28,10 +28,16 @@ export const vi: Dictionary = {
},
heading_5: {
title: "Tiêu đề H5",
- subtext: "Sử dụng cho tiêu đề cấp thấp nhất",
+ subtext: "Sử dụng cho tiêu đề phụ nhỏ hơn",
aliases: ["h5", "tieude5", "tieudephu5"],
group: "Tiêu đề",
},
+ heading_6: {
+ title: "Tiêu đề H6",
+ subtext: "Sử dụng cho tiêu đề cấp thấp nhất",
+ aliases: ["h6", "tieude6", "tieudephu6"],
+ group: "Tiêu đề",
+ },
quote: {
title: "Trích dẫn",
subtext: "Trích dẫn hoặc đoạn trích",
diff --git a/packages/core/src/i18n/locales/zh.ts b/packages/core/src/i18n/locales/zh.ts
index 84f36c5808..5ca8516de7 100644
--- a/packages/core/src/i18n/locales/zh.ts
+++ b/packages/core/src/i18n/locales/zh.ts
@@ -28,10 +28,16 @@ export const zh: Dictionary = {
},
heading_5: {
title: "五级标题",
- subtext: "用于最低层级的标题",
+ subtext: "用于较小的子节标题",
aliases: ["h5", "heading5", "subheading5", "五级标题"],
group: "标题",
},
+ heading_6: {
+ title: "六级标题",
+ subtext: "用于最低层级的标题",
+ aliases: ["h6", "heading6", "subheading6", "六级标题"],
+ group: "标题",
+ },
quote: {
title: "引用",
subtext: "引用或摘录",
diff --git a/packages/react/src/components/FormattingToolbar/DefaultSelects/BlockTypeSelect.tsx b/packages/react/src/components/FormattingToolbar/DefaultSelects/BlockTypeSelect.tsx
index 111f1c5d94..6fbb39451e 100644
--- a/packages/react/src/components/FormattingToolbar/DefaultSelects/BlockTypeSelect.tsx
+++ b/packages/react/src/components/FormattingToolbar/DefaultSelects/BlockTypeSelect.tsx
@@ -13,6 +13,7 @@ import {
RiH3,
RiH4,
RiH5,
+ RiH6,
RiListCheck3,
RiListOrdered,
RiListUnordered,
@@ -98,6 +99,16 @@ export const blockTypeSelectItems = (
"level" in block.props &&
block.props.level === 5,
},
+ {
+ name: dict.slash_menu.heading_6.title,
+ type: "heading",
+ props: { level: 6 },
+ icon: RiH6,
+ isSelected: (block) =>
+ block.type === "heading" &&
+ "level" in block.props &&
+ block.props.level === 6,
+ },
{
name: dict.slash_menu.quote.title,
type: "quote",
From 3eb5a97367c4e75cd48ba274574f5ca53160d205 Mon Sep 17 00:00:00 2001
From: Drew Johnson
Date: Wed, 23 Apr 2025 13:44:01 -0400
Subject: [PATCH 07/13] Update snapshot tests with h6
---
.../__snapshots__/html/basicBlockTypes.json | 24 +++++++-
.../__snapshots__/html/deepNestedContent.json | 26 +++++++--
.../parse/__snapshots__/html/googleDocs.json | 56 +++++++++++++------
.../parse/__snapshots__/html/notion.json | 52 +++++++++++------
.../parse/__snapshots__/markdown/complex.json | 48 +++++++++++-----
.../parse/parseTestInstances.ts | 5 ++
6 files changed, 154 insertions(+), 57 deletions(-)
diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/basicBlockTypes.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/basicBlockTypes.json
index e11339eae9..6f7b646d3c 100644
--- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/basicBlockTypes.json
+++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/basicBlockTypes.json
@@ -94,11 +94,29 @@
"content": [
{
"styles": {},
- "text": "Paragraph",
+ "text": "Heading 6",
"type": "text",
},
],
"id": "6",
+ "props": {
+ "backgroundColor": "default",
+ "level": 6,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Paragraph",
+ "type": "text",
+ },
+ ],
+ "id": "7",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -109,7 +127,7 @@
{
"children": [],
"content": undefined,
- "id": "7",
+ "id": "8",
"props": {
"backgroundColor": "default",
"caption": "Image Caption",
@@ -168,7 +186,7 @@
"type": "text",
},
],
- "id": "8",
+ "id": "9",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json
index fac0b83650..b693d91e73 100644
--- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json
+++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json
@@ -162,11 +162,29 @@
"content": [
{
"styles": {},
- "text": "Paragraph",
+ "text": "Heading 6",
"type": "text",
},
],
"id": "10",
+ "props": {
+ "backgroundColor": "default",
+ "level": 5,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Paragraph",
+ "type": "text",
+ },
+ ],
+ "id": "11",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -177,7 +195,7 @@
{
"children": [],
"content": undefined,
- "id": "11",
+ "id": "12",
"props": {
"backgroundColor": "default",
"caption": "Image Caption",
@@ -251,7 +269,7 @@
"type": "text",
},
],
- "id": "12",
+ "id": "13",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -268,7 +286,7 @@
"type": "text",
},
],
- "id": "13",
+ "id": "14",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/googleDocs.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/googleDocs.json
index a5e2dc0b18..385df9d2a3 100644
--- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/googleDocs.json
+++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/googleDocs.json
@@ -99,6 +99,26 @@
},
"type": "heading",
},
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {
+ "bold": true,
+ },
+ "text": "Heading 6",
+ "type": "text",
+ },
+ ],
+ "id": "6",
+ "props": {
+ "backgroundColor": "default",
+ "level": 6,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
{
"children": [],
"content": [
@@ -108,7 +128,7 @@
"type": "text",
},
],
- "id": "6",
+ "id": "7",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -125,7 +145,7 @@
"type": "text",
},
],
- "id": "7",
+ "id": "8",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -142,7 +162,7 @@
"type": "text",
},
],
- "id": "8",
+ "id": "9",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -160,7 +180,7 @@ Hard Break",
"type": "text",
},
],
- "id": "9",
+ "id": "10",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -217,7 +237,7 @@ Hard Break",
"type": "text",
},
],
- "id": "10",
+ "id": "11",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -238,7 +258,7 @@ Hard Break",
"type": "text",
},
],
- "id": "13",
+ "id": "14",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -255,7 +275,7 @@ Hard Break",
"type": "text",
},
],
- "id": "14",
+ "id": "15",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -271,7 +291,7 @@ Hard Break",
"type": "text",
},
],
- "id": "12",
+ "id": "13",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -288,7 +308,7 @@ Hard Break",
"type": "text",
},
],
- "id": "15",
+ "id": "16",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -304,7 +324,7 @@ Hard Break",
"type": "text",
},
],
- "id": "11",
+ "id": "12",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -321,7 +341,7 @@ Hard Break",
"type": "text",
},
],
- "id": "16",
+ "id": "17",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -338,7 +358,7 @@ Hard Break",
"type": "text",
},
],
- "id": "17",
+ "id": "18",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -355,7 +375,7 @@ Hard Break",
"type": "text",
},
],
- "id": "18",
+ "id": "19",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -366,7 +386,7 @@ Hard Break",
{
"children": [],
"content": undefined,
- "id": "19",
+ "id": "20",
"props": {
"backgroundColor": "default",
"caption": "",
@@ -388,7 +408,7 @@ Hard Break",
"type": "text",
},
],
- "id": "20",
+ "id": "21",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -575,7 +595,7 @@ Hard Break",
],
"type": "tableContent",
},
- "id": "21",
+ "id": "22",
"props": {
"textColor": "default",
},
@@ -590,7 +610,7 @@ Hard Break",
"type": "text",
},
],
- "id": "22",
+ "id": "23",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -608,7 +628,7 @@ Hard Break",
"type": "text",
},
],
- "id": "23",
+ "id": "24",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/notion.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/notion.json
index 84a9766da6..d95864ff74 100644
--- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/notion.json
+++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/notion.json
@@ -94,11 +94,29 @@
"content": [
{
"styles": {},
- "text": "Paragraph 1",
+ "text": "Heading 6",
"type": "text",
},
],
"id": "6",
+ "props": {
+ "backgroundColor": "default",
+ "level": 6,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Paragraph 1",
+ "type": "text",
+ },
+ ],
+ "id": "7",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -115,7 +133,7 @@
"type": "text",
},
],
- "id": "7",
+ "id": "8",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -132,7 +150,7 @@
"type": "text",
},
],
- "id": "8",
+ "id": "9",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -149,7 +167,7 @@
"type": "text",
},
],
- "id": "9",
+ "id": "10",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -206,7 +224,7 @@
"type": "text",
},
],
- "id": "10",
+ "id": "11",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -227,7 +245,7 @@
"type": "text",
},
],
- "id": "13",
+ "id": "14",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -244,7 +262,7 @@
"type": "text",
},
],
- "id": "14",
+ "id": "15",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -260,7 +278,7 @@
"type": "text",
},
],
- "id": "12",
+ "id": "13",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -277,7 +295,7 @@
"type": "text",
},
],
- "id": "15",
+ "id": "16",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -293,7 +311,7 @@
"type": "text",
},
],
- "id": "11",
+ "id": "12",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -310,7 +328,7 @@
"type": "text",
},
],
- "id": "16",
+ "id": "17",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -327,7 +345,7 @@
"type": "text",
},
],
- "id": "17",
+ "id": "18",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -344,7 +362,7 @@
"type": "text",
},
],
- "id": "18",
+ "id": "19",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -361,7 +379,7 @@
"type": "text",
},
],
- "id": "19",
+ "id": "20",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -389,7 +407,7 @@
"type": "link",
},
],
- "id": "20",
+ "id": "21",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -576,7 +594,7 @@
],
"type": "tableContent",
},
- "id": "21",
+ "id": "22",
"props": {
"textColor": "default",
},
@@ -591,7 +609,7 @@
"type": "text",
},
],
- "id": "22",
+ "id": "23",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/markdown/complex.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/markdown/complex.json
index 3db20d42bd..08b5c12080 100644
--- a/tests/src/unit/core/formatConversion/parse/__snapshots__/markdown/complex.json
+++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/markdown/complex.json
@@ -94,11 +94,29 @@
"content": [
{
"styles": {},
- "text": "Paragraph",
+ "text": "Heading 6",
"type": "text",
},
],
"id": "6",
+ "props": {
+ "backgroundColor": "default",
+ "level": 6,
+ "textAlignment": "left",
+ "textColor": "default",
+ },
+ "type": "heading",
+ },
+ {
+ "children": [],
+ "content": [
+ {
+ "styles": {},
+ "text": "Paragraph",
+ "type": "text",
+ },
+ ],
+ "id": "7",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -134,7 +152,7 @@
"type": "text",
},
],
- "id": "7",
+ "id": "8",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -170,7 +188,7 @@
"type": "text",
},
],
- "id": "8",
+ "id": "9",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -187,7 +205,7 @@
"type": "text",
},
],
- "id": "9",
+ "id": "10",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -208,7 +226,7 @@
"type": "text",
},
],
- "id": "12",
+ "id": "13",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -224,7 +242,7 @@
"type": "text",
},
],
- "id": "11",
+ "id": "12",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -243,7 +261,7 @@
"type": "text",
},
],
- "id": "14",
+ "id": "15",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -260,7 +278,7 @@
"type": "text",
},
],
- "id": "15",
+ "id": "16",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -279,7 +297,7 @@
"type": "text",
},
],
- "id": "17",
+ "id": "18",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -295,7 +313,7 @@
"type": "text",
},
],
- "id": "16",
+ "id": "17",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -312,7 +330,7 @@
"type": "text",
},
],
- "id": "18",
+ "id": "19",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -328,7 +346,7 @@
"type": "text",
},
],
- "id": "13",
+ "id": "14",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -345,7 +363,7 @@
"type": "text",
},
],
- "id": "19",
+ "id": "20",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -361,7 +379,7 @@
"type": "text",
},
],
- "id": "10",
+ "id": "11",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
@@ -378,7 +396,7 @@
"type": "text",
},
],
- "id": "20",
+ "id": "21",
"props": {
"backgroundColor": "default",
"textAlignment": "left",
diff --git a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts
index f5d0744bdf..5d8494fe7e 100644
--- a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts
+++ b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts
@@ -24,6 +24,7 @@ export const parseTestInstancesHTML: TestInstance<
Heading 3
Heading 4
Heading 5
+Heading 6
Paragraph
Image Caption
None Bold Italic Underline Strikethrough All
`,
@@ -290,6 +291,7 @@ export const parseTestInstancesHTML: TestInstance<
Heading 3
Heading 4
Heading 5
+ Heading 6
Paragraph
Image Caption
Bold Italic Underline Strikethrough All
@@ -421,6 +423,7 @@ With Hard Break
Heading 3
Heading 4
Heading 5
+Heading 6
Paragraph 1
Paragraph 2
Paragraph 3
@@ -576,6 +579,8 @@ Paragraph
##### Heading 5
+###### Heading 6
+
Paragraph
P**ara***grap*h
From 9f47f75122733947ef1fd7f7fe36849b31b7bf8c Mon Sep 17 00:00:00 2001
From: Drew Johnson
Date: Wed, 23 Apr 2025 13:45:24 -0400
Subject: [PATCH 08/13] Add the h6 icon for slash menu item
---
.../components/SuggestionMenu/getDefaultReactSlashMenuItems.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/packages/react/src/components/SuggestionMenu/getDefaultReactSlashMenuItems.tsx b/packages/react/src/components/SuggestionMenu/getDefaultReactSlashMenuItems.tsx
index 979e82f984..c97b50b8ed 100644
--- a/packages/react/src/components/SuggestionMenu/getDefaultReactSlashMenuItems.tsx
+++ b/packages/react/src/components/SuggestionMenu/getDefaultReactSlashMenuItems.tsx
@@ -15,6 +15,7 @@ import {
RiH3,
RiH4,
RiH5,
+ RiH6,
RiImage2Fill,
RiListCheck3,
RiListOrdered,
@@ -32,6 +33,7 @@ const icons = {
heading_3: RiH3,
heading_4: RiH4,
heading_5: RiH5,
+ heading_6: RiH6,
quote: RiQuoteText,
numbered_list: RiListOrdered,
bullet_list: RiListUnordered,
From 0cf25c0fb11fd58182a75edf8f0776cf7ab57844 Mon Sep 17 00:00:00 2001
From: Drew Johnson
Date: Wed, 23 Apr 2025 13:47:46 -0400
Subject: [PATCH 09/13] Test H6 notion snapshot
---
tests/src/unit/core/formatConversion/parse/parseTestInstances.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts
index 5d8494fe7e..76c3fa602e 100644
--- a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts
+++ b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts
@@ -360,6 +360,7 @@ export const parseTestInstancesHTML: TestInstance<
Heading 3
Heading 4
Heading 5
+Heading 6
Paragraph 1
Nested Paragraph 1
Nested Paragraph 2
From d06e86e516fb91bbae6c0b7b1730067c24ee46b4 Mon Sep 17 00:00:00 2001
From: Drew Johnson
Date: Tue, 20 May 2025 12:01:08 -0400
Subject: [PATCH 10/13] zh locale and pdf export
---
packages/core/src/i18n/locales/zh-tw.ts | 18 ++++++++++++++++++
.../src/pdf/defaultSchema/blocks.tsx | 12 +++++++++---
2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/packages/core/src/i18n/locales/zh-tw.ts b/packages/core/src/i18n/locales/zh-tw.ts
index e9556ae225..98099bc767 100644
--- a/packages/core/src/i18n/locales/zh-tw.ts
+++ b/packages/core/src/i18n/locales/zh-tw.ts
@@ -20,6 +20,24 @@ export const zhTW: Dictionary = {
aliases: ["h3", "heading3", "subheading", "標題", "三級標題"],
group: "標題",
},
+ heading_4: {
+ title: "四級標題",
+ subtext: "用於小節和分組標題",
+ aliases: ["h4", "heading4", "subheading", "標題", "四級標題"],
+ group: "標題",
+ },
+ heading_5: {
+ title: "五級標題",
+ subtext: "用於小節和分組標題",
+ aliases: ["h5", "heading5", "subheading", "標題", "五級標題"],
+ group: "標題",
+ },
+ heading_6: {
+ title: "六級標題",
+ subtext: "用於小節和分組標題",
+ aliases: ["h6", "heading6", "subheading", "標題", "六級標題"],
+ group: "標題",
+ },
quote: {
title: "引用",
subtext: "引用或摘錄",
diff --git a/packages/xl-pdf-exporter/src/pdf/defaultSchema/blocks.tsx b/packages/xl-pdf-exporter/src/pdf/defaultSchema/blocks.tsx
index 31e4c23323..2ae9ed0557 100644
--- a/packages/xl-pdf-exporter/src/pdf/defaultSchema/blocks.tsx
+++ b/packages/xl-pdf-exporter/src/pdf/defaultSchema/blocks.tsx
@@ -59,12 +59,18 @@ export const pdfBlockMappingForDefaultSchema: BlockMapping<
);
},
heading: (block, exporter) => {
- const fontSizeEM =
- block.props.level === 1 ? 2 : block.props.level === 2 ? 1.5 : 1.17;
+ const levelFontSizeEM = {
+ 1: 2,
+ 2: 1.5,
+ 3: 1.17,
+ 4: 1,
+ 5: 0.83,
+ 6: 0.67,
+ }[block.props.level];
return (
From c0826e2098fff681f1436f6d7a2f83819adc98c0 Mon Sep 17 00:00:00 2001
From: Drew Johnson
Date: Wed, 21 May 2025 08:23:07 -0400
Subject: [PATCH 11/13] Update tests for new heading levels
---
.../api/schema/__snapshots__/schemaToJSONSchema.test.ts.snap | 3 +++
.../parse/__snapshots__/html/deepNestedContent.json | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/packages/xl-ai/src/api/schema/__snapshots__/schemaToJSONSchema.test.ts.snap b/packages/xl-ai/src/api/schema/__snapshots__/schemaToJSONSchema.test.ts.snap
index 818662b135..361c3e4bb9 100644
--- a/packages/xl-ai/src/api/schema/__snapshots__/schemaToJSONSchema.test.ts.snap
+++ b/packages/xl-ai/src/api/schema/__snapshots__/schemaToJSONSchema.test.ts.snap
@@ -45,6 +45,9 @@ exports[`creates json schema 1`] = `
1,
2,
3,
+ 4,
+ 5,
+ 6,
],
"type": "number",
},
diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json
index 5c7ce1157d..af4b4a5bd5 100644
--- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json
+++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/deepNestedContent.json
@@ -169,7 +169,7 @@
"id": "10",
"props": {
"backgroundColor": "default",
- "level": 5,
+ "level": 6,
"textAlignment": "left",
"textColor": "default",
},
From 9431c320e893de88775d2c85016616a0dd144ace Mon Sep 17 00:00:00 2001
From: Nick the Sick
Date: Mon, 23 Jun 2025 13:42:20 +0200
Subject: [PATCH 12/13] feat: make headings configurable up to 6 levels
---
docs/pages/docs/editor-basics/setup.mdx | 5 +
.../HeadingBlockContent.ts | 12 +-
packages/core/src/editor/BlockNoteEditor.ts | 18 +++
.../getDefaultSlashMenuItems.ts | 115 ++++++++----------
packages/core/src/i18n/locales/ar.ts | 12 +-
packages/core/src/i18n/locales/de.ts | 12 +-
packages/core/src/i18n/locales/en.ts | 12 +-
packages/core/src/i18n/locales/es.ts | 12 +-
packages/core/src/i18n/locales/fr.ts | 12 +-
packages/core/src/i18n/locales/hr.ts | 12 +-
packages/core/src/i18n/locales/is.ts | 12 +-
packages/core/src/i18n/locales/it.ts | 12 +-
packages/core/src/i18n/locales/ja.ts | 12 +-
packages/core/src/i18n/locales/ko.ts | 10 +-
packages/core/src/i18n/locales/nl.ts | 12 +-
packages/core/src/i18n/locales/no.ts | 12 +-
packages/core/src/i18n/locales/pl.ts | 12 +-
packages/core/src/i18n/locales/pt.ts | 12 +-
packages/core/src/i18n/locales/ru.ts | 12 +-
packages/core/src/i18n/locales/sk.ts | 12 +-
packages/core/src/i18n/locales/uk.ts | 12 +-
packages/core/src/i18n/locales/vi.ts | 12 +-
packages/core/src/i18n/locales/zh-tw.ts | 12 +-
packages/core/src/i18n/locales/zh.ts | 12 +-
24 files changed, 202 insertions(+), 186 deletions(-)
diff --git a/docs/pages/docs/editor-basics/setup.mdx b/docs/pages/docs/editor-basics/setup.mdx
index fbb8795f89..84115ddd5f 100644
--- a/docs/pages/docs/editor-basics/setup.mdx
+++ b/docs/pages/docs/editor-basics/setup.mdx
@@ -32,6 +32,9 @@ type BlockNoteEditorOptions = {
width?: number;
class?: string;
}) => Plugin;
+ heading?: {
+ levels?: number[];
+ };
initialContent?: PartialBlock[];
pasteHandler?: (context: {
event: ClipboardEvent;
@@ -73,6 +76,8 @@ The hook takes two optional parameters:
`initialContent:` The content that should be in the editor when it's created, represented as an array of [Partial Blocks](/docs/manipulating-blocks#partial-blocks).
+`heading`: Configuration for headings. Allows you to configure the number of levels of headings that should be available in the editor. Defaults to `[1, 2, 3]`. Configurable up to 6 levels of headings.
+
`pasteHandler`: A function that can be used to override the default paste behavior. See [Paste Handling](/docs/advanced/paste-handling) for more.
`resolveFileUrl:` Function to resolve file URLs for display/download. Useful for creating authenticated URLs or implementing custom protocols.
diff --git a/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts b/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts
index deb2172755..5b8d7003d0 100644
--- a/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts
+++ b/packages/core/src/blocks/HeadingBlockContent/HeadingBlockContent.ts
@@ -11,6 +11,7 @@ import {
import { createDefaultBlockDOMOutputSpec } from "../defaultBlockHelpers.js";
import { defaultProps } from "../defaultProps.js";
import { createToggleWrapper } from "../ToggleWrapper/createToggleWrapper.js";
+import { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
const HEADING_LEVELS = [1, 2, 3, 4, 5, 6] as const;
@@ -30,8 +31,9 @@ const HeadingBlockContent = createStronglyTypedTiptapNode({
},
addInputRules() {
+ const editor = this.options.editor as BlockNoteEditor;
return [
- ...HEADING_LEVELS.map((level) => {
+ ...editor.settings.heading.levels.map((level) => {
// Creates a heading of appropriate level when starting with "#", "##", or "###".
return new InputRule({
find: new RegExp(`^(#{${level}})\\s$`),
@@ -63,8 +65,10 @@ const HeadingBlockContent = createStronglyTypedTiptapNode({
},
addKeyboardShortcuts() {
+ const editor = this.options.editor as BlockNoteEditor;
+
return Object.fromEntries(
- HEADING_LEVELS.map((level) => [
+ editor.settings.heading.levels.map((level) => [
`Mod-Alt-${level}`,
() => {
const blockInfo = getBlockInfoFromSelection(this.editor.state);
@@ -88,13 +92,15 @@ const HeadingBlockContent = createStronglyTypedTiptapNode({
);
},
parseHTML() {
+ const editor = this.options.editor as BlockNoteEditor;
+
return [
// Parse from internal HTML.
{
tag: "div[data-content-type=" + this.name + "]",
contentElement: ".bn-inline-content",
},
- ...HEADING_LEVELS.map((level) => ({
+ ...editor.settings.heading.levels.map((level) => ({
tag: `h${level}`,
attrs: { level },
node: "heading",
diff --git a/packages/core/src/editor/BlockNoteEditor.ts b/packages/core/src/editor/BlockNoteEditor.ts
index 8008312c34..fe68128033 100644
--- a/packages/core/src/editor/BlockNoteEditor.ts
+++ b/packages/core/src/editor/BlockNoteEditor.ts
@@ -229,6 +229,18 @@ export type BlockNoteEditorOptions<
class?: string;
}) => Plugin;
+ /**
+ * Configuration for headings
+ */
+ heading?: {
+ /**
+ * The levels of headings that should be available in the editor.
+ * @note Configurable up to 6 levels of headings.
+ * @default [1, 2, 3]
+ */
+ levels?: (1 | 2 | 3 | 4 | 5 | 6)[];
+ };
+
/**
* The content that should be in the editor when it's created, represented as an array of partial block objects.
*/
@@ -527,6 +539,9 @@ export class BlockNoteEditor<
headers: boolean;
};
codeBlock: CodeBlockOptions;
+ heading: {
+ levels: (1 | 2 | 3 | 4 | 5 | 6)[];
+ };
};
public static create<
@@ -580,6 +595,9 @@ export class BlockNoteEditor<
supportedLanguages: options?.codeBlock?.supportedLanguages ?? {},
createHighlighter: options?.codeBlock?.createHighlighter ?? undefined,
},
+ heading: {
+ levels: options?.heading?.levels ?? [1, 2, 3],
+ },
};
// apply defaults
diff --git a/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts b/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts
index 5a4e4ee2e5..bcc95c83a7 100644
--- a/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts
+++ b/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts
@@ -122,70 +122,6 @@ export function getDefaultSlashMenuItems<
key: "heading_3",
...editor.dictionary.slash_menu.heading_3,
},
- {
- onItemClick: () => {
- insertOrUpdateBlock(editor, {
- type: "heading",
- props: { level: 4 },
- });
- },
- badge: formatKeyboardShortcut("Mod-Alt-4"),
- key: "heading_4",
- ...editor.dictionary.slash_menu.heading_4,
- },
- {
- onItemClick: () => {
- insertOrUpdateBlock(editor, {
- type: "heading",
- props: { level: 5 },
- });
- },
- badge: formatKeyboardShortcut("Mod-Alt-5"),
- key: "heading_5",
- ...editor.dictionary.slash_menu.heading_5,
- },
- {
- onItemClick: () => {
- insertOrUpdateBlock(editor, {
- type: "heading",
- props: { level: 6 },
- });
- },
- badge: formatKeyboardShortcut("Mod-Alt-6"),
- key: "heading_6",
- ...editor.dictionary.slash_menu.heading_6,
- },
- {
- onItemClick: () => {
- insertOrUpdateBlock(editor, {
- type: "heading",
- props: { level: 1, isToggleable: true },
- });
- },
- key: "toggle_heading",
- ...editor.dictionary.slash_menu.toggle_heading,
- },
- {
- onItemClick: () => {
- insertOrUpdateBlock(editor, {
- type: "heading",
- props: { level: 2, isToggleable: true },
- });
- },
-
- key: "toggle_heading_2",
- ...editor.dictionary.slash_menu.toggle_heading_2,
- },
- {
- onItemClick: () => {
- insertOrUpdateBlock(editor, {
- type: "heading",
- props: { level: 3, isToggleable: true },
- });
- },
- key: "toggle_heading_3",
- ...editor.dictionary.slash_menu.toggle_heading_3,
- },
);
}
@@ -379,6 +315,57 @@ export function getDefaultSlashMenuItems<
});
}
+ if (checkDefaultBlockTypeInSchema("heading", editor)) {
+ items.push(
+ {
+ onItemClick: () => {
+ insertOrUpdateBlock(editor, {
+ type: "heading",
+ props: { level: 1, isToggleable: true },
+ });
+ },
+ key: "toggle_heading",
+ ...editor.dictionary.slash_menu.toggle_heading,
+ },
+ {
+ onItemClick: () => {
+ insertOrUpdateBlock(editor, {
+ type: "heading",
+ props: { level: 2, isToggleable: true },
+ });
+ },
+
+ key: "toggle_heading_2",
+ ...editor.dictionary.slash_menu.toggle_heading_2,
+ },
+ {
+ onItemClick: () => {
+ insertOrUpdateBlock(editor, {
+ type: "heading",
+ props: { level: 3, isToggleable: true },
+ });
+ },
+ key: "toggle_heading_3",
+ ...editor.dictionary.slash_menu.toggle_heading_3,
+ },
+ );
+
+ editor.settings.heading.levels
+ .filter((level): level is 4 | 5 | 6 => level > 3)
+ .forEach((level) => {
+ items.push({
+ onItemClick: () => {
+ insertOrUpdateBlock(editor, {
+ type: "heading",
+ props: { level: level },
+ });
+ },
+ key: `heading_${level}`,
+ ...editor.dictionary.slash_menu[`heading_${level}`],
+ });
+ });
+ }
+
items.push({
onItemClick: () => {
editor.openSuggestionMenu(":", {
diff --git a/packages/core/src/i18n/locales/ar.ts b/packages/core/src/i18n/locales/ar.ts
index dc360af5f5..12ae9f6980 100644
--- a/packages/core/src/i18n/locales/ar.ts
+++ b/packages/core/src/i18n/locales/ar.ts
@@ -24,37 +24,37 @@ export const ar: Dictionary = {
title: "عنوان 4",
subtext: "عنوان فرعي ثانوي صغير",
aliases: ["ع4", "عنوان4", "عنوان فرعي صغير"],
- group: "العناوين",
+ group: "العناوين الفرعية",
},
heading_5: {
title: "عنوان 5",
subtext: "عنوان فرعي صغير",
aliases: ["ع5", "عنوان5", "عنوان فرعي صغير"],
- group: "العناوين",
+ group: "العناوين الفرعية",
},
heading_6: {
title: "عنوان 6",
subtext: "أدنى مستوى للعناوين",
aliases: ["ع6", "عنوان6", "العنوان الفرعي الأدنى"],
- group: "العناوين",
+ group: "العناوين الفرعية",
},
toggle_heading: {
title: "عنوان قابل للطي 1",
subtext: "عنوان قابل للطي لإظهار وإخفاء المحتوى",
aliases: ["ع", "عنوان1", "ع1", "قابل للطي", "طي"],
- group: "العناوين",
+ group: "العناوين الفرعية",
},
toggle_heading_2: {
title: "عنوان قابل للطي 2",
subtext: "عنوان فرعي قابل للطي لإظهار وإخفاء المحتوى",
aliases: ["ع2", "عنوان2", "عنوان فرعي", "قابل للطي", "طي"],
- group: "العناوين",
+ group: "العناوين الفرعية",
},
toggle_heading_3: {
title: "عنوان قابل للطي 3",
subtext: "عنوان فرعي ثانوي قابل للطي لإظهار وإخفاء المحتوى",
aliases: ["ع3", "عنوان3", "عنوان فرعي", "قابل للطي", "طي"],
- group: "العناوين",
+ group: "العناوين الفرعية",
},
quote: {
title: "اقتباس",
diff --git a/packages/core/src/i18n/locales/de.ts b/packages/core/src/i18n/locales/de.ts
index 8bb41c7c48..fa97a6aeb2 100644
--- a/packages/core/src/i18n/locales/de.ts
+++ b/packages/core/src/i18n/locales/de.ts
@@ -24,25 +24,25 @@ export const de: Dictionary = {
title: "Überschrift 4",
subtext: "Überschrift für kleinere Unterabschnitte",
aliases: ["h4", "überschrift4", "unterüberschrift4"],
- group: "Überschriften",
+ group: "Unterüberschriften",
},
heading_5: {
title: "Überschrift 5",
subtext: "Überschrift für tiefere Unterabschnitte",
aliases: ["h5", "überschrift5", "unterüberschrift5"],
- group: "Überschriften",
+ group: "Unterüberschriften",
},
heading_6: {
title: "Überschrift 6",
subtext: "Überschrift auf der untersten Ebene",
aliases: ["h6", "überschrift6", "unterüberschrift6"],
- group: "Überschriften",
+ group: "Unterüberschriften",
},
toggle_heading: {
title: "Aufklappbare Überschrift 1",
subtext: "Aufklappbare Hauptebene Überschrift",
aliases: ["h", "überschrift1", "h1", "aufklappbar", "einklappbar"],
- group: "Überschriften",
+ group: "Unterüberschrift",
},
toggle_heading_2: {
title: "Aufklappbare Überschrift 2",
@@ -54,7 +54,7 @@ export const de: Dictionary = {
"aufklappbar",
"einklappbar",
],
- group: "Überschriften",
+ group: "Unterüberschriften",
},
toggle_heading_3: {
title: "Aufklappbare Überschrift 3",
@@ -66,7 +66,7 @@ export const de: Dictionary = {
"aufklappbar",
"einklappbar",
],
- group: "Überschriften",
+ group: "Unterüberschriften",
},
quote: {
title: "Zitat",
diff --git a/packages/core/src/i18n/locales/en.ts b/packages/core/src/i18n/locales/en.ts
index ded53da300..78f5d83bb0 100644
--- a/packages/core/src/i18n/locales/en.ts
+++ b/packages/core/src/i18n/locales/en.ts
@@ -22,37 +22,37 @@ export const en = {
title: "Heading 4",
subtext: "Minor subsection heading",
aliases: ["h4", "heading4", "subheading4"],
- group: "Headings",
+ group: "Subheadings",
},
heading_5: {
title: "Heading 5",
subtext: "Small subsection heading",
aliases: ["h5", "heading5", "subheading5"],
- group: "Headings",
+ group: "Subheadings",
},
heading_6: {
title: "Heading 6",
subtext: "Lowest-level heading",
aliases: ["h6", "heading6", "subheading6"],
- group: "Headings",
+ group: "Subheadings",
},
toggle_heading: {
title: "Toggle Heading 1",
subtext: "Toggleable top-level heading",
aliases: ["h", "heading1", "h1", "collapsable"],
- group: "Headings",
+ group: "Subheadings",
},
toggle_heading_2: {
title: "Toggle Heading 2",
subtext: "Toggleable key section heading",
aliases: ["h2", "heading2", "subheading", "collapsable"],
- group: "Headings",
+ group: "Subheadings",
},
toggle_heading_3: {
title: "Toggle Heading 3",
subtext: "Toggleable subsection and group heading",
aliases: ["h3", "heading3", "subheading", "collapsable"],
- group: "Headings",
+ group: "Subheadings",
},
quote: {
title: "Quote",
diff --git a/packages/core/src/i18n/locales/es.ts b/packages/core/src/i18n/locales/es.ts
index 140187349d..66af2f0926 100644
--- a/packages/core/src/i18n/locales/es.ts
+++ b/packages/core/src/i18n/locales/es.ts
@@ -24,37 +24,37 @@ export const es: Dictionary = {
title: "Encabezado 4",
subtext: "Encabezado de subsección menor",
aliases: ["h4", "encabezado4", "subencabezado4"],
- group: "Encabezados",
+ group: "Subencabezados",
},
heading_5: {
title: "Encabezado 5",
subtext: "Encabezado de subsección pequeña",
aliases: ["h5", "encabezado5", "subencabezado5"],
- group: "Encabezados",
+ group: "Subencabezados",
},
heading_6: {
title: "Encabezado 6",
subtext: "Encabezado de nivel más bajo",
aliases: ["h6", "encabezado6", "subencabezado6"],
- group: "Encabezados",
+ group: "Subencabezados",
},
toggle_heading: {
title: "Encabezado Plegable 1",
subtext: "Encabezado de primer nivel que se puede plegar",
aliases: ["h", "encabezado1", "h1", "plegable", "contraible"],
- group: "Encabezados",
+ group: "Subencabezados",
},
toggle_heading_2: {
title: "Encabezado Plegable 2",
subtext: "Encabezado de sección principal que se puede plegar",
aliases: ["h2", "encabezado2", "subencabezado", "plegable", "contraible"],
- group: "Encabezados",
+ group: "Subencabezados",
},
toggle_heading_3: {
title: "Encabezado Plegable 3",
subtext: "Encabezado de subsección y grupo que se puede plegar",
aliases: ["h3", "encabezado3", "subencabezado", "plegable", "contraible"],
- group: "Encabezados",
+ group: "Subencabezados",
},
quote: {
title: "Cita",
diff --git a/packages/core/src/i18n/locales/fr.ts b/packages/core/src/i18n/locales/fr.ts
index 955568fe4b..b5cc28b1ac 100644
--- a/packages/core/src/i18n/locales/fr.ts
+++ b/packages/core/src/i18n/locales/fr.ts
@@ -25,26 +25,26 @@ export const fr: Dictionary = {
title: "Titre 4",
subtext: "Titre de sous‑section mineure",
aliases: ["h4", "titre4", "sous‑titre4"],
- group: "Titres",
+ group: "Sous-titres",
},
heading_5: {
title: "Titre 5",
subtext: "Titre de sous-section mineure",
aliases: ["h5", "titre5", "sous-titre5"],
- group: "Titres",
+ group: "Sous-titres",
},
heading_6: {
title: "Titre 6",
subtext: "Titre de niveau le plus bas",
aliases: ["h6", "titre6", "sous-titre6"],
- group: "Titres",
+ group: "Sous-titres",
},
toggle_heading: {
title: "Titre Repliable 1",
subtext:
"Titre de premier niveau qui peut être replié pour masquer son contenu",
aliases: ["h", "titre1", "h1", "repliable", "masquable", "déroulant"],
- group: "Titres",
+ group: "Sous-titres",
},
toggle_heading_2: {
title: "Titre Repliable 2",
@@ -57,7 +57,7 @@ export const fr: Dictionary = {
"masquable",
"déroulant",
],
- group: "Titres",
+ group: "Sous-titres",
},
toggle_heading_3: {
title: "Titre Repliable 3",
@@ -71,7 +71,7 @@ export const fr: Dictionary = {
"masquable",
"déroulant",
],
- group: "Titres",
+ group: "Sous-titres",
},
quote: {
title: "Citation",
diff --git a/packages/core/src/i18n/locales/hr.ts b/packages/core/src/i18n/locales/hr.ts
index 2632287387..74527a60c9 100644
--- a/packages/core/src/i18n/locales/hr.ts
+++ b/packages/core/src/i18n/locales/hr.ts
@@ -24,37 +24,37 @@ export const hr: Dictionary = {
title: "Naslov 4",
subtext: "Manji naslov podpoglavlja",
aliases: ["h4", "naslov4", "podnaslov4"],
- group: "Naslovi",
+ group: "Podnaslovi",
},
heading_5: {
title: "Naslov 5",
subtext: "Mali naslov podpoglavlja",
aliases: ["h5", "naslov5", "podnaslov5"],
- group: "Naslovi",
+ group: "Podnaslovi",
},
heading_6: {
title: "Naslov 6",
subtext: "Naslov najniže razine",
aliases: ["h6", "naslov6", "podnaslov6"],
- group: "Naslovi",
+ group: "Podnaslovi",
},
toggle_heading: {
title: "Proširivi Naslov 1",
subtext: "Proširivi glavni naslov",
aliases: ["h", "naslov1", "h1", "proširivi"],
- group: "Naslovi",
+ group: "Podnaslovi",
},
toggle_heading_2: {
title: "Proširivi Naslov 2",
subtext: "Proširivi naslov poglavlja",
aliases: ["h2", "naslov2", "podnaslov", "proširivi"],
- group: "Naslovi",
+ group: "Podnaslovi",
},
toggle_heading_3: {
title: "Proširivi Naslov 3",
subtext: "Proširivi naslov podpoglavlja",
aliases: ["h3", "naslov3", "podnaslov", "proširivi"],
- group: "Naslovi",
+ group: "Podnaslovi",
},
quote: {
title: "Citat",
diff --git a/packages/core/src/i18n/locales/is.ts b/packages/core/src/i18n/locales/is.ts
index 66f9b42e17..e0d08db73f 100644
--- a/packages/core/src/i18n/locales/is.ts
+++ b/packages/core/src/i18n/locales/is.ts
@@ -24,26 +24,26 @@ export const is: Dictionary = {
title: "Fyrirsögn 4",
subtext: "Titill fyrir minni undirhluta",
aliases: ["h4", "fyrirsogn4", "undirfyrirsogn4"],
- group: "Fyrirsagnir",
+ group: "Undirfyrirsagnir",
},
heading_5: {
title: "Fyrirsögn 5",
subtext: "Titill fyrir litla undirkafla",
aliases: ["h5", "fyrirsogn5", "undirfyrirsogn5"],
- group: "Fyrirsagnir",
+ group: "Undirfyrirsagnir",
},
heading_6: {
title: "Fyrirsögn 6",
subtext: "Titill á lægsta stigi",
aliases: ["h6", "fyrirsogn6", "undirfyrirsogn6"],
- group: "Fyrirsagnir",
+ group: "Undirfyrirsagnir",
},
toggle_heading: {
title: "Fellanleg Fyrirsögn 1",
subtext:
"Fellanleg efsta fyrirsögn sem hægt er að sýna eða fela innihald",
aliases: ["h", "fyrirsogn1", "h1", "fellanleg", "fellanlegt"],
- group: "Fyrirsagnir",
+ group: "Undirfyrirsagnir",
},
toggle_heading_2: {
title: "Fellanleg Fyrirsögn 2",
@@ -56,7 +56,7 @@ export const is: Dictionary = {
"fellanleg",
"fellanlegt",
],
- group: "Fyrirsagnir",
+ group: "Undirfyrirsagnir",
},
toggle_heading_3: {
title: "Fellanleg Fyrirsögn 3",
@@ -69,7 +69,7 @@ export const is: Dictionary = {
"fellanleg",
"fellanlegt",
],
- group: "Fyrirsagnir",
+ group: "Undirfyrirsagnir",
},
quote: {
title: "Tilvitnun",
diff --git a/packages/core/src/i18n/locales/it.ts b/packages/core/src/i18n/locales/it.ts
index f0637c24ef..cba938b4c3 100644
--- a/packages/core/src/i18n/locales/it.ts
+++ b/packages/core/src/i18n/locales/it.ts
@@ -24,26 +24,26 @@ export const it: Dictionary = {
title: "Intestazione 4",
subtext: "Intestazione di sottosezione minore",
aliases: ["h4", "intestazione4", "sottotitolo4"],
- group: "Intestazioni",
+ group: "Sottotitoli",
},
heading_5: {
title: "Intestazione 5",
subtext: "Intestazione di sottosezione minore",
aliases: ["h5", "intestazione5", "sottotitolo5"],
- group: "Intestazioni",
+ group: "Sottotitoli",
},
heading_6: {
title: "Intestazione 6",
subtext: "Intestazione di livello più basso",
aliases: ["h6", "intestazione6", "sottotitolo6"],
- group: "Intestazioni",
+ group: "Sottotitoli",
},
toggle_heading: {
title: "Intestazione Espandibile 1",
subtext:
"Intestazione di primo livello che può essere espansa o compressa per mostrare il contenuto",
aliases: ["h", "intestazione1", "h1", "espandibile", "comprimibile"],
- group: "Intestazioni",
+ group: "Sottotitoli",
},
toggle_heading_2: {
title: "Intestazione Espandibile 2",
@@ -56,7 +56,7 @@ export const it: Dictionary = {
"espandibile",
"comprimibile",
],
- group: "Intestazioni",
+ group: "Sottotitoli",
},
toggle_heading_3: {
title: "Intestazione Espandibile 3",
@@ -69,7 +69,7 @@ export const it: Dictionary = {
"espandibile",
"comprimibile",
],
- group: "Intestazioni",
+ group: "Sottotitoli",
},
quote: {
title: "Citazione",
diff --git a/packages/core/src/i18n/locales/ja.ts b/packages/core/src/i18n/locales/ja.ts
index 5719773d16..3bd6ff47fb 100644
--- a/packages/core/src/i18n/locales/ja.ts
+++ b/packages/core/src/i18n/locales/ja.ts
@@ -24,25 +24,25 @@ export const ja: Dictionary = {
title: "見出し4",
subtext: "小さなサブセクションの見出しに使用",
aliases: ["h4", "見出し4", "subheading4", "小見出し4"],
- group: "見出し",
+ group: "サブ見出し",
},
heading_5: {
title: "見出し5",
subtext: "小さなサブセクションの見出しに使用",
aliases: ["h5", "見出し5", "subheading5", "小見出し5"],
- group: "見出し",
+ group: "サブ見出し",
},
heading_6: {
title: "見出し6",
subtext: "最下位レベルの見出しに使用",
aliases: ["h6", "見出し6", "subheading6", "小見出し6"],
- group: "見出し",
+ group: "サブ見出し",
},
toggle_heading: {
title: "折りたたみ見出し1",
subtext: "内容の表示/非表示が切り替え可能なトップレベルの見出し",
aliases: ["h", "見出し1", "h1", "大見出し", "折りたたみ", "トグル"],
- group: "見出し",
+ group: "サブ見出し",
},
toggle_heading_2: {
title: "折りたたみ見出し2",
@@ -55,7 +55,7 @@ export const ja: Dictionary = {
"折りたたみ",
"トグル",
],
- group: "見出し",
+ group: "サブ見出し",
},
toggle_heading_3: {
title: "折りたたみ見出し3",
@@ -68,7 +68,7 @@ export const ja: Dictionary = {
"折りたたみ",
"トグル",
],
- group: "見出し",
+ group: "サブ見出し",
},
quote: {
title: "引用",
diff --git a/packages/core/src/i18n/locales/ko.ts b/packages/core/src/i18n/locales/ko.ts
index c4b52bb1df..dc13c893ce 100644
--- a/packages/core/src/i18n/locales/ko.ts
+++ b/packages/core/src/i18n/locales/ko.ts
@@ -24,19 +24,19 @@ export const ko: Dictionary = {
title: "제목4",
subtext: "하위 소단락 제목",
aliases: ["h4", "제목4", "소제목4"],
- group: "제목",
+ group: "소제목",
},
heading_5: {
title: "제목5",
subtext: "작은 하위 섹션 제목",
aliases: ["h5", "제목5", "소제목5"],
- group: "제목",
+ group: "소제목",
},
heading_6: {
title: "제목6",
subtext: "가장 하위 수준 제목",
aliases: ["h6", "제목6", "소제목6"],
- group: "제목",
+ group: "소제목",
},
toggle_heading: {
title: "접을 수 있는 제목1",
@@ -48,13 +48,13 @@ export const ko: Dictionary = {
title: "접을 수 있는 제목2",
subtext: "내용을 표시하거나 숨길 수 있는 섹션 제목(중)",
aliases: ["h2", "제목2", "중제목", "접기", "토글"],
- group: "제목",
+ group: "소제목",
},
toggle_heading_3: {
title: "접을 수 있는 제목3",
subtext: "내용을 표시하거나 숨길 수 있는 섹션 제목(소)",
aliases: ["h3", "제목3", "subheading", "접기", "토글"],
- group: "제목",
+ group: "소제목",
},
quote: {
title: "인용",
diff --git a/packages/core/src/i18n/locales/nl.ts b/packages/core/src/i18n/locales/nl.ts
index f67ebe337d..923026e834 100644
--- a/packages/core/src/i18n/locales/nl.ts
+++ b/packages/core/src/i18n/locales/nl.ts
@@ -24,38 +24,38 @@ export const nl: Dictionary = {
title: "Kop 4",
subtext: "Gebruikt voor kleinere subsecties",
aliases: ["h4", "kop4", "subkop4"],
- group: "Koppen",
+ group: "Subkoppen",
},
heading_5: {
title: "Kop 5",
subtext: "Gebruikt voor kleinere subsecties",
aliases: ["h5", "kop5", "subkop5"],
- group: "Koppen",
+ group: "Subkoppen",
},
heading_6: {
title: "Kop 6",
subtext: "Gebruikt voor koppen op het laagste niveau",
aliases: ["h6", "kop6", "subkop6"],
- group: "Koppen",
+ group: "Subkoppen",
},
toggle_heading: {
title: "Uitklapbare Kop 1",
subtext: "Hoofdkop die kan worden uit- en ingeklapt om inhoud te tonen",
aliases: ["h", "kop1", "h1", "uitklapbaar", "inklapbaar"],
- group: "Koppen",
+ group: "Subkoppen",
},
toggle_heading_2: {
title: "Uitklapbare Kop 2",
subtext: "Sectiekop die kan worden uit- en ingeklapt om inhoud te tonen",
aliases: ["h2", "kop2", "subkop", "uitklapbaar", "inklapbaar"],
- group: "Koppen",
+ group: "Subkoppen",
},
toggle_heading_3: {
title: "Uitklapbare Kop 3",
subtext:
"Subsectiekop die kan worden uit- en ingeklapt om inhoud te tonen",
aliases: ["h3", "kop3", "subkop", "uitklapbaar", "inklapbaar"],
- group: "Koppen",
+ group: "Subkoppen",
},
quote: {
title: "Citaat",
diff --git a/packages/core/src/i18n/locales/no.ts b/packages/core/src/i18n/locales/no.ts
index f873ccb4fe..e6c6616647 100644
--- a/packages/core/src/i18n/locales/no.ts
+++ b/packages/core/src/i18n/locales/no.ts
@@ -24,25 +24,25 @@ export const no: Dictionary = {
title: "Overskrift 4",
subtext: "Underoverskrift for mindre underseksjoner",
aliases: ["h4", "overskrift4", "underoverskrift4"],
- group: "Overskrifter",
+ group: "Underoverskrifter",
},
heading_5: {
title: "Overskrift 5",
subtext: "Overskrift for mindre underseksjoner",
aliases: ["h5", "overskrift5", "underoverskrift5"],
- group: "Overskrifter",
+ group: "Underoverskrifter",
},
heading_6: {
title: "Overskrift 6",
subtext: "Overskrift på laveste nivå",
aliases: ["h6", "overskrift6", "underoverskrift6"],
- group: "Overskrifter",
+ group: "Underoverskrifter",
},
toggle_heading: {
title: "Sammenleggbar Overskrift 1",
subtext: "Toppnivåoverskrift som kan vises eller skjules",
aliases: ["h", "overskrift1", "h1", "sammenleggbar", "toggle"],
- group: "Overskrifter",
+ group: "Underoverskrifter",
},
toggle_heading_2: {
title: "Sammenleggbar Overskrift 2",
@@ -54,7 +54,7 @@ export const no: Dictionary = {
"sammenleggbar",
"toggle",
],
- group: "Overskrifter",
+ group: "Underoverskrifter",
},
toggle_heading_3: {
title: "Sammenleggbar Overskrift 3",
@@ -66,7 +66,7 @@ export const no: Dictionary = {
"sammenleggbar",
"toggle",
],
- group: "Overskrifter",
+ group: "Underoverskrifter",
},
quote: {
title: "Sitat",
diff --git a/packages/core/src/i18n/locales/pl.ts b/packages/core/src/i18n/locales/pl.ts
index d3ff97230a..8684c6a91d 100644
--- a/packages/core/src/i18n/locales/pl.ts
+++ b/packages/core/src/i18n/locales/pl.ts
@@ -24,37 +24,37 @@ export const pl: Dictionary = {
title: "Nagłówek 4",
subtext: "Nagłówek mniejszej podsekcji",
aliases: ["h4", "naglowek4", "podnaglowek4"],
- group: "Nagłówki",
+ group: "Podnagłówki",
},
heading_5: {
title: "Nagłówek 5",
subtext: "Nagłówek mniejszej podsekcji",
aliases: ["h5", "naglowek5", "podnaglowek5"],
- group: "Nagłówki",
+ group: "Podnagłówki",
},
heading_6: {
title: "Nagłówek 6",
subtext: "Nagłówek najniższego poziomu",
aliases: ["h6", "naglowek6", "podnaglowek6"],
- group: "Nagłówki",
+ group: "Podnagłówki",
},
toggle_heading: {
title: "Nagłówek rozwijany 1",
subtext: "Rozwijany nagłówek najwyższego poziomu",
aliases: ["h", "naglowek1", "h1", "rozwijany"],
- group: "Nagłówki",
+ group: "Podnagłówki",
},
toggle_heading_2: {
title: "Nagłówek rozwijany 2",
subtext: "Rozwijany nagłówek dla kluczowych sekcji",
aliases: ["h2", "naglowek2", "podnaglowek", "rozwijany"],
- group: "Nagłówki",
+ group: "Podnagłówki",
},
toggle_heading_3: {
title: "Nagłówek rozwijany 3",
subtext: "Rozwijany nagłówek dla podsekcji i grup",
aliases: ["h3", "naglowek3", "podnaglowek", "rozwijany"],
- group: "Nagłówki",
+ group: "Podnagłówki",
},
quote: {
title: "Cytat",
diff --git a/packages/core/src/i18n/locales/pt.ts b/packages/core/src/i18n/locales/pt.ts
index fa6efe7315..a10c5ec3ac 100644
--- a/packages/core/src/i18n/locales/pt.ts
+++ b/packages/core/src/i18n/locales/pt.ts
@@ -24,37 +24,37 @@ export const pt: Dictionary = {
title: "Título 4",
subtext: "Usado para subseções menores",
aliases: ["h4", "titulo4", "subtitulo4"],
- group: "Títulos",
+ group: "Subtítulos",
},
heading_5: {
title: "Título 5",
subtext: "Usado para títulos de subseções pequenas",
aliases: ["h5", "titulo5", "subtitulo5"],
- group: "Títulos",
+ group: "Subtítulos",
},
heading_6: {
title: "Título 6",
subtext: "Usado para títulos de nível mais baixo",
aliases: ["h6", "titulo6", "subtitulo6"],
- group: "Títulos",
+ group: "Subtítulos",
},
toggle_heading: {
title: "Título Expansível",
subtext: "Título expansível de nível superior",
aliases: ["h", "titulo1", "h1", "expansível"],
- group: "Títulos",
+ group: "Subtítulos",
},
toggle_heading_2: {
title: "Título Expansível 2",
subtext: "Título expansível para seções principais",
aliases: ["h2", "titulo2", "subtitulo", "expansível"],
- group: "Títulos",
+ group: "Subtítulos",
},
toggle_heading_3: {
title: "Título Expansível 3",
subtext: "Título expansível para subseções e títulos de grupo",
aliases: ["h3", "titulo3", "subtitulo", "expansível"],
- group: "Títulos",
+ group: "Subtítulos",
},
quote: {
title: "Citação",
diff --git a/packages/core/src/i18n/locales/ru.ts b/packages/core/src/i18n/locales/ru.ts
index fc910d52ca..e7f9f19e02 100644
--- a/packages/core/src/i18n/locales/ru.ts
+++ b/packages/core/src/i18n/locales/ru.ts
@@ -24,25 +24,25 @@ export const ru: Dictionary = {
title: "Заголовок 4 уровня",
subtext: "Используется для более мелких подразделов",
aliases: ["h4", "heading4", "subheading4", "заголовок4", "подзаголовок4"],
- group: "Заголовки",
+ group: "Подзаголовки",
},
heading_5: {
title: "Заголовок 5 уровня",
subtext: "Используется для заголовков небольших подразделов",
aliases: ["h5", "heading5", "subheading5", "заголовок5", "подзаголовок5"],
- group: "Заголовки",
+ group: "Подзаголовки",
},
heading_6: {
title: "Заголовок 6 уровня",
subtext: "Используется для заголовков самого низкого уровня",
aliases: ["h6", "heading6", "subheading6", "заголовок6", "подзаголовок6"],
- group: "Заголовки",
+ group: "Подзаголовки",
},
toggle_heading: {
title: "Сворачиваемый заголовок 1 уровня",
subtext: "Заголовок верхнего уровня, который можно свернуть/развернуть",
aliases: ["h", "heading1", "h1", "заголовок1", "сворачиваемый"],
- group: "Заголовки",
+ group: "Подзаголовки",
},
toggle_heading_2: {
title: "Сворачиваемый заголовок 2 уровня",
@@ -56,7 +56,7 @@ export const ru: Dictionary = {
"подзаголовок",
"сворачиваемый",
],
- group: "Заголовки",
+ group: "Подзаголовки",
},
toggle_heading_3: {
title: "Сворачиваемый заголовок 3 уровня",
@@ -70,7 +70,7 @@ export const ru: Dictionary = {
"подзаголовок",
"сворачиваемый",
],
- group: "Заголовки",
+ group: "Подзаголовки",
},
quote: {
title: "Цитата",
diff --git a/packages/core/src/i18n/locales/sk.ts b/packages/core/src/i18n/locales/sk.ts
index ec56a6f20d..8fc6167581 100644
--- a/packages/core/src/i18n/locales/sk.ts
+++ b/packages/core/src/i18n/locales/sk.ts
@@ -22,37 +22,37 @@ export const sk = {
title: "Nadpis 4",
subtext: "Podsekcia alebo skupinový nadpis",
aliases: ["h4", "nadpis4", "podnadpis"],
- group: "Nadpisy",
+ group: "Podnáslovi",
},
heading_5: {
title: "Nadpis 5",
subtext: "Podsekcia alebo skupinový nadpis",
aliases: ["h5", "nadpis5", "podnadpis"],
- group: "Nadpisy",
+ group: "Podnáslovi",
},
heading_6: {
title: "Nadpis 6",
subtext: "Podsekcia alebo skupinový nadpis",
aliases: ["h6", "nadpis6", "podnadpis"],
- group: "Nadpisy",
+ group: "Podnáslovi",
},
toggle_heading: {
title: "Rozbaľovací Nadpis 1",
subtext: "Rozbaľovací nadpis najvyššej úrovne",
aliases: ["h", "nadpis1", "h1", "rozbaľovací"],
- group: "Nadpisy",
+ group: "Podnáslovi",
},
toggle_heading_2: {
title: "Rozbaľovací Nadpis 2",
subtext: "Rozbaľovací kľúčový nadpis sekcie",
aliases: ["h2", "nadpis2", "podnadpis", "rozbaľovací"],
- group: "Nadpisy",
+ group: "Podnáslovi",
},
toggle_heading_3: {
title: "Rozbaľovací Nadpis 3",
subtext: "Rozbaľovací nadpis podsekcie alebo skupiny",
aliases: ["h3", "nadpis3", "podnadpis", "rozbaľovací"],
- group: "Nadpisy",
+ group: "Podnáslovi",
},
quote: {
title: "Citát",
diff --git a/packages/core/src/i18n/locales/uk.ts b/packages/core/src/i18n/locales/uk.ts
index 54ba809d75..c44c4c1988 100644
--- a/packages/core/src/i18n/locales/uk.ts
+++ b/packages/core/src/i18n/locales/uk.ts
@@ -24,37 +24,37 @@ export const uk: Dictionary = {
title: "Заголовок 4",
subtext: "Використовується для менших підрозділів",
aliases: ["h4", "heading4", "subheading4", "заголовок4"],
- group: "Заголовки",
+ group: "Підзаголовки",
},
heading_5: {
title: "Заголовок 5",
subtext: "Використовується для заголовків менших підрозділів",
aliases: ["h5", "heading5", "subheading5", "заголовок5", "підзаголовок5"],
- group: "Заголовки",
+ group: "Підзаголовки",
},
heading_6: {
title: "Заголовок 6",
subtext: "Використовується для заголовків найнижчого рівня",
aliases: ["h6", "heading6", "subheading6", "заголовок6", "підзаголовок6"],
- group: "Заголовки",
+ group: "Підзаголовки",
},
toggle_heading: {
title: "Розгортаємий заголовок 1",
subtext: "Розгортаємий заголовок найвищого рівня",
aliases: ["h", "heading1", "h1", "заголовок1", "розгортаємий"],
- group: "Заголовки",
+ group: "Підзаголовки",
},
toggle_heading_2: {
title: "Розгортаємий заголовок 2",
subtext: "Розгортаємий основний заголовок розділу",
aliases: ["h2", "heading2", "subheading", "заголовок2", "розгортаємий"],
- group: "Заголовки",
+ group: "Підзаголовки",
},
toggle_heading_3: {
title: "Розгортаємий заголовок 3",
subtext: "Розгортаємий підзаголовок і груповий заголовок",
aliases: ["h3", "heading3", "subheading", "заголовок3", "розгортаємий"],
- group: "Заголовки",
+ group: "Підзаголовки",
},
quote: {
title: "Цитата",
diff --git a/packages/core/src/i18n/locales/vi.ts b/packages/core/src/i18n/locales/vi.ts
index c052418326..12f005b4e3 100644
--- a/packages/core/src/i18n/locales/vi.ts
+++ b/packages/core/src/i18n/locales/vi.ts
@@ -24,37 +24,37 @@ export const vi: Dictionary = {
title: "Tiêu đề H4",
subtext: "Sử dụng cho tiêu đề phụ nhỏ hơn",
aliases: ["h4", "tieude4", "tieudephu4"],
- group: "Tiêu đề",
+ group: "Tiêu đề phụ",
},
heading_5: {
title: "Tiêu đề H5",
subtext: "Sử dụng cho tiêu đề phụ nhỏ hơn",
aliases: ["h5", "tieude5", "tieudephu5"],
- group: "Tiêu đề",
+ group: "Tiêu đề phụ",
},
heading_6: {
title: "Tiêu đề H6",
subtext: "Sử dụng cho tiêu đề cấp thấp nhất",
aliases: ["h6", "tieude6", "tieudephu6"],
- group: "Tiêu đề",
+ group: "Tiêu đề phụ",
},
toggle_heading: {
title: "Tiêu đề có thể thu gọn H1",
subtext: "Tiêu đề cấp cao nhất có thể thu gọn",
aliases: ["h", "tieude1", "dd1", "thugon"],
- group: "Tiêu đề",
+ group: "Tiêu đề phụ",
},
toggle_heading_2: {
title: "Tiêu đề có thể thu gọn H2",
subtext: "Tiêu đề cho các phần chính có thể thu gọn",
aliases: ["h2", "tieude2", "tieudephu", "thugon"],
- group: "Tiêu đề",
+ group: "Tiêu đề phụ",
},
toggle_heading_3: {
title: "Tiêu đề có thể thu gọn H3",
subtext: "Tiêu đề cho phụ đề và tiêu đề nhóm có thể thu gọn",
aliases: ["h3", "tieude3", "tieudephu", "thugon"],
- group: "Tiêu đề",
+ group: "Tiêu đề phụ",
},
quote: {
title: "Trích dẫn",
diff --git a/packages/core/src/i18n/locales/zh-tw.ts b/packages/core/src/i18n/locales/zh-tw.ts
index 8fe28d9dc9..91a86c1e6c 100644
--- a/packages/core/src/i18n/locales/zh-tw.ts
+++ b/packages/core/src/i18n/locales/zh-tw.ts
@@ -24,25 +24,25 @@ export const zhTW: Dictionary = {
title: "四級標題",
subtext: "用於小節和分組標題",
aliases: ["h4", "heading4", "subheading", "標題", "四級標題"],
- group: "標題",
+ group: "副標題",
},
heading_5: {
title: "五級標題",
subtext: "用於小節和分組標題",
aliases: ["h5", "heading5", "subheading", "標題", "五級標題"],
- group: "標題",
+ group: "副標題",
},
heading_6: {
title: "六級標題",
subtext: "用於小節和分組標題",
aliases: ["h6", "heading6", "subheading", "標題", "六級標題"],
- group: "標題",
+ group: "副標題",
},
toggle_heading: {
title: "可摺疊一級標題",
subtext: "可摺疊的頂級標題",
aliases: ["h", "heading1", "h1", "標題", "一級標題", "摺疊"],
- group: "標題",
+ group: "副標題",
},
toggle_heading_2: {
title: "可摺疊二級標題",
@@ -56,13 +56,13 @@ export const zhTW: Dictionary = {
"副標題",
"摺疊",
],
- group: "標題",
+ group: "副標題",
},
toggle_heading_3: {
title: "可摺疊三級標題",
subtext: "可摺疊的小節和分組標題",
aliases: ["h3", "heading3", "subheading", "標題", "三級標題", "摺疊"],
- group: "標題",
+ group: "副標題",
},
quote: {
title: "引用",
diff --git a/packages/core/src/i18n/locales/zh.ts b/packages/core/src/i18n/locales/zh.ts
index 030aed458a..1de7db42ab 100644
--- a/packages/core/src/i18n/locales/zh.ts
+++ b/packages/core/src/i18n/locales/zh.ts
@@ -24,25 +24,25 @@ export const zh: Dictionary = {
title: "四级标题",
subtext: "用于较小的子节标题",
aliases: ["h4", "heading4", "subheading4", "四级标题"],
- group: "标题",
+ group: "副标题",
},
heading_5: {
title: "五级标题",
subtext: "用于较小的子节标题",
aliases: ["h5", "heading5", "subheading5", "五级标题"],
- group: "标题",
+ group: "副标题",
},
heading_6: {
title: "六级标题",
subtext: "用于最低层级的标题",
aliases: ["h6", "heading6", "subheading6", "六级标题"],
- group: "标题",
+ group: "副标题",
},
toggle_heading: {
title: "可折叠一级标题",
subtext: "可折叠的顶级标题",
aliases: ["h", "heading1", "h1", "标题", "一级标题", "折叠"],
- group: "标题",
+ group: "副标题",
},
toggle_heading_2: {
title: "可折叠二级标题",
@@ -56,13 +56,13 @@ export const zh: Dictionary = {
"副标题",
"折叠",
],
- group: "标题",
+ group: "副标题",
},
toggle_heading_3: {
title: "可折叠三级标题",
subtext: "可折叠的小节和分组标题",
aliases: ["h3", "heading3", "subheading", "标题", "三级标题", "折叠"],
- group: "标题",
+ group: "副标题",
},
quote: {
title: "引用",
From f4d5a8095858cfc641ceb2da8a6023764c7f5cf2 Mon Sep 17 00:00:00 2001
From: Nick the Sick
Date: Mon, 23 Jun 2025 16:19:45 +0200
Subject: [PATCH 13/13] test: update snaps
---
.../ariakit-emoji-picker-webkit-linux.png | Bin 175836 -> 175758 bytes
.../ariakit-link-toolbar-webkit-linux.png | Bin 26850 -> 26928 bytes
.../ariakit-slash-menu-chromium-linux.png | Bin 45846 -> 48004 bytes
.../ariakit-slash-menu-firefox-linux.png | Bin 75332 -> 75339 bytes
.../ariakit-slash-menu-webkit-linux.png | Bin 161541 -> 160474 bytes
...shadcn-formatting-toolbar-webkit-linux.png | Bin 31193 -> 34050 bytes
.../shadcn-image-toolbar-webkit-linux.png | Bin 38006 -> 41413 bytes
.../shadcn-link-toolbar-webkit-linux.png | Bin 27477 -> 27387 bytes
.../shadcn-slash-menu-chromium-linux.png | Bin 58854 -> 59325 bytes
.../shadcn-slash-menu-firefox-linux.png | Bin 92736 -> 89558 bytes
.../shadcn-slash-menu-webkit-linux.png | Bin 187794 -> 176515 bytes
...dark-formatting-toolbar-chromium-linux.png | Bin 11807 -> 11896 bytes
.../dark-slash-menu-chromium-linux.png | Bin 56234 -> 54308 bytes
.../dark-slash-menu-firefox-linux.png | Bin 81310 -> 76760 bytes
.../dark-slash-menu-webkit-linux.png | Bin 172878 -> 161557 bytes
tests/src/unit/core/createTestEditor.ts | 3 +++
.../__snapshots__/html/basicBlockTypes.json | 3 +++
.../__snapshots__/html/deepNestedContent.json | 3 +++
.../parse/__snapshots__/html/googleDocs.json | 3 +++
.../parse/__snapshots__/html/notion.json | 3 +++
.../parse/__snapshots__/markdown/complex.json | 3 +++
21 files changed, 18 insertions(+)
diff --git a/tests/src/end-to-end/ariakit/ariakit.test.ts-snapshots/ariakit-emoji-picker-webkit-linux.png b/tests/src/end-to-end/ariakit/ariakit.test.ts-snapshots/ariakit-emoji-picker-webkit-linux.png
index 02baab8f2628f96f6245a8a3886b0e9c86ff2163..3e48eae5e2cecc50c9fac7ff6a782611ee415f53 100644
GIT binary patch
literal 175758
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