Skip to content

DetailSection headerColor reaches the DOM only as bg-${...} — a template-literal Tailwind class that generates no CSS, so the key works only by collision with other files' literal classes #6178

Description

@os-warren

Measured at 190fbd01 (the current objectstack .objectui-sha pin) while working objectstack-ai/objectstack#11661 (declaring renderer-honoured record:details section keys):

  • packages/plugin-detail/src/DetailSection.tsx:513 and :542 are the only read points: section.headerColor && + a template-literal class of the form bg- + ${section.headerColor} inside cn(...).
  • Tailwind here is v4 (tailwindcss ^4.3.3) with @source scanning over source files and no safelistapps/console/src/__tests__/sdui-preview-page-source-styling.test.ts documents this repo's own reading: "a utility class authored in real page metadata produces no CSS". A template-literal class is never a complete token in scanned source, so this call site generates no CSS at all; an authored value styles the header only when some other source file happens to use the identical bg-<value> class literally (accidental, unversioned liveness).
  • Dead-in-practice at the pin: zero producers author headerColor anywhere in objectstack (examples, platform pages, content) or in objectui outside the @object-ui/types mirror and the detail-section registry input row (packages/plugin-detail/src/index.tsx:287) — both declaration-only surfaces, which is why check:react-declaration-parity never saw it (it compares two declarations, never a declaration against a renderer).

Consequence: the key is unsafe-by-construction — advertised by the registry input and the @object-ui/types mirror (views.ts documents 'muted', 'primary/10' examples) while the renderer cannot deliver it for arbitrary values. objectstack#11661 therefore deliberately does not declare headerColor on the strict spec section schema (declaring a dead key is the capability-illusion shape).

Fix directions (either, plus dropping the registry input row and the mirror examples):

  1. Remove the dead read entirely (headerColor from DetailSection.tsx, the detail-section registry inputs, and the @object-ui/types mirror) — smallest honest surface; matches the spec-side refusal.
  2. Implement it safely: map a closed enum of supported values to static class literals Tailwind can see (e.g. a lookup object with complete bg-muted / bg-primary/10 strings), then propose the enum for spec declaration.

Filed as a finding (observation, unassigned) — the disposition is a triage call.

Back-link: objectstack-ai/objectstack#11661.

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions