Fix Studio model picker toolbar overflow (#7403)
* fix(studio): contain model picker toolbar * fix(studio): preserve model picker tab icons
This commit is contained in:
parent
275c046c09
commit
1bd080208c
4 changed files with 37 additions and 11 deletions
|
|
@ -301,12 +301,12 @@ const HUB_SECTION_TABS: { value: string; label: string; icon?: ReactNode }[] = [
|
|||
{
|
||||
value: "recommended",
|
||||
label: "Recommended",
|
||||
icon: <HugeiconsIcon icon={StarIcon} className="size-3.5" />,
|
||||
icon: <HugeiconsIcon icon={StarIcon} className="size-3.5 shrink-0" />,
|
||||
},
|
||||
{
|
||||
value: "downloaded",
|
||||
label: "On Device",
|
||||
icon: <HugeiconsIcon icon={Download01Icon} className="size-3.5" />,
|
||||
icon: <HugeiconsIcon icon={Download01Icon} className="size-3.5 shrink-0" />,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -384,7 +384,9 @@ function ModelSelectorContent({
|
|||
{
|
||||
value: "connected",
|
||||
label: "Connected",
|
||||
icon: <HugeiconsIcon icon={CloudIcon} className="size-3.5" />,
|
||||
icon: (
|
||||
<HugeiconsIcon icon={CloudIcon} className="size-3.5 shrink-0" />
|
||||
),
|
||||
},
|
||||
]
|
||||
: HUB_SECTION_TABS,
|
||||
|
|
|
|||
|
|
@ -3064,13 +3064,18 @@ export function HubModelPicker({
|
|||
) : null}
|
||||
</div>
|
||||
|
||||
{/* Section tabs then the format and sort dropdowns, packed left with one
|
||||
uniform gap between every control. The box is sized so the last
|
||||
dropdown still lands on Search Hub's edge. Dropdowns hide on Connected. */}
|
||||
<div className="flex items-center gap-2">
|
||||
{/* Keep the left-packed controls on one line while they fit, then wrap
|
||||
whole groups before their intrinsic widths cross the picker edge.
|
||||
Dropdowns hide on Connected. */}
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-wrap items-center gap-2",
|
||||
hasConnected ? "-mr-4" : "-mr-2",
|
||||
)}
|
||||
>
|
||||
{sectionToggle}
|
||||
{showConnected ? null : (
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex max-w-full min-w-0 flex-wrap items-center gap-2">
|
||||
<HubOptionMenu
|
||||
value={formatFilter}
|
||||
options={FORMAT_FILTER_OPTIONS}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ export function PillTabs({
|
|||
className?: string;
|
||||
compact?: boolean;
|
||||
/** Size each tab to its label instead of equal widths. The active tab carries
|
||||
* the pill background directly (the toggle never animates). */
|
||||
* the pill background directly (the toggle never animates). Tabs only shrink
|
||||
* when their combined intrinsic width exceeds the available space. */
|
||||
fit?: boolean;
|
||||
}) {
|
||||
const activeIndex = Math.max(
|
||||
|
|
@ -84,7 +85,7 @@ export function PillTabs({
|
|||
onClick={() => onValueChange(tab.value)}
|
||||
className={cn(
|
||||
"relative z-10 inline-flex items-center justify-center gap-1.5 rounded-full transition-colors",
|
||||
fit ? "shrink-0" : "min-w-0 flex-1",
|
||||
fit ? "min-w-0 shrink" : "min-w-0 flex-1",
|
||||
compact ? "h-7 px-2.5 text-ui-11" : "h-9 px-3 text-ui-12p5",
|
||||
value === tab.value
|
||||
? "text-foreground"
|
||||
|
|
@ -97,7 +98,7 @@ export function PillTabs({
|
|||
)}
|
||||
>
|
||||
{tab.icon}
|
||||
{tab.label}
|
||||
<span className="min-w-0 truncate">{tab.label}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -217,6 +217,24 @@ def test_local_picker_rows_require_chat_capability():
|
|||
assert "row.capabilities.canChat" in memo.group(0)
|
||||
|
||||
|
||||
def test_model_picker_toolbar_reflows_before_crossing_picker_edge():
|
||||
"""The content-sized section tabs and fixed-width dropdowns must reflow,
|
||||
while an oversized tab group must shrink labels but preserve its icons."""
|
||||
picker = _read("features/model-picker/components/model-selector/pickers.tsx")
|
||||
assert '"flex flex-wrap items-center gap-2"' in picker
|
||||
assert 'hasConnected ? "-mr-4" : "-mr-2"' in picker
|
||||
assert '"flex max-w-full min-w-0 flex-wrap items-center gap-2"' in picker
|
||||
|
||||
tabs = _read("features/model-picker/components/model-selector/pill-tabs.tsx")
|
||||
assert 'fit ? "min-w-0 shrink" : "min-w-0 flex-1"' in tabs
|
||||
assert '<span className="min-w-0 truncate">{tab.label}</span>' in tabs
|
||||
|
||||
selector = _read("features/model-picker/components/model-selector.tsx")
|
||||
assert 'icon={StarIcon} className="size-3.5 shrink-0"' in selector
|
||||
assert 'icon={Download01Icon} className="size-3.5 shrink-0"' in selector
|
||||
assert 'icon={CloudIcon} className="size-3.5 shrink-0"' in selector
|
||||
|
||||
|
||||
def test_native_picked_gguf_template_read_through_lease():
|
||||
"""A native (picked / drag-drop) GGUF's path lives only in its signed lease,
|
||||
and the picker chat-template GET has no lease plumbing, so the default
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue