@evergis/react 4.0.115 → 4.0.116

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.
@@ -43,3 +43,17 @@ export declare const DEFAULT_DROPDOWN_WIDTH = 312;
43
43
  export declare const DEFAULT_FILTER_PADDING = 12;
44
44
  /** Базовый отступ обёртки контейнера. Снимается, когда контейнер занимает ячейку целиком. */
45
45
  export declare const BASE_CONTAINER_STYLE: CSSObject;
46
+ /**
47
+ * Маркер тела контейнера внутри `ContainerRoot` — содержимое без заголовка.
48
+ *
49
+ * Нужен, чтобы находить тело по DOM снаружи: `#<id контейнера>` теперь указывает на корень,
50
+ * то есть на пару «заголовок + тело».
51
+ */
52
+ export declare const CONTAINER_BODY_ATTRIBUTE = "data-container-body";
53
+ /**
54
+ * Заданная высота контейнера достаётся телу — за вычетом заголовка.
55
+ *
56
+ * Сама высота остаётся на корне, поэтому тело забирает остаток ячейки, а заголовок сохраняет
57
+ * `flex-shrink: 0` и не сжимается.
58
+ */
59
+ export declare const CONTAINER_BODY_FILL_STYLE: CSSObject;
@@ -2,6 +2,7 @@ export * from './useAttachmentItems';
2
2
  export * from './useAttachmentPreviewImages';
3
3
  export * from './useAutoCompleteControl';
4
4
  export * from './useContainerAttributes';
5
+ export * from './useContainerRoot';
5
6
  export * from './useEditGroupAttributes';
6
7
  export * from './useFetchImageWithAuth';
7
8
  export * from './useFetchWithAuth';
@@ -0,0 +1,29 @@
1
+ import { CSSObject } from 'styled-components';
2
+ import { CONTAINER_BODY_ATTRIBUTE } from '../constants';
3
+ import { WrapperRootProps } from './useWrapperSize';
4
+ import { ConfigContainerChild } from '../types';
5
+ interface UseContainerRootParams {
6
+ elementConfig?: ConfigContainerChild;
7
+ /** Внутренние дефолты корневой обёртки. Ссылка должна быть стабильной (константа или useMemo). */
8
+ defaults?: CSSObject;
9
+ }
10
+ /** Пропсы тела контейнера — узла с содержимым, соседнего с заголовком внутри `ContainerRoot`. */
11
+ export interface ContainerBodyProps {
12
+ [CONTAINER_BODY_ATTRIBUTE]?: string;
13
+ $sizeCss?: CSSObject;
14
+ }
15
+ export interface ContainerRootParts {
16
+ /** Пропсы корневого узла: идентификаторы, авторский `style`, размеры. */
17
+ root: WrapperRootProps;
18
+ /** Пропсы тела: маркер для поиска по DOM и доля высоты, оставшаяся от корня. */
19
+ body: ContainerBodyProps;
20
+ }
21
+ /**
22
+ * Пропсы двух узлов контейнера с заголовком: корня (`ContainerRoot`) и тела.
23
+ *
24
+ * Контейнер обязан иметь ОДИН корневой узел — иначе в строке (`options.column: false`) заголовок
25
+ * и тело становятся двумя ячейками родительского flex-row. Размеры из конфига поэтому уходят на
26
+ * корень, а тело получает лишь остаток высоты под заголовком.
27
+ */
28
+ export declare const useContainerRoot: ({ elementConfig, defaults }: UseContainerRootParams) => ContainerRootParts;
29
+ export {};
@@ -18,6 +18,18 @@ export declare const ElementValueWrapper: import('styled-components').StyledComp
18
18
  noMargin?: boolean;
19
19
  $sizeTransparent?: boolean;
20
20
  }, never>;
21
+ /**
22
+ * Единственный корневой узел контейнера: внутри — заголовок (`ExpandableTitle`) и тело.
23
+ *
24
+ * Два корня (фрагмент из заголовка и тела) ломают раскладку родителя: в строке
25
+ * (`options.column: false`) они становятся ДВУМЯ ячейками flex-row и делят её ширину между собой,
26
+ * а доля из `options.width` достаётся только телу. Поэтому `id`, `data-templatename`, авторский
27
+ * `style` и `$sizeCss` живут здесь, а не на теле — см. `useContainerRoot`.
28
+ *
29
+ * Всегда flex-колонка: заголовок и тело раньше были flex-элементами родительского `Container`,
30
+ * и блочная обёртка вернула бы схлопывание вертикальных отступов между ними.
31
+ */
32
+ export declare const ContainerRoot: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps & ContainerRootProps, never>;
21
33
  export declare const Container: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps & ContainerRootProps & {
22
34
  isTitle?: boolean;
23
35
  isColumn?: boolean;
package/dist/index.js CHANGED
@@ -3534,6 +3534,24 @@ const DEFAULT_FILTER_PADDING = 12;
3534
3534
  const BASE_CONTAINER_STYLE = {
3535
3535
  marginBottom: "1rem",
3536
3536
  };
3537
+ /**
3538
+ * Маркер тела контейнера внутри `ContainerRoot` — содержимое без заголовка.
3539
+ *
3540
+ * Нужен, чтобы находить тело по DOM снаружи: `#<id контейнера>` теперь указывает на корень,
3541
+ * то есть на пару «заголовок + тело».
3542
+ */
3543
+ const CONTAINER_BODY_ATTRIBUTE = "data-container-body";
3544
+ /**
3545
+ * Заданная высота контейнера достаётся телу — за вычетом заголовка.
3546
+ *
3547
+ * Сама высота остаётся на корне, поэтому тело забирает остаток ячейки, а заголовок сохраняет
3548
+ * `flex-shrink: 0` и не сжимается.
3549
+ */
3550
+ const CONTAINER_BODY_FILL_STYLE = {
3551
+ flex: "1 1 auto",
3552
+ minHeight: 0,
3553
+ minWidth: 0,
3554
+ };
3537
3555
 
3538
3556
  const StackBarContainer = styled(uilibGl.Flex).withConfig({ displayName: "StackBarContainer", componentId: "sc-stc97k" }) `
3539
3557
  flex-wrap: nowrap;
@@ -4591,7 +4609,24 @@ const ElementValueWrapper = styled.div.withConfig({ displayName: "ElementValueWr
4591
4609
  }
4592
4610
  `};
