Files
jiapuapp/docs/superpowers/plans/2026-07-19-g01-centered-minimum-sheet.md
T
2026-07-20 06:52:26 +08:00

288 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# G01 Centered Minimum-Height Add Sheet Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:executing-plans` to 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 G01s 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`, or `git 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 `AppButton` styles.
- 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 users 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, `780rpx` minimum 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:
```powershell
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 `620rpx` and fixed-close assertions**
Use these exact contracts:
```powershell
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
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`, and `createGenealogy` behavior.
- 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:
```vue
<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:
```scss
.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
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
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:5173` page 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:
```js
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:
```js
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.height` is approximately `429px` (`780rpx`, tolerance ±3px).
- `Math.abs(topSpace - bottomSpace) <= 3` in H5 where the safe-area inset is zero.
- Each adjacent-button visual gap is approximately `13.2px` (`24rpx`, tolerance ±2px).
- Three `.app-button` elements are visible and horizontal overflow is `0`.
- 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.clientHeight` for 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 === 0` and the title is reachable at the top.
- Setting `content.scrollTop = content.scrollHeight` produces a positive scroll position and reaches the final button.
- [ ] **Step 6: Verify close behavior and restore approval state**
Verify in order:
- Clicking `.add-dialog__content` keeps the layer open.
- Clicking `.add-dialog__close` closes it.
- Reopening and clicking `.add-dialog-layer` closes 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: passed` only 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
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.