@redneckz/wildless-cms-uni-blocks 0.3.55 → 0.3.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/blocks.schema.json +1 -1
- package/bundle/bundle.umd.js +69 -21
- package/bundle/bundle.umd.min.js +1 -1
- package/dist/components/BlockContent.d.ts +2 -1
- package/dist/components/Blocks.d.ts +1 -0
- package/dist/components/Blocks.js +2 -0
- package/dist/components/Blocks.js.map +1 -1
- package/dist/components/ContentPage/ContentPage.js +3 -5
- package/dist/components/ContentPage/ContentPage.js.map +1 -1
- package/dist/components/ContentPage/CustomContentPage.d.ts +30 -0
- package/dist/components/ContentPage/CustomContentPage.js +33 -0
- package/dist/components/ContentPage/CustomContentPage.js.map +1 -0
- package/dist/components/GroupBlock/BlocksTypeProps.d.ts +36 -0
- package/dist/components/GroupBlock/BlocksTypeProps.js +2 -0
- package/dist/components/GroupBlock/BlocksTypeProps.js.map +1 -0
- package/dist/components/GroupBlock/EmbeddableGroupBlocks.d.ts +4 -0
- package/dist/components/GroupBlock/EmbeddableGroupBlocks.js +9 -0
- package/dist/components/GroupBlock/EmbeddableGroupBlocks.js.map +1 -0
- package/dist/components/GroupBlock/GroupBlock.d.ts +9 -0
- package/dist/components/GroupBlock/GroupBlock.js +19 -0
- package/dist/components/GroupBlock/GroupBlock.js.map +1 -0
- package/dist/components/GroupBlock/GroupBlockContent.d.ts +21 -0
- package/dist/components/GroupBlock/GroupBlockContent.js +2 -0
- package/dist/components/GroupBlock/GroupBlockContent.js.map +1 -0
- package/dist/components/GroupBlock/GroupBlockTabs.d.ts +10 -0
- package/dist/components/GroupBlock/GroupBlockTabs.js +18 -0
- package/dist/components/GroupBlock/GroupBlockTabs.js.map +1 -0
- package/dist/components/GroupBlock/GroupBlocksItem.d.ts +8 -0
- package/dist/components/GroupBlock/GroupBlocksItem.js +20 -0
- package/dist/components/GroupBlock/GroupBlocksItem.js.map +1 -0
- package/dist/components/GroupBlock/filterBlocksByTag.d.ts +2 -0
- package/dist/components/GroupBlock/filterBlocksByTag.js +7 -0
- package/dist/components/GroupBlock/filterBlocksByTag.js.map +1 -0
- package/dist/components/GroupBlock/renderBlocksTypes.d.ts +9 -0
- package/dist/components/GroupBlock/renderBlocksTypes.js +16 -0
- package/dist/components/GroupBlock/renderBlocksTypes.js.map +1 -0
- package/dist/components/OtherProducts/OtherProductsContent.d.ts +4 -2
- package/dist/components/ProductBlock/ProductBlockInner.js +1 -1
- package/dist/components/ProductBlock/ProductBlockInner.js.map +1 -1
- package/dist/components/ProductGalleryGreen/ProductGalleryGreen.js +9 -11
- package/dist/components/ProductGalleryGreen/ProductGalleryGreen.js.map +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/utils/style2className.d.ts +1 -0
- package/dist/utils/style2className.js +7 -0
- package/dist/utils/style2className.js.map +1 -0
- package/lib/common.css +1 -1
- package/lib/components/BlockContent.d.ts +2 -1
- package/lib/components/Blocks.d.ts +1 -0
- package/lib/components/Blocks.js +2 -0
- package/lib/components/Blocks.js.map +1 -1
- package/lib/components/ContentPage/ContentPage.js +1 -3
- package/lib/components/ContentPage/ContentPage.js.map +1 -1
- package/lib/components/ContentPage/CustomContentPage.d.ts +30 -0
- package/lib/components/ContentPage/CustomContentPage.js +31 -0
- package/lib/components/ContentPage/CustomContentPage.js.map +1 -0
- package/lib/components/GroupBlock/BlocksTypeProps.d.ts +36 -0
- package/lib/components/GroupBlock/BlocksTypeProps.js +2 -0
- package/lib/components/GroupBlock/BlocksTypeProps.js.map +1 -0
- package/lib/components/GroupBlock/EmbeddableGroupBlocks.d.ts +4 -0
- package/lib/components/GroupBlock/EmbeddableGroupBlocks.js +7 -0
- package/lib/components/GroupBlock/EmbeddableGroupBlocks.js.map +1 -0
- package/lib/components/GroupBlock/GroupBlock.d.ts +9 -0
- package/lib/components/GroupBlock/GroupBlock.fixture.d.ts +4 -0
- package/lib/components/GroupBlock/GroupBlock.js +17 -0
- package/lib/components/GroupBlock/GroupBlock.js.map +1 -0
- package/lib/components/GroupBlock/GroupBlockContent.d.ts +21 -0
- package/lib/components/GroupBlock/GroupBlockContent.js +2 -0
- package/lib/components/GroupBlock/GroupBlockContent.js.map +1 -0
- package/lib/components/GroupBlock/GroupBlockTabs.d.ts +10 -0
- package/lib/components/GroupBlock/GroupBlockTabs.js +16 -0
- package/lib/components/GroupBlock/GroupBlockTabs.js.map +1 -0
- package/lib/components/GroupBlock/GroupBlocksItem.d.ts +8 -0
- package/lib/components/GroupBlock/GroupBlocksItem.js +17 -0
- package/lib/components/GroupBlock/GroupBlocksItem.js.map +1 -0
- package/lib/components/GroupBlock/filterBlocksByTag.d.ts +2 -0
- package/lib/components/GroupBlock/filterBlocksByTag.js +4 -0
- package/lib/components/GroupBlock/filterBlocksByTag.js.map +1 -0
- package/lib/components/GroupBlock/renderBlocksTypes.d.ts +9 -0
- package/lib/components/GroupBlock/renderBlocksTypes.js +13 -0
- package/lib/components/GroupBlock/renderBlocksTypes.js.map +1 -0
- package/lib/components/OtherProducts/OtherProductsContent.d.ts +4 -2
- package/lib/components/ProductBlock/ProductBlockInner.js +1 -1
- package/lib/components/ProductBlock/ProductBlockInner.js.map +1 -1
- package/lib/components/ProductGalleryGreen/ProductGalleryGreen.js +9 -11
- package/lib/components/ProductGalleryGreen/ProductGalleryGreen.js.map +1 -1
- package/lib/types.d.ts +5 -0
- package/lib/utils/style2className.d.ts +1 -0
- package/lib/utils/style2className.js +4 -0
- package/lib/utils/style2className.js.map +1 -0
- package/mobile/bundle/bundle.umd.js +4 -3
- package/mobile/bundle/bundle.umd.min.js +1 -1
- package/mobile/dist/components/BlockContent.d.ts +2 -1
- package/mobile/dist/components/ContentPage/ContentPage.js +3 -5
- package/mobile/dist/components/ContentPage/ContentPage.js.map +1 -1
- package/mobile/dist/components/ContentPage/CustomContentPage.d.ts +30 -0
- package/mobile/dist/components/ContentPage/CustomContentPage.js +33 -0
- package/mobile/dist/components/ContentPage/CustomContentPage.js.map +1 -0
- package/mobile/dist/components/GroupBlock/BlocksTypeProps.d.ts +36 -0
- package/mobile/dist/components/GroupBlock/BlocksTypeProps.js +2 -0
- package/mobile/dist/components/GroupBlock/BlocksTypeProps.js.map +1 -0
- package/mobile/dist/components/GroupBlock/EmbeddableGroupBlocks.d.ts +4 -0
- package/mobile/dist/components/GroupBlock/EmbeddableGroupBlocks.js +9 -0
- package/mobile/dist/components/GroupBlock/EmbeddableGroupBlocks.js.map +1 -0
- package/mobile/dist/components/GroupBlock/GroupBlock.d.ts +9 -0
- package/mobile/dist/components/GroupBlock/GroupBlock.js +19 -0
- package/mobile/dist/components/GroupBlock/GroupBlock.js.map +1 -0
- package/mobile/dist/components/GroupBlock/GroupBlockContent.d.ts +21 -0
- package/mobile/dist/components/GroupBlock/GroupBlockContent.js +2 -0
- package/mobile/dist/components/GroupBlock/GroupBlockContent.js.map +1 -0
- package/mobile/dist/components/GroupBlock/GroupBlockTabs.d.ts +10 -0
- package/mobile/dist/components/GroupBlock/GroupBlockTabs.js +18 -0
- package/mobile/dist/components/GroupBlock/GroupBlockTabs.js.map +1 -0
- package/mobile/dist/components/GroupBlock/GroupBlocksItem.d.ts +8 -0
- package/mobile/dist/components/GroupBlock/GroupBlocksItem.js +20 -0
- package/mobile/dist/components/GroupBlock/GroupBlocksItem.js.map +1 -0
- package/mobile/dist/components/GroupBlock/filterBlocksByTag.d.ts +2 -0
- package/mobile/dist/components/GroupBlock/filterBlocksByTag.js +7 -0
- package/mobile/dist/components/GroupBlock/filterBlocksByTag.js.map +1 -0
- package/mobile/dist/components/GroupBlock/renderBlocksTypes.d.ts +9 -0
- package/mobile/dist/components/GroupBlock/renderBlocksTypes.js +16 -0
- package/mobile/dist/components/GroupBlock/renderBlocksTypes.js.map +1 -0
- package/mobile/dist/components/OtherProducts/OtherProductsContent.d.ts +4 -2
- package/mobile/dist/components/ProductGalleryGreen/ProductGalleryGreen.js +9 -11
- package/mobile/dist/components/ProductGalleryGreen/ProductGalleryGreen.js.map +1 -1
- package/mobile/dist/types.d.ts +5 -0
- package/mobile/dist/utils/style2className.d.ts +1 -0
- package/mobile/dist/utils/style2className.js +7 -0
- package/mobile/dist/utils/style2className.js.map +1 -0
- package/mobile/lib/components/BlockContent.d.ts +2 -1
- package/mobile/lib/components/ContentPage/ContentPage.js +1 -3
- package/mobile/lib/components/ContentPage/ContentPage.js.map +1 -1
- package/mobile/lib/components/ContentPage/CustomContentPage.d.ts +30 -0
- package/mobile/lib/components/ContentPage/CustomContentPage.js +31 -0
- package/mobile/lib/components/ContentPage/CustomContentPage.js.map +1 -0
- package/mobile/lib/components/GroupBlock/BlocksTypeProps.d.ts +36 -0
- package/mobile/lib/components/GroupBlock/BlocksTypeProps.js +2 -0
- package/mobile/lib/components/GroupBlock/BlocksTypeProps.js.map +1 -0
- package/mobile/lib/components/GroupBlock/EmbeddableGroupBlocks.d.ts +4 -0
- package/mobile/lib/components/GroupBlock/EmbeddableGroupBlocks.js +7 -0
- package/mobile/lib/components/GroupBlock/EmbeddableGroupBlocks.js.map +1 -0
- package/mobile/lib/components/GroupBlock/GroupBlock.d.ts +9 -0
- package/mobile/lib/components/GroupBlock/GroupBlock.js +17 -0
- package/mobile/lib/components/GroupBlock/GroupBlock.js.map +1 -0
- package/mobile/lib/components/GroupBlock/GroupBlockContent.d.ts +21 -0
- package/mobile/lib/components/GroupBlock/GroupBlockContent.js +2 -0
- package/mobile/lib/components/GroupBlock/GroupBlockContent.js.map +1 -0
- package/mobile/lib/components/GroupBlock/GroupBlockTabs.d.ts +10 -0
- package/mobile/lib/components/GroupBlock/GroupBlockTabs.js +16 -0
- package/mobile/lib/components/GroupBlock/GroupBlockTabs.js.map +1 -0
- package/mobile/lib/components/GroupBlock/GroupBlocksItem.d.ts +8 -0
- package/mobile/lib/components/GroupBlock/GroupBlocksItem.js +17 -0
- package/mobile/lib/components/GroupBlock/GroupBlocksItem.js.map +1 -0
- package/mobile/lib/components/GroupBlock/filterBlocksByTag.d.ts +2 -0
- package/mobile/lib/components/GroupBlock/filterBlocksByTag.js +4 -0
- package/mobile/lib/components/GroupBlock/filterBlocksByTag.js.map +1 -0
- package/mobile/lib/components/GroupBlock/renderBlocksTypes.d.ts +9 -0
- package/mobile/lib/components/GroupBlock/renderBlocksTypes.js +13 -0
- package/mobile/lib/components/GroupBlock/renderBlocksTypes.js.map +1 -0
- package/mobile/lib/components/OtherProducts/OtherProductsContent.d.ts +4 -2
- package/mobile/lib/components/ProductGalleryGreen/ProductGalleryGreen.js +9 -11
- package/mobile/lib/components/ProductGalleryGreen/ProductGalleryGreen.js.map +1 -1
- package/mobile/lib/types.d.ts +5 -0
- package/mobile/lib/utils/style2className.d.ts +1 -0
- package/mobile/lib/utils/style2className.js +4 -0
- package/mobile/lib/utils/style2className.js.map +1 -0
- package/mobile/src/components/BlockContent.ts +3 -1
- package/mobile/src/components/ContentPage/ContentPage.tsx +1 -4
- package/mobile/src/components/ContentPage/CustomContentPage.tsx +82 -0
- package/mobile/src/components/GroupBlock/BlocksTypeProps.ts +40 -0
- package/mobile/src/components/GroupBlock/EmbeddableGroupBlocks.tsx +7 -0
- package/mobile/src/components/GroupBlock/GroupBlock.example.json +27 -0
- package/mobile/src/components/GroupBlock/GroupBlock.tsx +43 -0
- package/mobile/src/components/GroupBlock/GroupBlockContent.ts +23 -0
- package/mobile/src/components/GroupBlock/GroupBlockTabs.tsx +54 -0
- package/mobile/src/components/GroupBlock/GroupBlocksItem.tsx +30 -0
- package/mobile/src/components/GroupBlock/filterBlocksByTag.ts +5 -0
- package/mobile/src/components/GroupBlock/renderBlocksTypes.tsx +27 -0
- package/mobile/src/components/OtherProducts/OtherProductsContent.ts +4 -2
- package/mobile/src/components/ProductGalleryGreen/ProductGalleryGreen.tsx +8 -14
- package/mobile/src/types.ts +7 -1
- package/mobile/src/utils/style2className.ts +3 -0
- package/package.json +1 -1
- package/src/components/BlockContent.ts +3 -1
- package/src/components/Blocks.ts +2 -0
- package/src/components/ContentPage/ContentPage.tsx +1 -4
- package/src/components/ContentPage/CustomContentPage.tsx +82 -0
- package/src/components/GroupBlock/BlocksTypeProps.ts +40 -0
- package/src/components/GroupBlock/EmbeddableGroupBlocks.tsx +7 -0
- package/src/components/GroupBlock/GroupBlock.example.json +27 -0
- package/src/components/GroupBlock/GroupBlock.fixture.tsx +51 -0
- package/src/components/GroupBlock/GroupBlock.tsx +43 -0
- package/src/components/GroupBlock/GroupBlockContent.ts +23 -0
- package/src/components/GroupBlock/GroupBlockTabs.tsx +54 -0
- package/src/components/GroupBlock/GroupBlocksItem.tsx +30 -0
- package/src/components/GroupBlock/filterBlocksByTag.ts +5 -0
- package/src/components/GroupBlock/renderBlocksTypes.tsx +27 -0
- package/src/components/OtherProducts/OtherProductsContent.ts +4 -2
- package/src/components/ProductBlock/ProductBlockInner.tsx +1 -1
- package/src/components/ProductGalleryGreen/ProductGalleryGreen.tsx +8 -14
- package/src/types.ts +7 -1
- package/src/utils/style2className.ts +3 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { JSXBlock } from '../../components/ContentPage/ContentPage';
|
|
2
|
+
import type { ContentPageContext } from '../../components/ContentPage/ContentPageContext';
|
|
3
|
+
import type { GroupBlockDef } from './BlocksTypeProps';
|
|
4
|
+
import { EmbeddableGroupBlocks } from './EmbeddableGroupBlocks';
|
|
5
|
+
import { style2className } from '../../utils/style2className';
|
|
6
|
+
|
|
7
|
+
type EmbeddableBlocksProps = {
|
|
8
|
+
groupBlocks?: GroupBlockDef[];
|
|
9
|
+
context: ContentPageContext;
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const renderBlock =
|
|
14
|
+
({ context, className }: EmbeddableBlocksProps) =>
|
|
15
|
+
(block: GroupBlockDef, i: number) => {
|
|
16
|
+
const type = block?.blockType;
|
|
17
|
+
if (!type || !(type in EmbeddableGroupBlocks)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const classNameBlock = style2className(block?.style);
|
|
21
|
+
const EmbeddedBlock: JSXBlock = EmbeddableGroupBlocks[type];
|
|
22
|
+
return (
|
|
23
|
+
<div className={className} key={`block_${i}`}>
|
|
24
|
+
<EmbeddedBlock context={context} {...block} className={classNameBlock} />
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
@@ -14,7 +14,10 @@ export interface BlockItemCommonProps {
|
|
|
14
14
|
* @title Отображать в раскрытом виде
|
|
15
15
|
*/
|
|
16
16
|
isExpanded?: boolean;
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* @title Блоки
|
|
19
|
+
* @maxItems 10
|
|
20
|
+
*/
|
|
18
21
|
blocks?: BlockDef[];
|
|
19
22
|
columns?: ColumnsCount;
|
|
20
23
|
}
|
|
@@ -27,7 +30,6 @@ export interface OtherProductsContent {
|
|
|
27
30
|
title?: string;
|
|
28
31
|
/**
|
|
29
32
|
* @title Список
|
|
30
|
-
* @maxItems 10
|
|
31
33
|
*/
|
|
32
34
|
blockItems?: BlockItemCommonProps[];
|
|
33
35
|
colorPalette?: ColorPalette;
|
|
@@ -28,7 +28,7 @@ const productSlideStyleMap: Record<BlockVersion, string> = {
|
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
export const ProductGalleryGreen = JSX<ProductGalleryProps>(
|
|
31
|
-
({ className = '', context, slides = [], version = 'primary',
|
|
31
|
+
({ className = '', context, slides = [], version = 'primary', anchor = null }) => {
|
|
32
32
|
const galleryNav = slides.map((s) => s.nav);
|
|
33
33
|
const galleryBlocks = slides.map((s) => s.productBlock);
|
|
34
34
|
const [activeSlideIndex, setActiveSlideIndex] = context.useState(0);
|
|
@@ -55,7 +55,6 @@ export const ProductGalleryGreen = JSX<ProductGalleryProps>(
|
|
|
55
55
|
activeSlideIndex,
|
|
56
56
|
onClick: () => setActiveSlideIndex(i),
|
|
57
57
|
version,
|
|
58
|
-
duration,
|
|
59
58
|
}),
|
|
60
59
|
)}
|
|
61
60
|
</div>
|
|
@@ -76,7 +75,7 @@ function renderProductBlock(block: ProductBlockInnerContent, i: number, context)
|
|
|
76
75
|
>
|
|
77
76
|
<div className="flex grow">
|
|
78
77
|
<ProductBlockInner
|
|
79
|
-
className={`pl-[50px]
|
|
78
|
+
className={`pl-[50px] z-[1] ${additionalClass}`}
|
|
80
79
|
context={context}
|
|
81
80
|
textBlockClassName="mb-[154px]"
|
|
82
81
|
{...block}
|
|
@@ -86,12 +85,12 @@ function renderProductBlock(block: ProductBlockInnerContent, i: number, context)
|
|
|
86
85
|
);
|
|
87
86
|
}
|
|
88
87
|
|
|
89
|
-
function renderNavButton({ slide, i, activeSlideIndex, onClick, version
|
|
88
|
+
function renderNavButton({ slide, i, activeSlideIndex, onClick, version }) {
|
|
90
89
|
const isActiveBtn = i === activeSlideIndex;
|
|
91
90
|
|
|
92
91
|
const btnClassName = isActiveBtn
|
|
93
|
-
? 'bg-white shadow-dark-blue/42 h-[102px] w-[354px] min-w-[354px]
|
|
94
|
-
: `min-w-[277px] px-0 pt-4 pb-[23px] hover:py-[26px] hover:py-[26px] ease-in duration-300
|
|
92
|
+
? 'bg-white shadow-dark-blue/42 h-[102px] w-[354px] min-w-[354px] p-0 border-none'
|
|
93
|
+
: `min-w-[277px] px-0 pt-4 pb-[23px] hover:py-[26px] hover:py-[26px] ease-in duration-300 bg-white/10
|
|
95
94
|
${productSlideStyleMap[version]}`;
|
|
96
95
|
const btnTitleClassName = isActiveBtn
|
|
97
96
|
? 'text-primary-text text-title-2xs'
|
|
@@ -100,8 +99,7 @@ function renderNavButton({ slide, i, activeSlideIndex, onClick, version, duratio
|
|
|
100
99
|
? 'text-secondary-text text-m-title-xs mt-2.5'
|
|
101
100
|
: `text-m-md mt-1.5 ${productBlockStyleMap[version].text}`;
|
|
102
101
|
|
|
103
|
-
const additionalBorder = version === 'secondary' ? 'border-white/50' : '';
|
|
104
|
-
const progressBarClassName = isActiveBtn ? 'animate-slide' : '';
|
|
102
|
+
const additionalBorder = version === 'secondary' ? 'border-white/50' : 'border-black/50';
|
|
105
103
|
|
|
106
104
|
return (
|
|
107
105
|
<button
|
|
@@ -109,18 +107,14 @@ function renderNavButton({ slide, i, activeSlideIndex, onClick, version, duratio
|
|
|
109
107
|
key={String(i)}
|
|
110
108
|
onClick={onClick}
|
|
111
109
|
aria-label={slide?.title}
|
|
112
|
-
className={`box-border font-sans
|
|
113
|
-
|
|
110
|
+
className={`box-border font-sans relative overflow-hidden border-[1px] border-white/50 cursor-pointer text-left mx-1 grow basis-0
|
|
111
|
+
${btnClassName} ${additionalBorder}
|
|
114
112
|
`}
|
|
115
113
|
>
|
|
116
114
|
<div className="border-0 px-6">
|
|
117
115
|
<div className={`font-medium ${btnTitleClassName}`}>{slide?.title}</div>
|
|
118
116
|
<div className={`text-secondary-text ${btnDescClassName}`}>{slide.description}</div>
|
|
119
117
|
</div>
|
|
120
|
-
<div
|
|
121
|
-
className={`absolute bottom-0 left-0 w-full h-[3px] bg-primary-main -translate-x-full ${progressBarClassName}`}
|
|
122
|
-
style={{ animationDuration: `${duration}s`, animationFillMode: 'forwards' }}
|
|
123
|
-
></div>
|
|
124
118
|
</button>
|
|
125
119
|
);
|
|
126
120
|
}
|
package/mobile/src/types.ts
CHANGED
|
@@ -44,10 +44,16 @@ export interface ContentPageMeta {
|
|
|
44
44
|
jsonLd?: string;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
export interface CustomPageTemplate {
|
|
48
|
+
content?: Record<string, any>;
|
|
49
|
+
type?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
47
52
|
export interface ContentPageDef extends ContentPageMeta {
|
|
48
53
|
style?: string[];
|
|
49
|
-
blocks?: BlockDef[];
|
|
54
|
+
blocks?: BlockDef[];
|
|
50
55
|
slots?: SlotsMap;
|
|
56
|
+
customPageTmpl?: CustomPageTemplate;
|
|
51
57
|
likeControl?: boolean;
|
|
52
58
|
colorPalette?: ColorPalette;
|
|
53
59
|
}
|
package/package.json
CHANGED
|
@@ -5,6 +5,7 @@ import type { ExchangeRateTileContent } from './ExchangeRateTile/ExchangeRateTil
|
|
|
5
5
|
import type { FooterContent } from './Footer/FooterContent';
|
|
6
6
|
import type { GalleryContent } from './Gallery/GalleryContent';
|
|
7
7
|
import type { GracePeriodContent } from './GracePeriod/GracePeriodContent';
|
|
8
|
+
import type { GroupBlockContent } from './GroupBlock/GroupBlockContent';
|
|
8
9
|
import type { HeaderContent } from './Header/HeaderContent';
|
|
9
10
|
import type { LinkDocsContent } from './LinkDocs/LinkDocsContent';
|
|
10
11
|
import type { LinkListContent } from './LinkList/LinkListContent';
|
|
@@ -48,4 +49,5 @@ export type BlockContent =
|
|
|
48
49
|
| TextBlockContent
|
|
49
50
|
| TileContent
|
|
50
51
|
| NavigationContent
|
|
51
|
-
| LinkListContent
|
|
52
|
+
| LinkListContent
|
|
53
|
+
| GroupBlockContent;
|
package/src/components/Blocks.ts
CHANGED
|
@@ -27,6 +27,7 @@ import { StepsBlock } from './StepsBlock/StepsBlock';
|
|
|
27
27
|
import { TariffsTable } from './TariffsTable/TariffsTable';
|
|
28
28
|
import { TextBlock } from './TextBlock/TextBlock';
|
|
29
29
|
import { Tile } from './Tile/Tile';
|
|
30
|
+
import { GroupBlock } from './GroupBlock/GroupBlock';
|
|
30
31
|
|
|
31
32
|
export const Blocks = {
|
|
32
33
|
Accordion,
|
|
@@ -58,4 +59,5 @@ export const Blocks = {
|
|
|
58
59
|
Tile,
|
|
59
60
|
Navigation,
|
|
60
61
|
Placeholder,
|
|
62
|
+
GroupBlock,
|
|
61
63
|
};
|
|
@@ -2,6 +2,7 @@ import { JSX, PropsWithChildren } from '@redneckz/uni-jsx';
|
|
|
2
2
|
import type { BlockDef, ContentPageDef, UniBlockProps } from '../../types';
|
|
3
3
|
import { changeHashOnScroll } from '../../utils/changeHashOnScroll';
|
|
4
4
|
import { isSSR } from '../../utils/isSSR';
|
|
5
|
+
import { style2className } from '../../utils/style2className';
|
|
5
6
|
import type { BlockContent } from '../BlockContent';
|
|
6
7
|
import { LikeControl } from '../LikeControl/LikeControl';
|
|
7
8
|
import { Placeholder } from '../Placeholder/Placeholder';
|
|
@@ -128,7 +129,3 @@ function renderBlock(
|
|
|
128
129
|
`block-${i}`,
|
|
129
130
|
);
|
|
130
131
|
}
|
|
131
|
-
|
|
132
|
-
function style2className(style: string[] | undefined | null): string {
|
|
133
|
-
return style ? style.join(' ') : '';
|
|
134
|
-
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { ContentPageDef, CustomPageTemplate, UniBlockProps } from '../../types';
|
|
3
|
+
import { style2className } from '../../utils/style2className';
|
|
4
|
+
import { ContentPageContext } from './ContentPageContext';
|
|
5
|
+
|
|
6
|
+
interface PageDecoratorProps<VNode> {
|
|
7
|
+
pageClassName: string;
|
|
8
|
+
pageTemplate: CustomPageTemplate;
|
|
9
|
+
render: (props: { pageClassName: string; pageTemplate: CustomPageTemplate }) => VNode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type PageDecorator<VNode = any> = (
|
|
13
|
+
props: PageDecoratorProps<VNode>,
|
|
14
|
+
index?: number | string,
|
|
15
|
+
) => any;
|
|
16
|
+
|
|
17
|
+
export interface PageTemplate {
|
|
18
|
+
name: string;
|
|
19
|
+
template: any;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type PageTemplatesRegistry = Record<string, PageTemplate>;
|
|
23
|
+
|
|
24
|
+
export interface CustomContentPageProps extends UniBlockProps {
|
|
25
|
+
pageTemplatesRegistry: PageTemplatesRegistry;
|
|
26
|
+
data: ContentPageDef;
|
|
27
|
+
pageDecorator?: PageDecorator;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface RenderPageFunc {
|
|
31
|
+
pageTemplate: CustomPageTemplate;
|
|
32
|
+
pageClassName: string;
|
|
33
|
+
pageDecorator: PageDecorator;
|
|
34
|
+
pageTemplatesRegistry: PageTemplatesRegistry;
|
|
35
|
+
context: ContentPageContext;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const defaultPageDecorator: PageDecorator = ({ pageClassName, pageTemplate, render }) =>
|
|
39
|
+
render({ pageClassName, pageTemplate });
|
|
40
|
+
|
|
41
|
+
export const CustomContentPage = JSX<CustomContentPageProps>(
|
|
42
|
+
({
|
|
43
|
+
className = '',
|
|
44
|
+
context,
|
|
45
|
+
pageTemplatesRegistry,
|
|
46
|
+
data: { style: pageStyle, customPageTmpl: pageTemplate },
|
|
47
|
+
pageDecorator = defaultPageDecorator,
|
|
48
|
+
}) => {
|
|
49
|
+
return pageTemplate
|
|
50
|
+
? renderPage({
|
|
51
|
+
pageTemplate,
|
|
52
|
+
pageClassName: `${style2className(pageStyle)} ${className}`,
|
|
53
|
+
pageDecorator,
|
|
54
|
+
pageTemplatesRegistry,
|
|
55
|
+
context,
|
|
56
|
+
})
|
|
57
|
+
: null;
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
function renderPage({
|
|
62
|
+
pageTemplate,
|
|
63
|
+
pageClassName,
|
|
64
|
+
pageDecorator,
|
|
65
|
+
pageTemplatesRegistry,
|
|
66
|
+
context,
|
|
67
|
+
}: RenderPageFunc) {
|
|
68
|
+
const { type } = pageTemplate;
|
|
69
|
+
if (!(type && type in pageTemplatesRegistry) || !pageTemplatesRegistry[type].template) {
|
|
70
|
+
throw new Error(`No page template with "${type}" is registered`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const { template: PageComponent } = pageTemplatesRegistry[type];
|
|
74
|
+
return pageDecorator({
|
|
75
|
+
pageClassName,
|
|
76
|
+
pageTemplate,
|
|
77
|
+
render: (props) => {
|
|
78
|
+
const { content } = props.pageTemplate;
|
|
79
|
+
return <PageComponent className={props.pageClassName} context={context} {...content} />;
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ProductBlockContent } from '../../components/ProductBlock/ProductBlockContent';
|
|
2
|
+
import type { ProductTileContent } from '../../components/ProductTile/ProductTileContent';
|
|
3
|
+
import { ContentPageContext } from '../../components/ContentPage/ContentPageContext';
|
|
4
|
+
|
|
5
|
+
export interface ActiveHandler {
|
|
6
|
+
context: ContentPageContext;
|
|
7
|
+
blocks?: GroupBlockDef[];
|
|
8
|
+
initialState?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface GroupBlockCommonProps {
|
|
12
|
+
/** @title Стиль */
|
|
13
|
+
style?: string[];
|
|
14
|
+
/** @title Теги */
|
|
15
|
+
tags?: string[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @title Продуктовый блок
|
|
20
|
+
* @default {"blockType": "ProductBlock"}
|
|
21
|
+
*/
|
|
22
|
+
export type ProductBlockDef = ProductBlockContent &
|
|
23
|
+
GroupBlockCommonProps & { blockType: 'ProductBlock' };
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @title Продуктовая плитка
|
|
27
|
+
* @default {"blockType": "ProductTile"}
|
|
28
|
+
*/
|
|
29
|
+
export type ProductTileDef = ProductTileContent &
|
|
30
|
+
GroupBlockCommonProps & { blockType: 'ProductTile' };
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @title Выберите блок
|
|
34
|
+
*/
|
|
35
|
+
export type EmptyOption = null;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @title Содержимое блока
|
|
39
|
+
*/
|
|
40
|
+
export type GroupBlockDef = EmptyOption | ProductBlockDef | ProductTileDef;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tabs": [
|
|
3
|
+
{ "title": "Еще программы", "index": 0 },
|
|
4
|
+
{ "title": "Страхование жизни", "index": 1, "tag": "tag1" },
|
|
5
|
+
{ "title": "Страхование здоровья", "index": 2, "tag": "tag2" }
|
|
6
|
+
],
|
|
7
|
+
"blocks": [
|
|
8
|
+
{
|
|
9
|
+
"blockType": "ProductBlock",
|
|
10
|
+
"title": "Продуктовый блок",
|
|
11
|
+
"description": "Описание текстового блока",
|
|
12
|
+
"tags":["tag2"]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"blockType": "ProductTile",
|
|
16
|
+
"title": "Продуктовая плитка",
|
|
17
|
+
"description": "Описание текстового блока",
|
|
18
|
+
"tags":["tag1"]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"blockType": "ProductBlock",
|
|
22
|
+
"title": "Продуктовый блок",
|
|
23
|
+
"description": "Описание текстового блока",
|
|
24
|
+
"tags":["tag2"]
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { context } from '../../setup-fixture';
|
|
2
|
+
import { PRODUCT_TILE } from '../ProductTile/ProductTile.fixture';
|
|
3
|
+
import { PRODUCT_BLOCK } from '../ProductBlock/ProductBlock.fixture';
|
|
4
|
+
import { GroupBlock } from './GroupBlock';
|
|
5
|
+
import groupBlockExample from './GroupBlock.example.json';
|
|
6
|
+
import type { ProductTileDef, ProductBlockDef } from './BlocksTypeProps';
|
|
7
|
+
|
|
8
|
+
const PRODUCT_TILE_GROUP_BLOCK: ProductTileDef = {
|
|
9
|
+
blockType: 'ProductTile',
|
|
10
|
+
tags: ['tag2'],
|
|
11
|
+
style: ['col-span-6'],
|
|
12
|
+
...PRODUCT_TILE,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const PRODUCT_TILE_GROUP_BLOCK2: ProductTileDef = {
|
|
16
|
+
blockType: 'ProductTile',
|
|
17
|
+
tags: ['tag2'],
|
|
18
|
+
style: ['col-span-6'],
|
|
19
|
+
...PRODUCT_TILE,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const PRODUCT_BLOCK_GROUP_BLOCK: ProductBlockDef = {
|
|
23
|
+
blockType: 'ProductBlock',
|
|
24
|
+
tags: ['tag1'],
|
|
25
|
+
style: ['col-span-12'],
|
|
26
|
+
...PRODUCT_BLOCK,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const PRODUCT_BLOCK_GROUP_BLOCK2: ProductBlockDef = {
|
|
30
|
+
blockType: 'ProductBlock',
|
|
31
|
+
style: ['col-span-12'],
|
|
32
|
+
...PRODUCT_BLOCK,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default {
|
|
36
|
+
default: (
|
|
37
|
+
<div className="container grid grid-cols-12">
|
|
38
|
+
<GroupBlock
|
|
39
|
+
context={context}
|
|
40
|
+
className="col-span-12"
|
|
41
|
+
tabs={groupBlockExample.tabs}
|
|
42
|
+
groupBlocks={[
|
|
43
|
+
PRODUCT_TILE_GROUP_BLOCK,
|
|
44
|
+
PRODUCT_TILE_GROUP_BLOCK2,
|
|
45
|
+
PRODUCT_BLOCK_GROUP_BLOCK,
|
|
46
|
+
PRODUCT_BLOCK_GROUP_BLOCK2,
|
|
47
|
+
]}
|
|
48
|
+
/>
|
|
49
|
+
</div>
|
|
50
|
+
),
|
|
51
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { UniBlockProps } from '../../types';
|
|
3
|
+
import type { GroupBlockContent, GroupBlockTab } from './GroupBlockContent';
|
|
4
|
+
import { GroupBlockTabs } from './GroupBlockTabs';
|
|
5
|
+
import { GroupBlocksItem } from './GroupBlocksItem';
|
|
6
|
+
import { filterBlocksByTag } from './filterBlocksByTag';
|
|
7
|
+
|
|
8
|
+
export interface TabsItemProps extends GroupBlockTab {
|
|
9
|
+
count?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface GroupBlockProps extends GroupBlockContent, UniBlockProps {
|
|
13
|
+
tabs?: TabsItemProps[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const GroupBlock = JSX<GroupBlockProps>(
|
|
17
|
+
({ className = '', tabs, context, anchor = null, groupBlocks = [] }) => {
|
|
18
|
+
const [currentTag, setCurrentTag] = context.useState(tabs?.[0]?.tag);
|
|
19
|
+
|
|
20
|
+
const filteredBlocks = filterBlocksByTag(groupBlocks, currentTag);
|
|
21
|
+
|
|
22
|
+
const tabsNewMap = tabs?.map((tab) => {
|
|
23
|
+
const count = tab.tag
|
|
24
|
+
? groupBlocks.filter((block) => block?.tags?.includes(`${tab.tag}`)).length
|
|
25
|
+
: groupBlocks.length;
|
|
26
|
+
|
|
27
|
+
return { ...tab, count };
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<section id={anchor} className={`box-border gap-1 h-12 ${className}`}>
|
|
32
|
+
{tabsNewMap?.length ? (
|
|
33
|
+
<GroupBlockTabs currentTag={currentTag} onTabClick={setCurrentTag} tabs={tabsNewMap} />
|
|
34
|
+
) : null}
|
|
35
|
+
{groupBlocks.length ? (
|
|
36
|
+
<div className="list-none">
|
|
37
|
+
<GroupBlocksItem context={context} groupBlocks={filteredBlocks} />
|
|
38
|
+
</div>
|
|
39
|
+
) : null}
|
|
40
|
+
</section>
|
|
41
|
+
);
|
|
42
|
+
},
|
|
43
|
+
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { GroupBlockDef } from './BlocksTypeProps';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @title Таб
|
|
5
|
+
*/
|
|
6
|
+
export interface GroupBlockTab {
|
|
7
|
+
/** @title Название */
|
|
8
|
+
title?: string;
|
|
9
|
+
/** @title Tег */
|
|
10
|
+
tag?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @title Блок-группировки
|
|
15
|
+
*/
|
|
16
|
+
export interface GroupBlockContent {
|
|
17
|
+
/** @title Блоки */
|
|
18
|
+
groupBlocks?: GroupBlockDef[];
|
|
19
|
+
/** @title Табы */
|
|
20
|
+
tabs?: GroupBlockTab[];
|
|
21
|
+
/** @title Показывать счетчик блоков во вкладках */
|
|
22
|
+
isShowCounter?: boolean;
|
|
23
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { TabsItemProps } from './GroupBlock';
|
|
3
|
+
|
|
4
|
+
export type TabClickHandler = (tag) => void;
|
|
5
|
+
|
|
6
|
+
export interface GroupBlockTabsProps {
|
|
7
|
+
onTabClick: TabClickHandler;
|
|
8
|
+
currentTag?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
tabs?: TabsItemProps[];
|
|
11
|
+
isShowCounter?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const GroupBlockTabs = JSX<GroupBlockTabsProps>((props) => {
|
|
15
|
+
const { tabs, currentTag, onTabClick, className = '', isShowCounter = true } = props;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div className={`mb-2 box-border flex gap-x-1 h-12 ${className}`} role="tablist">
|
|
19
|
+
{tabs?.map(renderTab(onTabClick, isShowCounter, currentTag))}
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const badgeStyle = 'w-[22px] h-[22px] rounded-full text-m-sm';
|
|
25
|
+
|
|
26
|
+
const renderTab =
|
|
27
|
+
(onTabClick: TabClickHandler, isShowCounter: boolean, currentTag?: string) =>
|
|
28
|
+
(tab: TabsItemProps, i: number) => {
|
|
29
|
+
const isActive = currentTag === tab.tag;
|
|
30
|
+
const tabBg = isActive ? 'bg-primary-main' : 'group bg-white';
|
|
31
|
+
const tabText = isActive ? 'text-white' : 'text-secondary-text group-hover:text-primary-main';
|
|
32
|
+
const counterBlockStyle = `${badgeStyle}
|
|
33
|
+
${isActive ? 'bg-white/30 text-white' : 'bg-secondary-text/10 text-secondary-text'}`;
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
key={String(i)}
|
|
38
|
+
className={`flex h-full w-full flex-1 cursor-pointer mr-2 last:mr-0 box-content ${tabBg}`}
|
|
39
|
+
role="tab"
|
|
40
|
+
onClick={() => onTabClick(tab.tag)}
|
|
41
|
+
aria-selected={String(isActive)}
|
|
42
|
+
tag={tab?.tag}
|
|
43
|
+
>
|
|
44
|
+
<div className="flex flex-1 items-center justify-center">
|
|
45
|
+
{tab?.title ? <h3 className={`mr-8 ${tabText}`}>{tab?.title}</h3> : null}
|
|
46
|
+
{isShowCounter ? (
|
|
47
|
+
<div className={`flex items-center justify-center ${counterBlockStyle}`}>
|
|
48
|
+
<span>{tab.count}</span>
|
|
49
|
+
</div>
|
|
50
|
+
) : null}
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { JSXBlock } from '../../components/ContentPage/ContentPage';
|
|
3
|
+
import type { ContentPageContext } from '../../components/ContentPage/ContentPageContext';
|
|
4
|
+
import type { UniBlockProps } from '../../types';
|
|
5
|
+
import { style2className } from '../../utils/style2className';
|
|
6
|
+
import type { GroupBlockDef } from './BlocksTypeProps';
|
|
7
|
+
import { EmbeddableGroupBlocks } from './EmbeddableGroupBlocks';
|
|
8
|
+
import { GroupBlockContent } from './GroupBlockContent';
|
|
9
|
+
|
|
10
|
+
export interface GroupBlocksProps extends GroupBlockContent, UniBlockProps {}
|
|
11
|
+
|
|
12
|
+
export const GroupBlocksItem = JSX<GroupBlocksProps>(({ groupBlocks, context }) => {
|
|
13
|
+
return (
|
|
14
|
+
<div className={'grid grid-cols-12 gap-2 box-border'}>
|
|
15
|
+
{groupBlocks?.length ? groupBlocks.map(renderBlock(context)) : null}
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const renderBlock = (context: ContentPageContext) => (block: GroupBlockDef, i: number) => {
|
|
21
|
+
const type = block?.blockType;
|
|
22
|
+
if (!type || !(type in EmbeddableGroupBlocks)) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const classNameBlock = style2className(block?.style);
|
|
26
|
+
const EmbeddedBlock: JSXBlock = EmbeddableGroupBlocks[type];
|
|
27
|
+
return (
|
|
28
|
+
<EmbeddedBlock key={`block_${i}`} context={context} {...block} className={classNameBlock} />
|
|
29
|
+
);
|
|
30
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { JSXBlock } from '../../components/ContentPage/ContentPage';
|
|
2
|
+
import type { ContentPageContext } from '../../components/ContentPage/ContentPageContext';
|
|
3
|
+
import type { GroupBlockDef } from './BlocksTypeProps';
|
|
4
|
+
import { EmbeddableGroupBlocks } from './EmbeddableGroupBlocks';
|
|
5
|
+
import { style2className } from '../../utils/style2className';
|
|
6
|
+
|
|
7
|
+
type EmbeddableBlocksProps = {
|
|
8
|
+
groupBlocks?: GroupBlockDef[];
|
|
9
|
+
context: ContentPageContext;
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const renderBlock =
|
|
14
|
+
({ context, className }: EmbeddableBlocksProps) =>
|
|
15
|
+
(block: GroupBlockDef, i: number) => {
|
|
16
|
+
const type = block?.blockType;
|
|
17
|
+
if (!type || !(type in EmbeddableGroupBlocks)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const classNameBlock = style2className(block?.style);
|
|
21
|
+
const EmbeddedBlock: JSXBlock = EmbeddableGroupBlocks[type];
|
|
22
|
+
return (
|
|
23
|
+
<div className={className} key={`block_${i}`}>
|
|
24
|
+
<EmbeddedBlock context={context} {...block} className={classNameBlock} />
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
@@ -14,7 +14,10 @@ export interface BlockItemCommonProps {
|
|
|
14
14
|
* @title Отображать в раскрытом виде
|
|
15
15
|
*/
|
|
16
16
|
isExpanded?: boolean;
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* @title Блоки
|
|
19
|
+
* @maxItems 10
|
|
20
|
+
*/
|
|
18
21
|
blocks?: BlockDef[];
|
|
19
22
|
columns?: ColumnsCount;
|
|
20
23
|
}
|
|
@@ -27,7 +30,6 @@ export interface OtherProductsContent {
|
|
|
27
30
|
title?: string;
|
|
28
31
|
/**
|
|
29
32
|
* @title Список
|
|
30
|
-
* @maxItems 10
|
|
31
33
|
*/
|
|
32
34
|
blockItems?: BlockItemCommonProps[];
|
|
33
35
|
colorPalette?: ColorPalette;
|