Skip to content

Commit 404adbc

Browse files
authored
Encode rem values derived from pixels using rems_from_px (#9367)
This PR adds a new `rems_from_px` helper function that can be used to compute rem values based on a pixel value. This is something we do fairly commonly, where we want to express a size that is a given pixel size at the base rem size (e.g., "14px when the rem size is 16px"). `rems_from_px` helps make the intent more explicit, as well as prevent the base rem size from being duplicated everywhere. Note: Ideally we would want `rems_from_px` to be `const`, but that depends on rust-lang/rust#57241. Release Notes: - N/A
1 parent a78576a commit 404adbc

File tree

13 files changed

+54
-35
lines changed

13 files changed

+54
-35
lines changed

crates/breadcrumbs/src/breadcrumbs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ impl Render for Breadcrumbs {
8686
),
8787
None => element
8888
// Match the height of the `ButtonLike` in the other arm.
89-
.h(rems(22. / 16.))
89+
.h(rems_from_px(22.))
9090
.child(breadcrumbs_stack),
9191
}
9292
}

crates/collab_ui/src/collab_panel/channel_modal.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ impl Render for ChannelModal {
174174
.child(
175175
h_flex()
176176
.w_full()
177-
.h(rems(22. / 16.))
177+
.h(rems_from_px(22.))
178178
.justify_between()
179179
.line_height(rems(1.25))
180180
.child(CheckboxWithLabel::new(

crates/extensions_ui/src/extensions_ui.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ impl ExtensionsPage {
521521
.gap_2()
522522
.border_1()
523523
.border_color(editor_border)
524-
.min_w(rems(384. / 16.))
524+
.min_w(rems_from_px(384.))
525525
.rounded_lg()
526526
.child(Icon::new(IconName::MagnifyingGlass))
527527
.child(self.render_text_input(&self.query_editor, cx)),

crates/ui/src/components/avatar/avatar_audio_status_indicator.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ impl RenderOnce for AvatarAudioStatusIndicator {
3737

3838
div()
3939
.absolute()
40-
.bottom(rems(-3. / 16.))
41-
.right(rems(-6. / 16.))
40+
.bottom(rems_from_px(-3.))
41+
.right(rems_from_px(-6.))
4242
.w(width_in_px + padding_x)
4343
.h(icon_size.rems())
4444
.child(

crates/ui/src/components/button/button_like.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use gpui::{relative, DefiniteLength, MouseButton};
2-
use gpui::{rems, transparent_black, AnyElement, AnyView, ClickEvent, Hsla, Rems};
2+
use gpui::{transparent_black, AnyElement, AnyView, ClickEvent, Hsla, Rems};
33
use smallvec::SmallVec;
44

55
use crate::prelude::*;
@@ -278,10 +278,10 @@ pub enum ButtonSize {
278278
impl ButtonSize {
279279
fn height(self) -> Rems {
280280
match self {
281-
ButtonSize::Large => rems(32. / 16.),
282-
ButtonSize::Default => rems(22. / 16.),
283-
ButtonSize::Compact => rems(18. / 16.),
284-
ButtonSize::None => rems(16. / 16.),
281+
ButtonSize::Large => rems_from_px(32.),
282+
ButtonSize::Default => rems_from_px(22.),
283+
ButtonSize::Compact => rems_from_px(18.),
284+
ButtonSize::None => rems_from_px(16.),
285285
}
286286
}
287287
}

crates/ui/src/components/icon.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use gpui::{rems, svg, IntoElement, Rems};
1+
use gpui::{svg, IntoElement, Rems};
22
use strum::EnumIter;
33

44
use crate::prelude::*;
@@ -15,10 +15,10 @@ pub enum IconSize {
1515
impl IconSize {
1616
pub fn rems(self) -> Rems {
1717
match self {
18-
IconSize::Indicator => rems(10. / 16.),
19-
IconSize::XSmall => rems(12. / 16.),
20-
IconSize::Small => rems(14. / 16.),
21-
IconSize::Medium => rems(16. / 16.),
18+
IconSize::Indicator => rems_from_px(10.),
19+
IconSize::XSmall => rems_from_px(12.),
20+
IconSize::Small => rems_from_px(14.),
21+
IconSize::Medium => rems_from_px(16.),
2222
}
2323
}
2424
}

crates/ui/src/components/keybinding.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{h_flex, prelude::*, Icon, IconName, IconSize};
2-
use gpui::{relative, rems, Action, FocusHandle, IntoElement, Keystroke};
2+
use gpui::{relative, Action, FocusHandle, IntoElement, Keystroke};
33

44
/// The way a [`KeyBinding`] should be displayed.
55
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
@@ -158,12 +158,15 @@ impl RenderOnce for Key {
158158
.py_0()
159159
.map(|this| {
160160
if single_char {
161-
this.w(rems(14. / 16.)).flex().flex_none().justify_center()
161+
this.w(rems_from_px(14.))
162+
.flex()
163+
.flex_none()
164+
.justify_center()
162165
} else {
163166
this.px_0p5()
164167
}
165168
})
166-
.h(rems(14. / 16.))
169+
.h(rems_from_px(14.))
167170
.text_ui()
168171
.line_height(relative(1.))
169172
.text_color(cx.theme().colors().text_muted)
@@ -184,7 +187,7 @@ pub struct KeyIcon {
184187

185188
impl RenderOnce for KeyIcon {
186189
fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
187-
div().w(rems(14. / 16.)).child(
190+
div().w(rems_from_px(14.)).child(
188191
Icon::new(self.icon)
189192
.size(IconSize::Small)
190193
.color(Color::Muted),

crates/ui/src/components/popover_menu.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::{cell::RefCell, rc::Rc};
22

33
use gpui::{
4-
div, overlay, point, prelude::FluentBuilder, px, rems, AnchorCorner, AnyElement, Bounds,
4+
div, overlay, point, prelude::FluentBuilder, px, AnchorCorner, AnyElement, Bounds,
55
DismissEvent, DispatchPhase, Element, ElementContext, ElementId, HitboxId, InteractiveElement,
66
IntoElement, LayoutId, ManagedView, MouseDownEvent, ParentElement, Pixels, Point, View,
77
VisualContext, WindowContext,
88
};
99

10-
use crate::{Clickable, Selectable};
10+
use crate::prelude::*;
1111

1212
pub trait PopoverTrigger: IntoElement + Clickable + Selectable + 'static {}
1313

@@ -102,7 +102,7 @@ impl<M: ManagedView> PopoverMenu<M> {
102102
fn resolved_offset(&self, cx: &WindowContext) -> Point<Pixels> {
103103
self.offset.unwrap_or_else(|| {
104104
// Default offset = 4px padding + 1px border
105-
let offset = rems(5. / 16.) * cx.rem_size();
105+
let offset = rems_from_px(5.) * cx.rem_size();
106106
match self.anchor {
107107
AnchorCorner::TopRight | AnchorCorner::BottomRight => point(offset, px(0.)),
108108
AnchorCorner::TopLeft | AnchorCorner::BottomLeft => point(-offset, px(0.)),

crates/ui/src/components/tab.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
use crate::prelude::*;
1+
use std::cmp::Ordering;
2+
23
use gpui::{AnyElement, IntoElement, Stateful};
34
use smallvec::SmallVec;
4-
use std::cmp::Ordering;
5+
6+
use crate::{prelude::*, BASE_REM_SIZE_IN_PX};
57

68
/// The position of a [`Tab`] within a list of tabs.
79
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -51,9 +53,9 @@ impl Tab {
5153
}
5254
}
5355

54-
pub const CONTAINER_HEIGHT_IN_REMS: f32 = 29. / 16.;
56+
pub const CONTAINER_HEIGHT_IN_REMS: f32 = 29. / BASE_REM_SIZE_IN_PX;
5557

56-
const CONTENT_HEIGHT_IN_REMS: f32 = 28. / 16.;
58+
const CONTENT_HEIGHT_IN_REMS: f32 = 28. / BASE_REM_SIZE_IN_PX;
5759

5860
pub fn position(mut self, position: TabPosition) -> Self {
5961
self.position = position;

crates/ui/src/components/tab_bar.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,13 @@ impl ParentElement for TabBar {
9090

9191
impl RenderOnce for TabBar {
9292
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
93-
const HEIGHT_IN_REMS: f32 = 29. / 16.;
94-
9593
div()
9694
.id(self.id)
9795
.group("tab_bar")
9896
.flex()
9997
.flex_none()
10098
.w_full()
101-
.h(rems(HEIGHT_IN_REMS))
99+
.h(rems_from_px(29.))
102100
.bg(cx.theme().colors().tab_bar_background)
103101
.when(!self.start_children.is_empty(), |this| {
104102
this.child(

crates/ui/src/prelude.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub use crate::clickable::*;
1111
pub use crate::disableable::*;
1212
pub use crate::fixed::*;
1313
pub use crate::selectable::*;
14-
pub use crate::styles::{vh, vw};
14+
pub use crate::styles::{rems_from_px, vh, vw};
1515
pub use crate::visible_on_hover::*;
1616
pub use crate::{h_flex, v_flex};
1717
pub use crate::{Button, ButtonSize, ButtonStyle, IconButton, SelectableButton};

crates/ui/src/styles/typography.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use gpui::{
44
use settings::Settings;
55
use theme::{ActiveTheme, ThemeSettings};
66

7+
use crate::rems_from_px;
8+
79
#[derive(Debug, Default, Clone)]
810
pub enum UiTextSize {
911
/// The default size for UI text.
@@ -38,10 +40,10 @@ pub enum UiTextSize {
3840
impl UiTextSize {
3941
pub fn rems(self) -> Rems {
4042
match self {
41-
Self::Large => rems(16. / 16.),
42-
Self::Default => rems(14. / 16.),
43-
Self::Small => rems(12. / 16.),
44-
Self::XSmall => rems(10. / 16.),
43+
Self::Large => rems_from_px(16.),
44+
Self::Default => rems_from_px(14.),
45+
Self::Small => rems_from_px(12.),
46+
Self::XSmall => rems_from_px(10.),
4547
}
4648
}
4749
}

crates/ui/src/styles/units.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
1-
use gpui::{Length, WindowContext};
1+
use gpui::{rems, Length, Rems, WindowContext};
2+
3+
/// The base size of a rem, in pixels.
4+
pub(crate) const BASE_REM_SIZE_IN_PX: f32 = 16.;
5+
6+
/// Returns a rem value derived from the provided pixel value and the base rem size (16px).
7+
///
8+
/// This can be used to compute rem values relative to pixel sizes, without
9+
/// needing to hard-code the rem value.
10+
///
11+
/// For instance, instead of writing `rems(0.875)` you can write `rems_from_px(14.)`
12+
#[inline(always)]
13+
pub fn rems_from_px(px: f32) -> Rems {
14+
rems(px / BASE_REM_SIZE_IN_PX)
15+
}
216

317
/// Returns a [`Length`] corresponding to the specified percentage of the viewport's width.
418
///

0 commit comments

Comments
 (0)