@underverse-ui/underverse 1.0.70 → 1.0.72
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/api-reference.json +1 -1
- package/dist/index.cjs +730 -311
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +646 -227
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20112,10 +20112,65 @@ var TableCaption = React52.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
20112
20112
|
TableCaption.displayName = "TableCaption";
|
|
20113
20113
|
|
|
20114
20114
|
// src/components/DataTable/DataTable.tsx
|
|
20115
|
-
import
|
|
20115
|
+
import React62 from "react";
|
|
20116
20116
|
|
|
20117
20117
|
// src/components/DataTable/components/DataTableBody.tsx
|
|
20118
|
+
import React53 from "react";
|
|
20118
20119
|
import { jsx as jsx62, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
20120
|
+
function DataTableOverflowText({
|
|
20121
|
+
text,
|
|
20122
|
+
align
|
|
20123
|
+
}) {
|
|
20124
|
+
const triggerId = React53.useId();
|
|
20125
|
+
const [isOverflowing, setIsOverflowing] = React53.useState(false);
|
|
20126
|
+
const alignClass = align === "right" ? "text-right" : align === "center" ? "text-center" : "text-left";
|
|
20127
|
+
const measureOverflow = React53.useCallback(() => {
|
|
20128
|
+
if (typeof document === "undefined") return;
|
|
20129
|
+
const element = document.querySelector(`[data-underverse-datatable-cell="${triggerId}"]`);
|
|
20130
|
+
if (!element) return;
|
|
20131
|
+
setIsOverflowing(
|
|
20132
|
+
element.scrollWidth - element.clientWidth > 1 || element.scrollHeight - element.clientHeight > 1
|
|
20133
|
+
);
|
|
20134
|
+
}, [triggerId]);
|
|
20135
|
+
React53.useLayoutEffect(() => {
|
|
20136
|
+
measureOverflow();
|
|
20137
|
+
}, [measureOverflow, text]);
|
|
20138
|
+
React53.useEffect(() => {
|
|
20139
|
+
if (typeof document === "undefined") return;
|
|
20140
|
+
const element = document.querySelector(`[data-underverse-datatable-cell="${triggerId}"]`);
|
|
20141
|
+
if (!element) return;
|
|
20142
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
20143
|
+
const observer = new ResizeObserver(() => {
|
|
20144
|
+
measureOverflow();
|
|
20145
|
+
});
|
|
20146
|
+
observer.observe(element);
|
|
20147
|
+
return () => observer.disconnect();
|
|
20148
|
+
}, [measureOverflow, triggerId]);
|
|
20149
|
+
const trigger = /* @__PURE__ */ jsx62(
|
|
20150
|
+
"button",
|
|
20151
|
+
{
|
|
20152
|
+
type: "button",
|
|
20153
|
+
"data-underverse-datatable-cell": triggerId,
|
|
20154
|
+
onMouseEnter: measureOverflow,
|
|
20155
|
+
onFocus: measureOverflow,
|
|
20156
|
+
className: cn(
|
|
20157
|
+
"block w-full truncate bg-transparent p-0 font-inherit text-inherit select-text",
|
|
20158
|
+
"cursor-text",
|
|
20159
|
+
alignClass
|
|
20160
|
+
),
|
|
20161
|
+
children: text
|
|
20162
|
+
}
|
|
20163
|
+
);
|
|
20164
|
+
return /* @__PURE__ */ jsx62(
|
|
20165
|
+
Tooltip,
|
|
20166
|
+
{
|
|
20167
|
+
disabled: !isOverflowing,
|
|
20168
|
+
placement: "top",
|
|
20169
|
+
content: /* @__PURE__ */ jsx62("div", { className: cn("max-w-[min(40rem,calc(100vw-2rem))] whitespace-pre-wrap break-all select-text", alignClass), children: text }),
|
|
20170
|
+
children: trigger
|
|
20171
|
+
}
|
|
20172
|
+
);
|
|
20173
|
+
}
|
|
20119
20174
|
function DataTableBodyRows({
|
|
20120
20175
|
leafColumns,
|
|
20121
20176
|
displayedData,
|
|
@@ -20164,6 +20219,7 @@ function DataTableBodyRows({
|
|
|
20164
20219
|
return /* @__PURE__ */ jsx62(
|
|
20165
20220
|
TableCell,
|
|
20166
20221
|
{
|
|
20222
|
+
"data-underverse-column-key": col.key,
|
|
20167
20223
|
style: getStickyColumnStyle(col),
|
|
20168
20224
|
className: cn(
|
|
20169
20225
|
cellPadding,
|
|
@@ -20172,7 +20228,7 @@ function DataTableBodyRows({
|
|
|
20172
20228
|
showBorderLeft && "border-l border-border/60",
|
|
20173
20229
|
getStickyCellClass(col, isStripedRow)
|
|
20174
20230
|
),
|
|
20175
|
-
children: col.render ? col.render(value, row, idx) : String(value ?? "")
|
|
20231
|
+
children: col.render ? col.render(value, row, idx) : /* @__PURE__ */ jsx62(DataTableOverflowText, { text: String(value ?? ""), align: col.align })
|
|
20176
20232
|
},
|
|
20177
20233
|
col.key
|
|
20178
20234
|
);
|
|
@@ -20184,7 +20240,7 @@ function DataTableBodyRows({
|
|
|
20184
20240
|
}
|
|
20185
20241
|
|
|
20186
20242
|
// src/components/DataTable/components/DataTableHeader.tsx
|
|
20187
|
-
import
|
|
20243
|
+
import React54 from "react";
|
|
20188
20244
|
import { Filter as FilterIcon } from "lucide-react";
|
|
20189
20245
|
import { Fragment as Fragment22, jsx as jsx63, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
20190
20246
|
function DataTableHeader({
|
|
@@ -20200,11 +20256,13 @@ function DataTableHeader({
|
|
|
20200
20256
|
setCurPage,
|
|
20201
20257
|
setFilters,
|
|
20202
20258
|
setSort,
|
|
20259
|
+
onAutoFitColumn,
|
|
20260
|
+
enableHeaderAutoFit,
|
|
20203
20261
|
getStickyHeaderClass,
|
|
20204
20262
|
getStickyHeaderCellStyle,
|
|
20205
20263
|
t
|
|
20206
20264
|
}) {
|
|
20207
|
-
const renderFilterControl =
|
|
20265
|
+
const renderFilterControl = React54.useCallback(
|
|
20208
20266
|
(col) => {
|
|
20209
20267
|
if (!col.filter) return null;
|
|
20210
20268
|
const key = col.key;
|
|
@@ -20257,7 +20315,7 @@ function DataTableHeader({
|
|
|
20257
20315
|
},
|
|
20258
20316
|
[filters, setCurPage, setFilters, size]
|
|
20259
20317
|
);
|
|
20260
|
-
const renderHeaderContent =
|
|
20318
|
+
const renderHeaderContent = React54.useCallback(
|
|
20261
20319
|
(col, isLeaf) => {
|
|
20262
20320
|
if (!isLeaf) {
|
|
20263
20321
|
return /* @__PURE__ */ jsx63(
|
|
@@ -20397,22 +20455,55 @@ function DataTableHeader({
|
|
|
20397
20455
|
const prevCol = prevCell?.column;
|
|
20398
20456
|
const isAfterFixedLeft = prevCol?.fixed === "left";
|
|
20399
20457
|
const showBorderLeft = columnDividers && cellIndex > 0 && !isAfterFixedLeft && !col.fixed;
|
|
20400
|
-
return /* @__PURE__ */
|
|
20458
|
+
return /* @__PURE__ */ jsxs53(
|
|
20401
20459
|
TableHead,
|
|
20402
20460
|
{
|
|
20403
20461
|
colSpan,
|
|
20404
20462
|
rowSpan,
|
|
20463
|
+
"data-underverse-column-key": isLeaf ? col.key : void 0,
|
|
20405
20464
|
style: {
|
|
20406
20465
|
width: col.width,
|
|
20407
20466
|
...getStickyHeaderCellStyle(headerCell)
|
|
20408
20467
|
},
|
|
20409
20468
|
className: cn(
|
|
20469
|
+
"relative",
|
|
20410
20470
|
(col.align === "right" || !col.align && headerAlign === "right") && "text-right",
|
|
20411
20471
|
(col.align === "center" || !col.align && headerAlign === "center") && "text-center",
|
|
20412
20472
|
showBorderLeft && "border-l border-border/60",
|
|
20413
20473
|
getStickyHeaderClass(col)
|
|
20414
20474
|
),
|
|
20415
|
-
children:
|
|
20475
|
+
children: [
|
|
20476
|
+
renderHeaderContent(col, isLeaf),
|
|
20477
|
+
isLeaf && enableHeaderAutoFit && /* @__PURE__ */ jsx63(
|
|
20478
|
+
Tooltip,
|
|
20479
|
+
{
|
|
20480
|
+
placement: "top",
|
|
20481
|
+
content: /* @__PURE__ */ jsx63("span", { className: "text-xs font-medium", children: "Double click to auto-fit" }),
|
|
20482
|
+
children: /* @__PURE__ */ jsx63(
|
|
20483
|
+
"button",
|
|
20484
|
+
{
|
|
20485
|
+
type: "button",
|
|
20486
|
+
"aria-label": `Auto fit ${String(col.title)}`,
|
|
20487
|
+
onClick: (event) => {
|
|
20488
|
+
event.preventDefault();
|
|
20489
|
+
event.stopPropagation();
|
|
20490
|
+
},
|
|
20491
|
+
onDoubleClick: (event) => {
|
|
20492
|
+
event.preventDefault();
|
|
20493
|
+
event.stopPropagation();
|
|
20494
|
+
onAutoFitColumn?.(col.key);
|
|
20495
|
+
},
|
|
20496
|
+
className: cn(
|
|
20497
|
+
"absolute inset-y-0 right-0 z-10 w-3 -mr-1",
|
|
20498
|
+
"cursor-col-resize select-none bg-transparent",
|
|
20499
|
+
"after:absolute after:inset-y-2 after:right-[3px] after:w-px after:bg-border/0 after:transition-colors",
|
|
20500
|
+
"hover:after:bg-primary/50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary"
|
|
20501
|
+
)
|
|
20502
|
+
}
|
|
20503
|
+
)
|
|
20504
|
+
}
|
|
20505
|
+
)
|
|
20506
|
+
]
|
|
20416
20507
|
},
|
|
20417
20508
|
col.key
|
|
20418
20509
|
);
|
|
@@ -20420,7 +20511,7 @@ function DataTableHeader({
|
|
|
20420
20511
|
}
|
|
20421
20512
|
|
|
20422
20513
|
// src/components/DataTable/components/Pagination.tsx
|
|
20423
|
-
import
|
|
20514
|
+
import React55 from "react";
|
|
20424
20515
|
import { jsx as jsx64, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
20425
20516
|
function DataTablePagination({
|
|
20426
20517
|
totalItems,
|
|
@@ -20432,7 +20523,7 @@ function DataTablePagination({
|
|
|
20432
20523
|
size
|
|
20433
20524
|
}) {
|
|
20434
20525
|
const totalPages = Math.ceil(totalItems / curPageSize);
|
|
20435
|
-
const pages =
|
|
20526
|
+
const pages = React55.useMemo(() => {
|
|
20436
20527
|
const result = [];
|
|
20437
20528
|
if (totalPages <= 5) {
|
|
20438
20529
|
for (let i = 1; i <= totalPages; i++) result.push(i);
|
|
@@ -20514,7 +20605,7 @@ function DataTablePagination({
|
|
|
20514
20605
|
}
|
|
20515
20606
|
|
|
20516
20607
|
// src/components/DataTable/components/Toolbar.tsx
|
|
20517
|
-
import
|
|
20608
|
+
import React56 from "react";
|
|
20518
20609
|
|
|
20519
20610
|
// src/components/DataTable/utils/headers.ts
|
|
20520
20611
|
function isLeafColumn(col) {
|
|
@@ -20635,7 +20726,7 @@ function DataTableToolbar({
|
|
|
20635
20726
|
const controlButtonClass = size === "sm" ? "h-7 px-2 text-xs" : size === "lg" ? "h-9 px-3 text-sm" : "h-8 px-2";
|
|
20636
20727
|
const iconClass = size === "sm" ? "w-3.5 h-3.5 mr-1" : "w-4 h-4 mr-1";
|
|
20637
20728
|
const captionClass = size === "sm" ? "text-xs" : size === "lg" ? "text-sm" : "text-sm";
|
|
20638
|
-
const leafCols =
|
|
20729
|
+
const leafCols = React56.useMemo(() => getLeafColumns(columns), [columns]);
|
|
20639
20730
|
return /* @__PURE__ */ jsxs55("div", { className: "flex items-center justify-between gap-4 mb-1", children: [
|
|
20640
20731
|
/* @__PURE__ */ jsx65("div", { className: captionClass + " text-muted-foreground", children: caption }),
|
|
20641
20732
|
/* @__PURE__ */ jsxs55("div", { className: "flex items-center gap-2", children: [
|
|
@@ -20703,10 +20794,10 @@ function DataTableToolbar({
|
|
|
20703
20794
|
}
|
|
20704
20795
|
|
|
20705
20796
|
// src/components/DataTable/hooks/useDebounced.ts
|
|
20706
|
-
import
|
|
20797
|
+
import React57 from "react";
|
|
20707
20798
|
function useDebounced(value, delay = 300) {
|
|
20708
|
-
const [debounced, setDebounced] =
|
|
20709
|
-
|
|
20799
|
+
const [debounced, setDebounced] = React57.useState(value);
|
|
20800
|
+
React57.useEffect(() => {
|
|
20710
20801
|
const id = setTimeout(() => setDebounced(value), delay);
|
|
20711
20802
|
return () => clearTimeout(id);
|
|
20712
20803
|
}, [value, delay]);
|
|
@@ -20714,7 +20805,7 @@ function useDebounced(value, delay = 300) {
|
|
|
20714
20805
|
}
|
|
20715
20806
|
|
|
20716
20807
|
// src/components/DataTable/hooks/useDataTableModel.ts
|
|
20717
|
-
import
|
|
20808
|
+
import React58 from "react";
|
|
20718
20809
|
|
|
20719
20810
|
// src/components/DataTable/utils/columns.ts
|
|
20720
20811
|
function getColumnWidth(col, fallback = 150) {
|
|
@@ -20742,22 +20833,22 @@ function useDataTableModel({
|
|
|
20742
20833
|
isServerMode,
|
|
20743
20834
|
total
|
|
20744
20835
|
}) {
|
|
20745
|
-
const visibleColsSet =
|
|
20746
|
-
const allLeafColumns =
|
|
20747
|
-
const columnMap =
|
|
20836
|
+
const visibleColsSet = React58.useMemo(() => new Set(visibleCols), [visibleCols]);
|
|
20837
|
+
const allLeafColumns = React58.useMemo(() => getLeafColumns(columns), [columns]);
|
|
20838
|
+
const columnMap = React58.useMemo(() => {
|
|
20748
20839
|
return new Map(allLeafColumns.map((column) => [column.key, column]));
|
|
20749
20840
|
}, [allLeafColumns]);
|
|
20750
|
-
const visibleColumns =
|
|
20841
|
+
const visibleColumns = React58.useMemo(() => {
|
|
20751
20842
|
return filterVisibleColumns(columns, visibleColsSet);
|
|
20752
20843
|
}, [columns, visibleColsSet]);
|
|
20753
|
-
const leafColumns =
|
|
20844
|
+
const leafColumns = React58.useMemo(() => {
|
|
20754
20845
|
return getLeafColumnsWithFixedInheritance(visibleColumns);
|
|
20755
20846
|
}, [visibleColumns]);
|
|
20756
|
-
const headerRows =
|
|
20757
|
-
const totalColumnsWidth =
|
|
20847
|
+
const headerRows = React58.useMemo(() => buildHeaderRows(visibleColumns), [visibleColumns]);
|
|
20848
|
+
const totalColumnsWidth = React58.useMemo(() => {
|
|
20758
20849
|
return leafColumns.reduce((sum, column) => sum + getColumnWidth(column), 0);
|
|
20759
20850
|
}, [leafColumns]);
|
|
20760
|
-
const processedData =
|
|
20851
|
+
const processedData = React58.useMemo(() => {
|
|
20761
20852
|
if (isServerMode) return data;
|
|
20762
20853
|
let result = [...data];
|
|
20763
20854
|
if (Object.keys(filters).length > 0) {
|
|
@@ -20789,7 +20880,7 @@ function useDataTableModel({
|
|
|
20789
20880
|
return result;
|
|
20790
20881
|
}, [columnMap, data, filters, isServerMode, sort]);
|
|
20791
20882
|
const totalItems = isServerMode ? total : processedData.length;
|
|
20792
|
-
const displayedData =
|
|
20883
|
+
const displayedData = React58.useMemo(() => {
|
|
20793
20884
|
if (isServerMode) return data;
|
|
20794
20885
|
const start = (curPage - 1) * curPageSize;
|
|
20795
20886
|
return processedData.slice(start, start + curPageSize);
|
|
@@ -20805,10 +20896,10 @@ function useDataTableModel({
|
|
|
20805
20896
|
}
|
|
20806
20897
|
|
|
20807
20898
|
// src/components/DataTable/hooks/useDataTableState.ts
|
|
20808
|
-
import
|
|
20899
|
+
import React60 from "react";
|
|
20809
20900
|
|
|
20810
20901
|
// src/components/DataTable/hooks/usePageSizeStorage.ts
|
|
20811
|
-
import
|
|
20902
|
+
import React59 from "react";
|
|
20812
20903
|
function readStoredPageSize(storageKey) {
|
|
20813
20904
|
if (typeof window === "undefined" || !storageKey) return null;
|
|
20814
20905
|
try {
|
|
@@ -20821,8 +20912,8 @@ function readStoredPageSize(storageKey) {
|
|
|
20821
20912
|
}
|
|
20822
20913
|
}
|
|
20823
20914
|
function usePageSizeStorage({ pageSize, storageKey }) {
|
|
20824
|
-
const storedPageSize =
|
|
20825
|
-
const [overrideState, setOverrideState] =
|
|
20915
|
+
const storedPageSize = React59.useMemo(() => readStoredPageSize(storageKey), [storageKey]);
|
|
20916
|
+
const [overrideState, setOverrideState] = React59.useState({
|
|
20826
20917
|
storageKey,
|
|
20827
20918
|
pageSize: null
|
|
20828
20919
|
});
|
|
@@ -20830,7 +20921,7 @@ function usePageSizeStorage({ pageSize, storageKey }) {
|
|
|
20830
20921
|
const persistedPageSize = storageKey ? overridePageSize ?? storedPageSize : null;
|
|
20831
20922
|
const loadedFromStorage = persistedPageSize != null;
|
|
20832
20923
|
const curPageSize = storageKey ? persistedPageSize ?? pageSize : overridePageSize ?? pageSize;
|
|
20833
|
-
const setCurPageSize =
|
|
20924
|
+
const setCurPageSize = React59.useCallback(
|
|
20834
20925
|
(nextPageSize) => {
|
|
20835
20926
|
const baseValue = storageKey ? persistedPageSize ?? pageSize : overridePageSize ?? pageSize;
|
|
20836
20927
|
const resolved = typeof nextPageSize === "function" ? nextPageSize(baseValue) : nextPageSize;
|
|
@@ -20859,17 +20950,17 @@ function useDataTableState({
|
|
|
20859
20950
|
size,
|
|
20860
20951
|
storageKey
|
|
20861
20952
|
}) {
|
|
20862
|
-
const allLeafColumns =
|
|
20863
|
-
const defaultVisibleLeafKeys =
|
|
20864
|
-
const knownLeafKeysRef =
|
|
20865
|
-
const [headerAlign, setHeaderAlign] =
|
|
20866
|
-
const [visibleCols, setVisibleCols] =
|
|
20867
|
-
const [filters, setFilters] =
|
|
20868
|
-
const [sort, setSort] =
|
|
20869
|
-
const [density, setDensity] =
|
|
20870
|
-
const [curPage, setCurPage] =
|
|
20953
|
+
const allLeafColumns = React60.useMemo(() => getLeafColumns(columns), [columns]);
|
|
20954
|
+
const defaultVisibleLeafKeys = React60.useMemo(() => allLeafColumns.filter((column) => column.visible !== false).map((column) => column.key), [allLeafColumns]);
|
|
20955
|
+
const knownLeafKeysRef = React60.useRef(new Set(defaultVisibleLeafKeys));
|
|
20956
|
+
const [headerAlign, setHeaderAlign] = React60.useState("left");
|
|
20957
|
+
const [visibleCols, setVisibleCols] = React60.useState(defaultVisibleLeafKeys);
|
|
20958
|
+
const [filters, setFilters] = React60.useState({});
|
|
20959
|
+
const [sort, setSort] = React60.useState(null);
|
|
20960
|
+
const [density, setDensity] = React60.useState(() => SIZE_TO_DENSITY[size]);
|
|
20961
|
+
const [curPage, setCurPage] = React60.useState(page);
|
|
20871
20962
|
const { curPageSize, setCurPageSize } = usePageSizeStorage({ pageSize, storageKey });
|
|
20872
|
-
|
|
20963
|
+
React60.useEffect(() => {
|
|
20873
20964
|
const knownLeafKeys = knownLeafKeysRef.current;
|
|
20874
20965
|
setVisibleCols((prev) => {
|
|
20875
20966
|
const prevSet = new Set(prev);
|
|
@@ -20877,10 +20968,10 @@ function useDataTableState({
|
|
|
20877
20968
|
});
|
|
20878
20969
|
knownLeafKeysRef.current = new Set(allLeafColumns.map((column) => column.key));
|
|
20879
20970
|
}, [allLeafColumns]);
|
|
20880
|
-
|
|
20971
|
+
React60.useEffect(() => {
|
|
20881
20972
|
setCurPage(page);
|
|
20882
20973
|
}, [page]);
|
|
20883
|
-
|
|
20974
|
+
React60.useEffect(() => {
|
|
20884
20975
|
setDensity(SIZE_TO_DENSITY[size]);
|
|
20885
20976
|
}, [size]);
|
|
20886
20977
|
return {
|
|
@@ -20902,7 +20993,7 @@ function useDataTableState({
|
|
|
20902
20993
|
}
|
|
20903
20994
|
|
|
20904
20995
|
// src/components/DataTable/hooks/useStickyColumns.ts
|
|
20905
|
-
import
|
|
20996
|
+
import React61 from "react";
|
|
20906
20997
|
|
|
20907
20998
|
// src/components/DataTable/utils/sticky.ts
|
|
20908
20999
|
function buildStickyLayout(visibleColumns) {
|
|
@@ -20949,8 +21040,8 @@ function resolveGroupStickyPosition(column, positions) {
|
|
|
20949
21040
|
|
|
20950
21041
|
// src/components/DataTable/hooks/useStickyColumns.ts
|
|
20951
21042
|
function useStickyColumns(visibleColumns) {
|
|
20952
|
-
const { positions, leftBoundaryKey, rightBoundaryKey } =
|
|
20953
|
-
const getStickyColumnStyle =
|
|
21043
|
+
const { positions, leftBoundaryKey, rightBoundaryKey } = React61.useMemo(() => buildStickyLayout(visibleColumns), [visibleColumns]);
|
|
21044
|
+
const getStickyColumnStyle = React61.useCallback(
|
|
20954
21045
|
(col) => {
|
|
20955
21046
|
const pos = resolveStickyPosition(col, positions);
|
|
20956
21047
|
if (!pos) return {};
|
|
@@ -20961,7 +21052,7 @@ function useStickyColumns(visibleColumns) {
|
|
|
20961
21052
|
},
|
|
20962
21053
|
[positions]
|
|
20963
21054
|
);
|
|
20964
|
-
const getBoundaryShadowClass =
|
|
21055
|
+
const getBoundaryShadowClass = React61.useCallback(
|
|
20965
21056
|
(col) => {
|
|
20966
21057
|
if (col.fixed === "left" && col.key === leftBoundaryKey) {
|
|
20967
21058
|
return "border-r border-border/80 shadow-[10px_0_16px_-10px_rgba(0,0,0,0.55)]";
|
|
@@ -20973,14 +21064,14 @@ function useStickyColumns(visibleColumns) {
|
|
|
20973
21064
|
},
|
|
20974
21065
|
[leftBoundaryKey, rightBoundaryKey]
|
|
20975
21066
|
);
|
|
20976
|
-
const getStickyHeaderClass =
|
|
21067
|
+
const getStickyHeaderClass = React61.useCallback(
|
|
20977
21068
|
(col) => {
|
|
20978
21069
|
if (!col.fixed) return "";
|
|
20979
21070
|
return cn("sticky", col.fixed === "left" && "left-0", col.fixed === "right" && "right-0", getBoundaryShadowClass(col), "z-50 !bg-muted");
|
|
20980
21071
|
},
|
|
20981
21072
|
[getBoundaryShadowClass]
|
|
20982
21073
|
);
|
|
20983
|
-
const getStickyCellClass =
|
|
21074
|
+
const getStickyCellClass = React61.useCallback(
|
|
20984
21075
|
(col, isStripedRow) => {
|
|
20985
21076
|
if (!col.fixed) return "";
|
|
20986
21077
|
return cn(
|
|
@@ -20993,7 +21084,7 @@ function useStickyColumns(visibleColumns) {
|
|
|
20993
21084
|
},
|
|
20994
21085
|
[getBoundaryShadowClass]
|
|
20995
21086
|
);
|
|
20996
|
-
const getStickyHeaderCellStyle =
|
|
21087
|
+
const getStickyHeaderCellStyle = React61.useCallback(
|
|
20997
21088
|
(headerCell) => {
|
|
20998
21089
|
const col = headerCell.column;
|
|
20999
21090
|
if (headerCell.isLeaf) {
|
|
@@ -21092,6 +21183,66 @@ function validateColumns(columns) {
|
|
|
21092
21183
|
|
|
21093
21184
|
// src/components/DataTable/DataTable.tsx
|
|
21094
21185
|
import { jsx as jsx66, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
21186
|
+
function applyColumnWidthOverrides(columns, widthOverrides) {
|
|
21187
|
+
return columns.map((column) => {
|
|
21188
|
+
if (column.children?.length) {
|
|
21189
|
+
return {
|
|
21190
|
+
...column,
|
|
21191
|
+
children: applyColumnWidthOverrides(column.children, widthOverrides)
|
|
21192
|
+
};
|
|
21193
|
+
}
|
|
21194
|
+
const nextWidth = widthOverrides[column.key];
|
|
21195
|
+
if (nextWidth == null) {
|
|
21196
|
+
return column;
|
|
21197
|
+
}
|
|
21198
|
+
return {
|
|
21199
|
+
...column,
|
|
21200
|
+
width: nextWidth
|
|
21201
|
+
};
|
|
21202
|
+
});
|
|
21203
|
+
}
|
|
21204
|
+
function measureNaturalContentWidth(node) {
|
|
21205
|
+
if (typeof document === "undefined") return 0;
|
|
21206
|
+
const measurementRoot = document.createElement("div");
|
|
21207
|
+
measurementRoot.style.position = "absolute";
|
|
21208
|
+
measurementRoot.style.left = "-99999px";
|
|
21209
|
+
measurementRoot.style.top = "0";
|
|
21210
|
+
measurementRoot.style.visibility = "hidden";
|
|
21211
|
+
measurementRoot.style.pointerEvents = "none";
|
|
21212
|
+
measurementRoot.style.whiteSpace = "nowrap";
|
|
21213
|
+
measurementRoot.style.width = "max-content";
|
|
21214
|
+
measurementRoot.style.maxWidth = "none";
|
|
21215
|
+
measurementRoot.style.minWidth = "0";
|
|
21216
|
+
measurementRoot.style.overflow = "visible";
|
|
21217
|
+
const clone = (node.firstElementChild instanceof HTMLElement ? node.firstElementChild : node).cloneNode(true);
|
|
21218
|
+
if (!(clone instanceof HTMLElement)) {
|
|
21219
|
+
return 0;
|
|
21220
|
+
}
|
|
21221
|
+
const sourceStyle = window.getComputedStyle(node);
|
|
21222
|
+
const cloneStyle = window.getComputedStyle(clone);
|
|
21223
|
+
clone.style.width = "max-content";
|
|
21224
|
+
clone.style.maxWidth = "none";
|
|
21225
|
+
clone.style.minWidth = "0";
|
|
21226
|
+
clone.style.overflow = "visible";
|
|
21227
|
+
clone.style.textOverflow = "clip";
|
|
21228
|
+
clone.style.whiteSpace = cloneStyle.whiteSpace === "normal" ? "pre-wrap" : "nowrap";
|
|
21229
|
+
measurementRoot.appendChild(clone);
|
|
21230
|
+
document.body.appendChild(measurementRoot);
|
|
21231
|
+
const horizontalPadding = parseFloat(sourceStyle.paddingLeft || "0") + parseFloat(sourceStyle.paddingRight || "0");
|
|
21232
|
+
const horizontalBorder = parseFloat(sourceStyle.borderLeftWidth || "0") + parseFloat(sourceStyle.borderRightWidth || "0");
|
|
21233
|
+
const cloneRectWidth = clone.getBoundingClientRect().width;
|
|
21234
|
+
const cloneScrollWidth = clone.scrollWidth;
|
|
21235
|
+
const sourceScrollWidth = node.scrollWidth;
|
|
21236
|
+
const measuredContentWidth = Math.max(cloneRectWidth, cloneScrollWidth) || sourceScrollWidth;
|
|
21237
|
+
const measured = Math.ceil(measuredContentWidth + horizontalPadding + horizontalBorder);
|
|
21238
|
+
document.body.removeChild(measurementRoot);
|
|
21239
|
+
return measured;
|
|
21240
|
+
}
|
|
21241
|
+
function isNodeOverflowing(node) {
|
|
21242
|
+
const contentNode = node.firstElementChild instanceof HTMLElement ? node.firstElementChild : node;
|
|
21243
|
+
return node.scrollWidth > node.clientWidth + 1 || contentNode.scrollWidth > contentNode.clientWidth + 1;
|
|
21244
|
+
}
|
|
21245
|
+
var AUTO_FIT_BUFFER_PX = 8;
|
|
21095
21246
|
function DataTable({
|
|
21096
21247
|
columns,
|
|
21097
21248
|
data,
|
|
@@ -21115,9 +21266,15 @@ function DataTable({
|
|
|
21115
21266
|
stickyHeader = true,
|
|
21116
21267
|
maxHeight = 500,
|
|
21117
21268
|
useOverlayScrollbar = false,
|
|
21269
|
+
enableHeaderAutoFit = true,
|
|
21118
21270
|
labels
|
|
21119
21271
|
}) {
|
|
21120
21272
|
const t = useSmartTranslations("Common");
|
|
21273
|
+
const [columnWidthOverrides, setColumnWidthOverrides] = React62.useState({});
|
|
21274
|
+
const columnsWithWidthOverrides = React62.useMemo(
|
|
21275
|
+
() => applyColumnWidthOverrides(columns, columnWidthOverrides),
|
|
21276
|
+
[columnWidthOverrides, columns]
|
|
21277
|
+
);
|
|
21121
21278
|
const {
|
|
21122
21279
|
headerAlign,
|
|
21123
21280
|
setHeaderAlign,
|
|
@@ -21134,22 +21291,22 @@ function DataTable({
|
|
|
21134
21291
|
curPageSize,
|
|
21135
21292
|
setCurPageSize
|
|
21136
21293
|
} = useDataTableState({
|
|
21137
|
-
columns,
|
|
21294
|
+
columns: columnsWithWidthOverrides,
|
|
21138
21295
|
page,
|
|
21139
21296
|
pageSize,
|
|
21140
21297
|
size,
|
|
21141
21298
|
storageKey
|
|
21142
21299
|
});
|
|
21143
|
-
|
|
21300
|
+
React62.useEffect(() => {
|
|
21144
21301
|
if (process.env.NODE_ENV === "development") {
|
|
21145
|
-
const warnings = validateColumns(
|
|
21302
|
+
const warnings = validateColumns(columnsWithWidthOverrides);
|
|
21146
21303
|
warnings.forEach((w) => console.warn(`[DataTable] ${w}`));
|
|
21147
21304
|
}
|
|
21148
|
-
}, [
|
|
21305
|
+
}, [columnsWithWidthOverrides]);
|
|
21149
21306
|
const debouncedFilters = useDebounced(filters, 350);
|
|
21150
21307
|
const isServerMode = Boolean(onQueryChange);
|
|
21151
|
-
const hasEmittedQuery =
|
|
21152
|
-
|
|
21308
|
+
const hasEmittedQuery = React62.useRef(false);
|
|
21309
|
+
React62.useEffect(() => {
|
|
21153
21310
|
if (!onQueryChange) return;
|
|
21154
21311
|
if (!hasEmittedQuery.current) {
|
|
21155
21312
|
hasEmittedQuery.current = true;
|
|
@@ -21157,7 +21314,7 @@ function DataTable({
|
|
|
21157
21314
|
}
|
|
21158
21315
|
onQueryChange({ filters: debouncedFilters, sort, page: curPage, pageSize: curPageSize });
|
|
21159
21316
|
}, [debouncedFilters, sort, curPage, curPageSize, onQueryChange]);
|
|
21160
|
-
|
|
21317
|
+
React62.useEffect(() => {
|
|
21161
21318
|
if (process.env.NODE_ENV !== "development" || rowKey) return;
|
|
21162
21319
|
const hasQueryFeatures = columns.some((column) => column.sortable || column.filter) || Boolean(pageSizeOptions?.length) || isServerMode;
|
|
21163
21320
|
if (!hasQueryFeatures) return;
|
|
@@ -21169,7 +21326,7 @@ function DataTable({
|
|
|
21169
21326
|
const headerMinHeightClass = size === "sm" ? "min-h-9" : size === "lg" ? "min-h-11" : "min-h-10";
|
|
21170
21327
|
const sortIconClass = size === "sm" ? "w-3.5 h-3.5" : size === "lg" ? "w-4 h-4" : "w-3.5 h-3.5";
|
|
21171
21328
|
const { visibleColumns, leafColumns, headerRows, totalColumnsWidth, totalItems, displayedData } = useDataTableModel({
|
|
21172
|
-
columns,
|
|
21329
|
+
columns: columnsWithWidthOverrides,
|
|
21173
21330
|
data,
|
|
21174
21331
|
visibleCols,
|
|
21175
21332
|
filters,
|
|
@@ -21185,15 +21342,45 @@ function DataTable({
|
|
|
21185
21342
|
if (typeof rowKey === "function") return String(rowKey(row));
|
|
21186
21343
|
return String(row[rowKey]);
|
|
21187
21344
|
};
|
|
21188
|
-
const viewportRef =
|
|
21345
|
+
const viewportRef = React62.useRef(null);
|
|
21346
|
+
const tableRef = React62.useRef(null);
|
|
21189
21347
|
useOverlayScrollbarTarget(viewportRef, { enabled: useOverlayScrollbar });
|
|
21348
|
+
const autoFitColumn = React62.useCallback((columnKey) => {
|
|
21349
|
+
const tableElement = tableRef.current;
|
|
21350
|
+
if (!tableElement) return;
|
|
21351
|
+
const nodes = Array.from(
|
|
21352
|
+
tableElement.querySelectorAll(`[data-underverse-column-key="${columnKey}"]`)
|
|
21353
|
+
);
|
|
21354
|
+
if (nodes.length === 0) return;
|
|
21355
|
+
const hasOverflow = nodes.some((node) => isNodeOverflowing(node));
|
|
21356
|
+
if (!hasOverflow) return;
|
|
21357
|
+
const measuredWidth = nodes.reduce((maxWidth, node) => {
|
|
21358
|
+
const nextWidth2 = measureNaturalContentWidth(node);
|
|
21359
|
+
return Math.max(maxWidth, nextWidth2);
|
|
21360
|
+
}, 0);
|
|
21361
|
+
const currentRenderedWidth = nodes.reduce((maxWidth, node) => {
|
|
21362
|
+
const nextWidth2 = Math.max(
|
|
21363
|
+
Math.ceil(node.getBoundingClientRect().width || 0),
|
|
21364
|
+
node.offsetWidth || 0,
|
|
21365
|
+
node.clientWidth || 0
|
|
21366
|
+
);
|
|
21367
|
+
return Math.max(maxWidth, nextWidth2);
|
|
21368
|
+
}, 0);
|
|
21369
|
+
if (measuredWidth <= 0) return;
|
|
21370
|
+
if (currentRenderedWidth > 0 && measuredWidth <= currentRenderedWidth + AUTO_FIT_BUFFER_PX) return;
|
|
21371
|
+
const nextWidth = Math.max(80, measuredWidth + AUTO_FIT_BUFFER_PX);
|
|
21372
|
+
setColumnWidthOverrides((prev) => {
|
|
21373
|
+
if (prev[columnKey] === nextWidth) return prev;
|
|
21374
|
+
return { ...prev, [columnKey]: nextWidth };
|
|
21375
|
+
});
|
|
21376
|
+
}, []);
|
|
21190
21377
|
return /* @__PURE__ */ jsxs56("div", { className: cn("space-y-2", className), children: [
|
|
21191
21378
|
/* @__PURE__ */ jsx66(
|
|
21192
21379
|
DataTableToolbar,
|
|
21193
21380
|
{
|
|
21194
21381
|
caption,
|
|
21195
21382
|
toolbar,
|
|
21196
|
-
columns,
|
|
21383
|
+
columns: columnsWithWidthOverrides,
|
|
21197
21384
|
visibleCols,
|
|
21198
21385
|
setVisibleCols,
|
|
21199
21386
|
enableDensityToggle,
|
|
@@ -21223,6 +21410,7 @@ function DataTable({
|
|
|
21223
21410
|
children: /* @__PURE__ */ jsxs56(
|
|
21224
21411
|
Table,
|
|
21225
21412
|
{
|
|
21413
|
+
ref: tableRef,
|
|
21226
21414
|
disableContainer: true,
|
|
21227
21415
|
className: cn(
|
|
21228
21416
|
"table-fixed",
|
|
@@ -21245,6 +21433,8 @@ function DataTable({
|
|
|
21245
21433
|
setCurPage,
|
|
21246
21434
|
setFilters,
|
|
21247
21435
|
setSort,
|
|
21436
|
+
onAutoFitColumn: autoFitColumn,
|
|
21437
|
+
enableHeaderAutoFit,
|
|
21248
21438
|
getStickyHeaderClass,
|
|
21249
21439
|
getStickyHeaderCellStyle,
|
|
21250
21440
|
t
|
|
@@ -21291,10 +21481,10 @@ function DataTable({
|
|
|
21291
21481
|
var DataTable_default = DataTable;
|
|
21292
21482
|
|
|
21293
21483
|
// src/components/Form.tsx
|
|
21294
|
-
import * as
|
|
21484
|
+
import * as React63 from "react";
|
|
21295
21485
|
import { Controller, FormProvider, useFormContext, useForm } from "react-hook-form";
|
|
21296
21486
|
import { jsx as jsx67, jsxs as jsxs57 } from "react/jsx-runtime";
|
|
21297
|
-
var FormConfigContext =
|
|
21487
|
+
var FormConfigContext = React63.createContext({ size: "md" });
|
|
21298
21488
|
var FormWrapper = ({
|
|
21299
21489
|
children,
|
|
21300
21490
|
onSubmit,
|
|
@@ -21307,7 +21497,7 @@ var FormWrapper = ({
|
|
|
21307
21497
|
const methods = useForm({
|
|
21308
21498
|
defaultValues: initialValues
|
|
21309
21499
|
});
|
|
21310
|
-
|
|
21500
|
+
React63.useEffect(() => {
|
|
21311
21501
|
if (initialValues) {
|
|
21312
21502
|
methods.reset(initialValues);
|
|
21313
21503
|
}
|
|
@@ -21316,15 +21506,15 @@ var FormWrapper = ({
|
|
|
21316
21506
|
return /* @__PURE__ */ jsx67(FormProvider, { ...methods, children: /* @__PURE__ */ jsx67(FormConfigContext.Provider, { value: { size }, children: /* @__PURE__ */ jsx67("form", { onSubmit: methods.handleSubmit(onSubmit), className, ...formProps, children }) }) });
|
|
21317
21507
|
};
|
|
21318
21508
|
var Form = FormWrapper;
|
|
21319
|
-
var FormFieldContext =
|
|
21509
|
+
var FormFieldContext = React63.createContext({});
|
|
21320
21510
|
var FormField = ({
|
|
21321
21511
|
...props
|
|
21322
21512
|
}) => {
|
|
21323
21513
|
return /* @__PURE__ */ jsx67(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx67(Controller, { ...props }) });
|
|
21324
21514
|
};
|
|
21325
21515
|
var useFormField = () => {
|
|
21326
|
-
const fieldContext =
|
|
21327
|
-
const itemContext =
|
|
21516
|
+
const fieldContext = React63.useContext(FormFieldContext);
|
|
21517
|
+
const itemContext = React63.useContext(FormItemContext);
|
|
21328
21518
|
const { getFieldState, formState } = useFormContext();
|
|
21329
21519
|
if (!fieldContext) {
|
|
21330
21520
|
throw new Error("useFormField must be used within FormField");
|
|
@@ -21340,16 +21530,16 @@ var useFormField = () => {
|
|
|
21340
21530
|
...fieldState
|
|
21341
21531
|
};
|
|
21342
21532
|
};
|
|
21343
|
-
var FormItemContext =
|
|
21344
|
-
var FormItem =
|
|
21345
|
-
const id =
|
|
21533
|
+
var FormItemContext = React63.createContext({});
|
|
21534
|
+
var FormItem = React63.forwardRef(({ className, ...props }, ref) => {
|
|
21535
|
+
const id = React63.useId();
|
|
21346
21536
|
return /* @__PURE__ */ jsx67(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx67("div", { ref, className: cn("space-y-2", className), ...props }) });
|
|
21347
21537
|
});
|
|
21348
21538
|
FormItem.displayName = "FormItem";
|
|
21349
|
-
var FormLabel =
|
|
21539
|
+
var FormLabel = React63.forwardRef(
|
|
21350
21540
|
({ className, children, required, ...props }, ref) => {
|
|
21351
21541
|
const { error, formItemId } = useFormField();
|
|
21352
|
-
const config =
|
|
21542
|
+
const config = React63.useContext(FormConfigContext);
|
|
21353
21543
|
const sizeClass = config.size === "sm" ? "text-xs" : config.size === "lg" ? "text-base" : "text-sm";
|
|
21354
21544
|
return /* @__PURE__ */ jsxs57(Label, { ref, className: cn(sizeClass, error && "text-destructive", className), htmlFor: formItemId, ...props, children: [
|
|
21355
21545
|
children,
|
|
@@ -21358,7 +21548,7 @@ var FormLabel = React62.forwardRef(
|
|
|
21358
21548
|
}
|
|
21359
21549
|
);
|
|
21360
21550
|
FormLabel.displayName = "FormLabel";
|
|
21361
|
-
var FormControl =
|
|
21551
|
+
var FormControl = React63.forwardRef(({ ...props }, ref) => {
|
|
21362
21552
|
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
|
21363
21553
|
return /* @__PURE__ */ jsx67(
|
|
21364
21554
|
"div",
|
|
@@ -21372,12 +21562,12 @@ var FormControl = React62.forwardRef(({ ...props }, ref) => {
|
|
|
21372
21562
|
);
|
|
21373
21563
|
});
|
|
21374
21564
|
FormControl.displayName = "FormControl";
|
|
21375
|
-
var FormDescription =
|
|
21565
|
+
var FormDescription = React63.forwardRef(({ className, ...props }, ref) => {
|
|
21376
21566
|
const { formDescriptionId } = useFormField();
|
|
21377
21567
|
return /* @__PURE__ */ jsx67("p", { ref, id: formDescriptionId, className: cn("text-sm text-muted-foreground", className), ...props });
|
|
21378
21568
|
});
|
|
21379
21569
|
FormDescription.displayName = "FormDescription";
|
|
21380
|
-
var FormMessage =
|
|
21570
|
+
var FormMessage = React63.forwardRef(({ className, children, ...props }, ref) => {
|
|
21381
21571
|
const { error, formMessageId } = useFormField();
|
|
21382
21572
|
const body = error ? String(error?.message) : children;
|
|
21383
21573
|
if (!body) {
|
|
@@ -21386,7 +21576,7 @@ var FormMessage = React62.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
21386
21576
|
return /* @__PURE__ */ jsx67("p", { ref, id: formMessageId, className: cn("text-sm font-medium text-destructive", className), ...props, children: body });
|
|
21387
21577
|
});
|
|
21388
21578
|
FormMessage.displayName = "FormMessage";
|
|
21389
|
-
var FormInput =
|
|
21579
|
+
var FormInput = React63.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ jsx67(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ jsx67(
|
|
21390
21580
|
FormField,
|
|
21391
21581
|
{
|
|
21392
21582
|
name,
|
|
@@ -21397,7 +21587,7 @@ var FormInput = React62.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */
|
|
|
21397
21587
|
}
|
|
21398
21588
|
) }));
|
|
21399
21589
|
FormInput.displayName = "FormInput";
|
|
21400
|
-
var FormCheckbox =
|
|
21590
|
+
var FormCheckbox = React63.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ jsx67(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ jsx67(
|
|
21401
21591
|
FormField,
|
|
21402
21592
|
{
|
|
21403
21593
|
name,
|
|
@@ -21421,9 +21611,9 @@ var FormCheckbox = React62.forwardRef(({ name, ...props }, ref) => /* @__PURE__
|
|
|
21421
21611
|
}
|
|
21422
21612
|
) }));
|
|
21423
21613
|
FormCheckbox.displayName = "FormCheckbox";
|
|
21424
|
-
var FormActions =
|
|
21614
|
+
var FormActions = React63.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx67("div", { ref, className: cn("flex gap-2 justify-end", className), ...props }));
|
|
21425
21615
|
FormActions.displayName = "FormActions";
|
|
21426
|
-
var FormSubmitButton =
|
|
21616
|
+
var FormSubmitButton = React63.forwardRef(
|
|
21427
21617
|
({ children, loading: loading2, ...props }, ref) => /* @__PURE__ */ jsx67(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ jsx67(Button_default, { ref, type: "submit", size: props.size ?? size, disabled: loading2, ...props, children }) })
|
|
21428
21618
|
);
|
|
21429
21619
|
FormSubmitButton.displayName = "FormSubmitButton";
|
|
@@ -21713,7 +21903,7 @@ var VARIANT_STYLES_ALERT = {
|
|
|
21713
21903
|
};
|
|
21714
21904
|
|
|
21715
21905
|
// ../../lib/i18n/translation-adapter.tsx
|
|
21716
|
-
import * as
|
|
21906
|
+
import * as React65 from "react";
|
|
21717
21907
|
import { jsx as jsx72 } from "react/jsx-runtime";
|
|
21718
21908
|
function isUnresolvedTranslation2(value, namespace, key) {
|
|
21719
21909
|
return value === key || value === `${namespace}.${key}`;
|
|
@@ -21738,7 +21928,7 @@ function useTranslations(namespace) {
|
|
|
21738
21928
|
const nextIntlBridge = useNextIntlBridge();
|
|
21739
21929
|
const internalLocale = useUnderverseLocale();
|
|
21740
21930
|
const internalT = useUnderverseTranslations(namespace);
|
|
21741
|
-
return
|
|
21931
|
+
return React65.useCallback((key, params) => {
|
|
21742
21932
|
if (nextIntlBridge) {
|
|
21743
21933
|
const nextIntlResult = nextIntlBridge.translate(namespace, key, params);
|
|
21744
21934
|
if (nextIntlResult.translated && !isUnresolvedTranslation2(nextIntlResult.translated, namespace, key)) {
|
|
@@ -21763,7 +21953,7 @@ function useLocale2() {
|
|
|
21763
21953
|
}
|
|
21764
21954
|
|
|
21765
21955
|
// src/components/UEditor/UEditor.tsx
|
|
21766
|
-
import
|
|
21956
|
+
import React75, { useEffect as useEffect35, useImperativeHandle as useImperativeHandle3, useMemo as useMemo25, useRef as useRef32 } from "react";
|
|
21767
21957
|
import { useEditor, EditorContent } from "@tiptap/react";
|
|
21768
21958
|
|
|
21769
21959
|
// src/components/UEditor/extensions.ts
|
|
@@ -21803,7 +21993,7 @@ import { common, createLowlight } from "lowlight";
|
|
|
21803
21993
|
import { Extension } from "@tiptap/core";
|
|
21804
21994
|
import Suggestion from "@tiptap/suggestion";
|
|
21805
21995
|
import { ReactRenderer } from "@tiptap/react";
|
|
21806
|
-
import
|
|
21996
|
+
import React66, { forwardRef as forwardRef13, useEffect as useEffect30, useImperativeHandle, useRef as useRef26 } from "react";
|
|
21807
21997
|
import {
|
|
21808
21998
|
FileCode as FileCode2,
|
|
21809
21999
|
Heading1,
|
|
@@ -21846,9 +22036,9 @@ var DEFAULT_MESSAGES = {
|
|
|
21846
22036
|
tableDesc: "Insert a table"
|
|
21847
22037
|
};
|
|
21848
22038
|
function useResettingIndex2(resetToken) {
|
|
21849
|
-
const [state, setState] =
|
|
22039
|
+
const [state, setState] = React66.useState({ resetToken, index: 0 });
|
|
21850
22040
|
const selectedIndex = Object.is(state.resetToken, resetToken) ? state.index : 0;
|
|
21851
|
-
const setSelectedIndex =
|
|
22041
|
+
const setSelectedIndex = React66.useCallback((nextIndex) => {
|
|
21852
22042
|
setState((prev) => {
|
|
21853
22043
|
const prevIndex = Object.is(prev.resetToken, resetToken) ? prev.index : 0;
|
|
21854
22044
|
return {
|
|
@@ -22227,14 +22417,14 @@ import { Extension as Extension3 } from "@tiptap/core";
|
|
|
22227
22417
|
import Suggestion2 from "@tiptap/suggestion";
|
|
22228
22418
|
import { ReactRenderer as ReactRenderer2 } from "@tiptap/react";
|
|
22229
22419
|
import { PluginKey } from "@tiptap/pm/state";
|
|
22230
|
-
import
|
|
22420
|
+
import React67, { forwardRef as forwardRef14, useImperativeHandle as useImperativeHandle2 } from "react";
|
|
22231
22421
|
import { Smile as Smile2 } from "lucide-react";
|
|
22232
22422
|
import tippy2 from "tippy.js";
|
|
22233
22423
|
import { jsx as jsx74, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
22234
22424
|
function useResettingIndex3(resetToken) {
|
|
22235
|
-
const [state, setState] =
|
|
22425
|
+
const [state, setState] = React67.useState({ resetToken, index: 0 });
|
|
22236
22426
|
const selectedIndex = Object.is(state.resetToken, resetToken) ? state.index : 0;
|
|
22237
|
-
const setSelectedIndex =
|
|
22427
|
+
const setSelectedIndex = React67.useCallback((nextIndex) => {
|
|
22238
22428
|
setState((prev) => {
|
|
22239
22429
|
const prevIndex = Object.is(prev.resetToken, resetToken) ? prev.index : 0;
|
|
22240
22430
|
return {
|
|
@@ -22875,7 +23065,7 @@ function buildUEditorExtensions({
|
|
|
22875
23065
|
}
|
|
22876
23066
|
|
|
22877
23067
|
// src/components/UEditor/toolbar.tsx
|
|
22878
|
-
import
|
|
23068
|
+
import React72, { useRef as useRef30, useState as useState44 } from "react";
|
|
22879
23069
|
import {
|
|
22880
23070
|
AlignCenter,
|
|
22881
23071
|
AlignJustify,
|
|
@@ -23362,7 +23552,7 @@ function fileToDataUrl2(file) {
|
|
|
23362
23552
|
reader.readAsDataURL(file);
|
|
23363
23553
|
});
|
|
23364
23554
|
}
|
|
23365
|
-
var ToolbarButton =
|
|
23555
|
+
var ToolbarButton = React72.forwardRef(({ onClick, onMouseDown, active, disabled, children, title, className }, ref) => {
|
|
23366
23556
|
const button = /* @__PURE__ */ jsx79(
|
|
23367
23557
|
"button",
|
|
23368
23558
|
{
|
|
@@ -24580,7 +24770,7 @@ async function prepareUEditorContentForSave({
|
|
|
24580
24770
|
}
|
|
24581
24771
|
|
|
24582
24772
|
// src/components/UEditor/table-controls.tsx
|
|
24583
|
-
import
|
|
24773
|
+
import React74 from "react";
|
|
24584
24774
|
|
|
24585
24775
|
// node_modules/prosemirror-model/dist/index.js
|
|
24586
24776
|
function findDiffStart(a, b, pos) {
|
|
@@ -28756,6 +28946,19 @@ import {
|
|
|
28756
28946
|
import { Fragment as Fragment27, jsx as jsx81, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
28757
28947
|
var FALLBACK_TABLE_ROW_HEIGHT = 44;
|
|
28758
28948
|
var FALLBACK_TABLE_COLUMN_WIDTH = 160;
|
|
28949
|
+
var MENU_HOVER_PADDING = 18;
|
|
28950
|
+
var ROW_HANDLE_HOVER_WIDTH = 28;
|
|
28951
|
+
var COLUMN_HANDLE_HOVER_HEIGHT = 28;
|
|
28952
|
+
var ADD_COLUMN_HOVER_WIDTH = 24;
|
|
28953
|
+
var ADD_ROW_HOVER_HEIGHT = 24;
|
|
28954
|
+
var HANDLE_HOVER_RADIUS = 14;
|
|
28955
|
+
var DEFAULT_HOVER_STATE = {
|
|
28956
|
+
menuVisible: false,
|
|
28957
|
+
addColumnVisible: false,
|
|
28958
|
+
addRowVisible: false,
|
|
28959
|
+
rowHandleIndex: null,
|
|
28960
|
+
columnHandleIndex: null
|
|
28961
|
+
};
|
|
28759
28962
|
function resolveElement(target) {
|
|
28760
28963
|
if (target instanceof Element) return target;
|
|
28761
28964
|
if (target instanceof Node) return target.parentElement;
|
|
@@ -28881,6 +29084,12 @@ function buildLayout(editor, surface, cell) {
|
|
|
28881
29084
|
};
|
|
28882
29085
|
}
|
|
28883
29086
|
function getSelectedCell(editor) {
|
|
29087
|
+
const browserSelection = window.getSelection();
|
|
29088
|
+
const anchorElement = resolveElement(browserSelection?.anchorNode ?? null);
|
|
29089
|
+
const anchorCell = anchorElement?.closest?.("th,td");
|
|
29090
|
+
if (anchorCell instanceof HTMLTableCellElement) {
|
|
29091
|
+
return anchorCell;
|
|
29092
|
+
}
|
|
28884
29093
|
const domAtPos = editor.view.domAtPos(editor.state.selection.from);
|
|
28885
29094
|
return getCellFromTarget(domAtPos.node);
|
|
28886
29095
|
}
|
|
@@ -28907,14 +29116,15 @@ function collectChildren(node) {
|
|
|
28907
29116
|
}
|
|
28908
29117
|
function TableControls({ editor, containerRef }) {
|
|
28909
29118
|
const t = useSmartTranslations("UEditor");
|
|
28910
|
-
const [layout, setLayout] =
|
|
28911
|
-
const [dragPreview, setDragPreview] =
|
|
28912
|
-
const
|
|
28913
|
-
const
|
|
28914
|
-
|
|
29119
|
+
const [layout, setLayout] = React74.useState(null);
|
|
29120
|
+
const [dragPreview, setDragPreview] = React74.useState(null);
|
|
29121
|
+
const [hoverState, setHoverState] = React74.useState(DEFAULT_HOVER_STATE);
|
|
29122
|
+
const layoutRef = React74.useRef(null);
|
|
29123
|
+
const dragStateRef = React74.useRef(null);
|
|
29124
|
+
React74.useEffect(() => {
|
|
28915
29125
|
layoutRef.current = layout;
|
|
28916
29126
|
}, [layout]);
|
|
28917
|
-
const syncFromCell =
|
|
29127
|
+
const syncFromCell = React74.useCallback((cell) => {
|
|
28918
29128
|
const surface = containerRef.current;
|
|
28919
29129
|
if (!surface || !cell) {
|
|
28920
29130
|
setLayout(null);
|
|
@@ -28922,10 +29132,10 @@ function TableControls({ editor, containerRef }) {
|
|
|
28922
29132
|
}
|
|
28923
29133
|
setLayout(buildLayout(editor, surface, cell));
|
|
28924
29134
|
}, [containerRef, editor]);
|
|
28925
|
-
const syncFromSelection =
|
|
29135
|
+
const syncFromSelection = React74.useCallback(() => {
|
|
28926
29136
|
syncFromCell(getSelectedCell(editor));
|
|
28927
29137
|
}, [editor, syncFromCell]);
|
|
28928
|
-
const refreshCurrentLayout =
|
|
29138
|
+
const refreshCurrentLayout = React74.useCallback(() => {
|
|
28929
29139
|
setLayout((prev) => {
|
|
28930
29140
|
if (!prev) return prev;
|
|
28931
29141
|
const surface = containerRef.current;
|
|
@@ -28935,22 +29145,55 @@ function TableControls({ editor, containerRef }) {
|
|
|
28935
29145
|
return cell ? buildLayout(editor, surface, cell) : null;
|
|
28936
29146
|
});
|
|
28937
29147
|
}, [containerRef, editor]);
|
|
28938
|
-
const clearDrag =
|
|
29148
|
+
const clearDrag = React74.useCallback(() => {
|
|
28939
29149
|
dragStateRef.current = null;
|
|
28940
29150
|
setDragPreview(null);
|
|
28941
29151
|
document.body.style.cursor = "";
|
|
28942
29152
|
}, []);
|
|
28943
|
-
|
|
29153
|
+
const updateHoverState = React74.useCallback((event) => {
|
|
29154
|
+
const activeLayout = layoutRef.current;
|
|
29155
|
+
const surface = containerRef.current;
|
|
29156
|
+
if (!activeLayout || !surface || dragStateRef.current) {
|
|
29157
|
+
setHoverState(DEFAULT_HOVER_STATE);
|
|
29158
|
+
return;
|
|
29159
|
+
}
|
|
29160
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
29161
|
+
const relativeX = event.clientX - surfaceRect.left + surface.scrollLeft;
|
|
29162
|
+
const relativeY = event.clientY - surfaceRect.top + surface.scrollTop;
|
|
29163
|
+
const rowHandleIndex = activeLayout.rowHandles.find((rowHandle) => relativeX >= activeLayout.tableLeft - ROW_HANDLE_HOVER_WIDTH && relativeX <= activeLayout.tableLeft && Math.abs(relativeY - rowHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
|
|
29164
|
+
const columnHandleIndex = activeLayout.columnHandles.find((columnHandle) => relativeY >= activeLayout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= activeLayout.tableTop && Math.abs(relativeX - columnHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
|
|
29165
|
+
const menuVisible = relativeX >= activeLayout.tableLeft - MENU_HOVER_PADDING && relativeX <= activeLayout.tableLeft + 42 && relativeY >= activeLayout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= activeLayout.tableTop + MENU_HOVER_PADDING;
|
|
29166
|
+
const addColumnVisible = relativeX >= activeLayout.tableLeft + activeLayout.tableWidth && relativeX <= activeLayout.tableLeft + activeLayout.tableWidth + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + activeLayout.tableHeight;
|
|
29167
|
+
const addRowVisible = relativeY >= activeLayout.tableTop + activeLayout.tableHeight && relativeY <= activeLayout.tableTop + activeLayout.tableHeight + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + activeLayout.tableWidth;
|
|
29168
|
+
setHoverState((prev) => {
|
|
29169
|
+
if (prev.menuVisible === menuVisible && prev.addColumnVisible === addColumnVisible && prev.addRowVisible === addRowVisible && prev.rowHandleIndex === rowHandleIndex && prev.columnHandleIndex === columnHandleIndex) {
|
|
29170
|
+
return prev;
|
|
29171
|
+
}
|
|
29172
|
+
return {
|
|
29173
|
+
menuVisible,
|
|
29174
|
+
addColumnVisible,
|
|
29175
|
+
addRowVisible,
|
|
29176
|
+
rowHandleIndex,
|
|
29177
|
+
columnHandleIndex
|
|
29178
|
+
};
|
|
29179
|
+
});
|
|
29180
|
+
}, [containerRef]);
|
|
29181
|
+
React74.useEffect(() => {
|
|
28944
29182
|
const proseMirror = editor.view.dom;
|
|
28945
29183
|
const surface = containerRef.current;
|
|
28946
29184
|
if (!surface) return void 0;
|
|
28947
29185
|
const handleMouseOver = (event) => {
|
|
28948
29186
|
if (dragStateRef.current) return;
|
|
28949
|
-
|
|
29187
|
+
const cell = getCellFromTarget(event.target);
|
|
29188
|
+
if (!cell) return;
|
|
29189
|
+
syncFromCell(cell);
|
|
29190
|
+
};
|
|
29191
|
+
const handleSurfaceMouseMove = (event) => {
|
|
29192
|
+
updateHoverState(event);
|
|
28950
29193
|
};
|
|
28951
29194
|
const handleMouseLeave = () => {
|
|
28952
29195
|
if (dragStateRef.current) return;
|
|
28953
|
-
|
|
29196
|
+
setHoverState(DEFAULT_HOVER_STATE);
|
|
28954
29197
|
};
|
|
28955
29198
|
const handleFocusIn = () => {
|
|
28956
29199
|
if (dragStateRef.current) return;
|
|
@@ -28959,6 +29202,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
28959
29202
|
proseMirror.addEventListener("mouseover", handleMouseOver);
|
|
28960
29203
|
proseMirror.addEventListener("mouseleave", handleMouseLeave);
|
|
28961
29204
|
proseMirror.addEventListener("focusin", handleFocusIn);
|
|
29205
|
+
surface.addEventListener("mousemove", handleSurfaceMouseMove);
|
|
28962
29206
|
surface.addEventListener("scroll", refreshCurrentLayout, { passive: true });
|
|
28963
29207
|
window.addEventListener("resize", refreshCurrentLayout);
|
|
28964
29208
|
editor.on("selectionUpdate", syncFromSelection);
|
|
@@ -28968,13 +29212,14 @@ function TableControls({ editor, containerRef }) {
|
|
|
28968
29212
|
proseMirror.removeEventListener("mouseover", handleMouseOver);
|
|
28969
29213
|
proseMirror.removeEventListener("mouseleave", handleMouseLeave);
|
|
28970
29214
|
proseMirror.removeEventListener("focusin", handleFocusIn);
|
|
29215
|
+
surface.removeEventListener("mousemove", handleSurfaceMouseMove);
|
|
28971
29216
|
surface.removeEventListener("scroll", refreshCurrentLayout);
|
|
28972
29217
|
window.removeEventListener("resize", refreshCurrentLayout);
|
|
28973
29218
|
editor.off("selectionUpdate", syncFromSelection);
|
|
28974
29219
|
editor.off("update", refreshCurrentLayout);
|
|
28975
29220
|
};
|
|
28976
|
-
}, [clearDrag, containerRef, editor, refreshCurrentLayout, syncFromCell, syncFromSelection]);
|
|
28977
|
-
const runAtCellPos =
|
|
29221
|
+
}, [clearDrag, containerRef, editor, refreshCurrentLayout, syncFromCell, syncFromSelection, updateHoverState]);
|
|
29222
|
+
const runAtCellPos = React74.useCallback((cellPos, command, options) => {
|
|
28978
29223
|
if (cellPos == null) return false;
|
|
28979
29224
|
focusCell(editor, cellPos);
|
|
28980
29225
|
const result = command(editor.chain().focus(null, { scrollIntoView: false })).run();
|
|
@@ -28983,17 +29228,17 @@ function TableControls({ editor, containerRef }) {
|
|
|
28983
29228
|
}
|
|
28984
29229
|
return result;
|
|
28985
29230
|
}, [editor, syncFromSelection]);
|
|
28986
|
-
const runAtActiveCell =
|
|
29231
|
+
const runAtActiveCell = React74.useCallback((command, options) => {
|
|
28987
29232
|
return runAtCellPos(layoutRef.current?.cellPos ?? null, command, options);
|
|
28988
29233
|
}, [runAtCellPos]);
|
|
28989
|
-
const getCurrentCornerCellPos =
|
|
29234
|
+
const getCurrentCornerCellPos = React74.useCallback(() => {
|
|
28990
29235
|
const activePos = layoutRef.current?.cellPos ?? editor.state.selection.from;
|
|
28991
29236
|
return getLastCellPosFromState(editor, activePos);
|
|
28992
29237
|
}, [editor]);
|
|
28993
|
-
const runAtCornerCell =
|
|
29238
|
+
const runAtCornerCell = React74.useCallback((command, options) => {
|
|
28994
29239
|
return runAtCellPos(getCurrentCornerCellPos(), command, options);
|
|
28995
29240
|
}, [getCurrentCornerCellPos, runAtCellPos]);
|
|
28996
|
-
const replaceTableAtCellPos =
|
|
29241
|
+
const replaceTableAtCellPos = React74.useCallback((cellPos, updateTable) => {
|
|
28997
29242
|
if (cellPos == null) return false;
|
|
28998
29243
|
const tableInfo = findTableInfo(editor, cellPos);
|
|
28999
29244
|
if (!tableInfo) return false;
|
|
@@ -29003,10 +29248,10 @@ function TableControls({ editor, containerRef }) {
|
|
|
29003
29248
|
requestAnimationFrame(syncFromSelection);
|
|
29004
29249
|
return true;
|
|
29005
29250
|
}, [editor, syncFromSelection]);
|
|
29006
|
-
const createEmptyCellNode =
|
|
29251
|
+
const createEmptyCellNode = React74.useCallback((cellNode) => {
|
|
29007
29252
|
return cellNode.type.createAndFill(cellNode.attrs) ?? cellNode;
|
|
29008
29253
|
}, []);
|
|
29009
|
-
const duplicateRowAt =
|
|
29254
|
+
const duplicateRowAt = React74.useCallback((rowIndex, cellPos) => {
|
|
29010
29255
|
return replaceTableAtCellPos(cellPos, (tableNode) => {
|
|
29011
29256
|
const rows = collectChildren(tableNode);
|
|
29012
29257
|
const rowNode = rows[rowIndex];
|
|
@@ -29015,7 +29260,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
29015
29260
|
return tableNode.type.create(tableNode.attrs, rows);
|
|
29016
29261
|
});
|
|
29017
29262
|
}, [replaceTableAtCellPos]);
|
|
29018
|
-
const clearRowAt =
|
|
29263
|
+
const clearRowAt = React74.useCallback((rowIndex, cellPos) => {
|
|
29019
29264
|
return replaceTableAtCellPos(cellPos, (tableNode) => {
|
|
29020
29265
|
const rows = collectChildren(tableNode);
|
|
29021
29266
|
const rowNode = rows[rowIndex];
|
|
@@ -29025,7 +29270,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
29025
29270
|
return tableNode.type.create(tableNode.attrs, rows);
|
|
29026
29271
|
});
|
|
29027
29272
|
}, [createEmptyCellNode, replaceTableAtCellPos]);
|
|
29028
|
-
const duplicateColumnAt =
|
|
29273
|
+
const duplicateColumnAt = React74.useCallback((columnIndex, cellPos) => {
|
|
29029
29274
|
return replaceTableAtCellPos(cellPos, (tableNode) => {
|
|
29030
29275
|
const rows = collectChildren(tableNode).map((rowNode) => {
|
|
29031
29276
|
const cells = collectChildren(rowNode);
|
|
@@ -29037,7 +29282,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
29037
29282
|
return tableNode.type.create(tableNode.attrs, rows);
|
|
29038
29283
|
});
|
|
29039
29284
|
}, [replaceTableAtCellPos]);
|
|
29040
|
-
const clearColumnAt =
|
|
29285
|
+
const clearColumnAt = React74.useCallback((columnIndex, cellPos) => {
|
|
29041
29286
|
return replaceTableAtCellPos(cellPos, (tableNode) => {
|
|
29042
29287
|
const rows = collectChildren(tableNode).map((rowNode) => {
|
|
29043
29288
|
const cells = collectChildren(rowNode);
|
|
@@ -29049,7 +29294,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
29049
29294
|
return tableNode.type.create(tableNode.attrs, rows);
|
|
29050
29295
|
});
|
|
29051
29296
|
}, [createEmptyCellNode, replaceTableAtCellPos]);
|
|
29052
|
-
const expandTableBy =
|
|
29297
|
+
const expandTableBy = React74.useCallback((rows, cols) => {
|
|
29053
29298
|
let ok = true;
|
|
29054
29299
|
for (let index = 0; index < rows; index += 1) {
|
|
29055
29300
|
ok = runAtCornerCell((chain) => chain.addRowAfter(), { sync: false });
|
|
@@ -29063,7 +29308,8 @@ function TableControls({ editor, containerRef }) {
|
|
|
29063
29308
|
return true;
|
|
29064
29309
|
}, [runAtCornerCell, syncFromSelection]);
|
|
29065
29310
|
const canExpandTable = Boolean(layout);
|
|
29066
|
-
|
|
29311
|
+
const controlsVisible = dragPreview !== null;
|
|
29312
|
+
React74.useEffect(() => {
|
|
29067
29313
|
const handleMouseMove = (event) => {
|
|
29068
29314
|
const dragState = dragStateRef.current;
|
|
29069
29315
|
const activeLayout = layoutRef.current;
|
|
@@ -29150,7 +29396,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
29150
29396
|
window.removeEventListener("blur", clearDrag);
|
|
29151
29397
|
};
|
|
29152
29398
|
}, [clearDrag, containerRef, editor, expandTableBy, syncFromSelection]);
|
|
29153
|
-
const menuItems =
|
|
29399
|
+
const menuItems = React74.useMemo(() => {
|
|
29154
29400
|
if (!layout) return [];
|
|
29155
29401
|
return [
|
|
29156
29402
|
{
|
|
@@ -29203,7 +29449,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
29203
29449
|
}
|
|
29204
29450
|
];
|
|
29205
29451
|
}, [layout, runAtActiveCell, t]);
|
|
29206
|
-
const getRowHandleMenuItems =
|
|
29452
|
+
const getRowHandleMenuItems = React74.useCallback((rowHandle) => [
|
|
29207
29453
|
{
|
|
29208
29454
|
label: t("tableMenu.addRowBefore"),
|
|
29209
29455
|
icon: ArrowUp2,
|
|
@@ -29231,7 +29477,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
29231
29477
|
destructive: true
|
|
29232
29478
|
}
|
|
29233
29479
|
], [clearRowAt, duplicateRowAt, runAtCellPos, t]);
|
|
29234
|
-
const getColumnHandleMenuItems =
|
|
29480
|
+
const getColumnHandleMenuItems = React74.useCallback((columnHandle) => [
|
|
29235
29481
|
{
|
|
29236
29482
|
label: t("tableMenu.addColumnBefore"),
|
|
29237
29483
|
icon: ArrowLeft2,
|
|
@@ -29274,107 +29520,147 @@ function TableControls({ editor, containerRef }) {
|
|
|
29274
29520
|
const expandPreviewHeight = dragPreview?.kind === "add-row" ? layout.tableHeight + dragPreview.previewRows * layout.avgRowHeight : layout.tableHeight;
|
|
29275
29521
|
const dragStatusText = dragPreview?.kind === "row" ? `${t("tableMenu.dragRow")} ${dragPreview.originIndex + 1} -> ${dragPreview.targetIndex + 1}` : dragPreview?.kind === "column" ? `${t("tableMenu.dragColumn")} ${dragPreview.originIndex + 1} -> ${dragPreview.targetIndex + 1}` : dragPreview?.kind === "add-row" ? `+${dragPreview.previewRows}R` : dragPreview?.kind === "add-column" ? `+${dragPreview.previewCols}C` : null;
|
|
29276
29522
|
return /* @__PURE__ */ jsxs71(Fragment27, { children: [
|
|
29277
|
-
layout.rowHandles.map((rowHandle) =>
|
|
29278
|
-
|
|
29279
|
-
|
|
29280
|
-
|
|
29281
|
-
|
|
29282
|
-
|
|
29283
|
-
"
|
|
29284
|
-
{
|
|
29285
|
-
|
|
29286
|
-
|
|
29287
|
-
|
|
29288
|
-
|
|
29289
|
-
|
|
29290
|
-
|
|
29291
|
-
|
|
29292
|
-
|
|
29293
|
-
|
|
29294
|
-
|
|
29295
|
-
|
|
29296
|
-
|
|
29297
|
-
|
|
29298
|
-
|
|
29299
|
-
|
|
29300
|
-
|
|
29301
|
-
|
|
29302
|
-
|
|
29303
|
-
|
|
29304
|
-
|
|
29305
|
-
|
|
29306
|
-
|
|
29307
|
-
|
|
29308
|
-
|
|
29309
|
-
|
|
29310
|
-
|
|
29311
|
-
|
|
29312
|
-
|
|
29313
|
-
|
|
29314
|
-
|
|
29315
|
-
|
|
29316
|
-
|
|
29317
|
-
|
|
29318
|
-
|
|
29319
|
-
|
|
29320
|
-
|
|
29321
|
-
|
|
29322
|
-
|
|
29323
|
-
|
|
29324
|
-
|
|
29325
|
-
|
|
29326
|
-
|
|
29327
|
-
|
|
29328
|
-
|
|
29329
|
-
|
|
29330
|
-
|
|
29331
|
-
|
|
29332
|
-
|
|
29333
|
-
|
|
29334
|
-
|
|
29335
|
-
|
|
29336
|
-
|
|
29337
|
-
|
|
29338
|
-
|
|
29339
|
-
|
|
29340
|
-
|
|
29341
|
-
|
|
29342
|
-
|
|
29343
|
-
|
|
29344
|
-
|
|
29345
|
-
|
|
29346
|
-
|
|
29347
|
-
|
|
29348
|
-
|
|
29349
|
-
|
|
29350
|
-
|
|
29351
|
-
|
|
29352
|
-
|
|
29353
|
-
|
|
29354
|
-
|
|
29355
|
-
|
|
29356
|
-
|
|
29523
|
+
layout.rowHandles.map((rowHandle) => {
|
|
29524
|
+
const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index;
|
|
29525
|
+
if (!visible) return null;
|
|
29526
|
+
return /* @__PURE__ */ jsx81(
|
|
29527
|
+
"div",
|
|
29528
|
+
{
|
|
29529
|
+
className: "absolute z-30",
|
|
29530
|
+
style: {
|
|
29531
|
+
top: Math.max(8, rowHandle.center - 12),
|
|
29532
|
+
left: rowHandleLeft
|
|
29533
|
+
},
|
|
29534
|
+
children: /* @__PURE__ */ jsx81(
|
|
29535
|
+
DropdownMenu,
|
|
29536
|
+
{
|
|
29537
|
+
placement: "right",
|
|
29538
|
+
items: getRowHandleMenuItems(rowHandle),
|
|
29539
|
+
trigger: /* @__PURE__ */ jsx81(
|
|
29540
|
+
"button",
|
|
29541
|
+
{
|
|
29542
|
+
type: "button",
|
|
29543
|
+
"aria-label": `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
|
|
29544
|
+
title: `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
|
|
29545
|
+
onMouseDown: (event) => {
|
|
29546
|
+
event.preventDefault();
|
|
29547
|
+
event.stopPropagation();
|
|
29548
|
+
dragStateRef.current = {
|
|
29549
|
+
kind: "row",
|
|
29550
|
+
originIndex: rowHandle.index,
|
|
29551
|
+
targetIndex: rowHandle.index,
|
|
29552
|
+
anchorPos: rowHandle.cellPos
|
|
29553
|
+
};
|
|
29554
|
+
setDragPreview({
|
|
29555
|
+
kind: "row",
|
|
29556
|
+
originIndex: rowHandle.index,
|
|
29557
|
+
targetIndex: rowHandle.index,
|
|
29558
|
+
targetStart: rowHandle.start,
|
|
29559
|
+
targetSize: rowHandle.size
|
|
29560
|
+
});
|
|
29561
|
+
document.body.style.cursor = "grabbing";
|
|
29562
|
+
},
|
|
29563
|
+
className: cn(
|
|
29564
|
+
"inline-flex h-6 w-6 items-center justify-center rounded-full",
|
|
29565
|
+
"border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
|
|
29566
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
|
|
29567
|
+
),
|
|
29568
|
+
children: /* @__PURE__ */ jsx81(GripVertical3, { className: "h-3.5 w-3.5" })
|
|
29569
|
+
}
|
|
29570
|
+
)
|
|
29571
|
+
}
|
|
29572
|
+
)
|
|
29573
|
+
},
|
|
29574
|
+
`row-handle-${rowHandle.index}`
|
|
29575
|
+
);
|
|
29576
|
+
}),
|
|
29577
|
+
layout.columnHandles.map((columnHandle) => {
|
|
29578
|
+
const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index;
|
|
29579
|
+
if (!visible) return null;
|
|
29580
|
+
return /* @__PURE__ */ jsx81(
|
|
29581
|
+
"div",
|
|
29582
|
+
{
|
|
29583
|
+
className: "absolute z-30",
|
|
29584
|
+
style: {
|
|
29585
|
+
top: columnHandleTop,
|
|
29586
|
+
left: Math.max(8, columnHandle.center - 12)
|
|
29587
|
+
},
|
|
29588
|
+
children: /* @__PURE__ */ jsx81(
|
|
29589
|
+
DropdownMenu,
|
|
29590
|
+
{
|
|
29591
|
+
placement: "bottom-start",
|
|
29592
|
+
items: getColumnHandleMenuItems(columnHandle),
|
|
29593
|
+
trigger: /* @__PURE__ */ jsx81(
|
|
29594
|
+
"button",
|
|
29595
|
+
{
|
|
29596
|
+
type: "button",
|
|
29597
|
+
"aria-label": `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
|
|
29598
|
+
title: `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
|
|
29599
|
+
onMouseDown: (event) => {
|
|
29600
|
+
event.preventDefault();
|
|
29601
|
+
event.stopPropagation();
|
|
29602
|
+
dragStateRef.current = {
|
|
29603
|
+
kind: "column",
|
|
29604
|
+
originIndex: columnHandle.index,
|
|
29605
|
+
targetIndex: columnHandle.index,
|
|
29606
|
+
anchorPos: columnHandle.cellPos
|
|
29607
|
+
};
|
|
29608
|
+
setDragPreview({
|
|
29609
|
+
kind: "column",
|
|
29610
|
+
originIndex: columnHandle.index,
|
|
29611
|
+
targetIndex: columnHandle.index,
|
|
29612
|
+
targetStart: columnHandle.start,
|
|
29613
|
+
targetSize: columnHandle.size
|
|
29614
|
+
});
|
|
29615
|
+
document.body.style.cursor = "grabbing";
|
|
29616
|
+
},
|
|
29617
|
+
className: cn(
|
|
29618
|
+
"inline-flex h-6 w-6 items-center justify-center rounded-full",
|
|
29619
|
+
"border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
|
|
29620
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
|
|
29621
|
+
),
|
|
29622
|
+
children: /* @__PURE__ */ jsx81(GripHorizontal, { className: "h-3.5 w-3.5" })
|
|
29623
|
+
}
|
|
29624
|
+
)
|
|
29625
|
+
}
|
|
29626
|
+
)
|
|
29627
|
+
},
|
|
29628
|
+
`column-handle-${columnHandle.index}`
|
|
29629
|
+
);
|
|
29630
|
+
}),
|
|
29631
|
+
(controlsVisible || hoverState.menuVisible) && /* @__PURE__ */ jsx81(
|
|
29632
|
+
"div",
|
|
29357
29633
|
{
|
|
29358
|
-
|
|
29359
|
-
|
|
29360
|
-
|
|
29361
|
-
|
|
29634
|
+
className: "absolute z-30",
|
|
29635
|
+
style: {
|
|
29636
|
+
top: menuTop,
|
|
29637
|
+
left: menuLeft
|
|
29638
|
+
},
|
|
29639
|
+
children: /* @__PURE__ */ jsx81(
|
|
29640
|
+
DropdownMenu,
|
|
29362
29641
|
{
|
|
29363
|
-
|
|
29364
|
-
|
|
29365
|
-
|
|
29366
|
-
|
|
29367
|
-
|
|
29368
|
-
|
|
29369
|
-
|
|
29370
|
-
|
|
29371
|
-
|
|
29372
|
-
|
|
29642
|
+
placement: "bottom-start",
|
|
29643
|
+
items: menuItems,
|
|
29644
|
+
trigger: /* @__PURE__ */ jsx81(
|
|
29645
|
+
"button",
|
|
29646
|
+
{
|
|
29647
|
+
type: "button",
|
|
29648
|
+
"aria-label": t("tableMenu.openControls"),
|
|
29649
|
+
title: t("tableMenu.openControls"),
|
|
29650
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
29651
|
+
className: cn(
|
|
29652
|
+
"pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-full",
|
|
29653
|
+
"border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
|
|
29654
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
|
|
29655
|
+
),
|
|
29656
|
+
children: /* @__PURE__ */ jsx81(MoreHorizontal2, { className: "h-4 w-4" })
|
|
29657
|
+
}
|
|
29658
|
+
)
|
|
29373
29659
|
}
|
|
29374
29660
|
)
|
|
29375
29661
|
}
|
|
29376
|
-
)
|
|
29377
|
-
/* @__PURE__ */ jsx81(
|
|
29662
|
+
),
|
|
29663
|
+
(controlsVisible || hoverState.addColumnVisible) && /* @__PURE__ */ jsx81(
|
|
29378
29664
|
"button",
|
|
29379
29665
|
{
|
|
29380
29666
|
type: "button",
|
|
@@ -29392,13 +29678,18 @@ function TableControls({ editor, containerRef }) {
|
|
|
29392
29678
|
className: cn(
|
|
29393
29679
|
"absolute z-30 inline-flex items-center justify-center rounded-md",
|
|
29394
29680
|
"border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
|
|
29395
|
-
"transition-colors hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
29681
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
29396
29682
|
),
|
|
29397
|
-
style: {
|
|
29683
|
+
style: {
|
|
29684
|
+
top: columnRailTop,
|
|
29685
|
+
left: columnRailLeft,
|
|
29686
|
+
width: 18,
|
|
29687
|
+
height: layout.tableHeight
|
|
29688
|
+
},
|
|
29398
29689
|
children: /* @__PURE__ */ jsx81("span", { className: "text-sm font-medium leading-none", children: "+" })
|
|
29399
29690
|
}
|
|
29400
29691
|
),
|
|
29401
|
-
/* @__PURE__ */ jsx81(
|
|
29692
|
+
(controlsVisible || hoverState.addRowVisible) && /* @__PURE__ */ jsx81(
|
|
29402
29693
|
"button",
|
|
29403
29694
|
{
|
|
29404
29695
|
type: "button",
|
|
@@ -29416,9 +29707,14 @@ function TableControls({ editor, containerRef }) {
|
|
|
29416
29707
|
className: cn(
|
|
29417
29708
|
"absolute z-30 inline-flex items-center justify-center rounded-md",
|
|
29418
29709
|
"border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
|
|
29419
|
-
"transition-colors hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
29710
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
29420
29711
|
),
|
|
29421
|
-
style: {
|
|
29712
|
+
style: {
|
|
29713
|
+
top: rowRailTop,
|
|
29714
|
+
left: rowRailLeft,
|
|
29715
|
+
width: layout.tableWidth,
|
|
29716
|
+
height: 16
|
|
29717
|
+
},
|
|
29422
29718
|
children: /* @__PURE__ */ jsx81("span", { className: "text-sm font-medium leading-none", children: "+" })
|
|
29423
29719
|
}
|
|
29424
29720
|
),
|
|
@@ -29553,6 +29849,19 @@ function resolveEventElement(target) {
|
|
|
29553
29849
|
if (target instanceof Node) return target.parentElement;
|
|
29554
29850
|
return null;
|
|
29555
29851
|
}
|
|
29852
|
+
function getSelectionTableCell(view) {
|
|
29853
|
+
const browserSelection = window.getSelection();
|
|
29854
|
+
const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
|
|
29855
|
+
const anchorCell = anchorElement?.closest?.("th,td");
|
|
29856
|
+
if (anchorCell instanceof HTMLElement) {
|
|
29857
|
+
return anchorCell;
|
|
29858
|
+
}
|
|
29859
|
+
const { from } = view.state.selection;
|
|
29860
|
+
const domAtPos = view.domAtPos(from);
|
|
29861
|
+
const element = resolveEventElement(domAtPos.node);
|
|
29862
|
+
const cell = element?.closest?.("th,td");
|
|
29863
|
+
return cell instanceof HTMLElement ? cell : null;
|
|
29864
|
+
}
|
|
29556
29865
|
function isRowResizeHotspot(cell, clientX, clientY) {
|
|
29557
29866
|
const rect = cell.getBoundingClientRect();
|
|
29558
29867
|
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
@@ -29579,7 +29888,17 @@ function getRelativeBoundaryMetrics(surface, table, row, cell) {
|
|
|
29579
29888
|
columnRight: cellRect.right - surfaceRect.left + surface.scrollLeft
|
|
29580
29889
|
};
|
|
29581
29890
|
}
|
|
29582
|
-
|
|
29891
|
+
function getRelativeCellMetrics(surface, cell) {
|
|
29892
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
29893
|
+
const cellRect = cell.getBoundingClientRect();
|
|
29894
|
+
return {
|
|
29895
|
+
left: cellRect.left - surfaceRect.left + surface.scrollLeft,
|
|
29896
|
+
top: cellRect.top - surfaceRect.top + surface.scrollTop,
|
|
29897
|
+
width: cellRect.width,
|
|
29898
|
+
height: cellRect.height
|
|
29899
|
+
};
|
|
29900
|
+
}
|
|
29901
|
+
var UEditor = React75.forwardRef(({
|
|
29583
29902
|
content = "",
|
|
29584
29903
|
onChange,
|
|
29585
29904
|
onHtmlChange,
|
|
@@ -29606,33 +29925,66 @@ var UEditor = React74.forwardRef(({
|
|
|
29606
29925
|
const editorContentRef = useRef32(null);
|
|
29607
29926
|
const tableColumnGuideRef = useRef32(null);
|
|
29608
29927
|
const tableRowGuideRef = useRef32(null);
|
|
29928
|
+
const activeTableCellHighlightRef = useRef32(null);
|
|
29929
|
+
const hoveredTableCellRef = useRef32(null);
|
|
29930
|
+
const activeTableCellRef = useRef32(null);
|
|
29609
29931
|
const rowResizeStateRef = useRef32(null);
|
|
29610
|
-
const setEditorResizeCursor =
|
|
29932
|
+
const setEditorResizeCursor = React75.useCallback((cursor) => {
|
|
29611
29933
|
const proseMirror = editorContentRef.current?.querySelector(".ProseMirror");
|
|
29612
29934
|
if (proseMirror) {
|
|
29613
29935
|
proseMirror.style.cursor = cursor;
|
|
29614
29936
|
}
|
|
29615
29937
|
}, []);
|
|
29616
|
-
const hideColumnGuide =
|
|
29938
|
+
const hideColumnGuide = React75.useCallback(() => {
|
|
29617
29939
|
editorContentRef.current?.classList.remove("resize-cursor");
|
|
29618
29940
|
const guide = tableColumnGuideRef.current;
|
|
29619
29941
|
if (guide) {
|
|
29620
29942
|
guide.style.opacity = "0";
|
|
29621
29943
|
}
|
|
29622
29944
|
}, []);
|
|
29623
|
-
const hideRowGuide =
|
|
29945
|
+
const hideRowGuide = React75.useCallback(() => {
|
|
29624
29946
|
editorContentRef.current?.classList.remove("resize-row-cursor");
|
|
29625
29947
|
const guide = tableRowGuideRef.current;
|
|
29626
29948
|
if (guide) {
|
|
29627
29949
|
guide.style.opacity = "0";
|
|
29628
29950
|
}
|
|
29629
29951
|
}, []);
|
|
29630
|
-
const clearAllTableResizeHover =
|
|
29952
|
+
const clearAllTableResizeHover = React75.useCallback(() => {
|
|
29631
29953
|
setEditorResizeCursor("");
|
|
29632
29954
|
hideColumnGuide();
|
|
29633
29955
|
hideRowGuide();
|
|
29634
29956
|
}, [hideColumnGuide, hideRowGuide, setEditorResizeCursor]);
|
|
29635
|
-
const
|
|
29957
|
+
const updateActiveCellHighlight = React75.useCallback((cell) => {
|
|
29958
|
+
const surface = editorContentRef.current;
|
|
29959
|
+
const highlight = activeTableCellHighlightRef.current;
|
|
29960
|
+
if (!highlight) return;
|
|
29961
|
+
if (!surface || !cell) {
|
|
29962
|
+
highlight.style.display = "none";
|
|
29963
|
+
return;
|
|
29964
|
+
}
|
|
29965
|
+
const metrics = getRelativeCellMetrics(surface, cell);
|
|
29966
|
+
highlight.style.display = "block";
|
|
29967
|
+
highlight.style.left = `${metrics.left}px`;
|
|
29968
|
+
highlight.style.top = `${metrics.top}px`;
|
|
29969
|
+
highlight.style.width = `${metrics.width}px`;
|
|
29970
|
+
highlight.style.height = `${metrics.height}px`;
|
|
29971
|
+
}, []);
|
|
29972
|
+
const setActiveTableCell = React75.useCallback((cell) => {
|
|
29973
|
+
if (activeTableCellRef.current === cell) return;
|
|
29974
|
+
activeTableCellRef.current = cell;
|
|
29975
|
+
updateActiveCellHighlight(activeTableCellRef.current);
|
|
29976
|
+
}, [updateActiveCellHighlight]);
|
|
29977
|
+
const clearActiveTableCell = React75.useCallback(() => {
|
|
29978
|
+
activeTableCellRef.current = null;
|
|
29979
|
+
updateActiveCellHighlight(null);
|
|
29980
|
+
}, [updateActiveCellHighlight]);
|
|
29981
|
+
const setHoveredTableCell = React75.useCallback((cell) => {
|
|
29982
|
+
hoveredTableCellRef.current = cell;
|
|
29983
|
+
}, []);
|
|
29984
|
+
const clearHoveredTableCell = React75.useCallback(() => {
|
|
29985
|
+
hoveredTableCellRef.current = null;
|
|
29986
|
+
}, []);
|
|
29987
|
+
const showColumnGuide = React75.useCallback((table, row, cell) => {
|
|
29636
29988
|
const surface = editorContentRef.current;
|
|
29637
29989
|
const guide = tableColumnGuideRef.current;
|
|
29638
29990
|
if (!surface || !guide) return;
|
|
@@ -29645,7 +29997,7 @@ var UEditor = React74.forwardRef(({
|
|
|
29645
29997
|
surface.classList.add("resize-cursor");
|
|
29646
29998
|
setEditorResizeCursor("col-resize");
|
|
29647
29999
|
}, [setEditorResizeCursor]);
|
|
29648
|
-
const showRowGuide =
|
|
30000
|
+
const showRowGuide = React75.useCallback((table, row, cell) => {
|
|
29649
30001
|
const surface = editorContentRef.current;
|
|
29650
30002
|
const guide = tableRowGuideRef.current;
|
|
29651
30003
|
if (!surface || !guide) return;
|
|
@@ -29813,6 +30165,10 @@ var UEditor = React74.forwardRef(({
|
|
|
29813
30165
|
onJsonChange?.(editor2.getJSON());
|
|
29814
30166
|
}
|
|
29815
30167
|
});
|
|
30168
|
+
const syncActiveTableCellFromSelection = React75.useCallback(() => {
|
|
30169
|
+
if (!editor) return;
|
|
30170
|
+
setActiveTableCell(getSelectionTableCell(editor.view));
|
|
30171
|
+
}, [editor, setActiveTableCell]);
|
|
29816
30172
|
useImperativeHandle3(
|
|
29817
30173
|
ref,
|
|
29818
30174
|
() => ({
|
|
@@ -29845,9 +30201,27 @@ var UEditor = React74.forwardRef(({
|
|
|
29845
30201
|
useEffect35(() => {
|
|
29846
30202
|
if (!editor) return void 0;
|
|
29847
30203
|
const proseMirror = editor.view.dom;
|
|
30204
|
+
const surface = editorContentRef.current;
|
|
30205
|
+
let selectionSyncTimeoutId = 0;
|
|
30206
|
+
const scheduleActiveCellSync = (fallbackCell = null) => {
|
|
30207
|
+
requestAnimationFrame(() => {
|
|
30208
|
+
setActiveTableCell(getSelectionTableCell(editor.view) ?? fallbackCell);
|
|
30209
|
+
});
|
|
30210
|
+
window.clearTimeout(selectionSyncTimeoutId);
|
|
30211
|
+
selectionSyncTimeoutId = window.setTimeout(() => {
|
|
30212
|
+
setActiveTableCell(getSelectionTableCell(editor.view) ?? fallbackCell);
|
|
30213
|
+
}, 0);
|
|
30214
|
+
};
|
|
30215
|
+
const handleSelectionChange = () => {
|
|
30216
|
+
scheduleActiveCellSync();
|
|
30217
|
+
};
|
|
30218
|
+
const handleActiveCellLayoutChange = () => {
|
|
30219
|
+
updateActiveCellHighlight(activeTableCellRef.current);
|
|
30220
|
+
};
|
|
29848
30221
|
const handleEditorMouseMove = (event) => {
|
|
29849
30222
|
const activeRowResize = rowResizeStateRef.current;
|
|
29850
30223
|
if (activeRowResize) {
|
|
30224
|
+
setHoveredTableCell(activeRowResize.cellElement);
|
|
29851
30225
|
showRowGuide(activeRowResize.tableElement, activeRowResize.rowElement, activeRowResize.cellElement);
|
|
29852
30226
|
return;
|
|
29853
30227
|
}
|
|
@@ -29858,12 +30232,15 @@ var UEditor = React74.forwardRef(({
|
|
|
29858
30232
|
}
|
|
29859
30233
|
const cell = target.closest("th,td");
|
|
29860
30234
|
if (!(cell instanceof HTMLElement)) {
|
|
30235
|
+
clearHoveredTableCell();
|
|
29861
30236
|
clearAllTableResizeHover();
|
|
29862
30237
|
return;
|
|
29863
30238
|
}
|
|
30239
|
+
setHoveredTableCell(cell);
|
|
29864
30240
|
const row = cell.closest("tr");
|
|
29865
30241
|
const table = cell.closest("table");
|
|
29866
30242
|
if (!(row instanceof HTMLTableRowElement) || !(table instanceof HTMLTableElement)) {
|
|
30243
|
+
clearHoveredTableCell();
|
|
29867
30244
|
clearAllTableResizeHover();
|
|
29868
30245
|
return;
|
|
29869
30246
|
}
|
|
@@ -29882,6 +30259,7 @@ var UEditor = React74.forwardRef(({
|
|
|
29882
30259
|
clearAllTableResizeHover();
|
|
29883
30260
|
};
|
|
29884
30261
|
const handleEditorMouseLeave = () => {
|
|
30262
|
+
clearHoveredTableCell();
|
|
29885
30263
|
if (!rowResizeStateRef.current) {
|
|
29886
30264
|
clearAllTableResizeHover();
|
|
29887
30265
|
}
|
|
@@ -29889,15 +30267,24 @@ var UEditor = React74.forwardRef(({
|
|
|
29889
30267
|
const handleEditorMouseDown = (event) => {
|
|
29890
30268
|
if (event.button !== 0) return;
|
|
29891
30269
|
const target = resolveEventElement(event.target);
|
|
29892
|
-
if (!(target instanceof Element))
|
|
30270
|
+
if (!(target instanceof Element)) {
|
|
30271
|
+
clearActiveTableCell();
|
|
30272
|
+
return;
|
|
30273
|
+
}
|
|
29893
30274
|
const cell = target.closest("th,td");
|
|
29894
|
-
if (!(cell instanceof HTMLTableCellElement))
|
|
30275
|
+
if (!(cell instanceof HTMLTableCellElement)) {
|
|
30276
|
+
clearActiveTableCell();
|
|
30277
|
+
return;
|
|
30278
|
+
}
|
|
30279
|
+
setActiveTableCell(cell);
|
|
30280
|
+
scheduleActiveCellSync(cell);
|
|
29895
30281
|
const row = cell.closest("tr");
|
|
29896
30282
|
const table = cell.closest("table");
|
|
29897
30283
|
if (!(row instanceof HTMLTableRowElement) || !(table instanceof HTMLTableElement)) return;
|
|
29898
30284
|
if (!isRowResizeHotspot(cell, event.clientX, event.clientY)) {
|
|
29899
30285
|
return;
|
|
29900
30286
|
}
|
|
30287
|
+
setHoveredTableCell(cell);
|
|
29901
30288
|
const rowInfo = findTableRowNodeInfo(editor.view, row);
|
|
29902
30289
|
if (!rowInfo) return;
|
|
29903
30290
|
rowResizeStateRef.current = {
|
|
@@ -29958,6 +30345,7 @@ var UEditor = React74.forwardRef(({
|
|
|
29958
30345
|
clearPreviewRowHeight(state.rowElement);
|
|
29959
30346
|
rowResizeStateRef.current = null;
|
|
29960
30347
|
document.body.style.cursor = "";
|
|
30348
|
+
clearHoveredTableCell();
|
|
29961
30349
|
clearAllTableResizeHover();
|
|
29962
30350
|
};
|
|
29963
30351
|
const handleWindowBlur = () => {
|
|
@@ -29966,30 +30354,53 @@ var UEditor = React74.forwardRef(({
|
|
|
29966
30354
|
clearPreviewRowHeight(state.rowElement);
|
|
29967
30355
|
rowResizeStateRef.current = null;
|
|
29968
30356
|
document.body.style.cursor = "";
|
|
30357
|
+
clearHoveredTableCell();
|
|
29969
30358
|
clearAllTableResizeHover();
|
|
29970
30359
|
};
|
|
29971
30360
|
proseMirror.addEventListener("mousemove", handleEditorMouseMove);
|
|
29972
30361
|
proseMirror.addEventListener("mouseleave", handleEditorMouseLeave);
|
|
29973
30362
|
proseMirror.addEventListener("mousedown", handleEditorMouseDown);
|
|
30363
|
+
proseMirror.addEventListener("click", handleSelectionChange);
|
|
30364
|
+
proseMirror.addEventListener("mouseup", handleSelectionChange);
|
|
30365
|
+
proseMirror.addEventListener("keyup", handleSelectionChange);
|
|
30366
|
+
proseMirror.addEventListener("focusin", handleSelectionChange);
|
|
30367
|
+
document.addEventListener("selectionchange", handleSelectionChange);
|
|
30368
|
+
surface?.addEventListener("scroll", handleActiveCellLayoutChange, { passive: true });
|
|
30369
|
+
window.addEventListener("resize", handleActiveCellLayoutChange);
|
|
29974
30370
|
window.addEventListener("mousemove", handlePointerMove);
|
|
29975
30371
|
document.addEventListener("pointermove", handlePointerMove);
|
|
29976
30372
|
window.addEventListener("mouseup", handlePointerUp);
|
|
29977
30373
|
document.addEventListener("pointerup", handlePointerUp);
|
|
29978
30374
|
window.addEventListener("blur", handleWindowBlur);
|
|
30375
|
+
editor.on("selectionUpdate", syncActiveTableCellFromSelection);
|
|
30376
|
+
editor.on("focus", syncActiveTableCellFromSelection);
|
|
30377
|
+
syncActiveTableCellFromSelection();
|
|
29979
30378
|
return () => {
|
|
29980
30379
|
proseMirror.removeEventListener("mousemove", handleEditorMouseMove);
|
|
29981
30380
|
proseMirror.removeEventListener("mouseleave", handleEditorMouseLeave);
|
|
29982
30381
|
proseMirror.removeEventListener("mousedown", handleEditorMouseDown);
|
|
30382
|
+
proseMirror.removeEventListener("click", handleSelectionChange);
|
|
30383
|
+
proseMirror.removeEventListener("mouseup", handleSelectionChange);
|
|
30384
|
+
proseMirror.removeEventListener("keyup", handleSelectionChange);
|
|
30385
|
+
proseMirror.removeEventListener("focusin", handleSelectionChange);
|
|
30386
|
+
document.removeEventListener("selectionchange", handleSelectionChange);
|
|
30387
|
+
surface?.removeEventListener("scroll", handleActiveCellLayoutChange);
|
|
30388
|
+
window.removeEventListener("resize", handleActiveCellLayoutChange);
|
|
29983
30389
|
window.removeEventListener("mousemove", handlePointerMove);
|
|
29984
30390
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
29985
30391
|
window.removeEventListener("mouseup", handlePointerUp);
|
|
29986
30392
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
29987
30393
|
window.removeEventListener("blur", handleWindowBlur);
|
|
30394
|
+
editor.off("selectionUpdate", syncActiveTableCellFromSelection);
|
|
30395
|
+
editor.off("focus", syncActiveTableCellFromSelection);
|
|
30396
|
+
window.clearTimeout(selectionSyncTimeoutId);
|
|
29988
30397
|
document.body.style.cursor = "";
|
|
30398
|
+
clearActiveTableCell();
|
|
30399
|
+
clearHoveredTableCell();
|
|
29989
30400
|
clearAllTableResizeHover();
|
|
29990
30401
|
rowResizeStateRef.current = null;
|
|
29991
30402
|
};
|
|
29992
|
-
}, [clearAllTableResizeHover, editor, hideColumnGuide, hideRowGuide, showColumnGuide, showRowGuide]);
|
|
30403
|
+
}, [clearActiveTableCell, clearAllTableResizeHover, clearHoveredTableCell, editor, hideColumnGuide, hideRowGuide, setHoveredTableCell, showColumnGuide, showRowGuide, syncActiveTableCellFromSelection, updateActiveCellHighlight]);
|
|
29993
30404
|
if (!editor) {
|
|
29994
30405
|
return /* @__PURE__ */ jsx82(
|
|
29995
30406
|
"div",
|
|
@@ -30041,6 +30452,14 @@ var UEditor = React74.forwardRef(({
|
|
|
30041
30452
|
className: "pointer-events-none absolute z-20 bg-primary opacity-0 transition-opacity duration-100"
|
|
30042
30453
|
}
|
|
30043
30454
|
),
|
|
30455
|
+
/* @__PURE__ */ jsx82(
|
|
30456
|
+
"span",
|
|
30457
|
+
{
|
|
30458
|
+
ref: activeTableCellHighlightRef,
|
|
30459
|
+
"aria-hidden": "true",
|
|
30460
|
+
className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-[#2383e2] bg-[#2383e2]/[0.06] transition-[left,top,width,height] duration-100"
|
|
30461
|
+
}
|
|
30462
|
+
),
|
|
30044
30463
|
editable && /* @__PURE__ */ jsx82(TableControls, { editor, containerRef: editorContentRef }),
|
|
30045
30464
|
/* @__PURE__ */ jsx82(
|
|
30046
30465
|
EditorContent,
|