Skip to content

feat: add native GridStack canvas transactions - #329

Merged
daniil-filippov-dev merged 72 commits into
daniil-filippov-dev/UXRFC-664-controlled-nestingfrom
daniil-filippov-dev/UXRFC-664-gridstack-integration
Nov 9, 2026
Merged

daniil-filippov-dev merged 72 commits into
daniil-filippov-dev/UXRFC-664-controlled-nestingfrom
daniil-filippov-dev/UXRFC-664-gridstack-integration

Conversation

@daniil-filippov-dev

@daniil-filippov-dev daniil-filippov-dev commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

🤖 AI TLDR

Add native GridStack canvas transactions, nested transfers, and scaled/bounded editing while retaining widget identity and shared DashKit behavior.

🤖 AI-generated

Depends on #335, after #328, #331, #333, and #334. Palette previews and full-document drops follow in #337.

Native dragging transfers widgets and whole container subtrees between grids, validates destination space and constraints, and commits one document transaction. Off-surface release saves the last valid bounded preview; Escape and rejected proposals restore the document and leave the next edit usable. Support live scalar/ref scale, physical bounds, custom/directional handles, overlap and touch while preserving controlled acknowledgments, autoheight, plugin lifecycle and portal identity. Converted cross-grid geometry is fitted once, foreign DOM moves are rejected, and active resize geometry rebases when scale changes. GridStack private hooks remain pinned to 12.6.0.

Scaled resize limits are normalized once, including fractional scales, and the first resize preserves its original gesture rectangle while later scale changes rebase active geometry. The shared StrictMode check matches post-remount metadata IDs and identities to the current widget DOM. Hidden/revealed canvases retain identity, saved config, event count and usable next-resize geometry; the no-extra-render invariant applies to the native engine.

CI repeatability update at 2026-11-02T10:06:27.416679+00:00, with source unchanged: root explicitly authorized exactly one rerun of the failed PR329 Browser Contracts job after an independent bounded diagnosis. The single-job endpoint returned HTTP 201; no full-workflow/all-runs rerun or duplicate request was used. Attempt 2 Browser Contracts passed at d8484e2035cf0756f0a9a0b87a5dc1b8902d66f0: 343 passed, two skipped. The current PR329 workflow/check results are terminal and successful; PR337's unchanged head 83b644ffb48dc07f07fe9e114dfccacedac5db59 retains its successful first-attempt CI. React 18 remains skipped, not executed.

The original PR329 first attempt remains a real recorded failure: 342 passed, two skipped, one failed WebKit legacy hidden/reveal resize. Its failed check, raw logs, trace, screenshot and artifact ZIP are preserved. The independent diagnosis found two unchanged focused macOS passes and one server-startup timeout with zero tests executed; those are not equivalent to Linux CI. A later original trace snapshot captured width 448px before release, refining the earlier after-move 441px sample. 448px is the largest captured sample, not proof of the true unsampled peak; both are below the recorded expected 478px. Cause remains unproved. A passing repeat does not establish a fix or exclude a real rapid-resize defect. No source, test, assertion or timeout changed for the repeat, and no further retry was authorized.

The publication snapshot below is preserved verbatim. Its first-attempt CI failure and no-retry statements describe that earlier observation, before the single explicit authorization above. Original failure evidence, canonical-tree erratum, prior validation and review-gate limits remain applicable. This update does not claim a GitHub merge, human approval, registry release or application-runtime acceptance.

Validation at published head d8484e2035cf0756f0a9a0b87a5dc1b8902d66f0 (base 29f5ba1e031df01ec7909904bf54dc0973a4edaf, tree a7fb53e7a1372c8876066b76554275f8c35cfd85), Node 22.22.0. Normal hooks and fast-forward publication preserved the accepted history and exact source. A different bounded AI Checker accepted both downstream candidates under Standards/Spec, ponytail-review, and codebase-design; this does not claim a fresh whole-feature review or new human approval.

The final source passed 79 existing component/nesting/transaction Jest cases, source and browser typechecks, scoped ESLint/Prettier, and a fresh normal build. Attributed exact-byte browser evidence covers 48 affected cases across Chromium, Firefox, and WebKit including controlled transfer/cancellation, start replacement/unmount, native scale, and failed-preview recovery. Existing assertions and timeouts were unchanged; retries remained zero. The six synchronous drag/resize-start unmount regressions also passed separately on each branch and again in the independent Checker run. Private connected-grid probes retained strict invalid explicit/ref/measured scale rejection, valid reciprocal calibration, and stale-root ownership behavior in all three engines. No permanent diagnostic test was added.

Before this correction, the preserved PR329 composition run at 1329ed099157829927e7722afae2b70bc5d4ca97 had 99 passes and six failures: synchronous drag/resize-start unmount threw transformScale must be finite and positive in all three engines. The PR337 broad browser command did not start after that failure; no pre-fix PR337 browser pass is claimed. A four-line guard now skips scale calibration only for disconnected or replaced grid roots while leaving native start cleanup and live validation intact. Captured failure stacks and the independent detached-root replay support this cause; the original failed gestures were not instrumented for numeric measurements. The candidate-tree metadata calculation was corrected to canonical Git directory mode before committing; actual trees match the independent corrected proof.

