Update List to support UI Density (#18079)

Tracking issue: #18078

Improve UI Density support for List.

UI density is an unstable feature. You can read more about it in the
above issue!

| Before Normal - Before Dense - After Normal - After Dense |
|--------------------------------------------------------|
| ![Group
8](https://github.com/user-attachments/assets/bb896fcf-e4a6-4776-9308-1405906d2dbe)
| | | |

| Before Normal - Before Dense - After Normal - After Dense |
|--------------------------------------------------------|
| ![Group
9](https://github.com/user-attachments/assets/00815a1b-071b-4d02-96bc-36bf37b5ae8b)
|

Release Notes:

- N/A
This commit is contained in:
Nate Butler 2024-09-19 12:31:40 -04:00 committed by GitHub
parent ac0d5d3152
commit 8074fba76b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 55 additions and 39 deletions

View file

@ -52,13 +52,15 @@ impl ParentElement for List {
}
impl RenderOnce for List {
fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
v_flex().w_full().py_1().children(self.header).map(|this| {
match (self.children.is_empty(), self.toggle) {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
v_flex()
.w_full()
.py(Spacing::Small.rems(cx))
.children(self.header)
.map(|this| match (self.children.is_empty(), self.toggle) {
(false, _) => this.children(self.children),
(true, Some(false)) => this,
(true, _) => this.child(Label::new(self.empty_message.clone()).color(Color::Muted)),
}
})
})
}
}

View file

@ -2,6 +2,8 @@ use std::sync::Arc;
use crate::{h_flex, prelude::*, Disclosure, Label};
use gpui::{AnyElement, ClickEvent};
use settings::Settings;
use theme::ThemeSettings;
#[derive(IntoElement)]
pub struct ListHeader {
@ -78,6 +80,8 @@ impl Selectable for ListHeader {
impl RenderOnce for ListHeader {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
let ui_density = ThemeSettings::get_global(cx).ui_density;
h_flex()
.id(self.label.clone())
.w_full()
@ -85,7 +89,10 @@ impl RenderOnce for ListHeader {
.group("list_header")
.child(
div()
.h_7()
.map(|this| match ui_density {
theme::UiDensity::Comfortable => this.h_5(),
_ => this.h_7(),
})
.when(self.inset, |this| this.px_2())
.when(self.selected, |this| {
this.bg(cx.theme().colors().ghost_element_selected)
@ -95,10 +102,10 @@ impl RenderOnce for ListHeader {
.items_center()
.justify_between()
.w_full()
.gap_1()
.gap(Spacing::Small.rems(cx))
.child(
h_flex()
.gap_1()
.gap(Spacing::Small.rems(cx))
.children(self.toggle.map(|is_open| {
Disclosure::new("toggle", is_open).on_toggle(self.on_toggle.clone())
}))
@ -106,7 +113,7 @@ impl RenderOnce for ListHeader {
div()
.id("label_container")
.flex()
.gap_1()
.gap(Spacing::Small.rems(cx))
.items_center()
.children(self.start_slot)
.child(Label::new(self.label.clone()).color(Color::Muted))

View file

@ -162,7 +162,7 @@ impl RenderOnce for ListItem {
// When an item is inset draw the indent spacing outside of the item
.when(self.inset, |this| {
this.ml(self.indent_level as f32 * self.indent_step_size)
.px_1()
.px(Spacing::Small.rems(cx))
})
.when(!self.inset && !self.disabled, |this| {
this
@ -185,7 +185,7 @@ impl RenderOnce for ListItem {
.w_full()
.relative()
.gap_1()
.px_1p5()
.px(Spacing::Medium.rems(cx))
.map(|this| match self.spacing {
ListItemSpacing::Dense => this,
ListItemSpacing::Sparse => this.py_1(),
@ -238,7 +238,7 @@ impl RenderOnce for ListItem {
.flex_grow()
.flex_shrink_0()
.flex_basis(relative(0.25))
.gap_1()
.gap(Spacing::Small.rems(cx))
.overflow_hidden()
.children(self.start_slot)
.children(self.children),
@ -260,7 +260,7 @@ impl RenderOnce for ListItem {
h_flex()
.h_full()
.absolute()
.right_1p5()
.right(Spacing::Medium.rems(cx))
.top_0()
.visible_on_hover("list_item")
.child(end_hover_slot),

View file

@ -8,7 +8,7 @@ impl RenderOnce for ListSeparator {
div()
.h_px()
.w_full()
.my_1p5()
.my(Spacing::Medium.rems(cx))
.bg(cx.theme().colors().border_variant)
}
}

View file

@ -39,30 +39,37 @@ impl Selectable for ListSubHeader {
impl RenderOnce for ListSubHeader {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
h_flex().flex_1().w_full().relative().pb_1().px_0p5().child(
div()
.h_6()
.when(self.inset, |this| this.px_2())
.when(self.selected, |this| {
this.bg(cx.theme().colors().ghost_element_selected)
})
.flex()
.flex_1()
.w_full()
.gap_1()
.items_center()
.justify_between()
.child(
div()
.flex()
.gap_1()
.items_center()
.children(
self.start_slot
.map(|i| Icon::new(i).color(Color::Muted).size(IconSize::Small)),
)
.child(Label::new(self.label.clone()).color(Color::Muted)),
),
)
h_flex()
.flex_1()
.w_full()
.relative()
.pb(Spacing::Small.rems(cx))
.px(Spacing::XSmall.rems(cx))
.child(
div()
.h_6()
.when(self.inset, |this| this.px_2())
.when(self.selected, |this| {
this.bg(cx.theme().colors().ghost_element_selected)
})
.flex()
.flex_1()
.w_full()
.gap_1()
.items_center()
.justify_between()
.child(
div()
.flex()
.gap_1()
.items_center()
.children(
self.start_slot.map(|i| {
Icon::new(i).color(Color::Muted).size(IconSize::Small)
}),
)
.child(Label::new(self.label.clone()).color(Color::Muted)),
),
)
}
}