mirror of
https://github.com/tiennm99/loto.git
synced 2026-10-12 22:14:40 +00:00
feat(settings): clearer "both" glyph + sticky title/footer on mobile
Two small UX fixes in the settings modal: 1. Mode picker "Cả hai" glyph was two stacked rectangles — read as "windows" rather than the two roles being combined. Replace with a mini player-grid + mini megaphone side-by-side so the glyph mirrors the two single-mode glyphs concretely. 2. On iPhone SE the modal body pushes the title and the action row off screen, so the close button needs scrolling-back to reach. Make the title block sticky at top and the action row sticky at bottom inside the existing scroll container; move the panel padding from the outer wrapper into per-section padding so the sticky bands can span edge-to-edge with matching backgrounds.
This commit is contained in:
1 parent
558d0c75b2
commit
2b74b2e2e9
4 files changed
+37
-18
No files matched your search
@@ -1,9 +1,10 @@
|
|||||||
---
|
---
|
||||||
name: Mode picker glyph redesign
|
name: Mode picker glyph redesign
|
||||||
phase: 3
|
phase: 3
|
||||||
status: todo
|
status: completed
|
||||||
priority: medium
|
priority: medium
|
||||||
effort: 45m
|
effort: 45m
|
||||||
|
completed: 2026-04-28
|
||||||
---
|
---
|
||||||
|
|
||||||
# Phase 3 — Mode picker glyph redesign
|
# Phase 3 — Mode picker glyph redesign
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
---
|
---
|
||||||
name: Settings modal sticky on small screens
|
name: Settings modal sticky on small screens
|
||||||
phase: 4
|
phase: 4
|
||||||
status: todo
|
status: completed
|
||||||
priority: medium
|
priority: medium
|
||||||
effort: 30m
|
effort: 30m
|
||||||
|
completed: 2026-04-28
|
||||||
---
|
---
|
||||||
|
|
||||||
# Phase 4 — Settings modal sticky header/footer
|
# Phase 4 — Settings modal sticky header/footer
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ YAGNI — parking-lot features and upstream-blocked items skipped.
|
|||||||
|---|-------|------|
|
|---|-------|------|
|
||||||
| 1 | Auto-tick integration test ✅ | `phase-01-auto-tick-test.md` |
|
| 1 | Auto-tick integration test ✅ | `phase-01-auto-tick-test.md` |
|
||||||
| 2 | CI inline-script guard ✅ | `phase-02-ci-inline-script-guard.md` |
|
| 2 | CI inline-script guard ✅ | `phase-02-ci-inline-script-guard.md` |
|
||||||
| 3 | Mode picker glyph redesign | `phase-03-mode-picker-glyphs.md` |
|
| 3 | Mode picker glyph redesign ✅ | `phase-03-mode-picker-glyphs.md` |
|
||||||
| 4 | Settings modal sticky on small screens | `phase-04-settings-modal-sticky.md` |
|
| 4 | Settings modal sticky on small screens ✅ | `phase-04-settings-modal-sticky.md` |
|
||||||
| 5 | Per-row "Chờ" indicator | `phase-05-cho-row-indicator.md` |
|
| 5 | Per-row "Chờ" indicator | `phase-05-cho-row-indicator.md` |
|
||||||
| 6 | Confetti polish (threshold + variety) | `phase-06-confetti-polish.md` |
|
| 6 | Confetti polish (threshold + variety) | `phase-06-confetti-polish.md` |
|
||||||
| 7 | Strict CSP via hashed inline script | `phase-07-strict-csp-hashed.md` |
|
| 7 | Strict CSP via hashed inline script | `phase-07-strict-csp-hashed.md` |
|
||||||
|
|||||||
@@ -164,17 +164,24 @@
|
|||||||
class="absolute inset-0"
|
class="absolute inset-0"
|
||||||
></div>
|
></div>
|
||||||
<div
|
<div
|
||||||
class="relative mx-4 max-w-sm sm:max-w-md w-full max-h-[90vh] overflow-y-auto rounded-3xl bg-white dark:bg-slate-800 p-6 shadow-2xl animate-pop-in"
|
class="relative mx-4 max-w-sm sm:max-w-md w-full max-h-[90vh] overflow-y-auto rounded-3xl bg-white dark:bg-slate-800 shadow-2xl animate-pop-in"
|
||||||
>
|
>
|
||||||
<h2
|
<!-- Sticky title — pinned so the modal stays anchored on small
|
||||||
id="settings-title"
|
viewports (iPhone SE: 375x667) where the body would otherwise
|
||||||
class="text-2xl font-bold text-slate-800 dark:text-slate-100 mb-1"
|
push the heading off-screen. -->
|
||||||
>
|
<div class="sticky top-0 z-10 bg-white dark:bg-slate-800 px-6 pt-6 pb-3 rounded-t-3xl">
|
||||||
Cài đặt
|
<h2
|
||||||
</h2>
|
id="settings-title"
|
||||||
<p class="text-sm text-slate-500 dark:text-slate-400 mb-5">
|
class="text-2xl font-bold text-slate-800 dark:text-slate-100 mb-1"
|
||||||
Tuỳ chỉnh giao diện bảng lô tô
|
>
|
||||||
</p>
|
Cài đặt
|
||||||
|
</h2>
|
||||||
|
<p class="text-sm text-slate-500 dark:text-slate-400">
|
||||||
|
Tuỳ chỉnh giao diện bảng lô tô
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="px-6 pt-2">
|
||||||
|
|
||||||
<!-- Theme -->
|
<!-- Theme -->
|
||||||
<fieldset class="mb-5">
|
<fieldset class="mb-5">
|
||||||
@@ -268,9 +275,14 @@
|
|||||||
<path d="M19 8a4 4 0 0 1 0 8" />
|
<path d="M19 8a4 4 0 0 1 0 8" />
|
||||||
</svg>
|
</svg>
|
||||||
{:else}
|
{:else}
|
||||||
<svg viewBox="0 0 24 20" class="w-7 h-6" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
|
<!-- "Both": mini grid (player) + mini megaphone (master)
|
||||||
<rect x="1" y="1" width="16" height="11" rx="1.2" />
|
side-by-side, so the glyph reads as the two roles
|
||||||
<rect x="7" y="7" width="16" height="11" rx="1.2" />
|
combined rather than two stacked windows. -->
|
||||||
|
<svg viewBox="0 0 28 16" class="w-7 h-5" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
|
||||||
|
<rect x="1" y="2" width="11" height="12" rx="1" />
|
||||||
|
<path d="M1 6h11M1 10h11M5 2v12M9 2v12" />
|
||||||
|
<path d="M16 6l9-3v10l-9-3z" stroke-linejoin="round" />
|
||||||
|
<path d="M16 6v4" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
<span>{label}</span>
|
<span>{label}</span>
|
||||||
@@ -433,7 +445,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="flex justify-between gap-2">
|
</div>
|
||||||
|
|
||||||
|
<!-- Sticky action row: keep "Xong" reachable without scrolling
|
||||||
|
back when the body overflows (iPhone SE). Border-t separates
|
||||||
|
visually from content slipping behind. -->
|
||||||
|
<div class="sticky bottom-0 z-10 bg-white dark:bg-slate-800 px-6 py-4 border-t border-slate-200 dark:border-slate-700 flex justify-between gap-2 rounded-b-3xl">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => resetSettings()}
|
onclick={() => resetSettings()}
|
||||||
|
|||||||
Reference in new issue
Block a user