diff --git a/docs/content/docs/react/components/formatting-toolbar.mdx b/docs/content/docs/react/components/formatting-toolbar.mdx index 962035ba57..a880274254 100644 --- a/docs/content/docs/react/components/formatting-toolbar.mdx +++ b/docs/content/docs/react/components/formatting-toolbar.mdx @@ -38,3 +38,29 @@ The first element in the default Formatting Toolbar is the Block Type Select, an Here, we use the `FormattingToolbar` component but keep the default buttons (we don't pass any children). Instead, we pass our customized Block Type Select items using the `blockTypeSelectItems` prop. + +## Adding a Text Align Select + +You can replace the default text alignment buttons with a `TextAlignSelect` dropdown, which groups all four alignment options (Left, Center, Right, Justify) into a single compact select. + +To use it, pass `` as a child of `FormattingToolbar` in a custom toolbar: + +```tsx +import { + BlockTypeSelect, + FormattingToolbar, + FormattingToolbarController, + TextAlignSelect, +} from "@blocknote/react"; + +const CustomFormattingToolbar = () => ( + + + {/* ... other toolbar items ... */} + + {/* ... other toolbar items ... */} + +); +``` + +The select is only rendered when the cursor or selection is on a block that supports the `textAlignment` prop (e.g. paragraphs and headings). For table blocks, it applies the chosen alignment to the individual cells covered by the current cell selection. diff --git a/packages/core/src/i18n/locales/ar.ts b/packages/core/src/i18n/locales/ar.ts index 37abc3e30b..04e2c6ed52 100644 --- a/packages/core/src/i18n/locales/ar.ts +++ b/packages/core/src/i18n/locales/ar.ts @@ -310,15 +310,19 @@ export const ar: Dictionary = { }, align_left: { tooltip: "محاذاة النص إلى اليسار", + label: "يسار", }, align_center: { tooltip: "محاذاة النص في المنتصف", + label: "وسط", }, align_right: { tooltip: "محاذاة النص إلى اليمين", + label: "يمين", }, align_justify: { tooltip: "ضبط النص", + label: "ضبط", }, table_cell_merge: { tooltip: "جمع الخلايا", diff --git a/packages/core/src/i18n/locales/de.ts b/packages/core/src/i18n/locales/de.ts index 40944212b3..9d064ed9dd 100644 --- a/packages/core/src/i18n/locales/de.ts +++ b/packages/core/src/i18n/locales/de.ts @@ -344,15 +344,19 @@ export const de: Dictionary = { }, align_left: { tooltip: "Text linksbündig", + label: "Links", }, align_center: { tooltip: "Text zentrieren", + label: "Zentriert", }, align_right: { tooltip: "Text rechtsbündig", + label: "Rechts", }, align_justify: { tooltip: "Text Blocksatz", + label: "Blocksatz", }, table_cell_merge: { tooltip: "Zellen zusammenführen", diff --git a/packages/core/src/i18n/locales/en.ts b/packages/core/src/i18n/locales/en.ts index 784d130094..0927e75f04 100644 --- a/packages/core/src/i18n/locales/en.ts +++ b/packages/core/src/i18n/locales/en.ts @@ -325,15 +325,19 @@ export const en = { }, align_left: { tooltip: "Align text left", + label: "Left" }, align_center: { tooltip: "Align text center", + label: "Center" }, align_right: { tooltip: "Align text right", + label: "Right" }, align_justify: { tooltip: "Justify text", + label: "Justify" }, table_cell_merge: { tooltip: "Merge cells", diff --git a/packages/core/src/i18n/locales/es.ts b/packages/core/src/i18n/locales/es.ts index 4757d9784f..dc4a568de9 100644 --- a/packages/core/src/i18n/locales/es.ts +++ b/packages/core/src/i18n/locales/es.ts @@ -323,15 +323,19 @@ export const es: Dictionary = { }, align_left: { tooltip: "Alinear texto a la izquierda", + label: "Izquierda", }, align_center: { tooltip: "Alinear texto al centro", + label: "Centro", }, align_right: { tooltip: "Alinear texto a la derecha", + label: "Derecha", }, align_justify: { tooltip: "Justificar texto", + label: "Justificar", }, table_cell_merge: { tooltip: "Combinar celdas", diff --git a/packages/core/src/i18n/locales/fa.ts b/packages/core/src/i18n/locales/fa.ts index dff80beb81..486fcf282e 100644 --- a/packages/core/src/i18n/locales/fa.ts +++ b/packages/core/src/i18n/locales/fa.ts @@ -293,15 +293,19 @@ export const fa = { }, align_left: { tooltip: "تراز متن چپ", + label: "چپ", }, align_center: { tooltip: "تراز متن وسط", + label: "وسط", }, align_right: { tooltip: "تراز متن راست", + label: "راست", }, align_justify: { tooltip: "تراز متن دوطرفه", + label: "دوطرفه", }, table_cell_merge: { tooltip: "ادغام سلول‌ها", diff --git a/packages/core/src/i18n/locales/fr.ts b/packages/core/src/i18n/locales/fr.ts index b05d346409..be9c51d75e 100644 --- a/packages/core/src/i18n/locales/fr.ts +++ b/packages/core/src/i18n/locales/fr.ts @@ -371,15 +371,19 @@ export const fr: Dictionary = { }, align_left: { tooltip: "Aligner le texte à gauche", + label: "Gauche", }, align_center: { tooltip: "Aligner le texte au centre", + label: "Centre", }, align_right: { tooltip: "Aligner le texte à droite", + label: "Droite", }, align_justify: { tooltip: "Justifier le texte", + label: "Justifier", }, table_cell_merge: { tooltip: "Fusionner les cellules", diff --git a/packages/core/src/i18n/locales/he.ts b/packages/core/src/i18n/locales/he.ts index 59cdc56414..5240454b8d 100644 --- a/packages/core/src/i18n/locales/he.ts +++ b/packages/core/src/i18n/locales/he.ts @@ -325,15 +325,19 @@ export const he: Dictionary = { }, align_left: { tooltip: "ישר טקסט לשמאל", + label: "שמאל", }, align_center: { tooltip: "מרכז טקסט", + label: "מרכז", }, align_right: { tooltip: "ישר טקסט לימין", + label: "ימין", }, align_justify: { tooltip: "ישר טקסט לשני הצדדים", + label: "יישור", }, table_cell_merge: { tooltip: "מיזוג תאים", diff --git a/packages/core/src/i18n/locales/hr.ts b/packages/core/src/i18n/locales/hr.ts index c2081599cc..79e8a57578 100644 --- a/packages/core/src/i18n/locales/hr.ts +++ b/packages/core/src/i18n/locales/hr.ts @@ -338,15 +338,19 @@ export const hr: Dictionary = { }, align_left: { tooltip: "Poravnaj tekst lijevo", + label: "Lijevo", }, align_center: { tooltip: "Poravnaj tekst po sredini", + label: "Sredina", }, align_right: { tooltip: "Poravnaj tekst desno", + label: "Desno", }, align_justify: { tooltip: "Poravnaj tekst obostrano", + label: "Obostrano", }, table_cell_merge: { tooltip: "Spoji ćelije", diff --git a/packages/core/src/i18n/locales/is.ts b/packages/core/src/i18n/locales/is.ts index fcde471e56..5da8541257 100644 --- a/packages/core/src/i18n/locales/is.ts +++ b/packages/core/src/i18n/locales/is.ts @@ -338,15 +338,19 @@ export const is: Dictionary = { }, align_left: { tooltip: "Vinstrijafna texta", + label: "Vinstri", }, align_center: { tooltip: "Miðjustilla texta", + label: "Miðja", }, align_right: { tooltip: "Hægrijafna texta", + label: "Hægri", }, align_justify: { tooltip: "Jafna texta", + label: "Jafna", }, table_cell_merge: { tooltip: "Sameina dálka", diff --git a/packages/core/src/i18n/locales/it.ts b/packages/core/src/i18n/locales/it.ts index 4053581107..30c7c5d989 100644 --- a/packages/core/src/i18n/locales/it.ts +++ b/packages/core/src/i18n/locales/it.ts @@ -347,15 +347,19 @@ export const it: Dictionary = { }, align_left: { tooltip: "Allinea testo a sinistra", + label: "Sinistra", }, align_center: { tooltip: "Allinea testo al centro", + label: "Centro", }, align_right: { tooltip: "Allinea testo a destra", + label: "Destra", }, align_justify: { tooltip: "Giustifica testo", + label: "Giustifica", }, table_cell_merge: { tooltip: "Unisci celle", diff --git a/packages/core/src/i18n/locales/ja.ts b/packages/core/src/i18n/locales/ja.ts index ce5ba87a77..8944f6d3b8 100644 --- a/packages/core/src/i18n/locales/ja.ts +++ b/packages/core/src/i18n/locales/ja.ts @@ -365,15 +365,19 @@ export const ja: Dictionary = { }, align_left: { tooltip: "左揃え", + label: "左", }, align_center: { tooltip: "中央揃え", + label: "中央", }, align_right: { tooltip: "右揃え", + label: "右", }, align_justify: { tooltip: "両端揃え", + label: "両端", }, table_cell_merge: { tooltip: "セルを結合", diff --git a/packages/core/src/i18n/locales/ko.ts b/packages/core/src/i18n/locales/ko.ts index 53a5def39e..e492432cfb 100644 --- a/packages/core/src/i18n/locales/ko.ts +++ b/packages/core/src/i18n/locales/ko.ts @@ -338,15 +338,19 @@ export const ko: Dictionary = { }, align_left: { tooltip: "텍스트 왼쪽 맞춤", + label: "왼쪽", }, align_center: { tooltip: "텍스트 가운데 맞춤", + label: "가운데", }, align_right: { tooltip: "텍스트 오른쪽 맞춤", + label: "오른쪽", }, align_justify: { tooltip: "텍스트 양쪽 맞춤", + label: "양쪽", }, table_cell_merge: { tooltip: "셀 병합", diff --git a/packages/core/src/i18n/locales/nl.ts b/packages/core/src/i18n/locales/nl.ts index a1bff3fc6b..3e39640c33 100644 --- a/packages/core/src/i18n/locales/nl.ts +++ b/packages/core/src/i18n/locales/nl.ts @@ -325,15 +325,19 @@ export const nl: Dictionary = { }, align_left: { tooltip: "Tekst links uitlijnen", + label: "Links", }, align_center: { tooltip: "Tekst centreren", + label: "Midden", }, align_right: { tooltip: "Tekst rechts uitlijnen", + label: "Rechts", }, align_justify: { tooltip: "Tekst uitvullen", + label: "Uitvullen", }, table_cell_merge: { tooltip: "Voeg cellen samen", diff --git a/packages/core/src/i18n/locales/no.ts b/packages/core/src/i18n/locales/no.ts index 5d518d116b..b3a3cb33e6 100644 --- a/packages/core/src/i18n/locales/no.ts +++ b/packages/core/src/i18n/locales/no.ts @@ -342,15 +342,19 @@ export const no: Dictionary = { }, align_left: { tooltip: "Venstrejuster tekst", + label: "Venstre", }, align_center: { tooltip: "Midtstill tekst", + label: "Midtstilt", }, align_right: { tooltip: "Høyrejuster tekst", + label: "Høyre", }, align_justify: { tooltip: "Juster tekst", + label: "Justert", }, comment: { tooltip: "Legg til kommentar", diff --git a/packages/core/src/i18n/locales/pl.ts b/packages/core/src/i18n/locales/pl.ts index 614f64e9f2..efee25e29c 100644 --- a/packages/core/src/i18n/locales/pl.ts +++ b/packages/core/src/i18n/locales/pl.ts @@ -316,15 +316,19 @@ export const pl: Dictionary = { }, align_left: { tooltip: "Wyrównaj tekst do lewej", + label: "Lewo", }, align_center: { tooltip: "Wyśrodkuj tekst", + label: "Środek", }, align_right: { tooltip: "Wyrównaj tekst do prawej", + label: "Prawo", }, align_justify: { tooltip: "Wyjustuj tekst", + label: "Wyjustuj", }, table_cell_merge: { tooltip: "Połącz komórki", diff --git a/packages/core/src/i18n/locales/pt.ts b/packages/core/src/i18n/locales/pt.ts index c12c94012e..45df8081df 100644 --- a/packages/core/src/i18n/locales/pt.ts +++ b/packages/core/src/i18n/locales/pt.ts @@ -317,15 +317,19 @@ export const pt: Dictionary = { }, align_left: { tooltip: "Alinhar à esquerda", + label: "Esquerda" }, align_center: { tooltip: "Alinhar ao centro", + label: "Centro" }, align_right: { tooltip: "Alinhar à direita", + label: "Direita" }, align_justify: { tooltip: "Justificar texto", + label: "Justificar" }, table_cell_merge: { tooltip: "Juntar células", diff --git a/packages/core/src/i18n/locales/ru.ts b/packages/core/src/i18n/locales/ru.ts index 2982c8f5f6..9a3029f293 100644 --- a/packages/core/src/i18n/locales/ru.ts +++ b/packages/core/src/i18n/locales/ru.ts @@ -368,15 +368,19 @@ export const ru: Dictionary = { }, align_left: { tooltip: "Текст по левому краю", + label: "Влево", }, align_center: { tooltip: "Текст по середине", + label: "По центру", }, align_right: { tooltip: "Текст по правому краю", + label: "Вправо", }, align_justify: { tooltip: "По середине текст", + label: "По ширине", }, table_cell_merge: { tooltip: "Объединить ячейки", diff --git a/packages/core/src/i18n/locales/sk.ts b/packages/core/src/i18n/locales/sk.ts index c1691e17e7..015b21ab7b 100644 --- a/packages/core/src/i18n/locales/sk.ts +++ b/packages/core/src/i18n/locales/sk.ts @@ -323,15 +323,19 @@ export const sk = { }, align_left: { tooltip: "Zarovnať text vľavo", + label: "Vľavo", }, align_center: { tooltip: "Zarovnať text na stred", + label: "Stred", }, align_right: { tooltip: "Zarovnať text vpravo", + label: "Vpravo", }, align_justify: { tooltip: "Zarovnať text do bloku", + label: "Do bloku", }, table_cell_merge: { tooltip: "Zlúčiť bunky", diff --git a/packages/core/src/i18n/locales/uk.ts b/packages/core/src/i18n/locales/uk.ts index a5d7d8f9af..dce8c7af73 100644 --- a/packages/core/src/i18n/locales/uk.ts +++ b/packages/core/src/i18n/locales/uk.ts @@ -349,15 +349,19 @@ export const uk: Dictionary = { }, align_left: { tooltip: "Вирівняти за лівим краєм", + label: "Ліво", }, align_center: { tooltip: "Вирівняти по центру", + label: "По центру", }, align_right: { tooltip: "Вирівняти за правим краєм", + label: "Право", }, align_justify: { tooltip: "Вирівняти за шириною", + label: "По ширині", }, table_cell_merge: { tooltip: "Об'єднати клітинки", diff --git a/packages/core/src/i18n/locales/uz.ts b/packages/core/src/i18n/locales/uz.ts index ffc8d04ac6..a8f464ee8c 100644 --- a/packages/core/src/i18n/locales/uz.ts +++ b/packages/core/src/i18n/locales/uz.ts @@ -370,10 +370,10 @@ export const uz: Dictionary = { nest: { tooltip: "O‘ngga surish", secondary_tooltip: "Tab" }, unnest: { tooltip: "Chapga surish", secondary_tooltip: "Shift+Tab" }, - align_left: { tooltip: "Chapga tekislash" }, - align_center: { tooltip: "Markazga tekislash" }, - align_right: { tooltip: "O‘ngga tekislash" }, - align_justify: { tooltip: "Eniga tekislash" }, + align_left: { tooltip: "Chapga tekislash", label: "Chap" }, + align_center: { tooltip: "Markazga tekislash", label: "Markaz" }, + align_right: { tooltip: "O’ngga tekislash", label: "O’ng" }, + align_justify: { tooltip: "Eniga tekislash", label: "Eni bo’yicha" }, table_cell_merge: { tooltip: "Kataklarni birlashtirish" }, comment: { tooltip: "Izoh qo‘shish" }, diff --git a/packages/core/src/i18n/locales/vi.ts b/packages/core/src/i18n/locales/vi.ts index cbe0e5e628..5c3a731923 100644 --- a/packages/core/src/i18n/locales/vi.ts +++ b/packages/core/src/i18n/locales/vi.ts @@ -324,15 +324,19 @@ export const vi: Dictionary = { }, align_left: { tooltip: "Căn trái văn bản", + label: "Trái", }, align_center: { tooltip: "Căn giữa văn bản", + label: "Giữa", }, align_right: { tooltip: "Căn phải văn bản", + label: "Phải", }, align_justify: { tooltip: "Căn đều văn bản", + label: "Đều", }, table_cell_merge: { tooltip: "Gộp các ô", diff --git a/packages/core/src/i18n/locales/zh-tw.ts b/packages/core/src/i18n/locales/zh-tw.ts index b64912255f..4257ab5e31 100644 --- a/packages/core/src/i18n/locales/zh-tw.ts +++ b/packages/core/src/i18n/locales/zh-tw.ts @@ -366,15 +366,19 @@ export const zhTW: Dictionary = { }, align_left: { tooltip: "靠左對齊", + label: "靠左", }, align_center: { tooltip: "置中", + label: "置中", }, align_right: { tooltip: "靠右對齊", + label: "靠右", }, align_justify: { tooltip: "兩端對齊", + label: "兩端", }, table_cell_merge: { tooltip: "合併儲存格", diff --git a/packages/core/src/i18n/locales/zh.ts b/packages/core/src/i18n/locales/zh.ts index ba5a2fe73b..3396171476 100644 --- a/packages/core/src/i18n/locales/zh.ts +++ b/packages/core/src/i18n/locales/zh.ts @@ -366,15 +366,19 @@ export const zh: Dictionary = { }, align_left: { tooltip: "左对齐", + label: "左对齐", }, align_center: { tooltip: "居中", + label: "居中", }, align_right: { tooltip: "右对齐", + label: "右对齐", }, align_justify: { tooltip: "文本对齐", + label: "两端对齐", }, table_cell_merge: { tooltip: "合并单元格", diff --git a/packages/react/src/components/FormattingToolbar/DefaultSelects/TextAlignSelect.tsx b/packages/react/src/components/FormattingToolbar/DefaultSelects/TextAlignSelect.tsx new file mode 100644 index 0000000000..1d11e95eca --- /dev/null +++ b/packages/react/src/components/FormattingToolbar/DefaultSelects/TextAlignSelect.tsx @@ -0,0 +1,192 @@ +import { + blockHasType, + BlockSchema, + defaultProps, + DefaultProps, + editorHasBlockWithType, + InlineContentSchema, + mapTableCell, + StyleSchema, + TableContent, +} from "@blocknote/core"; +import { TableHandlesExtension } from "@blocknote/core/extensions"; +import { useCallback, useMemo } from "react"; +import { IconType } from "react-icons"; +import { + RiAlignCenter, + RiAlignJustify, + RiAlignLeft, + RiAlignRight, +} from "react-icons/ri"; + +import { + ComponentProps, + useComponentsContext, +} from "../../../editor/ComponentsContext.js"; +import { useBlockNoteEditor } from "../../../hooks/useBlockNoteEditor.js"; +import { useEditorState } from "../../../hooks/useEditorState.js"; +import { useDictionary } from "../../../i18n/dictionary.js"; + +type TextAlignment = DefaultProps["textAlignment"]; + +const icons: Record = { + left: RiAlignLeft, + center: RiAlignCenter, + right: RiAlignRight, + justify: RiAlignJustify, +}; + +const alignments: TextAlignment[] = ["left", "center", "right", "justify"]; + +export const TextAlignSelect = () => { + const Components = useComponentsContext()!; + const dict = useDictionary(); + + const editor = useBlockNoteEditor< + BlockSchema, + InlineContentSchema, + StyleSchema + >(); + + const state = useEditorState({ + editor, + selector: ({ editor }) => { + if (!editor.isEditable) { + return undefined; + } + + const selectedBlocks = editor.getSelection()?.blocks || [ + editor.getTextCursorPosition().block, + ]; + + const firstBlock = selectedBlocks[0]; + + if ( + blockHasType(firstBlock, editor, firstBlock.type, { + textAlignment: defaultProps.textAlignment, + }) + ) { + return { + textAlignment: firstBlock.props.textAlignment, + blocks: selectedBlocks, + }; + } + + if ( + selectedBlocks.length === 1 && + blockHasType(firstBlock, editor, "table") + ) { + const cellSelection = editor + .getExtension(TableHandlesExtension) + ?.getCellSelection(); + + if (!cellSelection || cellSelection.cells.length === 0) { + return undefined; + } + + const { row, col } = cellSelection.cells[0]; + const tableContent = firstBlock.content as TableContent; + const selectedCell = tableContent.rows[row]?.cells[col]; + + if (!selectedCell) { + return undefined; + } + + return { + textAlignment: mapTableCell(selectedCell).props.textAlignment, + blocks: [firstBlock], + }; + } + + return undefined; + }, + }); + + const setTextAlignment = useCallback( + (textAlignment: TextAlignment) => { + if (state === undefined) { + return; + } + + editor.focus(); + + for (const block of state.blocks) { + if ( + blockHasType(block, editor, block.type, { + textAlignment: defaultProps.textAlignment, + }) && + editorHasBlockWithType(editor, block.type, { + textAlignment: defaultProps.textAlignment, + }) + ) { + editor.updateBlock(block, { + props: { textAlignment }, + }); + } else if (block.type === "table") { + const cellSelection = editor + .getExtension(TableHandlesExtension) + ?.getCellSelection(); + if (!cellSelection) { + continue; + } + + const newTable = (block.content as TableContent).rows.map( + (row) => ({ + ...row, + cells: row.cells.map((cell) => mapTableCell(cell)), + }), + ); + + cellSelection.cells.forEach(({ row, col }) => { + if (!newTable[row]?.cells[col]) { return; } + newTable[row].cells[col] = { + ...newTable[row].cells[col], + props: { + ...newTable[row].cells[col].props, + textAlignment, + }, + }; + }); + + editor.updateBlock(block, { + type: "table", + content: { + ...(block.content as TableContent), + type: "tableContent", + rows: newTable, + } as any, + }); + + editor.setTextCursorPosition(block); + } + } + }, + [editor, state], + ); + + const selectItems: ComponentProps["FormattingToolbar"]["Select"]["items"] = + useMemo( + () => + alignments.map((alignment) => { + const Icon = icons[alignment]; + return { + text: dict.formatting_toolbar[`align_${alignment}`].label, + icon: , + isSelected: state?.textAlignment === alignment, + onClick: () => setTextAlignment(alignment), + }; + }), + [dict, setTextAlignment, state?.textAlignment], + ); + + if (state === undefined) { + return null; + } + + return ( + + ); +}; diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 6ed745a789..836e8a43b1 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -34,6 +34,7 @@ export * from "./components/FormattingToolbar/DefaultButtons/NestBlockButtons.js export * from "./components/FormattingToolbar/DefaultButtons/TableCellMergeButton.js"; export * from "./components/FormattingToolbar/DefaultButtons/TextAlignButton.js"; export * from "./components/FormattingToolbar/DefaultSelects/BlockTypeSelect.js"; +export * from "./components/FormattingToolbar/DefaultSelects/TextAlignSelect.js"; export * from "./components/FormattingToolbar/FormattingToolbar.js"; export * from "./components/FormattingToolbar/FormattingToolbarController.js"; export * from "./components/FormattingToolbar/ExperimentalMobileFormattingToolbarController.js"; diff --git a/tests/src/unit/react/TextAlignSelect.test.tsx b/tests/src/unit/react/TextAlignSelect.test.tsx new file mode 100644 index 0000000000..acdfa5b77e --- /dev/null +++ b/tests/src/unit/react/TextAlignSelect.test.tsx @@ -0,0 +1,88 @@ +import { BlockNoteEditor } from "@blocknote/core"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; +import { TextAlignSelect } from "@blocknote/react"; +import { flushSync } from "react-dom"; +import { createRoot } from "react-dom/client"; +import { afterEach, beforeEach, describe, expect, it } from "vitest"; + +describe("TextAlignSelect", () => { + let container: HTMLDivElement; + + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + afterEach(() => { + document.body.removeChild(container); + }); + + it("renders null when editor is not editable", () => { + const editor = BlockNoteEditor.create(); + editor.isEditable = false; + const root = createRoot(container); + + flushSync(() => { + root.render( + + + , + ); + }); + + expect(container.querySelector("button")).toBeNull(); + + root.unmount(); + editor._tiptapEditor.destroy(); + }); + + it("renders select button for an alignable block", () => { + const editor = BlockNoteEditor.create(); + const root = createRoot(container); + + flushSync(() => { + root.render( + + + , + ); + }); + + expect(container.querySelector("button")).not.toBeNull(); + + root.unmount(); + editor._tiptapEditor.destroy(); + }); + + it("reactively updates button label when block alignment changes", () => { + const editor = BlockNoteEditor.create(); + const root = createRoot(container); + + flushSync(() => { + root.render( + + + , + ); + }); + + expect(container.querySelector("button")?.textContent).toContain("Left"); + + const block = editor.document[0]; + flushSync(() => { + editor.updateBlock(block, { props: { textAlignment: "center" } }); + }); + + expect(container.querySelector("button")?.textContent).toContain("Center"); + + flushSync(() => { + editor.updateBlock(block, { props: { textAlignment: "right" } }); + }); + + expect(container.querySelector("button")?.textContent).toContain("Right"); + + root.unmount(); + editor._tiptapEditor.destroy(); + }); +});