@asteby/metacore-pwa 0.5.1 → 0.6.1

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.
@@ -1,4 +1,3 @@
1
- import { type ComponentType, type ReactNode } from 'react';
2
1
  export interface InstallPromptMessages {
3
2
  title?: string;
4
3
  description?: string;
@@ -6,15 +5,14 @@ export interface InstallPromptMessages {
6
5
  dismissLabel?: string;
7
6
  }
8
7
  export interface InstallPromptProps {
9
- /** Optional custom button to render — receives onClick, children, variant and size. */
10
- ButtonComponent?: ComponentType<{
11
- onClick?: () => void;
12
- children?: ReactNode;
13
- variant?: 'default' | 'outline';
14
- size?: 'sm';
15
- }>;
16
8
  messages?: InstallPromptMessages;
17
- className?: string;
9
+ /** How long the toast stays before auto-dismissing (ms). Default: 10000. */
10
+ duration?: number;
18
11
  }
19
- export declare function PWAInstallPrompt({ ButtonComponent, messages, className, }?: InstallPromptProps): import("react").JSX.Element | null;
12
+ /**
13
+ * Renders through the shared notification toast (same card as bell/WS/SSE)
14
+ * instead of its own fixed-position banner, so it stacks with every other
15
+ * app notification rather than competing for a corner of the screen.
16
+ */
17
+ export declare function PWAInstallPrompt({ messages, duration }?: InstallPromptProps): null;
20
18
  //# sourceMappingURL=install-prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"install-prompt.d.ts","sourceRoot":"","sources":["../../src/components/install-prompt.tsx"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG/E,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,uFAAuF;IACvF,eAAe,CAAC,EAAE,aAAa,CAAC;QAC9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;QACpB,QAAQ,CAAC,EAAE,SAAS,CAAA;QACpB,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;QAC/B,IAAI,CAAC,EAAE,IAAI,CAAA;KACZ,CAAC,CAAA;IACF,QAAQ,CAAC,EAAE,qBAAqB,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAkCD,wBAAgB,gBAAgB,CAAC,EAC/B,eAA+B,EAC/B,QAAQ,EACR,SAAS,GACV,GAAE,kBAAuB,sCA2DzB"}
1
+ {"version":3,"file":"install-prompt.d.ts","sourceRoot":"","sources":["../../src/components/install-prompt.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,qBAAqB,CAAA;IAChC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AASD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,QAAgB,EAAE,GAAE,kBAAuB,QAmCvF"}
@@ -1,6 +1,5 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Download, X } from 'lucide-react';
3
- import { useEffect, useState } from 'react';
1
+ import { useEffect, useRef } from 'react';
2
+ import { showNotificationToast } from '@asteby/metacore-notifications';
4
3
  import { usePWAContext } from '../provider';
5
4
  const DEFAULTS = {
6
5
  title: 'Instalar App',
@@ -8,38 +7,44 @@ const DEFAULTS = {
8
7
  installLabel: 'Instalar',
9
8
  dismissLabel: 'Ahora no',
10
9
  };
11
- function DefaultButton({ onClick, children, variant = 'default', size, }) {
12
- const base = 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50';
13
- const sizeClass = size === 'sm' ? 'h-8 px-3' : 'h-9 px-4';
14
- const variantClass = variant === 'outline'
15
- ? 'border border-input bg-background hover:bg-accent hover:text-accent-foreground'
16
- : 'bg-primary text-primary-foreground hover:bg-primary/90';
17
- return (_jsx("button", { type: "button", onClick: onClick, className: `${base} ${sizeClass} ${variantClass}`, children: children }));
18
- }
19
- export function PWAInstallPrompt({ ButtonComponent = DefaultButton, messages, className, } = {}) {
10
+ /**
11
+ * Renders through the shared notification toast (same card as bell/WS/SSE)
12
+ * instead of its own fixed-position banner, so it stacks with every other
13
+ * app notification rather than competing for a corner of the screen.
14
+ */
15
+ export function PWAInstallPrompt({ messages, duration = 10000 } = {}) {
20
16
  const { isInstallable, installApp } = usePWAContext();
21
- const [show, setShow] = useState(false);
22
17
  const msgs = { ...DEFAULTS, ...messages };
18
+ const shown = useRef(false);
23
19
  useEffect(() => {
24
- if (isInstallable) {
25
- setShow(true);
26
- }
20
+ if (!isInstallable || shown.current)
21
+ return;
22
+ if (typeof localStorage !== 'undefined' && localStorage.getItem('pwa-install-dismissed'))
23
+ return;
24
+ shown.current = true;
25
+ showNotificationToast({
26
+ title: msgs.title,
27
+ body: msgs.description,
28
+ type: 'info',
29
+ icon: 'download',
30
+ duration,
31
+ action: {
32
+ label: msgs.installLabel,
33
+ onClick: () => {
34
+ void installApp();
35
+ },
36
+ },
37
+ cancel: {
38
+ label: msgs.dismissLabel,
39
+ onClick: () => {
40
+ if (typeof localStorage !== 'undefined') {
41
+ localStorage.setItem('pwa-install-dismissed', 'true');
42
+ }
43
+ },
44
+ },
45
+ });
46
+ // eslint-disable-next-line react-hooks/exhaustive-deps
27
47
  }, [isInstallable]);
28
- const handleInstall = async () => {
29
- const installed = await installApp();
30
- if (installed) {
31
- setShow(false);
32
- }
33
- };
34
- const handleDismiss = () => {
35
- setShow(false);
36
- if (typeof localStorage !== 'undefined') {
37
- localStorage.setItem('pwa-install-dismissed', 'true');
38
- }
39
- };
40
- if (!show || !isInstallable)
41
- return null;
42
- return (_jsxs("div", { className: className ??
43
- 'fixed top-4 right-4 z-50 max-w-sm rounded-lg border bg-background p-4 shadow-lg', children: [_jsx("button", { type: "button", onClick: handleDismiss, className: "absolute right-2 top-2 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100", "aria-label": "Dismiss", children: _jsx(X, { className: "h-4 w-4" }) }), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Download, { className: "h-5 w-5 mt-0.5" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "font-semibold", children: msgs.title }), _jsx("p", { className: "text-sm text-muted-foreground mt-1", children: msgs.description }), _jsxs("div", { className: "flex gap-2 mt-3", children: [_jsx(ButtonComponent, { onClick: handleInstall, size: "sm", children: msgs.installLabel }), _jsx(ButtonComponent, { onClick: handleDismiss, variant: "outline", size: "sm", children: msgs.dismissLabel })] })] })] })] }));
48
+ return null;
44
49
  }
