The design's split.jsx Pane header leads with an 8 px brand-accent dot, the lock indicator, host name in INK, then the tab title in INK_4. The previous header rendered a 24 px brand glyph plus the URL path — visually heavier and less informative once both panes share most of their URL prefix. * brand_glyph: `brand_accent_color(brand)` and `accent_color_for_host` collapse each Brand to one design-matching dot color (Figma 7c6cf7, Linear 5e6ad2, etc.). * split_pane: 32 → 30 px header, glyph → 8 px dot, URL path → tab title in INK_4. `pane_path_label` deleted; nothing else used it. cargo test --workspace: 440 passed, 0 failed.
161 lines
5.0 KiB
Rust
161 lines
5.0 KiB
Rust
use ely_design_system::colors;
|
|
use ely_domain::{BrowserTab, TabId};
|
|
use gpui::{
|
|
AnyElement, Context, FontWeight, InteractiveElement, IntoElement, ParentElement, SharedString,
|
|
StatefulInteractiveElement, Styled, div, px, rgb, rgba,
|
|
};
|
|
use gpui_component::IconName;
|
|
|
|
use crate::shell::ElyShell;
|
|
use crate::shell::chrome::accent_color_for_host;
|
|
|
|
/// Pane header chrome for a split tab.
|
|
///
|
|
/// Matches the design's split.jsx Pane header: 30 px tall, warm card bg,
|
|
/// hairline divider, an 8 px brand-accent dot, the secure indicator, host
|
|
/// name in INK, the tab title in INK_4, then reload + close glyphs.
|
|
pub(crate) fn render_split_pane_header(
|
|
host: String,
|
|
title: String,
|
|
secure: bool,
|
|
close_tab_id: TabId,
|
|
cx: &mut Context<ElyShell>,
|
|
) -> AnyElement {
|
|
let lock_or_globe = if secure { IconName::Search } else { IconName::Globe };
|
|
let accent = accent_color_for_host(Some(host.as_str()));
|
|
|
|
div()
|
|
.h(px(30.0))
|
|
.px(px(10.0))
|
|
.gap(px(8.0))
|
|
.flex()
|
|
.items_center()
|
|
.flex_shrink_0()
|
|
.border_b_1()
|
|
.border_color(rgb(colors::HAIRLINE))
|
|
.bg(rgb(0xf6f4ef))
|
|
.child(
|
|
div()
|
|
.size(px(8.0))
|
|
.rounded_full()
|
|
.bg(rgb(accent)),
|
|
)
|
|
.child(
|
|
div()
|
|
.text_color(rgb(colors::INK_3))
|
|
.text_size(px(11.0))
|
|
.child(lock_or_globe),
|
|
)
|
|
.child(
|
|
div()
|
|
.text_size(px(11.0))
|
|
.font_weight(FontWeight(500.0))
|
|
.text_color(rgb(colors::INK))
|
|
.child(host),
|
|
)
|
|
.child(
|
|
div()
|
|
.flex_1()
|
|
.min_w_0()
|
|
.truncate()
|
|
.text_size(px(11.0))
|
|
.text_color(rgb(colors::INK_4))
|
|
.child(title),
|
|
)
|
|
.child(render_reload_glyph(close_tab_id.clone(), cx))
|
|
.child(render_close_glyph(close_tab_id, cx))
|
|
.into_any_element()
|
|
}
|
|
|
|
fn render_reload_glyph(tab_id: TabId, cx: &mut Context<ElyShell>) -> AnyElement {
|
|
let id = format!("split-pane-reload-{}", tab_id.as_str());
|
|
div()
|
|
.id(SharedString::from(id))
|
|
.text_color(rgb(colors::INK_4))
|
|
.text_size(px(11.0))
|
|
.cursor_pointer()
|
|
.hover(|style| style.text_color(rgb(colors::INK)))
|
|
.on_click(cx.listener(move |shell, _, window, cx| {
|
|
shell.select_tab(&tab_id, window, cx);
|
|
}))
|
|
.child(IconName::Redo2)
|
|
.into_any_element()
|
|
}
|
|
|
|
fn render_close_glyph(close_tab_id: TabId, cx: &mut Context<ElyShell>) -> AnyElement {
|
|
let id = format!("split-pane-close-{}", close_tab_id.as_str());
|
|
div()
|
|
.id(SharedString::from(id))
|
|
.text_color(rgb(colors::INK_4))
|
|
.text_size(px(11.0))
|
|
.cursor_pointer()
|
|
.hover(|style| style.text_color(rgb(colors::INK)))
|
|
.on_click(cx.listener(move |shell, _, window, cx| {
|
|
shell.select_tab(&close_tab_id, window, cx);
|
|
shell.close_active_tab(window, cx);
|
|
}))
|
|
.child(IconName::Close)
|
|
.into_any_element()
|
|
}
|
|
|
|
pub(crate) fn pane_host_label(tab: &BrowserTab) -> String {
|
|
tab.url()
|
|
.host()
|
|
.map(|host| host.to_string())
|
|
.unwrap_or_else(|| tab.title().to_string())
|
|
}
|
|
|
|
pub(crate) fn pane_url_is_secure(tab: &BrowserTab) -> bool {
|
|
let url = tab.url().as_str();
|
|
url.starts_with("https://") || url.starts_with("ely://")
|
|
}
|
|
|
|
pub(crate) fn split_canvas_status(tab: &BrowserTab) -> String {
|
|
if tab.url().as_str() == "ely://new-tab" {
|
|
"Ready".to_string()
|
|
} else {
|
|
tab.display_url()
|
|
}
|
|
}
|
|
|
|
pub(crate) fn render_compact_split_canvas(tab: &BrowserTab) -> AnyElement {
|
|
div()
|
|
.flex_1()
|
|
.min_h_0()
|
|
.p(px(8.0))
|
|
.child(
|
|
div()
|
|
.size_full()
|
|
.min_h_0()
|
|
.rounded(px(10.0))
|
|
.bg(rgba(colors::GLASS_2))
|
|
.px(px(10.0))
|
|
.py(px(8.0))
|
|
.gap(px(8.0))
|
|
.flex()
|
|
.items_center()
|
|
.child(div().text_color(rgb(colors::INK_4)).child(IconName::Globe))
|
|
.child(
|
|
div()
|
|
.min_w_0()
|
|
.flex()
|
|
.flex_col()
|
|
.child(
|
|
div()
|
|
.truncate()
|
|
.text_size(px(13.0))
|
|
.font_weight(FontWeight(500.0))
|
|
.child(tab.title().to_string()),
|
|
)
|
|
.child(
|
|
div()
|
|
.truncate()
|
|
.text_size(px(11.0))
|
|
.text_color(rgb(colors::INK_4))
|
|
.child(split_canvas_status(tab)),
|
|
),
|
|
),
|
|
)
|
|
.into_any_element()
|
|
}
|