@gravity-ui/page-constructor 2.9.0 → 2.11.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 (51) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/build/cjs/blocks/Questions/Questions.js +1 -1
  3. package/build/cjs/blocks/Security/Security.js +1 -1
  4. package/build/cjs/blocks/Tabs/Tabs.js +5 -1
  5. package/build/cjs/components/Anchor/Anchor.d.ts +1 -0
  6. package/build/cjs/components/Anchor/Anchor.js +3 -1
  7. package/build/cjs/components/BlockBase/BlockBase.js +2 -2
  8. package/build/cjs/components/BlockBase/__tests__/BlockBase.test.d.ts +1 -0
  9. package/build/cjs/components/BlockBase/__tests__/BlockBase.test.js +44 -0
  10. package/build/cjs/components/Button/Button.d.ts +2 -1
  11. package/build/cjs/components/Button/Button.js +4 -3
  12. package/build/cjs/components/ButtonTabs/ButtonTabs.d.ts +1 -1
  13. package/build/cjs/components/ButtonTabs/ButtonTabs.js +3 -3
  14. package/build/cjs/components/Image/Image.js +7 -6
  15. package/build/cjs/components/ImageBase/ImageBase.d.ts +10 -0
  16. package/build/cjs/components/ImageBase/ImageBase.js +12 -0
  17. package/build/cjs/components/index.d.ts +2 -0
  18. package/build/cjs/components/index.js +3 -1
  19. package/build/cjs/containers/PageConstructor/Provider.d.ts +2 -0
  20. package/build/cjs/containers/PageConstructor/Provider.js +3 -1
  21. package/build/cjs/context/imageContext/imageContext.d.ts +7 -0
  22. package/build/cjs/context/imageContext/imageContext.js +6 -0
  23. package/build/cjs/context/imageContext/index.d.ts +1 -0
  24. package/build/cjs/context/imageContext/index.js +4 -0
  25. package/build/cjs/models/constructor-items/blocks.d.ts +1 -0
  26. package/build/esm/blocks/Questions/Questions.js +1 -1
  27. package/build/esm/blocks/Security/Security.js +2 -2
  28. package/build/esm/blocks/Tabs/Tabs.js +5 -1
  29. package/build/esm/components/Anchor/Anchor.d.ts +1 -0
  30. package/build/esm/components/Anchor/Anchor.js +2 -1
  31. package/build/esm/components/BlockBase/BlockBase.js +2 -2
  32. package/build/esm/components/BlockBase/__tests__/BlockBase.test.d.ts +1 -0
  33. package/build/esm/components/BlockBase/__tests__/BlockBase.test.js +41 -0
  34. package/build/esm/components/Button/Button.d.ts +2 -1
  35. package/build/esm/components/Button/Button.js +4 -3
  36. package/build/esm/components/ButtonTabs/ButtonTabs.d.ts +1 -1
  37. package/build/esm/components/ButtonTabs/ButtonTabs.js +3 -3
  38. package/build/esm/components/Image/Image.js +7 -6
  39. package/build/esm/components/ImageBase/ImageBase.d.ts +10 -0
  40. package/build/esm/components/ImageBase/ImageBase.js +7 -0
  41. package/build/esm/components/index.d.ts +2 -0
  42. package/build/esm/components/index.js +1 -0
  43. package/build/esm/containers/PageConstructor/Provider.d.ts +2 -0
  44. package/build/esm/containers/PageConstructor/Provider.js +3 -1
  45. package/build/esm/context/imageContext/imageContext.d.ts +7 -0
  46. package/build/esm/context/imageContext/imageContext.js +2 -0
  47. package/build/esm/context/imageContext/index.d.ts +1 -0
  48. package/build/esm/context/imageContext/index.js +1 -0
  49. package/build/esm/models/constructor-items/blocks.d.ts +1 -0
  50. package/package.json +1 -1
  51. package/server/models/constructor-items/blocks.d.ts +1 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.11.0](https://github.com/gravity-ui/page-constructor/compare/v2.10.0...v2.11.0) (2023-04-25)
4
+
5
+
6
+ ### Features
7
+
8
+ * add image context to use NextImage instead of normal img tag ([#313](https://github.com/gravity-ui/page-constructor/issues/313)) ([10841dc](https://github.com/gravity-ui/page-constructor/commit/10841dcbcc9bb16255dff57f4d79de94533a06c3))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **QuestionBlock:** fix itemprop parameter value for FaqPage microdata ([#316](https://github.com/gravity-ui/page-constructor/issues/316)) ([4395f8a](https://github.com/gravity-ui/page-constructor/commit/4395f8a78489ee254dfa25051d8f812a7ed0bf4b))
14
+
15
+ ## [2.10.0](https://github.com/gravity-ui/page-constructor/compare/v2.9.0...v2.10.0) (2023-04-24)
16
+
17
+
18
+ ### Features
19
+
20
+ * add scroll to the active tab ([#311](https://github.com/gravity-ui/page-constructor/issues/311)) ([a5f8576](https://github.com/gravity-ui/page-constructor/commit/a5f857640c9aa5d81859321a933fcef4913b5b76))
21
+
3
22
  ## [2.9.0](https://github.com/gravity-ui/page-constructor/compare/v2.8.4...v2.9.0) (2023-04-19)
4
23
 
5
24
 
@@ -12,7 +12,7 @@ const FaqMicrodataValues = {
12
12
  PageType: 'https://schema.org/FAQPage',
13
13
  QuestionType: 'https://schema.org/Question',
14
14
  QuestionProp: 'mainEntity',
15
- QuestionTextProp: 'name',
15
+ QuestionTextProp: 'text',
16
16
  AnswerType: 'https://schema.org/Answer',
17
17
  AnswerProp: 'acceptedAnswer',
18
18
  AnswerTextProp: 'text',
@@ -17,7 +17,7 @@ const SecurityBlock = (props) => {
17
17
  react_1.default.createElement(grid_1.Col, null,
18
18
  react_1.default.createElement("h2", { className: b('title') }, title))),
19
19
  points && (react_1.default.createElement(grid_1.Row, { className: b('points') }, points.map(({ text, link, img }, index) => (react_1.default.createElement(grid_1.Col, { key: index, className: b('point'), sizes: { sm: 4, all: 12 } },
20
- react_1.default.createElement("img", { className: b('point-icon'), src: img }),
20
+ react_1.default.createElement(components_1.ImageBase, { className: b('point-icon'), src: img }),
21
21
  react_1.default.createElement(components_1.HTML, { className: b('point-text'), block: true }, text),
22
22
  link && (react_1.default.createElement(components_1.Link, { className: b('point-link'), text: link.text, url: link.url, theme: 'normal', arrow: true }))))))),
23
23
  media && (react_1.default.createElement(grid_1.Row, { className: b('media') },
@@ -49,11 +49,15 @@ const TabsBlock = ({ items, title, description, animated, tabsColSizes, centered
49
49
  imageProps && (react_1.default.createElement(react_1.Fragment, null,
50
50
  react_1.default.createElement(FullscreenImage_1.default, Object.assign({}, imageProps, { imageClassName: b('image') })))),
51
51
  (activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.caption) && react_1.default.createElement("p", { className: b('caption') }, activeTabData.caption)));
52
+ const onSelectTab = (id, e) => {
53
+ setActiveTab(id);
54
+ e.currentTarget.scrollIntoView({ inline: 'center', behavior: 'smooth', block: 'nearest' });
55
+ };
52
56
  return (react_1.default.createElement(AnimateBlock_1.default, { className: b(), onScroll: () => setPlay(true), animate: animated },
53
57
  react_1.default.createElement(BlockHeader_1.default, { title: title, description: description, className: b('block-title', { centered: centered }) }),
54
58
  react_1.default.createElement(grid_1.Row, null,
55
59
  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 }) }))),
60
+ react_1.default.createElement(ButtonTabs_1.default, { items: tabs, onSelectTab: onSelectTab, activeTab: activeTab, className: b('tabs', { centered: centered }) }))),
57
61
  activeTabData && (react_1.default.createElement(grid_1.Row, { className: b('row', { reverse: isReverse }) },
58
62
  mediaContent,
59
63
  textContent))));
@@ -1,4 +1,5 @@
1
1
  import { ClassNameProps } from '../../models';
2
+ export declare const qaIdByDefault = "qa-anchor";
2
3
  export interface AnchorProps extends ClassNameProps {
3
4
  id: string;
4
5
  dataQa?: string;
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.qaIdByDefault = void 0;
3
4
  const tslib_1 = require("tslib");
4
5
  //TODO move to cloud components
5
6
  const react_1 = tslib_1.__importDefault(require("react"));
6
7
  const utils_1 = require("../../utils");
7
8
  const b = (0, utils_1.block)('Anchor');
8
- const Anchor = ({ id, className, dataQa }) => (react_1.default.createElement("div", { id: id, className: b(null, className), "data-qa": dataQa }));
9
+ exports.qaIdByDefault = 'qa-anchor';
10
+ const Anchor = ({ id, className, dataQa }) => (react_1.default.createElement("div", { id: id, className: b(null, className), "data-qa": dataQa || exports.qaIdByDefault }));
9
11
  exports.default = Anchor;
@@ -7,8 +7,8 @@ const utils_1 = require("../../utils");
7
7
  const Anchor_1 = tslib_1.__importDefault(require("../Anchor/Anchor"));
8
8
  const b = (0, utils_1.block)('block-base');
9
9
  const BlockBase = (props) => {
10
- const { anchor, visible, children, className, resetPaddings } = props;
11
- return (react_1.default.createElement(grid_1.Col, { className: b({ ['reset-paddings']: resetPaddings }, className), visible: visible, reset: true },
10
+ const { anchor, visible, children, className, resetPaddings, qa } = props;
11
+ return (react_1.default.createElement(grid_1.Col, { className: b({ ['reset-paddings']: resetPaddings }, className), visible: visible, reset: true, dataQa: qa },
12
12
  anchor && react_1.default.createElement(Anchor_1.default, { id: anchor.url, className: b('anchor') }),
13
13
  children));
14
14
  };
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const react_1 = tslib_1.__importDefault(require("react"));
5
+ const react_2 = require("@testing-library/react");
6
+ const Anchor_1 = require("../../../components/Anchor/Anchor");
7
+ const grid_1 = require("../../../grid");
8
+ const BlockBase_1 = tslib_1.__importDefault(require("../BlockBase"));
9
+ const qaId = 'block-base-component';
10
+ describe('BlockBase', () => {
11
+ test('render component by default', async () => {
12
+ (0, react_2.render)(react_1.default.createElement(BlockBase_1.default, { qa: qaId }));
13
+ const component = react_2.screen.getByTestId(qaId);
14
+ expect(component).toBeInTheDocument();
15
+ expect(component).toBeVisible();
16
+ expect(component).not.toBeDisabled();
17
+ });
18
+ test('add className', () => {
19
+ const className = 'my-class';
20
+ (0, react_2.render)(react_1.default.createElement(BlockBase_1.default, { qa: qaId, className: className }));
21
+ const component = react_2.screen.getByTestId(qaId);
22
+ expect(component).toHaveClass(className);
23
+ });
24
+ test('should reset paddings', () => {
25
+ (0, react_2.render)(react_1.default.createElement(BlockBase_1.default, { qa: qaId, resetPaddings: true }));
26
+ const component = react_2.screen.getByTestId(qaId);
27
+ expect(component).toHaveClass('pc-block-base_reset-paddings');
28
+ });
29
+ test.each(new Array(...Object.values(grid_1.GridColumnSize)))('render with given "%s" size', (size) => {
30
+ (0, react_2.render)(react_1.default.createElement(BlockBase_1.default, { qa: qaId, visible: size }));
31
+ const component = react_2.screen.getByTestId(qaId);
32
+ expect(component).toHaveClass(`d-${size}-block`);
33
+ });
34
+ test('should have anchor', () => {
35
+ const anchor = {
36
+ text: 'anchor',
37
+ url: 'https://github.com/gravity-ui/',
38
+ };
39
+ (0, react_2.render)(react_1.default.createElement(BlockBase_1.default, { anchor: anchor }));
40
+ const component = react_2.screen.getByTestId(Anchor_1.qaIdByDefault);
41
+ expect(component).toBeInTheDocument();
42
+ expect(component).toHaveAttribute('id', anchor.url);
43
+ });
44
+ });
@@ -1,8 +1,9 @@
1
+ import React from 'react';
1
2
  import { ButtonProps as ButtonParams } from '../../models';
2
3
  export interface ButtonProps extends Omit<ButtonParams, 'url'> {
3
4
  className?: string;
4
5
  url?: string;
5
- onClick?: () => void;
6
+ onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
6
7
  qa?: string;
7
8
  }
8
9
  declare const Button: (props: ButtonProps) => JSX.Element;
@@ -9,6 +9,7 @@ const useMetrika_1 = require("../../hooks/useMetrika");
9
9
  const icons_1 = require("../../icons");
10
10
  const models_1 = require("../../models");
11
11
  const utils_1 = require("../../utils");
12
+ const ImageBase_1 = tslib_1.__importDefault(require("../ImageBase/ImageBase"));
12
13
  const utils_2 = require("./utils");
13
14
  const b = (0, utils_1.block)('button-block');
14
15
  const Button = (props) => {
@@ -17,11 +18,11 @@ const Button = (props) => {
17
18
  const { className, metrikaGoals, pixelEvents, analyticsEvents, size = 'l', theme = 'normal', url, img, onClick: onClickOrigin, text } = props, rest = tslib_1.__rest(props, ["className", "metrikaGoals", "pixelEvents", "analyticsEvents", "size", "theme", "url", "img", "onClick", "text"]);
18
19
  const defaultImgPosition = 'left';
19
20
  const handleAnalytics = (0, hooks_1.useAnalytics)(models_1.DefaultEventNames.Button, url);
20
- const onClick = (0, react_1.useCallback)(() => {
21
+ const onClick = (0, react_1.useCallback)((e) => {
21
22
  handleMetrika({ metrikaGoals, pixelEvents });
22
23
  handleAnalytics(analyticsEvents);
23
24
  if (onClickOrigin) {
24
- onClickOrigin();
25
+ onClickOrigin(e);
25
26
  }
26
27
  }, [handleMetrika, metrikaGoals, pixelEvents, handleAnalytics, analyticsEvents, onClickOrigin]);
27
28
  const buttonImg = img instanceof Object
@@ -36,7 +37,7 @@ const Button = (props) => {
36
37
  return react_1.default.createElement(uikit_1.StoreBadge, { className: buttonClass, platform: platform, lang: lang, url: url });
37
38
  }
38
39
  let icon;
39
- let image = img && react_1.default.createElement("img", { className: b('image'), src: buttonImg.url, alt: buttonImg.alt });
40
+ let image = img && react_1.default.createElement(ImageBase_1.default, { className: b('image'), src: buttonImg.url, alt: buttonImg.alt });
40
41
  if (theme === 'github') {
41
42
  icon = react_1.default.createElement(uikit_1.Icon, { className: b('icon'), data: icons_1.Github, size: 24, qa: utils_2.ICON_QA });
42
43
  image = undefined;
@@ -9,7 +9,7 @@ export interface ButtonTabsProps {
9
9
  className?: string;
10
10
  items: ButtonTabsItemProps[];
11
11
  activeTab?: string | null;
12
- onSelectTab?: (tabId: string | null) => void;
12
+ onSelectTab?: (tabId: string | null, e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => void;
13
13
  tabSize?: ButtonSize;
14
14
  qa?: string;
15
15
  }
@@ -12,11 +12,11 @@ const ButtonTabs = ({ className, items, activeTab, onSelectTab, tabSize = 'l', q
12
12
  }
13
13
  return items[0].id;
14
14
  }, [activeTab, items]);
15
- const handleClick = (0, react_1.useCallback)((tabId) => {
15
+ const handleClick = (0, react_1.useCallback)((tabId) => (e) => {
16
16
  if (onSelectTab) {
17
- onSelectTab(tabId);
17
+ onSelectTab(tabId, e);
18
18
  }
19
19
  }, [onSelectTab]);
20
- return (react_1.default.createElement("div", { className: b(null, className), "data-qa": qa }, items.map(({ id, title }) => (react_1.default.createElement(index_1.Button, { text: title, className: b('item', { active: id === activeTabId }), key: title, size: tabSize, onClick: () => handleClick(id) })))));
20
+ return (react_1.default.createElement("div", { className: b(null, className), "data-qa": qa }, items.map(({ id, title }) => (react_1.default.createElement(index_1.Button, { text: title, className: b('item', { active: id === activeTabId }), key: title, size: tabSize, onClick: handleClick(id) })))));
21
21
  };
22
22
  exports.default = ButtonTabs;
@@ -5,20 +5,21 @@ const react_1 = tslib_1.__importStar(require("react"));
5
5
  const constants_1 = require("../../constants");
6
6
  const projectSettingsContext_1 = require("../../context/projectSettingsContext");
7
7
  const imageCompress_1 = require("../../utils/imageCompress");
8
+ const ImageBase_1 = tslib_1.__importDefault(require("../ImageBase/ImageBase"));
8
9
  const checkWebP = (src) => {
9
10
  return src.endsWith('.webp') ? src : src + '.webp';
10
11
  };
11
12
  const Image = (props) => {
12
13
  const projectSettings = (0, react_1.useContext)(projectSettingsContext_1.ProjectSettingsContext);
13
- const { src, alt, disableCompress, tablet, desktop, mobile, style, className, onClick, containerClassName, } = props;
14
+ const { src: imageSrc, alt, disableCompress, tablet, desktop, mobile, style, className, onClick, containerClassName, } = props;
14
15
  const [imgLoadingError, setImgLoadingError] = (0, react_1.useState)(false);
15
- const imageSrc = src || desktop;
16
- if (!imageSrc) {
16
+ const src = imageSrc || desktop;
17
+ if (!src) {
17
18
  return null;
18
19
  }
19
20
  const disableWebp = projectSettings.disableCompress ||
20
21
  disableCompress ||
21
- !(0, imageCompress_1.isCompressible)(imageSrc) ||
22
+ !(0, imageCompress_1.isCompressible)(src) ||
22
23
  imgLoadingError;
23
24
  return (react_1.default.createElement("picture", { className: containerClassName },
24
25
  mobile && (react_1.default.createElement(react_1.Fragment, null,
@@ -27,7 +28,7 @@ const Image = (props) => {
27
28
  tablet && (react_1.default.createElement(react_1.Fragment, null,
28
29
  !disableWebp && (react_1.default.createElement("source", { srcSet: checkWebP(tablet), type: "image/webp", media: `(max-width: ${constants_1.BREAKPOINTS.md}px)` })),
29
30
  react_1.default.createElement("source", { srcSet: tablet, media: `(max-width: ${constants_1.BREAKPOINTS.md}px)` }))),
30
- imageSrc && !disableWebp && react_1.default.createElement("source", { srcSet: checkWebP(imageSrc), type: "image/webp" }),
31
- react_1.default.createElement("img", { className: className, src: imageSrc, alt: alt, style: style, onClick: onClick, onError: () => setImgLoadingError(true) })));
31
+ src && !disableWebp && react_1.default.createElement("source", { srcSet: checkWebP(src), type: "image/webp" }),
32
+ react_1.default.createElement(ImageBase_1.default, { className: className, alt: alt, src: src, style: style, onClick: onClick, onError: () => setImgLoadingError(true) })));
32
33
  };
33
34
  exports.default = Image;
@@ -0,0 +1,10 @@
1
+ import { CSSProperties, MouseEventHandler } from 'react';
2
+ import { ImageObjectProps } from '../../models';
3
+ export interface ImageBaseProps extends Partial<ImageObjectProps> {
4
+ style?: CSSProperties;
5
+ className?: string;
6
+ onClick?: MouseEventHandler;
7
+ onError?: () => void;
8
+ }
9
+ export declare const ImageBase: (props: ImageBaseProps) => JSX.Element;
10
+ export default ImageBase;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImageBase = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importDefault(require("react"));
6
+ const imageContext_1 = require("../../context/imageContext/imageContext");
7
+ const ImageBase = (props) => {
8
+ const { Image } = react_1.default.useContext(imageContext_1.ImageContext);
9
+ return Image ? react_1.default.createElement(Image, Object.assign({}, props)) : react_1.default.createElement("img", Object.assign({}, props));
10
+ };
11
+ exports.ImageBase = ImageBase;
12
+ exports.default = exports.ImageBase;
@@ -16,6 +16,7 @@ export { default as FullWidthBackground } from './FullWidthBackground/FullWidthB
16
16
  export { default as HeaderBreadcrumbs } from './HeaderBreadcrumbs/HeaderBreadcrumbs';
17
17
  export { default as HeightCalculator } from './HeightCalculator/HeightCalculator';
18
18
  export { default as Image } from './Image/Image';
19
+ export { default as ImageBase } from './ImageBase/ImageBase';
19
20
  export { default as Link } from './Link/Link';
20
21
  export { default as Links } from './Link/Links';
21
22
  export { default as Media } from './Media/Media';
@@ -36,3 +37,4 @@ export { default as HTML } from './HTML/HTML';
36
37
  export { default as MetaInfo } from './MetaInfo/MetaInfo';
37
38
  export { default as FullScreenMedia } from './FullscreenMedia/FullScreenMedia';
38
39
  export type { RouterLinkProps } from './RouterLink/RouterLink';
40
+ export type { ImageBaseProps } from './ImageBase/ImageBase';
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.FullScreenMedia = exports.MetaInfo = exports.HTML = exports.RouterLink = exports.Author = exports.OverflowScroller = exports.Control = exports.YandexForm = exports.YFMWrapper = exports.VideoBlock = exports.UnpublishedLabel = exports.ToggleArrow = exports.Title = exports.Table = exports.ReactPlayer = exports.OutsideClick = exports.Media = exports.Links = exports.Link = exports.Image = exports.HeightCalculator = exports.HeaderBreadcrumbs = exports.FullWidthBackground = exports.FullscreenImage = exports.Foldable = exports.FileLink = exports.ErrorWrapper = exports.CardBase = exports.Button = exports.BlockHeader = exports.BlockBase = exports.BalancedMasonry = exports.BackLink = exports.BackgroundMedia = exports.BackgroundImage = exports.AnimateBlock = exports.Anchor = void 0;
6
+ exports.FullScreenMedia = exports.MetaInfo = exports.HTML = exports.RouterLink = exports.Author = exports.OverflowScroller = exports.Control = exports.YandexForm = exports.YFMWrapper = exports.VideoBlock = exports.UnpublishedLabel = exports.ToggleArrow = exports.Title = exports.Table = exports.ReactPlayer = exports.OutsideClick = exports.Media = exports.Links = exports.Link = exports.ImageBase = exports.Image = exports.HeightCalculator = exports.HeaderBreadcrumbs = exports.FullWidthBackground = exports.FullscreenImage = exports.Foldable = exports.FileLink = exports.ErrorWrapper = exports.CardBase = exports.Button = exports.BlockHeader = exports.BlockBase = exports.BalancedMasonry = exports.BackLink = exports.BackgroundMedia = exports.BackgroundImage = exports.AnimateBlock = exports.Anchor = void 0;
7
7
  var Anchor_1 = require("./Anchor/Anchor");
8
8
  Object.defineProperty(exports, "Anchor", { enumerable: true, get: function () { return __importDefault(Anchor_1).default; } });
9
9
  var AnimateBlock_1 = require("./AnimateBlock/AnimateBlock");
@@ -40,6 +40,8 @@ var HeightCalculator_1 = require("./HeightCalculator/HeightCalculator");
40
40
  Object.defineProperty(exports, "HeightCalculator", { enumerable: true, get: function () { return __importDefault(HeightCalculator_1).default; } });
41
41
  var Image_1 = require("./Image/Image");
42
42
  Object.defineProperty(exports, "Image", { enumerable: true, get: function () { return __importDefault(Image_1).default; } });
43
+ var ImageBase_1 = require("./ImageBase/ImageBase");
44
+ Object.defineProperty(exports, "ImageBase", { enumerable: true, get: function () { return __importDefault(ImageBase_1).default; } });
43
45
  var Link_1 = require("./Link/Link");
44
46
  Object.defineProperty(exports, "Link", { enumerable: true, get: function () { return __importDefault(Link_1).default; } });
45
47
  var Links_1 = require("./Link/Links");
@@ -1,4 +1,5 @@
1
1
  import { AnalyticsContextProps } from '../../context/analyticsContext';
2
+ import { ImageContextProps } from '../../context/imageContext';
2
3
  import { LocaleContextProps } from '../../context/localeContext';
3
4
  import { LocationContextProps } from '../../context/locationContext';
4
5
  import { MapsContextType } from '../../context/mapsContext/mapsContext';
@@ -17,5 +18,6 @@ export interface PageConstructorProviderProps {
17
18
  mapsContext?: MapsContextType;
18
19
  projectSettings?: ProjectSettingsContextProps;
19
20
  analytics?: AnalyticsContextProps;
21
+ image?: ImageContextProps;
20
22
  }
21
23
  export declare const PageConstructorProvider: (props: WithChildren<PageConstructorProviderProps>) => JSX.Element;
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importStar(require("react"));
6
6
  const constants_1 = require("../../components/constants");
7
7
  const analyticsContext_1 = require("../../context/analyticsContext");
8
+ const imageContext_1 = require("../../context/imageContext");
8
9
  const localeContext_1 = require("../../context/localeContext");
9
10
  const locationContext_1 = require("../../context/locationContext");
10
11
  const mapsContext_1 = require("../../context/mapsContext/mapsContext");
@@ -14,12 +15,13 @@ const projectSettingsContext_1 = require("../../context/projectSettingsContext")
14
15
  const ssrContext_1 = require("../../context/ssrContext");
15
16
  const ThemeValueContext_1 = require("../../context/theme/ThemeValueContext");
16
17
  const PageConstructorProvider = (props) => {
17
- const { isMobile, mapsContext = mapsContext_1.initialMapValue, locale = {}, location = {}, metrika = {}, analytics = {}, ssrConfig = {}, projectSettings = {}, theme = constants_1.DEFAULT_THEME, children, } = props;
18
+ const { isMobile, mapsContext = mapsContext_1.initialMapValue, locale = {}, location = {}, metrika = {}, analytics = {}, ssrConfig = {}, projectSettings = {}, theme = constants_1.DEFAULT_THEME, children, image = {}, } = props;
18
19
  /* eslint-disable react/jsx-key */
19
20
  const context = [
20
21
  react_1.default.createElement(ThemeValueContext_1.ThemeValueContext.Provider, { value: { themeValue: theme } }),
21
22
  react_1.default.createElement(projectSettingsContext_1.ProjectSettingsContext.Provider, { value: projectSettings }),
22
23
  react_1.default.createElement(localeContext_1.LocaleContext.Provider, { value: locale }),
24
+ react_1.default.createElement(imageContext_1.ImageContext.Provider, { value: image }),
23
25
  react_1.default.createElement(locationContext_1.LocationContext.Provider, { value: location }),
24
26
  react_1.default.createElement(mobileContext_1.MobileContext.Provider, { value: Boolean(isMobile) }),
25
27
  react_1.default.createElement(mapsContext_1.MapsContext.Provider, { value: mapsContext }),
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { ImageBaseProps } from '../../components';
3
+ export type Image = React.ComponentClass<ImageBaseProps> | React.FC<ImageBaseProps>;
4
+ export type ImageContextProps = {
5
+ Image?: Image;
6
+ };
7
+ export declare const ImageContext: React.Context<ImageContextProps>;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImageContext = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importDefault(require("react"));
6
+ exports.ImageContext = react_1.default.createContext({});
@@ -0,0 +1 @@
1
+ export * from './imageContext';
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./imageContext"), exports);
@@ -39,6 +39,7 @@ export interface BlockBaseProps {
39
39
  anchor?: AnchorProps;
40
40
  visible?: GridColumnSize;
41
41
  resetPaddings?: boolean;
42
+ qa?: string;
42
43
  }
43
44
  export interface LoadableProps {
44
45
  source: string;
@@ -10,7 +10,7 @@ const FaqMicrodataValues = {
10
10
  PageType: 'https://schema.org/FAQPage',
11
11
  QuestionType: 'https://schema.org/Question',
12
12
  QuestionProp: 'mainEntity',
13
- QuestionTextProp: 'name',
13
+ QuestionTextProp: 'text',
14
14
  AnswerType: 'https://schema.org/Answer',
15
15
  AnswerProp: 'acceptedAnswer',
16
16
  AnswerTextProp: 'text',
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { AnimateBlock, FullWidthBackground, HTML, Link, Media } from '../../components';
2
+ import { AnimateBlock, FullWidthBackground, HTML, ImageBase, Link, Media } from '../../components';
3
3
  import { Col, Grid, Row } from '../../grid';
4
4
  import { block } from '../../utils';
5
5
  import './Security.css';
@@ -14,7 +14,7 @@ export const SecurityBlock = (props) => {
14
14
  React.createElement(Col, null,
15
15
  React.createElement("h2", { className: b('title') }, title))),
16
16
  points && (React.createElement(Row, { className: b('points') }, points.map(({ text, link, img }, index) => (React.createElement(Col, { key: index, className: b('point'), sizes: { sm: 4, all: 12 } },
17
- React.createElement("img", { className: b('point-icon'), src: img }),
17
+ React.createElement(ImageBase, { className: b('point-icon'), src: img }),
18
18
  React.createElement(HTML, { className: b('point-text'), block: true }, text),
19
19
  link && (React.createElement(Link, { className: b('point-link'), text: link.text, url: link.url, theme: 'normal', arrow: true }))))))),
20
20
  media && (React.createElement(Row, { className: b('media') },
@@ -46,11 +46,15 @@ export const TabsBlock = ({ items, title, description, animated, tabsColSizes, c
46
46
  imageProps && (React.createElement(Fragment, null,
47
47
  React.createElement(FullScreenImage, Object.assign({}, imageProps, { imageClassName: b('image') })))),
48
48
  (activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.caption) && React.createElement("p", { className: b('caption') }, activeTabData.caption)));
49
+ const onSelectTab = (id, e) => {
50
+ setActiveTab(id);
51
+ e.currentTarget.scrollIntoView({ inline: 'center', behavior: 'smooth', block: 'nearest' });
52
+ };
49
53
  return (React.createElement(AnimateBlock, { className: b(), onScroll: () => setPlay(true), animate: animated },
50
54
  React.createElement(BlockHeader, { title: title, description: description, className: b('block-title', { centered: centered }) }),
51
55
  React.createElement(Row, null,
52
56
  React.createElement(Col, { sizes: tabsColSizes },
53
- React.createElement(ButtonTabs, { items: tabs, onSelectTab: setActiveTab, activeTab: activeTab, className: b('tabs', { centered: centered }) }))),
57
+ React.createElement(ButtonTabs, { items: tabs, onSelectTab: onSelectTab, activeTab: activeTab, className: b('tabs', { centered: centered }) }))),
54
58
  activeTabData && (React.createElement(Row, { className: b('row', { reverse: isReverse }) },
55
59
  mediaContent,
56
60
  textContent))));
@@ -1,5 +1,6 @@
1
1
  import { ClassNameProps } from '../../models';
2
2
  import './Anchor.css';
3
+ export declare const qaIdByDefault = "qa-anchor";
3
4
  export interface AnchorProps extends ClassNameProps {
4
5
  id: string;
5
6
  dataQa?: string;
@@ -3,5 +3,6 @@ import React from 'react';
3
3
  import { block } from '../../utils';
4
4
  import './Anchor.css';
5
5
  const b = block('Anchor');
6
- const Anchor = ({ id, className, dataQa }) => (React.createElement("div", { id: id, className: b(null, className), "data-qa": dataQa }));
6
+ export const qaIdByDefault = 'qa-anchor';
7
+ const Anchor = ({ id, className, dataQa }) => (React.createElement("div", { id: id, className: b(null, className), "data-qa": dataQa || qaIdByDefault }));
7
8
  export default Anchor;
@@ -5,8 +5,8 @@ import Anchor from '../Anchor/Anchor';
5
5
  import './BlockBase.css';
6
6
  const b = block('block-base');
7
7
  const BlockBase = (props) => {
8
- const { anchor, visible, children, className, resetPaddings } = props;
9
- return (React.createElement(Col, { className: b({ ['reset-paddings']: resetPaddings }, className), visible: visible, reset: true },
8
+ const { anchor, visible, children, className, resetPaddings, qa } = props;
9
+ return (React.createElement(Col, { className: b({ ['reset-paddings']: resetPaddings }, className), visible: visible, reset: true, dataQa: qa },
10
10
  anchor && React.createElement(Anchor, { id: anchor.url, className: b('anchor') }),
11
11
  children));
12
12
  };
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { qaIdByDefault } from '../../../components/Anchor/Anchor';
4
+ import { GridColumnSize } from '../../../grid';
5
+ import BlockBase from '../BlockBase';
6
+ const qaId = 'block-base-component';
7
+ describe('BlockBase', () => {
8
+ test('render component by default', async () => {
9
+ render(React.createElement(BlockBase, { qa: qaId }));
10
+ const component = screen.getByTestId(qaId);
11
+ expect(component).toBeInTheDocument();
12
+ expect(component).toBeVisible();
13
+ expect(component).not.toBeDisabled();
14
+ });
15
+ test('add className', () => {
16
+ const className = 'my-class';
17
+ render(React.createElement(BlockBase, { qa: qaId, className: className }));
18
+ const component = screen.getByTestId(qaId);
19
+ expect(component).toHaveClass(className);
20
+ });
21
+ test('should reset paddings', () => {
22
+ render(React.createElement(BlockBase, { qa: qaId, resetPaddings: true }));
23
+ const component = screen.getByTestId(qaId);
24
+ expect(component).toHaveClass('pc-block-base_reset-paddings');
25
+ });
26
+ test.each(new Array(...Object.values(GridColumnSize)))('render with given "%s" size', (size) => {
27
+ render(React.createElement(BlockBase, { qa: qaId, visible: size }));
28
+ const component = screen.getByTestId(qaId);
29
+ expect(component).toHaveClass(`d-${size}-block`);
30
+ });
31
+ test('should have anchor', () => {
32
+ const anchor = {
33
+ text: 'anchor',
34
+ url: 'https://github.com/gravity-ui/',
35
+ };
36
+ render(React.createElement(BlockBase, { anchor: anchor }));
37
+ const component = screen.getByTestId(qaIdByDefault);
38
+ expect(component).toBeInTheDocument();
39
+ expect(component).toHaveAttribute('id', anchor.url);
40
+ });
41
+ });
@@ -1,9 +1,10 @@
1
+ import React from 'react';
1
2
  import { ButtonProps as ButtonParams } from '../../models';
2
3
  import './Button.css';
3
4
  export interface ButtonProps extends Omit<ButtonParams, 'url'> {
4
5
  className?: string;
5
6
  url?: string;
6
- onClick?: () => void;
7
+ onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
7
8
  qa?: string;
8
9
  }
9
10
  declare const Button: (props: ButtonProps) => JSX.Element;
@@ -7,6 +7,7 @@ import { useMetrika } from '../../hooks/useMetrika';
7
7
  import { Github } from '../../icons';
8
8
  import { DefaultEventNames } from '../../models';
9
9
  import { block, setUrlTld } from '../../utils';
10
+ import ImageBase from '../ImageBase/ImageBase';
10
11
  import { ICON_QA, toCommonSize, toCommonView } from './utils';
11
12
  import './Button.css';
12
13
  const b = block('button-block');
@@ -16,11 +17,11 @@ const Button = (props) => {
16
17
  const { className, metrikaGoals, pixelEvents, analyticsEvents, size = 'l', theme = 'normal', url, img, onClick: onClickOrigin, text } = props, rest = __rest(props, ["className", "metrikaGoals", "pixelEvents", "analyticsEvents", "size", "theme", "url", "img", "onClick", "text"]);
17
18
  const defaultImgPosition = 'left';
18
19
  const handleAnalytics = useAnalytics(DefaultEventNames.Button, url);
19
- const onClick = useCallback(() => {
20
+ const onClick = useCallback((e) => {
20
21
  handleMetrika({ metrikaGoals, pixelEvents });
21
22
  handleAnalytics(analyticsEvents);
22
23
  if (onClickOrigin) {
23
- onClickOrigin();
24
+ onClickOrigin(e);
24
25
  }
25
26
  }, [handleMetrika, metrikaGoals, pixelEvents, handleAnalytics, analyticsEvents, onClickOrigin]);
26
27
  const buttonImg = img instanceof Object
@@ -35,7 +36,7 @@ const Button = (props) => {
35
36
  return React.createElement(StoreBadge, { className: buttonClass, platform: platform, lang: lang, url: url });
36
37
  }
37
38
  let icon;
38
- let image = img && React.createElement("img", { className: b('image'), src: buttonImg.url, alt: buttonImg.alt });
39
+ let image = img && React.createElement(ImageBase, { className: b('image'), src: buttonImg.url, alt: buttonImg.alt });
39
40
  if (theme === 'github') {
40
41
  icon = React.createElement(Icon, { className: b('icon'), data: Github, size: 24, qa: ICON_QA });
41
42
  image = undefined;
@@ -10,7 +10,7 @@ export interface ButtonTabsProps {
10
10
  className?: string;
11
11
  items: ButtonTabsItemProps[];
12
12
  activeTab?: string | null;
13
- onSelectTab?: (tabId: string | null) => void;
13
+ onSelectTab?: (tabId: string | null, e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => void;
14
14
  tabSize?: ButtonSize;
15
15
  qa?: string;
16
16
  }
@@ -10,11 +10,11 @@ const ButtonTabs = ({ className, items, activeTab, onSelectTab, tabSize = 'l', q
10
10
  }
11
11
  return items[0].id;
12
12
  }, [activeTab, items]);
13
- const handleClick = useCallback((tabId) => {
13
+ const handleClick = useCallback((tabId) => (e) => {
14
14
  if (onSelectTab) {
15
- onSelectTab(tabId);
15
+ onSelectTab(tabId, e);
16
16
  }
17
17
  }, [onSelectTab]);
18
- return (React.createElement("div", { className: b(null, className), "data-qa": qa }, items.map(({ id, title }) => (React.createElement(Button, { text: title, className: b('item', { active: id === activeTabId }), key: title, size: tabSize, onClick: () => handleClick(id) })))));
18
+ return (React.createElement("div", { className: b(null, className), "data-qa": qa }, items.map(({ id, title }) => (React.createElement(Button, { text: title, className: b('item', { active: id === activeTabId }), key: title, size: tabSize, onClick: handleClick(id) })))));
19
19
  };
20
20
  export default ButtonTabs;
@@ -2,20 +2,21 @@ import React, { Fragment, useContext, useState } from 'react';
2
2
  import { BREAKPOINTS } from '../../constants';
3
3
  import { ProjectSettingsContext } from '../../context/projectSettingsContext';
4
4
  import { isCompressible } from '../../utils/imageCompress';
5
+ import ImageBase from '../ImageBase/ImageBase';
5
6
  const checkWebP = (src) => {
6
7
  return src.endsWith('.webp') ? src : src + '.webp';
7
8
  };
8
9
  const Image = (props) => {
9
10
  const projectSettings = useContext(ProjectSettingsContext);
10
- const { src, alt, disableCompress, tablet, desktop, mobile, style, className, onClick, containerClassName, } = props;
11
+ const { src: imageSrc, alt, disableCompress, tablet, desktop, mobile, style, className, onClick, containerClassName, } = props;
11
12
  const [imgLoadingError, setImgLoadingError] = useState(false);
12
- const imageSrc = src || desktop;
13
- if (!imageSrc) {
13
+ const src = imageSrc || desktop;
14
+ if (!src) {
14
15
  return null;
15
16
  }
16
17
  const disableWebp = projectSettings.disableCompress ||
17
18
  disableCompress ||
18
- !isCompressible(imageSrc) ||
19
+ !isCompressible(src) ||
19
20
  imgLoadingError;
20
21
  return (React.createElement("picture", { className: containerClassName },
21
22
  mobile && (React.createElement(Fragment, null,
@@ -24,7 +25,7 @@ const Image = (props) => {
24
25
  tablet && (React.createElement(Fragment, null,
25
26
  !disableWebp && (React.createElement("source", { srcSet: checkWebP(tablet), type: "image/webp", media: `(max-width: ${BREAKPOINTS.md}px)` })),
26
27
  React.createElement("source", { srcSet: tablet, media: `(max-width: ${BREAKPOINTS.md}px)` }))),
27
- imageSrc && !disableWebp && React.createElement("source", { srcSet: checkWebP(imageSrc), type: "image/webp" }),
28
- React.createElement("img", { className: className, src: imageSrc, alt: alt, style: style, onClick: onClick, onError: () => setImgLoadingError(true) })));
28
+ src && !disableWebp && React.createElement("source", { srcSet: checkWebP(src), type: "image/webp" }),
29
+ React.createElement(ImageBase, { className: className, alt: alt, src: src, style: style, onClick: onClick, onError: () => setImgLoadingError(true) })));
29
30
  };
30
31
  export default Image;
@@ -0,0 +1,10 @@
1
+ import { CSSProperties, MouseEventHandler } from 'react';
2
+ import { ImageObjectProps } from '../../models';
3
+ export interface ImageBaseProps extends Partial<ImageObjectProps> {
4
+ style?: CSSProperties;
5
+ className?: string;
6
+ onClick?: MouseEventHandler;
7
+ onError?: () => void;
8
+ }
9
+ export declare const ImageBase: (props: ImageBaseProps) => JSX.Element;
10
+ export default ImageBase;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { ImageContext } from '../../context/imageContext/imageContext';
3
+ export const ImageBase = (props) => {
4
+ const { Image } = React.useContext(ImageContext);
5
+ return Image ? React.createElement(Image, Object.assign({}, props)) : React.createElement("img", Object.assign({}, props));
6
+ };
7
+ export default ImageBase;
@@ -16,6 +16,7 @@ export { default as FullWidthBackground } from './FullWidthBackground/FullWidthB
16
16
  export { default as HeaderBreadcrumbs } from './HeaderBreadcrumbs/HeaderBreadcrumbs';
17
17
  export { default as HeightCalculator } from './HeightCalculator/HeightCalculator';
18
18
  export { default as Image } from './Image/Image';
19
+ export { default as ImageBase } from './ImageBase/ImageBase';
19
20
  export { default as Link } from './Link/Link';
20
21
  export { default as Links } from './Link/Links';
21
22
  export { default as Media } from './Media/Media';
@@ -36,3 +37,4 @@ export { default as HTML } from './HTML/HTML';
36
37
  export { default as MetaInfo } from './MetaInfo/MetaInfo';
37
38
  export { default as FullScreenMedia } from './FullscreenMedia/FullScreenMedia';
38
39
  export type { RouterLinkProps } from './RouterLink/RouterLink';
40
+ export type { ImageBaseProps } from './ImageBase/ImageBase';
@@ -16,6 +16,7 @@ export { default as FullWidthBackground } from './FullWidthBackground/FullWidthB
16
16
  export { default as HeaderBreadcrumbs } from './HeaderBreadcrumbs/HeaderBreadcrumbs';
17
17
  export { default as HeightCalculator } from './HeightCalculator/HeightCalculator';
18
18
  export { default as Image } from './Image/Image';
19
+ export { default as ImageBase } from './ImageBase/ImageBase';
19
20
  export { default as Link } from './Link/Link';
20
21
  export { default as Links } from './Link/Links';
21
22
  export { default as Media } from './Media/Media';
@@ -1,4 +1,5 @@
1
1
  import { AnalyticsContextProps } from '../../context/analyticsContext';
2
+ import { ImageContextProps } from '../../context/imageContext';
2
3
  import { LocaleContextProps } from '../../context/localeContext';
3
4
  import { LocationContextProps } from '../../context/locationContext';
4
5
  import { MapsContextType } from '../../context/mapsContext/mapsContext';
@@ -17,5 +18,6 @@ export interface PageConstructorProviderProps {
17
18
  mapsContext?: MapsContextType;
18
19
  projectSettings?: ProjectSettingsContextProps;
19
20
  analytics?: AnalyticsContextProps;
21
+ image?: ImageContextProps;
20
22
  }
21
23
  export declare const PageConstructorProvider: (props: WithChildren<PageConstructorProviderProps>) => JSX.Element;
@@ -1,6 +1,7 @@
1
1
  import React, { Fragment } from 'react';
2
2
  import { DEFAULT_THEME } from '../../components/constants';
3
3
  import { AnalyticsContext } from '../../context/analyticsContext';
4
+ import { ImageContext } from '../../context/imageContext';
4
5
  import { LocaleContext } from '../../context/localeContext';
5
6
  import { LocationContext } from '../../context/locationContext';
6
7
  import { MapsContext, initialMapValue } from '../../context/mapsContext/mapsContext';
@@ -10,12 +11,13 @@ import { ProjectSettingsContext, } from '../../context/projectSettingsContext';
10
11
  import { SSRContext } from '../../context/ssrContext';
11
12
  import { ThemeValueContext } from '../../context/theme/ThemeValueContext';
12
13
  export const PageConstructorProvider = (props) => {
13
- const { isMobile, mapsContext = initialMapValue, locale = {}, location = {}, metrika = {}, analytics = {}, ssrConfig = {}, projectSettings = {}, theme = DEFAULT_THEME, children, } = props;
14
+ const { isMobile, mapsContext = initialMapValue, locale = {}, location = {}, metrika = {}, analytics = {}, ssrConfig = {}, projectSettings = {}, theme = DEFAULT_THEME, children, image = {}, } = props;
14
15
  /* eslint-disable react/jsx-key */
15
16
  const context = [
16
17
  React.createElement(ThemeValueContext.Provider, { value: { themeValue: theme } }),
17
18
  React.createElement(ProjectSettingsContext.Provider, { value: projectSettings }),
18
19
  React.createElement(LocaleContext.Provider, { value: locale }),
20
+ React.createElement(ImageContext.Provider, { value: image }),
19
21
  React.createElement(LocationContext.Provider, { value: location }),
20
22
  React.createElement(MobileContext.Provider, { value: Boolean(isMobile) }),
21
23
  React.createElement(MapsContext.Provider, { value: mapsContext }),
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { ImageBaseProps } from '../../components';
3
+ export type Image = React.ComponentClass<ImageBaseProps> | React.FC<ImageBaseProps>;
4
+ export type ImageContextProps = {
5
+ Image?: Image;
6
+ };
7
+ export declare const ImageContext: React.Context<ImageContextProps>;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export const ImageContext = React.createContext({});
@@ -0,0 +1 @@
1
+ export * from './imageContext';
@@ -0,0 +1 @@
1
+ export * from './imageContext';
@@ -39,6 +39,7 @@ export interface BlockBaseProps {
39
39
  anchor?: AnchorProps;
40
40
  visible?: GridColumnSize;
41
41
  resetPaddings?: boolean;
42
+ qa?: string;
42
43
  }
43
44
  export interface LoadableProps {
44
45
  source: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/page-constructor",
3
- "version": "2.9.0",
3
+ "version": "2.11.0",
4
4
  "description": "Gravity UI Page Constructor",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,6 +39,7 @@ export interface BlockBaseProps {
39
39
  anchor?: AnchorProps;
40
40
  visible?: GridColumnSize;
41
41
  resetPaddings?: boolean;
42
+ qa?: string;
42
43
  }
43
44
  export interface LoadableProps {
44
45
  source: string;