āļ§ัāļ™āđ€āļŠāļēāļĢ์āļ—ี่ 29 āļĄีāļ™āļēāļ„āļĄ āļž.āļĻ. 2568

🚀 āļāļēāļĢāđƒāļŠ้ Headless UI āļัāļš Next.js: āļĒืāļ”āļŦāļĒุ่āļ™āļāļ§่āļē āļŠāļ§āļĒāļāļ§่āļē āđƒāļŠ้āļ‡āļēāļ™āļ‡่āļēāļĒ!

āļ­āļĒāļēāļāđ„āļ”้ UI āļŠāļ§āļĒāđ† āđāļ•่āđ„āļĄ่āļ­āļĒāļēāļāļ•ิāļ”āļ”ีāđ„āļ‹āļ™์āđ€āļ”ิāļĄāđ† āđƒāļŠ่āđ„āļŦāļĄ? ðŸĪ”
Headless UI āļ„ืāļ­āļ—āļēāļ‡āļ­āļ­āļ! āļĄัāļ™āđ€āļ›็āļ™āļŠุāļ”āļ„āļ­āļĄāđ‚āļžāđ€āļ™āļ™āļ•์āļ—ี่ āđ„āļĄ่āļĄีāļŠāđ„āļ•āļĨ์āļ•āļēāļĒāļ•ัāļ§ āđƒāļŦ้āļ„ุāļ“āļ­āļ­āļāđāļšāļšāđ€āļ­āļ‡āđ„āļ”้āđ€āļ•็āļĄāļ—ี่

āđƒāļ™āļšāļ—āļ„āļ§āļēāļĄāļ™ี้ āđ€āļĢāļēāļˆāļ°āļĄāļēāļ”ูāļ§่āļē Headless UI āļ„ืāļ­āļ­āļ°āđ„āļĢ āļ—āļģāđ„āļĄāļ–ึāļ‡āđ€āļŦāļĄāļēāļ°āļัāļš Next.js āđāļĨāļ°āļĄีāļ§ิāļ˜ีāđƒāļŠ้āļ‡āļēāļ™āļĒัāļ‡āđ„āļ‡āļš้āļēāļ‡ āļžāļĢ้āļ­āļĄāļ•ัāļ§āļ­āļĒ่āļēāļ‡āđ‚āļ„้āļ”āļ—ี่āđƒāļŠ้āđ„āļ”้āļˆāļĢิāļ‡! ðŸŽŊ

🎭 Headless UI āļ„ืāļ­āļ­āļ°āđ„āļĢ?

Headless UI āđ€āļ›็āļ™āļŠุāļ”āļ‚āļ­āļ‡ UI Components āļ—ี่āļžัāļ’āļ™āļēāđ‚āļ”āļĒāļ—ีāļĄ Tailwind CSS āļ‹ึ่āļ‡āđ€āļ™้āļ™āđƒāļŦ้ āļ„āļ§āļēāļĄāļĒืāļ”āļŦāļĒุ่āļ™ āđāļĨāļ° āļ›āļĢัāļšāđāļ•่āļ‡āļŠāđ„āļ•āļĨ์āđ€āļ­āļ‡āđ„āļ”้

ðŸ”đ āļ‚้āļ­āđāļ•āļāļ•่āļēāļ‡āļˆāļēāļ UI Library āļ—ั่āļ§āđ„āļ›

