fix: 优化形态图库移动端筛选布局
移动端将搜索、筛选和图标操作拆分为三行,避免状态筛选与四个操作按钮互相挤压。
This commit is contained in:
+29
-29
@@ -1,49 +1,49 @@
|
|||||||
# Design QA
|
# Design QA
|
||||||
|
|
||||||
- Source visual truth: `/workspace/scratch/6e52996114b8/upload/18a4bcb0-1b3a-43c8-b459-deef213b5c2f.png`
|
- Source visual truth: `/workspace/scratch/6e52996114b8/upload/57970687-58ad-46f8-9977-15ec608a8b12.png`
|
||||||
- Source pixel dimensions: `235 × 137`.
|
- Source pixel dimensions: `504 × 158`.
|
||||||
- Intended implementation viewport: responsive dark theme; desktop shows hover explanations and mobile disables them at `760px` and below.
|
- Intended implementation viewport: dark-theme mobile workspace, focused content width around `393px` CSS pixels.
|
||||||
- Implementation screenshot: unavailable.
|
- Implementation screenshot: unavailable.
|
||||||
- CSS size and density normalization: unavailable because the implementation could not be opened in the cloud browser.
|
- CSS size and density normalization: unavailable because the implementation could not be opened in the cloud browser.
|
||||||
- State: 形态图片页默认筛选、网格布局、四个图标操作可见。
|
- State: 形态图片页默认筛选区,四个图标操作可见。
|
||||||
|
|
||||||
## Full-view comparison evidence
|
## Full-view comparison evidence
|
||||||
|
|
||||||
The source crop shows four adjacent icon buttons with two different spacing values: the grid/masonry pair is tightly grouped while refresh and batch image have visibly larger gaps.
|
The source crop shows the search and type controls on the first row, while the second row combines a wide status select with four icon buttons. The second row is visually crowded and leaves the controls competing for the same horizontal space.
|
||||||
|
|
||||||
The implementation now places all four controls in one flex group with a shared `8px` gap. Grid, masonry, refresh, and batch image each use `NPopover`; all four popovers share the same responsive `disabled` state and are disabled at `max-width: 760px`.
|
The mobile implementation now uses three explicit rows at container widths up to `460px`: full-width search, two equal-width selects, then a full-width right-aligned icon action row. The existing `10px` internal rhythm and icon ordering are preserved.
|
||||||
|
|
||||||
A local Sites preview started successfully, but the cloud browser rejected `terminal.local` with `net::ERR_BLOCKED_BY_CLIENT` on both attempts. Therefore no browser-rendered implementation screenshot is available.
|
A local Sites preview started successfully, but the cloud browser rejected `terminal.local` with `net::ERR_BLOCKED_BY_CLIENT`. Therefore no browser-rendered implementation screenshot is available.
|
||||||
|
|
||||||
## Focused region comparison evidence
|
## Focused region comparison evidence
|
||||||
|
|
||||||
- Control order: grid → masonry → refresh → batch image.
|
- Row 1: search spans both grid columns.
|
||||||
- Spacing: all four controls are direct children of the same `gallery-layout-switch` flex group with `gap: 8px`.
|
- Row 2: subject type and image status use equal-width `minmax(0, 1fr)` columns.
|
||||||
- Desktop explanations: all four controls use hover-triggered `NPopover` copy.
|
- Row 3: the four icon actions occupy the complete row and align to the right.
|
||||||
- Mobile behavior: all four popovers bind `:disabled="isMobile"`; the media query follows `(max-width: 760px)`.
|
- Spacing: both column and row gaps are `10px`.
|
||||||
- Accessibility: every icon-only button retains a stable Chinese `aria-label`; native `title` attributes were removed from the first two buttons.
|
- Accessibility and behavior: filter labels, layout switching, refresh, batch action, and mobile-disabled popovers remain unchanged.
|
||||||
|
|
||||||
These are code-level checks only and do not replace a rendered focused-region comparison.
|
These are code-level checks only and do not replace a rendered focused-region comparison.
|
||||||
|
|
||||||
## Required fidelity surfaces
|
## Required fidelity surfaces
|
||||||
|
|
||||||
- Fonts and typography: no visible toolbar type styles changed; popover typography remains Naive UI-managed.
|
- Fonts and typography: no typography or truncation rules changed.
|
||||||
- Spacing and layout rhythm: the four-button group now uses one uniform `8px` rhythm.
|
- Spacing and layout rhythm: mobile controls now follow a stable three-row grid instead of compressing the status select and actions together.
|
||||||
- Colors and visual tokens: selected and unselected button colors are unchanged.
|
- Colors and visual tokens: existing dark-theme surface and control tokens are unchanged.
|
||||||
- Image quality and asset fidelity: no image behavior changed.
|
- Image quality and asset fidelity: no image behavior or assets changed.
|
||||||
- Copy and content: desktop popovers explain `网格布局`, `瀑布流布局`, `刷新图库`, and `批量生图`; mobile keeps accessible names without hover overlays.
|
- Copy and content: all search, type, status, and icon action labels are preserved.
|
||||||
|
|
||||||
## Findings
|
## Findings
|
||||||
|
|
||||||
- [P1] Browser-rendered comparison unavailable
|
- [P1] Browser-rendered comparison unavailable
|
||||||
- Location: 形态图片筛选区的四个图标按钮。
|
- Location: 形态图片移动端筛选区。
|
||||||
- Evidence: the required cloud browser returns `net::ERR_BLOCKED_BY_CLIENT` for the healthy local preview on two attempts.
|
- Evidence: the required cloud browser returns `net::ERR_BLOCKED_BY_CLIENT` for the healthy local preview.
|
||||||
- Impact: exact pixel spacing, popover placement, hover visibility, responsive disabling, and console state cannot be visually certified.
|
- Impact: exact responsive wrapping, control heights, touch spacing, and console state cannot be visually certified.
|
||||||
- Fix: capture the page in an available browser at desktop and mobile widths and compare the four-button control group.
|
- Fix: capture the page in an available browser near `393px` content width and compare the three-row filter layout.
|
||||||
|
|
||||||
## Primary interactions tested
|
## Primary interactions tested
|
||||||
|
|
||||||
Automated tests verify the exact four-button order, layout switching, refresh behavior, four desktop popover bindings, responsive disabled binding, accessible labels, and uniform generated `8px` CSS gap. All 275 tests pass. Browser hover and touch interaction were unavailable.
|
Automated tests verify the mobile two-column grid, full-width search row, equal select row, full-width right-aligned icon row, filter behavior, icon ordering, layout switching, and refresh workflow. All 275 tests pass.
|
||||||
|
|
||||||
## Console errors checked
|
## Console errors checked
|
||||||
|
|
||||||
@@ -51,15 +51,15 @@ Not checked because the page could not be opened in the cloud browser.
|
|||||||
|
|
||||||
## Comparison history
|
## Comparison history
|
||||||
|
|
||||||
- Iteration 1: the source identified inconsistent spacing and missing explanations on the first two controls.
|
- Iteration 1: the source identified crowding between the status filter and the four icon actions.
|
||||||
- Iteration 2: consolidated all four controls into one spacing group, added popovers to grid and masonry, disabled all four popovers on mobile, and passed the full test/build suite. Browser capture remained blocked.
|
- Iteration 2: separated mobile controls into search, equal filters, and action rows; the full test/build suite passed, while browser capture remained blocked.
|
||||||
|
|
||||||
## Implementation checklist
|
## Implementation checklist
|
||||||
|
|
||||||
- [x] Give all four icon buttons the same gap.
|
- [x] Give mobile search the full first row.
|
||||||
- [x] Add `NPopover` explanations to grid and masonry.
|
- [x] Give type and status filters equal widths on the second row.
|
||||||
- [x] Disable all four `NPopover` components on mobile.
|
- [x] Move four icon actions to a dedicated right-aligned third row.
|
||||||
- [x] Preserve accessible labels and existing button behavior.
|
- [x] Preserve existing filter and action behavior.
|
||||||
- [ ] Capture and compare desktop hover and mobile touch states in the cloud browser.
|
- [ ] Capture and compare the rendered mobile state in the cloud browser.
|
||||||
|
|
||||||
final result: blocked
|
final result: blocked
|
||||||
|
|||||||
@@ -553,6 +553,7 @@ async function showStaleForms() {
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-image-filters" role="group" aria-label="形态图片筛选">
|
<div class="form-image-filters" role="group" aria-label="形态图片筛选">
|
||||||
<NInput
|
<NInput
|
||||||
|
class="search-filter"
|
||||||
placeholder="搜索主体、引用或形态"
|
placeholder="搜索主体、引用或形态"
|
||||||
:input-props="{ 'aria-label': '搜索形态图片' }"
|
:input-props="{ 'aria-label': '搜索形态图片' }"
|
||||||
v-model:value="search"
|
v-model:value="search"
|
||||||
@@ -560,6 +561,7 @@ async function showStaleForms() {
|
|||||||
><template #prefix><Search :size="14" /></template
|
><template #prefix><Search :size="14" /></template
|
||||||
></NInput>
|
></NInput>
|
||||||
<NSelect
|
<NSelect
|
||||||
|
class="module-filter"
|
||||||
aria-label="筛选主体类型"
|
aria-label="筛选主体类型"
|
||||||
v-model:value="module"
|
v-model:value="module"
|
||||||
:options="[
|
:options="[
|
||||||
@@ -964,7 +966,27 @@ async function showStaleForms() {
|
|||||||
}
|
}
|
||||||
@container (max-width: 460px) {
|
@container (max-width: 460px) {
|
||||||
.form-image-filters {
|
.form-image-filters {
|
||||||
@apply grid-cols-[minmax(0,_1fr)_120px] gap-x-2.5;
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
/* 移动端让搜索独占首行,两个筛选项等宽,图标操作独占末行,避免控件互相挤压。 */
|
||||||
|
.search-filter {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
grid-row: 1;
|
||||||
|
}
|
||||||
|
.module-filter {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
.status-filter {
|
||||||
|
grid-column: 2;
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
.form-image-display-controls {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
grid-row: 3;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
.filter-result-count {
|
.filter-result-count {
|
||||||
@apply hidden;
|
@apply hidden;
|
||||||
|
|||||||
@@ -208,8 +208,15 @@ describe('全站平面主题', () => {
|
|||||||
expect(css).toMatch(/\.asset-impact-context\s*\{[^}]*padding(?:-block)?:\s*5px/)
|
expect(css).toMatch(/\.asset-impact-context\s*\{[^}]*padding(?:-block)?:\s*5px/)
|
||||||
expect(css).toMatch(/\.asset-impact-context\s*\{[^}]*margin:\s*0/)
|
expect(css).toMatch(/\.asset-impact-context\s*\{[^}]*margin:\s*0/)
|
||||||
expect(css).toMatch(
|
expect(css).toMatch(
|
||||||
/@container \(max-width: 460px\)\s*\{[^}]*\.form-image-filters\s*\{[^}]*grid-template-columns:\s*minmax\(0, 1fr\) 120px;[^}]*\}[^}]*\.filter-result-count\s*\{[^}]*display:\s*none;/
|
/@container \(max-width: 460px\)\s*\{[^}]*\.form-image-filters\s*\{[^}]*grid-template-columns:\s*repeat\(2, minmax\(0, 1fr\)\);[^}]*gap:\s*10px;/
|
||||||
)
|
)
|
||||||
|
expect(css).toMatch(/\.search-filter\s*\{[^}]*grid-column:\s*1 \/ -1;[^}]*grid-row:\s*1;/)
|
||||||
|
expect(css).toMatch(/\.module-filter\s*\{[^}]*grid-column:\s*1;[^}]*grid-row:\s*2;/)
|
||||||
|
expect(css).toMatch(/\.status-filter\s*\{[^}]*grid-column:\s*2;[^}]*grid-row:\s*2;/)
|
||||||
|
expect(css).toMatch(
|
||||||
|
/\.form-image-display-controls\s*\{[^}]*grid-column:\s*1 \/ -1;[^}]*grid-row:\s*3;[^}]*width:\s*100%;[^}]*justify-content:\s*flex-end;/
|
||||||
|
)
|
||||||
|
expect(css).toMatch(/\.filter-result-count\s*\{[^}]*display:\s*none;/)
|
||||||
expect(css).toMatch(
|
expect(css).toMatch(
|
||||||
/\.gallery-layout-switch \.layout-option-button:not\(\.layout-option-active\)\s*\{[^}]*background:\s*var\(--app-control-hover\);/
|
/\.gallery-layout-switch \.layout-option-button:not\(\.layout-option-active\)\s*\{[^}]*background:\s*var\(--app-control-hover\);/
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user