Wire plugin marketplace search to filter the grid

Replaces the static "Install plugin · N active" hero button with the
design's pair: a glass search input + a primary Install action. The
input is bound to a new InputState on ElyShell (plugin_search_input);
on every render the catalog reads its current value and filters the
plugin grid by case-insensitive contains on name, author, and
description. An empty-needle render shows every installed plugin so
the page still works at rest.

When the search yields no matches, the grid swaps to an empty-state
copy that quotes the user's needle. Install action moves into a
trailing dark chip that calls choose_plugin_package, preserving the
existing file-picker flow.
This commit is contained in:
2026-05-09 19:30:17 -04:00
parent 6419609eba
commit 70b50f9852
2 changed files with 169 additions and 83 deletions
+4
View File
@@ -62,6 +62,7 @@ pub struct ElyShell {
state: ShellState,
focus_handle: FocusHandle,
command_input: Entity<InputState>,
pub(crate) plugin_search_input: Entity<InputState>,
download_action_error: Option<String>,
download_clear_confirmation: bool,
download_security_confirmation: Option<PendingDownloadFileAction>,
@@ -104,6 +105,8 @@ impl ElyShell {
) -> Self {
let command_input =
cx.new(|cx| InputState::new(window, cx).placeholder("Search or enter address"));
let plugin_search_input =
cx.new(|cx| InputState::new(window, cx).placeholder("Search plugins…"));
let command_subscription = cx.subscribe_in(
&command_input,
@@ -151,6 +154,7 @@ impl ElyShell {
state,
focus_handle: cx.focus_handle(),
command_input,
plugin_search_input,
download_action_error: None,
download_clear_confirmation: false,
download_security_confirmation: None,