Render omnibar host bold + path muted when not editing

The design omnibar shows the host in ink-1 weight 500 and the path in
ink-3, switching to a plain editable address only while the user types.
The shell now compares the input value to the active tab URL: when they
match (and the URL isn't ely://new-tab) the omnibar renders the styled
host/path display; clicking it routes through focus_address_bar which
re-mounts the Input via the same listener that already drove typing.

Internal: render_lock_or_search picks Search vs Globe based on the URL
scheme so insecure pages get a different leading glyph in display mode.
This commit is contained in:
2026-05-09 18:42:15 -04:00
parent c62954344a
commit a8deebcf1a
+78 -11
View File
@@ -2,8 +2,9 @@ use ely_browser_core::BrowserSnapshot;
use ely_design_system::{colors, spacing}; use ely_design_system::{colors, spacing};
use ely_domain::BrowserTab; use ely_domain::BrowserTab;
use gpui::{ use gpui::{
AnyElement, BoxShadow, Context, InteractiveElement, IntoElement, ParentElement, SharedString, AnyElement, BoxShadow, Context, FontWeight, InteractiveElement, IntoElement, ParentElement,
StatefulInteractiveElement, Styled, div, hsla, point, prelude::FluentBuilder, px, rgb, rgba, SharedString, StatefulInteractiveElement, Styled, div, hsla, point,
prelude::FluentBuilder, px, rgb, rgba,
}; };
use gpui_component::{IconName, input::Input}; use gpui_component::{IconName, input::Input};
@@ -70,6 +71,12 @@ fn render_omnibar(
} else { } else {
IconName::StarOff IconName::StarOff
}; };
let input_value = shell.command_input.read(cx).value().to_string();
let active_url = active_tab.url().as_str().to_string();
let show_styled = !input_value.is_empty()
&& input_value == active_url
&& active_url != "ely://new-tab";
let secure = active_url.starts_with("https://") || active_url.starts_with("ely://");
div() div()
.flex_1() .flex_1()
@@ -82,17 +89,21 @@ fn render_omnibar(
.flex() .flex()
.items_center() .items_center()
.gap(px(10.0)) .gap(px(10.0))
.child(render_lock_or_search(secure, show_styled))
.child( .child(
div() div()
.text_color(rgb(colors::INK_3)) .id(SharedString::from("omnibar-content"))
.child(IconName::Search), .flex_1()
) .min_w_0()
.child( .cursor_pointer()
div().flex_1().child( .on_click(cx.listener(|shell, _, window, cx| {
Input::new(&shell.command_input) shell.focus_address_bar(window, cx);
.appearance(false) }))
.cleanable(true), .child(if show_styled {
), render_styled_url(active_tab)
} else {
render_omnibar_input(shell)
}),
) )
.child(render_omnibar_chip( .child(render_omnibar_chip(
"omnibar-filters", "omnibar-filters",
@@ -111,6 +122,62 @@ fn render_omnibar(
.into_any_element() .into_any_element()
} }
fn render_omnibar_input(shell: &ElyShell) -> AnyElement {
Input::new(&shell.command_input)
.appearance(false)
.cleanable(true)
.into_any_element()
}
fn render_styled_url(active_tab: &BrowserTab) -> AnyElement {
let host = active_tab
.url()
.host()
.map(|host| host.to_string())
.unwrap_or_default();
let url = active_tab.url().as_str();
let path_start = url.find("://").map(|prefix| prefix + 3).unwrap_or(0);
let from_path = &url[path_start..];
let path = match from_path.find('/') {
Some(slash) => from_path[slash..].to_string(),
None => String::new(),
};
div()
.flex()
.items_center()
.gap(px(2.0))
.text_size(px(13.0))
.child(
div()
.font_weight(FontWeight(500.0))
.text_color(rgb(colors::INK))
.child(host),
)
.child(
div()
.min_w_0()
.truncate()
.text_color(rgb(colors::INK_3))
.child(path),
)
.into_any_element()
}
fn render_lock_or_search(secure: bool, show_styled: bool) -> AnyElement {
let icon = if !show_styled {
IconName::Search
} else if secure {
IconName::Search
} else {
IconName::Globe
};
div()
.text_color(rgb(colors::INK_3))
.child(icon)
.into_any_element()
}
fn render_omnibar_chip<F>( fn render_omnibar_chip<F>(
id: &'static str, id: &'static str,
icon: IconName, icon: IconName,