@evergis/react 4.0.145 → 4.0.146

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/react.esm.js CHANGED
@@ -8168,6 +8168,23 @@ const useProjectDashboardInit = () => {
8168
8168
  }, [projectInfo, updateProject]);
8169
8169
  };
8170
8170
 
8171
+ /**
8172
+ * Съесть клик, которым закончилось перетаскивание.
8173
+ *
8174
+ * Мышь отпускают уже за пределами ручки, поэтому браузер шлёт `click` не ей, а общему предку —
8175
+ * ячейке или заголовку. Без этого перетаскивание границы заканчивалось бы сортировкой таблицы
8176
+ * по колонке или сменой выделения в сетке.
8177
+ */
8178
+ const swallowNextClick = () => {
8179
+ const swallow = (event) => {
8180
+ event.stopPropagation();
8181
+ event.preventDefault();
8182
+ };
8183
+ window.addEventListener("click", swallow, { capture: true, once: true });
8184
+ // Клика может и не быть — например, мышь отпустили за пределами окна. Тогда снимаем слушатель
8185
+ // сами, иначе он съел бы следующий, уже осмысленный клик.
8186
+ window.setTimeout(() => window.removeEventListener("click", swallow, { capture: true }), 0);
8187
+ };
8171
8188
  /**
8172
8189
  * Перетаскивание границы: подписка на ручку, снимок на старте, предпросмотр на движении,
8173
8190
  * запись результата на отпускании.
@@ -8180,6 +8197,7 @@ const useResizeDrag = ({ onStart, onMove, onEnd }) => {
8180
8197
  const [handle, setHandle] = useState(null);
8181
8198
  const [dragging, setDragging] = useState(false);
8182
8199
  const stateRef = useRef(null);
8200
+ const movedRef = useRef(false);
8183
8201
  const mouseDown = useCallback((event) => {
8184
8202
  const state = onStart(event);
8185
8203
  if (state === null) {
@@ -8189,10 +8207,12 @@ const useResizeDrag = ({ onStart, onMove, onEnd }) => {
8189
8207
  // над чем проходит курсор.
8190
8208
  event.preventDefault();
8191
8209
  stateRef.current = state;
8210
+ movedRef.current = false;
8192
8211
  setDragging(true);
8193
8212
  }, [onStart]);
8194
8213
  const mouseMove = useCallback((event) => {
8195
8214
  if (stateRef.current !== null) {
8215
+ movedRef.current = true;
8196
8216
  onMove(stateRef.current, event);
8197
8217
  }
8198
8218
  }, [onMove]);
@@ -8203,6 +8223,9 @@ const useResizeDrag = ({ onStart, onMove, onEnd }) => {
8203
8223
  }
8204
8224
  stateRef.current = null;
8205
8225
  setDragging(false);
8226
+ if (movedRef.current) {
8227
+ swallowNextClick();
8228
+ }
8206
8229
  onEnd(state, event);
8207
8230
  }, [onEnd]);
8208
8231
  useDragAndDropEffect(handle, { mouseDown, mouseMove, mouseUp });
@@ -15532,6 +15555,7 @@ const TableHead = styled.thead.withConfig({ displayName: "TableHead", componentI
15532
15555
  const TableHeadCell = styled.th.withConfig({ displayName: "TableHeadCell", componentId: "sc-1m6xil2" }) `
15533
15556
  /* Относительное позиционирование держит захват границы колонки. */
15534
15557
  position: relative;
15558
+ box-sizing: border-box;
15535
15559
  padding: 0.375rem 0.5rem;
15536
15560
  text-align: left;
15537
15561
  font-weight: 600;
