HelixOverviewComponentsMapsGraphIntroductionInstallationDeriving a themeSandboxTheme builderVisual testingCortexDocsEngramBuildingTraceBuildingRecallDeclaredServicesInsightsGet in touchSource on GitHub
Loading the reference
NotificationsView SourceEdit in SandboxView MarkdownCopy MarkdownOpen in ClaudeOpen in CursorA feed of notifications, each marked read or unread.StableSince 0.1.0FeedbackUsageimport'@fusion.dev/helix/notifications'import'@fusion.dev/helix-headless/notifications'Preview
API ReferenceNotificationhelix-notificationA single notification about something that happened, marked read or unread.
PropTypeDescriptionatstringDefault""When it happened, as anything Date parses.defaultReadbooleanDefaultfalseWhether the notification starts as read, used until read is set.dismissiblebooleanDefaultfalseWhether the element shows a control that dismisses it.dismissLabelstringDefault"Dismiss {label}"The dismiss control's label, read by screen readers.localestringDefault""Locale for the timestamp.readbooleanWhether the notification has been read.separation"filled"|"outlined"|"plain"How a row is separated from the one above it.unreadLabelstringDefault"Unread"What a screen reader hears before an unread notification's text.
ReadTypeDescriptionwhenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.
SlotDescription(default)What happened, in your own markup.actionsActions the user can take on the notification.descriptionA second, quieter line with more detail. It is a bare slot with no wrapping box, so an item without a description costs nothing. Style it with ::slotted().detailA block of content in the row, such as a quoted comment, a status change from one value to another, or a preview. It sets no text size or color, because its content usually brings its own.dismissReplaces the icon inside the dismiss control, which is drawn only when the row is dismissible.mediaAn avatar or icon identifying who or what it came from.
EventTypeDescriptionhelix-dismissHelixDismissEventFired when the user dismisses the notification. Cancelable.helix-readHelixReadEventFired when the notification is marked read or unread. Cancelable.
MethodTypeDescriptiondismiss() => booleanFires helix-dismiss, and returns false if a listener cancels it.markRead(next: unknown) => booleanRequests that the notification be marked read, and returns whether the
change was applied.
PartDescriptionactionsThe trailing slot's box.bodyThe label and the caption together.controlsThe actions and the dismiss control, shown in place of the time.dismissThe control that dismisses the notification.dismiss-markThe icon on the dismiss control, when no icon is slotted.itemThe whole notification.labelWhat happened, on the first line.mediaThe leading slot's box.timeWhen it happened.time-dayFormat Date's day, forwarded for a time drawn as fields. An elapsed time draws none.time-day-periodFormat Date's day-period, forwarded for a time drawn as fields. An elapsed time draws none.time-eraFormat Date's era, forwarded for a time drawn as fields. An elapsed time draws none.time-fractional-secondFormat Date's fractional-second, forwarded for a time drawn as fields. An elapsed time draws none.time-hourFormat Date's hour, forwarded for a time drawn as fields. An elapsed time draws none.time-minuteFormat Date's minute, forwarded for a time drawn as fields. An elapsed time draws none.time-monthFormat Date's month, forwarded for a time drawn as fields. An elapsed time draws none.time-secondFormat Date's second, forwarded for a time drawn as fields. An elapsed time draws none.time-time-zone-nameFormat Date's time-zone-name, forwarded for a time drawn as fields. An elapsed time draws none.time-weekdayFormat Date's weekday, forwarded for a time drawn as fields. An elapsed time draws none.time-yearFormat Date's year, forwarded for a time drawn as fields. An elapsed time draws none.trailingThe column holding the time and the controls.
CSS PropertyDescription--notifications-colorText color in a read item.--notifications-dismiss-colorColor of the dismiss control. It is danger, because dismissing an item removes it for good.--notifications-item-edgeColor of a carded row's border.--notifications-item-fillFill behind a filled row.--notifications-item-gapSpace between carded rows, which have no hairline.--notifications-item-radiusCorner radius of a carded row.--notifications-padding-blockSpace above and below an item.--notifications-padding-inlineSpace either side of an item.--notifications-ruleThe hairline between items.--notifications-unread-block-sizeLength of the unread mark.--notifications-unread-inline-sizeThickness of the unread mark.--notifications-unread-insetDistance from the unread mark to the row's leading edge.--notifications-unread-markColor of the edge mark on an unread item.--notifications-unread-offsetDistance from the unread mark to the row's top edge.--notifications-unread-radiusCorner radius of the unread mark, which can turn it into a dot.
Custom stateDescriptionactionsWhile the actions slot holds something, so the words above make room for it.controlsThe item can be dismissed, so the time gives way to the dismiss control under a pointer.feed-filledThe feed's separation is filled and the row sets none of its own, so the row is drawn as filled.feed-outlinedThe feed's separation is outlined and the row sets none of its own, so the row is drawn as outlined.readWhile it has been read.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Grouphelix-notification-groupA named set of notifications, which can be collapsed to the first of
them.
PropTypeDescriptioncollapsiblebooleanDefaultfalseWhether the group can be collapsed to its first row.countnumberThe number of notifications the group represents.defaultOpenbooleanDefaultfalseWhether the element starts open. Ignored once open is written.labelstringDefault""The group's name, such as a day, a subject, or a person.openbooleanWhether the element is open.
ReadTypeDescriptionisNotificationGroupbooleanMarks this element as a notification group, so the feed can recognize it
without importing its class.itemsHelixHeadlessNotification[]The notifications written into this group, in the order they were given.totalnumberThe number of notifications the group represents: count when it is set,
or the number of rows.whenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.
SlotDescription(default)The notifications in this group.actionsBeside the count, for a link to the rest of them.labelReplaces the group's name, for a heading that includes an icon.
EventTypeDescriptionhelix-before-closeHelixBeforeCloseEventFired before the group collapses. Cancelable.helix-before-openHelixBeforeOpenEventFired before the group expands. Cancelable: cancel it to keep the group collapsed.toggleToggleEventThe group expanded or collapsed. The event carries newState and oldState.
MethodTypeDescriptionrequestOpen(next: boolean) => booleanRequests that the element open or close, and returns whether the change
was applied.toggleOpen() => booleanRequests the opposite of the current state.
PartDescriptionactionsThe trailing region of the header.countThe number of notifications in the group.headerThe label, the count, and the actions together.itemsThe region holding the notifications.labelThe group's name.triggerThe control that collapses and expands the group, when collapsible is set.
Custom stateDescriptionopenThe group shows all of its notifications.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Roothelix-notificationsA feed of notifications, each marked read or unread.
PropTypeDescriptionarrivedLabelstringDefault"{count, plural, one {# new notification} other {# new notifications}}"What the feed says when unread notifications arrive, with {count} the
number of them. Empty it to say nothing.emptyTextstringDefault"Nothing to show"The text shown and announced when there are no rows and none are loading.fallbackLabelstringDefault"Notifications"The region's name where label is empty.labelstringDefault""The feed's name, read by screen readers.loadErrorstring|nullDefault""What the feed says when a page of it could not be loaded, such as after a
request to a server fails. Empty, null or no attribute is no error, so
removing the attribute clears it.loadingbooleanDefaultfalseWhether the rows are still loading.loadingTextstringDefault"Loading"The text shown and announced while the rows load.loadMorebooleanDefaultfalseWhether to draw a button after the list that asks for the next page, by
sending helix-load-more. Take it off once there is nothing more.loadMoreLabelstringDefault"Load more"The text of the load-more button.markAllbooleanDefaultfalseWhether to draw a control that marks everything read.markAllLabelstringDefault"Mark all as read"Label for the mark-all control.separation"filled"|"outlined"|"plain"How every row in the feed is set apart from the one above it, where the
row does not say for itself.totalnumberHow many notifications there are in all, where the feed holds only some of
them, read as each row's aria-setsize. -1 says the count is unknown.
ReadTypeDescriptiongroupsHelixHeadlessNotificationGroup[]The groups written into the feed, in the order they are written.itemsHelixHeadlessNotification[]The notifications in the feed, in the order they are written.rowsElement[]The content assigned to the list slot: the rows and the groups, in the
order they are written.unreadnumberHow many items are unread, counted from the items themselves.whenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.
SlotDescription(default)The notifications.emptyReplaces the words of empty-text in the empty part, such as a picture and a line of your own.errorReplaces the words of load-error in the error part, such as a line with a retry button.footerBelow the list, for a link to everything.headerAbove the list, for a title and the mark-all control.loadingReplaces the words of loading-text in the loading part, such as a loader.
EventTypeDescriptionhelix-dismissHelixDismissEventFired when the user dismisses a row. The row dispatches it, and you can listen for it on the feed. Cancelable: cancel it to keep the row.helix-load-moreHelixLoadMoreEventFired when a reader presses the load-more button, asking for the next page of the feed.helix-readHelixReadEventFired by an item when it is marked read or unread, and by the feed when everything is marked read. Cancelable.
MethodTypeDescriptionfoldEveryGroup(folded: unknown) => numberCollapses every collapsible group, and returns how many changed.markEveryoneRead() => numberMarks every unread item read, and returns how many changed.
PartDescriptionemptyShown when there is nothing in the feed.errorThe line load-error shows under the rows, in the danger color.footerThe region below the list.headerThe region above the list.listThe list itself.liveA copy of the empty, loading and error messages, in a live region that screen readers announce when they change. Visually hidden in the styled tier.loadingShown while the feed is loading.mark-allThe control that marks everything read.moreThe button after the list that asks for more, while load-more is set. It stays while the feed is loading, in a lighter color and aria-disabled, so focus stays on it.
CSS PropertyDescription--notifications-error-colorThe color of the error line.--notifications-item-gapSpace before the first row, and between rows, while separation makes every row a box.--notifications-max-block-sizeHow tall the feed may get before the list scrolls.--notifications-media-columnWidth of the media column that every item keeps when any item in the feed has media.--notifications-padding-inlineSpace either side of the header and footer.--notifications-ruleThe hairline between items and around the regions.
Custom stateDescriptionemptyWhile the feed holds no notification and is not loading, and load-error is not set. Never on the server, which cannot count the rows.errorWhile load-error is set.loadingWhile loading is set.mediaWhile a notification in the list holds something in its media slot, so every row keeps that column.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Notificationhelix-headless-notificationA single notification about something that happened, marked read or unread.
PropTypeDescriptionatstringDefault""When it happened, as anything Date parses.defaultReadbooleanDefaultfalseWhether the notification starts as read, used until read is set.dismissiblebooleanDefaultfalseWhether the element shows a control that dismisses it.dismissLabelstringDefault"Dismiss {label}"The dismiss control's name, read by screen readers, with {label} for the
row's own words.localestringDefault""Locale for the timestamp.readbooleanWhether the notification has been read.unreadLabelstringDefault"Unread"What a screen reader hears before an unread notification's text.
ReadTypeDescriptionwhenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.
SlotDescription(default)What happened, in your own markup.actionsActions the user can take, shown under the text. They are always visible, because acting on the notification is the purpose of the row.descriptionA second, quieter line with more detail. It is a bare slot with no wrapping box, so an item without a description costs nothing. Style it with ::slotted().detailA block of content in the row, such as a quoted comment, a status change from one value to another, or a preview. It sets no text size or color, because its content usually brings its own.dismissReplaces the icon inside the dismiss control, which is drawn only when the row is dismissible.mediaAn avatar or icon identifying who or what it came from.
EventTypeDescriptionhelix-dismissHelixDismissEventFired when the user dismisses the notification. Cancelable.helix-readHelixReadEventFired when the notification is marked read or unread. Cancelable.
MethodTypeDescriptiondismiss() => booleanFires helix-dismiss, and returns false if a listener cancels it.markRead(next: unknown) => booleanRequests that the notification be marked read, and returns whether the
change was applied.
PartDescriptionactionsThe trailing slot's box.bodyThe label and the caption together.controlsThe actions and the dismiss control, shown in place of the time.dismissThe control that dismisses the notification.dismiss-markThe icon on the dismiss control, when no icon is slotted.itemThe whole notification.labelWhat happened, on the first line.mediaThe leading slot's box.timeWhen it happened, formatted for people to read.time-dayFormat Date's day, forwarded for a time drawn as fields. An elapsed time draws none.time-day-periodFormat Date's day-period, forwarded for a time drawn as fields. An elapsed time draws none.time-eraFormat Date's era, forwarded for a time drawn as fields. An elapsed time draws none.time-fractional-secondFormat Date's fractional-second, forwarded for a time drawn as fields. An elapsed time draws none.time-hourFormat Date's hour, forwarded for a time drawn as fields. An elapsed time draws none.time-minuteFormat Date's minute, forwarded for a time drawn as fields. An elapsed time draws none.time-monthFormat Date's month, forwarded for a time drawn as fields. An elapsed time draws none.time-secondFormat Date's second, forwarded for a time drawn as fields. An elapsed time draws none.time-time-zone-nameFormat Date's time-zone-name, forwarded for a time drawn as fields. An elapsed time draws none.time-weekdayFormat Date's weekday, forwarded for a time drawn as fields. An elapsed time draws none.time-yearFormat Date's year, forwarded for a time drawn as fields. An elapsed time draws none.trailingThe column holding the time and the controls.
Custom stateDescriptionactionsWhile the actions slot holds something, so the words above make room for it.controlsThe item can be dismissed, so the time gives way to the dismiss control under a pointer.readWhile it has been read.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Grouphelix-headless-notification-groupA named set of notifications, which can be collapsed to the first of
them.
PropTypeDescriptioncollapsiblebooleanDefaultfalseWhether the group can be collapsed to its first row.countnumberThe number of notifications the group represents.defaultOpenbooleanDefaultfalseWhether the element starts open. Ignored once open is written.labelstringDefault""The group's name, such as a day, a subject, or a person.openbooleanWhether the element is open.
ReadTypeDescriptionisNotificationGroupbooleanMarks this element as a notification group, so the feed can recognize it
without importing its class.itemsHelixHeadlessNotification[]The notifications written into this group, in the order they were given.totalnumberThe number of notifications the group represents: count when it is set,
or the number of rows.whenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.
SlotDescription(default)The notifications in this group.actionsBeside the count, for a link to the rest of them.labelReplaces the group's name, for a heading that includes an icon.
EventTypeDescriptionhelix-before-closeHelixBeforeCloseEventFired before the group collapses. Cancelable.helix-before-openHelixBeforeOpenEventFired before the group expands. Cancelable: cancel it to keep the group collapsed.toggleToggleEventThe group expanded or collapsed. The event carries newState and oldState.
MethodTypeDescriptionrequestOpen(next: boolean) => booleanRequests that the element open or close, and returns whether the change
was applied.toggleOpen() => booleanRequests the opposite of the current state.
PartDescriptionactionsThe trailing region of the header.countThe number of notifications in the group.headerThe label, the count, and the actions together.itemsThe region holding the notifications.labelThe group's name.triggerThe control that collapses and expands the group, when collapsible is set.
Custom stateDescriptionopenThe group shows all of its notifications.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Roothelix-headless-notificationsA feed of notifications, each marked read or unread.
PropTypeDescriptionarrivedLabelstringDefault"{count, plural, one {# new notification} other {# new notifications}}"What the feed says when unread notifications arrive, with {count} the
number of them. Empty it to say nothing.emptyTextstringDefault"Nothing to show"The text shown and announced when there are no rows and none are loading.fallbackLabelstringDefault"Notifications"The region's name where label is empty.labelstringDefault""The feed's name, read by screen readers.loadErrorstring|nullDefault""What the feed says when a page of it could not be loaded, such as after a
request to a server fails. Empty, null or no attribute is no error, so
removing the attribute clears it.loadingbooleanDefaultfalseWhether the rows are still loading.loadingTextstringDefault"Loading"The text shown and announced while the rows load.loadMorebooleanDefaultfalseWhether to draw a button after the list that asks for the next page, by
sending helix-load-more. Take it off once there is nothing more.loadMoreLabelstringDefault"Load more"The text of the load-more button.markAllbooleanDefaultfalseWhether to draw a control that marks everything read.markAllLabelstringDefault"Mark all as read"Label for the mark-all control.totalnumberHow many notifications there are in all, where the feed holds only some of
them, read as each row's aria-setsize. -1 says the count is unknown.
ReadTypeDescriptiongroupsHelixHeadlessNotificationGroup[]The groups written into the feed, in the order they are written.itemsHelixHeadlessNotification[]The notifications in the feed, in the order they are written.rowsElement[]The content assigned to the list slot: the rows and the groups, in the
order they are written.unreadnumberHow many items are unread, counted from the items themselves.whenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.
SlotDescription(default)The notifications.emptyReplaces the words of empty-text in the empty part, such as a picture and a line of your own. The live region still says empty-text.errorReplaces the words of load-error in the error part, such as a line with a retry button. The live region still says load-error.footerBelow the list, for a link to everything.headerAbove the list, for a title and the mark-all control.loadingReplaces the words of loading-text in the loading part, such as a loader. The live region still says loading-text.
EventTypeDescriptionhelix-dismissHelixDismissEventFired when the user dismisses a row. The row dispatches it, and you can listen for it on the feed. Cancelable: cancel it to keep the row.helix-load-moreHelixLoadMoreEventFired when a reader presses the load-more button, asking for the next page of the feed.helix-readHelixReadEventFired by an item when it is marked read or unread, and by the feed when everything is marked read. Cancelable.
MethodTypeDescriptionfoldEveryGroup(folded: unknown) => numberCollapses every collapsible group, and returns how many changed.markEveryoneRead() => numberMarks every unread item read, and returns how many changed.
PartDescriptionemptyShown when there is nothing in the feed.errorShown while load-error is set, under any rows there are, in place of the empty and loading lines.footerThe region below the list.headerThe region above the list.listThe list itself, a feed whose rows are its articles.liveA copy of the empty, loading and error messages, in a live region that screen readers announce when they change. Visually hidden in the styled tier.loadingShown while the feed is loading.mark-allThe control that marks everything read.moreThe button after the list that asks for more, while load-more is set. It is aria-disabled while the feed is loading.
Custom stateDescriptionemptyWhile the feed holds no notification and is not loading, and load-error is not set. Never on the server, which cannot count the rows.errorWhile load-error is set.loadingWhile loading is set.mediaWhile a notification in the list holds something in its media slot, so every row keeps that column.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Examples
NameDescriptionControlledRead state that your own code controls, so marking an item read can wait for a server round trip.EventsThe helix-read and helix-dismiss events, which report two different changes.FilledRows drawn as boxes, set once on the feed, each holding a different kind of content.GroupedA feed cut into named groups, one of them folded to its first row.In A DrawerA bell in the header, a count on it, and the feed in a drawer behind it.PreviewA feed with unread items, a mark-all control, and timestamps that stay correct.PreviewA feed with unread items, a mark-all control, and timestamps that stay correct.