@gravity-ui/page-constructor 1.8.2 → 1.9.0-alpha.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/build/cjs/blocks/Tabs/Tabs.css +64 -24
  3. package/build/cjs/blocks/Tabs/Tabs.d.ts +1 -1
  4. package/build/cjs/blocks/Tabs/Tabs.js +34 -27
  5. package/build/cjs/blocks/Tabs/schema.d.ts +68 -17
  6. package/build/cjs/blocks/Tabs/schema.js +14 -19
  7. package/build/cjs/components/ButtonTabs/ButtonTabs.css +12 -0
  8. package/build/cjs/components/ButtonTabs/ButtonTabs.d.ts +13 -0
  9. package/build/cjs/components/ButtonTabs/ButtonTabs.js +26 -0
  10. package/build/cjs/components/Image/Image.css +4 -0
  11. package/build/cjs/components/Image/Image.js +3 -1
  12. package/build/cjs/components/Media/Media.js +1 -1
  13. package/build/cjs/components/Media/Video/Video.js +4 -3
  14. package/build/cjs/components/ReactPlayer/ReactPlayer.d.ts +1 -0
  15. package/build/cjs/components/ReactPlayer/ReactPlayer.js +5 -5
  16. package/build/cjs/components/VideoBlock/VideoBlock.d.ts +2 -0
  17. package/build/cjs/components/VideoBlock/VideoBlock.js +7 -6
  18. package/build/cjs/constructor-items.d.ts +1 -1
  19. package/build/cjs/models/constructor-items/blocks.d.ts +7 -5
  20. package/build/cjs/text-transform/blocks.js +11 -4
  21. package/build/esm/blocks/Tabs/Tabs.css +64 -24
  22. package/build/esm/blocks/Tabs/Tabs.d.ts +1 -1
  23. package/build/esm/blocks/Tabs/Tabs.js +35 -28
  24. package/build/esm/blocks/Tabs/schema.d.ts +68 -17
  25. package/build/esm/blocks/Tabs/schema.js +14 -20
  26. package/build/esm/components/ButtonTabs/ButtonTabs.css +12 -0
  27. package/build/esm/components/ButtonTabs/ButtonTabs.d.ts +14 -0
  28. package/build/esm/components/ButtonTabs/ButtonTabs.js +24 -0
  29. package/build/esm/components/Image/Image.css +4 -0
  30. package/build/esm/components/Image/Image.d.ts +1 -0
  31. package/build/esm/components/Image/Image.js +4 -1
  32. package/build/esm/components/Media/Media.js +1 -1
  33. package/build/esm/components/Media/Video/Video.js +4 -3
  34. package/build/esm/components/ReactPlayer/ReactPlayer.d.ts +1 -0
  35. package/build/esm/components/ReactPlayer/ReactPlayer.js +5 -5
  36. package/build/esm/components/VideoBlock/VideoBlock.d.ts +2 -0
  37. package/build/esm/components/VideoBlock/VideoBlock.js +6 -6
  38. package/build/esm/constructor-items.d.ts +1 -1
  39. package/build/esm/models/constructor-items/blocks.d.ts +7 -5
  40. package/build/esm/text-transform/blocks.js +11 -4
  41. package/package.json +4 -1
  42. package/server/models/constructor-items/blocks.d.ts +7 -5
  43. 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-TabsBlock__content-title.pc-TabsBlock__content-title > * {
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-TabsBlock__block-title {
8
- margin-bottom: 12px;
7
+ .pc-tabs-block__block-title {
8
+ margin-bottom: 24px;
9
9
  }
10
- .pc-TabsBlock__tabs.pc-TabsBlock__tabs {
11
- flex-wrap: nowrap;
12
- overflow-x: auto;
13
- margin-bottom: 32px;
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
- .pc-TabsBlock__image {
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-TabsBlock__image, .pc-TabsBlock__media {
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-TabsBlock__caption {
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-TabsBlock__content {
46
+ .pc-tabs-block__content {
34
47
  display: flex;
35
48
  flex-direction: column;
36
49
  }
37
- .pc-TabsBlock__content-wrapper_margin {
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-TabsBlock__content-title {
59
+ .pc-tabs-block__content-title {
41
60
  margin: 0 auto 12px;
42
61
  }
43
- .pc-TabsBlock__content-title.pc-TabsBlock__content-title > * {
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-TabsBlock__content-wrapper_margin {
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-TabsBlock.pc-AnimateBlock .pc-TabsBlock__media, .pc-AnimateBlock .pc-TabsBlock .pc-TabsBlock__media {
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-TabsBlock.pc-AnimateBlock.animate .pc-TabsBlock__media, .pc-AnimateBlock .pc-TabsBlock.animate .pc-TabsBlock__media {
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-TabsBlock.pc-AnimateBlock .pc-TabsBlock__image, .pc-AnimateBlock .pc-TabsBlock .pc-TabsBlock__image {
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-TabsBlock.pc-AnimateBlock.animate .pc-TabsBlock__image, .pc-AnimateBlock .pc-TabsBlock.animate .pc-TabsBlock__image {
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,60 @@ 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 b = (0, utils_1.block)('TabsBlock');
18
- const TabsBlock = ({ items, title, description, animated }) => {
14
+ const ButtonTabs_1 = (0, tslib_1.__importDefault)(require("../../components/ButtonTabs/ButtonTabs"));
15
+ const sub_blocks_1 = require("../../sub-blocks");
16
+ const VideoBlock_1 = require("../../components/VideoBlock/VideoBlock");
17
+ const b = (0, utils_1.block)('tabs-block');
18
+ const TabsBlock = ({ items, title, description, animated, tabsColSizes, centered, direction = 'media-content', }) => {
19
+ var _a;
19
20
  const [activeTab, setActiveTab] = (0, react_1.useState)(items[0].tabName);
20
21
  const [play, setPlay] = (0, react_1.useState)(false);
21
22
  const { themeValue: theme } = (0, react_1.useContext)(ThemeValueContext_1.ThemeValueContext);
22
23
  const tabs = items.map(({ tabName }) => ({ title: tabName, id: tabName }));
23
24
  const activeTabData = items.find(({ tabName }) => tabName === activeTab);
25
+ const isReverse = direction === 'content-media';
26
+ const ref = (0, react_1.useRef)(null);
27
+ const mediaWidth = (_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.offsetWidth;
28
+ const mediaHeight = mediaWidth && (0, VideoBlock_1.getHeight)(mediaWidth);
24
29
  let imageProps;
25
30
  if (activeTabData) {
26
31
  const themedImage = (0, utils_1.getThemedValue)(activeTabData.image, theme);
27
32
  imageProps = themedImage && (0, utils_2.getMediaImage)(themedImage);
28
33
  }
29
34
  const showMedia = Boolean((activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) || imageProps);
35
+ const showText = Boolean(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.text);
36
+ const textContent = activeTabData && showText && (react_1.default.createElement(grid_1.Col, { sizes: { all: 12, md: showMedia ? 4 : 8 }, className: b('content', { centered: centered }) },
37
+ react_1.default.createElement("div", { className: b('content-wrapper', {
38
+ margin: Boolean(((activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) || imageProps) && !isReverse),
39
+ }) },
40
+ react_1.default.createElement(sub_blocks_1.Content, { title: activeTabData.title, text: activeTabData.text, additionalInfo: activeTabData.additionalInfo, size: "s", links: [
41
+ ...(activeTabData.link ? [activeTabData.link] : []),
42
+ ...(activeTabData.links || []),
43
+ ], buttons: activeTabData.buttons, colSizes: { all: 12 } }))));
44
+ const mediaContent = showMedia && (react_1.default.createElement(grid_1.Col, { sizes: { all: 12, md: 8 }, orders: {
45
+ all: grid_1.GridColumnOrderClasses.Last,
46
+ md: grid_1.GridColumnOrderClasses.First,
47
+ }, className: b('col', { centered: centered }) },
48
+ react_1.default.createElement("div", { ref: ref }, (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, height: mediaHeight })))),
49
+ imageProps && (react_1.default.createElement(react_1.Fragment, null,
50
+ react_1.default.createElement(FullscreenImage_1.default, Object.assign({}, imageProps, { imageClassName: b('image') })),
51
+ (activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.caption) && (react_1.default.createElement("p", { className: b('caption') }, activeTabData.caption))))));
30
52
  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(uikit_1.Tabs, { className: b('tabs'), items: tabs, activeTab: activeTab, onSelectTab: setActiveTab, size: "l" }),
33
- activeTabData && (react_1.default.createElement(grid_1.Row, null,
34
- showMedia && (react_1.default.createElement(grid_1.Col, { sizes: { all: 12, md: 8 }, orders: {
35
- all: grid_1.GridColumnOrderClasses.Last,
36
- md: grid_1.GridColumnOrderClasses.First,
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') })))))));
53
+ react_1.default.createElement(BlockHeader_1.default, { title: title, description: description, className: b('block-title', { centered: centered }) }),
54
+ react_1.default.createElement(grid_1.Row, null,
55
+ react_1.default.createElement(grid_1.Col, { sizes: tabsColSizes },
56
+ react_1.default.createElement(ButtonTabs_1.default, { items: tabs, onSelectTab: setActiveTab, activeTab: activeTab, className: b('tabs', { centered: centered }) }))),
57
+ activeTabData && (react_1.default.createElement(grid_1.Row, { className: b('row', { reverse: isReverse }) },
58
+ mediaContent,
59
+ textContent))));
53
60
  };
54
61
  exports.TabsBlock = TabsBlock;
55
62
  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', 'text'],
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
- }, items: (0, utils_1.filteredArray)(exports.tabsItem) }),
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;
@@ -0,0 +1,4 @@
1
+ .pc-image {
2
+ height: 100%;
3
+ width: 100%;
4
+ }
@@ -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", null,
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)` }))),
@@ -22,7 +22,7 @@ const Media = (props) => {
22
22
  result.push(react_1.default.createElement(Video_1.default, { key: "video", video: video, videoClassName: videoClassName, height: height, metrika: metrika, playVideo: playVideo, previewImg: previewImg, playButton: playButton, customBarControlsClassName: customBarControlsClassName, hasVideoFallback: hasVideoFallback, setHasVideoFallback: setHasVideoFallback }));
23
23
  }
24
24
  if (youtube) {
25
- result = (react_1.default.createElement(VideoBlock_1.default, { className: b('youtube', youtubeClassName), record: youtube, attributes: { color: 'white', rel: '0' }, previewImg: previewImg }));
25
+ result = (react_1.default.createElement(VideoBlock_1.default, { className: b('youtube', youtubeClassName), record: youtube, attributes: { color: 'white', rel: '0' }, previewImg: previewImg, height: height }));
26
26
  }
27
27
  if (dataLens) {
28
28
  result = react_1.default.createElement(DataLens_1.default, { dataLens: dataLens });
@@ -31,15 +31,16 @@ const Video = (props) => {
31
31
  }, [playVideo, video, setHasVideoFallback]);
32
32
  const reactPlayerBlock = (0, react_1.useMemo)(() => {
33
33
  const { src, loop, controls, muted, autoplay = true, elapsedTime, playButton } = video;
34
- return (react_1.default.createElement(ReactPlayer_1.default, { className: b('react-player', videoClassName), src: src, previewImgUrl: previewImg, loop: Boolean(loop), controls: controls, muted: muted, autoplay: autoplay && playVideo, elapsedTime: elapsedTime, playButton: playButton || commonPlayButton, customBarControlsClassName: customBarControlsClassName, metrika: metrika }));
34
+ return (react_1.default.createElement(ReactPlayer_1.default, { className: b('react-player', videoClassName), src: src, previewImgUrl: previewImg, loop: Boolean(loop), controls: controls, muted: muted, autoplay: autoplay && playVideo, elapsedTime: elapsedTime, playButton: playButton || commonPlayButton, customBarControlsClassName: customBarControlsClassName, metrika: metrika, height: height }));
35
35
  }, [
36
36
  video,
37
- metrika,
37
+ height,
38
+ videoClassName,
38
39
  previewImg,
39
40
  playVideo,
40
- videoClassName,
41
41
  commonPlayButton,
42
42
  customBarControlsClassName,
43
+ metrika,
43
44
  ]);
44
45
  const defaultVideoBlock = (0, react_1.useMemo)(() => {
45
46
  return video.src.length && !hasVideoFallback ? (react_1.default.createElement("div", { className: b('wrap', videoClassName), style: { height } },
@@ -7,6 +7,7 @@ export interface ReactPlayerBlockProps extends Omit<MediaVideoProps, 'loop' | 's
7
7
  customBarControlsClassName?: string;
8
8
  showPreview?: boolean;
9
9
  onClickPreview?: () => void;
10
+ height?: number;
10
11
  children?: React.ReactNode;
11
12
  }
12
13
  export declare const ReactPlayerBlock: React.ForwardRefExoticComponent<ReactPlayerBlockProps & React.RefAttributes<ReactPlayerBlockHandler>>;
@@ -19,7 +19,7 @@ const FPS = 60;
19
19
  exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
20
20
  const isMobile = (0, react_1.useContext)(mobileContext_1.MobileContext);
21
21
  const { metrika } = (0, react_1.useContext)(metrikaContext_1.MetrikaContext);
22
- const { src, previewImgUrl, loop = false, controls = models_1.MediaVideoControlsType.Default, muted: initiallyMuted = false, elapsedTime, playButton, className, customBarControlsClassName, showPreview, onClickPreview, metrika: videoMetrika, } = props;
22
+ const { src, previewImgUrl, loop = false, controls = models_1.MediaVideoControlsType.Default, muted: initiallyMuted = false, elapsedTime, playButton, className, customBarControlsClassName, showPreview, onClickPreview, metrika: videoMetrika, height, } = props;
23
23
  const { type = models_1.PlayButtonType.Default, theme = models_1.PlayButtonThemes.Blue, text, className: buttonClassName, } = playButton || {};
24
24
  const autoPlay = Boolean(!isMobile && !previewImgUrl && props.autoplay);
25
25
  const mute = initiallyMuted || autoPlay;
@@ -28,7 +28,7 @@ exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
28
28
  const [playerRef, setPlayerRef] = (0, react_1.useState)();
29
29
  const [isPlaying, setIsPlaying] = (0, react_1.useState)(autoPlay);
30
30
  const [playedPercent, setPlayedPercent] = (0, react_1.useState)(0);
31
- const [height, setHeight] = (0, react_1.useState)(0);
31
+ const [currentHeight, setCurrentHeight] = (0, react_1.useState)(height);
32
32
  const [width, setWidth] = (0, react_1.useState)(0);
33
33
  const [muted, setMuted] = (0, react_1.useState)(mute);
34
34
  const [started, setStarted] = (0, react_1.useState)(autoPlay);
@@ -73,7 +73,7 @@ exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
73
73
  parseFloat(paddingLeft) -
74
74
  parseFloat(paddingRight);
75
75
  setWidth(newWidth);
76
- setHeight(Math.floor(getHeight(newWidth)));
76
+ setCurrentHeight(Math.floor(getHeight(newWidth)));
77
77
  }
78
78
  }, 200);
79
79
  updateSize();
@@ -179,8 +179,8 @@ exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
179
179
  },
180
180
  }, elapsedTimePercent: elapsedTimePercent }));
181
181
  }, [controls, isPlaying, customBarControlsClassName, changeMute]);
182
- return (react_1.default.createElement("div", { className: b({ wrapper: !height }, className), ref: ref, onClick: handleClick },
183
- react_1.default.createElement(react_player_1.default, { className: b('player'), url: src, muted: muted, controls: controls === models_1.MediaVideoControlsType.Default, height: height || '100%', width: width || '100%', light: previewImgUrl, playing: isPlaying, playIcon: playIcon, progressInterval: FPS, onClickPreview: handleClickPreview, onStart: onStart, onReady: setPlayerRef, onPlay: onPlay, onPause: onPause, onProgress: onProgress, onEnded: onEnded }),
182
+ return (react_1.default.createElement("div", { className: b({ wrapper: !currentHeight }, className), ref: ref, onClick: handleClick },
183
+ react_1.default.createElement(react_player_1.default, { className: b('player'), url: src, muted: muted, controls: controls === models_1.MediaVideoControlsType.Default, height: currentHeight || '100%', width: width || '100%', light: previewImgUrl, playing: isPlaying, playIcon: playIcon, progressInterval: FPS, onClickPreview: handleClickPreview, onStart: onStart, onReady: setPlayerRef, onPlay: onPlay, onPause: onPause, onProgress: onProgress, onEnded: onEnded }),
184
184
  renderCustomBarControls(muted, playedPercent)));
185
185
  });
186
186
  function getHeight(width) {
@@ -3,6 +3,7 @@ export declare const AUTOPLAY_ATTRIBUTES: {
3
3
  autoplay: number;
4
4
  mute: number;
5
5
  };
6
+ export declare function getHeight(width: number): number;
6
7
  export interface VideoBlockProps {
7
8
  id?: string;
8
9
  stream?: string;
@@ -11,6 +12,7 @@ export interface VideoBlockProps {
11
12
  className?: string;
12
13
  previewImg?: string;
13
14
  playButton?: React.ReactNode;
15
+ height?: number;
14
16
  }
15
17
  declare const VideoBlock: (props: VideoBlockProps) => JSX.Element | null;
16
18
  export default VideoBlock;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AUTOPLAY_ATTRIBUTES = void 0;
3
+ exports.getHeight = exports.AUTOPLAY_ATTRIBUTES = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = (0, tslib_1.__importStar)(require("react"));
6
6
  const lodash_1 = (0, tslib_1.__importDefault)(require("lodash"));
@@ -36,14 +36,15 @@ function getVideoSrc(stream, record) {
36
36
  function getHeight(width) {
37
37
  return (width / 16) * 9;
38
38
  }
39
+ exports.getHeight = getHeight;
39
40
  const VideoBlock = (props) => {
40
- const { stream, record, attributes, className, id, previewImg, playButton } = props;
41
+ const { stream, record, attributes, className, id, previewImg, playButton, height } = props;
41
42
  const src = getVideoSrc(stream, record);
42
43
  const ref = (0, react_1.useRef)(null);
43
44
  const iframeRef = (0, react_1.useRef)();
44
45
  const [hidePreview, setHidePreview] = (0, react_1.useState)(false);
45
46
  const norender = (!stream && !record) || !src;
46
- const [height, setHeight] = (0, react_1.useState)();
47
+ const [currentHeight, setCurrentHeight] = (0, react_1.useState)(height || undefined);
47
48
  const fullId = `${iframeId}-${id || src}`;
48
49
  const onPreviewClick = (0, react_1.useCallback)(() => {
49
50
  if (iframeRef.current) {
@@ -53,14 +54,14 @@ const VideoBlock = (props) => {
53
54
  }, [src, attributes]);
54
55
  (0, react_1.useEffect)(() => {
55
56
  const updateSize = lodash_1.default.debounce(() => {
56
- setHeight(ref.current ? Math.round(getHeight(ref.current.offsetWidth)) : undefined);
57
+ setCurrentHeight(ref.current ? Math.round(getHeight(ref.current.offsetWidth)) : undefined);
57
58
  }, 100);
58
59
  updateSize();
59
60
  window.addEventListener('resize', updateSize);
60
61
  return () => {
61
62
  window.removeEventListener('resize', updateSize);
62
63
  };
63
- }, []);
64
+ }, [height]);
64
65
  (0, react_1.useEffect)(() => {
65
66
  if (norender) {
66
67
  return;
@@ -89,7 +90,7 @@ const VideoBlock = (props) => {
89
90
  if (norender) {
90
91
  return null;
91
92
  }
92
- return (react_1.default.createElement("div", { className: b(null, className), ref: ref, style: { height } }, previewImg && !hidePreview && (react_1.default.createElement("div", { className: b('preview'), onClick: onPreviewClick },
93
+ return (react_1.default.createElement("div", { className: b(null, className), ref: ref, style: { height: currentHeight } }, previewImg && !hidePreview && (react_1.default.createElement("div", { className: b('preview'), onClick: onPreviewClick },
93
94
  react_1.default.createElement(Image_1.default, { src: previewImg, className: b('image') }),
94
95
  playButton || (react_1.default.createElement("button", { className: b('button') },
95
96
  react_1.default.createElement(uikit_1.Icon, { className: b('icon'), data: icons_1.PlayVideo, size: 24 })))))));