@gravity-ui/page-constructor 4.5.2 → 4.6.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 (54) hide show
  1. package/build/cjs/blocks/Slider/Arrow/Arrow.js +2 -1
  2. package/build/cjs/blocks/Slider/Slider.css +4 -1
  3. package/build/cjs/blocks/Slider/Slider.js +32 -6
  4. package/build/cjs/blocks/Slider/i18n/en.json +4 -0
  5. package/build/cjs/blocks/Slider/i18n/index.d.ts +2 -0
  6. package/build/cjs/blocks/Slider/i18n/index.js +8 -0
  7. package/build/cjs/blocks/Slider/i18n/ru.json +4 -0
  8. package/build/cjs/components/HTML/HTML.d.ts +3 -1
  9. package/build/cjs/components/HTML/HTML.js +2 -1
  10. package/build/cjs/components/Link/Link.d.ts +2 -1
  11. package/build/cjs/components/Link/Link.js +4 -2
  12. package/build/cjs/components/YFMWrapper/YFMWrapper.d.ts +3 -2
  13. package/build/cjs/components/YFMWrapper/YFMWrapper.js +1 -1
  14. package/build/cjs/constructor-items.d.ts +1 -1
  15. package/build/cjs/editor/components/AddBlock/AddBlock.css +1 -1
  16. package/build/cjs/editor/components/EditBlock/EditBlock.css +1 -0
  17. package/build/cjs/editor/components/Layout/Layout.css +2 -1
  18. package/build/cjs/editor/containers/Form/Form.css +14 -35
  19. package/build/cjs/editor/styles/root.css +2 -1
  20. package/build/cjs/sub-blocks/Content/Content.d.ts +3 -1
  21. package/build/cjs/sub-blocks/Content/Content.js +7 -5
  22. package/build/cjs/sub-blocks/Content/ContentList/ContentList.d.ts +2 -1
  23. package/build/cjs/sub-blocks/Content/ContentList/ContentList.js +7 -5
  24. package/build/cjs/utils/blocks.d.ts +1 -0
  25. package/build/cjs/utils/blocks.js +14 -1
  26. package/build/esm/blocks/Slider/Arrow/Arrow.js +2 -1
  27. package/build/esm/blocks/Slider/Slider.css +4 -1
  28. package/build/esm/blocks/Slider/Slider.js +33 -7
  29. package/build/esm/blocks/Slider/i18n/en.json +4 -0
  30. package/build/esm/blocks/Slider/i18n/index.d.ts +2 -0
  31. package/build/esm/blocks/Slider/i18n/index.js +5 -0
  32. package/build/esm/blocks/Slider/i18n/ru.json +4 -0
  33. package/build/esm/components/HTML/HTML.d.ts +3 -1
  34. package/build/esm/components/HTML/HTML.js +2 -1
  35. package/build/esm/components/Link/Link.d.ts +2 -1
  36. package/build/esm/components/Link/Link.js +4 -2
  37. package/build/esm/components/YFMWrapper/YFMWrapper.d.ts +3 -2
  38. package/build/esm/components/YFMWrapper/YFMWrapper.js +1 -1
  39. package/build/esm/constructor-items.d.ts +1 -1
  40. package/build/esm/editor/components/AddBlock/AddBlock.css +1 -1
  41. package/build/esm/editor/components/EditBlock/EditBlock.css +1 -0
  42. package/build/esm/editor/components/Layout/Layout.css +2 -1
  43. package/build/esm/editor/containers/Form/Form.css +14 -35
  44. package/build/esm/editor/styles/root.css +2 -1
  45. package/build/esm/sub-blocks/Content/Content.d.ts +3 -1
  46. package/build/esm/sub-blocks/Content/Content.js +7 -5
  47. package/build/esm/sub-blocks/Content/ContentList/ContentList.d.ts +2 -1
  48. package/build/esm/sub-blocks/Content/ContentList/ContentList.js +7 -5
  49. package/build/esm/utils/blocks.d.ts +1 -0
  50. package/build/esm/utils/blocks.js +12 -0
  51. package/package.json +2 -2
  52. package/server/utils/blocks.d.ts +1 -0
  53. package/server/utils/blocks.js +14 -1
  54. package/widget/index.js +1 -1
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { WithChildren } from '../../models';
3
+ import { QAProps } from '../../models/common';
3
4
  export interface HTMLProps {
4
5
  children?: string;
5
6
  block?: boolean;
@@ -7,12 +8,13 @@ export interface HTMLProps {
7
8
  itemProp?: string;
8
9
  id?: string;
9
10
  }
10
- declare const HTML: ({ children, block, className, itemProp, id }: WithChildren<HTMLProps>) => React.DetailedReactHTMLElement<{
11
+ declare const HTML: ({ children, block, className, itemProp, id, qa, }: WithChildren<HTMLProps & QAProps>) => React.DetailedReactHTMLElement<{
11
12
  dangerouslySetInnerHTML: {
12
13
  __html: string | (string & React.ReactElement<any, string | React.JSXElementConstructor<any>>) | (string & React.ReactFragment) | (string & React.ReactPortal);
13
14
  };
14
15
  className: string | undefined;
15
16
  itemProp: string | undefined;
16
17
  id: string | undefined;
18
+ 'data-qa': string | undefined;
17
19
  }, HTMLElement> | null;
18
20
  export default HTML;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { hasBlockTag } from '../../utils';
3
- const HTML = ({ children, block = false, className, itemProp, id }) => {
3
+ const HTML = ({ children, block = false, className, itemProp, id, qa, }) => {
4
4
  if (!children) {
5
5
  return null;
6
6
  }
@@ -9,6 +9,7 @@ const HTML = ({ children, block = false, className, itemProp, id }) => {
9
9
  className,
10
10
  itemProp,
11
11
  id,
12
+ 'data-qa': qa,
12
13
  });
13
14
  };
14
15
  export default HTML;
@@ -1,5 +1,6 @@
1
1
  import { ClassNameProps, LinkProps, Tabbable, WithChildren } from '../../models';
2
+ import { QAProps } from '../../models/common';
2
3
  import './Link.css';
3
- export type LinkFullProps = LinkProps & ClassNameProps & Tabbable;
4
+ export type LinkFullProps = LinkProps & ClassNameProps & Tabbable & QAProps;
4
5
  declare const LinkBlock: (props: WithChildren<LinkFullProps>) => JSX.Element;
5
6
  export default LinkBlock;
@@ -7,6 +7,7 @@ import { useMetrika } from '../../hooks/useMetrika';
7
7
  import { Chevron } from '../../icons';
8
8
  import { DefaultEventNames, } from '../../models';
9
9
  import { block, getLinkProps, setUrlTld } from '../../utils';
10
+ import { getQaAttrubutes } from '../../utils/index';
10
11
  import BackLink from '../BackLink/BackLink';
11
12
  import FileLink from '../FileLink/FileLink';
12
13
  import './Link.css';
@@ -25,7 +26,8 @@ function getArrowSize(size) {
25
26
  }
26
27
  }
27
28
  const LinkBlock = (props) => {
28
- const { text, url, arrow, metrikaGoals, pixelEvents, analyticsEvents, theme = 'file-link', colorTheme = 'light', textSize = 'm', className, target, children, tabIndex, } = props;
29
+ const { text, url, arrow, metrikaGoals, pixelEvents, analyticsEvents, theme = 'file-link', colorTheme = 'light', textSize = 'm', className, target, children, tabIndex, qa, } = props;
30
+ const qaAttributes = getQaAttrubutes(qa, ['normal']);
29
31
  const handleMetrika = useMetrika();
30
32
  const handleAnalytics = useAnalytics(DefaultEventNames.Link, url);
31
33
  const { hostname } = useContext(LocationContext);
@@ -46,7 +48,7 @@ const LinkBlock = (props) => {
46
48
  case 'normal': {
47
49
  const linkProps = getLinkProps(url, hostname, target);
48
50
  const content = children || text;
49
- return (React.createElement("a", Object.assign({ className: b('link', { theme: colorTheme, 'has-arrow': arrow }), href: href, onClick: onClick, tabIndex: tabIndex }, linkProps), arrow ? (React.createElement(Fragment, null,
51
+ return (React.createElement("a", Object.assign({ className: b('link', { theme: colorTheme, 'has-arrow': arrow }), href: href, onClick: onClick, tabIndex: tabIndex }, linkProps, { "data-qa": qaAttributes.normal }), arrow ? (React.createElement(Fragment, null,
50
52
  React.createElement("span", { className: b('content') }, content),
51
53
  WORD_JOINER_SYM,
52
54
  React.createElement(Icon, { className: b('arrow'), data: Chevron, size: getArrowSize(textSize) }))) : (content)));
@@ -1,9 +1,10 @@
1
1
  import { ClassNameProps, Modifiers } from '../../models';
2
- export interface YFMWrapperProps extends ClassNameProps {
2
+ import { QAProps } from '../../models/common';
3
+ export interface YFMWrapperProps extends ClassNameProps, QAProps {
3
4
  content: string;
4
5
  modifiers?: Modifiers;
5
6
  itemProp?: string;
6
7
  id?: string;
7
8
  }
8
- declare const YFMWrapper: ({ content, modifiers, className, itemProp, id }: YFMWrapperProps) => JSX.Element;
9
+ declare const YFMWrapper: ({ content, modifiers, className, itemProp, id, qa }: YFMWrapperProps) => JSX.Element;
9
10
  export default YFMWrapper;
@@ -5,5 +5,5 @@ import block from 'bem-cn-lite';
5
5
  import toSnakeCase from 'snakecase-keys';
6
6
  import { HTML } from '../../components';
7
7
  const yfm = block('yfm');
8
- const YFMWrapper = ({ content, modifiers, className, itemProp, id }) => (React.createElement(HTML, { className: yfm(modifiers ? toSnakeCase(modifiers) : {}, className), itemProp: itemProp, id: id }, content));
8
+ const YFMWrapper = ({ content, modifiers, className, itemProp, id, qa }) => (React.createElement(HTML, { className: yfm(modifiers ? toSnakeCase(modifiers) : {}, className), itemProp: itemProp, id: id, qa: qa }, content));
9
9
  export default YFMWrapper;
@@ -26,7 +26,7 @@ export declare const subBlockMap: {
26
26
  "layout-item": ({ content: { links, ...content }, metaInfo, media, border, fullscreen, className, }: import("./models").LayoutItemProps) => JSX.Element;
27
27
  "background-card": (props: import("./models").BackgroundCardProps) => JSX.Element;
28
28
  "basic-card": (props: import("./models").BasicCardProps) => JSX.Element;
29
- content: (props: import("./models").ContentBlockProps & import("./models").ClassNameProps) => JSX.Element;
29
+ content: (props: import("./sub-blocks/Content/Content").ContentProps) => JSX.Element;
30
30
  quote: (props: import("./models").QuoteProps) => JSX.Element;
31
31
  };
32
32
  export declare const navItemMap: {
@@ -23,7 +23,7 @@ unpredictable css rules order in build */
23
23
  transition: transform 0.2s;
24
24
  width: 76px;
25
25
  height: 40px;
26
- color: var(--g-color-text-primary);
26
+ color: var(--pc-editor-control-icon-color);
27
27
  background-color: var(--pc-editor-base-color);
28
28
  border-radius: 8px;
29
29
  }
@@ -45,6 +45,7 @@ unpredictable css rules order in build */
45
45
  width: 48px;
46
46
  height: 32px;
47
47
  border-radius: 8px;
48
+ color: var(--pc-editor-control-icon-color);
48
49
  background-color: var(--pc-editor-control-color);
49
50
  }
50
51
  .pc-edit-block__control:hover {
@@ -4,7 +4,8 @@ body {
4
4
  --pc-editor-header-height: 48px;
5
5
  --pc-editor-divider-width: 12px;
6
6
  --pc-editor-base-color: var(--g-color-base-brand);
7
- --pc-editor-control-color: var(--g-color-private-yellow-400-solid);
7
+ --pc-editor-control-color: var(--g-color-base-brand);
8
+ --pc-editor-control-icon-color: var(--g-color-text-dark-primary);
8
9
  --pc-editor-left-column-width: calc(400px + var(--pc-editor-divider-width));
9
10
  }
10
11
 
@@ -1,46 +1,26 @@
1
1
  /* use this for style redefinitions to awoid problems with
2
2
  unpredictable css rules order in build */
3
3
  .pc-editor-form {
4
- --top-level-font-size: var(--g-text-display-2-font-size);
5
- --top-level-line-height: var(--g-text-display-2-line-height);
6
- --block-level-complex-propery-font-size: var(--g-text-body-3-font-size);
7
- --block-level-complex-property-line-height: var(--g-text-body-3-line-height);
8
- --complex-property-font-size: var(--g-text-body-2-font-size);
9
- --complex-property-line-height: var(--g-text-body-2-line-height);
10
- --property-font-size: var(--g-text-body-1-font-size);
11
- --property-line-height: var(--g-text-body-1-line-height);
4
+ --block-name-font-size: var(--g-text-display-1-font-size);
5
+ --block-name-line-height: var(--g-text-display-1-line-height);
6
+ --property-name-font-size: var(--g-text-body-1-font-size);
7
+ --property-name-line-height: var(--g-text-body-1-line-height);
12
8
  --input-min-width: 150px;
13
9
  --property-title-width: 96px;
14
10
  --button-height: 48px;
15
- --icon-size: 32px;
16
- --icon-margin: 42px;
11
+ --icon-size: 28px;
12
+ --icon-margin: 8px;
17
13
  --property-font-weight: 500;
18
- --header-text-size: var(--top-level-font-size);
19
- --header-line-height: var(--top-level-line-height);
20
- --text-size: var(--top-level-font-size);
21
- --line-height: var(--top-level-line-height);
14
+ --header-text-size: var(--block-name-font-size);
15
+ --header-line-height: var(--block-name-line-height);
22
16
  }
23
17
  .pc-editor-form .df-use-search .df-use-search {
24
- --button-height: 32px;
25
- --icon-size: 20px;
26
- --icon-margin: 30px;
27
- --header-text-size: var(--block-level-complex-propery-font-size);
28
- --header-line-height: var(--block-level-complex-property-line-height);
29
- --text-size: var(--property-font-size);
30
- --line-height: var(--property-line-height);
31
- --property-font-weight: 400;
32
- }
33
- .pc-editor-form .df-use-search .df-use-search .df-use-search {
34
18
  --button-height: 28px;
35
19
  --icon-size: 16px;
36
- --icon-margin: 25px;
20
+ --icon-margin: 0px;
21
+ --header-text-size: var(--property-name-font-size);
22
+ --header-line-height: var(--property-name-line-height);
37
23
  --property-font-weight: 400;
38
- --header-text-size: var(--complex-property-font-size);
39
- --header-line-height: var(--complex-property-line-height);
40
- --text-size: var(--property-font-size);
41
- --line-height: var(--property-line-height);
42
- --oneof-text-size: var(--complex-propery-font-size);
43
- --oneof-line-height: var(--complex-property-line-height);
44
24
  }
45
25
  .pc-editor-form .df-row {
46
26
  width: inherit;
@@ -49,8 +29,6 @@ unpredictable css rules order in build */
49
29
  width: var(--property-title-width);
50
30
  }
51
31
  .pc-editor-form .df-row__title {
52
- font-size: var(--text-size);
53
- line-height: var(--line-height);
54
32
  font-weight: var(--property-font-weight);
55
33
  white-space: nowrap;
56
34
  }
@@ -58,12 +36,13 @@ unpredictable css rules order in build */
58
36
  min-width: var(--input-min-width);
59
37
  min-height: var(--input-min-width);
60
38
  }
61
- .pc-editor-form .df-simple-vertical-accordeon__header .yc-button {
39
+ .pc-editor-form .df-simple-vertical-accordeon__header .yc-button,
40
+ .pc-editor-form .df-simple-vertical-accordeon__title {
62
41
  font-size: var(--header-text-size);
63
42
  line-height: var(--header-line-height);
64
43
  }
65
44
  .pc-editor-form .df-simple-vertical-accordeon__header .yc-button {
66
- --g-button-height: var(--button-height);
45
+ --yc-button-height: var(--button-height);
67
46
  display: flex;
68
47
  justify-content: center;
69
48
  align-items: center;
@@ -2,6 +2,7 @@ body {
2
2
  --pc-editor-header-height: 48px;
3
3
  --pc-editor-divider-width: 12px;
4
4
  --pc-editor-base-color: var(--g-color-base-brand);
5
- --pc-editor-control-color: var(--g-color-private-yellow-400-solid);
5
+ --pc-editor-control-color: var(--g-color-base-brand);
6
+ --pc-editor-control-icon-color: var(--g-color-text-dark-primary);
6
7
  --pc-editor-left-column-width: calc(400px + var(--pc-editor-divider-width));
7
8
  }
@@ -1,4 +1,6 @@
1
1
  import { ClassNameProps, ContentBlockProps } from '../../models';
2
+ import { QAProps } from '../../models/common';
2
3
  import './Content.css';
3
- declare const Content: (props: ContentBlockProps & ClassNameProps) => JSX.Element;
4
+ export type ContentProps = ContentBlockProps & ClassNameProps & QAProps;
5
+ declare const Content: (props: ContentProps) => JSX.Element;
4
6
  export default Content;
@@ -3,6 +3,7 @@ import { Button, Title, YFMWrapper } from '../../components';
3
3
  import LinkBlock from '../../components/Link/Link';
4
4
  import { Col } from '../../grid';
5
5
  import { block } from '../../utils';
6
+ import { getQaAttrubutes } from '../../utils/blocks';
6
7
  import ContentList from './ContentList/ContentList';
7
8
  import './Content.css';
8
9
  const b = block('content');
@@ -34,23 +35,24 @@ function getButtonSize(size) {
34
35
  }
35
36
  }
36
37
  const Content = (props) => {
37
- const { title, text, additionalInfo, size = 'l', links, buttons, colSizes = { all: 12, sm: 8 }, centered, theme, className, list, } = props;
38
+ const { title, text, additionalInfo, size = 'l', links, buttons, colSizes = { all: 12, sm: 8 }, centered, theme, className, list, qa, } = props;
39
+ const qaAttributes = getQaAttrubutes(qa, ['links', 'link', 'buttons', 'button', 'list']);
38
40
  const titleProps = !title || typeof title === 'string'
39
41
  ? { text: title, textSize: getTextSize(size) }
40
42
  : title;
41
43
  const hasTitle = Boolean(title);
42
- return (React.createElement(Col, { className: b({ size, centered, theme }, className), reset: true, sizes: colSizes },
44
+ return (React.createElement(Col, { className: b({ size, centered, theme }, className), reset: true, sizes: colSizes, qa: qaAttributes.container },
43
45
  title && React.createElement(Title, { className: b('title'), title: titleProps, colSizes: { all: 12 } }),
44
46
  text && (React.createElement("div", { className: b('text', { ['without-title']: !hasTitle }) },
45
47
  React.createElement(YFMWrapper, { content: text, modifiers: { constructor: true, [`constructor-size-${size}`]: true } }))),
46
- (list === null || list === void 0 ? void 0 : list.length) ? React.createElement(ContentList, { list: list, size: size }) : null,
48
+ (list === null || list === void 0 ? void 0 : list.length) ? React.createElement(ContentList, { list: list, size: size, qa: qaAttributes.list }) : null,
47
49
  additionalInfo && (React.createElement("div", { className: b('notice') },
48
50
  React.createElement(YFMWrapper, { content: additionalInfo, modifiers: {
49
51
  constructor: true,
50
52
  'constructor-notice': true,
51
53
  [`constructor-size-${size}`]: true,
52
54
  } }))),
53
- links && (React.createElement("div", { className: b('links') }, links.map((link) => (React.createElement(LinkBlock, Object.assign({ className: b('link') }, link, { textSize: getLinkSize(size), key: link.url })))))),
54
- buttons && (React.createElement("div", { className: b('buttons') }, buttons.map((item) => (React.createElement(Button, Object.assign({ className: b('button') }, item, { key: item.url, size: getButtonSize(size) }))))))));
55
+ links && (React.createElement("div", { className: b('links'), "data-qa": qaAttributes.links }, links.map((link) => (React.createElement(LinkBlock, Object.assign({ className: b('link') }, link, { textSize: getLinkSize(size), key: link.url, qa: qaAttributes.link })))))),
56
+ buttons && (React.createElement("div", { className: b('buttons'), "data-qa": qaAttributes.buttons }, buttons.map((item) => (React.createElement(Button, Object.assign({ className: b('button') }, item, { key: item.url, size: getButtonSize(size), qa: qaAttributes.button }))))))));
55
57
  };
56
58
  export default Content;
@@ -1,8 +1,9 @@
1
1
  import { ContentItemProps, ContentSize } from '../../../models';
2
+ import { QAProps } from '../../../models/common';
2
3
  import './ContentList.css';
3
4
  interface ContentListProps {
4
5
  list: ContentItemProps[];
5
6
  size: ContentSize;
6
7
  }
7
- declare const ContentList: ({ list, size }: ContentListProps) => JSX.Element;
8
+ declare const ContentList: ({ list, size, qa }: ContentListProps & QAProps) => JSX.Element;
8
9
  export default ContentList;
@@ -5,6 +5,7 @@ import Image from '../../../components/Image/Image';
5
5
  import { getMediaImage } from '../../../components/Media/Image/utils';
6
6
  import { useTheme } from '../../../context/theme';
7
7
  import { block, getThemedValue } from '../../../utils';
8
+ import { getQaAttrubutes } from '../../../utils/blocks';
8
9
  import './ContentList.css';
9
10
  const b = block('content-list');
10
11
  function getHeadingLevel(size) {
@@ -16,18 +17,19 @@ function getHeadingLevel(size) {
16
17
  return 'h3';
17
18
  }
18
19
  }
19
- const ContentList = ({ list, size }) => {
20
+ const ContentList = ({ list, size, qa }) => {
20
21
  const theme = useTheme();
21
- return (React.createElement("div", { className: b({ size }) }, list === null || list === void 0 ? void 0 : list.map((item) => {
22
+ const qaAttributes = getQaAttrubutes(qa, ['image', 'title', 'text']);
23
+ return (React.createElement("div", { className: b({ size }), "data-qa": qa }, list === null || list === void 0 ? void 0 : list.map((item) => {
22
24
  const { icon, title, text } = item;
23
25
  const iconThemed = getThemedValue(icon, theme);
24
26
  const iconData = getMediaImage(iconThemed);
25
27
  return (React.createElement("div", { className: b('item'), key: uuidv4() },
26
- React.createElement(Image, Object.assign({}, iconData, { className: b('icon') })),
28
+ React.createElement(Image, Object.assign({}, iconData, { className: b('icon'), qa: qaAttributes.image })),
27
29
  React.createElement("div", null,
28
30
  title &&
29
- React.createElement(getHeadingLevel(size), { className: b('title') }, title),
30
- text && (React.createElement(YFMWrapper, { className: b('text'), content: text, modifiers: { constructor: true } })))));
31
+ React.createElement(getHeadingLevel(size), { className: b('title'), 'data-qa': qaAttributes.title }, title),
32
+ text && (React.createElement(YFMWrapper, { className: b('text'), content: text, modifiers: { constructor: true }, qa: qaAttributes.text })))));
31
33
  })));
32
34
  };
33
35
  export default ContentList;
@@ -7,3 +7,4 @@ export declare const getCustomTypes: (types: (keyof CustomConfig)[], customBlock
7
7
  export declare const getOrderedBlocks: (blocks: ConstructorBlock[], headerBlockTypes?: string[]) => ConstructorBlock[];
8
8
  export declare const getHeaderBlock: (blocks: ConstructorBlock[], headerBlockTypes?: string[]) => ConstructorBlock | undefined;
9
9
  export declare const getShareLink: (url: string, type: PCShareSocialNetwork, title?: string, text?: string) => string | undefined;
10
+ export declare const getQaAttrubutes: (qa?: string, customKeys?: Array<string>) => Record<string, string>;
@@ -1,3 +1,4 @@
1
+ import { camelCase } from 'lodash';
1
2
  import { PCShareSocialNetwork } from '../models';
2
3
  const BLOCK_ELEMENTS = [
3
4
  'div',
@@ -36,6 +37,7 @@ const BLOCK_ELEMENTS = [
36
37
  'td',
37
38
  ];
38
39
  const BLOCK_ELEMENTS_REGEX = `<(${BLOCK_ELEMENTS.join('|')})[^>]*>`;
40
+ const QA_ATTRIBUTES_KEYS = ['container', 'content', 'wrapper', 'image', 'button'];
39
41
  export function getHeaderTag(size) {
40
42
  switch (size) {
41
43
  case 'l':
@@ -109,3 +111,13 @@ export const getShareLink = (url, type, title, text) => {
109
111
  return undefined;
110
112
  }
111
113
  };
114
+ export const getQaAttrubutes = (qa, customKeys = []) => {
115
+ const attributes = {};
116
+ if (qa) {
117
+ const keys = QA_ATTRIBUTES_KEYS.concat(customKeys);
118
+ keys.forEach((key) => {
119
+ attributes[camelCase(key)] = `${qa}-${key}`;
120
+ });
121
+ }
122
+ return attributes;
123
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/page-constructor",
3
- "version": "4.5.2",
3
+ "version": "4.6.0",
4
4
  "description": "Gravity UI Page Constructor",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -81,7 +81,7 @@
81
81
  },
82
82
  "dependencies": {
83
83
  "@gravity-ui/components": "^2.0.0",
84
- "@gravity-ui/dynamic-forms": "^2.0.0",
84
+ "@gravity-ui/dynamic-forms": "^2.3.0",
85
85
  "@gravity-ui/i18n": "^1.0.0",
86
86
  "ajv": "^8.12.0",
87
87
  "bem-cn-lite": "^4.0.0",
@@ -7,3 +7,4 @@ export declare const getCustomTypes: (types: (keyof CustomConfig)[], customBlock
7
7
  export declare const getOrderedBlocks: (blocks: ConstructorBlock[], headerBlockTypes?: string[]) => ConstructorBlock[];
8
8
  export declare const getHeaderBlock: (blocks: ConstructorBlock[], headerBlockTypes?: string[]) => ConstructorBlock | undefined;
9
9
  export declare const getShareLink: (url: string, type: PCShareSocialNetwork, title?: string, text?: string) => string | undefined;
10
+ export declare const getQaAttrubutes: (qa?: string, customKeys?: Array<string>) => Record<string, string>;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getShareLink = exports.getHeaderBlock = exports.getOrderedBlocks = exports.getCustomTypes = exports.getCustomItems = exports.getBlockKey = exports.hasBlockTag = exports.getHeaderTag = void 0;
3
+ exports.getQaAttrubutes = exports.getShareLink = exports.getHeaderBlock = exports.getOrderedBlocks = exports.getCustomTypes = exports.getCustomItems = exports.getBlockKey = exports.hasBlockTag = exports.getHeaderTag = void 0;
4
+ const lodash_1 = require("lodash");
4
5
  const models_1 = require("../models");
5
6
  const BLOCK_ELEMENTS = [
6
7
  'div',
@@ -39,6 +40,7 @@ const BLOCK_ELEMENTS = [
39
40
  'td',
40
41
  ];
41
42
  const BLOCK_ELEMENTS_REGEX = `<(${BLOCK_ELEMENTS.join('|')})[^>]*>`;
43
+ const QA_ATTRIBUTES_KEYS = ['container', 'content', 'wrapper', 'image', 'button'];
42
44
  function getHeaderTag(size) {
43
45
  switch (size) {
44
46
  case 'l':
@@ -120,3 +122,14 @@ const getShareLink = (url, type, title, text) => {
120
122
  }
121
123
  };
122
124
  exports.getShareLink = getShareLink;
125
+ const getQaAttrubutes = (qa, customKeys = []) => {
126
+ const attributes = {};
127
+ if (qa) {
128
+ const keys = QA_ATTRIBUTES_KEYS.concat(customKeys);
129
+ keys.forEach((key) => {
130
+ attributes[(0, lodash_1.camelCase)(key)] = `${qa}-${key}`;
131
+ });
132
+ }
133
+ return attributes;
134
+ };
135
+ exports.getQaAttrubutes = getQaAttrubutes;