feat(words): visible dotted band in the grip rail + trim to 1rem

Two complaints from the user on the rail:
1. Still too wide at 1.5rem (~24px).
2. The band doesn't visually distinguish itself from the canvas
   so the grip + "+" look detached.

Fixes:

- **Rail trimmed to 1rem (~16px)** — combined with content-px gives
  a 32px total padding on the rail side. The 28×28 grip lands
  at content.left+0 → +28 with a 4px gap before the text. This is
  the minimum band width that still keeps the grip fully inside
  the editor's visible content area.

- **Dotted pattern on the band** — `[data-words-content]::before`
  fills the rail's padding zone (32px wide, full height) with a
  radial-gradient dot pattern at 8×8 px tiles. Color is
  `status-color @ 40% opacity` so the dots read as a "this is a
  gutter" cue without competing with content. `pointer-events:
  none` and `z-index: 0` so they don't interfere with selection
  or caret.

- **Flips with drawer side** — when `<Words.Drawer side='left'>`
  the pseudo's inset moves to inline-end so the dotted band tracks
  the rail to the right side.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
active-uix
dev 4 months ago
parent 0edb7be26c
commit 33b3a580b7

@ -6,10 +6,11 @@
--_words-content-min-block-size: var(--words-content-min-block-size-md); --_words-content-min-block-size: var(--words-content-min-block-size-md);
/* Gutter reserved for the block-handle grip + inserter "+" overlay. /* Gutter reserved for the block-handle grip + inserter "+" overlay.
Content is padded by this much on the side OPPOSITE to the drawer Content is padded by this much on the side OPPOSITE to the drawer
so the floating overlays have a visible band to land in. 1.5rem so the floating overlays have a visible band to land in. 1rem
(≈24px) added to the existing content-px (16px) gives ~40px total (≈16px) is the minimum: combined with the existing content-px
on that side — just enough for a 28×28 hit area, no waste. */ (16px) it gives a 32px band — wide enough for the 28px grip to
--_words-rail-px: 1.5rem; start at the editor edge and leave 4px before the text. */
--_words-rail-px: 1rem;
--_words-toolbar-px: var(--words-toolbar-px-md); --_words-toolbar-px: var(--words-toolbar-px-md);
--_words-toolbar-py: var(--words-toolbar-py-md); --_words-toolbar-py: var(--words-toolbar-py-md);
--_words-button-size: var(--words-button-size-md); --_words-button-size: var(--words-button-size-md);
@ -1778,6 +1779,7 @@
} }
[data-words-content] { [data-words-content] {
position: relative;
min-block-size: var(--_words-content-min-block-size); min-block-size: var(--_words-content-min-block-size);
padding-block: var(--_words-content-py); padding-block: var(--_words-content-py);
/* Default (drawer on right): rail on the LEFT for the grip + "+". */ /* Default (drawer on right): rail on the LEFT for the grip + "+". */
@ -1792,6 +1794,34 @@
-webkit-user-select: text; -webkit-user-select: text;
} }
/* Dotted band — fills the rail's padding zone so the user reads it as
a dedicated gutter (where grip + "+" overlays live) instead of empty
content padding. Pointer-events disabled so it doesn't intercept
clicks/selection. Pseudo-elements on a contenteditable don't affect
text selection or caret in modern browsers. */
[data-words-content]::before {
content: '';
position: absolute;
inset-block: 0;
inset-inline-start: 0;
inline-size: calc(var(--_words-rail-px) + var(--_words-content-px));
background-image: radial-gradient(
circle 1px,
color-mix(in srgb, var(--words-status-color) 40%, transparent) 99%,
transparent 100%
);
background-size: 8px 8px;
background-position: 50% 50%;
background-repeat: repeat;
pointer-events: none;
z-index: 0;
}
[data-words]:has([data-words-drawer][data-side='left']) > [data-words-content]::before {
inset-inline-start: auto;
inset-inline-end: 0;
}
/* When the drawer lives on the LEFT, mirror: rail moves to the RIGHT /* When the drawer lives on the LEFT, mirror: rail moves to the RIGHT
so the grip + "+" don't fight the drawer's gutter. */ so the grip + "+" don't fight the drawer's gutter. */
[data-words]:has([data-words-drawer][data-side='left']) > [data-words-content], [data-words]:has([data-words-drawer][data-side='left']) > [data-words-content],

Loading…
Cancel
Save

Powered by TurnKey Linux.