diff --git a/docs/configuration.md b/docs/configuration.md index 6c50d41f3..7f4a88cb4 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -49,6 +49,17 @@ Editors support the following options, configurable using presets and element at - `markdown`: Pass `false` to disable Markdown support. - `multiLine`: Pass `false` to force single line editing. - `richText`: Pass `false` to disable rich text editing. +- `headings`: Pass an array of heading tags to configure which heading levels are available. The toolbar heading button will cycle through the configured levels. Defaults to `["h2", "h3", "h4"]`. Pass an empty array to disable headings entirely. + + ```js + // Via preset + Lexxy.configure({ + default: { headings: ["h1", "h2", "h3"] } + }) + + // Via element attribute + + ``` The toolbar is considered part of the editor for `lexxy:focus` and `lexxy:blur` events. If the toolbar registers event or lexical handlers, it should expose a `dispose()` function which will be called on editor disconnect. diff --git a/src/config/lexxy.js b/src/config/lexxy.js index e26c591c1..82e5dd983 100644 --- a/src/config/lexxy.js +++ b/src/config/lexxy.js @@ -17,6 +17,7 @@ const presets = new Configuration({ toolbar: { upload: "both" }, + headings: [ "h2", "h3", "h4" ], highlight: { buttons: { color: range(1, 9).map(n => `var(--highlight-${n})`), diff --git a/src/elements/toolbar.js b/src/elements/toolbar.js index d532eac8f..a5e8454e9 100644 --- a/src/elements/toolbar.js +++ b/src/elements/toolbar.js @@ -306,10 +306,10 @@ export class LexicalToolbarElement extends HTMLElement { } #closeDropdowns() { - this.#dropdowns.forEach((details) => { - details.open = false - }) - } + this.#dropdowns.forEach((details) => { + details.open = false + }) + } get #dropdowns() { return this.querySelectorAll("details") diff --git a/test/javascript/unit/editor/headings_configuration.test.js b/test/javascript/unit/editor/headings_configuration.test.js new file mode 100644 index 000000000..a88443efb --- /dev/null +++ b/test/javascript/unit/editor/headings_configuration.test.js @@ -0,0 +1,54 @@ +import { expect, test } from "vitest" +import { createElement } from "../helpers/dom_helper" +import EditorConfiguration from "src/editor/configuration" +import { configure } from "src/index" + +configure({ + default: { + headings: ["h2", "h3", "h4"] + }, + minimal: { + headings: ["h2"], + }, + noHeadings: { + headings: [], + }, +}) + +test("uses default headings", () => { + const element = createElement("") + const config = new EditorConfiguration(element) + expect(config.get("headings")).toEqual(["h2", "h3", "h4"]) +}) + +test("overrides headings with attribute", () => { + const element = createElement( + '' + ) + const config = new EditorConfiguration(element) + expect(config.get("headings")).toEqual(["h1", "h2", "h3", "h4", "h5", "h6"]) +}) + +test("overrides headings with attribute to include h1 and h5", () => { + const element = createElement( + '' + ) + const config = new EditorConfiguration(element) + expect(config.get("headings")).toEqual(["h1", "h2", "h5"]) +}) + +test("restricts headings to a subset", () => { + const element = createElement( + "" + ) + const config = new EditorConfiguration(element) + expect(config.get("headings")).toEqual(["h2"]) +}) + +test("handles empty headings array", () => { + const element = createElement( + "" + ) + const config = new EditorConfiguration(element) + expect(config.get("headings")).toEqual([]) +})