From 24b3501bc48b45b9f7d8899e372523e3d4e34621 Mon Sep 17 00:00:00 2001 From: Ogun Babacan Date: Thu, 23 Nov 2023 20:09:43 +0300 Subject: [PATCH] docs(notification): implement notification control Also improve notification object properties doc. --- .../notification/bl-notification.mdx | 36 +- .../notification/bl-notification.stories.ts | 428 ++++++++++-------- .../card/bl-notification-card.css | 2 +- 3 files changed, 276 insertions(+), 190 deletions(-) diff --git a/src/components/notification/bl-notification.mdx b/src/components/notification/bl-notification.mdx index 0725fce9..b5d45811 100644 --- a/src/components/notification/bl-notification.mdx +++ b/src/components/notification/bl-notification.mdx @@ -30,14 +30,10 @@ The `removeNotification` method accepts a notification id as a parameter and ret ### Adding a Notification -A notification could be added by calling the `addNotification` method with a notification object. +A notification could be added by calling the `addNotification` method with a [notification object](#notification-object). -#### Notification Object - - - ### Removing a Notification A notification could be removed by calling the `removeNotification` method with the notification's id. @@ -57,7 +53,14 @@ The `removeNotification` method returns a Promise that resolves when the notific A notification could have a primary and a secondary action. These actions are displayed as buttons on the notification. - + + #### Removing a Notification on Action Click @@ -65,7 +68,7 @@ A notification could be removed by calling notification's remove method. ### Permanent @@ -83,9 +86,26 @@ A notification could have one of the following variants: info, success, warning, ## Reference +### bl-notification + + +### Notification Object + +| Name | Description | Default | Type | +| ------------------- | ------------------------------------------------- | -------- | --------------------------------------------- | +| **caption** | The caption of the notification. | - | string | +| **description** | The description of the notification. | - | string | +| **icon** | The icon of the notification. | `true` | boolean or BaklavaIcon | +| **variant** | The variant of the notification. | `"info"` | `"info" \| "success" \| "warning" \| "error"` | +| **primaryAction** | The primary action of the notification. | - | `{ label: string, onClick: () => void }` | +| **secondaryAction** | The secondary action of the notification. | - | `{ label: string, onClick: () => void }` | +| **duration** | The duration of the notification in milliseconds. | `7` | number | +| **permanent** | Whether the notification is permanent. | `false` | boolean | +| **id** | The id of the notification. | - | string | +| **remove** | The remove method of the notification. | - | `() => Promise` | diff --git a/src/components/notification/bl-notification.stories.ts b/src/components/notification/bl-notification.stories.ts index 42ec8e23..5042640c 100644 --- a/src/components/notification/bl-notification.stories.ts +++ b/src/components/notification/bl-notification.stories.ts @@ -1,93 +1,150 @@ import { html } from "lit"; import { ifDefined } from "lit/directives/if-defined.js"; import { Meta, StoryObj } from "@storybook/web-components"; -import type BlNotification from "./bl-notification"; -import type { NotificationProps, Notification } from "./bl-notification"; import { fullscreenLayout } from "../../utilities/chromatic-decorators"; +import type { NotificationProps, Notification } from "./bl-notification"; const meta: Meta = { title: "Components/Notification", component: "bl-notification", parameters: { chromatic: { - viewports: [1000] + viewports: [1000], }, }, - decorators: [ - fullscreenLayout, - ], + decorators: [fullscreenLayout], argTypes: { - noAnimation: { - control: "boolean", - }, + // Notification Card Props duration: { control: "number", + description: "Duration in seconds", + defaultValue: 7, + }, + caption: { + control: "text", + description: "Caption of the notification", + }, + description: { + control: "text", + description: "Description of the notification. Required.", + }, + icon: { + control: "text", + defaultValue: "true", + description: + "Icon of the notification. If provided with a string, it will be used as an icon name. If provided with a boolean, it will use the default icon or no icon.", + }, + variant: { + options: ["info", "warning", "success", "error"], + default: "info", + control: { type: "select" }, + description: "Variant of the notification", + }, + permanent: { + control: "boolean", + defaultValue: false, + description: + "If true, the notification will not have duration and will be removed when the user clicks on the close button.", + }, + primaryAction: { + control: "object", + description: "Primary action of the notification. onClick and label properties are required.", + }, + secondaryAction: { + control: "object", + description: + "Secondary action of the notification. onClick and label properties are required.", + }, + }, + args: { + noAnimation: false, + duration: 20, + caption: "Notification Caption", + description: "Notification Description", + icon: "true", + variant: "info", + permanent: false, + primaryAction: { + label: "Primary Action", + onClick() {}, + }, + secondaryAction: { + label: "Secondary Action", + onClick() {}, }, }, }; export default meta; -const addNotification = (selector: string, options: NotificationProps) => { - const el = document.querySelector(selector) as BlNotification; +const addNotification = (options: NotificationProps) => { + const el = document.querySelector("bl-notification"); return el?.addNotification(options); }; +const stringifyArgs = (args: NotificationArgs | NotificationProps) => { + return JSON.stringify(args, null, 6); +}; + export type NotificationArgs = { noAnimation: boolean; duration: number; -}; +} & NotificationProps; export type Story = StoryObj; +const BasicTemplate = (args: NotificationArgs) => html` + +`; + +const NotificationCreator = (args: NotificationProps, buttonLabel = "Add Notification") => { + const slug = buttonLabel.toLowerCase().replace(/\s/g, "-"); + + return html` + ${buttonLabel} + + + `; +}; + export const AddExample: Story = { render(args: NotificationArgs) { - return html` - - Add Notification - - - `; + return html`${BasicTemplate(args)} ${NotificationCreator(args)} `; }, - play: () => { - addNotification("#basic", { - description: "Notification Description", - }); + args: { + duration: 60, + }, + play: ({ args }) => { + addNotification(args); }, }; export const RemoveExample: Story = { render(args: NotificationArgs) { return html` - - Remove Notification + ${BasicTemplate(args)} + Remove Notification `; }, - play: () => { - addNotification("#basic", { - caption: "Notification Caption", - description: "Notification Description", - permanent: true, - primaryAction: { - label: "Primary Action", - onClick: () => { - window.alert("Primary Action Clicked"); - }, - }, - secondaryAction: { - label: "Secondary Action", - onClick: () => { - window.alert("Secondary Action Clicked"); - }, - }, - }); +}; + +export const SecondaryActionExample: Story = { + render(args: NotificationArgs) { + return html` + ${BasicTemplate(args)} + + `; }, }; export const ActionsRemoveExample: Story = { render(args: NotificationArgs) { return html` - - Add Notification - + ${BasicTemplate(args)} `; }, play: () => { - addNotification("#basic", { + addNotification({ caption: "Notification Caption", description: "Notification Description", permanent: true, @@ -263,78 +300,107 @@ export const ActionsRemoveExample: Story = { export const PermanentExample: Story = { render(args: NotificationArgs) { - return html` - - Add Notification - - - `; + return html` ${BasicTemplate(args)} ${NotificationCreator(args)} `; }, - play: () => { - addNotification("#basic", { - caption: "Notification Caption", - description: "Notification Description", - permanent: true, - }); + args: { + permanent: true, + }, + play: ({ args }) => { + addNotification(args); }, }; export const VariantsExample: Story = { render(args: NotificationArgs) { return html` - - Add Notifications - - + ${BasicTemplate(args)} + ${NotificationCreator( + { + caption: "Notification Caption", + description: "Notification Variant: info", + permanent: true, + variant: "info", + primaryAction: { + label: "Primary Action", + onClick() {}, + }, + secondaryAction: { + label: "Secondary Action", + onClick() {}, + }, + }, + "Info" + )} + ${NotificationCreator( + { + caption: "Notification Caption", + description: "Notification Variant: success", + permanent: true, + variant: "success", + primaryAction: { + label: "Primary Action", + onClick() {}, + }, + secondaryAction: { + label: "Secondary Action", + onClick() {}, + }, + }, + "Success" + )} + ${NotificationCreator( + { + caption: "Notification Caption", + description: "Notification Variant: warning", + permanent: true, + variant: "warning", + primaryAction: { + label: "Primary Action", + onClick() {}, + }, + secondaryAction: { + label: "Secondary Action", + onClick() {}, + }, + }, + "Warning" + )} + ${NotificationCreator( + { + caption: "Notification Caption", + description: "Notification Variant: error", + permanent: true, + variant: "error", + primaryAction: { + label: "Primary Action", + onClick() {}, + }, + secondaryAction: { + label: "Secondary Action", + onClick() {}, + }, + }, + "Error" + )} `; }, play: () => { const variants = ["info", "success", "warning", "error"] as const; for (const variant of variants) { - addNotification("#basic", { - caption: variant, - description: variant, + addNotification({ + caption: "Notification Caption", + description: `Notification Variant: ${variant}`, permanent: true, variant, + primaryAction: { + label: "Primary Action", + onClick() {}, + }, + secondaryAction: { + label: "Secondary Action", + onClick() {}, + }, }); } }, diff --git a/src/components/notification/card/bl-notification-card.css b/src/components/notification/card/bl-notification-card.css index bed19c1d..454539c5 100644 --- a/src/components/notification/card/bl-notification-card.css +++ b/src/components/notification/card/bl-notification-card.css @@ -5,7 +5,7 @@ .notification { position: relative; border-radius: var(--bl-border-radius-m); - filter: drop-shadow(0 5px 30px rgb(39 49 66 / 25%)); + box-shadow: 0 5px 30px 0 rgba(39 49 66 / 25%); } .duration {