---
title: 开发文档
order: 3
category: atom
---

# PisellImport 开发文档

## 1. 基本信息

| 项目     | 内容                      |
| -------- | ------------------------- |
| 组件名称 | PisellImport              |
| 组件分类 | 原子组件 (atom) / Data Entry |
| 技术栈   | React + TypeScript + Less |
| 依赖组件 | IconFont（内置图标）、input[type=file] 隐藏触发 |

## 2. 组件描述

PisellImport 是导入功能的 UI 触发器组件，提供「仅图标」与「图标+文案」两种展示形态，支持小/中/大三种尺寸与默认、主色、禁用等状态。点击后打开系统文件选择框，可选择文件并做类型（accept）、大小（maxSize）校验，通过后通过 `onImport(files)` 回调将文件列表交给调用方处理上传或解析；校验失败时通过 `onError` 回调通知。

**核心特点**：

- 两种展示形态：Icon 样式、Button 样式（icon + 文案）
- 与 PisellExport 一致的六种交互状态样式与三种尺寸
- 隐藏的 `<input type="file">` 由按钮点击触发，支持 accept、multiple、maxSize 校验
- 不内置上传/解析逻辑，由调用方在 onImport 中实现

## 3. 需求点罗列

### 3.1 UI 展示

- [x] 支持 Icon 样式（仅图标）
- [x] 支持 Button 样式（图标 + 文案）
- [x] 支持小、中、大三种尺寸
- [x] 六种状态样式：默认、悬浮、focused、激活、禁用、激活禁用
- [x] 默认图标为 upload-cloud-01 语义（可由 icon 覆盖）

### 3.2 功能

- [x] 点击触发隐藏 input[type=file]，选择文件后回调 `onImport(files, e)`
- [x] 支持 `accept` 限制文件类型
- [x] 支持 `multiple` 多选
- [x] 支持 `maxSize`（MB）单文件大小校验，超限时调用 `onError` 不调用 onImport
- [x] 支持 `disabled` 禁用
- [x] 支持自定义文案 `label`、自定义图标 `icon`

### 3.3 扩展

- [x] 支持 `className`、`style`

## 4. 组件 API

### 4.1 Props 定义

| 属性       | 类型        | 默认值    | 必填 | 说明 |
| ---------- | ----------- | --------- | ---- | ---- |
| variant    | VariantType | 'button'  | 否   | 展示形态：icon / button |
| size       | SizeType    | 'medium'  | 否   | 尺寸：small / medium / large |
| type       | ImportButtonType | 'default' | 否 | 视觉类型：default / primary |
| disabled   | boolean     | false     | 否   | 是否禁用 |
| label      | ReactNode   | getText 或默认导入文案 | 否 | Button 形态文案 |
| icon       | ReactNode   | 内置上传图标 | 否 | 自定义图标 |
| accept     | string      | -         | 否   | 接受的文件类型，如 ".xlsx,.csv" |
| multiple   | boolean     | false     | 否   | 是否多选文件 |
| maxSize    | number      | -         | 否   | 单文件最大体积（MB），超限触发 onError |
| onImport   | (files: File[], e: ChangeEvent) => void | - | 否 | 选择并校验通过后回调 |
| onError    | (error: { type: 'MAX_SIZE'; message: string; file: File }) => void | - | 否 | 校验失败时回调（如超限） |
| className  | string      | -         | 否   | 自定义类名 |
| style      | CSSProperties | -       | 否   | 自定义样式 |

### 4.2 类型定义

```
type VariantType = 'icon' | 'button';
type SizeType = 'small' | 'medium' | 'large';
type ImportButtonType = 'default' | 'primary';
```

## 5. 组件模块拆解

```
pisellImport/
├── index.tsx                      # 组件导出入口
├── PisellImport.tsx               # 组件核心实现（按钮 + 隐藏 input）
├── PisellImport.less              # 组件样式（与 Export 一致）
├── types.ts                       # TypeScript 类型定义
└── docs/
    ├── pisellImport.md
    ├── pisellImport.$tab-design.md
    ├── pisellImport.$tab-dev.md
    └── pisellImport.$tab-test.md
```

### 5.1 模块职责

| 模块             | 职责 |
| ---------------- | ---- |
| PisellImport.tsx | 渲染 button + 隐藏 input；点击 button 触发 input.click()；onChange 中做 maxSize 校验，通过则 onImport(fileList, e)，超限则 onError；应用 variant/size/type/disabled 类名 |
| PisellImport.less| 与 PisellExport 一致的尺寸、状态样式，类名前缀 `.pisell-import` |
| types.ts         | VariantType、SizeType、ImportButtonType、PisellImportProps |

## 6. 实现方案

### 6.1 结构

- 根为 Fragment：内层为隐藏的 `<input type="file" ref={inputRef} accept={accept} multiple={multiple} onChange={handleFileChange} />`，以及可见的 `<button>`。
- 点击 button 时调用 `inputRef.current?.click()` 打开文件选择。
- Button 形态：图标 + label，类名 `pisell-import`、`pisell-import--${variant}`、`pisell-import--${size}`、`pisell-import--${type}`，disabled 时 `pisell-import--disabled`。

### 6.2 文件选择与校验

- `handleFileChange`：从 `e.target.files` 取 `File[]`，若存在 `maxSize` 则遍历校验，任一文件超过 `maxSize * 1024 * 1024` 字节则调用 `onError({ type: 'MAX_SIZE', message, file })`，清空 input.value 并 return；否则调用 `onImport(fileList, e)`，再清空 input.value。
- `message` 使用 locales `getText('pisell-import-error-max-size')`，支持 `{{maxSize}}` 占位替换为数字。

### 6.3 样式

- 使用 Less，类名前缀 `.pisell-import`，与 PisellExport 设计一致：边框 #D0D5DD、文案 #344054、主色、圆角 8px、阴影等。
- 尺寸：small 8px 14px、medium 10px 16px、large 12px 20px；图标 20×20px，gap 8px。

### 6.4 图标与文案

- 无 `icon` 时使用 IconFont `pisell2-upload-cloud-01`；无 `label` 时使用 `getText('pisell-import-button-label')`。

## 7. 组成部分与引用关系

```
PisellImport
├── <input type="file" />（隐藏，ref 触发）
└── <button>
    ├── 图标区域（icon 或 IconFont upload-cloud-01）
    └── [Button 形态] 文案 (label / getText)
```

---

**不包含**：上传请求、解析 Excel/CSV、进度条等；均由调用方在 `onImport` 中实现。
