feat(text): chevron expand + Monaco diff for long text/longtext cells#208
Merged
debba merged 5 commits intoMay 18, 2026
Merged
Conversation
Mirrors the JSON cell affordance from PR TabularisDB#181 for plain string columns whose value is long enough to be cumbersome in the inline grid cell. Closes TabularisDB#207. - isLongTextCellTarget — text-like column + value > 80 chars or contains a newline. JSON / BLOB / geometry / date paths stay untouched. - TextCell renders a single-line preview with a chevron (multi-line values get a ⏎ substitution). No separate viewer window — chevron is the only entry point per design discussion. - TextExpansionEditor opens inline below the row: Monaco in plaintext mode with a manual Diff toggle (default off) against the original. - FieldEditor swaps the plain textarea for Monaco-based TextInput when the sidebar value is long, so the diff toggle is available there too. - Width-aware Side-by-side toggle (Columns2) appears next to the Diff button whenever the editor's container is ≥ 480px. Below that the unified diff is the only mode, so the button doesn't promise a layout that won't fit. Same gating applied uniformly to JSON. - Json/Text Monaco wrappers are unified into a single CellCodeEditor / CellDiffEditor pair that takes a language prop, replacing the four per-language wrappers.
Long-standing Monaco bug: the read-only original editor in a
side-by-side DiffEditor refuses to wrap long lines no matter how
wordWrap or diffWordWrap is set on the diff editor or via
updateOptions on the inner editors. Fixes here:
- useInlineViewWhenSpaceIsLimited: false — Monaco's inline-fallback
code path poisons the original pane's wrap state even when the
fallback isn't actually being used (Monaco discussions #4454, #4701).
- key={renderSideBySide ? "sbs" : "inline"} — toggling renderSideBySide
at runtime can leave the original pane's wrap unrecoverable (issue
#3346). React-key remounting sidesteps it by forcing a clean Monaco
instance per mode.
- diffWordWrap: "on" — explicitly inherit wrap into the diff layer.
- Drop originalEditable: false and apply readOnly per-editor via
updateOptions, which Monaco respects without breaking layout.
The fixed 384px (w-96) width left no room for the new Monaco-based text input, especially with the side-by-side diff toggle. Adds a 4px drag handle on the left edge of RowEditorSidebar driven by a new useRowEditorResize hook: width is clamped to [320px, 90% of viewport] and persisted to localStorage. Default stays 384px so nothing changes for users who don't drag.
…ting Adds a focused seed alongside json_demo for the long-text chevron + Monaco diff feature. Nine rows, each targeting a specific edge case: short / long single-line / multi-line short / markdown article / code snippet / multi-line SQL / long VARCHAR(500) / all-NULL / unicode. MySQL relies on its default \\n-in-string handling; Postgres uses E'...' escape-string syntax for the multi-line bodies.
The mysql client used by docker-entrypoint-initdb.d does not default to utf8mb4 in MySQL 8's official image; emoji and CJK literals in the JSON / blog seeds were double-encoded on insert, so drivers that honor utf8mb4 read back mojibake even though the columns themselves are utf8mb4. Adding SET NAMES utf8mb4 at the top of each seed makes the insert path round-trip cleanly. Requires a fresh volume (docker compose down -v) to take effect.
e1e07ed to
e4cd824
Compare
Collaborator
|
LGTM. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends the chevron-expand + Monaco diff affordance (PR #181) from JSON/JSONB cells to plain string columns whose value is long enough to be cumbersome inline. Closes #207.
isLongTextCellTarget: text-like column AND value > 80 chars or contains a newline. Scoped so JSON / BLOB / geometry / date paths are untouched.TextCellrenders a single-line preview with a chevron (multi-line values get a⏎substitution). Per request, no separate viewer window for text — the chevron is the only entry point.TextExpansionEditoropens inline below the row: Monaco inplaintextmode with a manual Diff toggle (default off) against the original cell value.FieldEditorswaps the plain textarea for a Monaco-basedTextInputwhen the value is long, giving the sidebar a diff toggle too.Files
src/utils/text.ts,tests/utils/text.test.tsTextCell,TextCodeEditor,TextDiffEditor,TextExpansionEditor,TextInputDataGrid.tsx(expansion state generalised with akinddiscriminator; JSON path unchanged),FieldEditor.tsx,JsonInput.tsx,JsonExpansionEditor.tsx(side-by-side toggle),i18n/locales/en.jsondemo/init/{mysql,postgres}/04-text-demo.sql—tabularis_demo.text_demo, 9 rows covering every edge case belowTest setup
Then open the
tabularis_demodatabase (MySQL or Postgres) and browse thetext_demotable.Test plan
Automated:
pnpm typecheckpnpm lintpnpm test tests/utils/text.test.ts(15/15)pnpm buildManual — DataGrid chevron + inline expansion, by row in
text_demo:short): no chevron on any column — values stay in the inline textarea editor on double-click.long single-line):bodyshows a chevron; preview is single-line; expand → plain Monaco editor, no⏎symbol.multi-line short): chevron triggers via newline branch even though length < 80; preview shows⏎separators.markdown article): expandbody, edit a heading, toggle Diff on → modified lines highlighted; toggle Side-by-side → two-pane view; cancel restores original.code snippet): expandbody, change indentation on one line, Diff toggle shows whitespace-aware hunks.SQL query): expandbody, edit a clause, save → row gets the pending-change indicator; refresh confirms persistence.long varchar): chevron fires on thesummaryVARCHAR(500) column, not just on TEXT.all null): no chevron anywhere; null cells render the regularNULLplaceholder.unicode + emoji): Monaco renders multi-script + emoji glyphs correctly in editor, Diff, and Side-by-side.Manual — RowEditorSidebar (open via context menu → "Open Sidebar Editor"):
bodyon rows 2/4/5/6/9,summaryon row 7) render the Monaco-basedTextInputwith the Diff / Side-by-side toggles.labeleverywhere,summaryon row 1) keep the plain textarea.Regressions:
tabularis_demo.json_demo) still get the chevron, the open-viewer window button, and the same JSON tokenizer — unchanged frommain.