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

starry-sky-ui

v0.7.2

Published

starry-sky-ui — 轻量级 React UI 组件库

Readme

Starry Sky UI — 轻量级 React UI 组件库

license Gitee

一套轻量级 React UI 组件库,API 参考 Ant Design 标准,提供基础通用组件。
适用于博客、后台管理、个人项目等场景。

📖 文档地址:https://www.adai.org.cn/ad-ui
🏠 码云仓库:https://gitee.com/qqqsdx/starry-sky-ui

安装

npm install starry-sky-ui
# 或
yarn add starry-sky-ui
# 或
pnpm add starry-sky-ui

快速开始

import { Message, message, Select, Modal } from 'starry-sky-ui';
import type { SelectOption, ModalProps } from 'starry-sky-ui';

function App() {
  return (
    <div>
      <Message />
      <Select options={[{ label: '选项一', value: '1' }]} />
      <button onClick={() => message.success('Hello Starry Sky UI!')}>
        提示
      </button>
    </div>
  );
}

目录结构

src/components/ad-ui/
├── Message/
│   ├── index.tsx
│   └── index.scss
├── Modal/
│   ├── index.tsx
│   └── index.scss
├── Select/
│   ├── index.tsx
│   └── index.scss
├── Starfield/
│   ├── index.tsx
│   └── index.scss
├── Table/
│   ├── index.tsx
│   └── index.scss
├── Pagination/
│   ├── index.tsx
│   └── index.scss
├── types.ts          # 公共类型导出
├── index.ts          # 统一导出入口
└── README.md

Message — 消息提示

全局消息提示,支持 infosuccesserrorwarningloading 五种类型,自动消失。

基本用法

import { Message, message } from 'starry-sky-ui';

// 1. 在应用根节点挂载 Message 组件
function App() {
  return (
    <div>
      <Message />
      {/* your app */}
    </div>
  );
}

// 2. 通过 message 对象调用
message.success('操作成功');
message.error('操作失败');
message.warning('警告提示');
message.info('这是一条提示');
message.loading('加载中...', 0); // duration=0 不自动消失

// 返回的 MessageInstance 支持 then 语法
message.loading('提交中...');
await submitForm();
message.success('提交成功');

通用 open 方法

message.open({
  type: 'success',
  content: '自定义消息',
  duration: 5000,
  className: 'my-custom-class',
  style: { fontSize: 16 },
  onClose: () => console.log('closed'),
});

全局配置

message.config({
  top: 100,           // 距离顶部距离,默认 20
  duration: 5000,      // 默认显示时长,默认 3000ms
  maxCount: 3,         // 最大显示数量,超出时移除最早的消息
  getContainer: () => document.getElementById('msg-area')!,
});

销毁所有消息

message.destroy();

API 速查

| 方法 | 说明 | |------|------| | message.info(content, duration?, onClose?) | 信息提示 | | message.success(content, duration?, onClose?) | 成功提示 | | message.error(content, duration?, onClose?) | 错误提示 | | message.warning(content, duration?, onClose?) | 警告提示 | | message.loading(content, duration?, onClose?) | 加载提示 | | message.open(config) | 通用打开(支持 className/style) | | message.config(config) | 全局配置 | | message.destroy() | 销毁所有消息 |

| 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | top | number | 20 | 消息距离顶部距离 | | duration | number | 3000 | 默认自动消失时长(ms),0 为不消失 | | maxCount | number | Infinity | 最大显示数量 | | getContainer | () => HTMLElement | — | 自定义挂载容器 |


Select — 下拉选择器

通用下拉选择框,支持搜索、清除、受控/非受控、键盘导航、尺寸调整。

基本用法

import { Select } from 'starry-sky-ui';
import type { SelectOption } from 'starry-sky-ui';

const options: SelectOption[] = [
  { label: 'React', value: 'react' },
  { label: 'Vue', value: 'vue', disabled: true },
  { label: 'Angular', value: 'angular' },
];

// 非受控
<Select
  options={options}
  defaultValue="react"
  onChange={(val, option) => console.log(val, option)}
/>

// 受控
<Select
  options={options}
  value={value}
  onChange={(val) => setValue(String(val))}
  placeholder="请选择框架"
/>

搜索 & 清除

<Select
  options={options}
  showSearch                              // 启用搜索
  allowClear                              // 启用清除按钮
  filterOption={(input, opt) =>           // 自定义过滤
    opt.label.includes(input) || opt.value.toString().includes(input)
  }
  notFoundContent={<span>未找到匹配项</span>}
