今天就是这一天 — 我们刚刚发布了 Catalyst 的第一个开发预览版,正好赶上您的假日黑客编程时光。
Catalyst 是我们第一个完全组件化、功能齐全的应用程序 UI 套件 — 真实的 React 组件,具有经过深思熟虑设计的 API,这些 API 相互构建,形成一个真实的组件架构,就像我们在真实应用程序中会做的那样。
查看在线演示,阅读文档,如果您是 Tailwind UI 全访问客户,今天就下载它并在新项目中尝试使用。
Catalyst 目前处于开发预览阶段,还有很多内容即将推出,但我们今天就发布它,这样您可以立即开始使用它,而我们继续构建新组件并找到让它变得更好的方法。
您的组件,而不是我们的
在开发 Catalyst 时,我们致力于构建一个明天的 Stripe 或 Linear 都会乐于使用来构建其产品的 UI 套件 — 那些对设计有执着追求的团队,他们想要拥有自己的 UI 组件,而永远不会选择现成的库。
所以它不是您安装的依赖项,而是您下载源代码并将组件复制到您自己的项目中,它们成为您自己组件系统的起点:
想要更改按钮的边框圆角?只需打开 button.tsx 并更改一些类。您不需要开一个 GitHub issue 并试图说服我们暴露一个新的配置选项。
Catalyst 是一个"消失的 UI 套件" — 安装它六个月后,您应该几乎忘记不是您自己构建的原始组件。
设计在细节中
在这样的项目中,获得正确的视觉风格是很难的。我们带着几个目标进入了这个项目:
- 具有竞争力 — 我们希望设计出能够与当今网络上一些最漂亮的界面媲美的东西。
- 永不过时 — 我们不想设计出在 6 个月后看起来会过时的东西,因为它过于依赖特定的趋势。
- 高效 — 无论我们设计的是什么,都需要让真实用户感到快速和高效,而不仅仅是在 Dribbble 上看起来很棒。
这需要大量的工作,并且有很多权衡需要平衡,但我真的很喜欢我们最终的结果:
为了具有竞争力,我们在很多细节上进行了投资,比如在下拉菜单上使用微妙的背景模糊,完善阴影和边框在表单控件上的相互融合方式,以及在对话框和切换开关等事物中对动画的深思熟虑使用。
为了永不过时,我们试图在平面设计和拟物设计之间找到正确的平衡,具有足够的深度提示,即使趋势在任一方向上发生了一些变化,我们的组件也会看起来很棒。
我们还从浏览器中汲取灵感,使用无偏见的蓝色焦点环,以避免选择可能很快看起来过时的处理方式。
为了高效,我们仔细工作,确保仍有足够的空白,但 UI 仍然足够密集,可以在屏幕上容纳大量信息。
我们还限制了过渡和动画的使用,仅在感觉重要的地方使用,即使在那时也尽量保持快速,这样您永远不会觉得在等待 UI。
Catalyst 还支持完整的暗模式,使用 Catalyst 组件构建的任何内容都会自动适应明暗模式。
这并不明显,但我们必须更改大量细节,以使事物在暗模式下看起来最好,比如调整阴影,将外环更改为内环以模仿光照变化等等。
模仿 HTML
我们花了很多时间研究组件 API,努力使其非常容易立即使用,而不影响灵活性。
UI 库通常使用这样的 API:
function Example() { return ( <TextField name="product_name" label="Product name" description="Use the name you'd like people to see in their cart." /> );}但是,当所有的 props 都在同一个组件上时,开始很难做一些事情,比如仅向 <input> 元素本身添加一个类。
最终,这导致我们采用了与 HTML 非常相似的 API,在这种 API 中,单个组件很少渲染多个元素。
例如,使用 Catalyst 创建一个文本字段看起来像这样:
import { Description, Field, Label } from "@/components/fieldset";import { Input } from "@/components/input";function Example() { return ( <Field> <Label>Product name</Label> <Description>Use the name you'd like people to see in their cart.</Description> <Input name="product_name" /> </Field> );}通过保持这种可组合性,可以很容易地做一些事情,比如限制输入的宽度,而不限制任何其他元素的宽度:
import { Description, Field, Label } from "@/components/fieldset";import { Input } from "@/components/input";function Example() { return ( <Field> <Label>Product name</Label> <Description>Use the name you'd like people to see in their cart.</Description> <Input name="product_name" className="max-w-sm" /> </Field> );}这也使得将描述移到输入框下方变得容易,而不是上方:
import { Description, Field, Label } from '@/components/fieldset'import { Input } from '@/components/input'function Example() { return ( <Field> <Label>Product name</Label> <Description>Use the name you'd like people to see in their cart.</Description> <Input name="product_name" className="max-w-sm" /> <Description>Use the name you'd like people to see in their cart.</Description> </Field> )}我们花了很多时间试验,找出使这些 API 工作的正确方法,特别是在向正确的子元素添加布局样式等细节方面,但回报是值得的,这些组件真的很愉快使用。
由下一代 Headless UI 提供支持
我们在 2020 年夏天发布了第一个版本的 Headless UI,但自从上一个重要功能发布以来已经一年多了,因为我们一直专注于 Tailwind CSS 本身的工作。
Catalyst 是我们再次深入研究 Headless UI 的完美借口,我们很快发现了许多改进项目的方法,以简化 Catalyst 本身的代码。
我们刚刚发布了 Headless UI v2.0.0-alpha.1,其中包含大量新内容:
- 内置锚点定位 — 使用 Floating UI,像
Menu、Listbox等组件现在可以自动定位其弹出窗口,使其锚定到其触发器,并根据需要适应视口的变化。 - 无头复选框组件 — 我们添加了一个无头
Checkbox组件,以补充我们现有的RadioGroup组件,使构建完全自定义的复选框控件变得容易。 - HTML 表单组件 — 我们添加了
Input、Select、Textarea、Label、Description、Fieldset和Legend组件,这些组件处理所有的 ID 生成和aria-*属性映射,您需要将表单字段连接在一起。 - 改进的悬停和焦点可见检测 — 使用来自出色的 React Aria 库的钩子,Headless UI 现在向您的控件添加了更智能的
data-hover和data-focus属性,这些属性在不同设备上的行为比本机伪类更一致。 - 组合框列表虚拟化 — 下一版本的 Headless UI 现在可以处理巨大的组合框选项列表,而不会出现性能问题。
...还有许多其他改进即将推出,包括日期选择器、工具提示等。
这些改进目前仅适用于 React,在这个早期 alpha 阶段,但我们计划在标记 v2.0 之前将所有这些改进带到 Vue。
我们很快就会为这些内容发布文档,但即使这意味着在假期前几天发布 Headless UI 文档,我们也无法抗拒在假期前发布 Catalyst。
试试看
Catalyst 是所有 Tailwind UI 全访问 客户的免费更新,您可以下载它并开始使用这个第一个版本。
为了让我们今天发布的所有内容都恰到好处,投入的工作比您想象的要多得多,但我们渴望得到反馈和改进的方法,所以用它构建一些东西,并告诉我们您的想法。
我们将在假期期间休息几周,但在新的一年里,我们将立即回到 Catalyst,致力于新的组件,如应用程序布局、组合框、命令面板、工具提示等。