@@ -15587,6 +15611,10 @@ const TableRow = styled.tr.withConfig({ displayName: "TableRow", componentId: "s
15587
15611
  }
15588
15612
  `;
15589
15613
  const TableCellWrapper = styled.td.withConfig({ displayName: "TableCellWrapper", componentId: "sc-ziu5rk" }) `
15614
+ /* Относительное позиционирование держит захват границы колонки. */
15615
+ position: relative;
15616
+ /* Как и у заголовка: ширина колонки считается по внешнему краю ячейки. */
15617
+ box-sizing: border-box;
15590
15618
  padding: 0.125rem 0.25rem;
15591
15619
  vertical-align: middle;
15592
15620
  /* Предел снимает заданная ширина: с колонками по содержимому обрезать значение незачем. */
@@ -15961,15 +15989,15 @@ const getColumnStyle = (index, width, resizable) => {
15961
15989
  * состояние уходит один раз, на отпускание мыши. Так шаг жеста меняет одно свойство одного узла,
15962
15990
  * а не перерисовывает таблицу целиком.
15963
15991
  *
15964
- * Стартовая ширина берётся с самой ячейки заголовка: у колонки без `width` её выбрала раскладка
15965
- * таблицы, и тянуть надо от того, что видно.
15992
+ * Стартовая ширина берётся с той ячейки, за границу которой потянули: у колонки без `width` её
15993
+ * выбрала раскладка таблицы, и тянуть надо от того, что видно.
15966
15994
  */
15967
15995
  const useColumnResize = ({ index, onCommit }) => {
15968
15996
  const variable = getColumnWidthVariable(index);
15969
15997
  const onStart = useCallback((event) => {
15970
15998
  // Обработчик нажатия висит на самой ручке, поэтому её ячейка и таблица достаются отсюда —
15971
- // отдельный ref на них не нужен.
15972
- const cell = event.currentTarget?.closest("th");
15999
+ // отдельный ref на них не нужен. Ячейка любая: ручки стоят и в шапке, и в каждой строке.
16000
+ const cell = event.currentTarget?.closest("th, td");
15973
16001
  if (!cell) {
15974
16002
  return null;
15975
16003
  }
@@ -15994,15 +16022,17 @@ const useColumnResize = ({ index, onCommit }) => {
15994
16022
  };
15995
16023
 
15996
16024
  /**
15997
- * Ручка ширины колонки на правой границе заголовка.
16025
+ * Ручка ширины колонки на правой границе ячейки.
15998
16026
  *
15999
16027
  * Тот же компонент и тот же жест, что двигают границы ячеек сетки дашборда: пользователю это одно
16000
- * и то же действие, и выглядеть оно обязано одинаково.
16028
+ * и то же действие, и выглядеть оно обязано одинаково. Поэтому и стоит она у КАЖДОЙ ячейки
16029
+ * колонки, как в сетке, — тянуть границу можно на любой строке, а не только в шапке.
16001
16030
  */
16002
- const TableColumnResizer = memo(({ index, onCommit }) => {
16031
+ const TableColumnResizer = memo(({ index, attributeName, onResize }) => {
16032
+ const onCommit = useCallback((width) => onResize(attributeName, width), [attributeName, onResize]);
16003
16033
  const { setHandle, dragging } = useColumnResize({ index, onCommit });
16004
- // Ручка лежит внутри заголовка, и без остановки всплытия перетаскивание границы заканчивалось бы
16005
- // кликом по нему — то есть переключало бы сортировку.
16034
+ // Ручка лежит внутри ячейки, и без остановки всплытия перетаскивание границы заканчивалось бы
16035
+ // кликом по ней — то есть переключало бы сортировку в шапке и открывало бы правку в теле.
16006
16036
  const stopPropagation = useCallback((event) => event.stopPropagation(), []);
16007
16037
  return jsx(ResizeHandle, { ref: setHandle, "$axis": "column", "data-dragging": dragging, onClick: stopPropagation });
16008
16038
  });
@@ -16015,7 +16045,7 @@ const TableColumnResizer = memo(({ index, onCommit }) => {
16015
16045
  */
16016
16046
  const TableHeadRow = ({ columns, sort, sortEnabled, columnWidths, withActionsColumn, onSortToggle, onColumnResize, }) => (jsxs("tr", { children: [columns.map(({ attributeName, alias, description, resizable }, index) => {
16017
16047
  const sorted = sort?.attributeName === attributeName;
16018
- return (jsxs(TableHeadCell, { title: description || alias, style: getColumnStyle(index, columnWidths[attributeName], resizable), "$sortable": sortEnabled, onClick: sortEnabled ? () => onSortToggle(attributeName) : undefined, children: [jsxs(TableHeadContent, { children: [alias, sortEnabled && (jsx(TableSortSlot, { "$active": sorted, children: jsx(Icon, { kind: sorted && sort?.direction === "desc" ? "sorting_des" : "sorting_asc" }) }))] }), resizable && (jsx(TableColumnResizer, { index: index, onCommit: nextWidth => onColumnResize(attributeName, nextWidth) }))] }, attributeName));
16048
+ return (jsxs(TableHeadCell, { title: description || alias, style: getColumnStyle(index, columnWidths[attributeName], resizable), "$sortable": sortEnabled, onClick: sortEnabled ? () => onSortToggle(attributeName) : undefined, children: [jsxs(TableHeadContent, { children: [alias, sortEnabled && (jsx(TableSortSlot, { "$active": sorted, children: jsx(Icon, { kind: sorted && sort?.direction === "desc" ? "sorting_des" : "sorting_asc" }) }))] }), resizable && jsx(TableColumnResizer, { index: index, attributeName: attributeName, onResize: onColumnResize })] }, attributeName));
16019
16049
  }), withActionsColumn && jsx(TableHeadCell, {})] }));
16020
16050
 
16021
16051
  const ContainerLoading = () => (jsx(Flex, { alignContent: "center", justifyContent: "center", width: "100%", children: jsx(CircularProgress, { diameter: 1.5, mono: true }) }));
@@ -16191,13 +16221,13 @@ const ElementTable = memo(({ elementConfig }) => {
16191
16221
  defaultValue: "Схема данных не задана",
16192
16222
  }) }));
16193
16223
  }
16194
- return (jsx(TableBox, { "$sizeCss": sizeCss, children: jsxs(TableWrapper, { ref: setTable, "$contentWidth": contentWidth, children: [jsx(TableHead, { children: jsx(TableHeadRow, { columns: columns, sort: sort, sortEnabled: sortEnabled, columnWidths: columnWidths, withActionsColumn: context.canDelete, onSortToggle: onSortToggle, onColumnResize: onColumnResize }) }), jsx(TableBody, { children: rows.map(row => (jsxs(TableRow, { children: [columns.map((attribute, columnIndex) => (jsx(TableCellWrapper, {
16224
+ return (jsx(TableBox, { "$sizeCss": sizeCss, children: jsxs(TableWrapper, { ref: setTable, "$contentWidth": contentWidth, children: [jsx(TableHead, { children: jsx(TableHeadRow, { columns: columns, sort: sort, sortEnabled: sortEnabled, columnWidths: columnWidths, withActionsColumn: context.canDelete, onSortToggle: onSortToggle, onColumnResize: onColumnResize }) }), jsx(TableBody, { children: rows.map(row => (jsxs(TableRow, { children: [columns.map((attribute, columnIndex) => (jsxs(TableCellWrapper, {
16195
16225
  // Стиль колонки из конфига идёт последним: шрифт задан для значений, и ширину
16196
16226
  // он не трогает — своих размеров у него нет.
16197
16227
  style: {
16198
16228
  ...getColumnStyle(columnIndex, columnWidths[attribute.attributeName], attribute.resizable),
16199
16229
  ...attribute.style,
16200
- }, children: jsx(TableCell, { attribute: attribute, row: row, canEdit: context.canEdit, onChange: context.onCellChange }) }, attribute.attributeName))), context.canDelete && (jsx(TableActionsCell, { children: jsx(IconButton, { kind: "delete", title: t("actions.delete", { ns: "common", defaultValue: "Удалить" }), onClick: () => context.onRowDelete(row.key) }) }))] }, row.key))) })] }) }));
16230
+ }, children: [jsx(TableCell, { attribute: attribute, row: row, canEdit: context.canEdit, onChange: context.onCellChange }), attribute.resizable && (jsx(TableColumnResizer, { index: columnIndex, attributeName: attribute.attributeName, onResize: onColumnResize }))] }, attribute.attributeName))), context.canDelete && (jsx(TableActionsCell, { children: jsx(IconButton, { kind: "delete", title: t("actions.delete", { ns: "common", defaultValue: "Удалить" }), onClick: () => context.onRowDelete(row.key) }) }))] }, row.key))) })] }) }));
16201
16231
  });
16202
16232
 
16203
16233
  const TooltipIcon = styled(Icon).withConfig({ displayName: "TooltipIcon", componentId: "sc-1lkxudm" }) `