Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions apps/docs/editor/built-in-ui/toolbar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ const superdoc = new SuperDoc({
Custom button definitions. See [Custom Buttons](#custom-buttons).
</ParamField>

<ParamField path="modules.toolbar.showFormattingMarksButton" type="boolean" default="false">
Show the formatting marks (pilcrow) button in the toolbar. Off by default. Distinct from `layoutEngineOptions.showFormattingMarks`, which controls whether the marks render in the document.
</ParamField>

## Available buttons

Use button names with `excludeItems`, `groups`, and `icons` configuration.
Expand Down Expand Up @@ -190,6 +194,10 @@ Use button names with `excludeItems`, `groups`, and `icons` configuration.
Toggle document ruler
</ResponseField>

<ResponseField name="formattingMarks" type="button">
Toggle formatting marks (pilcrow) display. Hidden by default; enable with `modules.toolbar.showFormattingMarksButton: true`.
</ResponseField>

<ResponseField name="documentMode" type="dropdown">
Switch between editing/viewing/suggesting modes
</ResponseField>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,7 @@ export const makeDefaultItems = ({
const itemsToHideXL = ['linkedStyles', 'clearFormatting', 'copyFormat', 'ruler', 'formattingMarks'];
const itemsToHideSM = ['zoom', 'fontFamily', 'fontSize', 'redo'];
const shouldUseLgCompactStyles = availableWidth <= RESPONSIVE_BREAKPOINTS.lg;
const shouldIncludeFormattingMarks = superToolbar.config?.showFormattingMarksButton === true;

if (shouldUseLgCompactStyles) {
documentMode.attributes.value = {
Expand Down Expand Up @@ -1114,7 +1115,7 @@ export const makeDefaultItems = ({
linkedStyles,
separator,
ruler,
formattingMarks,
...(shouldIncludeFormattingMarks ? [formattingMarks] : []),
copyFormat,
clearFormatting,
aiButton,
Expand All @@ -1136,7 +1137,7 @@ export const makeDefaultItems = ({
const getLinkedStylesIndex = toolbarItems.findIndex((item) => item.name.value === 'linkedStyles');
toolbarItems.splice(getLinkedStylesIndex - 1, 2);

const filterItems = ['ruler', 'formattingMarks', 'zoom', 'undo', 'redo'];
const filterItems = ['ruler', 'zoom', 'undo', 'redo'];
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep formatting marks out of non-docx toolbars

When showFormattingMarksButton is enabled for a toolbar running with config.mode !== 'docx' (for example an html/text Editor toolbar, which the new test now expects), this filter no longer removes the pilcrow button even though the command is only implemented through SuperDoc's layout/presentation rendering path. In standalone SuperToolbar({ editor }) there is no superdoc.toggleFormattingMarks, so clicking falls through to a missing editor command and throws; in SuperDoc HTML documents the viewer is the plain HtmlViewer rather than a PresentationEditor, so toggling has no rendered effect. Please keep this item filtered for non-docx modes or gate it on an available formatting-marks implementation.

Useful? React with 👍 / 👎.

toolbarItems = toolbarItems.filter((item) => !filterItems.includes(item.name.value));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,22 @@ function getItemNames(list) {
return list.map((item) => item.name.value);
}

function buildItems(availableWidth) {
function getItem(defaultItems, overflowItems, name) {
return [...defaultItems, ...overflowItems].find((item) => item.name.value === name);
}

function buildItems(availableWidth, superToolbarOverrides = {}) {
const toolbar = {
...superToolbar,
...superToolbarOverrides,
config: {
...superToolbar.config,
...superToolbarOverrides.config,
},
};

return makeDefaultItems({
superToolbar,
superToolbar: toolbar,
toolbarIcons: stubProxy,
toolbarTexts: stubProxy,
toolbarFonts: [],
Expand All @@ -31,6 +44,32 @@ function buildItems(availableWidth) {
});
}

describe('makeDefaultItems formatting marks button opt-in', () => {
it('does not include formattingMarks in the default toolbar items', () => {
const { defaultItems, overflowItems } = buildItems(2000);
expect(getItem(defaultItems, overflowItems, 'formattingMarks')).toBeUndefined();
});

it('includes formattingMarks when showFormattingMarksButton is true', () => {
const { defaultItems, overflowItems } = buildItems(2000, {
config: { showFormattingMarksButton: true },
});
const formattingMarks = getItem(defaultItems, overflowItems, 'formattingMarks');

expect(formattingMarks).toBeDefined();
expect(formattingMarks.command).toBe('toggleFormattingMarks');
});

it('includes formattingMarks in non-docx mode when showFormattingMarksButton is true', () => {
const { defaultItems, overflowItems } = buildItems(2000, {
config: { mode: 'html', showFormattingMarksButton: true },
});
const formattingMarks = getItem(defaultItems, overflowItems, 'formattingMarks');

expect(formattingMarks).toBeDefined();
});
});

describe('makeDefaultItems XL overflow boundary (SD-2328)', () => {
const XL_OVERFLOW_SAFETY_BUFFER = 20;
const XL_CUTOFF = RESPONSIVE_BREAKPOINTS.xl + XL_OVERFLOW_SAFETY_BUFFER;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { markerTextToBulletStyle } from '@helpers/list-numbering-helpers.js';
* @property {string} [aiApiKey=null] - API key for AI integration
* @property {string} [aiEndpoint=null] - Endpoint for AI integration
* @property {ToolbarItem[]} [customButtons=[]] - Custom buttons to add to the toolbar
* @property {boolean} [showFormattingMarksButton=false] - Show the formatting marks (pilcrow) button in the toolbar. Distinct from `layoutEngineOptions.showFormattingMarks`, which controls whether the marks render in the document.
*/

/**
Expand Down Expand Up @@ -180,6 +181,7 @@ export class SuperToolbar extends EventEmitter {
aiApiKey: null,
aiEndpoint: null,
customButtons: [],
showFormattingMarksButton: false,
};

/**
Expand Down
6 changes: 6 additions & 0 deletions packages/superdoc/src/core/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,12 @@ export interface Modules {
* already pass through `modules.toolbar.customButtons`.
*/
customButtons?: Array<Record<string, unknown>>;
/**
* Show the formatting marks (pilcrow) button in the toolbar. Off by
* default. Distinct from `layoutEngineOptions.showFormattingMarks`, which
* controls whether the marks render in the document.
*/
showFormattingMarksButton?: boolean;
} & Record<string, unknown>;
/** Link click popover configuration. */
links?: {
Expand Down
Loading