From d710ae8a65d3580bb0905874ba435430a8899668 Mon Sep 17 00:00:00 2001 From: krutoo Date: Wed, 10 Jan 2024 14:05:37 +0500 Subject: [PATCH] #213 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `product-card`: теперь можно задать функцию фильтрации кнопок на изображении как опцию `hideImageButtons` функции `reduceBaseInfo` (minor) --- .../__stories__/01-primary.stories.tsx | 16 ++++++++++++- .../__test__/product-card.test.tsx | 23 ++++++++++++++++++- .../components/product-card/product-card.tsx | 19 ++++++++------- src/desktop/components/product-card/types.ts | 9 ++++++++ 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/desktop/components/product-card/__stories__/01-primary.stories.tsx b/src/desktop/components/product-card/__stories__/01-primary.stories.tsx index bf85f3e2..372030fb 100644 --- a/src/desktop/components/product-card/__stories__/01-primary.stories.tsx +++ b/src/desktop/components/product-card/__stories__/01-primary.stories.tsx @@ -3,6 +3,7 @@ import { ProductInfo, Parts } from '@sima-land/moleculas/common/components/produ import { Badge, BadgeProps } from '@sima-land/moleculas/common/components/badge'; import { Stepper } from '@sima-land/ui-nucleons/stepper'; import FavSVG from '@sima-land/ui-quarks/icons/24x24/Stroked/Favorite'; +import ComparisonAddSVG from '@sima-land/ui-quarks/icons/24x24/Stroked/ComparisonAdd'; import cupSrc from './cup.jpg'; export default { @@ -28,7 +29,14 @@ export function Primary() { return (
- reduceBaseInfo(elem, { hideImageButtons: false })}> + + reduceBaseInfo(elem, { + hideImageButtons: btn => (btn as any)?.props?.icon === FavSVG, + }) + } + > {/* Изображение */} @@ -38,6 +46,12 @@ export function Primary() { hint='Добавить в избранное' hintDirection='right' /> + {/* Шильдики */} diff --git a/src/desktop/components/product-card/__test__/product-card.test.tsx b/src/desktop/components/product-card/__test__/product-card.test.tsx index 614604b0..95a03e76 100644 --- a/src/desktop/components/product-card/__test__/product-card.test.tsx +++ b/src/desktop/components/product-card/__test__/product-card.test.tsx @@ -1,4 +1,4 @@ -import { Children } from 'react'; +import { Children, isValidElement } from 'react'; import { fireEvent, render } from '@testing-library/react'; import { ProductCard, reduceBaseInfo, reduceHoverInfo } from '../product-card'; import { ProductInfo, Parts } from '../../../../common/components/product-info'; @@ -128,6 +128,27 @@ describe('reduceBaseInfo', () => { expect(Children.toArray(result.props.children)).toEqual([]); }); + + it('should handle function as "hideImageButtons" option', () => { + const jsx = ( + + + some string + excluded +
survivor
+
+
+ ); + + const result = reduceBaseInfo(jsx, { + hideImageButtons: value => isValidElement(value) && value.type === 'article', + }); + + const { container } = render(result); + + expect(container.querySelectorAll('article')).toHaveLength(1); + expect(container.textContent).toBe('survivor'); + }); }); describe('reduceHoverInfo', () => { diff --git a/src/desktop/components/product-card/product-card.tsx b/src/desktop/components/product-card/product-card.tsx index 872c1786..c8975cd5 100644 --- a/src/desktop/components/product-card/product-card.tsx +++ b/src/desktop/components/product-card/product-card.tsx @@ -1,5 +1,5 @@ import { Children, forwardRef, isValidElement, cloneElement, useState } from 'react'; -import { ProductCardChildren, ProductCardProps } from './types'; +import { ProductCardChildren, ProductCardProps, ReduceBaseInfoOptions } from './types'; import { Parts } from '../../../common/components/product-info'; import { Plate, PlateProps } from '@sima-land/ui-nucleons/plate'; import { useLayer } from '@sima-land/ui-nucleons/helpers/layer'; @@ -62,13 +62,7 @@ export const HoverCard = forwardRef((props, r */ export function reduceBaseInfo( element: ProductCardChildren, - { - hideImageButtons = true, - hideFooter = true, - }: { - hideImageButtons?: boolean; - hideFooter?: boolean; - } = {}, + { hideImageButtons = true, hideFooter = true }: ReduceBaseInfoOptions = {}, ) { return cloneElement(element, { children: Children.map(element.props.children, child => { @@ -76,9 +70,14 @@ export function reduceBaseInfo( if (isValidElement(child)) { switch (true) { - // игнорируем кнопки-иконки на изображении + // игнорируем или фильтруем кнопки-иконки на изображении case Boolean(child.type === Parts.Image && hideImageButtons): - result = cloneElement(child, { children: undefined }); + result = cloneElement(child, { + children: + typeof hideImageButtons === 'function' + ? Children.toArray(child.props.children).filter(hideImageButtons) + : undefined, + }); break; // игнорируем футер diff --git a/src/desktop/components/product-card/types.ts b/src/desktop/components/product-card/types.ts index 1b81caa8..c31859ac 100644 --- a/src/desktop/components/product-card/types.ts +++ b/src/desktop/components/product-card/types.ts @@ -14,3 +14,12 @@ export interface ProductCardProps extends HTMLAttributes { /** Получив содержимое должен вернуть то что будет выведено во всплывающей карточке. */ reduceHoverInfo?: (children: ProductCardChildren) => ReactNode; } + +/** Опции фильтрации содержимого карточки без наведения. */ +export interface ReduceBaseInfoOptions { + /** Надо ли скрыть кнопки на картинке. При передаче функции она будет применена для каждого дочернего элемента внутри картинки как фильтр. */ + hideImageButtons?: boolean | ((element: ReactNode) => boolean); + + /** Надо ли скрыть футер. */ + hideFooter?: boolean; +}