Repository navigation
feat(ui)!: a record opened from a list opens in the drawer by default, and the split pane retires - #29108
Conversation
… retires The list keeps its full width under a non-modal drawer; the reader's record-open preference is drawer or page, and a stored split reads as the default. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jRrZ9h4h6RnBzGnhgi
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jRrZ9h4h6RnBzGnhgi
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jRrZ9h4h6RnBzGnhgi
|
domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y Contract reviewServed-tier: Face: declaration. The PR body and the changeset declare ① Derived judgments
② Semver levelThe five changeset entries are ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
|
domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y 席位核对 · ACCEPT · 2026-11-02T08:05ZHead-sha:
Generated by Claude Code |
Requested by Steedos · project thread
Fixes #28915
Clause-②: yes (narrowing)
Metadata-protocol: none
Skills-docs: follow-up owed — skills/objectstack-ui/rules/record-page.md, skills/objectstack-ui/evals/record-page.json
维护者速读
split偏好会按默认(抽屉)读出,不做兼容读;@object-ui/components移除了分屏相关的 7 个导出(BREAKING,changeset 写明迁移)。回滚即 revert 本 PR,无数据或元数据迁移。ui/packages/components/src/custom/navigation-overlay.tsx(分屏外观与 Esc 处理的删除)、ui/packages/app-shell/src/views/ObjectView.tsx(去掉 drawer→split 的映射)、ui/packages/app-shell/src/utils/recordOpenPreference.ts(偏好只认 drawer / page)。pnpm dev:crm打开 Accounts 列表,点一行:记录在右侧抽屉打开,列表不变窄;打开右上 Display 菜单,「打开记录」只有 Drawer 和 Full page。What changes
A record opened from a list now opens in the non-modal drawer over the list by default, and the list keeps its full width and every view column. The split pane beside the list retires: a record opens only as the drawer or as the full page.
recordOpenPreference.ts:RecordOpenPreferenceis'drawer' | 'page', defaultdrawer. A storedsplitis an unknown value and reads as the default, with no compatibility read.ObjectView.tsx: the drawer-to-split mapping is gone; the overlay receives the resolved mode as is. The record-count bar beside the pane (RecordPaneListCount) goes with it.navigation-overlay.tsx:NavigationOverlayModeispage | drawer | new_window | none. Removed: the split face,RECORD_SPLIT_MIN_CONTENT_PX, the width probe,useSplitEscape,paneBesideand the narrowed list face. The list under the drawer renders full width inside the active-row provider and goes inert while the drawer is maximized. Kept as they were: the non-modal drawer, a row click swapping the record, the stepper, drag-to-resize, maximize in place, and the modal sheet for a drawer with no list.record-list-face.tsxandcustom/index.ts: the narrowed-face API leaves (RecordListFaceProvider,useRecordListFace,recordListFaceFor,RECORD_LIST_CARD_FACE_BELOW_PX,RECORD_LIST_NARROW_COLUMN_COUNT,RecordListFace); the active-row store stays.ObjectGrid.tsx: no three-column or compact-card narrowing beside a pane; the grid draws every view column.ListView.tsx: the record-count bar always prints its count; thelist.recordOpenSplitdefault is gone.ViewSettingsPopover.tsx: the Open records control has two segments, Drawer and Full page;selectPageis gone from the host prop.list.recordOpenSplitleaves all ten packs.content/docs/frontend/plugins/plugin-view.mdx(the record drawer section) andcontent/docs/ui/views.mdx(the Open records paragraph)..changeset/28915-record-open-drawer-default.md: BREAKING, FROM-TO for each of the seven retired exports, ADR-0087 dispositionnot-required (runtime-export-retired ...).Why
Maintainer ruling on #28915: 「默认应该是普通列表,右侧弹出。drawer」 and 「默认改抽屉,分屏彻底退役,只留抽屉和整页,立卡。」 This supersedes #27545's Target item 1 and the split half of its item 2.
Tests
The #27545 split tests are converted to the drawer, not deleted:
navigation-overlay-split-27545becomesnavigation-overlay-drawer-27545(drawer over the list, list full width, ✕ closes, retired exports absent from the module).ObjectView.recordPaneV4-27545becomesObjectView.recordDrawer-27545(all five columns kept, storedsplitreads as drawer, list inert while maximized).ListView.recordPaneCount-27545becomesListView.recordDrawerCount-27545;ObjectGrid.recordPaneFace-27545becomesObjectGrid.recordDrawerList-27545.navigation-overlay-field-escape-28156,navigation-overlay-close-i18n,chrome-i18n-no-provider-fallback,record-top-bar-27524,record-list-face-27545,RecordPageColumns.enlargedEscapeInPane-27524,recordOpenPreference.test.ts,ObjectView.recordOpenPreference-26677,ObjectView.recordOpenDisplay-26681,ObjectView.recordCountFooter-10636,objectListTitle-27950,titleViewSwitcher-27594,viewRefusal-12112,phoneRecordPage-27058,RecordDetailView.topBar-27524,ViewSettingsPopover.recordOpen-26681.Ablation: decoding a stored
splitaspageinstead of the default turnsrecordOpenPreference.test.tsred (1 failed); restored, tree byte-identical to HEAD.Acceptance notes
Screenshots (examples/app-crm, Accounts, sidebar open; at 1000 px the sidebar is pinned open with Keep sidebar open, since the console folds it to a rail below 1416 px):
The 12 files are in the project files under
issue-28915/shots/(before-andafter-,1440-and1000-,list,display-menu,record-open).Premise reading,
ui/packages/app-shell/src/layout/consoleSidebarRail.ts(read-only here).CONSOLE_SIDEBAR_RAIL_BELOW_WIDTHis 1416 px, derived only from split content:RECORD_SPLIT_MIN_CONTENT_WIDTH = 440 + 720plus the 256 px expanded sidebar. With the split pane retired that derivation has no remaining reason. The fold itself still has one: #27593 quotes the maintainer 「窄屏幕左侧菜单自动折叠,点击弹出」 with an original target near 1100 px. So the threshold, not the fold, is left without a reason. Out-of-scope finding, carrier: seat.Other out-of-scope findings (carrier: seat):
record-top-bar.tsx:11,data-table.tsx:3735, plugin-detailRecordPageColumns.tsx:135/237,useRecordPageTier.ts:31,synth/recordPageColumns.ts:16/93/110, reactuseNavigationOverlay.ts:278, plugin-viewObjectView.tsx:590/1193,RecordDetailView.tsx:943/1003,objectViewOpenAsPage.tsx:15,appObjectScope.ts:45,ObjectGrid.tsx:3202.console.objectView.recordCountkey family is now read by no source file, and the overlay no longer readscommon.closePanel.skills/objectstack-ui/rules/record-page.md(line 48) andskills/objectstack-ui/evals/record-page.json(line 24) still say split is the default;skills/**is outside this card.Deviations:
content/docs/ui/views.mdx(one paragraph) is outside the declared file surface, a bounded in-place fix of the same claim; the plugin-detail andRecordDetailView.topBartest files are touched because they drove the split mode. Four test files are renamed. The dogfood battery ran as fourvitest --shardlegs because one foreground call is capped at 600 s; the legs cover all 387 files.Verification
Head
2255b429. Main was merged twice, at00d0668dand at5d3667e2, both clean; neither carried a parallel change to the touched files (ListView.tsxmerged with #29044's reset-to-default change automatically).Gates
node scripts/pm/dispatch-gates.mjs --commands: 67 derived, 67 run, all exit 0, reconciled with--ran(0 NOT-MEASURED).check:skill-examplesfirst exited 3 (needs@objectstack/client-reactbuilt) and passed after the full build.check:type-check-debtran under the verify lock.node scripts/check-sdui-manifest.mjsexit 0. Gates ran at407e38cf, before the main merge; the diff they derive from is unchanged by it.Type-check and tests
turbo run type-checkfor components, i18n, plugin-grid, plugin-list, plugin-detail, plugin-view, app-shell and console: 78 of 78 tasks, exit 0 (at407e38cf).407e38cf,--maxWorkers=2, locked: plugin-list whole suite 179 files 1725 tests; plugin-grid ObjectGrid set plus components/detail/view set 207 files 1692 tests; app-shell ObjectView set 141 files 1314 tests. All green, 527 files.4b3e19eb: the 54 test files the branch touches against the base, 377 tests, green.4b3e19eb, locked, four shards: 384 files passed, 3 skipped (387); 3166 tests passed, 28 skipped.2255b429(after the second merge): the touched tests plus every plugin-list test naming the Display menu or the record count, and main's newListView.restoreViewDefaults-28948and data-table row-action tests: 29 files, 228 tests, green;turbo run type-checkplugin-list and components 51 of 51.pnpm build: 117 of 117 tasks.ui/eslint (the Lint UI config) over the 41 touched ts/tsx files: 0 errors.Human Minimum
packages/specholds no runtime logic.pnpm lintpasses.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed. (not touched)content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01QsR2jRrZ9h4h6RnBzGnhgi
Generated by Claude Code