From 74a94a47c48a3db04359c8a28a8d4fa9e360d3d2 Mon Sep 17 00:00:00 2001 From: Andrey Goder Date: Thu, 6 Aug 2026 00:53:02 -0700 Subject: [PATCH] Forward a shared set of button props across the *Button components ChatSendButton was a closed props interface with no passthrough, so consumers could not attach `aria-describedby`, `aria-keyshortcuts`, `id`, `form`, or focus/keyboard handlers to it. ChatScrollButton had the opposite problem: it extended `ComponentPropsWithoutRef<'div'>` and spread arbitrary DOM props onto its wrapper. Introduce `ButtonPassthroughProps`, a curated `Pick` of `ButtonProps` covering identity, description, and interaction, and extend every button-like component with it so they all forward the same set to the button they render. Button itself gains the two members it was missing (`id`, `onFocus`); ActionElement already spread unlisted props, so it only needed the `onFocus` type. ChatScrollButton now forwards to the inner Button rather than the wrapper div, since that is the interactive element the props describe. Fixes #371 Claude-Session: https://claude.ai/code/session_01XFkkvUQfynGRedEYDNxKoY --- src/components/Button/Button.test.tsx | 23 ++++++++++++ src/components/Button/Button.tsx | 32 ++++++++++++++++ src/components/Button/index.ts | 1 + src/components/Chat/Chat.test.tsx | 25 +++++++++++++ src/components/Chat/ChatComposer.test.tsx | 37 +++++++++++++++++++ src/components/Chat/ChatScrollButton.tsx | 13 +++---- src/components/Chat/ChatSendButton.tsx | 6 ++- src/components/CopyButton/CopyButton.test.tsx | 25 +++++++++++++ src/components/CopyButton/CopyButton.tsx | 31 ++++++++++------ .../SplitButton/SplitButton.test.tsx | 23 ++++++++++++ src/components/SplitButton/SplitButton.tsx | 17 ++++++--- .../ToggleButton/ToggleButton.test.tsx | 22 +++++++++++ src/components/ToggleButton/ToggleButton.tsx | 6 ++- src/index.ts | 7 +++- src/internal/ActionElement.tsx | 2 + 15 files changed, 241 insertions(+), 29 deletions(-) diff --git a/src/components/Button/Button.test.tsx b/src/components/Button/Button.test.tsx index eec7cd4a..66539e13 100644 --- a/src/components/Button/Button.test.tsx +++ b/src/components/Button/Button.test.tsx @@ -599,4 +599,27 @@ describe('Button', () => { warn.mockRestore(); }); + + it('applies id and fires onFocus on both the button and the link', async () => { + const user = userEvent.setup(); + const onFocus = vi.fn(); + const {rerender} = render( +