๐Ÿ’ง Tailwind CSS+Reactใ‚’ไฝฟใฃใŸ้ ˜ๅŸŸๅค–ใ‚ฏใƒชใƒƒใ‚ฏใง้–‰ใ˜ใ‚‹ใƒ‰ใƒญใƒƒใƒ—ใƒ€ใ‚ฆใƒณใƒกใƒ‹ใƒฅใƒผ

2020-11-07 #Development

CSS Only ใฎใƒ•ใƒฌใƒผใƒ ใƒฏใƒผใ‚ฏใ‚’ไฝฟใ†ๆ™‚ใ‚‚ใƒ‰ใƒญใƒƒใƒ—ใƒ€ใ‚ฆใƒณใƒกใƒ‹ใƒฅใƒผใ‚’ไฝœใ‚‹ๅ ดๅˆใซใฏ้ ˜ๅŸŸๅค–ใ‚’ใ‚ฏใƒชใƒƒใ‚ฏใ—ใŸใ‚‰้–‰ใ˜ใ‚‹ๆฉŸ่ƒฝใ‚’ๅ…ฅใ‚ŒใฆใŠใใŸใ„ใฎใงใ™ใŒใ€ๆฐ—ใ‚’ๆŠœใ„ใŸใ‚‰ๆจช็€ใ—ใใ†ใชใฎใง็ฐกๅ˜ใซๅฎŸ่ฃ…ใงใใ‚‹ใ‚ˆใ†ใซใ‚„ใ‚Šๆ–นใ‚’ใƒกใƒขใ€‚

ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆๅด

  • useEffectใงใƒชใ‚นใƒŠใƒผใ‚’ใคใ‘ใŸใ‚Šๅค–ใ—ใŸใ‚Šใ™ใ‚‹
  • ใƒžใ‚ฆใ‚นใƒ€ใ‚ฆใƒณใ—ใŸๆ™‚ใซuseRefใ‚’ไฝฟใฃใฆ้ ˜ๅŸŸๅ†…ใ‹ใฉใ†ใ‹ใ‚’ๅˆคๅฎš
  • useStateใ‚’ไฝฟใฃใฆ็Šถๆ…‹ใ‚’ๅˆ‡ใ‚Šๆ›ฟใˆใ‚‹
import React, { useRef, useState, useEffect } from "react";

const Dropdown = (props) => {
  const [isOpen, setIsOpen] = useState(false);
  const dropdownRef = useRef();

  useEffect(() => {
    document.addEventListener("mousedown", handleOutsideClick);
    return () => {
      document.removeEventListener("mousedown", handleOutsideClick);
    };
  }, []);

  const handleOutsideClick = (e) => {
    if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
      setIsOpen(false);
    }
  };

  return (
    <>
      <div ref={dropdownRef} className="relative inline-block text-left">
        <span className="rounded-md shadow-sm">
          <button onClick={() => setIsOpen(!isOpen)} type="button" className="inline-flex justify-center w-full rounded-md border border-gray-300 px-4 py-2 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150" id="options-menu" aria-haspopup="true" aria-expanded={isOpen}>
            {props.title}
            <svg className="-mr-1 ml-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
              <path fillRule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clipRule="evenodd" />
            </svg>
          </button>
        </span>

        {isOpen && (
          <>
            <div className="origin-top-left absolute left-0 mt-2 w-56 rounded-md shadow-lg z-50">
              <div className="rounded-md bg-white shadow-xs">
                <div className="py-1" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
                  {props.children}
                </div>
              </div>
            </div>
          </>
        )}
      </div>
    </>
  );
};

export default Dropdown;

ไฝฟใ†ๅด

  • ใƒ‰ใƒญใƒƒใƒ—ใƒ€ใ‚ฆใƒณใฎไธญ่บซใฏ props.children ใงๅค–ใ‹ใ‚‰ๆธกใ™
<Dropdown label="Options">
  <a href="#" className="block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900" role="menuitem">
    Item0
  </a>
  <a href="#" className="block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900" role="menuitem">
    Item1
  </a>
  <a href="#" className="block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900" role="menuitem">
    Item2
  </a>
</Dropdown>

React ใฏใพใ ๆ…ฃใ‚Œใชใ„ใ‚“ใ ใ‘ใฉ Vue ใจ้•ใฃใฆ children ใฎไธญ่บซใ‚’ใƒœใ‚ฟใƒณใฎใจใ“ใจใ‚ณใƒณใƒ†ใƒณใƒ„ใฎใจใ“ใ‚ใ‚’ๅˆ†ใ‘ใฆๆธกใ™ใ‚ˆใ†ใชไบ‹ใฏใงใใชใ„ใฎใ‹ใช๏ผŸ๏ผˆVue ใ ใจslot:labelใจslot:contentใฟใŸใ„ใชใ‚ฟใ‚ฐใ‚’ใคใ‘ใฆๆธกใ™ไบ‹ใŒใงใใ‚‹๏ผ‰