Headless UI UI Library āļ—ั่āļ§āđ„āļ› (āđ€āļŠ่āļ™ MUI, Ant Design)
āļ”ีāđ„āļ‹āļ™์ āđ„āļĄ่āļĄีāļ”ีāđ„āļ‹āļ™์āļšัāļ‡āļ„ัāļš āļ›āļĢัāļšāđāļ•่āļ‡āđ€āļ­āļ‡ āļĄีāļ”ีāđ„āļ‹āļ™์āļ•āļēāļĒāļ•ัāļ§ āļ•้āļ­āļ‡āđƒāļŠ้āļ•āļēāļĄāļ—ี่ Library āļāļģāļŦāļ™āļ”
āļ„āļ§āļēāļĄāļĒืāļ”āļŦāļĒุ่āļ™ āđƒāļŠ้āļัāļš Tailwind, CSS, Styled Components āđ„āļ”้āļŦāļĄāļ” āļ•้āļ­āļ‡āđƒāļŠ้āļ•āļēāļĄāđ‚āļ„āļĢāļ‡āļŠāļĢ้āļēāļ‡āļ—ี่ Library āļāļģāļŦāļ™āļ”
āļ›āļĢāļ°āļŠิāļ—āļ˜ิāļ āļēāļž āđ€āļšāļē āđ€āļĢ็āļ§ āđ„āļĄ่āđ‚āļŦāļĨāļ”āļŠāđ„āļ•āļĨ์āđ€āļิāļ™āļˆāļģāđ€āļ›็āļ™ āļ­āļēāļˆāļĄี CSS āļŦāļĢืāļ­ JS āļŠ่āļ§āļ™āđ€āļิāļ™āļ—ี่āđ„āļĄ่āđ„āļ”้āđƒāļŠ้
āļāļēāļĢāļĢāļ­āļ‡āļĢัāļš Accessibility āļĄีāļāļēāļĢāļˆัāļ”āļāļēāļĢāđ‚āļŸāļัāļŠāđāļĨāļ°āļ„ีāļĒ์āļšāļ­āļĢ์āļ”āđƒāļŦ้ āļšāļēāļ‡āļ•ัāļ§āļĢāļ­āļ‡āļĢัāļš āđāļ•่āļšāļēāļ‡āļ•ัāļ§āļ­āļēāļˆāļ•้āļ­āļ‡āļ—āļģāđ€āļžิ่āļĄāđ€āļ­āļ‡
āđ€āļŦāļĄāļēāļ°āļัāļš āļ„āļ™āļ—ี่āļ•้āļ­āļ‡āļāļēāļĢ Custom UI āđ€āļ­āļ‡ āļ„āļ™āļ—ี่āļ•้āļ­āļ‡āļāļēāļĢ UI āļžāļĢ้āļ­āļĄāđƒāļŠ้

🛠 āļ§ิāļ˜ีāļ•ิāļ”āļ•ั้āļ‡ Headless UI āđƒāļ™ Next.js

āļ•ิāļ”āļ•ั้āļ‡āļœ่āļēāļ™ npm āļŦāļĢืāļ­ yarn āļ‡่āļēāļĒāđ†

npm install @headlessui/react

āļŦāļĢืāļ­

yarn add @headlessui/react


ðŸŽŊ āļ•ัāļ§āļ­āļĒ่āļēāļ‡āļāļēāļĢāđƒāļŠ้āļ‡āļēāļ™ Headless UI

ðŸ”Ĩ 1️⃣ āļ—āļģ Modal āļ—ี่āđƒāļŠ้āļˆāļĢิāļ‡āđ„āļ”้āđ€āļĨāļĒ

Modal āļŦāļĢืāļ­ Dialog āđ€āļ›็āļ™āļŠิ่āļ‡āļ—ี่āđƒāļŠ้āļš่āļ­āļĒāđƒāļ™āđ€āļ§็āļš āđ€āļŠ่āļ™ āđāļˆ้āļ‡āđ€āļ•ืāļ­āļ™, āļŸāļ­āļĢ์āļĄāļŠāļĄัāļ„āļĢāļŠāļĄāļēāļŠิāļ


ðŸ”đ āļ•ัāļ§āļ­āļĒ่āļēāļ‡ Modal āđāļšāļšāđƒāļŠ้ Headless UI

import { Dialog, Transition } from "@headlessui/react";
import { Fragment, useState } from "react";

