Skip to main content

gpui_kit_material/tokens/
layout.rs

1//! Control metrics and window breakpoints.
2use super::typography::rem;
3use gpui::{Pixels, Rems, Window, px};
4
5/// Ordinary controls share this height, padding included, at every text scale.
6pub const CONTROL_HEIGHT: Rems = rem(40.);
7/// Horizontal inset of an item's content inside a tile or card.
8pub const ITEM_INSET: Rems = rem(20.);
9/// The leading icon slot of an icon + label cluster, and the gap after it.
10pub const ICON_SLOT: Rems = rem(20.);
11pub const ICON_GAP: Rems = rem(8.);
12/// Supporting lines of an icon-labelled item start on its label text.
13pub const LABEL_INSET: Rems = rem(20. + 8.);
14/// Between a section title and its group's first tile. The gap follows the
15/// title's text, so it is in rems; prefer this over [`SECTION_TITLE_GAP`].
16pub const SECTION_TITLE_SPACE: Rems = rem(10.);
17/// Legacy px form of [`SECTION_TITLE_SPACE`] that does not follow the text
18/// scale; kept until its call sites move to the rem token.
19pub const SECTION_TITLE_GAP: Pixels = px(10.);
20/// Above and below the control row of an app bar.
21pub const APP_BAR_BLOCK_PADDING: Rems = rem(8.);
22
23/// The window width, in 100%-scale px, below which pages use narrow
24/// gutters, compact navigation and stacked controls.
25pub const COMPACT_WINDOW: f32 = 960.;
26
27/// The window width in 100%-scale px, so breakpoints follow the text scale.
28pub fn design_width(window: &Window) -> f32 {
29    f32::from(window.bounds().size.width) * super::typography::BASE_PX
30        / f32::from(window.rem_size())
31}
32
33pub fn is_compact(window: &Window) -> bool {
34    design_width(window) < COMPACT_WINDOW
35}
36
37/// An app bar of one control row with [`APP_BAR_BLOCK_PADDING`] above and
38/// below, all following the text scale.
39pub fn app_bar_height(window: &Window) -> Pixels {
40    app_bar_height_at(window.rem_size())
41}
42
43fn app_bar_height_at(rem_size: Pixels) -> Pixels {
44    (CONTROL_HEIGHT + APP_BAR_BLOCK_PADDING * 2.).to_pixels(rem_size)
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn app_bar_height_follows_the_text_scale() {
53        assert_eq!(app_bar_height_at(px(14.)), px(56.));
54        assert_eq!(app_bar_height_at(px(21.)), px(84.));
55    }
56
57    #[test]
58    fn section_title_space_matches_the_legacy_gap_at_100_percent() {
59        assert_eq!(SECTION_TITLE_SPACE.to_pixels(px(14.)), SECTION_TITLE_GAP);
60    }
61}