45
50
  //# sourceMappingURL=install-prompt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"install-prompt.js","sourceRoot":"","sources":["../../src/components/install-prompt.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install-prompt.js","sourceRoot":"","sources":["../../src/components/install-prompt.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAe3C,MAAM,QAAQ,GAAoC;IAChD,KAAK,EAAE,cAAc;IACrB,WAAW,EAAE,2DAA2D;IACxE,YAAY,EAAE,UAAU;IACxB,YAAY,EAAE,UAAU;CACzB,CAAA;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,KAAK,KAAyB,EAAE;IACtF,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,aAAa,EAAE,CAAA;IACrD,MAAM,IAAI,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAA;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAE3B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa,IAAI,KAAK,CAAC,OAAO;YAAE,OAAM;QAC3C,IAAI,OAAO,YAAY,KAAK,WAAW,IAAI,YAAY,CAAC,OAAO,CAAC,uBAAuB,CAAC;YAAE,OAAM;QAChG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAA;QAEpB,qBAAqB,CAAC;YACpB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,UAAU;YAChB,QAAQ;YACR,MAAM,EAAE;gBACN,KAAK,EAAE,IAAI,CAAC,YAAY;gBACxB,OAAO,EAAE,GAAG,EAAE;oBACZ,KAAK,UAAU,EAAE,CAAA;gBACnB,CAAC;aACF;YACD,MAAM,EAAE;gBACN,KAAK,EAAE,IAAI,CAAC,YAAY;gBACxB,OAAO,EAAE,GAAG,EAAE;oBACZ,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE,CAAC;wBACxC,YAAY,CAAC,OAAO,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAA;oBACvD,CAAC;gBACH,CAAC;aACF;SACF,CAAC,CAAA;QACF,uDAAuD;IACzD,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAA;IAEnB,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -1,4 +1,3 @@
