@gravity-ui/page-constructor 1.8.2 → 1.9.0
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/CHANGELOG.md +7 -0
- package/build/cjs/blocks/Tabs/Tabs.css +64 -24
- package/build/cjs/blocks/Tabs/Tabs.d.ts +1 -1
- package/build/cjs/blocks/Tabs/Tabs.js +29 -27
- package/build/cjs/blocks/Tabs/schema.d.ts +68 -17
- package/build/cjs/blocks/Tabs/schema.js +14 -19
- package/build/cjs/components/ButtonTabs/ButtonTabs.css +12 -0
- package/build/cjs/components/ButtonTabs/ButtonTabs.d.ts +13 -0
- package/build/cjs/components/ButtonTabs/ButtonTabs.js +26 -0
- package/build/cjs/components/Image/Image.css +4 -0
- package/build/cjs/components/Image/Image.js +3 -1
- package/build/cjs/constructor-items.d.ts +1 -1
- package/build/cjs/models/constructor-items/blocks.d.ts +7 -5
- package/build/cjs/text-transform/blocks.js +11 -4
- package/build/esm/blocks/Tabs/Tabs.css +64 -24
- package/build/esm/blocks/Tabs/Tabs.d.ts +1 -1
- package/build/esm/blocks/Tabs/Tabs.js +29 -27
- package/build/esm/blocks/Tabs/schema.d.ts +68 -17
- package/build/esm/blocks/Tabs/schema.js +14 -20
- package/build/esm/components/ButtonTabs/ButtonTabs.css +12 -0
- package/build/esm/components/ButtonTabs/ButtonTabs.d.ts +14 -0
- package/build/esm/components/ButtonTabs/ButtonTabs.js +24 -0
- package/build/esm/components/Image/Image.css +4 -0
- package/build/esm/components/Image/Image.d.ts +1 -0
- package/build/esm/components/Image/Image.js +4 -1
- package/build/esm/constructor-items.d.ts +1 -1
- package/build/esm/models/constructor-items/blocks.d.ts +7 -5
- package/build/esm/text-transform/blocks.js +11 -4
- package/package.json +1 -1
- package/server/models/constructor-items/blocks.d.ts +7 -5
- package/server/text-transform/blocks.js +11 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.9.0](https://github.com/gravity-ui/page-constructor/compare/v1.8.2...v1.9.0) (2022-12-05)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **Tabs:** change tabs to buttons ([#63](https://github.com/gravity-ui/page-constructor/issues/63)) ([f6195f3](https://github.com/gravity-ui/page-constructor/commit/f6195f3115bb5136c17336edb8a0ff64dcc50de5))
|
|
9
|
+
|
|
3
10
|
## [1.8.2](https://github.com/gravity-ui/page-constructor/compare/v1.8.1...v1.8.2) (2022-12-02)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -1,68 +1,108 @@
|
|
|
1
|
-
.pc-
|
|
1
|
+
.pc-tabs-block__content-title.pc-tabs-block__content-title > * {
|
|
2
2
|
margin: 0;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
/* use this for style redefinitions to awoid problems with
|
|
6
6
|
unpredictable css rules order in build */
|
|
7
|
-
.pc-
|
|
8
|
-
margin-bottom:
|
|
7
|
+
.pc-tabs-block__block-title {
|
|
8
|
+
margin-bottom: 24px;
|
|
9
9
|
}
|
|
10
|
-
.pc-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
.pc-tabs-block__block-title_centered {
|
|
11
|
+
display: flex;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
flex-wrap: wrap;
|
|
14
|
+
margin-left: auto;
|
|
15
|
+
margin-right: auto;
|
|
16
|
+
text-align: center;
|
|
14
17
|
}
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
.pc-tabs-block__tabs_centered {
|
|
19
|
+
display: flex;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
flex-wrap: wrap;
|
|
22
|
+
}
|
|
23
|
+
.pc-tabs-block__row_reverse {
|
|
24
|
+
flex-direction: row-reverse;
|
|
25
|
+
}
|
|
26
|
+
.pc-tabs-block__row_reverse .pc-tabs-block__content-wrapper {
|
|
27
|
+
margin: 24px 32px 0 0;
|
|
28
|
+
}
|
|
29
|
+
.pc-tabs-block__image {
|
|
17
30
|
width: 100%;
|
|
18
31
|
height: auto;
|
|
19
32
|
object-fit: cover;
|
|
20
33
|
display: block;
|
|
21
34
|
}
|
|
22
|
-
.pc-
|
|
35
|
+
.pc-tabs-block__image, .pc-tabs-block__media {
|
|
23
36
|
box-shadow: 0 2px 8px var(--pc-color-sfx-shadow), 0 4px 24px var(--pc-color-sfx-shadow);
|
|
24
37
|
overflow-x: hidden;
|
|
25
38
|
border-radius: var(--pc-border-radius);
|
|
26
39
|
}
|
|
27
|
-
.pc-
|
|
40
|
+
.pc-tabs-block__caption {
|
|
28
41
|
font-size: var(--yc-text-body-2-font-size);
|
|
29
42
|
line-height: var(--yc-text-body-2-line-height);
|
|
30
43
|
margin: 12px 0 0;
|
|
31
44
|
color: var(--yc-color-text-secondary);
|
|
32
45
|
}
|
|
33
|
-
.pc-
|
|
46
|
+
.pc-tabs-block__content {
|
|
34
47
|
display: flex;
|
|
35
48
|
flex-direction: column;
|
|
36
49
|
}
|
|
37
|
-
.pc-
|
|
50
|
+
.pc-tabs-block__content_centered {
|
|
51
|
+
margin: 0 auto;
|
|
52
|
+
}
|
|
53
|
+
.pc-tabs-block__col_centered {
|
|
54
|
+
margin: 0 auto;
|
|
55
|
+
}
|
|
56
|
+
.pc-tabs-block__content-wrapper_margin {
|
|
38
57
|
margin: 24px 0 0 32px;
|
|
39
58
|
}
|
|
40
|
-
.pc-
|
|
59
|
+
.pc-tabs-block__content-title {
|
|
41
60
|
margin: 0 auto 12px;
|
|
42
61
|
}
|
|
43
|
-
.pc-
|
|
62
|
+
.pc-tabs-block__content-title.pc-tabs-block__content-title > * {
|
|
44
63
|
font-size: var(--yc-text-header-1-font-size);
|
|
45
64
|
line-height: var(--yc-text-header-1-line-height);
|
|
46
65
|
color: var(--pc-text-header-color);
|
|
47
66
|
font-weight: var(--yc-text-accent-font-weight);
|
|
48
67
|
}
|
|
49
68
|
|
|
50
|
-
.pc-TabsBlock__tabs, .pc-TabsBlock__link {
|
|
51
|
-
font-size: var(--yc-text-body-2-font-size);
|
|
52
|
-
line-height: var(--yc-text-body-2-line-height);
|
|
53
|
-
}
|
|
54
69
|
@media (max-width: 769px) {
|
|
55
|
-
.pc-
|
|
70
|
+
.pc-tabs-block__tabs {
|
|
71
|
+
display: flex;
|
|
72
|
+
flex-wrap: nowrap;
|
|
73
|
+
justify-content: flex-start;
|
|
74
|
+
overflow: auto;
|
|
75
|
+
margin-left: -48px;
|
|
76
|
+
margin-right: -48px;
|
|
77
|
+
padding-left: 48px;
|
|
78
|
+
padding-right: 40px;
|
|
79
|
+
}
|
|
80
|
+
.pc-tabs-block__content-wrapper_margin {
|
|
56
81
|
margin: 0 0 32px 0;
|
|
57
82
|
}
|
|
83
|
+
.pc-tabs-block__row_reverse {
|
|
84
|
+
flex-direction: column-reverse;
|
|
85
|
+
}
|
|
86
|
+
.pc-tabs-block__row_reverse .pc-tabs-block__content > * {
|
|
87
|
+
margin-top: 32px;
|
|
88
|
+
padding-bottom: 0;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
@media (max-width: 577px) {
|
|
92
|
+
.pc-tabs-block__tabs {
|
|
93
|
+
margin-left: -24px;
|
|
94
|
+
margin-right: -24px;
|
|
95
|
+
padding-left: 24px;
|
|
96
|
+
padding-right: 16px;
|
|
97
|
+
}
|
|
58
98
|
}
|
|
59
99
|
@media (min-width: 769px) {
|
|
60
|
-
.pc-
|
|
100
|
+
.pc-tabs-block.pc-AnimateBlock .pc-tabs-block__media, .pc-AnimateBlock .pc-tabs-block .pc-tabs-block__media {
|
|
61
101
|
position: relative;
|
|
62
102
|
top: 100px;
|
|
63
103
|
opacity: 0;
|
|
64
104
|
}
|
|
65
|
-
.pc-
|
|
105
|
+
.pc-tabs-block.pc-AnimateBlock.animate .pc-tabs-block__media, .pc-AnimateBlock .pc-tabs-block.animate .pc-tabs-block__media {
|
|
66
106
|
top: 0;
|
|
67
107
|
opacity: 1;
|
|
68
108
|
transition: top 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
@@ -70,12 +110,12 @@ unpredictable css rules order in build */
|
|
|
70
110
|
}
|
|
71
111
|
}
|
|
72
112
|
@media (min-width: 769px) {
|
|
73
|
-
.pc-
|
|
113
|
+
.pc-tabs-block.pc-AnimateBlock .pc-tabs-block__image, .pc-AnimateBlock .pc-tabs-block .pc-tabs-block__image {
|
|
74
114
|
position: relative;
|
|
75
115
|
top: 100px;
|
|
76
116
|
opacity: 0;
|
|
77
117
|
}
|
|
78
|
-
.pc-
|
|
118
|
+
.pc-tabs-block.pc-AnimateBlock.animate .pc-tabs-block__image, .pc-AnimateBlock .pc-tabs-block.animate .pc-tabs-block__image {
|
|
79
119
|
top: 0;
|
|
80
120
|
opacity: 1;
|
|
81
121
|
transition: top 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { TabsBlockProps } from '../../models';
|
|
2
|
-
export declare const TabsBlock: ({ items, title, description, animated }: TabsBlockProps) => JSX.Element;
|
|
2
|
+
export declare const TabsBlock: ({ items, title, description, animated, tabsColSizes, centered, direction, }: TabsBlockProps) => JSX.Element;
|
|
3
3
|
export default TabsBlock;
|
|
@@ -3,53 +3,55 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TabsBlock = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = (0, tslib_1.__importStar)(require("react"));
|
|
6
|
-
const uikit_1 = require("@gravity-ui/uikit");
|
|
7
6
|
const utils_1 = require("../../utils");
|
|
8
7
|
const grid_1 = require("../../grid");
|
|
9
|
-
const YFMWrapper_1 = (0, tslib_1.__importDefault)(require("../../components/YFMWrapper/YFMWrapper"));
|
|
10
8
|
const AnimateBlock_1 = (0, tslib_1.__importDefault)(require("../../components/AnimateBlock/AnimateBlock"));
|
|
11
9
|
const BlockHeader_1 = (0, tslib_1.__importDefault)(require("../../components/BlockHeader/BlockHeader"));
|
|
12
10
|
const FullscreenImage_1 = (0, tslib_1.__importDefault)(require("../../components/FullscreenImage/FullscreenImage"));
|
|
13
11
|
const Media_1 = (0, tslib_1.__importDefault)(require("../../components/Media/Media"));
|
|
14
|
-
const Links_1 = (0, tslib_1.__importDefault)(require("../../components/Link/Links"));
|
|
15
12
|
const ThemeValueContext_1 = require("../../context/theme/ThemeValueContext");
|
|
16
13
|
const utils_2 = require("../../components/Media/Image/utils");
|
|
17
|
-
const
|
|
18
|
-
const
|
|
14
|
+
const ButtonTabs_1 = (0, tslib_1.__importDefault)(require("../../components/ButtonTabs/ButtonTabs"));
|
|
15
|
+
const sub_blocks_1 = require("../../sub-blocks");
|
|
16
|
+
const b = (0, utils_1.block)('tabs-block');
|
|
17
|
+
const TabsBlock = ({ items, title, description, animated, tabsColSizes, centered, direction = 'media-content', }) => {
|
|
19
18
|
const [activeTab, setActiveTab] = (0, react_1.useState)(items[0].tabName);
|
|
20
19
|
const [play, setPlay] = (0, react_1.useState)(false);
|
|
21
20
|
const { themeValue: theme } = (0, react_1.useContext)(ThemeValueContext_1.ThemeValueContext);
|
|
22
21
|
const tabs = items.map(({ tabName }) => ({ title: tabName, id: tabName }));
|
|
23
22
|
const activeTabData = items.find(({ tabName }) => tabName === activeTab);
|
|
23
|
+
const isReverse = direction === 'content-media';
|
|
24
24
|
let imageProps;
|
|
25
25
|
if (activeTabData) {
|
|
26
26
|
const themedImage = (0, utils_1.getThemedValue)(activeTabData.image, theme);
|
|
27
27
|
imageProps = themedImage && (0, utils_2.getMediaImage)(themedImage);
|
|
28
28
|
}
|
|
29
29
|
const showMedia = Boolean((activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) || imageProps);
|
|
30
|
+
const showText = Boolean(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.text);
|
|
31
|
+
const textContent = activeTabData && showText && (react_1.default.createElement(grid_1.Col, { sizes: { all: 12, md: showMedia ? 4 : 8 }, className: b('content', { centered: centered }) },
|
|
32
|
+
react_1.default.createElement("div", { className: b('content-wrapper', {
|
|
33
|
+
margin: Boolean(((activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) || imageProps) && !isReverse),
|
|
34
|
+
}) },
|
|
35
|
+
react_1.default.createElement(sub_blocks_1.Content, { title: activeTabData.title, text: activeTabData.text, additionalInfo: activeTabData.additionalInfo, size: "s", links: [
|
|
36
|
+
...(activeTabData.link ? [activeTabData.link] : []),
|
|
37
|
+
...(activeTabData.links || []),
|
|
38
|
+
], buttons: activeTabData.buttons, colSizes: { all: 12 } }))));
|
|
39
|
+
const mediaContent = showMedia && (react_1.default.createElement(grid_1.Col, { sizes: { all: 12, md: 8 }, orders: {
|
|
40
|
+
all: grid_1.GridColumnOrderClasses.Last,
|
|
41
|
+
md: grid_1.GridColumnOrderClasses.First,
|
|
42
|
+
}, className: b('col', { centered: centered }) },
|
|
43
|
+
(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) && (react_1.default.createElement(Media_1.default, Object.assign({}, (0, utils_1.getThemedValue)(activeTabData.media, theme), { key: activeTab, className: b('media'), playVideo: play }))),
|
|
44
|
+
imageProps && (react_1.default.createElement(react_1.Fragment, null,
|
|
45
|
+
react_1.default.createElement(FullscreenImage_1.default, Object.assign({}, imageProps, { imageClassName: b('image') })),
|
|
46
|
+
(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.caption) && (react_1.default.createElement("p", { className: b('caption') }, activeTabData.caption))))));
|
|
30
47
|
return (react_1.default.createElement(AnimateBlock_1.default, { className: b(), onScroll: () => setPlay(true), animate: animated },
|
|
31
|
-
react_1.default.createElement(BlockHeader_1.default, { title: title, description: description, className: b('block-title') }),
|
|
32
|
-
react_1.default.createElement(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) && (react_1.default.createElement(Media_1.default, Object.assign({}, (0, utils_1.getThemedValue)(activeTabData.media, theme), { key: activeTab, className: b('media'), playVideo: play }))),
|
|
39
|
-
imageProps && (react_1.default.createElement(react_1.Fragment, null,
|
|
40
|
-
react_1.default.createElement(FullscreenImage_1.default, Object.assign({}, imageProps, { imageClassName: b('image') })),
|
|
41
|
-
activeTabData && (react_1.default.createElement("p", { className: b('caption') }, activeTabData.caption)))))),
|
|
42
|
-
react_1.default.createElement(grid_1.Col, { sizes: { all: 12, md: showMedia ? 4 : 8 }, className: b('content') },
|
|
43
|
-
react_1.default.createElement("div", { className: b('content-wrapper', {
|
|
44
|
-
margin: Boolean((activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) || imageProps),
|
|
45
|
-
}) },
|
|
46
|
-
react_1.default.createElement("h4", { className: b('content-title') },
|
|
47
|
-
react_1.default.createElement(YFMWrapper_1.default, { content: activeTabData.title, modifiers: { constructor: true } })),
|
|
48
|
-
react_1.default.createElement(YFMWrapper_1.default, { content: activeTabData.text, modifiers: { constructor: true } }),
|
|
49
|
-
react_1.default.createElement(Links_1.default, { links: [
|
|
50
|
-
...(activeTabData.link ? [activeTabData.link] : []),
|
|
51
|
-
...(activeTabData.links || []),
|
|
52
|
-
], className: b('link') })))))));
|
|
48
|
+
react_1.default.createElement(BlockHeader_1.default, { title: title, description: description, className: b('block-title', { centered: centered }) }),
|
|
49
|
+
react_1.default.createElement(grid_1.Row, null,
|
|
50
|
+
react_1.default.createElement(grid_1.Col, { sizes: tabsColSizes },
|
|
51
|
+
react_1.default.createElement(ButtonTabs_1.default, { items: tabs, onSelectTab: setActiveTab, activeTab: activeTab, className: b('tabs', { centered: centered }) }))),
|
|
52
|
+
activeTabData && (react_1.default.createElement(grid_1.Row, { className: b('row', { reverse: isReverse }) },
|
|
53
|
+
mediaContent,
|
|
54
|
+
textContent))));
|
|
53
55
|
};
|
|
54
56
|
exports.TabsBlock = TabsBlock;
|
|
55
57
|
exports.default = exports.TabsBlock;
|
|
@@ -6,12 +6,6 @@ export declare const tabsItem: {
|
|
|
6
6
|
tabName: {
|
|
7
7
|
type: string;
|
|
8
8
|
};
|
|
9
|
-
title: {
|
|
10
|
-
type: string;
|
|
11
|
-
};
|
|
12
|
-
text: {
|
|
13
|
-
type: string;
|
|
14
|
-
};
|
|
15
9
|
caption: {
|
|
16
10
|
type: string;
|
|
17
11
|
};
|
|
@@ -184,17 +178,6 @@ export declare const tabsItem: {
|
|
|
184
178
|
when: {};
|
|
185
179
|
};
|
|
186
180
|
};
|
|
187
|
-
links: {
|
|
188
|
-
type: string;
|
|
189
|
-
items: {
|
|
190
|
-
type: string;
|
|
191
|
-
properties: {
|
|
192
|
-
when: {
|
|
193
|
-
type: string;
|
|
194
|
-
};
|
|
195
|
-
};
|
|
196
|
-
};
|
|
197
|
-
};
|
|
198
181
|
image: {
|
|
199
182
|
oneOf: ({
|
|
200
183
|
oneOf: ({
|
|
@@ -215,6 +198,66 @@ export declare const tabsItem: {
|
|
|
215
198
|
properties: {};
|
|
216
199
|
})[];
|
|
217
200
|
};
|
|
201
|
+
title?: {
|
|
202
|
+
oneOf: ({
|
|
203
|
+
type: string;
|
|
204
|
+
additionalProperties: boolean;
|
|
205
|
+
required: string[];
|
|
206
|
+
properties: {
|
|
207
|
+
text: {
|
|
208
|
+
type: string;
|
|
209
|
+
};
|
|
210
|
+
textSize: {
|
|
211
|
+
type: string;
|
|
212
|
+
enum: string[];
|
|
213
|
+
};
|
|
214
|
+
url: {
|
|
215
|
+
type: string;
|
|
216
|
+
};
|
|
217
|
+
resetMargin: {
|
|
218
|
+
type: string;
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
} | {
|
|
222
|
+
type: string;
|
|
223
|
+
})[];
|
|
224
|
+
} | undefined;
|
|
225
|
+
text?: {
|
|
226
|
+
type: string;
|
|
227
|
+
} | undefined;
|
|
228
|
+
additionalInfo?: {
|
|
229
|
+
type: string;
|
|
230
|
+
} | undefined;
|
|
231
|
+
size?: {
|
|
232
|
+
type: string;
|
|
233
|
+
enum: string[];
|
|
234
|
+
} | undefined;
|
|
235
|
+
links?: {
|
|
236
|
+
type: string;
|
|
237
|
+
items: {
|
|
238
|
+
type: string;
|
|
239
|
+
properties: {
|
|
240
|
+
when: {
|
|
241
|
+
type: string;
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
} | undefined;
|
|
246
|
+
buttons?: {
|
|
247
|
+
type: string;
|
|
248
|
+
items: {
|
|
249
|
+
type: string;
|
|
250
|
+
properties: {
|
|
251
|
+
when: {
|
|
252
|
+
type: string;
|
|
253
|
+
};
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
} | undefined;
|
|
257
|
+
theme?: {
|
|
258
|
+
type: string;
|
|
259
|
+
enum: string[];
|
|
260
|
+
} | undefined;
|
|
218
261
|
};
|
|
219
262
|
};
|
|
220
263
|
export declare const TabsBlock: {
|
|
@@ -245,6 +288,14 @@ export declare const TabsBlock: {
|
|
|
245
288
|
description: {
|
|
246
289
|
type: string;
|
|
247
290
|
};
|
|
291
|
+
tabsColSizes: {};
|
|
292
|
+
direction: {
|
|
293
|
+
type: string;
|
|
294
|
+
enum: string[];
|
|
295
|
+
};
|
|
296
|
+
centered: {
|
|
297
|
+
type: string;
|
|
298
|
+
};
|
|
248
299
|
items: {
|
|
249
300
|
type: string;
|
|
250
301
|
items: {
|
|
@@ -1,35 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TabsBlock = exports.tabsItem = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const utils_1 = require("../../schema/validators/utils");
|
|
5
6
|
const common_1 = require("../../schema/validators/common");
|
|
6
7
|
const schema_1 = require("../../components/Image/schema");
|
|
8
|
+
const lodash_1 = (0, tslib_1.__importDefault)(require("lodash"));
|
|
9
|
+
const schema_2 = require("../../sub-blocks/Content/schema");
|
|
10
|
+
const TabsItemContentProps = lodash_1.default.omit(schema_2.ContentBase, ['size', 'colSizes', 'centered', 'theme']);
|
|
7
11
|
exports.tabsItem = {
|
|
8
12
|
type: 'object',
|
|
9
13
|
additionalProperties: false,
|
|
10
|
-
required: ['tabName'
|
|
11
|
-
properties: {
|
|
12
|
-
tabName: {
|
|
14
|
+
required: ['tabName'],
|
|
15
|
+
properties: Object.assign(Object.assign({}, TabsItemContentProps), { tabName: {
|
|
13
16
|
type: 'string',
|
|
14
|
-
},
|
|
15
|
-
title: {
|
|
17
|
+
}, caption: {
|
|
16
18
|
type: 'string',
|
|
17
|
-
},
|
|
18
|
-
text: {
|
|
19
|
-
type: 'string',
|
|
20
|
-
},
|
|
21
|
-
caption: {
|
|
22
|
-
type: 'string',
|
|
23
|
-
},
|
|
24
|
-
media: (0, common_1.withTheme)({
|
|
19
|
+
}, media: (0, common_1.withTheme)({
|
|
25
20
|
type: 'object',
|
|
26
21
|
properties: common_1.MediaProps,
|
|
27
|
-
}),
|
|
22
|
+
}),
|
|
28
23
|
//TODO deprecated
|
|
29
|
-
link: common_1.LinkProps,
|
|
30
|
-
links: (0, utils_1.filteredArray)(common_1.LinkProps),
|
|
31
|
-
image: (0, common_1.withTheme)(schema_1.ImageProps),
|
|
32
|
-
},
|
|
24
|
+
link: common_1.LinkProps, image: (0, common_1.withTheme)(schema_1.ImageProps) }),
|
|
33
25
|
};
|
|
34
26
|
exports.TabsBlock = {
|
|
35
27
|
'tabs-block': {
|
|
@@ -37,6 +29,9 @@ exports.TabsBlock = {
|
|
|
37
29
|
required: ['title', 'items'],
|
|
38
30
|
properties: Object.assign(Object.assign({}, common_1.BlockBaseProps), { title: common_1.TitleProps, description: {
|
|
39
31
|
type: 'string',
|
|
40
|
-
},
|
|
32
|
+
}, tabsColSizes: common_1.containerSizesArray.reduce((acc, size) => (Object.assign(Object.assign({}, acc), { [size]: common_1.sizeNumber })), {}), direction: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
enum: common_1.mediaDirection,
|
|
35
|
+
}, centered: { type: 'boolean' }, items: (0, utils_1.filteredArray)(exports.tabsItem) }),
|
|
41
36
|
},
|
|
42
37
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* use this for style redefinitions to awoid problems with
|
|
2
|
+
unpredictable css rules order in build */
|
|
3
|
+
.pc-button-tabs {
|
|
4
|
+
margin-bottom: 20px;
|
|
5
|
+
}
|
|
6
|
+
.pc-button-tabs__item {
|
|
7
|
+
margin-right: 8px;
|
|
8
|
+
margin-bottom: 12px;
|
|
9
|
+
}
|
|
10
|
+
.pc-button-tabs__item_active {
|
|
11
|
+
pointer-events: none;
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ButtonProps } from '../../models';
|
|
2
|
+
export interface ButtonTabsItemProps extends Omit<ButtonProps, 'url' | 'primary' | 'target' | 'text'> {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ButtonTabsProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
items: ButtonTabsItemProps[];
|
|
9
|
+
activeTab?: string;
|
|
10
|
+
onSelectTab?: (tabId: string) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const ButtonTabs: (props: ButtonTabsProps) => JSX.Element;
|
|
13
|
+
export default ButtonTabs;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const react_1 = (0, tslib_1.__importStar)(require("react"));
|
|
5
|
+
const utils_1 = require("../../utils");
|
|
6
|
+
const index_1 = require("../index");
|
|
7
|
+
const b = (0, utils_1.block)('button-tabs');
|
|
8
|
+
const ButtonTabs = (props) => {
|
|
9
|
+
const { className, items, activeTab, onSelectTab } = props;
|
|
10
|
+
const activeTabId = (0, react_1.useMemo)(() => {
|
|
11
|
+
if (activeTab) {
|
|
12
|
+
return activeTab;
|
|
13
|
+
}
|
|
14
|
+
return items[0].id;
|
|
15
|
+
}, [activeTab, items]);
|
|
16
|
+
const handleClick = (0, react_1.useCallback)((tabId) => {
|
|
17
|
+
if (onSelectTab) {
|
|
18
|
+
onSelectTab(tabId);
|
|
19
|
+
}
|
|
20
|
+
}, [onSelectTab]);
|
|
21
|
+
return (react_1.default.createElement("div", { className: b(null, className) }, items.map((item) => {
|
|
22
|
+
const isActive = item.id === activeTabId;
|
|
23
|
+
return (react_1.default.createElement(index_1.Button, { text: item.title, className: b('item', { active: isActive }), key: item.title, size: 'l', onClick: () => handleClick(item.id), theme: isActive ? 'monochrome' : 'normal' }));
|
|
24
|
+
})));
|
|
25
|
+
};
|
|
26
|
+
exports.default = ButtonTabs;
|
|
@@ -4,6 +4,8 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const react_1 = (0, tslib_1.__importStar)(require("react"));
|
|
5
5
|
const projectSettingsContext_1 = require("../../context/projectSettingsContext");
|
|
6
6
|
const constants_1 = require("../../constants");
|
|
7
|
+
const utils_1 = require("../../utils");
|
|
8
|
+
const b = (0, utils_1.block)('image');
|
|
7
9
|
const checkWebP = (src) => {
|
|
8
10
|
return src.endsWith('.webp') ? src : src + '.webp';
|
|
9
11
|
};
|
|
@@ -20,7 +22,7 @@ const Image = (props) => {
|
|
|
20
22
|
disableCompress ||
|
|
21
23
|
imageSrc.endsWith('.svg') ||
|
|
22
24
|
imgLoadingError;
|
|
23
|
-
return (react_1.default.createElement("picture",
|
|
25
|
+
return (react_1.default.createElement("picture", { className: b() },
|
|
24
26
|
mobile && (react_1.default.createElement(react_1.Fragment, null,
|
|
25
27
|
!disableWebp && (react_1.default.createElement("source", { srcSet: checkWebP(mobile), type: "image/webp", media: `(max-width: ${constants_1.BREAKPOINTS.sm}px)` })),
|
|
26
28
|
react_1.default.createElement("source", { srcSet: mobile, media: `(max-width: ${constants_1.BREAKPOINTS.sm}px)` }))),
|
|
@@ -11,7 +11,7 @@ export declare const blockMap: {
|
|
|
11
11
|
"info-block": (props: import("./models").InfoBlockProps) => JSX.Element;
|
|
12
12
|
"security-block": (props: import("./models").SecurityBlockProps) => JSX.Element;
|
|
13
13
|
"table-block": (props: import("./models").TableBlockProps) => JSX.Element;
|
|
14
|
-
"tabs-block": ({ items, title, description, animated }: import("./models").TabsBlockProps) => JSX.Element;
|
|
14
|
+
"tabs-block": ({ items, title, description, animated, tabsColSizes, centered, direction, }: import("./models").TabsBlockProps) => JSX.Element;
|
|
15
15
|
"link-table-block": ({ items, title, description, linkTheme }: import("./models").LinkTableBlockProps) => JSX.Element;
|
|
16
16
|
"header-block": (props: import("./models").WithChildren<import("./models").HeaderBlockProps & import("./models").ClassNameProps>) => JSX.Element;
|
|
17
17
|
"icons-block": ({ title, size, items }: import("./models").IconsBlockProps) => JSX.Element;
|
|
@@ -219,18 +219,20 @@ export interface TableBlockProps {
|
|
|
219
219
|
title: string;
|
|
220
220
|
table: TableProps;
|
|
221
221
|
}
|
|
222
|
-
export interface TabsBlockItem {
|
|
222
|
+
export interface TabsBlockItem extends Omit<ContentBlockProps, 'size' | 'colSizes' | 'centered' | 'theme'> {
|
|
223
223
|
tabName: string;
|
|
224
|
-
|
|
225
|
-
|
|
224
|
+
/**
|
|
225
|
+
* @deprecated Use array links from ContentBlockProps instead
|
|
226
|
+
*/
|
|
226
227
|
link?: LinkProps;
|
|
227
228
|
image?: ThemedImage;
|
|
228
|
-
disableCompress?: boolean;
|
|
229
229
|
caption?: string;
|
|
230
230
|
media?: ThemedMediaProps;
|
|
231
|
-
links?: LinkProps[];
|
|
232
231
|
}
|
|
233
232
|
export interface TabsBlockProps extends BlockHeaderProps, Animatable {
|
|
233
|
+
tabsColSizes?: GridColumnSizesType;
|
|
234
|
+
centered?: boolean;
|
|
235
|
+
direction?: MediaDirection;
|
|
234
236
|
items: TabsBlockItem[];
|
|
235
237
|
}
|
|
236
238
|
export interface LinkTableBlockProps extends BlockHeaderProps {
|
|
@@ -23,7 +23,6 @@ const createItemsParser = (fields) => (transformer, items) => items.map((item) =
|
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
exports.createItemsParser = createItemsParser;
|
|
26
|
-
const parseItems = (0, exports.createItemsParser)(['title', 'text']);
|
|
27
26
|
function parseTableBlock(transformer, content) {
|
|
28
27
|
const legend = content === null || content === void 0 ? void 0 : content.legend;
|
|
29
28
|
return Object.assign(Object.assign({}, (content || {})), { legend: legend && legend.map((string) => transformer(string)) });
|
|
@@ -49,9 +48,13 @@ function parseSlider(transformer, block) {
|
|
|
49
48
|
}
|
|
50
49
|
const parseTitle = (transformer, title) => typeof title === 'object' && 'text' in title
|
|
51
50
|
? Object.assign(Object.assign({}, title), { text: transformer(title.text) }) : title && transformer(title);
|
|
51
|
+
const parseItemsTitle = (transformer, items) => items.map((_a) => {
|
|
52
|
+
var { title } = _a, rest = (0, tslib_1.__rest)(_a, ["title"]);
|
|
53
|
+
return (Object.assign({ title: title && parseTitle(transformer, title) }, rest));
|
|
54
|
+
});
|
|
52
55
|
function parsePriceDetailedBlock(transformer, block) {
|
|
53
56
|
const { priceType } = block;
|
|
54
|
-
|
|
57
|
+
block.items = block.items.map((item) => {
|
|
55
58
|
const { description, items: details = [] } = item;
|
|
56
59
|
if (priceType === 'marked-list') {
|
|
57
60
|
item.items = details.map((detail) => {
|
|
@@ -68,7 +71,6 @@ function parsePriceDetailedBlock(transformer, block) {
|
|
|
68
71
|
item.description = transformer(description);
|
|
69
72
|
return item;
|
|
70
73
|
});
|
|
71
|
-
block.items = transformedBlockItems;
|
|
72
74
|
return block;
|
|
73
75
|
}
|
|
74
76
|
const parseContentLayout = (transformer, content) => {
|
|
@@ -226,7 +228,12 @@ const config = {
|
|
|
226
228
|
{
|
|
227
229
|
fields: ['items'],
|
|
228
230
|
transformer: yfmTransformer,
|
|
229
|
-
parser:
|
|
231
|
+
parser: (0, exports.createItemsParser)(['text', 'additionalInfo']),
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
fields: ['items'],
|
|
235
|
+
transformer: typografTransformer,
|
|
236
|
+
parser: parseItemsTitle,
|
|
230
237
|
},
|
|
231
238
|
],
|
|
232
239
|
[models_1.BlockType.TableBlock]: [
|
|
@@ -1,68 +1,108 @@
|
|
|
1
|
-
.pc-
|
|
1
|
+
.pc-tabs-block__content-title.pc-tabs-block__content-title > * {
|
|
2
2
|
margin: 0;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
/* use this for style redefinitions to awoid problems with
|
|
6
6
|
unpredictable css rules order in build */
|
|
7
|
-
.pc-
|
|
8
|
-
margin-bottom:
|
|
7
|
+
.pc-tabs-block__block-title {
|
|
8
|
+
margin-bottom: 24px;
|
|
9
9
|
}
|
|
10
|
-
.pc-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
.pc-tabs-block__block-title_centered {
|
|
11
|
+
display: flex;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
flex-wrap: wrap;
|
|
14
|
+
margin-left: auto;
|
|
15
|
+
margin-right: auto;
|
|
16
|
+
text-align: center;
|
|
14
17
|
}
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
.pc-tabs-block__tabs_centered {
|
|
19
|
+
display: flex;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
flex-wrap: wrap;
|
|
22
|
+
}
|
|
23
|
+
.pc-tabs-block__row_reverse {
|
|
24
|
+
flex-direction: row-reverse;
|
|
25
|
+
}
|
|
26
|
+
.pc-tabs-block__row_reverse .pc-tabs-block__content-wrapper {
|
|
27
|
+
margin: 24px 32px 0 0;
|
|
28
|
+
}
|
|
29
|
+
.pc-tabs-block__image {
|
|
17
30
|
width: 100%;
|
|
18
31
|
height: auto;
|
|
19
32
|
object-fit: cover;
|
|
20
33
|
display: block;
|
|
21
34
|
}
|
|
22
|
-
.pc-
|
|
35
|
+
.pc-tabs-block__image, .pc-tabs-block__media {
|
|
23
36
|
box-shadow: 0 2px 8px var(--pc-color-sfx-shadow), 0 4px 24px var(--pc-color-sfx-shadow);
|
|
24
37
|
overflow-x: hidden;
|
|
25
38
|
border-radius: var(--pc-border-radius);
|
|
26
39
|
}
|
|
27
|
-
.pc-
|
|
40
|
+
.pc-tabs-block__caption {
|
|
28
41
|
font-size: var(--yc-text-body-2-font-size);
|
|
29
42
|
line-height: var(--yc-text-body-2-line-height);
|
|
30
43
|
margin: 12px 0 0;
|
|
31
44
|
color: var(--yc-color-text-secondary);
|
|
32
45
|
}
|
|
33
|
-
.pc-
|
|
46
|
+
.pc-tabs-block__content {
|
|
34
47
|
display: flex;
|
|
35
48
|
flex-direction: column;
|
|
36
49
|
}
|
|
37
|
-
.pc-
|
|
50
|
+
.pc-tabs-block__content_centered {
|
|
51
|
+
margin: 0 auto;
|
|
52
|
+
}
|
|
53
|
+
.pc-tabs-block__col_centered {
|
|
54
|
+
margin: 0 auto;
|
|
55
|
+
}
|
|
56
|
+
.pc-tabs-block__content-wrapper_margin {
|
|
38
57
|
margin: 24px 0 0 32px;
|
|
39
58
|
}
|
|
40
|
-
.pc-
|
|
59
|
+
.pc-tabs-block__content-title {
|
|
41
60
|
margin: 0 auto 12px;
|
|
42
61
|
}
|
|
43
|
-
.pc-
|
|
62
|
+
.pc-tabs-block__content-title.pc-tabs-block__content-title > * {
|
|
44
63
|
font-size: var(--yc-text-header-1-font-size);
|
|
45
64
|
line-height: var(--yc-text-header-1-line-height);
|
|
46
65
|
color: var(--pc-text-header-color);
|
|
47
66
|
font-weight: var(--yc-text-accent-font-weight);
|
|
48
67
|
}
|
|
49
68
|
|
|
50
|
-
.pc-TabsBlock__tabs, .pc-TabsBlock__link {
|
|
51
|
-
font-size: var(--yc-text-body-2-font-size);
|
|
52
|
-
line-height: var(--yc-text-body-2-line-height);
|
|
53
|
-
}
|
|
54
69
|
@media (max-width: 769px) {
|
|
55
|
-
.pc-
|
|
70
|
+
.pc-tabs-block__tabs {
|
|
71
|
+
display: flex;
|
|
72
|
+
flex-wrap: nowrap;
|
|
73
|
+
justify-content: flex-start;
|
|
74
|
+
overflow: auto;
|
|
75
|
+
margin-left: -48px;
|
|
76
|
+
margin-right: -48px;
|
|
77
|
+
padding-left: 48px;
|
|
78
|
+
padding-right: 40px;
|
|
79
|
+
}
|
|
80
|
+
.pc-tabs-block__content-wrapper_margin {
|
|
56
81
|
margin: 0 0 32px 0;
|
|
57
82
|
}
|
|
83
|
+
.pc-tabs-block__row_reverse {
|
|
84
|
+
flex-direction: column-reverse;
|
|
85
|
+
}
|
|
86
|
+
.pc-tabs-block__row_reverse .pc-tabs-block__content > * {
|
|
87
|
+
margin-top: 32px;
|
|
88
|
+
padding-bottom: 0;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
@media (max-width: 577px) {
|
|
92
|
+
.pc-tabs-block__tabs {
|
|
93
|
+
margin-left: -24px;
|
|
94
|
+
margin-right: -24px;
|
|
95
|
+
padding-left: 24px;
|
|
96
|
+
padding-right: 16px;
|
|
97
|
+
}
|
|
58
98
|
}
|
|
59
99
|
@media (min-width: 769px) {
|
|
60
|
-
.pc-
|
|
100
|
+
.pc-tabs-block.pc-AnimateBlock .pc-tabs-block__media, .pc-AnimateBlock .pc-tabs-block .pc-tabs-block__media {
|
|
61
101
|
position: relative;
|
|
62
102
|
top: 100px;
|
|
63
103
|
opacity: 0;
|
|
64
104
|
}
|
|
65
|
-
.pc-
|
|
105
|
+
.pc-tabs-block.pc-AnimateBlock.animate .pc-tabs-block__media, .pc-AnimateBlock .pc-tabs-block.animate .pc-tabs-block__media {
|
|
66
106
|
top: 0;
|
|
67
107
|
opacity: 1;
|
|
68
108
|
transition: top 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
@@ -70,12 +110,12 @@ unpredictable css rules order in build */
|
|
|
70
110
|
}
|
|
71
111
|
}
|
|
72
112
|
@media (min-width: 769px) {
|
|
73
|
-
.pc-
|
|
113
|
+
.pc-tabs-block.pc-AnimateBlock .pc-tabs-block__image, .pc-AnimateBlock .pc-tabs-block .pc-tabs-block__image {
|
|
74
114
|
position: relative;
|
|
75
115
|
top: 100px;
|
|
76
116
|
opacity: 0;
|
|
77
117
|
}
|
|
78
|
-
.pc-
|
|
118
|
+
.pc-tabs-block.pc-AnimateBlock.animate .pc-tabs-block__image, .pc-AnimateBlock .pc-tabs-block.animate .pc-tabs-block__image {
|
|
79
119
|
top: 0;
|
|
80
120
|
opacity: 1;
|
|
81
121
|
transition: top 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { TabsBlockProps } from '../../models';
|
|
2
2
|
import './Tabs.css';
|
|
3
|
-
export declare const TabsBlock: ({ items, title, description, animated }: TabsBlockProps) => JSX.Element;
|
|
3
|
+
export declare const TabsBlock: ({ items, title, description, animated, tabsColSizes, centered, direction, }: TabsBlockProps) => JSX.Element;
|
|
4
4
|
export default TabsBlock;
|
|
@@ -1,51 +1,53 @@
|
|
|
1
1
|
import React, { Fragment, useContext, useState } from 'react';
|
|
2
|
-
import { Tabs } from '@gravity-ui/uikit';
|
|
3
2
|
import { block, getThemedValue } from '../../utils';
|
|
4
3
|
import { Row, Col, GridColumnOrderClasses } from '../../grid';
|
|
5
|
-
import YFMWrapper from '../../components/YFMWrapper/YFMWrapper';
|
|
6
4
|
import AnimateBlock from '../../components/AnimateBlock/AnimateBlock';
|
|
7
5
|
import BlockHeader from '../../components/BlockHeader/BlockHeader';
|
|
8
6
|
import FullScreenImage from '../../components/FullscreenImage/FullscreenImage';
|
|
9
7
|
import Media from '../../components/Media/Media';
|
|
10
|
-
import Links from '../../components/Link/Links';
|
|
11
8
|
import { ThemeValueContext } from '../../context/theme/ThemeValueContext';
|
|
12
9
|
import { getMediaImage } from '../../components/Media/Image/utils';
|
|
10
|
+
import ButtonTabs from '../../components/ButtonTabs/ButtonTabs';
|
|
11
|
+
import { Content } from '../../sub-blocks';
|
|
13
12
|
import './Tabs.css';
|
|
14
|
-
const b = block('
|
|
15
|
-
export const TabsBlock = ({ items, title, description, animated }) => {
|
|
13
|
+
const b = block('tabs-block');
|
|
14
|
+
export const TabsBlock = ({ items, title, description, animated, tabsColSizes, centered, direction = 'media-content', }) => {
|
|
16
15
|
const [activeTab, setActiveTab] = useState(items[0].tabName);
|
|
17
16
|
const [play, setPlay] = useState(false);
|
|
18
17
|
const { themeValue: theme } = useContext(ThemeValueContext);
|
|
19
18
|
const tabs = items.map(({ tabName }) => ({ title: tabName, id: tabName }));
|
|
20
19
|
const activeTabData = items.find(({ tabName }) => tabName === activeTab);
|
|
20
|
+
const isReverse = direction === 'content-media';
|
|
21
21
|
let imageProps;
|
|
22
22
|
if (activeTabData) {
|
|
23
23
|
const themedImage = getThemedValue(activeTabData.image, theme);
|
|
24
24
|
imageProps = themedImage && getMediaImage(themedImage);
|
|
25
25
|
}
|
|
26
26
|
const showMedia = Boolean((activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) || imageProps);
|
|
27
|
+
const showText = Boolean(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.text);
|
|
28
|
+
const textContent = activeTabData && showText && (React.createElement(Col, { sizes: { all: 12, md: showMedia ? 4 : 8 }, className: b('content', { centered: centered }) },
|
|
29
|
+
React.createElement("div", { className: b('content-wrapper', {
|
|
30
|
+
margin: Boolean(((activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) || imageProps) && !isReverse),
|
|
31
|
+
}) },
|
|
32
|
+
React.createElement(Content, { title: activeTabData.title, text: activeTabData.text, additionalInfo: activeTabData.additionalInfo, size: "s", links: [
|
|
33
|
+
...(activeTabData.link ? [activeTabData.link] : []),
|
|
34
|
+
...(activeTabData.links || []),
|
|
35
|
+
], buttons: activeTabData.buttons, colSizes: { all: 12 } }))));
|
|
36
|
+
const mediaContent = showMedia && (React.createElement(Col, { sizes: { all: 12, md: 8 }, orders: {
|
|
37
|
+
all: GridColumnOrderClasses.Last,
|
|
38
|
+
md: GridColumnOrderClasses.First,
|
|
39
|
+
}, className: b('col', { centered: centered }) },
|
|
40
|
+
(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) && (React.createElement(Media, Object.assign({}, getThemedValue(activeTabData.media, theme), { key: activeTab, className: b('media'), playVideo: play }))),
|
|
41
|
+
imageProps && (React.createElement(Fragment, null,
|
|
42
|
+
React.createElement(FullScreenImage, Object.assign({}, imageProps, { imageClassName: b('image') })),
|
|
43
|
+
(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.caption) && (React.createElement("p", { className: b('caption') }, activeTabData.caption))))));
|
|
27
44
|
return (React.createElement(AnimateBlock, { className: b(), onScroll: () => setPlay(true), animate: animated },
|
|
28
|
-
React.createElement(BlockHeader, { title: title, description: description, className: b('block-title') }),
|
|
29
|
-
React.createElement(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) && (React.createElement(Media, Object.assign({}, getThemedValue(activeTabData.media, theme), { key: activeTab, className: b('media'), playVideo: play }))),
|
|
36
|
-
imageProps && (React.createElement(Fragment, null,
|
|
37
|
-
React.createElement(FullScreenImage, Object.assign({}, imageProps, { imageClassName: b('image') })),
|
|
38
|
-
activeTabData && (React.createElement("p", { className: b('caption') }, activeTabData.caption)))))),
|
|
39
|
-
React.createElement(Col, { sizes: { all: 12, md: showMedia ? 4 : 8 }, className: b('content') },
|
|
40
|
-
React.createElement("div", { className: b('content-wrapper', {
|
|
41
|
-
margin: Boolean((activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) || imageProps),
|
|
42
|
-
}) },
|
|
43
|
-
React.createElement("h4", { className: b('content-title') },
|
|
44
|
-
React.createElement(YFMWrapper, { content: activeTabData.title, modifiers: { constructor: true } })),
|
|
45
|
-
React.createElement(YFMWrapper, { content: activeTabData.text, modifiers: { constructor: true } }),
|
|
46
|
-
React.createElement(Links, { links: [
|
|
47
|
-
...(activeTabData.link ? [activeTabData.link] : []),
|
|
48
|
-
...(activeTabData.links || []),
|
|
49
|
-
], className: b('link') })))))));
|
|
45
|
+
React.createElement(BlockHeader, { title: title, description: description, className: b('block-title', { centered: centered }) }),
|
|
46
|
+
React.createElement(Row, null,
|
|
47
|
+
React.createElement(Col, { sizes: tabsColSizes },
|
|
48
|
+
React.createElement(ButtonTabs, { items: tabs, onSelectTab: setActiveTab, activeTab: activeTab, className: b('tabs', { centered: centered }) }))),
|
|
49
|
+
activeTabData && (React.createElement(Row, { className: b('row', { reverse: isReverse }) },
|
|
50
|
+
mediaContent,
|
|
51
|
+
textContent))));
|
|
50
52
|
};
|
|
51
53
|
export default TabsBlock;
|
|
@@ -6,12 +6,6 @@ export declare const tabsItem: {
|
|
|
6
6
|
tabName: {
|
|
7
7
|
type: string;
|
|
8
8
|
};
|
|
9
|
-
title: {
|
|
10
|
-
type: string;
|
|
11
|
-
};
|
|
12
|
-
text: {
|
|
13
|
-
type: string;
|
|
14
|
-
};
|
|
15
9
|
caption: {
|
|
16
10
|
type: string;
|
|
17
11
|
};
|
|
@@ -184,17 +178,6 @@ export declare const tabsItem: {
|
|
|
184
178
|
when: {};
|
|
185
179
|
};
|
|
186
180
|
};
|
|
187
|
-
links: {
|
|
188
|
-
type: string;
|
|
189
|
-
items: {
|
|
190
|
-
type: string;
|
|
191
|
-
properties: {
|
|
192
|
-
when: {
|
|
193
|
-
type: string;
|
|
194
|
-
};
|
|
195
|
-
};
|
|
196
|
-
};
|
|
197
|
-
};
|
|
198
181
|
image: {
|
|
199
182
|
oneOf: ({
|
|
200
183
|
oneOf: ({
|
|
@@ -215,6 +198,66 @@ export declare const tabsItem: {
|
|
|
215
198
|
properties: {};
|
|
216
199
|
})[];
|
|
217
200
|
};
|
|
201
|
+
title?: {
|
|
202
|
+
oneOf: ({
|
|
203
|
+
type: string;
|
|
204
|
+
additionalProperties: boolean;
|
|
205
|
+
required: string[];
|
|
206
|
+
properties: {
|
|
207
|
+
text: {
|
|
208
|
+
type: string;
|
|
209
|
+
};
|
|
210
|
+
textSize: {
|
|
211
|
+
type: string;
|
|
212
|
+
enum: string[];
|
|
213
|
+
};
|
|
214
|
+
url: {
|
|
215
|
+
type: string;
|
|
216
|
+
};
|
|
217
|
+
resetMargin: {
|
|
218
|
+
type: string;
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
} | {
|
|
222
|
+
type: string;
|
|
223
|
+
})[];
|
|
224
|
+
} | undefined;
|
|
225
|
+
text?: {
|
|
226
|
+
type: string;
|
|
227
|
+
} | undefined;
|
|
228
|
+
additionalInfo?: {
|
|
229
|
+
type: string;
|
|
230
|
+
} | undefined;
|
|
231
|
+
size?: {
|
|
232
|
+
type: string;
|
|
233
|
+
enum: string[];
|
|
234
|
+
} | undefined;
|
|
235
|
+
links?: {
|
|
236
|
+
type: string;
|
|
237
|
+
items: {
|
|
238
|
+
type: string;
|
|
239
|
+
properties: {
|
|
240
|
+
when: {
|
|
241
|
+
type: string;
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
} | undefined;
|
|
246
|
+
buttons?: {
|
|
247
|
+
type: string;
|
|
248
|
+
items: {
|
|
249
|
+
type: string;
|
|
250
|
+
properties: {
|
|
251
|
+
when: {
|
|
252
|
+
type: string;
|
|
253
|
+
};
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
} | undefined;
|
|
257
|
+
theme?: {
|
|
258
|
+
type: string;
|
|
259
|
+
enum: string[];
|
|
260
|
+
} | undefined;
|
|
218
261
|
};
|
|
219
262
|
};
|
|
220
263
|
export declare const TabsBlock: {
|
|
@@ -245,6 +288,14 @@ export declare const TabsBlock: {
|
|
|
245
288
|
description: {
|
|
246
289
|
type: string;
|
|
247
290
|
};
|
|
291
|
+
tabsColSizes: {};
|
|
292
|
+
direction: {
|
|
293
|
+
type: string;
|
|
294
|
+
enum: string[];
|
|
295
|
+
};
|
|
296
|
+
centered: {
|
|
297
|
+
type: string;
|
|
298
|
+
};
|
|
248
299
|
items: {
|
|
249
300
|
type: string;
|
|
250
301
|
items: {
|
|
@@ -1,32 +1,23 @@
|
|
|
1
1
|
import { filteredArray } from '../../schema/validators/utils';
|
|
2
|
-
import { LinkProps, withTheme, BlockBaseProps, TitleProps, MediaProps, } from '../../schema/validators/common';
|
|
2
|
+
import { LinkProps, withTheme, BlockBaseProps, TitleProps, MediaProps, containerSizesArray, sizeNumber, mediaDirection, } from '../../schema/validators/common';
|
|
3
3
|
import { ImageProps } from '../../components/Image/schema';
|
|
4
|
+
import _ from 'lodash';
|
|
5
|
+
import { ContentBase } from '../../sub-blocks/Content/schema';
|
|
6
|
+
const TabsItemContentProps = _.omit(ContentBase, ['size', 'colSizes', 'centered', 'theme']);
|
|
4
7
|
export const tabsItem = {
|
|
5
8
|
type: 'object',
|
|
6
9
|
additionalProperties: false,
|
|
7
|
-
required: ['tabName'
|
|
8
|
-
properties: {
|
|
9
|
-
tabName: {
|
|
10
|
+
required: ['tabName'],
|
|
11
|
+
properties: Object.assign(Object.assign({}, TabsItemContentProps), { tabName: {
|
|
10
12
|
type: 'string',
|
|
11
|
-
},
|
|
12
|
-
title: {
|
|
13
|
+
}, caption: {
|
|
13
14
|
type: 'string',
|
|
14
|
-
},
|
|
15
|
-
text: {
|
|
16
|
-
type: 'string',
|
|
17
|
-
},
|
|
18
|
-
caption: {
|
|
19
|
-
type: 'string',
|
|
20
|
-
},
|
|
21
|
-
media: withTheme({
|
|
15
|
+
}, media: withTheme({
|
|
22
16
|
type: 'object',
|
|
23
17
|
properties: MediaProps,
|
|
24
|
-
}),
|
|
18
|
+
}),
|
|
25
19
|
//TODO deprecated
|
|
26
|
-
link: LinkProps,
|
|
27
|
-
links: filteredArray(LinkProps),
|
|
28
|
-
image: withTheme(ImageProps),
|
|
29
|
-
},
|
|
20
|
+
link: LinkProps, image: withTheme(ImageProps) }),
|
|
30
21
|
};
|
|
31
22
|
export const TabsBlock = {
|
|
32
23
|
'tabs-block': {
|
|
@@ -34,6 +25,9 @@ export const TabsBlock = {
|
|
|
34
25
|
required: ['title', 'items'],
|
|
35
26
|
properties: Object.assign(Object.assign({}, BlockBaseProps), { title: TitleProps, description: {
|
|
36
27
|
type: 'string',
|
|
37
|
-
},
|
|
28
|
+
}, tabsColSizes: containerSizesArray.reduce((acc, size) => (Object.assign(Object.assign({}, acc), { [size]: sizeNumber })), {}), direction: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
enum: mediaDirection,
|
|
31
|
+
}, centered: { type: 'boolean' }, items: filteredArray(tabsItem) }),
|
|
38
32
|
},
|
|
39
33
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* use this for style redefinitions to awoid problems with
|
|
2
|
+
unpredictable css rules order in build */
|
|
3
|
+
.pc-button-tabs {
|
|
4
|
+
margin-bottom: 20px;
|
|
5
|
+
}
|
|
6
|
+
.pc-button-tabs__item {
|
|
7
|
+
margin-right: 8px;
|
|
8
|
+
margin-bottom: 12px;
|
|
9
|
+
}
|
|
10
|
+
.pc-button-tabs__item_active {
|
|
11
|
+
pointer-events: none;
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ButtonProps } from '../../models';
|
|
2
|
+
import './ButtonTabs.css';
|
|
3
|
+
export interface ButtonTabsItemProps extends Omit<ButtonProps, 'url' | 'primary' | 'target' | 'text'> {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ButtonTabsProps {
|
|
8
|
+
className?: string;
|
|
9
|
+
items: ButtonTabsItemProps[];
|
|
10
|
+
activeTab?: string;
|
|
11
|
+
onSelectTab?: (tabId: string) => void;
|
|
12
|
+
}
|
|
13
|
+
declare const ButtonTabs: (props: ButtonTabsProps) => JSX.Element;
|
|
14
|
+
export default ButtonTabs;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React, { useCallback, useMemo } from 'react';
|
|
2
|
+
import { block } from '../../utils';
|
|
3
|
+
import { Button } from '../index';
|
|
4
|
+
import './ButtonTabs.css';
|
|
5
|
+
const b = block('button-tabs');
|
|
6
|
+
const ButtonTabs = (props) => {
|
|
7
|
+
const { className, items, activeTab, onSelectTab } = props;
|
|
8
|
+
const activeTabId = useMemo(() => {
|
|
9
|
+
if (activeTab) {
|
|
10
|
+
return activeTab;
|
|
11
|
+
}
|
|
12
|
+
return items[0].id;
|
|
13
|
+
}, [activeTab, items]);
|
|
14
|
+
const handleClick = useCallback((tabId) => {
|
|
15
|
+
if (onSelectTab) {
|
|
16
|
+
onSelectTab(tabId);
|
|
17
|
+
}
|
|
18
|
+
}, [onSelectTab]);
|
|
19
|
+
return (React.createElement("div", { className: b(null, className) }, items.map((item) => {
|
|
20
|
+
const isActive = item.id === activeTabId;
|
|
21
|
+
return (React.createElement(Button, { text: item.title, className: b('item', { active: isActive }), key: item.title, size: 'l', onClick: () => handleClick(item.id), theme: isActive ? 'monochrome' : 'normal' }));
|
|
22
|
+
})));
|
|
23
|
+
};
|
|
24
|
+
export default ButtonTabs;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CSSProperties, MouseEventHandler } from 'react';
|
|
2
2
|
import { ImageDeviceProps, ImageObjectProps } from '../../models';
|
|
3
|
+
import './Image.css';
|
|
3
4
|
export interface ImageProps extends Partial<ImageObjectProps>, Partial<ImageDeviceProps> {
|
|
4
5
|
style?: CSSProperties;
|
|
5
6
|
className?: string;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React, { useContext, useState, Fragment } from 'react';
|
|
2
2
|
import { ProjectSettingsContext } from '../../context/projectSettingsContext';
|
|
3
3
|
import { BREAKPOINTS } from '../../constants';
|
|
4
|
+
import { block } from '../../utils';
|
|
5
|
+
import './Image.css';
|
|
6
|
+
const b = block('image');
|
|
4
7
|
const checkWebP = (src) => {
|
|
5
8
|
return src.endsWith('.webp') ? src : src + '.webp';
|
|
6
9
|
};
|
|
@@ -17,7 +20,7 @@ const Image = (props) => {
|
|
|
17
20
|
disableCompress ||
|
|
18
21
|
imageSrc.endsWith('.svg') ||
|
|
19
22
|
imgLoadingError;
|
|
20
|
-
return (React.createElement("picture",
|
|
23
|
+
return (React.createElement("picture", { className: b() },
|
|
21
24
|
mobile && (React.createElement(Fragment, null,
|
|
22
25
|
!disableWebp && (React.createElement("source", { srcSet: checkWebP(mobile), type: "image/webp", media: `(max-width: ${BREAKPOINTS.sm}px)` })),
|
|
23
26
|
React.createElement("source", { srcSet: mobile, media: `(max-width: ${BREAKPOINTS.sm}px)` }))),
|
|
@@ -11,7 +11,7 @@ export declare const blockMap: {
|
|
|
11
11
|
"info-block": (props: import("./models").InfoBlockProps) => JSX.Element;
|
|
12
12
|
"security-block": (props: import("./models").SecurityBlockProps) => JSX.Element;
|
|
13
13
|
"table-block": (props: import("./models").TableBlockProps) => JSX.Element;
|
|
14
|
-
"tabs-block": ({ items, title, description, animated }: import("./models").TabsBlockProps) => JSX.Element;
|
|
14
|
+
"tabs-block": ({ items, title, description, animated, tabsColSizes, centered, direction, }: import("./models").TabsBlockProps) => JSX.Element;
|
|
15
15
|
"link-table-block": ({ items, title, description, linkTheme }: import("./models").LinkTableBlockProps) => JSX.Element;
|
|
16
16
|
"header-block": (props: import("./models").WithChildren<import("./models").HeaderBlockProps & import("./models").ClassNameProps>) => JSX.Element;
|
|
17
17
|
"icons-block": ({ title, size, items }: import("./models").IconsBlockProps) => JSX.Element;
|
|
@@ -219,18 +219,20 @@ export interface TableBlockProps {
|
|
|
219
219
|
title: string;
|
|
220
220
|
table: TableProps;
|
|
221
221
|
}
|
|
222
|
-
export interface TabsBlockItem {
|
|
222
|
+
export interface TabsBlockItem extends Omit<ContentBlockProps, 'size' | 'colSizes' | 'centered' | 'theme'> {
|
|
223
223
|
tabName: string;
|
|
224
|
-
|
|
225
|
-
|
|
224
|
+
/**
|
|
225
|
+
* @deprecated Use array links from ContentBlockProps instead
|
|
226
|
+
*/
|
|
226
227
|
link?: LinkProps;
|
|
227
228
|
image?: ThemedImage;
|
|
228
|
-
disableCompress?: boolean;
|
|
229
229
|
caption?: string;
|
|
230
230
|
media?: ThemedMediaProps;
|
|
231
|
-
links?: LinkProps[];
|
|
232
231
|
}
|
|
233
232
|
export interface TabsBlockProps extends BlockHeaderProps, Animatable {
|
|
233
|
+
tabsColSizes?: GridColumnSizesType;
|
|
234
|
+
centered?: boolean;
|
|
235
|
+
direction?: MediaDirection;
|
|
234
236
|
items: TabsBlockItem[];
|
|
235
237
|
}
|
|
236
238
|
export interface LinkTableBlockProps extends BlockHeaderProps {
|
|
@@ -19,7 +19,6 @@ export const createItemsParser = (fields) => (transformer, items) => items.map((
|
|
|
19
19
|
}, {}));
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
|
-
const parseItems = createItemsParser(['title', 'text']);
|
|
23
22
|
function parseTableBlock(transformer, content) {
|
|
24
23
|
const legend = content === null || content === void 0 ? void 0 : content.legend;
|
|
25
24
|
return Object.assign(Object.assign({}, (content || {})), { legend: legend && legend.map((string) => transformer(string)) });
|
|
@@ -45,9 +44,13 @@ function parseSlider(transformer, block) {
|
|
|
45
44
|
}
|
|
46
45
|
const parseTitle = (transformer, title) => typeof title === 'object' && 'text' in title
|
|
47
46
|
? Object.assign(Object.assign({}, title), { text: transformer(title.text) }) : title && transformer(title);
|
|
47
|
+
const parseItemsTitle = (transformer, items) => items.map((_a) => {
|
|
48
|
+
var { title } = _a, rest = __rest(_a, ["title"]);
|
|
49
|
+
return (Object.assign({ title: title && parseTitle(transformer, title) }, rest));
|
|
50
|
+
});
|
|
48
51
|
function parsePriceDetailedBlock(transformer, block) {
|
|
49
52
|
const { priceType } = block;
|
|
50
|
-
|
|
53
|
+
block.items = block.items.map((item) => {
|
|
51
54
|
const { description, items: details = [] } = item;
|
|
52
55
|
if (priceType === 'marked-list') {
|
|
53
56
|
item.items = details.map((detail) => {
|
|
@@ -64,7 +67,6 @@ function parsePriceDetailedBlock(transformer, block) {
|
|
|
64
67
|
item.description = transformer(description);
|
|
65
68
|
return item;
|
|
66
69
|
});
|
|
67
|
-
block.items = transformedBlockItems;
|
|
68
70
|
return block;
|
|
69
71
|
}
|
|
70
72
|
const parseContentLayout = (transformer, content) => {
|
|
@@ -220,7 +222,12 @@ const config = {
|
|
|
220
222
|
{
|
|
221
223
|
fields: ['items'],
|
|
222
224
|
transformer: yfmTransformer,
|
|
223
|
-
parser:
|
|
225
|
+
parser: createItemsParser(['text', 'additionalInfo']),
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
fields: ['items'],
|
|
229
|
+
transformer: typografTransformer,
|
|
230
|
+
parser: parseItemsTitle,
|
|
224
231
|
},
|
|
225
232
|
],
|
|
226
233
|
[BlockType.TableBlock]: [
|
package/package.json
CHANGED
|
@@ -219,18 +219,20 @@ export interface TableBlockProps {
|
|
|
219
219
|
title: string;
|
|
220
220
|
table: TableProps;
|
|
221
221
|
}
|
|
222
|
-
export interface TabsBlockItem {
|
|
222
|
+
export interface TabsBlockItem extends Omit<ContentBlockProps, 'size' | 'colSizes' | 'centered' | 'theme'> {
|
|
223
223
|
tabName: string;
|
|
224
|
-
|
|
225
|
-
|
|
224
|
+
/**
|
|
225
|
+
* @deprecated Use array links from ContentBlockProps instead
|
|
226
|
+
*/
|
|
226
227
|
link?: LinkProps;
|
|
227
228
|
image?: ThemedImage;
|
|
228
|
-
disableCompress?: boolean;
|
|
229
229
|
caption?: string;
|
|
230
230
|
media?: ThemedMediaProps;
|
|
231
|
-
links?: LinkProps[];
|
|
232
231
|
}
|
|
233
232
|
export interface TabsBlockProps extends BlockHeaderProps, Animatable {
|
|
233
|
+
tabsColSizes?: GridColumnSizesType;
|
|
234
|
+
centered?: boolean;
|
|
235
|
+
direction?: MediaDirection;
|
|
234
236
|
items: TabsBlockItem[];
|
|
235
237
|
}
|
|
236
238
|
export interface LinkTableBlockProps extends BlockHeaderProps {
|
|
@@ -36,7 +36,6 @@ const createItemsParser = (fields) => (transformer, items) => items.map((item) =
|
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
38
|
exports.createItemsParser = createItemsParser;
|
|
39
|
-
const parseItems = (0, exports.createItemsParser)(['title', 'text']);
|
|
40
39
|
function parseTableBlock(transformer, content) {
|
|
41
40
|
const legend = content === null || content === void 0 ? void 0 : content.legend;
|
|
42
41
|
return Object.assign(Object.assign({}, (content || {})), { legend: legend && legend.map((string) => transformer(string)) });
|
|
@@ -62,9 +61,13 @@ function parseSlider(transformer, block) {
|
|
|
62
61
|
}
|
|
63
62
|
const parseTitle = (transformer, title) => typeof title === 'object' && 'text' in title
|
|
64
63
|
? Object.assign(Object.assign({}, title), { text: transformer(title.text) }) : title && transformer(title);
|
|
64
|
+
const parseItemsTitle = (transformer, items) => items.map((_a) => {
|
|
65
|
+
var { title } = _a, rest = __rest(_a, ["title"]);
|
|
66
|
+
return (Object.assign({ title: title && parseTitle(transformer, title) }, rest));
|
|
67
|
+
});
|
|
65
68
|
function parsePriceDetailedBlock(transformer, block) {
|
|
66
69
|
const { priceType } = block;
|
|
67
|
-
|
|
70
|
+
block.items = block.items.map((item) => {
|
|
68
71
|
const { description, items: details = [] } = item;
|
|
69
72
|
if (priceType === 'marked-list') {
|
|
70
73
|
item.items = details.map((detail) => {
|
|
@@ -81,7 +84,6 @@ function parsePriceDetailedBlock(transformer, block) {
|
|
|
81
84
|
item.description = transformer(description);
|
|
82
85
|
return item;
|
|
83
86
|
});
|
|
84
|
-
block.items = transformedBlockItems;
|
|
85
87
|
return block;
|
|
86
88
|
}
|
|
87
89
|
const parseContentLayout = (transformer, content) => {
|
|
@@ -239,7 +241,12 @@ const config = {
|
|
|
239
241
|
{
|
|
240
242
|
fields: ['items'],
|
|
241
243
|
transformer: yfmTransformer,
|
|
242
|
-
parser:
|
|
244
|
+
parser: (0, exports.createItemsParser)(['text', 'additionalInfo']),
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
fields: ['items'],
|
|
248
|
+
transformer: typografTransformer,
|
|
249
|
+
parser: parseItemsTitle,
|
|
243
250
|
},
|
|
244
251
|
],
|
|
245
252
|
[models_1.BlockType.TableBlock]: [
|