Skip to content

Commit

Permalink
feat(ImageViewer): add imageReferrerpolicy API (#2813)
Browse files Browse the repository at this point in the history
* feat(imageviewer): add imageReferrerpolicy API

* chore: remove test
  • Loading branch information
uyarn committed Mar 28, 2024
1 parent 51d9f0b commit bcf50c3
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/image-viewer/ImageViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const ImageViewer: React.FC<ImageViewerProps> = (originalProps) => {
closeOnEscKeydown={props.closeOnEscKeydown}
onClose={close}
onOpen={open}
imageReferrerpolicy={props.imageReferrerpolicy}
/>,
document.body,
)}
Expand Down
4 changes: 4 additions & 0 deletions src/image-viewer/ImageViewerMini.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { ImageInfo, ImageScale, ImageViewerScale } from './type';
import { ImageModalItem, ImageViewerUtils } from './ImageViewerModal';
import useConfig from '../hooks/useConfig';

import type { TdImageViewerProps } from './type';

export interface ImageModalMiniProps {
visible: boolean;
title?: TNode;
Expand Down Expand Up @@ -32,6 +34,7 @@ export interface ImageModalMiniProps {
rotate: string;
originsize: string;
};
imageReferrerpolicy?: TdImageViewerProps['imageReferrerpolicy'];
}

export const ImageModalMiniContent: React.FC<ImageModalMiniProps> = (props) => {
Expand All @@ -46,6 +49,7 @@ export const ImageModalMiniContent: React.FC<ImageModalMiniProps> = (props) => {
src={props.currentImage.mainImage}
preSrc={props.currentImage.thumbnail}
errorText={props.errorText}
imageReferrerpolicy={props.imageReferrerpolicy}
/>
</div>
);
Expand Down
46 changes: 39 additions & 7 deletions src/image-viewer/ImageViewerModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ import useGlobalIcon from '../hooks/useGlobalIcon';
import useIconMap from './hooks/useIconMap';
import Image from '../image';

import type { TdImageViewerProps } from './type';
import { ImageViewerProps } from './ImageViewer';

const ImageError = ({ errorText }: { errorText: string }) => {
const { classPrefix } = useConfig();
const { ImageErrorIcon } = useGlobalIcon({ ImageErrorIcon: TdImageErrorIcon });
Expand All @@ -47,10 +50,19 @@ interface ImageModalItemProps {
src: string | File;
preSrc?: string | File;
errorText: string;
imageReferrerpolicy?: TdImageViewerProps['imageReferrerpolicy'];
}

// 单个弹窗实例
export const ImageModalItem: React.FC<ImageModalItemProps> = ({ rotateZ, scale, src, preSrc, mirror, errorText }) => {
export const ImageModalItem: React.FC<ImageModalItemProps> = ({
rotateZ,
scale,
src,
preSrc,
mirror,
errorText,
imageReferrerpolicy,
}) => {
const { classPrefix } = useConfig();

const [position, onMouseDown] = usePosition({ initPosition: [0, 0] });
Expand Down Expand Up @@ -84,7 +96,7 @@ export const ImageModalItem: React.FC<ImageModalItemProps> = ({ rotateZ, scale,
}}
src={preSrcImagePreviewUrl}
style={preImgStyle}
data-testid="img-drag"
referrerPolicy={imageReferrerpolicy}
alt="image"
draggable="false"
/>
Expand All @@ -100,7 +112,6 @@ export const ImageModalItem: React.FC<ImageModalItemProps> = ({ rotateZ, scale,
onLoad={() => setLoaded(true)}
onError={() => setError(true)}
style={imgStyle}
data-testid="img-drag"
alt="image"
draggable="false"
/>
Expand Down Expand Up @@ -228,16 +239,33 @@ type ImageViewerHeaderProps = {
onImgClick: (index: number, ctx: { trigger: 'current' }) => void;
images: ImageInfo[];
currentIndex: number;
imageRreferrerpolicy?: TdImageViewerProps['imageReferrerpolicy'];
};

function OneImagePreview({ image, classPrefix }: { image: ImageInfo; classPrefix: string }) {
function OneImagePreview({
image,
classPrefix,
imageRreferrerpolicy,
}: {
image: ImageInfo;
classPrefix: string;
imageRreferrerpolicy?: TdImageViewerProps['imageReferrerpolicy'];
}) {
const { previewUrl } = useImagePreviewUrl(image.thumbnail || image.mainImage);
return <Image alt="" error="" src={previewUrl} className={`${classPrefix}-image-viewer__header-img`} />;
return (
<Image
alt=""
error=""
src={previewUrl}
className={`${classPrefix}-image-viewer__header-img`}
referrerpolicy={imageRreferrerpolicy}
/>
);
}

const ImageViewerHeader = (props: ImageViewerHeaderProps) => {
const { classPrefix } = useConfig();
const { images, currentIndex, onImgClick } = props;
const { images, currentIndex, onImgClick, imageRreferrerpolicy } = props;

const [isExpand, setIsExpand] = useState(true);

Expand Down Expand Up @@ -265,7 +293,7 @@ const ImageViewerHeader = (props: ImageViewerHeaderProps) => {
})}
onClick={() => onImgClick(index, { trigger: 'current' })}
>
<OneImagePreview image={image} classPrefix={classPrefix} />
<OneImagePreview image={image} classPrefix={classPrefix} imageRreferrerpolicy={imageRreferrerpolicy} />
</div>
))}
</div>
Expand All @@ -292,6 +320,7 @@ interface ImageModalProps {
closeBtn: boolean | TNode;
closeOnEscKeydown?: boolean;
onIndexChange?: (index: number, context: { trigger: 'prev' | 'next' }) => void;
imageReferrerpolicy?: ImageViewerProps['imageReferrerpolicy'];
}

// 弹窗基础组件
Expand All @@ -311,6 +340,7 @@ export const ImageModal: React.FC<ImageModalProps> = (props) => {
visible,
title,
closeOnEscKeydown,
imageReferrerpolicy,
...resProps
} = props;
const { classPrefix } = useConfig();
Expand Down Expand Up @@ -410,6 +440,7 @@ export const ImageModal: React.FC<ImageModalProps> = (props) => {
onRotate={onRotate}
errorText={errorText}
tipText={tipText}
imageReferrerpolicy={imageReferrerpolicy}
/>
);
}
Expand Down Expand Up @@ -481,6 +512,7 @@ export const ImageModal: React.FC<ImageModalProps> = (props) => {
preSrc={currentImage.thumbnail}
src={currentImage.mainImage}
errorText={errorText}
imageReferrerpolicy={imageReferrerpolicy}
/>
</div>
);
Expand Down
19 changes: 19 additions & 0 deletions src/image-viewer/__tests__/image-viewer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,23 @@ describe('ImageViewerModal', () => {
transform: 'rotateZ(0deg) scale(2)',
});
});

