2026-05-31 18:34:36 +08:00
|
|
|
# RustUI
|
|
|
|
|
|
|
|
|
|
A modern React component library.
|
|
|
|
|
|
|
|
|
|
## Install
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npm install rustui
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
pnpm add rustui
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
yarn add rustui
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
|
import { Button, Input, Modal } from 'rustui'
|
|
|
|
|
import 'rustui/styles'
|
|
|
|
|
|
|
|
|
|
function App() {
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<Button variant="primary">Click Me</Button>
|
|
|
|
|
<Input placeholder="Type something..." />
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Theme
|
|
|
|
|
|
|
|
|
|
RustUI supports light and dark themes via `ConfigProvider`:
|
|
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
|
import { ConfigProvider } from 'rustui'
|
|
|
|
|
|
|
|
|
|
function App() {
|
|
|
|
|
return (
|
|
|
|
|
<ConfigProvider theme="dark">
|
2026-05-31 22:07:22 +08:00
|
|
|
{/* your app content */}
|
2026-05-31 18:34:36 +08:00
|
|
|
</ConfigProvider>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Components
|
|
|
|
|
|
|
|
|
|
### Common
|
|
|
|
|
|
|
|
|
|
| Component | Description |
|
|
|
|
|
|-----------|-------------|
|
|
|
|
|
| `Button` | Button component with multiple variants and sizes |
|
|
|
|
|
| `Icon` | Icon component with 100+ built-in icons |
|
|
|
|
|
| `Typography` | Typography with Text, Title, Paragraph, Link |
|
|
|
|
|
| `Affix` | Affix component to fix element on scroll |
|
|
|
|
|
| `Anchor` | Anchor navigation with links |
|
|
|
|
|
| `App` | App wrapper providing Message, Modal, Notification context |
|
|
|
|
|
| `BackTop` | Back to top button |
|
|
|
|
|
| `ConfigProvider` | Global configuration provider for theme and locale |
|
|
|
|
|
| `FloatButton` | Floating action button with group support |
|
|
|
|
|
| `Watermark` | Watermark overlay |
|
|
|
|
|
|
|
|
|
|
### Layout
|
|
|
|
|
|
|
|
|
|
| Component | Description |
|
|
|
|
|
|-----------|-------------|
|
|
|
|
|
| `Layout` | Page layout with Header, Footer, Content, Sider |
|
|
|
|
|
| `Divider` | Divider line |
|
|
|
|
|
| `Flex` | Flexbox layout |
|
|
|
|
|
| `HStack` | Horizontal stack layout |
|
|
|
|
|
| `VStack` | Vertical stack layout |
|
|
|
|
|
| `Row` / `Col` | Grid system with 24 columns |
|
|
|
|
|
| `Masonry` | Masonry/waterfall layout |
|
|
|
|
|
| `Space` | Consistent spacing between elements |
|
|
|
|
|
| `Splitter` | Resizable split panels |
|
|
|
|
|
| `Stack` | Stack layout |
|
|
|
|
|
|
|
|
|
|
### Navigation
|
|
|
|
|
|
|
|
|
|
| Component | Description |
|
|
|
|
|
|-----------|-------------|
|
|
|
|
|
| `Breadcrumb` | Breadcrumb navigation |
|
|
|
|
|
| `Dropdown` | Dropdown menu |
|
|
|
|
|
| `Menu` | Navigation menu |
|
|
|
|
|
| `Pagination` | Pagination controls |
|
|
|
|
|
| `Steps` | Step-by-step navigation |
|
|
|
|
|
| `Tabs` | Tabbed content |
|
|
|
|
|
|
|
|
|
|
### Data Entry
|
|
|
|
|
|
|
|
|
|
| Component | Description |
|
|
|
|
|
|-----------|-------------|
|
|
|
|
|
| `Form` | Form with validation support |
|
|
|
|
|
| `Input` | Text input with password and search variants |
|
|
|
|
|
| `TextArea` | Multi-line text input |
|
|
|
|
|
| `InputNumber` | Numeric input with step controls |
|
|
|
|
|
| `AutoComplete` | Input with autocomplete suggestions |
|
|
|
|
|
| `Select` | Dropdown selector |
|
|
|
|
|
| `Cascader` | Cascading selector |
|
|
|
|
|
| `TreeSelect` | Tree-structured selector |
|
|
|
|
|
| `Checkbox` | Checkbox with group support |
|
|
|
|
|
| `Radio` | Radio button with group support |
|
|
|
|
|
| `Switch` | Toggle switch |
|
|
|
|
|
| `Slider` | Slider input |
|
|
|
|
|
| `Transfer` | Dual-list transfer |
|
|
|
|
|
| `DatePicker` | Date picker |
|
|
|
|
|
| `RangePicker` | Date range picker |
|
|
|
|
|
| `TimePicker` | Time picker |
|
|
|
|
|
| `Upload` | File upload with drag support |
|
|
|
|
|
| `Rate` | Star rating |
|
|
|
|
|
| `Mention` | @ mention input |
|
|
|
|
|
|
|
|
|
|
### Feedback
|
|
|
|
|
|
|
|
|
|
| Component | Description |
|
|
|
|
|
|-----------|-------------|
|
|
|
|
|
| `Alert` | Alert banner |
|
|
|
|
|
| `Drawer` | Side drawer panel |
|
|
|
|
|
| `Message` | Global message toast |
|
|
|
|
|
| `Modal` | Dialog modal |
|
|
|
|
|
| `Notification` | Notification notification box |
|
|
|
|
|
| `Popconfirm` | Popover confirmation |
|
|
|
|
|
| `Progress` | Progress indicator |
|
|
|
|
|
| `Result` | Result page |
|
|
|
|
|
| `Skeleton` | Content placeholder skeleton |
|
|
|
|
|
| `Spin` | Loading spinner |
|
|
|
|
|
|
|
|
|
|
### Display
|
|
|
|
|
|
|
|
|
|
| Component | Description |
|
|
|
|
|
|-----------|-------------|
|
|
|
|
|
| `Avatar` / `AvatarGroup` | User avatar with group |
|
|
|
|
|
| `Badge` / `BadgeRibbon` | Status badge and ribbon |
|
|
|
|
|
| `Tag` / `CheckableTag` | Tag label |
|
|
|
|
|
| `Tooltip` | Tooltip on hover |
|
|
|
|
|
| `Popover` | Popover card |
|
|
|
|
|
| `Card` / `CardGrid` / `CardMeta` | Content card |
|
|
|
|
|
| `Empty` | Empty state placeholder |
|
|
|
|
|
| `Statistic` / `StatisticTimer` | Statistic number display |
|
|
|
|
|
| `Collapse` | Collapsible panels |
|
|
|
|
|
| `Timeline` | Timeline display |
|
|
|
|
|
| `Descriptions` | Key-value description list |
|
|
|
|
|
| `Segmented` | Segmented control |
|
|
|
|
|
| `Table` | Data table with sorting, filtering, selection |
|
|
|
|
|
| `Tree` | Tree view |
|
|
|
|
|
| `Carousel` | Image/content carousel |
|
|
|
|
|
| `Image` / `ImagePreviewGroup` | Image with preview |
|
|
|
|
|
| `Calendar` | Calendar view |
|
|
|
|
|
| `QRCode` | QR code generator |
|
|
|
|
|
| `Tour` | Guided tour |
|
|
|
|
|
| `List` | Data list |
|
|
|
|
|
|
|
|
|
|
## API Reference
|
|
|
|
|
|
|
|
|
|
### Button
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `variant` | `'primary' \| 'default' \| 'dashed' \| 'text' \| 'link'` | `'default'` | Button style variant |
|
|
|
|
|
| `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | Button size |
|
|
|
|
|
| `disabled` | `boolean` | `false` | Whether the button is disabled |
|
|
|
|
|
| `loading` | `boolean` | `false` | Show loading spinner |
|
|
|
|
|
| `danger` | `boolean` | `false` | Danger style |
|
|
|
|
|
| `block` | `boolean` | `false` | Full width button |
|
|
|
|
|
| `icon` | `ReactNode` | - | Icon element |
|
|
|
|
|
| `onClick` | `(e: MouseEvent) => void` | - | Click handler |
|
|
|
|
|
|
|
|
|
|
### Input
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `value` | `string` | - | Input value (controlled) |
|
|
|
|
|
| `defaultValue` | `string` | - | Default value |
|
|
|
|
|
| `placeholder` | `string` | - | Placeholder text |
|
|
|
|
|
| `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | Input size |
|
|
|
|
|
| `status` | `'default' \| 'error' \| 'warning'` | `'default'` | Validation status |
|
|
|
|
|
| `disabled` | `boolean` | `false` | Whether the input is disabled |
|
|
|
|
|
| `readOnly` | `boolean` | `false` | Read only |
|
|
|
|
|
| `prefix` | `ReactNode` | - | Prefix icon/element |
|
|
|
|
|
| `suffix` | `ReactNode` | - | Suffix icon/element |
|
|
|
|
|
| `onChange` | `(e: ChangeEvent) => void` | - | Change handler |
|
|
|
|
|
|
|
|
|
|
### Modal
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `open` | `boolean` | `false` | Whether the modal is visible |
|
|
|
|
|
| `title` | `ReactNode` | - | Modal title |
|
|
|
|
|
| `footer` | `ReactNode \| null` | - | Footer content, `null` to hide |
|
|
|
|
|
| `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | Modal size |
|
|
|
|
|
| `closable` | `boolean` | `true` | Show close button |
|
|
|
|
|
| `centered` | `boolean` | `false` | Vertically center the modal |
|
|
|
|
|
| `mask` | `boolean` | `true` | Show mask overlay |
|
|
|
|
|
| `maskClosable` | `boolean` | `true` | Close on mask click |
|
|
|
|
|
| `keyboard` | `boolean` | `true` | Close on ESC key |
|
|
|
|
|
| `confirmLoading` | `boolean` | `false` | Loading state for confirm button |
|
|
|
|
|
| `okText` | `ReactNode` | - | Confirm button text |
|
|
|
|
|
| `cancelText` | `ReactNode` | - | Cancel button text |
|
|
|
|
|
| `onOk` | `(e: MouseEvent) => void` | - | Confirm handler |
|
|
|
|
|
| `onCancel` | `(e: MouseEvent) => void` | - | Cancel handler |
|
|
|
|
|
|
|
|
|
|
### Form
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `initialValues` | `Record<string, any>` | - | Initial form values |
|
|
|
|
|
| `onFinish` | `(values: Record<string, any>) => void` | - | Submit handler (validation passed) |
|
|
|
|
|
| `onFinishFailed` | `(errors: FormErrorInfo) => void` | - | Submit handler (validation failed) |
|
|
|
|
|
| `layout` | `'horizontal' \| 'vertical' \| 'inline'` | `'horizontal'` | Form layout |
|
|
|
|
|
|
|
|
|
|
#### Form.Item
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `name` | `string` | - | Field name |
|
|
|
|
|
| `label` | `ReactNode` | - | Field label |
|
|
|
|
|
| `rules` | `ValidationRule[]` | - | Validation rules |
|
|
|
|
|
| `required` | `boolean` | `false` | Whether the field is required |
|
|
|
|
|
|
|
|
|
|
### Select
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `value` | `string \| string[]` | - | Selected value (controlled) |
|
|
|
|
|
| `options` | `SelectOption[]` | - | Options list |
|
|
|
|
|
| `mode` | `'single' \| 'multiple' \| 'tags'` | `'single'` | Selection mode |
|
|
|
|
|
| `placeholder` | `string` | - | Placeholder text |
|
|
|
|
|
| `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | Select size |
|
|
|
|
|
| `disabled` | `boolean` | `false` | Whether the select is disabled |
|
|
|
|
|
| `showSearch` | `boolean` | `false` | Enable search filtering |
|
|
|
|
|
| `showClear` | `boolean` | `false` | Show clear button |
|
|
|
|
|
| `onChange` | `(value, option) => void` | - | Change handler |
|
|
|
|
|
|
|
|
|
|
### Table
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `dataSource` | `T[]` | `[]` | Data array |
|
|
|
|
|
| `columns` | `ColumnType<T>[]` | - | Column definitions |
|
|
|
|
|
| `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | Table size |
|
|
|
|
|
| `variant` | `'bordered' \| 'borderless'` | `'bordered'` | Table variant |
|
|
|
|
|
| `loading` | `boolean` | `false` | Loading state |
|
|
|
|
|
| `rowKey` | `string \| ((record) => string)` | - | Row key field |
|
|
|
|
|
| `rowSelection` | `RowSelectionConfig` | - | Row selection config |
|
|
|
|
|
| `pagination` | `PaginationConfig \| false` | - | Pagination config |
|
|
|
|
|
|
|
|
|
|
### Message
|
|
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
|
import { Message } from 'rustui'
|
|
|
|
|
|
|
|
|
|
Message.success('Operation completed')
|
|
|
|
|
Message.error('Something went wrong')
|
|
|
|
|
Message.warning('Warning message')
|
|
|
|
|
Message.info('Info message')
|
|
|
|
|
Message.loading('Loading...')
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
| Method | Description |
|
|
|
|
|
|--------|-------------|
|
|
|
|
|
| `Message.success(content, duration?)` | Success message |
|
|
|
|
|
| `Message.error(content, duration?)` | Error message |
|
|
|
|
|
| `Message.warning(content, duration?)` | Warning message |
|
|
|
|
|
| `Message.info(content, duration?)` | Info message |
|
|
|
|
|
| `Message.loading(content, duration?)` | Loading message |
|
|
|
|
|
|
|
|
|
|
### Notification
|
|
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
|
import { Notification } from 'rustui'
|
|
|
|
|
|
|
|
|
|
Notification.open({ message: 'Title', description: 'Description' })
|
|
|
|
|
Notification.success({ message: 'Success', description: 'Operation completed' })
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Icon
|
|
|
|
|
|
|
|
|
|
RustUI includes 100+ built-in icons. All icons follow the `XxxOutlined` / `XxxFilled` / `XxxTwoTone` naming convention:
|
|
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
|
import { SearchOutlined, StarFilled, HeartTwoTone } from 'rustui'
|
|
|
|
|
|
|
|
|
|
<SearchOutlined />
|
|
|
|
|
<StarFilled style={{ color: 'gold' }} />
|
|
|
|
|
<HeartTwoTone twoToneColor="#eb2f96" />
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `spin` | `boolean` | `false` | Rotate icon animation |
|
|
|
|
|
| `rotate` | `number` | `0` | Rotation degrees |
|
|
|
|
|
| `style` | `CSSProperties` | - | Custom styles |
|
|
|
|
|
| `onClick` | `(e: MouseEvent) => void` | - | Click handler |
|
|
|
|
|
|
|
|
|
|
Custom icon from SVG:
|
|
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
|
import { Icon } from 'rustui'
|
|
|
|
|
|
|
|
|
|
const SvgIcon = () => (
|
|
|
|
|
<Icon component={() => <svg>...</svg>} />
|
|
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Icon from iconfont:
|
|
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
|
import { createFromIconfontCN } from 'rustui'
|
|
|
|
|
|
|
|
|
|
const IconFont = createFromIconfontCN({
|
|
|
|
|
scriptUrl: '//at.alicdn.com/t/font_xxx.js'
|
|
|
|
|
})
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### ConfigProvider
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `theme` | `'light' \| 'dark'` | `'light'` | Theme mode |
|
|
|
|
|
| `locale` | `Locale` | - | Locale configuration |
|
|
|
|
|
| `prefixCls` | `string` | - | CSS class prefix |
|
|
|
|
|
|
|
|
|
|
### DatePicker
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `value` | `string \| null` | - | Selected date value (controlled), format `YYYY-MM-DD` |
|
|
|
|
|
| `defaultValue` | `string \| null` | - | Default date value |
|
|
|
|
|
| `placeholder` | `string` | `'选择日期'` | Placeholder text |
|
|
|
|
|
| `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | Picker size |
|
|
|
|
|
| `status` | `'default' \| 'error' \| 'warning'` | `'default'` | Validation status |
|
|
|
|
|
| `disabled` | `boolean` | `false` | Whether the picker is disabled |
|
|
|
|
|
| `showTime` | `boolean` | `false` | Show time selection |
|
|
|
|
|
| `disabledDate` | `(date: Date) => boolean` | - | Disable specific dates |
|
|
|
|
|
| `onChange` | `(value: string, date: Date) => void` | - | Date change handler |
|
|
|
|
|
|
|
|
|
|
### Upload
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `action` | `string` | - | Upload URL |
|
|
|
|
|
| `method` | `string` | `'post'` | HTTP method |
|
|
|
|
|
| `accept` | `string` | - | Accepted file types |
|
|
|
|
|
| `multiple` | `boolean` | `false` | Allow multiple file selection |
|
|
|
|
|
| `draggable` | `boolean` | `false` | Enable drag-and-drop upload |
|
|
|
|
|
| `disabled` | `boolean` | `false` | Whether the upload is disabled |
|
|
|
|
|
| `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | Upload area size |
|
|
|
|
|
| `showUploadList` | `boolean` | `true` | Show file list |
|
|
|
|
|
| `fileList` | `UploadFile[]` | - | File list (controlled) |
|
|
|
|
|
| `defaultFileList` | `UploadFile[]` | `[]` | Default file list |
|
|
|
|
|
| `maxCount` | `number` | - | Max upload count |
|
|
|
|
|
| `onChange` | `(file: UploadFile, fileList: UploadFile[]) => void` | - | File status change handler |
|
|
|
|
|
| `onRemove` | `(file: UploadFile) => boolean \| void` | - | File remove handler, return `false` to prevent |
|
|
|
|
|
| `beforeUpload` | `(file: File, fileList: File[]) => boolean \| void \| Promise<boolean \| void>` | - | Pre-upload hook, return `false` to cancel |
|
|
|
|
|
|
|
|
|
|
#### UploadFile
|
|
|
|
|
|
|
|
|
|
| Field | Type | Description |
|
|
|
|
|
|-------|------|-------------|
|
|
|
|
|
| `uid` | `string` | Unique file identifier |
|
|
|
|
|
| `name` | `string` | File name |
|
|
|
|
|
| `status` | `'pending' \| 'uploading' \| 'success' \| 'error'` | Upload status |
|
|
|
|
|
| `percent` | `number` | Upload progress (0-100) |
|
|
|
|
|
| `url` | `string` | File access URL |
|
|
|
|
|
| `response` | `unknown` | Upload response data |
|
|
|
|
|
| `error` | `string` | Error message |
|
|
|
|
|
|
|
|
|
|
### Drawer
|
|
|
|
|
|
|
|
|
|
| Prop | Type | Default | Description |
|
|
|
|
|
|------|------|---------|-------------|
|
|
|
|
|
| `open` | `boolean` | `false` | Whether the drawer is visible |
|
|
|
|
|
| `title` | `ReactNode` | - | Drawer title |
|
|
|
|
|
| `footer` | `ReactNode \| null` | - | Footer content, `null` to hide |
|
|
|
|
|
| `placement` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'right'` | Drawer placement |
|
|
|
|
|
| `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | Drawer size (378/480/736px) |
|
|
|
|
|
| `width` | `number \| string` | - | Custom width (for left/right placement) |
|
|
|
|
|
| `height` | `number \| string` | - | Custom height (for top/bottom placement) |
|
|
|
|
|
| `closable` | `boolean` | `true` | Show close button |
|
|
|
|
|
| `closeIcon` | `ReactNode` | - | Custom close icon |
|
|
|
|
|
| `mask` | `boolean` | `true` | Show mask overlay |
|
|
|
|
|
| `maskClosable` | `boolean` | `true` | Close on mask click |
|
|
|
|
|
| `keyboard` | `boolean` | `true` | Close on ESC key |
|
|
|
|
|
| `loading` | `boolean` | `false` | Loading state |
|
|
|
|
|
| `extra` | `ReactNode` | - | Extra content in header |
|
|
|
|
|
| `destroyOnClose` | `boolean` | `false` | Destroy content when closed |
|
|
|
|
|
| `forceRender` | `boolean` | `false` | Force render content even when hidden |
|
|
|
|
|
| `push` | `boolean \| { distance?: number \| string }` | `false` | Push behavior when nested drawers |
|
|
|
|
|
| `zIndex` | `number` | - | Z-index of the drawer |
|
|
|
|
|
| `onClose` | `(e: MouseEvent) => void` | - | Close handler |
|
|
|
|
|
| `afterOpenChange` | `(open: boolean) => void` | - | Callback after open state changed |
|
|
|
|
|
|
|
|
|
|
## Development
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# Install dependencies
|
|
|
|
|
pnpm install
|
|
|
|
|
|
|
|
|
|
# Start dev server
|
|
|
|
|
pnpm dev
|
|
|
|
|
|
|
|
|
|
# Build
|
|
|
|
|
pnpm build
|
|
|
|
|
|
|
|
|
|
# Run tests
|
|
|
|
|
pnpm test
|
|
|
|
|
|
|
|
|
|
# Lint
|
|
|
|
|
pnpm lint
|
|
|
|
|
|
|
|
|
|
# Format
|
|
|
|
|
pnpm format
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## License
|
|
|
|
|
|
|
|
|
|
MIT
|