feat(design): the header search is a 40 glass pill; a wrapper field dims for its input only (E28 S3c)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import clsx from "clsx";
|
||||
import {
|
||||
useRef,
|
||||
type FocusEventHandler,
|
||||
@@ -12,10 +13,12 @@ import { PaletteKeycap } from "./PaletteLauncher";
|
||||
import { Button } from "./ui/Button";
|
||||
import { IconButton } from "./ui/IconButton";
|
||||
import { InnerInput } from "./ui/Input";
|
||||
import { fieldClass } from "./ui/fieldStyles";
|
||||
|
||||
// The floating search pill in the top header. One component for every module that searches
|
||||
// (feed, Plex, channels, playlists): a glass rounded box with a search icon, the input, a
|
||||
// clear button, and a "Go" trigger (Enter also fires it). The feed passes its live-YouTube
|
||||
// (feed, Plex, channels, playlists): a 40px glass pill with the A4 field edge (the page's one hero
|
||||
// field, the YouTube/Gmail shape), holding a search icon, the input, a clear button and a "Go"
|
||||
// trigger (Enter also fires it). What sits inside the pill is round too, so the radii nest. The feed passes its live-YouTube
|
||||
// escalation as the Go action; the other modules filter as you type and Go just commits/blurs.
|
||||
//
|
||||
// Optional slots keep the box reusable while letting one module enrich it: `leading` replaces the
|
||||
@@ -72,10 +75,15 @@ export default function SearchBar({
|
||||
// small pills (module name + Plex scope toggle / feed sync chip) share the line above it.
|
||||
return (
|
||||
<div className="pointer-events-auto relative flex-1 min-w-0 max-w-xl @min-[420px]/appmain:min-w-[15rem] @max-[640px]/appmain:order-last @max-[640px]/appmain:basis-full">
|
||||
<div className="h-11 pl-3 pr-2 rounded-2xl glass-menu flex items-center gap-2 focus-within:outline-2 focus-within:outline-accent/60 focus-within:outline-offset-2">
|
||||
{/* `free` + its own padding: the Go button sits 6px in from the pill's end, not a field's 12. */}
|
||||
<div
|
||||
className={clsx(
|
||||
fieldClass({ size: "free", pill: true, floating: true }),
|
||||
"flex h-10 items-center gap-2 pr-1.5 pl-3 text-sm pointer-coarse:text-base",
|
||||
)}
|
||||
>
|
||||
{leading ?? <Search className="w-4 h-4 shrink-0 text-muted" />}
|
||||
<InnerInput
|
||||
className="text-sm"
|
||||
{...inputProps}
|
||||
ref={inputRef}
|
||||
value={value}
|
||||
@@ -94,7 +102,7 @@ export default function SearchBar({
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
{value && (
|
||||
<IconButton onClick={() => onChange("")} label={t("header.clearSearch")}>
|
||||
<IconButton round onClick={() => onChange("")} label={t("header.clearSearch")}>
|
||||
<X />
|
||||
</IconButton>
|
||||
)}
|
||||
@@ -102,6 +110,7 @@ export default function SearchBar({
|
||||
{onGo && (
|
||||
<Button
|
||||
size="sm"
|
||||
round
|
||||
onClick={fire}
|
||||
disabled={goDisabled}
|
||||
title={goTitle ?? goLabel ?? t("header.goTip")}
|
||||
|
||||
Reference in New Issue
Block a user