Componente
Notification
Notifiche brevi con titolo, icona e barra laterale colorata. Nel flusso della pagina, oppure in un angolo dello schermo come popover nativo posizionato da daisyUI toast.
- Riferimento
<it-notification>- Classi
ita-notificationita-notification-successita-notification-errorita-notification-infoita-notification-warningita-notification-bodyita-notification-titleita-notification-textita-notification-closeita-toast- Basato su (daisyUI)
alerttoasttoast-toptoast-bottomtoast-starttoast-centertoast-endbtn-ghostbtn-square- Solo CSS
- Le notifiche posizionate sono popover="manual": le mostra un pulsante con popovertarget e le chiude un pulsante con popovertargetaction="hide", senza script. La chiusura automatica dopo qualche secondo richiede JavaScript. Errori e avvisi usano role=alert, gli altri role=status.
- Storybook
- Apri le storie di Notification
Varianti
Notifica di esempio
Testo della notifica.
Domanda inviata
Riceverai una conferma via email.
Pagamento non riuscito
Controlla i dati della carta e riprova.
Manutenzione programmata
Il servizio non sarà disponibile domenica dalle 8 alle 12.
Sessione in scadenza
Salva il modulo entro 5 minuti.
Mostra il codice HTMLNascondi il codice HTML
<div class="flex flex-col gap-4">
<div role="status" aria-labelledby="notification-1-title" class="ita-notification">
<div class="ita-notification-body">
<p id="notification-1-title" class="ita-notification-title"><span>Notifica di esempio</span></p>
<p class="ita-notification-text">Testo della notifica.</p>
</div>
</div>
<div role="status" aria-labelledby="notification-2-title" class="ita-notification ita-notification-success">
<div class="ita-notification-body">
<p id="notification-2-title" class="ita-notification-title"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M17.1,7.9l0.7,0.7L10,16.2l-4.7-4.6L6,10.9l4,3.9L17.1,7.9z M22,12c0,5.5-4.5,10-10,10S2,17.5,2,12S6.5,2,12,2S22,6.5,22,12z M21,12c0-5-4-9-9-9s-9,4-9,9s4,9,9,9S21,17,21,12z" /></svg><span>Domanda inviata</span></p>
<p class="ita-notification-text">Riceverai una conferma via email.</p>
</div>
</div>
<div role="alert" aria-labelledby="notification-3-title" class="ita-notification ita-notification-error">
<div class="ita-notification-body">
<p id="notification-3-title" class="ita-notification-title"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M16.3,8.3L12.6,12l3.7,3.6l-0.7,0.7l-3.7-3.6l-3.6,3.6l-0.7-0.7l3.6-3.6L7.6,8.3l0.7-0.7l3.6,3.7l3.7-3.7L16.3,8.3z M22,12 c0,5.5-4.5,10-10,10S2,17.5,2,12S6.5,2,12,2S22,6.5,22,12z M21,12c0-5-4-9-9-9s-9,4-9,9s4,9,9,9S21,17,21,12z" /></svg><span>Pagamento non riuscito</span></p>
<p class="ita-notification-text">Controlla i dati della carta e riprova.</p>
</div>
</div>
<div role="status" aria-labelledby="notification-4-title" class="ita-notification ita-notification-info">
<div class="ita-notification-body">
<p id="notification-4-title" class="ita-notification-title"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M12,21c-5,0-9-4-9-9s4-9,9-9s9,4,9,9S17,21,12,21L12,21z M11.3,6h1.5v2h-1.5V6z M11.3,9h1.5v9h-1.5V9z" /></svg><span>Manutenzione programmata</span></p>
<p class="ita-notification-text">Il servizio non sarà disponibile domenica dalle 8 alle 12.</p>
</div>
</div>
<div role="alert" aria-labelledby="notification-5-title" class="ita-notification ita-notification-warning">
<div class="ita-notification-body">
<p id="notification-5-title" class="ita-notification-title"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M12,21c-5,0-9-4-9-9s4-9,9-9s9,4,9,9S17,21,12,21L12,21z M11.5,14.2V5.7h1.2v8.5H11.5z M11.4,16.5h1.2v1.8h-1.2V16.5z" /></svg><span>Sessione in scadenza</span></p>
<p class="ita-notification-text">Salva il modulo entro 5 minuti.</p>
</div>
</div>
</div>Solo titolo
Modifiche salvate
Senza icona
Mostra il codice HTMLNascondi il codice HTML
<div class="flex flex-col gap-4">
<div role="status" aria-labelledby="notification-6-title" class="ita-notification ita-notification-success">
<div class="ita-notification-body">
<p id="notification-6-title" class="ita-notification-title"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M17.1,7.9l0.7,0.7L10,16.2l-4.7-4.6L6,10.9l4,3.9L17.1,7.9z M22,12c0,5.5-4.5,10-10,10S2,17.5,2,12S6.5,2,12,2S22,6.5,22,12z M21,12c0-5-4-9-9-9s-9,4-9,9s4,9,9,9S21,17,21,12z" /></svg><span>Modifiche salvate</span></p>
</div>
</div>
<div role="status" aria-labelledby="notification-7-title" class="ita-notification">
<div class="ita-notification-body">
<p id="notification-7-title" class="ita-notification-title"><span>Senza icona</span></p>
</div>
</div>
</div>Con chiusura
Premi la X: la notifica si nasconde solo con CSS.
Nuovo messaggio
Hai un nuovo messaggio dall'ufficio tributi.
Documento in scadenza
Mostra il codice HTMLNascondi il codice HTML
<div class="flex flex-col gap-4">
<div role="status" aria-labelledby="notification-8-title" class="ita-notification ita-notification-info">
<div class="ita-notification-body">
<p id="notification-8-title" class="ita-notification-title"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M12,21c-5,0-9-4-9-9s4-9,9-9s9,4,9,9S17,21,12,21L12,21z M11.3,6h1.5v2h-1.5V6z M11.3,9h1.5v9h-1.5V9z" /></svg><span>Nuovo messaggio</span></p>
<p class="ita-notification-text">Hai un nuovo messaggio dall'ufficio tributi.</p>
</div>
<label class="ita-notification-close"><input type="checkbox" class="sr-only"><span class="sr-only">Chiudi notifica</span><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12.7,12l3.7,3.6l-0.8,0.8L12,12.7l-3.6,3.7l-0.8-0.8l3.7-3.6L7.6,8.4l0.8-0.8l3.6,3.7l3.6-3.7l0.8,0.8L12.7,12z" /></svg></label>
</div>
<div role="alert" aria-labelledby="notification-9-title" class="ita-notification ita-notification-warning">
<div class="ita-notification-body">
<p id="notification-9-title" class="ita-notification-title"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M12,21c-5,0-9-4-9-9s4-9,9-9s9,4,9,9S17,21,12,21L12,21z M11.5,14.2V5.7h1.2v8.5H11.5z M11.4,16.5h1.2v1.8h-1.2V16.5z" /></svg><span>Documento in scadenza</span></p>
</div>
<label class="ita-notification-close"><input type="checkbox" class="sr-only"><span class="sr-only">Chiudi notifica</span><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12.7,12l3.7,3.6l-0.8,0.8L12,12.7l-3.6,3.7l-0.8-0.8l3.7-3.6L7.6,8.4l0.8-0.8l3.6,3.7l3.6-3.7l0.8,0.8L12.7,12z" /></svg></label>
</div>
</div>Posizioni sullo schermo
Ogni pulsante apre una notifica popover nell'angolo indicato; chiudila con la X.
Notifica top-start
Aperta con popovertarget, senza JavaScript.
Notifica top-center
Aperta con popovertarget, senza JavaScript.
Notifica top-end
Aperta con popovertarget, senza JavaScript.
Notifica bottom-start
Aperta con popovertarget, senza JavaScript.
Notifica bottom-center
Aperta con popovertarget, senza JavaScript.
Notifica bottom-end
Aperta con popovertarget, senza JavaScript.
Mostra il codice HTMLNascondi il codice HTML
<div class="flex flex-wrap gap-3">
<button type="button" class="ita-btn ita-btn-primary ita-btn-outline ita-btn-xs" popovertarget="notifica-top-start" popovertargetaction="show">top-start</button>
<button type="button" class="ita-btn ita-btn-primary ita-btn-outline ita-btn-xs" popovertarget="notifica-top-center" popovertargetaction="show">top-center</button>
<button type="button" class="ita-btn ita-btn-primary ita-btn-outline ita-btn-xs" popovertarget="notifica-top-end" popovertargetaction="show">top-end</button>
<button type="button" class="ita-btn ita-btn-primary ita-btn-outline ita-btn-xs" popovertarget="notifica-bottom-start" popovertargetaction="show">bottom-start</button>
<button type="button" class="ita-btn ita-btn-primary ita-btn-outline ita-btn-xs" popovertarget="notifica-bottom-center" popovertargetaction="show">bottom-center</button>
<button type="button" class="ita-btn ita-btn-primary ita-btn-outline ita-btn-xs" popovertarget="notifica-bottom-end" popovertargetaction="show">bottom-end</button>
</div>
<div id="notifica-top-start" popover="manual" role="status" aria-labelledby="notifica-top-start-title" class="toast toast-top toast-start ita-toast">
<div class="ita-notification">
<div class="ita-notification-body">
<p id="notifica-top-start-title" class="ita-notification-title"><span>Notifica top-start</span></p>
<p class="ita-notification-text">Aperta con popovertarget, senza JavaScript.</p>
</div>
<button type="button" class="ita-notification-close" popovertarget="notifica-top-start" popovertargetaction="hide" aria-label="Chiudi notifica"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12.7,12l3.7,3.6l-0.8,0.8L12,12.7l-3.6,3.7l-0.8-0.8l3.7-3.6L7.6,8.4l0.8-0.8l3.6,3.7l3.6-3.7l0.8,0.8L12.7,12z" /></svg></button>
</div>
</div>
<div id="notifica-top-center" popover="manual" role="status" aria-labelledby="notifica-top-center-title" class="toast toast-top toast-center ita-toast">
<div class="ita-notification ita-notification-success">
<div class="ita-notification-body">
<p id="notifica-top-center-title" class="ita-notification-title"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M17.1,7.9l0.7,0.7L10,16.2l-4.7-4.6L6,10.9l4,3.9L17.1,7.9z M22,12c0,5.5-4.5,10-10,10S2,17.5,2,12S6.5,2,12,2S22,6.5,22,12z M21,12c0-5-4-9-9-9s-9,4-9,9s4,9,9,9S21,17,21,12z" /></svg><span>Notifica top-center</span></p>
<p class="ita-notification-text">Aperta con popovertarget, senza JavaScript.</p>
</div>
<button type="button" class="ita-notification-close" popovertarget="notifica-top-center" popovertargetaction="hide" aria-label="Chiudi notifica"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12.7,12l3.7,3.6l-0.8,0.8L12,12.7l-3.6,3.7l-0.8-0.8l3.7-3.6L7.6,8.4l0.8-0.8l3.6,3.7l3.6-3.7l0.8,0.8L12.7,12z" /></svg></button>
</div>
</div>
<div id="notifica-top-end" popover="manual" role="status" aria-labelledby="notifica-top-end-title" class="toast toast-top toast-end ita-toast">
<div class="ita-notification ita-notification-info">
<div class="ita-notification-body">
<p id="notifica-top-end-title" class="ita-notification-title"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M12,21c-5,0-9-4-9-9s4-9,9-9s9,4,9,9S17,21,12,21L12,21z M11.3,6h1.5v2h-1.5V6z M11.3,9h1.5v9h-1.5V9z" /></svg><span>Notifica top-end</span></p>
<p class="ita-notification-text">Aperta con popovertarget, senza JavaScript.</p>
</div>
<button type="button" class="ita-notification-close" popovertarget="notifica-top-end" popovertargetaction="hide" aria-label="Chiudi notifica"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12.7,12l3.7,3.6l-0.8,0.8L12,12.7l-3.6,3.7l-0.8-0.8l3.7-3.6L7.6,8.4l0.8-0.8l3.6,3.7l3.6-3.7l0.8,0.8L12.7,12z" /></svg></button>
</div>
</div>
<div id="notifica-bottom-start" popover="manual" role="alert" aria-labelledby="notifica-bottom-start-title" class="toast toast-bottom toast-start ita-toast">
<div class="ita-notification ita-notification-warning">
<div class="ita-notification-body">
<p id="notifica-bottom-start-title" class="ita-notification-title"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M12,21c-5,0-9-4-9-9s4-9,9-9s9,4,9,9S17,21,12,21L12,21z M11.5,14.2V5.7h1.2v8.5H11.5z M11.4,16.5h1.2v1.8h-1.2V16.5z" /></svg><span>Notifica bottom-start</span></p>
<p class="ita-notification-text">Aperta con popovertarget, senza JavaScript.</p>
</div>
<button type="button" class="ita-notification-close" popovertarget="notifica-bottom-start" popovertargetaction="hide" aria-label="Chiudi notifica"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12.7,12l3.7,3.6l-0.8,0.8L12,12.7l-3.6,3.7l-0.8-0.8l3.7-3.6L7.6,8.4l0.8-0.8l3.6,3.7l3.6-3.7l0.8,0.8L12.7,12z" /></svg></button>
</div>
</div>
<div id="notifica-bottom-center" popover="manual" role="alert" aria-labelledby="notifica-bottom-center-title" class="toast toast-bottom toast-center ita-toast">
<div class="ita-notification ita-notification-error">
<div class="ita-notification-body">
<p id="notifica-bottom-center-title" class="ita-notification-title"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M16.3,8.3L12.6,12l3.7,3.6l-0.7,0.7l-3.7-3.6l-3.6,3.6l-0.7-0.7l3.6-3.6L7.6,8.3l0.7-0.7l3.6,3.7l3.7-3.7L16.3,8.3z M22,12 c0,5.5-4.5,10-10,10S2,17.5,2,12S6.5,2,12,2S22,6.5,22,12z M21,12c0-5-4-9-9-9s-9,4-9,9s4,9,9,9S21,17,21,12z" /></svg><span>Notifica bottom-center</span></p>
<p class="ita-notification-text">Aperta con popovertarget, senza JavaScript.</p>
</div>
<button type="button" class="ita-notification-close" popovertarget="notifica-bottom-center" popovertargetaction="hide" aria-label="Chiudi notifica"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12.7,12l3.7,3.6l-0.8,0.8L12,12.7l-3.6,3.7l-0.8-0.8l3.7-3.6L7.6,8.4l0.8-0.8l3.6,3.7l3.6-3.7l0.8,0.8L12.7,12z" /></svg></button>
</div>
</div>
<div id="notifica-bottom-end" popover="manual" role="status" aria-labelledby="notifica-bottom-end-title" class="toast toast-bottom toast-end ita-toast">
<div class="ita-notification">
<div class="ita-notification-body">
<p id="notifica-bottom-end-title" class="ita-notification-title"><span>Notifica bottom-end</span></p>
<p class="ita-notification-text">Aperta con popovertarget, senza JavaScript.</p>
</div>
<button type="button" class="ita-notification-close" popovertarget="notifica-bottom-end" popovertargetaction="hide" aria-label="Chiudi notifica"><svg class="shrink-0 fill-current" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12.7,12l3.7,3.6l-0.8,0.8L12,12.7l-3.6,3.7l-0.8-0.8l3.7-3.6L7.6,8.4l0.8-0.8l3.6,3.7l3.6-3.7l0.8,0.8L12.7,12z" /></svg></button>
</div>
</div>Con JavaScript (opzionale)
La ricetta è solo CSS e funziona così com'è. Questi frammenti non sono inclusi nel pacchetto: mostrano come aggiungere il comportamento che richiede uno script, in JavaScript semplice o in React.
Chiusura automaticajs
Mostra la notifica popover e la chiude dopo qualche secondo; il timer si ferma al passaggio del mouse e al focus.
function notify(id, ms = 6000) {
const el = document.getElementById(id);
el.showPopover();
let timer = setTimeout(() => el.hidePopover(), ms);
const pause = () => clearTimeout(timer);
const resume = () => (timer = setTimeout(() => el.hidePopover(), ms));
el.addEventListener("mouseenter", pause);
el.addEventListener("mouseleave", resume);
el.addEventListener("focusin", pause);
el.addEventListener("focusout", resume);
}
// notify("notifica-bottom-end");Notifiche in Reacttsx
Una coda di notifiche in una regione aria-live, con chiusura automatica.
import { createContext, useCallback, useContext, useState, type ReactNode } from "react";
type Toast = { id: number; title: string; variant?: "success" | "error" | "info" | "warning" };
const Ctx = createContext<(t: Omit<Toast, "id">) => void>(() => {});
export const useNotify = () => useContext(Ctx);
const tone = { success: "ita-notification-success", error: "ita-notification-error", info: "ita-notification-info", warning: "ita-notification-warning" };
export function Notifications({ children }: { children: ReactNode }) {
const [items, setItems] = useState<Toast[]>([]);
const notify = useCallback((t: Omit<Toast, "id">) => {
const id = Date.now();
setItems((xs) => [...xs, { ...t, id }]);
setTimeout(() => setItems((xs) => xs.filter((x) => x.id !== id)), 6000);
}, []);
return (
<Ctx.Provider value={notify}>
{children}
<div className="toast toast-end" role="status" aria-live="polite">
{items.map((t) => (
<div key={t.id} className={"ita-notification " + tone[t.variant ?? "info"]}>
<p className="ita-notification-title">{t.title}</p>
</div>
))}
</div>
</Ctx.Provider>
);
}