/>

受控展开

<Select
  options={options}
  open={open}
  onOpenChange={(o) => setOpen(o)}
/>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | options | SelectOption[] | — | 选项列表 | | value | string \| number | — | 受控:当前选中值 | | defaultValue | string \| number | — | 非受控:默认选中值 | | onChange | (value, option) => void | — | 选中回调 | | placeholder | string | '请选择' | 占位文本 | | disabled | boolean | false | 禁用 | | size | 'small' \| 'middle' \| 'large' | 'middle' | 尺寸 | | allowClear | boolean | false | 显示清除按钮 | | showSearch | boolean | false | 支持搜索过滤 | | filterOption | (input, option) => boolean | 按 label 匹配 | 自定义过滤逻辑 | | notFoundContent | ReactNode | '暂无数据' | 空数据内容 | | bordered | boolean | true | 是否显示边框 | | open | boolean | — | 受控:是否展开 | | onOpenChange | (open) => void | — | 展开变化回调 | | dropdownMatchSelectWidth | boolean | true | 下拉菜单匹配选择器宽度 | | listHeight | number | 256 | 下拉菜单最大高度 | | className | string | '' | 自定义类名 | | style | CSSProperties | — | 自定义样式 | | dropdownClassName | string | '' | 下拉菜单类名 | | onBlur | () => void | — | 失焦回调 | | onFocus | () => void | — | 聚焦回调 | | getPopupContainer | () => HTMLElement | — | 自定义下拉容器 |

类型

interface SelectOption {
  label: string;
  value: string | number;
  disabled?: boolean;
}

Modal — 弹窗

通用模态弹窗,支持标题、底部按钮、动画、确认/取消、loading 态。

基本用法

import { Modal } from 'starry-sky-ui';
import { useState } from 'react';

const [open, setOpen] = useState(false);

<Modal open={open} onClose={() => setOpen(false)} title="提示">
  <p>弹窗内容</p>
</Modal>

确认弹窗

<Modal
  open={open}
  title="确认删除"
  onOk={async () => {
    await deleteItem();
    setOpen(false);
  }}
  onCancel={() => setOpen(false)}
  confirmLoading
  okText="删除"
  cancelText="取消"
  centered
>
  <p>确定要删除此项吗?删除后不可恢复。</p>
</Modal>

自定义底部 & 隐藏关闭按钮

<Modal
  open={open}
  onClose={() => setOpen(false)}
  title="自定义"
  closable={false}           // 隐藏关闭按钮
  footer={null}               // 隐藏底部
>
  {/* 自定义内容 */}
</Modal>

<Modal
  open={open}
  title="自定义底部"
  footer={
    <div style={{ textAlign: 'center' }}>
      <button onClick={() => setOpen(false)}>我知道了</button>
    </div>
  }
>
  <p>内容</p>
</Modal>

无遮罩 & 禁止遮罩关闭

<Modal
  open={open}
  mask={false}                // 无遮罩
  maskClosable={false}        // 禁止点击遮罩关闭
  keyboard={false}            // 禁止 ESC 关闭
>
  <p>必须通过按钮关闭</p>
</Modal>

destroyOnClose

<Modal open={open} destroyOnClose>
  {/* 关闭后子节点会被销毁,适合包含表单等需要重置的场景 */}
  <ExpensiveForm />
</Modal>

afterClose

<Modal
  open={open}
  onClose={() => setOpen(false)}
  afterClose={() => console.log('弹窗已完全关闭')}
>
  <p>内容</p>
</Modal>

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | open | boolean | false | 是否显示 | | onClose | () => void | — | 关闭回调 | | onOk | () => void \| Promise<void> | — | 确认回调(支持 async) | | onCancel | () => void | — | 取消回调 | | afterClose | () => void | — | 关闭动画完成后回调 | | title | ReactNode | — | 标题 | | children | ReactNode | — | 内容 | | footer | ReactNode \| null | 默认确定/取消按钮 | 底部,null 隐藏 | | closeButton | ReactNode | — | 自定义关闭按钮 | | width | number \| string | 520 | 宽度(数字为 px) | | height | number \| string | — | 高度 | | centered | boolean | false | 垂直居中 | | mask | boolean | true | 是否显示遮罩 | | maskClosable | boolean | true | 点击遮罩是否关闭 | | closable | boolean | true | 是否显示关闭按钮 | | keyboard | boolean | true | 是否支持 ESC 关闭 | | confirmLoading | boolean | false | 确认按钮 loading 态 | | destroyOnClose | boolean | false | 关闭时销毁子节点 | | zIndex | number | 1000 | 自定义 z-index | | okText | string | '确定' | 确定按钮文案 | | cancelText | string | '取消' | 取消按钮文案 | | className | string | '' | 自定义类名 | | style | CSSProperties | — | 自定义样式 | | bodyStyle | CSSProperties | — | 内容区样式 | | getContainer | () => HTMLElement | — | 自定义容器 |


