From ea55dfd1722f386ff829aab935ea26176f39aba3 Mon Sep 17 00:00:00 2001 From: Joey Slater Date: Mon, 2 Jun 2025 23:24:35 -0400 Subject: [PATCH 1/3] pass onKeyDown to Link instead of swalloing the entire event --- package.json | 3 ++- src/common/utils/event/index.ts | 2 ++ src/ui/link/index.tsx | 2 ++ src/ui/link/test.tsx | 18 +++++++++++++++++- src/ui/link/utils/handle-navigation.tsx | 18 +++++++++++++++--- 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 95ae5e01..61ca3e86 100644 --- a/package.json +++ b/package.json @@ -140,5 +140,6 @@ }, "engines": { "node": ">=16.0" - } + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/src/common/utils/event/index.ts b/src/common/utils/event/index.ts index 5f10f93b..ee76c8fe 100644 --- a/src/common/utils/event/index.ts +++ b/src/common/utils/event/index.ts @@ -1,3 +1,5 @@ +import type { KeyboardEvent } from 'react'; + export const isModifiedEvent = (event: { [key: string]: any }) => !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); diff --git a/src/ui/link/index.tsx b/src/ui/link/index.tsx index 8e0997eb..52c3c001 100644 --- a/src/ui/link/index.tsx +++ b/src/ui/link/index.tsx @@ -31,6 +31,7 @@ const Link = forwardRef( href = undefined, to = undefined, onClick = undefined, + onKeyDown = undefined, onMouseEnter = undefined, onMouseLeave = undefined, onPointerDown = undefined, @@ -103,6 +104,7 @@ const Link = forwardRef( const handleLinkPress = (e: MouseEvent | KeyboardEvent) => handleNavigation(e, { onClick, + onKeyDown, target, replace, routerActions, diff --git a/src/ui/link/test.tsx b/src/ui/link/test.tsx index d6f518c8..7314f8aa 100644 --- a/src/ui/link/test.tsx +++ b/src/ui/link/test.tsx @@ -362,7 +362,9 @@ describe('', () => { describe('when the link has focus, and a keypress is fired', () => { it('should navigate if the key was an `enter`', async () => { const user = userEvent.setup(); - renderInRouter('my link', { href: newPath }); + const mockKeyHandler = jest.fn(); + + renderInRouter('my link', { href: newPath, onKeyDown: mockKeyHandler }); const linkElement = screen.getByRole('link', { name: 'my link' }); linkElement.focus(); @@ -370,6 +372,7 @@ describe('', () => { expect(HistoryMock.push).toHaveBeenCalledTimes(1); expect(HistoryMock.push).toHaveBeenCalledWith(newPath, undefined); + expect(mockKeyHandler).not.toHaveBeenCalled(); }); it('should not navigate for any other key', async () => { @@ -382,6 +385,19 @@ describe('', () => { expect(HistoryMock.push).not.toHaveBeenCalled(); }); + + it('should respect onKeyDown as long as it is not {Enter}', async () => { + const user = userEvent.setup(); + const mockKeyHandler = jest.fn(); + renderInRouter('my link', { href: newPath, onKeyDown: mockKeyHandler }); + + const linkElement = screen.getByRole('link', { name: 'my link' }); + linkElement.focus(); + await user.keyboard('{a}'); + + expect(HistoryMock.push).not.toHaveBeenCalled(); + expect(mockKeyHandler).toHaveBeenCalled(); + }); }); describe('when styles are passed into Link, element should be rendered with styles', () => { diff --git a/src/ui/link/utils/handle-navigation.tsx b/src/ui/link/utils/handle-navigation.tsx index 76eb3fef..07711889 100644 --- a/src/ui/link/utils/handle-navigation.tsx +++ b/src/ui/link/utils/handle-navigation.tsx @@ -1,6 +1,6 @@ -import { KeyboardEvent, MouseEvent } from 'react'; +import type { KeyboardEvent, MouseEvent } from 'react'; -import { Route } from '../../../common/types'; +import type { Route } from '../../../common/types'; import { isKeyboardEvent, isModifiedEvent } from '../../../common/utils/event'; type LinkNavigationEvent = MouseEvent | KeyboardEvent; @@ -16,15 +16,27 @@ type LinkPressArgs = { replace: boolean; href: string; onClick?: (e: LinkNavigationEvent) => void; + onKeyDown?: (e: KeyboardEvent) => void; to: [Route, any] | void; state?: unknown; }; export const handleNavigation = ( event: any, - { onClick, target, replace, routerActions, href, to, state }: LinkPressArgs + { + onClick, + onKeyDown, + target, + replace, + routerActions, + href, + to, + state, + }: LinkPressArgs ): void => { if (isKeyboardEvent(event) && event.key !== 'Enter') { + onKeyDown?.(event as KeyboardEvent); + return; } From ce323e9dde8e024540b52d57c2086091156e6b30 Mon Sep 17 00:00:00 2001 From: Joey Slater Date: Tue, 3 Jun 2025 10:15:07 -0400 Subject: [PATCH 2/3] remove corepack addition --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 61ca3e86..3df63b1c 100644 --- a/package.json +++ b/package.json @@ -140,6 +140,5 @@ }, "engines": { "node": ">=16.0" - }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" -} + } +} \ No newline at end of file From 476aae14c944f17292f76326713146523c2ecd29 Mon Sep 17 00:00:00 2001 From: Joey Slater Date: Tue, 3 Jun 2025 10:48:46 -0400 Subject: [PATCH 3/3] add changeset --- .changeset/fruity-bags-love.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fruity-bags-love.md diff --git a/.changeset/fruity-bags-love.md b/.changeset/fruity-bags-love.md new file mode 100644 index 00000000..347a0a04 --- /dev/null +++ b/.changeset/fruity-bags-love.md @@ -0,0 +1,5 @@ +--- +'react-resource-router': patch +--- + +pass down onKeyDown to Link