@gravity-ui/dynamic-forms 1.11.2 → 2.1.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/build/cjs/lib/kit/components/Card/Card.css +4 -0
  2. package/build/cjs/lib/kit/components/Card/Card.js +9 -3
  3. package/build/cjs/lib/kit/components/Inputs/MonacoInput/MonacoHeader.css +1 -1
  4. package/build/cjs/lib/kit/components/Inputs/MultiOneOf/MultiOneOf.css +14 -0
  5. package/build/cjs/lib/kit/components/Inputs/MultiOneOf/MultiOneOf.js +73 -0
  6. package/build/cjs/lib/kit/components/Inputs/MultiOneOf/index.js +4 -0
  7. package/build/cjs/lib/kit/components/Inputs/TextArea/TextArea.js +1 -1
  8. package/build/cjs/lib/kit/components/Inputs/index.js +3 -2
  9. package/build/cjs/lib/kit/components/Layouts/Row/Row.js +4 -3
  10. package/build/cjs/lib/kit/components/Layouts/Section/Section.css +4 -0
  11. package/build/cjs/lib/kit/components/Layouts/Section/Section.js +9 -3
  12. package/build/cjs/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.css +1 -0
  13. package/build/cjs/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.js +12 -4
  14. package/build/cjs/lib/kit/components/Views/MultiOneOfView/MultiOneOfView.css +21 -0
  15. package/build/cjs/lib/kit/components/Views/MultiOneOfView/MultiOneOfView.js +43 -0
  16. package/build/cjs/lib/kit/components/Views/MultiOneOfView/index.js +4 -0
  17. package/build/cjs/lib/kit/components/Views/index.js +1 -0
  18. package/build/cjs/lib/kit/constants/common.js +5 -0
  19. package/build/cjs/lib/kit/constants/config.js +8 -0
  20. package/build/cjs/lib/kit/constants/index.js +1 -0
  21. package/build/esm/lib/core/types/specs.d.ts +1 -0
  22. package/build/esm/lib/kit/components/Card/Card.css +4 -0
  23. package/build/esm/lib/kit/components/Card/Card.js +10 -4
  24. package/build/esm/lib/kit/components/Inputs/MonacoInput/MonacoHeader.css +1 -1
  25. package/build/esm/lib/kit/components/Inputs/MultiOneOf/MultiOneOf.css +14 -0
  26. package/build/esm/lib/kit/components/Inputs/MultiOneOf/MultiOneOf.d.ts +8 -0
  27. package/build/esm/lib/kit/components/Inputs/MultiOneOf/MultiOneOf.js +68 -0
  28. package/build/esm/lib/kit/components/Inputs/MultiOneOf/index.d.ts +1 -0
  29. package/build/esm/lib/kit/components/Inputs/MultiOneOf/index.js +1 -0
  30. package/build/esm/lib/kit/components/Inputs/TextArea/TextArea.js +2 -2
  31. package/build/esm/lib/kit/components/Inputs/index.d.ts +3 -2
  32. package/build/esm/lib/kit/components/Inputs/index.js +3 -2
  33. package/build/esm/lib/kit/components/Layouts/Row/Row.js +2 -1
  34. package/build/esm/lib/kit/components/Layouts/Section/Section.css +4 -0
  35. package/build/esm/lib/kit/components/Layouts/Section/Section.js +10 -4
  36. package/build/esm/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.css +1 -0
  37. package/build/esm/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.d.ts +1 -0
  38. package/build/esm/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.js +12 -4
  39. package/build/esm/lib/kit/components/Views/MultiOneOfView/MultiOneOfView.css +21 -0
  40. package/build/esm/lib/kit/components/Views/MultiOneOfView/MultiOneOfView.d.ts +8 -0
  41. package/build/esm/lib/kit/components/Views/MultiOneOfView/MultiOneOfView.js +38 -0
  42. package/build/esm/lib/kit/components/Views/MultiOneOfView/index.d.ts +1 -0
  43. package/build/esm/lib/kit/components/Views/MultiOneOfView/index.js +1 -0
  44. package/build/esm/lib/kit/components/Views/index.d.ts +1 -0
  45. package/build/esm/lib/kit/components/Views/index.js +1 -0
  46. package/build/esm/lib/kit/constants/common.d.ts +3 -0
  47. package/build/esm/lib/kit/constants/common.js +2 -0
  48. package/build/esm/lib/kit/constants/config.js +9 -1
  49. package/build/esm/lib/kit/constants/index.d.ts +1 -0
  50. package/build/esm/lib/kit/constants/index.js +1 -0
  51. package/package.json +5 -4
@@ -51,6 +51,10 @@
51
51
  font-size: var(--yc-text-subheader-2-font-size);
52
52
  font-weight: var(--yc-text-subheader-font-weight);
53
53
  line-height: var(--yc-text-subheader-2-line-height);
54
+ white-space: nowrap;
55
+ overflow: hidden;
56
+ text-overflow: ellipsis;
57
+ max-width: 533px;
54
58
  }