Table — 表格

功能丰富的表格组件,支持排序、分页、行选择、自定义渲染、固定表头、加载态等。

基本用法

import { Table } from 'starry-sky-ui';
import type { ColumnType } from 'starry-sky-ui';

const columns: ColumnType[] = [
  { title: '名称', dataIndex: 'name', key: 'name', sorter: (a, b) => a.name.localeCompare(b.name) },
  { title: '版本', dataIndex: 'version', key: 'version' },
  { title: '使用率', dataIndex: 'usage', key: 'usage', render: (val) => <ProgressBar value={val} /> },
];

const data = [
  { key: '1', name: 'React', version: '18.3.1', usage: '81%' },
  { key: '2', name: 'Vue', version: '3.4.0', usage: '65%' },
];

<Table
  columns={columns}
  dataSource={data}
  rowKey="key"
  pagination={{ pageSize: 10, showTotal: true }}
/>

排序

在 ColumnType 中设置 sorter 即可启用排序,支持传入排序函数或 true

const columns: ColumnType[] = [
  { title: '名称', dataIndex: 'name', sorter: (a, b) => a.name.localeCompare(b.name) },
  { title: '版本', dataIndex: 'version', sorter: true },
];

true 时会尝试默认比较,推荐传入具体的比较函数以获得准确排序。

行选择

const [selectedKeys, setSelectedKeys] = useState<string[]>([]);

<Table
  columns={columns}
  dataSource={data}
  rowKey="key"
  rowSelection={{
    selectedRowKeys: selectedKeys,
    onChange: (keys, rows) => setSelectedKeys(keys),
    getCheckboxProps: (record) => ({ disabled: record.name === 'Angular' }),
  }}
/>

加载态 & 空态

// 加载中
<Table columns={columns} dataSource={[]} loading />

// 空数据
<Table columns={columns} dataSource={[]} emptyText="暂无数据" />

// 自定义空态
<Table columns={columns} dataSource={[]} emptyText={<Empty description="暂无数据" />} />

拖拽排序

传入 onSortEnd 回调即可启用拖拽排序。拖拽完成后会返回排序后的完整数据列表。

<Table
  columns={columns}
  dataSource={data}
  rowKey="key"
  onSortEnd={(newData) => {
    console.log('排序后的数据:', newData);
    setData(newData);
  }}
/>

拖拽排序会在表格左侧自动生成拖拽手柄列,支持跨行拖拽,拖拽目标行会高亮显示虚线边框。

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | columns | ColumnType[] | — | 列定义 | | dataSource | T[] | — | 数据源 | | rowKey | string \| (record) => string | keyid | 行唯一标识 | | pagination | false \| PaginationConfig | 默认分页 | 分页配置,false 禁用 | | loading | boolean | false | 加载中 | | emptyText | ReactNode | '暂无数据' | 空数据展示 | | size | 'small' \| 'middle' \| 'large' | 'large' | 表格尺寸 | | bordered | boolean | false | 是否显示列边框 | | showHeader | boolean | true | 是否显示表头 | | rowSelection | RowSelectionType | — | 行选择配置 | | scroll | { y?: number } | — | 设置 y 固定表头 | | defaultSortBy | { columnKey, order } | — | 默认排序 | | onChange | (pagination, sorter) => void | — | 分页/排序变化回调 | | onSortEnd | (newDataSource) => void | — | 拖拽排序完成回调,入参为排序后的完整数据列表 | | onRow | (record) => { onClick, style, className } | — | 行事件与样式 | | className | string | '' | 自定义类名 |

PaginationConfig

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | current | number | — | 受控当前页 | | defaultCurrent | number | 1 | 默认当前页 | | pageSize | number | — | 受控每页条数 | | defaultPageSize | number | 10 | 默认每页条数 | | total | number | dataSource.length | 数据总量 | | showSizeChanger | boolean | false | 显示每页条数切换 | | pageSizeOptions | number[] | [10, 20, 50, 100] | 可选的每页条数 | | showTotal | boolean | false | 显示总条数 | | simple | boolean | false | 简洁模式 | | onChange | (page, pageSize) => void | — | 分页变化回调 |

