feat(03-07): InstallPrompt — iOS walkthrough banner + Android beforeinstallprompt
- Implement isIOSSafariNonStandalone(): iOS UA + navigator.standalone detection - Implement useAndroidInstallPrompt(): captures beforeinstallprompt, exposes canInstall/triggerInstall - InstallPrompt renders nothing when display-mode:standalone or navigator.standalone (already installed) - iOS branch: dismissible banner with 'Install FamilySync' heading, 'How to install' link opens 5-step walkthrough sheet (exact UI-SPEC copy, orange #F5A623 step number annotation) - Android branch: banner with 'Install' button shown only when canInstall=true - localStorage.installPromptDismissed persists banner dismissal - role="banner", dismiss aria-label="Dismiss install prompt", 44px touch targets - Mount <InstallPrompt /> in CalendarShell (phone: below AppNav; desktop: top of content area) - InstallPrompt.test.tsx GREEN (5 behavior tests); full PWA suite 44 tests green; tsc clean
This commit is contained in:
@@ -48,6 +48,7 @@ import { EventDetailPopover } from './EventDetailPopover.js'
|
||||
import { AppNav } from './AppNav.js'
|
||||
import { ColorLegend } from './ColorLegend.js'
|
||||
import { SkeletonCalendar } from './SkeletonCalendar.js'
|
||||
import { InstallPrompt } from './InstallPrompt.js'
|
||||
|
||||
// ── Helpers ────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -314,6 +315,7 @@ export function CalendarShell() {
|
||||
currentUserColor={meQuery.data?.user.color}
|
||||
currentUserName={meQuery.data?.user.displayName ?? undefined}
|
||||
/>
|
||||
<InstallPrompt />
|
||||
<CalendarContent />
|
||||
<EventDetailPopover />
|
||||
</div>
|
||||
@@ -341,7 +343,10 @@ export function CalendarShell() {
|
||||
/>
|
||||
|
||||
{/* Main content area */}
|
||||
<CalendarContent />
|
||||
<div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
|
||||
<InstallPrompt />
|
||||
<CalendarContent />
|
||||
</div>
|
||||
|
||||
{/* EventDetailPopover — standalone mode driven by Zustand openEventId */}
|
||||
<EventDetailPopover />
|
||||
|
||||
Reference in New Issue
Block a user