Skip to content

Commit bff743b

Browse files
feat(Image): add prop filter (#8171)
* feat(Image): add prop filter * fix(Image): fix prettier
1 parent 9205131 commit bff743b

File tree

4 files changed

+47
-5
lines changed

4 files changed

+47
-5
lines changed

packages/vkui/src/components/Image/Image.stories.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ const story: Meta<ImageProps> = {
77
title: 'Blocks/Image',
88
component: Image,
99
parameters: { ...CanvasFullLayout, ...DisableCartesianParam },
10+
argTypes: {
11+
filter: {
12+
control: { type: 'select' },
13+
options: ['blur', 'contrast', 'grayscale', 'hue-rotate', 'drop-shadow'],
14+
mapping: {
15+
'blur': 'blur(5px)',
16+
'contrast': 'contrast(200%)',
17+
'grayscale': 'grayscale(80%)',
18+
'hue-rotate': 'hue-rotate(90deg)',
19+
'drop-shadow': 'drop-shadow(16px 16px 20px red) invert(75%)',
20+
},
21+
},
22+
},
1023
};
1124

1225
export default story;

packages/vkui/src/components/ImageBase/ImageBase.module.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@
8080
);
8181
}
8282

83+
.withFilter {
84+
--vkui_internal--ImageBase_object_filter_default: none;
85+
86+
filter: var(
87+
--vkui_internal--ImageBase_object_filter,
88+
var(--vkui_internal--ImageBase_object_filter_default)
89+
);
90+
}
91+
8392
.loaded .img {
8493
visibility: visible;
8594
}

packages/vkui/src/components/ImageBase/ImageBase.test.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,15 @@ describe(ImageBase, () => {
223223
});
224224
});
225225

226+
it('should apply custom filter style', () => {
227+
render(<ImageBaseTest src="#" filter="blur(5px)" />);
228+
229+
expect(getImageBaseImgEl()).toHaveClass(styles.withFilter);
230+
expect(getImageBaseImgEl()).toHaveStyle({
231+
'--vkui_internal--ImageBase_object_filter': 'blur(5px)',
232+
});
233+
});
234+
226235
describe('DEV errros', () => {
227236
beforeEach(() => setNodeEnv('development'));
228237
afterEach(() => setNodeEnv('test'));

packages/vkui/src/components/ImageBase/ImageBase.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ export interface ImageBaseProps
115115
* см. https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/elementtiming
116116
*/
117117
elementTiming?: string;
118+
/**
119+
* Пользовательское значения стиля filter
120+
* Подробнее можно почитать в [документации](https://developer.mozilla.org/ru/docs/Web/CSS/filter)
121+
*/
122+
filter?: React.CSSProperties['filter'];
118123
}
119124

120125
const getObjectFitClassName = (objectFit: React.CSSProperties['objectFit']) => {
@@ -177,6 +182,7 @@ export const ImageBase: React.FC<ImageBaseProps> & {
177182
withTransparentBackground,
178183
objectFit = 'cover',
179184
objectPosition,
185+
filter,
180186
keepAspectRatio = false,
181187
getRootRef,
182188
elementTiming,
@@ -256,11 +262,15 @@ export const ImageBase: React.FC<ImageBaseProps> & {
256262
[size],
257263
);
258264

259-
const imgStyles: CSSCustomProperties<string | number> | undefined = objectPosition
260-
? {
261-
'--vkui_internal--ImageBase_object_position': objectPosition,
262-
}
263-
: undefined;
265+
const imgStyles:
266+
| CSSCustomProperties<React.CSSProperties['objectPosition'] | React.CSSProperties['filter']>
267+
| undefined =
268+
objectPosition || filter
269+
? {
270+
'--vkui_internal--ImageBase_object_position': objectPosition,
271+
'--vkui_internal--ImageBase_object_filter': filter,
272+
}
273+
: undefined;
264274

265275
const keepAspectRationStyles = keepAspectRatio
266276
? {
@@ -291,6 +301,7 @@ export const ImageBase: React.FC<ImageBaseProps> & {
291301
styles.img,
292302
getObjectFitClassName(objectFit),
293303
objectPosition && styles.withObjectPosition,
304+
filter && styles.withFilter,
294305
keepAspectRatio && styles.imgKeepRatio,
295306
)}
296307
crossOrigin={crossOrigin}

0 commit comments

Comments
 (0)