Uh oh!
There was an error while loading. Please reload this page.
fix(components): retire AccordionItem.icon, honor item-level disabled - #4723
Conversation
AccordionItem declared icon?: string and disabled?: boolean while the accordion renderer read neither. Same defect as ToggleGroupItem in the same file (objectui#4632, PR #4651): a corpus sweep (schema catalog, docs, example apps, and the objectstack sibling checkout) found zero sites authoring either key. icon is retired from the interface and the Zod mirror. disabled is wired, since item-level disabled is already established convention (tabs, select, dropdown-menu, menubar, context-menu, toggle-group) and Radix's accordion item supports it natively, so the renderer forwarding one prop is the whole change. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnQd8iMMUwXQEV1crFmQiQ
The latest updates on your projects. Learn more about Vercel for GitHub. |
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
commented
Aug 15, 2026
Review verdict: ACCEPT (reviewer of record, PM session Verified against this PR, not the report: all eight changed files are enumerated and justified in the body — including the catalog example now exercising the wired key and the one-line docs pointer, which the corpus-teaches-what-works lesson explicitly wants shipped together (the report summary under-enumerated these two; the PR body is the complete account, so recorded as a nit only). The two out-of-scope findings (#4721, #4722) get their first-touch grades on their own cards. Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#4652
AccordionItemdeclareddisabled?: booleanandicon?: stringwhile theaccordionrenderer read neither — it mapped items to
value/title/contentonly. Premisere-verified against
origin/main(fec06835e): both keys declared atpackages/types/src/disclosure.ts:39,43and its Zod mirrorpackages/types/src/zod/disclosure.zod.ts; neither read atpackages/components/src/renderers/disclosure/accordion.tsx. Radix's underlyingAccordionPrimitive.Item(spread viapackages/components/src/ui/accordion.tsx) supportsdisablednatively. The mechanism hypothesis held in full — same shape as objectui#4632(PR #4651), one interface up in the same file.
The measurement (per the inherited #4632/#4651 framing)
Enforce-or-remove, decided per key by measured pull, not by symmetry. Full corpus sweep:
schema catalog (
examples/schema-catalog), docs (content/docs), example/applicationcode (
apps/console,apps/site), and this repo'sobjectstacksibling checkout.icondisabledicon— retired. Zero measured pull anywhere in the sweep, including theobjectstacksibling checkout (noAccordionItem/page:accordionicon authoringfound there at all —
page:accordionitems are a separate, unrelated interface, seeNotes). Under declared=enforced it is removed rather than speculatively implemented.
disabled— wired, despite also having zero direct catalog pull today. Item-leveldisabledis established live convention in this codebase:tabs,select,dropdown-menu,menubar,context-menuand (objectui#4632)toggle-groupallforward it.
accordionwas the next outlier, and the underlying Radix item supportsdisablednatively, so forwarding one prop is the whole change — the synced no-touchui/accordion.tsx(AGENTS.md 构建一个 **Live Playground (实时演练场)** (用于展示引擎能力) #7) is untouched.Surfaces changed
packages/types/src/disclosure.ts—iconremoved fromAccordionItem;disabledkept and documented as forwarded.
packages/types/src/zod/disclosure.zod.ts—AccordionItemSchemadeclaredicontoo;removed in the same commit so the retirement closes on both hand-maintained
declarations together.
packages/components/src/renderers/disclosure/accordion.tsx— forwardsdisabledperitem to the
AccordionItemprimitive.examples/schema-catalog/.../basic-accordion.json— one item now demonstratesdisabled: true, so the corpus teaches a key that actually works. Contents-only edit,no index regeneration (
examples/schema-catalog/src/index.tsimports the file by path;per fix(examples,scripts): regenerating the schema catalog stops discarding curated metadata #4637's own model).
content/docs/components/disclosure/accordion.mdx— one line of prose above theSchemaExampledescribing the new disabled-item demo. The page's "Schema" code blockunderneath is pre-existing, unrelated drift (missing
value, wrong root field namesdefaultOpen/multiplevs. the realaccordionType/defaultValue/etc.) — left aloneand filed separately as finding(docs): accordion.mdx's schema block is stale against the real AccordionSchema/AccordionItem interface #4722, since fixing it is a different defect class than this
card's declared-but-unenforced-key settlement.
Tests, all at
015360404Full verification ran after the final commit, tree clean.
packages/types/src/__tests__/accordion-item-authorable-keys.test.ts(declarationsurfaces —
iconretired via@ts-expect-error+ Zod-drop + Zod-shape pins;disabledstays declared, preserved through the Zod mirror, rejects non-boolean).
packages/components/src/__tests__/accordion-item-disabled.test.tsx(behavior — thedisabled item's trigger carries a real
disabledattribute and does not expand onclick; positive control: a non-disabled item does expand on click; leaves every item
enabled when none declares
disabled; still renders each title).pnpm exec vitest run --maxWorkers=2 packages/types/ packages/components/ examples/schema-catalog/— 173 files / 3114 tests passed.pnpm --filter @object-ui/types type-checkandpnpm --filter @object-ui/components type-check— clean (dependency closure built first viapnpm --filter '@object-ui/components^...' build, a fresh worktree fails type-check onunresolved workspace deps otherwise).
check-changeset-presence/check-changeset-no-major/check-control-bytes/check-doc-links— all green. ESLint on the changed files: 0 errors (1 pre-existingno-explicit-anywarning on an untouched line, confirmed present onorigin/main).Reverse verification, direction predicted before each run:
disabledforward (dropdisabled={item.disabled}) ⇒ predictedthe two behavior pins asserting the forward go red, the rest of the file stays green.
Observed exactly that:
disables exactly the item that declares itanddoes not expand the disabled item on clickfailed (dump showedaria-expanded="true"and nodisabledattribute on the trigger button); the positive-control test, the no-
disabled-declaredtest, and the title-render test stayed green (2 failed / 3 passed).
iconin a@object-ui/components-side scratch test againstthe rebuilt
@object-ui/typesd.ts ⇒error TS2353: Object literal may only specify known properties, and 'icon' does not exist in type 'AccordionItem'. Observed exactlythat; the retirement reaches consumers, and the verdict came from the rebuilt
declaration, not a cached one. Scratch file removed afterward, type-check re-confirmed
green.
Each ablation was restored with
git checkoutfrom the committed state and confirmedbyte-clean (
git status --porcelainempty).Notes
minorfor both packages, matching PR fix(components): retire ToggleGroupItem.icon, honor item-level disabled #4651's classification for theidentical defect class: breaking for TypeScript authors of
icon(excess-propertychecking), per this repo's version-alignment rule (AGENTS.md 版本号策略) reserving
majorfor following
@objectstackacross a major. Runtime behavior of an authorediconisunchanged — it rendered nothing before and renders nothing now.
findinglabel):PageAccordionItem.icon(a different component,page:accordioninpackages/components/src/renderers/layout/containers.tsx, notAccordionItem/ui:accordion) is declared and never read — same defect shape, different file/claim.content/docs/components/disclosure/accordion.mdx's schema code block isstale against the real
AccordionSchema/AccordionIteminterface (predates thiscard, different defect class).
three-surface reconciliation instrument this is one more measured instance of, not a
blocker for either.
Generated by Claude Code