diff --git a/packages/core/src/editor/Block.css b/packages/core/src/editor/Block.css index 5c94b887a..85d61fadd 100644 --- a/packages/core/src/editor/Block.css +++ b/packages/core/src/editor/Block.css @@ -305,11 +305,8 @@ NESTED BLOCKS } /* PLACEHOLDERS*/ - -.bn-is-empty .bn-inline-content:before, -.bn-is-filter .bn-inline-content:before { +.bn-inline-content:has(> .ProseMirror-trailingBreak):before { /*float: left; */ - content: ""; pointer-events: none; height: 0; /* width: 0; */ @@ -317,33 +314,7 @@ NESTED BLOCKS font-style: italic; } -/* TODO: would be nicer if defined from code */ - -.bn-block-content.bn-is-empty.bn-has-anchor .bn-inline-content:before { - content: "Enter text or type '/' for commands"; -} - -.bn-block-content.bn-is-filter.bn-has-anchor .bn-inline-content:before { - content: "Type to filter"; -} - -.bn-block-content[data-content-type="heading"].bn-is-empty - .bn-inline-content:before { - content: "Heading"; -} - -.bn-block-content[data-content-type="bulletListItem"].bn-is-empty - .bn-inline-content:before, -.bn-block-content[data-content-type="numberedListItem"].bn-is-empty - .bn-inline-content:before { - content: "List"; -} - -.bn-is-empty - .bn-block-content[data-content-type="captionedImage"] - .bn-inline-content:before { - content: "Caption"; -} +/* TODO: should this be here? */ /* TEXT COLORS */ [data-text-color="gray"] { diff --git a/packages/core/src/editor/BlockNoteEditor.ts b/packages/core/src/editor/BlockNoteEditor.ts index 23483d570..65596426c 100644 --- a/packages/core/src/editor/BlockNoteEditor.ts +++ b/packages/core/src/editor/BlockNoteEditor.ts @@ -72,6 +72,8 @@ export type BlockNoteEditorOptions< // TODO: Figure out if enableBlockNoteExtensions/disableHistoryExtension are needed and document them. enableBlockNoteExtensions: boolean; + placeholders: Record; + /** * An object containing attributes that should be added to HTML elements of the editor. * @@ -243,6 +245,7 @@ export class BlockNoteEditor< const extensions = getBlockNoteExtensions({ editor: this, + placeholders: newOptions.placeholders, domAttributes: newOptions.domAttributes || {}, blockSchema: this.schema.blockSchema, blockSpecs: this.schema.blockSpecs, diff --git a/packages/core/src/editor/BlockNoteExtensions.ts b/packages/core/src/editor/BlockNoteExtensions.ts index 902ed5d49..2cf41f98f 100644 --- a/packages/core/src/editor/BlockNoteExtensions.ts +++ b/packages/core/src/editor/BlockNoteExtensions.ts @@ -39,6 +39,7 @@ export const getBlockNoteExtensions = < S extends StyleSchema >(opts: { editor: BlockNoteEditor; + placeholders?: Record; domAttributes: Partial; blockSchema: BSchema; blockSpecs: BlockSpecs; @@ -66,9 +67,10 @@ export const getBlockNoteExtensions = < // DropCursor, Placeholder.configure({ - editor: opts.editor, - includeChildren: true, - showOnlyCurrent: false, + // TODO: This shorthand is kind of ugly + ...(opts.placeholders !== undefined + ? { placeholders: opts.placeholders } + : {}), }), UniqueID.configure({ types: ["blockContainer"], diff --git a/packages/core/src/extensions/Placeholder/PlaceholderExtension.ts b/packages/core/src/extensions/Placeholder/PlaceholderExtension.ts index 71e80d75b..b25e6d4c5 100644 --- a/packages/core/src/extensions/Placeholder/PlaceholderExtension.ts +++ b/packages/core/src/extensions/Placeholder/PlaceholderExtension.ts @@ -1,9 +1,6 @@ -import { Editor, Extension } from "@tiptap/core"; -import { Node as ProsemirrorNode } from "prosemirror-model"; +import { Extension } from "@tiptap/core"; import { Plugin, PluginKey } from "prosemirror-state"; import { Decoration, DecorationSet } from "prosemirror-view"; -import type { BlockNoteEditor } from "../../editor/BlockNoteEditor"; -import { suggestionMenuPluginKey } from "../SuggestionMenu/SuggestionPlugin"; const PLUGIN_KEY = new PluginKey(`blocknote-placeholder`); @@ -15,22 +12,7 @@ const PLUGIN_KEY = new PluginKey(`blocknote-placeholder`); * */ export interface PlaceholderOptions { - editor: BlockNoteEditor | undefined; - emptyEditorClass: string; - emptyNodeClass: string; - isFilterClass: string; - hasAnchorClass: string; - placeholder: - | ((PlaceholderProps: { - editor: Editor; - node: ProsemirrorNode; - pos: number; - hasAnchor: boolean; - }) => string) - | string; - showOnlyWhenEditable: boolean; - showOnlyCurrent: boolean; - includeChildren: boolean; + placeholders: Record; } export const Placeholder = Extension.create({ @@ -38,94 +20,102 @@ export const Placeholder = Extension.create({ addOptions() { return { - editor: undefined, - emptyEditorClass: "bn-is-editor-empty", - emptyNodeClass: "bn-is-empty", - isFilterClass: "bn-is-filter", - hasAnchorClass: "bn-has-anchor", - placeholder: "Write something …", - showOnlyWhenEditable: true, - showOnlyCurrent: true, - includeChildren: false, + placeholders: { + default: "Enter text or type '/' for commands", + heading: "Heading", + bulletListItem: "List", + numberedListItem: "List", + }, }; }, addProseMirrorPlugins() { + const placeholders = this.options.placeholders; return [ new Plugin({ key: PLUGIN_KEY, + view: () => { + const styleEl = document.createElement("style"); + document.head.appendChild(styleEl); + const styleSheet = styleEl.sheet!; + + const getBaseSelector = (additionalSelectors = "") => + `.bn-block-content${additionalSelectors} .bn-inline-content:has(> .ProseMirror-trailingBreak):before`; + + const getSelector = ( + blockType: string | "default", + mustBeFocused = true + ) => { + const mustBeFocusedSelector = mustBeFocused + ? `[data-is-empty-and-focused]` + : ``; + + if (blockType === "default") { + return getBaseSelector(mustBeFocusedSelector); + } + + const blockTypeSelector = `[data-content-type="${blockType}"]`; + return getBaseSelector(mustBeFocusedSelector + blockTypeSelector); + }; + + for (const [blockType, placeholder] of Object.entries(placeholders)) { + const mustBeFocused = blockType === "default"; + + styleSheet.insertRule( + `${getSelector( + blockType, + mustBeFocused + )}{ content: ${JSON.stringify(placeholder)}; }` + ); + + // For some reason, the placeholders which show when the block is focused + // take priority over ones which show depending on block type, so we need + // to make sure the block specific ones are also used when the block is + // focused. + if (!mustBeFocused) { + styleSheet.insertRule( + `${getSelector(blockType, true)}{ content: ${JSON.stringify( + placeholder + )}; }` + ); + } + } + + return { + destroy: () => { + document.head.removeChild(styleEl); + }, + }; + }, props: { + // TODO: maybe also add placeholder for empty document ("e.g.: start writing..") decorations: (state) => { const { doc, selection } = state; - // Get state of slash menu - const menuState = suggestionMenuPluginKey.getState(state); - const active = - this.editor.isEditable || !this.options.showOnlyWhenEditable; - const { anchor } = selection; - const decorations: Decoration[] = []; + + const active = this.editor.isEditable; if (!active) { return; } - doc.descendants((node, pos) => { - const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize; - const isEmpty = !node.isLeaf && !node.childCount; - - if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) { - const classes = [this.options.emptyNodeClass]; - - // TODO: Doesn't work? - if (this.editor.isEmpty) { - classes.push(this.options.emptyEditorClass); - } - - if (hasAnchor) { - classes.push(this.options.hasAnchorClass); - } - - // If slash menu is of drag type and active, show the filter placeholder - if (menuState?.triggerCharacter === "" && menuState?.active) { - classes.push(this.options.isFilterClass); - } - // using widget, didn't work (caret position bug) - // const decoration = Decoration.widget( - // pos + 1, - // () => { - // const el = document.createElement("span"); - // el.innerText = "hello"; - // return el; - // }, - // { side: 0 } - - // Code that sets variables / classes - // const ph = - // typeof this.options.placeholder === "function" - // ? this.options.placeholder({ - // editor: this.editor, - // node, - // pos, - // hasAnchor, - // }) - // : this.options.placeholder; - // const decoration = Decoration.node(pos, pos + node.nodeSize, { - // class: classes.join(" "), - // style: `--placeholder:'${ph.replaceAll("'", "\\'")}';`, - // "data-placeholder": ph, - // }); - - // Latest version, only set isEmpty and hasAnchor, rest is done via CSS - - const decoration = Decoration.node(pos, pos + node.nodeSize, { - class: classes.join(" "), - }); - decorations.push(decoration); - } - - return this.options.includeChildren; + if (!selection.empty) { + return; + } + + const $pos = selection.$anchor; + const node = $pos.parent; + + if (node.content.size > 0) { + return null; + } + + const before = $pos.before(); + + const dec = Decoration.node(before, before + node.nodeSize, { + "data-is-empty-and-focused": "true", }); - return DecorationSet.create(doc, decorations); + return DecorationSet.create(doc, [dec]); }, }, }), diff --git a/packages/react/src/editor/styles.css b/packages/react/src/editor/styles.css index e4d6e112d..8aa5705e9 100644 --- a/packages/react/src/editor/styles.css +++ b/packages/react/src/editor/styles.css @@ -3,569 +3,577 @@ /* Default theme params */ .bn-container { - --bn-colors-editor-text: #3F3F3F; - --bn-colors-editor-background: #FFFFFF; - --bn-colors-menu-text: #3F3F3F; - --bn-colors-menu-background: #FFFFFF; - --bn-colors-tooltip-text: #3F3F3F; - --bn-colors-tooltip-background: #EFEFEF; - --bn-colors-hovered-text: #3F3F3F; - --bn-colors-hovered-background: #EFEFEF; - --bn-colors-selected-text: #FFFFFF; - --bn-colors-selected-background: #3F3F3F; - --bn-colors-disabled-text: #AFAFAF; - --bn-colors-disabled-background: #EFEFEF; - - --bn-colors-shadow: #CFCFCF; - --bn-colors-border: #EFEFEF; - --bn-colors-side-menu: #CFCFCF; - - --bn-colors-highlights-gray-text: #9b9a97; - --bn-colors-highlights-gray-background: #ebeced; - --bn-colors-highlights-brown-text: #64473a; - --bn-colors-highlights-brown-background: #e9e5e3; - --bn-colors-highlights-red-text: #e03e3e; - --bn-colors-highlights-red-background: #fbe4e4; - --bn-colors-highlights-orange-text: #d9730d; - --bn-colors-highlights-orange-background: #f6e9d9; - --bn-colors-highlights-yellow-text: #dfab01; - --bn-colors-highlights-yellow-background: #fbf3db; - --bn-colors-highlights-green-text: #4d6461; - --bn-colors-highlights-green-background: #ddedea; - --bn-colors-highlights-blue-text: #0b6e99; - --bn-colors-highlights-blue-background: #ddebf1; - --bn-colors-highlights-purple-text: #6940a5; - --bn-colors-highlights-purple-background: #eae4f2; - --bn-colors-highlights-pink-text: #ad1a72; - --bn-colors-highlights-pink-background: #f4dfeb; - - --bn-font-family: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, "Open Sans", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - --bn-border-radius: 6px; - - /* Derived values */ - --bn-shadow-medium: 0 4px 12px var(--bn-colors-shadow); - --bn-shadow-light: 0 2px 6px var(--bn-colors-border); - --bn-border: 1px solid var(--bn-colors-border); - --bn-border-radius-small: max(var(--bn-border-radius) - 2px, 1px); - --bn-border-radius-medium: var(--bn-border-radius); - --bn-border-radius-large: max(var(--bn-border-radius) + 2px, 1px); + --bn-colors-editor-text: #3f3f3f; + --bn-colors-editor-background: #ffffff; + --bn-colors-menu-text: #3f3f3f; + --bn-colors-menu-background: #ffffff; + --bn-colors-tooltip-text: #3f3f3f; + --bn-colors-tooltip-background: #efefef; + --bn-colors-hovered-text: #3f3f3f; + --bn-colors-hovered-background: #efefef; + --bn-colors-selected-text: #ffffff; + --bn-colors-selected-background: #3f3f3f; + --bn-colors-disabled-text: #afafaf; + --bn-colors-disabled-background: #efefef; + + --bn-colors-shadow: #cfcfcf; + --bn-colors-border: #efefef; + --bn-colors-side-menu: #cfcfcf; + + --bn-colors-highlights-gray-text: #9b9a97; + --bn-colors-highlights-gray-background: #ebeced; + --bn-colors-highlights-brown-text: #64473a; + --bn-colors-highlights-brown-background: #e9e5e3; + --bn-colors-highlights-red-text: #e03e3e; + --bn-colors-highlights-red-background: #fbe4e4; + --bn-colors-highlights-orange-text: #d9730d; + --bn-colors-highlights-orange-background: #f6e9d9; + --bn-colors-highlights-yellow-text: #dfab01; + --bn-colors-highlights-yellow-background: #fbf3db; + --bn-colors-highlights-green-text: #4d6461; + --bn-colors-highlights-green-background: #ddedea; + --bn-colors-highlights-blue-text: #0b6e99; + --bn-colors-highlights-blue-background: #ddebf1; + --bn-colors-highlights-purple-text: #6940a5; + --bn-colors-highlights-purple-background: #eae4f2; + --bn-colors-highlights-pink-text: #ad1a72; + --bn-colors-highlights-pink-background: #f4dfeb; + + --bn-font-family: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, + "Open Sans", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", + "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + --bn-border-radius: 6px; + + /* Derived values */ + --bn-shadow-medium: 0 4px 12px var(--bn-colors-shadow); + --bn-shadow-light: 0 2px 6px var(--bn-colors-border); + --bn-border: 1px solid var(--bn-colors-border); + --bn-border-radius-small: max(var(--bn-border-radius) - 2px, 1px); + --bn-border-radius-medium: var(--bn-border-radius); + --bn-border-radius-large: max(var(--bn-border-radius) + 2px, 1px); } .bn-container[data-color-scheme="dark"] { - --bn-colors-editor-text: #CFCFCF; - --bn-colors-editor-background: #1F1F1F; - --bn-colors-menu-text: #CFCFCF; - --bn-colors-menu-background: #1F1F1F; - --bn-colors-tooltip-text: #CFCFCF; - --bn-colors-tooltip-background: #161616; - --bn-colors-hovered-text: #CFCFCF; - --bn-colors-hovered-background: #161616; - --bn-colors-selected-text: #CFCFCF; - --bn-colors-selected-background: #0F0F0F; - --bn-colors-disabled-text: #3F3F3F; - --bn-colors-disabled-background: #161616; - - --bn-colors-shadow: #0F0F0F; - --bn-colors-border: #161616; - --bn-colors-side-menu: #7F7F7F; - - --bn-colors-highlights-gray-text: #bebdb8; - --bn-colors-highlights-gray-background: #9b9a97; - --bn-colors-highlights-brown-text: #8e6552; - --bn-colors-highlights-brown-background: #64473a; - --bn-colors-highlights-red-text: #ec4040; - --bn-colors-highlights-red-background: #be3434; - --bn-colors-highlights-orange-text: #e3790d; - --bn-colors-highlights-orange-background: #b7600a; - --bn-colors-highlights-yellow-text: #dfab01; - --bn-colors-highlights-yellow-background: #b58b00; - --bn-colors-highlights-green-text: #6b8b87; - --bn-colors-highlights-green-background: #4d6461; - --bn-colors-highlights-blue-text: #0e87bc; - --bn-colors-highlights-blue-background: #0b6e99; - --bn-colors-highlights-purple-text: #8552d7; - --bn-colors-highlights-purple-background: #6940a5; - --bn-colors-highlights-pink-text: #da208f; - --bn-colors-highlights-pink-background: #ad1a72; + --bn-colors-editor-text: #cfcfcf; + --bn-colors-editor-background: #1f1f1f; + --bn-colors-menu-text: #cfcfcf; + --bn-colors-menu-background: #1f1f1f; + --bn-colors-tooltip-text: #cfcfcf; + --bn-colors-tooltip-background: #161616; + --bn-colors-hovered-text: #cfcfcf; + --bn-colors-hovered-background: #161616; + --bn-colors-selected-text: #cfcfcf; + --bn-colors-selected-background: #0f0f0f; + --bn-colors-disabled-text: #3f3f3f; + --bn-colors-disabled-background: #161616; + + --bn-colors-shadow: #0f0f0f; + --bn-colors-border: #161616; + --bn-colors-side-menu: #7f7f7f; + + --bn-colors-highlights-gray-text: #bebdb8; + --bn-colors-highlights-gray-background: #9b9a97; + --bn-colors-highlights-brown-text: #8e6552; + --bn-colors-highlights-brown-background: #64473a; + --bn-colors-highlights-red-text: #ec4040; + --bn-colors-highlights-red-background: #be3434; + --bn-colors-highlights-orange-text: #e3790d; + --bn-colors-highlights-orange-background: #b7600a; + --bn-colors-highlights-yellow-text: #dfab01; + --bn-colors-highlights-yellow-background: #b58b00; + --bn-colors-highlights-green-text: #6b8b87; + --bn-colors-highlights-green-background: #4d6461; + --bn-colors-highlights-blue-text: #0e87bc; + --bn-colors-highlights-blue-background: #0b6e99; + --bn-colors-highlights-purple-text: #8552d7; + --bn-colors-highlights-purple-background: #6940a5; + --bn-colors-highlights-pink-text: #da208f; + --bn-colors-highlights-pink-background: #ad1a72; } .bn-container * { - font-family: var(--bn-font-family); + font-family: var(--bn-font-family); } /* Mantine base styles*/ /* Mantine Badge component base styles */ .bn-container .mantine-Badge-root { - background-color: var(--bn-colors-tooltip-background); - color: var(--bn-colors-tooltip-text); + background-color: var(--bn-colors-tooltip-background); + color: var(--bn-colors-tooltip-text); } /* Mantine FileInput component base styles */ .bn-container .mantine-FileInput-input { - align-items: center; - background-color: var(--bn-colors-menu-background); - border: none; - border-radius: 4px; - color: var(--bn-colors-menu-text); - display: flex; - flex-direction: row; - justify-content: center; + align-items: center; + background-color: var(--bn-colors-menu-background); + border: none; + border-radius: 4px; + color: var(--bn-colors-menu-text); + display: flex; + flex-direction: row; + justify-content: center; } .bn-container .mantine-FileInput-input:hover { - background-color: var(--bn-colors-hovered-background); + background-color: var(--bn-colors-hovered-background); } .bn-container .mantine-FileInput-wrapper { - border: solid var(--bn-colors-border) 1px; - border-radius: 4px; + border: solid var(--bn-colors-border) 1px; + border-radius: 4px; } .bn-container .mantine-InputPlaceholder-placeholder { - color: var(--bn-colors-menu-text); - font-weight: 600; + color: var(--bn-colors-menu-text); + font-weight: 600; } /* Mantine Menu component base styles */ .bn-container .mantine-Menu-dropdown { - background-color: var(--bn-colors-menu-background); - border: var(--bn-border); - border-radius: var(--bn-border-radius-medium); - box-shadow: var(--bn-shadow-medium); - box-sizing: border-box; - color: var(--bn-colors-menu-text); - overflow-y: auto; - padding: 2px; + background-color: var(--bn-colors-menu-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-medium); + box-shadow: var(--bn-shadow-medium); + box-sizing: border-box; + color: var(--bn-colors-menu-text); + overflow-y: auto; + padding: 2px; } .bn-container .mantine-Menu-label { - background-color: var(--bn-colors-menu-background); - color: var(--bn-colors-menu-text); + background-color: var(--bn-colors-menu-background); + color: var(--bn-colors-menu-text); } .bn-container .mantine-Menu-item { - background-color: var(--bn-colors-menu-background); - border: none; - border-radius: var(--bn-border-radius-small); - color: var(--bn-colors-menu-text); + background-color: var(--bn-colors-menu-background); + border: none; + border-radius: var(--bn-border-radius-small); + color: var(--bn-colors-menu-text); } .bn-container .mantine-Menu-item[data-hovered] { - background-color: var(--bn-colors-hovered-background); - border: none; - color: var(--bn-colors-hovered-text); + background-color: var(--bn-colors-hovered-background); + border: none; + color: var(--bn-colors-hovered-text); } /* Mantine Popover component base styles */ .bn-container .mantine-Popover-dropdown { - background-color: transparent; - border: none; - border-radius: 0; - box-shadow: none; - padding: 0; + background-color: transparent; + border: none; + border-radius: 0; + box-shadow: none; + padding: 0; } /* Mantine Tabs component base styles */ .bn-container .mantine-Tabs-root { - width: 100%; - background-color: var(--bn-colors-menu-background); + width: 100%; + background-color: var(--bn-colors-menu-background); } .bn-container .mantine-Tabs-list:before { - border-color: var(--bn-colors-hovered-background); + border-color: var(--bn-colors-hovered-background); } .bn-container .mantine-Tabs-tab { - color: var(--bn-colors-menu-text); - border-color: var(--bn-colors-hovered-background); + color: var(--bn-colors-menu-text); + border-color: var(--bn-colors-hovered-background); } .bn-container .mantine-Tabs-tab:hover { - background-color: var(--bn-colors-hovered-background); - border-color: var(--bn-colors-hovered-background); - color: var(--bn-colors-hovered-text); + background-color: var(--bn-colors-hovered-background); + border-color: var(--bn-colors-hovered-background); + color: var(--bn-colors-hovered-text); } .bn-container .mantine-Tabs-tab[data-active], .bn-container .mantine-Tabs-tab[data-active]:hover { - border-color: var(--bn-colors-menu-text); - color: var(--bn-colors-menu-text); + border-color: var(--bn-colors-menu-text); + color: var(--bn-colors-menu-text); } .bn-container .mantine-Tabs-panel { - padding: 8px; + padding: 8px; } /* Mantine TextInput component base styles */ .bn-container .mantine-TextInput-input { - background-color: var(--bn-colors-menu-background); - border: solid var(--bn-colors-border) 1px; - border-radius: 4px; - color: var(--bn-colors-menu-text); - height: 32px; + background-color: var(--bn-colors-menu-background); + border: solid var(--bn-colors-border) 1px; + border-radius: 4px; + color: var(--bn-colors-menu-text); + height: 32px; } /* Mantine Tooltip component base styles */ .mantine-Tooltip-tooltip { - background-color: transparent; - border: none; - border-radius: 0; - box-shadow: none; - padding: 0; + background-color: transparent; + border: none; + border-radius: 0; + box-shadow: none; + padding: 0; } - /* Editor body styling */ /* Editor styling */ .bn-editor { - background-color: var(--bn-colors-editor-background); - border-radius: var(--bn-border-radius-large); - color: var(--bn-colors-editor-text); - font-family: var(--bn-font-family); + background-color: var(--bn-colors-editor-background); + border-radius: var(--bn-border-radius-large); + color: var(--bn-colors-editor-text); + font-family: var(--bn-font-family); } /* Indent line styling */ .bn-block-group -.bn-block-group -.bn-block-outer:not([data-prev-depth-changed])::before { - border-left: 1px solid var(--bn-colors-side-menu) + .bn-block-group + .bn-block-outer:not([data-prev-depth-changed])::before { + border-left: 1px solid var(--bn-colors-side-menu); } /* Placeholder styling */ -.bn-is-empty .bn-inline-content:before, .bn-is-filter .bn-inline-content:before { - color: var(--bn-colors-side-menu); +.bn-inline-content:has(> .ProseMirror-trailingBreak):before { + color: var(--bn-colors-side-menu); } /* Highlight color styling */ [data-text-color="gray"] { - color: var(--bn-colors-highlights-gray-text); + color: var(--bn-colors-highlights-gray-text); } [data-text-color="brown"] { - color: var(--bn-colors-highlights-brown-text); + color: var(--bn-colors-highlights-brown-text); } [data-text-color="red"] { - color: var(--bn-colors-highlights-red-text); + color: var(--bn-colors-highlights-red-text); } [data-text-color="orange"] { - color: var(--bn-colors-highlights-orange-text); + color: var(--bn-colors-highlights-orange-text); } [data-text-color="yellow"] { - color: var(--bn-colors-highlights-yellow-text); + color: var(--bn-colors-highlights-yellow-text); } [data-text-color="green"] { - color: var(--bn-colors-highlights-green-text); + color: var(--bn-colors-highlights-green-text); } [data-text-color="blue"] { - color: var(--bn-colors-highlights-blue-text); + color: var(--bn-colors-highlights-blue-text); } [data-text-color="purple"] { - color: var(--bn-colors-highlights-purple-text); + color: var(--bn-colors-highlights-purple-text); } [data-text-color="pink"] { - color: var(--bn-colors-highlights-pink-text); + color: var(--bn-colors-highlights-pink-text); } [data-background-color="gray"] { - background-color: var(--bn-colors-highlights-gray-background); + background-color: var(--bn-colors-highlights-gray-background); } [data-background-color="brown"] { - background-color: var(--bn-colors-highlights-brown-background); + background-color: var(--bn-colors-highlights-brown-background); } [data-background-color="red"] { - background-color: var(--bn-colors-highlights-red-background); + background-color: var(--bn-colors-highlights-red-background); } [data-background-color="orange"] { - background-color: var(--bn-colors-highlights-orange-background); + background-color: var(--bn-colors-highlights-orange-background); } [data-background-color="yellow"] { - background-color: var(--bn-colors-highlights-yellow-background); + background-color: var(--bn-colors-highlights-yellow-background); } [data-background-color="green"] { - background-color: var(--bn-colors-highlights-green-background); + background-color: var(--bn-colors-highlights-green-background); } [data-background-color="blue"] { - background-color: var(--bn-colors-highlights-blue-background); + background-color: var(--bn-colors-highlights-blue-background); } [data-background-color="purple"] { - background-color: var(--bn-colors-highlights-purple-background); + background-color: var(--bn-colors-highlights-purple-background); } [data-background-color="pink"] { - background-color: var(--bn-colors-highlights-pink-background); + background-color: var(--bn-colors-highlights-pink-background); } /* UI element styling */ /* Toolbar styling */ .bn-container .bn-toolbar { - background-color: var(--bn-colors-menu-background); - border: var(--bn-border); - border-radius: var(--bn-border-radius-medium); - box-shadow: var(--bn-shadow-medium); - flex-wrap: nowrap; - gap: 2px; - padding: 2px; - width: fit-content; + background-color: var(--bn-colors-menu-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-medium); + box-shadow: var(--bn-shadow-medium); + flex-wrap: nowrap; + gap: 2px; + padding: 2px; + width: fit-content; } .bn-container .bn-toolbar .mantine-Button-root, .bn-container .bn-toolbar .mantine-ActionIcon-root { - background-color: var(--bn-colors-menu-background); - border: none; - border-radius: var(--bn-border-radius-small); - color: var(--bn-colors-menu-text); + background-color: var(--bn-colors-menu-background); + border: none; + border-radius: var(--bn-border-radius-small); + color: var(--bn-colors-menu-text); } .bn-container .bn-toolbar .mantine-Button-root:hover, .bn-container .bn-toolbar .mantine-ActionIcon-root:hover { - background-color: var(--bn-colors-hovered-background); - border: none; - color: var(--bn-colors-hovered-text); + background-color: var(--bn-colors-hovered-background); + border: none; + color: var(--bn-colors-hovered-text); } .bn-container .bn-toolbar .mantine-Button-root[data-selected], .bn-container .bn-toolbar .mantine-ActionIcon-root[data-selected] { - background-color: var(--bn-colors-selected-background); - border: none; - color: var(--bn-colors-selected-text); + background-color: var(--bn-colors-selected-background); + border: none; + color: var(--bn-colors-selected-text); } .bn-container .bn-toolbar .mantine-Button-root[data-disabled], .bn-container .bn-toolbar .mantine-ActionIcon-root[data-disabled] { - background-color: var(--bn-colors-disabled-background); - border: none; - color: var(--bn-colors-disabled-text); + background-color: var(--bn-colors-disabled-background); + border: none; + color: var(--bn-colors-disabled-text); } .bn-container .bn-toolbar .mantine-Menu-dropdown .mantine-Menu-item { - font-size: 12px; - height: 30px; + font-size: 12px; + height: 30px; } .bn-container .bn-toolbar .mantine-Menu-dropdown .mantine-Menu-item:hover { - background-color: var(--bn-colors-hovered-background); + background-color: var(--bn-colors-hovered-background); } .bn-container .bn-toolbar .bn-embed-image-button { - border: solid var(--bn-colors-border) 1px; - border-radius: var(--bn-border-radius-small); - height: 32px; - width: 60%; + border: solid var(--bn-colors-border) 1px; + border-radius: var(--bn-border-radius-small); + height: 32px; + width: 60%; } .bn-container .bn-toolbar-input-dropdown { - background-color: var(--bn-colors-menu-background); - border: var(--bn-border); - border-radius: var(--bn-border-radius-medium); - box-shadow: var(--bn-shadow-medium); - color: var(--bn-colors-menu-text); - gap: 4px; - min-width: 145px; - padding: 2px; + background-color: var(--bn-colors-menu-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-medium); + box-shadow: var(--bn-shadow-medium); + color: var(--bn-colors-menu-text); + gap: 4px; + min-width: 145px; + padding: 2px; } .bn-container .bn-toolbar-input-dropdown .mantine-Group-root { - flex-wrap: nowrap; + flex-wrap: nowrap; } .bn-container .bn-toolbar-input-dropdown .mantine-TextInput-root, .bn-container .bn-toolbar-input-dropdown .mantine-FileInput-root { - width: 300px; + width: 300px; } .bn-container .bn-toolbar-input-dropdown .mantine-TextInput-wrapper, .bn-container .bn-toolbar-input-dropdown .mantine-FileInput-wrapper { - padding: 0; - border-radius: 4px; + padding: 0; + border-radius: 4px; } .bn-container .bn-toolbar-input-dropdown .mantine-TextInput-wrapper:hover { - background-color: var(--bn-colors-hovered-background); + background-color: var(--bn-colors-hovered-background); } .bn-container .bn-toolbar-input-dropdown .mantine-TextInput-input, .bn-container .bn-toolbar-input-dropdown .mantine-FileInput-input { - border: none; - font-size: 12px; + border: none; + font-size: 12px; } .bn-container .bn-toolbar-input-dropdown .mantine-FileInput-input:hover { - background-color: var(--bn-colors-hovered-background); + background-color: var(--bn-colors-hovered-background); } -.bn-container .bn-toolbar-input-dropdown -.mantine-FileInput-section[data-position="left"] { - color: var(--bn-colors-menu-text); +.bn-container + .bn-toolbar-input-dropdown + .mantine-FileInput-section[data-position="left"] { + color: var(--bn-colors-menu-text); } .bn-container .bn-toolbar-input-dropdown .mantine-FileInput-placeholder { - color: var(--bn-colors-menu-text); + color: var(--bn-colors-menu-text); } .bn-container .bn-image-toolbar { - width: 500px + width: 500px; } .bn-container .bn-image-toolbar .bn-upload-image-panel > div { - align-items: stretch; - display: flex; - flex-direction: column; - gap: 8px; + align-items: stretch; + display: flex; + flex-direction: column; + gap: 8px; } .bn-container -.bn-image-toolbar -.bn-upload-image-panel -> div -> .mantine-Text-root { - text-align: center; + .bn-image-toolbar + .bn-upload-image-panel + > div + > .mantine-Text-root { + text-align: center; } .bn-container .bn-image-toolbar .bn-embed-image-panel > div { - align-items: center; - display: flex; - flex-direction: column; - gap: 8px; - width: 100%; + align-items: center; + display: flex; + flex-direction: column; + gap: 8px; + width: 100%; } -.bn-container .bn-image-toolbar .bn-embed-image-panel > div .mantine-TextInput-root { - width: 100%; +.bn-container + .bn-image-toolbar + .bn-embed-image-panel + > div + .mantine-TextInput-root { + width: 100%; } /* Slash Menu styling*/ .bn-container .bn-slash-menu { - max-height: 100%; - position: relative; + max-height: 100%; + position: relative; } .bn-container .bn-slash-menu .mantine-Menu-item { - height: 52px; + height: 52px; } .bn-container .bn-slash-menu .mantine-Menu-itemSection { - color: var(--bn-colors-tooltip-text); + color: var(--bn-colors-tooltip-text); } .bn-container .bn-slash-menu .mantine-Menu-itemSection[data-position="left"] { - background-color: var(--bn-colors-tooltip-background); - border-radius: var(--bn-border-radius-small); - padding: 8px; + background-color: var(--bn-colors-tooltip-background); + border-radius: var(--bn-border-radius-small); + padding: 8px; } .bn-container .bn-slash-menu .mantine-Menu-itemLabel { - padding-right: 16px; + padding-right: 16px; } .bn-container .bn-slash-menu .mantine-Menu-itemLabel .mantine-Stack-root { - gap: 0; + gap: 0; } .bn-container .bn-slash-menu .bn-slash-menu-loader { - height: 20px; - width: 100%; + height: 20px; + width: 100%; } .bn-container .bn-slash-menu .bn-slash-menu-loader span { - background-color: var(--bn-colors-side-menu); + background-color: var(--bn-colors-side-menu); } /* Side Menu & Drag Handle styling */ .bn-container .bn-side-menu { - background-color: transparent; + background-color: transparent; } .bn-container .bn-side-menu .mantine-UnstyledButton-root { - background-color: transparent; - color: var(--bn-colors-side-menu); + background-color: transparent; + color: var(--bn-colors-side-menu); } .bn-container .bn-side-menu .mantine-UnstyledButton-root:hover { - background-color: var(--bn-colors-hovered-background); + background-color: var(--bn-colors-hovered-background); } .bn-container .bn-drag-handle { - height: 24px; - width: 24px; + height: 24px; + width: 24px; } /* Table Handle styling */ .bn-container .bn-table-handle { - align-items: center; - background-color: var(--bn-colors-menu-background); - border: var(--bn-border); - border-radius: var(--bn-border-radius-small); - box-shadow: var(--bn-shadow-light); - color: var(--bn-colors-side-menu); - cursor: pointer; - display: flex; - justify-content: center; - overflow: visible; + align-items: center; + background-color: var(--bn-colors-menu-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-small); + box-shadow: var(--bn-shadow-light); + color: var(--bn-colors-side-menu); + cursor: pointer; + display: flex; + justify-content: center; + overflow: visible; } .bn-container .bn-table-handle > svg { - margin-inline: -4px; + margin-inline: -4px; } -.bn-container .bn-table-handle:hover, .bn-container .bn-table-handle-dragging { - background-color: var(--bn-colors-hovered-background); +.bn-container .bn-table-handle:hover, +.bn-container .bn-table-handle-dragging { + background-color: var(--bn-colors-hovered-background); } /* Drag Handle & Table Handle Menu styling */ -.bn-container .bn-drag-handle-menu, .bn-container .bn-table-handle-menu { - overflow: visible; +.bn-container .bn-drag-handle-menu, +.bn-container .bn-table-handle-menu { + overflow: visible; } .bn-container .bn-drag-handle-menu .mantine-Menu-item, .bn-container .bn-table-handle-menu .mantine-Menu-item { - color: var(--bn-colors-menu-text); - font-size: 12px; - height: 30px; + color: var(--bn-colors-menu-text); + font-size: 12px; + height: 30px; } /* Tooltip styling */ .bn-container .bn-tooltip { - background-color: var(--bn-colors-tooltip-background); - border: var(--bn-border); - border-radius: var(--bn-border-radius-medium); - box-shadow: var(--bn-shadow-medium); - color: var(--bn-colors-tooltip-text); - padding: 4px 10px; - text-align: center; + background-color: var(--bn-colors-tooltip-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-medium); + box-shadow: var(--bn-shadow-medium); + color: var(--bn-colors-tooltip-text); + padding: 4px 10px; + text-align: center; } /* Color Icon styling */ .bn-container .bn-color-icon { - align-items: center; - border: var(--bn-border); - border-radius: var(--bn-border-radius-small); - display: flex; - justify-content: center; + align-items: center; + border: var(--bn-border); + border-radius: var(--bn-border-radius-small); + display: flex; + justify-content: center; } /* Tick styling */ .bn-container .bn-tick-icon { - padding-left: 8px; + padding-left: 8px; } .bn-container .bn-tick-space { - padding: 0; - width: 20px; + padding: 0; + width: 20px; } diff --git a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-chromium-linux.png b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-chromium-linux.png index ccdb394fc..056de61cc 100644 Binary files a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-chromium-linux.png and b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-chromium-linux.png differ diff --git a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-firefox-linux.png b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-firefox-linux.png index 17ae13286..79430f918 100644 Binary files a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-firefox-linux.png and b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-firefox-linux.png differ diff --git a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-webkit-linux.png b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-webkit-linux.png index 5ad46ba70..981e6b741 100644 Binary files a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-webkit-linux.png and b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-drag-handle-menu-webkit-linux.png differ diff --git a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-chromium-linux.png b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-chromium-linux.png index 80f7df74a..51df51faf 100644 Binary files a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-chromium-linux.png and b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-chromium-linux.png differ diff --git a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-firefox-linux.png b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-firefox-linux.png index 064314d00..bae404d27 100644 Binary files a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-firefox-linux.png and b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-firefox-linux.png differ diff --git a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-webkit-linux.png b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-webkit-linux.png index a92b3d26f..0d70f857c 100644 Binary files a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-webkit-linux.png and b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-image-toolbar-webkit-linux.png differ diff --git a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-chromium-linux.png b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-chromium-linux.png index 57585454b..05e83c4ee 100644 Binary files a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-chromium-linux.png and b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-chromium-linux.png differ diff --git a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-firefox-linux.png b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-firefox-linux.png index 5a4485a39..f2db7999e 100644 Binary files a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-firefox-linux.png and b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-firefox-linux.png differ diff --git a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-webkit-linux.png b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-webkit-linux.png index 8d829d589..c2c79840a 100644 Binary files a/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-webkit-linux.png and b/tests/src/end-to-end/theming/theming.test.ts-snapshots/dark-side-menu-webkit-linux.png differ