diff --git a/app/webui/js/components/notifications.js b/app/webui/js/components/notifications.js new file mode 100644 index 0000000..f2f639e --- /dev/null +++ b/app/webui/js/components/notifications.js @@ -0,0 +1,44 @@ +/** + * Toast-Notification Component (Alpine.js) + * + * Renders the global notification queue from $store.notifications as a stack + * of toasts in the top-right corner. Pages include this component exactly once, + * typically in a shared layout fragment (e.g. app.html and index.html). + * + * Usage in HTML: + *
+ * + *
+ * + * R-5: x-text only, never x-html. + */ + +export function toastContainer() { + return { + get items() { + return window.Alpine ? Alpine.store('notifications').items : []; + }, + dismiss(id) { + if (window.Alpine) Alpine.store('notifications').dismiss(id); + }, + }; +} + +// Register the component as a global Alpine.data() factory. Pages can use +// `x-data="toastContainer()"` after this module is imported. +if (typeof window !== 'undefined') { + document.addEventListener('alpine:init', () => { + if (window.Alpine && !Alpine.$data_registry) { + // no-op: Alpine 3 stores factories on the global namespace + } + // Alpine 3: Alpine.data(name, factory) registers globally for x-data="name" + if (window.Alpine) { + window.Alpine.data('toastContainer', toastContainer); + } + }); +} + +export default toastContainer;