Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/viewport-qa-layout-hotfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@app/ratewise': patch
---

修復 360×800 與 320×568 裝置上 CTA 與 bottom nav 重疊、匯率文字與 RateSelector 重疊,以及加入歷史按鈕觸控目標不足 44px 的問題
2 changes: 1 addition & 1 deletion apps/ratewise/src/components/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export function AppLayout() {
ref={mainRef}
data-scroll-container="main"
tabIndex={0}
className="flex-1 min-h-0 min-w-0 w-full relative overflow-y-auto overflow-x-hidden pb-[calc(56px+env(safe-area-inset-bottom,0px))] md:pb-0 [-webkit-overflow-scrolling:touch] overscroll-y-contain"
className={`flex-1 min-h-0 min-w-0 w-full relative overflow-y-auto overflow-x-hidden ${navigationTokens.mainScroll.paddingBottomClass} [-webkit-overflow-scrolling:touch] overscroll-y-contain`}
>
<PullToRefreshIndicator
pullDistance={pullDistance}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,19 @@ describe('AppLayout Safe Area', () => {

expect(screen.getByRole('main')).toHaveAttribute('tabindex', '0');
});

it('主要滾動區域應保留 bottom nav 留白並含 narrow 360px 加值', () => {
render(
<MemoryRouter initialEntries={['/']}>
<Routes>
<Route path="/" element={<AppLayout />}>
<Route index element={<div>內容</div>} />
</Route>
</Routes>
</MemoryRouter>,
);

const main = screen.getByRole('main');
expect(main.className).toContain(navigationTokens.mainScroll.paddingBottomClass);
});
});
16 changes: 16 additions & 0 deletions apps/ratewise/src/config/design-tokens.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,22 @@ describe('Design Token System - BDD', () => {
expect(singleConverterLayoutTokens.rateCard.chartHeight).toContain('compact:h-16');
expect(singleConverterLayoutTokens.rateCard.rateTypeContainer).toContain('absolute');
expect(singleConverterLayoutTokens.rateCard.rateTypeButton).toContain('px-');
expect(singleConverterLayoutTokens.rateCard.infoPadding).toContain('micro:pt-10');
expect(singleConverterLayoutTokens.rateCard.infoPadding).toContain('nano:pt-10');
expect(singleConverterLayoutTokens.addToHistory.className).toContain('micro:min-h-11');
expect(singleConverterLayoutTokens.addToHistory.className).toContain('nano:min-h-11');
});
});

describe('🟢 GREEN: 導覽 main 滾動留白 Token', () => {
it('應該導出 narrow 360px 額外 bottom padding', async () => {
const { navigationTokens } = await import('./design-tokens');

expect(navigationTokens.mainScroll.paddingBottomClass).toContain(
'pb-[calc(56px+env(safe-area-inset-bottom,0px))]',
);
expect(navigationTokens.mainScroll.paddingBottomClass).toContain('max-[360px]:pb-[calc(84px');
expect(navigationTokens.mainScroll.paddingBottomClass).toContain('md:pb-0');
});
});

Expand Down
18 changes: 14 additions & 4 deletions apps/ratewise/src/config/design-tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,15 @@ export const navigationTokens = {
bottom: 'pb-safe-bottom',
},
},

/**
* 行動版 main 滾動區底部留白(fixed bottom nav 上方可捲動空間)
* narrow 額外 +28px:Galaxy S21 360×800 QA 曾見 CTA 與 bottom nav 重疊
*/
mainScroll: {
paddingBottomClass:
'pb-[calc(56px+env(safe-area-inset-bottom,0px))] max-[360px]:pb-[calc(84px+env(safe-area-inset-bottom,0px))] md:pb-0',
},
} as const;

/**
Expand Down Expand Up @@ -689,9 +698,9 @@ export const singleConverterLayoutTokens = {
/** 卡片底部間距 */
cardSpacing: 'mb-3 compact:mb-2.5 short:mb-2 tiny:mb-1.5 micro:mb-1.5 nano:mb-1',

/** 匯率資訊區內距 - 保持充足空間感 */
/** 匯率資訊區內距 - micro/nano 頂部 ≥40px,避免 RateSelector 與匯率文字重疊 */
infoPadding:
'pt-12 pb-6 compact:pt-10 compact:pb-5 short:pt-8 short:pb-4 tiny:pt-6 tiny:pb-3 micro:pt-5 micro:pb-2.5 nano:pt-4 nano:pb-2',
'pt-12 pb-6 compact:pt-10 compact:pb-5 short:pt-8 short:pb-4 tiny:pt-6 tiny:pb-3 micro:pt-10 micro:pb-2.5 nano:pt-10 nano:pb-2',

/** 匯率類型按鈕容器定位 */
rateTypeContainer:
Expand Down Expand Up @@ -778,9 +787,10 @@ export const singleConverterLayoutTokens = {
glowHidden: 'short:hidden',
},

/** 加入歷史按鈕 - 線性縮減 */
/** 加入歷史按鈕 - micro/nano 維持 WCAG 44px 最小觸控高度 */
addToHistory: {
className: 'py-3.5 compact:py-3 short:py-2.5 tiny:py-2 micro:py-1.5 nano:py-1.5',
className:
'py-3.5 compact:py-3 short:py-2.5 tiny:py-2 micro:min-h-11 micro:py-2 nano:min-h-11 nano:py-2',
},
} as const;

Expand Down
7 changes: 6 additions & 1 deletion docs/dev/002_development_reward_penalty_log.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> 版本:outline-v2-ultra
> 原則:每筆只保留日期、ID、原因、解法。
> 本次分數變化:+1(reward 1、penalty 0、neutral 0)|累計總分:+80
> 本次分數變化:+1(reward 1、penalty 0、neutral 0)|累計總分:+81

## 新增模板(4 行)

Expand All @@ -13,6 +13,11 @@

## 條目(新→舊)

- 日期:2026-06-28
- ID:reward-viewport-qa-layout-hotfix
- 原因:10 裝置 QA 矩陣在 Galaxy S21 360×800 與 iPhone SE 320×568 出現 CTA 與 bottom nav 重疊、匯率文字蓋住 RateSelector、CTA 觸控高度僅 38px
- 解法:design-tokens SSOT 調整 infoPadding/addToHistory min-h-11,AppLayout narrow 360px 額外 bottom padding +28px

- 日期:2026-06-28
- ID:reward-pwa-https-cold-start-manifest-regression
- 原因:#447 已改絕對 HTTPS start_url,但 SW seo-files-cache 以 SWR 快取舊 manifest(相對 start_url),冷啟動仍觸發 HTTPS-First 警告
Expand Down
Loading