From d0e94e34e5afcecbf67c321bc363f4bd427d02f9 Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Mon, 18 May 2026 12:49:26 +0530 Subject: [PATCH 1/2] fix: showClearButton --- .../data-table/__tests__/data-table.test.tsx | 21 +++++++++++ .../data-table/components/search.tsx | 2 +- .../data-view-beta/components/search.tsx | 2 +- .../search/__tests__/search.test.tsx | 4 +- .../components/search/search.module.css | 4 ++ .../raystack/components/search/search.tsx | 37 +++++++++---------- 6 files changed, 47 insertions(+), 23 deletions(-) diff --git a/packages/raystack/components/data-table/__tests__/data-table.test.tsx b/packages/raystack/components/data-table/__tests__/data-table.test.tsx index 0094d290c..f1b6d83d3 100644 --- a/packages/raystack/components/data-table/__tests__/data-table.test.tsx +++ b/packages/raystack/components/data-table/__tests__/data-table.test.tsx @@ -187,6 +187,27 @@ describe('DataTable', () => { expect(screen.getByLabelText('Search')).toBeInTheDocument(); }); + + it('clears the search input when the clear button is clicked', async () => { + const user = userEvent.setup(); + render( + + + + + ); + + const input = screen.getByLabelText('Search') as HTMLInputElement; + await user.type(input, 'hello'); + expect(input.value).toBe('hello'); + + await user.click(screen.getByLabelText('Clear search')); + expect(input.value).toBe(''); + }); }); describe('Zero State and Empty State', () => { diff --git a/packages/raystack/components/data-table/components/search.tsx b/packages/raystack/components/data-table/components/search.tsx index a7b909d5d..e91b0e05f 100644 --- a/packages/raystack/components/data-table/components/search.tsx +++ b/packages/raystack/components/data-table/components/search.tsx @@ -54,7 +54,7 @@ export function TableSearch({ diff --git a/packages/raystack/components/data-view-beta/components/search.tsx b/packages/raystack/components/data-view-beta/components/search.tsx index 330692689..546fd57e3 100644 --- a/packages/raystack/components/data-view-beta/components/search.tsx +++ b/packages/raystack/components/data-view-beta/components/search.tsx @@ -54,7 +54,7 @@ export function DataViewSearch({ diff --git a/packages/raystack/components/search/__tests__/search.test.tsx b/packages/raystack/components/search/__tests__/search.test.tsx index ed9430f00..6321f2fdd 100644 --- a/packages/raystack/components/search/__tests__/search.test.tsx +++ b/packages/raystack/components/search/__tests__/search.test.tsx @@ -85,9 +85,9 @@ describe('Search', () => { expect(screen.getByLabelText('Clear search')).toBeInTheDocument(); }); - it('hides clear button when no value', () => { + it('renders clear button regardless of value (CSS hides it when empty)', () => { render(); - expect(screen.queryByLabelText('Clear search')).not.toBeInTheDocument(); + expect(screen.getByLabelText('Clear search')).toBeInTheDocument(); }); it('calls onClear when clear button clicked', () => { diff --git a/packages/raystack/components/search/search.module.css b/packages/raystack/components/search/search.module.css index ae18df8cd..8925c770b 100644 --- a/packages/raystack/components/search/search.module.css +++ b/packages/raystack/components/search/search.module.css @@ -13,6 +13,10 @@ justify-content: center; } +.container:has(input:placeholder-shown) .clearButtonWrapper { + display: none; +} + .clearButton { color: var(--rs-color-foreground-base-tertiary); } diff --git a/packages/raystack/components/search/search.tsx b/packages/raystack/components/search/search.tsx index 63335eeab..807ca7f1b 100644 --- a/packages/raystack/components/search/search.tsx +++ b/packages/raystack/components/search/search.tsx @@ -24,25 +24,24 @@ export function Search({ variant = 'default', ...props }: SearchProps) { - const trailingIconWithClear = - showClearButton && value ? ( -
- { - e.stopPropagation(); - if (!disabled && onClear) { - onClear(); - } - }} - disabled={disabled} - aria-label='Clear search' - className={styles.clearButton} - > - - -
- ) : undefined; + const trailingIconWithClear = showClearButton ? ( +
+ { + e.stopPropagation(); + if (!disabled && onClear) { + onClear(); + } + }} + disabled={disabled} + aria-label='Clear search' + className={styles.clearButton} + > + + +
+ ) : undefined; return (
From ddfd3ed0dcc799ea560bd667d0857456bf664a42 Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Mon, 18 May 2026 13:35:56 +0530 Subject: [PATCH 2/2] fix: search style --- apps/www/src/components/datatable-demo.tsx | 25 ++++++++++++++++++- apps/www/src/components/demo/demo.tsx | 7 +++++- .../content/docs/components/datatable/demo.ts | 23 +++++++++++++++++ .../docs/components/datatable/index.mdx | 4 ++- .../components/input/input.module.css | 1 - 5 files changed, 56 insertions(+), 4 deletions(-) diff --git a/apps/www/src/components/datatable-demo.tsx b/apps/www/src/components/datatable-demo.tsx index 482158948..1eccfd3c5 100644 --- a/apps/www/src/components/datatable-demo.tsx +++ b/apps/www/src/components/datatable-demo.tsx @@ -146,4 +146,27 @@ const DataTableVirtualizedDemo = () => { ); }; -export { DataTableDemo, DataTableVirtualizedDemo }; +const DataTableSearchDemo = () => { + const data = useMemo(() => generateData(50), []); + + return ( + + + + + + + ); +}; + +export { DataTableDemo, DataTableSearchDemo, DataTableVirtualizedDemo }; diff --git a/apps/www/src/components/demo/demo.tsx b/apps/www/src/components/demo/demo.tsx index 5db96e688..4d9b8978a 100644 --- a/apps/www/src/components/demo/demo.tsx +++ b/apps/www/src/components/demo/demo.tsx @@ -36,7 +36,11 @@ import dayjs from 'dayjs'; import { Home, Info, Laugh, X } from 'lucide-react'; import NextLink from 'next/link'; import { Suspense } from 'react'; -import { DataTableDemo, DataTableVirtualizedDemo } from '../datatable-demo'; +import { + DataTableDemo, + DataTableSearchDemo, + DataTableVirtualizedDemo +} from '../datatable-demo'; import DataTableSelectionDemo from '../datatable-selection-demo'; import ChipInputDemo from '../inputfield-chip-demo'; import LinearMenuDemo from '../linear-dropdown-demo'; @@ -56,6 +60,7 @@ export default function Demo(props: DemoProps) { OrganizationIcon, SidebarIcon, DataTableDemo, + DataTableSearchDemo, DataTableVirtualizedDemo, ChipInputDemo, DataTableSelectionDemo, diff --git a/apps/www/src/content/docs/components/datatable/demo.ts b/apps/www/src/content/docs/components/datatable/demo.ts index cda0902ae..8d2ab6332 100644 --- a/apps/www/src/content/docs/components/datatable/demo.ts +++ b/apps/www/src/content/docs/components/datatable/demo.ts @@ -49,6 +49,29 @@ export const virtualizedPreview = { ] }; +export const searchPreview = { + type: 'code', + style: { + padding: 0 + }, + previewCode: false, + code: ``, + codePreview: [ + { + label: 'index.tsx', + code: ` + + + + ` + } + ] +}; + export const rowSelectionDemo = { type: 'code', previewCode: false, diff --git a/apps/www/src/content/docs/components/datatable/index.mdx b/apps/www/src/content/docs/components/datatable/index.mdx index 89ffe8833..5944d0e75 100644 --- a/apps/www/src/content/docs/components/datatable/index.mdx +++ b/apps/www/src/content/docs/components/datatable/index.mdx @@ -4,7 +4,7 @@ description: An advanced React table that supports filtering, sorting, and pagin source: packages/raystack/components/datatable --- -import { preview, virtualizedPreview, rowSelectionDemo } from "./demo.ts"; +import { preview, virtualizedPreview, searchPreview, rowSelectionDemo } from "./demo.ts"; @@ -329,6 +329,8 @@ onColumnVisibilityChange={handleColumnVisibilityChange}> The `DataTable.Search` component provides search functionality that automatically integrates with the table query. By default, it is disabled in zero state (when no data and no filters/search applied). + + ```tsx