这周很忙,我们一直在完成一些项目,但一切都终于完成了,所以现在感觉是时候进行另一次更新了。
自从我上次发帖以来,我们已经整理并解决了另外226 个 GitHub 问题和拉取请求,而且我们整个组织中未解决的问题/PR 首次降至 50 个以下。所以请停止寻找错误,我只想用 Tailwind CSS 来设计和构建精美的作品。
说到精美的作品,以下是过去几周发布的内容!
焦点:您的全新个人网站
几天前,我们发布了Spotlight,这是一个为 Tailwind UI 设计的令人惊艳的全新个人网站模板。

像我们的其他模板一样,它使用Next.js 构建,这次我们使用MDX 来驱动所有诸如博客部分之类的 Markdown 内容。
设计这个模板是一个非常有趣和具有挑战性的任务 — 我们想要提出一些真正美丽和鼓舞人心的东西,但也足够不偏颇,以至于感觉几乎适合任何人。我们最终采用了一个非常简约的设计,它的个性来自诸如旋转的图像、链接的颜色提示以及诸如顶部导航之类的位置的阴影和分层带来的一些微妙的深度等小细节。

像往常一样,我建议查看实时预览以获得完整的体验 — 特别是注意在您滚动时,首页上的头像和导航的工作方式,当您使用真实站点时,它非常完美。
我们尝试按照我们构建自己的个人网站的方式来构建该网站,因此它包括一个专门的博客、一个列出您最喜欢的一些项目的页面、一个用于链接您所做会议演讲等内容的区域以及一个“使用”页面来列出您所有喜欢的工具和装备。
如果您拥有Tailwind UI 全面访问许可证,那么您已经可以访问此模板了!如果您没有,请考虑购买 — 这是支持我们对 Tailwind CSS、Headless UI 和 Heroicons 等开源项目工作的最佳方式。
Heroicons v2.0
去年我们发布了Heroicons v1.0。上周,我们发布了Heroicons v2.0,这是一个全新的图标集,由 Steve 从头开始绘制,他为此工作了大约一年。

它包含 280 个以三种不同样式绘制的图标
- 轮廓 — 具有 1.5px 描边的线条图标,在 24px 视口中绘制。
- 实心 — 具有填充形状的实心图标,在 24px 视口中绘制。
- 迷你 — 具有填充形状的实心图标,在 20px 视口中绘制。
与 v1 的最大区别在于,轮廓集使用了更细的描边,这在当今感觉更现代和时尚,并且在视觉上,图标的风格更加活泼。
尽管这些图标的名称中带有“v2”,但最好将 Heroicons v2 视为《终结者 2》而不是 OpenSSL 2 — 我们觉得它们代表了我们最好的作品,但它是一个新的图标集,而不是严格意义上对原始图标集的升级。不要像对待真正的应用程序依赖项那样感到需要升级现有项目,但如果您想迁移,请查看发行说明以获取您需要切换的所有内容。
要浏览所有新图标,请访问我们使用新图标集推出的完全重新设计的 Heroicons 网站。
Headless UI v1.7
本周早些时候,我们标记了Headless UI 的新版本,这是我们的 React 和 Vue 无样式 UI 组件库。

