fix: the ruler stays over the page beside the balloon strip

`.paper-scaler` reserves page plus strip and centres the pair, so a document
with margin balloons sits left of centre — the ruler, sized from the page
alone, centred over a narrower box and hung to the right of the page it
measures. It now reserves the same strip as `padding-right`.
This commit is contained in:
Steffen Becker committed 2026-09-06 19:07:24 +02:00
1 parent 4b1a03b121
commit 9b426832e1
3 files changed
+10 -5

No files matched your search

+4 -2
View File
@@ -304,8 +304,10 @@ Accept/reject and edit/resolve/remove happen in the balloon — `CommentCard.sve
- The strip is `REVIEW_MARGIN_CM` (gap + balloon) and is **only reserved when the document
has markup the margin shows** — a kind switched to the pane, or a mode that hides it,
leaves `.paper-scaler` exactly the page, centred as before.
`scaledCanvasWidth` (`Editor.svelte`) adds it; `scaledWidth` stays the page, which is
what the `Ruler` is sized from.
`scaledCanvasWidth` (`Editor.svelte`) adds it; `scaledWidth` stays the page. The `Ruler`
is sized from the page but reserves the strip as `padding-right`, or its own `margin:
auto` would centre it over a narrower box than `.paper-scaler` and it would hang right
of the page it measures.
- **The leader runs in the gap under the anchor's line** (`coordsAtPos(...).bottom`, not the
line's middle) and eases into the card's left edge at the anchor's own height where the
card reaches that far — so a balloon sitting at its line is joined by one straight line
+1 -1
View File
@@ -1590,7 +1590,7 @@ import { EMPTY_PAGE_DECOR, type PageDecor } from '../storage/pageDecor';
<!-- Hidden while a header/footer zone is active: those have no tab stops, so the
ruler would edit the body paragraph behind the user's back. -->
{#if showRuler && scaledWidth && !hfActive}
<Ruler {editor} {tick} zoom={appliedZoom} width={scaledWidth} margins={pageMargins} />
<Ruler {editor} {tick} zoom={appliedZoom} width={scaledWidth} margins={pageMargins} gutter={scaledCanvasWidth - scaledWidth} />
{/if}
<!-- Reserves the scaled scroll footprint; the transform on .paper reserves none.
Before the first measure (size 0) it's left unsized so .paper isn't clipped. -->
+5 -2
View File
@@ -6,12 +6,13 @@
// Horizontal ruler: the tab stops and indents of the block the cursor is in.
// Positions are cm from the left text margin, the attr's own origin.
let { editor, tick, zoom, width, margins }: {
let { editor, tick, zoom, width, margins, gutter = 0 }: {
editor: Editor | null;
tick: number;
zoom: number;
width: number; // the page's SCALED width in px (.paper-scaler's)
margins: PageMargins;
gutter?: number; // the balloon strip .paper-scaler reserves beside the page
} = $props();
const TYPES: TabAlign[] = ['left', 'center', 'right', 'decimal'];
@@ -110,7 +111,9 @@
const at = (t: Drag, stored: number) => (dragging(t) && preview != null ? preview : stored);
</script>
<div class="ruler" style="width: {width}px">
<!-- The strip beside the page is reserved here too, so the auto margins centre the
ruler over the same footprint as .paper-scaler and it stays above the page. -->
<div class="ruler" style="width: {width + gutter}px; padding-right: {gutter}px">
<button
class="tab-type"
onpointerdown={(e) => e.preventDefault()}