clone

a deno framework for local-first web apps that open instantly, work offline and sync when users choose

feat/141-effect-library
lofi / package / preact / use-notices.ts
use-notices.ts 1.9K
1/**2 * Preact binding for the durable notice queue behind `s.notice`: the live list3 * of user-visible messages an effect enqueued when a write settled, plus the4 * dismissal action. Apps render their own surface over this, or use the5 * built-in {@link Notices} component.6 *7 * @module8 */910import { useEffect, useState } from "preact/hooks";11import {12 dismissAllNotices,13 dismissNotice,14 listNotices,15 type NoticeEntry,16 subscribeNotices,17} from "../runtime/mod.ts";1819export type { NoticeEntry, NoticeTone } from "../runtime/mod.ts";2021/** The live notices and the actions to retire them. */22export type NoticesSurface = {23 /** The live notices: enqueued, not dismissed, not past their TTL. */24 notices: readonly NoticeEntry[];25 /** Dismisses one notice by id. */26 dismiss: (id: string) => void;27 /** Dismisses every notice. */28 dismissAll: () => void;29};3031/**32 * Subscribes a Preact component to the durable notice queue. The list stays33 * live across enqueues (including effects that fire at a boot re-arm),34 * dismissals, and TTL retirement.35 *36 * @example37 * ```tsx38 * import { useNotices } from "@nzip/lofi/preact";39 *40 * const { notices, dismiss } = useNotices();41 * return notices.map((n) => (42 * <div key={n.id} data-tone={n.tone}>43 * {n.message}44 * <button type="button" onClick={() => dismiss(n.id)}>Dismiss</button>45 * </div>46 * ));47 * ```48 *49 * @returns The live notices and the dismissal actions.50 */51export function useNotices(): NoticesSurface {52 const [notices, setNotices] = useState<readonly NoticeEntry[]>(() => listNotices());53 useEffect(() => {54 // Publish the current list once on mount — an effect may have enqueued55 // before this component subscribed — then follow every change.56 setNotices(listNotices());57 return subscribeNotices(() => setNotices(listNotices()));58 }, []);59 return { notices, dismiss: dismissNotice, dismissAll: dismissAllNotices };60}