4593
4611
  `;
4594
- const Container = styled(uilibGl.Flex).withConfig({ displayName: "Container", componentId: "sc-1gpmkbq" }) `
4612
+ /**
4613
+ * Единственный корневой узел контейнера: внутри — заголовок (`ExpandableTitle`) и тело.
4614
+ *
4615
+ * Два корня (фрагмент из заголовка и тела) ломают раскладку родителя: в строке
4616
+ * (`options.column: false`) они становятся ДВУМЯ ячейками flex-row и делят её ширину между собой,
4617
+ * а доля из `options.width` достаётся только телу. Поэтому `id`, `data-templatename`, авторский
4618
+ * `style` и `$sizeCss` живут здесь, а не на теле — см. `useContainerRoot`.
4619
+ *
4620
+ * Всегда flex-колонка: заголовок и тело раньше были flex-элементами родительского `Container`,
4621
+ * и блочная обёртка вернула бы схлопывание вертикальных отступов между ними.
4622
+ */
4623
+ const ContainerRoot = styled(uilibGl.Flex).withConfig({ displayName: "ContainerRoot", componentId: "sc-2j6lbd" }) `
4624
+ flex-direction: column;
4625
+ min-width: 0;
4626
+
4627
+ ${sizeCssMixin};
4628
+ `;
4629
+ const Container = styled(uilibGl.Flex).withConfig({ displayName: "Container", componentId: "sc-1o8dsu2" }) `
4595
4630
  flex-direction: column;
4596
4631
  width: 100%;
4597
4632
 
@@ -4645,7 +4680,7 @@ const Container = styled(uilibGl.Flex).withConfig({ displayName: "Container", co
4645
4680
 
4646
4681
  ${sizeCssMixin};
4647
4682
  `;
4648
- const ContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName: "ContainerWrapper", componentId: "sc-4nlisz" }) `
4683
+ const ContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName: "ContainerWrapper", componentId: "sc-16tb6s0" }) `
4649
4684
  position: relative;
4650
4685
  box-sizing: border-box;
4651
4686
  width: 100%;
@@ -4666,7 +4701,7 @@ const ContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName: "Contain
4666
4701
  }
4667
4702
  `}
4668
4703
  `;
4669
- const DashboardChip = styled(uilibGl.Chip).withConfig({ displayName: "DashboardChip", componentId: "sc-8os072" }) `
4704
+ const DashboardChip = styled(uilibGl.Chip).withConfig({ displayName: "DashboardChip", componentId: "sc-19j7obx" }) `
4670
4705
  margin: 0 0.25rem 0.25rem 0;
4671
4706
  background: ${({ $isDefault, $bgColor, theme: { palette } }) => $isDefault ? palette.element : $bgColor || palette.primary};
4672
4707
  border-radius: ${({ $radius, theme: { borderRadius } }) => $radius || borderRadius.medium};
@@ -4682,7 +4717,7 @@ const DashboardChip = styled(uilibGl.Chip).withConfig({ displayName: "DashboardC
4682
4717
  color: ${({ $isDefault, $fontColor, theme: { palette } }) => $isDefault ? palette.icon : $fontColor || "#fff"};
4683
4718
  }
4684
4719
  `;
4685
- const DashboardPlaceholderWrap = styled(uilibGl.Flex).withConfig({ displayName: "DashboardPlaceholderWrap", componentId: "sc-1qpd82p" }) `
4720
+ const DashboardPlaceholderWrap = styled(uilibGl.Flex).withConfig({ displayName: "DashboardPlaceholderWrap", componentId: "sc-anwihw" }) `
4686
4721
  flex-grow: 1;
4687
4722
  flex-direction: column;
4688
4723
  justify-content: center;
@@ -4690,7 +4725,7 @@ const DashboardPlaceholderWrap = styled(uilibGl.Flex).withConfig({ displayName:
4690
4725
  width: 100%;
4691
4726
  margin-bottom: 2rem;
4692
4727
  `;
4693
- const DashboardPlaceholder = styled(uilibGl.Flex).withConfig({ displayName: "DashboardPlaceholder", componentId: "sc-1ls3oxv" }) `
4728
+ const DashboardPlaceholder = styled(uilibGl.Flex).withConfig({ displayName: "DashboardPlaceholder", componentId: "sc-jry8vp" }) `
4694
4729
  flex-direction: column;
4695
4730
  justify-content: center;
4696
4731
  align-items: center;
@@ -4723,7 +4758,7 @@ const DashboardPlaceholder = styled(uilibGl.Flex).withConfig({ displayName: "Das
4723
4758
  }
4724
4759
  }
4725
4760
  `;
4726
- const DashboardWrapper = styled(uilibGl.Flex).withConfig({ displayName: "DashboardWrapper", componentId: "sc-bx93vz" }) `
4761
+ const DashboardWrapper = styled(uilibGl.Flex).withConfig({ displayName: "DashboardWrapper", componentId: "sc-100ipup" }) `
4727
4762
  flex-direction: column;
4728
4763
  flex-wrap: nowrap;
4729
4764
  flex-grow: 1;
@@ -4736,7 +4771,7 @@ const DashboardWrapper = styled(uilibGl.Flex).withConfig({ displayName: "Dashboa
4736
4771
  margin-top: -0.35rem;
4737
4772
  `}
