파크로그

headlessUI with styled-components

어제 올린 글 에서 headlessUI 로 로직을 분리한다면, 스타일은 어떻게 접목시킬지에 대해 고민을 했었다.

이리저리 삽질을 해보았는데, 해결책은 Styled-components 공식문서에서 찾았다. 

 

import { createContext, useContext, useState } from "react";

const DropdownContext = createContext();

function DropDown(props) {
  const openState = useState(false);
  return (
    <DropdownContext.Provider value={openState}>
      {props.children}
    </DropdownContext.Provider>
  );
}

function useDropdownContext() {
  const context = useContext(DropdownContext);
  return context;
}

function DropDownTrigger(props) {
  const [, setOpen] = useDropdownContext();
  const handleTrigger = () => {
    setOpen((prev) => !prev);
  };
  return (
    <button {...props} onClick={handleTrigger}>
      Trigger!
    </button>
  );
}

function DropDownList(props) {
  const [open] = useDropdownContext();
  return open ? <ul>{props.children}</ul> : null;
}

function DropDownItem() {
  return <li>hi</li>;
}

DropDown.Trigger = DropDownTrigger;
DropDown.List = DropDownList;
DropDown.Item = DropDownItem;

export default DropDown;
import DropDown from "./Dropdown";
import "./styles.css";
import styled from "styled-components";

const MyTrigger = styled(DropDown.Trigger)`
  width: 150px;
  height: 100px;
  background-color: red;
`;

export default function App() {
  return (
    <div className="App">
      <h1>Title</h1>
      <DropDown>
        <MyTrigger />
        <DropDown.List>
          <DropDown.Item />
          <DropDown.Item />
          <DropDown.Item />
        </DropDown.List>
      </DropDown>
    </div>
  );
}

뭔가 간단히 Dropdown 처럼 느껴질만한 컴포넌트를 만들고, Trigger 버튼을 누르면 DropDown 의 List 가 보여지도록 하길 원했다.

그리고 Dropdown 에는 별도의 styled 가 적용되지 않는다.

스타일링을 위한 방법으로 styled 를 third-party component 와 결합하는 방법으로 className 을 주어 사용하도록 했다. styled 를 함수형태로 사용하여 스타일링을 하고자하는 컴포넌트(DropDown.Trigger)를 인수로 주고, DropDown.Trigger 컴포넌트는 props 로 받는 className 을 스타일을 입히는 태그에 className 을 주면 된다.  

 

Compound Component Pattern 을 활용한 Headless 를 사용해보았는데, 실제 사용하고자 하는 컴포넌트에서 사용자가 의도대로 컴포넌트를 사용할지에 대한 우려가 있다.

profile

파크로그

@파크park

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!