Comunicazione Iframe - Toast
Panoramica
Questo documento descrive il sistema di comunicazione tra l'iframe e il parent window per mostrare notifiche toast nella SPA React.
Architettura
Hook: useToastBridge
L'hook useToastBridge è responsabile di:
- Registrare l'oggetto
toastsulwindowglobale - Fornire le funzioni che l'iframe può chiamare per mostrare notifiche
- Utilizzare internamente l'hook
useToastdi@elerama/uiper mostrare i toast - Pulire l'oggetto
toastquando il componente viene smontato
Type Declaration
Il file app/types/window.d.ts estende l'interfaccia Window per includere l'oggetto toast:
toast?: {
/**
* Mostra un toast generico
* @param message - Messaggio da mostrare
* @param description - Descrizione opzionale
*/
show: (message: string, description?: string) => void;
/**
* Mostra un toast di successo
* @param message - Messaggio da mostrare
* @param description - Descrizione opzionale
*/
success: (message: string, description?: string) => void;
/**
* Mostra un toast informativo
* @param message - Messaggio da mostrare
* @param description - Descrizione opzionale
*/
info: (message: string, description?: string) => void;
/**
* Mostra un toast di warning
* @param message - Messaggio da mostrare
* @param description - Descrizione opzionale
*/
warning: (message: string, description?: string) => void;
/**
* Mostra un toast di errore
* @param message - Messaggio da mostrare
* @param description - Descrizione opzionale
*/
error: (message: string, description?: string) => void;
/**
* Chiude tutti i toast attivi
*/
dismiss: () => void;
};Utilizzo
Nel Parent Window (React App)
L'hook useToastBridge viene utilizzato nell'AuthenticatedLayout:
export function AuthenticatedLayout({ children }: AuthenticatedLayoutProps) {
// ... altri hook ...
// Registra l'oggetto toast sul window per mostrare notifiche dall'iframe
useToastBridge();
// ...
}Importante: L'hook deve essere chiamato all'interno dell'AuthenticatedLayout perché:
- I toast sono disponibili solo per utenti autenticati
- Il componente
<Sonner />(che renderizza i toast) è montato nelroot.tsx
Nell'Iframe (PHP/JavaScript)
L'iframe può chiamare le funzioni toast tramite window.parent:
1. Toast generico
window.parent.toast.show('Operazione in corso...');
window.parent.toast.show('Titolo', 'Descrizione dettagliata');2. Toast di successo
window.parent.toast.success('Salvataggio completato!');
window.parent.toast.success('Salvato', 'I dati sono stati salvati correttamente nel database.');3. Toast informativo
window.parent.toast.info('Informazione importante');
window.parent.toast.info('Nota', 'Questa è una nota informativa per l\'utente.');4. Toast di warning
window.parent.toast.warning('Attenzione');
window.parent.toast.warning('Attenzione', 'Questa operazione potrebbe avere conseguenze irreversibili.');5. Toast di errore
window.parent.toast.error('Errore durante il salvataggio');
window.parent.toast.error('Errore di connessione', 'Impossibile raggiungere il server. Riprova più tardi.');6. Chiudere tutti i toast
window.parent.toast.dismiss();Esempio Completo
PHP nell'iframe
<!-- Mostra un toast di successo dopo un salvataggio -->
<script>
function salvaArticolo() {
fetch('/api/articoli', { method: 'POST', body: formData })
.then(response => {
if (response.ok) {
window.parent.toast.success('Articolo salvato', 'L\'articolo è stato salvato correttamente.');
} else {
window.parent.toast.error('Errore', 'Impossibile salvare l\'articolo.');
}
})
.catch(error => {
window.parent.toast.error('Errore di connessione', error.message);
});
}
</script>
<!-- Toast informativo al caricamento della pagina -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const messaggioPendente = <?= json_encode($messaggio_pendente) ?>;
if (messaggioPendente) {
window.parent.toast.info('Nota', messaggioPendente);
}
});
</script>
<!-- Toast di warning per operazioni rischiose -->
<script>
function eliminaArticolo(id) {
if (confirm('Sei sicuro di voler eliminare questo articolo?')) {
fetch('/api/articoli/' + id, { method: 'DELETE' })
.then(response => {
if (response.ok) {
window.parent.toast.success('Articolo eliminato');
// Ricarica la lista
location.reload();
} else {
window.parent.toast.error('Errore', 'Impossibile eliminare l\'articolo.');
}
});
}
}
</script>Verificare la disponibilità dell'API
Prima di chiamare le funzioni toast, è buona pratica verificare che l'API sia disponibile:
function mostraToast(tipo, messaggio, descrizione) {
if (window.parent && window.parent.toast && typeof window.parent.toast[tipo] === 'function') {
window.parent.toast[tipo](messaggio, descrizione);
} else {
// Fallback: usa alert o console.log
console.log('[Toast ' + tipo + ']', messaggio, descrizione);
}
}
// Utilizzo
mostraToast('success', 'Operazione completata');
mostraToast('error', 'Errore', 'Descrizione dell\'errore');Comportamento dei Toast
I toast utilizzano la libreria Sonner tramite il componente <Sonner /> di @elerama/ui:
- Posizione: In basso a destra dello schermo
- Durata: Auto-dismiss dopo alcuni secondi (configurabile)
- Stacking: I toast si impilano verticalmente
- Animazioni: Entrata/uscita animate
Varianti Stilistiche
| Metodo | Colore | Icona | Uso consigliato |
|---|---|---|---|
show() | Neutro | - | Messaggi generici |
success() | Verde | ✓ | Operazioni completate con successo |
info() | Blu | ℹ | Informazioni non critiche |
warning() | Arancione | ⚠ | Avvisi e attenzioni |
error() | Rosso | ✗ | Errori e problemi |
Test
Test Unitari
Il file tests/hooks/useToastBridge.test.ts contiene i test per verificare:
- ✅ Registrazione dell'oggetto
toastsul window - ✅ Rimozione dell'oggetto quando l'hook viene smontato
- ✅
show()chiama la funzione toast corretta - ✅
success()chiama la funzione success con i parametri corretti - ✅
info()chiama la funzione info con i parametri corretti - ✅
warning()chiama la funzione warning con i parametri corretti - ✅
error()chiama la funzione error con i parametri corretti - ✅
dismiss()chiude tutti i toast - ✅ Scenario completo di operazioni
- ✅ Stabilità delle funzioni tra i render
Esecuzione Test
# Esegui solo i test di useToastBridge
npm run test:run -- tests/hooks/useToastBridge.test.ts
# Esegui tutti i test
npm run test:runTest Manuali
Usa la pagina /test-iframe per testare manualmente:
- Vai alla pagina
/test-iframe - Clicca sul tab "Toast"
- Testa i vari tipi di toast:
Toast Generico- chiamashow()Toast Successo- chiamasuccess()Toast Info- chiamainfo()Toast Warning- chiamawarning()Toast Errore- chiamaerror()Successo con Descrizione- chiamasuccess()con descrizioneErrore con Descrizione- chiamaerror()con descrizioneChiudi Tutti i Toast- chiamadismiss()
Note sulla Sicurezza
- La comunicazione avviene tramite
window.parent, quindi funziona solo se l'iframe è sullo stesso dominio o configurato con CORS - L'oggetto
toastviene rimosso quando il componente viene smontato per evitare memory leaks - I messaggi passati ai toast vengono visualizzati così come sono (non vengono sanitizzati per HTML)
Logging
L'hook logga automaticamente tutte le operazioni nella console:
[useToastBridge] Hook montato, registrazione toast...
[useToastBridge] ✅ Oggetto toast registrato sul window
[useToastBridge] ✅ success chiamata dall'iframe: Operazione completata
[useToastBridge] ❌ error chiamata dall'iframe: Errore di connessione
[useToastBridge] ⚠️ Cleanup: rimozione toast...
[useToastBridge] ❌ Oggetto toast rimosso dal windowQuesti log sono utili per il debugging durante lo sviluppo.
Relazione con Altri Bridge
Il sistema di toast bridge segue lo stesso pattern degli altri bridge per la comunicazione iframe:
| Bridge | Oggetto Window | Scopo |
|---|---|---|
useTopbarMenu | window.topbar | Aggiornamento menu dinamico |
useTopbarMessages | window.messages | Gestione messaggi non letti |
useTopbarCart | window.cart | Gestione carrello |
useIframeNavigation | window.navigation | Navigazione tra pagine |
useTopbarSidebar | window.sidebar | Controllo sidebar |
useToastBridge | window.toast | Notifiche toast |
Tutti questi hook vengono chiamati nell'AuthenticatedLayout per garantire che siano disponibili solo per utenti autenticati.