4738
4773
  `;
4739
- const DashboardContent = styled(uilibGl.Flex).withConfig({ displayName: "DashboardContent", componentId: "sc-mslago" }) `
4774
+ const DashboardContent = styled(uilibGl.Flex).withConfig({ displayName: "DashboardContent", componentId: "sc-77il9k" }) `
4740
4775
  flex-grow: 1;
4741
4776
  width: 100%;
4742
4777
  padding: 1.5rem 1.5rem 2rem;
@@ -4751,16 +4786,16 @@ const PresentationWrapperCss = styled.css `
4751
4786
  border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
4752
4787
  box-shadow: ${uilibGl.shadows.raised};
4753
4788
  `;
4754
- const PresentationWrapper = styled.div.withConfig({ displayName: "PresentationWrapper", componentId: "sc-1aajdp8" }) `
4789
+ const PresentationWrapper = styled.div.withConfig({ displayName: "PresentationWrapper", componentId: "sc-891z9z" }) `
4755
4790
  ${PresentationWrapperCss};
4756
4791
  position: relative;
4757
4792
  z-index: 1;
4758
4793
  `;
4759
- const PresentationPanelWrapper = styled(PresentationWrapper).withConfig({ displayName: "PresentationPanelWrapper", componentId: "sc-9w36pj" }) `
4794
+ const PresentationPanelWrapper = styled(PresentationWrapper).withConfig({ displayName: "PresentationPanelWrapper", componentId: "sc-1ptpbt9" }) `
4760
4795
  margin-top: 0.75rem;
4761
4796
  transition: background-color ${uilibGl.transition.toggle};
4762
4797
  `;
4763
- const PresentationHeader = styled.div.withConfig({ displayName: "PresentationHeader", componentId: "sc-xe6ev3" }) `
4798
+ const PresentationHeader = styled.div.withConfig({ displayName: "PresentationHeader", componentId: "sc-182b7wg" }) `
4764
4799
  margin: -1.5rem -1.5rem 0 -1.5rem;
4765
4800
  padding: 1.5rem;
4766
4801
  // background: url(images.presentationHeader) 0 0 no-repeat;
@@ -4772,7 +4807,7 @@ const PresentationHeader = styled.div.withConfig({ displayName: "PresentationHea
4772
4807
  padding-top: 7rem;
4773
4808
  `};
4774
4809
  `;
4775
- const PresentationHeaderTools = styled(uilibGl.Flex).withConfig({ displayName: "PresentationHeaderTools", componentId: "sc-13dyz78" }) `
4810
+ const PresentationHeaderTools = styled(uilibGl.Flex).withConfig({ displayName: "PresentationHeaderTools", componentId: "sc-dms7fm" }) `
4776
4811
  justify-content: space-between;
4777
4812
  align-items: center;
4778
4813
  margin-bottom: -0.5rem;
@@ -4790,7 +4825,7 @@ const PresentationHeaderTools = styled(uilibGl.Flex).withConfig({ displayName: "
4790
4825
  }
4791
4826
  }
4792
4827
  `;
4793
- const LayerGroupList = styled(uilibGl.Flex).withConfig({ displayName: "LayerGroupList", componentId: "sc-110h1r0" }) `
4828
+ const LayerGroupList = styled(uilibGl.Flex).withConfig({ displayName: "LayerGroupList", componentId: "sc-19uothl" }) `
4794
4829
  flex-direction: column;
4795
4830
  height: 100%;
4796
4831
  flex-wrap: nowrap;
