From be5f92cfa8eb2f3235561164ecb530a82b07b0e3 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Tue, 20 Oct 2026 14:30:13 +0200 Subject: [PATCH] Added `lang` default prop --- .../21-block-language/.bnexample.json | 8 ++ .../21-block-language/README.md | 9 ++ .../21-block-language/index.html | 17 ++++ .../21-block-language/main.tsx | 11 +++ .../21-block-language/package.json | 30 +++++++ .../21-block-language/src/App.tsx | 70 ++++++++++++++++ .../21-block-language/tsconfig.json | 32 ++++++++ .../21-block-language/vite-env.d.ts | 1 + .../21-block-language/vite.config.ts | 35 ++++++++ .../ListItem/CheckListItem/block.test.ts | 2 + packages/core/src/blocks/Quote/block.ts | 5 +- packages/core/src/blocks/defaultProps.ts | 14 ++++ .../core/src/editor/BlockNoteEditor.test.ts | 3 +- .../managers/ExtensionManager/extensions.ts | 2 + .../Language/LanguageExtension.ts | 31 +++++++ .../src/extensions/tiptap-extensions/index.ts | 1 + packages/core/src/i18n/locales/ar.ts | 3 + packages/core/src/i18n/locales/de.ts | 3 + packages/core/src/i18n/locales/en.ts | 3 + packages/core/src/i18n/locales/es.ts | 3 + packages/core/src/i18n/locales/fa.ts | 3 + packages/core/src/i18n/locales/fr.ts | 3 + packages/core/src/i18n/locales/he.ts | 3 + packages/core/src/i18n/locales/hr.ts | 3 + packages/core/src/i18n/locales/is.ts | 3 + packages/core/src/i18n/locales/it.ts | 3 + packages/core/src/i18n/locales/ja.ts | 3 + packages/core/src/i18n/locales/ko.ts | 3 + packages/core/src/i18n/locales/nl.ts | 3 + packages/core/src/i18n/locales/no.ts | 3 + packages/core/src/i18n/locales/pl.ts | 3 + packages/core/src/i18n/locales/pt.ts | 3 + packages/core/src/i18n/locales/ru.ts | 3 + packages/core/src/i18n/locales/sk.ts | 3 + packages/core/src/i18n/locales/uk.ts | 3 + packages/core/src/i18n/locales/uz.ts | 3 + packages/core/src/i18n/locales/vi.ts | 3 + packages/core/src/i18n/locales/zh-tw.ts | 3 + packages/core/src/i18n/locales/zh.ts | 3 + packages/core/src/schema/propTypes.ts | 4 +- packages/core/src/y/utils.test.ts | 33 ++++++++ .../moveColorAttributes.test.ts | 2 +- packages/core/src/yjs/utils.test.ts | 33 ++++++++ .../DefaultItems/BlockLanguageItem.tsx | 82 +++++++++++++++++++ packages/react/src/index.ts | 1 + .../src/context/ServerBlockNoteEditor.test.ts | 3 + playground/src/examples.gen.tsx | 20 +++++ pnpm-lock.yaml | 43 ++++++++++ shared/formatConversionTestUtil.ts | 8 ++ .../blocknoteHTML/language/empty.html | 9 ++ .../blocknoteHTML/language/explicit.html | 9 ++ .../blocknoteHTML/language/regional.html | 9 ++ .../blocknoteHTML/language/undefined.html | 9 ++ .../__snapshots__/html/language/empty.html | 1 + .../__snapshots__/html/language/explicit.html | 1 + .../__snapshots__/html/language/regional.html | 1 + .../html/language/undefined.html | 1 + .../__snapshots__/markdown/language/empty.md | 1 + .../markdown/language/explicit.md | 1 + .../markdown/language/regional.md | 1 + .../markdown/language/undefined.md | 1 + .../__snapshots__/nodes/complex/document.json | 7 ++ .../__snapshots__/nodes/complex/misc.json | 3 + .../custom-blocks/simpleCustomParagraph.json | 1 + .../__snapshots__/nodes/hardbreak/basic.json | 1 + .../nodes/hardbreak/between-links.json | 1 + .../__snapshots__/nodes/hardbreak/end.json | 1 + .../__snapshots__/nodes/hardbreak/link.json | 1 + .../nodes/hardbreak/multiple.json | 1 + .../__snapshots__/nodes/hardbreak/only.json | 1 + .../__snapshots__/nodes/hardbreak/start.json | 1 + .../__snapshots__/nodes/hardbreak/styles.json | 1 + .../__snapshots__/nodes/heading/h1.json | 1 + .../__snapshots__/nodes/heading/h2.json | 1 + .../__snapshots__/nodes/heading/h3.json | 1 + .../__snapshots__/nodes/heading/h4.json | 1 + .../__snapshots__/nodes/heading/h5.json | 1 + .../__snapshots__/nodes/heading/h6.json | 1 + .../__snapshots__/nodes/heading/styled.json | 1 + .../nodes/heading/toggleable.json | 2 + .../mentionWithToExternalHTML.json | 1 + .../tagWithoutToExternalHTML.json | 1 + .../__snapshots__/nodes/language/empty.json | 25 ++++++ .../nodes/language/explicit.json | 25 ++++++ .../nodes/language/regional.json | 25 ++++++ .../nodes/language/undefined.json | 25 ++++++ .../nodes/layoutBlock/basic.json | 1 + .../nodes/layoutBlock/emptyChildren.json | 1 + .../nodes/layoutBlock/nested.json | 2 + .../__snapshots__/nodes/link/adjacent.json | 1 + .../__snapshots__/nodes/link/basic.json | 1 + .../__snapshots__/nodes/link/plainUrl.json | 1 + .../__snapshots__/nodes/link/styled.json | 1 + .../nodes/link/urlWithParens.json | 1 + .../__snapshots__/nodes/link/withCode.json | 1 + .../__snapshots__/nodes/lists/basic.json | 7 ++ .../__snapshots__/nodes/lists/nested.json | 7 ++ .../nodes/lists/numberedListStart.json | 2 + .../nodes/lists/toggleWithChildren.json | 5 ++ .../__snapshots__/nodes/malformed/JSON.json | 1 + .../__snapshots__/nodes/paragraph/basic.json | 1 + .../__snapshots__/nodes/paragraph/empty.json | 1 + .../nodes/paragraph/emptyBetween.json | 3 + .../nodes/paragraph/lineBreaks.json | 1 + .../nodes/paragraph/multiple.json | 3 + .../__snapshots__/nodes/paragraph/nested.json | 3 + .../__snapshots__/nodes/paragraph/styled.json | 1 + .../__snapshots__/nodes/quote/basic.json | 1 + .../__snapshots__/nodes/quote/multiple.json | 2 + .../__snapshots__/nodes/quote/nested.json | 2 + .../__snapshots__/nodes/quote/styled.json | 1 + .../__snapshots__/nodes/quote/withLink.json | 1 + .../nodes/style/backgroundColor.json | 1 + .../__snapshots__/nodes/style/bold.json | 1 + .../nodes/style/boldItalicStrike.json | 1 + .../__snapshots__/nodes/style/code.json | 1 + .../__snapshots__/nodes/style/combined.json | 1 + .../__snapshots__/nodes/style/italic.json | 1 + .../nodes/style/mixedInParagraph.json | 1 + .../__snapshots__/nodes/style/strike.json | 1 + .../__snapshots__/nodes/style/textColor.json | 1 + .../__snapshots__/nodes/style/underline.json | 1 + .../nodes/titledBlock/basic.json | 2 + .../export/exportTestInstances.ts | 40 +++++++++ .../exportParseEqualityTestInstances.ts | 6 ++ .../html/language/data-attribute.json | 20 +++++ .../__snapshots__/html/language/empty.json | 20 +++++ .../__snapshots__/html/language/explicit.json | 20 +++++ .../__snapshots__/html/language/regional.json | 20 +++++ .../parse/parseTestInstances.ts | 28 +++++++ 130 files changed, 954 insertions(+), 7 deletions(-) create mode 100644 examples/03-ui-components/21-block-language/.bnexample.json create mode 100644 examples/03-ui-components/21-block-language/README.md create mode 100644 examples/03-ui-components/21-block-language/index.html create mode 100644 examples/03-ui-components/21-block-language/main.tsx create mode 100644 examples/03-ui-components/21-block-language/package.json create mode 100644 examples/03-ui-components/21-block-language/src/App.tsx create mode 100644 examples/03-ui-components/21-block-language/tsconfig.json create mode 100644 examples/03-ui-components/21-block-language/vite-env.d.ts create mode 100644 examples/03-ui-components/21-block-language/vite.config.ts create mode 100644 packages/core/src/extensions/tiptap-extensions/Language/LanguageExtension.ts create mode 100644 packages/react/src/components/SideMenu/DragHandleMenu/DefaultItems/BlockLanguageItem.tsx create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/empty.html create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/explicit.html create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/regional.html create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/undefined.html create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/html/language/empty.html create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/html/language/explicit.html create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/html/language/regional.html create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/html/language/undefined.html create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/empty.md create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/explicit.md create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/regional.md create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/undefined.md create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/empty.json create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/explicit.json create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/regional.json create mode 100644 tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/undefined.json create mode 100644 tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/data-attribute.json create mode 100644 tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/empty.json create mode 100644 tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/explicit.json create mode 100644 tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/regional.json diff --git a/examples/03-ui-components/21-block-language/.bnexample.json b/examples/03-ui-components/21-block-language/.bnexample.json new file mode 100644 index 0000000000..36f0b7cd0a --- /dev/null +++ b/examples/03-ui-components/21-block-language/.bnexample.json @@ -0,0 +1,8 @@ +{ + "playground": true, + "docs": true, + "author": "", + "tags": ["Intermediate", "Blocks", "UI Components", "Block Side Menu"], + "dependencies": {}, + "pro": false +} diff --git a/examples/03-ui-components/21-block-language/README.md b/examples/03-ui-components/21-block-language/README.md new file mode 100644 index 0000000000..dfed404c5d --- /dev/null +++ b/examples/03-ui-components/21-block-language/README.md @@ -0,0 +1,9 @@ +# Block languages + +This example adds an optional language submenu to the drag handle menu, with English, French, and German. Each block can declare its language for assistive technology or inherit the surrounding language. + +**Try it out:** Open a block's drag handle menu and choose a language. + +## Relevant Docs + +- [Changing the Drag Handle Menu](https://www.blocknotejs.org/docs/react/components/side-menu) diff --git a/examples/03-ui-components/21-block-language/index.html b/examples/03-ui-components/21-block-language/index.html new file mode 100644 index 0000000000..8fda0fb9f6 --- /dev/null +++ b/examples/03-ui-components/21-block-language/index.html @@ -0,0 +1,17 @@ + + + + + Block languages + + + +
+ + + diff --git a/examples/03-ui-components/21-block-language/main.tsx b/examples/03-ui-components/21-block-language/main.tsx new file mode 100644 index 0000000000..1260513388 --- /dev/null +++ b/examples/03-ui-components/21-block-language/main.tsx @@ -0,0 +1,11 @@ +// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY +import React from "react"; +import { createRoot } from "react-dom/client"; +import App from "./src/App.jsx"; + +const root = createRoot(document.getElementById("root")!); +root.render( + + + , +); diff --git a/examples/03-ui-components/21-block-language/package.json b/examples/03-ui-components/21-block-language/package.json new file mode 100644 index 0000000000..1977784498 --- /dev/null +++ b/examples/03-ui-components/21-block-language/package.json @@ -0,0 +1,30 @@ +{ + "name": "@blocknote/example-ui-components-block-language", + "description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY", + "type": "module", + "private": true, + "version": "0.12.4", + "scripts": { + "start": "vite", + "dev": "vite", + "build:prod": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@blocknote/ariakit": "latest", + "@blocknote/core": "latest", + "@blocknote/mantine": "latest", + "@blocknote/react": "latest", + "@blocknote/shadcn": "latest", + "@mantine/core": "^9.0.2", + "@mantine/hooks": "^9.0.2", + "react": "^19.2.3", + "react-dom": "^19.2.3" + }, + "devDependencies": { + "@types/react": "^19.2.3", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "vite": "^8.0.0" + } +} diff --git a/examples/03-ui-components/21-block-language/src/App.tsx b/examples/03-ui-components/21-block-language/src/App.tsx new file mode 100644 index 0000000000..cb90ec6f1f --- /dev/null +++ b/examples/03-ui-components/21-block-language/src/App.tsx @@ -0,0 +1,70 @@ +import "@blocknote/core/fonts/inter.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; +import { + BlockColorsItem, + BlockLanguageItem, + DragHandleMenu, + RemoveBlockItem, + SideMenu, + SideMenuController, + type SideMenuProps, + useCreateBlockNote, +} from "@blocknote/react"; + +function LanguageDragHandleMenu() { + return ( + + Delete + Colors + + Language + + + ); +} + +function LanguageSideMenu(props: SideMenuProps) { + return ; +} + +export default function App() { + const editor = useCreateBlockNote({ + initialContent: [ + { + type: "paragraph", + content: "Open a block's drag handle menu to choose its language.", + }, + { + type: "paragraph", + props: { lang: "en" }, + content: + "The block looks the same, but screen readers will read content inside with the correct pronounciation for that language.", + }, + { + type: "paragraph", + props: { lang: "fr" }, + content: "Bonjour tout le monde !", + }, + { + type: "paragraph", + props: { lang: "de" }, + content: "Guten Tag zusammen!", + }, + ], + }); + + return ( +
+ + + +
+ ); +} diff --git a/examples/03-ui-components/21-block-language/tsconfig.json b/examples/03-ui-components/21-block-language/tsconfig.json new file mode 100644 index 0000000000..2aa62c56e6 --- /dev/null +++ b/examples/03-ui-components/21-block-language/tsconfig.json @@ -0,0 +1,32 @@ +{ + "__comment": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "allowJs": false, + "skipLibCheck": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "composite": true, + "paths": { + "@shared/*": ["../../../shared/*"] + } + }, + "include": ["."], + "__ADD_FOR_LOCAL_DEV_references": [ + { + "path": "../../../packages/core/" + }, + { + "path": "../../../packages/react/" + } + ] +} diff --git a/examples/03-ui-components/21-block-language/vite-env.d.ts b/examples/03-ui-components/21-block-language/vite-env.d.ts new file mode 100644 index 0000000000..11f02fe2a0 --- /dev/null +++ b/examples/03-ui-components/21-block-language/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/examples/03-ui-components/21-block-language/vite.config.ts b/examples/03-ui-components/21-block-language/vite.config.ts new file mode 100644 index 0000000000..cbf6ff2ffc --- /dev/null +++ b/examples/03-ui-components/21-block-language/vite.config.ts @@ -0,0 +1,35 @@ +// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY +import react from "@vitejs/plugin-react"; +import * as fs from "fs"; +import * as path from "path"; +import { defineConfig } from "vite"; +// https://vitejs.dev/config/ +export default defineConfig(((conf: { command: string }) => ({ + plugins: [react()], + optimizeDeps: {}, + build: { + sourcemap: true, + }, + resolve: { + alias: + conf.command === "build" || + !fs.existsSync(path.resolve(__dirname, "../../../packages/core/src")) + ? {} + : ({ + // The repo-wide alias for the shared test-utils directory (private, + // so it only resolves inside the monorepo). Harmless for examples + // that don't use it. + "@shared": path.resolve(__dirname, "../../../shared/"), + // Comment out the lines below to load a built version of blocknote + // or, keep as is to load live from sources with live reload working + "@blocknote/core": path.resolve( + __dirname, + "../../../packages/core/src/", + ), + "@blocknote/react": path.resolve( + __dirname, + "../../../packages/react/src/", + ), + } as any), + }, +})) as Parameters[0]); diff --git a/packages/core/src/blocks/ListItem/CheckListItem/block.test.ts b/packages/core/src/blocks/ListItem/CheckListItem/block.test.ts index 9715bc503e..45207f7f90 100644 --- a/packages/core/src/blocks/ListItem/CheckListItem/block.test.ts +++ b/packages/core/src/blocks/ListItem/CheckListItem/block.test.ts @@ -25,6 +25,7 @@ it("renders checkbox as enabled when editor is editable", () => { id: "1", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textAlignment: "left", textColor: "default", @@ -46,6 +47,7 @@ it("renders checkbox as disabled when editor is not editable", () => { id: "1", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textAlignment: "left", textColor: "default", diff --git a/packages/core/src/blocks/Quote/block.ts b/packages/core/src/blocks/Quote/block.ts index b6b6a7710f..4d968d3fcb 100644 --- a/packages/core/src/blocks/Quote/block.ts +++ b/packages/core/src/blocks/Quote/block.ts @@ -13,6 +13,7 @@ export const createQuoteBlockConfig = createBlockConfig( ({ type: "quote" as const, propSchema: { + lang: defaultProps.lang, backgroundColor: defaultProps.backgroundColor, textColor: defaultProps.textColor, }, @@ -28,9 +29,7 @@ export const createQuoteBlockSpec = createBlockSpec( }, parse(element) { if (element.tagName === "BLOCKQUOTE") { - const { backgroundColor, textColor } = parseDefaultProps(element); - - return { backgroundColor, textColor }; + return parseDefaultProps(element); } return undefined; diff --git a/packages/core/src/blocks/defaultProps.ts b/packages/core/src/blocks/defaultProps.ts index 5d55d21d35..cae5943503 100644 --- a/packages/core/src/blocks/defaultProps.ts +++ b/packages/core/src/blocks/defaultProps.ts @@ -7,6 +7,10 @@ import type { Props, PropSchema } from "../schema/index.js"; // The dependency from schema on this file doesn't make sense export const defaultProps = { + lang: { + default: undefined, + type: "string" as const, + }, backgroundColor: { default: "default" as const, }, @@ -24,6 +28,12 @@ export type DefaultProps = Props; export const parseDefaultProps = (element: HTMLElement) => { const props: Partial = {}; + if (element.hasAttribute("data-lang")) { + props.lang = element.getAttribute("data-lang")!; + } else if (element.hasAttribute("lang")) { + props.lang = element.lang; + } + // If the `data-` attribute is found, set the prop to the value, as this most // likely means the parsed element was exported by BlockNote originally. // Otherwise, just use whatever is found in the inline styles, if anything. @@ -55,6 +65,10 @@ export const addDefaultPropsExternalHTML = ( props: Partial, element: HTMLElement, ) => { + if (props.lang !== undefined) { + element.lang = props.lang; + } + if ( props.backgroundColor && props.backgroundColor !== defaultProps.backgroundColor.default diff --git a/packages/core/src/editor/BlockNoteEditor.test.ts b/packages/core/src/editor/BlockNoteEditor.test.ts index 680a663b98..85127a03f5 100644 --- a/packages/core/src/editor/BlockNoteEditor.test.ts +++ b/packages/core/src/editor/BlockNoteEditor.test.ts @@ -179,6 +179,7 @@ it("sets an initial block id when using Y.js", async () => { { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -207,7 +208,7 @@ it("sets an initial block id when using Y.js", async () => { expect(transactionCount).toBe(2); // Only after a real modification is made, will the fragment be updated expect(fragment.toJSON()).toMatch( - /^Hello<\/paragraph><\/blockcontainer><\/blockgroup>$/, + /^Hello<\/paragraph><\/blockcontainer><\/blockgroup>$/, ); }); diff --git a/packages/core/src/editor/managers/ExtensionManager/extensions.ts b/packages/core/src/editor/managers/ExtensionManager/extensions.ts index e7f95358d2..58c1c5ceed 100644 --- a/packages/core/src/editor/managers/ExtensionManager/extensions.ts +++ b/packages/core/src/editor/managers/ExtensionManager/extensions.ts @@ -32,6 +32,7 @@ import { } from "../../../extensions/index.js"; import { BackgroundColorExtension, + LanguageExtension, HardBreak, KeyboardShortcutsExtension, LinkExtension, @@ -83,6 +84,7 @@ export function getDefaultTiptapExtensions( }); }) as any[]), + LanguageExtension, TextColorExtension, BackgroundColorExtension, diff --git a/packages/core/src/extensions/tiptap-extensions/Language/LanguageExtension.ts b/packages/core/src/extensions/tiptap-extensions/Language/LanguageExtension.ts new file mode 100644 index 0000000000..5e50c0bdcf --- /dev/null +++ b/packages/core/src/extensions/tiptap-extensions/Language/LanguageExtension.ts @@ -0,0 +1,31 @@ +import { Extension } from "@tiptap/core"; +import { Plugin } from "prosemirror-state"; +import { Decoration, DecorationSet } from "prosemirror-view"; + +// The `lang` prop renders out to a `data-lang` HTML attributes like all other props. To be useful +// for assistive technologies though, a `lang` attribute has to be rendered. This extension applies +// the `lang` attribute wherever `data-lang` appears. +export const LanguageExtension = Extension.create({ + name: "blockLanguage", + addProseMirrorPlugins() { + return [ + new Plugin({ + props: { + decorations: ({ doc }) => { + const decorations: Decoration[] = []; + doc.descendants((node, pos) => { + if (typeof node.attrs.lang === "string") { + decorations.push( + Decoration.node(pos, pos + node.nodeSize, { + lang: node.attrs.lang, + }), + ); + } + }); + return DecorationSet.create(doc, decorations); + }, + }, + }), + ]; + }, +}); diff --git a/packages/core/src/extensions/tiptap-extensions/index.ts b/packages/core/src/extensions/tiptap-extensions/index.ts index 71d31935f4..c43d64bed7 100644 --- a/packages/core/src/extensions/tiptap-extensions/index.ts +++ b/packages/core/src/extensions/tiptap-extensions/index.ts @@ -5,3 +5,4 @@ export * from "./TextAlignment/TextAlignmentExtension.js"; export * from "./TextColor/TextColorExtension.js"; export * from "./UniqueID/UniqueID.js"; export * from "./Link/link.js"; +export * from "./Language/LanguageExtension.js"; diff --git a/packages/core/src/i18n/locales/ar.ts b/packages/core/src/i18n/locales/ar.ts index 99ad5ee6e8..b9f2292bae 100644 --- a/packages/core/src/i18n/locales/ar.ts +++ b/packages/core/src/i18n/locales/ar.ts @@ -215,6 +215,9 @@ export const ar: Dictionary = { suggestion_menu: { no_items_title: "لم يتم العثور على عناصر", }, + language_picker: { + default: "تلقائي", + }, color_picker: { text_title: "نص", background_title: "خلفية", diff --git a/packages/core/src/i18n/locales/de.ts b/packages/core/src/i18n/locales/de.ts index 1e8c3851f6..b760d57150 100644 --- a/packages/core/src/i18n/locales/de.ts +++ b/packages/core/src/i18n/locales/de.ts @@ -250,6 +250,9 @@ export const de: Dictionary = { suggestion_menu: { no_items_title: "Keine Elemente gefunden", }, + language_picker: { + default: "Automatisch", + }, color_picker: { text_title: "Text", background_title: "Hintergrund", diff --git a/packages/core/src/i18n/locales/en.ts b/packages/core/src/i18n/locales/en.ts index 860d26f37a..0ee577e988 100644 --- a/packages/core/src/i18n/locales/en.ts +++ b/packages/core/src/i18n/locales/en.ts @@ -230,6 +230,9 @@ export const en = { suggestion_menu: { no_items_title: "No items found", }, + language_picker: { + default: "Auto", + }, color_picker: { text_title: "Text", background_title: "Background", diff --git a/packages/core/src/i18n/locales/es.ts b/packages/core/src/i18n/locales/es.ts index 7ed2da20b3..78bf348b8f 100644 --- a/packages/core/src/i18n/locales/es.ts +++ b/packages/core/src/i18n/locales/es.ts @@ -229,6 +229,9 @@ export const es: Dictionary = { suggestion_menu: { no_items_title: "No se encontraron elementos", }, + language_picker: { + default: "Automático", + }, color_picker: { text_title: "Texto", background_title: "Fondo", diff --git a/packages/core/src/i18n/locales/fa.ts b/packages/core/src/i18n/locales/fa.ts index 9de694d62d..9f2fa323f0 100644 --- a/packages/core/src/i18n/locales/fa.ts +++ b/packages/core/src/i18n/locales/fa.ts @@ -198,6 +198,9 @@ export const fa = { suggestion_menu: { no_items_title: "موردی یافت نشد", }, + language_picker: { + default: "خودکار", + }, color_picker: { text_title: "متن", background_title: "پس‌زمینه", diff --git a/packages/core/src/i18n/locales/fr.ts b/packages/core/src/i18n/locales/fr.ts index 89edab7765..a13c42024b 100644 --- a/packages/core/src/i18n/locales/fr.ts +++ b/packages/core/src/i18n/locales/fr.ts @@ -276,6 +276,9 @@ export const fr: Dictionary = { suggestion_menu: { no_items_title: "Aucun élément trouvé", }, + language_picker: { + default: "Auto", + }, color_picker: { text_title: "Texte", background_title: "Fond", diff --git a/packages/core/src/i18n/locales/he.ts b/packages/core/src/i18n/locales/he.ts index b839862ac3..e6c18b15c6 100644 --- a/packages/core/src/i18n/locales/he.ts +++ b/packages/core/src/i18n/locales/he.ts @@ -231,6 +231,9 @@ export const he: Dictionary = { suggestion_menu: { no_items_title: "לא נמצאו פריטים", }, + language_picker: { + default: "אוטומטי", + }, color_picker: { text_title: "טקסט", background_title: "רקע", diff --git a/packages/core/src/i18n/locales/hr.ts b/packages/core/src/i18n/locales/hr.ts index 34d6aec49c..4c02d4c408 100644 --- a/packages/core/src/i18n/locales/hr.ts +++ b/packages/core/src/i18n/locales/hr.ts @@ -243,6 +243,9 @@ export const hr: Dictionary = { suggestion_menu: { no_items_title: "Stavke nisu pronađene", }, + language_picker: { + default: "Automatski", + }, color_picker: { text_title: "Tekst", background_title: "Pozadina", diff --git a/packages/core/src/i18n/locales/is.ts b/packages/core/src/i18n/locales/is.ts index 290fb963dc..35e42f2372 100644 --- a/packages/core/src/i18n/locales/is.ts +++ b/packages/core/src/i18n/locales/is.ts @@ -243,6 +243,9 @@ export const is: Dictionary = { suggestion_menu: { no_items_title: "Engir hlutir fundust", }, + language_picker: { + default: "Sjálfvirkt", + }, color_picker: { text_title: "Texti", background_title: "Bakgrunnur", diff --git a/packages/core/src/i18n/locales/it.ts b/packages/core/src/i18n/locales/it.ts index 72ff93db0a..ebd44b1e15 100644 --- a/packages/core/src/i18n/locales/it.ts +++ b/packages/core/src/i18n/locales/it.ts @@ -252,6 +252,9 @@ export const it: Dictionary = { suggestion_menu: { no_items_title: "Nessun elemento trovato", }, + language_picker: { + default: "Automatico", + }, color_picker: { text_title: "Testo", background_title: "Sfondo", diff --git a/packages/core/src/i18n/locales/ja.ts b/packages/core/src/i18n/locales/ja.ts index 47c11ce4e9..868e56991c 100644 --- a/packages/core/src/i18n/locales/ja.ts +++ b/packages/core/src/i18n/locales/ja.ts @@ -270,6 +270,9 @@ export const ja: Dictionary = { suggestion_menu: { no_items_title: "アイテムが見つかりません", }, + language_picker: { + default: "自動", + }, color_picker: { text_title: "文字色", background_title: "背景色", diff --git a/packages/core/src/i18n/locales/ko.ts b/packages/core/src/i18n/locales/ko.ts index d7cce2f392..1e44cbf4fb 100644 --- a/packages/core/src/i18n/locales/ko.ts +++ b/packages/core/src/i18n/locales/ko.ts @@ -243,6 +243,9 @@ export const ko: Dictionary = { suggestion_menu: { no_items_title: "항목을 찾을 수 없음", }, + language_picker: { + default: "자동", + }, color_picker: { text_title: "텍스트", background_title: "배경", diff --git a/packages/core/src/i18n/locales/nl.ts b/packages/core/src/i18n/locales/nl.ts index 4cd90d5383..e8c6d27fb4 100644 --- a/packages/core/src/i18n/locales/nl.ts +++ b/packages/core/src/i18n/locales/nl.ts @@ -231,6 +231,9 @@ export const nl: Dictionary = { suggestion_menu: { no_items_title: "Geen items gevonden", }, + language_picker: { + default: "Automatisch", + }, color_picker: { text_title: "Tekst", background_title: "Achtergrond", diff --git a/packages/core/src/i18n/locales/no.ts b/packages/core/src/i18n/locales/no.ts index 8cc16e93ee..b5669e6ef7 100644 --- a/packages/core/src/i18n/locales/no.ts +++ b/packages/core/src/i18n/locales/no.ts @@ -248,6 +248,9 @@ export const no: Dictionary = { suggestion_menu: { no_items_title: "Ingen elementer funnet", }, + language_picker: { + default: "Automatisk", + }, color_picker: { text_title: "Tekst", background_title: "Bakgrunn", diff --git a/packages/core/src/i18n/locales/pl.ts b/packages/core/src/i18n/locales/pl.ts index 3f25c5f07c..f1e524c4ae 100644 --- a/packages/core/src/i18n/locales/pl.ts +++ b/packages/core/src/i18n/locales/pl.ts @@ -221,6 +221,9 @@ export const pl: Dictionary = { suggestion_menu: { no_items_title: "Nie znaleziono elementów", }, + language_picker: { + default: "Automatyczny", + }, color_picker: { text_title: "Tekst", background_title: "Tło", diff --git a/packages/core/src/i18n/locales/pt.ts b/packages/core/src/i18n/locales/pt.ts index ebac76c283..00b0856fd3 100644 --- a/packages/core/src/i18n/locales/pt.ts +++ b/packages/core/src/i18n/locales/pt.ts @@ -222,6 +222,9 @@ export const pt: Dictionary = { suggestion_menu: { no_items_title: "Nenhum item encontrado", }, + language_picker: { + default: "Automático", + }, color_picker: { text_title: "Texto", background_title: "Fundo", diff --git a/packages/core/src/i18n/locales/ru.ts b/packages/core/src/i18n/locales/ru.ts index 0cc71efc3a..61766de5a4 100644 --- a/packages/core/src/i18n/locales/ru.ts +++ b/packages/core/src/i18n/locales/ru.ts @@ -273,6 +273,9 @@ export const ru: Dictionary = { suggestion_menu: { no_items_title: "ничего не найдено", }, + language_picker: { + default: "Авто", + }, color_picker: { text_title: "Текст", background_title: "Задний фон", diff --git a/packages/core/src/i18n/locales/sk.ts b/packages/core/src/i18n/locales/sk.ts index 3bd8f0f7aa..41c770c31a 100644 --- a/packages/core/src/i18n/locales/sk.ts +++ b/packages/core/src/i18n/locales/sk.ts @@ -229,6 +229,9 @@ export const sk = { suggestion_menu: { no_items_title: "Nenašli sa žiadne položky", }, + language_picker: { + default: "Automaticky", + }, color_picker: { text_title: "Text", background_title: "Pozadie", diff --git a/packages/core/src/i18n/locales/uk.ts b/packages/core/src/i18n/locales/uk.ts index f02b177996..0b95d619a4 100644 --- a/packages/core/src/i18n/locales/uk.ts +++ b/packages/core/src/i18n/locales/uk.ts @@ -255,6 +255,9 @@ export const uk: Dictionary = { suggestion_menu: { no_items_title: "Нічого не знайдено", }, + language_picker: { + default: "Авто", + }, color_picker: { text_title: "Текст", background_title: "Фон", diff --git a/packages/core/src/i18n/locales/uz.ts b/packages/core/src/i18n/locales/uz.ts index 182d0bdc4b..8e47fd60ef 100644 --- a/packages/core/src/i18n/locales/uz.ts +++ b/packages/core/src/i18n/locales/uz.ts @@ -295,6 +295,9 @@ export const uz: Dictionary = { no_items_title: "hech narsa topilmadi", }, + language_picker: { + default: "Avtomatik", + }, color_picker: { text_title: "Matn", background_title: "Fon", diff --git a/packages/core/src/i18n/locales/vi.ts b/packages/core/src/i18n/locales/vi.ts index c9d3396846..fc3e544572 100644 --- a/packages/core/src/i18n/locales/vi.ts +++ b/packages/core/src/i18n/locales/vi.ts @@ -229,6 +229,9 @@ export const vi: Dictionary = { suggestion_menu: { no_items_title: "Không tìm thấy mục nào", }, + language_picker: { + default: "Tự động", + }, color_picker: { text_title: "Văn bản", background_title: "Nền", diff --git a/packages/core/src/i18n/locales/zh-tw.ts b/packages/core/src/i18n/locales/zh-tw.ts index 5bc0608037..022d8ba09e 100644 --- a/packages/core/src/i18n/locales/zh-tw.ts +++ b/packages/core/src/i18n/locales/zh-tw.ts @@ -271,6 +271,9 @@ export const zhTW: Dictionary = { suggestion_menu: { no_items_title: "無相符項目", }, + language_picker: { + default: "自動", + }, color_picker: { text_title: "文字", background_title: "背景色", diff --git a/packages/core/src/i18n/locales/zh.ts b/packages/core/src/i18n/locales/zh.ts index c262bc0d48..f939218110 100644 --- a/packages/core/src/i18n/locales/zh.ts +++ b/packages/core/src/i18n/locales/zh.ts @@ -271,6 +271,9 @@ export const zh: Dictionary = { suggestion_menu: { no_items_title: "无匹配项", }, + language_picker: { + default: "自动", + }, color_picker: { text_title: "文本", background_title: "背景色", diff --git a/packages/core/src/schema/propTypes.ts b/packages/core/src/schema/propTypes.ts index 00e6bcf147..9d2c35ffbd 100644 --- a/packages/core/src/schema/propTypes.ts +++ b/packages/core/src/schema/propTypes.ts @@ -2,7 +2,7 @@ // Note that props are always optional when used as "input" // (i.e., when creating a PartialBlock, for example by calling `insertBlocks({...})`) // -// However, internally they're always set to `default`, unless a prop is marked optional +// Internally they use `default`; a default of undefined represents an optional value. // // At some point we should migrate this to zod or effect-schema export type PropSpec = @@ -54,7 +54,7 @@ export type Props = { : string : never ) extends infer T - ? PSchema[PName] extends { optional: true } + ? PSchema[PName] extends { default: undefined } ? T | undefined : T : never; diff --git a/packages/core/src/y/utils.test.ts b/packages/core/src/y/utils.test.ts index 2174c6ae53..4dcb03acb3 100644 --- a/packages/core/src/y/utils.test.ts +++ b/packages/core/src/y/utils.test.ts @@ -87,6 +87,7 @@ describe("Test y (v14) utils", () => { id: "1", type: "heading", props: { + lang: undefined, backgroundColor: "blue", textColor: "yellow", textAlignment: "right", @@ -116,6 +117,7 @@ describe("Test y (v14) utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "red", textAlignment: "left", textColor: "default", @@ -133,6 +135,7 @@ describe("Test y (v14) utils", () => { id: "3", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -220,6 +223,7 @@ describe("Test y (v14) utils", () => { id: "1", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -237,6 +241,7 @@ describe("Test y (v14) utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "center", @@ -260,6 +265,7 @@ describe("Test y (v14) utils", () => { id: "1", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -276,6 +282,7 @@ describe("Test y (v14) utils", () => { id: "2", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -292,6 +299,7 @@ describe("Test y (v14) utils", () => { id: "3", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -308,6 +316,7 @@ describe("Test y (v14) utils", () => { id: "4", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -337,6 +346,7 @@ describe("Test y (v14) utils", () => { id: "1", type: "numberedListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -354,6 +364,7 @@ describe("Test y (v14) utils", () => { id: "2", type: "numberedListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -370,6 +381,7 @@ describe("Test y (v14) utils", () => { id: "3", type: "numberedListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -395,6 +407,7 @@ describe("Test y (v14) utils", () => { id: "1", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -413,6 +426,7 @@ describe("Test y (v14) utils", () => { id: "2", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -430,6 +444,7 @@ describe("Test y (v14) utils", () => { id: "3", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -456,6 +471,7 @@ describe("Test y (v14) utils", () => { id: "1", type: "toggleListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -472,6 +488,7 @@ describe("Test y (v14) utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -533,6 +550,7 @@ describe("Test y (v14) utils", () => { id: "1", type: "quote", props: { + lang: undefined, backgroundColor: "default", textColor: "default", }, @@ -550,6 +568,7 @@ describe("Test y (v14) utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -575,6 +594,7 @@ describe("Test y (v14) utils", () => { id: "1", type: "heading", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -594,6 +614,7 @@ describe("Test y (v14) utils", () => { id: "2", type: "heading", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -613,6 +634,7 @@ describe("Test y (v14) utils", () => { id: "3", type: "heading", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -631,6 +653,7 @@ describe("Test y (v14) utils", () => { id: "4", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -656,6 +679,7 @@ describe("Test y (v14) utils", () => { id: "1", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -703,6 +727,7 @@ describe("Test y (v14) utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -870,6 +895,7 @@ describe("Test y (v14) utils", () => { id: "1", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -894,6 +920,7 @@ describe("Test y (v14) utils", () => { id: "3", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -917,6 +944,7 @@ describe("Test y (v14) utils", () => { id: "1", type: "heading", props: { + lang: undefined, backgroundColor: "blue", textColor: "yellow", textAlignment: "center", @@ -938,6 +966,7 @@ describe("Test y (v14) utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "red", textColor: "default", textAlignment: "right", @@ -983,6 +1012,7 @@ describe("Test y (v14) utils", () => { id: "3", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -1002,6 +1032,7 @@ describe("Test y (v14) utils", () => { id: "4", type: "quote", props: { + lang: undefined, backgroundColor: "default", textColor: "default", }, @@ -1035,6 +1066,7 @@ describe("Test y (v14) utils", () => { id: "6", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -1053,6 +1085,7 @@ describe("Test y (v14) utils", () => { id: "7", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", diff --git a/packages/core/src/yjs/extensions/schemaMigration/migrationRules/moveColorAttributes.test.ts b/packages/core/src/yjs/extensions/schemaMigration/migrationRules/moveColorAttributes.test.ts index 3458c96e70..655aa9b961 100644 --- a/packages/core/src/yjs/extensions/schemaMigration/migrationRules/moveColorAttributes.test.ts +++ b/packages/core/src/yjs/extensions/schemaMigration/migrationRules/moveColorAttributes.test.ts @@ -68,7 +68,7 @@ it("does not move color attributes on newer documents", async () => { expect(fragment.toJSON()).toMatchInlineSnapshot( // The color attributes are on the paragraph, not the blockContainer. - `"Welcome to this demo!"`, + `"Welcome to this demo!"`, ); const tr = editor.prosemirrorState.tr; diff --git a/packages/core/src/yjs/utils.test.ts b/packages/core/src/yjs/utils.test.ts index 5c388c433f..6852b4b2ca 100644 --- a/packages/core/src/yjs/utils.test.ts +++ b/packages/core/src/yjs/utils.test.ts @@ -42,6 +42,7 @@ describe("Test yjs utils", () => { id: "1", type: "heading", props: { + lang: undefined, backgroundColor: "blue", textColor: "yellow", textAlignment: "right", @@ -71,6 +72,7 @@ describe("Test yjs utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "red", textAlignment: "left", textColor: "default", @@ -88,6 +90,7 @@ describe("Test yjs utils", () => { id: "3", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -170,6 +173,7 @@ describe("Test yjs utils", () => { id: "1", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -187,6 +191,7 @@ describe("Test yjs utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "center", @@ -210,6 +215,7 @@ describe("Test yjs utils", () => { id: "1", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -226,6 +232,7 @@ describe("Test yjs utils", () => { id: "2", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -242,6 +249,7 @@ describe("Test yjs utils", () => { id: "3", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -258,6 +266,7 @@ describe("Test yjs utils", () => { id: "4", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -287,6 +296,7 @@ describe("Test yjs utils", () => { id: "1", type: "numberedListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -304,6 +314,7 @@ describe("Test yjs utils", () => { id: "2", type: "numberedListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -320,6 +331,7 @@ describe("Test yjs utils", () => { id: "3", type: "numberedListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -345,6 +357,7 @@ describe("Test yjs utils", () => { id: "1", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -363,6 +376,7 @@ describe("Test yjs utils", () => { id: "2", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -380,6 +394,7 @@ describe("Test yjs utils", () => { id: "3", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -406,6 +421,7 @@ describe("Test yjs utils", () => { id: "1", type: "toggleListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -422,6 +438,7 @@ describe("Test yjs utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -473,6 +490,7 @@ describe("Test yjs utils", () => { id: "1", type: "quote", props: { + lang: undefined, backgroundColor: "default", textColor: "default", }, @@ -490,6 +508,7 @@ describe("Test yjs utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -515,6 +534,7 @@ describe("Test yjs utils", () => { id: "1", type: "heading", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -534,6 +554,7 @@ describe("Test yjs utils", () => { id: "2", type: "heading", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -553,6 +574,7 @@ describe("Test yjs utils", () => { id: "3", type: "heading", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -571,6 +593,7 @@ describe("Test yjs utils", () => { id: "4", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -596,6 +619,7 @@ describe("Test yjs utils", () => { id: "1", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -643,6 +667,7 @@ describe("Test yjs utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -810,6 +835,7 @@ describe("Test yjs utils", () => { id: "1", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -834,6 +860,7 @@ describe("Test yjs utils", () => { id: "3", type: "paragraph", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -857,6 +884,7 @@ describe("Test yjs utils", () => { id: "1", type: "heading", props: { + lang: undefined, backgroundColor: "blue", textColor: "yellow", textAlignment: "center", @@ -878,6 +906,7 @@ describe("Test yjs utils", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "red", textColor: "default", textAlignment: "right", @@ -923,6 +952,7 @@ describe("Test yjs utils", () => { id: "3", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -942,6 +972,7 @@ describe("Test yjs utils", () => { id: "4", type: "quote", props: { + lang: undefined, backgroundColor: "default", textColor: "default", }, @@ -975,6 +1006,7 @@ describe("Test yjs utils", () => { id: "6", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", @@ -993,6 +1025,7 @@ describe("Test yjs utils", () => { id: "7", type: "checkListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", diff --git a/packages/react/src/components/SideMenu/DragHandleMenu/DefaultItems/BlockLanguageItem.tsx b/packages/react/src/components/SideMenu/DragHandleMenu/DefaultItems/BlockLanguageItem.tsx new file mode 100644 index 0000000000..7302045327 --- /dev/null +++ b/packages/react/src/components/SideMenu/DragHandleMenu/DefaultItems/BlockLanguageItem.tsx @@ -0,0 +1,82 @@ +import { + blockHasType, + type BlockSchema, + type InlineContentSchema, + type StyleSchema, + defaultProps, + editorHasBlockWithType, +} from "@blocknote/core"; +import { SideMenuExtension } from "@blocknote/core/extensions"; +import type { ReactNode } from "react"; + +import { useComponentsContext } from "../../../../editor/ComponentsContext.js"; +import { usePortalElement } from "../../../../editor/PortalElementOverride.js"; +import { useBlockNoteEditor } from "../../../../hooks/useBlockNoteEditor.js"; +import { useExtensionState } from "../../../../hooks/useExtension.js"; +import { useDictionary } from "../../../../i18n/dictionary.js"; + +/** An opt-in submenu for assigning a human language to a block. */ +export function BlockLanguageItem(props: { + children: ReactNode; + languages: readonly { label: string; language: string }[]; +}) { + const Components = useComponentsContext()!; + const dict = useDictionary(); + const portalElement = usePortalElement(); + const editor = useBlockNoteEditor< + BlockSchema, + InlineContentSchema, + StyleSchema + >(); + const block = useExtensionState(SideMenuExtension, { + editor, + selector: (state) => state?.block, + }); + const languageProps = { lang: defaultProps.lang }; + + if ( + !block || + !blockHasType(block, editor, block.type, languageProps) || + !editorHasBlockWithType(editor, block.type, languageProps) + ) { + return null; + } + + return ( + + + + {props.children} + + + + + editor.updateBlock(block, { props: { lang: undefined } }) + } + > + {dict.language_picker.default} + + {props.languages.map(({ label, language }) => ( + + editor.updateBlock(block, { props: { lang: language } }) + } + > + {label} + + ))} + + + ); +} diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index d17381ac88..e55046e37d 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -79,6 +79,7 @@ export * from "./components/AttributionTooltip/AttributionTooltipProps.js"; export * from "./components/AttributionTooltip/formatChangeLabel.js"; export * from "./components/SideMenu/DragHandleMenu/DefaultItems/BlockColorsItem.js"; +export * from "./components/SideMenu/DragHandleMenu/DefaultItems/BlockLanguageItem.js"; export * from "./components/SideMenu/DragHandleMenu/DefaultItems/RemoveBlockItem.js"; export * from "./components/SideMenu/DragHandleMenu/DefaultItems/TableHeadersItem.js"; export * from "./components/SideMenu/DragHandleMenu/DragHandleMenu.js"; diff --git a/packages/server-util/src/context/ServerBlockNoteEditor.test.ts b/packages/server-util/src/context/ServerBlockNoteEditor.test.ts index fd45b2fadd..7c4318c19f 100644 --- a/packages/server-util/src/context/ServerBlockNoteEditor.test.ts +++ b/packages/server-util/src/context/ServerBlockNoteEditor.test.ts @@ -10,6 +10,7 @@ describe("Test ServerBlockNoteEditor", () => { id: "1", type: "heading", props: { + lang: undefined, backgroundColor: "blue", textColor: "yellow", textAlignment: "right", @@ -39,6 +40,7 @@ describe("Test ServerBlockNoteEditor", () => { id: "2", type: "paragraph", props: { + lang: undefined, backgroundColor: "red", textAlignment: "left", textColor: "default", @@ -56,6 +58,7 @@ describe("Test ServerBlockNoteEditor", () => { id: "3", type: "bulletListItem", props: { + lang: undefined, backgroundColor: "default", textColor: "default", textAlignment: "left", diff --git a/playground/src/examples.gen.tsx b/playground/src/examples.gen.tsx index 6fa9173445..5f1f727c01 100644 --- a/playground/src/examples.gen.tsx +++ b/playground/src/examples.gen.tsx @@ -891,6 +891,26 @@ export const examples = { readme: "By default, BlockNote's floating components (formatting toolbar, slash menu, table handles, etc.) mount next to the editor, inside its `bn-container` (or inside whatever you render `BlockNoteViewEditor` into). The `portalElements` prop on `BlockNoteView` lets you change that: globally via `default`, or per component by key. The menus and popovers a floating component opens follow it wherever it mounts.\n\nThis example renders two editors side-by-side, both wrapped in a small `overflow: hidden` container. The left editor uses the default, so the slash menu is clipped by the editor's bounds. The right editor passes `portalElements={{ default: document.body }}` so the floating components escape the wrapper and render fully.\n\n```tsx\n\n```\n\n**Relevant Docs:**\n\n- [UI Components](/docs/react/components)\n- [Mobile Formatting Toolbar](/docs/react/components/formatting-toolbar#mobile-formatting-toolbar)", }, + { + projectSlug: "block-language", + fullSlug: "ui-components/block-language", + pathFromRoot: "examples/03-ui-components/21-block-language", + config: { + playground: true, + docs: true, + author: "", + tags: ["Intermediate", "Blocks", "UI Components", "Block Side Menu"], + dependencies: {} as any, + pro: false, + }, + title: "Block languages", + group: { + pathFromRoot: "examples/03-ui-components", + slug: "ui-components", + }, + readme: + "This example adds an optional language submenu to the drag handle menu, with English, French, and German. Each block can declare its language for assistive technology or inherit the surrounding language.\n\n**Try it out:** Open a block's drag handle menu and choose a language.\n\n## Relevant Docs\n\n- [Changing the Drag Handle Menu](https://www.blocknotejs.org/docs/react/components/side-menu)", + }, ], }, theming: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8900ba6725..a0601c9699 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2304,6 +2304,49 @@ importers: specifier: ^8.0.0 version: 8.0.8(@types/node@25.9.5)(esbuild@0.27.5)(jiti@2.6.1)(terser@5.51.2)(tsx@4.21.0)(yaml@2.9.0) + examples/03-ui-components/21-block-language: + dependencies: + '@blocknote/ariakit': + specifier: latest + version: link:../../../packages/ariakit + '@blocknote/core': + specifier: latest + version: link:../../../packages/core + '@blocknote/mantine': + specifier: latest + version: link:../../../packages/mantine + '@blocknote/react': + specifier: latest + version: link:../../../packages/react + '@blocknote/shadcn': + specifier: latest + version: link:../../../packages/shadcn + '@mantine/core': + specifier: ^9.0.2 + version: 9.1.1(@mantine/hooks@9.1.1(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@mantine/hooks': + specifier: ^9.0.2 + version: 9.1.1(react@19.2.5) + react: + specifier: ^19.2.3 + version: 19.2.5 + react-dom: + specifier: ^19.2.3 + version: 19.2.5(react@19.2.5) + devDependencies: + '@types/react': + specifier: ^19.2.3 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': + specifier: ^6.0.1 + version: 6.0.1(babel-plugin-react-compiler@1.0.0)(vite@8.0.8(@types/node@25.9.5)(esbuild@0.27.5)(jiti@2.6.1)(terser@5.51.2)(tsx@4.21.0)(yaml@2.9.0)) + vite: + specifier: ^8.0.0 + version: 8.0.8(@types/node@25.9.5)(esbuild@0.27.5)(jiti@2.6.1)(terser@5.51.2)(tsx@4.21.0)(yaml@2.9.0) + examples/04-theming/01-theming-dom-attributes: dependencies: '@blocknote/ariakit': diff --git a/shared/formatConversionTestUtil.ts b/shared/formatConversionTestUtil.ts index 7b22c22013..88046d499d 100644 --- a/shared/formatConversionTestUtil.ts +++ b/shared/formatConversionTestUtil.ts @@ -176,9 +176,17 @@ export function partialBlockToBlockForTesting< children: [] as any, ...partialBlock, }; + withDefaults.props = { ...withDefaults.props }; Object.entries(schema[partialBlock.type!].propSchema).forEach( ([propKey, propValue]) => { + // Optional props with no value are omitted by nodeToBlock on import. + if ( + propValue.default === undefined && + withDefaults.props[propKey] === undefined + ) { + delete withDefaults.props[propKey]; + } if ( withDefaults.props[propKey] === undefined && propValue.default !== undefined diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/empty.html b/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/empty.html new file mode 100644 index 0000000000..a762646e9a --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/empty.html @@ -0,0 +1,9 @@ +
+
+
+
+

