Skip to content

Commit 11a5e9a

Browse files
committed
enhance(UserNotification): add possibility to make user notification dismissible
1 parent e61915b commit 11a5e9a

3 files changed

Lines changed: 64 additions & 3 deletions

File tree

packages/design-system/src/UserNotification.stories.mdx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import UserNotification from './UserNotification'
2+
import { useState } from 'react'
23

34
{/* START README */}
45
<div className="prose prose-sm max-w-none">
@@ -22,6 +23,9 @@ The UserNotification component accepts the following props:
2223
- @param type - The type of the notification. This can be either 'success', 'info' or 'error'. This determines the icon that is displayed and some conditional styling. If not type is provided, the information icon is displayed.
2324
- @param children - The optional children are displayed in the notification in addition to the provided message icon.
2425
- @param className - The optional className object allows you to override the default styling.
26+
- @param dismissible - If true, shows an X button in the top-right.
27+
- @param hidden - If true, hides the notification (useful with dismissible).
28+
- @param onDismiss - Callback when the X button is clicked.
2529
</div>
2630
{/* END README */}
2731

@@ -210,6 +214,26 @@ export const Default = () => {
210214
)
211215
}
212216

217+
export const Dismissible = () => {
218+
const [hidden, setHidden] = useState(false)
219+
220+
return (
221+
<div>
222+
<UserNotification
223+
dismissible
224+
hidden={hidden}
225+
onDismiss={() => setHidden(true)}
226+
message="This is the default notif style when the provided type is not 'success', 'error', or 'info'"
227+
/>
228+
{hidden && (
229+
<button onClick={() => setHidden(false)}>
230+
Show notification again
231+
</button>
232+
)}
233+
</div>
234+
)
235+
}
236+
213237
export const Success = () => {
214238
return (
215239
<UserNotification

packages/design-system/src/UserNotification.tsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
faCircleInfo,
44
faCircleXmark,
55
faTriangleExclamation,
6+
faXmark,
67
IconDefinition,
78
} from '@fortawesome/free-solid-svg-icons'
89
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
@@ -17,10 +18,14 @@ export interface UserNotificationProps {
1718
}
1819
message?: string
1920
type?: 'default' | 'info' | 'success' | 'warning' | 'error'
21+
dismissible?: boolean
22+
hidden?: boolean
23+
onDismiss?: () => void
2024
children?: React.ReactNode
2125
className?: {
2226
root?: string
2327
icon?: string
28+
closeIcon?: string
2429
message?: string
2530
content?: string
2631
}
@@ -42,6 +47,9 @@ export interface UserNotificationChildrenProps extends UserNotificationProps {
4247
* @param data - The object of data attributes that can be used for testing (e.g. data-test or data-cy)
4348
* @param message - The message that is displayed in the notification.
4449
* @param type - The type of the notification. This can be either 'success', 'info' or 'error'. This determines the icon that is displayed and some conditional styling. If not type is provided, the information icon is displayed.
50+
* @param dismissible - If true, a close button is displayed in the top right corner of the notification. When clicked, the onDismiss function is called.
51+
* @param hidden - If true, the notification is hidden. This can be used in combination with the dismissible prop to hide the notification when the close button is clicked.
52+
* @param onDismiss - The function that is called when the close button is clicked. This prop is required if the dismissible prop is set to true.
4553
* @param children - The optional children are displayed in the notification in addition to the provided message icon.
4654
* @param className - The optional className object allows you to override the default styling.
4755
* @returns UserNotification component
@@ -51,12 +59,19 @@ export function UserNotification({
5159
data,
5260
message,
5361
type = 'default',
62+
dismissible = false,
63+
hidden = false,
64+
onDismiss,
5465
children,
5566
className,
5667
}: UserNotificationMessageProps | UserNotificationChildrenProps) {
5768
let notifIcon: IconDefinition
5869
let computedClassName: string
5970

71+
if (hidden) {
72+
return null
73+
}
74+
6075
switch (type) {
6176
case 'warning':
6277
computedClassName = 'text-uzh-red-100 bg-uzh-red-20'
@@ -85,11 +100,26 @@ export function UserNotification({
85100
data-cy={data?.cy}
86101
data-test={data?.test}
87102
className={twMerge(
88-
'flex flex-row gap-2 rounded-md p-2 text-sm',
103+
'relative flex flex-row gap-2 rounded-md p-2 text-sm',
89104
className?.root,
90-
computedClassName!
105+
computedClassName!,
106+
dismissible && 'pr-8'
91107
)}
92108
>
109+
{dismissible && (
110+
<button
111+
type="button"
112+
aria-label="Dismiss notification"
113+
title="Dismiss"
114+
onClick={onDismiss}
115+
className={twMerge(
116+
'focus:ring-uzh-blue-100 absolute top-2 right-2 inline-flex h-5 w-5 items-center justify-center rounded text-base hover:opacity-80 focus:ring-2 focus:ring-offset-2 focus:outline-none',
117+
className?.closeIcon
118+
)}
119+
>
120+
<FontAwesomeIcon icon={faXmark} className="h-4 w-4" />
121+
</button>
122+
)}
93123
<span>
94124
<FontAwesomeIcon icon={notifIcon!} className={className?.icon} />
95125
</span>

packages/design-system/types/index.d.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3173,11 +3173,14 @@ export declare const useFormField: () => {
31733173
* @param data - The object of data attributes that can be used for testing (e.g. data-test or data-cy)
31743174
* @param message - The message that is displayed in the notification.
31753175
* @param type - The type of the notification. This can be either 'success', 'info' or 'error'. This determines the icon that is displayed and some conditional styling. If not type is provided, the information icon is displayed.
3176+
* @param dismissible - If true, a close button is displayed in the top right corner of the notification. When clicked, the onDismiss function is called.
3177+
* @param hidden - If true, the notification is hidden. This can be used in combination with the dismissible prop to hide the notification when the close button is clicked.
3178+
* @param onDismiss - The function that is called when the close button is clicked. This prop is required if the dismissible prop is set to true.
31763179
* @param children - The optional children are displayed in the notification in addition to the provided message icon.
31773180
* @param className - The optional className object allows you to override the default styling.
31783181
* @returns UserNotification component
31793182
*/
3180-
export declare function UserNotification({ id, data, message, type, children, className, }: UserNotificationMessageProps | UserNotificationChildrenProps): JSX.Element;
3183+
export declare function UserNotification({ id, data, message, type, dismissible, hidden, onDismiss, children, className, }: UserNotificationMessageProps | UserNotificationChildrenProps): JSX.Element | null;
31813184

31823185
export declare interface UserNotificationChildrenProps extends UserNotificationProps {
31833186
message?: never;
@@ -3197,10 +3200,14 @@ export declare interface UserNotificationProps {
31973200
};
31983201
message?: string;
31993202
type?: 'default' | 'info' | 'success' | 'warning' | 'error';
3203+
dismissible?: boolean;
3204+
hidden?: boolean;
3205+
onDismiss?: () => void;
32003206
children?: default_3.ReactNode;
32013207
className?: {
32023208
root?: string;
32033209
icon?: string;
3210+
closeIcon?: string;
32043211
message?: string;
32053212
content?: string;
32063213
};

0 commit comments

Comments
 (0)