Skip to content

refactor(direction): add getTableVisualDirection helper, migrate consumers (SD-3138)#3279

Merged
caio-pizzol merged 1 commit into
mainfrom
caio-pizzol/SD-3138-table-direction-context
May 14, 2026
Merged

refactor(direction): add getTableVisualDirection helper, migrate consumers (SD-3138)#3279
caio-pizzol merged 1 commit into
mainfrom
caio-pizzol/SD-3138-table-direction-context

Conversation

@caio-pizzol
Copy link
Copy Markdown
Contributor

Phase 1A of SD-3138 (under SD-2771 Wave 3). Centralizes the read of table visual direction (w:bidiVisual, ECMA-376 §17.4.1) through one helper, mirroring the paragraph-axis pattern already established for getParagraphInlineDirection.

What lands

  • Add getTableVisualDirection(attrs) to @superdoc/contracts. Reads attrs.tableDirectionContext.visualDirection first (future-ready for when pm-adapter writes the resolved context onto TableAttrs), falls back to attrs.tableProperties.rightToLeft (or bidiVisual alias) for compatibility.
  • Migrate three consumers off raw tableProperties.rightToLeft reads:
    • layout-engine/src/layout-table.ts — table-frame X positioning
    • painters/dom/src/table/renderTableFragment.ts — visual mirror gate at paint
    • super-editor/.../tableBoundaryNavigation.js — RTL cursor navigation

