From 7a00e8a68e1febb9c3d52adeb3f9db524b7d609f Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Mon, 19 Aug 2024 16:13:14 +0800 Subject: [PATCH] Add search to List example. (#168) - Fix drawer, modal open to focus on first input. --- crates/story/src/list_story.rs | 32 +++++++++++++++++++++++--------- crates/story/src/modal_story.rs | 8 +++----- crates/ui/src/list/list.rs | 20 ++++++++++---------- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/crates/story/src/list_story.rs b/crates/story/src/list_story.rs index 22d83b82..c5609f29 100644 --- a/crates/story/src/list_story.rs +++ b/crates/story/src/list_story.rs @@ -3,7 +3,7 @@ use core::time; use fake::Fake; use gpui::{ actions, div, px, ElementId, FocusHandle, FocusableView, InteractiveElement, IntoElement, - ParentElement, Render, RenderOnce, Styled, Timer, View, ViewContext, VisualContext, + ParentElement, Render, RenderOnce, Styled, Task, Timer, View, ViewContext, VisualContext, WindowContext, }; @@ -133,25 +133,38 @@ impl RenderOnce for CompanyListItem { struct CompanyListDelegate { companies: Vec, + matched_companies: Vec, selected_index: usize, + confirmed_index: Option, } impl ListDelegate for CompanyListDelegate { type Item = CompanyListItem; fn items_count(&self) -> usize { - self.companies.len() + self.matched_companies.len() } fn confirmed_index(&self) -> Option { - Some(self.selected_index) + self.confirmed_index + } + + fn perform_search(&mut self, query: &str, _: &mut ViewContext>) -> Task<()> { + self.matched_companies = self + .companies + .iter() + .filter(|company| company.name.to_lowercase().contains(&query.to_lowercase())) + .cloned() + .collect(); + + Task::Ready(Some(())) } fn confirm(&mut self, ix: Option, cx: &mut ViewContext>) { - if let Some(ix) = ix { - self.selected_index = ix; + self.confirmed_index = ix; + if let Some(_) = ix { + cx.dispatch_action(Box::new(SelectedCompany)); } - cx.dispatch_action(Box::new(SelectedCompany)); } fn set_selected_index(&mut self, ix: Option, cx: &mut ViewContext>) { @@ -162,8 +175,8 @@ impl ListDelegate for CompanyListDelegate { } fn render_item(&self, ix: usize, _cx: &mut ViewContext>) -> Option { - let selected = ix == self.selected_index; - if let Some(company) = self.companies.get(ix) { + let selected = ix == self.selected_index || Some(ix) == self.confirmed_index; + if let Some(company) = self.matched_companies.get(ix) { return Some(CompanyListItem::new(ix, company.clone(), ix, selected)); } @@ -196,12 +209,13 @@ impl ListStory { let company_list = cx.new_view(|cx| { List::new( CompanyListDelegate { + matched_companies: companies.clone(), companies, selected_index: 0, + confirmed_index: None, }, cx, ) - .no_query() }); // Spawn a background to random refresh the list diff --git a/crates/story/src/modal_story.rs b/crates/story/src/modal_story.rs index cda52a35..179c15fc 100644 --- a/crates/story/src/modal_story.rs +++ b/crates/story/src/modal_story.rs @@ -254,9 +254,8 @@ impl ModalStory { }; let overlay = self.modal_overlay; + input.focus_handle(cx).focus(cx); cx.open_drawer(move |this, cx| { - input.focus_handle(cx).focus(cx); - this.margin_top(px(33.)) .placement(placement) .overlay(overlay) @@ -307,9 +306,8 @@ impl ModalStory { let date_picker = self.date_picker.clone(); let view = cx.view().clone(); + input1.focus_handle(cx).focus(cx); cx.open_modal(move |modal, cx| { - input1.focus_handle(cx).focus(cx); - modal .margin_top(px(33.)) .title("Form Modal") @@ -357,7 +355,7 @@ impl ModalStory { cx.close_modal(); })), ) - }) + }); } } diff --git a/crates/ui/src/list/list.rs b/crates/ui/src/list/list.rs index da1764da..745839e2 100644 --- a/crates/ui/src/list/list.rs +++ b/crates/ui/src/list/list.rs @@ -211,7 +211,7 @@ where }); }); } - InputEvent::PressEnter => self.action_confirm(&Confirm, cx), + InputEvent::PressEnter => self.on_action_confirm(&Confirm, cx), _ => {} } } @@ -224,13 +224,13 @@ where cx.notify(); } - fn action_cancel(&mut self, _: &Cancel, cx: &mut ViewContext) { + fn on_action_cancel(&mut self, _: &Cancel, cx: &mut ViewContext) { self.set_selected_index(None, cx); self.delegate.cancel(cx); cx.notify(); } - fn action_confirm(&mut self, _: &Confirm, cx: &mut ViewContext) { + fn on_action_confirm(&mut self, _: &Confirm, cx: &mut ViewContext) { if self.delegate.items_count() == 0 { return; } @@ -239,7 +239,7 @@ where cx.notify(); } - fn action_select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext) { + fn on_action_select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext) { if self.delegate.items_count() == 0 { return; } @@ -255,7 +255,7 @@ where cx.notify(); } - fn action_select_next(&mut self, _: &SelectNext, cx: &mut ViewContext) { + fn on_action_select_next(&mut self, _: &SelectNext, cx: &mut ViewContext) { if self.delegate.items_count() == 0 { return; } @@ -311,10 +311,10 @@ where .size_full() .relative() .overflow_hidden() - .on_action(cx.listener(Self::action_cancel)) - .on_action(cx.listener(Self::action_confirm)) - .on_action(cx.listener(Self::action_select_next)) - .on_action(cx.listener(Self::action_select_prev)) + .on_action(cx.listener(Self::on_action_cancel)) + .on_action(cx.listener(Self::on_action_confirm)) + .on_action(cx.listener(Self::on_action_select_next)) + .on_action(cx.listener(Self::on_action_select_prev)) .when_some(self.query_input.clone(), |this, input| { this.child( div() @@ -357,7 +357,7 @@ where cx.listener(move |this, _, cx| { cx.stop_propagation(); this.selected_index = Some(ix); - this.action_confirm(&Confirm, cx); + this.on_action_confirm(&Confirm, cx); }), ) })