1
- import { type ComponentType, type ReactNode } from 'react';
2
1
  export interface NotificationPermissionPromptMessages {
3
2
  title?: string;
4
3
  description?: string;
@@ -9,19 +8,16 @@ export interface NotificationPermissionPromptMessages {
9
8
  blockedDescription?: string;
10
9
  }
11
10
  export interface NotificationPermissionPromptProps {
12
- ButtonComponent?: ComponentType<{
13
- onClick?: () => void;
14
- children?: ReactNode;
15
- variant?: 'default' | 'outline';
16
- size?: 'sm';
17
- className?: string;
18
- }>;
19
11
  messages?: NotificationPermissionPromptMessages;
20
12
  /** Delay before auto-showing the prompt on mount (ms). Default: 2000. */
21
13
  autoShowDelayMs?: number;
22
14
  /** Reload the page after granting to sync state. Default: true. */
23
15
  reloadOnGrant?: boolean;
24
- className?: string;
25
16
  }
26
- export declare function NotificationPermissionPrompt({ ButtonComponent, messages, autoShowDelayMs, reloadOnGrant, className, }?: NotificationPermissionPromptProps): import("react").JSX.Element | null;
17
+ /**
18
+ * Renders through the shared notification toast instead of its own
19
+ * fixed-position banner, so it stacks with every other app notification
20
+ * rather than competing for a corner of the screen.
21
+ */
22
+ export declare function NotificationPermissionPrompt({ messages, autoShowDelayMs, reloadOnGrant, }?: NotificationPermissionPromptProps): null;
27
23
  //# sourceMappingURL=notification-permission-prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"notification-permission-prompt.d.ts","sourceRoot":"","sources":["../../src/components/notification-permission-prompt.tsx"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG/E,MAAM,WAAW,oCAAoC;IACnD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,iCAAiC;IAChD,eAAe,CAAC,EAAE,aAAa,CAAC;QAC9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;QACpB,QAAQ,CAAC,EAAE,SAAS,CAAA;QACpB,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;QAC/B,IAAI,CAAC,EAAE,IAAI,CAAA;QACX,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,CAAC,CAAA;IACF,QAAQ,CAAC,EAAE,oCAAoC,CAAA;IAC/C,yEAAyE;IACzE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,mEAAmE;IACnE,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA6CD,wBAAgB,4BAA4B,CAAC,EAC3C,eAA+B,EAC/B,QAAQ,EACR,eAAsB,EACtB,aAAoB,EACpB,SAAS,GACV,GAAE,iCAAsC,sCAmGxC"}
1
+ {"version":3,"file":"notification-permission-prompt.d.ts","sourceRoot":"","sources":["../../src/components/notification-permission-prompt.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,oCAAoC;IACnD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,EAAE,oCAAoC,CAAA;IAC/C,yEAAyE;IACzE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,mEAAmE;IACnE,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAcD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,EAC3C,QAAQ,EACR,eAAsB,EACtB,aAAoB,GACrB,GAAE,iCAAsC,QA2ExC"}
@@ -1,6 +1,5 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Bell, X } from 'lucide-react';
3
- import { useEffect, useState } from 'react';
1
+ import { useEffect, useRef } from 'react';
2
+ import { showNotificationToast } from '@asteby/metacore-notifications';
4
3
  import { toast } from 'sonner';
5
4
  const DEFAULTS = {
6
5
  title: 'Activar Notificaciones',
@@ -11,42 +10,15 @@ const DEFAULTS = {
11
10
  blockedTitle: 'Notificaciones bloqueadas por el navegador',
12
11
  blockedDescription: 'Debes habilitarlas manualmente: Click en el ícono de la barra de direcciones → Permisos → Notificaciones → Permitir',
13
12
  };
14
- function DefaultButton({ onClick, children, variant = 'default', size, className, }) {
15
- const base = 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50';
16
- const sizeClass = size === 'sm' ? 'h-8 px-3 text-xs' : 'h-9 px-4';
17
- const variantClass = variant === 'outline'
18
- ? 'border border-input bg-background hover:bg-accent hover:text-accent-foreground'
19
- : 'bg-primary text-primary-foreground hover:bg-primary/90';
20
- return (_jsx("button", { type: "button", onClick: onClick, className: `${base} ${sizeClass} ${variantClass} ${className ?? ''}`, children: children }));
21
- }
22
- export function NotificationPermissionPrompt({ ButtonComponent = DefaultButton, messages, autoShowDelayMs = 2000, reloadOnGrant = true, className, } = {}) {
23
- const [show, setShow] = useState(false);
13
+ /**
14
+ * Renders through the shared notification toast instead of its own
15
+ * fixed-position banner, so it stacks with every other app notification
16
+ * rather than competing for a corner of the screen.
17
+ */
18
+ export function NotificationPermissionPrompt({ messages, autoShowDelayMs = 2000, reloadOnGrant = true, } = {}) {
24
19
  const msgs = { ...DEFAULTS, ...messages };
25
- useEffect(() => {
26
- if (typeof window === 'undefined')
27
- return;
28
- if ('Notification' in window && Notification.permission === 'default') {
29
- const timer = setTimeout(() => setShow(true), autoShowDelayMs);
30
- return () => clearTimeout(timer);
31
- }
32
- return undefined;
33
- }, [autoShowDelayMs]);
34
- useEffect(() => {
35
- if (typeof window === 'undefined')
36
- return;
37
- const handleTrigger = () => {
38
- if (!('Notification' in window))
39
- return;
40
- if (Notification.permission !== 'granted') {
41
- setShow(true);
42
- sessionStorage.removeItem('notification-prompt-dismissed');
43
- }
44
- };
45
- window.addEventListener('show-notification-prompt', handleTrigger);
46
- return () => window.removeEventListener('show-notification-prompt', handleTrigger);
47
- }, []);
20
+ const shownRef = useRef(false);
48
21
  const handleAllow = async () => {
49
- setShow(false);
50
22
  try {
51
23
  const permission = await Notification.requestPermission();
52
24
  if (permission === 'granted') {
@@ -68,17 +40,53 @@ export function NotificationPermissionPrompt({ ButtonComponent = DefaultButton,
68
40
  }
69
41
  };
70
42
  const handleDismiss = () => {
71
- setShow(false);
72
43
  if (typeof sessionStorage !== 'undefined') {
73
44
  sessionStorage.setItem('notification-prompt-dismissed', 'true');
74
45
  }
75
46
  };
76
- if (!show)
77
- return null;
78
- if (typeof sessionStorage !== 'undefined' && sessionStorage.getItem('notification-prompt-dismissed')) {
79
- return null;
80
- }
81
- return (_jsxs("div", { className: className ??
82
- 'fixed top-4 left-4 z-50 max-w-sm rounded-lg border bg-background p-4 shadow-lg animate-in slide-in-from-top-2 duration-500', children: [_jsx("button", { type: "button", onClick: handleDismiss, className: "absolute right-2 top-2 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100", "aria-label": "Dismiss", children: _jsx(X, { className: "h-4 w-4" }) }), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "p-2 bg-primary/10 rounded-full shrink-0", children: _jsx(Bell, { className: "h-5 w-5 text-primary" }) }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "font-semibold text-sm", children: msgs.title }), _jsx("p", { className: "text-xs text-muted-foreground mt-1 mb-3 leading-relaxed", children: msgs.description }), _jsxs("div", { className: "flex gap-2", children: [_jsx(ButtonComponent, { onClick: handleAllow, size: "sm", children: msgs.allowLabel }), _jsx(ButtonComponent, { onClick: handleDismiss, variant: "outline", size: "sm", children: msgs.dismissLabel })] })] })] })] }));
47
+ const show = () => {
48
+ if (typeof sessionStorage !== 'undefined' && sessionStorage.getItem('notification-prompt-dismissed')) {
49
+ return;
50
+ }
51
+ showNotificationToast({
52
+ title: msgs.title,
53
+ body: msgs.description,
54
+ type: 'info',
55
+ icon: 'bell',
56
+ duration: 15000,
57
+ action: { label: msgs.allowLabel, onClick: () => void handleAllow() },
58
+ cancel: { label: msgs.dismissLabel, onClick: handleDismiss },
59
+ });
60
+ };
61
+ useEffect(() => {
62
+ if (typeof window === 'undefined')
63
+ return;
64
+ if (!('Notification' in window) || Notification.permission !== 'default')
65
+ return;
66
+ if (shownRef.current)
67
+ return;
68
+ const timer = setTimeout(() => {
69
+ shownRef.current = true;
70
+ show();
71
+ }, autoShowDelayMs);
72
+ return () => clearTimeout(timer);
73
+ // eslint-disable-next-line react-hooks/exhaustive-deps
74
+ }, [autoShowDelayMs]);
75
+ useEffect(() => {
76
+ if (typeof window === 'undefined')
77
+ return;
78
+ const handleTrigger = () => {
79
+ if (!('Notification' in window))
80
+ return;
81
+ if (Notification.permission !== 'granted') {
82
+ sessionStorage.removeItem('notification-prompt-dismissed');
83
+ show();
84
+ }
85
+ };
86
+ window.addEventListener('show-notification-prompt', handleTrigger);
87
+ return () => window.removeEventListener('show-notification-prompt', handleTrigger);
88
+ // eslint-disable-next-line react-hooks/exhaustive-deps
89
+ }, []);
90
+ return null;
83
91
  }
