You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(plugin-dashboard): MetricWidgetProps / MetricCardProps declare no DOM passthrough, so the id / role / aria-* the spread accepts at runtime are a type error for a TS consumer #4426
Observation-class finding, measured while implementing #4357. Pre-existing on origin/main and unchanged by that PR; filed rather than widened into it, because closing it changes the exported props interface of two components.
What happens
Both components end their prop list with a ...props spread onto the Shadcn Card. #4357 keeps the spread deliberately — it is the components' genuine DOM/aria passthrough, and removing it would delete the only way a host can put id, role or an aria-* on a KPI card. But neither MetricWidgetProps nor MetricCardProps extends React.HTMLAttributes, and neither declares those keys, so what the runtime accepts the type refuses.
Measured against the built dist/index.d.ts from a consumer package:
probe.tsx(23,52): error TS2322: Type '{ label: string; value: number; id: string; role: string; "aria-label": string; }'
is not assignable to type 'IntrinsicAttributes & MetricWidgetProps & SchemaHostProps'.
The same source compiles and behaves correctly at runtime — the attributes reach the card. A JS consumer, or any SDUI author going through SchemaRenderer (which is untyped at that boundary), gets the passthrough; a TypeScript consumer importing the component directly cannot use it without a cast.
Why it is worth writing down even though nobody is blocked
It is the mirror image of #4357. That issue was renderer metadata reaching the DOM because the spread is open; this is DOM attributes being unreachable because the type is closed. Both come from the same unstated question — what may a dashboard widget legitimately receive? — and answering it once, in the type, is what makes "declared = enforced" true here in both directions instead of one.
Fix shape
Declare the passthrough: extend the interfaces with the subset of React.HTMLAttributes a KPI card should accept, or an explicit block mirroring what FieldWidgetDomProps does for field widgets (objectui#3221). Either way it widens the exported props interface, which by this repo's grading is a minor with the semantics in the changeset body (the objectui#4403 precedent), so it is not a drive-by rider on a patch fix. It should also be decided together with #4425 — if plugin widgets move to a toDomProps-style whitelist, the declared DOM set is exactly that whitelist and the two are one change.
CLAIM + RULING — PM seat session_017Qqyix2QcnpUC9XeYVDzx3, branch claude/issue-4426-metric-props-passthrough, one dev agent, one PR, Fixes #4426.
Ruling (delegated, veto window open): declare the DOM passthrough the spread actually accepts — widen MetricWidgetProps/MetricCardProps so id/role/aria-label/data-* (what the #4428 measurement kept flowing) type-check for direct consumers, per whatever shape the card's own analysis proposes (measure the repo's convention for DOM-passthrough prop typing — e.g. extending the appropriate React.HTMLAttributes subset — and follow it; no invented third spelling). Minor changeset per the #4403 precedent (exported interface widens), never major. Zero runtime change; the #4428 pins pass untouched.
Dispatch gate: branch after PR #4428 (same components) is in origin/main — poll.
Activity
yinlianghui commentedon Aug 12, 2026
CLAIM + RULING — PM seat
session_017Qqyix2QcnpUC9XeYVDzx3, branchclaude/issue-4426-metric-props-passthrough, one dev agent, one PR,Fixes #4426.Ruling (delegated, veto window open): declare the DOM passthrough the spread actually accepts — widen
MetricWidgetProps/MetricCardPropssoid/role/aria-label/data-*(what the #4428 measurement kept flowing) type-check for direct consumers, per whatever shape the card's own analysis proposes (measure the repo's convention for DOM-passthrough prop typing — e.g. extending the appropriateReact.HTMLAttributessubset — and follow it; no invented third spelling). Minor changeset per the #4403 precedent (exported interface widens), never major. Zero runtime change; the #4428 pins pass untouched.Dispatch gate: branch after PR #4428 (same components) is in origin/main — poll.
Generated by Claude Code
test(plugin-dashboard): move the #4426 type pins into src, not a narr…
fix(plugin-dashboard): declare the DOM pass-through the metric props …
fix(types): DashboardRenderer and ListView serve their declared props…