Repository navigation
fix(components): the record header draws one primary action, the rest as outline buttons - #12635
Merged
objectstack-fleet[bot] merged 3 commits intoOct 16, 2026
Merged
Conversation
… as outline buttons page:header drew every action without a declared variant with the filled style, so a record header with three actions showed three primaries. The primary is now the first action declaring variant 'primary', else the first by order; the next inline actions are outline buttons; what exceeds maxVisible folds into the overflow menu above the host's Share / Delete. The host's Edit stays a labelled outline button in the row and takes no slot, replacing the icon-only twin it folded behind. Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB Co-authored-by: Claude <noreply@anthropic.com>
…t any Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB 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
|
This was referenced Oct 16, 2026
…cord-header-actions
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
|
Contributor
Author
Review: ACCEPT — objectui PR #12635 ·
|
objectstack-fleet
Bot
deleted the
claude/issue-12617-record-header-actions
branch
October 16, 2026 10:01
This was referenced Oct 16, 2026
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.
Fixes #12617
Clause-②: no
What changed
page:header(the record page header) now draws ONE primary action and the rest as secondary buttons, as@objectstack/spec's action contract documents ("inrecord_headerthe first visible action becomes the primary button"; a renderer may prefervariant: 'primary').variant: 'primary', else the first byorder. It leads the row and is the only filled button. With no app action, the host's Edit is the primary.maxVisiblebudget (3 desktop / 1 mobile); the rest go to the⋯, above favorites / Share / Delete.⋯behind an icon-only pencil (this replaces that rule from objectui#12529). A destructive host action (Delete) always goes to the⋯, never inline.Measured mechanism (assumption A1 confirmed): the inline renderer mapped every action's
variantwithaction.variant || 'default', and Shadcn'sdefaultis the filled style, so every action without a declared variant drew as a primary. Nothing readorderfor the styling;orderonly sorted.Files:
packages/components/src/renderers/layout/containers.tsx(the banding),packages/app-shell/src/views/RecordDetailView.tsx(the Edit entry no longer declares avariantthe header does not read; comment updated), tests beside each,.changeset/12617-record-header-actions.md(patch, components + app-shell).Target 2: the missing Convert Lead is not an objectui drop (premise not reproduced)
Booted HotCRM at the walked commit
63db83e2(and at850f75c) withobjectstack dev --fresh, ran this branch's console against it, and drove the Mira Costa lead in Chromium. With a temporary log in the header's filter (removed before commit):convert_leadandschedule_followupdeclarevisible: has(record.is_converted) && record.is_converted == false && …, which fails closed against no record, so the header shows exactly the card's state: Log a Call · Log a Meeting · Schedule a Meeting, and a ⋯ of Edit · favorites · Share · Delete.is_converted: false,status: contacted,conversion_approval_status: not_required), the predicate holds and both actions render: before this PR, Convert Lead · Schedule Follow-up · Log a Call inline with Log a Meeting · Schedule a Meeting in the ⋯; after it, the same, with only Convert Lead filled.No count cap discards actions (assumption A2 refuted): folded actions move into the ⋯. The cause is HotCRM's own
visiblepredicate evaluated against the record the header holds: no record yet, or a stored lead whoseis_convertedis notfalse. The walk's database is not available here, so which of the two produced the screenshot is NOT MEASURED. No HotCRM change made.Target 3: list row ⋯
On the lead list, the row ⋯ for Mira Costa lists Edit, Delete, Convert Lead, Add to Campaign, Log a Call, Log a Meeting, Schedule a Meeting, Schedule Follow-up. Every
list_itemaction is present. No change.Tests
packages/components/src/__tests__/page-header-primary-12617.test.tsx: three actions give one filled primary + two outline + a labelled outline Edit; a fourth goes to the ⋯ above Share / Delete;variant: 'primary'wins overorder; a declared action whosevisibleholds is present, and (CONTROL) one whosevisiblefails is absent; with no app action, Edit is the primary.RecordDetailView.headerMenuIcons-12529.test.tsx(Edit is labelled and in the row, not icon-only in the ⋯) and one case inpage-header-actions.test.tsx(a hostsys_deletewith no placement renders in the ⋯).action.variant || 'default'mapping turned 2 of the 5 new pins red (the one-primary and the primary-wins-over-order pins); restore was proven by the blob matchingHEADand an emptygit diff HEAD.Gate readings, the targeted vitest runs, and the commit they ran on are in the
os-dev-reportcomment on the card.Acceptance notes
secondary/ghost/link/dangervariant inline: the primary is filled, every other inline button is outline.dangerwas never a Shadcn button variant, so it did not draw red inline before either.Generated by Claude Code