@hook-sdk/template 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1442 -206
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -1
- package/dist/index.d.ts +101 -1
- package/dist/index.js +1423 -197
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -23,6 +23,7 @@ declare const AppConfigSchema: z.ZodObject<{
|
|
|
23
23
|
leaderboard: "leaderboard";
|
|
24
24
|
push: "push";
|
|
25
25
|
subscription: "subscription";
|
|
26
|
+
install_prompt: "install_prompt";
|
|
26
27
|
}>>;
|
|
27
28
|
persistedKeys: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
28
29
|
dependencies_allowlist: z.ZodArray<z.ZodString>;
|
|
@@ -105,6 +106,18 @@ interface PushPromptProps {
|
|
|
105
106
|
}
|
|
106
107
|
declare function PushPrompt({ texts, onSubscribed, onDeclined, onInstallRequested, className }: PushPromptProps): react_jsx_runtime.JSX.Element | null;
|
|
107
108
|
|
|
109
|
+
interface InstallGateProps {
|
|
110
|
+
children: ReactNode;
|
|
111
|
+
}
|
|
112
|
+
declare function InstallGate({ children }: InstallGateProps): react_jsx_runtime.JSX.Element;
|
|
113
|
+
|
|
114
|
+
interface InstallSplashProps {
|
|
115
|
+
children: ReactNode;
|
|
116
|
+
title: string;
|
|
117
|
+
subtitle?: string;
|
|
118
|
+
}
|
|
119
|
+
declare function InstallSplash({ children, title, subtitle }: InstallSplashProps): react_jsx_runtime.JSX.Element;
|
|
120
|
+
|
|
108
121
|
declare function DefaultSignupScreen({ onNavigate }: AuthScreenProps): react_jsx_runtime.JSX.Element;
|
|
109
122
|
|
|
110
123
|
declare function DefaultForgotScreen({ onNavigate }: AuthScreenProps): react_jsx_runtime.JSX.Element;
|
|
@@ -393,4 +406,91 @@ declare function useToast(): {
|
|
|
393
406
|
dismiss: (id: string) => void;
|
|
394
407
|
};
|
|
395
408
|
|
|
396
|
-
|
|
409
|
+
/**
|
|
410
|
+
* useInstallPrompt — headless hook pra PWA install prompt.
|
|
411
|
+
*
|
|
412
|
+
* Responsabilidades:
|
|
413
|
+
* - Detectar plataforma (Android / iOS Safari / iOS outros / in-app / desktop)
|
|
414
|
+
* - Detectar browser específico (Chrome, Firefox, Samsung, Instagram, ...)
|
|
415
|
+
* - Detectar standalone mode (PWA já instalado)
|
|
416
|
+
* - Gerenciar dismissal graduada (session → permanente 14d)
|
|
417
|
+
* - Expor `promptInstall()` que dispara `window.__pwaInstallPrompt.prompt()`
|
|
418
|
+
*
|
|
419
|
+
* Não renderiza UI. Componente `<InstallGate>` consome o hook e renderiza.
|
|
420
|
+
*
|
|
421
|
+
* Porta regexes + lógica de `hook-old/src/hooks/usePWAInstall.ts` com
|
|
422
|
+
* divergências deliberadas (ver docs/adr/017 + P20 plan):
|
|
423
|
+
* - enum InAppApp granular pra copy por rede social (G60 amendment)
|
|
424
|
+
* - dismissal graduada em vez de permanente direto
|
|
425
|
+
* - TTL de 14d no permanent dismiss
|
|
426
|
+
* - tracking `skipCount` separado
|
|
427
|
+
*
|
|
428
|
+
* Gotchas de referência:
|
|
429
|
+
* - G61: beforeinstallprompt capturado pré-React (shell main.tsx faz)
|
|
430
|
+
* - G62: distinção ios-safari vs ios-other (Chrome iOS não instala)
|
|
431
|
+
* - G63: in-app browsers checados ANTES de Android/iOS
|
|
432
|
+
*/
|
|
433
|
+
type Platform = 'android' | 'ios-safari' | 'ios-other' | 'in-app' | 'desktop' | 'unknown';
|
|
434
|
+
type IOSBrowser = 'safari' | 'chrome' | 'firefox' | 'edge' | 'other';
|
|
435
|
+
type AndroidBrowser = 'chrome' | 'firefox' | 'opera' | 'samsung' | 'edge' | 'other';
|
|
436
|
+
type InAppApp = 'instagram' | 'facebook' | 'tiktok' | 'whatsapp' | 'twitter' | 'linkedin' | 'telegram' | 'line' | 'snapchat' | 'pinterest' | 'wechat' | 'other';
|
|
437
|
+
type InstallVariant = 'android-native' | 'android-manual' | 'ios-safari' | 'ios-other' | 'in-app' | 'desktop' | 'none';
|
|
438
|
+
interface BeforeInstallPromptEvent extends Event {
|
|
439
|
+
prompt: () => Promise<void>;
|
|
440
|
+
userChoice: Promise<{
|
|
441
|
+
outcome: 'accepted' | 'dismissed';
|
|
442
|
+
platform: string;
|
|
443
|
+
}>;
|
|
444
|
+
}
|
|
445
|
+
declare global {
|
|
446
|
+
interface Window {
|
|
447
|
+
__pwaInstallPrompt?: BeforeInstallPromptEvent | null;
|
|
448
|
+
posthog?: {
|
|
449
|
+
capture?: (event: string, props?: Record<string, unknown>) => void;
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
interface InstallState {
|
|
454
|
+
platform: Platform;
|
|
455
|
+
iosBrowser: IOSBrowser | null;
|
|
456
|
+
androidBrowser: AndroidBrowser | null;
|
|
457
|
+
inAppApp: InAppApp | null;
|
|
458
|
+
isInstallable: boolean;
|
|
459
|
+
isInstalled: boolean;
|
|
460
|
+
isDismissedSession: boolean;
|
|
461
|
+
isDismissedPermanent: boolean;
|
|
462
|
+
skipCount: number;
|
|
463
|
+
variant: InstallVariant;
|
|
464
|
+
}
|
|
465
|
+
interface InstallActions {
|
|
466
|
+
promptInstall: () => Promise<boolean>;
|
|
467
|
+
dismissSession: () => void;
|
|
468
|
+
dismissPermanent: () => void;
|
|
469
|
+
redirectToSafari: () => void;
|
|
470
|
+
copyLink: () => Promise<void>;
|
|
471
|
+
reset: () => void;
|
|
472
|
+
}
|
|
473
|
+
declare function detectPlatform(ua: string): Platform;
|
|
474
|
+
declare function detectIOSBrowser(ua: string): IOSBrowser | null;
|
|
475
|
+
declare function detectAndroidBrowser(ua: string): AndroidBrowser | null;
|
|
476
|
+
declare function detectInAppApp(ua: string): InAppApp | null;
|
|
477
|
+
declare function detectStandalone(): {
|
|
478
|
+
installed: boolean;
|
|
479
|
+
source: 'match_media' | 'navigator_standalone' | 'storage_marker' | null;
|
|
480
|
+
};
|
|
481
|
+
/**
|
|
482
|
+
* Hook principal. Passar o slug do app (usado pra namespacing de storage +
|
|
483
|
+
* analytics). Componentes do template pegam via useTemplateConfig().slug.
|
|
484
|
+
*/
|
|
485
|
+
declare function useInstallPrompt(slug: string): InstallState & InstallActions;
|
|
486
|
+
/**
|
|
487
|
+
* Exposto pra InstallGate decidir se renderiza splash (não faz parte do hook
|
|
488
|
+
* retornado pra manter surface pequena — componente usa).
|
|
489
|
+
*/
|
|
490
|
+
declare function shouldBlockInstall(state: InstallState, now?: number): boolean;
|
|
491
|
+
/**
|
|
492
|
+
* Exposto pra decidir se mostra "Não me pergunte mais".
|
|
493
|
+
*/
|
|
494
|
+
declare function shouldShowPermanentOption(state: InstallState): boolean;
|
|
495
|
+
|
|
496
|
+
export { type AndroidBrowser, AppRoot, type AppRootProps, type AuthFormError, type AuthFormErrorCode, type AuthScreen, type AuthScreenProps, DefaultForgotScreen, DefaultLoginScreen, DefaultPaywall, DefaultResetScreen, DefaultSignupScreen, EmptyState, ErrorBoundary, type IOSBrowser, type InAppApp, type InstallActions, InstallGate, InstallSplash, type InstallState, type InstallVariant, LoadingState, type Platform, PushPrompt, type PushPromptProps, type PushPromptTexts, type PushUiState, type SubscriptionStatus, type ToastItem, type UseLoginFormResult, type UseResetFormResult, detectAndroidBrowser, detectIOSBrowser, detectInAppApp, detectPlatform, detectStandalone, shouldBlockInstall, shouldShowPermanentOption, useAuth, useAuthPrimitives, useForgotForm, useInstallPrompt, useLoginForm, usePaywallState, usePush, useReminders, useResetForm, useSignupForm, useSubscription, useToast };
|
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ declare const AppConfigSchema: z.ZodObject<{
|
|
|
23
23
|
leaderboard: "leaderboard";
|
|
24
24
|
push: "push";
|
|
25
25
|
subscription: "subscription";
|
|
26
|
+
install_prompt: "install_prompt";
|
|
26
27
|
}>>;
|
|
27
28
|
persistedKeys: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
28
29
|
dependencies_allowlist: z.ZodArray<z.ZodString>;
|
|
@@ -105,6 +106,18 @@ interface PushPromptProps {
|
|
|
105
106
|
}
|
|
106
107
|
declare function PushPrompt({ texts, onSubscribed, onDeclined, onInstallRequested, className }: PushPromptProps): react_jsx_runtime.JSX.Element | null;
|
|
107
108
|
|
|
109
|
+
interface InstallGateProps {
|
|
110
|
+
children: ReactNode;
|
|
111
|
+
}
|
|
112
|
+
declare function InstallGate({ children }: InstallGateProps): react_jsx_runtime.JSX.Element;
|
|
113
|
+
|
|
114
|
+
interface InstallSplashProps {
|
|
115
|
+
children: ReactNode;
|
|
116
|
+
title: string;
|
|
117
|
+
subtitle?: string;
|
|
118
|
+
}
|
|
119
|
+
declare function InstallSplash({ children, title, subtitle }: InstallSplashProps): react_jsx_runtime.JSX.Element;
|
|
120
|
+
|
|
108
121
|
declare function DefaultSignupScreen({ onNavigate }: AuthScreenProps): react_jsx_runtime.JSX.Element;
|
|
109
122
|
|
|
110
123
|
declare function DefaultForgotScreen({ onNavigate }: AuthScreenProps): react_jsx_runtime.JSX.Element;
|
|
@@ -393,4 +406,91 @@ declare function useToast(): {
|
|
|
393
406
|
dismiss: (id: string) => void;
|
|
394
407
|
};
|
|
395
408
|
|
|
396
|
-
|
|
409
|
+
/**
|
|
410
|
+
* useInstallPrompt — headless hook pra PWA install prompt.
|
|
411
|
+
*
|
|
412
|
+
* Responsabilidades:
|
|
413
|
+
* - Detectar plataforma (Android / iOS Safari / iOS outros / in-app / desktop)
|
|
414
|
+
* - Detectar browser específico (Chrome, Firefox, Samsung, Instagram, ...)
|
|
415
|
+
* - Detectar standalone mode (PWA já instalado)
|
|
416
|
+
* - Gerenciar dismissal graduada (session → permanente 14d)
|
|
417
|
+
* - Expor `promptInstall()` que dispara `window.__pwaInstallPrompt.prompt()`
|
|
418
|
+
*
|
|
419
|
+
* Não renderiza UI. Componente `<InstallGate>` consome o hook e renderiza.
|
|
420
|
+
*
|
|
421
|
+
* Porta regexes + lógica de `hook-old/src/hooks/usePWAInstall.ts` com
|
|
422
|
+
* divergências deliberadas (ver docs/adr/017 + P20 plan):
|
|
423
|
+
* - enum InAppApp granular pra copy por rede social (G60 amendment)
|
|
424
|
+
* - dismissal graduada em vez de permanente direto
|
|
425
|
+
* - TTL de 14d no permanent dismiss
|
|
426
|
+
* - tracking `skipCount` separado
|
|
427
|
+
*
|
|
428
|
+
* Gotchas de referência:
|
|
429
|
+
* - G61: beforeinstallprompt capturado pré-React (shell main.tsx faz)
|
|
430
|
+
* - G62: distinção ios-safari vs ios-other (Chrome iOS não instala)
|
|
431
|
+
* - G63: in-app browsers checados ANTES de Android/iOS
|
|
432
|
+
*/
|
|
433
|
+
type Platform = 'android' | 'ios-safari' | 'ios-other' | 'in-app' | 'desktop' | 'unknown';
|
|
434
|
+
type IOSBrowser = 'safari' | 'chrome' | 'firefox' | 'edge' | 'other';
|
|
435
|
+
type AndroidBrowser = 'chrome' | 'firefox' | 'opera' | 'samsung' | 'edge' | 'other';
|
|
436
|
+
type InAppApp = 'instagram' | 'facebook' | 'tiktok' | 'whatsapp' | 'twitter' | 'linkedin' | 'telegram' | 'line' | 'snapchat' | 'pinterest' | 'wechat' | 'other';
|
|
437
|
+
type InstallVariant = 'android-native' | 'android-manual' | 'ios-safari' | 'ios-other' | 'in-app' | 'desktop' | 'none';
|
|
438
|
+
interface BeforeInstallPromptEvent extends Event {
|
|
439
|
+
prompt: () => Promise<void>;
|
|
440
|
+
userChoice: Promise<{
|
|
441
|
+
outcome: 'accepted' | 'dismissed';
|
|
442
|
+
platform: string;
|
|
443
|
+
}>;
|
|
444
|
+
}
|
|
445
|
+
declare global {
|
|
446
|
+
interface Window {
|
|
447
|
+
__pwaInstallPrompt?: BeforeInstallPromptEvent | null;
|
|
448
|
+
posthog?: {
|
|
449
|
+
capture?: (event: string, props?: Record<string, unknown>) => void;
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
interface InstallState {
|
|
454
|
+
platform: Platform;
|
|
455
|
+
iosBrowser: IOSBrowser | null;
|
|
456
|
+
androidBrowser: AndroidBrowser | null;
|
|
457
|
+
inAppApp: InAppApp | null;
|
|
458
|
+
isInstallable: boolean;
|
|
459
|
+
isInstalled: boolean;
|
|
460
|
+
isDismissedSession: boolean;
|
|
461
|
+
isDismissedPermanent: boolean;
|
|
462
|
+
skipCount: number;
|
|
463
|
+
variant: InstallVariant;
|
|
464
|
+
}
|
|
465
|
+
interface InstallActions {
|
|
466
|
+
promptInstall: () => Promise<boolean>;
|
|
467
|
+
dismissSession: () => void;
|
|
468
|
+
dismissPermanent: () => void;
|
|
469
|
+
redirectToSafari: () => void;
|
|
470
|
+
copyLink: () => Promise<void>;
|
|
471
|
+
reset: () => void;
|
|
472
|
+
}
|
|
473
|
+
declare function detectPlatform(ua: string): Platform;
|
|
474
|
+
declare function detectIOSBrowser(ua: string): IOSBrowser | null;
|
|
475
|
+
declare function detectAndroidBrowser(ua: string): AndroidBrowser | null;
|
|
476
|
+
declare function detectInAppApp(ua: string): InAppApp | null;
|
|
477
|
+
declare function detectStandalone(): {
|
|
478
|
+
installed: boolean;
|
|
479
|
+
source: 'match_media' | 'navigator_standalone' | 'storage_marker' | null;
|
|
480
|
+
};
|
|
481
|
+
/**
|
|
482
|
+
* Hook principal. Passar o slug do app (usado pra namespacing de storage +
|
|
483
|
+
* analytics). Componentes do template pegam via useTemplateConfig().slug.
|
|
484
|
+
*/
|
|
485
|
+
declare function useInstallPrompt(slug: string): InstallState & InstallActions;
|
|
486
|
+
/**
|
|
487
|
+
* Exposto pra InstallGate decidir se renderiza splash (não faz parte do hook
|
|
488
|
+
* retornado pra manter surface pequena — componente usa).
|
|
489
|
+
*/
|
|
490
|
+
declare function shouldBlockInstall(state: InstallState, now?: number): boolean;
|
|
491
|
+
/**
|
|
492
|
+
* Exposto pra decidir se mostra "Não me pergunte mais".
|
|
493
|
+
*/
|
|
494
|
+
declare function shouldShowPermanentOption(state: InstallState): boolean;
|
|
495
|
+
|
|
496
|
+
export { type AndroidBrowser, AppRoot, type AppRootProps, type AuthFormError, type AuthFormErrorCode, type AuthScreen, type AuthScreenProps, DefaultForgotScreen, DefaultLoginScreen, DefaultPaywall, DefaultResetScreen, DefaultSignupScreen, EmptyState, ErrorBoundary, type IOSBrowser, type InAppApp, type InstallActions, InstallGate, InstallSplash, type InstallState, type InstallVariant, LoadingState, type Platform, PushPrompt, type PushPromptProps, type PushPromptTexts, type PushUiState, type SubscriptionStatus, type ToastItem, type UseLoginFormResult, type UseResetFormResult, detectAndroidBrowser, detectIOSBrowser, detectInAppApp, detectPlatform, detectStandalone, shouldBlockInstall, shouldShowPermanentOption, useAuth, useAuthPrimitives, useForgotForm, useInstallPrompt, useLoginForm, usePaywallState, usePush, useReminders, useResetForm, useSignupForm, useSubscription, useToast };
|