ZIm/crates/ui2/src/to_extract/breadcrumb.rs
Marshall Bowers 76db100d11
ui2: Reorganize components (#3228)
This PR reorganizes the components in the `ui2` crate.

The distinction between "elements" and "components" is now gone, with
all of the reusable components living under `components/`.

The components that we built while prototyping but will eventually live
in other crates currently reside in the `to_extract/` module.

Release Notes:

- N/A
2023-11-03 17:34:11 -04:00

115 lines
3.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use std::path::PathBuf;
use crate::prelude::*;
use crate::{h_stack, HighlightedText};
use gpui2::Div;
#[derive(Clone)]
pub struct Symbol(pub Vec<HighlightedText>);
#[derive(Component)]
pub struct Breadcrumb {
path: PathBuf,
symbols: Vec<Symbol>,
}
impl Breadcrumb {
pub fn new(path: PathBuf, symbols: Vec<Symbol>) -> Self {
Self { path, symbols }
}
fn render_separator<V: 'static>(&self, cx: &WindowContext) -> Div<V> {
div()
.child(" ")
.text_color(cx.theme().colors().text_muted)
}
fn render<V: 'static>(self, view_state: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
let symbols_len = self.symbols.len();
h_stack()
.id("breadcrumb")
.px_1()
.text_sm()
.text_color(cx.theme().colors().text_muted)
.rounded_md()
.hover(|style| style.bg(cx.theme().colors().ghost_element_hover))
.active(|style| style.bg(cx.theme().colors().ghost_element_active))
.child(self.path.clone().to_str().unwrap().to_string())
.child(if !self.symbols.is_empty() {
self.render_separator(cx)
} else {
div()
})
.child(
div().flex().children(
self.symbols
.iter()
.enumerate()
// TODO: Could use something like `intersperse` here instead.
.flat_map(|(ix, symbol)| {
let mut items =
vec![div().flex().children(symbol.0.iter().map(|segment| {
div().child(segment.text.clone()).text_color(segment.color)
}))];
let is_last_segment = ix == symbols_len - 1;
if !is_last_segment {
items.push(self.render_separator(cx));
}
items
})
.collect::<Vec<_>>(),
),
)
}
}
#[cfg(feature = "stories")]
pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
use super::*;
use crate::Story;
use gpui2::Render;
use std::str::FromStr;
pub struct BreadcrumbStory;
impl Render for BreadcrumbStory {
type Element = Div<Self>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, Breadcrumb>(cx))
.child(Story::label(cx, "Default"))
.child(Breadcrumb::new(
PathBuf::from_str("crates/ui/src/components/toolbar.rs").unwrap(),
vec![
Symbol(vec![
HighlightedText {
text: "impl ".to_string(),
color: cx.theme().syntax_color("keyword"),
},
HighlightedText {
text: "BreadcrumbStory".to_string(),
color: cx.theme().syntax_color("function"),
},
]),
Symbol(vec![
HighlightedText {
text: "fn ".to_string(),
color: cx.theme().syntax_color("keyword"),
},
HighlightedText {
text: "render".to_string(),
color: cx.theme().syntax_color("function"),
},
]),
],
))
}
}
}