@@ -4803,8 +4838,8 @@ const LayerGroupList = styled(uilibGl.Flex).withConfig({ displayName: "LayerGrou
4803
4838
  flex-grow: 1;
4804
4839
  }
4805
4840
  `;
4806
- const PresentationHeaderButtons = styled(uilibGl.Flex).withConfig({ displayName: "PresentationHeaderButtons", componentId: "sc-5xerc" }) ``;
4807
- const PresentationPanelContainer = styled.div.withConfig({ displayName: "PresentationPanelContainer", componentId: "sc-ok1jzl" }) `
4841
+ const PresentationHeaderButtons = styled(uilibGl.Flex).withConfig({ displayName: "PresentationHeaderButtons", componentId: "sc-c24t7n" }) ``;
4842
+ const PresentationPanelContainer = styled.div.withConfig({ displayName: "PresentationPanelContainer", componentId: "sc-17q0jzw" }) `
4808
4843
  position: absolute;
4809
4844
  top: 0;
4810
4845
  left: calc(${({ left }) => left || 0}px + 0.75rem);
@@ -4873,7 +4908,7 @@ const PresentationPanelContainer = styled.div.withConfig({ displayName: "Present
4873
4908
  }
4874
4909
  }
4875
4910
  `;
4876
- const DataSourceErrorContainer = styled(uilibGl.Flex).withConfig({ displayName: "DataSourceErrorContainer", componentId: "sc-16x60eq" }) `
4911
+ const DataSourceErrorContainer = styled(uilibGl.Flex).withConfig({ displayName: "DataSourceErrorContainer", componentId: "sc-nh93ry" }) `
4877
4912
  align-items: center;
4878
4913
  justify-content: center;
4879
4914
  flex-wrap: nowrap;
@@ -4892,12 +4927,12 @@ const DataSourceErrorContainer = styled(uilibGl.Flex).withConfig({ displayName:
4892
4927
  }
4893
4928
  }
4894
4929
  `;
4895
- const AttributeLabel = styled(uilibGl.Description).withConfig({ displayName: "AttributeLabel", componentId: "sc-1bou1dd" }) `
4930
+ const AttributeLabel = styled(uilibGl.Description).withConfig({ displayName: "AttributeLabel", componentId: "sc-9u3noy" }) `
4896
4931
  margin-top: 0 !important;
4897
4932
  margin-bottom: ${({ forCheckbox }) => forCheckbox ? "0.75rem" : "0.25rem"} !important;
4898
4933
  padding-left: ${({ isEdit }) => (isEdit ? "0.5rem" : "0")};
4899
4934
  `;
4900
- const FeatureControls = styled(uilibGl.Flex).withConfig({ displayName: "FeatureControls", componentId: "sc-fpl3fy" }) `
4935
+ const FeatureControls = styled(uilibGl.Flex).withConfig({ displayName: "FeatureControls", componentId: "sc-1wenq0r" }) `
4901
4936
  align-items: center;
4902
4937
  gap: 1rem;
4903
4938
  flex-wrap: nowrap;
@@ -6538,6 +6573,45 @@ const useContainerAttributes = ({ elementConfig, type, renderElement }) => {
6538
6573
  return { getRenderContainerItem, attributesToRender };
6539
6574
  };
6540
6575
 
6576
+ /**
6577
+ * Пропсы корневой обёртки контейнера: идентификаторы для внешних селекторов, авторский `style`
6578
+ * из конфига и css-объект размеров.
6579
+ *
6580
+ * Размеры уходят styled-пропом (класс), а не inline-стилем, поэтому перебиваются снаружи
6581
+ * без `!important`. Авторский `style` остаётся inline — у него приоритет по замыслу автора конфига.
6582
+ */
6583
+ const useWrapperSize = ({ elementConfig, defaults }) => {
6584
+ const { id, style, templateName, options } = elementConfig || {};
6585
+ const { width, height, overflow } = options || {};
6586
+ return React.useMemo(() => ({
6587
+ id,
6588
+ "data-templatename": templateName,
6589
+ style,
6590
+ $sizeCss: getWrapperSizeStyle({ style, width, height, overflow, defaults, defaultWidth: FILL_SIZE }),
6591
+ }), [id, templateName, style, width, height, overflow, defaults]);
6592
+ };
6593
+
6594
+ /**
6595
+ * Пропсы двух узлов контейнера с заголовком: корня (`ContainerRoot`) и тела.
6596
+ *
6597
+ * Контейнер обязан иметь ОДИН корневой узел — иначе в строке (`options.column: false`) заголовок
6598
+ * и тело становятся двумя ячейками родительского flex-row. Размеры из конфига поэтому уходят на
6599
+ * корень, а тело получает лишь остаток высоты под заголовком.
6600
+ */
6601
+ const useContainerRoot = ({ elementConfig, defaults }) => {
6602
+ const root = useWrapperSize({ elementConfig, defaults });
6603
+ // Гейт по РЕЗУЛЬТИРУЮЩЕЙ высоте, а не по `options.height`: высоту задаёт ещё и авторский `style`,
6604
+ // и внутренние `defaults` контейнера. `auto` высотой не считаем — делить нечего.
6605
+ const fillsHeight = !!root.$sizeCss?.height && root.$sizeCss.height !== "auto";
6606
+ return React.useMemo(() => ({
6607
+ root,
6608
+ body: {
6609
+ [CONTAINER_BODY_ATTRIBUTE]: "",
6610
+ $sizeCss: fillsHeight ? CONTAINER_BODY_FILL_STYLE : undefined,
6611
+ },
6612
+ }), [root, fillsHeight]);
6613
+ };
6614
+
6541
6615
  const useEditGroupAttributes = ({ elementConfig, type }) => {
6542
6616
  const { options } = elementConfig || {};
6543
6617
  const { controls, useProjectHiddenAttributes } = options || {};
@@ -7483,7 +7557,11 @@ const useExportPdf = (id, margin = 20) => {
7483
7557
  return;
7484
7558
  }
7485
7559
  setLoading(true);
7486
- const container = document.querySelector(`#${id}`);
7560
+ const target = document.querySelector(`#${id}`);
7561
+ // `#id` — корень контейнера, то есть пара «заголовок + тело». Постранично режем содержимое
7562
+ // тела: у самого корня детей всего два, и длинное тело уехало бы одной картинкой на первую
7563
+ // страницу. Fallback — для одноузловых целей вроде корня дашборда.
7564
+ const container = target?.querySelector(`:scope > [${CONTAINER_BODY_ATTRIBUTE}]`) ?? target;
7487
7565
  if (!container) {
7488
7566
  setLoading(false);
7489
7567
  return;
@@ -7867,32 +7945,14 @@ const useUpdateDataSource = ({ dataSource, config, filters, attributes, layerPar
7867
7945
  }, [dataSource, getDataSourcePromises, getUpdatedDataSources, dataSources]);
7868
7946
  };
7869
7947
 
7870
- /**
7871
- * Пропсы корневой обёртки контейнера: идентификаторы для внешних селекторов, авторский `style`
7872
- * из конфига и css-объект размеров.
7873
- *
7874
- * Размеры уходят styled-пропом (класс), а не inline-стилем, поэтому перебиваются снаружи
7875
- * без `!important`. Авторский `style` остаётся inline — у него приоритет по замыслу автора конфига.
7876
- */
7877
- const useWrapperSize = ({ elementConfig, defaults }) => {
7878
- const { id, style, templateName, options } = elementConfig || {};
7879
- const { width, height, overflow } = options || {};
7880
- return React.useMemo(() => ({
7881
- id,
7882
- "data-templatename": templateName,
7883
- style,
7884
- $sizeCss: getWrapperSizeStyle({ style, width, height, overflow, defaults, defaultWidth: FILL_SIZE }),
7885
- }), [id, templateName, style, width, height, overflow, defaults]);
7886
- };
7887
-
7888
7948
  const ContainersGroupContainer = React.memo(({ elementConfig, type, renderElement }) => {
7889
7949
  const { expandedContainers } = useWidgetContext(type);
7890
7950
  const { id, children, options } = elementConfig || {};
7891
7951
  const { column, expandable, expanded, alignItems } = options || {};
7892
7952
  const isColumn = column === undefined || column;
7893
7953
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
7894
- const root = useWrapperSize({ elementConfig });
7895
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...root, isColumn: isColumn, "$alignItems": alignItems, children: jsxRuntime.jsx(ContainerChildren, { type: type, items: children, elementConfig: elementConfig, isColumn: isColumn, isMain: id?.startsWith(CONFIG_PAGE_ID), renderElement: renderElement }) }))] }));
7954
+ const { root, body } = useContainerRoot({ elementConfig });
7955
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...body, isColumn: isColumn, "$alignItems": alignItems, children: jsxRuntime.jsx(ContainerChildren, { type: type, items: children, elementConfig: elementConfig, isColumn: isColumn, isMain: id?.startsWith(CONFIG_PAGE_ID), renderElement: renderElement }) }))] }));
7896
7956
  });
