From 0e6e56696923053b97efaa2ee58ccb0455f3d299 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Fri, 28 Aug 2026 03:48:53 +0000
Subject: [PATCH] feat(ux): add clear button to filter input in shortcuts
dialog
Co-authored-by: d-oit <6849456+d-oit@users.noreply.github.com>
---
next-env.d.ts | 2 +-
.../studio/shortcuts-dialog.test.tsx | 42 +++++++++++++++++--
src/components/studio/shortcuts-dialog.tsx | 19 ++++++++-
3 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/next-env.d.ts b/next-env.d.ts
index 9edff1c7..c4b7818f 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,6 +1,6 @@
///
///
-import "./.next/types/routes.d.ts";
+import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/src/components/studio/shortcuts-dialog.test.tsx b/src/components/studio/shortcuts-dialog.test.tsx
index 026195c4..eabd012b 100644
--- a/src/components/studio/shortcuts-dialog.test.tsx
+++ b/src/components/studio/shortcuts-dialog.test.tsx
@@ -27,7 +27,7 @@ vi.mock('@/lib/studio/use-reduced-motion', () => ({
}))
vi.mock('@/components/studio/ui/shared-primitives', () => ({
- Overlay: ({ children, open, onClose, 'aria-label': ariaLabel }: {
+ Overlay: ({ children, open, 'aria-label': ariaLabel }: {
children: ReactNode
open: boolean
onClose: () => void
@@ -38,7 +38,7 @@ vi.mock('@/components/studio/ui/shared-primitives', () => ({
className?: string
}) =>
open ? (
-
+
{children}
) : null,
@@ -62,7 +62,43 @@ vi.mock('@/lib/studio/store', () => ({
),
}))
-import { ShortcutsTrigger } from './shortcuts-dialog'
+import { ShortcutsDialog, ShortcutsTrigger } from './shortcuts-dialog'
+
+describe('ShortcutsDialog', () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ })
+
+ it('renders filter search clear button when text is entered and clears input on click', () => {
+ render(
+ <>
+
+
+ >,
+ )
+
+ // Open the dialog
+ fireEvent.click(screen.getByLabelText('Show keyboard shortcuts'))
+
+ const filterInput = screen.getByLabelText('Filter shortcuts') as HTMLInputElement
+ expect(filterInput.value).toBe('')
+ expect(screen.queryByLabelText('Clear filter search')).toBeNull()
+
+ // Type filter text
+ fireEvent.change(filterInput, { target: { value: 'Bold' } })
+ expect(filterInput.value).toBe('Bold')
+
+ // Clear button should now be visible
+ const clearBtn = screen.getByLabelText('Clear filter search')
+ expect(clearBtn).toBeDefined()
+ expect(clearBtn.getAttribute('title')).toBe('Clear filter search')
+
+ // Click clear button (prevent default / click handlers on buttons contained inside mocked Overlay)
+ fireEvent.click(clearBtn)
+ expect(filterInput.value).toBe('')
+ expect(screen.queryByLabelText('Clear filter search')).toBeNull()
+ })
+})
describe('ShortcutsTrigger', () => {
beforeEach(() => {
diff --git a/src/components/studio/shortcuts-dialog.tsx b/src/components/studio/shortcuts-dialog.tsx
index 9aaaf499..f7f00838 100644
--- a/src/components/studio/shortcuts-dialog.tsx
+++ b/src/components/studio/shortcuts-dialog.tsx
@@ -274,9 +274,26 @@ export function ShortcutsDialog() {
value={filter}
onChange={(e) => { setFilter(e.target.value); }}
placeholder="Filter shortcuts..."
- className="w-full rounded-md border border-border bg-background py-1.5 pl-8 pr-3 text-body-sm text-ink placeholder:text-ink-faint focus:border-saffron focus:outline-none focus:ring-1 focus:ring-saffron/30"
+ className={cn(
+ 'w-full rounded-md border border-border bg-background py-1.5 pl-8 text-body-sm text-ink placeholder:text-ink-faint focus:border-saffron focus:outline-none focus:ring-1 focus:ring-saffron/30',
+ filter ? 'pr-8' : 'pr-3',
+ )}
aria-label="Filter shortcuts"
/>
+ {filter && (
+
+ )}