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>停用帐户</Dialog.Title>
<Dialog.Description>这将永久停用您的帐户</Dialog.Description>
<p>
您确定要停用帐户吗?您的所有数据将被永久删除。此操作无法撤回。
</p>
<button onClick={() => setIsOpen(false)}>停用</button>
<button onClick={() => setIsOpen(false)}>取消</button>
</Dialog>
);
}

披露

我们添加了一个新的 Disclosure 组件,使得以可访问的方式显示/隐藏内联内容变得简单。这对于可折叠的常见问题、"显示更多" 接口,或者甚至是开放并推走其他页面内容的汉堡菜单都很有用。

<template>
<Disclosure>
<DisclosureButton> 是否提供团队定价? </DisclosureButton>
<DisclosurePanel> 是的!您可以购买一个许可证,您可以与整个团队共享。 </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>计划</RadioGroup.Label>
<RadioGroup.Option value="startup">
{({ checked }) => <span className={checked ? "bg-blue-200" : ""}>初创</span>}
</RadioGroup.Option>
<RadioGroup.Option value="business">
{({ checked }) => <span className={checked ? "bg-blue-200" : ""}>商务</span>}
</RadioGroup.Option>
<RadioGroup.Option value="enterprise">
{({ checked }) => <span className={checked ? "bg-blue-200" : ""}>企业</span>}
</RadioGroup.Option>
</RadioGroup>
);
}

弹出菜单

新的 Popover 组件允许您构建自定义下拉 UI,而没有像常规 Menu 组件那样的内容限制。非常适合市场网站上的飞出菜单、包含表单字段的下拉菜单等等。

<template>
<Popover class="relative">
<PopoverButton>解决方案</PopoverButton>
<PopoverPanel class="absolute z-10">
<div>
<a href="/analytics">分析</a>
<a href="/engagement">互动</a>
<a href="/security">安全</a>
<a href="/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 用户使用原生的 <transition>,它已经随 Vue 一起提供。然而,原生过渡有一些局限性,要协调应该并行运行的嵌套过渡时会变得复杂。

Headless UI v1.0 将我们的 React Transition 组件引入 Vue,这使过渡模态对话框等事物变得更加容易。

<template>
<!-- 此 `show` 属性控制所有嵌套的 `Transition.Child` 组件。 -->
<TransitionRoot :show="isOpen">
<!-- 背景叠加 -->
<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>
<!-- 滑动侧边栏 -->
<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.