User reports the sidebar can't be resized. Until now sidebar width
was only mutable through the COLLAPSED/DEFAULT toggle and through
typed settings. Real browsers (Arc, Dia, Zen) all let you drag the
right edge of the sidebar to size it live.
Wire it through the existing space.sidebar_width_px:
* `ElyShell.sidebar_resize_origin: Option<(f32, u16)>` records the
cursor-x and width-px at the moment the handle is grabbed.
* `begin_sidebar_resize` / `end_sidebar_resize` set and clear it.
* Window-level `on_mouse_move` consults the origin first; while held,
it forwards the delta to `set_active_sidebar_width` clamped to
220–480 px so you can't accidentally annihilate either pane.
* Window-level `on_mouse_up` releases the drag.
* The handle itself is a 6 px transparent strip pinned to the right
edge of the expanded sidebar, `cursor_col_resize`, with a soft white
hover. mouse-down captures the origin; the rest is window events.
cargo test --workspace: 440 passed, 0 failed.
The design's TopBar.url placeholder reads `Search ELY or type a
command…`. We were shipping `Search or enter address`, the generic
URL-bar string from when the omnibar didn't yet host commands.
Match the design copy so the empty-state on `ely://new-tab` matches
home.jsx and command.jsx exactly.
The footer chips already advertised ↑↓ to navigate and ↵ to open;
they now match reality.
- chrome::command_match exposes COMMAND_ACTIONS / matching_actions
alongside the tab/history/bookmark match helpers and a
CommandSelection enum + visible_command_rows that returns the flat
ordered list of activatable rows. command_overlay drops its private
copies of the action const and matcher and consumes them from the
shared module so render and key handling share one source of truth.
- ElyShell tracks command_selected_index with command_select_next /
command_select_prev (cyclic, no notify when index doesn't change)
and activate_selected_command which dispatches the right shell call
for the currently selected CommandSelection variant and dismisses
the overlay. Dismissing command mode resets the index to 0.
- The shell root captures key_down via on_command_overlay_key_down.
When the live snapshot's command_query starts with '>', up / down
/ enter run the matching helper and the event stops propagating so
the omnibar input doesn't move its caret.
- Each rendered row receives a `selected` flag. The selected row gets
the design's tinted bg + accent-bar on the left edge so the active
result is unambiguous at any keyboard step.
Domain ships HIDDEN_SIDEBAR_WIDTH_PX = 8 alongside the existing
collapsed/default tiers. ElyShell tracks sidebar_hover_expanded with
expand_hidden_sidebar / collapse_hidden_sidebar helpers; switching
back to a non-hidden width via the layout cards or core API resets
the flag automatically so the sidebar can never be both hidden and
expanded after a mode change.
Renderer:
- render_sidebar takes a sidebar_hidden flag and routes to a thin
8 px clickable rail (hover bg + click expands) when the active
space's width is at HIDDEN.
- While the rail is expanded, render_browser overlays a transparent
backdrop + the full default-width sidebar absolutely positioned in
the shell inset, so the main pane content never reflows.
- collapsed_sidebar_active still drives the COLLAPSED-tier compact
sidebar; the hidden tier is opted out of that path.
Appearance form:
- Layout cards section gains the design's third "Hidden on hover"
card with a 6 px sliver preview that mutates the active space to
HIDDEN_SIDEBAR_WIDTH_PX. LayoutMode now derives id/width/preview
from a small enum so adding a fourth mode would be one match arm.
The hover-expanded state never persists into the domain; once the
user switches modes or clicks the backdrop, it collapses cleanly.
Clicking the picker pill now opens an in-flow space-list disclosure
beneath the workspace row instead of cycling to the next space. The
list shows every space's emoji glyph + name, highlights the active one
with the accent check, and on row click switches to that space and
closes the disclosure.
Sidebar disclosure rules:
- The chevron flips ChevronDown → ChevronUp when open so the affordance
reads at a glance.
- A "Manage spaces" footer routes to ely://settings/spaces and closes
the picker.
- ElyShell carries a workspace_picker_open: bool with toggle / close /
select_space_from_picker helpers; render_sidebar_header receives a
&ElyShell so it can read the open flag without leaking shell internals
to free helpers.
The existing SelectNextSpace shortcut still routes through
cycle_to_next_space, so the keyboard cycle behaviour is unchanged.
ElyShell now hosts a translucency_slider: Entity<SliderState> bound to
0..=100 step 1, defaulting to DEFAULT_TRANSLUCENCY_PCT. A subscription
on SliderEvent::Change writes the rounded value into the core via
set_translucency_pct, so dragging the thumb mutates the persisted
appearance setting in real time.
The appearance form swaps the static track-and-thumb visual for the
gpui_component Slider (160 wide) plus a live percentage readout. The
three preset chips move below the row as fast-set buttons that go
through a new set_translucency_pct_from_preset helper which writes
both core and the SliderState so the thumb tracks the chip choice.
reset_appearance now resets the slider to DEFAULT_TRANSLUCENCY_PCT
alongside resetting the core, keeping every UI source of truth in
lock-step.
Replaces the static "Install plugin · N active" hero button with the
design's pair: a glass search input + a primary Install action. The
input is bound to a new InputState on ElyShell (plugin_search_input);
on every render the catalog reads its current value and filters the
plugin grid by case-insensitive contains on name, author, and
description. An empty-needle render shows every installed plugin so
the page still works at rest.
When the search yields no matches, the grid swaps to an empty-state
copy that quotes the user's needle. Install action moves into a
trailing dark chip that calls choose_plugin_package, preserving the
existing file-picker flow.
Designs call for a radial-gradient dawn (cream base + pink upper-right
glow + blue lower-left glow). GPUI 0.2.2 only supports linear gradients,
so the wallpaper is composed of a cream base layer with two diagonal
linear gradients that fade to transparent at ~60% — the perceived effect
matches the design's softness without needing radial-gradient support.
Wallpaper is isolated to chrome::wallpaper so future appearance themes
(violet, mint, slate) extend the enum without touching the shell.