From 2b971b6249a5807a902200fc3f803be1becb771d Mon Sep 17 00:00:00 2001 From: Matt Rothenberg Date: Thu, 17 Sep 2026 13:15:15 -0400 Subject: [PATCH] fix(button-group): preserve open trigger corners --- .changeset/tidy-buttons-smile.md | 5 +++++ .../components/button-group/button-group.test.tsx | 13 +++++++++++++ .../src/components/button-group/button-group.tsx | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 .changeset/tidy-buttons-smile.md diff --git a/.changeset/tidy-buttons-smile.md b/.changeset/tidy-buttons-smile.md new file mode 100644 index 0000000000..789bc4b857 --- /dev/null +++ b/.changeset/tidy-buttons-smile.md @@ -0,0 +1,5 @@ +--- +"@cloudflare/kumo": patch +--- + +Preserve ButtonGroup's outer corners while an overlay control is open. diff --git a/packages/kumo/src/components/button-group/button-group.test.tsx b/packages/kumo/src/components/button-group/button-group.test.tsx index 3ed7449103..a76de92420 100644 --- a/packages/kumo/src/components/button-group/button-group.test.tsx +++ b/packages/kumo/src/components/button-group/button-group.test.tsx @@ -62,6 +62,19 @@ describe("ButtonGroup", () => { expect(screen.getByRole("group").className).toContain("flex-row"); }); + it("ignores non-control siblings mounted by an open overlay", () => { + render( + + + + + , + ); + expect(screen.getByRole("group").className).toContain( + "[&>*:is(button,a):has(~_:is(button,a))]:rounded-e-none", + ); + }); + it("uses logical child-position selectors to join controls", () => { render( diff --git a/packages/kumo/src/components/button-group/button-group.tsx b/packages/kumo/src/components/button-group/button-group.tsx index c9ae60ea3a..f217841172 100644 --- a/packages/kumo/src/components/button-group/button-group.tsx +++ b/packages/kumo/src/components/button-group/button-group.tsx @@ -27,7 +27,7 @@ export const KUMO_BUTTON_GROUP_STYLING = { // and LinkButton groups retain the correct outer corners. The one-level // descendant selectors support Button's tooltip wrapper. "[&>*:not(:first-child):is(button,a)]:rounded-s-none", - "[&>*:not(:last-child):is(button,a)]:rounded-e-none", + "[&>*:is(button,a):has(~_:is(button,a))]:rounded-e-none", "[&>*:not(:first-child)>:is(button,a)]:rounded-s-none", "[&>*:not(:last-child)>:is(button,a)]:rounded-e-none", // Overlap borders/rings by 1px so adjacent buttons share a single seam