Style contact finder (#3717)
This PR styles the contact finder. <img width="598" alt="Screenshot 2023-12-19 at 12 59 00 PM" src="https://github.com/zed-industries/zed/assets/1486634/ca9d9345-bf27-4256-aabc-6017a0c4d217"> Release Notes: - N/A
This commit is contained in:
parent
ef39382c84
commit
a3bab25792
3 changed files with 40 additions and 79 deletions
|
@ -2204,14 +2204,9 @@ impl CollabPanel {
|
|||
.into_any_element()
|
||||
}),
|
||||
Section::Contacts => Some(
|
||||
div()
|
||||
.border_1()
|
||||
.border_color(gpui::red())
|
||||
.child(
|
||||
IconButton::new("add-contact", Icon::Plus)
|
||||
.on_click(cx.listener(|this, _, cx| this.toggle_contact_finder(cx)))
|
||||
.tooltip(|cx| Tooltip::text("Search for new contact", cx)),
|
||||
)
|
||||
IconButton::new("add-contact", Icon::Plus)
|
||||
.on_click(cx.listener(|this, _, cx| this.toggle_contact_finder(cx)))
|
||||
.tooltip(|cx| Tooltip::text("Search for new contact", cx))
|
||||
.into_any_element(),
|
||||
),
|
||||
Section::Channels => Some(
|
||||
|
|
|
@ -7,7 +7,7 @@ use gpui::{
|
|||
use picker::{Picker, PickerDelegate};
|
||||
use std::sync::Arc;
|
||||
use theme::ActiveTheme as _;
|
||||
use ui::{prelude::*, Avatar};
|
||||
use ui::{prelude::*, Avatar, ListItem};
|
||||
use util::{ResultExt as _, TryFutureExt};
|
||||
use workspace::ModalView;
|
||||
|
||||
|
@ -23,7 +23,7 @@ impl ContactFinder {
|
|||
potential_contacts: Arc::from([]),
|
||||
selected_index: 0,
|
||||
};
|
||||
let picker = cx.build_view(|cx| Picker::new(delegate, cx));
|
||||
let picker = cx.build_view(|cx| Picker::new(delegate, cx).modal(false));
|
||||
|
||||
Self { picker }
|
||||
}
|
||||
|
@ -37,16 +37,17 @@ impl ContactFinder {
|
|||
|
||||
impl Render for ContactFinder {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
fn render_mode_button(text: &'static str) -> AnyElement {
|
||||
Label::new(text).into_any_element()
|
||||
}
|
||||
|
||||
v_stack()
|
||||
.elevation_3(cx)
|
||||
.child(
|
||||
v_stack()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.bg(cx.theme().colors().element_background)
|
||||
// HACK: Prevent the background color from overflowing the parent container.
|
||||
.rounded_t(px(8.))
|
||||
.child(Label::new("Contacts"))
|
||||
.child(h_stack().children([render_mode_button("Invite new contacts")]))
|
||||
.bg(cx.theme().colors().element_background),
|
||||
.child(h_stack().child(Label::new("Invite new contacts"))),
|
||||
)
|
||||
.child(self.picker.clone())
|
||||
.w(rems(34.))
|
||||
|
@ -72,7 +73,8 @@ impl FocusableView for ContactFinder {
|
|||
}
|
||||
|
||||
impl PickerDelegate for ContactFinderDelegate {
|
||||
type ListItem = Div;
|
||||
type ListItem = ListItem;
|
||||
|
||||
fn match_count(&self) -> usize {
|
||||
self.potential_contacts.len()
|
||||
}
|
||||
|
@ -150,46 +152,14 @@ impl PickerDelegate for ContactFinderDelegate {
|
|||
ContactRequestStatus::RequestAccepted => None,
|
||||
};
|
||||
Some(
|
||||
div()
|
||||
.flex_1()
|
||||
.justify_between()
|
||||
.child(Avatar::new(user.avatar_uri.clone()))
|
||||
ListItem::new(ix)
|
||||
.inset(true)
|
||||
.selected(selected)
|
||||
.start_slot(Avatar::new(user.avatar_uri.clone()))
|
||||
.child(Label::new(user.github_login.clone()))
|
||||
.children(icon_path.map(|icon_path| svg().path(icon_path))),
|
||||
.end_slot::<IconElement>(
|
||||
icon_path.map(|icon_path| IconElement::from_path(icon_path)),
|
||||
),
|
||||
)
|
||||
// todo!()
|
||||
// Flex::row()
|
||||
// .with_children(user.avatar.clone().map(|avatar| {
|
||||
// Image::from_data(avatar)
|
||||
// .with_style(theme.contact_avatar)
|
||||
// .aligned()
|
||||
// .left()
|
||||
// }))
|
||||
// .with_child(
|
||||
// Label::new(user.github_login.clone(), style.label.clone())
|
||||
// .contained()
|
||||
// .with_style(theme.contact_username)
|
||||
// .aligned()
|
||||
// .left(),
|
||||
// )
|
||||
// .with_children(icon_path.map(|icon_path| {
|
||||
// Svg::new(icon_path)
|
||||
// .with_color(button_style.color)
|
||||
// .constrained()
|
||||
// .with_width(button_style.icon_width)
|
||||
// .aligned()
|
||||
// .contained()
|
||||
// .with_style(button_style.container)
|
||||
// .constrained()
|
||||
// .with_width(button_style.button_width)
|
||||
// .with_height(button_style.button_width)
|
||||
// .aligned()
|
||||
// .flex_float()
|
||||
// }))
|
||||
// .contained()
|
||||
// .with_style(style.container)
|
||||
// .constrained()
|
||||
// .with_height(tabbed_modal.row_height)
|
||||
// .into_any()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use editor::Editor;
|
||||
use gpui::{
|
||||
div, prelude::*, rems, uniform_list, AnyElement, AppContext, DismissEvent, Div, EventEmitter,
|
||||
FocusHandle, FocusableView, Length, MouseButton, MouseDownEvent, Render, Task,
|
||||
UniformListScrollHandle, View, ViewContext, WindowContext,
|
||||
div, prelude::*, rems, uniform_list, AppContext, DismissEvent, Div, EventEmitter, FocusHandle,
|
||||
FocusableView, Length, MouseButton, MouseDownEvent, Render, Task, UniformListScrollHandle,
|
||||
View, ViewContext, WindowContext,
|
||||
};
|
||||
use std::{cmp, sync::Arc};
|
||||
use ui::{prelude::*, v_stack, Color, Divider, Label};
|
||||
|
@ -15,6 +15,11 @@ pub struct Picker<D: PickerDelegate> {
|
|||
pending_update_matches: Option<Task<()>>,
|
||||
confirm_on_update: Option<bool>,
|
||||
width: Option<Length>,
|
||||
|
||||
/// Whether the `Picker` is rendered as a self-contained modal.
|
||||
///
|
||||
/// Set this to `false` when rendering the `Picker` as part of a larger modal.
|
||||
is_modal: bool,
|
||||
}
|
||||
|
||||
pub trait PickerDelegate: Sized + 'static {
|
||||
|
@ -58,6 +63,7 @@ impl<D: PickerDelegate> Picker<D> {
|
|||
pending_update_matches: None,
|
||||
confirm_on_update: None,
|
||||
width: None,
|
||||
is_modal: true,
|
||||
};
|
||||
this.update_matches("".to_string(), cx);
|
||||
this
|
||||
|
@ -68,6 +74,11 @@ impl<D: PickerDelegate> Picker<D> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn modal(mut self, modal: bool) -> Self {
|
||||
self.is_modal = modal;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn focus(&self, cx: &mut WindowContext) {
|
||||
self.editor.update(cx, |editor, cx| editor.focus(cx));
|
||||
}
|
||||
|
@ -234,7 +245,11 @@ impl<D: PickerDelegate> Render for Picker<D> {
|
|||
el.w(width)
|
||||
})
|
||||
.overflow_hidden()
|
||||
.elevation_3(cx)
|
||||
// This is a bit of a hack to remove the modal styling when we're rendering the `Picker`
|
||||
// as a part of a modal rather than the entire modal.
|
||||
//
|
||||
// We should revisit how the `Picker` is styled to make it more composable.
|
||||
.when(self.is_modal, |this| this.elevation_3(cx))
|
||||
.on_action(cx.listener(Self::select_next))
|
||||
.on_action(cx.listener(Self::select_prev))
|
||||
.on_action(cx.listener(Self::select_first))
|
||||
|
@ -295,22 +310,3 @@ impl<D: PickerDelegate> Render for Picker<D> {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn simple_picker_match(
|
||||
selected: bool,
|
||||
cx: &mut WindowContext,
|
||||
children: impl FnOnce(&mut WindowContext) -> AnyElement,
|
||||
) -> AnyElement {
|
||||
let colors = cx.theme().colors();
|
||||
|
||||
div()
|
||||
.px_1()
|
||||
.text_color(colors.text)
|
||||
.text_ui()
|
||||
.bg(colors.ghost_element_background)
|
||||
.rounded_md()
|
||||
.when(selected, |this| this.bg(colors.ghost_element_selected))
|
||||
.hover(|this| this.bg(colors.ghost_element_hover))
|
||||
.child((children)(cx))
|
||||
.into_any()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue