<div align="center">
  <h1>@rc-component/image</h1>
  <p><sub><a href="https://ant.design"><img alt="Ant Design" height="14" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" style="vertical-align: -0.125em;" /></a> Ant Design 生态的一部分。</sub></p>
  <p>🖼️ React 图片预览组件，支持预览组、缩放、旋转和自定义工具栏。</p>

  <p>
    <a href="https://npmjs.org/package/@rc-component/image"><img alt="NPM version" src="https://img.shields.io/npm/v/@rc-component/image.svg?style=flat-square"></a>
    <a href="https://npmjs.org/package/@rc-component/image"><img alt="npm downloads" src="https://img.shields.io/npm/dm/@rc-component/image.svg?style=flat-square"></a>
    <a href="https://github.com/react-component/image/actions/workflows/react-component-ci.yml"><img alt="build status" src="https://github.com/react-component/image/actions/workflows/react-component-ci.yml/badge.svg"></a>
    <a href="https://app.codecov.io/gh/react-component/image"><img alt="Codecov" src="https://img.shields.io/codecov/c/github/react-component/image/master.svg?style=flat-square"></a>
    <a href="https://bundlephobia.com/package/@rc-component/image"><img alt="bundle size" src="https://img.shields.io/bundlephobia/minzip/@rc-component/image?style=flat-square"></a>
    <a href="https://github.com/umijs/dumi"><img alt="dumi" src="https://img.shields.io/badge/docs%20by-dumi-blue?style=flat-square"></a>
  </p>
</div>

<p align="center"><a href="./README.md">English</a> | 简体中文</p>

## 特性

- 支持占位符、后备和预览。
- 预览支持缩放、旋转、翻转、拖动、键盘访问和自定义操作。
- `Image.PreviewGroup` 支持分组预览和自定义预览项。
- 提供编译后的 JavaScript、TypeScript 类型定义和 CSS 资源。

## 安装

```bash
npm install @rc-component/image
```

## 使用

```tsx | pure
import Image from '@rc-component/image';
import '@rc-component/image/assets/index.css';

export default function App() {
  return (
    <Image src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png" />
  );
}
```

## Preview Group

```tsx | pure
import Image from '@rc-component/image';
import '@rc-component/image/assets/index.css';

export default function App() {
  return (
    <Image.PreviewGroup>
      <Image src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png" />
      <Image src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*P0S-QIRUbsUAAAAAAAAAAABkARQnAQ" />
    </Image.PreviewGroup>
  );
}
```

## 示例

运行本地 dumi 站点：

```bash
npm install
npm start
```

然后打开 `http://localhost:8000`。

## API

### Image

| 参数             | 说明                   | 类型                            | 默认值             |
| ---------------- | ---------------------- | ------------------------------- | ------------------ |
| fallback         | 加载失败时使用的图片源 | string                          | -                  |
| placeholder      | 图片加载前的占位内容   | boolean \| `React.ReactElement` | -                  |
| prefixCls        | 组件 className 前缀    | string                          | `rc-image`         |
| preview          | 是否以及如何显示预览   | boolean \| `PreviewConfig`      | true               |
| previewPrefixCls | 预览 className 前缀    | string                          | `rc-image-preview` |
| src              | 图片地址               | string                          | -                  |
| onError          | 图片加载失败时的回调   | `(event: Event) => void`        | -                  |

也支持原生图片属性。

### PreviewConfig

| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| actionsRender | 自定义工具栏渲染器 | `(node: React.ReactElement, info: Omit<ToolbarRenderInfoType, 'current' \| 'total'>) => React.ReactNode` | - |
| closeIcon | 自定义关闭图标 | `React.ReactNode` | - |
| cover | 自定义预览封面 | `React.ReactNode \| CoverConfig` | - |
| countRender | 自定义计数渲染器 | `(current: number, total: number) => React.ReactNode` | - |
| forceRender | 强制渲染预览 | boolean | false |
| getContainer | 预览容器 | string \| HTMLElement \| `() => HTMLElement` \| false | `document.body` |
| imageRender | 自定义图像渲染器 | `(node: React.ReactElement, info: { transform: TransformType; image: ImgInfo }) => React.ReactNode` | - |
| maskClosable | 单击蒙版是否关闭预览 | boolean | true |
| maxScale | 最大缩放比例 | number | 50 |
| minScale | 最小缩放比例 | number | 1 |
| movable | 启用拖动 | boolean | true |
| open | 受控预览打开状态 | boolean | - |
| scaleStep | 缩放步长 | number | 0.5 |
| src | 自定义预览图像源 | string | - |
| wheel | 启用鼠标滚轮缩放 | boolean | true |
| onOpenChange | 预览打开状态变化时回调 | `(open: boolean) => void` | - |
| onTransform | 变换变化时的回调 | `(info: { transform: TransformType; action: TransformAction }) => void` | - |

### Image.PreviewGroup

| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| children | 子元素 | `React.ReactNode` | - |
| classNames | 语义预览弹层 className | `{ popup?: Partial<Record<PreviewSemanticName, string>> }` | - |
| fallback | 加载失败时使用的图片源 | string | - |
| icons | 自定义预览操作图标 | `PreviewProps['icons']` | - |
| items | 预览项目 | `(string \| ImageElementProps)[]` | - |
| preview | 是否以及如何显示预览 group | boolean \| `GroupPreviewConfig` | true |
| previewPrefixCls | 预览 className 前缀 | string | `rc-image-preview` |
| styles | 语义预览弹层样式 | `{ popup?: Partial<Record<PreviewSemanticName, React.CSSProperties>> }` | - |

### TransformType

```ts
type TransformType = {
  x: number;
  y: number;
  rotate: number;
  scale: number;
  flipX: boolean;
  flipY: boolean;
};

type TransformAction =
  | 'flipY'
  | 'flipX'
  | 'rotateLeft'
  | 'rotateRight'
  | 'zoomIn'
  | 'zoomOut'
  | 'close'
  | 'prev'
  | 'next'
  | 'wheel'
  | 'doubleClick'
  | 'move'
  | 'dragRebound';

type Actions = {
  onActive: (offset: number) => void;
  onFlipY: () => void;
  onFlipX: () => void;
  onRotateLeft: () => void;
  onRotateRight: () => void;
  onZoomOut: () => void;
  onZoomIn: () => void;
  onClose: () => void;
  onReset: () => void;
};

type ToolbarRenderInfoType = {
  icons: {
    prevIcon?: React.ReactNode;
    nextIcon?: React.ReactNode;
    flipYIcon: React.ReactNode;
    flipXIcon: React.ReactNode;
    rotateLeftIcon: React.ReactNode;
    rotateRightIcon: React.ReactNode;
    zoomOutIcon: React.ReactNode;
    zoomInIcon: React.ReactNode;
  };
  actions: Actions;
  transform: TransformType;
  current: number;
  total: number;
  image: ImgInfo;
};
```

## 本地开发

```bash
npm install
npm start
```

dumi 站点默认运行在 `http://localhost:8000`。

```bash
npm test
npm run tsc
npm run lint
npm run compile
npm run build
```

## 发布

```bash
npm run prepublishOnly
```

包构建完成后，发布流程由 `@rc-component/np` 通过 `rc-np` 命令处理。

## 许可证

@rc-component/image 基于 [MIT](./LICENSE) 许可证发布。
