feat(slint): search input slides into the JUMP TO bar inline

Moves the in-page search out of the body column into the JUMP TO
bar itself, with a width animation so the input slides over the
tabs from the right edge on open (and back to 0 on close), matching
Tauri's `.page-search.open` behaviour.

JumpNavBar:
  - New `search-text` (in-out) and `search-text-edited` callback so
    the parent owns the query string + filter wiring while the bar
    owns the input UI.
  - Center region is a single Rectangle whose `clip: true` hides the
    expanding search-overlay until it has width. The overlay's
    width binds to `search-open ? parent.width : 0px` with a 200ms
    ease-in-out animation, so the tabs visually disappear behind it.
  - Tabs' TouchAreas are disabled while the search is open, so the
    visible click target is just the input.
  - Search icon flips to an X glyph and stays accent-tinted while
    open, signalling "click again to close".

ArtistPageView:
  - The standalone in-page search Rectangle in the body column is
    removed. The 24px head spacer stays so the loading state /
    Popular Tracks header sit at the same y as before.
  - JumpNavBar wired: search-text-edited routes through to
    ArtistActions.search; search-clicked toggles search-visible and
    also clears the query (and re-runs the empty search) on close
    so the filter releases as the input disappears.

cc
This commit is contained in:
vicrodh committed 2026-05-20 13:24:29 -06:00
1 parent df3ef14c81
commit 2b5e4aead1
2 files changed
+135 -111

No files matched your search

+11 -58
View File
@@ -501,66 +501,12 @@ export component ArtistPageView inherits Rectangle {
horizontal-stretch: 1;
spacing: 0px;
// 24px head spacing then straight into the loading state /
// Popular Tracks header — the in-page search now lives
// inside the JUMP TO bar (see jump-nav below), no longer
// a separate row in the body column.
Rectangle { height: 24px; }
// --- In-page search ---------------------------------------------
// Single client-side substring filter — applied to Popular
// Tracks (title + artist) and to every release-section
// album title. Hidden by default; the JUMP TO bar's search
// icon toggles `search-visible` (mirrors Tauri's search
// toggle inside `.jump-nav`).
if root.search-visible
&& (!ArtistState.loading || ArtistState.top-tracks.length > 0):
Rectangle {
height: 36px;
border-radius: Radius.sm;
background: Theme.surface-card;
border-width: 1px;
border-color: artist-search.has-focus
? Theme.border-subtle
: transparent;
HorizontalLayout {
padding-left: 12px;
padding-right: 12px;
spacing: 8px;
VerticalLayout {
alignment: center;
horizontal-stretch: 0;
QbzIcon {
source: @image-url("../assets/icons/search.svg");
width: 14px;
height: 14px;
tint: Theme.text-muted;
}
}
Rectangle {
horizontal-stretch: 1;
artist-search := TextInput {
width: 100%;
height: 100%;
color: Theme.text-primary;
font-size: Typography.body;
vertical-alignment: center;
single-line: true;
edited => {
ArtistActions.search(self.text);
}
}
Text {
visible: artist-search.text == "";
width: 100%;
height: 100%;
text: @tr("Search this page…");
color: Theme.text-muted;
font-size: Typography.body;
vertical-alignment: center;
}
}
}
}
Rectangle { height: 12px; }
if ArtistState.loading && ArtistState.top-tracks.length == 0: Rectangle {
height: 280px;
VerticalLayout {
@@ -757,6 +703,13 @@ export component ArtistPageView inherits Rectangle {
}
search-clicked => {
root.search-visible = !root.search-visible;
if (!root.search-visible) {
self.search-text = "";
ArtistActions.search("");
}
}
search-text-edited(query) => {
ArtistActions.search(query);
}
}