Repository navigation
mo.ui.matrix: type-to-edit cells and modifier-key scrubbing - #10520
Conversation
Double-click a cell, press Enter, or start typing to edit its value as text, so exact values like 2.32e7 can be entered directly. Typed values are clamped to bounds but not snapped to step. Hold shift while dragging or pressing arrow keys for 10x coarser steps, alt/option for 10x finer steps; PageUp/PageDown also step by 10x. Frontend-only; the Python API is unchanged.
…t updates withCellValue is now the single chokepoint for bounds enforcement: in symmetric mode the shared value is clamped to the intersection of both cells' ranges, and it returns null when the clamped value is already in place so no edit path emits setValue with an identical matrix (previously every pointermove past a transpose-capped bound fired a redundant kernel update). Also removes a stray numpy entry from marimo's core dependencies, and adds tests for the redundant-update guard, debounced drags, the double-commit guard, and schema rejection of invalid payloads. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
All contributors have signed the CLA ✍️ ✅ |
for more information, see https://pre-commit.ci
Coverage Report for ./frontend
File Coverage
|
||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
cleanFloat's noise tolerance was floored at ~2.2e-14 regardless of step size, so steps below that threshold were silently snapped to zero. Scale the tolerance with max(|x|, |step|) instead: legitimately tiny results survive, while noise from arithmetic on ordinary magnitudes (e.g. the 5.55e-17 residue of 0.3 - 3 * 0.1) still rounds away. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR enhances mo.ui.matrix’s frontend interaction model by adding an inline “type-to-edit” mode for exact numeric entry, improving modifier-key scrubbing behavior for drag/keyboard adjustments, and tightening symmetric-mode bounds enforcement so mirrored cells always respect both cells’ constraints.
Changes:
- Added an inline cell editor (double-click / Enter / F2 / type-to-edit) that commits on Enter/blur, cancels on Escape, and clamps to bounds without snapping to
step. - Implemented modifier-key scrubbing (shift=coarse, alt= fine, PageUp/PageDown coarse) with mid-drag modifier rebasing to avoid value jumps.
- Centralized mutation via
withCellValueand fixed symmetric-mode bounds clamping to the intersection of transpose-cell ranges; added extensive frontend test coverage.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| marimo/_plugins/ui/_impl/matrix.py | Updates mo.ui.matrix docstring to describe new editor + modifier scrubbing behavior. |
| frontend/src/plugins/impl/MatrixPlugin.tsx | Implements inline editing, modifier scrubbing, float-noise cleanup, and symmetric bounds enforcement via a shared mutation helper. |
| frontend/src/plugins/impl/tests/MatrixPlugin.test.tsx | Adds comprehensive tests for editing lifecycle, clamping, debounce behavior, symmetric intersection clamping, and modifier scrubbing. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
pointerdown's preventDefault (needed for drag-scrubbing) also suppressed the browser's click-to-focus, so keyboard stepping was only reachable via Tab or by opening and closing the cell editor. Focus the cell explicitly on pointerdown. ArrowRight/ArrowLeft now step the value alongside ArrowUp/ArrowDown with the same modifier scaling, matching the horizontal drag direction and the native slider convention. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
for more information, see https://pre-commit.ci
…eam#10520) **This pull request was authored by a coding agent.** ## Summary Two interaction upgrades for `mo.ui.matrix`, plus a correctness fix for symmetric matrices with per-cell bounds. ### Type-to-edit cells - Double-click a cell (or press Enter/F2 while focused, or just start typing a digit/sign) to open an inline editor prefilled with the exact value. - Enter or blur commits; Escape cancels; invalid input is discarded. - Typed values are clamped to bounds but **not** snapped to `step`, so exact values like `2.32e7` survive the round trip. - A ref-mirrored editing state prevents the blur fired during commit-refocus from committing twice. ### Modifier-key scrubbing - Shift+drag (or shift+arrow) steps 10× coarser; alt/option 10× finer; PageUp/PageDown step 10×. - Toggling a modifier mid-drag rebases the drag origin so the value rescales future movement instead of jumping. - Clicking a cell focuses it, so keyboard stepping works immediately; ArrowRight/ArrowLeft step alongside ArrowUp/ArrowDown (matching the horizontal drag direction and native slider convention). ### Symmetric bounds fix `withCellValue` is now the single mutation chokepoint for bounds enforcement. In symmetric mode the shared value is clamped to the **intersection** of both cells' ranges — previously the mirrored cell received a value clamped only to the edited cell's bounds, so editing `[0][1]` could push `[1][0]` outside its own range. It also returns `null` when the clamped value is already in place, so no edit path emits `setValue` with an identical matrix. Also updates the `mo.ui.matrix` docstring. ## Tests 35 frontend tests in `MatrixPlugin.test.tsx` covering the editor lifecycle (open/commit/cancel/invalid), clamping (typed, dragged, symmetric intersection), the redundant-update and double-commit guards, debounced drags, modifier scrubbing including mid-drag rebase, and schema validation incl. a negative case. ## Verification - `pnpm vitest run src/plugins/impl/__tests__/MatrixPlugin.test.tsx` — 35 passed - `make fe-check` — clean - `make py-check` — ruff lint/format clean; the typecheck step could not run locally (network cert issue downloading optional deps), relying on CI - Verified live against `examples/ui/matrix.py`: typed `2.5e-3` into the identity matrix, value rendered as `2.500e-3` and `matrix.value` round-tripped `0.0025` un-snapped 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Akshay Agrawal <akshay@marimo.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This pull request was authored by a coding agent.
Summary
Two interaction upgrades for
mo.ui.matrix, plus a correctness fix for symmetric matrices with per-cell bounds.Type-to-edit cells
step, so exact values like2.32e7survive the round trip.Modifier-key scrubbing
Symmetric bounds fix
withCellValueis now the single mutation chokepoint for bounds enforcement. In symmetric mode the shared value is clamped to the intersection of both cells' ranges — previously the mirrored cell received a value clamped only to the edited cell's bounds, so editing[0][1]could push[1][0]outside its own range. It also returnsnullwhen the clamped value is already in place, so no edit path emitssetValuewith an identical matrix.Also updates the
mo.ui.matrixdocstring.Tests
35 frontend tests in
MatrixPlugin.test.tsxcovering the editor lifecycle (open/commit/cancel/invalid), clamping (typed, dragged, symmetric intersection), the redundant-update and double-commit guards, debounced drags, modifier scrubbing including mid-drag rebase, and schema validation incl. a negative case.Verification
pnpm vitest run src/plugins/impl/__tests__/MatrixPlugin.test.tsx— 35 passedmake fe-check— cleanmake py-check— ruff lint/format clean; the typecheck step could not run locally (network cert issue downloading optional deps), relying on CIexamples/ui/matrix.py: typed2.5e-3into the identity matrix, value rendered as2.500e-3andmatrix.valueround-tripped0.0025un-snapped🤖 Generated with Claude Code