fix(objects): collapse toolbar controls when object view is narrow

This commit is contained in:
zipg
2026-09-21 11:37:24 +08:00
committed by GitHub
parent e2d7bba760
commit e364e4a70f
6 changed files with 44 additions and 3 deletions
@@ -3393,8 +3393,8 @@ function getObjectBrowserMenuItems(item: ObjectBrowserRow): ContextMenuItem[] {
{{ props.database }}
</span>
</div>
<div class="flex min-w-24 flex-1 items-center gap-2">
<div class="relative min-w-0 flex-1">
<div class="flex flex-1 items-center gap-2">
<div class="relative min-w-[6rem] flex-1">
<Search class="pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" />
<Input v-model="search" data-object-search-input class="h-7 pl-8 pr-6 text-xs" :placeholder="isMongodb ? t('objects.searchCollections') : t('objects.search')" @keydown="onSearchKeydown" />
<button v-if="search" type="button" class="absolute right-1.5 top-1/2 flex h-4 w-4 -translate-y-1/2 items-center justify-center rounded text-muted-foreground hover:bg-muted hover:text-foreground" :aria-label="t('common.clear')" @click="clearObjectSearch">
@@ -3402,7 +3402,14 @@ function getObjectBrowserMenuItems(item: ObjectBrowserRow): ContextMenuItem[] {
</button>
</div>
<div v-if="showObjectFilter && showInlineObjectFilter" class="flex h-7 shrink-0 items-center rounded border bg-muted/20 p-0.5">
<button v-for="filter in objectFilters" :key="filter" type="button" class="h-6 rounded-sm px-2 text-xs text-muted-foreground transition-colors hover:text-foreground" :class="{ 'bg-background text-foreground shadow-sm': objectFilter === filter }" @click="selectObjectFilter(filter)">
<button
v-for="filter in objectFilters"
:key="filter"
type="button"
class="h-6 shrink-0 whitespace-nowrap rounded-sm px-2 text-xs text-muted-foreground transition-colors hover:text-foreground"
:class="{ 'bg-background text-foreground shadow-sm': objectFilter === filter }"
@click="selectObjectFilter(filter)"
>
{{ filterLabel(filter) }}
</button>
</div>
@@ -0,0 +1,34 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
// Issue #9200: when the "Browse Objects" pane is narrow, the keyword search box
// collapsed to a sliver and the "全部/表/视图" chips were painted on top of it,
// instead of the toolbar condensing its controls into the overflow menu.
//
// useToolbarOverflow only condenses while the row reports real overflow, and its
// contract requires "non-shrinking (shrink-0) or floored (min-w-*) children":
// 1. the collapsed search wrapper was `min-w-0`, so the wrapper dropped to 0
// width while the input inside still painted at its padding width (58px),
// drawing on top of the neighbouring filter chips;
// 2. the search + filter group carried `min-w-24`, which overrode the
// content-based minimum and let the group shrink below its own content, so
// its children spilled into the sort control instead of overflowing the row;
// 3. the filter chips allowed their labels to wrap, so the group's min-content
// (longest word) was far below the width the chips actually occupy.
// Each of the three is load-bearing; removing any one of them brings the overlap
// back at some pane width.
const objectBrowserSource = readFileSync(new URL("../ObjectBrowser.vue", import.meta.url), "utf8");
describe("ObjectBrowser toolbar condenses instead of overlapping when narrow", () => {
it("floors the search box and lets the search + filter group keep its content minimum", () => {
// The floored wrapper keeps the input from painting over its neighbours, and
// dropping `min-w-24` lets the group's content-based minimum stop the spill
// into the sort control, so the row reports overflow instead.
expect(objectBrowserSource).toMatch(/<div class="flex flex-1 items-center gap-2">\s*<div class="relative min-w-\[6rem\] flex-1">/);
});
it("pins the filter chips to their single-line width so the row reports overflow", () => {
expect(objectBrowserSource).toMatch(/<button\s+v-for="filter in objectFilters"[\s\S]*?class="h-6 shrink-0 whitespace-nowrap rounded-sm/);
});
});
Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB