13 KiB
G01 Centered Minimum-Height Add Sheet Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use
superpowers:executing-plansto implement this plan task-by-task. Subagents and worktrees are prohibited for this project.
Goal: Make the G01 “添加家谱” sheet use a 780rpx minimum height whose visible upper edge reaches the user-marked position, center the complete title-and-actions group, and separate adjacent buttons by 24rpx while preserving safe growth and scrolling for longer content.
Architecture: Keep the existing single g01-add-sheet-background-v3.png nine-slice sheet and existing AppButton assets. The add-dialog__body flow container uses vertical auto margins to remain centered as its two adjacent-button gaps increase from 6rpx to 24rpx; the margins collapse when content grows, while the close control follows the heading in every height state.
Tech Stack: uni-app Vue single-file component, SCSS with rpx, PowerShell visual-contract tests, Chrome DevTools Protocol on the existing port-9222 project tab.
Global Constraints
- Modify only G01’s current “添加家谱” sheet; do not change other G01 states, the genealogy switcher, or other pages.
- Do not use subagents, worktrees,
git add,git commit,git push,git reset, orgit checkout. - Preserve every existing modified, untracked, ignored, test, document, screenshot, master, candidate, and asset file.
- Do not loosen test thresholds and do not connect APIs.
- Keep the single complete background asset and existing project
AppButtonstyles. - Keep
max-height: calc(100vh - 80rpx)and content scrolling. - H5 evidence is internal only; Android/HBuilderX remains unverified.
- Do not mark G01
[x], frozen, or accepted without the user’s explicit “通过”.
Task 1: Tighten the G01 visual contract for the centered body
Files:
- Modify:
tests/g01-visual-contract.ps1:78-135 - Test:
tests/g01-visual-contract.ps1
Interfaces:
-
Consumes: the G01 add-sheet template and SCSS as plain UTF-8 source text.
-
Produces: a source contract requiring
add-dialog__body, nested close control,780rpxminimum height, symmetric content padding, and flow-based centering. -
Step 1: Require the new body structure and nested close control
Add class="add-dialog__body" to the required markup tokens and add this structural check:
if ($addMarkup -notmatch '(?s)<view class="add-dialog__body">\s*<view class="add-dialog__heading">.*?class="add-dialog__close".*?</view>\s*</view>\s*<view class="add-dialog__actions">') {
throw 'G-01 add sheet must keep the close control with the centered heading and actions body.'
}
- Step 2: Replace the obsolete
620rpxand fixed-close assertions
Use these exact contracts:
if ($page -notmatch '(?s)\.add-dialog\s*\{[^}]*min-height:\s*780rpx;[^}]*max-height:\s*calc\(100vh\s*-\s*80rpx\);') {
throw 'G-01 add sheet does not reach the approved arrow-aligned minimum height.'
}
if ($page -notmatch '(?s)\.add-dialog__content\s*\{[^}]*min-height:\s*780rpx;[^}]*max-height:\s*calc\(100vh\s*-\s*80rpx\);[^}]*padding:\s*96rpx\s+52rpx\s+calc\(96rpx\s*\+\s*env\(safe-area-inset-bottom\)\);') {
throw 'G-01 add sheet does not reserve the approved symmetric centering area.'
}
if ($page -notmatch '(?s)\.add-dialog__body\s*\{[^}]*margin:\s*auto\s+0;') {
throw 'G-01 add sheet body does not center safely with collapsible auto margins.'
}
if ($page -notmatch '(?s)\.add-dialog__heading\s*\{[^}]*position:\s*relative;[^}]*padding-right:\s*96rpx;') {
throw 'G-01 add sheet heading does not own the close-control positioning context.'
}
if ($page -notmatch '(?s)\.add-dialog__close\s*\{[^}]*position:\s*absolute;[^}]*top:\s*0;[^}]*right:\s*-22rpx;') {
throw 'G-01 add sheet close control does not follow the centered heading.'
}
if ($page -notmatch '(?s)\.add-dialog__actions\s*>\s*\.app-button\s*\+\s*\.app-button\s*\{[^}]*margin-top:\s*24rpx;') {
throw 'G-01 add sheet buttons do not keep the approved 24rpx spacing.'
}
Remove the assertions requiring 620rpx, 118rpx 52rpx calc(64rpx...), and top: 116rpx.
- Step 3: Run the contract and observe the intended failure
Run:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
Expected: FAIL with G-01 add sheet must keep the close control with the centered heading and actions body. or the new 780rpx minimum-height failure. A script parse error is not an acceptable red state.
Task 2: Implement the centered, safely growing sheet body
Files:
- Modify:
pages/genealogy/g01-my-genealogies.vue:235-250 - Modify:
pages/genealogy/g01-my-genealogies.vue:952-961 - Test:
tests/g01-visual-contract.ps1
Interfaces:
-
Consumes: existing
addDialogVisible,closeAddDialog,applyToJoin,joinByInvite, andcreateGenealogybehavior. -
Produces:
add-dialog__body, which centers at the minimum height, grows with content, and becomes top-origin scroll content at the maximum height. -
Step 1: Group the heading and actions, and nest close under the heading
Replace only the inner add-sheet markup with:
<view class="add-dialog__content">
<view class="add-dialog__body">
<view class="add-dialog__heading">
<text class="dialog-title">添加家谱</text>
<text class="dialog-copy">建议先搜索已有家谱,避免重复创建</text>
<view class="add-dialog__close" role="button" aria-label="关闭" hover-class="action-hover" @click="closeAddDialog">
<image class="add-dialog__close-icon" src="/static/assets/modules/genealogy/transparent/g01-dialog-close.png" mode="aspectFit" />
</view>
</view>
<view class="add-dialog__actions">
<AppButton block label="搜索家谱" @click="applyToJoin" />
<AppButton block type="secondary" label="邀请码加入" @click="joinByInvite" />
<AppButton block type="secondary" label="继续创建家谱" @click="createGenealogy" />
</view>
</view>
</view>
- Step 2: Apply the minimum-height and safe-centering styles
Use these exact declarations while preserving the current border-image declarations:
.add-dialog { position: relative; width: 100%; min-height: 780rpx; max-height: calc(100vh - 80rpx); box-sizing: border-box; border: 1px solid transparent; border-image-source: url("/static/assets/modules/genealogy/transparent/g01-add-sheet-background-v3.png"); border-image-slice: 220 0 1 0 fill; border-image-width: 118rpx 0 1rpx; border-image-repeat: stretch; }
.add-dialog__content { position: relative; z-index: 2; display: flex; min-height: 780rpx; max-height: calc(100vh - 80rpx); flex-direction: column; align-items: stretch; box-sizing: border-box; padding: 96rpx 52rpx calc(96rpx + env(safe-area-inset-bottom)); overflow-y: auto; }
.add-dialog__body { margin: auto 0; }
.add-dialog__heading { position: relative; padding-right: 96rpx; }
.add-dialog__close { position: absolute; z-index: 3; top: 0; right: -22rpx; display: flex; width: 80rpx; height: 80rpx; align-items: center; justify-content: center; }
.add-dialog__actions { display: flex; flex-direction: column; margin: 62rpx -32rpx 0; }
.add-dialog__actions > .app-button + .app-button { margin-top: 24rpx; }
- Step 3: Run the focused contract
Run:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
Expected: PASS G-01 visual contract.
- Step 4: Run the adjacent G01 state contracts
Run:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/g01-loading-state-contract.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/g01-error-state-contract.ps1
git diff --check
Expected: all four G01 contracts pass; git diff --check exits 0. Existing line-ending warnings may remain, but no whitespace error may be introduced.
Task 3: Verify minimum, growth, overflow, and interactions in the existing Chrome tab
Files:
- Create evidence only:
docs/design/screens/runtime/2026-07-19/g01-approval/05-add-dialog-centered-min-412x915.png - Create evidence only:
docs/design/screens/runtime/2026-07-19/g01-approval/05-add-dialog-centered-six-buttons-412x915.png - No production or test file changes.
Interfaces:
-
Consumes: the unique existing
http://localhost:5173page exposed by Chrome debugging port 9222. -
Produces: measured H5 evidence without opening another browser or project tab.
-
Step 1: Assert the unique project tab and restore 412×915
Connect through CDP, filter pages with:
const projectPages = pages.filter(page => page.type === 'page' && page.url.startsWith('http://localhost:5173'))
if (projectPages.length !== 1) throw new Error(`Expected one existing project tab, found ${projectPages.length}`)
Set device metrics to 412×915, navigate that same page to G01, and open .create-action.
- Step 2: Measure the three-button minimum and centering
Capture the dialog and body rectangles:
const dialog = document.querySelector('.add-dialog').getBoundingClientRect()
const body = document.querySelector('.add-dialog__body').getBoundingClientRect()
const topSpace = body.top - dialog.top
const bottomSpace = dialog.bottom - body.bottom
Expected at 412×915:
-
dialog.heightis approximately429px(780rpx, tolerance ±3px). -
Math.abs(topSpace - bottomSpace) <= 3in H5 where the safe-area inset is zero. -
Each adjacent-button visual gap is approximately
13.2px(24rpx, tolerance ±2px). -
Three
.app-buttonelements are visible and horizontal overflow is0. -
Save
05-add-dialog-centered-min-412x915.png. -
Step 3: Verify 320×568
Set 320×568, reopen the same state, and measure again.
Expected:
-
Dialog minimum is approximately
333px(tolerance ±3px). -
Each adjacent-button visual gap is approximately
10.2px(24rpx, tolerance ±2px). -
The last button bottom is not below the viewport.
-
No horizontal overflow or heading/close overlap.
-
Step 4: Verify natural six-button growth
At 412×915, clone the three existing button nodes once inside .add-dialog__actions for pressure evidence only.
Expected:
-
Button count is 6.
-
Dialog height is greater than the three-button minimum and less than its maximum.
-
content.scrollHeight === content.clientHeightfor this medium pressure state. -
Save
05-add-dialog-centered-six-buttons-412x915.png. -
Step 5: Verify safe maximum-height scrolling
Continue cloning button nodes until content exceeds the maximum height.
Expected:
-
Dialog height does not exceed
calc(100vh - 80rpx)by more than 2px. -
content.scrollHeight > content.clientHeight. -
Initial
content.scrollTop === 0and the title is reachable at the top. -
Setting
content.scrollTop = content.scrollHeightproduces a positive scroll position and reaches the final button. -
Step 6: Verify close behavior and restore approval state
Verify in order:
- Clicking
.add-dialog__contentkeeps the layer open. - Clicking
.add-dialog__closecloses it. - Reopening and clicking
.add-dialog-layercloses it. - No runtime exceptions or failed 4xx/5xx asset responses occur on a fresh navigation.
Finally restore the same tab to 412×915, three buttons, no injected clones, and keep the add sheet open.
Task 4: Record internal design QA without claiming user or Android acceptance
Files:
- Modify:
design-qa.md - Test:
tests/g01-visual-contract.ps1
Interfaces:
-
Consumes: the user-marked screenshot, three-button capture, six-button capture, measured centering, responsive check, interaction results, and console/network results.
-
Produces: an internal H5 QA entry whose final result describes only the candidate evidence.
-
Step 1: Create a same-viewport comparison image
Place the previous 412×915 state and 05-add-dialog-centered-min-412x915.png side by side without rescaling either app viewport. Save it under the existing G01 approval evidence folder.
- Step 2: Inspect the combined comparison and both pressure captures
Check the five required surfaces explicitly: typography, spacing/layout, color/tokens, image quality/assets, and copy. Record any P0/P1/P2 finding before claiming an internal pass.
- Step 3: Update
design-qa.md
Record:
-
Source screenshot and approved arrow target.
-
Implementation and comparison paths.
-
412×915 and 320×568 metrics.
-
Three-button centering, six-button growth, and maximum-height scrolling.
-
Interaction and console/network evidence.
-
final result: passedonly if no actionable H5 P0/P1/P2 issue remains. -
Explicit limits: user acceptance pending; Android/HBuilderX unverified; G01 not frozen.
-
Step 4: Run the final verification gate
Run:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/g01-loading-state-contract.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/g01-error-state-contract.ps1
git diff --check
Expected: all contracts pass and git diff --check exits 0. Report line-ending warnings separately from failures.
Do not run any Git write command. Leave the existing 412×915 Chrome tab showing only the three-button add sheet and wait for explicit user approval.