Out of scope (separate phases)

  • pm-adapter wiring that populates TableAttrs.tableDirectionContext (Phase 1B — the helper is future-ready but the context isn't written yet, so the fallback path is exercised today).
  • packages/super-editor/.../TableResizeOverlay.vue reads a different shape (tableMetadata.value?.rtl); migration deferred to keep this PR scoped.

Why now

Before SD-3134 (PR #3272 merged) + #3273 (in review), several spots pre-mirrored for RTL. The fixes removed the worst offenders but the rule still relied on contributor memory. Centralizing the read via a helper makes the rule structural: there's one function to call, and future contributors who try to read tableProperties.rightToLeft directly will be visible to the grep checks shipped in #3278.

Verified

  • 14 new unit tests for getTableVisualDirection (precedence, alias, no signal, null fallback).
  • 174 painter table tests, 652 layout-engine tests, 189 super-editor table extension tests all pass.

Companion / sequencing

@caio-pizzol caio-pizzol requested a review from a team as a code owner May 14, 2026 10:04
@linear
Copy link
Copy Markdown

linear Bot commented May 14, 2026

SD-3138

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…umers (SD-3138)

Centralize the read of table visual direction (w:bidiVisual, ECMA-376
section 17.4.1) through one helper, mirroring the paragraph-axis pattern
already established for getParagraphInlineDirection.

- Add getTableVisualDirection(attrs) to @superdoc/contracts. Reads
  attrs.tableDirectionContext.visualDirection first (future-ready for
  when pm-adapter writes the resolved context onto TableAttrs), falls
  back to attrs.tableProperties.rightToLeft (or bidiVisual alias) for
  compatibility.
- Migrate three consumers off raw reads:
  - layout-engine/src/layout-table.ts (table-frame X positioning)
  - painters/dom/src/table/renderTableFragment.ts (visual mirror gate)
  - super-editor/.../tableBoundaryNavigation.js (RTL cursor nav)

Out of scope for this PR:
- pm-adapter wiring that populates TableAttrs.tableDirectionContext.
  Phase 1B - the helper is future-ready but the context isn't written
  yet, so the fallback path is exercised today.
- packages/super-editor/.../TableResizeOverlay.vue reads a different
  shape (tableMetadata.value.rtl); migration deferred to keep this PR
  scoped.

Companion to SD-3134 and PRs #3272/#3273/#3278; under SD-2771 Wave 3.

Tests:
- 14 unit tests for getTableVisualDirection (precedence, alias, no
  signal, null fallback).
- 174 painter table tests, 652 layout-engine tests, 189 super-editor
  table extension tests all pass.
@caio-pizzol caio-pizzol force-pushed the caio-pizzol/SD-3138-table-direction-context branch from 30f4220 to 6079ba2 Compare May 14, 2026 10:20
caio-pizzol added a commit that referenced this pull request May 14, 2026
…ection (SD-3141) (#3283)

resolveTableDirection previously emitted visualDirection only for the
explicit-true case, conflating "no signal" with "explicit false."

Per ECMA-376 section 17.4.1 + 17.17.4, w:bidiVisual w:val="0" is an
explicit-false that can override a style-cascade true. Cascade-override
semantics match paragraph w:bidi, which resolveParagraphDirection
already handles symmetrically. The table resolver had a gap.

Add the missing else-if branch so an explicit false emits
visualDirection: 'ltr'. The helper getTableVisualDirection added in
SD-3138 (PR #3279) already returned 'ltr' for the legacy fallback path;
this aligns the resolver with the helper so Phase 1B (pm-adapter wiring
of tableDirectionContext) does not silently regress the explicit-false
case from 'ltr' to undefined.

Tests:
- rightToLeft: false -> visualDirection: 'ltr'
- bidiVisual: false -> visualDirection: 'ltr'
- empty input -> visualDirection: undefined
- rtl wins when mixed signals present
- 24 existing direction tests still pass.
@caio-pizzol caio-pizzol merged commit 59de419 into main May 14, 2026
66 checks passed
@caio-pizzol caio-pizzol deleted the caio-pizzol/SD-3138-table-direction-context branch May 14, 2026 10:44
caio-pizzol added a commit that referenced this pull request May 14, 2026
…ter (SD-3138 Phase 1B)

Phase 1A (PR #3279) landed the getTableVisualDirection helper and
migrated three consumers. The helper preferred a resolved
TableDirectionContext but pm-adapter never wrote one - consumers fell
through to the legacy fallback path on every read.

Phase 1B closes the loop:

- Add tableDirectionContext?: TableDirectionContext to TableAttrs in
  @superdoc/contracts (mirrors directionContext on ParagraphAttrs from
  Wave 1a / SD-2776).
- In pm-adapter table.ts, resolve the effective table direction from
  cascade-resolved table properties (style cascade + inline override)
  and write the result via resolveTableDirection.

The cascade resolution uses style-engine's resolveTableProperties for
the style chain and `??` to layer inline on top. Because `??` treats
null/undefined as missing but preserves explicit false, inline
w:bidiVisual w:val="0" correctly overrides a style cascade true and
produces visualDirection: 'ltr' (relies on SD-3141 resolver symmetry).

After this lands, the helper's fast path is exercised at runtime:
- Inline true → 'rtl'
- Style cascade true → 'rtl'
- Inline false overriding style true → 'ltr'
- Absent signal → undefined

Tests:
- 4 new converter tests for the cascade scenarios above
- pm-adapter: 1836 tests pass
- painter table: 174 tests pass
caio-pizzol added a commit that referenced this pull request May 14, 2026
…ter (SD-3138 Phase 1B)

Phase 1A (PR #3279) landed the getTableVisualDirection helper and
migrated three consumers. The helper preferred a resolved
TableDirectionContext but pm-adapter never wrote one - consumers fell
through to the legacy fallback path on every read.

Phase 1B closes the loop:

- Add tableDirectionContext?: TableDirectionContext to TableAttrs in
  @superdoc/contracts (mirrors directionContext on ParagraphAttrs from
  Wave 1a / SD-2776).
- In pm-adapter table.ts, resolve the effective table direction from
  cascade-resolved table properties (style cascade + inline override)
  and write the result via resolveTableDirection.

The cascade resolution uses style-engine's resolveTableProperties for
the style chain and `??` to layer inline on top. Because `??` treats
null/undefined as missing but preserves explicit false, inline
w:bidiVisual w:val="0" correctly overrides a style cascade true and
produces visualDirection: 'ltr' (relies on SD-3141 resolver symmetry).

After this lands, the helper's fast path is exercised at runtime:
- Inline true → 'rtl'
- Style cascade true → 'rtl'
- Inline false overriding style true → 'ltr'
- Absent signal → undefined

Tests:
- 4 new converter tests for the cascade scenarios above
- pm-adapter: 1836 tests pass
- painter table: 174 tests pass
caio-pizzol added a commit that referenced this pull request May 14, 2026
…ter (SD-3138 Phase 1B) (#3285)

Phase 1A (PR #3279) landed the getTableVisualDirection helper and
migrated three consumers. The helper preferred a resolved
TableDirectionContext but pm-adapter never wrote one - consumers fell
through to the legacy fallback path on every read.

Phase 1B closes the loop:

- Add tableDirectionContext?: TableDirectionContext to TableAttrs in
  @superdoc/contracts (mirrors directionContext on ParagraphAttrs from
  Wave 1a / SD-2776).
- In pm-adapter table.ts, resolve the effective table direction from
  cascade-resolved table properties (style cascade + inline override)
  and write the result via resolveTableDirection.

The cascade resolution uses style-engine's resolveTableProperties for
the style chain and `??` to layer inline on top. Because `??` treats
null/undefined as missing but preserves explicit false, inline
w:bidiVisual w:val="0" correctly overrides a style cascade true and
produces visualDirection: 'ltr' (relies on SD-3141 resolver symmetry).

After this lands, the helper's fast path is exercised at runtime:
- Inline true → 'rtl'
- Style cascade true → 'rtl'
- Inline false overriding style true → 'ltr'
- Absent signal → undefined

Tests:
- 4 new converter tests for the cascade scenarios above
- pm-adapter: 1836 tests pass
- painter table: 174 tests pass
@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented May 14, 2026

🎉 This PR is included in vscode-ext v2.3.0-next.137

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented May 14, 2026

🎉 This PR is included in @superdoc-dev/react v1.2.0-next.135

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented May 14, 2026

🎉 This PR is included in @superdoc-dev/mcp v0.3.0-next.92

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented May 14, 2026

🎉 This PR is included in superdoc-cli v0.8.0-next.107

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented May 14, 2026

🎉 This PR is included in superdoc v1.30.0-next.88

The release is available on GitHub release

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.

2 participants