Merge pull request #32110 from autodesk-forks/mukul-notifications

feat(notifications): Allow Custom UI Rendering
This commit is contained in:
Fredrik Adelöw
2026-02-17 09:35:05 +01:00
committed by GitHub
3 changed files with 57 additions and 11 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-notifications': patch
---
Added `renderItem` prop to `NotificationsSidebarItem` component, allowing custom UI rendering while retaining all built-in notification logic (unread count, snackbar, signals, web notifications).
+8
View File
@@ -141,6 +141,13 @@ export const notificationsPlugin: BackstagePlugin<
{}
>;
// @public
export type NotificationsRenderItemProps = {
unreadCount: number;
to: string;
onClick: () => void;
};
// @public (undocumented)
export const NotificationsSidebarItem: (
props?: NotificationsSideBarItemProps,
@@ -158,6 +165,7 @@ export type NotificationsSideBarItemProps = {
text?: string;
disableHighlight?: boolean;
noTrack?: boolean;
renderItem?: (props: NotificationsRenderItemProps) => React.ReactNode;
};
// @public (undocumented)
@@ -99,6 +99,19 @@ export type NotificationSnackbarProperties = {
};
};
/**
* Props passed to the custom renderItem function
* @public
*/
export type NotificationsRenderItemProps = {
/** Current unread notification count */
unreadCount: number;
/** Route path to the notifications page */
to: string;
/** Click handler that requests web notification permission */
onClick: () => void;
};
/**
* @public
*/
@@ -119,6 +132,10 @@ export type NotificationsSideBarItemProps = {
text?: string;
disableHighlight?: boolean;
noTrack?: boolean;
/**
* Optional render function to provide custom UI instead of the default SidebarItem.
*/
renderItem?: (props: NotificationsRenderItemProps) => React.ReactNode;
};
/** @public */
@@ -304,6 +321,20 @@ export const NotificationsSidebarItem = (
const count = !error && !!unreadCount ? unreadCount : undefined;
const handleClick = useCallback(() => {
requestUserPermission();
}, [requestUserPermission]);
// Props to pass to custom renderItem function
const renderItemProps: NotificationsRenderItemProps = useMemo(
() => ({
unreadCount,
to: notificationsRoute,
onClick: handleClick,
}),
[unreadCount, notificationsRoute, handleClick],
);
return (
<>
{snackbarEnabled && (
@@ -336,17 +367,19 @@ export const NotificationsSidebarItem = (
}}
/>
)}
<SidebarItem
to={notificationsRoute}
onClick={() => {
requestUserPermission();
}}
text={text}
icon={icon}
{...restProps}
>
{count && <Chip size="small" label={count > 99 ? '99+' : count} />}
</SidebarItem>
{props?.renderItem ? (
props.renderItem(renderItemProps)
) : (
<SidebarItem
to={notificationsRoute}
onClick={handleClick}
text={text}
icon={icon}
{...restProps}
>
{count && <Chip size="small" label={count > 99 ? '99+' : count} />}
</SidebarItem>
)}
</>
);
};