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