test('imageReferrerpolicy', async () => {
const referrerPolicy = 'strict-origin-when-cross-origin';

const BasicImageViewer = () => {
const trigger = ({ onOpen }) => <span onClick={onOpen}>{triggerText}</span>;
return <ImageViewer trigger={trigger} images={[imgUrl, imgUrl2]} imageReferrerpolicy={referrerPolicy} />;
};
const { getByText } = render(<BasicImageViewer />);

// 模拟鼠标点击
act(() => {
fireEvent.click(getByText(triggerText));
});

await mockDelay();

expect(document.querySelector('.t-image-viewer__modal-image')?.getAttribute('referrerpolicy')).toBe(referrerPolicy);
});
});
20 changes: 11 additions & 9 deletions src/image-viewer/_example/base.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import {ImageViewer, Image, Space} from 'tdesign-react';
import {BrowseIcon} from 'tdesign-icons-react'
import { ImageViewer, Image, Space } from 'tdesign-react';
import { BrowseIcon } from 'tdesign-icons-react';

const img = 'https://tdesign.gtimg.com/demo/demo-image-1.png';

export default function BasicImageViewer() {
const trigger = ({open}) => {
const trigger = ({ open }) => {
const mask = (
<div
style={{
Expand All @@ -14,11 +14,13 @@ export default function BasicImageViewer() {
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
justifyContent: 'center',
}}
onClick={open}
>
<span><BrowseIcon size="16px" name={'browse'}/> 预览</span>
<span>
<BrowseIcon size="16px" name={'browse'} /> 预览
</span>
</div>
);

Expand All @@ -34,15 +36,15 @@ export default function BasicImageViewer() {
height: 160,
border: '4px solid var(--td-bg-color-secondarycontainer)',
borderRadius: 'var(--td-radius-medium)',
backgroundColor: '#fff'
backgroundColor: '#fff',
}}
/>
)
}
);
};