Exact-head GitHub checks observed at 2026-11-02T09:06:39.501964+00:00 are terminal, with Browser Contracts FAILED on the first attempt: 342 passed, two skipped, one failed. The failure is WebKit legacy hidden finite canvas reveals without remount and accepts the next resize, boundaries-common.spec.ts:95: expected Events: 1, observed Events: 0. Other executed checks passed: Verify Files, Tests (React 19), Build, validate-package. All current-head workflow run sets completed on their first attempts; no rerun was requested. React 18 was skipped by the existing release-only workflow guard and was not executed. GitHub reports MERGEABLE/BLOCKED and REVIEW_REQUIRED; repository review gates and stack merge order remain required.

Stack CI caveat: PR329's first-attempt legacy hidden/reveal resize failure remains open. Its original trace shows a 54px pointer movement producing only 17px of temporary resize, then restoring width 424px with saved w=8 and zero events. Raw logs, trace, screenshot, and artifact ZIP are preserved. Stale incremental resize props are a hypothesis, not a proved cause; this is not classified as a harmless flake. The same legacy test body and legacy resize implementation pass in PR337's complete first-attempt CI, but its palette story/fixture additions mean it is not an exact whole-program counterfactual. No assertion, timeout, test, or source was changed after this CI failure, and no retry was requested.

The fully paginated six-PR audit read 18 review bodies, all 30 per-review/thread comments including the four PENDING comments, and six issue comments. No feedback body was added, removed, or changed. Six PENDING reviews and four outdated unresolved draft threads remain untouched; prior approvals on the updated heads were automatically dismissed. No review, reply, draft publication, thread resolution, merge, or release was performed.

Previous validation evidence (historical heads and bases)

The following record is preserved from the prior published head. Its head, base, checks, archive, and risk statements describe that earlier snapshot.

Validation at published head 2ace6a3508dd501e3067fdda02755e738e1057e8 with Node 22.22.0: 176 relevant mounted Jest tests, 72 browser cases across Chromium, Firefox and WebKit, source/browser types, scoped ESLint/formatting and normal build passed. Ten independent mounted subcell-boundary probes also passed. Settled drag and acknowledgment helpers now wait for exact intermediate/final live geometry. Nested autoheight proposals reject overflow and disallowed sibling overlap, retain the last accepted visual layout, and reconcile controlled shrink without changing saved heights or growing the parent. Native nowrap recovery now proves exactly one fresh event and the expected full saved document. Independent bounded AI review accepted the exact patches; no fresh whole-PR review or human approval is claimed. Existing exact saved-coordinate, immediate-release and outside-release assertions remain. Synthetic native-event probes establish a possible stale-state mechanism; they do not prove the old CI schedule or fix/exclude rapid-input product risk.

Current base: 150b644bd0ff40964ad70dc283ec680a50135dc8. Exact-head GitHub checks observed at 2026-10-29T21:55:51.425303+00:00 all completed successfully: Build, Verify Files, validate-package, Tests (React 19), Browser Contracts. React 18 was skipped by the existing release-only workflow guard and was not executed. GitHub mergeability is blocked and review decision is REVIEW_REQUIRED at this snapshot. Repository review gates and dependency merge order remain required; no merge or release is claimed.

@gravity-ui-bot

Copy link
Copy Markdown
Contributor

Preview is ready.

@daniil-filippov-dev
daniil-filippov-dev marked this pull request as ready for review October 23, 2026 12:41
@daniil-filippov-dev
daniil-filippov-dev marked this pull request as draft October 26, 2026 13:04

@korvin89 korvin89 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI generated

This review was done with AI assistance. I validated every comment myself, but the wording — including the points I found myself — was written by the AI.

Severity legend

  • 🔴 blocker — should be fixed before merge.
  • 🟠 should-fix — a real problem; worth fixing before or right after merge. If you can't get to it now, please open an issue and leave a comment linking it.
  • 🔵 nit — minor; author's discretion.
  • ❓ question — I need more context; not necessarily a defect.

Comment thread src/components/GridStack/native-grid.ts Resolved
Comment thread src/components/GridStack/engine.ts Resolved
Comment thread tests/browser/converted-fit.spec.ts Resolved
Comment thread src/components/GridStack/native-grid.ts Resolved
Comment thread docs/gridstack.md Resolved
Comment thread src/components/GridStack/GridStack.scss Resolved
korvin89
korvin89 previously approved these changes Oct 30, 2026

@korvin89 korvin89 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI generated

Re-checked the fixes on 2ace6a3 against the scenarios from the review (Chromium and the engine). The addressed comments behave as expected. Approving.

One follow-up on the off-surface release question. Bounded grids now keep the last destination: dragging from left into right and releasing beyond right saves the widget in right, which matches docs/gridstack.md:79. Unbounded grids still return the preview to the source once the pointer leaves the destination past its far edge, and the release saves it there (left, x: 10 in the same scenario). If that is intended, please say so in docs/gridstack.md:79 — for example, that in unbounded grids leaving the destination returns the preview to the source. Not blocking.

roberthovsepyan
roberthovsepyan previously approved these changes Nov 3, 2026
@daniil-filippov-dev
daniil-filippov-dev added this pull request to the merge queue Nov 9, 2026
Merged via the queue into main with commit eca47fd Nov 9, 2026
6 checks passed
@daniil-filippov-dev
daniil-filippov-dev deleted the daniil-filippov-dev/UXRFC-664-gridstack-integration branch November 9, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants