<div class="container"></div>
console.clear();

//ES6 const, let
//ES6 Destructuring 
 
const { Component, useEffect, useCallback, useState, useSyncExternalStore, memo, useRef } = React;
const { css } = styled

  const CIRCLE_GAP = 8
  const CIRCLE_RADIUS = 10
  const PADDING_Y = 17.5
  const BORDER_WIDTH = 1.5
  const MenuStyleBorder = styled.div`
    position: relative;
    width: 50%;
  height: 50px;
    border: ${BORDER_WIDTH}px solid orange;
    border-radius: 7px;
  padding: 25px;
  `

  const CircleCSS = css`
    width: ${CIRCLE_RADIUS * 2}px;
    height: ${CIRCLE_RADIUS}px;
    border-bottom-left-radius: ${CIRCLE_RADIUS}px;
    border-bottom-right-radius: ${CIRCLE_RADIUS}px;
    border: ${BORDER_WIDTH}px solid orange;
    border-top: ${BORDER_WIDTH}px solid #fff;
    box-sizing: border-box;
    background: #fff;
  `

  const HalfCircle = styled.div`
    ${CircleCSS}
  
    position: absolute;
    bottom: 0px;
  border-top: 2px solid white;
  `

  const TopCircleWrapper = styled.div`
    position: absolute;
    top: 8px;
    left: 0px;
  `

  const CircleWrapper = styled.div`
    position: relative;
    display: flex;
    padding: 0 ${PADDING_Y}px;
  `

  const DynamicHalfCircle = ({ parentRef }) => {
    const circleData = useSyncExternalStore(
      (callback) => {
        window.addEventListener('resize', callback)
        return () => window.removeEventListener('resize', callback)
      },
      () => {
        const { width } = parentRef.current?.getBoundingClientRect() || { width: 0 }
        const count = Math.ceil((width - 7 * 2 - PADDING_Y - CIRCLE_GAP) / (CIRCLE_RADIUS * 2 + CIRCLE_GAP))
        const initLeft = Math.max((width - count * CIRCLE_RADIUS * 2 - (count - 1) * CIRCLE_GAP) / 2, 0)
        return JSON.stringify({
          count: Math.max(count, 0),
          width,
          initLeft,
        })
      },
      () =>
        JSON.stringify({
          count: 0,
          width: 0,
          initLeft: 0,
        }),
    )

    const circleInfo = JSON.parse(circleData || '{}')

    return (
      <CircleWrapper>
        {Array.from({ length: circleInfo?.count || 0 }, (_, i) => i).map((i) => (
          <HalfCircle key={i} style={{ left: (CIRCLE_GAP + CIRCLE_RADIUS * 2) * i + (circleInfo.initLeft ?? 0) }} />
        ))}
      </CircleWrapper>
  )
}

  const MenuCard = memo(
    ({ className, children }) => {
      const MenuElemRef = useRef()
      return (
          <MenuStyleBorder ref={MenuElemRef}>
              <TopCircleWrapper>
                <DynamicHalfCircle parentRef={MenuElemRef} />
              </TopCircleWrapper>
            {children}
          </MenuStyleBorder>
      )
    },
  )
 const  App = () => {
  
  return <MenuCard> Menu </MenuCard>;
}


ReactDOM.render(<App />, document.querySelector(".container"));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/styled-components/6.1.6/styled-components.min.js