7897
7957
 
7898
7958
  const ChartLegendContainer = styled(uilibGl.Flex).withConfig({ displayName: "ChartLegendContainer", componentId: "sc-1di1zl9" }) `
@@ -8313,7 +8373,7 @@ const DataSourceProgressContainer = React.memo(({ config, elementConfig, type, i
8313
8373
  const { maxValue, showTotal, relatedDataSource, expandable, expanded } = options || {};
8314
8374
  const valueElement = children?.find(item => item.id === "value");
8315
8375
  const unitsElement = children?.find(item => item.id === "units");
8316
- const root = useWrapperSize({ elementConfig });
8376
+ const { root, body } = useContainerRoot({ elementConfig });
8317
8377
  const { sliceItems, checkIsSliced, showMore, onShowMore } = useShownOtherItems(options);
8318
8378
  const totalUnits = React.useMemo(() => unitsElement?.type === "attributeUnits"
8319
8379
  ? attributes?.find(({ attributeName }) => attributeName === unitsElement.attributeName)?.stringFormat
@@ -8344,7 +8404,7 @@ const DataSourceProgressContainer = React.memo(({ config, elementConfig, type, i
8344
8404
  return jsxRuntime.jsx(DataSourceError, { name: elementConfig.templateName });
8345
8405
  }
8346
8406
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
8347
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxRuntime.jsxs(DataSourceProgressContainerWrapper, { ...root, children: [sliceItems(dataSource?.features)?.map((feature, index) => (jsxRuntime.jsx(DataSourceInnerContainer, { type: type, index: index, feature: feature, config: config, elementConfig: elementConfig, maxValue: currentMaxValue, innerComponent: innerComponent }, index))), checkIsSliced(dataSource?.features) && (jsxRuntime.jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore ? t("hide", { ns: "dashboard", defaultValue: "Свернуть" }) : t("showAll", {
8407
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxRuntime.jsxs(DataSourceProgressContainerWrapper, { ...body, children: [sliceItems(dataSource?.features)?.map((feature, index) => (jsxRuntime.jsx(DataSourceInnerContainer, { type: type, index: index, feature: feature, config: config, elementConfig: elementConfig, maxValue: currentMaxValue, innerComponent: innerComponent }, index))), checkIsSliced(dataSource?.features) && (jsxRuntime.jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore ? t("hide", { ns: "dashboard", defaultValue: "Свернуть" }) : t("showAll", {
8348
8408
  ns: "dashboard",
8349
8409
  defaultValue: "Показать все",
8350
8410
  }) })), showTotal && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(uilibGl.Divider, {}), jsxRuntime.jsxs(ProgressTotal, { children: [jsxRuntime.jsx(ProgressTotalTitle, { children: t("total", { ns: "dashboard", defaultValue: "Итого" }) }), jsxRuntime.jsxs(ProgressValue, { children: [totalValue, jsxRuntime.jsx(ProgressUnits, { children: totalUnits })] })] })] }))] })) : (jsxRuntime.jsx(ContainerLoading, {})), jsxRuntime.jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type })] }));
@@ -8605,7 +8665,7 @@ const FiltersContainer = React.memo(({ elementConfig, config, type, renderElemen
8605
8665
  const { filters: configFilters } = currentPage;
8606
8666
  const { id, options } = elementConfig || {};
8607
8667
  const { padding, bgColor, fontColor, fontSize, expandable, expanded } = options || {};
8608
- const root = useWrapperSize({ elementConfig });
8668
+ const { root, body } = useContainerRoot({ elementConfig });
8609
8669
  const isLoading = React.useMemo(() => checkIsLoading(dataSources, config, configFilters), [configFilters, config, dataSources]);
8610
8670
  const filterItems = React.useMemo(() => elementConfig?.children?.filter(child => child.options?.filterName), [elementConfig?.children]);
8611
8671
  const renderFilter = React.useCallback((filter, index) => {
@@ -8614,7 +8674,7 @@ const FiltersContainer = React.memo(({ elementConfig, config, type, renderElemen
8614
8674
  }, [config, type]);
8615
8675
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
8616
8676
  const selectedItems = React.useMemo(() => getFilterSelectedItems(filterItems, filters, configFilters), [configFilters, filters, filterItems]);
8617
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(uilibGl.Flex, { mb: !isVisible && selectedItems.length ? "2rem" : 0, children: jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }) }), isLoading && jsxRuntime.jsx(ContainerLoading, {}), !isLoading && isVisible && (jsxRuntime.jsx(FiltersContainerWrapper, { ...root, "$padding": padding, "$bgColor": bgColor, "$fontSize": fontSize, "$fontColor": fontColor, children: filterItems?.map(renderFilter) })), jsxRuntime.jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type, filter: filterItems[0]?.options?.filterName })] }));
8677
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(uilibGl.Flex, { mb: !isVisible && selectedItems.length ? "2rem" : 0, children: jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }) }), isLoading && jsxRuntime.jsx(ContainerLoading, {}), !isLoading && isVisible && (jsxRuntime.jsx(FiltersContainerWrapper, { ...body, "$padding": padding, "$bgColor": bgColor, "$fontSize": fontSize, "$fontColor": fontColor, children: filterItems?.map(renderFilter) })), jsxRuntime.jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type, filter: filterItems[0]?.options?.filterName })] }));
8618
8678
  });
8619
8679
 
8620
8680
  const DefaultAttributesContainer = React.memo(({ type, renderElement }) => {
@@ -8622,26 +8682,6 @@ const DefaultAttributesContainer = React.memo(({ type, renderElement }) => {
8622
8682
  return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: attributes?.map(({ attributeName }) => (jsxRuntime.jsx(Container, { isColumn: true, children: renderElement({ id: attributeName }) }, attributeName))) }));
8623
8683
  });
8624
8684
 
8625
- const ChartContainerWrapper = styled(uilibGl.FlexSpan).withConfig({ displayName: "ChartContainerWrapper", componentId: "sc-17oj4lo" }) `
8626
- flex-direction: column;
8627
- min-width: 0;
8628
-
8629
- /* Заданная высота контейнера достаётся телу графика — за вычетом заголовка. */
8630
- ${({ $sizeCss }) => !!$sizeCss?.height &&
8631
- styled.css `
8632
- /* Раздача высоты требует, чтобы обёртка была flex-колонкой (FlexSpan сам по себе не flex),
8633
- иначе Container с flex:1 1 auto не растянется на заданную высоту, а fill-график не впишется по высоте. */
8634
- display: flex;
8635
-
8636
- > ${Container} {
8637
- flex: 1 1 auto;
8638
- min-height: 0;
8639
- }
8640
- `}
8641
-
8642
- ${sizeCssMixin};
8643
- `;
8644
-
8645
8685
  /**
8646
8686
  * Контекст вписывания графика (`options.fill` контейнера Chart).
8647
8687
  *
@@ -8659,7 +8699,7 @@ const ChartContainer = React.memo(({ elementConfig, isVisible, type, renderEleme
8659
8699
  const aliasElement = children.find(child => child.id === "alias");
8660
8700
  const chartElement = children.find(child => child.id === "chart");
8661
8701
  const legendElement = children.find(child => child.id === "legend");
8662
- const root = useWrapperSize({ elementConfig });
8702
+ const { root, body } = useContainerRoot({ elementConfig });
8663
8703
  const { data, loading } = useChartData({
8664
8704
  element: chartElement,
8665
8705
  type,
@@ -8670,7 +8710,7 @@ const ChartContainer = React.memo(({ elementConfig, isVisible, type, renderEleme
8670
8710
  const hasItems = !!data[0]?.items?.length;
8671
8711
  if (!loading && !hasItems && hideEmpty)
8672
8712
  return null;
8673
- return (jsxRuntime.jsxs(ChartContainerWrapper, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { isColumn: true, children: [aliasElement && jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { column: !twoColumns, alignItems: twoColumns && fill ? "stretch" : "center", "$fill": !!fill, children: hasItems ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ContainerChart, { "$fill": !!fill, children: jsxRuntime.jsx(FillContext.Provider, { value: fillContextValue, children: renderElement({ id: "chart" }) }) }), jsxRuntime.jsx(ContainerLegend, { justifyContent: legendElement?.options?.center ? "center" : "flex-start", children: renderElement({ id: "legend" }) })] })) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u2014" })) })] }))] }));
8713
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { ...body, isColumn: true, children: [aliasElement && jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { column: !twoColumns, alignItems: twoColumns && fill ? "stretch" : "center", "$fill": !!fill, children: hasItems ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ContainerChart, { "$fill": !!fill, children: jsxRuntime.jsx(FillContext.Provider, { value: fillContextValue, children: renderElement({ id: "chart" }) }) }), jsxRuntime.jsx(ContainerLegend, { justifyContent: legendElement?.options?.center ? "center" : "flex-start", children: renderElement({ id: "legend" }) })] })) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u2014" })) })] }))] }));
8674
8714
  });
8675
8715
 
8676
8716
  const PagesContainer = React.memo(({ type = exports.WidgetType.Dashboard, noBorders }) => {
@@ -8896,13 +8936,13 @@ const DataSourceContainer = React.memo(({ config, elementConfig, type, innerComp
8896
8936
  gap: gap ?? DEFAULT_TILE_GAP,
8897
8937
  });
8898
8938
  const defaults = React.useMemo(() => ({ height: isLoading ? "3rem" : "auto" }), [isLoading]);
8899
- const root = useWrapperSize({ elementConfig, defaults });
8939
+ const { root, body } = useContainerRoot({ elementConfig, defaults });
8900
8940
  if (!relatedDataSource)
8901
8941
  return null;
8902
8942
  if (dataSource && !dataSource.features) {
8903
8943
  return jsxRuntime.jsx(DataSourceError, { name: elementConfig.templateName });
8904
8944
  }
8905
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(DataSourceContainerWrapper, { ...root, ref: tilesRef, isColumn: column, "$isRow": !column, "$columns": columns, "$gap": gap, "$align": align, "$stretch": stretch, "$tileWidth": tileWidth, children: sliceItems(dataSource.features)?.map((feature, index) => (jsxRuntime.jsx(DataSourceInnerContainer, { index: index, type: type, config: config, feature: feature, elementConfig: elementConfig, innerComponent: innerComponent }, index))) }), checkIsSliced(dataSource.features) && (jsxRuntime.jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore
8945
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(DataSourceContainerWrapper, { ...body, ref: tilesRef, isColumn: column, "$isRow": !column, "$columns": columns, "$gap": gap, "$align": align, "$stretch": stretch, "$tileWidth": tileWidth, children: sliceItems(dataSource.features)?.map((feature, index) => (jsxRuntime.jsx(DataSourceInnerContainer, { index: index, type: type, config: config, feature: feature, elementConfig: elementConfig, innerComponent: innerComponent }, index))) }), checkIsSliced(dataSource.features) && (jsxRuntime.jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore
8906
8946
  ? t("hide", { ns: "dashboard", defaultValue: "Свернуть" })
8907
8947
  : t("showAll", { ns: "dashboard", defaultValue: "Показать все" }) }))] })) : (jsxRuntime.jsx(ContainerLoading, {}))] }));
8908
8948
  });
@@ -9062,7 +9102,7 @@ const SlideshowContainer = React.memo(({ config, elementConfig, type }) => {
9062
9102
  const { id, options } = elementConfig || {};
9063
9103
  const { expandable, expanded } = options || {};
9064
9104
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9065
- const root = useWrapperSize({ elementConfig });
9105
+ const { root, body } = useContainerRoot({ elementConfig });
9066
9106
  const render = React.useMemo(() => getRenderElement({
9067
9107
  config,
9068
9108
  elementConfig,
@@ -9088,11 +9128,11 @@ const SlideshowContainer = React.memo(({ config, elementConfig, type }) => {
9088
9128
  // Подпись `alias` не задают почти всегда — тогда обёртку не рендерим, чтобы в DOM не оставался
9089
9129
  // пустой блок, который вдобавок отъедал бы половину ширины у галереи (см. isColumn ниже).
9090
9130
  const aliasNode = render({ id: "alias" });
9091
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: render }), isVisible && (
9131
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: render }), isVisible && (
9092
9132
  // `isColumn`: подпись над галереей, а сама галерея на всю ширину. Без него Container
9093
9133
  // раскладывает alias и slideshow в ряд, и оба (Flex с `width: 100%`) сжимаются пополам —
9094
9134
  // картинка занимала лишь половину доступной ширины.
9095
- jsxRuntime.jsxs(Container, { ...root, isColumn: true, children: [aliasNode && jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: aliasNode }), jsxRuntime.jsx(ContainerValue, { children: render({
9135
+ jsxRuntime.jsxs(Container, { ...body, isColumn: true, children: [aliasNode && jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: aliasNode }), jsxRuntime.jsx(ContainerValue, { children: render({
9096
9136
  id: "slideshow",
9097
9137
  wrap: false,
9098
9138
  }) })] }))] }));
@@ -9103,8 +9143,8 @@ const CameraContainer = React.memo(({ elementConfig, type, renderElement }) => {
9103
9143
  const { id, options } = elementConfig || {};
9104
9144
  const { expandable, expanded } = options || {};
9105
9145
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9106
- const root = useWrapperSize({ elementConfig });
9107
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { ...root, children: [jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { children: renderElement({ id: "value", wrap: false }) })] }))] }));
9146
+ const { root, body } = useContainerRoot({ elementConfig });
9147
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { ...body, children: [jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { children: renderElement({ id: "value", wrap: false }) })] }))] }));
9108
9148
  });
9109
9149
 
9110
9150
  const TabAnchor = styled.div.withConfig({ displayName: "TabAnchor", componentId: "sc-emqf31" }) `
