Headless UI v1.0

Adam Wathan

去年秋天我们宣布了 Headless UI,这是一个完全无样式、完全可访问的 UI 组件库,专为与 Tailwind CSS 完美配合而设计。

今天我们非常兴奋地发布 Headless UI v1.0,它为 React 和 Vue 两个版本都增加了一倍多的组件。

Headless UI

新增内容

我们为 React 库添加了四个新组件,为 Vue 添加了五个新组件。

对话框(模态框)

Headless UI 现在包含了一个强大的对话框实现,您可以用它来构建传统的模态对话框、移动端滑出菜单,或任何其他需要获取整个页面焦点的接管式 UI。

import { useState } from "react";import { Dialog } from "@headlessui/react";function MyDialog() {  let [isOpen, setIsOpen] = useState(true);  return (    <Dialog open={isOpen} onClose={setIsOpen}>      <Dialog.Overlay />      <Dialog.Title>Deactivate account</Dialog.Title>      <Dialog.Description>This will permanently deactivate your account</Dialog.Description>      <p>        Are you sure you want to deactivate your account? All of your data will be permanently removed. This action        cannot be undone.      </p>      <button onClick={() => setIsOpen(false)}>Deactivate</button>      <button onClick={() => setIsOpen(false)}>Cancel</button>    </Dialog>  );}

展开/折叠面板

我们添加了一个新的 Disclosure 组件,它可以让您轻松地以无障碍的方式显示/隐藏内联内容。这对于折叠式 FAQ 问题、"显示更多"界面,甚至是打开后会推开页面其他内容的汉堡菜单都很有用。

<template>  <Disclosure>    <DisclosureButton> Is team pricing available? </DisclosureButton>    <DisclosurePanel> Yes! You can purchase a license that you can share with your entire team. </DisclosurePanel>  </Disclosure></template><script>  import { Disclosure, DisclosureButton, DisclosurePanel } from "@headlessui/vue";  export default {    components: { Disclosure, DisclosureButton, DisclosurePanel },  };</script>

单选按钮组

现在有了一个 RadioGroup 组件,您可以用它来构建完全自定义的单选按钮 UI,比如当您想使用花哨的卡片而不是简单的小圆圈时。

import { useState } from "react";import { RadioGroup } from "@headlessui/react";function MyRadioGroup() {  let [plan, setPlan] = useState("startup");  return (    <RadioGroup value={plan} onChange={setPlan}>      <RadioGroup.Label>Plan</RadioGroup.Label>      <RadioGroup.Option value="startup">        {({ checked }) => <span className={checked ? "bg-blue-200" : ""}>Startup</span>}      </RadioGroup.Option>      <RadioGroup.Option value="business">        {({ checked }) => <span className={checked ? "bg-blue-200" : ""}>Business</span>}      </RadioGroup.Option>      <RadioGroup.Option value="enterprise">        {({ checked }) => <span className={checked ? "bg-blue-200" : ""}>Enterprise</span>}      </RadioGroup.Option>    </RadioGroup>  );}

弹出框

新的 Popover 组件让您可以构建自定义的下拉 UI,这些 UI 没有普通 Menu 组件那样的内容限制。非常适合用于营销网站上的弹出菜单、包含表单字段的下拉菜单等。

<template>  <Popover class="relative">    <PopoverButton>Solutions</PopoverButton>    <PopoverPanel class="absolute z-10">      <div>        <a href="/analytics">Analytics</a>        <a href="/engagement">Engagement</a>        <a href="/security">Security</a>        <a href="/integrations">Integrations</a>      </div>      <img src="/solutions.jpg" alt="" />    </PopoverPanel>  </Popover></template><script>  import { Popover, PopoverButton, PopoverPanel } from "@headlessui/vue";  export default {    components: { Popover, PopoverButton, PopoverPanel },  };</script>

TransitionRoot 和 TransitionChild(Vue 版本)

Headless UI 已经为 React 提供了 Transition 组件,但对于 Vue 用户,我们一直推荐使用 Vue 自带的原生 <transition>。不过原生过渡也有一些限制,当试图协调需要并行运行的嵌套过渡时,事情会变得复杂。

Headless UI v1.0 也将我们的 React Transition 组件引入了 Vue,这使得过渡像模态对话框这样的东西变得更容易。

<template>  <!-- This `show` prop controls all nested `Transition.Child` components. -->  <TransitionRoot :show="isOpen">    <!-- Background overlay -->    <TransitionChild      enter="transition-opacity"      ease-linear      duration-300"      enter-from="opacity-0"      enter-to="opacity-100"      leave="transition-opacity"      ease-linear      duration-300"      leave-from="opacity-100"      leave-to="opacity-0"    >      <!-- … -->    </TransitionChild>    <!-- Sliding sidebar -->    <TransitionChild      enter="transition"      ease-in-out      duration-300      transform"      enter-from="-translate-x-full"      enter-to="translate-x-0"      leave="transition"      ease-in-out      duration-300      transform"      leave-from="translate-x-0"      leave-to="-translate-x-full"    >      <!-- … -->    </TransitionChild>  </TransitionRoot></template><script>import { ref } from "vue";import { Transition, TransitionChild } from "@headlessui/vue";export default {  components: { TransitionRoot: Transition, TransitionChild },  setup() {    const isShowing = ref(true);    return {      isShowing,    };  },};</script>

立即尝试

前往我们的 全新文档网站 将 Headless UI 引入您的项目并开始使用吧!它采用 MIT 许可证并且开源,所以如果您想查看代码或需要报告问题,请 访问 GitHub 仓库

准备好试试了吗?访问 Headless UI 网站 →

Get all of our updates directly to your inbox.
Sign up for our newsletter.