84
92
  //# sourceMappingURL=notification-permission-prompt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"notification-permission-prompt.js","sourceRoot":"","sources":["../../src/components/notification-permission-prompt.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAsC,MAAM,OAAO,CAAA;AAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AA4B9B,MAAM,QAAQ,GAAmD;IAC/D,KAAK,EAAE,wBAAwB;IAC/B,WAAW,EACT,uFAAuF;IACzF,UAAU,EAAE,UAAU;IACtB,YAAY,EAAE,UAAU;IACxB,cAAc,EAAE,4BAA4B;IAC5C,YAAY,EAAE,4CAA4C;IAC1D,kBAAkB,EAChB,qHAAqH;CACxH,CAAA;AAED,SAAS,aAAa,CAAC,EACrB,OAAO,EACP,QAAQ,EACR,OAAO,GAAG,SAAS,EACnB,IAAI,EACJ,SAAS,GAOV;IACC,MAAM,IAAI,GACR,2LAA2L,CAAA;IAC7L,MAAM,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAA;IACjE,MAAM,YAAY,GAChB,OAAO,KAAK,SAAS;QACnB,CAAC,CAAC,gFAAgF;QAClF,CAAC,CAAC,wDAAwD,CAAA;IAC9D,OAAO,CACL,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,GAAG,IAAI,IAAI,SAAS,IAAI,YAAY,IAAI,SAAS,IAAI,EAAE,EAAE,YAEnE,QAAQ,GACF,CACV,CAAA;AACH,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,EAC3C,eAAe,GAAG,aAAa,EAC/B,QAAQ,EACR,eAAe,GAAG,IAAI,EACtB,aAAa,GAAG,IAAI,EACpB,SAAS,MAC4B,EAAE;IACvC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACvC,MAAM,IAAI,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAA;IAEzC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAM;QACzC,IAAI,cAAc,IAAI,MAAM,IAAI,YAAY,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACtE,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC,CAAA;YAC9D,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QAClC,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAA;IAErB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAM;QAEzC,MAAM,aAAa,GAAG,GAAG,EAAE;YACzB,IAAI,CAAC,CAAC,cAAc,IAAI,MAAM,CAAC;gBAAE,OAAM;YACvC,IAAI,YAAY,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC1C,OAAO,CAAC,IAAI,CAAC,CAAA;gBACb,cAAc,CAAC,UAAU,CAAC,+BAA+B,CAAC,CAAA;YAC5D,CAAC;QACH,CAAC,CAAA;QAED,MAAM,CAAC,gBAAgB,CAAC,0BAA0B,EAAE,aAAa,CAAC,CAAA;QAClE,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,0BAA0B,EAAE,aAAa,CAAC,CAAA;IACpF,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;QAC7B,OAAO,CAAC,KAAK,CAAC,CAAA;QAEd,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,iBAAiB,EAAE,CAAA;YAEzD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;gBAClC,IAAI,aAAa,EAAE,CAAC;oBAClB,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAA;gBAClD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE;oBAC7B,WAAW,EAAE,IAAI,CAAC,kBAAkB;oBACpC,QAAQ,EAAE,IAAI;iBACf,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,sCAAsC;YACtC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACtB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,OAAO,CAAC,KAAK,CAAC,CAAA;QACd,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE,CAAC;YAC1C,cAAc,CAAC,OAAO,CAAC,+BAA+B,EAAE,MAAM,CAAC,CAAA;QACjE,CAAC;IACH,CAAC,CAAA;IAED,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IACtB,IAAI,OAAO,cAAc,KAAK,WAAW,IAAI,cAAc,CAAC,OAAO,CAAC,+BAA+B,CAAC,EAAE,CAAC;QACrG,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,CACL,eACE,SAAS,EACP,SAAS;YACT,4HAA4H,aAG9H,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,aAAa,EACtB,SAAS,EAAC,0GAA0G,gBACzG,SAAS,YAEpB,KAAC,CAAC,IAAC,SAAS,EAAC,SAAS,GAAG,GAClB,EACT,eAAK,SAAS,EAAC,wBAAwB,aACrC,cAAK,SAAS,EAAC,yCAAyC,YACtD,KAAC,IAAI,IAAC,SAAS,EAAC,sBAAsB,GAAG,GACrC,EACN,eAAK,SAAS,EAAC,QAAQ,aACrB,aAAI,SAAS,EAAC,uBAAuB,YAAE,IAAI,CAAC,KAAK,GAAM,EACvD,YAAG,SAAS,EAAC,yDAAyD,YACnE,IAAI,CAAC,WAAW,GACf,EACJ,eAAK,SAAS,EAAC,YAAY,aACzB,KAAC,eAAe,IAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAC,IAAI,YAC7C,IAAI,CAAC,UAAU,GACA,EAClB,KAAC,eAAe,IAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,IAAI,YACjE,IAAI,CAAC,YAAY,GACF,IACd,IACF,IACF,IACF,CACP,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"notification-permission-prompt.js","sourceRoot":"","sources":["../../src/components/notification-permission-prompt.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- import { type ComponentType, type ReactNode } from 'react';
