Skip to content

feat(ui): notification manager#1689

Draft
vlad-schur-external-sap wants to merge 1 commit into
mainfrom
vlad-notification-manager-second-iteration
Draft

feat(ui): notification manager#1689
vlad-schur-external-sap wants to merge 1 commit into
mainfrom
vlad-notification-manager-second-iteration

Conversation

@vlad-schur-external-sap
Copy link
Copy Markdown
Contributor

Summary

Changes Made

  • Change 1
  • Change 2
  • Change 3

Related Issues

  • Issue 1: [link to issue]

Screenshots (if applicable)

Testing Instructions

  1. pnpm i
  2. pnpm TASK

Checklist

  • I have performed a self-review of my code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have made corresponding changes to the documentation (if applicable).
  • My changes generate no new warnings or errors.
  • I have created a changeset for my changes.

PR Manifesto

Review the PR Manifesto for best practises.

Signed-off-by: Vladislav Schur <u.shchur@sap.com>
Copilot AI review requested due to automatic review settings May 13, 2026 11:28
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 13, 2026

⚠️ No Changeset found

Latest commit: 33cd9f7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

PR Preview Action v1.8.1

🚀 View preview at
https://cloudoperators.github.io/juno/pr-preview/pr-1689/

Built to branch gh-pages at 2026-05-13 11:30 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@vlad-schur-external-sap vlad-schur-external-sap linked an issue May 13, 2026 that may be closed by this pull request
2 tasks
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new NotificationManager component to ui-components that wraps the Sonner toast system and exposes a Juno-flavored toast API, alongside initial Storybook stories and Vitest coverage.

Changes:

  • Introduces NotificationManager (Sonner <Toaster /> wrapper) and an exported toast API with semantic helpers (info/success/warning/error/danger).
  • Adds Storybook stories demonstrating basic usage, modal overlay behavior, and ShadowRoot caveats.
  • Adds tests covering basic rendering, semantic toast rendering, dismissal by id, and multi-manager scenarios; updates dependencies/lockfile to include sonner.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
pnpm-lock.yaml Adds the sonner dependency resolution to the workspace lockfile.
packages/ui-components/package.json Adds sonner@2.0.7 to ui-components dependencies.
packages/ui-components/src/components/NotificationManager/NotificationManager.types.tsx Defines the public toast/option types and a customToast helper.
packages/ui-components/src/components/NotificationManager/NotificationManager.component.tsx Implements NotificationManager and the semantic toast wrapper over Sonner.
packages/ui-components/src/components/NotificationManager/NotificationManager.test.tsx Adds Vitest tests for toaster rendering, semantic toast content, dismissal, and scoping.
packages/ui-components/src/components/NotificationManager/NotificationManager.stories.tsx Adds Storybook stories for common integration patterns and known Sonner limitations.
packages/ui-components/src/components/NotificationManager/index.ts Exports NotificationManager and toast from the component module.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

packages/ui-components/src/components/NotificationManager/NotificationManager.component.tsx:173

  • The dismissible prop (and per-toast closeButton option) isn’t actually enforced for semantic toasts because the rendered Toast component always shows a close icon and can hide itself on click. To honor the API contract, the close control should be hidden/disabled when dismissal is not allowed (and ideally dismissal should always go through Sonner’s dismiss).
    return customToast(
      ({ dismiss }) => (
        <Toast variant={variant} onDismiss={dismiss}>
          <div className="jn:flex jn:flex-col jn:gap-1">
            <div>{title}</div>
            {description ? <div className="jn:text-theme-medium">{description}</div> : null}
          </div>
        </Toast>

*/

import React from "react"
import { Meta, StoryObj } from "@storybook/react-vite"
Comment on lines +15 to +19
type ToastAction = {
label: React.ReactNode
onClick: () => void
actionButtonStyle?: CSSProperties
}
Comment on lines +47 to +53
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
export type SonnerCustomToast = (
_content: (_t: { dismiss: () => void; id: ToastId }) => React.ReactNode,
_options?: NotificationOptions
) => ToastId
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
export const customToast = (sonnerToast as any).custom as SonnerCustomToast
Comment on lines +124 to +142
export const NotificationManager = ({
dismissible = true,
duration = 4000,
visibleToasts = 3,
position = "bottom-right",
...props
}: NotificationManagerProps) => (
<Toaster
expand
className="juno-notification-manager"
closeButton={dismissible}
duration={duration}
visibleToasts={visibleToasts}
position={position}
toastOptions={{
classNames: { toast: "juno-toast" },
}}
{...props}
/>
const title = typeof message === "function" ? message() : message
const description = typeof data?.description === "function" ? data.description() : data?.description

// const { description: _description, ...customOptions } = data || {}
Comment on lines +1 to +6
/*
* SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Juno contributors
* SPDX-License-Identifier: Apache-2.0
*/
import type { CSSProperties, ReactNode } from "react"
import { toast as sonnerToast } from "sonner"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task](ui): create a first version of NotificationManager

2 participants