@@ -9524,7 +9564,7 @@ const LayersContainer = React.memo(({ type, elementConfig, renderElement }) => {
9524
9564
  const { id, options } = elementConfig || {};
9525
9565
  const { layerNames, expandable, expanded } = options || {};
9526
9566
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9527
- const root = useWrapperSize({ elementConfig });
9567
+ const { root, body } = useContainerRoot({ elementConfig });
9528
9568
  const layers = React.useMemo(() => {
9529
9569
  if (!currentPage?.layers)
9530
9570
  return [];
@@ -9532,7 +9572,7 @@ const LayersContainer = React.memo(({ type, elementConfig, renderElement }) => {
9532
9572
  return currentPage.layers;
9533
9573
  return currentPage.layers.filter(({ name }) => layerNames.includes(name));
9534
9574
  }, [currentPage?.layers, layerNames]);
9535
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(LayersContainerWrapper, { ...root, children: jsxRuntime.jsx(LayerTree, { layers: layers, onlyMainTools: true }) }))] }));
9575
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(LayersContainerWrapper, { ...body, children: jsxRuntime.jsx(LayerTree, { layers: layers, onlyMainTools: true }) }))] }));
9536
9576
  });
9537
9577
 
9538
9578
  const ExportPdfContainer = React.memo(({ type, elementConfig }) => {
@@ -9568,8 +9608,8 @@ const UploadContainer = React.memo(({ type, elementConfig, renderElement }) => {
9568
9608
  const { id, options } = elementConfig || {};
9569
9609
  const { expandable, expanded } = options || {};
9570
9610
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9571
- const root = useWrapperSize({ elementConfig });
9572
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(UploadContainerWrapper, { ...root, children: renderElement({ id: "uploader", wrap: false }) }))] }));
9611
+ const { root, body } = useContainerRoot({ elementConfig });
9612
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(UploadContainerWrapper, { ...body, children: renderElement({ id: "uploader", wrap: false }) }))] }));
9573
9613
  });
