From 1de17e890dd58ed555a0f4ac2a4d474cd8f875f8 Mon Sep 17 00:00:00 2001 From: krutoo Date: Mon, 22 Jul 2024 15:12:36 +0500 Subject: [PATCH 1/3] #279 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - product-info: проп src заменен пропом images (major) - product-slider: добавлен проп itemProps по аналогии с ProductCarousel (minor) --- .../components/product-info/parts/image.tsx | 23 +++++++++++-------- src/common/components/product-info/types.ts | 8 +++---- .../product-slider/product-slider.tsx | 20 +++++++++++++--- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/common/components/product-info/parts/image.tsx b/src/common/components/product-info/parts/image.tsx index 3d3d4c53..f8b7b22f 100644 --- a/src/common/components/product-info/parts/image.tsx +++ b/src/common/components/product-info/parts/image.tsx @@ -1,6 +1,6 @@ import { ProductInfoImageProps } from '../types'; import { useContext } from 'react'; -import { ProductImage } from '../../product-image'; +import { ProductImage, ProductImageProps } from '../../product-image'; import { HoverSlider, HoverSliderItem } from '../../hover-slider'; import { ProductInfoContext } from '../utils'; import { ProductInfoMedia } from './media'; @@ -13,7 +13,7 @@ import styles from './image.m.scss'; * @return Элемент. */ export function ProductInfoImage({ - src, + images = [], href, children, anchorProps, @@ -30,8 +30,6 @@ export function ProductInfoImage({ anchorProps?.className, ); - const list = Array.isArray(src) ? src : [src]; - return ( - {list.length > 1 && !adult ? ( + {images.length > 1 && !adult ? ( - {list.map((item, index) => ( - - - + {images.map((imageProps, index) => ( + {renderImage(imageProps)} ))} ) : ( - + images.slice(0, 1).map(renderImage) )} @@ -62,3 +58,10 @@ export function ProductInfoImage({ ); } + +/** @inheritdoc */ +function renderImage(props: ProductImageProps, key?: string | number | null | undefined) { + return ( + + ); +} diff --git a/src/common/components/product-info/types.ts b/src/common/components/product-info/types.ts index 1ca6c442..5baa97ef 100644 --- a/src/common/components/product-info/types.ts +++ b/src/common/components/product-info/types.ts @@ -1,6 +1,6 @@ import type { LinkProps } from '@sima-land/ui-nucleons/link'; import type { StrokedSVGProps } from '@sima-land/ui-nucleons/stroked-svg'; -import type { ProductImageStyle } from '../product-image'; +import type { ProductImageProps, ProductImageStyle } from '../product-image'; import type { HoverSliderProps } from '../hover-slider/types'; import type { AnchorHTMLAttributes, @@ -38,12 +38,12 @@ export interface ProductInfoMediaProps extends HTMLAttributes { } export interface ProductInfoImageProps extends ProductInfoMediaProps { - /** Ссылка на картинку или список ссылок для вывода слайдера. */ - src?: string | string[]; - /** Ссылка на товар. */ href?: string; + /** Картинки. */ + images?: ProductImageProps[]; + /** Прочие атрибуты элемента-ссылки. */ anchorProps?: AnchorHTMLAttributes; diff --git a/src/mobile/components/product-slider/product-slider.tsx b/src/mobile/components/product-slider/product-slider.tsx index 7c81e1cf..59b4edd0 100644 --- a/src/mobile/components/product-slider/product-slider.tsx +++ b/src/mobile/components/product-slider/product-slider.tsx @@ -1,7 +1,8 @@ -import { Children, isValidElement, ReactElement, useMemo, useRef } from 'react'; +import { Children, CSSProperties, isValidElement, ReactElement, useMemo, useRef } from 'react'; import { useIntersection } from '@sima-land/ui-nucleons/hooks'; import { TouchSlider } from '@sima-land/ui-nucleons/touch-slider'; import { ProductInfo, ProductInfoProps, Parts } from '../../../common/components/product-info'; +import classNames from 'classnames'; import styles from './product-slider.m.scss'; export type ItemElement = ReactElement; @@ -15,6 +16,9 @@ export interface ProductSliderProps { /** Функция, инициализирующая загрузку рекомендаций. */ onNeedRequest?: () => void; + + /** Предоставит свойства для элемента . */ + itemProps?: { style?: CSSProperties; className?: string }; } /** @@ -22,7 +26,12 @@ export interface ProductSliderProps { * @param props Свойства. * @return Элемент. */ -export const ProductSlider = ({ children, onInViewport, onNeedRequest }: ProductSliderProps) => { +export const ProductSlider = ({ + children, + onInViewport, + onNeedRequest, + itemProps, +}: ProductSliderProps) => { const rootRef = useRef(null); // инициируем загрузку данных, когда компонент почти попал в зону видимости @@ -48,7 +57,12 @@ export const ProductSlider = ({ children, onInViewport, onNeedRequest }: Product isValidElement(item) && item.type === ProductInfo && list.push( -
+
{item}
, ); From a4163e64aeb3b062e10cb7727e509ddceaa4b7a6 Mon Sep 17 00:00:00 2001 From: krutoo Date: Mon, 22 Jul 2024 15:15:54 +0500 Subject: [PATCH 2/3] #279 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - правки тестов --- .../__test__/product-info.test.tsx | 44 +++++++++++++++---- .../__test__/product-carousel.test.tsx | 24 ++++++---- .../__test__/product-slider.test.tsx | 10 +++-- 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/src/common/components/product-info/__test__/product-info.test.tsx b/src/common/components/product-info/__test__/product-info.test.tsx index 2b0aefd1..ef08cdbe 100644 --- a/src/common/components/product-info/__test__/product-info.test.tsx +++ b/src/common/components/product-info/__test__/product-info.test.tsx @@ -10,7 +10,7 @@ describe('ProductInfo', () => { it('should render all parts', () => { const { container, queryAllByTestId } = render( - + { it('should hide parts for unavailable product', () => { const { queryAllByTestId } = render( - + { const { queryAllByTestId } = render( { const { container } = render( My product! - +
My custom child element!
, ); @@ -217,7 +224,7 @@ describe('ProductInfo', () => { const { getByTestId } = render( - + { it('should render link to waiting list', () => { const { getByTestId } = render( - + { const { getByTestId } = render( - + { it('should render hover slider when src is an array', () => { const { queryAllByTestId } = render( - + { it('should render cart control loading', () => { const { container, queryAllByTestId } = render( - + { expect(container.textContent).not.toContain('По 1 шт'); expect(container.textContent).not.toContain('Комплектация + 50 ₽ при покупке до 20 шт'); }); + + it('Parts.Image should accept undefined for "images"', () => { + const { queryAllByTestId } = render( + + + , + ); + + expect(queryAllByTestId('product-image-link')).toHaveLength(1); + expect(queryAllByTestId('product-image')).toHaveLength(0); + }); }); diff --git a/src/desktop/components/product-carousel/__test__/product-carousel.test.tsx b/src/desktop/components/product-carousel/__test__/product-carousel.test.tsx index d3284957..db3fa0f1 100644 --- a/src/desktop/components/product-carousel/__test__/product-carousel.test.tsx +++ b/src/desktop/components/product-carousel/__test__/product-carousel.test.tsx @@ -50,7 +50,11 @@ describe('ProductCarousel', () => { {items.map((item, index) => ( - + { const { container } = render( - + { {items.map((item, index) => ( - + { {items.map((item, index) => ( - + { {items.map((item, index) => ( - + { {items.map((item, index) => ( - + { {items.map((item, index) => ( - + { {items.map((item, index) => ( - + { {items.map((item, index) => ( - + { {items.map((item, index) => ( - + { {items.map((item, index) => ( - + Date: Mon, 22 Jul 2024 15:20:03 +0500 Subject: [PATCH 3/3] #279 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs: правки примеров использования ProductInfo --- .github/workflows/gh-pages.yml | 5 ++++ .../product-info/01-primary.stories.tsx | 2 +- .../02-image-slider.stories.meta.json | 7 ++++++ .../product-info/02-image-slider.stories.tsx | 21 ++++++++++------ .../03-custom-ratio.stories.meta.json | 7 ++++++ .../product-info/03-custom-ratio.stories.tsx | 18 ++++++++------ .../product-info/04-cart-loading.stories.tsx | 2 +- .../product-info/05-not-enough.stories.tsx | 2 +- .../06-not-enough-waited.stories.tsx | 2 +- .../product-info/07-unavailable.stories.tsx | 2 +- .../08-mature-content.stories.tsx | 24 ++++++++++++++++--- .../product-info/09-with-carousel.stories.tsx | 2 +- .../components/product-info/styles.m.css | 7 ++++++ .../product-carousel/01-primary.stories.tsx | 2 +- .../02-unavailable.stories.tsx | 2 +- .../product-carousel/03-adult.stories.tsx | 2 +- .../04-deferred-data.stories.tsx | 2 +- .../product-carousel/05-few-items.stories.tsx | 2 +- .../06-custom-item-size.stories.tsx | 2 +- .../product-slider/01-primary.stories.tsx | 2 +- .../product-slider/02-unavailable.stories.tsx | 2 +- .../product-slider/03-adult.stories.tsx | 2 +- 22 files changed, 87 insertions(+), 32 deletions(-) create mode 100644 docs/stories/common/components/product-info/02-image-slider.stories.meta.json create mode 100644 docs/stories/common/components/product-info/03-custom-ratio.stories.meta.json create mode 100644 docs/stories/common/components/product-info/styles.m.css diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index d0a0b842..d6579eec 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -23,6 +23,11 @@ jobs: npm ci working-directory: docs + - name: Lint docs + run: | + npm run check + working-directory: docs + - name: Build docs run: | NODE_ENV=production npm run build diff --git a/docs/stories/common/components/product-info/01-primary.stories.tsx b/docs/stories/common/components/product-info/01-primary.stories.tsx index 97a11b51..7ba1c840 100644 --- a/docs/stories/common/components/product-info/01-primary.stories.tsx +++ b/docs/stories/common/components/product-info/01-primary.stories.tsx @@ -18,7 +18,7 @@ export default function Primary() { return (
- + +
- + +
- + - + - + - + +
- + - + {items.map((item, index) => ( - + {items.map((item, index) => ( - + {items.map((item, index) => ( - + ( { e.preventDefault(); diff --git a/docs/stories/desktop/components/product-carousel/05-few-items.stories.tsx b/docs/stories/desktop/components/product-carousel/05-few-items.stories.tsx index eed70355..52f2541e 100644 --- a/docs/stories/desktop/components/product-carousel/05-few-items.stories.tsx +++ b/docs/stories/desktop/components/product-carousel/05-few-items.stories.tsx @@ -34,7 +34,7 @@ export default function FewItems() { {items.slice(0, 4).map((item, index) => ( { e.preventDefault(); diff --git a/docs/stories/desktop/components/product-carousel/06-custom-item-size.stories.tsx b/docs/stories/desktop/components/product-carousel/06-custom-item-size.stories.tsx index 2129261c..ee604259 100644 --- a/docs/stories/desktop/components/product-carousel/06-custom-item-size.stories.tsx +++ b/docs/stories/desktop/components/product-carousel/06-custom-item-size.stories.tsx @@ -22,7 +22,7 @@ export default function CustomItemSize() { > {items.map((item, index) => ( - + {items.map((item, index) => ( - + {items.map((item, index) => ( - + {items.map((item, index) => ( - +