55
59
  .df-card__note {
56
60
  margin-left: 5px;
@@ -3,13 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Card = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importDefault(require("react"));
6
+ const components_1 = require("@gravity-ui/components");
6
7
  const icons_1 = require("@gravity-ui/icons");
7
8
  const uikit_1 = require("@gravity-ui/uikit");
8
9
  const lodash_1 = tslib_1.__importDefault(require("lodash"));
10
+ const common_1 = require("../../constants/common");
9
11
  const utils_1 = require("../../utils");
10
12
  const b = (0, utils_1.block)('card');
11
13
  const Card = ({ name, title: propsTitle, description, actions, open: propsOpen, onToggle, alwaysOpen, disableHeaderToggle, checkEmptyBody, children, }) => {
14
+ var _a;
12
15
  const containerRef = react_1.default.useRef(null);
16
+ const titleRef = react_1.default.useRef(null);
13
17
  const bodyRef = react_1.default.useRef(null);
14
18
  const [open, setOpen] = react_1.default.useState(alwaysOpen || propsOpen || false);
15
19
  const emptyBody = Boolean(bodyRef.current && !bodyRef.current.childElementCount);
@@ -29,15 +33,17 @@ const Card = ({ name, title: propsTitle, description, actions, open: propsOpen,
29
33
  return;
30
34
  }, [disableHeaderToggle, handleToggle]);
31
35
  const preventEvent = react_1.default.useCallback((e) => e.stopPropagation(), []);
36
+ const titlePopoverDisabled = (((_a = titleRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0) <= common_1.COMMON_TITLE_MAX_WIDTH;
32
37
  const title = react_1.default.useMemo(() => {
33
38
  if (lodash_1.default.isString(propsTitle)) {
34
39
  return (react_1.default.createElement(react_1.default.Fragment, null,
35
- react_1.default.createElement("div", { className: b('title') }, propsTitle),
40
+ react_1.default.createElement(uikit_1.Popover, { content: propsTitle, disabled: titlePopoverDisabled, placement: common_1.COMMON_POPOVER_PLACEMENT },
41
+ react_1.default.createElement("div", { ref: titleRef, className: b('title') }, propsTitle)),
36
42
  description ? (react_1.default.createElement("div", { className: b('note') },
37
- react_1.default.createElement(uikit_1.HelpPopover, { htmlContent: description, placement: ['bottom', 'top'] }))) : null));
43
+ react_1.default.createElement(components_1.HelpPopover, { htmlContent: description, placement: common_1.COMMON_POPOVER_PLACEMENT }))) : null));
38
44
  }
39
45
  return propsTitle;
40
- }, [propsTitle, description]);
46
+ }, [propsTitle, titlePopoverDisabled, description]);
41
47
  react_1.default.useEffect(() => {
42
48
  if (!alwaysOpen && propsOpen !== undefined && propsOpen !== open) {
43
49
  setOpen(propsOpen);
@@ -4,7 +4,7 @@
4
4
  justify-content: space-between;
5
5
  padding: 15px;
6
6
  align-items: center;
7
- background-color: var(--yc-color-private-black-50-solid);
7
+ background-color: var(--yc-color-base-float-hover);
8
8
  }
9
9
  .df-monaco-header_card {
10
10
  border-bottom: 1px solid var(--yc-color-line-generic);
@@ -0,0 +1,14 @@
1
+ .df-multi-oneof__select {
2
+ max-width: 305px;
3
+ }
4
+ .df-multi-oneof__content_flat > .df-group-indent {
5
+ margin: 0;
6
+ border-left: none;
7
+ padding: 0;
8
+ }
9
+ .df-multi-oneof__content_flat > .df-group-indent > .df-use-search {
10
+ margin-top: 15px;
11
+ }
12
+ .df-multi-oneof__content_flat > .df-group-indent > .df-use-search:empty {
13
+ display: none;
14
+ }
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MultiOneOfFlat = exports.MultiOneOf = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importDefault(require("react"));
6
+ const uikit_1 = require("@gravity-ui/uikit");
7
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
8
+ const core_1 = require("../../../../core");
9
+ const utils_1 = require("../../../utils");
10
+ const GroupIndent_1 = require("../../GroupIndent");
11
+ const b = (0, utils_1.block)('multi-oneof');
12
+ const MultiOneOf = (props) => {
13
+ const { name, input, spec, Layout, withoutIndent } = props;
14
+ const { value, onBlur, onChange, onFocus, parentOnUnmount } = input;
15
+ const [valueSelect, setValueSelect] = react_1.default.useState(() => (value ? Object.keys(value) : []));
16
+ const handleOpenChange = react_1.default.useCallback((open) => {
17
+ if (open) {
18
+ onFocus();
19
+ }
20
+ else {
21
+ onBlur();
22
+ }
23
+ }, [onFocus, onBlur]);
24
+ const parentOnChange = react_1.default.useCallback((childName, childValue, childErrors) => {
25
+ onChange((currentValue) => lodash_1.default.set(Object.assign({}, currentValue), childName.split(`${name}.`).join(''), childValue), childErrors);
26
+ }, [name, onChange]);
27
+ const specProperties = react_1.default.useMemo(() => (lodash_1.default.isObjectLike(spec.properties) ? spec.properties : {}), [spec.properties]);
28
+ const options = react_1.default.useMemo(() => (spec.viewSpec.order || Object.keys(specProperties)).map((value) => {
29
+ var _a, _b;
30
+ const title = ((_a = spec.description) === null || _a === void 0 ? void 0 : _a[value]) ||
31
+ ((_b = specProperties[value]) === null || _b === void 0 ? void 0 : _b.viewSpec.layoutTitle) ||
32
+ value ||
33
+ '';
34
+ return {
35
+ value,
36
+ title,
37
+ content: title,
38
+ };
39
+ }), [spec.description, spec.viewSpec.order, specProperties]);
40
+ const filterable = react_1.default.useMemo(() => (options.length || 0) > 9, [options.length]);
41
+ const selectInput = react_1.default.useMemo(() => {
42
+ const select = (react_1.default.createElement(uikit_1.Select, { width: "max", value: valueSelect, options: options, onUpdate: setValueSelect, onOpenChange: handleOpenChange, disabled: spec.viewSpec.disabled, placeholder: spec.viewSpec.placeholder, filterable: filterable, multiple: true, className: b('select'), qa: name }));
43
+ if (Layout) {
44
+ return react_1.default.createElement(Layout, Object.assign({}, props), select);
45
+ }
46
+ return react_1.default.createElement(react_1.default.Fragment, null, select);
47
+ }, [
48
+ Layout,
49
+ filterable,
50
+ handleOpenChange,
51
+ name,
52
+ options,
53
+ props,
54
+ spec.viewSpec.disabled,
55
+ spec.viewSpec.placeholder,
56
+ valueSelect,
57
+ ]);
58
+ if (!options) {
59
+ return null;
60
+ }
61
+ return (react_1.default.createElement(react_1.default.Fragment, null,
62
+ selectInput,
63
+ react_1.default.createElement("div", { className: b('content', {
64
+ flat: withoutIndent,
65
+ }) },
66
+ react_1.default.createElement(GroupIndent_1.GroupIndent, null, valueSelect.map((property) => {
67
+ var _a;
68
+ return (react_1.default.createElement(react_1.default.Fragment, { key: property }, specProperties && specProperties[property] ? (react_1.default.createElement(core_1.Controller, { name: `${name}.${property}`, spec: specProperties[property], parentOnUnmount: parentOnUnmount, parentOnChange: parentOnChange, value: (_a = input.value) === null || _a === void 0 ? void 0 : _a[property] })) : null));
69
+ })))));
70
+ };
71
+ exports.MultiOneOf = MultiOneOf;
72
+ const MultiOneOfFlat = (props) => (react_1.default.createElement(exports.MultiOneOf, Object.assign({}, props, { withoutIndent: true })));
73
+ exports.MultiOneOfFlat = MultiOneOfFlat;
@@ -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("./MultiOneOf"), exports);
@@ -6,6 +6,6 @@ const react_1 = tslib_1.__importDefault(require("react"));
6
6
  const uikit_1 = require("@gravity-ui/uikit");
7
7
  const TextArea = ({ name, input, spec }) => {
8
8
  const { value, onBlur, onChange, onFocus } = input;
9
- return (react_1.default.createElement(uikit_1.TextInput, { value: value, onBlur: onBlur, onFocus: onFocus, onUpdate: onChange, maxRows: 20, minRows: 8, hasClear: true, disabled: spec.viewSpec.disabled, multiline: true, placeholder: spec.viewSpec.placeholder, qa: name }));
9
+ return (react_1.default.createElement(uikit_1.TextArea, { value: value, onBlur: onBlur, onFocus: onFocus, onUpdate: onChange, maxRows: 20, minRows: 8, hasClear: true, disabled: spec.viewSpec.disabled, placeholder: spec.viewSpec.placeholder, qa: name }));
10
10
  };
11
11
  exports.TextArea = TextArea;
@@ -5,7 +5,10 @@ tslib_1.__exportStar(require("./ArrayBase"), exports);
5
5
  tslib_1.__exportStar(require("./CardOneOf"), exports);
6
6
  tslib_1.__exportStar(require("./Checkbox"), exports);
7
7
  tslib_1.__exportStar(require("./FileInput"), exports);
8
+ tslib_1.__exportStar(require("./MonacoInput"), exports);
9
+ tslib_1.__exportStar(require("./MultiOneOf"), exports);
8
10
  tslib_1.__exportStar(require("./MultiSelect"), exports);
11
+ tslib_1.__exportStar(require("./NumberWithScale"), exports);
9
12
  tslib_1.__exportStar(require("./ObjectBase"), exports);
10
13
  tslib_1.__exportStar(require("./ObjectValueInput"), exports);
11
14
  tslib_1.__exportStar(require("./OneOf"), exports);
@@ -18,5 +21,3 @@ tslib_1.__exportStar(require("./Text"), exports);
18
21
  tslib_1.__exportStar(require("./TextArea"), exports);
19
22
  tslib_1.__exportStar(require("./TextContent"), exports);
20
23
  tslib_1.__exportStar(require("./TextLink"), exports);
21
- tslib_1.__exportStar(require("./NumberWithScale"), exports);
22
- tslib_1.__exportStar(require("./MonacoInput"), exports);
@@ -3,10 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RowVerbose = exports.Row = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importDefault(require("react"));
6
+ const components_1 = require("@gravity-ui/components");
6
7
  const icons_1 = require("@gravity-ui/icons");
7
8
  const uikit_1 = require("@gravity-ui/uikit");
8
9
  const core_1 = require("../../../../core");
9
- const components_1 = require("../../../components");
10
+ const components_2 = require("../../../components");
10
11
  const utils_1 = require("../../../utils");
11
12
  const b = (0, utils_1.block)('row');
12
13
  const RowBase = ({ name, spec, input, meta, verboseDescription, children, }) => {
@@ -17,10 +18,10 @@ const RowBase = ({ name, spec, input, meta, verboseDescription, children, }) =>
17
18
  react_1.default.createElement("span", { className: b('title', { required: spec.required }) }, spec.viewSpec.layoutTitle),
18
19
  !verboseDescription && spec.viewSpec.layoutDescription ? (react_1.default.createElement("span", { className: b('note') },
19
20
  react_1.default.createElement("span", { className: b('note-inner') },
20
- react_1.default.createElement(uikit_1.HelpPopover, { htmlContent: spec.viewSpec.layoutDescription, placement: ['bottom', 'top'] })))) : null)),
21
+ react_1.default.createElement(components_1.HelpPopover, { htmlContent: spec.viewSpec.layoutDescription, placement: ['bottom', 'top'] })))) : null)),
21
22
  react_1.default.createElement("div", { className: b('right') },
22
23
  react_1.default.createElement("div", { className: b('right-inner') },
23
- react_1.default.createElement(components_1.ErrorWrapper, { name: name, meta: meta, withoutChildErrorStyles: (0, core_1.isArraySpec)(spec) || (0, core_1.isObjectSpec)(spec) }, children),
24
+ react_1.default.createElement(components_2.ErrorWrapper, { name: name, meta: meta, withoutChildErrorStyles: (0, core_1.isArraySpec)(spec) || (0, core_1.isObjectSpec)(spec) }, children),
24
25
  arrayItem ? (react_1.default.createElement(uikit_1.Button, { view: "flat", className: b('remove-button'), onClick: input.onDrop, qa: `${name}-remove-item` },
25
26
  react_1.default.createElement(uikit_1.Icon, { data: icons_1.Xmark, size: 16 }))) : null),
26
27
  verboseDescription && spec.viewSpec.layoutDescription ? (react_1.default.createElement("div", { className: b('description'), dangerouslySetInnerHTML: { __html: spec.viewSpec.layoutDescription } })) : null)));
