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

@canvas-components/react-components

v0.3.33

Published

Shared React UI primitives for canvas-components adapters.

Readme

@canvas-components/react-components

@canvas-components/react-components 提供一组为表格适配层和业务表单场景准备的 React 基础组件,包含输入类组件、弹层、过渡、虚拟列表、分页和图片预览等能力。

功能作用

  • 提供统一风格的 React 基础交互组件
  • 为 @canvas-components/react-list-table 提供编辑器、弹层和辅助 UI
  • 暴露 Popup、Popconfirm、Transition、VirtualList 等可独立复用组件

安装方法

pnpm add @canvas-components/react-components react@^16.8 react-dom@^16.8

最低依赖版本:

  • react >= 16.8.0
  • react-dom >= 16.8.0
  • Node.js >= 18.12.0
  • pnpm >= 9.0.0

使用方法

import {
  ReactHomeOutlined,
  ReactIcon,
  ReactPopconfirm,
  ReactPopup,
  ReactTransition,
} from "@canvas-components/react-components";

function Demo() {
  return (
    <>
      <ReactIcon name="HomeOutlined" size={20} aria-label="首页" />
      <ReactHomeOutlined size={20} aria-hidden="true" />
      <ReactPopconfirm
        title="确认删除这条记录?"
        description="删除后不可恢复"
        onConfirm={() => console.log("confirmed")}
      >
        <button type="button">删除</button>
      </ReactPopconfirm>
    </>
  );
}

表单组件

组件可作为受控输入使用,也可以放进普通 HTML 表单或 ReactForm 中。以下示例组合文本框、可搜索选择器、日期选择器、复选框、按钮和确认气泡:

import { useState } from "react";
import {
  ReactButton,
  ReactCheckbox,
  ReactDatePicker,
  ReactFlex,
  ReactInput,
  ReactPopconfirm,
  ReactSelect,
} from "@canvas-components/react-components";

export function ProfileForm() {
  const [name, setName] = useState("林晨");
  const [team, setTeam] = useState("design");
  const [date, setDate] = useState("2026-10-18");
  const [subscribed, setSubscribed] = useState(true);

  return (
    <form onSubmit={(event) => event.preventDefault()}>
      <label>
        姓名
        <ReactInput
          value={name}
          onChange={(event) => setName(event.currentTarget.value)}
        />
      </label>
      <label>
        团队
        <ReactSelect
          value={team}
          showSearch
          options={[
            { value: "design", label: "设计团队" },
            { value: "engineering", label: "研发团队" },
          ]}
          onChange={setTeam}
        />
      </label>
      <ReactDatePicker value={date} onChange={setDate} />
      <ReactCheckbox
        checked={subscribed}
        onChange={(event) => setSubscribed(event.currentTarget.checked)}
      >
        接收团队动态
      </ReactCheckbox>
      <ReactFlex gap={8}>
        <ReactButton type="primary" htmlType="submit">
          保存
        </ReactButton>
        <ReactPopconfirm title="确认删除?" onConfirm={() => setName("")}>
          <ReactButton danger>删除</ReactButton>
        </ReactPopconfirm>
      </ReactFlex>
    </form>
  );
}

文档站「React Components」目录为每个组件提供了独立示例,包含组件用途、属性说明和可复制的 JSX 用法;图标目录也列出全部具名图标。

ReactSelect 的暗色模式通过 ReactConfigProvider 配置。输入框与挂载到页面外层的下拉面板会使用同一组颜色:

import {
  ReactConfigProvider,
  ReactSelect,
} from "@canvas-components/react-components";

<ReactConfigProvider
  theme={{
    colorScheme: "dark",
    colorText: "#e8ebee",
    colorTextSecondary: "#a4adb5",
    colorBorder: "#3b4348",
    colorBackground: "#24282d",
    colorBackgroundSoft: "#2b3035",
    colorBackgroundHover: "#30363b",
    colorBackgroundActive: "#263e59",
  }}
>
  <ReactSelect options={[{ label: "选项一", value: "one" }]} />
</ReactConfigProvider>;

组件列表

表单与选择

  • ReactInput
  • ReactInputNumber
  • ReactInputRange
  • ReactCheckbox
  • ReactRadio
  • ReactSelect
  • ReactAutoComplete
  • ReactCascader
  • ReactTreeSelect
  • ReactColorPicker
  • ReactTextArea
  • ReactForm

ReactInputNumber 和 ReactInputRange 默认不使用鼠标滚轮调整数值;需要该行为时传入 changeOnWheel,例如 <ReactInputNumber value={count} onChange={setCount} changeOnWheel />。