Headless UI v1.7 包括通常的大量错误修复和改进,还有一些非常有用的新功能!
添加了用于控制对象比较的“by”属性
我们在 Listbox
、Combobox
和 RadioGroup
组件中添加了一个新的 by
属性,这使得将对象绑定为表单值变得不那么麻烦了。
import { Listbox } from "@headlessui/react";const departments = [ { id: 1, name: "Marketing", contact: "Durward Reynolds" }, { id: 2, name: "HR", contact: "Kenton Towne" }, { id: 3, name: "Sales", contact: "Therese Wunsch" }, { id: 4, name: "Finance", contact: "Benedict Kessler" }, { id: 5, name: "Customer service", contact: "Katelyn Rohan" },];function DepartmentPicker({ selectedDepartment, onChange }) { return ( <Listbox value={selectedDepartment} by="id" onChange={onChange}> <Listbox.Button>{selectedDepartment.name}</Listbox.Button> <Listbox.Options> {departments.map((department) => ( <Listbox.Option key={department.id} value={department}> {department.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> );}
这使得值更容易来自组件外部,并节省了您只需绑定 id
或类似项并在需要时自己进行大量查找来查找完整对象的时间。
查看每个组件的更新后的“将对象绑定为值”文档,以获取更多详细信息。
使用表单控件作为非受控组件
Listbox
、Combobox
和 RadioGroup
组件现在允许您选择性地传递 defaultValue
而不是 value
,从而允许您将它们用作非受控组件。
import { Listbox } from "@headlessui/react";const people = [ { id: 1, name: "Durward Reynolds" }, { id: 2, name: "Kenton Towne" }, { id: 3, name: "Therese Wunsch" }, { id: 4, name: "Benedict Kessler" }, { id: 5, name: "Katelyn Rohan" },];function Example() { return ( <form action="/projects/1/assignee" method="post"> <Listbox name="assignee" defaultValue={people[0]}> <Listbox.Button>{({ value }) => value.name}</Listbox.Button> <Listbox.Options> {people.map((person) => ( <Listbox.Option key={person.id} value={person}> {person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> <button>Submit</button> </form> );}
当使用传统的 HTML 表单或使用 FormData
而不是使用 React 状态来跟踪其状态的表单 API 时,这可以简化您的代码。
查看每个组件的“用作非受控组件”文档,以查看更多示例。
用于仅 CSS 状态样式的数据属性
过去,您必须通过检查通过渲染属性传递的参数并有条件地渲染任何有意义的类或内容来样式化 Headless UI 组件的不同状态。当仅尝试调整背景颜色或进行其他仅 CSS 的更改时,这可能会感觉有很多样板。
在 Headless UI v1.7 中,我们向渲染的 HTML 添加了一个 data-headlessui-state
属性,其中包含有关当前状态的信息,因此您可以使用 CSS 对其进行定位。
我们还发布了一个新的@headlessui/tailwindcss 插件,该插件为您提供这些状态的变体,因此它们非常容易仅使用 Tailwind CSS 类进行样式设置
<Listbox.Option key={person.id} value={person} className="ui-active:bg-blue-500 ui-active:text-white ui-not-active:bg-white ui-not-active:text-black"> <CheckIcon className="ui-selected:block hidden" /> {person.name}</Listbox.Option>
查看有关使用数据属性进行样式设置的新文档以获取更多详细信息。
Tailwind Play 上的 Insiders 支持
并非所有人都知道,但是我们会向 npm 发布一个 Tailwind CSS 的 insiders
构建版本,该版本会在每次有新提交进入存储库时自动构建和部署。这使得在实际版本中标记之前测试新功能和修复变得非常容易。
现在,我们在 Tailwind Play 中也包括了对 insiders 构建版本的访问权限,因此您可以在不设置项目的情况下使用最前沿的内容

我们只保留 Play 上的最新 insiders 版本,因此,如果您使用 insiders 版本创建演示,请知道如果下一个 insiders 版本更改了您正在使用的某些未发布的功能,则可能会中断。无论如何,您不应该在那里放置重要的东西,来吧,要专业。
Tailwind CSS + Phoenix v1.7
不久前,我们开始与 Phoenix 团队交谈,因为他们希望在未来的版本中默认发布 Tailwind CSS。我认为这非常令人兴奋,并希望与他们合作,使开箱即用的体验非常棒。
我们为他们的生成器系统设计了一个新的启动屏幕和所有必要的脚手架,这将作为 Phoenix v1.7 的一部分发布。

Phoenix 的创建者 Chris McCord 上周进行了一次精彩的演讲,其中介绍了他们正在发布的所有 Tailwind CSS 内容,如果您有兴趣了解更多信息,值得一看。
所以,这就是我们过去几周一直在开发的所有最酷的东西!
在接下来的一个月左右,我很高兴构建我们一直在设计的一系列新的 Tailwind UI 组件,探索 Tailwind CSS 的一些新功能创意,并开始研究使用 Tailwind + Next.js 创建一种应用程序入门工具包模板是什么样的 — 如果我们能成功,我认为它会非常酷。
下次更新见!