Unknown language

+
+
+
+
\ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/explicit.html b/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/explicit.html new file mode 100644 index 0000000000..b157937ddb --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/explicit.html @@ -0,0 +1,9 @@ +
+
+
+
+

Bonjour

+
+
+
+
\ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/regional.html b/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/regional.html new file mode 100644 index 0000000000..bf654c07b1 --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/regional.html @@ -0,0 +1,9 @@ +
+
+
+
+

Hello

+
+
+
+
\ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/undefined.html b/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/undefined.html new file mode 100644 index 0000000000..534d714d1e --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/language/undefined.html @@ -0,0 +1,9 @@ +
+
+
+
+

No language

+
+
+
+
\ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/empty.html b/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/empty.html new file mode 100644 index 0000000000..f1530df25e --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/empty.html @@ -0,0 +1 @@ +

Unknown language

\ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/explicit.html b/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/explicit.html new file mode 100644 index 0000000000..d59eccf213 --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/explicit.html @@ -0,0 +1 @@ +

Bonjour

\ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/regional.html b/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/regional.html new file mode 100644 index 0000000000..7603f00396 --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/regional.html @@ -0,0 +1 @@ +

Hello

\ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/undefined.html b/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/undefined.html new file mode 100644 index 0000000000..1180a68f9f --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/html/language/undefined.html @@ -0,0 +1 @@ +