日期时间

  • ReactDatePicker
  • ReactDateRangePicker
  • ReactDateTimePicker
  • ReactDateTimeRangePicker
  • ReactTimePicker
  • ReactTimeRangePicker
  • ReactMonthPicker
  • ReactQuarterPicker
  • ReactYearPicker

弹层与反馈

  • ReactPopup
  • ReactDropdown
  • ReactModal
  • ReactDrawer
  • ReactPopconfirm
  • ReactTooltip
  • ReactTransition
  • reactMessage

展示、布局与交互

  • ReactPagination
  • ReactVirtualList
  • ReactWaterfall
  • ReactResizablePanels
  • ReactImagePreview
  • ReactButton
  • ReactTag
  • ReactIcon 与 831 个内置 SVG 图标(例如 ReactHomeOutlined)
  • ReactFlex / ReactRow / ReactCol
  • ReactFilterPanel

属性说明

ReactPagination

<ReactPagination
  current={current}
  total={1000}
  pageSize={pageSize}
  showSizeChanger
  allowPageSizeInput
  minPageSize={5}
  maxPageSize={500}
  onChange={setCurrent}
  onPageSizeChange={(page, size) => {
    setCurrent(page);
    setPageSize(size);
  }}
/>

allowPageSizeInput 默认关闭。开启后可在每页条数下拉框中输入正整数,按回车或失焦提交;合法值触发 onPageSizeChange(1, size),并在当前组件挂载期间作为去重、升序的候选项保留,切换到其他条数后仍可再次选择。空候选列表也支持输入。自定义选项右侧可点击删除,预设选项和默认每页 10 条不可删除;删除当前选中的自定义项时回到每页 10 条并切回第 1 页,若 10 超出配置范围则取范围内最近的值。删除其他项不改变当前分页,删除后仍可重新输入该值。

minPageSize 默认 1,maxPageSize 默认 Number.MAX_SAFE_INTEGER,上下限均包含边界。非法或越界输入不触发变更,失焦恢复当前值;范围外的候选项不可选择。无效的上下限使用默认值,最大值小于最小值时按最小值处理。组件不会主动修改外部传入的当前 pageSize。

ReactTag

<ReactTag closeLabel="移除标题" onClose={() => removeTag("title")}>
  标题
</ReactTag>

children 可放文字或其他 React 内容;省略 onClose 时只展示标签。可用 className、style 和原生 span 属性调整外观。移除按钮使用 type="button",在表单中不会触发提交。

ReactDropdown

<ReactDropdown
  items={[
    { key: "json", label: "导出 JSON" },
    { key: "pdf", label: "导出 PDF", description: "实验性功能" },
  ]}
  onSelect={(key) => exportFile(key)}
>
  导出
</ReactDropdown>

children 可省略;只传 icon 时触发按钮显示居中的图标,建议同时通过 triggerProps 提供 aria-label。菜单项支持禁用、图标、说明、拖拽事件和指针进入事件。可用 open、defaultOpen、onOpenChange 控制展开状态;支持方向键、Home、End 和 Esc。

ReactPopupProps

| 属性 | 类型 | 说明 | | ------------------ | ---------------------------------------------------------------------------------------------------------------------- | ------------------ | | open | boolean | 是否显示 | | anchorRef | RefObject<HTMLElement \| null> | 锚点元素引用 | | anchorRect | PopupAnchorRect \| null | 外部传入的锚点矩形 | | placement | "bottomLeft" \| "bottomRight" \| "topLeft" \| "topRight" \| "rightTop" \| "rightBottom" \| "leftTop" \| "leftBottom" | 弹层位置 | | offset | number | 与锚点间距 | | matchAnchorWidth | boolean | 是否跟随锚点宽度 | | minWidth | number | 最小宽度 | | zIndex | number | 层级 | | className | string | 外层类名 | | surfaceClassName | string | 面板类名 | | style | CSSProperties | 外层样式 | | surfaceStyle | CSSProperties | 面板样式 | | onOpenChange | (open: boolean) => void | 打开状态变化回调 | | children | ReactNode | 弹层内容 |

ReactPopconfirmProps

