npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vavt/react-ui

v1.4.4

Published

A modern React component library

Readme

@vavt/react-ui

面向 React 18/19 的 TypeScript 组件库,提供 ESM、CommonJS、NodeNext 兼容声明文件以及全量/按组件 CSS 入口。

安装

npm install @vavt/react-ui

使用

import { VlButton, VlCard } from '@vavt/react-ui';
import '@vavt/react-ui/styles.css';

export default function Example() {
  return (
    <VlCard>
      <VlButton status="primary">开始使用</VlButton>
    </VlCard>
  );
}

组件子路径和单组件样式也可以直接引用:

import { VlButton } from '@vavt/react-ui/components/Button';
import '@vavt/react-ui/base.css';
import '@vavt/react-ui/components/Button/style.css';

全量样式入口 styles.css 已包含基础主题与所有组件样式,因此不要再同时引入 base.css 或单组件 CSS。

Next.js SSR / App Router

发布后的 ESM 根入口和组件子路径都声明为 Client Component。Server Component 可以导入组件并把它直接渲染进 JSX,继续获得服务端预渲染;但不能读取组件上的静态属性(见下一节)。若项目还通过源码别名或旧缓存消费,也可以用一个显式 'use client' wrapper 固定边界:

// components/ui.ts
'use client';

export { VlButton, VlModal, VlSelect } from '@vavt/react-ui';

全局样式放在 app/layout.tsx 或其他全局入口中:

import '@vavt/react-ui/styles.css';

Dropdown、Tooltip 等可由受控状态打开的浮层会在 hydration 首轮保持结构一致,并在客户端挂载后迁移到 document.body;Modal、Drawer 和 MessageBox 的 Portal 内容仍属于客户端增强内容。命令式 VlMessageBox.alert/confirm 只可在浏览器事件或客户端组件中调用;服务端导入 @vavt/react-ui/register 不会再修改 Node 进程级 globalThis,如需注册请显式调用 registerGlobalComponents(target)。

复合组件的静态属性不能跨 Server Component 边界

VlForm.Item、VlMessageBox.alert、VlMessageBox.confirm 是挂在组件函数上的静态属性。Server Component 从 'use client' 模块导入拿到的是打包器生成的 client reference 代理,它只应答 $$typeof、name 等少数键,点号访问任何其他属性都会在服务端渲染时抛错:

Cannot access VlForm.Item on the server. You cannot dot into a client module
from a server component. You can only pass the imported name through.

TypeScript 拦不住这类错误:'use client' 是打包器层面的模块指令,类型系统里没有对应表示,声明文件只有一份、两侧解析结果相同,所以 VlForm.Item 在 Server Component 里同样能通过编译,只在运行时崩。

绝大多数情况下正确的修法是给渲染表单的文件加上 'use client'——onFinish、onChange 这类函数 prop 本来也跨不过序列化边界,可用的表单始终要在客户端文件里:

'use client';

import { VlForm, VlInput } from '@vavt/react-ui';

export default function ProfileForm() {
  return (
    <VlForm onFinish={save}>
      <VlForm.Item name="name" label="姓名">
        <VlInput />
      </VlForm.Item>
    </VlForm>
  );
}

如果确实要在 Server Component 里拼装静态结构,改用独立导出的 VlFormItem,不要点进 VlForm:

// app/page.tsx —— 无需 'use client'
import { VlForm, VlFormItem, VlInput } from '@vavt/react-ui';

export default function Page() {
  return (
    <VlForm>
      <VlFormItem name="name" label="姓名">
        <VlInput />
      </VlFormItem>
    </VlForm>
  );
}

VlMessageBox.alert/confirm 没有对应的独立导出——它们是命令式 API,只能在浏览器事件或客户端组件中调用。

自动按需导入

Vite 项目可安装独立的构建插件:

npm install -D @vavt/component-resolver
// vite.config.ts
import react from '@vitejs/plugin-react';
import Components from '@vavt/component-resolver';

export default {
  plugins: [react(), Components()]
};

配置后可以继续使用根入口命名导入:

import { VlButton, VlCard } from '@vavt/react-ui';

构建时会转换为 Button、Card 的组件子路径,并注入各自的样式入口 components/Button/style,不会加载其他组件样式。此时不要再手动导入全量 styles.css。

样式入口负责基础样式和跨组件样式依赖,因此不需要另外导入 base.css。例如 Table 内部会渲染 Scrollbar 与 Tooltip,只引用 Table 就会自动带上它们的样式;同页再单独使用 Tooltip 时,打包器按模块地址去重,不会产生重复规则。

插件也支持直接使用未导入的 <VlButton />;该模式需要在 tsconfig.json 的原有 types 中追加 @vavt/react-ui/global。@vavt/component-resolver 是消费端可选工具,不是本包的依赖。

受控 API 迁移

当前版本统一使用 React 语义的受控属性;这是破坏性变更,旧的 Vue 风格模型属性已移除。

| 组件 | 受控属性 | 非受控初始属性 | | -------------------------------------------------- | --------- | ---------------- | | Input、Textarea、NumberInput、Select、Slider、Tabs | value | defaultValue | | Checkbox、Switch | checked | defaultChecked | | Modal、MessageBox、Drawer、Dropdown、Tooltip | open | defaultOpen |

Checkbox 数组选择使用 VlCheckboxGroup,其 value/defaultValue 为 CheckboxValue[];Checkbox 的 onChange 返回 (value, checked)。Radio 使用 VlRadioGroup 管理单个 RadioValue,Radio 和 Switch 的事件也分别遵循各自组件的值语义。

全局注册与类型提示

在应用入口导入运行时注册和全量样式:

import '@vavt/react-ui/register';
import '@vavt/react-ui/styles.css';

在 tsconfig.json 的已有 types 中追加 @vavt/react-ui/global:

{
  "compilerOptions": {
    "types": ["vite/client", "@vavt/react-ui/global"]
  }
}

现在可以直接使用全局组件,TypeScript 会同时检查组件名和 Props:

export default function App() {
  return <VlButton status="primary">开始使用</VlButton>;
}

如果项目没有配置 compilerOptions.types,也可以在应用的 .d.ts 文件中添加:

/// <reference types="@vavt/react-ui/global" />

registerGlobalComponents() 也从包根入口导出,支持传入自定义对象;默认注册到 globalThis。全局注册会加载整个组件集合,按需场景仍建议使用组件子路径。

Peer dependencies

  • react ^18.2 || ^19
  • react-dom ^18.2 || ^19

仓库开发说明见 开发手册。