ใƒœใ‚ฟใƒณใฎใƒฉใƒ™ใƒซใฎ้ƒจๅˆ†ใ‚’ใ‚ขใ‚คใ‚ณใƒณใซใ—ใŸใ„ๆ™‚ใ‚‚ใ‚ใ‚‹ใฎใงใงใใ‚Œใฐใƒฉใƒ™ใƒซ้ƒจๅˆ†ใ‚‚ html ใ‚ฟใ‚ฐใ”ใจใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎๅค–ใ‹ใ‚‰ๆธกใ—ใŸใ„ใ‘ใฉใ€ใใฎๆ™‚ใฏใพใŸไธ€ๆ‰‹้–“ใ‹ใ‹ใ‚Šใใ†ใ€‚

ๆ‰€ๆ„Ÿ

Tailwind CSS ใ‚’ๅˆใ‚ใฆไฝฟใฃใฆใฟใŸใ‚“ใ ใ‘ใฉใจใฆใ‚‚ใ‚ˆใ•ใใ†ใงใ™ใญใ€‚ tailwind.config.js ใซใกใ‚‡ใ‚ใฃใจ่จ˜่ฟฐใ‚’ๅ…ฅใ‚Œใ‚‹ใ ใ‘ใง purgeCSS ใŒไฝฟใˆใ‚‹ใจใ“ใ‚ใ‚‚็ด ๆ•ตใ€‚

CSS ใƒ•ใƒฌใƒผใƒ ใƒฏใƒผใ‚ฏใ€ใ„ใใคใ‹ไฝฟใฃใฆใฟใŸ็ตๆžœใ‚„ใฃใฑใ‚Š Bootstrap ใŒ่‰ฏใ„ใจๆ€ใฃใฆใ„ใŸใ‚“ใ ใ‘ใฉใ€Tailwind CSS ใฏไปฒ่‰ฏใใ‚„ใฃใฆใ„ใ‘ใใ†ใงใ™ใ€‚

ใ—ใ‹ใ—ใ“ใ“ใพใงใ‚นใ‚ฟใ‚คใƒซใ‚’ html ใซๆ›ธใใพใใ‚‹ใฎใ ใฃใŸใ‚‰ใ„ใฃใ Vanilla CSS ใ‚’ใ‚ฟใ‚ฐใซ็›ดๆ›ธใใ™ใ‚‹ใฎใจๅค‰ใ‚ใ‚‰ใชใ„ใฎใงใฏใจๆ€ใฃใŸใ‘ใฉใ€ใใ†ใ‹ใ€ใ‚ณใƒผใƒ‰้‡ใŒๆธ›ใ‚‹ใƒกใƒชใƒƒใƒˆใŒใ‚ใฃใŸใ‚Šใ™ใ‚‹ใฎใ‹ใชใ€‚ใ ใจใ—ใŸใ‚‰ CSS ใฏๆ™ฎ้€šใซ่‡ชๅˆ†ใงๆ›ธใ„ใŸๆ–นใŒไฝ™ๅˆ†ใชใ‚ฟใ‚ฐใ‚‚ๆธ›ใฃใฆ็ถบ้บ—ใงใ‚ทใƒณใƒ—ใƒซใซๆ›ธใ‘ใ‚‹ใ‚ˆใชใจใ‚‚ๆ€ใ„ใคใคใ€ใ„ใ‚„ใ—ใ‹ใ— CSS ใซไธ€ๅˆ‡่งฆใ‚Œใšใซ้–‹็™บใ‚’้€ฒใ‚ใ‚‰ใ‚Œใ‚‹ใฎใฏใƒ—ใƒญใƒˆใ‚ฟใ‚คใƒ—ใฎๆฎต้šŽใงใฏ้‡่ฆใ ใ‚ˆใชใจๆ€ใ†ใ—ใ€ใชใ‹ใชใ‹็ญ”ใˆใŒๅ‡บใฆใใพใ›ใ‚“…

comments powered by Disqus
Profile
๐Ÿ˜›

็ŸณๅŽŸใ€€ๆ‚  / Yu Ishihara

ใƒ‡ใ‚ถใ‚คใƒณใจใƒ—ใƒญใ‚ฐใƒฉใƒŸใƒณใ‚ฐใจใƒจใƒผใ‚ฐใƒซใƒˆไฝœใ‚ŠใŒๅฅฝใใงใ™ใ€‚