| 属性 | 类型 | 说明 | | ------------------------------------- | ---------------------------------- | ---------------------------------- | | children | ReactNode | 触发器内容 | | title | ReactNode | 标题 | | description | ReactNode | 描述文本 | | open / defaultOpen | boolean | 受控 / 非受控打开状态 | | disabled | boolean | 是否禁用 | | placement | ReactPopconfirmPlacement | 弹层位置 | | offset | number | 触发器与弹层间距 | | zIndex | number | 层级 | | icon | ReactNode | 自定义图标,传 null 隐藏默认图标 | | okText / cancelText | ReactNode | 按钮文案 | | showCancel | boolean | 是否显示取消按钮 | | confirmLoading | boolean | 是否强制确认按钮 loading | | okButtonProps / cancelButtonProps | ReactPopconfirmButtonProps | 按钮透传属性 | | onConfirm | (event) => void \| Promise<void> | 点击确认回调,支持异步 | | onCancel | (event) => void | 点击取消回调 | | onOpenChange | (open: boolean) => void | 状态变化回调 | | className / style | string / CSSProperties | 触发器样式 | | popupClassName / popupStyle | string / CSSProperties | 弹层面板样式 |

ReactTransitionProps

| 属性 | 类型 | 说明 | | ---------- | ---------------------------------------------- | ------------------------ | | show | boolean | 是否显示内容 | | name | string | CSS 类名前缀 | | duration | number \| { enter?: number; leave?: number } | 动画时长 | | appear | boolean | 首次显示是否执行进入动画 | | children | (state: ReactTransitionState) => ReactNode | 根据阶段渲染内容 |

ReactVirtualListProps<Item>

| 属性 | 类型 | 说明 | | ------------ | ----------------------------------- | ---------- | | items | Item[] | 数据列表 | | height | number | 视口高度 | | itemHeight | number | 固定项高度 | | overscan | number | 预渲染项数 | | renderItem | (item, index, meta) => ReactNode | 渲染函数 | | itemKey | (item, index) => string \| number | 列表 key |

方法说明

ReactTransition

| 导出 | 说明 | | -------------------- | -------------------------------------- | | ReactTransition | 无包装过渡组件,离场动画结束后自动卸载 | | useReactTransition | 获取 Vue 风格过渡阶段和 className |

ReactVirtualListRef

| 方法 | 说明 | | --------------- | -------------- | | scrollTo | 滚动到指定位置 | | scrollToIndex | 滚动到指定索引 |

其他导出

| 导出 | 说明 | | ---------------------------------------------------- | -------------- | | ReactContentScaleProvider / useReactContentScale | 内容缩放上下文 | | REACT_COMPONENT_PREFIX | 统一类名前缀 |

说明

这个包的导出面比较大,输入类组件大多保持接近原生表单语义;如果需要精确字段,请优先查看对应组件的 Props 类型定义。

图标组件使用包内自包含的 SVG 路径数据,不需要安装额外图标运行时或图标数据包。图标名称、尺寸、颜色、旋转和加载动画由 ReactIconProps 提供;也可以直接使用 ReactHomeOutlined 等具名组件。SVG 路径数据的上游许可和版权信息见随包发布的 THIRD_PARTY_NOTICES.md。

通用折叠面板

ReactCollapsePanel 使用现有方向图标,支持鼠标及 Enter / 空格展开折叠。折叠时保留内容节点和输入草稿。

<ReactCollapsePanel title="位置与尺寸" defaultOpen>
  <ReactInput placeholder="输入名称" />
</ReactCollapsePanel>

通过 open 与 onOpenChange 控制展开状态;disabled 禁止切换,contentClassName 可定制内容区样式。默认收起。

通用拖拽排序

ReactSortableList 统一提供与 ListTable 工具栏列排序一致的浮动行、实时让位动画、边缘自动滚动和全屏浮层。通过 items(包含 key、parentKey、label)、renderItem(item, handleProps) 和 onOrderChange(parentKey, orderedKeys) 接入;把 handleProps 传给使用现有图标的拖拽手柄。scrollContainerRef 指向滚动容器,disabled 禁止拖拽,dragThreshold 默认 4px。Esc、失焦和指针取消会丢弃排序,放下才提交一次顺序。后续拖拽排序统一复用此组件。

大量节点可传入 virtual={{ height: 360, itemHeight: 34, overscan: 6 }} 启用固定行高虚拟列表;组件使用内部滚动容器自动滚动,拖拽命中按完整列表计算,包含尚未挂载的节点。

SelectColor 颜色选择框

ReactSelectColor(别名 SelectColor)在左侧显示颜色名称,右侧显示颜色块,支持搜索、清空、禁用选项与键盘选择,其他属性沿用 ReactSelect。ref 指向输入框。

<ReactSelectColor
  value={color}
  onChange={setColor}
  showSearch
  options={[
    { label: "海蓝", value: "blue", color: "#1677ff" },
    { label: "草绿", value: "#52c41a" },
  ]}
/>

选项的 label 为颜色名称、value 为业务值;可选 color 为 CSS 颜色,未传时使用 value。onChange 与 ReactSelect 一致返回字符串值,第二参数包含触发来源。