baklava icon indicating copy to clipboard operation
baklava copied to clipboard

Notification Component

Open muratcorlu opened this issue 3 years ago • 6 comments

Design

Figma Design Document

Implementation

General usage example:

<bl-notification
    variant="info"
    caption="Info Caption"
    description="Info Description"
    permanent
    swipe
>
    Info Notification Component Text
</bl-notification>

Rules

Put some rules about how this component should behave and implemented

  • permanent attribute controls the component visibility. If true component stays on the screen, if false component disappears after 7 seconds. (For default it's false.) (If a user hover their mouse over component, countdown stops.)
  • swipe attribute controls the component dismiss functionality. If true component can be dismissed by swipe to right. (For default it's false.)

API Reference:

bl-notification component

Notification component displays an informational message to users for a while with additional features if desired.

Description

Attributes

Attribute Description Default Value
variant (string) Decides variants of notification box ( info, success, warning, error ) "info"
caption (string) Sets notification caption -
description (string) Sets notification description -
permanent (boolean) Stays component always on the screen false
swipe (boolean) Makes component swipeable to dismiss false

muratcorlu avatar Jun 27 '22 22:06 muratcorlu

Notification Component Design Meeting Report

Date: 12.10.2022 15:30 (UTC+3)

  • Notification component will cover uses cases that we previously named as Toast.
  • Notifications will be temporary by default.
  • Default duration will be decided.
  • Duration can be set by the user.
  • We'll consider setting default duration regarding to content length.
  • Notification can be set as permanent. In this case Notification will be dismissed by a user action (close button)
  • Notifications can be dismissed with swipe event (swipe down for small screens, swipe right for large screens)
  • Close button will be optional.
  • A progress will be shown in temporary mode.
  • Dismiss progress will be paused when user hover on notification.
  • Notification will be position on bottom on small screens, and top right (or top left regarding to text direction) on large screens.
  • Notification will enter/leave screen with an animation. Comes/leaves from/to bottom on small screens, right on large screens.
  • Multiple notifications would be visible with a vertical stack. New notifications will come to top on large screens, and will come to bottom on small screens.
  • By default distance of the notification group to top and bottom of the screen will be defined on both small and large screens. On small screens maximum area will be kept as half of the screen height at most. These margins would be set by the user (top-distance, bottom-distance)
  • Notifications can have multiple variants. Variants will be defined in design phase.
  • Technically we may use Alert component inside Notification component since visually they may look very identical with some exceptions. This will be considered during design phase.

muratcorlu avatar Oct 12 '22 14:10 muratcorlu

Here is Figma link for design & documentation, we are still working on the notification design for small screens.

buseselvi avatar Nov 16 '22 10:11 buseselvi

Current design is heavily using our Alert component. But there are some arrangements to do first on Alert component. We have a separate issue for that. #318

muratcorlu avatar Dec 05 '22 15:12 muratcorlu

I have 2 more issues that I found, I use alert and progress indicator component when making notification component so:

  • Progress indicator needs to have more than 2 colors.
  • Progress indicator border radius needs to be arrangeable.

How can we fix those problems?

onursert avatar Dec 28 '22 11:12 onursert

When I check figma design, I see the component as same as our Alert component. Maybe notification component should just be a wrapper of alert component. Then variant, caption, description can be set with alert component.

<bl-notification permanent>
  <bl-alert variant="success" caption="Message sent!">
      Your message has been sent successfully!
      <bl-button slot="action">Undo</bl-button>
  </bl-alert>
</bl-notification>

Even progress indicator and auto dismissing functionality can be part of Alert component. Maybe notification component can just handle the positioning (and swipe to dismiss). What do you think? @buseselvi @onursert

Regarding to your questions:

  • We can add a CSS variable to progress-indicator component like progress-color that defaults to --bl-color-success.
  • If progress will be part of alert component, then border-radiuses can be handled by covering corners inside alert component borders.

We'll also need some events to track if a notification dismissed, showed-up etc. And I don't think that we need to set an attribute to enable swiping. If notification is not permanent (means can be dismissable) then dismissing always would be done via swiping or by pressing close icon.

muratcorlu avatar Dec 28 '22 11:12 muratcorlu

We shouldn't use auto dismissing function on alert component because choosing one gets complicated and alerts don't work that way 🥲 Apart from that, if we can, we can use the alert component as base component for the notification. @muratcorlu @onursert

buseselvi avatar Dec 28 '22 11:12 buseselvi

Hey,

The way I understand from the ADR, the usage of this component is similar to bl-dialog. We expect user to render it when they need it. I believe we should provide user with programmatic interface instead. Since the main usage of this component is mostly going to be errors on async actions. The usage example could be:

<bl-notification />

<script>
const notificationController = document.querySelector('bl-notification');

notificationController.addNotification({
  caption: 'Error',
  description: 'Something went wrong',
  variant: 'error',
  icon: true,
  permanent: true,
  action: {
    label: 'Ok',
    onClick: notification => {
      // maybe wait for animation to end?
      await notificationController.removeNotification(notification.id);
      // or
      await notification.remove()
    },
  },
});
</script>

ogunb avatar Jul 20 '23 12:07 ogunb

Hi @ogunb,

Since we provide web components here, I think we should always try to keep providing a declarative way to implement basic functionality. But we can (should) also provide imperative ways of doing functionality, if it adds practical options.

So, maybe instead of using <bl-notification> for both ways, we can define a <bl-notification-container> component which has a method like you mentioned above. It can simple add bl-notification component in its template internally. That means, some developers can still just use bl-notification component to show and hide a notification in HTML easily (but putting and removing it to/from DOM) and some others can use this method to programmatically add notifications.

Even we can consider adding some extra methods as shortcuts like showAlert that will set some parameters with a predefined value for a "alert" type notification (like error variant, error icon, permenent true, etc).

muratcorlu avatar Aug 08 '23 10:08 muratcorlu

I will be revising the ADR for this component in the upcoming days.

Here are some key points from our last update meeting:

  • We are planning to introduce two components: a standalone bl-notification and a bl-notification-container.
  • The container component will offer an interface for managing notifications and will handle their positioning.
  • The question of whether the bl-notification should dictate its own position is still open. Various ideas were discussed:
    • The bl-notification component could publish and listen for events related to being opened/dismissed within the document, allowing it to determine the top position dynamically.
    • Alternatively, the bl-notification might not have any positioning logic altogether, serving as a blank canvas. Users would then have the freedom to develop their own interfaces on top of it.
    • Another option is to restrict the use of bl-notification to being a child component of bl-notification-container. In this scenario, the container would take charge of positioning. However, a potential drawback is that if multiple containers exist, notifications from different containers might overlap. Users should exercise caution in such cases.

ogunb avatar Aug 18 '23 15:08 ogunb

We created a quick and dirty POC w/ @CagriAldemir. It covers all cases mentioned before.

The concept is:

  • bl-notification component emits a global created and removed events.
  • bl-notification-container listens these events and moves the components as its child or removes them.
  • bl-notification-container renders them inside light dom so user can still access the bl-notification element.
  • If the user doesn't use bl-notification-container, bl-notification will render on place. User can position and implement their own interface as they'd like.

Any feedback would be appreciated.

Template Usage

<bl-notification-container></bl-notification-container>

<bl-notification
  id="notification"
  caption="Welcome to Baklava!"
  description="This is a notification"
  variant="info"
  icon
></bl-notification>

JS Usage

<bl-notification-container></bl-notification-container>

<script>
  const el = document.querySelector("bl-notification-container");

  el.addNotification({
    caption: "Welcome to Baklava!",
    description: "This is a notification",
    variant: "info",
    icon: true,
    action: {
      label: "Action",
      onClick: notification => {
        notification.dismiss();
      },
    },
  });
</script>

ogunb avatar Aug 24 '23 15:08 ogunb

Thank you for the work you've put into the Notification component and the PoC 🚀 . I'm impressed with the considerations you've incorporated. As we move forward, please keep in mind a few points to ensure we're meeting our standards:

  • Ensure every notification is equipped with the correct ARIA roles, states, and properties. For clarity, roles like "alert" or "status" would be suitable in many contexts.
  • It's essential that users can navigate to and interact with notifications using only their keyboards, with particular attention to the action buttons.
  • Maintain a smooth user experience by ensuring that the appearance and dismissal of notifications do not result in jarring content shifts. @buseselvi can help us about this. 🙏

leventozen avatar Oct 25 '23 13:10 leventozen

https://github.com/Trendyol/baklava/issues/617

We have the same issue as above. Murat suggested that Popover API could be used and it does solve the covering issue but, dialog element will prevent any action outside of it regardless of their placement on top layer. So the notifications becomes non-interactive.

I haven't figured out a workaround for this. Here is a codesanbox setup if anyone is willing to give it a shot.

My suggestion would be to ditch dialog element all together.

ogunb avatar Nov 14 '23 14:11 ogunb

Have you tried dialog element with polyfilled=true attribute, is this problem still ocurring?

stovein avatar Nov 14 '23 14:11 stovein

Nope. Since polyfilled version is actually a div and doesn't use the top layer; it will work, which is why I suggest ditching the dialog all together.

ogunb avatar Nov 14 '23 14:11 ogunb

Design

Figma Design Document

bl-notification Implementation

General usage example:

<bl-notification
    no-animation
    duration="7"
></bl-notification>

<script>
  const el = document.querySelector("bl-notification");

  const addedNotification = el.addNotification({
    caption: "Notification Caption",
    description: "This is a notification",
    variant: "warning",
    icon: "academy",
    primaryAction: {
      label: "Action",
      onClick: notification => {
        notification.remove();
      },
    },
    secondaryAction: {
      label: "Action",
      onClick: async notification => {
        await notification.remove();
        first.remove();
      },
    },
  });

  // some actions
  addedNotification.remove();
  // or
  el.removeNotification(addedNotification.id);
</script>

Rules

  • duration attribute sets the default duration of notifications when not provided.
  • no-animation attribute disables animation of notifications. Animations will respect the user's preferences regardless of this property.
  • Cards animate in from right on desktop and animate in from top on mobile (screens smaller than 480px).
  • Last in card will be on top of the notification list on desktop, and last in card will be on bottom of the notification list on mobile.
  • Cards has touch support on mobile. User can swipe to up to dismiss the notification.
  • This component will act as an interface that will manage notifications. It will have two methods to add and remove notifications.

API Reference

Notification component acts as an interface that will manage notifications. It has two methods to add and remove notifications.

Attributes

Attribute Description Default Value
duration (number) Sets the default duration of notifications in seconds when not provided 7
no-animation (boolean) Disables animation of notifications false

Methods

Method Description Parameters Return Value
addNotification Adds a notification to the notification list BlNotificationCard Props The added notification object with remove method
removeNotification Async method that removes a notification from the notification list after the animation is finished Notification ID A promise that resolves when the animation is finished

bl-notification-card Implementation

General usage example:

<bl-notification-card
  caption="Caption"
  icon
  variant="error"
  permanent
  duration="7"
  closed
  @bl-notification-card-request-close
  @bl-notification-card-close
>
  Lorem ipsum dolor sit amet consectetur adipisicing elit.

  <bl-button slot="primary-action">Action</bl-button>
  <bl-button slot="secondary-action">Secondary Action</bl-button>
</bl-notification-card

Rules

  • duration attribute sets the duration of the notification in seconds. When the duration is over, the notification will be dismissed automatically.
  • permanent attribute makes the notification permanent and it will not be dismissed automatically. User can still dismiss it manually.
  • closed attribute makes the notification closed and it will not be displayed.
  • caption attribute sets the caption of the notification.
  • icon attribute sets the icon of the notification. Either boolean or icon name can be provided. True value will use bl-alert default.
  • variant attribute sets the variant of the notification. Possible values are info, success, warning, error.
  • primary-action slot will be displayed as a primary action button.
  • secondary-action slot will be displayed as a secondary action button.
  • bl-notification-card-request-close event will be fired when the notification is requested to be closed. If default prevented, the notification will not be closed.
  • bl-notification-card-close event will be fired when the notification is closed.

API Reference

Notification card component is a component that will be used to display notifications.

Attributes

Attribute Description Default Value
duration (number) Sets the duration of the notification in seconds 7
permanent (boolean) Makes the notification permanent and it will not be dismissed automatically false
closed (boolean) Makes the notification closed and it will not be displayed false
caption (string) Sets the caption of the notification ""
icon (string) Sets the icon of the notification ""
variant (string) Sets the variant of the notification ""

Slots

Slot Description
default Will be displayed as the description of the notification
primary-action Will be displayed as a primary action button
secondary-action Will be displayed as a secondary action button

Events

Event Description Detail
bl-notification-card-request-close Fired when the notification is requested to be closed { source: "duration-ended" / "close-button" }
bl-notification-card-close Fired when the notification is closed { source: "duration-ended" / "close-button" }

ogunb avatar Nov 16 '23 08:11 ogunb

I think we should rename slot names that has been named as 'action' and 'action-secondary'. Primary-action and secondary-action fit better, imho.

erbilnas avatar Nov 16 '23 09:11 erbilnas

:tada: This issue has been resolved in version 2.4.0-beta.3 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

github-actions[bot] avatar Nov 30 '23 14:11 github-actions[bot]

:tada: This issue has been resolved in version 3.0.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

github-actions[bot] avatar Jan 25 '24 13:01 github-actions[bot]