去年秋天,我们发布了 Headless UI,一个完全无样式、完全可访问的 UI 组件库,旨在与 Tailwind CSS 完美搭配。
今天,我们非常激动地发布 Headless UI v1.0,它使 React 和 Vue 的组件数量增加了一倍以上。

新功能
我们为 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
我们添加了一个新的 Disclosure
组件,可以轻松地以可访问的方式显示/隐藏内联内容。这对于诸如可折叠的常见问题解答、“显示更多”界面,甚至是展开并推开页面其余内容的汉堡菜单等功能非常有用。
<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>
Radio Group
现在有一个 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
新的 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 网站 →