From d438e6dc1ffb75cb50b7416ebfb746ddb6a51623 Mon Sep 17 00:00:00 2001 From: thinkasany <480968828@qq.com> Date: Tue, 18 Feb 2025 17:40:19 +0800 Subject: [PATCH] feat: support classnames and styles --- src/Image.tsx | 12 ++++++++++-- src/Operations.tsx | 12 ++++++++++-- src/Preview.tsx | 4 ++++ tests/basic.test.tsx | 19 +++++++++++++++++++ tests/preview.test.tsx | 20 ++++++++++++++++++++ 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/Image.tsx b/src/Image.tsx index 71e2e1f2..33d9ce9e 100644 --- a/src/Image.tsx +++ b/src/Image.tsx @@ -49,6 +49,8 @@ export interface ImagePreviewType ) => React.ReactNode; } +export type SemanticName = 'actions' | 'mask'; + export interface ImageProps extends Omit, 'placeholder' | 'onClick'> { // Original @@ -67,6 +69,8 @@ export interface ImageProps onPreviewClose?: (value: boolean, prevValue: boolean) => void; onClick?: (e: React.MouseEvent) => void; onError?: (e: React.SyntheticEvent) => void; + classNames?: Partial>; + styles?: Partial>; } interface CompoundedComponent

extends React.FC

{ @@ -92,7 +96,8 @@ const ImageInternal: CompoundedComponent = props => { wrapperClassName, wrapperStyle, rootClassName, - + classNames: imageClassNames, + styles, ...otherProps } = props; @@ -222,9 +227,10 @@ const ImageInternal: CompoundedComponent = props => { {/* Preview Click Mask */} {previewMask && canPreview && (

{previewMask} @@ -252,6 +258,8 @@ const ImageInternal: CompoundedComponent = props => { imageRender={imageRender} imgCommonProps={imgCommonProps} toolbarRender={toolbarRender} + classNames={imageClassNames} + styles={styles} {...dialogProps} /> )} diff --git a/src/Operations.tsx b/src/Operations.tsx index e7091c17..a47abd64 100644 --- a/src/Operations.tsx +++ b/src/Operations.tsx @@ -4,10 +4,11 @@ import CSSMotion from 'rc-motion'; import KeyCode from 'rc-util/lib/KeyCode'; import * as React from 'react'; import { useContext } from 'react'; -import type { ImgInfo } from './Image'; +import type { ImgInfo, SemanticName } from './Image'; import type { PreviewProps, ToolbarRenderInfoType } from './Preview'; import { PreviewGroupContext } from './context'; import type { TransformType } from './hooks/useImageTransform'; +import classNames from 'classnames'; type OperationType = | 'prev' @@ -61,6 +62,8 @@ interface OperationsProps ) => React.ReactNode; zIndex?: number; image?: ImgInfo; + classNames?: Partial>; + styles?: Partial>; } const Operations: React.FC = props => { @@ -93,6 +96,8 @@ const Operations: React.FC = props => { toolbarRender, zIndex, image, + classNames: imageClassNames, + styles, } = props; const groupContext = useContext(PreviewGroupContext); const { rotateLeft, rotateRight, zoomIn, zoomOut, close, left, right, flipX, flipY } = icons; @@ -195,7 +200,10 @@ const Operations: React.FC = props => { }); const toolbarNode = ( -
+
{flipYNode} {flipXNode} {rotateLeftNode} diff --git a/src/Preview.tsx b/src/Preview.tsx index 42e2b400..e953471b 100644 --- a/src/Preview.tsx +++ b/src/Preview.tsx @@ -134,6 +134,8 @@ const Preview: React.FC = props => { toolbarRender, onTransform, onChange, + classNames: imageClassNames, + styles, ...restProps } = props; @@ -339,6 +341,8 @@ const Preview: React.FC = props => { onReset={onReset} zIndex={restProps.zIndex !== undefined ? restProps.zIndex + 1 : undefined} image={image} + classNames={imageClassNames} + styles={styles} /> ); diff --git a/tests/basic.test.tsx b/tests/basic.test.tsx index a58d5e7a..b91540e9 100644 --- a/tests/basic.test.tsx +++ b/tests/basic.test.tsx @@ -97,4 +97,23 @@ describe('Basic', () => { const operationsElement = baseElement.querySelector('.rc-image-preview-operations-wrapper'); expect(operationsElement).toHaveStyle({ zIndex: 10000 }); }); + it('support classnames and styles', () => { + const customClassnames = { + actions: 'custom-actions', + }; + const customStyles = { + actions: { backgroundColor: 'blue' }, + }; + const { baseElement } = render( + , + ); + const actionsElement = baseElement.querySelector('.rc-image-preview-operations'); + expect(actionsElement).toHaveClass('custom-actions'); + expect(actionsElement).toHaveStyle({ backgroundColor: 'blue' }); + }); }); diff --git a/tests/preview.test.tsx b/tests/preview.test.tsx index 04890740..9fec2a15 100644 --- a/tests/preview.test.tsx +++ b/tests/preview.test.tsx @@ -1030,4 +1030,24 @@ describe('Preview', () => { expect(previewImg).not.toHaveAttribute('width'); expect(previewImg).not.toHaveAttribute('height'); }); + it('support classnames and styles', () => { + const customClassnames = { + mask: 'custom-mask', + }; + const customStyles = { + mask: { color: 'red' }, + }; + render( + , + ); + expect(document.querySelector('.rc-image-mask')).toHaveClass('custom-mask'); + expect(document.querySelector('.rc-image-mask')).toHaveStyle({ color: 'red' }); + }); });