Question

How to create a curve on top of app bar when selected

I am creating one mobile appbar. I am trying to create a curve above when user selects it.i created another curve div. but that is separate div. so it hasn't worked out. I tried but I don't how to implement it. Can anyone help me with that. I need a curve above when the user clicked on the item

enter image description here

Here's the code:

import { AiFillBell } from "react-icons/ai";
import { GoHomeFill } from "react-icons/go";
import { IoMdSettings } from "react-icons/io";
import { FaUser } from "react-icons/fa";
import { useState } from "react";

export default function App() {
  const [selectedItem, setSelectedItem] = useState("home");

  const menuItems = [
    {
      name: "notification",
      icon: <AiFillBell style={{ height: "24px", width: "24px" }} />,
    },
    {
      name: "home",
      icon: <GoHomeFill style={{ height: "24px", width: "24px" }} />,
    },
    {
      name: "settings",
      icon: <IoMdSettings style={{ height: "24px", width: "24px" }} />,
    },
    {
      name: "user",
      icon: <FaUser style={{ height: "24px", width: "24px" }} />,
    },
  ];

  return (
    <div style={{ background: "black", height: "100vh", padding: "50px" }}>
      <div
        style={{
          background: "#0a0e18",
          height: "58px",
          borderRadius: "20px",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          padding: "0px 30px",
          border: "1px solid #2e3239",
        }}
      >
        {menuItems.map((item, index) => (
          <div
            key={index}
            onClick={() => setSelectedItem(item.name)}
            style={{
              opacity: selectedItem === item.name ? 1 : 0.2,
              cursor: "pointer",
              color: "#fff",
            }}
          >
            {item.icon}
          </div>
        ))}
      </div>
    </div>
  );
}
 2  66  2
1 Jan 1970

Solution

 1

You can use this trick

const indicator = document.querySelector('.indicator');
const items = document.querySelectorAll('li');

items.forEach(item => {
    item.addEventListener('click', e => {
        indicator.style.left = `${item.offsetLeft}px`;
        indicator.style.width = `${item.offsetWidth}px`;
        
        // remove active class from all items
        items.forEach(item => {
            item.classList.remove('active');
        });
        
        // add active class to clicked item
        item.classList.add('active');
    });
});
* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

body {
    display: grid;
    place-items: center;
    height: 100vh;
    background: black;
}

.navigation-bar {
    position: relative;
    width: 300px;
    height: 65px;
    background: #0a0e18;
    border-radius: 5px;
    padding: 5px 15px;
    /* use drop-shadow to add border */
    filter: drop-shadow(1px 0 0 #2e3239)
            drop-shadow(-1px 0 0 #2e3239)
            drop-shadow(0 1px 0 #2e3239)
            drop-shadow(0 -1px 0 #2e3239);
}

ul {
    display: flex;
    justify-content: space-between;
    list-style: none;
    height: 100%;
}

li {
    width: 50px;
    height: 50px;
    display: grid;
    place-items: center;
    cursor: pointer;
    position: relative;
    border-radius: 50%;
    z-index: 2;
    transition: 0.5s;
    color: white;
}


li.active {
    background: red;
}

.indicator {
    position: absolute;
    top: -15px;
    left: 15px;
    width: 50px;
    height: 50px;
    background-color: #0a0e18;
    border-radius: 50%;
    transition: 0.5s;
    z-index: 1;
}


.indicator::before {
    content: '';
    position: absolute;
    top: -7px;
    left: -15px;
    width: 22px;
    height: 22px;
    background-color: transparent;
    /* Remove the comment to see how it works well */
    /* background-color: green; */
    border-radius: 50%;
    box-shadow: 7px 17px #0a0e18;
}

.indicator::after {
    content: '';
    position: absolute;
    top: -7px;
    right: -15px;
    width: 22px;
    height: 22px;
    background-color: transparent;
    /* Remove the comment to see how it works well */
    /* background-color: green; */
    border-radius: 50%;
    box-shadow: -7px 17px #0a0e18;
}
<div class="navigation-bar">
    <ul>
      <li class="active">1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <div class="indicator"></div>
    </ul>
</div>

2024-07-23
Youcef Hammadi