feat(slint): split sidebar toggle from nav buttons, animate side panels

NavButtons now renders the collapse toggle and history buttons as two
spaced pills instead of separating them with a bar. Queue and Lyrics
sidebars animate their own width open/closed (160ms ease-in-out) so
they slide in like the main sidebar instead of appearing abruptly.

cc
This commit is contained in:
vicrodh committed 2026-05-18 22:43:13 -06:00
1 parent 7e6e548598
commit 1f6159f3ba
4 files changed
+57 -38

No files matched your search

+5 -4
View File
@@ -108,10 +108,11 @@ export component AppShell inherits Rectangle {
}
}
// Right-side panel — a layout sibling of the content area,
// so it shrinks the content rather than overlaying it.
if ShellState.right-panel == 1: QueueSidebar { }
if ShellState.right-panel == 2: LyricsSidebar { }
// Right-side panels — layout siblings of the content area, so
// they shrink the content rather than overlaying it. Always
// present; each animates its own width open/closed.
QueueSidebar { }
LyricsSidebar { }
}
PlayerBar {
@@ -37,7 +37,11 @@ component CloseButton inherits Rectangle {
}
export component LyricsSidebar inherits Rectangle {
width: 320px;
// Always present; the width animates 0 <-> 320 so the panel slides
// in smoothly, matching the left sidebar's collapse animation.
width: ShellState.right-panel == 2 ? 320px : 0px;
clip: true;
animate width { duration: 160ms; easing: ease-in-out; }
background: Theme.surface-card;
VerticalLayout {
+42 -32
View File
@@ -1,9 +1,9 @@
// Browser-like back / forward navigation pair.
// Sidebar-collapse toggle + browser-like back / forward navigation pair.
//
// Same visual format as the Discover tab pill group (an elevated rounded
// container). Used inline beside the Discover tabs and in place of the
// per-page Back button. Both buttons drive the NavState global, so the
// Rust nav history records every move.
// Two separate elevated pills with a gap between them: the sidebar
// toggle stands on its own, the [<] [>] history pair is its own group.
// Used inline beside the Discover tabs and in place of the per-page
// Back button.
import { Theme } from "../foundation/semantic-colors.slint";
import { NavState, ShellState } from "../state.slint";
@@ -39,40 +39,50 @@ component NavBtn inherits Rectangle {
}
}
export component NavButtons inherits Rectangle {
// One elevated rounded pill wrapping its NavBtn children.
component NavPill inherits Rectangle {
background: Theme.surface-elevated;
border-radius: 6px;
width: btn-row.preferred-width;
height: 34px;
@children
}
btn-row := HorizontalLayout {
padding: 3px;
spacing: 4px;
// Leading button: collapses / expands the left sidebar. Lives
// here so it appears just left of the [<] [>] pair in every view.
NavBtn {
icon: @image-url("../assets/icons/panel-left.svg");
clicked => {
ShellState.sidebar-collapsed = !ShellState.sidebar-collapsed;
export component NavButtons inherits HorizontalLayout {
spacing: 8px;
// Sidebar collapse toggle — its own pill.
NavPill {
width: collapse-row.preferred-width;
collapse-row := HorizontalLayout {
padding: 3px;
NavBtn {
icon: @image-url("../assets/icons/panel-left.svg");
clicked => {
ShellState.sidebar-collapsed = !ShellState.sidebar-collapsed;
}
}
}
// 1px separator between the collapse button and the history pair.
Rectangle {
width: 1px;
background: Theme.border-subtle;
}
NavBtn {
icon: @image-url("../assets/icons/chevron-left.svg");
enabled: NavState.can-back;
clicked => {
NavState.request-back();
}
// Back / forward history pair — its own pill.
NavPill {
width: history-row.preferred-width;
history-row := HorizontalLayout {
padding: 3px;
spacing: 4px;
NavBtn {
icon: @image-url("../assets/icons/chevron-left.svg");
enabled: NavState.can-back;
clicked => {
NavState.request-back();
}
}
}
NavBtn {
icon: @image-url("../assets/icons/chevron-right.svg");
enabled: NavState.can-forward;
clicked => {
NavState.request-forward();
NavBtn {
icon: @image-url("../assets/icons/chevron-right.svg");
enabled: NavState.can-forward;
clicked => {
NavState.request-forward();
}
}
}
}
+5 -1
View File
@@ -110,7 +110,11 @@ component QueueRow inherits Rectangle {
}
export component QueueSidebar inherits Rectangle {
width: 320px;
// Always present; the width animates 0 <-> 320 so the panel slides
// in smoothly, matching the left sidebar's collapse animation.
width: ShellState.right-panel == 1 ? 320px : 0px;
clip: true;
animate width { duration: 160ms; easing: ease-in-out; }
background: Theme.surface-card;
VerticalLayout {