[자주 쓰는 컴포넌트]-드롭다운

wkawhaRo·2024년 4월 18일
0

서론

여러 프로젝트를 하면서, 다양한 컴포넌트를 만들었는데 거의 대부분 부트스트랩이나 다른 라이브러리를 사용했던거 같다. 자주 사용하면서, 간단한 컴포넌트는 직접 구현해보고 싶어 하나씩 만들어보고자 한다.

드롭다운 메뉴

간간히 메뉴 선택에 있어 자주 사용되는 컴포넌트이기도 하고, 금방 만들 수 있을 것 같았다.
메뉴 선택란이 있고 하단 버튼을 클릭하면 하위 메뉴들이 보이는 식으로 구성된다.
만들기 전에 다른 블로그를 둘러 보았는데, 하단 버튼 클릭 시 하위 메뉴가 보여지는 데 에니메이션을 적용한 사례가 없어서, 필자는 간단하게 적용한 버전을 만들어 보았다.

html

<div style="margin: 100px auto; width: 200px">
            <div class="selector">
                <span class="choice">Select Menu</span>
                <svg
                    class="btn"
                    xmlns="http://www.w3.org/2000/svg"
                    id="Outline"
                    viewBox="0 0 24 24"
                    width="20"
                    height="20"
                >
                    <path
                        d="M18.71,8.21a1,1,0,0,0-1.42,0l-4.58,4.58a1,1,0,0,1-1.42,0L6.71,8.21a1,1,0,0,0-1.42,0,1,1,0,0,0,0,1.41l4.59,4.59a3,3,0,0,0,4.24,0l4.59-4.59A1,1,0,0,0,18.71,8.21Z"
                    />
                </svg>
            </div>
            <div class="options">
                <div class="content">item 1</div>
                <div class="content">item 2</div>
                <div class="content">item 3</div>
                <div class="content">item 4</div>
            </div>
        </div>

css

.selector {
    width: 200px;
    padding: 10px;
    display: flex;
    justify-content: space-between;
    border: 1px solid black;
    border-radius: 5px;
}

.options {
    width: 220px;
    display: flex;
    flex-direction: column;
    margin-top: 5px;

    border: 1px solid black;
    border-radius: 5px;

    visibility: hidden;
    opacity: 0;
    transform: translateY(-5%);
    transition: opacity 0.1s ease, transform 0.1s ease, linear 0.1s;
}

.content {
    display: flex;
    height: 45px;
    align-items: center;
    justify-content: center;
}
.content:hover {
    background-color: lightgray;
}

.options.expended {
    width: 220px;
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
    transition-delay: 0s;
}

js

window.onload = () => {
    const button = document.querySelector(".btn");
    const options = document.querySelector(".options");
    const choiceItem = document.querySelector(".choice");

    button.addEventListener("click", () => {
        console.log("click");
        options.classList.toggle("expended");
        showMenu();
    });

    const showMenu = () => {
        const items = document.querySelectorAll(".content");
        items.forEach((item) => {
            item.addEventListener("click", () => itemClick(item));
        });
    };

    const itemClick = (item) => {
        choiceItem.textContent = item.textContent;
        options.classList.remove("expended");
    };
};

결과

profile
1일 1백준을 목표로

0개의 댓글

관련 채용 정보