2
1
  export interface UpdatePromptMessages {
3
2
  title?: string;
4
3
  description?: string;
@@ -6,14 +5,14 @@ export interface UpdatePromptMessages {
6
5
  dismissLabel?: string;
7
6
  }
8
7
  export interface UpdatePromptProps {
9
- ButtonComponent?: ComponentType<{
10
- onClick?: () => void;
11
- children?: ReactNode;
12
- variant?: 'default' | 'outline';
13
- size?: 'sm';
14
- }>;
15
8
  messages?: UpdatePromptMessages;
16
- className?: string;
9
+ /** How long the toast stays before auto-dismissing (ms). Default: 0 (sticky). */
10
+ duration?: number;
17
11
  }
18
- export declare function PWAUpdatePrompt({ ButtonComponent, messages, className, }?: UpdatePromptProps): import("react").JSX.Element | null;
12
+ /**
13
+ * Renders through the shared notification toast instead of its own
14
+ * fixed-position banner, so it stacks with every other app notification
15
+ * rather than competing for a corner of the screen.
16
+ */
17
+ export declare function PWAUpdatePrompt({ messages, duration }?: UpdatePromptProps): null;
19
18
  //# sourceMappingURL=update-prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"update-prompt.d.ts","sourceRoot":"","sources":["../../src/components/update-prompt.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG1D,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,eAAe,CAAC,EAAE,aAAa,CAAC;QAC9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;QACpB,QAAQ,CAAC,EAAE,SAAS,CAAA;QACpB,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;QAC/B,IAAI,CAAC,EAAE,IAAI,CAAA;KACZ,CAAC,CAAA;IACF,QAAQ,CAAC,EAAE,oBAAoB,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAkCD,wBAAgB,eAAe,CAAC,EAC9B,eAA+B,EAC/B,QAAQ,EACR,SAAS,GACV,GAAE,iBAAsB,sCAsCxB"}
1
+ {"version":3,"file":"update-prompt.d.ts","sourceRoot":"","sources":["../../src/components/update-prompt.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,oBAAoB,CAAA;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AASD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,QAAY,EAAE,GAAE,iBAAsB,QA4BjF"}
@@ -1,6 +1,5 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { RefreshCw, X } from 'lucide-react';
3
- import {} from 'react';
1
+ import { useEffect, useRef } from 'react';
2
+ import { showNotificationToast } from '@asteby/metacore-notifications';
4
3
  import { usePWAContext } from '../provider';
5
4
  const DEFAULTS = {
6
5
  title: 'Actualización disponible',
@@ -8,20 +7,36 @@ const DEFAULTS = {
8
7
  updateLabel: 'Actualizar',
9
8
  dismissLabel: 'Después',
10
9
  };
11
- function DefaultButton({ onClick, children, variant = 'default', size, }) {
12
- const base = 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50';
13
- const sizeClass = size === 'sm' ? 'h-8 px-3' : 'h-9 px-4';
14
- const variantClass = variant === 'outline'
15
- ? 'border border-input bg-background hover:bg-accent hover:text-accent-foreground'
16
- : 'bg-primary text-primary-foreground hover:bg-primary/90';
17
- return (_jsx("button", { type: "button", onClick: onClick, className: `${base} ${sizeClass} ${variantClass}`, children: children }));
18
- }
19
- export function PWAUpdatePrompt({ ButtonComponent = DefaultButton, messages, className, } = {}) {
10
+ /**
11
+ * Renders through the shared notification toast instead of its own
12
+ * fixed-position banner, so it stacks with every other app notification
13
+ * rather than competing for a corner of the screen.
14
+ */
15
+ export function PWAUpdatePrompt({ messages, duration = 0 } = {}) {
20
16
  const { needRefresh, updateApp, closeUpdatePrompt } = usePWAContext();
21
17
  const msgs = { ...DEFAULTS, ...messages };
22
- if (!needRefresh)
23
- return null;
24
- return (_jsxs("div", { className: className ??
25
- 'fixed bottom-4 left-4 z-50 max-w-sm rounded-lg border bg-background p-4 shadow-lg', children: [_jsx("button", { type: "button", onClick: closeUpdatePrompt, className: "absolute right-2 top-2 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100", "aria-label": "Dismiss", children: _jsx(X, { className: "h-4 w-4" }) }), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(RefreshCw, { className: "h-5 w-5 mt-0.5" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "font-semibold", children: msgs.title }), _jsx("p", { className: "text-sm text-muted-foreground mt-1", children: msgs.description }), _jsxs("div", { className: "flex gap-2 mt-3", children: [_jsx(ButtonComponent, { onClick: updateApp, size: "sm", children: msgs.updateLabel }), _jsx(ButtonComponent, { onClick: closeUpdatePrompt, variant: "outline", size: "sm", children: msgs.dismissLabel })] })] })] })] }));
18
+ const shown = useRef(false);
19
+ useEffect(() => {
20
+ if (!needRefresh || shown.current)
21
+ return;
22
+ shown.current = true;
23
+ showNotificationToast({
24
+ title: msgs.title,
25
+ body: msgs.description,
26
+ type: 'info',
27
+ icon: 'refresh-cw',
28
+ duration: duration || Infinity,
29
+ action: {
30
+ label: msgs.updateLabel,
31
+ onClick: updateApp,
32
+ },
33
+ cancel: {
34
+ label: msgs.dismissLabel,
35
+ onClick: closeUpdatePrompt,
36
+ },
37
+ });
38
+ // eslint-disable-next-line react-hooks/exhaustive-deps
39
+ }, [needRefresh]);
40
+ return null;
26
41
  }
