Skip to content

Narrow the remaining Chat components to curated props - #440

Merged
czarandy merged 1 commit into
mainfrom
fix/chat-curated-props
Aug 6, 2026
Merged

Narrow the remaining Chat components to curated props#440
czarandy merged 1 commit into
mainfrom
fix/chat-curated-props

Conversation

@czarandy

@czarandy czarandy commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Fixes #439. Follow-up to #438, applying the same curated-props treatment to the rest of the Chat directory.

ChatPassthroughProps

The identity and description props every Chat container forwards to its root:

export interface ChatPassthroughProps {
  'aria-describedby'?: AriaAttributes['aria-describedby'];
  'aria-label'?: AriaAttributes['aria-label'];
  'aria-labelledby'?: AriaAttributes['aria-labelledby'];
  id?: string;
}

Applied to ChatLayout, ChatComposer, ChatMessage, ChatMessageList, ChatMessageBubble, ChatMessageMetadata, and ChatSystemMessage — replacing ComponentPropsWithoutRef<'div' | 'article'> in each.

ChatComposerInput is a textarea, so it extends the shared set with the text-input props a chat composer actually needs: autoComplete, enterKeyHint, maxLength, name, onBlur, onFocus, onPaste, and onKeyDown. That last one is worth flagging — the component already destructured and called onKeyDown, but only declared it via the wide extension, so narrowing without adding it explicitly would have broken the documented Enter-to-submit escape hatch.

Two behavior fixes that fall out of the narrowing

  • ChatMessage dropped consumer labels. It spread ...rest before its generated aria-label/aria-labelledby, so <ChatMessage aria-label="…"> was silently overridden. The consumer's value now wins and falls back to the generated one.
  • ChatMessageList hardcoded aria-live="polite" with no way to opt out. It's now a documented prop defaulting to polite, so a static transcript can pass aria-live="off".

Notes

  • spellCheck was on my shortlist for ChatComposerInput but the repo's boolean-prop-naming rule rejects it, and inventing a hasSpellCheck alias for one speculative prop didn't seem worth it. Easy to add if you want it.
  • This is a breaking change for anyone passing arbitrary DOM props to these components, same as Forward a shared set of button props across the *Button components #438 was for ChatScrollButton.

Tests

12 new tests: passthrough coverage per component, both ChatSystemMessage variants (it spreads in two branches), the consumer-label override on ChatMessage, the aria-live default and override, and the textarea's focus/blur/paste handlers.

Full suite passes (3197 tests), lint/typecheck/format clean.

https://claude.ai/code/session_01XFkkvUQfynGRedEYDNxKoY

The eight Chat components outside the button pair still extended
ComponentPropsWithoutRef and spread `...rest` onto their root, so they
accepted the whole DOM prop surface — including props that fight their
own contract (`role`, `aria-live`, `data-sender`) with no indication
which one wins.

Introduce `ChatPassthroughProps` — id plus the three aria naming and
description attributes — and extend each component with it, mirroring
`ButtonPassthroughProps` from #438. ChatComposerInput is a textarea, so
it adds the text-input props a chat composer actually needs on top:
autoComplete, enterKeyHint, maxLength, name, onBlur, onFocus, onPaste,
and onKeyDown (which the component already consumed but only declared
via the wide extension).

Two behavior fixes fall out of the narrowing:

- ChatMessage spread `...rest` before its generated `aria-label` /
  `aria-labelledby`, so a consumer label was silently dropped. The
  consumer's value now wins and falls back to the generated one.
- ChatMessageList hardcoded `aria-live="polite"` with no way to opt
  out; it is now a prop defaulting to `polite`.

Fixes #439

Claude-Session: https://claude.ai/code/session_01XFkkvUQfynGRedEYDNxKoY
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
silver-ui-site Ready Ready Preview Aug 6, 2026 2:59pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
silver-ui Ignored Ignored Aug 6, 2026 2:59pm

@czarandy
czarandy merged commit 65d43a7 into main Aug 6, 2026
4 checks passed
@czarandy
czarandy deleted the fix/chat-curated-props branch August 6, 2026 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Narrow the remaining Chat components to curated props

1 participant