Add search to List example. (#168)
- Fix drawer, modal open to focus on first input.
This commit is contained in:
parent
b3bee1db3a
commit
7a00e8a68e
3 changed files with 36 additions and 24 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
})),
|
||||
)
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue