headlessui 基础

下面是一个使用 Headless UI 的基础示例,主要演示如何使用 Headless UI 创建交互式 UI 组件:

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

function Modal() {
  const [isOpen, setIsOpen] = useState(false);

  function closeModal() {
    setIsOpen(false);
  }

  function openModal() {
    setIsOpen(true);
  }

  return (
    <>
      <button
        type="button"
        onClick={openModal}
        className="px-4 py-2 text-sm font-medium text-white bg-black rounded-md bg-opacity-20 hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"
      >
        Open Modal
      </button>

      <Transition appear show={isOpen} as={Fragment}>
        <Dialog as="div" className="fixed inset-0 z-10 overflow-y-auto" onClose={closeModal}>
          <div className="min-h-screen px-4 text-center">
            <Transition.Child
              as={Fragment}
              enter="ease-out duration-300"
              enterFrom="opacity-0"
              enterTo="opacity-100"
              leave="ease-in duration-200"
              leaveFrom="opacity-100"
              leaveTo="opacity-0"
            >
              <Dialog.Overlay className="fixed inset-0 bg-black bg-opacity-30" />
            </Transition.Child>

            {/* This element is to trick the browser into centering the modal contents. */}
            <span className="inline-block h-screen align-middle" aria-hidden="true">
              &#8203;
            </span>
            <Transition.Child
              as={Fragment}
              enter="ease-out duration-300"
              enterFrom="opacity-0 scale-95"
              enterTo="opacity-100 scale-100"
              leave="ease-in duration-200"
              leaveFrom="opacity-100 scale-100"
              leaveTo="opacity-0 scale-95"
            >
              <div className="inline-block w-full max-w-md p-6 my-8 overflow-hidden text-left align-middle transition-all transform bg-white shadow-xl rounded-2xl">
                <Dialog.Title as="h3" className="text-lg font-medium leading-6 text-gray-900">
                  Modal Title
                </Dialog.Title>
                <div className="mt-2">
                  <p className="text-sm text-gray-500">Modal content goes here...</p>
                </div>
              </div>
            </Transition.Child>
          </div>
        </Dialog>
      </Transition>
    </>
  );
}

export default Modal;

在这个示例中,我们使用 Headless UI 的 TransitionDialog 组件创建了一个简单的模态对话框。

  1. 首先,我们使用 useState 钩子来管理模态对话框的打开和关闭状态。
  2. 然后,我们渲染一个按钮,当点击时会打开模态对话框。
  3. Transition 组件用于控制模态对话框的过渡动画效果。
  4. Dialog 组件提供了模态对话框的基本结构和功能,包括背景遮罩层和对话框内容。
  5. Transition.Child 组件中,我们定义了过渡动画的进入和离开效果。
  6. 最后,我们在对话框内容中渲染了标题和一些占位符文本。

通过这个示例,你可以看到 Headless UI 提供了一种无样式的、高度可组合的方式来构建交互式 UI 组件。它使用了 React 的组合模式,允许你自由地控制组件的渲染和行为,同时还提供了一些内置的辅助功能,如过渡动画和焦点管理。

Headless UI 非常适合于构建自定义的、可访问的 UI 组件,并且与任何 CSS 框架或样式方案兼容,如 Tailwind CSS。它提供了一种更加灵活和可组合的方式来构建 UI,而不会像 UI 组件库那样受到限制。