190 lines · 5.4 KB · Rust
RawDownload
//! # Component Preview//!//! A view for exploring Zed components. use component::{components, ComponentMetadata};use gpui::{prelude::*, App, EventEmitter, FocusHandle, Focusable, Window};use ui::prelude::*; use workspace::{item::ItemEvent, Item, Workspace, WorkspaceId}; pub fn init(cx: &mut App) {    cx.observe_new(|workspace: &mut Workspace, _, _cx| {        workspace.register_action(            |workspace, _: &workspace::OpenComponentPreview, window, cx| {                let component_preview = cx.new(ComponentPreview::new);                workspace.add_item_to_active_pane(                    Box::new(component_preview),                    None,                    true,                    window,                    cx,                )            },        );    })    .detach();} struct ComponentPreview {    focus_handle: FocusHandle,} impl ComponentPreview {    pub fn new(cx: &mut Context<Self>) -> Self {        Self {            focus_handle: cx.focus_handle(),        }    }     fn render_sidebar(&self, _window: &Window, _cx: &Context<Self>) -> impl IntoElement {        let components = components().all_sorted();        let sorted_components = components.clone();         v_flex()            .max_w_48()            .gap_px()            .p_1()            .children(                sorted_components                    .into_iter()                    .map(|component| self.render_sidebar_entry(&component, _cx)),            )            .child(                Label::new("These will be clickable once the layout is moved to a gpui::List.")                    .color(Color::Muted)                    .size(LabelSize::XSmall)                    .italic(),            )    }     fn render_sidebar_entry(        &self,        component: &ComponentMetadata,        _cx: &Context<Self>,    ) -> impl IntoElement {        h_flex()            .w_40()            .px_1p5()            .py_0p5()            .text_sm()            .child(component.name().clone())    }     fn render_preview(        &self,        component: &ComponentMetadata,        window: &mut Window,        cx: &Context<Self>,    ) -> impl IntoElement {        let name = component.name();        let scope = component.scope();         let description = component.description();         v_flex()            .border_b_1()            .border_color(cx.theme().colors().border)            .w_full()            .gap_3()            .py_6()            .child(                v_flex()                    .gap_1()                    .child(                        h_flex()                            .gap_1()                            .text_2xl()                            .child(div().child(name))                            .when_some(scope, |this, scope| {                                this.child(div().opacity(0.5).child(format!("({})", scope)))                            }),                    )                    .when_some(description, |this, description| {                        this.child(                            div()                                .text_ui_sm(cx)                                .text_color(cx.theme().colors().text_muted)                                .max_w(px(600.0))                                .child(description),                        )                    }),            )            .when_some(component.preview(), |this, preview| {                this.child(preview(window, cx))            })            .into_any_element()    }     fn render_previews(&self, window: &mut Window, cx: &Context<Self>) -> impl IntoElement {        v_flex()            .id("component-previews")            .size_full()            .overflow_y_scroll()            .p_4()            .gap_4()            .children(                components()                    .all_previews_sorted()                    .iter()                    .map(|component| self.render_preview(component, window, cx)),            )    }} impl Render for ComponentPreview {    fn render(&mut self, window: &mut Window, cx: &mut Context<'_, Self>) -> impl IntoElement {        h_flex()            .id("component-preview")            .key_context("ComponentPreview")            .items_start()            .overflow_hidden()            .size_full()            .max_h_full()            .track_focus(&self.focus_handle)            .px_2()            .bg(cx.theme().colors().editor_background)            .child(self.render_sidebar(window, cx))            .child(self.render_previews(window, cx))    }} impl EventEmitter<ItemEvent> for ComponentPreview {} impl Focusable for ComponentPreview {    fn focus_handle(&self, _: &App) -> gpui::FocusHandle {        self.focus_handle.clone()    }} impl Item for ComponentPreview {    type Event = ItemEvent;     fn tab_content_text(&self, _window: &Window, _cx: &App) -> Option<SharedString> {        Some("Component Preview".into())    }     fn telemetry_event_text(&self) -> Option<&'static str> {        None    }     fn show_toolbar(&self) -> bool {        false    }     fn clone_on_split(        &self,        _workspace_id: Option<WorkspaceId>,        _window: &mut Window,        cx: &mut Context<Self>,    ) -> Option<gpui::Entity<Self>>    where        Self: Sized,    {        Some(cx.new(Self::new))    }     fn to_item_events(event: &Self::Event, mut f: impl FnMut(workspace::item::ItemEvent)) {        f(*event)    }}