sidebar: Fix sidebar example and add right side example. (#626)

This commit is contained in:
Jason Lee 2025-02-14 15:06:37 +08:00 committed by GitHub
parent cca6277ea5
commit bf300a2880
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 56 additions and 10 deletions

View file

@ -19,7 +19,7 @@ impl Example {
impl Render for Example {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div().p_4().size_full().child(self.root.clone())
div().mt(-px(1.)).size_full().child(self.root.clone())
}
}

View file

@ -1,6 +1,6 @@
use gpui::{
div, impl_internal_actions, prelude::FluentBuilder, relative, App, AppContext, ClickEvent,
Context, Entity, Focusable, ParentElement, Render, SharedString, Styled, Window,
Context, Entity, Focusable, IntoElement, ParentElement, Render, SharedString, Styled, Window,
};
use gpui_component::{
@ -12,7 +12,8 @@ use gpui_component::{
sidebar::{
Sidebar, SidebarFooter, SidebarGroup, SidebarHeader, SidebarMenu, SidebarToggleButton,
},
v_flex, white, ActiveTheme, Collapsible, Icon, IconName,
switch::Switch,
v_flex, white, ActiveTheme, Collapsible, Icon, IconName, Side,
};
use serde::Deserialize;
@ -25,6 +26,7 @@ pub struct SidebarStory {
active_item: Item,
active_subitem: Option<SubItem>,
is_collapsed: bool,
side: Side,
focus_handle: gpui::FocusHandle,
}
@ -38,9 +40,24 @@ impl SidebarStory {
active_item: Item::Playground,
active_subitem: None,
is_collapsed: false,
side: Side::Left,
focus_handle: cx.focus_handle(),
}
}
fn render_content(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
v_flex().child(
h_flex().gap_2().child(
Switch::new("side")
.label("Placement Right")
.checked(self.side.is_right())
.on_click(cx.listener(|this, checked: &bool, _, cx| {
this.side = if *checked { Side::Right } else { Side::Left };
cx.notify();
})),
),
)
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
@ -174,6 +191,7 @@ impl super::Story for SidebarStory {
Self::view(window, cx)
}
}
impl Focusable for SidebarStory {
fn focus_handle(&self, _: &gpui::App) -> gpui::FocusHandle {
self.focus_handle.clone()
@ -182,7 +200,7 @@ impl Focusable for SidebarStory {
impl Render for SidebarStory {
fn render(
&mut self,
_: &mut gpui::Window,
window: &mut gpui::Window,
cx: &mut gpui::Context<Self>,
) -> impl gpui::IntoElement {
let groups: [Vec<Item>; 2] = [
@ -199,13 +217,20 @@ impl Render for SidebarStory {
],
];
let sidebar = if self.side.is_left() {
Sidebar::left(&cx.entity())
} else {
Sidebar::right(&cx.entity())
};
h_flex()
.rounded(cx.theme().radius)
.border_1()
.border_color(cx.theme().border)
.h_full()
.when(self.side.is_right(), |this| this.flex_row_reverse())
.child(
Sidebar::left(&cx.entity())
sidebar
.collapsed(self.is_collapsed)
.header(
SidebarHeader::new()
@ -221,9 +246,14 @@ impl Render for SidebarStory {
.text_color(white())
.size_8()
.flex_shrink_0()
.child(Icon::new(IconName::GalleryVerticalEnd).size_4())
.when(!self.is_collapsed, |this| {
this.child(Icon::new(IconName::GalleryVerticalEnd).size_4())
})
.when(self.is_collapsed, |this| {
this.size_4().bg(cx.theme().transparent)
this.size_4()
.bg(cx.theme().transparent)
.text_color(cx.theme().foreground)
.child(Icon::new(IconName::GalleryVerticalEnd).size_5())
}),
)
.when(!self.is_collapsed, |this| {
@ -326,8 +356,12 @@ impl Render for SidebarStory {
h_flex()
.items_center()
.gap_3()
.when(self.side.is_right(), |this| {
this.flex_row_reverse().justify_between()
})
.child(
SidebarToggleButton::left()
.side(self.side)
.collapsed(self.is_collapsed)
.on_click(cx.listener(|this, _, _, cx| {
this.is_collapsed = !this.is_collapsed;
@ -355,7 +389,7 @@ impl Render for SidebarStory {
}),
),
)
.child("This content"),
.child(self.render_content(window, cx)),
)
}
}

View file

@ -132,6 +132,11 @@ impl SidebarToggleButton {
Self::new(Side::Right)
}
pub fn side(mut self, side: Side) -> Self {
self.side = side;
self
}
pub fn collapsed(mut self, is_collapsed: bool) -> Self {
self.is_collapsed = is_collapsed;
self
@ -191,7 +196,7 @@ impl<E: Collapsible + IntoElement> RenderOnce for Sidebar<E> {
.border_color(cx.theme().sidebar_border)
.map(|this| match self.side {
Side::Left => this.border_r_1(),
Side::Right => this.text_2xl(),
Side::Right => this.border_l_1(),
})
.when_some(self.header.take(), |this, header| {
this.child(h_flex().id("header").p_2().gap_2().child(header))

View file

@ -443,10 +443,17 @@ pub enum Side {
}
impl Side {
/// Returns true if the side is left.
#[inline]
pub(crate) fn is_left(&self) -> bool {
pub fn is_left(&self) -> bool {
matches!(self, Self::Left)
}
/// Returns true if the side is right.
#[inline]
pub fn is_right(&self) -> bool {
matches!(self, Self::Right)
}
}
/// A trait for defining element that can be collapsed.