From 79c5a03a6b142e019a0d92b3b7a01207bb30005b Mon Sep 17 00:00:00 2001 From: Bao <72965498+wBaob@users.noreply.github.com> Date: Sun, 1 Nov 2026 22:01:39 +0500 Subject: [PATCH] Respect canceled token removal key events --- .changeset/token-cancel-keyboard-removal.md | 5 +++++ packages/react/src/Token/TokenBase.tsx | 4 ++++ .../react/src/Token/__tests__/Token.test.tsx | 22 +++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 .changeset/token-cancel-keyboard-removal.md diff --git a/.changeset/token-cancel-keyboard-removal.md b/.changeset/token-cancel-keyboard-removal.md new file mode 100644 index 00000000000..2687d83cae4 --- /dev/null +++ b/.changeset/token-cancel-keyboard-removal.md @@ -0,0 +1,5 @@ +--- +'@primer/react': patch +--- + +Token, IssueLabelToken: Respect canceled keyboard events when removing tokens with Backspace or Delete. diff --git a/packages/react/src/Token/TokenBase.tsx b/packages/react/src/Token/TokenBase.tsx index 03202c6f0cb..89ab5270f9d 100644 --- a/packages/react/src/Token/TokenBase.tsx +++ b/packages/react/src/Token/TokenBase.tsx @@ -60,6 +60,10 @@ const TokenBase = React.forwardRef) => { onKeyDown && onKeyDown(event) + if (event.defaultPrevented) { + return + } + if ((event.key === 'Backspace' || event.key === 'Delete') && onRemove) { onRemove() } diff --git a/packages/react/src/Token/__tests__/Token.test.tsx b/packages/react/src/Token/__tests__/Token.test.tsx index 73c01124c2a..edccf817c75 100644 --- a/packages/react/src/Token/__tests__/Token.test.tsx +++ b/packages/react/src/Token/__tests__/Token.test.tsx @@ -70,6 +70,28 @@ const testTokenComponent = (Component: React.ComponentType { + const onRemove = vi.fn() + const onKeyDown = vi.fn((event: React.KeyboardEvent) => event.preventDefault()) + const {getByText} = HTMLRender() + + fireEvent.keyDown(getByText('token'), {key}) + + expect(onKeyDown).toHaveBeenCalledTimes(1) + expect(onRemove).not.toHaveBeenCalled() + }) + + it.each(['Backspace', 'Delete'])('removes with %s when onKeyDown does not cancel the event', key => { + const onRemove = vi.fn() + const onKeyDown = vi.fn() + const {getByText} = HTMLRender() + + fireEvent.keyDown(getByText('token'), {key}) + + expect(onKeyDown).toHaveBeenCalledTimes(1) + expect(onRemove).toHaveBeenCalledTimes(1) + }) + it('renders with correct data-cursor-is-interactive attribute for button element', () => { const {getByText} = HTMLRender() const domNode = getByText('token')