@evergis/react 4.0.146 → 4.0.147
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/hooks/useColumnResize.d.ts +11 -7
- package/dist/components/Dashboard/elements/ElementTable/hooks/useTableView.d.ts +1 -1
- package/dist/components/Dashboard/elements/ElementTable/styled.d.ts +9 -5
- package/dist/components/Dashboard/elements/ElementTable/types.d.ts +3 -3
- package/dist/components/Dashboard/elements/ElementTable/utils/columnStyle.d.ts +10 -8
- package/dist/index.js +76 -58
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +76 -58
- package/dist/react.esm.js.map +1 -1
- package/package.json +2 -2
package/dist/react.esm.js
CHANGED
|
@@ -15552,7 +15552,19 @@ const TableHead = styled.thead.withConfig({ displayName: "TableHead", componentI
|
|
|
15552
15552
|
top: 0;
|
|
15553
15553
|
z-index: 1;
|
|
15554
15554
|
`;
|
|
15555
|
-
|
|
15555
|
+
/**
|
|
15556
|
+
* Содержимое заголовка: псевдоним и место под значок сортировки.
|
|
15557
|
+
*
|
|
15558
|
+
* Само по себе не сжимается и ничего не обрезает — иначе перестало бы задавать минимальную
|
|
15559
|
+
* ширину колонки, и раскладка считала бы её по одному лишь телу таблицы. Обрезку включает
|
|
15560
|
+
* заголовок, и только когда ширина колонки задана явно (см. `TableHeadCell`).
|
|
15561
|
+
*/
|
|
15562
|
+
const TableHeadContent = styled.span.withConfig({ displayName: "TableHeadContent", componentId: "sc-19t325s" }) `
|
|
15563
|
+
display: flex;
|
|
15564
|
+
align-items: center;
|
|
15565
|
+
gap: 0.25rem;
|
|
15566
|
+
`;
|
|
15567
|
+
const TableHeadCell = styled.th.withConfig({ displayName: "TableHeadCell", componentId: "sc-19bpg7s" }) `
|
|
15556
15568
|
/* Относительное позиционирование держит захват границы колонки. */
|
|
15557
15569
|
position: relative;
|
|
15558
15570
|
box-sizing: border-box;
|
|
@@ -15560,7 +15572,6 @@ const TableHeadCell = styled.th.withConfig({ displayName: "TableHeadCell", compo
|
|
|
15560
15572
|
text-align: left;
|
|
15561
15573
|
font-weight: 600;
|
|
15562
15574
|
white-space: nowrap;
|
|
15563
|
-
overflow: hidden;
|
|
15564
15575
|
color: ${({ theme }) => theme.palette.textSecondary};
|
|
15565
15576
|
/* Рамка принадлежит ячейке (рамки раздельные), поэтому едет вместе с липкой шапкой. */
|
|
15566
15577
|
border-bottom: 1px solid ${({ theme }) => theme.palette.elementDeep};
|
|
@@ -15570,18 +15581,22 @@ const TableHeadCell = styled.th.withConfig({ displayName: "TableHeadCell", compo
|
|
|
15570
15581
|
cursor: pointer;
|
|
15571
15582
|
user-select: none;
|
|
15572
15583
|
`}
|
|
15573
|
-
|
|
15574
|
-
|
|
15575
|
-
|
|
15576
|
-
|
|
15577
|
-
|
|
15578
|
-
|
|
15579
|
-
|
|
15580
|
-
|
|
15581
|
-
|
|
15582
|
-
|
|
15583
|
-
|
|
15584
|
-
|
|
15584
|
+
|
|
15585
|
+
/*
|
|
15586
|
+
* Обрезка только у колонки с заданной шириной: там длинный псевдоним иначе выдавил бы значок
|
|
15587
|
+
* сортировки за край. У колонки без ширины обрезать нечего — её ширину и задаёт заголовок,
|
|
15588
|
+
* а сжатое содержимое отдало бы этот расчёт телу таблицы, и заголовок схлопнулся бы в ноль.
|
|
15589
|
+
*/
|
|
15590
|
+
${({ $fixedWidth }) => $fixedWidth &&
|
|
15591
|
+
css `
|
|
15592
|
+
overflow: hidden;
|
|
15593
|
+
|
|
15594
|
+
${TableHeadContent} {
|
|
15595
|
+
min-width: 0;
|
|
15596
|
+
overflow: hidden;
|
|
15597
|
+
text-overflow: ellipsis;
|
|
15598
|
+
}
|
|
15599
|
+
`}
|
|
15585
15600
|
`;
|
|
15586
15601
|
/**
|
|
15587
15602
|
* Место под значок сортировки. Занято всегда, пока сортировка включена, а сам значок только
|
|
@@ -15954,30 +15969,30 @@ const TableCell = memo(({ attribute, row, canEdit, onChange }) => {
|
|
|
15954
15969
|
* Имя переменной ширины колонки.
|
|
15955
15970
|
*
|
|
15956
15971
|
* Через неё идёт и предпросмотр перетаскивания, и итоговая ширина: пока переменная не задана,
|
|
15957
|
-
* работает запасное
|
|
15958
|
-
*
|
|
15972
|
+
* работает запасное значение, а жест на время перетаскивания объявляет её на самой таблице —
|
|
15973
|
+
* одним свойством на один узел, как сетка меняет свой шаблон треков.
|
|
15959
15974
|
*/
|
|
15960
15975
|
const getColumnWidthVariable = (index) => `--table-col-${index}`;
|
|
15961
15976
|
/**
|
|
15962
|
-
* Инлайн-размер ячейки
|
|
15977
|
+
* Инлайн-размер ячейки колонки.
|
|
15963
15978
|
*
|
|
15964
|
-
*
|
|
15965
|
-
*
|
|
15966
|
-
*
|
|
15979
|
+
* Ставится всем колонкам, а не только тем, у кого ширина задана: жест фиксирует на время
|
|
15980
|
+
* перетаскивания ВСЕ колонки, иначе соседние перераспределялись бы на первом же шаге и таблицу
|
|
15981
|
+
* дёргало бы. Пока переменной нет, каждый предел падает на своё запасное значение и колонка
|
|
15982
|
+
* ведёт себя ровно так, как вела бы без инлайн-стиля вовсе.
|
|
15967
15983
|
*
|
|
15968
|
-
*
|
|
15984
|
+
* Раскладка таблицы автоматическая (ширину колонок выбирает содержимое), и одной `width` ей мало —
|
|
15985
|
+
* она для неё лишь пожелание. Жёстко колонку держат все три предела сразу.
|
|
15969
15986
|
*/
|
|
15970
|
-
const getColumnStyle = (index, width,
|
|
15971
|
-
if (width == null && !resizable) {
|
|
15972
|
-
return undefined;
|
|
15973
|
-
}
|
|
15987
|
+
const getColumnStyle = (index, width, isHead) => {
|
|
15974
15988
|
const variable = getColumnWidthVariable(index);
|
|
15975
15989
|
const fixed = width == null ? null : `${width}px`;
|
|
15976
15990
|
return {
|
|
15977
15991
|
width: `var(${variable}, ${fixed ?? "auto"})`,
|
|
15978
15992
|
minWidth: `var(${variable}, ${fixed ?? "0"})`,
|
|
15979
|
-
// Без заданной ширины предел остаётся
|
|
15980
|
-
|
|
15993
|
+
// Без заданной ширины предел остаётся тем, что задан стилем: у ячейки тела — общий предел
|
|
15994
|
+
// таблицы, у заголовка его нет вовсе.
|
|
15995
|
+
maxWidth: `var(${variable}, ${fixed ?? (isHead ? "none" : "var(--table-cell-max-width, 20rem)")})`,
|
|
15981
15996
|
};
|
|
15982
15997
|
};
|
|
15983
15998
|
|
|
@@ -15985,39 +16000,41 @@ const getColumnStyle = (index, width, resizable) => {
|
|
|
15985
16000
|
* Перетаскивание правой границы колонки.
|
|
15986
16001
|
*
|
|
15987
16002
|
* Жест — общий {@link useResizeDrag}, тот же, что двигает границы ячеек сетки дашборда. Здесь
|
|
15988
|
-
* остаётся только табличное: во время жеста
|
|
15989
|
-
* состояние
|
|
15990
|
-
*
|
|
16003
|
+
* остаётся только табличное: во время жеста ширины рисуются переменными на самой таблице, а в
|
|
16004
|
+
* состояние уходят один раз, на отпускание мыши.
|
|
16005
|
+
*
|
|
16006
|
+
* Снимок берётся по ВСЕМ колонкам, и все они на время жеста фиксируются — так же, как сетка
|
|
16007
|
+
* фиксирует все треки. Иначе автоматическая раскладка перераспределяла бы соседние колонки на
|
|
16008
|
+
* первом же шаге, и таблицу дёргало бы в самом начале перетаскивания. По той же причине в
|
|
16009
|
+
* состояние уходят ширины всех колонок: без этого соседи прыгнули бы обратно на отпускании.
|
|
15991
16010
|
*
|
|
15992
|
-
*
|
|
15993
|
-
* выбрала раскладка таблицы, и тянуть надо от того, что видно.
|
|
16011
|
+
* Ширины снимаются с ячеек шапки: колонка одна на всю таблицу, а строк в ней сколько угодно.
|
|
15994
16012
|
*/
|
|
15995
|
-
const useColumnResize = ({ index,
|
|
15996
|
-
const variable = getColumnWidthVariable(index);
|
|
16013
|
+
const useColumnResize = ({ index, onResize }) => {
|
|
15997
16014
|
const onStart = useCallback((event) => {
|
|
15998
|
-
// Обработчик нажатия висит на самой ручке, поэтому
|
|
15999
|
-
//
|
|
16000
|
-
const
|
|
16001
|
-
|
|
16015
|
+
// Обработчик нажатия висит на самой ручке, поэтому таблица достаётся отсюда — отдельный
|
|
16016
|
+
// ref на неё не нужен.
|
|
16017
|
+
const table = event.currentTarget?.closest("table");
|
|
16018
|
+
const head = table?.querySelector("thead tr");
|
|
16019
|
+
if (!head) {
|
|
16002
16020
|
return null;
|
|
16003
16021
|
}
|
|
16004
|
-
|
|
16005
|
-
|
|
16006
|
-
|
|
16007
|
-
|
|
16008
|
-
|
|
16009
|
-
|
|
16010
|
-
const
|
|
16011
|
-
const onMove = useCallback((state, event) => state.table?.style.setProperty(variable, `${getNextWidth(state, event)}px`), [getNextWidth, variable]);
|
|
16022
|
+
const widths = Array.from(head.children).map(cell => cell.getBoundingClientRect().width);
|
|
16023
|
+
return widths[index] === undefined ? null : { start: event.clientX, widths, table };
|
|
16024
|
+
}, [index]);
|
|
16025
|
+
const getNextWidths = useCallback((state, event) => state.widths.map((width, position) => position === index
|
|
16026
|
+
? Math.max(MIN_COLUMN_WIDTH, Math.round(width + event.clientX - state.start))
|
|
16027
|
+
: Math.round(width)), [index]);
|
|
16028
|
+
const onMove = useCallback((state, event) => getNextWidths(state, event).forEach((width, position) => state.table?.style.setProperty(getColumnWidthVariable(position), `${width}px`)), [getNextWidths]);
|
|
16012
16029
|
const onEnd = useCallback((state, event) => {
|
|
16013
|
-
state.table?.style.removeProperty(
|
|
16014
|
-
const
|
|
16030
|
+
state.widths.forEach((_width, position) => state.table?.style.removeProperty(getColumnWidthVariable(position)));
|
|
16031
|
+
const widths = getNextWidths(state, event);
|
|
16015
16032
|
// Клик по границе без перетаскивания ширину менять не должен.
|
|
16016
|
-
if (
|
|
16033
|
+
if (widths[index] === Math.round(state.widths[index])) {
|
|
16017
16034
|
return;
|
|
16018
16035
|
}
|
|
16019
|
-
|
|
16020
|
-
}, [
|
|
16036
|
+
onResize(widths);
|
|
16037
|
+
}, [getNextWidths, index, onResize]);
|
|
16021
16038
|
return useResizeDrag({ onStart, onMove, onEnd });
|
|
16022
16039
|
};
|
|
16023
16040
|
|
|
@@ -16028,9 +16045,8 @@ const useColumnResize = ({ index, onCommit }) => {
|
|
|
16028
16045
|
* и то же действие, и выглядеть оно обязано одинаково. Поэтому и стоит она у КАЖДОЙ ячейки
|
|
16029
16046
|
* колонки, как в сетке, — тянуть границу можно на любой строке, а не только в шапке.
|
|
16030
16047
|
*/
|
|
16031
|
-
const TableColumnResizer = memo(({ index,
|
|
16032
|
-
const
|
|
16033
|
-
const { setHandle, dragging } = useColumnResize({ index, onCommit });
|
|
16048
|
+
const TableColumnResizer = memo(({ index, onResize }) => {
|
|
16049
|
+
const { setHandle, dragging } = useColumnResize({ index, onResize });
|
|
16034
16050
|
// Ручка лежит внутри ячейки, и без остановки всплытия перетаскивание границы заканчивалось бы
|
|
16035
16051
|
// кликом по ней — то есть переключало бы сортировку в шапке и открывало бы правку в теле.
|
|
16036
16052
|
const stopPropagation = useCallback((event) => event.stopPropagation(), []);
|
|
@@ -16045,7 +16061,7 @@ const TableColumnResizer = memo(({ index, attributeName, onResize }) => {
|
|
|
16045
16061
|
*/
|
|
16046
16062
|
const TableHeadRow = ({ columns, sort, sortEnabled, columnWidths, withActionsColumn, onSortToggle, onColumnResize, }) => (jsxs("tr", { children: [columns.map(({ attributeName, alias, description, resizable }, index) => {
|
|
16047
16063
|
const sorted = sort?.attributeName === attributeName;
|
|
16048
|
-
return (jsxs(TableHeadCell, { title: description || alias, style: getColumnStyle(index, columnWidths[attributeName],
|
|
16064
|
+
return (jsxs(TableHeadCell, { title: description || alias, style: getColumnStyle(index, columnWidths[attributeName], true), "$sortable": sortEnabled, "$fixedWidth": columnWidths[attributeName] != null, 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, onResize: onColumnResize })] }, attributeName));
|
|
16049
16065
|
}), withActionsColumn && jsx(TableHeadCell, {})] }));
|
|
16050
16066
|
|
|
16051
16067
|
const ContainerLoading = () => (jsx(Flex, { alignContent: "center", justifyContent: "center", width: "100%", children: jsx(CircularProgress, { diameter: 1.5, mono: true }) }));
|
|
@@ -16180,7 +16196,9 @@ const useTableView = (elementConfig) => {
|
|
|
16180
16196
|
// Растянутая мышью ширина живёт только в рантайме и перебивает конфигурационную: последнее
|
|
16181
16197
|
// слово за тем, кто тянул. Обратно в конфиг она не пишется.
|
|
16182
16198
|
const columnWidths = useMemo(() => columns.reduce((acc, attribute) => ({ ...acc, [attribute.attributeName]: widths[attribute.attributeName] ?? attribute.width }), {}), [columns, widths]);
|
|
16183
|
-
|
|
16199
|
+
// Жест отдаёт ширины всех колонок разом: соседние он тоже фиксировал, и вернуть их к
|
|
16200
|
+
// автоподбору значило бы дёрнуть таблицу сразу после отпускания.
|
|
16201
|
+
const onColumnResize = useCallback((next) => setWidths(columns.reduce((acc, { attributeName }, position) => next[position] === undefined ? acc : { ...acc, [attributeName]: next[position] }, {})), [columns]);
|
|
16184
16202
|
const onSortToggle = useCallback((attributeName) => setSort(current => getNextSort(current, attributeName)), []);
|
|
16185
16203
|
return {
|
|
16186
16204
|
context,
|
|
@@ -16225,9 +16243,9 @@ const ElementTable = memo(({ elementConfig }) => {
|
|
|
16225
16243
|
// Стиль колонки из конфига идёт последним: шрифт задан для значений, и ширину
|
|
16226
16244
|
// он не трогает — своих размеров у него нет.
|
|
16227
16245
|
style: {
|
|
16228
|
-
...getColumnStyle(columnIndex, columnWidths[attribute.attributeName]
|
|
16246
|
+
...getColumnStyle(columnIndex, columnWidths[attribute.attributeName]),
|
|
16229
16247
|
...attribute.style,
|
|
16230
|
-
}, children: [jsx(TableCell, { attribute: attribute, row: row, canEdit: context.canEdit, onChange: context.onCellChange }), attribute.resizable && (jsx(TableColumnResizer, { index: columnIndex,
|
|
16248
|
+
}, children: [jsx(TableCell, { attribute: attribute, row: row, canEdit: context.canEdit, onChange: context.onCellChange }), attribute.resizable && (jsx(TableColumnResizer, { index: columnIndex, 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))) })] }) }));
|
|
16231
16249
|
});
|
|
16232
16250
|
|
|
16233
16251
|
const TooltipIcon = styled(Icon).withConfig({ displayName: "TooltipIcon", componentId: "sc-1lkxudm" }) `
|