无头界面 v1.0

Adam Wathan
Headless UI

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

今天我们非常高兴地发布 Headless UI v1.0,它使 React 和 Vue 的内置组件数量增加了一倍多。

有哪些新功能(What’s new)

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

🌐 We’ve added four new components to the React library, and five new components for Vue.

对话框(模态框)(Dialog (modal))

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

🌐 Headless UI now includes a robust dialog implementation you can use to build traditional modal dialogs, mobile slide-out menus, or any other take-over-style UI that needs to capture the focus of the entire page.

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 组件,使显示/隐藏内联内容变得更容易且可访问。这对于可折叠的常见问题解答、“显示更多”界面,甚至是会打开并推动页面其他内容的汉堡菜单等情况非常有用。

🌐 We’ve added a new Disclosure component that makes it easy to show/hide inline content accessibly. This is useful for things like collapsible FAQ questions, "show more" interfaces, or even hamburger menus that open up and push the rest of the page content away.

<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 组件,你可以用它来构建完全自定义的单选按钮界面,比如当你想使用华丽的卡片或其他东西,而不是简单的小圆圈时。

🌐 There’s now a RadioGroup component that you can use to build totally custom radio button UIs, like when you want to use fancy cards or something instead of a simple little radio circle.

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 组件让你可以构建自定义下拉界面,不像普通的 Menu 组件那样有内容限制。非常适合用于营销网站的浮出菜单、包含表单字段的下拉菜单,以及更多其他场景。

🌐 The new Popover component lets you build custom dropdown UIs that don’t have any content restrictions like a regular Menu component would. Great for fly-out menus on marketing sites, dropdowns that have form fields in them, and tons more.

<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)(TransitionRoot and TransitionChild (for Vue))

Headless UI 已经为 React 提供了一个 Transition 组件,但我们一直推荐 Vue 用户使用已经随 Vue 自带的原生 <transition>。不过,原生过渡有一些限制,而且在尝试协调应该并行运行的嵌套过渡时情况可能会变得复杂。

🌐 Headless UI already had a Transition component for React, but we’ve always recommended the native <transition> that already ships with Vue for Vue users. There are some limitations to the native transition though, and things can get complicated when trying to co-ordinate nested transitions that are supposed to run in parallel.

Headless UI v1.0 也将我们的 React Transition 组件引入到了 Vue 中,这使得像模态对话框这样的功能迁移变得容易得多。

🌐 Headless UI v1.0 brings our React Transition component to Vue as well, which makes it a lot easier to transition things like modal dialogs.

<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>

试用(Try it out)

前往我们的 全新文档网站,将 Headless UI 引入你的项目并尝试使用!它是 MIT 许可证的开源项目,所以如果你想浏览代码或需要报告问题, 请访问 GitHub 仓库

想试试吗? 访问 Headless UI 网站 →

TailwindCSS 中文网 - 粤ICP备13048890号