Skip to content

fix: support paragraph bar borders (w:pBdr/w:bar)#2742

Closed
Abdeltoto wants to merge 5 commits intosuperdoc-dev:mainfrom
Abdeltoto:fix/paragraph-bar-border
Closed

fix: support paragraph bar borders (w:pBdr/w:bar)#2742
Abdeltoto wants to merge 5 commits intosuperdoc-dev:mainfrom
Abdeltoto:fix/paragraph-bar-border

Conversation

@Abdeltoto
Copy link
Copy Markdown
Contributor

Summary

  • Add bar to ParagraphBorders type in contracts so it flows through the data model
  • Include bar in normalizeParagraphBorders() in the pm-adapter so the OOXML property is forwarded to the layout format
  • Render the bar border as a left-side vertical line in applyParagraphBorderStyles() in DomPainter
  • Include bar in the paragraph border hash for correct grouping comparisons

Files changed

  • Modified: contracts/src/index.tsbar?: ParagraphBorder on ParagraphBorders
  • Modified: pm-adapter/src/attributes/borders.tsbar in sides array
  • Modified: painters/dom/src/features/paragraph-borders/border-layer.ts — render bar as CSS left border
  • Modified: painters/dom/src/paragraph-hash-utils.ts — include bar in hash

Test plan

  • All existing border tests pass (81 between-border tests, 23 hash tests)
  • Pre-commit hooks pass (format + lint + commitlint)
  • Test with a .docx file containing w:pBdr/w:bar elements

Closes #2282

Add bar to ParagraphBorders type in contracts, include it in
normalizeParagraphBorders so it flows through the pm-adapter,
render it as a left-side vertical line in DomPainter, and
include it in the paragraph border hash for grouping parity.

Closes superdoc-dev#2282

Made-with: Cursor
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 974ecf97af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +219 to +220
if (borders.bar && borders.bar.style !== 'none') {
setBorderSideStyle(element, 'left', borders.bar);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Include bar border in left-side geometry calculations

Applying borders.bar directly to border-left here introduces a rendering mismatch: the layer box is still expanded from borders.left only (computeBorderSpaceExpansion and computeRenderedBorderWidths), so bar.width/bar.space are not reserved. In paragraphs with only w:bar (or with a wider bar than left), the new bar border is drawn into the content box and can overlap text instead of being offset outward like other paragraph borders.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch — fixed in f0162e0. Added a getEffectiveLeftBorder helper and used it in computeBorderSpaceExpansion, computeRenderedBorderWidths and applyParagraphBorderStyles so the layout and paint paths agree on which border occupies the left slot. Bar-only and wider-than-left cases now reserve the right amount of room.

@caio-pizzol caio-pizzol self-assigned this Apr 9, 2026
The bar border (OOXML 17.3.1.4) is rendered on the CSS border-left slot
when present, overriding w:left. But computeBorderSpaceExpansion and
computeRenderedBorderWidths only inspected borders.left, so the layer
box was sized without reserving room for bar.width / bar.space.

Result: paragraphs with only w:bar (or with a wider bar than left) had
the bar drawn into the content box, overlapping text.

Introduced a small getEffectiveLeftBorder helper and used it in all three
sites (geometry helpers + applyParagraphBorderStyles), so layout and
paint stay in sync on which border occupies the left slot.

Closes the Codex P1 finding on the PR.

Made-with: Cursor
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

caio-pizzol and others added 3 commits April 18, 2026 13:36
Word ignores w:bar in every observed configuration, and ECMA-376
§17.3.1.4 explicitly permits ignoring the element. Rendering it on the
CSS border-left slot created two regressions vs Word:

1. When a paragraph has both w:left and w:bar (e.g. the spec example
   in §17.3.1.4), the original w:left border became invisible because
   bar overrode it on the same slot. Word keeps w:left.
2. Including bar in the painter-dom grouping hash broke between-border
   grouping for consecutive paragraphs that differed only in w:bar.
   Word groups such paragraphs normally.

This keeps the useful part of the original change — bar flows through
the contract and the pm-adapter normalize step for round-trip fidelity —
and drops the rendering. Removes getEffectiveLeftBorder and the bar
entry in hashParagraphBorders.

Adds tests pinning the new behaviour: bar normalizes alongside other
sides, bar is excluded from the grouping hash, and two paragraphs that
differ only in bar hash identically so they still group.
Adds 3 tests to between-borders.test.ts asserting that
applyParagraphBorderStyles:
- does not set border-left when only w:bar is set
- keeps w:left intact when both w:left and w:bar are present
- does not affect top/right/bottom when bar is set

Guards against a future refactor accidentally reintroducing
bar-on-the-left-slot rendering, which would diverge from Word's output.
@caio-pizzol caio-pizzol enabled auto-merge April 18, 2026 16:51
@caio-pizzol
Copy link
Copy Markdown
Contributor

@Abdeltoto thanks for digging in.

Tested in Word: w:bar is never drawn on screen, only kept in the
file on save. The spec allows ignoring it, and Word does. Drawing
it would make SuperDoc differ from Word on every doc that uses it.

The save-loss concern in #2282 wasn't real either — our converter
already keeps w:bar.

Closing — the issue itself was a wrong assumption, not your code.
Reasoning on main in 8b1da54. Thanks for the care.

auto-merge was automatically disabled April 18, 2026 17:28

Pull request was closed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support paragraph bar borders (w:pBdr/w:bar)

3 participants