From 8b8885d0b75442154627d77dd6e65cf362fff727 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 21 Jun 2026 06:19:29 +0000 Subject: [PATCH] fix(cuesheet): align lazy cell placeholder with its editor Two regressions from the lazy text-cell placeholders: - single-line placeholders centered their text in the full (possibly tall) cell, so the text jumped upward when the top-aligned editor mounted. Keep the glyph in a 2rem band at the top (scoped to editable cells via a `topAligned` prop so the time/duration delay indicator is unaffected). - multi-line placeholders only grew to their content height, so a short note in a row made tall by another column was not fully clickable. Use `min-height: 100%` so the placeholder fills the cell (and still grows with content, no clipping). Verified by measuring text/editor positions: single-line jump ~0px; all text placeholders fill the cell and the whole area is clickable. Cuesheet e2e (4/4). --- .../cuesheet-table-elements/EditableCell.tsx | 1 + .../TextLikeInput.module.scss | 9 ++++++++- .../cuesheet-table-elements/TextLikeInput.tsx | 14 +++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EditableCell.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EditableCell.tsx index 9eccf566c..9ca9ce21a 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EditableCell.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EditableCell.tsx @@ -69,6 +69,7 @@ function EditableCell({ initialValue, multiline, fieldId, fieldLabel, handleUpda onClick={enterEdit} onFocus={enterEdit} multiline={multiline} + topAligned aria-label={fieldLabel ? `${fieldLabel} cell` : undefined} > {initialValue} diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.module.scss b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.module.scss index 7287229a9..68ec5ec18 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.module.scss +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.module.scss @@ -35,9 +35,16 @@ cursor: text; } + // single-line placeholder: keep the glyph in a 2rem band at the top of the cell so it lines up + // with the editor (which mounts top-aligned) and does not jump when the cell is taller than 2rem + &.topAligned:not(.multiline) { + align-items: flex-start; + line-height: 2rem; + } + &.multiline { height: auto; - min-height: 2rem; + min-height: 100%; // fill the cell so the whole area is clickable (grows with content) text-wrap: wrap; white-space: break-spaces; overflow: hidden; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.tsx index 73e33bae0..08877ae10 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.tsx @@ -9,11 +9,22 @@ interface TextLikeInputProps extends HTMLAttributes { muted?: boolean; disabled?: boolean; multiline?: boolean; + /** keep the content at the top of the cell (matches an editor that mounts top-aligned) */ + topAligned?: boolean; } const TextLikeInput = forwardRef( ( - { offset, muted, disabled, multiline, children, className, ...elementProps }: PropsWithChildren, + { + offset, + muted, + disabled, + multiline, + topAligned, + children, + className, + ...elementProps + }: PropsWithChildren, textRef, ) => { const ref = useRef(null); @@ -23,6 +34,7 @@ const TextLikeInput = forwardRef( muted && style.muted, disabled && style.disabled, multiline && style.multiline, + topAligned && style.topAligned, className, ]);