ColumnType

| 属性 | 类型 | 说明 | |------|------|------| | title | string | 列标题 | | dataIndex | string | 数据字段 | | key | string | 列唯一标识 | | render | (value, record, index) => ReactNode | 自定义渲染 | | width | number \| string | 列宽度 | | align | 'left' \| 'center' \| 'right' | 对齐方式 | | sorter | boolean \| (a, b) => number | 排序函数(启用排序) | | className | string | 列类名 | | fixed | 'left' \| 'right' | 固定列 | | visible | boolean | 是否显示 | | minWidth | number | 最小宽度 |

RowSelectionType

| 属性 | 类型 | 说明 | |------|------|------| | selectedRowKeys | string[] | 受控选中 key 列表 | | defaultSelectedRowKeys | string[] | 默认选中 key 列表 | | onChange | (keys, rows) => void | 选中变化回调 | | getCheckboxProps | (record) => { disabled } | 复选框属性 | | columnWidth | number \| string | 选择列宽度 |


Pagination — 分页

分页组件,支持受控/非受控、简洁模式、每页条数切换、快速跳转、禁用态和小尺寸。

基本用法

import { Pagination } from 'starry-sky-ui';

<Pagination
  total={200}
  defaultCurrent={1}
  defaultPageSize={10}
  showTotal
  showSizeChanger
  onChange={(page, pageSize) => console.log(page, pageSize)}
/>

受控模式

const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);

<Pagination
  current={page}
  pageSize={pageSize}
  total={500}
  showTotal
  onChange={(p, s) => { setPage(p); setPageSize(s); }}
/>

简洁模式

<Pagination total={100} simple />

快速跳转

<Pagination total={500} showQuickJumper />

小尺寸

<Pagination total={200} size="small" showTotal showSizeChanger />

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | current | number | — | 受控:当前页数 | | defaultCurrent | number | 1 | 非受控:默认当前页数 | | pageSize | number | — | 受控:每页条数 | | defaultPageSize | number | 10 | 非受控:默认每页条数 | | total | number | — | 数据总数(必填) | | onChange | (page, pageSize) => void | — | 页码或 pageSize 变化回调 | | showSizeChanger | boolean | false | 是否显示每页条数切换器 | | pageSizeOptions | number[] | [10, 20, 50, 100] | 每页条数可选值 | | showTotal | boolean | false | 是否显示总条数 | | showTotalRender | (total, range) => ReactNode | — | 总条数自定义渲染 | | simple | boolean | false | 简洁模式(仅显示翻页 + 输入框) | | disabled | boolean | false | 禁用 | | showQuickJumper | boolean | false | 是否显示快速跳转输入框 | | size | 'default' \| 'small' | 'default' | 尺寸 | | className | string | '' | 自定义类名 |


Starfield — 星空背景

星空背景组件,在容器内生成随机分布的闪烁星星,支持自定义数量、颜色和闪烁速度。

基本用法

import { Starfield } from 'starry-sky-ui';

// 使用默认参数(350 颗星星,紫/蓝/白三色,3s 闪烁)
<Starfield />

// 自定义参数
<Starfield
  starCount={500}
  starColors={['#ff6b6b', '#ffd93d', '#6bcb77']}
  time={5}
  className="my-starfield"
/>

性能

  • 使用 DocumentFragment 批量追加 DOM,仅触发一次 reflow
  • 通过 CSS 自定义属性(--star-color, --star-glow)传递颜色,避免动态生成大量样式类
  • 清理时使用 innerHTML 一次性清除所有子节点

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | starCount | number | 350 | 星星数量 | | starColors | string[] | ['#8b5cf6', '#3b82f6', '#ffffff'] | 颜色列表,支持任意 CSS 合法颜色值 | | time | number | 3 | 闪烁动画最大延迟时间(秒) | | className | string | '' | 自定义类名 |


类型导出

所有组件类型均可从 starry-sky-ui 直接导入:

import type {
  SelectOption,
  SelectProps,
  ModalProps,
  MessageInstance,
  MessageOpenConfig,
  MessageGlobalConfig,
  ColumnType,
  TableProps,
  PaginationConfig,
  RowSelectionType,
  PaginationProps,
  StarfieldProps,
} from 'starry-sky-ui';