Add search to List example. (#168)

- Fix drawer, modal open to focus on first input.
This commit is contained in:
Jason Lee 2024-08-19 16:13:14 +08:00 committed by GitHub
parent b3bee1db3a
commit 7a00e8a68e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 36 additions and 24 deletions

View file

@ -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<Company>,
matched_companies: Vec<Company>,
selected_index: usize,
confirmed_index: Option<usize>,
}
impl ListDelegate for CompanyListDelegate {
type Item = CompanyListItem;
fn items_count(&self) -> usize {
self.companies.len()
self.matched_companies.len()
}
fn confirmed_index(&self) -> Option<usize> {
Some(self.selected_index)
self.confirmed_index
}
fn perform_search(&mut self, query: &str, _: &mut ViewContext<List<Self>>) -> 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<usize>, cx: &mut ViewContext<List<Self>>) {
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<usize>, cx: &mut ViewContext<List<Self>>) {
@ -162,8 +175,8 @@ impl ListDelegate for CompanyListDelegate {
}
fn render_item(&self, ix: usize, _cx: &mut ViewContext<List<Self>>) -> Option<Self::Item> {
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

View file

@ -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();
})),
)
})
});
}
}

View file

@ -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<Self>) {
fn on_action_cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
self.set_selected_index(None, cx);
self.delegate.cancel(cx);
cx.notify();
}
fn action_confirm(&mut self, _: &Confirm, cx: &mut ViewContext<Self>) {
fn on_action_confirm(&mut self, _: &Confirm, cx: &mut ViewContext<Self>) {
if self.delegate.items_count() == 0 {
return;
}
@ -239,7 +239,7 @@ where
cx.notify();
}
fn action_select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext<Self>) {
fn on_action_select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext<Self>) {
if self.delegate.items_count() == 0 {
return;
}
@ -255,7 +255,7 @@ where
cx.notify();
}
fn action_select_next(&mut self, _: &SelectNext, cx: &mut ViewContext<Self>) {
fn on_action_select_next(&mut self, _: &SelectNext, cx: &mut ViewContext<Self>) {
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);
}),
)
})