Repository navigation
feat(plugins): four plugin single selects pick with the shared Select (objectui#11865, slice m) - #12019
Merged
objectstack-fleet[bot] merged 4 commits intoOct 9, 2026
Conversation
… (objectui#11865, slice m) SharedViewLink's expiry, ViewSettingsPopover's "Color by field", the kanban InlineQuickAdd select field and the grouped grid's "Rows per page" were browser-native selects. Each is now the shared Radix Select. What each writes is unchanged (pinned against a base probe's reads); a value outside the options shows as itself. InlineQuickAdd keeps the form's keys: Enter on the closed picker submits, Escape cancels, and keys inside the open list stay in it. Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU Co-authored-by: Claude <noreply@anthropic.com>
…5, slice m) Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
…lect Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU Co-authored-by: Claude <noreply@anthropic.com>
…color as the shared Select (objectui#11865, slice m) The compact toolbar's View settings popover now draws "Color by field" with the shared Select, so the position row reads the fields its listbox offers, leaving out "None" as before. The wide toolbar's Color popover is ListView's own native select and keeps the native reader. Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
objectstack-fleet
Bot
deleted the
claude/issue-11865-plugin-singles-select
branch
October 9, 2026 02:53
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.
Part of #11865
Clause-②: no
Slice m of claim
6071773793(domain:uiseat 2, accountos-bill, sessionsession_01MgfduSkFrfM3eorB3UGfAU): four plugin single selects now use the shared RadixSelectfrom@object-ui/components, the control the rest of the console picks with. It follows the card's earlier slices (objectui#11976 through objectui#12013): items carry option indexes, so an option whose value is''needs no emptySelectItem, and a stored value outside the options shows as its own item. Each picker is module-private; nothing new is exported.packages/plugin-view/src/SharedViewLink.tsxExpiryPickerpackages/plugin-list/src/components/ViewSettingsPopover.tsxColorFieldPickerplugins-views, eagerpackages/plugin-kanban/src/InlineQuickAdd.tsxselectfield of the quick-add formQuickAddPickerplugin-kanban, lazypackages/plugin-grid/src/ObjectGrid.tsxplugin-grid, eagerWhat stays the same
Every option writes what the native control wrote. A scratch probe on base
5d77c099bfired achangeevent for every option of each native control and recorded the write. Each pin compares against those readings as JSON text:onShareoptions for each expiry (fake clock). "Never" still sends both keys asundefined, pinned withtoStrictEqual.setRowColorConfigover four configs: none, a field with colours, a field with no colours, and a field outside the options. "None" still writesundefined.''.Re-picking the current option writes nothing, as a browser's native select did. The probe's synthetic
changefired for the current option too, so the re-pick rows pin the primitive.Accessible names:
label htmlForgave the native select (idis on the trigger).htmlFor, noaria-label, and the probe read an empty name. So none is kept, and none is added.Keys and focus:
Enter opens a picker and Enter on an option selects it; pinned on the expiry, colour and size pickers.
The quick-add picker still takes the form's first focus.
The quick-add picker keeps the form's own contract, read on base: Enter on the closed native select submitted the form, and Escape cancelled it. Two in-file companions keep both:
Space and the arrow keys open the list. See the open question below.
Popovers: a pick inside the share popover leaves the popover open (pinned).
Read-only: none of the four surfaces has a read-only or disabled state, so there is nothing to show through the primitive.
One display change
A value outside the options now shows as itself. On base, the native select showed its first option instead:
ghostread "None";ghostread the placeholder.Both are pinned. Picking that item writes nothing.
The quick-add picker matches a value by its string, as the native select did: a prefilled number
2still shows the option whose value is"2". This is pinned too.First-load bytes
apps/console,CI=true vite build, under the verify lock. Base was built in a detached worktree at5d77c099b. Head was built at39da00233; the later commit changes only a test file.eagerGzipByteseagerRawBytes5d77c099bplugins-views(+158 gzip / +307 raw; it holdsColorFieldPicker) and minifier churn:plugin-grid−27 / +21,index−12, and five more chunks at −1.pnpm check:eager-closureon the head build prints "Console eager closure is 3160.1 KB gzipped across 289 of 2474 chunks (budget: 3204.6 KB, headroom: 44.4 KB)", with every per-chunk ceiling and the chunk membership green.scripts/check-eager-closure-budget.mjsis untouched.Evidence (head
391623d4c)pnpm exec vitest run --maxWorkers=2 packages/plugin-view/ packages/plugin-kanban/ packages/plugin-list/ packages/plugin-grid/ packages/core/src/utils/__tests__/column-identity.ratchet.test.ts scripts/__tests__/one-authority-per-exported-name-6273.test.ts(repo root, under the lock) reads "Test Files 456 passed (456)", "Tests 4269 passed (4269)", VERDICT command-exit 0.pnpm --filter @object-ui/PKG type-checkforplugin-view,plugin-list,plugin-kanbanandplugin-grideach exits 0. The closure was built first withpnpm --workspace-concurrency=2 --filteron each package's dependencies (16 of 47 projects, VERDICT command-exit 0).tsc -p tsconfig.test.json --listFilesOnlylists all six touched test files.pnpm exec eslint --format jsonon the 10 touched files reads 0 errors. Warnings per file equal the base blob's (read through stdin with the same filename). The four new pins read 0 / 0.node scripts/check-changeset-presence.mjs[0]: "10 source file(s) of 4 released package(s) changed, and this change declares 1 changeset(s)".node scripts/check-changeset-no-major.mjs[0].pnpm check:new-line-citations[0]: "0 new citation(s)".pnpm check:control-bytes[0].pnpm check:vi-mock-specifiers, vi-mock-inherit, vi-mock-override-shape, test-path-roots, i18n-keys, changeset-claims, pending-changeset-literals, phantom-deps, unused-deps, self-import, handler-key-reads, metadata-write-doors and unreferenced-sources each exit 0.git hash-objectequals the base blob.git checkout HEADin a trap. Each blob equals HEAD, andgit diff HEADis empty.scripts/ablation-replace.mjs. Each printed "ok mutation landed" and "ok restored: blob == HEAD (b2757532d083) andgit diff HEADis empty".content/docspage describes these four controls' markup, so there is nothing to update.Files
SharedViewLink.sharedSelect-11865,ViewSettingsPopover.sharedSelect-11865,InlineQuickAdd.sharedSelect-11865andObjectGrid.groupedPagerSelect-11865;groupedPagination.test.tsxandObjectGrid.displayPageSizeDefault-9853.test.tsx, which read the size picker as a native select and now open the shared one;.changeset/11865-m-plugin-singles-shared-select.md, a patch for each of the four packages.Open question for the seat
Should Enter on the quick-add picker keep submitting the form, as on base and in the component's own doc ("Submit with Enter or the Save button")? Or should it open the list, as every other converted picker does?
Recommendation: A. The form's Enter is its submit key on every field, and Space and the arrow keys still open the list.
Acceptance notes (noted, not filed)
ListView.tsxkeeps its own native "Color by field" select. That copy is the legacy twin of the popover's control.ListView.tsxis not on this claim; objectui#11984's re-land holds it.Generated by Claude Code