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
9 changes: 9 additions & 0 deletions packages/layout-engine/painters/dom/src/styles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ describe('ensureSdtContainerStyles', () => {
);
expect(cssText).toContain('background: none;');
});

it('keeps hidden-appearance inline SDTs transparent at rest', () => {
ensureSdtContainerStyles(document);
const styleEl = document.querySelector('[data-superdoc-sdt-container-styles="true"]');
const cssText = styleEl?.textContent ?? '';

expect(cssText).toContain(".superdoc-structured-content-inline[data-appearance='hidden'] {");
expect(cssText).toContain('background-color: transparent;');
});
});

describe('ensureTrackChangeStyles', () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/layout-engine/painters/dom/src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ const SDT_CONTAINER_STYLES = `
box-sizing: border-box;
border-radius: 4px;
border: 1px solid transparent;
background-color: var(--sd-content-controls-block-bg, transparent);
position: relative;
}

Expand Down Expand Up @@ -596,6 +597,7 @@ const SDT_CONTAINER_STYLES = `
box-sizing: border-box;
border-radius: 4px;
border: 1px solid transparent;
background-color: var(--sd-content-controls-inline-bg, transparent);
position: relative;
display: inline;
font-size: initial;
Expand Down Expand Up @@ -651,6 +653,7 @@ const SDT_CONTAINER_STYLES = `
padding: 0;
border: none;
border-radius: 0;
background-color: transparent;
}
.superdoc-structured-content-inline[data-appearance='hidden']:hover {
background-color: transparent;
Expand Down
24 changes: 18 additions & 6 deletions packages/template-builder/src/styles/field-types.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@
.superdoc-structured-content-block.superdoc-structured-content-block {
border-color: var(--superdoc-field-owner-color, #629be7);
--sd-content-controls-inline-border: var(--superdoc-field-owner-color, #629be7);
--sd-content-controls-inline-bg: color-mix(in srgb, var(--superdoc-field-owner-color, #629be7) 8%, transparent);
--sd-content-controls-inline-hover-border: var(--superdoc-field-owner-color, #629be7);
--sd-content-controls-inline-hover-bg: color-mix(in srgb, var(--superdoc-field-owner-color, #629be7) 8%, transparent);
--sd-content-controls-inline-hover-bg: color-mix(
in srgb,
var(--superdoc-field-owner-color, #629be7) 12%,
transparent
);
--sd-content-controls-block-border: var(--superdoc-field-owner-color, #629be7);
--sd-content-controls-block-bg: color-mix(in srgb, var(--superdoc-field-owner-color, #629be7) 8%, transparent);
--sd-content-controls-block-hover-border: var(--superdoc-field-owner-color, #629be7);
--sd-content-controls-block-hover-bg: color-mix(in srgb, var(--superdoc-field-owner-color, #629be7) 8%, transparent);
--sd-content-controls-lock-hover-bg: color-mix(in srgb, var(--superdoc-field-owner-color, #629be7) 8%, transparent);
--sd-content-controls-block-hover-bg: color-mix(in srgb, var(--superdoc-field-owner-color, #629be7) 12%, transparent);
--sd-content-controls-lock-hover-bg: color-mix(in srgb, var(--superdoc-field-owner-color, #629be7) 12%, transparent);
--sd-content-controls-label-border: var(--superdoc-field-owner-color, #629be7);
--sd-content-controls-label-bg: color-mix(in srgb, var(--superdoc-field-owner-color, #629be7) 87%, transparent);
}
Expand All @@ -26,16 +32,22 @@
.superdoc-structured-content-block[data-sdt-tag*='"fieldType":"signer"'] {
border-color: var(--superdoc-field-signer-color, #d97706);
--sd-content-controls-inline-border: var(--superdoc-field-signer-color, #d97706);
--sd-content-controls-inline-bg: color-mix(in srgb, var(--superdoc-field-signer-color, #d97706) 8%, transparent);
--sd-content-controls-inline-hover-border: var(--superdoc-field-signer-color, #d97706);
--sd-content-controls-inline-hover-bg: color-mix(
in srgb,
var(--superdoc-field-signer-color, #d97706) 8%,
var(--superdoc-field-signer-color, #d97706) 12%,
transparent
);
--sd-content-controls-block-border: var(--superdoc-field-signer-color, #d97706);
--sd-content-controls-block-bg: color-mix(in srgb, var(--superdoc-field-signer-color, #d97706) 8%, transparent);
--sd-content-controls-block-hover-border: var(--superdoc-field-signer-color, #d97706);
--sd-content-controls-block-hover-bg: color-mix(in srgb, var(--superdoc-field-signer-color, #d97706) 8%, transparent);
--sd-content-controls-lock-hover-bg: color-mix(in srgb, var(--superdoc-field-signer-color, #d97706) 8%, transparent);
--sd-content-controls-block-hover-bg: color-mix(
in srgb,
var(--superdoc-field-signer-color, #d97706) 12%,
transparent
);
--sd-content-controls-lock-hover-bg: color-mix(in srgb, var(--superdoc-field-signer-color, #d97706) 12%, transparent);
--sd-content-controls-label-border: var(--superdoc-field-signer-color, #d97706);
--sd-content-controls-label-bg: color-mix(in srgb, var(--superdoc-field-signer-color, #d97706) 87%, transparent);
}
Expand Down
13 changes: 11 additions & 2 deletions packages/template-builder/src/tests/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,18 @@ describe('generateFieldColorCSS', () => {
const css = generateFieldColorCSS({ signer: '#d97706' }, '.scope');

expect(css).toContain('--sd-content-controls-block-border: #d97706;');
expect(css).toContain('--sd-content-controls-block-bg: color-mix(in srgb, #d97706 8%, transparent);');
expect(css).toContain('--sd-content-controls-block-hover-border: #d97706;');
expect(css).toContain('--sd-content-controls-block-hover-bg: color-mix(in srgb, #d97706 8%, transparent);');
expect(css).toContain('--sd-content-controls-lock-hover-bg: color-mix(in srgb, #d97706 8%, transparent);');
expect(css).toContain('--sd-content-controls-block-hover-bg: color-mix(in srgb, #d97706 12%, transparent);');
expect(css).toContain('--sd-content-controls-inline-bg: color-mix(in srgb, #d97706 8%, transparent);');
expect(css).toContain('--sd-content-controls-lock-hover-bg: color-mix(in srgb, #d97706 12%, transparent);');
});

it('sets resting background variables for owner default rules', () => {
const css = generateFieldColorCSS({ owner: '#629be7' }, '.scope');

expect(css).toContain('--sd-content-controls-inline-bg: color-mix(in srgb, #629be7 8%, transparent);');
expect(css).toContain('--sd-content-controls-block-bg: color-mix(in srgb, #629be7 8%, transparent);');
});

it('keeps label text color configurable through the content control token', () => {
Expand Down
7 changes: 6 additions & 1 deletion packages/template-builder/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
};

export const getPresentationEditor = (superdoc: SuperDoc | null) => {
const docs = (superdoc as any)?.superdocStore?.documents;

Check warning on line 59 in packages/template-builder/src/utils.ts

View workflow job for this annotation

GitHub Actions / CI Template Builder / validate

Unexpected any. Specify a different type
if (!Array.isArray(docs) || docs.length === 0) return null;
return docs[0].getPresentationEditor?.() ?? null;
};
Expand Down Expand Up @@ -87,17 +87,22 @@
const LEGACY_BLOCK_LABEL = '.superdoc-structured-content__label';

function buildColorRules(scope: string, selector: string, color: string): string {
const hoverFill = `color-mix(in srgb, ${color} 8%, transparent)`;
// Keep base/hover fills separate so we can tune resting vs hover opacity independently later.
// SD-2533: resting uses 8%, hover uses 12% for a slightly stronger interaction cue.
const baseFill = `color-mix(in srgb, ${color} 8%, transparent)`;
const hoverFill = `color-mix(in srgb, ${color} 12%, transparent)`;
const labelFill = `color-mix(in srgb, ${color} 87%, transparent)`;

return `
${scope} ${SDT_INLINE}${selector},
${scope} ${SDT_BLOCK}${selector} {
border-color: ${color};
--sd-content-controls-inline-border: ${color};
--sd-content-controls-inline-bg: ${baseFill};
--sd-content-controls-inline-hover-border: ${color};
--sd-content-controls-inline-hover-bg: ${hoverFill};
--sd-content-controls-block-border: ${color};
--sd-content-controls-block-bg: ${baseFill};
--sd-content-controls-block-hover-border: ${color};
--sd-content-controls-block-hover-bg: ${hoverFill};
--sd-content-controls-lock-hover-bg: ${hoverFill};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,38 @@ test('inline and block structured content field chrome use Template Builder fiel
const getBlock = (fieldType: 'owner' | 'signer') =>
renderedPage.locator(`.superdoc-structured-content-block[data-sdt-tag*='"fieldType":"${fieldType}"']`).first();

const expectRestingBackgrounds = async (fieldType: 'owner' | 'signer') => {
const inline = getInline(fieldType);
const block = getBlock(fieldType);

await inline.evaluate((el) => el.classList.remove('ProseMirror-selectednode'));
await block.evaluate((el) => {
el.classList.remove('ProseMirror-selectednode');
el.classList.remove('sdt-group-hover');
});

const inlineBackground = await inline.evaluate((el) => getComputedStyle(el).backgroundColor);
const blockBackground = await block.evaluate((el) => getComputedStyle(el).backgroundColor);

expect(inlineBackground).toBe(blockBackground);
Comment thread
artem-harbour marked this conversation as resolved.
expect(inlineBackground).not.toBe('rgba(0, 0, 0, 0)');
};

const expectSelectedStateBackgrounds = async (fieldType: 'owner' | 'signer') => {
const inline = getInline(fieldType);
const block = getBlock(fieldType);

await inline.evaluate((el) => el.classList.add('ProseMirror-selectednode'));
await block.evaluate((el) => {
el.classList.remove('sdt-group-hover');
el.classList.add('ProseMirror-selectednode');
});

await expect(inline).toHaveCSS('background-color', 'rgba(0, 0, 0, 0)');
const blockSelectedBackground = await block.evaluate((el) => getComputedStyle(el).backgroundColor);
expect(blockSelectedBackground).not.toBe('rgba(0, 0, 0, 0)');
};

const showInlineLabel = async (fieldType: 'owner' | 'signer') => {
const inline = getInline(fieldType);
await inline.evaluate((el) => el.classList.add('ProseMirror-selectednode'));
Expand Down Expand Up @@ -132,7 +164,9 @@ test('inline and block structured content field chrome use Template Builder fiel
const signerBlockLabel = signerBlock.locator('.superdoc-structured-content-block__label');
await expect(signerBlockLabel).toHaveCSS('color', 'rgb(255, 255, 0)');
await expect(signerBlockLabel).toHaveCSS('border-color', 'rgb(220, 38, 38)');
await expectRestingBackgrounds('signer');
await expectHoverBackgroundParity('signer');
await expectSelectedStateBackgrounds('signer');

const ownerInline = await showInlineLabel('owner');
await expect(ownerInline).toBeVisible();
Expand All @@ -149,7 +183,17 @@ test('inline and block structured content field chrome use Template Builder fiel
const ownerBlockLabel = ownerBlock.locator('.superdoc-structured-content-block__label');
await expect(ownerBlockLabel).toHaveCSS('color', 'rgb(255, 255, 0)');
await expect(ownerBlockLabel).toHaveCSS('border-color', 'rgb(37, 99, 235)');
await expectRestingBackgrounds('owner');
await expectHoverBackgroundParity('owner');
await expectSelectedStateBackgrounds('owner');

for (const fieldType of ['signer', 'owner'] as const) {
await getInline(fieldType).evaluate((el) => el.classList.remove('ProseMirror-selectednode'));
await getBlock(fieldType).evaluate((el) => {
el.classList.remove('ProseMirror-selectednode');
el.classList.remove('sdt-group-hover');
});
}

await superdoc.screenshot('template-builder-owner-and-signer-inline-and-block-field-styling');
});
Loading