@@ -12,8 +12,12 @@
12
12
  align-items: center;
13
13
  }
14
14
  .df-section__title {
15
+ max-width: 533px;
15
16
  font-weight: 500;
16
17
  margin: 0;
18
+ white-space: nowrap;
19
+ overflow: hidden;
20
+ text-overflow: ellipsis;
17
21
  }
18
22
  .df-section__title_size_s {
19
23
  font-size: 13px;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Group2 = exports.Group = exports.SectionWithSubtitle2 = exports.SectionWithSubtitle = exports.Section2 = exports.Section = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importDefault(require("react"));
6
+ const components_1 = require("@gravity-ui/components");
6
7
  const uikit_1 = require("@gravity-ui/uikit");
7
8
  const __1 = require("../../");
8
9
  const __2 = require("../../../");
@@ -10,9 +11,11 @@ const core_1 = require("../../../../core");
10
11
  const utils_1 = require("../../../utils");
11
12
  const b = (0, utils_1.block)('section');
12
13
  const SectionBase = (_a) => {
14
+ var _b;
13
15
  var { name, spec, titleSize, withIndent, ignoreDescription, descriptionAsSubtitle, children } = _a, restProps = tslib_1.__rest(_a, ["name", "spec", "titleSize", "withIndent", "ignoreDescription", "descriptionAsSubtitle", "children"]);
14
16
  const meta = restProps.meta;
15
17
  const arrOrObjFlag = (0, core_1.isArraySpec)(spec) || (0, core_1.isObjectSpec)(spec);
18
+ const titleRef = react_1.default.useRef(null);
16
19
  let content = children;
17
20
  if (meta) {
18
21
  content = (react_1.default.createElement(__2.ErrorWrapper, { name: name, meta: meta, withoutChildErrorStyles: arrOrObjFlag }, content));
@@ -29,14 +32,17 @@ const SectionBase = (_a) => {
29
32
  }
30
33
  else {
31
34
  description = (react_1.default.createElement("div", { className: b('note') },
32
- react_1.default.createElement(uikit_1.HelpPopover, { htmlContent: spec.viewSpec.layoutDescription, placement: ['bottom', 'top'] })));
35
+ react_1.default.createElement(components_1.HelpPopover, { htmlContent: spec.viewSpec.layoutDescription, placement: ['bottom', 'top'] })));
33
36
  }
34
37
  }
