드랍다운 디자인 하기

jonyChoiGenius·2023년 2월 11일
0

드랍다운 태그 디자인하기

드랍다운은 디자인하기가 까다롭다.
리액트 스테이트를 이용해 드랍다운을 디자인했다.
useRef를 이용해서 바깥을 클릭하면 드랍다운 창이 꺼진다.

import React, { useEffect, useRef, useState } from 'react';
import { TiArrowSortedDown } from 'react-icons/ti';
import styled from 'styled-components';

const VideoFilterDropdown = ({ scrollProp, setScrollProp }) => {
  const [Dropped, setDropped] = useState(false);
  const [selected, setSelected] = useState('');
  const categoryArray = ['전체', '목', '허리', '전신'];

  useEffect(() => {
    if (typeof selected !== 'number') return;
    setScrollProp({ ...scrollProp, category: selected, page: 0 });
  }, [selected]);

  const ref = useRef();
  const handleClickOutSide = (e) => {
    if (Dropped && !ref.current.contains(e.target)) {
      setDropped(false);
    }
  };

  useEffect(() => {
    if (Dropped) document.addEventListener('mousedown', handleClickOutSide);
    return () => {
      document.removeEventListener('mousedown', handleClickOutSide);
    };
  });

  return (
    <DropdownWrapper ref={ref}>
      <Selected
        onClick={() => {
          setDropped(!Dropped);
        }}
      >
        {typeof selected === 'number' ? categoryArray[selected] : '카테고리'}
        <span
          style={
            Dropped ? { transform: 'translateY(-50%) rotate(180deg)' } : {}
          }
        >
          <TiArrowSortedDown />
        </span>
      </Selected>
      <DropDownlist style={Dropped ? {} : { visibility: 'hidden' }}>
        {categoryArray.map((e, idx) => {
          return (
            <ListItem
              key={e}
              onClick={() => {
                setSelected(idx);
                setDropped(false);
              }}
            >
              {e}
            </ListItem>
          );
        })}
      </DropDownlist>
    </DropdownWrapper>
  );
};

export default VideoFilterDropdown;

const DropdownWrapper = styled.div`
  margin-left: 0.1rem;
  margin-right: 0.5rem;
  width: 6rem;
`;

const Selected = styled.div`
  text-align: center;
  background-color: ${(props) => props.theme.color.secondary};
  color: ${(props) => props.theme.color.primary};
  font-weight: bold;
  padding: 0.3rem;
  border-radius: 0.5rem;
  border: 0.1rem solid ${(props) => props.theme.color.primary};
  box-shadow: 0 0.1rem 0.5rem ${(props) => props.theme.color.lightGrayColor};
  cursor: pointer;
  span {
    position: absolute;
    display: flex;
    top: 8.2rem;
    left: 4.9rem;
    font-size: 0.9rem;
    align-items: center;
    transform: translateY(-50%);
    width: 1rem;
    opacity: 0.7;
    transition: 0.2s ease;
  }
`;

const DropDownlist = styled.div`
  width: 6rem;
  position: absolute;
  z-index: 2;
`;

const ListItem = styled.div`
  text-align: center;
  background-color: ${(props) => props.theme.color.whiteColor};
  cursor: pointer;
  color: ${(props) => props.theme.color.primary};
  font-weight: bold;
  padding: 0.3rem;
  border-radius: 0.5rem;
  border: 0.1rem solid ${(props) => props.theme.color.primary};
  box-shadow: 0 0.1rem 0.5rem ${(props) => props.theme.color.lightGrayColor};
  &:hover {
    background-color: ${(props) => props.theme.color.secondary};
  }
`;

엔터 키를 누르면 요청이 가도록

onKeyDown 이벤트를 이용해 일반 인풋 태그에서 엔터를 누르면 요청이 가도록 했다.
Form 태그를 이용하는 것이 가장 좋지만, 미처 form 태그를 적용하지 못한 경우에 사용하면 좋다.

onKeyDown, onKeyUp은 Keycode값이고, onKeyPress는 ASCII 값이다 출처

onKeyPress는 deprecated 되었다.

return (
            <InputWrapper>
              <StyledInput
                autoFocus
                id="nickname-input"
                value={nicknameInput}
                onChange={(e) => setNicknameInput(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === 'Enter') onSubmit();
                }}
              />
            </InputWrapper>
)

const InputWrapper = styled.div`
  font-size: 1.2rem;
  font-weight: bold;
  color: ${(props) => props.theme.color.primary};
`;

const StyledInput = styled.input`
  text-align: right;
`;
profile
천재가 되어버린 박제를 아시오?

0개의 댓글