Skip to content

Commit

Permalink
feat(ImageBase): add prop keepAspectRatio to ImageBase (#7187)
Browse files Browse the repository at this point in the history
Добавил флаг keepAspectRatio, который задает необходимый класснейм для картинки
  • Loading branch information
EldarMuhamethanov authored Jul 19, 2024
1 parent e7e4da4 commit 4ad610e
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
5 changes: 5 additions & 0 deletions packages/vkui/src/components/ImageBase/ImageBase.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
visibility: hidden;
}

.ImageBase__img--keepRatio {
inline-size: auto;
block-size: auto;
}

.ImageBase__img--objectFit-contain {
object-fit: contain;
}
Expand Down
6 changes: 6 additions & 0 deletions packages/vkui/src/components/ImageBase/ImageBase.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ describe(ImageBase, () => {
// make sure we ignore img.onLoad that is fired for some reason after we manually handled the complete state.
expect(onLoadMock).toHaveBeenCalledTimes(1);
});

it('should have className with keepRatio', () => {
render(<ImageBaseTest src="#" keepAspectRatio={true} />);

expect(getImageBaseImgEl()).toHaveClass(styles['ImageBase__img--keepRatio']);
});
});

describe(ImageBase.Badge, () => {
Expand Down
44 changes: 38 additions & 6 deletions packages/vkui/src/components/ImageBase/ImageBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ export interface ImageBaseProps
/**
* Ширина изображения
*/
widthSize?: number;
widthSize?: number | string;
/**
* Высота изображения
*/
heightSize?: number;
heightSize?: number | string;
/**
* Отключает обводку.
*/
Expand Down Expand Up @@ -82,6 +82,11 @@ export interface ImageBaseProps
* Подробнее можно почитать в [документации](https://developer.mozilla.org/ru/docs/Web/CSS/object-fit)
*/
objectFit?: React.CSSProperties['objectFit'];
/**
* Флаг для сохранения пропорций картинки.
* Для корректной работы необходимо задать размеры хотя бы одной стороны картинки
*/
keepAspectRatio?: boolean;
}

const getObjectFitClassName = (objectFit: React.CSSProperties['objectFit']) => {
Expand All @@ -98,6 +103,20 @@ const getObjectFitClassName = (objectFit: React.CSSProperties['objectFit']) => {
return undefined;
};

const parsePx = (value: string): number | undefined => {
if (value.endsWith('px')) {
return parseInt(value);
}
return undefined;
};

const sizeToNumber = (size: number | string | undefined): number | undefined => {
if (typeof size === 'string') {
return parsePx(size);
}
return size;
};

/**
* @see https://vkcom.github.io/VKUI/#/ImageBase
*/
Expand Down Expand Up @@ -129,12 +148,13 @@ export const ImageBase: React.FC<ImageBaseProps> & {
onError,
withTransparentBackground,
objectFit = 'cover',
keepAspectRatio = false,
...restProps
}: ImageBaseProps) => {
const size = sizeProp ?? minOr([widthSize, heightSize], defaultSize);
const size = sizeProp ?? minOr([sizeToNumber(widthSize), sizeToNumber(heightSize)], defaultSize);

const width = widthSize ?? size;
const height = heightSize ?? size;
const width = widthSize ?? (keepAspectRatio ? undefined : size);
const height = heightSize ?? (keepAspectRatio ? undefined : size);

const [loaded, setLoaded] = React.useState(false);
const [failed, setFailed] = React.useState(false);
Expand Down Expand Up @@ -199,11 +219,23 @@ export const ImageBase: React.FC<ImageBaseProps> & {
<img
ref={imgRef}
alt={alt}
className={classNames(styles['ImageBase__img'], getObjectFitClassName(objectFit))}
className={classNames(
styles['ImageBase__img'],
getObjectFitClassName(objectFit),
keepAspectRatio && styles['ImageBase__img--keepRatio'],
)}
crossOrigin={crossOrigin}
decoding={decoding}
loading={loading}
referrerPolicy={referrerPolicy}
style={
keepAspectRatio
? {
width: widthImg || width,
height: heightImg || height,
}
: undefined
}
sizes={sizes}
src={src}
srcSet={srcSet}
Expand Down

0 comments on commit 4ad610e

Please sign in to comment.