9574
9614
 
9575
9615
  const StatusBadge = styled(uilibGl.Chip).withConfig({ displayName: "StatusBadge", componentId: "sc-1xmfl10" }) `
@@ -9789,7 +9829,7 @@ const TaskContainer = React.memo(({ type, elementConfig, renderElement }) => {
9789
9829
  const { taskId, runTask, stopTask, status, openLog, loading, isLogDialogOpen, closeLog, log, lastMessage, result, } = usePythonTask();
9790
9830
  const { options } = elementConfig || {};
9791
9831
  const { title, relatedResources, center, icon, statusColors, responseFilters, useNotifications, } = options || {};
9792
- const root = useWrapperSize({ elementConfig });
9832
+ const { root, body } = useContainerRoot({ elementConfig });
9793
9833
  const { setNotificationDismissed } = useTaskNotifications({
9794
9834
  enabled: !!useNotifications,
9795
9835
  suppressed: isLogDialogOpen,
@@ -9829,12 +9869,12 @@ const TaskContainer = React.memo(({ type, elementConfig, renderElement }) => {
9829
9869
  return runTask({ resourceId, parameters: newParams, script, fileName, methodName });
9830
9870
  }));
9831
9871
  }, [attributes, currentPage.filters, dataSources, ewktGeometry, layerInfo, projectDataSources, relatedResources, runTask, selectedFilters, stopTask, taskId]);
9832
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxRuntime.jsxs(TaskContainerWrapper, { ...root, justifyContent: center ? "center" : "flex-start", children: [jsxRuntime.jsx(StatusWaitingButton, { title: title || t("run", { ns: "dashboard", defaultValue: "Запуск" }), icon: icon, status: status, statusColors: statusColors, isWaiting: loading || !!taskId, isDisabled: !relatedResources?.length, onClick: onClick }), !!(log || taskId) && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(uilibGl.IconButton, { kind: "info", onClick: openLog }), jsxRuntime.jsx(LogDialog, { logs: log, status: status, statusColors: statusColors, isOpen: isLogDialogOpen, onClose: onCloseLog, onMinimize: useNotifications ? onMinimizeLog : undefined })] }))] })] }));
9872
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxRuntime.jsxs(TaskContainerWrapper, { ...body, justifyContent: center ? "center" : "flex-start", children: [jsxRuntime.jsx(StatusWaitingButton, { title: title || t("run", { ns: "dashboard", defaultValue: "Запуск" }), icon: icon, status: status, statusColors: statusColors, isWaiting: loading || !!taskId, isDisabled: !relatedResources?.length, onClick: onClick }), !!(log || taskId) && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(uilibGl.IconButton, { kind: "info", onClick: openLog }), jsxRuntime.jsx(LogDialog, { logs: log, status: status, statusColors: statusColors, isOpen: isLogDialogOpen, onClose: onCloseLog, onMinimize: useNotifications ? onMinimizeLog : undefined })] }))] })] }));
9833
9873
  });
9834
9874
 
9835
9875
  const EditContainer = ({ type, elementConfig, renderElement }) => {
9836
- const { id, style } = elementConfig || {};
9837
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: style, children: [jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { children: renderElement({ id: "value" }) })] })] }));
9876
+ const { root, body } = useContainerRoot({ elementConfig });
9877
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxRuntime.jsxs(Container, { ...body, isColumn: true, children: [jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { children: renderElement({ id: "value" }) })] })] }));
9838
9878
  };
9839
9879
 
9840
9880
  const getControlTemplateName = (type) => {
@@ -10571,7 +10611,7 @@ const AttachmentContainer = React.memo(({ type, elementConfig, renderElement })
10571
10611
  const { items, visibleItems, viewMode, setViewMode, showMore, setShowMore, hasMore, hiddenCount } = useAttachmentContainer({ type, elementConfig });
10572
10612
  const { id, options } = elementConfig || {};
10573
10613
  const { expandable, expanded } = options || {};
10574
- const root = useWrapperSize({ elementConfig, defaults: BASE_CONTAINER_STYLE });
10614
+ const { root, body } = useContainerRoot({ elementConfig, defaults: BASE_CONTAINER_STYLE });
10575
10615
  const [previewIndex, setPreviewIndex] = React.useState(null);
10576
10616
  const previewImages = useAttachmentPreviewImages({ items, active: previewIndex !== null });
10577
10617
  const handlePreview = React.useCallback((link) => {
@@ -10582,7 +10622,7 @@ const AttachmentContainer = React.memo(({ type, elementConfig, renderElement })
10582
10622
  const handleClosePreview = React.useCallback(() => setPreviewIndex(null), []);
10583
10623
  const handleShowMore = React.useCallback(() => setShowMore(true), [setShowMore]);
10584
10624
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
10585
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...root, children: jsxRuntime.jsxs(uilibGl.Flex, { column: true, children: [jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: false, onPreview: handlePreview })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: false, onPreview: handlePreview })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview, errorTitleText: t("attachments.resourceUnavailable", {
10625
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...body, children: jsxRuntime.jsxs(uilibGl.Flex, { column: true, children: [jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: false, onPreview: handlePreview })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: false, onPreview: handlePreview })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview, errorTitleText: t("attachments.resourceUnavailable", {
10586
10626
  ns: "common",
10587
10627
  defaultValue: "Ресурс недоступен",
10588
10628
  }) }, previewIndex))] }) }))] }));
@@ -15225,6 +15265,8 @@ exports.CHART_TYPES = CHART_TYPES;
15225
15265
  exports.COMPACT_FRACTION_DIGITS = COMPACT_FRACTION_DIGITS;
15226
15266
  exports.CONFIG_PAGES_ID = CONFIG_PAGES_ID;
15227
15267
  exports.CONFIG_PAGE_ID = CONFIG_PAGE_ID;
15268
+ exports.CONTAINER_BODY_ATTRIBUTE = CONTAINER_BODY_ATTRIBUTE;
15269
+ exports.CONTAINER_BODY_FILL_STYLE = CONTAINER_BODY_FILL_STYLE;
15228
15270
  exports.CameraContainer = CameraContainer;
15229
15271
  exports.Chart = Chart;
15230
15272
  exports.ChartContainer = ChartContainer;
@@ -15233,6 +15275,7 @@ exports.ChartLoading = ChartLoading;
15233
15275
  exports.Container = Container;
15234
15276
  exports.ContainerChildren = ContainerChildren;
15235
15277
  exports.ContainerLoading = ContainerLoading;
15278
+ exports.ContainerRoot = ContainerRoot;
15236
15279
  exports.ContainerWrapper = ContainerWrapper;
15237
15280
  exports.ContainersGroupContainer = ContainersGroupContainer;
15238
15281
  exports.DEFAULT_ATTRIBUTE_NAME = DEFAULT_ATTRIBUTE_NAME;
@@ -15526,6 +15569,7 @@ exports.useBeforeSave = useBeforeSave;
15526
15569
  exports.useChartChange = useChartChange;
15527
15570
  exports.useChartData = useChartData;
15528
15571
  exports.useContainerAttributes = useContainerAttributes;
15572
+ exports.useContainerRoot = useContainerRoot;
15529
15573
  exports.useCurrentPageLayers = useCurrentPageLayers;
15530
15574
  exports.useCustomFeatureSelect = useCustomFeatureSelect;
15531
15575
  exports.useDashboardHeader = useDashboardHeader;