feat(studio): flat inspector — persisted pinning + multi-field Text#2125
feat(studio): flat inspector — persisted pinning + multi-field Text#2125vanceingalls wants to merge 8 commits into
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
miga-heygen
left a comment
There was a problem hiding this comment.
Reviewed as part of the 15-PR edit-panel redesign stack. Full stack review posted on #2120. No blockers on this PR. — Miga
…rences Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reads/writes the per-element-kind pinned-groups map added to studioUiPreferences in the prior task, read-modify-writing the whole map since writeStudioUiPreferences only shallow-merges top-level keys.
Review of the pin-aware group list refactor flagged the test name claiming the group "closes" on unpin — it doesn't assert that, and structurally the group re-opens (togglePin never touches openGroupId). Retitled to describe only the return-to-stack behavior actually tested. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Originated layout, no design mock exists — flag for design review. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Review proved the existing test didn't catch a broken stopPropagation by temporarily removing it and confirming the suite still passed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
FlatTextSection's multi-field branch (textFields.length > 1) now renders FlatTextLayerList (Task 5) + the existing single-field FlatTextFieldEditor for the active field, tracked via new local activeFieldKey state that resyncs (useEffect) when the active field disappears from props. This retires the legacy TextSection delegation entirely for that case; the TextSection import is removed from propertyPanelFlatTextSection.tsx since nothing else in the file referenced it. Also updates propertyPanelSections.test.tsx and PropertyPanel.test.tsx, which exercised/documented the old multi-field-falls-back-to-legacy- TextSection behavior in comments and test titles — reworded to describe the new flat path (assertions were already compatible and still pass). Flag for reviewer: hideOwnHeading on the legacy TextSection component (propertyPanelSections.tsx) was added in an earlier plan specifically for this now-removed call site. It has no remaining consumer after this task lands (PropertyPanel.tsx's legacy caller doesn't pass it). Left in place per brief instruction — not deleting unilaterally, since that's a scope decision for whoever reviews this task. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
miguel-heygen
left a comment
There was a problem hiding this comment.
Final current-head pass: f3389dc. Reviewed the stack boundaries and current diff against the flat-inspector contracts; required checks have no failures/pending checks and no unresolved review threads remain. No new drift found; residual notes are non-blocking.
a9409d1 to
dfdc68a
Compare
f3389dc to
45a06a5
Compare
miguel-heygen
left a comment
There was a problem hiding this comment.
Superseding earlier approval: the latest max-review pass found confirmed correctness issues in this flat-inspector stack (identity/selector-index state, hide-all write races, timing inference, slider pointer/keyboard/reset semantics, and duplicate React keys). Hold merge and require fixes plus re-review on the current stack head.

What
Sixth and final PR in a 6-PR stack for the flat inspector redesign (see #2120 for the foundation and full stack list). Makes pinning an actually-observable, persisted feature — pinned groups now render first, always open, above a divider, and the pin state survives reload per element type — and flattens the multi-field Text case, retiring its legacy fallback.
Stack: #2120 (Foundation+Text) → #2121 (Style) → #2122 (Layout+Motion) → #2123 (Media) → #2124 (Grade) → #2125 (this).
Why
FlatGroup's pin button andPinnedZoneDividerexisted since #2120 but nothing actually reordered a pinned group to the top or persisted the choice — pinning was invisible. Multi-field Text still fell back to the legacy stacked-sections component, the last remaining dependency on old UI in the migrated groups.How
pinnedGroupsByElementTypepersisted to the existingstudioUiPreferences.tslocalStorage module (reused, not a new key), keyed per element kind (text/media/other).usePersistedPinnedGroups(elementKind)hook wraps read/write with atogglePinthat does a correct read-modify-write against the full map (the underlying preferences write is a shallow merge, not a deep one, so this hook is the single place that must not clobber other element kinds' pins — verified).PinnedGroupRowis a new always-open wrapper (no collapse caret, "Pinned" badge) distinct fromFlatGroup's normal accordion state.PropertyPanelFlat.tsxrefactored to a data-driven group-descriptor list, partitioned into pinned (rendered viaPinnedGroupRow) and unpinned (rendered viaFlatGroup's accordion) — every group from feat(studio): flat inspector foundation + Text group #2120–feat(studio): flat inspector — Grade (color grading) group #2124 participates in the same mechanism.FlatTextLayerList(originated layout — no design mock exists for this row; flagged for design review) lists each text field as a selectable "layer";FlatTextSection's multi-field branch now uses it directly instead of delegating to the legacyTextSection, which no multi-field path in the flat inspector depends on anymore.STUDIO_FLAT_INSPECTOR_ENABLED(default off).Test plan
TextSectioncomponent, the full monorepo suite passes (1562+ tests, 0 failures), and the repo'sfallowcomplexity/duplication gate passes clean.