@dmitryvim/form-builder 0.2.20 → 0.2.22
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/browser/formbuilder.min.js +138 -119
- package/dist/browser/formbuilder.v0.2.22.min.js +602 -0
- package/dist/cjs/index.cjs +318 -60
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +301 -50
- package/dist/esm/index.js.map +1 -1
- package/dist/form-builder.js +138 -119
- package/dist/types/components/table.d.ts +1 -1
- package/dist/types/types/config.d.ts +8 -0
- package/dist/types/types/schema.d.ts +17 -8
- package/package.json +1 -1
- package/dist/browser/formbuilder.v0.2.20.min.js +0 -583
package/dist/cjs/index.cjs
CHANGED
|
@@ -4778,18 +4778,54 @@ function updateGroupField(element, fieldPath, value, context) {
|
|
|
4778
4778
|
}
|
|
4779
4779
|
|
|
4780
4780
|
// src/components/table.ts
|
|
4781
|
+
function isLegacyMerge(m) {
|
|
4782
|
+
return m !== null && typeof m === "object" && "row" in m && "col" in m && "rowspan" in m && "colspan" in m;
|
|
4783
|
+
}
|
|
4784
|
+
function isValidMergeShape(m) {
|
|
4785
|
+
if (m === null || typeof m !== "object") return false;
|
|
4786
|
+
const o = m;
|
|
4787
|
+
return typeof o.top === "number" && typeof o.left === "number" && typeof o.bottom === "number" && typeof o.right === "number";
|
|
4788
|
+
}
|
|
4789
|
+
function migrateMerge(m) {
|
|
4790
|
+
if (isLegacyMerge(m)) {
|
|
4791
|
+
return {
|
|
4792
|
+
top: m.row,
|
|
4793
|
+
left: m.col,
|
|
4794
|
+
bottom: m.row + m.rowspan - 1,
|
|
4795
|
+
right: m.col + m.colspan - 1
|
|
4796
|
+
};
|
|
4797
|
+
}
|
|
4798
|
+
if (isValidMergeShape(m)) return m;
|
|
4799
|
+
return null;
|
|
4800
|
+
}
|
|
4801
|
+
function migrateMerges(merges) {
|
|
4802
|
+
return merges.map(migrateMerge).filter((m) => m !== null);
|
|
4803
|
+
}
|
|
4781
4804
|
function createEmptyCells(rows, cols) {
|
|
4782
4805
|
return Array.from(
|
|
4783
4806
|
{ length: rows },
|
|
4784
4807
|
() => Array.from({ length: cols }, () => "")
|
|
4785
4808
|
);
|
|
4786
4809
|
}
|
|
4810
|
+
function validateMerges(merges, rows, cols) {
|
|
4811
|
+
for (let i = 0; i < merges.length; i++) {
|
|
4812
|
+
const a = merges[i];
|
|
4813
|
+
if (a.top < 0 || a.left < 0 || a.bottom >= rows || a.right >= cols || a.top > a.bottom || a.left > a.right)
|
|
4814
|
+
return `Merge ${i} out of bounds`;
|
|
4815
|
+
for (let j = i + 1; j < merges.length; j++) {
|
|
4816
|
+
const b = merges[j];
|
|
4817
|
+
if (a.top <= b.bottom && a.bottom >= b.top && a.left <= b.right && a.right >= b.left)
|
|
4818
|
+
return `Merges ${i} and ${j} overlap`;
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4821
|
+
return null;
|
|
4822
|
+
}
|
|
4787
4823
|
function getShadowingMerge(row, col, merges) {
|
|
4788
4824
|
for (const m of merges) {
|
|
4789
|
-
if (m.
|
|
4825
|
+
if (m.top === row && m.left === col) {
|
|
4790
4826
|
return null;
|
|
4791
4827
|
}
|
|
4792
|
-
if (row >= m.
|
|
4828
|
+
if (row >= m.top && row <= m.bottom && col >= m.left && col <= m.right) {
|
|
4793
4829
|
return m;
|
|
4794
4830
|
}
|
|
4795
4831
|
}
|
|
@@ -4797,7 +4833,7 @@ function getShadowingMerge(row, col, merges) {
|
|
|
4797
4833
|
}
|
|
4798
4834
|
function getMergeAt(row, col, merges) {
|
|
4799
4835
|
var _a;
|
|
4800
|
-
return (_a = merges.find((m) => m.
|
|
4836
|
+
return (_a = merges.find((m) => m.top === row && m.left === col)) != null ? _a : null;
|
|
4801
4837
|
}
|
|
4802
4838
|
function selectionRange(sel) {
|
|
4803
4839
|
var _a;
|
|
@@ -4873,8 +4909,10 @@ function renderReadonlyTable(data, wrapper) {
|
|
|
4873
4909
|
const merge = getMergeAt(rIdx, cIdx, merges);
|
|
4874
4910
|
const td = document.createElement(rIdx === 0 ? "th" : "td");
|
|
4875
4911
|
if (merge) {
|
|
4876
|
-
|
|
4877
|
-
|
|
4912
|
+
const rowspan = merge.bottom - merge.top + 1;
|
|
4913
|
+
const colspan = merge.right - merge.left + 1;
|
|
4914
|
+
if (rowspan > 1) td.rowSpan = rowspan;
|
|
4915
|
+
if (colspan > 1) td.colSpan = colspan;
|
|
4878
4916
|
}
|
|
4879
4917
|
td.textContent = (_b = rowData[cIdx]) != null ? _b : "";
|
|
4880
4918
|
td.style.cssText = `
|
|
@@ -4961,22 +4999,56 @@ function startCellEditing(span, r, c, getCells, persistValue, selectCell) {
|
|
|
4961
4999
|
span.addEventListener("keydown", onKeyDown);
|
|
4962
5000
|
span.addEventListener("blur", onBlur);
|
|
4963
5001
|
}
|
|
5002
|
+
function ensureSpinKeyframes() {
|
|
5003
|
+
if (document.getElementById("fb-spin-keyframes")) return;
|
|
5004
|
+
const style = document.createElement("style");
|
|
5005
|
+
style.id = "fb-spin-keyframes";
|
|
5006
|
+
style.textContent = `@keyframes fb-spin { to { transform: rotate(360deg); } }`;
|
|
5007
|
+
document.head.appendChild(style);
|
|
5008
|
+
}
|
|
5009
|
+
function showLoadingOverlay(parent, text) {
|
|
5010
|
+
ensureSpinKeyframes();
|
|
5011
|
+
const overlay = document.createElement("div");
|
|
5012
|
+
overlay.className = "fb-table-loading-overlay";
|
|
5013
|
+
overlay.style.cssText = `
|
|
5014
|
+
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
|
|
5015
|
+
background: rgba(255,255,255,0.8); display: flex;
|
|
5016
|
+
align-items: center; justify-content: center; flex-direction: column;
|
|
5017
|
+
gap: 8px; z-index: 100;
|
|
5018
|
+
`;
|
|
5019
|
+
const spinner = document.createElement("div");
|
|
5020
|
+
spinner.style.cssText = `
|
|
5021
|
+
width: 24px; height: 24px; border: 3px solid var(--fb-border-color, #ccc);
|
|
5022
|
+
border-top-color: var(--fb-primary-color, #0066cc); border-radius: 50%;
|
|
5023
|
+
animation: fb-spin 0.8s linear infinite;
|
|
5024
|
+
`;
|
|
5025
|
+
const label = document.createElement("span");
|
|
5026
|
+
label.textContent = text;
|
|
5027
|
+
label.style.cssText = `font-size: var(--fb-font-size-small, 12px); color: var(--fb-text-color, #333);`;
|
|
5028
|
+
overlay.appendChild(spinner);
|
|
5029
|
+
overlay.appendChild(label);
|
|
5030
|
+
parent.appendChild(overlay);
|
|
5031
|
+
return overlay;
|
|
5032
|
+
}
|
|
4964
5033
|
function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
4965
|
-
var _a, _b;
|
|
5034
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
4966
5035
|
const state = ctx.state;
|
|
4967
5036
|
const instance = ctx.instance;
|
|
4968
|
-
const
|
|
5037
|
+
const mergeAllowed = element.mergeAllowed !== false;
|
|
5038
|
+
const cellsKey = (_b = (_a = element.fieldNames) == null ? void 0 : _a.cells) != null ? _b : "cells";
|
|
5039
|
+
const mergesKey = (_d = (_c = element.fieldNames) == null ? void 0 : _c.merges) != null ? _d : "merges";
|
|
5040
|
+
const cells = initialData.cells.length > 0 ? initialData.cells.map((r) => [...r]) : createEmptyCells((_e = element.rows) != null ? _e : 3, (_f = element.columns) != null ? _f : 3);
|
|
4969
5041
|
let merges = initialData.merges ? [...initialData.merges] : [];
|
|
4970
5042
|
const sel = { anchor: null, focus: null, dragging: false };
|
|
4971
5043
|
const hiddenInput = document.createElement("input");
|
|
4972
5044
|
hiddenInput.type = "hidden";
|
|
4973
5045
|
hiddenInput.name = pathKey;
|
|
4974
|
-
hiddenInput.value = JSON.stringify({ cells, merges });
|
|
5046
|
+
hiddenInput.value = JSON.stringify({ [cellsKey]: cells, [mergesKey]: merges });
|
|
4975
5047
|
wrapper.appendChild(hiddenInput);
|
|
4976
5048
|
function persistValue() {
|
|
4977
|
-
hiddenInput.value = JSON.stringify({ cells, merges });
|
|
5049
|
+
hiddenInput.value = JSON.stringify({ [cellsKey]: cells, [mergesKey]: merges });
|
|
4978
5050
|
if (instance) {
|
|
4979
|
-
instance.triggerOnChange(pathKey, { cells, merges });
|
|
5051
|
+
instance.triggerOnChange(pathKey, { [cellsKey]: cells, [mergesKey]: merges });
|
|
4980
5052
|
}
|
|
4981
5053
|
}
|
|
4982
5054
|
hiddenInput._applyExternalUpdate = (data) => {
|
|
@@ -5002,6 +5074,116 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5002
5074
|
table-layout: fixed;
|
|
5003
5075
|
`;
|
|
5004
5076
|
tableWrapper.appendChild(tableEl);
|
|
5077
|
+
const acceptExts = (_h = (_g = element.importAccept) == null ? void 0 : _g.map((ext) => `.${ext.toLowerCase()}`)) != null ? _h : [];
|
|
5078
|
+
async function importFile(file) {
|
|
5079
|
+
var _a2, _b2, _c2;
|
|
5080
|
+
if (!state.config.parseTableFile) return;
|
|
5081
|
+
if (acceptExts.length > 0) {
|
|
5082
|
+
const ext = file.name.toLowerCase().replace(/^.*(\.[^.]+)$/, "$1");
|
|
5083
|
+
if (!acceptExts.includes(ext)) return;
|
|
5084
|
+
}
|
|
5085
|
+
const overlay = showLoadingOverlay(
|
|
5086
|
+
tableWrapper,
|
|
5087
|
+
t("tableImporting", state)
|
|
5088
|
+
);
|
|
5089
|
+
try {
|
|
5090
|
+
const result = await state.config.parseTableFile(file);
|
|
5091
|
+
const importedCells = result.cells;
|
|
5092
|
+
const importedMerges = (_a2 = result.merges) != null ? _a2 : [];
|
|
5093
|
+
if (importedMerges.length > 0) {
|
|
5094
|
+
const err = validateMerges(
|
|
5095
|
+
importedMerges,
|
|
5096
|
+
importedCells.length,
|
|
5097
|
+
(_c2 = (_b2 = importedCells[0]) == null ? void 0 : _b2.length) != null ? _c2 : 0
|
|
5098
|
+
);
|
|
5099
|
+
if (err) throw new Error(err);
|
|
5100
|
+
}
|
|
5101
|
+
cells.length = 0;
|
|
5102
|
+
importedCells.forEach((row) => cells.push([...row]));
|
|
5103
|
+
merges.length = 0;
|
|
5104
|
+
importedMerges.forEach((m) => merges.push({ ...m }));
|
|
5105
|
+
sel.anchor = null;
|
|
5106
|
+
sel.focus = null;
|
|
5107
|
+
persistValue();
|
|
5108
|
+
rebuild();
|
|
5109
|
+
} catch (e) {
|
|
5110
|
+
const errMsg = e instanceof Error ? e.message : String(e);
|
|
5111
|
+
console.error(
|
|
5112
|
+
t("tableImportError", state).replace("{error}", errMsg)
|
|
5113
|
+
);
|
|
5114
|
+
} finally {
|
|
5115
|
+
overlay.remove();
|
|
5116
|
+
}
|
|
5117
|
+
}
|
|
5118
|
+
if (element.importAccept && state.config.parseTableFile) {
|
|
5119
|
+
const importBtn = document.createElement("button");
|
|
5120
|
+
importBtn.type = "button";
|
|
5121
|
+
importBtn.title = t("tableImportFile", state);
|
|
5122
|
+
importBtn.innerHTML = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48"/></svg>`;
|
|
5123
|
+
importBtn.style.cssText = `
|
|
5124
|
+
position: absolute; top: 2px; left: 2px;
|
|
5125
|
+
width: 20px; height: 20px;
|
|
5126
|
+
padding: 0;
|
|
5127
|
+
display: flex; align-items: center; justify-content: center;
|
|
5128
|
+
color: var(--fb-text-color, #999);
|
|
5129
|
+
border: none;
|
|
5130
|
+
background: transparent;
|
|
5131
|
+
cursor: pointer;
|
|
5132
|
+
z-index: 2;
|
|
5133
|
+
`;
|
|
5134
|
+
importBtn.addEventListener("mouseenter", () => {
|
|
5135
|
+
importBtn.style.color = "var(--fb-primary-color, #0066cc)";
|
|
5136
|
+
});
|
|
5137
|
+
importBtn.addEventListener("mouseleave", () => {
|
|
5138
|
+
importBtn.style.color = "var(--fb-text-color, #999)";
|
|
5139
|
+
});
|
|
5140
|
+
const importInput = document.createElement("input");
|
|
5141
|
+
importInput.type = "file";
|
|
5142
|
+
importInput.accept = acceptExts.join(",");
|
|
5143
|
+
importInput.style.display = "none";
|
|
5144
|
+
tableWrapper.appendChild(importInput);
|
|
5145
|
+
importBtn.addEventListener("click", () => {
|
|
5146
|
+
importInput.click();
|
|
5147
|
+
});
|
|
5148
|
+
importInput.addEventListener("change", () => {
|
|
5149
|
+
var _a2;
|
|
5150
|
+
const file = (_a2 = importInput.files) == null ? void 0 : _a2[0];
|
|
5151
|
+
if (file) importFile(file);
|
|
5152
|
+
importInput.value = "";
|
|
5153
|
+
});
|
|
5154
|
+
tableWrapper.appendChild(importBtn);
|
|
5155
|
+
let dragCounter = 0;
|
|
5156
|
+
tableWrapper.addEventListener("dragenter", (e) => {
|
|
5157
|
+
e.preventDefault();
|
|
5158
|
+
dragCounter++;
|
|
5159
|
+
if (dragCounter === 1) {
|
|
5160
|
+
tableWrapper.style.outline = "2px dashed var(--fb-primary-color, #0066cc)";
|
|
5161
|
+
tableWrapper.style.outlineOffset = "-2px";
|
|
5162
|
+
}
|
|
5163
|
+
});
|
|
5164
|
+
tableWrapper.addEventListener("dragover", (e) => {
|
|
5165
|
+
e.preventDefault();
|
|
5166
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "copy";
|
|
5167
|
+
});
|
|
5168
|
+
tableWrapper.addEventListener("dragleave", (e) => {
|
|
5169
|
+
e.preventDefault();
|
|
5170
|
+
dragCounter--;
|
|
5171
|
+
if (dragCounter <= 0) {
|
|
5172
|
+
dragCounter = 0;
|
|
5173
|
+
tableWrapper.style.outline = "";
|
|
5174
|
+
tableWrapper.style.outlineOffset = "";
|
|
5175
|
+
}
|
|
5176
|
+
});
|
|
5177
|
+
tableWrapper.addEventListener("drop", (e) => {
|
|
5178
|
+
var _a2, _b2;
|
|
5179
|
+
e.preventDefault();
|
|
5180
|
+
dragCounter = 0;
|
|
5181
|
+
tableWrapper.style.outline = "";
|
|
5182
|
+
tableWrapper.style.outlineOffset = "";
|
|
5183
|
+
const file = (_b2 = (_a2 = e.dataTransfer) == null ? void 0 : _a2.files) == null ? void 0 : _b2[0];
|
|
5184
|
+
if (file) importFile(file);
|
|
5185
|
+
});
|
|
5186
|
+
}
|
|
5005
5187
|
wrapper.appendChild(tableWrapper);
|
|
5006
5188
|
const contextMenu = document.createElement("div");
|
|
5007
5189
|
contextMenu.style.cssText = `
|
|
@@ -5045,6 +5227,7 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5045
5227
|
return btn;
|
|
5046
5228
|
}
|
|
5047
5229
|
function showContextMenu(x, y) {
|
|
5230
|
+
if (!mergeAllowed) return;
|
|
5048
5231
|
contextMenu.innerHTML = "";
|
|
5049
5232
|
contextMenu.style.display = "flex";
|
|
5050
5233
|
const range = selectionRange(sel);
|
|
@@ -5128,11 +5311,11 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5128
5311
|
const insertAt = afterIndex !== void 0 ? afterIndex + 1 : cells.length;
|
|
5129
5312
|
cells.splice(insertAt, 0, newRow);
|
|
5130
5313
|
merges = merges.map((m) => {
|
|
5131
|
-
if (m.
|
|
5132
|
-
return { ...m,
|
|
5314
|
+
if (m.top >= insertAt) {
|
|
5315
|
+
return { ...m, top: m.top + 1, bottom: m.bottom + 1 };
|
|
5133
5316
|
}
|
|
5134
|
-
if (m.
|
|
5135
|
-
return { ...m,
|
|
5317
|
+
if (m.top < insertAt && m.bottom >= insertAt) {
|
|
5318
|
+
return { ...m, bottom: m.bottom + 1 };
|
|
5136
5319
|
}
|
|
5137
5320
|
return m;
|
|
5138
5321
|
});
|
|
@@ -5143,19 +5326,18 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5143
5326
|
if (cells.length <= 1) return;
|
|
5144
5327
|
const rowToRemove = targetRow !== void 0 ? targetRow : sel.anchor ? sel.anchor.row : cells.length - 1;
|
|
5145
5328
|
merges = merges.map((m) => {
|
|
5146
|
-
|
|
5147
|
-
if (m.
|
|
5148
|
-
|
|
5149
|
-
return { ...m, row: m.row + 1, rowspan: m.rowspan - 1 };
|
|
5329
|
+
if (m.top === rowToRemove && m.bottom === rowToRemove) return null;
|
|
5330
|
+
if (m.top === rowToRemove) {
|
|
5331
|
+
return { ...m, bottom: m.bottom - 1 };
|
|
5150
5332
|
}
|
|
5151
|
-
if (
|
|
5152
|
-
return { ...m,
|
|
5333
|
+
if (m.bottom === rowToRemove) {
|
|
5334
|
+
return { ...m, bottom: m.bottom - 1 };
|
|
5153
5335
|
}
|
|
5154
|
-
if (m.
|
|
5155
|
-
return { ...m,
|
|
5336
|
+
if (m.top < rowToRemove && m.bottom > rowToRemove) {
|
|
5337
|
+
return { ...m, bottom: m.bottom - 1 };
|
|
5156
5338
|
}
|
|
5157
|
-
if (m.
|
|
5158
|
-
return { ...m,
|
|
5339
|
+
if (m.top > rowToRemove) {
|
|
5340
|
+
return { ...m, top: m.top - 1, bottom: m.bottom - 1 };
|
|
5159
5341
|
}
|
|
5160
5342
|
return m;
|
|
5161
5343
|
}).filter((m) => m !== null);
|
|
@@ -5171,11 +5353,11 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5171
5353
|
const insertAt = afterIndex !== void 0 ? afterIndex + 1 : (_b2 = (_a2 = cells[0]) == null ? void 0 : _a2.length) != null ? _b2 : 0;
|
|
5172
5354
|
cells.forEach((row) => row.splice(insertAt, 0, ""));
|
|
5173
5355
|
merges = merges.map((m) => {
|
|
5174
|
-
if (m.
|
|
5175
|
-
return { ...m,
|
|
5356
|
+
if (m.left >= insertAt) {
|
|
5357
|
+
return { ...m, left: m.left + 1, right: m.right + 1 };
|
|
5176
5358
|
}
|
|
5177
|
-
if (m.
|
|
5178
|
-
return { ...m,
|
|
5359
|
+
if (m.left < insertAt && m.right >= insertAt) {
|
|
5360
|
+
return { ...m, right: m.right + 1 };
|
|
5179
5361
|
}
|
|
5180
5362
|
return m;
|
|
5181
5363
|
});
|
|
@@ -5186,19 +5368,18 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5186
5368
|
if (cells.length === 0 || cells[0].length <= 1) return;
|
|
5187
5369
|
const colToRemove = targetCol !== void 0 ? targetCol : sel.anchor ? sel.anchor.col : cells[0].length - 1;
|
|
5188
5370
|
merges = merges.map((m) => {
|
|
5189
|
-
|
|
5190
|
-
if (m.
|
|
5191
|
-
|
|
5192
|
-
return { ...m, col: m.col + 1, colspan: m.colspan - 1 };
|
|
5371
|
+
if (m.left === colToRemove && m.right === colToRemove) return null;
|
|
5372
|
+
if (m.left === colToRemove) {
|
|
5373
|
+
return { ...m, right: m.right - 1 };
|
|
5193
5374
|
}
|
|
5194
|
-
if (
|
|
5195
|
-
return { ...m,
|
|
5375
|
+
if (m.right === colToRemove) {
|
|
5376
|
+
return { ...m, right: m.right - 1 };
|
|
5196
5377
|
}
|
|
5197
|
-
if (m.
|
|
5198
|
-
return { ...m,
|
|
5378
|
+
if (m.left < colToRemove && m.right > colToRemove) {
|
|
5379
|
+
return { ...m, right: m.right - 1 };
|
|
5199
5380
|
}
|
|
5200
|
-
if (m.
|
|
5201
|
-
return { ...m,
|
|
5381
|
+
if (m.left > colToRemove) {
|
|
5382
|
+
return { ...m, left: m.left - 1, right: m.right - 1 };
|
|
5202
5383
|
}
|
|
5203
5384
|
return m;
|
|
5204
5385
|
}).filter((m) => m !== null);
|
|
@@ -5210,14 +5391,14 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5210
5391
|
rebuild();
|
|
5211
5392
|
}
|
|
5212
5393
|
function mergeCells() {
|
|
5394
|
+
var _a2, _b2;
|
|
5395
|
+
if (!mergeAllowed) return;
|
|
5213
5396
|
const range = selectionRange(sel);
|
|
5214
5397
|
if (!range) return;
|
|
5215
5398
|
const { r1, c1, r2, c2 } = range;
|
|
5216
5399
|
if (r1 === r2 && c1 === c2) return;
|
|
5217
5400
|
merges = merges.filter((m) => {
|
|
5218
|
-
const
|
|
5219
|
-
const mEndCol = m.col + m.colspan - 1;
|
|
5220
|
-
const overlaps = m.row <= r2 && mEndRow >= r1 && m.col <= c2 && mEndCol >= c1;
|
|
5401
|
+
const overlaps = m.top <= r2 && m.bottom >= r1 && m.left <= c2 && m.right >= c1;
|
|
5221
5402
|
return !overlaps;
|
|
5222
5403
|
});
|
|
5223
5404
|
const anchorText = cells[r1][c1];
|
|
@@ -5229,16 +5410,24 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5229
5410
|
}
|
|
5230
5411
|
}
|
|
5231
5412
|
cells[r1][c1] = anchorText;
|
|
5232
|
-
|
|
5413
|
+
const newMerge = { top: r1, left: c1, bottom: r2, right: c2 };
|
|
5414
|
+
const testMerges = [...merges, newMerge];
|
|
5415
|
+
const err = validateMerges(testMerges, cells.length, (_b2 = (_a2 = cells[0]) == null ? void 0 : _a2.length) != null ? _b2 : 0);
|
|
5416
|
+
if (err) {
|
|
5417
|
+
console.warn("Merge validation failed:", err);
|
|
5418
|
+
return;
|
|
5419
|
+
}
|
|
5420
|
+
merges.push(newMerge);
|
|
5233
5421
|
sel.anchor = { row: r1, col: c1 };
|
|
5234
5422
|
sel.focus = null;
|
|
5235
5423
|
persistValue();
|
|
5236
5424
|
rebuild();
|
|
5237
5425
|
}
|
|
5238
5426
|
function splitCell() {
|
|
5427
|
+
if (!mergeAllowed) return;
|
|
5239
5428
|
if (!sel.anchor) return;
|
|
5240
5429
|
const { row, col } = sel.anchor;
|
|
5241
|
-
const mIdx = merges.findIndex((m) => m.
|
|
5430
|
+
const mIdx = merges.findIndex((m) => m.top === row && m.left === col);
|
|
5242
5431
|
if (mIdx === -1) return;
|
|
5243
5432
|
merges.splice(mIdx, 1);
|
|
5244
5433
|
sel.focus = null;
|
|
@@ -5263,8 +5452,10 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5263
5452
|
td.setAttribute("data-row", String(rIdx));
|
|
5264
5453
|
td.setAttribute("data-col", String(cIdx));
|
|
5265
5454
|
if (merge) {
|
|
5266
|
-
|
|
5267
|
-
|
|
5455
|
+
const rowspan = merge.bottom - merge.top + 1;
|
|
5456
|
+
const colspan = merge.right - merge.left + 1;
|
|
5457
|
+
if (rowspan > 1) td.rowSpan = rowspan;
|
|
5458
|
+
if (colspan > 1) td.colSpan = colspan;
|
|
5268
5459
|
}
|
|
5269
5460
|
const inRange = range !== null && rIdx >= range.r1 && rIdx <= range.r2 && cIdx >= range.c1 && cIdx <= range.c2;
|
|
5270
5461
|
const isAnchor = sel.anchor !== null && sel.anchor.row === rIdx && sel.anchor.col === cIdx;
|
|
@@ -5327,6 +5518,7 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5327
5518
|
}
|
|
5328
5519
|
});
|
|
5329
5520
|
td.addEventListener("contextmenu", (e) => {
|
|
5521
|
+
if (!mergeAllowed) return;
|
|
5330
5522
|
const currentRange = selectionRange(sel);
|
|
5331
5523
|
const isMulti = currentRange && (currentRange.r1 !== currentRange.r2 || currentRange.c1 !== currentRange.c2);
|
|
5332
5524
|
const isMerged = sel.anchor && getMergeAt(sel.anchor.row, sel.anchor.col, merges);
|
|
@@ -5388,18 +5580,18 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5388
5580
|
selectCell(nr, nc);
|
|
5389
5581
|
return;
|
|
5390
5582
|
}
|
|
5391
|
-
if (e.key === "m" && e.ctrlKey && !e.shiftKey) {
|
|
5583
|
+
if (mergeAllowed && e.key === "m" && e.ctrlKey && !e.shiftKey) {
|
|
5392
5584
|
e.preventDefault();
|
|
5393
5585
|
mergeCells();
|
|
5394
5586
|
return;
|
|
5395
5587
|
}
|
|
5396
|
-
if (e.key === "M" && e.ctrlKey && e.shiftKey) {
|
|
5588
|
+
if (mergeAllowed && e.key === "M" && e.ctrlKey && e.shiftKey) {
|
|
5397
5589
|
e.preventDefault();
|
|
5398
5590
|
splitCell();
|
|
5399
5591
|
}
|
|
5400
5592
|
};
|
|
5401
5593
|
tableEl.oncopy = (e) => {
|
|
5402
|
-
var _a3, _b3,
|
|
5594
|
+
var _a3, _b3, _c2, _d2;
|
|
5403
5595
|
const range2 = selectionRange(sel);
|
|
5404
5596
|
if (!range2) return;
|
|
5405
5597
|
e.preventDefault();
|
|
@@ -5420,11 +5612,11 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5420
5612
|
}
|
|
5421
5613
|
const tsvText = tsvRows.join("\n");
|
|
5422
5614
|
const htmlText = `<table>${htmlRows.join("")}</table>`;
|
|
5423
|
-
(
|
|
5424
|
-
(
|
|
5615
|
+
(_c2 = e.clipboardData) == null ? void 0 : _c2.setData("text/plain", tsvText);
|
|
5616
|
+
(_d2 = e.clipboardData) == null ? void 0 : _d2.setData("text/html", htmlText);
|
|
5425
5617
|
};
|
|
5426
5618
|
tableEl.onpaste = (e) => {
|
|
5427
|
-
var _a3, _b3,
|
|
5619
|
+
var _a3, _b3, _c2, _d2, _e2, _f2, _g2, _h2, _i;
|
|
5428
5620
|
const anchor = sel.anchor;
|
|
5429
5621
|
if (!anchor) return;
|
|
5430
5622
|
const text = (_b3 = (_a3 = e.clipboardData) == null ? void 0 : _a3.getData("text/plain")) != null ? _b3 : "";
|
|
@@ -5435,15 +5627,15 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5435
5627
|
if (editing) {
|
|
5436
5628
|
editing.contentEditable = "inherit";
|
|
5437
5629
|
const r = parseInt(
|
|
5438
|
-
(
|
|
5630
|
+
(_d2 = (_c2 = editing.closest("td")) == null ? void 0 : _c2.getAttribute("data-row")) != null ? _d2 : "0",
|
|
5439
5631
|
10
|
|
5440
5632
|
);
|
|
5441
5633
|
const c = parseInt(
|
|
5442
|
-
(
|
|
5634
|
+
(_f2 = (_e2 = editing.closest("td")) == null ? void 0 : _e2.getAttribute("data-col")) != null ? _f2 : "0",
|
|
5443
5635
|
10
|
|
5444
5636
|
);
|
|
5445
5637
|
if (cells[r]) {
|
|
5446
|
-
cells[r][c] = (
|
|
5638
|
+
cells[r][c] = (_g2 = editing.textContent) != null ? _g2 : "";
|
|
5447
5639
|
}
|
|
5448
5640
|
}
|
|
5449
5641
|
if (!text.trim()) return;
|
|
@@ -5455,7 +5647,7 @@ function renderEditTable(element, initialData, pathKey, ctx, wrapper) {
|
|
|
5455
5647
|
const startC = anchor.col;
|
|
5456
5648
|
const neededRows = startR + pasteRows.length;
|
|
5457
5649
|
while (cells.length < neededRows) {
|
|
5458
|
-
cells.push(Array((_i = (
|
|
5650
|
+
cells.push(Array((_i = (_h2 = cells[0]) == null ? void 0 : _h2.length) != null ? _i : 1).fill(""));
|
|
5459
5651
|
}
|
|
5460
5652
|
const maxPasteCols = Math.max(...pasteRows.map((r) => r.length));
|
|
5461
5653
|
const neededCols = startC + maxPasteCols;
|
|
@@ -5744,10 +5936,50 @@ function defaultTableData(element) {
|
|
|
5744
5936
|
function isTableData(v) {
|
|
5745
5937
|
return v !== null && typeof v === "object" && "cells" in v && Array.isArray(v.cells);
|
|
5746
5938
|
}
|
|
5939
|
+
function isTableDataWithFieldNames(v, cellsKey) {
|
|
5940
|
+
return v !== null && typeof v === "object" && cellsKey in v && Array.isArray(v[cellsKey]);
|
|
5941
|
+
}
|
|
5747
5942
|
function renderTableElement(element, ctx, wrapper, pathKey) {
|
|
5943
|
+
var _a, _b, _c, _d;
|
|
5748
5944
|
const state = ctx.state;
|
|
5749
5945
|
const rawPrefill = ctx.prefill[element.key];
|
|
5750
|
-
const
|
|
5946
|
+
const cellsKey = (_b = (_a = element.fieldNames) == null ? void 0 : _a.cells) != null ? _b : "cells";
|
|
5947
|
+
const mergesKey = (_d = (_c = element.fieldNames) == null ? void 0 : _c.merges) != null ? _d : "merges";
|
|
5948
|
+
let initialData;
|
|
5949
|
+
if (isTableData(rawPrefill)) {
|
|
5950
|
+
initialData = {
|
|
5951
|
+
cells: rawPrefill.cells,
|
|
5952
|
+
merges: rawPrefill.merges ? migrateMerges(rawPrefill.merges) : []
|
|
5953
|
+
};
|
|
5954
|
+
} else if (rawPrefill && isTableDataWithFieldNames(rawPrefill, cellsKey)) {
|
|
5955
|
+
const rawMerges = rawPrefill[mergesKey];
|
|
5956
|
+
initialData = {
|
|
5957
|
+
cells: rawPrefill[cellsKey],
|
|
5958
|
+
merges: rawMerges ? migrateMerges(rawMerges) : []
|
|
5959
|
+
};
|
|
5960
|
+
} else if (isTableData(element.default)) {
|
|
5961
|
+
initialData = {
|
|
5962
|
+
cells: element.default.cells,
|
|
5963
|
+
merges: element.default.merges ? migrateMerges(element.default.merges) : []
|
|
5964
|
+
};
|
|
5965
|
+
} else if (element.default && isTableDataWithFieldNames(element.default, cellsKey)) {
|
|
5966
|
+
const rawMerges = element.default[mergesKey];
|
|
5967
|
+
initialData = {
|
|
5968
|
+
cells: element.default[cellsKey],
|
|
5969
|
+
merges: rawMerges ? migrateMerges(rawMerges) : []
|
|
5970
|
+
};
|
|
5971
|
+
} else {
|
|
5972
|
+
initialData = defaultTableData(element);
|
|
5973
|
+
}
|
|
5974
|
+
if (initialData.merges && initialData.merges.length > 0) {
|
|
5975
|
+
const rows = initialData.cells.length;
|
|
5976
|
+
const cols = rows > 0 ? initialData.cells[0].length : 0;
|
|
5977
|
+
const err = validateMerges(initialData.merges, rows, cols);
|
|
5978
|
+
if (err) {
|
|
5979
|
+
console.warn(`Table "${element.key}": invalid prefill merges stripped (${err})`);
|
|
5980
|
+
initialData = { ...initialData, merges: [] };
|
|
5981
|
+
}
|
|
5982
|
+
}
|
|
5751
5983
|
if (state.config.readonly) {
|
|
5752
5984
|
renderReadonlyTable(initialData, wrapper);
|
|
5753
5985
|
} else {
|
|
@@ -5755,8 +5987,10 @@ function renderTableElement(element, ctx, wrapper, pathKey) {
|
|
|
5755
5987
|
}
|
|
5756
5988
|
}
|
|
5757
5989
|
function validateTableElement(element, key, context) {
|
|
5990
|
+
var _a, _b;
|
|
5758
5991
|
const { scopeRoot, skipValidation } = context;
|
|
5759
5992
|
const errors = [];
|
|
5993
|
+
const cellsKey = (_b = (_a = element.fieldNames) == null ? void 0 : _a.cells) != null ? _b : "cells";
|
|
5760
5994
|
const hiddenInput = scopeRoot.querySelector(
|
|
5761
5995
|
`[name="${key}"]`
|
|
5762
5996
|
);
|
|
@@ -5771,7 +6005,8 @@ function validateTableElement(element, key, context) {
|
|
|
5771
6005
|
return { value: null, errors };
|
|
5772
6006
|
}
|
|
5773
6007
|
if (!skipValidation && element.required) {
|
|
5774
|
-
const
|
|
6008
|
+
const cells = value[cellsKey];
|
|
6009
|
+
const hasContent = cells == null ? void 0 : cells.some(
|
|
5775
6010
|
(row) => row.some((cell) => cell.trim() !== "")
|
|
5776
6011
|
);
|
|
5777
6012
|
if (!hasContent) {
|
|
@@ -5780,8 +6015,11 @@ function validateTableElement(element, key, context) {
|
|
|
5780
6015
|
}
|
|
5781
6016
|
return { value, errors };
|
|
5782
6017
|
}
|
|
5783
|
-
function updateTableField(
|
|
6018
|
+
function updateTableField(element, fieldPath, value, context) {
|
|
6019
|
+
var _a, _b, _c, _d;
|
|
5784
6020
|
const { scopeRoot } = context;
|
|
6021
|
+
const cellsKey = (_b = (_a = element.fieldNames) == null ? void 0 : _a.cells) != null ? _b : "cells";
|
|
6022
|
+
const mergesKey = (_d = (_c = element.fieldNames) == null ? void 0 : _c.merges) != null ? _d : "merges";
|
|
5785
6023
|
const hiddenInput = scopeRoot.querySelector(
|
|
5786
6024
|
`[name="${fieldPath}"]`
|
|
5787
6025
|
);
|
|
@@ -5791,8 +6029,21 @@ function updateTableField(_element, fieldPath, value, context) {
|
|
|
5791
6029
|
);
|
|
5792
6030
|
return;
|
|
5793
6031
|
}
|
|
5794
|
-
|
|
5795
|
-
|
|
6032
|
+
let tableData = null;
|
|
6033
|
+
if (isTableData(value)) {
|
|
6034
|
+
tableData = {
|
|
6035
|
+
cells: value.cells,
|
|
6036
|
+
merges: value.merges ? migrateMerges(value.merges) : []
|
|
6037
|
+
};
|
|
6038
|
+
} else if (value && isTableDataWithFieldNames(value, cellsKey)) {
|
|
6039
|
+
const rawMerges = value[mergesKey];
|
|
6040
|
+
tableData = {
|
|
6041
|
+
cells: value[cellsKey],
|
|
6042
|
+
merges: rawMerges ? migrateMerges(rawMerges) : []
|
|
6043
|
+
};
|
|
6044
|
+
}
|
|
6045
|
+
if (tableData && hiddenInput._applyExternalUpdate) {
|
|
6046
|
+
hiddenInput._applyExternalUpdate(tableData);
|
|
5796
6047
|
} else {
|
|
5797
6048
|
hiddenInput.value = JSON.stringify(value);
|
|
5798
6049
|
}
|
|
@@ -7501,6 +7752,7 @@ var defaultConfig = {
|
|
|
7501
7752
|
enableFilePreview: true,
|
|
7502
7753
|
maxPreviewSize: "200px",
|
|
7503
7754
|
readonly: false,
|
|
7755
|
+
parseTableFile: null,
|
|
7504
7756
|
locale: "en",
|
|
7505
7757
|
translations: {
|
|
7506
7758
|
en: {
|
|
@@ -7554,6 +7806,9 @@ var defaultConfig = {
|
|
|
7554
7806
|
tableRemoveColumn: "Remove column",
|
|
7555
7807
|
tableMergeCells: "Merge cells (Ctrl+M)",
|
|
7556
7808
|
tableSplitCell: "Split cell (Ctrl+Shift+M)",
|
|
7809
|
+
tableImportFile: "Import",
|
|
7810
|
+
tableImporting: "Importing...",
|
|
7811
|
+
tableImportError: "Import failed: {error}",
|
|
7557
7812
|
richinputPlaceholder: "Type text...",
|
|
7558
7813
|
richinputAttachFile: "Attach file",
|
|
7559
7814
|
richinputMention: "Mention",
|
|
@@ -7610,6 +7865,9 @@ var defaultConfig = {
|
|
|
7610
7865
|
tableRemoveColumn: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0442\u043E\u043B\u0431\u0435\u0446",
|
|
7611
7866
|
tableMergeCells: "\u041E\u0431\u044A\u0435\u0434\u0438\u043D\u0438\u0442\u044C \u044F\u0447\u0435\u0439\u043A\u0438 (Ctrl+M)",
|
|
7612
7867
|
tableSplitCell: "\u0420\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u044C \u044F\u0447\u0435\u0439\u043A\u0443 (Ctrl+Shift+M)",
|
|
7868
|
+
tableImportFile: "\u0418\u043C\u043F\u043E\u0440\u0442",
|
|
7869
|
+
tableImporting: "\u0418\u043C\u043F\u043E\u0440\u0442...",
|
|
7870
|
+
tableImportError: "\u041E\u0448\u0438\u0431\u043A\u0430 \u0438\u043C\u043F\u043E\u0440\u0442\u0430: {error}",
|
|
7613
7871
|
richinputPlaceholder: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0442\u0435\u043A\u0441\u0442...",
|
|
7614
7872
|
richinputAttachFile: "\u041F\u0440\u0438\u043A\u0440\u0435\u043F\u0438\u0442\u044C \u0444\u0430\u0439\u043B",
|
|
7615
7873
|
richinputMention: "\u0423\u043F\u043E\u043C\u044F\u043D\u0443\u0442\u044C",
|