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:
4 files changed
+57
-38
No files matched your search
@@ -108,10 +108,11 @@ export component AppShell inherits Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right-side panel — a layout sibling of the content area,
|
// Right-side panels — layout siblings of the content area, so
|
||||||
// so it shrinks the content rather than overlaying it.
|
// they shrink the content rather than overlaying it. Always
|
||||||
if ShellState.right-panel == 1: QueueSidebar { }
|
// present; each animates its own width open/closed.
|
||||||
if ShellState.right-panel == 2: LyricsSidebar { }
|
QueueSidebar { }
|
||||||
|
LyricsSidebar { }
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerBar {
|
PlayerBar {
|
||||||
|
|||||||
@@ -37,7 +37,11 @@ component CloseButton inherits Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export component LyricsSidebar 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;
|
background: Theme.surface-card;
|
||||||
|
|
||||||
VerticalLayout {
|
VerticalLayout {
|
||||||
|
|||||||
@@ -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
|
// Two separate elevated pills with a gap between them: the sidebar
|
||||||
// container). Used inline beside the Discover tabs and in place of the
|
// toggle stands on its own, the [<] [>] history pair is its own group.
|
||||||
// per-page Back button. Both buttons drive the NavState global, so the
|
// Used inline beside the Discover tabs and in place of the per-page
|
||||||
// Rust nav history records every move.
|
// Back button.
|
||||||
|
|
||||||
import { Theme } from "../foundation/semantic-colors.slint";
|
import { Theme } from "../foundation/semantic-colors.slint";
|
||||||
import { NavState, ShellState } from "../state.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;
|
background: Theme.surface-elevated;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
width: btn-row.preferred-width;
|
|
||||||
height: 34px;
|
height: 34px;
|
||||||
|
@children
|
||||||
|
}
|
||||||
|
|
||||||
btn-row := HorizontalLayout {
|
export component NavButtons inherits HorizontalLayout {
|
||||||
padding: 3px;
|
spacing: 8px;
|
||||||
spacing: 4px;
|
|
||||||
// Leading button: collapses / expands the left sidebar. Lives
|
// Sidebar collapse toggle — its own pill.
|
||||||
// here so it appears just left of the [<] [>] pair in every view.
|
NavPill {
|
||||||
NavBtn {
|
width: collapse-row.preferred-width;
|
||||||
icon: @image-url("../assets/icons/panel-left.svg");
|
collapse-row := HorizontalLayout {
|
||||||
clicked => {
|
padding: 3px;
|
||||||
ShellState.sidebar-collapsed = !ShellState.sidebar-collapsed;
|
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;
|
// Back / forward history pair — its own pill.
|
||||||
background: Theme.border-subtle;
|
NavPill {
|
||||||
}
|
width: history-row.preferred-width;
|
||||||
NavBtn {
|
history-row := HorizontalLayout {
|
||||||
icon: @image-url("../assets/icons/chevron-left.svg");
|
padding: 3px;
|
||||||
enabled: NavState.can-back;
|
spacing: 4px;
|
||||||
clicked => {
|
NavBtn {
|
||||||
NavState.request-back();
|
icon: @image-url("../assets/icons/chevron-left.svg");
|
||||||
|
enabled: NavState.can-back;
|
||||||
|
clicked => {
|
||||||
|
NavState.request-back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
NavBtn {
|
||||||
NavBtn {
|
icon: @image-url("../assets/icons/chevron-right.svg");
|
||||||
icon: @image-url("../assets/icons/chevron-right.svg");
|
enabled: NavState.can-forward;
|
||||||
enabled: NavState.can-forward;
|
clicked => {
|
||||||
clicked => {
|
NavState.request-forward();
|
||||||
NavState.request-forward();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,11 @@ component QueueRow inherits Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export component QueueSidebar 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;
|
background: Theme.surface-card;
|
||||||
|
|
||||||
VerticalLayout {
|
VerticalLayout {
|
||||||
|
|||||||
Reference in new issue
Block a user