No language

\ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/empty.md b/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/empty.md new file mode 100644 index 0000000000..87a0873bad --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/empty.md @@ -0,0 +1 @@ +Unknown language diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/explicit.md b/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/explicit.md new file mode 100644 index 0000000000..632e4fe73c --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/explicit.md @@ -0,0 +1 @@ +Bonjour diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/regional.md b/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/regional.md new file mode 100644 index 0000000000..e965047ad7 --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/regional.md @@ -0,0 +1 @@ +Hello diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/undefined.md b/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/undefined.md new file mode 100644 index 0000000000..4e5b2aaed0 --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/markdown/language/undefined.md @@ -0,0 +1 @@ +No language diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/complex/document.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/complex/document.json index 0eb89bbcda..8614b013ec 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/complex/document.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/complex/document.json @@ -8,6 +8,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": false, + "lang": undefined, "level": 1, "textAlignment": "left", "textColor": "default", @@ -31,6 +32,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -54,6 +56,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": false, + "lang": undefined, "level": 2, "textAlignment": "left", "textColor": "default", @@ -77,6 +80,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -128,6 +132,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -150,6 +155,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -183,6 +189,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textColor": "default", }, "content": [ diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/complex/misc.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/complex/misc.json index 5689b6b144..4fe7e10d5f 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/complex/misc.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/complex/misc.json @@ -8,6 +8,7 @@ "attrs": { "backgroundColor": "blue", "isToggleable": false, + "lang": undefined, "level": 2, "textAlignment": "right", "textColor": "yellow", @@ -50,6 +51,7 @@ { "attrs": { "backgroundColor": "red", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -72,6 +74,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/custom-blocks/simpleCustomParagraph.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/custom-blocks/simpleCustomParagraph.json index c63e9fad19..2df9c26cdf 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/custom-blocks/simpleCustomParagraph.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/custom-blocks/simpleCustomParagraph.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/basic.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/basic.json index 9f61632bab..0c4e600dd4 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/basic.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/basic.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/between-links.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/between-links.json index 9db2d101f6..10c52f5ed6 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/between-links.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/between-links.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/end.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/end.json index 8ac49d80e1..59b81cd41d 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/end.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/end.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/link.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/link.json index 7a3369fd10..af5d2fa33f 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/link.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/link.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/multiple.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/multiple.json index 2f47b4bc9b..116923be63 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/multiple.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/multiple.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/only.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/only.json index 08f5ee78ee..e1af37de70 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/only.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/only.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/start.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/start.json index 72eb111324..f4b0bfb7f2 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/start.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/start.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/styles.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/styles.json index f7f3c35ae8..c6394b3acb 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/styles.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/hardbreak/styles.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h1.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h1.json index d147b23ade..22c1ada3d4 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h1.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h1.json @@ -8,6 +8,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": false, + "lang": undefined, "level": 1, "textAlignment": "left", "textColor": "default", diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h2.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h2.json index f9f92e7081..84782b9300 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h2.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h2.json @@ -8,6 +8,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": false, + "lang": undefined, "level": 2, "textAlignment": "left", "textColor": "default", diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h3.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h3.json index 6399a58563..c02d33f968 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h3.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h3.json @@ -8,6 +8,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": false, + "lang": undefined, "level": 3, "textAlignment": "left", "textColor": "default", diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h4.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h4.json index c23a0c4809..9953d835b1 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h4.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h4.json @@ -8,6 +8,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": false, + "lang": undefined, "level": 4, "textAlignment": "left", "textColor": "default", diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h5.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h5.json index 0867b7796f..4aeda8b9e2 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h5.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h5.json @@ -8,6 +8,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": false, + "lang": undefined, "level": 5, "textAlignment": "left", "textColor": "default", diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h6.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h6.json index b5eddefddc..fe81e66a3e 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h6.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/h6.json @@ -8,6 +8,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": false, + "lang": undefined, "level": 6, "textAlignment": "left", "textColor": "default", diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/styled.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/styled.json index ff107bc15f..1536f8848e 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/styled.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/styled.json @@ -8,6 +8,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": false, + "lang": undefined, "level": 1, "textAlignment": "left", "textColor": "default", diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/toggleable.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/toggleable.json index 7bb4c57f86..9990fe0775 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/toggleable.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/heading/toggleable.json @@ -8,6 +8,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": true, + "lang": undefined, "level": 2, "textAlignment": "left", "textColor": "default", @@ -30,6 +31,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/inlineContent/mentionWithToExternalHTML.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/inlineContent/mentionWithToExternalHTML.json index b006f6ec56..5d0a87f376 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/inlineContent/mentionWithToExternalHTML.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/inlineContent/mentionWithToExternalHTML.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/inlineContent/tagWithoutToExternalHTML.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/inlineContent/tagWithoutToExternalHTML.json index 9072d90228..449a54ae9c 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/inlineContent/tagWithoutToExternalHTML.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/inlineContent/tagWithoutToExternalHTML.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/empty.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/empty.json new file mode 100644 index 0000000000..fbb0198803 --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/empty.json @@ -0,0 +1,25 @@ +[ + { + "attrs": { + "id": "1", + }, + "content": [ + { + "attrs": { + "backgroundColor": "default", + "lang": "", + "textAlignment": "left", + "textColor": "default", + }, + "content": [ + { + "text": "Unknown language", + "type": "text", + }, + ], + "type": "paragraph", + }, + ], + "type": "blockContainer", + }, +] \ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/explicit.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/explicit.json new file mode 100644 index 0000000000..9484465750 --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/explicit.json @@ -0,0 +1,25 @@ +[ + { + "attrs": { + "id": "1", + }, + "content": [ + { + "attrs": { + "backgroundColor": "default", + "lang": "fr", + "textAlignment": "left", + "textColor": "default", + }, + "content": [ + { + "text": "Bonjour", + "type": "text", + }, + ], + "type": "paragraph", + }, + ], + "type": "blockContainer", + }, +] \ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/regional.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/regional.json new file mode 100644 index 0000000000..8e4c4837ef --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/regional.json @@ -0,0 +1,25 @@ +[ + { + "attrs": { + "id": "1", + }, + "content": [ + { + "attrs": { + "backgroundColor": "default", + "lang": "en-GB", + "textAlignment": "left", + "textColor": "default", + }, + "content": [ + { + "text": "Hello", + "type": "text", + }, + ], + "type": "paragraph", + }, + ], + "type": "blockContainer", + }, +] \ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/undefined.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/undefined.json new file mode 100644 index 0000000000..9d8581600f --- /dev/null +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/language/undefined.json @@ -0,0 +1,25 @@ +[ + { + "attrs": { + "id": "1", + }, + "content": [ + { + "attrs": { + "backgroundColor": "default", + "lang": undefined, + "textAlignment": "left", + "textColor": "default", + }, + "content": [ + { + "text": "No language", + "type": "text", + }, + ], + "type": "paragraph", + }, + ], + "type": "blockContainer", + }, +] \ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/basic.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/basic.json index cd4b7fa368..a61290bae8 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/basic.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/basic.json @@ -13,6 +13,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/emptyChildren.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/emptyChildren.json index 7b02725a5d..f4f9385da8 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/emptyChildren.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/emptyChildren.json @@ -13,6 +13,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/nested.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/nested.json index 4a45ff2fa9..a51ee037e5 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/nested.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/layoutBlock/nested.json @@ -14,6 +14,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": false, + "lang": undefined, "level": 1, "textAlignment": "left", "textColor": "default", @@ -43,6 +44,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/adjacent.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/adjacent.json index f3020cdf7f..d779b4d1a3 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/adjacent.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/adjacent.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/basic.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/basic.json index b85306efc8..c17d2b276c 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/basic.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/basic.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/plainUrl.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/plainUrl.json index dc5aa26397..d50fc0c9a2 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/plainUrl.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/plainUrl.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/styled.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/styled.json index 2c01e6c1a1..29472c39b9 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/styled.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/styled.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/urlWithParens.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/urlWithParens.json index 4de7926c89..605fba2416 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/urlWithParens.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/urlWithParens.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/withCode.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/withCode.json index bf1f1da31f..a48339463e 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/withCode.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/link/withCode.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/basic.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/basic.json index 7a7d1b00e1..3781b7b8bc 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/basic.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/basic.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -29,6 +30,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -51,6 +53,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "start": undefined, "textAlignment": "left", "textColor": "default", @@ -74,6 +77,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "start": undefined, "textAlignment": "left", "textColor": "default", @@ -98,6 +102,7 @@ "attrs": { "backgroundColor": "default", "checked": false, + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -121,6 +126,7 @@ "attrs": { "backgroundColor": "default", "checked": true, + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -143,6 +149,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/nested.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/nested.json index d51adf974b..f2284954fe 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/nested.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/nested.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -29,6 +30,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -50,6 +52,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "start": undefined, "textAlignment": "left", "textColor": "default", @@ -73,6 +76,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "start": undefined, "textAlignment": "left", "textColor": "default", @@ -96,6 +100,7 @@ "attrs": { "backgroundColor": "default", "checked": false, + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -119,6 +124,7 @@ "attrs": { "backgroundColor": "default", "checked": true, + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -140,6 +146,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/numberedListStart.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/numberedListStart.json index 387b4fa073..6e07fe7387 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/numberedListStart.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/numberedListStart.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "start": 5, "textAlignment": "left", "textColor": "default", @@ -30,6 +31,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "start": undefined, "textAlignment": "left", "textColor": "default", diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/toggleWithChildren.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/toggleWithChildren.json index 9b7407a060..0b7acd7ec6 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/toggleWithChildren.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/lists/toggleWithChildren.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -28,6 +29,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -50,6 +52,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -79,6 +82,7 @@ "attrs": { "backgroundColor": "default", "isToggleable": true, + "lang": undefined, "level": 2, "textAlignment": "left", "textColor": "default", @@ -101,6 +105,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/malformed/JSON.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/malformed/JSON.json index b70720d495..d49b33bb27 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/malformed/JSON.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/malformed/JSON.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/basic.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/basic.json index d32dcc601e..dc8c747a58 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/basic.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/basic.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/empty.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/empty.json index 8fdcafd2e5..0d65b3ea2d 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/empty.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/empty.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/emptyBetween.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/emptyBetween.json index 5807d53144..bca737e39c 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/emptyBetween.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/emptyBetween.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -29,6 +30,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -45,6 +47,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/lineBreaks.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/lineBreaks.json index fda9b14014..3fc3316084 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/lineBreaks.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/lineBreaks.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/multiple.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/multiple.json index affba0772c..e8022ccba5 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/multiple.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/multiple.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -29,6 +30,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -51,6 +53,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/nested.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/nested.json index 363e14eec7..6441b2ba18 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/nested.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/nested.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -28,6 +29,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -50,6 +52,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/styled.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/styled.json index 282b3bb4d5..f956200349 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/styled.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/paragraph/styled.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "pink", + "lang": undefined, "textAlignment": "center", "textColor": "orange", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/basic.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/basic.json index 9234a8f05f..4562f81db1 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/basic.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/basic.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textColor": "default", }, "content": [ diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/multiple.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/multiple.json index 458e24879a..dfecd20faa 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/multiple.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/multiple.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textColor": "default", }, "content": [ @@ -28,6 +29,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textColor": "default", }, "content": [ diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/nested.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/nested.json index b3c46ed220..267442210e 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/nested.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/nested.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textColor": "default", }, "content": [ @@ -27,6 +28,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/styled.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/styled.json index a482c2ad58..00b3a1d333 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/styled.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/styled.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textColor": "default", }, "content": [ diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/withLink.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/withLink.json index c0e2857679..cbdc340e9e 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/withLink.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/quote/withLink.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textColor": "default", }, "content": [ diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/backgroundColor.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/backgroundColor.json index e07954b219..c661968354 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/backgroundColor.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/backgroundColor.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/bold.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/bold.json index b6d5b7a208..e1936839cc 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/bold.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/bold.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/boldItalicStrike.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/boldItalicStrike.json index 7c5f05d763..8465be836e 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/boldItalicStrike.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/boldItalicStrike.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/code.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/code.json index 2cf0463e03..710cbaf255 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/code.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/code.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/combined.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/combined.json index 5b91fb8abb..8b420bb57d 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/combined.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/combined.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/italic.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/italic.json index 7d22809e81..f7d32b0ad9 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/italic.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/italic.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/mixedInParagraph.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/mixedInParagraph.json index d72aa1d3bb..0805a95e64 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/mixedInParagraph.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/mixedInParagraph.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/strike.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/strike.json index 756569ade9..1a41b3fe54 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/strike.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/strike.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/textColor.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/textColor.json index 7bca812fd7..1e3f80bf3a 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/textColor.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/textColor.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/underline.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/underline.json index 348c2ae742..242020e918 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/underline.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/style/underline.json @@ -7,6 +7,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/titledBlock/basic.json b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/titledBlock/basic.json index 44e5e45d26..e96c62d066 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/titledBlock/basic.json +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/nodes/titledBlock/basic.json @@ -23,6 +23,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, @@ -45,6 +46,7 @@ { "attrs": { "backgroundColor": "default", + "lang": undefined, "textAlignment": "left", "textColor": "default", }, diff --git a/tests/src/unit/core/formatConversion/export/exportTestInstances.ts b/tests/src/unit/core/formatConversion/export/exportTestInstances.ts index a3e5600295..49abb4341d 100644 --- a/tests/src/unit/core/formatConversion/export/exportTestInstances.ts +++ b/tests/src/unit/core/formatConversion/export/exportTestInstances.ts @@ -18,6 +18,46 @@ export const exportTestInstancesBlockNoteHTML: TestInstance< TestInlineContentSchema, TestStyleSchema >[] = [ + { + testCase: { + name: "language/explicit", + content: [ + { type: "paragraph", props: { lang: "fr" }, content: "Bonjour" }, + ], + }, + executeTest: testExportBlockNoteHTML, + }, + { + testCase: { + name: "language/regional", + content: [ + { type: "paragraph", props: { lang: "en-GB" }, content: "Hello" }, + ], + }, + executeTest: testExportBlockNoteHTML, + }, + { + testCase: { + name: "language/undefined", + content: [ + { + type: "paragraph", + props: { lang: undefined }, + content: "No language", + }, + ], + }, + executeTest: testExportBlockNoteHTML, + }, + { + testCase: { + name: "language/empty", + content: [ + { type: "paragraph", props: { lang: "" }, content: "Unknown language" }, + ], + }, + executeTest: testExportBlockNoteHTML, + }, { testCase: { name: "paragraph/empty", diff --git a/tests/src/unit/core/formatConversion/exportParseEquality/exportParseEqualityTestInstances.ts b/tests/src/unit/core/formatConversion/exportParseEquality/exportParseEqualityTestInstances.ts index f3dfa02604..15a3fba988 100644 --- a/tests/src/unit/core/formatConversion/exportParseEquality/exportParseEqualityTestInstances.ts +++ b/tests/src/unit/core/formatConversion/exportParseEquality/exportParseEqualityTestInstances.ts @@ -36,6 +36,12 @@ export const exportParseEqualityTestInstancesHTML: TestInstance< TestInlineContentSchema, TestStyleSchema >[] = [ + ...exportTestInstancesBlockNoteHTML + .filter(({ testCase }) => testCase.name.startsWith("language/")) + .map(({ testCase }) => ({ + testCase, + executeTest: testExportParseEqualityHTML, + })), { testCase: { name: "schema/blocks", diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/data-attribute.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/data-attribute.json new file mode 100644 index 0000000000..e43198b7cf --- /dev/null +++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/data-attribute.json @@ -0,0 +1,20 @@ +[ + { + "children": [], + "content": [ + { + "styles": {}, + "text": "Bonjour", + "type": "text", + }, + ], + "id": "1", + "props": { + "backgroundColor": "default", + "lang": "fr", + "textAlignment": "left", + "textColor": "default", + }, + "type": "paragraph", + }, +] \ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/empty.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/empty.json new file mode 100644 index 0000000000..e5fdc01909 --- /dev/null +++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/empty.json @@ -0,0 +1,20 @@ +[ + { + "children": [], + "content": [ + { + "styles": {}, + "text": "Unknown language", + "type": "text", + }, + ], + "id": "1", + "props": { + "backgroundColor": "default", + "lang": "", + "textAlignment": "left", + "textColor": "default", + }, + "type": "paragraph", + }, +] \ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/explicit.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/explicit.json new file mode 100644 index 0000000000..e43198b7cf --- /dev/null +++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/explicit.json @@ -0,0 +1,20 @@ +[ + { + "children": [], + "content": [ + { + "styles": {}, + "text": "Bonjour", + "type": "text", + }, + ], + "id": "1", + "props": { + "backgroundColor": "default", + "lang": "fr", + "textAlignment": "left", + "textColor": "default", + }, + "type": "paragraph", + }, +] \ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/regional.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/regional.json new file mode 100644 index 0000000000..c8ca2e4d1b --- /dev/null +++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/language/regional.json @@ -0,0 +1,20 @@ +[ + { + "children": [], + "content": [ + { + "styles": {}, + "text": "Hello", + "type": "text", + }, + ], + "id": "1", + "props": { + "backgroundColor": "default", + "lang": "en-GB", + "textAlignment": "left", + "textColor": "default", + }, + "type": "paragraph", + }, +] \ No newline at end of file diff --git a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts index 33b00531c5..8b7a26fed3 100644 --- a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts +++ b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts @@ -16,6 +16,34 @@ export const parseTestInstancesHTML: TestInstance< TestInlineContentSchema, TestStyleSchema >[] = [ + { + testCase: { + name: "language/explicit", + content: '

Bonjour

', + }, + executeTest: testParseHTML, + }, + { + testCase: { + name: "language/regional", + content: '

Hello

', + }, + executeTest: testParseHTML, + }, + { + testCase: { + name: "language/empty", + content: '

Unknown language

', + }, + executeTest: testParseHTML, + }, + { + testCase: { + name: "language/data-attribute", + content: '

Bonjour

', + }, + executeTest: testParseHTML, + }, { testCase: { name: "basicBlockTypes",