From 25548b12ee7acd2efc74f8916b7c27c7bff75763 Mon Sep 17 00:00:00 2001 From: Artem Nistuley Date: Tue, 26 May 2026 13:29:23 +0300 Subject: [PATCH] feat: namespace internal ui classes --- .../editors/v1/assets/styles/elements/ai.css | 8 +- .../src/editors/v1/components/SuperEditor.vue | 1 + .../components/context-menu/ContextMenu.vue | 6 +- .../context-menu/tests/ContextMenu.test.js | 6 +- .../v1/components/popovers/Mentions.vue | 4 +- .../v1/components/toolbar/AIWriter.vue | 2 +- .../components/toolbar/AlignmentButtons.vue | 6 +- .../v1/components/toolbar/ButtonGroup.test.js | 24 ++-- .../v1/components/toolbar/ButtonGroup.vue | 14 +-- .../v1/components/toolbar/DocumentMode.vue | 10 +- .../v1/components/toolbar/IconGridRow.vue | 18 +-- .../v1/components/toolbar/LinkInput.test.js | 6 +- .../v1/components/toolbar/LinkInput.vue | 16 +-- .../v1/components/toolbar/SearchInput.vue | 12 +- .../components/toolbar/StyleButtonsList.vue | 12 +- .../v1/components/toolbar/TableGrid.vue | 8 +- .../editors/v1/components/toolbar/Toolbar.vue | 1 + .../v1/components/toolbar/ToolbarButton.vue | 109 +++++++++--------- .../components/toolbar/ToolbarButtonIcon.vue | 12 +- .../toolbar/ToolbarDropdown.test.js | 2 +- .../v1/components/toolbar/ToolbarDropdown.vue | 35 ++++-- .../v1/components/toolbar/defaultItems.js | 8 +- .../components/toolbar/defaultItems.test.js | 8 +- .../custom-selection/custom-selection.js | 7 +- .../src/editors/v1/tests/css-no-bleed.test.js | 96 +++++++++++++++ .../src/assets/styles/elements/superdoc.css | 5 - .../src/assets/styles/layout/global.css | 6 +- .../CommentsLayer/CommentDialog.vue | 15 +-- .../CommentsLayer/CommentsDropdown.vue | 4 +- .../CommentsLayer/InternalDropdown.vue | 28 ++--- .../comments/reject-format-suggestion.spec.ts | 2 +- .../tests/formatting/apply-font.spec.ts | 2 +- .../formatting/toggle-formatting-off.spec.ts | 4 +- .../tests/lists/bullet-style-export.spec.ts | 2 +- .../tests/lists/bullet-style-picker.spec.ts | 2 +- .../lists/bullet-style-undo-redo.spec.ts | 2 +- .../tests/lists/list-style-changes.spec.ts | 12 +- .../tests/tables/add-row-formatting.spec.ts | 4 +- .../tests/toolbar/basic-styles.spec.ts | 14 +-- .../tests/toolbar/composite-styles.spec.ts | 40 +++---- tests/behavior/tests/toolbar/link.spec.ts | 2 +- .../responsive-container-overflow.spec.ts | 2 +- .../tests/toolbar/table-styles.spec.ts | 10 +- .../behavior/tests/toolbar/undo-redo.spec.ts | 4 +- 44 files changed, 348 insertions(+), 243 deletions(-) diff --git a/packages/super-editor/src/editors/v1/assets/styles/elements/ai.css b/packages/super-editor/src/editors/v1/assets/styles/elements/ai.css index b4cabe4eeb..b7d42effe2 100644 --- a/packages/super-editor/src/editors/v1/assets/styles/elements/ai.css +++ b/packages/super-editor/src/editors/v1/assets/styles/elements/ai.css @@ -1,16 +1,16 @@ /* Custom toolbar styling */ /* AI button icon styling with gradient */ -.super-editor .toolbar-icon__icon--ai { +.super-editor .sd-toolbar-icon__icon--ai { position: relative; z-index: 1; } -.super-editor .toolbar-icon__icon--ai svg { +.super-editor .sd-toolbar-icon__icon--ai svg { fill: transparent; } -.super-editor .toolbar-icon__icon--ai::before { +.super-editor .sd-toolbar-icon__icon--ai::before { content: ''; position: absolute; top: 0; @@ -33,7 +33,7 @@ transition: filter 0.2s ease; } -.super-editor .toolbar-icon__icon--ai:hover::before { +.super-editor .sd-toolbar-icon__icon--ai:hover::before { filter: brightness(1.3); } diff --git a/packages/super-editor/src/editors/v1/components/SuperEditor.vue b/packages/super-editor/src/editors/v1/components/SuperEditor.vue index 9ef3822539..84c3827a6a 100644 --- a/packages/super-editor/src/editors/v1/components/SuperEditor.vue +++ b/packages/super-editor/src/editors/v1/components/SuperEditor.vue @@ -1293,6 +1293,7 @@ onBeforeUnmount(() => { class="super-editor-container" :class="{ 'web-layout': isWebLayout, contained: isContained }" :style="containerStyle" + data-sd-part="editor-root" > { diff --git a/packages/super-editor/src/editors/v1/components/toolbar/SearchInput.vue b/packages/super-editor/src/editors/v1/components/toolbar/SearchInput.vue index 55d7b85dab..d650e172fd 100644 --- a/packages/super-editor/src/editors/v1/components/toolbar/SearchInput.vue +++ b/packages/super-editor/src/editors/v1/components/toolbar/SearchInput.vue @@ -17,7 +17,7 @@ const handleSubmit = () => { @@ -57,15 +57,15 @@ const handleSubmit = () => { } } - .row { + .sd-row { display: flex; - &.submit { + &.sd-submit { margin-top: 10px; flex-direction: row-reverse; } } - .submit-btn { + .sd-submit-btn { display: flex; justify-content: center; align-items: center; diff --git a/packages/super-editor/src/editors/v1/components/toolbar/StyleButtonsList.vue b/packages/super-editor/src/editors/v1/components/toolbar/StyleButtonsList.vue index ae52363778..6417f0458a 100644 --- a/packages/super-editor/src/editors/v1/components/toolbar/StyleButtonsList.vue +++ b/packages/super-editor/src/editors/v1/components/toolbar/StyleButtonsList.vue @@ -79,8 +79,8 @@ onMounted(() => {
{ padding: 8px; box-sizing: border-box; - .button-icon { + .sd-button-icon { cursor: pointer; padding: 5px; font-size: var(--sd-ui-font-size-600, 16px); @@ -123,16 +123,16 @@ onMounted(() => { fill: currentColor; } - &.selected { + &.sd-selected { background-color: var(--sd-ui-dropdown-active-bg, #d8dee5); color: var(--sd-ui-dropdown-selected-text, #47484a); } } &.high-contrast { - .button-icon { + .sd-button-icon { &:hover, - &.selected { + &.sd-selected { background-color: #000; color: #fff; } diff --git a/packages/super-editor/src/editors/v1/components/toolbar/TableGrid.vue b/packages/super-editor/src/editors/v1/components/toolbar/TableGrid.vue index 5aa1b591be..e48e957d98 100644 --- a/packages/super-editor/src/editors/v1/components/toolbar/TableGrid.vue +++ b/packages/super-editor/src/editors/v1/components/toolbar/TableGrid.vue @@ -35,9 +35,9 @@ const selectGridItems = (allItems, cols, rows) => { let itemsRows = parseInt(item.dataset.rows, 10); if (itemsCols <= cols && itemsRows <= rows) { - item.classList.add('selected'); + item.classList.add('sd-selected'); } else { - item.classList.remove('selected'); + item.classList.remove('sd-selected'); } } }; @@ -162,7 +162,7 @@ onMounted(() => { transition: all 0.15s; } - .toolbar-table-grid__item.selected { + .toolbar-table-grid__item.sd-selected { background-color: var(--sd-ui-dropdown-hover-bg, #d8dee5); } @@ -171,7 +171,7 @@ onMounted(() => { border-color: #000; } - .toolbar-table-grid__item.selected { + .toolbar-table-grid__item.sd-selected { background: #000; } } diff --git a/packages/super-editor/src/editors/v1/components/toolbar/Toolbar.vue b/packages/super-editor/src/editors/v1/components/toolbar/Toolbar.vue index d6dc0ca991..82e5165afa 100644 --- a/packages/super-editor/src/editors/v1/components/toolbar/Toolbar.vue +++ b/packages/super-editor/src/editors/v1/components/toolbar/Toolbar.vue @@ -138,6 +138,7 @@ const handleToolbarMousedown = (e) => { :key="toolbarKey" role="toolbar" aria-label="Toolbar" + data-sd-part="toolbar" data-editor-ui-surface @mousedown="handleToolbarMousedown" > diff --git a/packages/super-editor/src/editors/v1/components/toolbar/ToolbarButton.vue b/packages/super-editor/src/editors/v1/components/toolbar/ToolbarButton.vue index d1e9e7338f..f73ec83b19 100644 --- a/packages/super-editor/src/editors/v1/components/toolbar/ToolbarButton.vue +++ b/packages/super-editor/src/editors/v1/components/toolbar/ToolbarButton.vue @@ -132,19 +132,20 @@ const caretIcon = computed(() => { diff --git a/packages/super-editor/src/editors/v1/components/toolbar/ToolbarButtonIcon.vue b/packages/super-editor/src/editors/v1/components/toolbar/ToolbarButtonIcon.vue index d0f6739150..dcc9289a03 100644 --- a/packages/super-editor/src/editors/v1/components/toolbar/ToolbarButtonIcon.vue +++ b/packages/super-editor/src/editors/v1/components/toolbar/ToolbarButtonIcon.vue @@ -27,21 +27,21 @@ const hasColorBar = computed(() => { diff --git a/packages/superdoc/src/components/CommentsLayer/CommentsDropdown.vue b/packages/superdoc/src/components/CommentsLayer/CommentsDropdown.vue index a6bbd3d911..58565f330f 100644 --- a/packages/superdoc/src/components/CommentsLayer/CommentsDropdown.vue +++ b/packages/superdoc/src/components/CommentsLayer/CommentsDropdown.vue @@ -150,7 +150,7 @@ onBeforeUnmount(() => { v-for="option in options" :key="option.key" class="comments-dropdown__option" - :class="{ disabled: option.disabled }" + :class="{ 'sd-disabled': option.disabled }" @click="onOptionClick(option)" > @@ -201,7 +201,7 @@ onBeforeUnmount(() => { color: var(--sd-ui-comments-option-hover-text, #212121); } -.comments-dropdown__option.disabled { +.comments-dropdown__option.sd-disabled { opacity: 0.5; pointer-events: none; } diff --git a/packages/superdoc/src/components/CommentsLayer/InternalDropdown.vue b/packages/superdoc/src/components/CommentsLayer/InternalDropdown.vue index 38ecc5c3f3..2dd952251e 100644 --- a/packages/superdoc/src/components/CommentsLayer/InternalDropdown.vue +++ b/packages/superdoc/src/components/CommentsLayer/InternalDropdown.vue @@ -76,36 +76,36 @@ onMounted(() => { diff --git a/tests/behavior/tests/comments/reject-format-suggestion.spec.ts b/tests/behavior/tests/comments/reject-format-suggestion.spec.ts index d0b23b4d85..ce194ec951 100644 --- a/tests/behavior/tests/comments/reject-format-suggestion.spec.ts +++ b/tests/behavior/tests/comments/reject-format-suggestion.spec.ts @@ -172,7 +172,7 @@ for (const tc of ALL_CASES) { if (tc.restoredFontFamily) { await superdoc.selectAll(); await superdoc.waitForStable(); - await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .button-label')).toHaveText( + await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .sd-button-label')).toHaveText( tc.restoredFontFamily, ); } diff --git a/tests/behavior/tests/formatting/apply-font.spec.ts b/tests/behavior/tests/formatting/apply-font.spec.ts index 1b5926f3a5..c94a280327 100644 --- a/tests/behavior/tests/formatting/apply-font.spec.ts +++ b/tests/behavior/tests/formatting/apply-font.spec.ts @@ -33,7 +33,7 @@ test('apply Courier New font to selected text in loaded document', async ({ supe await superdoc.assertTextContains(originalText.substring(0, 20)); // Verify font applied via toolbar state for the current selection. - await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .button-label')).toHaveText('Courier New'); + await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .sd-button-label')).toHaveText('Courier New'); await superdoc.snapshot('apply-font-courier'); }); diff --git a/tests/behavior/tests/formatting/toggle-formatting-off.spec.ts b/tests/behavior/tests/formatting/toggle-formatting-off.spec.ts index 21315c3a52..88a7142529 100644 --- a/tests/behavior/tests/formatting/toggle-formatting-off.spec.ts +++ b/tests/behavior/tests/formatting/toggle-formatting-off.spec.ts @@ -46,8 +46,8 @@ test('toggle bold off retains other formatting', async ({ superdoc }) => { await superdoc.type('hello italic'); await superdoc.waitForStable(); - await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-bold"]')).not.toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-bold"]')).not.toHaveClass(/sd-active/); await superdoc.snapshot('toggle-formatting-off'); }); diff --git a/tests/behavior/tests/lists/bullet-style-export.spec.ts b/tests/behavior/tests/lists/bullet-style-export.spec.ts index 799b50b831..ee57be67c6 100644 --- a/tests/behavior/tests/lists/bullet-style-export.spec.ts +++ b/tests/behavior/tests/lists/bullet-style-export.spec.ts @@ -3,7 +3,7 @@ import JSZip from 'jszip'; test.use({ config: { toolbar: 'full' } }); -const BULLET_DROPDOWN_CARET = '[aria-label="Bullet list"] .dropdown-caret'; +const BULLET_DROPDOWN_CARET = '[aria-label="Bullet list"] .sd-dropdown-caret'; const STYLE_OPTION = (label: string) => `.style-buttons-list [aria-label="${label}"]`; const STYLE_LABEL = { diff --git a/tests/behavior/tests/lists/bullet-style-picker.spec.ts b/tests/behavior/tests/lists/bullet-style-picker.spec.ts index 2e86946b07..da0c0f2830 100644 --- a/tests/behavior/tests/lists/bullet-style-picker.spec.ts +++ b/tests/behavior/tests/lists/bullet-style-picker.spec.ts @@ -3,7 +3,7 @@ import { LIST_MARKER_SELECTOR, getParagraphNumberingByText } from '../../helpers test.use({ config: { toolbar: 'full' } }); -const BULLET_DROPDOWN_CARET = '[aria-label="Bullet list"] .dropdown-caret'; +const BULLET_DROPDOWN_CARET = '[aria-label="Bullet list"] .sd-dropdown-caret'; const STYLE_OPTION = (label: string) => `.style-buttons-list [aria-label="${label}"]`; const STYLE_LABEL = { diff --git a/tests/behavior/tests/lists/bullet-style-undo-redo.spec.ts b/tests/behavior/tests/lists/bullet-style-undo-redo.spec.ts index f6b70d9a9d..c880452eb1 100644 --- a/tests/behavior/tests/lists/bullet-style-undo-redo.spec.ts +++ b/tests/behavior/tests/lists/bullet-style-undo-redo.spec.ts @@ -2,7 +2,7 @@ import { test, expect, type SuperDocFixture } from '../../fixtures/superdoc.js'; test.use({ config: { toolbar: 'full' } }); -const BULLET_DROPDOWN_CARET = '[aria-label="Bullet list"] .dropdown-caret'; +const BULLET_DROPDOWN_CARET = '[aria-label="Bullet list"] .sd-dropdown-caret'; const STYLE_OPTION = (label: string) => `.style-buttons-list [aria-label="${label}"]`; const STYLE_LABEL = { diff --git a/tests/behavior/tests/lists/list-style-changes.spec.ts b/tests/behavior/tests/lists/list-style-changes.spec.ts index b23f33a6ff..6a564f7be5 100644 --- a/tests/behavior/tests/lists/list-style-changes.spec.ts +++ b/tests/behavior/tests/lists/list-style-changes.spec.ts @@ -73,8 +73,8 @@ test.describe('PR-2873 list style changes', () => { await superdoc.waitForStable(); await placeCursorIn(superdoc, 'item'); - await expect(superdoc.page.locator('[data-item="btn-list"]').first()).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-numberedlist"]').first()).not.toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-list"]').first()).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-numberedlist"]').first()).not.toHaveClass(/sd-active/); }); test('numbered list button is active when caret is in an ordered list', async ({ superdoc }) => { @@ -83,16 +83,16 @@ test.describe('PR-2873 list style changes', () => { await superdoc.waitForStable(); await placeCursorIn(superdoc, 'item'); - await expect(superdoc.page.locator('[data-item="btn-numberedlist"]').first()).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-list"]').first()).not.toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-numberedlist"]').first()).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-list"]').first()).not.toHaveClass(/sd-active/); }); test('neither button is active when caret is on a plain paragraph', async ({ superdoc }) => { await superdoc.type('plain'); await superdoc.waitForStable(); - await expect(superdoc.page.locator('[data-item="btn-list"]').first()).not.toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-numberedlist"]').first()).not.toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-list"]').first()).not.toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-numberedlist"]').first()).not.toHaveClass(/sd-active/); }); }); diff --git a/tests/behavior/tests/tables/add-row-formatting.spec.ts b/tests/behavior/tests/tables/add-row-formatting.spec.ts index 3ca0b8dc0d..1686e26d51 100644 --- a/tests/behavior/tests/tables/add-row-formatting.spec.ts +++ b/tests/behavior/tests/tables/add-row-formatting.spec.ts @@ -11,7 +11,7 @@ test('adding a row after bold cell preserves formatting in new row', async ({ su await superdoc.type('Bold header'); await superdoc.waitForStable(); - await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/sd-active/); // Add a row after the current one await superdoc.executeCommand('addRowAfter'); @@ -26,5 +26,5 @@ test('adding a row after bold cell preserves formatting in new row', async ({ su await superdoc.assertTextContains('Bold header'); // The new text inherits bold from the row it was cloned from. - await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/sd-active/); }); diff --git a/tests/behavior/tests/toolbar/basic-styles.spec.ts b/tests/behavior/tests/toolbar/basic-styles.spec.ts index 938f394ff0..92e3b96499 100644 --- a/tests/behavior/tests/toolbar/basic-styles.spec.ts +++ b/tests/behavior/tests/toolbar/basic-styles.spec.ts @@ -28,7 +28,7 @@ test('bold button applies bold', async ({ superdoc }) => { await boldButton.click(); await superdoc.waitForStable(); - await expect(boldButton).toHaveClass(/active/); + await expect(boldButton).toHaveClass(/sd-active/); await superdoc.snapshot('bold applied'); await superdoc.assertTextHasMarks('is a sentence', ['bold']); @@ -42,7 +42,7 @@ test('italic button applies italic', async ({ superdoc }) => { await italicButton.click(); await superdoc.waitForStable(); - await expect(italicButton).toHaveClass(/active/); + await expect(italicButton).toHaveClass(/sd-active/); await superdoc.snapshot('italic applied'); await superdoc.assertTextHasMarks('is a sentence', ['italic']); @@ -56,7 +56,7 @@ test('underline button applies underline', async ({ superdoc }) => { await underlineButton.click(); await superdoc.waitForStable(); - await expect(underlineButton).toHaveClass(/active/); + await expect(underlineButton).toHaveClass(/sd-active/); await superdoc.snapshot('underline applied'); await superdoc.assertTextHasMarks('is a sentence', ['underline']); @@ -70,7 +70,7 @@ test('strikethrough button applies strike', async ({ superdoc }) => { await strikeButton.click(); await superdoc.waitForStable(); - await expect(strikeButton).toHaveClass(/active/); + await expect(strikeButton).toHaveClass(/sd-active/); await superdoc.snapshot('strikethrough applied'); await superdoc.assertTextHasMarks('is a sentence', ['strike']); @@ -92,7 +92,7 @@ test('font family dropdown changes font', async ({ superdoc }) => { await superdoc.waitForStable(); // Assert the toolbar displays "Georgia" - await expect(fontButton.locator('.button-label')).toHaveText('Georgia'); + await expect(fontButton.locator('.sd-button-label')).toHaveText('Georgia'); await superdoc.snapshot('Georgia font applied'); await superdoc.assertTextMarkAttrs('is a sentence', 'textStyle', { fontFamily: 'Georgia' }); @@ -132,7 +132,7 @@ test('color dropdown changes text color', async ({ superdoc }) => { await superdoc.snapshot('color dropdown open'); // Click the red color swatch (#D2003F) - const redSwatch = superdoc.page.locator('.option[aria-label="red"]').first(); + const redSwatch = superdoc.page.locator('.sd-option[aria-label="red"]').first(); await redSwatch.click(); await superdoc.waitForStable(); @@ -155,7 +155,7 @@ test('highlight dropdown changes background color', async ({ superdoc }) => { await superdoc.snapshot('highlight dropdown open'); // Click a highlight color swatch (#ECCF35) - const yellowSwatch = superdoc.page.locator('.option[aria-label="yellow"]').first(); + const yellowSwatch = superdoc.page.locator('.sd-option[aria-label="yellow"]').first(); await yellowSwatch.click(); await superdoc.waitForStable(); diff --git a/tests/behavior/tests/toolbar/composite-styles.spec.ts b/tests/behavior/tests/toolbar/composite-styles.spec.ts index 35a9397d72..63d8445bb3 100644 --- a/tests/behavior/tests/toolbar/composite-styles.spec.ts +++ b/tests/behavior/tests/toolbar/composite-styles.spec.ts @@ -28,7 +28,7 @@ async function selectDropdownOption(superdoc: SuperDocFixture, dataItem: string, async function selectColorSwatch(superdoc: SuperDocFixture, dataItem: string, label: string): Promise { await superdoc.page.locator(`[data-item="btn-${dataItem}"]`).click(); await superdoc.waitForStable(); - await superdoc.page.locator(`.option[aria-label="${label}"]`).first().click(); + await superdoc.page.locator(`.sd-option[aria-label="${label}"]`).first().click(); await superdoc.waitForStable(); } @@ -41,8 +41,8 @@ test('bold + italic', async ({ superdoc }) => { await clickToolbarButton(superdoc, 'bold'); await clickToolbarButton(superdoc, 'italic'); - await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/sd-active/); await superdoc.snapshot('bold + italic applied'); await superdoc.assertTextHasMarks('is a sentence', ['bold', 'italic']); @@ -55,8 +55,8 @@ test('bold + underline', async ({ superdoc }) => { await clickToolbarButton(superdoc, 'bold'); await clickToolbarButton(superdoc, 'underline'); - await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-underline"]')).toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-underline"]')).toHaveClass(/sd-active/); await superdoc.snapshot('bold + underline applied'); await superdoc.assertTextHasMarks('is a sentence', ['bold', 'underline']); @@ -69,8 +69,8 @@ test('italic + strikethrough', async ({ superdoc }) => { await clickToolbarButton(superdoc, 'italic'); await clickToolbarButton(superdoc, 'strike'); - await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-strike"]')).toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-strike"]')).toHaveClass(/sd-active/); await superdoc.snapshot('italic + strikethrough applied'); await superdoc.assertTextHasMarks('is a sentence', ['italic', 'strike']); @@ -87,10 +87,10 @@ test('bold + italic + underline + strikethrough', async ({ superdoc }) => { await clickToolbarButton(superdoc, 'underline'); await clickToolbarButton(superdoc, 'strike'); - await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-underline"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-strike"]')).toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-underline"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-strike"]')).toHaveClass(/sd-active/); await superdoc.snapshot('all four toggles applied'); await superdoc.assertTextHasMarks('is a sentence', ['bold', 'italic', 'underline', 'strike']); @@ -106,8 +106,8 @@ test('bold + font family + font size', async ({ superdoc }) => { await selectDropdownOption(superdoc, 'fontFamily', 'Georgia'); await selectDropdownOption(superdoc, 'fontSize', '24'); - await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .button-label')).toHaveText('Georgia'); + await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .sd-button-label')).toHaveText('Georgia'); await expect(superdoc.page.locator('#inlineTextInput-fontSize')).toHaveValue('24'); await superdoc.snapshot('bold + Georgia 24pt applied'); @@ -123,7 +123,7 @@ test('italic + color', async ({ superdoc }) => { await clickToolbarButton(superdoc, 'italic'); await selectColorSwatch(superdoc, 'color', 'red'); - await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/sd-active/); const colorBar = superdoc.page.locator('[data-item="btn-color"] .color-bar'); await expect(colorBar).toHaveCSS('background-color', 'rgb(210, 0, 63)'); await superdoc.snapshot('italic + red color applied'); @@ -142,7 +142,7 @@ test('font family + font size + color', async ({ superdoc }) => { await selectDropdownOption(superdoc, 'fontSize', '18'); await selectColorSwatch(superdoc, 'color', 'dark red'); - await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .button-label')).toHaveText('Georgia'); + await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .sd-button-label')).toHaveText('Georgia'); await expect(superdoc.page.locator('#inlineTextInput-fontSize')).toHaveValue('18'); const colorBar = superdoc.page.locator('[data-item="btn-color"] .color-bar'); await expect(colorBar).toHaveCSS('background-color', 'rgb(134, 0, 40)'); @@ -173,11 +173,11 @@ test('all styles combined', async ({ superdoc }) => { await selectColorSwatch(superdoc, 'highlight', 'yellow'); // Assert all toolbar button states - await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-underline"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-strike"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .button-label')).toHaveText('Courier New'); + await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-underline"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-strike"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .sd-button-label')).toHaveText('Courier New'); await expect(superdoc.page.locator('#inlineTextInput-fontSize')).toHaveValue('24'); const colorBar = superdoc.page.locator('[data-item="btn-color"] .color-bar'); await expect(colorBar).toHaveCSS('background-color', 'rgb(210, 0, 63)'); diff --git a/tests/behavior/tests/toolbar/link.spec.ts b/tests/behavior/tests/toolbar/link.spec.ts index d4ea8c695d..aef99cb455 100644 --- a/tests/behavior/tests/toolbar/link.spec.ts +++ b/tests/behavior/tests/toolbar/link.spec.ts @@ -140,7 +140,7 @@ test('link is not editable in viewing mode', async ({ superdoc }) => { // Link toolbar button should be disabled in viewing mode const linkButton = superdoc.page.locator('[data-item="btn-link"]'); - await expect(linkButton).toHaveClass(/disabled/); + await expect(linkButton).toHaveClass(/sd-disabled/); // Stub window.open so we can assert navigation without depending on popup handling await superdoc.page.evaluate(() => { diff --git a/tests/behavior/tests/toolbar/responsive-container-overflow.spec.ts b/tests/behavior/tests/toolbar/responsive-container-overflow.spec.ts index eb3bdc9a38..4a5d2b7603 100644 --- a/tests/behavior/tests/toolbar/responsive-container-overflow.spec.ts +++ b/tests/behavior/tests/toolbar/responsive-container-overflow.spec.ts @@ -37,7 +37,7 @@ test('toolbar buttons stay inside the container when it narrows (SD-2328)', asyn const container = document.getElementById('toolbar'); if (!container) return null; const containerRect = container.getBoundingClientRect(); - const items = Array.from(container.querySelectorAll('.button-group > .toolbar-item-ctn')); + const items = Array.from(container.querySelectorAll('.button-group > .sd-toolbar-item-ctn')); const overflowing = items .map((el) => { const rect = (el as HTMLElement).getBoundingClientRect(); diff --git a/tests/behavior/tests/toolbar/table-styles.spec.ts b/tests/behavior/tests/toolbar/table-styles.spec.ts index ba8f47af35..70c2997428 100644 --- a/tests/behavior/tests/toolbar/table-styles.spec.ts +++ b/tests/behavior/tests/toolbar/table-styles.spec.ts @@ -25,7 +25,7 @@ test('bold inside a table cell', async ({ superdoc }) => { await boldButton.click(); await superdoc.waitForStable(); - await expect(boldButton).toHaveClass(/active/); + await expect(boldButton).toHaveClass(/sd-active/); await superdoc.snapshot('bold applied in cell'); await superdoc.assertTextHasMarks('table text', ['bold']); @@ -46,12 +46,12 @@ test('multiple styles in one cell', async ({ superdoc }) => { // Open color dropdown and pick red await superdoc.page.locator('[data-item="btn-color"]').click(); await superdoc.waitForStable(); - await superdoc.page.locator('.option[aria-label="red"]').first().click(); + await superdoc.page.locator('.sd-option[aria-label="red"]').first().click(); await superdoc.waitForStable(); // Assert all toolbar states - await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/active/); - await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/active/); + await expect(superdoc.page.locator('[data-item="btn-bold"]')).toHaveClass(/sd-active/); + await expect(superdoc.page.locator('[data-item="btn-italic"]')).toHaveClass(/sd-active/); const colorBar = superdoc.page.locator('[data-item="btn-color"] .color-bar'); await expect(colorBar).toHaveCSS('background-color', 'rgb(210, 0, 63)'); await superdoc.snapshot('bold + italic + red color applied'); @@ -117,7 +117,7 @@ test('font family and size in a table cell', async ({ superdoc }) => { await superdoc.waitForStable(); // Assert toolbar - await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .button-label')).toHaveText('Georgia'); + await expect(superdoc.page.locator('[data-item="btn-fontFamily"] .sd-button-label')).toHaveText('Georgia'); await expect(superdoc.page.locator('#inlineTextInput-fontSize')).toHaveValue('24'); await superdoc.snapshot('Georgia 24pt applied in cell'); diff --git a/tests/behavior/tests/toolbar/undo-redo.spec.ts b/tests/behavior/tests/toolbar/undo-redo.spec.ts index d4d6b62fce..31dcea4bfd 100644 --- a/tests/behavior/tests/toolbar/undo-redo.spec.ts +++ b/tests/behavior/tests/toolbar/undo-redo.spec.ts @@ -13,11 +13,11 @@ async function clickBodySurface(page: Page) { async function expectToolbarButtonDisabledState(button: Locator, disabled: boolean) { if (disabled) { - await expect(button).toHaveClass(/disabled/); + await expect(button).toHaveClass(/sd-disabled/); return; } - await expect(button).not.toHaveClass(/disabled/); + await expect(button).not.toHaveClass(/sd-disabled/); } test('undo button removes last typed text', async ({ superdoc }) => {