Problem
The custom Button component (src/diagram/components/Button.tsx) destructures an explicit allowlist of props (variant, color, size, disabled, onClick, onMouseDown, className, style, startIcon, children, type, component, and three specific aria-* attributes) and does NOT spread the rest onto the rendered <button>. Any other prop is silently dropped.
Concretely, ModuleDetails.tsx (line ~288) passes data-testid="add-input-button" to Button, and that attribute never reaches the DOM:
TypeScript does not catch this because hyphenated JSX attributes (data-*, aria-*) are exempt from excess-property checking, so the API looks like it supports arbitrary DOM attributes but doesn't. Note the data-testid="model-ref-select" a few lines earlier in the same file works fine -- it's on a native <select> -- which makes the trap easy to fall into.
Why it matters
- Developer experience / test reliability: testids that appear to be wired up are no-ops, and
getByTestId failures push tests toward brittle visible-text matching.
- API honesty: the component library reads as if it accepts standard DOM attributes; the silent drop violates that expectation with no compile-time or runtime signal.
Scope
Not Button-specific: only 6 of the 24 components in src/diagram/components/ spread rest props (Autocomplete, IconButton, icons, Snackbar, SvgIcon, TextField); the rest use explicit allowlists with the same silent-drop behavior. Button is the one with a concrete dead attribute today.
Possible approaches
- Have
Button (and, for consistency, the other allowlist components) forward rest props onto the underlying element -- at minimum data-*/aria-*, or extend React.ButtonHTMLAttributes<HTMLButtonElement> and spread {...rest} after the handled props.
- Alternatively, remove the dead
data-testid from ModuleDetails.tsx and document that the component library takes explicit props only.
Option 1 matches how the components are actually used and is the smaller ongoing-maintenance surface.
Context
Component: src/diagram (component library). Severity: low. Discovered during the readOnlyMode capability-gate work for #935 (branch production-risk-burndown).
Problem
The custom
Buttoncomponent (src/diagram/components/Button.tsx) destructures an explicit allowlist of props (variant,color,size,disabled,onClick,onMouseDown,className,style,startIcon,children,type,component, and three specificaria-*attributes) and does NOT spread the rest onto the rendered<button>. Any other prop is silently dropped.Concretely,
ModuleDetails.tsx(line ~288) passesdata-testid="add-input-button"toButton, and that attribute never reaches the DOM:data-testidis dead code.TypeScript does not catch this because hyphenated JSX attributes (
data-*,aria-*) are exempt from excess-property checking, so the API looks like it supports arbitrary DOM attributes but doesn't. Note thedata-testid="model-ref-select"a few lines earlier in the same file works fine -- it's on a native<select>-- which makes the trap easy to fall into.Why it matters
getByTestIdfailures push tests toward brittle visible-text matching.Scope
Not Button-specific: only 6 of the 24 components in
src/diagram/components/spread rest props (Autocomplete, IconButton, icons, Snackbar, SvgIcon, TextField); the rest use explicit allowlists with the same silent-drop behavior. Button is the one with a concrete dead attribute today.Possible approaches
Button(and, for consistency, the other allowlist components) forward rest props onto the underlying element -- at minimumdata-*/aria-*, or extendReact.ButtonHTMLAttributes<HTMLButtonElement>and spread{...rest}after the handled props.data-testidfromModuleDetails.tsxand document that the component library takes explicit props only.Option 1 matches how the components are actually used and is the smaller ongoing-maintenance surface.
Context
Component:
src/diagram(component library). Severity: low. Discovered during the readOnlyMode capability-gate work for #935 (branchproduction-risk-burndown).