Skip to content

Commit 11f7bc0

Browse files
fix(apollo-react): default add-node search placeholder to "Search nodes" [MST-11831]
1 parent 2b4b4c5 commit 11f7bc0

6 files changed

Lines changed: 52 additions & 2 deletions

File tree

packages/apollo-react/src/canvas/components/AddNodePanel/AddNodePanel.test.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ vi.mock('../Toolbox', () => ({
2222
onClose,
2323
onItemSelect,
2424
renderEmptyState,
25+
searchPlaceholder,
2526
}: ToolboxProps<NodeItemData>) => (
2627
<div data-testid="toolbox-mock">
2728
<div data-testid="toolbox-title">{title}</div>
29+
<div data-testid="toolbox-search-placeholder">{searchPlaceholder}</div>
2830
<div data-testid="toolbox-items">{JSON.stringify(initialItems)}</div>
2931
<button type="button" data-testid="toolbox-close" onClick={onClose}>
3032
Close
@@ -121,6 +123,26 @@ describe('AddNodePanel', () => {
121123
expect(screen.getByTestId('toolbox-title')).toHaveTextContent('Add node');
122124
});
123125

126+
it('should default the search placeholder to "Search nodes"', () => {
127+
render(
128+
<NodeRegistryProvider manifest={mockManifest}>
129+
<AddNodePanel {...defaultProps} />
130+
</NodeRegistryProvider>
131+
);
132+
133+
expect(screen.getByTestId('toolbox-search-placeholder')).toHaveTextContent('Search nodes');
134+
});
135+
136+
it('should forward a custom searchPlaceholder to Toolbox', () => {
137+
render(
138+
<NodeRegistryProvider manifest={mockManifest}>
139+
<AddNodePanel {...defaultProps} searchPlaceholder="Search agents" />
140+
</NodeRegistryProvider>
141+
);
142+
143+
expect(screen.getByTestId('toolbox-search-placeholder')).toHaveTextContent('Search agents');
144+
});
145+
124146
it('should transform empty registry into empty list items', () => {
125147
render(
126148
<NodeRegistryProvider manifest={{ version: '1.0.0', categories: [], nodes: [] }}>

packages/apollo-react/src/canvas/components/AddNodePanel/AddNodePanel.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { memo, useCallback, useMemo } from 'react';
2+
import { useSafeLingui } from '../../../i18n';
23
import { useOptionalNodeTypeRegistry } from '../../core';
34
import { usePreviewNode } from '../../hooks';
45
import { type ListItem, Toolbox } from '../Toolbox';
@@ -21,7 +22,9 @@ export const AddNodePanel = memo(function AddNodePanel({
2122
title,
2223
loading,
2324
renderEmptyState,
25+
searchPlaceholder,
2426
}: AddNodePanelProps) {
27+
const { _ } = useSafeLingui();
2528
const registry = useOptionalNodeTypeRegistry();
2629
const { previewNodeConnectionInfo } = usePreviewNode();
2730

@@ -87,6 +90,9 @@ export const AddNodePanel = memo(function AddNodePanel({
8790
onClose={onClose}
8891
onItemHover={onNodeHover}
8992
renderEmptyState={renderEmptyState}
93+
searchPlaceholder={
94+
searchPlaceholder ?? _({ id: 'add-node-panel.search-nodes', message: 'Search nodes' })
95+
}
9096
/>
9197
);
9298
});

packages/apollo-react/src/canvas/components/AddNodePanel/AddNodePanel.types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ export interface AddNodePanelProps {
2929
* When provided, replaces the built-in icon + message empty state.
3030
*/
3131
renderEmptyState?: ToolboxEmptyStateRenderer<NodeItemData>;
32+
/**
33+
* Placeholder for the search input. Should describe what will be searched,
34+
* such as "Search agents". Defaults to "Search nodes".
35+
*/
36+
searchPlaceholder?: string;
3237
}

packages/apollo-react/src/canvas/components/Toolbox/Toolbox.test.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ describe('Toolbox', () => {
4747
expect(screen.getByPlaceholderText('Search')).toBeInTheDocument();
4848
});
4949

50+
it('should render a custom search placeholder when provided', () => {
51+
render(<Toolbox {...defaultProps} searchPlaceholder="Search nodes" />);
52+
53+
expect(screen.getByPlaceholderText('Search nodes')).toBeInTheDocument();
54+
expect(screen.queryByPlaceholderText('Search')).not.toBeInTheDocument();
55+
});
56+
5057
it('should render all items in ListView', () => {
5158
render(<Toolbox {...defaultProps} />);
5259

packages/apollo-react/src/canvas/components/Toolbox/Toolbox.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ export interface ToolboxProps<T> {
8080
onItemHover?: (item: ListItem<T>) => void;
8181
onBack?: () => void;
8282
onSearch?: ToolboxSearchHandler<T>;
83+
/**
84+
* Placeholder for the search input. Should describe what will be searched,
85+
* such as "Search nodes". Defaults to a generic "Search".
86+
*/
87+
searchPlaceholder?: string;
8388
/**
8489
* Optional row of icon shortcuts rendered above the title. Apollo controls
8590
* the visuals so the strip stays consistent across consumers; pass the
@@ -155,9 +160,10 @@ export function Toolbox<T>({
155160
fullHeight = false,
156161
quickActions,
157162
renderEmptyState,
163+
searchPlaceholder: searchPlaceholderProp,
158164
}: ToolboxProps<T>) {
159165
const { _ } = useSafeLingui();
160-
const searchPlaceholder = _({ id: 'toolbox.search', message: 'Search' });
166+
const searchPlaceholder = searchPlaceholderProp ?? _({ id: 'toolbox.search', message: 'Search' });
161167
const [items, setItems] = useState<ListItem<T>[]>(initialItems);
162168
const [search, setSearch] = useState('');
163169
const [searchLoading, setSearchLoading] = useState(false);
@@ -203,7 +209,10 @@ export function Toolbox<T>({
203209
const wrappedRenderEmptyState = useMemo(
204210
() =>
205211
renderEmptyState && !isSearching
206-
? () => renderEmptyState({ currentCategory: currentParentItem ?? undefined })
212+
? () =>
213+
renderEmptyState({
214+
currentCategory: currentParentItem ?? undefined,
215+
})
207216
: undefined,
208217
[renderEmptyState, isSearching, currentParentItem]
209218
);

packages/apollo-react/src/canvas/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"sticky-note.toolbar.color": "Color",
4545
"sticky-note.toolbar.delete": "Delete",
4646
"sticky-note.toolbar.edit": "Edit",
47+
"add-node-panel.search-nodes": "Search nodes",
4748
"toolbox.search": "Search",
4849
"loop-node.add-node": "Add node to loop",
4950
"loop-node.mode.parallel": "Parallel",

0 commit comments

Comments
 (0)