Notification Bell

Implement a bell icon that shows a red notification badge; clicking on the bell shows a dropdown with messages.

Solution

Explanation

Bell Icon and Notification Badge

The bell icon serves as a visual indicator that users can click to check their messages. The red badge is only displayed when there are unread notifications. This is controlled by the isViewed state, and the state toggles to remove the badge once the button is clicked.

Accessibility

Accessibility is improved with the use of the aria-label attribute, which provides a descriptive label for screen readers. This allows users with disabilities to understand what the bell icon is for.

State Management

The component uses the useState hook to track whether the notifications have been viewed. The state isViewed is initially set to falseand changes to true once the bell is clicked, which reveals the message dropdown and hides the notification badge.

Dropdown for Messages

When the bell icon is clicked, the message dropdown is rendered using an unordered list. Each message from the messages array is displayed inside a styled list item. This provides users with a simple and clear way to see their notifications.

CSS Styling

The bell icon is styled to be an appropriate size and position, with the red badge being placed in the top-right corner by using position absolute. The badge is styled with a red background and is shaped like a circle. The dropdown messages are styled with borders and padding for readability and visual distinction.

Code

import { useState } from "react";
import styles from "./Solution.module.css";
const messages = ["Message one", "Message two"];

const Solution = () => {
  const [isViewed, setIsViewed] = useState(false);

  return (
    <>
      <button
        onClick={() => setIsViewed(true)}
        aria-label="click for notifications"
        className={styles.bell}
      >
        🔔{!isViewed && <span className={styles.badge}></span>}
      </button>
      {isViewed && (
        <ul>
          {messages.map((msg, index) => (
            <li className={styles.msg} key={index}>
              {msg}
            </li>
          ))}
        </ul>
      )}
    </>
  );
};

export default Solution;

Styling

.bell {
  border: none;
  background-color: transparent;
  font-size: 30px;
  position: relative;
  width: max-content;
  padding: 5px;
  cursor: pointer;
}

.badge {
  position: absolute;
  top: 0;
  right: 0;
  display: block;
  background-color: red;
  height: 20px;
  width: 20px;
  border-radius: 100%;
}

.msg {
  padding: 5px;
  border: 2px solid black;
  margin: 5px 0;
  background-color: white;
}

Links