27
42
  //# sourceMappingURL=update-prompt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"update-prompt.js","sourceRoot":"","sources":["../../src/components/update-prompt.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAsC,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAoB3C,MAAM,QAAQ,GAAmC;IAC/C,KAAK,EAAE,0BAA0B;IACjC,WAAW,EAAE,kCAAkC;IAC/C,WAAW,EAAE,YAAY;IACzB,YAAY,EAAE,SAAS;CACxB,CAAA;AAED,SAAS,aAAa,CAAC,EACrB,OAAO,EACP,QAAQ,EACR,OAAO,GAAG,SAAS,EACnB,IAAI,GAML;IACC,MAAM,IAAI,GACR,2LAA2L,CAAA;IAC7L,MAAM,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAA;IACzD,MAAM,YAAY,GAChB,OAAO,KAAK,SAAS;QACnB,CAAC,CAAC,gFAAgF;QAClF,CAAC,CAAC,wDAAwD,CAAA;IAC9D,OAAO,CACL,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,IAAI,SAAS,IAAI,YAAY,EAAE,YACtF,QAAQ,GACF,CACV,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,EAC9B,eAAe,GAAG,aAAa,EAC/B,QAAQ,EACR,SAAS,MACY,EAAE;IACvB,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,aAAa,EAAE,CAAA;IACrE,MAAM,IAAI,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAA;IAEzC,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAA;IAE7B,OAAO,CACL,eACE,SAAS,EACP,SAAS;YACT,mFAAmF,aAGrF,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,iBAAiB,EAC1B,SAAS,EAAC,0GAA0G,gBACzG,SAAS,YAEpB,KAAC,CAAC,IAAC,SAAS,EAAC,SAAS,GAAG,GAClB,EACT,eAAK,SAAS,EAAC,wBAAwB,aACrC,KAAC,SAAS,IAAC,SAAS,EAAC,gBAAgB,GAAG,EACxC,eAAK,SAAS,EAAC,QAAQ,aACrB,aAAI,SAAS,EAAC,eAAe,YAAE,IAAI,CAAC,KAAK,GAAM,EAC/C,YAAG,SAAS,EAAC,oCAAoC,YAAE,IAAI,CAAC,WAAW,GAAK,EACxE,eAAK,SAAS,EAAC,iBAAiB,aAC9B,KAAC,eAAe,IAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAC,IAAI,YAC3C,IAAI,CAAC,WAAW,GACD,EAClB,KAAC,eAAe,IAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,IAAI,YACrE,IAAI,CAAC,YAAY,GACF,IACd,IACF,IACF,IACF,CACP,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"update-prompt.js","sourceRoot":"","sources":["../../src/components/update-prompt.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAe3C,MAAM,QAAQ,GAAmC;IAC/C,KAAK,EAAE,0BAA0B;IACjC,WAAW,EAAE,kCAAkC;IAC/C,WAAW,EAAE,YAAY;IACzB,YAAY,EAAE,SAAS;CACxB,CAAA;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,CAAC,KAAwB,EAAE;IAChF,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,aAAa,EAAE,CAAA;IACrE,MAAM,IAAI,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAA;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAE3B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO;YAAE,OAAM;QACzC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAA;QAEpB,qBAAqB,CAAC;YACpB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,YAAY;YAClB,QAAQ,EAAE,QAAQ,IAAI,QAAQ;YAC9B,MAAM,EAAE;gBACN,KAAK,EAAE,IAAI,CAAC,WAAW;gBACvB,OAAO,EAAE,SAAS;aACnB;YACD,MAAM,EAAE;gBACN,KAAK,EAAE,IAAI,CAAC,YAAY;gBACxB,OAAO,EAAE,iBAAiB;aAC3B;SACF,CAAC,CAAA;QACF,uDAAuD;IACzD,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,OAAO,IAAI,CAAA;AACb,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asteby/metacore-pwa",
3
- "version": "0.5.1",
3
+ "version": "0.6.1",
4
4
  "description": "Metacore PWA helpers — vite plugin wrapper, install/update prompts, push notifications, offline indicator",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -48,7 +48,8 @@
48
48
  "vite-plugin-pwa": ">=1"
49
49
  },
50
50
  "dependencies": {
51
- "lucide-react": "^1.0.0"
51
+ "lucide-react": "^1.0.0",
52
+ "@asteby/metacore-notifications": "26.0.0"
52
53
  },
53
54
  "devDependencies": {
54
55
  "@types/react": "^19.0.0",