@evergis/react 4.0.104 → 4.0.105
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.
- package/dist/components/Dashboard/componentTypes.d.ts +3 -3
- package/dist/components/Dashboard/components/TextTrim/index.d.ts +1 -0
- package/dist/components/Dashboard/components/TextTrim/styled.d.ts +4 -0
- package/dist/components/Dashboard/containers/DataSourceContainer/constants.d.ts +7 -0
- package/dist/components/Dashboard/containers/DataSourceContainer/styled.d.ts +7 -12
- package/dist/components/Dashboard/containers/FiltersContainer/components/ChipsFilter.styled.d.ts +2 -1
- package/dist/components/Dashboard/containers/RoundedBackgroundContainer/styled.d.ts +1 -0
- package/dist/components/Dashboard/containers/TitleContainer/styled.d.ts +2 -2
- package/dist/components/Dashboard/hooks/index.d.ts +1 -0
- package/dist/components/Dashboard/hooks/useEqualTileWidth.d.ts +13 -0
- package/dist/components/Dashboard/types.d.ts +17 -2
- package/dist/components/Layer/types.d.ts +2 -2
- package/dist/core/classification/getLayerClientStyle.d.ts +3 -0
- package/dist/core/classification/index.d.ts +1 -0
- package/dist/index.js +223 -188
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +221 -189
- package/dist/react.esm.js.map +1 -1
- package/dist/types/styling.d.ts +6 -20
- package/package.json +2 -3
package/dist/index.js
CHANGED
|
@@ -3402,6 +3402,11 @@ const asResourceId = (value) => value;
|
|
|
3402
3402
|
const CHART_TYPES = ["bar", "line", "pie", "stack"];
|
|
3403
3403
|
/** Выравнивание текста/блоков. */
|
|
3404
3404
|
const ALIGNMENTS = ["left", "center", "right"];
|
|
3405
|
+
/**
|
|
3406
|
+
* Выравнивание плиток контейнера DataSource+RoundedBackground: к базовым `left/center/right`
|
|
3407
|
+
* добавлен режим `stretch` — плитки строки растягиваются на всю ширину (ТЗ 9.4/9.5).
|
|
3408
|
+
*/
|
|
3409
|
+
const TILE_ALIGNMENTS = ["left", "center", "right", "stretch"];
|
|
3405
3410
|
/** Выравнивание детей контейнера по поперечной оси (CSS `align-items`). */
|
|
3406
3411
|
const ALIGN_ITEMS = ["flex-start", "center", "flex-end", "stretch", "baseline"];
|
|
3407
3412
|
/** Масштабирование изображения внутри своего бокса (CSS `object-fit`). */
|
|
@@ -7219,6 +7224,56 @@ const useDiffPage = (type) => {
|
|
|
7219
7224
|
return React.useMemo(() => isDiffPage, [isDiffPage]);
|
|
7220
7225
|
};
|
|
7221
7226
|
|
|
7227
|
+
/**
|
|
7228
|
+
* Уравнивает ширину всех плиток контейнера по самой широкой.
|
|
7229
|
+
*
|
|
7230
|
+
* Натуральная ширина каждой плитки измеряется через временное inline `width: max-content`
|
|
7231
|
+
* (снимает применённое ограничение `--tile-width`, поэтому замер устойчив к динамике данных и не
|
|
7232
|
+
* зацикливает ResizeObserver — итоговый максимум совпадает с уже применённым). Возвращаемое число
|
|
7233
|
+
* контейнер прокидывает в CSS-переменную `--tile-width`, которую читает каждая плитка.
|
|
7234
|
+
*
|
|
7235
|
+
* `enabled: false` (режим «Растянуть», «В столбец» или старые конфиги без `columns`) полностью
|
|
7236
|
+
* отключает измерение — ширина берётся из grid-ячейки.
|
|
7237
|
+
*/
|
|
7238
|
+
const useEqualTileWidth = (enabled, itemsCount) => {
|
|
7239
|
+
const ref = React.useRef(null);
|
|
7240
|
+
const [width, setWidth] = React.useState();
|
|
7241
|
+
const measure = React.useCallback(() => {
|
|
7242
|
+
const node = ref.current;
|
|
7243
|
+
if (!node)
|
|
7244
|
+
return;
|
|
7245
|
+
const tiles = Array.from(node.querySelectorAll("[data-tile]"));
|
|
7246
|
+
if (!tiles.length)
|
|
7247
|
+
return;
|
|
7248
|
+
tiles.forEach(tile => {
|
|
7249
|
+
tile.style.width = "max-content";
|
|
7250
|
+
});
|
|
7251
|
+
let max = 0;
|
|
7252
|
+
tiles.forEach(tile => {
|
|
7253
|
+
max = Math.max(max, tile.getBoundingClientRect().width);
|
|
7254
|
+
});
|
|
7255
|
+
tiles.forEach(tile => {
|
|
7256
|
+
tile.style.width = "";
|
|
7257
|
+
});
|
|
7258
|
+
const next = Math.ceil(max);
|
|
7259
|
+
setWidth(previous => (max && previous !== next ? next : previous));
|
|
7260
|
+
}, []);
|
|
7261
|
+
React.useEffect(() => {
|
|
7262
|
+
if (!enabled) {
|
|
7263
|
+
setWidth(undefined);
|
|
7264
|
+
return;
|
|
7265
|
+
}
|
|
7266
|
+
const node = ref.current;
|
|
7267
|
+
if (!node)
|
|
7268
|
+
return;
|
|
7269
|
+
measure();
|
|
7270
|
+
const observer = new ResizeObserver(() => measure());
|
|
7271
|
+
observer.observe(node);
|
|
7272
|
+
return () => observer.disconnect();
|
|
7273
|
+
}, [enabled, itemsCount, measure]);
|
|
7274
|
+
return [ref, enabled ? width : undefined];
|
|
7275
|
+
};
|
|
7276
|
+
|
|
7222
7277
|
const SAVE_HOOK_RESULT_DURATION = 4000;
|
|
7223
7278
|
const NOTIFICATION_ID_RADIX = 36;
|
|
7224
7279
|
const NOTIFICATION_ID_LENGTH = 8;
|
|
@@ -8686,33 +8741,70 @@ const IconContainer = React.memo(({ elementConfig, renderElement }) => {
|
|
|
8686
8741
|
return (jsxRuntime.jsxs(IconContainerWrapper, { id: id, style: style, children: [jsxRuntime.jsxs(IconContainerHeaderWrapper, { children: [jsxRuntime.jsxs(IconContainerHeader, { children: [renderElement({ id: "icon" }), jsxRuntime.jsx(IconContainerTitle, { children: renderElement({ id: "alias" }) })] }), renderElement({ id: "link" })] }), jsxRuntime.jsx(IconContainerText, { children: renderElement({ id: "text" }) })] }));
|
|
8687
8742
|
});
|
|
8688
8743
|
|
|
8689
|
-
/**
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
8695
|
-
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
|
|
8699
|
-
|
|
8744
|
+
/** Дефолтный внутренний отступ между плитками, px (ТЗ §11). */
|
|
8745
|
+
const DEFAULT_TILE_GAP = 8;
|
|
8746
|
+
/** Раскладка ряда плиток (grid `justify-content`) для не-`stretch` выравнивания. */
|
|
8747
|
+
const ROW_JUSTIFY = {
|
|
8748
|
+
left: "start",
|
|
8749
|
+
center: "center",
|
|
8750
|
+
right: "end",
|
|
8751
|
+
stretch: "stretch",
|
|
8752
|
+
};
|
|
8753
|
+
/** Горизонтальное положение плитки в режиме «В столбец» (CSS `align-items`). */
|
|
8754
|
+
const COLUMN_ALIGN_ITEMS = {
|
|
8755
|
+
left: "flex-start",
|
|
8756
|
+
center: "center",
|
|
8757
|
+
right: "flex-end",
|
|
8758
|
+
stretch: "stretch",
|
|
8759
|
+
};
|
|
8760
|
+
|
|
8700
8761
|
const DataSourceContainerWrapper = styled(Container).withConfig({ displayName: "DataSourceContainerWrapper", componentId: "sc-1xnd27m" }) `
|
|
8701
|
-
${({ $
|
|
8702
|
-
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
|
|
8706
|
-
|
|
8762
|
+
${({ $tileWidth }) => $tileWidth != null && `--tile-width: ${$tileWidth}px;`}
|
|
8763
|
+
|
|
8764
|
+
${({ $isRow, $columns, $gap, $align, $stretch }) => {
|
|
8765
|
+
if ($isRow) {
|
|
8766
|
+
if ($columns) {
|
|
8767
|
+
return styled.css `
|
|
8768
|
+
display: grid;
|
|
8769
|
+
grid-template-columns: repeat(${$columns}, ${$stretch ? "minmax(0, 1fr)" : "auto"});
|
|
8770
|
+
justify-content: ${$stretch ? "stretch" : ROW_JUSTIFY[$align ?? "left"]};
|
|
8771
|
+
align-items: stretch;
|
|
8772
|
+
gap: ${$gap ?? DEFAULT_TILE_GAP}px;
|
|
8773
|
+
`;
|
|
8774
|
+
}
|
|
8775
|
+
return styled.css `
|
|
8776
|
+
flex-wrap: wrap;
|
|
8777
|
+
justify-content: flex-start;
|
|
8778
|
+
gap: ${$gap != null ? `${$gap}px` : "0.5rem"};
|
|
8779
|
+
`;
|
|
8780
|
+
}
|
|
8781
|
+
return styled.css `
|
|
8782
|
+
align-items: ${$stretch ? "stretch" : COLUMN_ALIGN_ITEMS[$align ?? "left"]};
|
|
8783
|
+
|
|
8784
|
+
> * {
|
|
8785
|
+
width: ${$stretch ? "100%" : "auto"};
|
|
8786
|
+
}
|
|
8787
|
+
|
|
8788
|
+
/* Вертикальный отступ между плитками в столбце — настраиваемый gap (ТЗ §7): переопределяем
|
|
8789
|
+
фикс. margin-bottom 0.5rem, который навешивает детям база Container(isColumn). */
|
|
8790
|
+
&& > *:not(:last-child) {
|
|
8791
|
+
margin-bottom: ${$gap != null ? `${$gap}px` : `${DEFAULT_TILE_GAP}px`};
|
|
8792
|
+
}
|
|
8793
|
+
`;
|
|
8794
|
+
}};
|
|
8707
8795
|
`;
|
|
8708
8796
|
|
|
8709
8797
|
const DataSourceContainer = React.memo(({ config, elementConfig, type, innerComponent, renderElement }) => {
|
|
8798
|
+
const { t } = useGlobalContext();
|
|
8710
8799
|
const { dataSources, expandedContainers } = useWidgetContext(type);
|
|
8711
8800
|
const { id, options } = elementConfig || {};
|
|
8712
|
-
const { column = true, relatedDataSource, expandable, expanded } = options || {};
|
|
8801
|
+
const { column = true, relatedDataSource, expandable, expanded, columns, gap, align } = options || {};
|
|
8713
8802
|
const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
|
|
8803
|
+
const { sliceItems, checkIsSliced, showMore, onShowMore } = useShownOtherItems(options);
|
|
8714
8804
|
const dataSource = React.useMemo(() => dataSources?.find(({ name }) => name === relatedDataSource), [dataSources, relatedDataSource]);
|
|
8715
8805
|
const isLoading = !dataSource?.features;
|
|
8806
|
+
const stretch = align === "stretch";
|
|
8807
|
+
const [tilesRef, tileWidth] = useEqualTileWidth(!column && !!columns && !stretch, dataSource?.features?.length ?? 0);
|
|
8716
8808
|
const defaults = React.useMemo(() => ({ height: isLoading ? "3rem" : "auto" }), [isLoading]);
|
|
8717
8809
|
const root = useWrapperSize({ elementConfig, defaults });
|
|
8718
8810
|
if (!relatedDataSource)
|
|
@@ -8720,7 +8812,9 @@ const DataSourceContainer = React.memo(({ config, elementConfig, type, innerComp
|
|
|
8720
8812
|
if (dataSource && !dataSource.features) {
|
|
8721
8813
|
return jsxRuntime.jsx(DataSourceError, { name: elementConfig.templateName });
|
|
8722
8814
|
}
|
|
8723
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxRuntime.jsx(DataSourceContainerWrapper, { ...root, isColumn: column, "$isRow": !column, children: dataSource.features?.map((feature, index) => (jsxRuntime.jsx(DataSourceInnerContainer, { index: index, type: type, config: config, feature: feature, elementConfig: elementConfig, innerComponent: innerComponent }, index))) }))
|
|
8815
|
+
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
|
|
8816
|
+
? t("hide", { ns: "dashboard", defaultValue: "Свернуть" })
|
|
8817
|
+
: t("showAll", { ns: "dashboard", defaultValue: "Показать все" }) }))] })) : (jsxRuntime.jsx(ContainerLoading, {}))] }));
|
|
8724
8818
|
});
|
|
8725
8819
|
|
|
8726
8820
|
const SvgContainerColorMixin = styled.css `
|
|
@@ -8743,11 +8837,11 @@ const SvgContainer = styled.div.withConfig({ displayName: "SvgContainer", compon
|
|
|
8743
8837
|
}
|
|
8744
8838
|
`;
|
|
8745
8839
|
|
|
8746
|
-
/** Выравнивание заголовка по горизонтали — в терминах flex-раскладки. */
|
|
8747
8840
|
const ALIGN_TO_JUSTIFY = {
|
|
8748
8841
|
left: "flex-start",
|
|
8749
8842
|
center: "center",
|
|
8750
8843
|
right: "flex-end",
|
|
8844
|
+
stretch: "flex-start",
|
|
8751
8845
|
};
|
|
8752
8846
|
const ContainerIconTitle = styled(uilibGl.Flex).withConfig({ displayName: "ContainerIconTitle", componentId: "sc-1jfnkqo" }) `
|
|
8753
8847
|
/* inline-flex, а не блочный flex во всю ширину: иначе text-align родителя игнорируется. */
|
|
@@ -9025,16 +9119,14 @@ const ContainerIconValue = styled(uilibGl.Flex).withConfig({ displayName: "Conta
|
|
|
9025
9119
|
const RoundedBackgroundContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName: "RoundedBackgroundContainerWrapper", componentId: "sc-a1l8h3" }) `
|
|
9026
9120
|
position: relative;
|
|
9027
9121
|
flex-direction: ${({ $bigIcon }) => ($bigIcon ? "row" : "column")};
|
|
9028
|
-
width: 9rem;
|
|
9122
|
+
width: ${({ $fillWidth }) => ($fillWidth ? "var(--tile-width, 100%)" : "9rem")};
|
|
9123
|
+
height: 100%;
|
|
9124
|
+
box-sizing: border-box;
|
|
9029
9125
|
padding: 0.75rem 0.75rem 0.5rem;
|
|
9030
9126
|
background-color: ${({ theme: { palette } }) => palette.element};
|
|
9031
9127
|
border-radius: ${({ theme: { borderRadius } }) => borderRadius.large};
|
|
9032
9128
|
flex-wrap: nowrap;
|
|
9033
9129
|
|
|
9034
|
-
&& {
|
|
9035
|
-
margin-bottom: 0.5rem;
|
|
9036
|
-
}
|
|
9037
|
-
|
|
9038
9130
|
${({ $center }) => $center &&
|
|
9039
9131
|
styled.css `
|
|
9040
9132
|
align-items: center;
|
|
@@ -9051,7 +9143,7 @@ const RoundedBackgroundContainerWrapper = styled(uilibGl.Flex).withConfig({ disp
|
|
|
9051
9143
|
styled.css `
|
|
9052
9144
|
background-color: ${transparentizeColor($color, 6)};
|
|
9053
9145
|
|
|
9054
|
-
|
|
9146
|
+
${ContainerValue}, ${ContainerUnits}, ${ContainerAlias} {
|
|
9055
9147
|
color: ${$color};
|
|
9056
9148
|
fill: ${$color};
|
|
9057
9149
|
}
|
|
@@ -9111,11 +9203,13 @@ const RoundedBackgroundContainerWrapper = styled(uilibGl.Flex).withConfig({ disp
|
|
|
9111
9203
|
}
|
|
9112
9204
|
|
|
9113
9205
|
${ContainerAlias} {
|
|
9114
|
-
margin-top:
|
|
9206
|
+
margin-top: auto;
|
|
9207
|
+
padding-top: 0.25rem;
|
|
9115
9208
|
}
|
|
9116
9209
|
`;
|
|
9117
9210
|
|
|
9118
9211
|
const ALIAS_DEFAULT_MAX_LENGTH = 28;
|
|
9212
|
+
const DESCRIPTION_DEFAULT_MAX_LINES = 2;
|
|
9119
9213
|
const RoundedBackgroundContainer = React.memo(({ type, elementConfig, feature, renderElement, }) => {
|
|
9120
9214
|
const { t } = useGlobalContext();
|
|
9121
9215
|
const { dataSources, attributes: ctxAttributes } = useWidgetContext(type);
|
|
@@ -9127,7 +9221,7 @@ const RoundedBackgroundContainer = React.memo(({ type, elementConfig, feature, r
|
|
|
9127
9221
|
});
|
|
9128
9222
|
const attributes = lodash.isEmpty(dsAttributes) ? ctxAttributes : dsAttributes;
|
|
9129
9223
|
const { id, options, style, children } = elementConfig || {};
|
|
9130
|
-
const { maxLength, wordBreak, center, fontColor, innerTemplateStyle, inlineUnits, big, bigIcon, hideEmpty, colorAttribute } = options || {};
|
|
9224
|
+
const { maxLength, maxLines, wordBreak, center, fontColor, innerTemplateStyle, inlineUnits, big, bigIcon, hideEmpty, colorAttribute, columns } = options || {};
|
|
9131
9225
|
const iconElement = children?.find(item => item.id === "icon");
|
|
9132
9226
|
const aliasElement = children?.find(item => item.id === "alias");
|
|
9133
9227
|
const unitsElement = children?.find(item => item.id === "units");
|
|
@@ -9146,11 +9240,35 @@ const RoundedBackgroundContainer = React.memo(({ type, elementConfig, feature, r
|
|
|
9146
9240
|
return null;
|
|
9147
9241
|
return (jsxRuntime.jsx(uilibGl.FlexSpan, { width: iconElement.options?.width || "1rem", alignItems: "center", mr: "0.5rem", children: renderElement({ id: "icon", wrap: false }) }));
|
|
9148
9242
|
}, [iconElement, renderElement]);
|
|
9149
|
-
const
|
|
9150
|
-
|
|
9243
|
+
const aliasAttribute = React.useMemo(() => aliasElement && !aliasElement.type && aliasElement.attributeName
|
|
9244
|
+
? attributes.find(({ attributeName }) => attributeName === aliasElement.attributeName)
|
|
9245
|
+
: undefined, [attributes, aliasElement]);
|
|
9246
|
+
const aliasContent = React.useMemo(() => aliasAttribute
|
|
9247
|
+
? formatAttributeValue({
|
|
9248
|
+
t,
|
|
9249
|
+
type: aliasAttribute.type,
|
|
9250
|
+
value: aliasAttribute.value,
|
|
9251
|
+
stringFormat: aliasAttribute.stringFormat,
|
|
9252
|
+
noUnits: true,
|
|
9253
|
+
})
|
|
9254
|
+
: renderElement({ id: "alias", wrap: false }), [aliasAttribute, t, renderElement]);
|
|
9255
|
+
const renderAlias = React.useMemo(() => (jsxRuntime.jsx(ContainerAlias, { style: aliasElement?.style, children: jsxRuntime.jsx(TextTrim, { maxLength: maxLength || ALIAS_DEFAULT_MAX_LENGTH, maxLines: maxLines ?? (columns ? DESCRIPTION_DEFAULT_MAX_LINES : undefined), wordBreak: wordBreak, children: aliasContent }) })), [aliasElement?.style, maxLength, maxLines, columns, aliasContent, wordBreak]);
|
|
9256
|
+
const unitsAttribute = React.useMemo(() => unitsElement && !unitsElement.type && unitsElement.attributeName
|
|
9257
|
+
? attributes.find(({ attributeName }) => attributeName === unitsElement.attributeName)
|
|
9258
|
+
: undefined, [attributes, unitsElement]);
|
|
9259
|
+
const unitsContent = React.useMemo(() => unitsAttribute
|
|
9260
|
+
? formatAttributeValue({
|
|
9261
|
+
t,
|
|
9262
|
+
type: unitsAttribute.type,
|
|
9263
|
+
value: unitsAttribute.value,
|
|
9264
|
+
stringFormat: unitsAttribute.stringFormat,
|
|
9265
|
+
noUnits: true,
|
|
9266
|
+
})
|
|
9267
|
+
: renderElement({ id: "units" }), [unitsAttribute, t, renderElement]);
|
|
9268
|
+
const renderValue = React.useMemo(() => lodash.isNil(value) ? null : (jsxRuntime.jsxs(ContainerValue, { style: valueElement?.style, big: true, children: [value, !!unitsElement && (jsxRuntime.jsx(ContainerUnits, { style: unitsElement?.style, children: unitsContent }))] })), [valueElement?.style, value, unitsElement, unitsContent]);
|
|
9151
9269
|
if (lodash.isNil(value) && hideEmpty)
|
|
9152
9270
|
return null;
|
|
9153
|
-
return (jsxRuntime.jsxs(RoundedBackgroundContainerWrapper, { id: id, style: innerTemplateStyle || style, "$center": center, "$color": color, "$inlineUnits": inlineUnits, "$big": big, "$bigIcon": bigIcon, children: [jsxRuntime.jsxs(ContainerIconValue, { children: [renderIcon, big ? renderAlias : renderValue] }), big ? renderValue : renderAlias] }));
|
|
9271
|
+
return (jsxRuntime.jsxs(RoundedBackgroundContainerWrapper, { id: id, "data-tile": true, style: innerTemplateStyle || style, "$center": center !== false, "$color": color, "$inlineUnits": inlineUnits, "$big": big, "$bigIcon": bigIcon, "$fillWidth": !!columns, children: [jsxRuntime.jsxs(ContainerIconValue, { children: [renderIcon, big ? renderAlias : renderValue] }), big ? renderValue : renderAlias] }));
|
|
9154
9272
|
});
|
|
9155
9273
|
|
|
9156
9274
|
const AddFeatureContainer = React.memo(({ elementConfig }) => {
|
|
@@ -9425,23 +9543,16 @@ exports.EditGeometryType = void 0;
|
|
|
9425
9543
|
|
|
9426
9544
|
exports.StyligClassificationTypes = void 0;
|
|
9427
9545
|
(function (StyligClassificationTypes) {
|
|
9428
|
-
StyligClassificationTypes["FillColor"] = "fill";
|
|
9429
|
-
StyligClassificationTypes["
|
|
9430
|
-
StyligClassificationTypes["
|
|
9431
|
-
StyligClassificationTypes["
|
|
9432
|
-
StyligClassificationTypes["
|
|
9546
|
+
StyligClassificationTypes["FillColor"] = "fill-color";
|
|
9547
|
+
StyligClassificationTypes["FillExtrusionColor"] = "fill-extrusion-color";
|
|
9548
|
+
StyligClassificationTypes["CircleColor"] = "circle-color";
|
|
9549
|
+
StyligClassificationTypes["LineColor"] = "line-color";
|
|
9550
|
+
StyligClassificationTypes["CircleStrokeColor"] = "circle-stroke-color";
|
|
9433
9551
|
StyligClassificationTypes["CircleRadius"] = "circle-radius";
|
|
9434
9552
|
StyligClassificationTypes["CircleStrokeWidth"] = "circle-stroke-width";
|
|
9435
9553
|
StyligClassificationTypes["LineWidth"] = "line-width";
|
|
9436
|
-
StyligClassificationTypes["PolygonStrokeWidth"] = "polygon-stroke-width";
|
|
9437
9554
|
StyligClassificationTypes["CircleBlur"] = "circle-blur";
|
|
9438
9555
|
StyligClassificationTypes["LineBlur"] = "line-blur";
|
|
9439
|
-
StyligClassificationTypes["PolygonStrokeBlur"] = "polygon-stroke-blur";
|
|
9440
|
-
StyligClassificationTypes["FillOpacity"] = "fill-opacity";
|
|
9441
|
-
StyligClassificationTypes["CircleOpacity"] = "circle-opacity";
|
|
9442
|
-
StyligClassificationTypes["LineOpacity"] = "line-opacity";
|
|
9443
|
-
StyligClassificationTypes["PolygonStrokeOpacity"] = "polygon-stroke-opacity";
|
|
9444
|
-
StyligClassificationTypes["CircleTranslate"] = "circle-translate";
|
|
9445
9556
|
})(exports.StyligClassificationTypes || (exports.StyligClassificationTypes = {}));
|
|
9446
9557
|
|
|
9447
9558
|
const StyledButton = styled(uilibGl.FlatButton).withConfig({ displayName: "StyledButton", componentId: "sc-13r9ztd" }) `
|
|
@@ -9497,7 +9608,7 @@ const buildFiltersFromResponse = (responseFilters, result) => {
|
|
|
9497
9608
|
return Object.keys(filters).length ? filters : null;
|
|
9498
9609
|
};
|
|
9499
9610
|
|
|
9500
|
-
const ClampedText = styled.div.withConfig({ displayName: "ClampedText", componentId: "sc-138git7" }) `
|
|
9611
|
+
const ClampedText$1 = styled.div.withConfig({ displayName: "ClampedText", componentId: "sc-138git7" }) `
|
|
9501
9612
|
display: -webkit-box;
|
|
9502
9613
|
-webkit-line-clamp: 2;
|
|
9503
9614
|
-webkit-box-orient: vertical;
|
|
@@ -9505,7 +9616,7 @@ const ClampedText = styled.div.withConfig({ displayName: "ClampedText", componen
|
|
|
9505
9616
|
text-overflow: ellipsis;
|
|
9506
9617
|
word-break: break-word;
|
|
9507
9618
|
`;
|
|
9508
|
-
const clampDescription = (text) => React.createElement(ClampedText, null, text);
|
|
9619
|
+
const clampDescription = (text) => React.createElement(ClampedText$1, null, text);
|
|
9509
9620
|
|
|
9510
9621
|
const RUN_ID_RADIX = 36;
|
|
9511
9622
|
const RUN_ID_LENGTH = 8;
|
|
@@ -14420,6 +14531,13 @@ const ExpandableTitle = React.memo(({ elementConfig, type, renderElement }) => {
|
|
|
14420
14531
|
const titleElement = children?.find(item => item.id === "title");
|
|
14421
14532
|
if (!titleElement)
|
|
14422
14533
|
return null;
|
|
14534
|
+
const titleIconElement = children?.find(item => item.id === "titleIcon");
|
|
14535
|
+
const isLayers = templateName === exports.ContainerTemplate.Layers;
|
|
14536
|
+
const hasTitleText = !!titleElement.value?.toString().trim() || !!titleElement.attributeName;
|
|
14537
|
+
const hasTitleIcon = !!titleIconElement?.value;
|
|
14538
|
+
const hasControls = !!expandable || !!titleElement.options?.downloadById || isLayers;
|
|
14539
|
+
if (!hasTitleText && !hasTitleIcon && !hasControls)
|
|
14540
|
+
return null;
|
|
14423
14541
|
const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
|
|
14424
14542
|
return (jsxRuntime.jsx(TitleContainer, { containerId: id, elementConfig: titleElement, templateName: templateName, layerNames: layerNames, fontColor: fontColor, expandable: expandable, expanded: expanded, type: type, isVisible: isVisible, renderElement: renderElement }));
|
|
14425
14543
|
});
|
|
@@ -14745,8 +14863,40 @@ const TextTrimValue = styled.div.withConfig({ displayName: "TextTrimValue", comp
|
|
|
14745
14863
|
word-break: ${({ wordBreak }) => wordBreak ?? "break-word"};
|
|
14746
14864
|
overflow: hidden;
|
|
14747
14865
|
`;
|
|
14866
|
+
const ClampedText = styled.div.withConfig({ displayName: "ClampedText", componentId: "sc-asq1h5" }) `
|
|
14867
|
+
display: -webkit-box;
|
|
14868
|
+
-webkit-line-clamp: ${({ $maxLines }) => $maxLines};
|
|
14869
|
+
-webkit-box-orient: vertical;
|
|
14870
|
+
overflow: hidden;
|
|
14871
|
+
width: 100%;
|
|
14872
|
+
max-width: 100%;
|
|
14873
|
+
word-break: ${({ wordBreak }) => wordBreak ?? "break-word"};
|
|
14874
|
+
`;
|
|
14748
14875
|
|
|
14749
|
-
|
|
14876
|
+
/**
|
|
14877
|
+
* Обрезка описания по числу строк (line-clamp). Тултип с полным текстом показывается ТОЛЬКО при
|
|
14878
|
+
* реальном переполнении (`scrollHeight > clientHeight`), отслеживаемом через ResizeObserver, —
|
|
14879
|
+
* у необрезанного текста тултипа нет (ТЗ 9.7).
|
|
14880
|
+
*/
|
|
14881
|
+
const TextTrimLineClamp = React.memo(({ maxLines, wordBreak, children }) => {
|
|
14882
|
+
const ref = React.useRef(null);
|
|
14883
|
+
const [isOverflow, setIsOverflow] = React.useState(false);
|
|
14884
|
+
React.useEffect(() => {
|
|
14885
|
+
const node = ref.current;
|
|
14886
|
+
if (!node)
|
|
14887
|
+
return;
|
|
14888
|
+
const check = () => setIsOverflow(node.scrollHeight > node.clientHeight);
|
|
14889
|
+
check();
|
|
14890
|
+
const observer = new ResizeObserver(check);
|
|
14891
|
+
observer.observe(node);
|
|
14892
|
+
return () => observer.disconnect();
|
|
14893
|
+
}, [children, maxLines]);
|
|
14894
|
+
const clamped = (jsxRuntime.jsx(ClampedText, { ref: ref, "$maxLines": maxLines, wordBreak: wordBreak, children: children }));
|
|
14895
|
+
if (!isOverflow)
|
|
14896
|
+
return clamped;
|
|
14897
|
+
return (jsxRuntime.jsx(uilibGl.Tooltip, { placement: "top", arrow: true, content: children, children: tooltipRef => jsxRuntime.jsx("div", { ref: tooltipRef, children: clamped }) }));
|
|
14898
|
+
});
|
|
14899
|
+
const TextTrim = React.memo(({ maxLength, maxLines, expandable, lineBreak, wordBreak, children }) => {
|
|
14750
14900
|
const { t } = useGlobalContext();
|
|
14751
14901
|
const [expanded, toggleExpanded] = useToggle();
|
|
14752
14902
|
const text = children?.toString();
|
|
@@ -14755,6 +14905,9 @@ const TextTrim = React.memo(({ maxLength, expandable, lineBreak, wordBreak, chil
|
|
|
14755
14905
|
return jsxRuntime.jsx(TextTrimValue, { wordBreak: wordBreak, children: value });
|
|
14756
14906
|
return jsxRuntime.jsx(TextTrimValue, { wordBreak: wordBreak, dangerouslySetInnerHTML: { __html: lodash.unescape(value).split(lineBreak).join("<br />") } });
|
|
14757
14907
|
}, [lineBreak, wordBreak]);
|
|
14908
|
+
if (maxLines && text?.length) {
|
|
14909
|
+
return jsxRuntime.jsx(TextTrimLineClamp, { maxLines: maxLines, wordBreak: wordBreak, children: text });
|
|
14910
|
+
}
|
|
14758
14911
|
if (!text?.length || !maxLength || text.length <= maxLength)
|
|
14759
14912
|
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: formatValue(text) });
|
|
14760
14913
|
const substring = `${text.substring(0, maxLength)}...`;
|
|
@@ -14801,41 +14954,6 @@ const RasterLayer = ({ layer, tileUrl, visible, beforeId, }) => {
|
|
|
14801
14954
|
return (jsxRuntime.jsx(MapGL.Source, { id: layer.name, type: "raster", tiles: tiles, children: jsxRuntime.jsx(MapGL.Layer, { id: layer.name, type: "raster", "source-layer": "default", beforeId: beforeId, layout: { visibility: visible ? "visible" : "none" } }) }, `${layer.name}-${tileUrl}`));
|
|
14802
14955
|
};
|
|
14803
14956
|
|
|
14804
|
-
const getClientStyleItemPrefixSuffix = (geometryType, itemType) => {
|
|
14805
|
-
switch (geometryType) {
|
|
14806
|
-
case api.OgcGeometryType.Point:
|
|
14807
|
-
case api.OgcGeometryType.MultiPoint:
|
|
14808
|
-
switch (itemType) {
|
|
14809
|
-
case "symbol":
|
|
14810
|
-
return ["point-label-layer-", "-label"];
|
|
14811
|
-
default:
|
|
14812
|
-
return ["point-layer-", ""];
|
|
14813
|
-
}
|
|
14814
|
-
case api.OgcGeometryType.LineString:
|
|
14815
|
-
case api.OgcGeometryType.MultiLineString:
|
|
14816
|
-
switch (itemType) {
|
|
14817
|
-
case "symbol":
|
|
14818
|
-
return ["polyline-label-layer-", "-label"];
|
|
14819
|
-
default:
|
|
14820
|
-
return ["polyline-layer-", ""];
|
|
14821
|
-
}
|
|
14822
|
-
case api.OgcGeometryType.Polygon:
|
|
14823
|
-
case api.OgcGeometryType.MultiPolygon:
|
|
14824
|
-
switch (itemType) {
|
|
14825
|
-
case "line":
|
|
14826
|
-
return ["polygon-stroke-layer-", "-stroke"];
|
|
14827
|
-
case "fill-extrusion":
|
|
14828
|
-
return ["polygon-extrusion-layer-", "-extrusion"];
|
|
14829
|
-
case "symbol":
|
|
14830
|
-
return ["polygon-label-layer-", "-label"];
|
|
14831
|
-
default:
|
|
14832
|
-
return ["polygon-layer-", ""];
|
|
14833
|
-
}
|
|
14834
|
-
default:
|
|
14835
|
-
return ["", ""];
|
|
14836
|
-
}
|
|
14837
|
-
};
|
|
14838
|
-
|
|
14839
14957
|
const findAttributeInExpression = (expression) => {
|
|
14840
14958
|
if (Array.isArray(expression) && expression.length === 2 && expression[0] === "get") {
|
|
14841
14959
|
return [expression[1]];
|
|
@@ -14857,6 +14975,14 @@ const getActualExtrusionHeight = (paint) => {
|
|
|
14857
14975
|
: paint?.["fill-extrusion-height"];
|
|
14858
14976
|
};
|
|
14859
14977
|
|
|
14978
|
+
const getLayerClientStyle = (layer) => {
|
|
14979
|
+
const clientStyle = layer?.configuration?.clientStyle;
|
|
14980
|
+
return {
|
|
14981
|
+
...clientStyle,
|
|
14982
|
+
items: clientStyle?.items ?? [],
|
|
14983
|
+
};
|
|
14984
|
+
};
|
|
14985
|
+
|
|
14860
14986
|
const extractAttributesFromObject = (obj) => {
|
|
14861
14987
|
if (!obj || lodash.isEmpty(obj)) {
|
|
14862
14988
|
return [];
|
|
@@ -14886,7 +15012,6 @@ const VectorLayer = ({ layer, tileUrl, visible, beforeId, getLayerTempStyle, })
|
|
|
14886
15012
|
const layerConfiguration = layer?.configuration;
|
|
14887
15013
|
const clientStyle = layerConfiguration?.clientStyle;
|
|
14888
15014
|
const idAttribute = layerConfiguration?.attributesConfiguration?.idAttribute;
|
|
14889
|
-
const geometryType = layerConfiguration?.geometryType;
|
|
14890
15015
|
const tiles = React.useMemo(() => [tileUrl], [tileUrl]);
|
|
14891
15016
|
// Собираем конфигурации иконок для загрузки из clientStyle
|
|
14892
15017
|
const iconConfigs = React.useMemo(() => {
|
|
@@ -14913,121 +15038,28 @@ const VectorLayer = ({ layer, tileUrl, visible, beforeId, getLayerTempStyle, })
|
|
|
14913
15038
|
}).filter((config) => config !== null);
|
|
14914
15039
|
}, [clientStyle]);
|
|
14915
15040
|
useMapImages({ images: iconConfigs });
|
|
14916
|
-
const renderLayerByGeometryType = React.useCallback(() => {
|
|
14917
|
-
const visibility = visible ? "visible" : "none";
|
|
14918
|
-
switch (geometryType) {
|
|
14919
|
-
case api.OgcGeometryType.Point:
|
|
14920
|
-
case api.OgcGeometryType.MultiPoint:
|
|
14921
|
-
return (jsxRuntime.jsx(MapGL.Layer, { id: layer.name, type: "circle", "source-layer": "default", beforeId: beforeId, layout: {
|
|
14922
|
-
...getLayerTempStyle?.(layer.name, "circle")?.layout,
|
|
14923
|
-
visibility,
|
|
14924
|
-
}, paint: {
|
|
14925
|
-
...DEFAULT_CIRCLE_PAINT,
|
|
14926
|
-
...getLayerTempStyle?.(layer.name, "circle")?.paint,
|
|
14927
|
-
} }));
|
|
14928
|
-
case api.OgcGeometryType.Polygon:
|
|
14929
|
-
case api.OgcGeometryType.MultiPolygon:
|
|
14930
|
-
return [
|
|
14931
|
-
jsxRuntime.jsx(MapGL.Layer, { id: layer.name, type: "fill", "source-layer": "default", beforeId: beforeId, layout: {
|
|
14932
|
-
...getLayerTempStyle?.(layer.name, "fill")?.layout,
|
|
14933
|
-
visibility: visible &&
|
|
14934
|
-
getLayerTempStyle?.(layer.name, "fill-extrusion")?.settings?.fill?.showBottomSurface !== false &&
|
|
14935
|
-
Boolean(getActualExtrusionHeight({
|
|
14936
|
-
...DEFAULT_FILL_EXTRUSION_PAINT,
|
|
14937
|
-
...getLayerTempStyle?.(layer.name, "fill-extrusion")?.paint,
|
|
14938
|
-
}))
|
|
14939
|
-
? "visible"
|
|
14940
|
-
: "none",
|
|
14941
|
-
}, paint: {
|
|
14942
|
-
...DEFAULT_FILL_PAINT,
|
|
14943
|
-
...getLayerTempStyle?.(layer.name, "fill")?.paint,
|
|
14944
|
-
} }, `polygon-layer-${layer.name}`),
|
|
14945
|
-
jsxRuntime.jsx(MapGL.Layer, { id: `${layer.name}-stroke`, type: "line", "source-layer": "default", beforeId: beforeId, layout: {
|
|
14946
|
-
...getLayerTempStyle?.(layer.name, "line")?.layout,
|
|
14947
|
-
visibility: visible &&
|
|
14948
|
-
getLayerTempStyle?.(layer.name, "fill-extrusion")?.settings?.fill?.showBottomSurface !== false &&
|
|
14949
|
-
Boolean(getActualExtrusionHeight({
|
|
14950
|
-
...DEFAULT_FILL_EXTRUSION_PAINT,
|
|
14951
|
-
...getLayerTempStyle?.(layer.name, "fill-extrusion")?.paint,
|
|
14952
|
-
}))
|
|
14953
|
-
? "visible"
|
|
14954
|
-
: "none",
|
|
14955
|
-
}, paint: {
|
|
14956
|
-
...DEFAULT_LINE_PAINT,
|
|
14957
|
-
...getLayerTempStyle?.(layer.name, "line")?.paint,
|
|
14958
|
-
} }, `polygon-stroke-layer-${layer.name}`),
|
|
14959
|
-
jsxRuntime.jsx(MapGL.Layer, { id: `${layer.name}-extrusion`, type: "fill-extrusion", "source-layer": "default", beforeId: beforeId, minzoom: 0, maxzoom: 23, layout: {
|
|
14960
|
-
...getLayerTempStyle?.(layer.name, "fill-extrusion")?.layout,
|
|
14961
|
-
visibility,
|
|
14962
|
-
}, paint: {
|
|
14963
|
-
...DEFAULT_FILL_EXTRUSION_PAINT,
|
|
14964
|
-
...getLayerTempStyle?.(layer.name, "fill-extrusion")?.paint,
|
|
14965
|
-
} }, `polygon-extrusion-layer-${layer.name}`),
|
|
14966
|
-
];
|
|
14967
|
-
case api.OgcGeometryType.LineString:
|
|
14968
|
-
case api.OgcGeometryType.MultiLineString:
|
|
14969
|
-
return (jsxRuntime.jsx(MapGL.Layer, { id: layer.name, type: "line", "source-layer": "default", beforeId: beforeId, layout: {
|
|
14970
|
-
...getLayerTempStyle?.(layer.name, "line")?.layout,
|
|
14971
|
-
visibility,
|
|
14972
|
-
}, paint: {
|
|
14973
|
-
...DEFAULT_LINE_PAINT,
|
|
14974
|
-
...getLayerTempStyle?.(layer.name, "line")?.paint,
|
|
14975
|
-
} }));
|
|
14976
|
-
default:
|
|
14977
|
-
return null;
|
|
14978
|
-
}
|
|
14979
|
-
}, [
|
|
14980
|
-
geometryType,
|
|
14981
|
-
layer,
|
|
14982
|
-
beforeId,
|
|
14983
|
-
visible,
|
|
14984
|
-
getLayerTempStyle,
|
|
14985
|
-
]);
|
|
14986
15041
|
const renderClientStyle = React.useCallback(() => {
|
|
14987
|
-
|
|
14988
|
-
|
|
14989
|
-
|
|
14990
|
-
const
|
|
14991
|
-
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
|
|
14995
|
-
...getLayerTempStyle?.(layer.name, "fill-extrusion")?.paint,
|
|
14996
|
-
}
|
|
14997
|
-
: undefined;
|
|
14998
|
-
const currentSettings = {
|
|
14999
|
-
...clientStyle?.settings,
|
|
15000
|
-
...getLayerTempStyle?.(layer.name, mockItem.type)?.settings,
|
|
15001
|
-
};
|
|
15002
|
-
const processedExtrusionHeight = getActualExtrusionHeight(fillExtrusionPaint);
|
|
15003
|
-
const hasExtrusion = Boolean(processedExtrusionHeight);
|
|
15004
|
-
const visibility = visible &&
|
|
15005
|
-
((isExtrusionItem && hasExtrusion) ||
|
|
15006
|
-
(!isPolygonPart && !isExtrusionItem) ||
|
|
15007
|
-
(isPolygonPart && (!hasExtrusion || (currentSettings?.fill?.showBottomSurface ?? true))))
|
|
15008
|
-
? "visible"
|
|
15009
|
-
: "none";
|
|
15010
|
-
return (jsxRuntime.jsx(MapGL.Layer, { id: `${layer.name}${suffix}`, type: mockItem.type, "source-layer": "default", beforeId: beforeId, ...(mockItem.filter && { filter: mockItem.filter }), minzoom: mockItem.minzoom ?? clientStyle?.minzoom ?? 0, maxzoom: mockItem.maxzoom ?? clientStyle?.maxzoom ?? 23, layout: {
|
|
15042
|
+
const items = [...(getLayerTempStyle(layer.name)?.items ?? clientStyle?.items ?? [])];
|
|
15043
|
+
let currentBeforeId = beforeId;
|
|
15044
|
+
return items.map((mockItem, mockItemIndex) => {
|
|
15045
|
+
const visibility = visible ? "visible" : "none";
|
|
15046
|
+
if (mockItemIndex > 0) {
|
|
15047
|
+
currentBeforeId = `${layer.name}-${items[mockItemIndex - 1].id}`;
|
|
15048
|
+
}
|
|
15049
|
+
return (jsxRuntime.jsx(MapGL.Layer, { id: `${layer.name}-${mockItem.id}`, type: mockItem.type, "source-layer": "default", beforeId: currentBeforeId, ...(mockItem.filter && { filter: mockItem.filter }), minzoom: mockItem.minzoom ?? clientStyle?.minzoom ?? 0, maxzoom: mockItem.maxzoom ?? clientStyle?.maxzoom ?? 23, layout: {
|
|
15011
15050
|
...mockItem.layout,
|
|
15012
|
-
...getLayerTempStyle
|
|
15051
|
+
...getLayerTempStyle(layer.name)?.items?.find(item => item.id === mockItem.id)?.layout,
|
|
15013
15052
|
visibility,
|
|
15014
15053
|
}, paint: {
|
|
15015
15054
|
...mockItem.paint,
|
|
15016
|
-
...getLayerTempStyle
|
|
15017
|
-
} }, `${
|
|
15055
|
+
...getLayerTempStyle(layer.name)?.items?.find(item => item.id === mockItem.id)?.paint,
|
|
15056
|
+
} }, `${layer.name}-${mockItem.id}`));
|
|
15018
15057
|
});
|
|
15019
|
-
}, [
|
|
15020
|
-
beforeId,
|
|
15021
|
-
clientStyle,
|
|
15022
|
-
geometryType,
|
|
15023
|
-
layer.name,
|
|
15024
|
-
visible,
|
|
15025
|
-
getLayerTempStyle,
|
|
15026
|
-
]);
|
|
15058
|
+
}, [beforeId, clientStyle, layer.name, visible, getLayerTempStyle]);
|
|
15027
15059
|
if (!layer) {
|
|
15028
15060
|
return null;
|
|
15029
15061
|
}
|
|
15030
|
-
return (jsxRuntime.jsx(MapGL.Source, { promoteId: idAttribute, id: layer.name, type: "vector", tiles: tiles, children:
|
|
15062
|
+
return (jsxRuntime.jsx(MapGL.Source, { promoteId: idAttribute, id: layer.name, type: "vector", tiles: tiles, children: renderClientStyle() }, `${layer.name}-${tileUrl}`));
|
|
15031
15063
|
};
|
|
15032
15064
|
|
|
15033
15065
|
const Layer = ({ layer, layerType, visible, beforeId, tileUrl, getLayerTempStyle, onMount = () => { }, }) => {
|
|
@@ -15234,6 +15266,7 @@ exports.SmallPreviewLeft = SmallPreviewLeft;
|
|
|
15234
15266
|
exports.SmallPreviewRight = SmallPreviewRight;
|
|
15235
15267
|
exports.StackBar = StackBar;
|
|
15236
15268
|
exports.SvgImage = SvgImage;
|
|
15269
|
+
exports.TILE_ALIGNMENTS = TILE_ALIGNMENTS;
|
|
15237
15270
|
exports.TIME_ZONE_FORMAT = TIME_ZONE_FORMAT;
|
|
15238
15271
|
exports.TabsContainer = TabsContainer;
|
|
15239
15272
|
exports.TextTrim = TextTrim;
|
|
@@ -15309,6 +15342,7 @@ exports.getFilterSelectedItems = getFilterSelectedItems;
|
|
|
15309
15342
|
exports.getFilterValue = getFilterValue;
|
|
15310
15343
|
exports.getFormattedAttributes = getFormattedAttributes;
|
|
15311
15344
|
exports.getGradientColors = getGradientColors;
|
|
15345
|
+
exports.getLayerClientStyle = getLayerClientStyle;
|
|
15312
15346
|
exports.getLayerInfo = getLayerInfo;
|
|
15313
15347
|
exports.getLayerInfoAttribute = getLayerInfoAttribute;
|
|
15314
15348
|
exports.getLayerInfoFromDataSources = getLayerInfoFromDataSources;
|
|
@@ -15381,6 +15415,7 @@ exports.useDataSources = useDataSources;
|
|
|
15381
15415
|
exports.useDebouncedCallback = useDebouncedCallback;
|
|
15382
15416
|
exports.useDiffPage = useDiffPage;
|
|
15383
15417
|
exports.useEditGroupAttributes = useEditGroupAttributes;
|
|
15418
|
+
exports.useEqualTileWidth = useEqualTileWidth;
|
|
15384
15419
|
exports.useExpandableContainers = useExpandableContainers;
|
|
15385
15420
|
exports.useExportPdf = useExportPdf;
|
|
15386
15421
|
exports.useFeatureSaveHooks = useFeatureSaveHooks;
|