lynx-ui 正式发布
← 所有文章lynx-ui 在去年 12 月的 React Advanced London 上首次亮相并开源。几个月来,我们一直在打磨组件、完善文档、丰富示例。今天,lynx-ui 正式发布。
原生基础,Web 速度
内置元素和 XElement 为 Lynx 提供了至关重要的底层能力:流畅滚动、精准手势、原生渲染。但产品不是仅靠原子就能构建的,这正是组件的意义所在。Lynx 采用分层架构:原生层提供底层基础能力,Web 前端技术栈则在其上负责组件组合、状态管理、样式系统与产品特定行为的扩展。
lynx-ui 落地了这一分层思路:保留原生用户体验,提供 Web 级别的开发速度。
lynx-ui 的 ScrollView 基于原生
<scroll-view>
原语构建
可组合的原语(Primitive)
当一个组件把所有东西都封在里面,每来一个新需求就要加一个 prop,最终会变成谁也不敢动的黑盒。lynx-ui 是一个 unstyled 组件库。每个组件是一个 primitive,负责行为和状态,但不附带任何视觉样式。一个 primitive 由多个 part 组成,每个 part 独立渲染、独立样式化。
Popover 展示了这个思路。它不是一个不透明的单体组件,而是由各司其职的 part 组合而成:PopoverRoot 管理状态,PopoverTrigger 定义意图,PopoverPositioner 处理定位,PopoverContent 保持结构独立。
正因为 primitive 是 unstyled 的,同样的可组合模型也为设计系统奠定了基础。你可以通过样式与主题机制定义自己的主题,也可以按照 shadcn/ui 的模式在 primitive 之上组合出带主题的 wrapper。
LUNA
LUNA 是我们在此基础上构建的参考设计语言。
LUNA 从 Lynx 标志性的渐变色出发,将品牌表达调适为更柔和的 UI 色调:温暖的粉红和玫瑰色渐变至薰衣草和水蓝色。在 LUNA 中,渐变作为一等视觉材质,用于表达形态和运动,赋予组件一种流动介质的质感。这种细腻也延伸到了 token 命名:LUNA 描述的是表面的感受,而非其位置——ambient 融入背景,faint 处于感知的阈值,veil 和 film 创造柔和的半透明层。
可编程的交互
手势驱动的组件对两件事要求很高:行为要可定制,响应要低延迟。滑动、拖拽、轻扫,每一帧都在被用户感知。反馈一旦跟不上手势,体验就不再是原生的。
Lynx 采用双线程模型,JavaScript 默认跑在后台线程,主线程专注渲染。需要时,主线程脚本可以把交互逻辑搬到主线程,逐帧行为因此完全可编程。Swiper 就是一个例子:拖拽时卡片逐帧跟手,不会事后追赶。
通过 main-thread:customAnimation 传入 'main thread'
函数,逐帧逻辑运行在主线程
有了原生基础和可编程的交互,动效不再只是装饰,而是组件行为的一部分。
Motion
Motion 是 Web 社区最知名的动画库之一,同时支持弹簧和贝塞尔曲线过渡。有了主线程脚本的可编程性做基础,我们把 Motion 搬到了 Lynx 上,实验版随 lynx-ui 一起发布。@lynx-js/motion 通过一层很薄的适配直接使用 Motion 源码,保持了和 Web 完全一致的使用方式。
Sheet 是一个很好的例子。拖拽、阻尼、释放、归位,这些需要连贯成一个完整的行为。主线程脚本让交互紧贴渲染,Motion 控制面板怎么动,两者配合之下,面板给人一种被"握住"的感觉,而不是在回放动画。
Sheet 底层使用 @lynx-js/motion
驱动弹簧拖拽和归位过渡
立即体验
lynx-ui 目前已支持 iOS、Android 和 HarmonyOS,Web 和 Desktop 支持也在推进中。阅读简介了解全貌,或直接跳到快速开始安装 @lynx-js/lynx-ui-*。
下载 Lynx Explorer,扫描组件示例中的二维码,即可在真机上查看实际效果。你也可以直接将组件集成到自己的 Lynx 应用中,在真实业务流中试用。
我们希望 lynx-ui 能在真实应用的实践中不断成长。如果它体验很好、阻碍了你、或者缺少了什么,请在 lynx-family/lynx-ui 仓库中告诉我们。一起塑造它的未来。