38
+ const layoutTitle = spec.viewSpec.layoutTitle;
39
+ const layoutTitlePopoverDisabled = (((_b = titleRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth) || 0) <= __2.COMMON_TITLE_MAX_WIDTH;
35
40
  return (react_1.default.createElement("section", { className: b() },
36
- spec.viewSpec.layoutTitle ? (react_1.default.createElement("div", { className: b('header', {
41
+ layoutTitle ? (react_1.default.createElement("div", { className: b('header', {
37
42
  'with-popover': !descriptionAsSubtitle,
38
43
  }) },
39
- react_1.default.createElement("h2", { className: b('title', { size: titleSize }) }, spec.viewSpec.layoutTitle),
44
+ react_1.default.createElement(uikit_1.Popover, { content: layoutTitle, placement: __2.COMMON_POPOVER_PLACEMENT, disabled: layoutTitlePopoverDisabled },
45
+ react_1.default.createElement("h2", { className: b('title', { size: titleSize }), ref: titleRef }, layoutTitle)),
40
46
  description)) : null,
41
47
  react_1.default.createElement("div", { className: b('content') }, content)));
42
48
  };
@@ -15,6 +15,7 @@
15
15
  }
16
16
  .df-simple-vertical-accordeon__header-inner {
17
17
  margin-left: -13px;
18
+ max-width: 533px;
18
19
  }
19
20
  .df-simple-vertical-accordeon__title {
20
21
  font-weight: 500;
@@ -3,14 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SimpleVerticalAccordeon = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importDefault(require("react"));
6
+ const components_1 = require("@gravity-ui/components");
6
7
  const icons_1 = require("@gravity-ui/icons");
7
8
  const uikit_1 = require("@gravity-ui/uikit");
9
+ const common_1 = require("../../constants/common");
8
10
  const utils_1 = require("../../utils");
9
11
  const b = (0, utils_1.block)('simple-vertical-accordeon');
12
+ const TITLE_TEXT_MAX_WIDTH = 485; /** 533px (COMMON_TITLE_MAX_WIDTH) - 48px of padding */
10
13
  class SimpleVerticalAccordeon extends react_1.default.Component {
11
14
  constructor(props) {
12
15
  super(props);
13
16
  this.componentRef = react_1.default.createRef();
17
+ this.titleRef = react_1.default.createRef();
14
18
  this.checkVisibility = () => {
15
19
  if (this.props.viewLayout) {
16
20
  if (this.componentRef.current &&
@@ -47,17 +51,21 @@ class SimpleVerticalAccordeon extends react_1.default.Component {
47
51
  this.checkVisibility();
48
52
  }
49
53
  render() {
54
+ var _a;
50
55
  const { titleSize, children, headerActionsTemplate, className, contentClassName, buttonClassName, hideInsteadOfDestroy, withBranchView, viewLayout, name, } = this.props;
51
56
  const { open, hidden, isFirstRender } = this.state;
52
57
  const content = hideInsteadOfDestroy ? (react_1.default.createElement("div", { ref: this.componentRef, className: b('body', { hidden: !open }) }, children)) : (open && (react_1.default.createElement("div", { ref: this.componentRef, className: b('body', contentClassName) }, children)));
53
58
  if (viewLayout && !isFirstRender && hidden) {
54
59
  return null;
55
60
  }
61
+ const title = this.getTitle();
62
+ const titlePopoverDisabled = (((_a = this.titleRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0) <= TITLE_TEXT_MAX_WIDTH;
56
63
  return (Boolean(react_1.default.Children.count(children)) && (react_1.default.createElement("div", { className: b({ branch: withBranchView, view: viewLayout }, className) },
57
64
  react_1.default.createElement("div", { className: b('header') },
58
- react_1.default.createElement(uikit_1.Button, { view: "flat", className: b('header-inner', buttonClassName), onClick: this.handleClick, qa: `${name}-accordeon-toggler` },
59
- react_1.default.createElement("b", { className: b('title', { size: titleSize }) }, this.getTitle()),
60
- react_1.default.createElement(uikit_1.Icon, { data: icons_1.ChevronDown, className: b('chevron', { open }), size: 16 })),
65
+ react_1.default.createElement(uikit_1.Popover, { content: title, disabled: titlePopoverDisabled, placement: common_1.COMMON_POPOVER_PLACEMENT },
66
+ react_1.default.createElement(uikit_1.Button, { view: "flat", className: b('header-inner', buttonClassName), onClick: this.handleClick, qa: `${name}-accordeon-toggler`, width: "auto" },
67
+ react_1.default.createElement("b", { ref: this.titleRef, className: b('title', { size: titleSize }) }, title),
68
+ react_1.default.createElement(uikit_1.Icon, { data: icons_1.ChevronDown, className: b('chevron', { open }), size: 16 }))),
61
69
  this.getTooltip(),
62
70
  headerActionsTemplate ? headerActionsTemplate : null),
63
71
  content)));
@@ -72,7 +80,7 @@ class SimpleVerticalAccordeon extends react_1.default.Component {
72
80
  getTooltip() {
73
81
  const { note } = this.props;
74
82
  return note ? (react_1.default.createElement("span", { className: b('tooltip') },
75
- react_1.default.createElement(uikit_1.HelpPopover, { htmlContent: note, placement: ['bottom', 'top'] }))) : null;
83
+ react_1.default.createElement(components_1.HelpPopover, { htmlContent: note, placement: ['bottom', 'top'] }))) : null;
76
84
  }
77
85
  }
78
86
  exports.SimpleVerticalAccordeon = SimpleVerticalAccordeon;
@@ -0,0 +1,21 @@
1
+ .df-multi-oneof-view__tooltip {
2
+ overflow-wrap: break-word;
3
+ }
4
+ .df-multi-oneof-view__tooltip-container {
5
+ max-width: 100%;
6
+ overflow: hidden;
7
+ text-overflow: ellipsis;
8
+ display: block;
9
+ margin-bottom: 6px;
10
+ }
11
+ .df-multi-oneof-view__tooltip-container:last-child {
12
+ margin-bottom: 0;
13
+ }
14
+ .df-multi-oneof-view__content_multiple-values > .df-group-indent {
15
+ padding-top: 0px;
16
+ }
17
+ .df-multi-oneof-view__content_flat > .df-group-indent {
18
+ margin: 0 0 20px;
19
+ border-left: none;
20
+ padding: 0;
21
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MultiOneOfFlatView = exports.MultiOneOfView = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importDefault(require("react"));
6
+ const uikit_1 = require("@gravity-ui/uikit");
7
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
8
+ const core_1 = require("../../../../core");
9
+ const utils_1 = require("../../../utils");
10
+ const GroupIndent_1 = require("../../GroupIndent");
11
+ const b = (0, utils_1.block)('multi-oneof-view');
12
+ const MultiOneOfView = (props) => {
13
+ const { name, value, Layout, spec, withoutIndent } = props;
14
+ const specProperties = react_1.default.useMemo(() => (lodash_1.default.isObjectLike(spec.properties) ? spec.properties : {}), [spec.properties]);
15
+ const values = react_1.default.useMemo(() => Object.keys(value || []), [value]);
16
+ const items = react_1.default.useMemo(() => values.map((value) => {
17
+ var _a, _b;
18
+ const title = ((_a = spec.description) === null || _a === void 0 ? void 0 : _a[value]) ||
19
+ ((_b = specProperties[value]) === null || _b === void 0 ? void 0 : _b.viewSpec.layoutTitle) ||
20
+ value ||
21
+ '';
22
+ return title;
23
+ }), [spec.description, specProperties, values]);
24
+ const selectView = react_1.default.useMemo(() => {
25
+ const selectView = (react_1.default.createElement(react_1.default.Fragment, null, items.map((item) => {
26
+ return (react_1.default.createElement(uikit_1.Popover, { placement: ['bottom', 'top'], key: item, content: item, className: b('tooltip-container'), contentClassName: b('tooltip'), disabled: item.length < 51 }, item));
27
+ })));
28
+ if (Layout) {
29
+ return (react_1.default.createElement(Layout, Object.assign({}, props, { value: values }), selectView));
30
+ }
31
+ return react_1.default.createElement(react_1.default.Fragment, null, selectView);
32
+ }, [Layout, items, props, values]);
33
+ if (values.length === 0) {
34
+ return null;
35
+ }
36
+ return (react_1.default.createElement(react_1.default.Fragment, null,
37
+ selectView,
38
+ react_1.default.createElement("div", { className: b('content', { flat: withoutIndent, 'multiple-values': items.length > 1 }) },
39
+ react_1.default.createElement(GroupIndent_1.GroupIndent, null, values.map((value) => (react_1.default.createElement(react_1.default.Fragment, { key: value }, specProperties && specProperties[value] ? (react_1.default.createElement(core_1.ViewController, { name: `${name}.${value}`, spec: specProperties[value] })) : null)))))));
40
+ };
41
+ exports.MultiOneOfView = MultiOneOfView;
42
+ const MultiOneOfFlatView = (props) => (react_1.default.createElement(exports.MultiOneOfView, Object.assign({}, props, { withoutIndent: true })));
43
+ exports.MultiOneOfFlatView = MultiOneOfFlatView;
@@ -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("./MultiOneOfView"), exports);
@@ -6,6 +6,7 @@ tslib_1.__exportStar(require("./BaseView"), exports);
6
6
  tslib_1.__exportStar(require("./CardOneOfView"), exports);
7
7
  tslib_1.__exportStar(require("./FileInputView"), exports);
8
8
  tslib_1.__exportStar(require("./MonacoInputView"), exports);
9
+ tslib_1.__exportStar(require("./MultiOneOfView"), exports);
9
10
  tslib_1.__exportStar(require("./MultiSelectView"), exports);
10
11
  tslib_1.__exportStar(require("./NumberWithScaleView"), exports);
11
12
  tslib_1.__exportStar(require("./ObjectBaseView"), exports);
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.COMMON_TITLE_MAX_WIDTH = exports.COMMON_POPOVER_PLACEMENT = void 0;
4
+ exports.COMMON_POPOVER_PLACEMENT = ['bottom', 'top'];
5
+ exports.COMMON_TITLE_MAX_WIDTH = 533;
@@ -64,6 +64,8 @@ exports.dynamicConfig = {
64
64
  base: { Component: components_1.ObjectBase, independent: true },
65
65
  text_link: { Component: components_1.TextLink, independent: true },
66
66
  object_value: { Component: components_1.ObjectValueInput, independent: true },
67
+ multi_oneof: { Component: components_1.MultiOneOf, independent: true },
68
+ multi_oneof_flat: { Component: components_1.MultiOneOfFlat, independent: true },
67
69
  },
68
70
  layouts: {
69
71
  row: components_1.Row,
@@ -163,6 +165,8 @@ exports.dynamicCardConfig = {
163
165
  base: { Component: components_1.ObjectBase, independent: true },
164
166
  text_link: { Component: components_1.TextLink, independent: true },
165
167
  object_value: { Component: components_1.ObjectValueInput, independent: true },
168
+ multi_oneof: { Component: components_1.MultiOneOf, independent: true },
169
+ multi_oneof_flat: { Component: components_1.MultiOneOfFlat, independent: true },
166
170
  },
167
171
  layouts: {
168
172
  row: components_1.Row2,
@@ -255,6 +259,8 @@ exports.dynamicViewConfig = {
255
259
  base: { Component: components_1.ObjectBaseView, independent: true },
256
260
  text_link: { Component: components_1.TextLinkView, independent: true },
257
261
  object_value: { Component: components_1.ObjectValueInputView, independent: true },
262
+ multi_oneof: { Component: components_1.MultiOneOfView, independent: true },
263
+ multi_oneof_flat: { Component: components_1.MultiOneOfFlatView, independent: true },
258
264
  },
259
265
  layouts: {
260
266
  row: components_1.ViewRow,
@@ -338,6 +344,8 @@ exports.dynamicViewCardConfig = {
338
344
  base: { Component: components_1.ObjectBaseView, independent: true },
339
345
  text_link: { Component: components_1.TextLinkView, independent: true },
340
346
  object_value: { Component: components_1.ObjectValueInputView, independent: true },
347
+ multi_oneof: { Component: components_1.MultiOneOfView, independent: true },
348
+ multi_oneof_flat: { Component: components_1.MultiOneOfFlatView, independent: true },
341
349
  },
342
350
  layouts: {
343
351
  row: components_1.ViewRow2,
@@ -2,3 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./config"), exports);
5
+ tslib_1.__exportStar(require("./common"), exports);
@@ -81,6 +81,7 @@ export interface ObjectSpec<LinkType = any> {
81
81
  oneOfParams?: {
82
82
  toggler?: 'select' | 'radio';
83
83
  };
84
+ placeholder?: string;
84
85
  };
85
86
  }
86
87
  export interface StringSpec<LinkType = any> {
@@ -51,6 +51,10 @@
51
51
  font-size: var(--yc-text-subheader-2-font-size);
52
52
  font-weight: var(--yc-text-subheader-font-weight);
53
53
  line-height: var(--yc-text-subheader-2-line-height);
54
+ white-space: nowrap;
55
+ overflow: hidden;
56
+ text-overflow: ellipsis;
57
+ max-width: 533px;
54
58
  }
55
59
  .df-card__note {
56
60
  margin-left: 5px;
@@ -1,12 +1,16 @@
1
1
  import React from 'react';
2
+ import { HelpPopover } from '@gravity-ui/components';
2
3
  import { ChevronDown } from '@gravity-ui/icons';
3
- import { Button, Card as CardBase, HelpPopover, Icon } from '@gravity-ui/uikit';
4
+ import { Button, Card as CardBase, Icon, Popover } from '@gravity-ui/uikit';
4
5
  import _ from 'lodash';
6
+ import { COMMON_POPOVER_PLACEMENT, COMMON_TITLE_MAX_WIDTH } from '../../constants/common';
5
7
  import { block } from '../../utils';
6
8
  import './Card.css';
7
9
  const b = block('card');
8
10
  export const Card = ({ name, title: propsTitle, description, actions, open: propsOpen, onToggle, alwaysOpen, disableHeaderToggle, checkEmptyBody, children, }) => {
11
+ var _a;
9
12
  const containerRef = React.useRef(null);
13
+ const titleRef = React.useRef(null);
10
14
  const bodyRef = React.useRef(null);
11
15
  const [open, setOpen] = React.useState(alwaysOpen || propsOpen || false);
12
16
  const emptyBody = Boolean(bodyRef.current && !bodyRef.current.childElementCount);
@@ -26,15 +30,17 @@ export const Card = ({ name, title: propsTitle, description, actions, open: prop
26
30
  return;
27
31
  }, [disableHeaderToggle, handleToggle]);
28
32
  const preventEvent = React.useCallback((e) => e.stopPropagation(), []);
33
+ const titlePopoverDisabled = (((_a = titleRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0) <= COMMON_TITLE_MAX_WIDTH;
29
34
  const title = React.useMemo(() => {
30
35
  if (_.isString(propsTitle)) {
31
36
  return (React.createElement(React.Fragment, null,
32
- React.createElement("div", { className: b('title') }, propsTitle),
37
+ React.createElement(Popover, { content: propsTitle, disabled: titlePopoverDisabled, placement: COMMON_POPOVER_PLACEMENT },
38
+ React.createElement("div", { ref: titleRef, className: b('title') }, propsTitle)),
33
39
  description ? (React.createElement("div", { className: b('note') },
34
- React.createElement(HelpPopover, { htmlContent: description, placement: ['bottom', 'top'] }))) : null));
40
+ React.createElement(HelpPopover, { htmlContent: description, placement: COMMON_POPOVER_PLACEMENT }))) : null));
35
41
  }
36
42
  return propsTitle;
37
- }, [propsTitle, description]);
43
+ }, [propsTitle, titlePopoverDisabled, description]);
38
44
  React.useEffect(() => {
39
45
  if (!alwaysOpen && propsOpen !== undefined && propsOpen !== open) {
40
46
  setOpen(propsOpen);
@@ -4,7 +4,7 @@
4
4
  justify-content: space-between;
5
5
  padding: 15px;
6
6
  align-items: center;
7
- background-color: var(--yc-color-private-black-50-solid);
7
+ background-color: var(--yc-color-base-float-hover);
8
8
  }
9
9
  .df-monaco-header_card {
10
10
  border-bottom: 1px solid var(--yc-color-line-generic);
@@ -0,0 +1,14 @@
1
+ .df-multi-oneof__select {
2
+ max-width: 305px;
3
+ }
4
+ .df-multi-oneof__content_flat > .df-group-indent {
5
+ margin: 0;
6
+ border-left: none;
7
+ padding: 0;
8
+ }
9
+ .df-multi-oneof__content_flat > .df-group-indent > .df-use-search {
10
+ margin-top: 15px;
11
+ }
12
+ .df-multi-oneof__content_flat > .df-group-indent > .df-use-search:empty {
13
+ display: none;
14
+ }
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { ObjectIndependentInput, ObjectIndependentInputProps } from '../../../../core';
3
+ import './MultiOneOf.css';
4
+ export interface MultiOneOfProps extends ObjectIndependentInputProps {
5
+ withoutIndent?: boolean;
6
+ }
7
+ export declare const MultiOneOf: React.FC<MultiOneOfProps>;
8
+ export declare const MultiOneOfFlat: ObjectIndependentInput;
@@ -0,0 +1,68 @@
1
+ import React from 'react';
2
+ import { Select } from '@gravity-ui/uikit';
3
+ import _ from 'lodash';
4
+ import { Controller, } from '../../../../core';
5
+ import { block } from '../../../utils';
6
+ import { GroupIndent } from '../../GroupIndent';
7
+ import './MultiOneOf.css';
8
+ const b = block('multi-oneof');
9
+ export const MultiOneOf = (props) => {
10
+ const { name, input, spec, Layout, withoutIndent } = props;
11
+ const { value, onBlur, onChange, onFocus, parentOnUnmount } = input;
12
+ const [valueSelect, setValueSelect] = React.useState(() => (value ? Object.keys(value) : []));
13
+ const handleOpenChange = React.useCallback((open) => {
14
+ if (open) {
15
+ onFocus();
16
+ }
17
+ else {
18
+ onBlur();
19
+ }
20
+ }, [onFocus, onBlur]);
21
+ const parentOnChange = React.useCallback((childName, childValue, childErrors) => {
22
+ onChange((currentValue) => _.set(Object.assign({}, currentValue), childName.split(`${name}.`).join(''), childValue), childErrors);
23
+ }, [name, onChange]);
24
+ const specProperties = React.useMemo(() => (_.isObjectLike(spec.properties) ? spec.properties : {}), [spec.properties]);
25
+ const options = React.useMemo(() => (spec.viewSpec.order || Object.keys(specProperties)).map((value) => {
26
+ var _a, _b;
27
+ const title = ((_a = spec.description) === null || _a === void 0 ? void 0 : _a[value]) ||
28
+ ((_b = specProperties[value]) === null || _b === void 0 ? void 0 : _b.viewSpec.layoutTitle) ||
29
+ value ||
30
+ '';
31
+ return {
32
+ value,
33
+ title,
34
+ content: title,
35
+ };
36
+ }), [spec.description, spec.viewSpec.order, specProperties]);
37
+ const filterable = React.useMemo(() => (options.length || 0) > 9, [options.length]);
38
+ const selectInput = React.useMemo(() => {
39
+ const select = (React.createElement(Select, { width: "max", value: valueSelect, options: options, onUpdate: setValueSelect, onOpenChange: handleOpenChange, disabled: spec.viewSpec.disabled, placeholder: spec.viewSpec.placeholder, filterable: filterable, multiple: true, className: b('select'), qa: name }));
40
+ if (Layout) {
41
+ return React.createElement(Layout, Object.assign({}, props), select);
42
+ }
43
+ return React.createElement(React.Fragment, null, select);
44
+ }, [
45
+ Layout,
46
+ filterable,
47
+ handleOpenChange,
48
+ name,
49
+ options,
50
+ props,
51
+ spec.viewSpec.disabled,
52
+ spec.viewSpec.placeholder,
53
+ valueSelect,
54
+ ]);
55
+ if (!options) {
56
+ return null;
57
+ }
58
+ return (React.createElement(React.Fragment, null,
59
+ selectInput,
60
+ React.createElement("div", { className: b('content', {
61
+ flat: withoutIndent,
62
+ }) },
63
+ React.createElement(GroupIndent, null, valueSelect.map((property) => {
64
+ var _a;
65
+ return (React.createElement(React.Fragment, { key: property }, specProperties && specProperties[property] ? (React.createElement(Controller, { name: `${name}.${property}`, spec: specProperties[property], parentOnUnmount: parentOnUnmount, parentOnChange: parentOnChange, value: (_a = input.value) === null || _a === void 0 ? void 0 : _a[property] })) : null));
66
+ })))));
67
+ };
68
+ export const MultiOneOfFlat = (props) => (React.createElement(MultiOneOf, Object.assign({}, props, { withoutIndent: true })));
@@ -0,0 +1 @@
1
+ export * from './MultiOneOf';
@@ -0,0 +1 @@
1
+ export * from './MultiOneOf';
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { TextInput as TextInputBase } from '@gravity-ui/uikit';
2
+ import { TextArea as TextAreaBase } from '@gravity-ui/uikit';
3
3
  export const TextArea = ({ name, input, spec }) => {
4
4
  const { value, onBlur, onChange, onFocus } = input;
5
- return (React.createElement(TextInputBase, { value: value, onBlur: onBlur, onFocus: onFocus, onUpdate: onChange, maxRows: 20, minRows: 8, hasClear: true, disabled: spec.viewSpec.disabled, multiline: true, placeholder: spec.viewSpec.placeholder, qa: name }));
5
+ return (React.createElement(TextAreaBase, { value: value, onBlur: onBlur, onFocus: onFocus, onUpdate: onChange, maxRows: 20, minRows: 8, hasClear: true, disabled: spec.viewSpec.disabled, placeholder: spec.viewSpec.placeholder, qa: name }));
6
6
  };
@@ -2,7 +2,10 @@ export * from './ArrayBase';
2
2
  export * from './CardOneOf';
3
3
  export * from './Checkbox';
4
4
  export * from './FileInput';
5
+ export * from './MonacoInput';
6
+ export * from './MultiOneOf';
5
7
  export * from './MultiSelect';
8
+ export * from './NumberWithScale';
6
9
  export * from './ObjectBase';
7
10
  export * from './ObjectValueInput';
8
11
  export * from './OneOf';
@@ -15,5 +18,3 @@ export * from './Text';
15
18
  export * from './TextArea';
16
19
  export * from './TextContent';
17
20
  export * from './TextLink';
18
- export * from './NumberWithScale';
19
- export * from './MonacoInput';
@@ -2,7 +2,10 @@ export * from './ArrayBase';
2
2
  export * from './CardOneOf';
3
3
  export * from './Checkbox';
4
4
  export * from './FileInput';
5
+ export * from './MonacoInput';
6
+ export * from './MultiOneOf';
5
7
  export * from './MultiSelect';
8
+ export * from './NumberWithScale';
6
9
  export * from './ObjectBase';
7
10
  export * from './ObjectValueInput';
8
11
  export * from './OneOf';
@@ -15,5 +18,3 @@ export * from './Text';
15
18
  export * from './TextArea';
16
19
  export * from './TextContent';
17
20
  export * from './TextLink';
18
- export * from './NumberWithScale';
19
- export * from './MonacoInput';
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
+ import { HelpPopover } from '@gravity-ui/components';
2
3
  import { Xmark } from '@gravity-ui/icons';
3
- import { Button, HelpPopover, Icon } from '@gravity-ui/uikit';
4
+ import { Button, Icon } from '@gravity-ui/uikit';
4
5
  import { isArrayItem, isArraySpec, isObjectSpec, } from '../../../../core';
5
6
  import { ErrorWrapper } from '../../../components';
6
7
  import { block } from '../../../utils';
@@ -12,8 +12,12 @@
12
12
  align-items: center;
13
13
  }
14
14
  .df-section__title {
15
+ max-width: 533px;
15
16
  font-weight: 500;
16
17
  margin: 0;
18
+ white-space: nowrap;
19
+ overflow: hidden;
20
+ text-overflow: ellipsis;
17
21
  }
18
22
  .df-section__title_size_s {
19
23
  font-size: 13px;
@@ -1,16 +1,19 @@
1
1
  import { __rest } from "tslib";
2
2
  import React from 'react';
3
- import { HelpPopover } from '@gravity-ui/uikit';
3
+ import { HelpPopover } from '@gravity-ui/components';
4
+ import { Popover } from '@gravity-ui/uikit';
4
5
  import { GroupIndent } from '../../';
5
- import { ErrorWrapper } from '../../../';
6
+ import { COMMON_POPOVER_PLACEMENT, COMMON_TITLE_MAX_WIDTH, ErrorWrapper } from '../../../';
6
7
  import { isArraySpec, isObjectSpec, } from '../../../../core';
7
8
  import { block } from '../../../utils';
8
9
  import './Section.css';
9
10
  const b = block('section');
10
11
  const SectionBase = (_a) => {
12
+ var _b;
11
13
  var { name, spec, titleSize, withIndent, ignoreDescription, descriptionAsSubtitle, children } = _a, restProps = __rest(_a, ["name", "spec", "titleSize", "withIndent", "ignoreDescription", "descriptionAsSubtitle", "children"]);
12
14
  const meta = restProps.meta;
13
15
  const arrOrObjFlag = isArraySpec(spec) || isObjectSpec(spec);
16
+ const titleRef = React.useRef(null);
14
17
  let content = children;
15
18
  if (meta) {
16
19
  content = (React.createElement(ErrorWrapper, { name: name, meta: meta, withoutChildErrorStyles: arrOrObjFlag }, content));
@@ -30,11 +33,14 @@ const SectionBase = (_a) => {
30
33
  React.createElement(HelpPopover, { htmlContent: spec.viewSpec.layoutDescription, placement: ['bottom', 'top'] })));
31
34
  }
32
35
  }
36
+ const layoutTitle = spec.viewSpec.layoutTitle;
37
+ const layoutTitlePopoverDisabled = (((_b = titleRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth) || 0) <= COMMON_TITLE_MAX_WIDTH;
33
38
  return (React.createElement("section", { className: b() },
34
- spec.viewSpec.layoutTitle ? (React.createElement("div", { className: b('header', {
39
+ layoutTitle ? (React.createElement("div", { className: b('header', {
35
40
  'with-popover': !descriptionAsSubtitle,
36
41
  }) },
37
- React.createElement("h2", { className: b('title', { size: titleSize }) }, spec.viewSpec.layoutTitle),
42
+ React.createElement(Popover, { content: layoutTitle, placement: COMMON_POPOVER_PLACEMENT, disabled: layoutTitlePopoverDisabled },
43
+ React.createElement("h2", { className: b('title', { size: titleSize }), ref: titleRef }, layoutTitle)),
38
44
  description)) : null,
39
45
  React.createElement("div", { className: b('content') }, content)));
40
46
  };
@@ -15,6 +15,7 @@
15
15
  }
16
16
  .df-simple-vertical-accordeon__header-inner {
17
17
  margin-left: -13px;
18
+ max-width: 533px;
18
19
  }
19
20
  .df-simple-vertical-accordeon__title {
20
21
  font-weight: 500;
@@ -29,6 +29,7 @@ export declare class SimpleVerticalAccordeon extends React.Component<SimpleVerti
29
29
  withBranchView: boolean;
30
30
  };
31
31
  componentRef: React.RefObject<HTMLDivElement>;
32
+ titleRef: React.RefObject<HTMLElement>;
32
33
  constructor(props: SimpleVerticalAccordeonProps);
33
34
  componentDidUpdate(prevProps: Readonly<SimpleVerticalAccordeonProps>): void;
34
35
  componentDidMount(): void;
@@ -1,13 +1,17 @@
1
1
  import React from 'react';
2
+ import { HelpPopover } from '@gravity-ui/components';
2
3
  import { ChevronDown } from '@gravity-ui/icons';
3
- import { Button, HelpPopover, Icon } from '@gravity-ui/uikit';
4
+ import { Button, Icon, Popover } from '@gravity-ui/uikit';
5
+ import { COMMON_POPOVER_PLACEMENT } from '../../constants/common';
4
6
  import { block } from '../../utils';
5
7
  import './SimpleVerticalAccordeon.css';
6
8
  const b = block('simple-vertical-accordeon');
9
+ const TITLE_TEXT_MAX_WIDTH = 485; /** 533px (COMMON_TITLE_MAX_WIDTH) - 48px of padding */
7
10
  export class SimpleVerticalAccordeon extends React.Component {
8
11
  constructor(props) {
9
12
  super(props);
10
13
  this.componentRef = React.createRef();
14
+ this.titleRef = React.createRef();
11
15
  this.checkVisibility = () => {
12
16
  if (this.props.viewLayout) {
13
17
  if (this.componentRef.current &&
@@ -44,17 +48,21 @@ export class SimpleVerticalAccordeon extends React.Component {
44
48
  this.checkVisibility();
45
49
  }
46
50
  render() {
51
+ var _a;
47
52
  const { titleSize, children, headerActionsTemplate, className, contentClassName, buttonClassName, hideInsteadOfDestroy, withBranchView, viewLayout, name, } = this.props;
48
53
  const { open, hidden, isFirstRender } = this.state;
49
54
  const content = hideInsteadOfDestroy ? (React.createElement("div", { ref: this.componentRef, className: b('body', { hidden: !open }) }, children)) : (open && (React.createElement("div", { ref: this.componentRef, className: b('body', contentClassName) }, children)));
50
55
  if (viewLayout && !isFirstRender && hidden) {
51
56
  return null;
52
57
  }
58
+ const title = this.getTitle();
59
+ const titlePopoverDisabled = (((_a = this.titleRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0) <= TITLE_TEXT_MAX_WIDTH;
53
60
  return (Boolean(React.Children.count(children)) && (React.createElement("div", { className: b({ branch: withBranchView, view: viewLayout }, className) },
54
61
  React.createElement("div", { className: b('header') },
55
- React.createElement(Button, { view: "flat", className: b('header-inner', buttonClassName), onClick: this.handleClick, qa: `${name}-accordeon-toggler` },
56
- React.createElement("b", { className: b('title', { size: titleSize }) }, this.getTitle()),
57
- React.createElement(Icon, { data: ChevronDown, className: b('chevron', { open }), size: 16 })),
62
+ React.createElement(Popover, { content: title, disabled: titlePopoverDisabled, placement: COMMON_POPOVER_PLACEMENT },
63
+ React.createElement(Button, { view: "flat", className: b('header-inner', buttonClassName), onClick: this.handleClick, qa: `${name}-accordeon-toggler`, width: "auto" },
64
+ React.createElement("b", { ref: this.titleRef, className: b('title', { size: titleSize }) }, title),
65
+ React.createElement(Icon, { data: ChevronDown, className: b('chevron', { open }), size: 16 }))),
58
66
  this.getTooltip(),
59
67
  headerActionsTemplate ? headerActionsTemplate : null),
60
68
  content)));
@@ -0,0 +1,21 @@
1
+ .df-multi-oneof-view__tooltip {
2
+ overflow-wrap: break-word;
3
+ }
4
+ .df-multi-oneof-view__tooltip-container {
5
+ max-width: 100%;
6
+ overflow: hidden;
7
+ text-overflow: ellipsis;
8
+ display: block;
9
+ margin-bottom: 6px;
10
+ }
11
+ .df-multi-oneof-view__tooltip-container:last-child {
12
+ margin-bottom: 0;
13
+ }
14
+ .df-multi-oneof-view__content_multiple-values > .df-group-indent {
15
+ padding-top: 0px;
16
+ }
17
+ .df-multi-oneof-view__content_flat > .df-group-indent {
18
+ margin: 0 0 20px;
19
+ border-left: none;
20
+ padding: 0;
21
+ }
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { ObjectIndependentView, ObjectIndependentViewProps } from '../../../../core';
3
+ import './MultiOneOfView.css';
4
+ export interface MultiOneOfViewProps extends ObjectIndependentViewProps {
5
+ withoutIndent?: boolean;
6
+ }
7
+ export declare const MultiOneOfView: React.FC<MultiOneOfViewProps>;
8
+ export declare const MultiOneOfFlatView: ObjectIndependentView;
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import { Popover } from '@gravity-ui/uikit';
3
+ import _ from 'lodash';
4
+ import { ViewController } from '../../../../core';
5
+ import { block } from '../../../utils';
6
+ import { GroupIndent } from '../../GroupIndent';
7
+ import './MultiOneOfView.css';
8
+ const b = block('multi-oneof-view');
9
+ export const MultiOneOfView = (props) => {
10
+ const { name, value, Layout, spec, withoutIndent } = props;
11
+ const specProperties = React.useMemo(() => (_.isObjectLike(spec.properties) ? spec.properties : {}), [spec.properties]);
12
+ const values = React.useMemo(() => Object.keys(value || []), [value]);
13
+ const items = React.useMemo(() => values.map((value) => {
14
+ var _a, _b;
15
+ const title = ((_a = spec.description) === null || _a === void 0 ? void 0 : _a[value]) ||
16
+ ((_b = specProperties[value]) === null || _b === void 0 ? void 0 : _b.viewSpec.layoutTitle) ||
17
+ value ||
18
+ '';
19
+ return title;
20
+ }), [spec.description, specProperties, values]);
21
+ const selectView = React.useMemo(() => {
22
+ const selectView = (React.createElement(React.Fragment, null, items.map((item) => {
23
+ return (React.createElement(Popover, { placement: ['bottom', 'top'], key: item, content: item, className: b('tooltip-container'), contentClassName: b('tooltip'), disabled: item.length < 51 }, item));
24
+ })));
25
+ if (Layout) {
26
+ return (React.createElement(Layout, Object.assign({}, props, { value: values }), selectView));
27
+ }
28
+ return React.createElement(React.Fragment, null, selectView);
29
+ }, [Layout, items, props, values]);
30
+ if (values.length === 0) {
31
+ return null;
32
+ }
33
+ return (React.createElement(React.Fragment, null,
34
+ selectView,
35
+ React.createElement("div", { className: b('content', { flat: withoutIndent, 'multiple-values': items.length > 1 }) },
36
+ React.createElement(GroupIndent, null, values.map((value) => (React.createElement(React.Fragment, { key: value }, specProperties && specProperties[value] ? (React.createElement(ViewController, { name: `${name}.${value}`, spec: specProperties[value] })) : null)))))));
37
+ };
38
+ export const MultiOneOfFlatView = (props) => (React.createElement(MultiOneOfView, Object.assign({}, props, { withoutIndent: true })));
@@ -0,0 +1 @@
1
+ export * from './MultiOneOfView';
@@ -0,0 +1 @@
1
+ export * from './MultiOneOfView';
@@ -3,6 +3,7 @@ export * from './BaseView';
3
3
  export * from './CardOneOfView';
4
4
  export * from './FileInputView';
5
5
  export * from './MonacoInputView';
6
+ export * from './MultiOneOfView';
6
7
  export * from './MultiSelectView';
7
8
  export * from './NumberWithScaleView';
8
9
  export * from './ObjectBaseView';
@@ -3,6 +3,7 @@ export * from './BaseView';
3
3
  export * from './CardOneOfView';
4
4
  export * from './FileInputView';
5
5
  export * from './MonacoInputView';
6
+ export * from './MultiOneOfView';
6
7
  export * from './MultiSelectView';
7
8
  export * from './NumberWithScaleView';
8
9
  export * from './ObjectBaseView';
@@ -0,0 +1,3 @@
1
+ import type { PopoverProps } from '@gravity-ui/uikit';
2
+ export declare const COMMON_POPOVER_PLACEMENT: PopoverProps['placement'];
3
+ export declare const COMMON_TITLE_MAX_WIDTH = 533;
@@ -0,0 +1,2 @@
1
+ export const COMMON_POPOVER_PLACEMENT = ['bottom', 'top'];
2
+ export const COMMON_TITLE_MAX_WIDTH = 533;
@@ -1,4 +1,4 @@
1
- import { Accordeon, AccordeonCardLayout, ArrayBase, ArrayBaseView, BaseView, CardAccordeon, CardOneOf, CardOneOfView, CardSection, Checkbox, FileInput, FileInputView, Group, Group2, MonacoInput, MonacoInputCard, MonacoView, MonacoViewCard, MultiSelect, MultiSelectView, NumberWithScale, NumberWithScaleView, ObjectBase, ObjectBaseView, ObjectValueInput, ObjectValueInputView, OneOf, OneOfCard, OneOfCardView, OneOfFlat, OneOfFlatView, OneOfView, Row, Row2, RowVerbose, Secret, Section, Section2, SectionCard, SectionCard2, SectionWithSubtitle, SectionWithSubtitle2, Select, Switch, TableArrayInput, TableArrayView, TableCell, Text, TextArea, TextAreaView, TextContent, TextLink, TextLinkView, Transparent, ViewAccordeon, ViewAccordeonCard, ViewCardAccordeon, ViewCardSection, ViewGroup, ViewGroup2, ViewRow, ViewRow2, ViewSection, ViewSection2, ViewSectionCard, ViewSectionCard2, ViewTableCell, ViewTransparent, } from '../components';
1
+ import { Accordeon, AccordeonCardLayout, ArrayBase, ArrayBaseView, BaseView, CardAccordeon, CardOneOf, CardOneOfView, CardSection, Checkbox, FileInput, FileInputView, Group, Group2, MonacoInput, MonacoInputCard, MonacoView, MonacoViewCard, MultiOneOf, MultiOneOfFlat, MultiOneOfFlatView, MultiOneOfView, MultiSelect, MultiSelectView, NumberWithScale, NumberWithScaleView, ObjectBase, ObjectBaseView, ObjectValueInput, ObjectValueInputView, OneOf, OneOfCard, OneOfCardView, OneOfFlat, OneOfFlatView, OneOfView, Row, Row2, RowVerbose, Secret, Section, Section2, SectionCard, SectionCard2, SectionWithSubtitle, SectionWithSubtitle2, Select, Switch, TableArrayInput, TableArrayView, TableCell, Text, TextArea, TextAreaView, TextContent, TextLink, TextLinkView, Transparent, ViewAccordeon, ViewAccordeonCard, ViewCardAccordeon, ViewCardSection, ViewGroup, ViewGroup2, ViewRow, ViewRow2, ViewSection, ViewSection2, ViewSectionCard, ViewSectionCard2, ViewTableCell, ViewTransparent, } from '../components';
2
2
  import { getArrayValidator, getBooleanValidator, getNumberValidator, getObjectValidator, getStringValidator, } from '../validators';
3
3
  export const dynamicConfig = {
4
4
  array: {
@@ -61,6 +61,8 @@ export const dynamicConfig = {
61
61
  base: { Component: ObjectBase, independent: true },
62
62
  text_link: { Component: TextLink, independent: true },
63
63
  object_value: { Component: ObjectValueInput, independent: true },
64
+ multi_oneof: { Component: MultiOneOf, independent: true },
65
+ multi_oneof_flat: { Component: MultiOneOfFlat, independent: true },
64
66
  },
65
67
  layouts: {
66
68
  row: Row,
@@ -160,6 +162,8 @@ export const dynamicCardConfig = {
160
162
  base: { Component: ObjectBase, independent: true },
161
163
  text_link: { Component: TextLink, independent: true },
162
164
  object_value: { Component: ObjectValueInput, independent: true },
165
+ multi_oneof: { Component: MultiOneOf, independent: true },
166
+ multi_oneof_flat: { Component: MultiOneOfFlat, independent: true },
163
167
  },
164
168
  layouts: {
165
169
  row: Row2,
@@ -252,6 +256,8 @@ export const dynamicViewConfig = {
252
256
  base: { Component: ObjectBaseView, independent: true },
253
257
  text_link: { Component: TextLinkView, independent: true },
254
258
  object_value: { Component: ObjectValueInputView, independent: true },
259
+ multi_oneof: { Component: MultiOneOfView, independent: true },
260
+ multi_oneof_flat: { Component: MultiOneOfFlatView, independent: true },
255
261
  },
256
262
  layouts: {
257
263
  row: ViewRow,
@@ -335,6 +341,8 @@ export const dynamicViewCardConfig = {
335
341
  base: { Component: ObjectBaseView, independent: true },
336
342
  text_link: { Component: TextLinkView, independent: true },
337
343
  object_value: { Component: ObjectValueInputView, independent: true },
344
+ multi_oneof: { Component: MultiOneOfView, independent: true },
345
+ multi_oneof_flat: { Component: MultiOneOfFlatView, independent: true },
338
346
  },
339
347
  layouts: {
340
348
  row: ViewRow2,
@@ -1 +1,2 @@
1
1
  export * from './config';
2
+ export * from './common';
@@ -1 +1,2 @@
1
1
  export * from './config';
2
+ export * from './common';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/dynamic-forms",
3
- "version": "1.11.2",
3
+ "version": "2.1.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "build/cjs/index.js",
@@ -37,6 +37,7 @@
37
37
  "prepublishOnly": "npm run build"
38
38
  },
39
39
  "dependencies": {
40
+ "@gravity-ui/components": "^2.0.0",
40
41
  "@gravity-ui/i18n": "^1.0.0",
41
42
  "@gravity-ui/icons": "^2.1.0",
42
43
  "bem-cn-lite": "^4.0.0",
@@ -47,11 +48,11 @@
47
48
  "@babel/preset-typescript": "^7.18.6",
48
49
  "@commitlint/cli": "^17.0.0",
49
50
  "@commitlint/config-conventional": "^17.0.0",
50
- "@gravity-ui/eslint-config": "^2.0.0",
51
+ "@gravity-ui/eslint-config": "^2.1.1",
51
52
  "@gravity-ui/prettier-config": "^1.0.1",
52
53
  "@gravity-ui/stylelint-config": "^2.0.0",
53
54
  "@gravity-ui/tsconfig": "^1.0.0",
54
- "@gravity-ui/uikit": "^4.10.0",
55
+ "@gravity-ui/uikit": "^5.0.2",
55
56
  "@storybook/addon-essentials": "^7.0.27",
56
57
  "@storybook/preset-scss": "^1.0.3",
57
58
  "@storybook/react": "^7.0.27",
@@ -97,7 +98,7 @@
97
98
  "typescript": "^4.9.5"
98
99
  },
99
100
  "peerDependencies": {
100
- "@gravity-ui/uikit": "^4.0.0",
101
+ "@gravity-ui/uikit": "^5.0.0",
101
102
  "final-form": "^4.20.2",
102
103
  "react": "^16.0.0 || ^17.0.0 || ^18.0.0",
103
104
  "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0",