export default function ExampleModal() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div className="text-center mt-10">
      <button
        onClick={() => setIsOpen(true)}
        className="px-4 py-2 bg-blue-500 text-white rounded"
      >
        āđ€āļ›ิāļ” Modal
      </button>

      <Transition appear show={isOpen} as={Fragment}>
        <Dialog as="div" className="fixed inset-0 z-50 flex items-center justify-center" onClose={() => setIsOpen(false)}>
          <div className="bg-white p-6 rounded-lg shadow-lg">
            <Dialog.Title className="text-lg font-bold">āļ™ี่āļ„ืāļ­ Modal!</Dialog.Title>
            <Dialog.Description className="mt-2 text-gray-600">
              āļāļ”āļ›ุ่āļĄāļ›ิāļ”āđ€āļžื่āļ­āļ­āļ­āļāļˆāļēāļ Modal
            </Dialog.Description>
            <button
              onClick={() => setIsOpen(false)}
              className="mt-4 px-4 py-2 bg-red-500 text-white rounded"
            >
              āļ›ิāļ”
            </button>
          </div>
        </Dialog>
      </Transition>
    </div>
  );
}

✅ āļ—āļģāđ„āļĄ Headless UI āļ–ึāļ‡āļ”ีāļāļ§่āļē Modal āļ›āļāļ•ิ?

  • āđƒāļŠ้āļ‡āļēāļ™āļ‡่āļēāļĒ āđāļ„่āđƒāļŠ่ Dialog
  • āļĢāļ­āļ‡āļĢัāļš Keyboard Accessibility āļ­ัāļ•āđ‚āļ™āļĄัāļ•ิ
  • āđ„āļĄ่āļĄีāļŠāđ„āļ•āļĨ์āđ€āļิāļ™āļˆāļģāđ€āļ›็āļ™ ðŸ‘‰ Customize āđ„āļ”้āđ€āļ•็āļĄāļ—ี่!


📜 2️⃣ āļ—āļģ Dropdown Menu āđāļšāļšāđ‚āļ›āļĢ

ðŸ”đ āļ•ัāļ§āļ­āļĒ่āļēāļ‡ Dropdown Menu

import { Menu, Transition } from "@headlessui/react";
import { Fragment } from "react";

export default function Dropdown() {
  return (
    <Menu as="div" className="relative inline-block text-left">
      <Menu.Button className="px-4 py-2 bg-blue-500 text-white rounded">āđ€āļĄāļ™ู</Menu.Button>

      <Transition
        as={Fragment}
        enter="transition ease-out duration-100"
        enterFrom="opacity-0 scale-95"
        enterTo="opacity-100 scale-100"
        leave="transition ease-in duration-75"
        leaveFrom="opacity-100 scale-100"
        leaveTo="opacity-0 scale-95"
      >
        <Menu.Items className="absolute mt-2 w-48 bg-white border rounded shadow-lg">
          <Menu.Item>
            {({ active }) => (
              <a className={`block px-4 py-2 ${active ? "bg-gray-200" : ""}`} href="#">
                āđ‚āļ›āļĢāđ„āļŸāļĨ์
              </a>
            )}
          </Menu.Item>
          <Menu.Item>
            {({ active }) => (
              <a className={`block px-4 py-2 ${active ? "bg-gray-200" : ""}`} href="#">
                āļ•ั้āļ‡āļ„่āļē
              </a>
            )}
          </Menu.Item>
        </Menu.Items>
      </Transition>
    </Menu>
  );
}

✅ Dropdown āļ‚āļ­āļ‡ Headless UI āļ”ีāļĒัāļ‡āđ„āļ‡?

  • āļ›āļĢัāļšāđāļ•่āļ‡āđ„āļ”้āļ‡่āļēāļĒ āđ„āļĄ่āļĄีāļŠāđ„āļ•āļĨ์āļšัāļ‡āļ„ัāļš
  • āļĢāļ­āļ‡āļĢัāļš Keyboard Navigation
  • Animate āđ„āļ”้ Smooth (āđāļ„่āđƒāļŠ้ Transition)


🏁 āļŠāļĢุāļ›