return (
<Space breakLine size={16}>
<ImageViewer trigger={trigger} images={[img]}/>
<ImageViewer trigger={trigger} images={[img]} />

{/* TODO: fix visible=true can not show image previewer */}
{/* <ImageViewer images={[img]} visible={true} /> */}
Expand Down
6 changes: 4 additions & 2 deletions src/image-viewer/image-viewer.en-US.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
:: BASE_DOC ::

## API

### ImageViewer Props

name | type | default | description | required
-- | -- | -- | -- | --
className | String | - | 类名 | N
style | Object | - | 样式,Typescript:`React.CSSProperties` | N
className | String | - | className of component | N
style | Object | - | CSS(Cascading Style Sheets),Typescript:`React.CSSProperties` | N
closeBtn | TNode | true | Typescript:`boolean \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
closeOnEscKeydown | Boolean | true | trigger image viewer close event on `ESC` keydown | N
closeOnOverlay | Boolean | - | \- | N
draggable | Boolean | undefined | \- | N
imageReferrerpolicy | String | - | attribute of `<img>`, [MDN Definition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy)。options: no-referrer/no-referrer-when-downgrade/origin/origin-when-cross-origin/same-origin/strict-origin/strict-origin-when-cross-origin/unsafe-url | N
imageScale | Object | - | Typescript:`ImageScale` `interface ImageScale { max: number; min: number; step: number; defaultScale?: number; }`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/image-viewer/type.ts) | N
images | Array | [] | Typescript:`Array<string \| File \| ImageInfo>` `interface ImageInfo { mainImage: string \| File; thumbnail?: string \| File; download?: boolean }`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/image-viewer/type.ts) | N
index | Number | 0 | \- | N
Expand Down
4 changes: 3 additions & 1 deletion src/image-viewer/image-viewer.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
:: BASE_DOC ::

## API

### ImageViewer Props

名称 | 类型 | 默认值 | 说明 | 必传
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
className | String | - | 类名 | N
style | Object | - | 样式,TS 类型:`React.CSSProperties` | N
closeBtn | TNode | true | 是否展示关闭按钮,值为 `true` 显示默认关闭按钮;值为 `false` 则不显示关闭按钮;也可以完全自定义关闭按钮。TS 类型:`boolean \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
closeOnEscKeydown | Boolean | true | 按下 ESC 时是否触发图片预览器关闭事件 | N
closeOnOverlay | Boolean | - | 是否在点击遮罩层时,触发预览关闭 | N
draggable | Boolean | undefined | 是否允许拖拽调整位置。`mode=modal` 时,默认不允许拖拽;`mode=modeless` 时,默认允许拖拽 | N
imageReferrerpolicy | String | - | 图片预览中的 `<img>` 标签的原生属性,[MDN 定义](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy)。可选项:no-referrer/no-referrer-when-downgrade/origin/origin-when-cross-origin/same-origin/strict-origin/strict-origin-when-cross-origin/unsafe-url | N
imageScale | Object | - | 图片缩放相关配置。`imageScale.max` 缩放的最大比例;`imageScale.min` 缩放的最小比例;`imageScale.step` 缩放的步长速度; `imageScale.defaultScale` 默认的缩放比例。TS 类型:`ImageScale` `interface ImageScale { max: number; min: number; step: number; defaultScale?: number; }`[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/image-viewer/type.ts) | N
images | Array | [] | 图片数组。`mainImage` 表示主图,必传;`thumbnail` 表示缩略图,如果不存在,则使用主图显示;`download` 是否允许下载图片,默认允许下载。示例: `['img_url_1', 'img_url_2']``[{ thumbnail: 'small_image_url', mainImage: 'big_image_url', download: false }]`。TS 类型:`Array<string \| File \| ImageInfo>` `interface ImageInfo { mainImage: string \| File; thumbnail?: string \| File; download?: boolean }`[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/image-viewer/type.ts) | N
index | Number | 0 | 当前预览图片所在的下标 | N
Expand Down
30 changes: 30 additions & 0 deletions src/image-viewer/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ export interface TdImageViewerProps {
* 是否允许拖拽调整位置。`mode=modal` 时,默认不允许拖拽;`mode=modeless` 时,默认允许拖拽
*/
draggable?: boolean;
/**
* 图片预览中的 `<img>` 标签的原生属性,[MDN 定义](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy)
*/
imageReferrerpolicy?:
| 'no-referrer'
| 'no-referrer-when-downgrade'
| 'origin'
| 'origin-when-cross-origin'
| 'same-origin'
| 'strict-origin'
| 'strict-origin-when-cross-origin'
| 'unsafe-url';
/**
* 图片缩放相关配置。`imageScale.max` 缩放的最大比例;`imageScale.min` 缩放的最小比例;`imageScale.step` 缩放的步长速度; `imageScale.defaultScale` 默认的缩放比例
*/
Expand Down Expand Up @@ -102,12 +114,30 @@ export interface ImageScale {
defaultScale?: number;
}

export interface ImageScale {
max: number;
min: number;
step: number;
defaultScale?: number;
}

export interface ImageInfo {
mainImage: string | File;
thumbnail?: string | File;
download?: boolean;
}

export interface ImageInfo {
mainImage: string | File;
thumbnail?: string | File;
download?: boolean;
}

export interface ImageViewerScale {
minWidth: number;
minHeight: number;
}

export interface ImageViewerScale {
minWidth: number;
minHeight: number;
Expand Down

0 comments on commit bcf50c3

Please sign in to comment.