āļŦัāļ§āļ‚้āļ­ āļĢāļēāļĒāļĨāļ°āđ€āļ­ีāļĒāļ”
Headless UI āļ„ืāļ­āļ­āļ°āđ„āļĢ? āļŠุāļ”āļ„āļ­āļĄāđ‚āļžāđ€āļ™āļ™āļ•์āļ—ี่āđ„āļĄ่āļĄีāļŠāđ„āļ•āļĨ์āļšัāļ‡āļ„ัāļš āđƒāļŦ้āđ€āļĢāļēāļ›āļĢัāļšāđāļ•่āļ‡āđ„āļ”้āđ€āļ­āļ‡
āļ‚้āļ­āļ”ี āļĒืāļ”āļŦāļĒุ่āļ™, āđƒāļŠ้āļัāļš Tailwind CSS āđ„āļ”้āļ”ี, āđ€āļĢ็āļ§āđāļĨāļ°āđ€āļšāļēāļāļ§่āļē UI Library āļ­ื่āļ™āđ†
āļāļēāļĢāļ•ิāļ”āļ•ั้āļ‡ npm install @headlessui/react
āļ„āļ­āļĄāđ‚āļžāđ€āļ™āļ™āļ•์āļ—ี่āđƒāļŠ้āļ‡āļēāļ™āļš่āļ­āļĒ Modal (Dialog), Dropdown (Menu), Tabs, Popover
āđ€āļŦāļĄāļēāļ°āļัāļšāđƒāļ„āļĢ? āļ„āļ™āļ—ี่āļ•้āļ­āļ‡āļāļēāļĢ UI āļ—ี่ Custom āđ„āļ”้āđ€āļ•็āļĄāļ—ี่ āđ‚āļ”āļĒāđ„āļĄ่āļ­āļĒāļēāļāļ•ิāļ”āļ”ีāđ„āļ‹āļ™์āđ€āļ”ิāļĄāđ†

ðŸŽŊ āļŠāļĢุāļ›āļ‡่āļēāļĒāđ†

āļ–้āļēāļ„ุāļ“āļ­āļĒāļēāļāđƒāļŦ้āđ€āļ§็āļšāļĄี UI āļ—ี่āļĒืāļ”āļŦāļĒุ่āļ™ āđ„āļĄ่āļ–ูāļāļšัāļ‡āļ„ัāļšāļ”้āļ§āļĒāļ”ีāđ„āļ‹āļ™์āđ€āļ”ิāļĄāđ† āđāļĨāļ°āļĢāļ­āļ‡āļĢัāļš Accessibility āļ”ีāđ€āļĒี่āļĒāļĄ ðŸ‘‰ āđƒāļŠ้ Headless UI āđ€āļ–āļ­āļ°!

āļĨāļ­āļ‡āđ„āļ›āđƒāļŠ้āļัāļš Tailwind CSS āđāļĨ้āļ§āļ„ุāļ“āļˆāļ°āļŦāļĨāļ‡āļĢัāļ ðŸ’™

āđ„āļĄ่āļĄีāļ„āļ§āļēāļĄāļ„ิāļ”āđ€āļŦ็āļ™:

āđāļŠāļ”āļ‡āļ„āļ§āļēāļĄāļ„ิāļ”āđ€āļŦ็āļ™

āļāļēāļĢāđƒāļŠ้ Image Optimization āđƒāļ™ Next.js: āđ‚āļŦāļĨāļ”āđ„āļ§ SEO āļ”ี āļ›āļĢāļ°āļŦāļĒัāļ”āđāļšāļ™āļ”์āļ§ิāļ˜!

āđ€āļ„āļĒāđ€āļˆāļ­āļ›ัāļāļŦāļēāđ€āļ§็āļšāđ‚āļŦāļĨāļ”āļŠ้āļēāđ€āļžāļĢāļēāļ°āļĢูāļ›āļ āļēāļžāļ‚āļ™āļēāļ”āđƒāļŦāļ่āļŦāļĢืāļ­āđ€āļ›āļĨ่āļē? 📷 āļ–้āļēāđƒāļŠ่ Next.js āļĄีāļŸีāđ€āļˆāļ­āļĢ์ Image Optimization āļ—ี่āļŠ่āļ§āļĒāđƒāļŦ้āļĢูāļ›āļ āļēāļžāđ‚āļŦāļĨāļ”āđ€āļĢ็āļ§āļ‚ึ้āļ™ āļ­ัāļ•āđ‚āļ™āļĄัāļ•ิ āđ„āļĄ...