@extend-ai/react-xlsx 0.13.4 → 0.14.1
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/README.md +47 -0
- package/dist/duke_sheets_wasm_bg.wasm +0 -0
- package/dist/index.cjs +1060 -212
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +173 -1
- package/dist/index.d.ts +173 -1
- package/dist/index.js +1060 -212
- package/dist/index.js.map +1 -1
- package/dist/xlsx-worker.js +187 -0
- package/dist/xlsx-worker.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -3642,7 +3642,6 @@ var SPREADSHEET_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
|
3642
3642
|
var CONTENT_TYPES_NS = "http://schemas.openxmlformats.org/package/2006/content-types";
|
|
3643
3643
|
var DRAWING_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing";
|
|
3644
3644
|
var VML_DRAWING_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing";
|
|
3645
|
-
var CTRL_PROP_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp";
|
|
3646
3645
|
var IMAGE_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
3647
3646
|
var DRAWING_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.drawing+xml";
|
|
3648
3647
|
var EMU_PER_PIXEL2 = 9525;
|
|
@@ -5085,6 +5084,124 @@ function parseSpreadsheetBooleanNode(node) {
|
|
|
5085
5084
|
}
|
|
5086
5085
|
return parseSpreadsheetBooleanValue(node.getAttribute("val") ?? node.textContent);
|
|
5087
5086
|
}
|
|
5087
|
+
function mapDukeFormControlAnchor(anchor) {
|
|
5088
|
+
return {
|
|
5089
|
+
from: {
|
|
5090
|
+
col: anchor.fromCol,
|
|
5091
|
+
colOffsetEmu: anchor.fromColOffset,
|
|
5092
|
+
row: anchor.fromRow,
|
|
5093
|
+
rowOffsetEmu: anchor.fromRowOffset
|
|
5094
|
+
},
|
|
5095
|
+
kind: "two-cell",
|
|
5096
|
+
to: {
|
|
5097
|
+
col: anchor.toCol,
|
|
5098
|
+
colOffsetEmu: anchor.toColOffset,
|
|
5099
|
+
row: anchor.toRow,
|
|
5100
|
+
rowOffsetEmu: anchor.toRowOffset
|
|
5101
|
+
}
|
|
5102
|
+
};
|
|
5103
|
+
}
|
|
5104
|
+
function mapDukeFormControlKind(kind) {
|
|
5105
|
+
switch (kind.kind) {
|
|
5106
|
+
case "button":
|
|
5107
|
+
return { caption: kind.caption, kind: "button", label: normalizeControlLabel(kind.caption) };
|
|
5108
|
+
case "checkbox":
|
|
5109
|
+
return {
|
|
5110
|
+
caption: kind.caption,
|
|
5111
|
+
checked: kind.state === "checked",
|
|
5112
|
+
kind: "checkbox",
|
|
5113
|
+
label: normalizeControlLabel(kind.caption),
|
|
5114
|
+
linkedCell: kind.cellLink,
|
|
5115
|
+
no3D: kind.no3D,
|
|
5116
|
+
state: kind.state
|
|
5117
|
+
};
|
|
5118
|
+
case "optionButton":
|
|
5119
|
+
return {
|
|
5120
|
+
caption: kind.caption,
|
|
5121
|
+
checked: kind.state === "checked",
|
|
5122
|
+
firstInGroup: kind.firstInGroup,
|
|
5123
|
+
kind: "radio",
|
|
5124
|
+
label: normalizeControlLabel(kind.caption),
|
|
5125
|
+
linkedCell: kind.cellLink,
|
|
5126
|
+
no3D: kind.no3D,
|
|
5127
|
+
state: kind.state
|
|
5128
|
+
};
|
|
5129
|
+
case "label":
|
|
5130
|
+
return { caption: kind.caption, kind: "label", label: normalizeControlLabel(kind.caption) };
|
|
5131
|
+
case "groupBox":
|
|
5132
|
+
return {
|
|
5133
|
+
caption: kind.caption,
|
|
5134
|
+
kind: "group-box",
|
|
5135
|
+
label: normalizeControlLabel(kind.caption),
|
|
5136
|
+
no3D: kind.no3D
|
|
5137
|
+
};
|
|
5138
|
+
case "listBox":
|
|
5139
|
+
return {
|
|
5140
|
+
inputRange: kind.inputRange,
|
|
5141
|
+
kind: "listbox",
|
|
5142
|
+
linkedCell: kind.cellLink,
|
|
5143
|
+
no3D: kind.no3D,
|
|
5144
|
+
selected: [...kind.selected],
|
|
5145
|
+
selection: kind.selection
|
|
5146
|
+
};
|
|
5147
|
+
case "dropdown":
|
|
5148
|
+
return {
|
|
5149
|
+
inputRange: kind.inputRange,
|
|
5150
|
+
kind: "dropdown",
|
|
5151
|
+
lines: kind.lines,
|
|
5152
|
+
linkedCell: kind.cellLink,
|
|
5153
|
+
no3D: kind.no3D,
|
|
5154
|
+
selected: kind.selected
|
|
5155
|
+
};
|
|
5156
|
+
case "scrollbar":
|
|
5157
|
+
return {
|
|
5158
|
+
horizontal: kind.horizontal,
|
|
5159
|
+
increment: kind.increment,
|
|
5160
|
+
kind: "scrollbar",
|
|
5161
|
+
linkedCell: kind.cellLink,
|
|
5162
|
+
max: kind.max,
|
|
5163
|
+
min: kind.min,
|
|
5164
|
+
page: kind.page,
|
|
5165
|
+
value: kind.value
|
|
5166
|
+
};
|
|
5167
|
+
case "spinner":
|
|
5168
|
+
return {
|
|
5169
|
+
increment: kind.increment,
|
|
5170
|
+
kind: "spinner",
|
|
5171
|
+
linkedCell: kind.cellLink,
|
|
5172
|
+
max: kind.max,
|
|
5173
|
+
min: kind.min,
|
|
5174
|
+
value: kind.value
|
|
5175
|
+
};
|
|
5176
|
+
}
|
|
5177
|
+
}
|
|
5178
|
+
function mapDukeFormControl(control, controlIndex, workbookSheetIndex) {
|
|
5179
|
+
return {
|
|
5180
|
+
anchor: mapDukeFormControlAnchor(control.anchor),
|
|
5181
|
+
controlIndex,
|
|
5182
|
+
dukeAnchor: { ...control.anchor },
|
|
5183
|
+
editAs: control.anchor.editAs,
|
|
5184
|
+
hidden: false,
|
|
5185
|
+
id: `form-control-${workbookSheetIndex}-${controlIndex}`,
|
|
5186
|
+
locked: control.locked,
|
|
5187
|
+
name: control.name,
|
|
5188
|
+
printable: control.printable,
|
|
5189
|
+
sheetIndex: workbookSheetIndex,
|
|
5190
|
+
workbookSheetIndex,
|
|
5191
|
+
zIndex: controlIndex + 1,
|
|
5192
|
+
...mapDukeFormControlKind(control.kind)
|
|
5193
|
+
};
|
|
5194
|
+
}
|
|
5195
|
+
function collectWorkbookFormControls(workbook) {
|
|
5196
|
+
return Array.from({ length: workbook.sheetCount }, (_, workbookSheetIndex) => {
|
|
5197
|
+
try {
|
|
5198
|
+
const controls = workbook.getSheet(workbookSheetIndex).formControls;
|
|
5199
|
+
return Array.isArray(controls) ? controls.map((control, controlIndex) => mapDukeFormControl(control, controlIndex, workbookSheetIndex)) : [];
|
|
5200
|
+
} catch {
|
|
5201
|
+
return [];
|
|
5202
|
+
}
|
|
5203
|
+
});
|
|
5204
|
+
}
|
|
5088
5205
|
function parseFormControlKind(rawType) {
|
|
5089
5206
|
const normalized = (rawType ?? "").trim().toLowerCase();
|
|
5090
5207
|
switch (normalized) {
|
|
@@ -5850,27 +5967,10 @@ function parseSheetFormControlNodes(archive, sheetPath) {
|
|
|
5850
5967
|
}
|
|
5851
5968
|
return getLocalElements(sheetDocument, "control").map((controlNode) => ({
|
|
5852
5969
|
anchor: parseAnchor(getFirstDescendant(controlNode, "anchor") ?? controlNode),
|
|
5853
|
-
controlRelationshipId: getRelationshipId(controlNode),
|
|
5854
5970
|
name: controlNode.getAttribute("name") ?? void 0,
|
|
5855
5971
|
shapeId: parseFormControlShapeId(controlNode.getAttribute("shapeId"))
|
|
5856
5972
|
}));
|
|
5857
5973
|
}
|
|
5858
|
-
function parseCtrlPropDocument(archive, ctrlPropPath) {
|
|
5859
|
-
const xml = readArchiveText2(archive, ctrlPropPath);
|
|
5860
|
-
if (!xml) {
|
|
5861
|
-
return null;
|
|
5862
|
-
}
|
|
5863
|
-
const document2 = parseXml2(xml);
|
|
5864
|
-
const root = document2?.documentElement;
|
|
5865
|
-
if (!root) {
|
|
5866
|
-
return null;
|
|
5867
|
-
}
|
|
5868
|
-
return {
|
|
5869
|
-
checked: parseSpreadsheetBooleanValue(root.getAttribute("checked")),
|
|
5870
|
-
linkedCell: root.getAttribute("fmlaLink") ?? void 0,
|
|
5871
|
-
objectType: root.getAttribute("objectType") ?? void 0
|
|
5872
|
-
};
|
|
5873
|
-
}
|
|
5874
5974
|
function parseVmlFormControls(archive, vmlDrawingPath) {
|
|
5875
5975
|
const xml = readArchiveText2(archive, vmlDrawingPath);
|
|
5876
5976
|
if (!xml) {
|
|
@@ -5928,21 +6028,18 @@ function parseSheetFormControls(archive, sheetPath, sheetRelationships, workbook
|
|
|
5928
6028
|
if (!controlNode.anchor) {
|
|
5929
6029
|
return;
|
|
5930
6030
|
}
|
|
5931
|
-
const ctrlPropRelationship = controlNode.controlRelationshipId ? sheetRelationships.get(controlNode.controlRelationshipId) ?? null : null;
|
|
5932
|
-
const ctrlPropPath = ctrlPropRelationship?.type === CTRL_PROP_REL_TYPE ? ctrlPropRelationship.target : null;
|
|
5933
|
-
const ctrlProp = ctrlPropPath ? parseCtrlPropDocument(archive, ctrlPropPath) : null;
|
|
5934
6031
|
const vmlControl = controlNode.shapeId !== null ? vmlControlsByShapeId.get(controlNode.shapeId) ?? null : null;
|
|
5935
|
-
const kind = parseFormControlKind(
|
|
6032
|
+
const kind = parseFormControlKind(vmlControl?.objectType);
|
|
5936
6033
|
parsedControls.push({
|
|
5937
6034
|
anchor: controlNode.anchor,
|
|
5938
|
-
checked:
|
|
6035
|
+
checked: vmlControl?.checked,
|
|
5939
6036
|
fontFamily: vmlControl?.fontFamily,
|
|
5940
6037
|
fontSizePt: vmlControl?.fontSizePt,
|
|
5941
6038
|
hidden: vmlControl?.hidden ?? false,
|
|
5942
6039
|
id: `form-control-${workbookSheetIndex}-${index}`,
|
|
5943
6040
|
kind,
|
|
5944
6041
|
label: vmlControl?.label,
|
|
5945
|
-
linkedCell:
|
|
6042
|
+
linkedCell: vmlControl?.linkedCell,
|
|
5946
6043
|
name: controlNode.name,
|
|
5947
6044
|
sheetIndex: workbookSheetIndex,
|
|
5948
6045
|
textAlign: vmlControl?.textAlign,
|
|
@@ -6028,6 +6125,92 @@ function enrichFormControlsWithHiddenShapes(formControls, shapes, sheetState) {
|
|
|
6028
6125
|
};
|
|
6029
6126
|
});
|
|
6030
6127
|
}
|
|
6128
|
+
function getFormControlAnchorStart(anchor) {
|
|
6129
|
+
return anchor.kind === "absolute" ? null : { col: anchor.from.col, row: anchor.from.row };
|
|
6130
|
+
}
|
|
6131
|
+
function scoreParsedFormControlMatch(dukeControl, parsedControl, parsedIndex) {
|
|
6132
|
+
if (dukeControl.kind !== parsedControl.kind && parsedControl.kind !== "unknown") {
|
|
6133
|
+
return Number.NEGATIVE_INFINITY;
|
|
6134
|
+
}
|
|
6135
|
+
let score = 10;
|
|
6136
|
+
const dukeName = normalizeControlLabel(dukeControl.name)?.toLowerCase();
|
|
6137
|
+
const parsedName = normalizeControlLabel(parsedControl.name)?.toLowerCase();
|
|
6138
|
+
if (dukeName && parsedName) {
|
|
6139
|
+
if (dukeName !== parsedName) {
|
|
6140
|
+
return Number.NEGATIVE_INFINITY;
|
|
6141
|
+
}
|
|
6142
|
+
score += 100;
|
|
6143
|
+
}
|
|
6144
|
+
const dukeStart = getFormControlAnchorStart(dukeControl.anchor);
|
|
6145
|
+
const parsedStart = getFormControlAnchorStart(parsedControl.anchor);
|
|
6146
|
+
if (dukeStart && parsedStart && dukeStart.col === parsedStart.col && dukeStart.row === parsedStart.row) {
|
|
6147
|
+
score += 40;
|
|
6148
|
+
}
|
|
6149
|
+
if (dukeControl.controlIndex === parsedIndex) {
|
|
6150
|
+
score += 5;
|
|
6151
|
+
}
|
|
6152
|
+
return score;
|
|
6153
|
+
}
|
|
6154
|
+
function areDukeFormControlAnchorsEqual(left, right) {
|
|
6155
|
+
if (!left || !right) {
|
|
6156
|
+
return true;
|
|
6157
|
+
}
|
|
6158
|
+
return left.editAs === right.editAs && left.fromCol === right.fromCol && left.fromColOffset === right.fromColOffset && left.fromRow === right.fromRow && left.fromRowOffset === right.fromRowOffset && left.toCol === right.toCol && left.toColOffset === right.toColOffset && left.toRow === right.toRow && left.toRowOffset === right.toRowOffset;
|
|
6159
|
+
}
|
|
6160
|
+
function mergeDukeAndParsedFormControls(dukeControls, parsedControls, keepUnmatchedParsedControl = () => true) {
|
|
6161
|
+
const usedParsedIndexes = /* @__PURE__ */ new Set();
|
|
6162
|
+
const mergedControls = dukeControls.map((dukeControl) => {
|
|
6163
|
+
let bestIndex = -1;
|
|
6164
|
+
let bestScore = Number.NEGATIVE_INFINITY;
|
|
6165
|
+
parsedControls.forEach((parsedControl2, parsedIndex) => {
|
|
6166
|
+
if (usedParsedIndexes.has(parsedIndex)) {
|
|
6167
|
+
return;
|
|
6168
|
+
}
|
|
6169
|
+
const score = scoreParsedFormControlMatch(dukeControl, parsedControl2, parsedIndex);
|
|
6170
|
+
if (score > bestScore) {
|
|
6171
|
+
bestIndex = parsedIndex;
|
|
6172
|
+
bestScore = score;
|
|
6173
|
+
}
|
|
6174
|
+
});
|
|
6175
|
+
const parsedControl = bestIndex >= 0 && bestScore >= 10 ? parsedControls[bestIndex] : null;
|
|
6176
|
+
if (!parsedControl) {
|
|
6177
|
+
return dukeControl;
|
|
6178
|
+
}
|
|
6179
|
+
usedParsedIndexes.add(bestIndex);
|
|
6180
|
+
const dukeAnchorChanged = !areDukeFormControlAnchorsEqual(
|
|
6181
|
+
parsedControl.dukeAnchor,
|
|
6182
|
+
dukeControl.dukeAnchor
|
|
6183
|
+
);
|
|
6184
|
+
return {
|
|
6185
|
+
...parsedControl,
|
|
6186
|
+
...dukeControl,
|
|
6187
|
+
anchor: dukeAnchorChanged ? dukeControl.anchor : parsedControl.anchor,
|
|
6188
|
+
fontFamily: parsedControl.fontFamily,
|
|
6189
|
+
fontSizePt: parsedControl.fontSizePt,
|
|
6190
|
+
hidden: parsedControl.hidden,
|
|
6191
|
+
id: parsedControl.id,
|
|
6192
|
+
label: dukeControl.label ?? parsedControl.label,
|
|
6193
|
+
name: dukeControl.name ?? parsedControl.name,
|
|
6194
|
+
textAlign: parsedControl.textAlign,
|
|
6195
|
+
textColor: parsedControl.textColor,
|
|
6196
|
+
zIndex: parsedControl.zIndex
|
|
6197
|
+
};
|
|
6198
|
+
});
|
|
6199
|
+
parsedControls.forEach((parsedControl, parsedIndex) => {
|
|
6200
|
+
if (!usedParsedIndexes.has(parsedIndex) && keepUnmatchedParsedControl(parsedControl)) {
|
|
6201
|
+
mergedControls.push(parsedControl);
|
|
6202
|
+
}
|
|
6203
|
+
});
|
|
6204
|
+
return mergedControls.sort((left, right) => left.zIndex - right.zIndex);
|
|
6205
|
+
}
|
|
6206
|
+
function refreshWorkbookFormControls(workbook, currentControlsByWorkbookSheetIndex) {
|
|
6207
|
+
const dukeControlsByWorkbookSheetIndex = collectWorkbookFormControls(workbook);
|
|
6208
|
+
return dukeControlsByWorkbookSheetIndex.map((dukeControls, workbookSheetIndex) => mergeDukeAndParsedFormControls(
|
|
6209
|
+
dukeControls,
|
|
6210
|
+
currentControlsByWorkbookSheetIndex[workbookSheetIndex] ?? [],
|
|
6211
|
+
(control) => control.controlIndex === void 0
|
|
6212
|
+
));
|
|
6213
|
+
}
|
|
6031
6214
|
function revokeWorkbookImageAssets(assets) {
|
|
6032
6215
|
if (!assets) {
|
|
6033
6216
|
return;
|
|
@@ -6060,7 +6243,7 @@ function parseWorkbookStructureAssetsFromArchive(archive, options) {
|
|
|
6060
6243
|
workbookSheets
|
|
6061
6244
|
};
|
|
6062
6245
|
}
|
|
6063
|
-
function parseWorkbookImageAssets(bytes) {
|
|
6246
|
+
function parseWorkbookImageAssets(bytes, workbookOrFormControls) {
|
|
6064
6247
|
const archive = (0, import_fflate2.unzipSync)(bytes);
|
|
6065
6248
|
const {
|
|
6066
6249
|
contentTypes,
|
|
@@ -6079,6 +6262,7 @@ function parseWorkbookImageAssets(bytes) {
|
|
|
6079
6262
|
const shapesByWorkbookSheetIndex = [];
|
|
6080
6263
|
const sheetOrigins = [];
|
|
6081
6264
|
const imageOriginsById = /* @__PURE__ */ new Map();
|
|
6265
|
+
const dukeFormControlsByWorkbookSheetIndex = Array.isArray(workbookOrFormControls) ? workbookOrFormControls : collectWorkbookFormControls(workbookOrFormControls);
|
|
6082
6266
|
workbookSheets.forEach((sheet, workbookSheetIndex) => {
|
|
6083
6267
|
const sheetRelationships = parseRelationships(archive, relsPathForDocument(sheet.path), sheet.path);
|
|
6084
6268
|
const attachments = [];
|
|
@@ -6124,7 +6308,10 @@ function parseWorkbookImageAssets(bytes) {
|
|
|
6124
6308
|
shapeList,
|
|
6125
6309
|
sheetStatesByWorkbookSheetIndex[workbookSheetIndex] ?? null
|
|
6126
6310
|
);
|
|
6127
|
-
formControlsByWorkbookSheetIndex[workbookSheetIndex] =
|
|
6311
|
+
formControlsByWorkbookSheetIndex[workbookSheetIndex] = mergeDukeAndParsedFormControls(
|
|
6312
|
+
dukeFormControlsByWorkbookSheetIndex[workbookSheetIndex] ?? [],
|
|
6313
|
+
enrichedFormControlList
|
|
6314
|
+
);
|
|
6128
6315
|
imagesByWorkbookSheetIndex[workbookSheetIndex] = imageList;
|
|
6129
6316
|
shapesByWorkbookSheetIndex[workbookSheetIndex] = visibleShapeList;
|
|
6130
6317
|
sheetOrigins[workbookSheetIndex] = attachments.length > 0 ? {
|
|
@@ -7199,6 +7386,144 @@ function parseA1RangeReference2(reference) {
|
|
|
7199
7386
|
}
|
|
7200
7387
|
return normalizeRange({ start, end });
|
|
7201
7388
|
}
|
|
7389
|
+
function resolveWorkbookReference(workbook, defaultWorkbookSheetIndex, rawReference, resolvingNamedRange = false) {
|
|
7390
|
+
const reference = rawReference.trim().replace(/^=/, "");
|
|
7391
|
+
if (!reference) {
|
|
7392
|
+
return null;
|
|
7393
|
+
}
|
|
7394
|
+
let workbookSheetIndex = defaultWorkbookSheetIndex;
|
|
7395
|
+
let rangeReference = reference;
|
|
7396
|
+
const bangIndex = reference.lastIndexOf("!");
|
|
7397
|
+
if (bangIndex >= 0) {
|
|
7398
|
+
let sheetName = reference.slice(0, bangIndex).trim();
|
|
7399
|
+
rangeReference = reference.slice(bangIndex + 1).trim();
|
|
7400
|
+
if (sheetName.startsWith("'") && sheetName.endsWith("'")) {
|
|
7401
|
+
sheetName = sheetName.slice(1, -1).replace(/''/g, "'");
|
|
7402
|
+
}
|
|
7403
|
+
const resolvedSheetIndex = workbook.sheetIndex(sheetName);
|
|
7404
|
+
if (resolvedSheetIndex === void 0) {
|
|
7405
|
+
return null;
|
|
7406
|
+
}
|
|
7407
|
+
workbookSheetIndex = resolvedSheetIndex;
|
|
7408
|
+
} else if (!resolvingNamedRange) {
|
|
7409
|
+
const namedRange = workbook.getNamedRange(reference);
|
|
7410
|
+
if (namedRange) {
|
|
7411
|
+
return resolveWorkbookReference(workbook, defaultWorkbookSheetIndex, namedRange, true);
|
|
7412
|
+
}
|
|
7413
|
+
}
|
|
7414
|
+
const range = parseA1RangeReference2(rangeReference.replace(/\$/g, ""));
|
|
7415
|
+
if (!range || workbookSheetIndex < 0 || workbookSheetIndex >= workbook.sheetCount) {
|
|
7416
|
+
return null;
|
|
7417
|
+
}
|
|
7418
|
+
try {
|
|
7419
|
+
return {
|
|
7420
|
+
range,
|
|
7421
|
+
workbookSheetIndex,
|
|
7422
|
+
worksheet: workbook.getSheet(workbookSheetIndex)
|
|
7423
|
+
};
|
|
7424
|
+
} catch {
|
|
7425
|
+
return null;
|
|
7426
|
+
}
|
|
7427
|
+
}
|
|
7428
|
+
function formControlInputFromDukeControl(control) {
|
|
7429
|
+
return {
|
|
7430
|
+
anchor: { ...control.anchor },
|
|
7431
|
+
kind: { ...control.kind },
|
|
7432
|
+
locked: control.locked,
|
|
7433
|
+
name: control.name,
|
|
7434
|
+
printable: control.printable
|
|
7435
|
+
};
|
|
7436
|
+
}
|
|
7437
|
+
function getFormControlCellLink(kind) {
|
|
7438
|
+
return "cellLink" in kind ? kind.cellLink : void 0;
|
|
7439
|
+
}
|
|
7440
|
+
function anchorContainsControl(group, control) {
|
|
7441
|
+
const groupAnchor = group.anchor;
|
|
7442
|
+
const controlAnchor = control.anchor;
|
|
7443
|
+
return controlAnchor.fromCol >= groupAnchor.fromCol && controlAnchor.fromCol <= groupAnchor.toCol && controlAnchor.fromRow >= groupAnchor.fromRow && controlAnchor.fromRow <= groupAnchor.toRow;
|
|
7444
|
+
}
|
|
7445
|
+
function resolveOptionButtonGroupIndexes(controls, targetIndex) {
|
|
7446
|
+
const target = controls[targetIndex];
|
|
7447
|
+
if (!target || target.kind.kind !== "optionButton") {
|
|
7448
|
+
return [];
|
|
7449
|
+
}
|
|
7450
|
+
if (target.kind.cellLink) {
|
|
7451
|
+
const targetCellLink = target.kind.cellLink;
|
|
7452
|
+
return controls.flatMap((control, index) => control.kind.kind === "optionButton" && control.kind.cellLink === targetCellLink ? [index] : []);
|
|
7453
|
+
}
|
|
7454
|
+
const containingGroups = controls.map((control, index) => ({ control, index })).filter(({ control }) => control.kind.kind === "groupBox" && anchorContainsControl(control, target)).sort((left, right) => {
|
|
7455
|
+
const leftArea = (left.control.anchor.toCol - left.control.anchor.fromCol) * (left.control.anchor.toRow - left.control.anchor.fromRow);
|
|
7456
|
+
const rightArea = (right.control.anchor.toCol - right.control.anchor.fromCol) * (right.control.anchor.toRow - right.control.anchor.fromRow);
|
|
7457
|
+
return leftArea - rightArea;
|
|
7458
|
+
});
|
|
7459
|
+
const containingGroup = containingGroups[0]?.control;
|
|
7460
|
+
if (containingGroup) {
|
|
7461
|
+
return controls.flatMap((control, index) => control.kind.kind === "optionButton" && anchorContainsControl(containingGroup, control) ? [index] : []);
|
|
7462
|
+
}
|
|
7463
|
+
const optionIndexes = controls.flatMap((control, index) => control.kind.kind === "optionButton" ? [index] : []);
|
|
7464
|
+
const targetPosition = optionIndexes.indexOf(targetIndex);
|
|
7465
|
+
if (targetPosition < 0) {
|
|
7466
|
+
return [];
|
|
7467
|
+
}
|
|
7468
|
+
let startPosition = targetPosition;
|
|
7469
|
+
while (startPosition > 0) {
|
|
7470
|
+
const control = controls[optionIndexes[startPosition] ?? -1];
|
|
7471
|
+
if (control?.kind.kind === "optionButton" && control.kind.firstInGroup) {
|
|
7472
|
+
break;
|
|
7473
|
+
}
|
|
7474
|
+
startPosition -= 1;
|
|
7475
|
+
}
|
|
7476
|
+
let endPosition = targetPosition + 1;
|
|
7477
|
+
while (endPosition < optionIndexes.length) {
|
|
7478
|
+
const control = controls[optionIndexes[endPosition] ?? -1];
|
|
7479
|
+
if (control?.kind.kind === "optionButton" && control.kind.firstInGroup) {
|
|
7480
|
+
break;
|
|
7481
|
+
}
|
|
7482
|
+
endPosition += 1;
|
|
7483
|
+
}
|
|
7484
|
+
return optionIndexes.slice(startPosition, endPosition);
|
|
7485
|
+
}
|
|
7486
|
+
function resolveLinkedCellValue(controls, controlIndex) {
|
|
7487
|
+
const control = controls[controlIndex];
|
|
7488
|
+
if (!control) {
|
|
7489
|
+
return void 0;
|
|
7490
|
+
}
|
|
7491
|
+
switch (control.kind.kind) {
|
|
7492
|
+
case "checkbox":
|
|
7493
|
+
return control.kind.state === "mixed" ? "#N/A" : control.kind.state === "checked";
|
|
7494
|
+
case "optionButton": {
|
|
7495
|
+
const groupIndexes = resolveOptionButtonGroupIndexes(controls, controlIndex);
|
|
7496
|
+
const checkedIndex = groupIndexes.find((index) => controls[index]?.kind.kind === "optionButton" && controls[index]?.kind.state === "checked");
|
|
7497
|
+
const groupPosition = checkedIndex === void 0 ? -1 : groupIndexes.indexOf(checkedIndex);
|
|
7498
|
+
return groupPosition >= 0 ? groupPosition + 1 : "";
|
|
7499
|
+
}
|
|
7500
|
+
case "dropdown":
|
|
7501
|
+
return control.kind.selected === void 0 ? "" : control.kind.selected + 1;
|
|
7502
|
+
case "listBox":
|
|
7503
|
+
return control.kind.selection === "single" && control.kind.selected.length === 1 ? (control.kind.selected[0] ?? -1) + 1 : "";
|
|
7504
|
+
case "scrollbar":
|
|
7505
|
+
case "spinner":
|
|
7506
|
+
return control.kind.value;
|
|
7507
|
+
default:
|
|
7508
|
+
return void 0;
|
|
7509
|
+
}
|
|
7510
|
+
}
|
|
7511
|
+
function syncFormControlLinkedCell(workbook, workbookSheetIndex, controls, controlIndex) {
|
|
7512
|
+
const control = controls[controlIndex];
|
|
7513
|
+
if (!control) {
|
|
7514
|
+
return;
|
|
7515
|
+
}
|
|
7516
|
+
const cellLink = getFormControlCellLink(control.kind);
|
|
7517
|
+
const value = resolveLinkedCellValue(controls, controlIndex);
|
|
7518
|
+
if (!cellLink || value === void 0) {
|
|
7519
|
+
return;
|
|
7520
|
+
}
|
|
7521
|
+
const target = resolveWorkbookReference(workbook, workbookSheetIndex, cellLink);
|
|
7522
|
+
if (!target || target.range.start.row !== target.range.end.row || target.range.start.col !== target.range.end.col) {
|
|
7523
|
+
return;
|
|
7524
|
+
}
|
|
7525
|
+
target.worksheet.setCell(cellAddressToA1(target.range.start), value);
|
|
7526
|
+
}
|
|
7202
7527
|
function parseWorksheetFreezePanes(worksheet) {
|
|
7203
7528
|
const rawFreezePanes = worksheet.freezePanes;
|
|
7204
7529
|
const row = typeof rawFreezePanes?.row === "number" && rawFreezePanes.row >= 0 ? rawFreezePanes.row : null;
|
|
@@ -7965,7 +8290,7 @@ function createBasicWorkbookAssets(workbook) {
|
|
|
7965
8290
|
const objectUrls = [];
|
|
7966
8291
|
return {
|
|
7967
8292
|
archive: {},
|
|
7968
|
-
formControlsByWorkbookSheetIndex:
|
|
8293
|
+
formControlsByWorkbookSheetIndex: collectWorkbookFormControls(workbook),
|
|
7969
8294
|
imageOriginsById: /* @__PURE__ */ new Map(),
|
|
7970
8295
|
imagesByWorkbookSheetIndex: collectWorksheetApiImages(workbook, objectUrls),
|
|
7971
8296
|
namedCellStyleByName: {},
|
|
@@ -7983,7 +8308,7 @@ function loadWorkbookImageAssets(bytes, workbook, skipXmlParsing = false) {
|
|
|
7983
8308
|
if (shouldSkipXmlParsingForWorkbook(bytes, skipXmlParsing) || !isZipWorkbook(bytes)) {
|
|
7984
8309
|
return createBasicWorkbookAssets(workbook);
|
|
7985
8310
|
}
|
|
7986
|
-
const parsedAssets = parseWorkbookImageAssets(bytes);
|
|
8311
|
+
const parsedAssets = parseWorkbookImageAssets(bytes, workbook);
|
|
7987
8312
|
const apiImagesByWorkbookSheetIndex = collectWorksheetApiImages(workbook, parsedAssets.objectUrls);
|
|
7988
8313
|
const imagesByWorkbookSheetIndex = Array.from(
|
|
7989
8314
|
{ length: Math.max(workbook.sheetCount, parsedAssets.imagesByWorkbookSheetIndex.length, apiImagesByWorkbookSheetIndex.length) },
|
|
@@ -8300,6 +8625,12 @@ function useXlsxViewerController(options) {
|
|
|
8300
8625
|
};
|
|
8301
8626
|
}, [skipXmlParsing]);
|
|
8302
8627
|
const refreshWorkbookState = React.useCallback((targetWorkbook) => {
|
|
8628
|
+
const currentFormControls = imageAssetsRef.current?.formControlsByWorkbookSheetIndex ?? [];
|
|
8629
|
+
const nextFormControls = refreshWorkbookFormControls(targetWorkbook, currentFormControls);
|
|
8630
|
+
if (imageAssetsRef.current) {
|
|
8631
|
+
imageAssetsRef.current.formControlsByWorkbookSheetIndex = nextFormControls;
|
|
8632
|
+
}
|
|
8633
|
+
setFormControlsByWorkbookSheetIndex(nextFormControls);
|
|
8303
8634
|
const nextSheets = buildSheetList(
|
|
8304
8635
|
targetWorkbook,
|
|
8305
8636
|
imageAssetsRef.current?.sheetStatesByWorkbookSheetIndex,
|
|
@@ -8421,12 +8752,24 @@ function useXlsxViewerController(options) {
|
|
|
8421
8752
|
if (!effectiveSkipXmlParsing && hasIncompleteWorkerChartSnapshot(snapshot)) {
|
|
8422
8753
|
throw new Error("Worker chart payload incomplete");
|
|
8423
8754
|
}
|
|
8755
|
+
const workerImageAssets = effectiveSkipXmlParsing ? null : parseWorkbookImageAssets(
|
|
8756
|
+
new Uint8Array(buffer),
|
|
8757
|
+
snapshot.formControlsByWorkbookSheetIndex
|
|
8758
|
+
);
|
|
8759
|
+
if (!isCurrent || abortController.signal.aborted) {
|
|
8760
|
+
revokeWorkbookImageAssets(workerImageAssets);
|
|
8761
|
+
return;
|
|
8762
|
+
}
|
|
8763
|
+
setImageAssets(workerImageAssets);
|
|
8424
8764
|
setWorkbook(null);
|
|
8425
8765
|
setSheets(snapshot.sheets);
|
|
8426
8766
|
setChartsByWorkbookSheetIndex(snapshot.chartsByWorkbookSheetIndex);
|
|
8427
8767
|
setChartsheets(snapshot.chartsheets);
|
|
8428
8768
|
setTabs(snapshot.tabs);
|
|
8429
8769
|
chartAssetsRef.current = null;
|
|
8770
|
+
if (!workerImageAssets) {
|
|
8771
|
+
setFormControlsByWorkbookSheetIndex(snapshot.formControlsByWorkbookSheetIndex);
|
|
8772
|
+
}
|
|
8430
8773
|
setWorkerTablesByWorkbookSheetIndex(snapshot.tablesByWorkbookSheetIndex);
|
|
8431
8774
|
setShouldAutoCalculate(false);
|
|
8432
8775
|
setIsWorkerBacked(true);
|
|
@@ -8646,6 +8989,7 @@ function useXlsxViewerController(options) {
|
|
|
8646
8989
|
setChartsheets(snapshot.chartsheets);
|
|
8647
8990
|
setTabs(snapshot.tabs);
|
|
8648
8991
|
chartAssetsRef.current = null;
|
|
8992
|
+
setFormControlsByWorkbookSheetIndex(snapshot.formControlsByWorkbookSheetIndex);
|
|
8649
8993
|
setWorkerTablesByWorkbookSheetIndex(snapshot.tablesByWorkbookSheetIndex);
|
|
8650
8994
|
setShouldAutoCalculate(false);
|
|
8651
8995
|
setIsWorkerBacked(true);
|
|
@@ -8767,6 +9111,20 @@ function useXlsxViewerController(options) {
|
|
|
8767
9111
|
}
|
|
8768
9112
|
return workbook.getSheet(activeSheet.workbookSheetIndex);
|
|
8769
9113
|
}, [activeSheet, workbook]);
|
|
9114
|
+
const getFormControlWorksheet = React.useCallback((sheetIndex = activeSheetIndex) => {
|
|
9115
|
+
const targetSheet = sheets[sheetIndex];
|
|
9116
|
+
if (!workbook || !targetSheet) {
|
|
9117
|
+
return null;
|
|
9118
|
+
}
|
|
9119
|
+
try {
|
|
9120
|
+
return {
|
|
9121
|
+
workbookSheetIndex: targetSheet.workbookSheetIndex,
|
|
9122
|
+
worksheet: workbook.getSheet(targetSheet.workbookSheetIndex)
|
|
9123
|
+
};
|
|
9124
|
+
} catch {
|
|
9125
|
+
return null;
|
|
9126
|
+
}
|
|
9127
|
+
}, [activeSheetIndex, sheets, workbook]);
|
|
8770
9128
|
const tables = React.useMemo(
|
|
8771
9129
|
() => isWorkerBacked ? workerTablesByWorkbookSheetIndex[activeSheet?.workbookSheetIndex ?? -1] ?? [] : mapWorksheetTables(getActiveWorksheet()),
|
|
8772
9130
|
[activeSheet?.workbookSheetIndex, getActiveWorksheet, isWorkerBacked, revision, workerTablesByWorkbookSheetIndex]
|
|
@@ -8906,6 +9264,33 @@ function useXlsxViewerController(options) {
|
|
|
8906
9264
|
return (formControlsByWorkbookSheetIndex[targetSheet.workbookSheetIndex] ?? []).map(mapPublicFormControl);
|
|
8907
9265
|
}, [activeSheetIndex, formControlsByWorkbookSheetIndex, mapPublicFormControl, sheets]);
|
|
8908
9266
|
const formControls = React.useMemo(() => getSheetFormControls(activeSheetIndex), [activeSheetIndex, getSheetFormControls]);
|
|
9267
|
+
const getFormControlItems = React.useCallback((controlIndex, sheetIndex = activeSheetIndex) => {
|
|
9268
|
+
const target = getFormControlWorksheet(sheetIndex);
|
|
9269
|
+
if (!workbook || !target) {
|
|
9270
|
+
const targetSheet = sheets[sheetIndex];
|
|
9271
|
+
if (!targetSheet) {
|
|
9272
|
+
return [];
|
|
9273
|
+
}
|
|
9274
|
+
const control2 = (formControlsByWorkbookSheetIndex[targetSheet.workbookSheetIndex] ?? []).find((entry) => entry.controlIndex === controlIndex);
|
|
9275
|
+
return control2?.items?.slice() ?? [];
|
|
9276
|
+
}
|
|
9277
|
+
const control = target.worksheet.formControls[controlIndex];
|
|
9278
|
+
const inputRange = control?.kind.kind === "listBox" || control?.kind.kind === "dropdown" ? control.kind.inputRange : void 0;
|
|
9279
|
+
if (!inputRange) {
|
|
9280
|
+
return [];
|
|
9281
|
+
}
|
|
9282
|
+
const source = resolveWorkbookReference(workbook, target.workbookSheetIndex, inputRange);
|
|
9283
|
+
if (!source) {
|
|
9284
|
+
return [];
|
|
9285
|
+
}
|
|
9286
|
+
const items = [];
|
|
9287
|
+
for (let row = source.range.start.row; row <= source.range.end.row; row += 1) {
|
|
9288
|
+
for (let col = source.range.start.col; col <= source.range.end.col; col += 1) {
|
|
9289
|
+
items.push(source.worksheet.getFormattedValueAt(row, col));
|
|
9290
|
+
}
|
|
9291
|
+
}
|
|
9292
|
+
return items;
|
|
9293
|
+
}, [activeSheetIndex, formControlsByWorkbookSheetIndex, getFormControlWorksheet, sheets, workbook]);
|
|
8909
9294
|
const getSheetShapes = React.useCallback((sheetIndex = activeSheetIndex) => {
|
|
8910
9295
|
const targetSheet = sheets[sheetIndex];
|
|
8911
9296
|
if (!targetSheet) {
|
|
@@ -9303,6 +9688,89 @@ function useXlsxViewerController(options) {
|
|
|
9303
9688
|
redoStackRef.current = [];
|
|
9304
9689
|
setHistoryRevision((current) => current + 1);
|
|
9305
9690
|
}, [createHistoryEntry]);
|
|
9691
|
+
const addFormControl = React.useCallback((input, sheetIndex = activeSheetIndex) => {
|
|
9692
|
+
const target = getFormControlWorksheet(sheetIndex);
|
|
9693
|
+
if (readOnly || !workbook || !target) {
|
|
9694
|
+
return null;
|
|
9695
|
+
}
|
|
9696
|
+
recordHistoryBeforeMutation();
|
|
9697
|
+
const controlIndex = target.worksheet.addFormControl(input);
|
|
9698
|
+
const controls = target.worksheet.formControls;
|
|
9699
|
+
const addedControl = controls[controlIndex];
|
|
9700
|
+
if (addedControl?.kind.kind === "optionButton" && addedControl.kind.state === "checked") {
|
|
9701
|
+
const groupIndexes = resolveOptionButtonGroupIndexes(controls, controlIndex);
|
|
9702
|
+
for (const siblingIndex of groupIndexes) {
|
|
9703
|
+
if (siblingIndex === controlIndex) {
|
|
9704
|
+
continue;
|
|
9705
|
+
}
|
|
9706
|
+
const sibling = target.worksheet.formControls[siblingIndex];
|
|
9707
|
+
if (sibling?.kind.kind === "optionButton" && sibling.kind.state !== "unchecked") {
|
|
9708
|
+
target.worksheet.setFormControl(siblingIndex, {
|
|
9709
|
+
...formControlInputFromDukeControl(sibling),
|
|
9710
|
+
kind: { ...sibling.kind, state: "unchecked" }
|
|
9711
|
+
});
|
|
9712
|
+
}
|
|
9713
|
+
}
|
|
9714
|
+
}
|
|
9715
|
+
syncFormControlLinkedCell(
|
|
9716
|
+
workbook,
|
|
9717
|
+
target.workbookSheetIndex,
|
|
9718
|
+
target.worksheet.formControls,
|
|
9719
|
+
controlIndex
|
|
9720
|
+
);
|
|
9721
|
+
maybeRecalculateWorkbook(workbook);
|
|
9722
|
+
refreshWorkbookState(workbook);
|
|
9723
|
+
return controlIndex;
|
|
9724
|
+
}, [activeSheetIndex, getFormControlWorksheet, maybeRecalculateWorkbook, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
9725
|
+
const updateFormControl = React.useCallback((controlIndex, patch, sheetIndex = activeSheetIndex) => {
|
|
9726
|
+
const target = getFormControlWorksheet(sheetIndex);
|
|
9727
|
+
const currentControl = target?.worksheet.formControls[controlIndex];
|
|
9728
|
+
if (readOnly || !workbook || !target || !currentControl) {
|
|
9729
|
+
return false;
|
|
9730
|
+
}
|
|
9731
|
+
recordHistoryBeforeMutation();
|
|
9732
|
+
const nextInput = {
|
|
9733
|
+
...formControlInputFromDukeControl(currentControl),
|
|
9734
|
+
...patch,
|
|
9735
|
+
anchor: patch.anchor ? { ...patch.anchor } : { ...currentControl.anchor },
|
|
9736
|
+
kind: patch.kind ? { ...patch.kind } : { ...currentControl.kind }
|
|
9737
|
+
};
|
|
9738
|
+
if (nextInput.kind.kind === "optionButton" && nextInput.kind.state === "checked") {
|
|
9739
|
+
const groupIndexes = resolveOptionButtonGroupIndexes(target.worksheet.formControls, controlIndex);
|
|
9740
|
+
for (const siblingIndex of groupIndexes) {
|
|
9741
|
+
if (siblingIndex === controlIndex) {
|
|
9742
|
+
continue;
|
|
9743
|
+
}
|
|
9744
|
+
const sibling = target.worksheet.formControls[siblingIndex];
|
|
9745
|
+
if (sibling?.kind.kind === "optionButton" && sibling.kind.state !== "unchecked") {
|
|
9746
|
+
target.worksheet.setFormControl(siblingIndex, {
|
|
9747
|
+
...formControlInputFromDukeControl(sibling),
|
|
9748
|
+
kind: { ...sibling.kind, state: "unchecked" }
|
|
9749
|
+
});
|
|
9750
|
+
}
|
|
9751
|
+
}
|
|
9752
|
+
}
|
|
9753
|
+
target.worksheet.setFormControl(controlIndex, nextInput);
|
|
9754
|
+
syncFormControlLinkedCell(
|
|
9755
|
+
workbook,
|
|
9756
|
+
target.workbookSheetIndex,
|
|
9757
|
+
target.worksheet.formControls,
|
|
9758
|
+
controlIndex
|
|
9759
|
+
);
|
|
9760
|
+
maybeRecalculateWorkbook(workbook);
|
|
9761
|
+
refreshWorkbookState(workbook);
|
|
9762
|
+
return true;
|
|
9763
|
+
}, [activeSheetIndex, getFormControlWorksheet, maybeRecalculateWorkbook, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
9764
|
+
const removeFormControl = React.useCallback((controlIndex, sheetIndex = activeSheetIndex) => {
|
|
9765
|
+
const target = getFormControlWorksheet(sheetIndex);
|
|
9766
|
+
if (readOnly || !workbook || !target || !target.worksheet.formControls[controlIndex]) {
|
|
9767
|
+
return false;
|
|
9768
|
+
}
|
|
9769
|
+
recordHistoryBeforeMutation();
|
|
9770
|
+
target.worksheet.removeFormControl(controlIndex);
|
|
9771
|
+
refreshWorkbookState(workbook);
|
|
9772
|
+
return true;
|
|
9773
|
+
}, [activeSheetIndex, getFormControlWorksheet, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
9306
9774
|
const recordCellEditHistory = React.useCallback((cell, before, after) => {
|
|
9307
9775
|
if (!activeSheet || isApplyingHistoryRef.current) {
|
|
9308
9776
|
return;
|
|
@@ -10111,8 +10579,15 @@ function useXlsxViewerController(options) {
|
|
|
10111
10579
|
}
|
|
10112
10580
|
workbook.addSheet(candidate);
|
|
10113
10581
|
sheetOriginsRef.current = [...sheetOriginsRef.current, null];
|
|
10582
|
+
setFormControlsByWorkbookSheetIndex((current) => [...current, []]);
|
|
10114
10583
|
setImagesByWorkbookSheetIndex((current) => [...current, []]);
|
|
10115
10584
|
setShapesByWorkbookSheetIndex((current) => [...current, []]);
|
|
10585
|
+
if (imageAssetsRef.current) {
|
|
10586
|
+
imageAssetsRef.current.formControlsByWorkbookSheetIndex = [
|
|
10587
|
+
...imageAssetsRef.current.formControlsByWorkbookSheetIndex,
|
|
10588
|
+
[]
|
|
10589
|
+
];
|
|
10590
|
+
}
|
|
10116
10591
|
const nextSheets = buildSheetList(
|
|
10117
10592
|
workbook,
|
|
10118
10593
|
imageAssetsRef.current?.sheetStatesByWorkbookSheetIndex,
|
|
@@ -10142,9 +10617,13 @@ function useXlsxViewerController(options) {
|
|
|
10142
10617
|
recordHistoryBeforeMutation();
|
|
10143
10618
|
workbook.removeSheet(activeSheet.workbookSheetIndex);
|
|
10144
10619
|
sheetOriginsRef.current = sheetOriginsRef.current.filter((_, index) => index !== activeSheet.workbookSheetIndex);
|
|
10620
|
+
setFormControlsByWorkbookSheetIndex((current) => current.filter((_, index) => index !== activeSheet.workbookSheetIndex));
|
|
10145
10621
|
setImagesByWorkbookSheetIndex((current) => current.filter((_, index) => index !== activeSheet.workbookSheetIndex));
|
|
10146
10622
|
setShapesByWorkbookSheetIndex((current) => current.filter((_, index) => index !== activeSheet.workbookSheetIndex));
|
|
10147
10623
|
if (imageAssetsRef.current) {
|
|
10624
|
+
imageAssetsRef.current.formControlsByWorkbookSheetIndex = imageAssetsRef.current.formControlsByWorkbookSheetIndex.filter(
|
|
10625
|
+
(_, index) => index !== activeSheet.workbookSheetIndex
|
|
10626
|
+
);
|
|
10148
10627
|
imageAssetsRef.current.sheetStatesByWorkbookSheetIndex = imageAssetsRef.current.sheetStatesByWorkbookSheetIndex.filter(
|
|
10149
10628
|
(_, index) => index !== activeSheet.workbookSheetIndex
|
|
10150
10629
|
);
|
|
@@ -10445,6 +10924,7 @@ function useXlsxViewerController(options) {
|
|
|
10445
10924
|
activeSheetIndex,
|
|
10446
10925
|
activeTab,
|
|
10447
10926
|
activeTabIndex,
|
|
10927
|
+
addFormControl,
|
|
10448
10928
|
addSheet,
|
|
10449
10929
|
canRedo,
|
|
10450
10930
|
canDownload: Boolean(file ?? src),
|
|
@@ -10484,6 +10964,7 @@ function useXlsxViewerController(options) {
|
|
|
10484
10964
|
getClipboardData,
|
|
10485
10965
|
getCellDisplayValue: getCellDisplayValue2,
|
|
10486
10966
|
getCellFormula,
|
|
10967
|
+
getFormControlItems,
|
|
10487
10968
|
getCellSnapshotAsync: isWorkerBacked ? getCellSnapshotAsync : void 0,
|
|
10488
10969
|
getActiveWorksheet,
|
|
10489
10970
|
getRowsBatchAsync: isWorkerBacked ? getRowsBatchAsync : void 0,
|
|
@@ -10501,6 +10982,7 @@ function useXlsxViewerController(options) {
|
|
|
10501
10982
|
pasteStructuredClipboardData,
|
|
10502
10983
|
pasteText,
|
|
10503
10984
|
removeActiveSheet,
|
|
10985
|
+
removeFormControl,
|
|
10504
10986
|
readOnly,
|
|
10505
10987
|
recalculate,
|
|
10506
10988
|
redo,
|
|
@@ -10551,6 +11033,7 @@ function useXlsxViewerController(options) {
|
|
|
10551
11033
|
undo,
|
|
10552
11034
|
unmergeSelection,
|
|
10553
11035
|
updateChart,
|
|
11036
|
+
updateFormControl,
|
|
10554
11037
|
workbook,
|
|
10555
11038
|
zoomIn,
|
|
10556
11039
|
zoomOut,
|
|
@@ -10563,6 +11046,7 @@ function useXlsxViewerController(options) {
|
|
|
10563
11046
|
activeSheetIndex,
|
|
10564
11047
|
activeTab,
|
|
10565
11048
|
activeTabIndex,
|
|
11049
|
+
addFormControl,
|
|
10566
11050
|
addSheet,
|
|
10567
11051
|
canLoadDeferred,
|
|
10568
11052
|
canRedo,
|
|
@@ -10599,6 +11083,7 @@ function useXlsxViewerController(options) {
|
|
|
10599
11083
|
getClipboardData,
|
|
10600
11084
|
getCellDisplayValue2,
|
|
10601
11085
|
getCellFormula,
|
|
11086
|
+
getFormControlItems,
|
|
10602
11087
|
getCellSnapshotAsync,
|
|
10603
11088
|
getActiveWorksheet,
|
|
10604
11089
|
historyRevision,
|
|
@@ -10616,6 +11101,7 @@ function useXlsxViewerController(options) {
|
|
|
10616
11101
|
pasteStructuredClipboardData,
|
|
10617
11102
|
pasteText,
|
|
10618
11103
|
removeActiveSheet,
|
|
11104
|
+
removeFormControl,
|
|
10619
11105
|
readOnly,
|
|
10620
11106
|
recalculate,
|
|
10621
11107
|
redo,
|
|
@@ -10666,6 +11152,7 @@ function useXlsxViewerController(options) {
|
|
|
10666
11152
|
undo,
|
|
10667
11153
|
unmergeSelection,
|
|
10668
11154
|
updateChart,
|
|
11155
|
+
updateFormControl,
|
|
10669
11156
|
workbook,
|
|
10670
11157
|
zoomIn,
|
|
10671
11158
|
zoomOut,
|
|
@@ -20338,6 +20825,40 @@ function getCellBooleanValue(worksheet, row, col) {
|
|
|
20338
20825
|
}
|
|
20339
20826
|
return null;
|
|
20340
20827
|
}
|
|
20828
|
+
function getBatchedCellNumericValue(cell) {
|
|
20829
|
+
if (!cell) {
|
|
20830
|
+
return null;
|
|
20831
|
+
}
|
|
20832
|
+
const text = cell.value.trim();
|
|
20833
|
+
if (text.length === 0) {
|
|
20834
|
+
return null;
|
|
20835
|
+
}
|
|
20836
|
+
if (text.toLowerCase() === "true") {
|
|
20837
|
+
return 1;
|
|
20838
|
+
}
|
|
20839
|
+
if (text.toLowerCase() === "false") {
|
|
20840
|
+
return 0;
|
|
20841
|
+
}
|
|
20842
|
+
const value = Number(text.replace(/,/g, ""));
|
|
20843
|
+
return Number.isFinite(value) ? value : null;
|
|
20844
|
+
}
|
|
20845
|
+
function getBatchedCellBooleanValue(cell) {
|
|
20846
|
+
if (!cell) {
|
|
20847
|
+
return null;
|
|
20848
|
+
}
|
|
20849
|
+
const text = cell.value.trim().toLowerCase();
|
|
20850
|
+
if (text.length === 0) {
|
|
20851
|
+
return null;
|
|
20852
|
+
}
|
|
20853
|
+
if (text === "true") {
|
|
20854
|
+
return true;
|
|
20855
|
+
}
|
|
20856
|
+
if (text === "false") {
|
|
20857
|
+
return false;
|
|
20858
|
+
}
|
|
20859
|
+
const value = Number(text);
|
|
20860
|
+
return Number.isFinite(value) ? value !== 0 : null;
|
|
20861
|
+
}
|
|
20341
20862
|
function parseA1RangeReference3(reference) {
|
|
20342
20863
|
const [startRef, endRef = startRef] = reference.split(":");
|
|
20343
20864
|
const start = parseA1CellReference3(startRef ?? "");
|
|
@@ -21637,13 +22158,90 @@ function renderConditionalIcon(icon, scale = 1) {
|
|
|
21637
22158
|
}
|
|
21638
22159
|
);
|
|
21639
22160
|
}
|
|
21640
|
-
function
|
|
22161
|
+
function isFormControlChecked(control) {
|
|
22162
|
+
return control.state ? control.state === "checked" : Boolean(control.checked);
|
|
22163
|
+
}
|
|
22164
|
+
function isFormControlMixed(control) {
|
|
22165
|
+
return control.state === "mixed";
|
|
22166
|
+
}
|
|
22167
|
+
function buildFormControlKindInput(control) {
|
|
22168
|
+
switch (control.kind) {
|
|
22169
|
+
case "button":
|
|
22170
|
+
return { caption: control.caption ?? control.label ?? "", kind: "button" };
|
|
22171
|
+
case "checkbox":
|
|
22172
|
+
return {
|
|
22173
|
+
caption: control.caption ?? control.label ?? "",
|
|
22174
|
+
cellLink: control.linkedCell,
|
|
22175
|
+
kind: "checkbox",
|
|
22176
|
+
no3D: control.no3D ?? false,
|
|
22177
|
+
state: control.state ?? (control.checked ? "checked" : "unchecked")
|
|
22178
|
+
};
|
|
22179
|
+
case "radio":
|
|
22180
|
+
return {
|
|
22181
|
+
caption: control.caption ?? control.label ?? "",
|
|
22182
|
+
cellLink: control.linkedCell,
|
|
22183
|
+
firstInGroup: control.firstInGroup,
|
|
22184
|
+
kind: "optionButton",
|
|
22185
|
+
no3D: control.no3D ?? false,
|
|
22186
|
+
state: control.state === "checked" ? "checked" : "unchecked"
|
|
22187
|
+
};
|
|
22188
|
+
case "label":
|
|
22189
|
+
return { caption: control.caption ?? control.label ?? "", kind: "label" };
|
|
22190
|
+
case "group-box":
|
|
22191
|
+
return {
|
|
22192
|
+
caption: control.caption ?? control.label ?? "",
|
|
22193
|
+
kind: "groupBox",
|
|
22194
|
+
no3D: control.no3D ?? false
|
|
22195
|
+
};
|
|
22196
|
+
case "listbox":
|
|
22197
|
+
return {
|
|
22198
|
+
cellLink: control.linkedCell,
|
|
22199
|
+
inputRange: control.inputRange,
|
|
22200
|
+
kind: "listBox",
|
|
22201
|
+
no3D: control.no3D ?? false,
|
|
22202
|
+
selected: Array.isArray(control.selected) ? control.selected : control.selected === void 0 ? [] : [control.selected],
|
|
22203
|
+
selection: control.selection ?? "single"
|
|
22204
|
+
};
|
|
22205
|
+
case "dropdown":
|
|
22206
|
+
return {
|
|
22207
|
+
cellLink: control.linkedCell,
|
|
22208
|
+
inputRange: control.inputRange,
|
|
22209
|
+
kind: "dropdown",
|
|
22210
|
+
lines: control.lines ?? 8,
|
|
22211
|
+
no3D: control.no3D ?? false,
|
|
22212
|
+
selected: typeof control.selected === "number" ? control.selected : void 0
|
|
22213
|
+
};
|
|
22214
|
+
case "scrollbar":
|
|
22215
|
+
return {
|
|
22216
|
+
cellLink: control.linkedCell,
|
|
22217
|
+
horizontal: control.horizontal ?? true,
|
|
22218
|
+
increment: control.increment ?? 1,
|
|
22219
|
+
kind: "scrollbar",
|
|
22220
|
+
max: control.max ?? 100,
|
|
22221
|
+
min: control.min ?? 0,
|
|
22222
|
+
page: control.page ?? 10,
|
|
22223
|
+
value: control.value ?? control.min ?? 0
|
|
22224
|
+
};
|
|
22225
|
+
case "spinner":
|
|
22226
|
+
return {
|
|
22227
|
+
cellLink: control.linkedCell,
|
|
22228
|
+
increment: control.increment ?? 1,
|
|
22229
|
+
kind: "spinner",
|
|
22230
|
+
max: control.max ?? 100,
|
|
22231
|
+
min: control.min ?? 0,
|
|
22232
|
+
value: control.value ?? control.min ?? 0
|
|
22233
|
+
};
|
|
22234
|
+
default:
|
|
22235
|
+
return null;
|
|
22236
|
+
}
|
|
22237
|
+
}
|
|
22238
|
+
function renderCheckboxControl(checked, palette, scale = 1, mixed = false) {
|
|
21641
22239
|
const stroke = paletteIsDark(palette) ? "#cbd5e1" : "#475569";
|
|
21642
|
-
const fill = checked ? paletteIsDark(palette) ? "#60a5fa" : "#2563eb" : "transparent";
|
|
22240
|
+
const fill = checked || mixed ? paletteIsDark(palette) ? "#60a5fa" : "#2563eb" : "transparent";
|
|
21643
22241
|
const check = paletteIsDark(palette) ? "#020617" : "#ffffff";
|
|
21644
22242
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { "aria-hidden": "true", height: 14 * scale, style: { display: "block" }, viewBox: "0 0 16 16", width: 14 * scale, children: [
|
|
21645
22243
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { fill, height: 11, rx: 2, ry: 2, stroke, strokeWidth: 1.2, width: 11, x: 2.5, y: 2.5 }),
|
|
21646
|
-
checked ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
22244
|
+
mixed ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M5 8h6", fill: "none", stroke: check, strokeLinecap: "round", strokeWidth: 1.8 }) : checked ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
21647
22245
|
"path",
|
|
21648
22246
|
{
|
|
21649
22247
|
d: "M5 8.1 7.1 10.2 11.3 5.8",
|
|
@@ -21813,6 +22411,8 @@ function drawStaticFormControl(context, control, rect, palette, zoomFactor, shee
|
|
|
21813
22411
|
const textColor = control.textColor ?? "#000000";
|
|
21814
22412
|
const fontSizePx = Math.max(9 * zoomFactor, (control.fontSizePt ?? 9) * 96 / 72 * zoomFactor);
|
|
21815
22413
|
const iconSize = Math.min(14 * zoomFactor, Math.max(0, rect.height - 4 * zoomFactor));
|
|
22414
|
+
const controlChecked = isFormControlChecked(control);
|
|
22415
|
+
const controlMixed = isFormControlMixed(control);
|
|
21816
22416
|
context.save();
|
|
21817
22417
|
context.font = `400 ${fontSizePx}px ${control.fontFamily ?? "Calibri, sans-serif"}`;
|
|
21818
22418
|
context.textBaseline = "middle";
|
|
@@ -21853,14 +22453,19 @@ function drawStaticFormControl(context, control, rect, palette, zoomFactor, shee
|
|
|
21853
22453
|
const textRightInset = control.kind === "dropdown" ? 18 * zoomFactor : 6 * zoomFactor;
|
|
21854
22454
|
if (control.kind === "checkbox") {
|
|
21855
22455
|
context.strokeRect(rect.left + 2 * zoomFactor, rect.top + (rect.height - iconSize) / 2, iconSize, iconSize);
|
|
21856
|
-
if (
|
|
22456
|
+
if (controlChecked || controlMixed) {
|
|
21857
22457
|
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
21858
22458
|
context.fillRect(rect.left + 2 * zoomFactor + 1.5, rect.top + (rect.height - iconSize) / 2 + 1.5, Math.max(0, iconSize - 3), Math.max(0, iconSize - 3));
|
|
21859
22459
|
context.strokeStyle = paletteIsDark(palette) ? "#020617" : "#ffffff";
|
|
21860
22460
|
context.beginPath();
|
|
21861
|
-
|
|
21862
|
-
|
|
21863
|
-
|
|
22461
|
+
if (controlMixed) {
|
|
22462
|
+
context.moveTo(rect.left + 2 * zoomFactor + iconSize * 0.25, rect.top + rect.height / 2);
|
|
22463
|
+
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.75, rect.top + rect.height / 2);
|
|
22464
|
+
} else {
|
|
22465
|
+
context.moveTo(rect.left + 2 * zoomFactor + iconSize * 0.24, rect.top + rect.height / 2 + iconSize * 0.06);
|
|
22466
|
+
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.45, rect.top + rect.height / 2 + iconSize * 0.26);
|
|
22467
|
+
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.8, rect.top + rect.height / 2 - iconSize * 0.2);
|
|
22468
|
+
}
|
|
21864
22469
|
context.stroke();
|
|
21865
22470
|
}
|
|
21866
22471
|
textLeft += iconSize + 4 * zoomFactor;
|
|
@@ -21868,7 +22473,7 @@ function drawStaticFormControl(context, control, rect, palette, zoomFactor, shee
|
|
|
21868
22473
|
context.beginPath();
|
|
21869
22474
|
context.arc(rect.left + 2 * zoomFactor + iconSize / 2, rect.top + rect.height / 2, iconSize / 2, 0, Math.PI * 2);
|
|
21870
22475
|
context.stroke();
|
|
21871
|
-
if (
|
|
22476
|
+
if (controlChecked) {
|
|
21872
22477
|
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
21873
22478
|
context.beginPath();
|
|
21874
22479
|
context.arc(rect.left + 2 * zoomFactor + iconSize / 2, rect.top + rect.height / 2, iconSize * 0.25, 0, Math.PI * 2);
|
|
@@ -22504,7 +23109,10 @@ function XlsxGrid({
|
|
|
22504
23109
|
getCellStyle,
|
|
22505
23110
|
loadingComponent,
|
|
22506
23111
|
loadingState,
|
|
23112
|
+
onFormControlAction,
|
|
23113
|
+
onFormControlChange,
|
|
22507
23114
|
renderChartLoading,
|
|
23115
|
+
renderFormControl,
|
|
22508
23116
|
palette,
|
|
22509
23117
|
renderImage,
|
|
22510
23118
|
renderImageSelection,
|
|
@@ -22541,6 +23149,7 @@ function XlsxGrid({
|
|
|
22541
23149
|
getRowsBatchAsync,
|
|
22542
23150
|
getClipboardData,
|
|
22543
23151
|
getCellDisplayValue: getControllerCellDisplayValue,
|
|
23152
|
+
getFormControlItems,
|
|
22544
23153
|
images,
|
|
22545
23154
|
shapes,
|
|
22546
23155
|
isLoadDeferred,
|
|
@@ -22578,9 +23187,13 @@ function XlsxGrid({
|
|
|
22578
23187
|
sortTable,
|
|
22579
23188
|
tables,
|
|
22580
23189
|
undo,
|
|
23190
|
+
updateFormControl,
|
|
22581
23191
|
workbook,
|
|
22582
23192
|
zoomScale
|
|
22583
23193
|
} = controller;
|
|
23194
|
+
const formControlItemsById = React4.useMemo(() => new Map(
|
|
23195
|
+
formControls.flatMap((control) => control.controlIndex !== void 0 && (control.kind === "dropdown" || control.kind === "listbox") ? [[control.id, getFormControlItems(control.controlIndex, control.sheetIndex)]] : [])
|
|
23196
|
+
), [formControls, getFormControlItems]);
|
|
22584
23197
|
const canResizeHeaders = !readOnly || allowResizeInReadOnly;
|
|
22585
23198
|
const scrollRef = React4.useRef(null);
|
|
22586
23199
|
const wrapperRef = React4.useRef(null);
|
|
@@ -25064,14 +25677,7 @@ function XlsxGrid({
|
|
|
25064
25677
|
() => shouldBakeCanvasStaticDrawings ? shapeRects.filter(({ shape }) => shape.hyperlink) : shapeRects,
|
|
25065
25678
|
[shapeRects, shouldBakeCanvasStaticDrawings]
|
|
25066
25679
|
);
|
|
25067
|
-
const
|
|
25068
|
-
() => shouldBakeCanvasStaticDrawings ? formControlRects : [],
|
|
25069
|
-
[formControlRects, shouldBakeCanvasStaticDrawings]
|
|
25070
|
-
);
|
|
25071
|
-
const domFormControlRects = React4.useMemo(
|
|
25072
|
-
() => shouldBakeCanvasStaticDrawings ? [] : formControlRects,
|
|
25073
|
-
[formControlRects, shouldBakeCanvasStaticDrawings]
|
|
25074
|
-
);
|
|
25680
|
+
const domFormControlRects = formControlRects;
|
|
25075
25681
|
const bakedImageRects = React4.useMemo(
|
|
25076
25682
|
() => shouldBakeCanvasImages ? imageRects.filter(({ image }) => !image.hyperlink && selectedImageId !== image.id) : [],
|
|
25077
25683
|
[imageRects, selectedImageId, shouldBakeCanvasImages]
|
|
@@ -25088,11 +25694,9 @@ function XlsxGrid({
|
|
|
25088
25694
|
return "";
|
|
25089
25695
|
}
|
|
25090
25696
|
const shapeSignature = bakedShapeRects.map(({ rect, shape }) => `s:${shape.id}:${shape.zIndex}:${Math.round(rect.left)}:${Math.round(rect.top)}:${Math.round(rect.width)}:${Math.round(rect.height)}`).join("|");
|
|
25091
|
-
const controlSignature = bakedFormControlRects.map(({ control, rect }) => `f:${control.id}:${control.zIndex}:${Boolean(control.checked)}:${Math.round(rect.left)}:${Math.round(rect.top)}:${Math.round(rect.width)}:${Math.round(rect.height)}`).join("|");
|
|
25092
25697
|
const imageSignature = bakedImageRects.map(({ image, rect }) => `i:${image.id}:${image.src}:${image.zIndex}:${Math.round(rect.left)}:${Math.round(rect.top)}:${Math.round(rect.width)}:${Math.round(rect.height)}`).join("|");
|
|
25093
|
-
return `${revision}:${canvasImageLoadVersion}:${shapeSignature}:${
|
|
25698
|
+
return `${revision}:${canvasImageLoadVersion}:${shapeSignature}:${imageSignature}`;
|
|
25094
25699
|
}, [
|
|
25095
|
-
bakedFormControlRects,
|
|
25096
25700
|
bakedImageRects,
|
|
25097
25701
|
bakedShapeRects,
|
|
25098
25702
|
canvasImageLoadVersion,
|
|
@@ -26627,12 +27231,6 @@ function XlsxGrid({
|
|
|
26627
27231
|
shape,
|
|
26628
27232
|
zIndex: shape.zIndex
|
|
26629
27233
|
})),
|
|
26630
|
-
...bakedFormControlRects.map(({ control, rect }) => ({
|
|
26631
|
-
control,
|
|
26632
|
-
kind: "formControl",
|
|
26633
|
-
rect,
|
|
26634
|
-
zIndex: control.zIndex
|
|
26635
|
-
})),
|
|
26636
27234
|
...bakedImageRects.map(({ image, rect }) => ({
|
|
26637
27235
|
image,
|
|
26638
27236
|
kind: "image",
|
|
@@ -26783,90 +27381,6 @@ function XlsxGrid({
|
|
|
26783
27381
|
drawBakedShapeText(context, shape, localLeft, localTop, rect.width, rect.height);
|
|
26784
27382
|
context.restore();
|
|
26785
27383
|
};
|
|
26786
|
-
const drawBakedFormControl = (context, control, rect) => {
|
|
26787
|
-
const label = resolveFormControlLabel(control);
|
|
26788
|
-
const stroke = paletteIsDark(palette) ? "#cbd5e1" : "#475569";
|
|
26789
|
-
const textColor = control.textColor ?? "#000000";
|
|
26790
|
-
const fontSizePx = Math.max(9 * zoomFactor, (control.fontSizePt ?? 9) * 96 / 72 * zoomFactor);
|
|
26791
|
-
const iconSize = Math.min(14 * zoomFactor, Math.max(0, rect.height - 4 * zoomFactor));
|
|
26792
|
-
context.save();
|
|
26793
|
-
context.font = `400 ${fontSizePx}px ${control.fontFamily ?? "Calibri, sans-serif"}`;
|
|
26794
|
-
context.textBaseline = "middle";
|
|
26795
|
-
context.fillStyle = textColor;
|
|
26796
|
-
context.strokeStyle = stroke;
|
|
26797
|
-
context.lineWidth = Math.max(1, zoomFactor);
|
|
26798
|
-
if (control.kind === "group-box") {
|
|
26799
|
-
const labelInset = label ? Math.max(7, fontSizePx * 0.5) : 0;
|
|
26800
|
-
drawCanvasRoundedRect(context, rect.left, rect.top + labelInset, rect.width, Math.max(0, rect.height - labelInset), 2 * zoomFactor);
|
|
26801
|
-
context.stroke();
|
|
26802
|
-
if (label) {
|
|
26803
|
-
context.fillStyle = SHEET_SURFACE;
|
|
26804
|
-
const labelWidth = Math.min(rect.width - 16 * zoomFactor, measureCanvasTextWidth(context, label) + 8 * zoomFactor);
|
|
26805
|
-
context.fillRect(rect.left + 8 * zoomFactor, rect.top, labelWidth, fontSizePx * 1.2);
|
|
26806
|
-
context.fillStyle = textColor;
|
|
26807
|
-
context.textAlign = "left";
|
|
26808
|
-
context.fillText(label, rect.left + 12 * zoomFactor, rect.top + fontSizePx * 0.55);
|
|
26809
|
-
}
|
|
26810
|
-
context.restore();
|
|
26811
|
-
return;
|
|
26812
|
-
}
|
|
26813
|
-
if (control.kind === "button" || control.kind === "dropdown" || control.kind === "editbox" || control.kind === "listbox" || control.kind === "scrollbar" || control.kind === "spinner" || control.kind === "unknown") {
|
|
26814
|
-
if (control.kind === "button") {
|
|
26815
|
-
const gradient = context.createLinearGradient(rect.left, rect.top, rect.left, rect.top + rect.height);
|
|
26816
|
-
gradient.addColorStop(0, "#f8fafc");
|
|
26817
|
-
gradient.addColorStop(1, "#e2e8f0");
|
|
26818
|
-
context.fillStyle = gradient;
|
|
26819
|
-
} else {
|
|
26820
|
-
context.fillStyle = "transparent";
|
|
26821
|
-
}
|
|
26822
|
-
drawCanvasRoundedRect(context, rect.left, rect.top, rect.width, rect.height, control.kind === "button" ? 4 * zoomFactor : 2 * zoomFactor);
|
|
26823
|
-
if (control.kind === "button") {
|
|
26824
|
-
context.fill();
|
|
26825
|
-
}
|
|
26826
|
-
context.stroke();
|
|
26827
|
-
}
|
|
26828
|
-
let textLeft = rect.left + 2 * zoomFactor;
|
|
26829
|
-
const textRightInset = control.kind === "dropdown" ? 18 * zoomFactor : 6 * zoomFactor;
|
|
26830
|
-
if (control.kind === "checkbox") {
|
|
26831
|
-
context.strokeRect(rect.left + 2 * zoomFactor, rect.top + (rect.height - iconSize) / 2, iconSize, iconSize);
|
|
26832
|
-
if (control.checked) {
|
|
26833
|
-
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
26834
|
-
context.fillRect(rect.left + 2 * zoomFactor + 1.5, rect.top + (rect.height - iconSize) / 2 + 1.5, Math.max(0, iconSize - 3), Math.max(0, iconSize - 3));
|
|
26835
|
-
context.strokeStyle = paletteIsDark(palette) ? "#020617" : "#ffffff";
|
|
26836
|
-
context.beginPath();
|
|
26837
|
-
context.moveTo(rect.left + 2 * zoomFactor + iconSize * 0.24, rect.top + rect.height / 2 + iconSize * 0.06);
|
|
26838
|
-
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.45, rect.top + rect.height / 2 + iconSize * 0.26);
|
|
26839
|
-
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.8, rect.top + rect.height / 2 - iconSize * 0.2);
|
|
26840
|
-
context.stroke();
|
|
26841
|
-
}
|
|
26842
|
-
textLeft += iconSize + 4 * zoomFactor;
|
|
26843
|
-
} else if (control.kind === "radio") {
|
|
26844
|
-
context.beginPath();
|
|
26845
|
-
context.arc(rect.left + 2 * zoomFactor + iconSize / 2, rect.top + rect.height / 2, iconSize / 2, 0, Math.PI * 2);
|
|
26846
|
-
context.stroke();
|
|
26847
|
-
if (control.checked) {
|
|
26848
|
-
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
26849
|
-
context.beginPath();
|
|
26850
|
-
context.arc(rect.left + 2 * zoomFactor + iconSize / 2, rect.top + rect.height / 2, iconSize * 0.25, 0, Math.PI * 2);
|
|
26851
|
-
context.fill();
|
|
26852
|
-
}
|
|
26853
|
-
textLeft += iconSize + 4 * zoomFactor;
|
|
26854
|
-
}
|
|
26855
|
-
if (label) {
|
|
26856
|
-
const maxTextWidth = Math.max(0, rect.left + rect.width - textLeft - textRightInset);
|
|
26857
|
-
const text = truncateCanvasText(context, label, maxTextWidth);
|
|
26858
|
-
context.fillStyle = textColor;
|
|
26859
|
-
context.textAlign = control.textAlign === "right" ? "right" : control.textAlign === "center" ? "center" : "left";
|
|
26860
|
-
const textX = context.textAlign === "right" ? rect.left + rect.width - textRightInset : context.textAlign === "center" ? textLeft + maxTextWidth / 2 : textLeft;
|
|
26861
|
-
context.fillText(text, textX, rect.top + rect.height / 2);
|
|
26862
|
-
}
|
|
26863
|
-
if (control.kind === "dropdown") {
|
|
26864
|
-
context.fillStyle = textColor;
|
|
26865
|
-
context.textAlign = "center";
|
|
26866
|
-
context.fillText("\u25BC", rect.left + rect.width - 10 * zoomFactor, rect.top + rect.height / 2);
|
|
26867
|
-
}
|
|
26868
|
-
context.restore();
|
|
26869
|
-
};
|
|
26870
27384
|
const drawBakedCanvasDrawings = (pane, context, dirtyRects) => {
|
|
26871
27385
|
if (bakedCanvasDrawingEntries.length === 0 || dirtyRects.length === 0) {
|
|
26872
27386
|
return;
|
|
@@ -26881,8 +27395,6 @@ function XlsxGrid({
|
|
|
26881
27395
|
}
|
|
26882
27396
|
if (entry.kind === "shape") {
|
|
26883
27397
|
drawBakedShape(context, entry.shape, localRect);
|
|
26884
|
-
} else if (entry.kind === "formControl") {
|
|
26885
|
-
drawBakedFormControl(context, entry.control, localRect);
|
|
26886
27398
|
} else {
|
|
26887
27399
|
const imageElement = getCanvasImage(entry.image);
|
|
26888
27400
|
if (imageElement) {
|
|
@@ -27576,7 +28088,6 @@ function XlsxGrid({
|
|
|
27576
28088
|
activeSheet,
|
|
27577
28089
|
applyCanvasViewportCompensation,
|
|
27578
28090
|
bakedCanvasDrawingSignature,
|
|
27579
|
-
bakedFormControlRects,
|
|
27580
28091
|
bakedImageRects,
|
|
27581
28092
|
bakedShapeRects,
|
|
27582
28093
|
canvasColumnHeaderCells,
|
|
@@ -28159,10 +28670,22 @@ function XlsxGrid({
|
|
|
28159
28670
|
const fontSizePx = Math.max(9 * zoomFactor, (control.fontSizePt ?? 9) * 96 / 72 * zoomFactor);
|
|
28160
28671
|
const stroke = paletteIsDark(palette) ? "#cbd5e1" : "#475569";
|
|
28161
28672
|
const textColor = control.textColor ?? "#000000";
|
|
28673
|
+
const canMutateControl = !readOnly && control.controlIndex !== void 0 && [
|
|
28674
|
+
"checkbox",
|
|
28675
|
+
"dropdown",
|
|
28676
|
+
"listbox",
|
|
28677
|
+
"radio",
|
|
28678
|
+
"scrollbar",
|
|
28679
|
+
"spinner"
|
|
28680
|
+
].includes(control.kind);
|
|
28681
|
+
const canActivateButton = !readOnly && control.kind === "button" && Boolean(onFormControlAction);
|
|
28682
|
+
const isInteractiveControl = canMutateControl || canActivateButton;
|
|
28683
|
+
const controlItems = formControlItemsById.get(control.id) ?? [];
|
|
28162
28684
|
const commonStyle = {
|
|
28163
28685
|
alignItems: control.kind === "group-box" ? "stretch" : "center",
|
|
28164
28686
|
color: textColor,
|
|
28165
28687
|
contain: "layout paint",
|
|
28688
|
+
cursor: isInteractiveControl ? "pointer" : void 0,
|
|
28166
28689
|
display: "flex",
|
|
28167
28690
|
fontFamily: control.fontFamily ?? "Calibri, sans-serif",
|
|
28168
28691
|
fontSize: fontSizePx,
|
|
@@ -28173,12 +28696,98 @@ function XlsxGrid({
|
|
|
28173
28696
|
left: rect.left,
|
|
28174
28697
|
lineHeight: 1.2,
|
|
28175
28698
|
overflow: "hidden",
|
|
28176
|
-
pointerEvents: "none",
|
|
28699
|
+
pointerEvents: isInteractiveControl ? "auto" : "none",
|
|
28177
28700
|
position: "absolute",
|
|
28178
28701
|
top: rect.top,
|
|
28179
28702
|
width: rect.width,
|
|
28180
28703
|
zIndex: isFrozenDrawing ? control.zIndex + 20 : control.zIndex
|
|
28181
28704
|
};
|
|
28705
|
+
const stopControlPointerEvent = (event) => {
|
|
28706
|
+
event.stopPropagation();
|
|
28707
|
+
};
|
|
28708
|
+
const commitControlKind = (kind, nextControl) => {
|
|
28709
|
+
if (readOnly || control.controlIndex === void 0) {
|
|
28710
|
+
return false;
|
|
28711
|
+
}
|
|
28712
|
+
const didUpdate = updateFormControl(control.controlIndex, { kind }, control.sheetIndex);
|
|
28713
|
+
if (didUpdate) {
|
|
28714
|
+
onFormControlChange?.({
|
|
28715
|
+
control: { ...control, ...nextControl },
|
|
28716
|
+
previousControl: control,
|
|
28717
|
+
type: "change"
|
|
28718
|
+
});
|
|
28719
|
+
}
|
|
28720
|
+
return didUpdate;
|
|
28721
|
+
};
|
|
28722
|
+
const setControlState = (state = "unchecked") => {
|
|
28723
|
+
const kind = buildFormControlKindInput(control);
|
|
28724
|
+
if (kind?.kind === "checkbox") {
|
|
28725
|
+
return commitControlKind(
|
|
28726
|
+
{ ...kind, state },
|
|
28727
|
+
{ checked: state === "checked", state }
|
|
28728
|
+
);
|
|
28729
|
+
}
|
|
28730
|
+
if (kind?.kind === "optionButton" && state !== "mixed") {
|
|
28731
|
+
return commitControlKind(
|
|
28732
|
+
{ ...kind, state },
|
|
28733
|
+
{ checked: state === "checked", state }
|
|
28734
|
+
);
|
|
28735
|
+
}
|
|
28736
|
+
return false;
|
|
28737
|
+
};
|
|
28738
|
+
const setControlSelected = (selected) => {
|
|
28739
|
+
const kind = buildFormControlKindInput(control);
|
|
28740
|
+
if (kind?.kind === "dropdown") {
|
|
28741
|
+
const nextSelected = typeof selected === "number" ? selected : void 0;
|
|
28742
|
+
return commitControlKind(
|
|
28743
|
+
{ ...kind, selected: nextSelected },
|
|
28744
|
+
{ selected: nextSelected }
|
|
28745
|
+
);
|
|
28746
|
+
}
|
|
28747
|
+
if (kind?.kind === "listBox") {
|
|
28748
|
+
const nextSelected = Array.isArray(selected) ? selected : typeof selected === "number" ? [selected] : [];
|
|
28749
|
+
return commitControlKind(
|
|
28750
|
+
{ ...kind, selected: nextSelected },
|
|
28751
|
+
{ selected: nextSelected }
|
|
28752
|
+
);
|
|
28753
|
+
}
|
|
28754
|
+
return false;
|
|
28755
|
+
};
|
|
28756
|
+
const setControlValue = (value) => {
|
|
28757
|
+
if (!Number.isFinite(value)) {
|
|
28758
|
+
return false;
|
|
28759
|
+
}
|
|
28760
|
+
const kind = buildFormControlKindInput(control);
|
|
28761
|
+
if (kind?.kind !== "scrollbar" && kind?.kind !== "spinner") {
|
|
28762
|
+
return false;
|
|
28763
|
+
}
|
|
28764
|
+
const nextValue = Math.max(kind.min, Math.min(kind.max, value));
|
|
28765
|
+
return commitControlKind({ ...kind, value: nextValue }, { value: nextValue });
|
|
28766
|
+
};
|
|
28767
|
+
const activateControl = () => {
|
|
28768
|
+
if (!readOnly && control.kind === "button") {
|
|
28769
|
+
onFormControlAction?.({ control, type: "activate" });
|
|
28770
|
+
}
|
|
28771
|
+
};
|
|
28772
|
+
if (renderFormControl) {
|
|
28773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(React4.Fragment, { children: renderFormControl({
|
|
28774
|
+
activate: activateControl,
|
|
28775
|
+
checked: isFormControlChecked(control),
|
|
28776
|
+
control,
|
|
28777
|
+
disabled: !isInteractiveControl,
|
|
28778
|
+
items: controlItems,
|
|
28779
|
+
label: controlLabel,
|
|
28780
|
+
mixed: isFormControlMixed(control),
|
|
28781
|
+
readOnly,
|
|
28782
|
+
rect,
|
|
28783
|
+
setSelected: setControlSelected,
|
|
28784
|
+
setState: setControlState,
|
|
28785
|
+
setValue: setControlValue,
|
|
28786
|
+
stopPropagation: stopControlPointerEvent,
|
|
28787
|
+
style: commonStyle,
|
|
28788
|
+
zoomFactor
|
|
28789
|
+
}) }, `${pane}-${control.id}`);
|
|
28790
|
+
}
|
|
28182
28791
|
if (control.kind === "group-box") {
|
|
28183
28792
|
const hasLabel = controlLabel.length > 0;
|
|
28184
28793
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -28220,15 +28829,83 @@ function XlsxGrid({
|
|
|
28220
28829
|
`${pane}-${control.id}`
|
|
28221
28830
|
);
|
|
28222
28831
|
}
|
|
28223
|
-
let content;
|
|
28224
28832
|
if (control.kind === "radio") {
|
|
28225
|
-
|
|
28226
|
-
|
|
28227
|
-
|
|
28228
|
-
|
|
28833
|
+
const checked = isFormControlChecked(control);
|
|
28834
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
28835
|
+
"button",
|
|
28836
|
+
{
|
|
28837
|
+
"aria-disabled": readOnly || control.controlIndex === void 0,
|
|
28838
|
+
"aria-checked": checked,
|
|
28839
|
+
disabled: !readOnly && control.controlIndex === void 0,
|
|
28840
|
+
onClick: (event) => {
|
|
28841
|
+
event.stopPropagation();
|
|
28842
|
+
if (!checked) {
|
|
28843
|
+
setControlState("checked");
|
|
28844
|
+
}
|
|
28845
|
+
},
|
|
28846
|
+
onPointerDown: stopControlPointerEvent,
|
|
28847
|
+
role: "radio",
|
|
28848
|
+
style: {
|
|
28849
|
+
...commonStyle,
|
|
28850
|
+
background: "transparent",
|
|
28851
|
+
border: 0,
|
|
28852
|
+
boxSizing: "border-box",
|
|
28853
|
+
padding: `0 ${Math.max(1, zoomFactor)}px`
|
|
28854
|
+
},
|
|
28855
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
28856
|
+
type: "button",
|
|
28857
|
+
children: [
|
|
28858
|
+
renderRadioControl(checked, palette, zoomFactor),
|
|
28859
|
+
controlLabel ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: controlLabel }) : null
|
|
28860
|
+
]
|
|
28861
|
+
},
|
|
28862
|
+
`${pane}-${control.id}`
|
|
28863
|
+
);
|
|
28864
|
+
}
|
|
28865
|
+
if (control.kind === "checkbox") {
|
|
28866
|
+
const checked = isFormControlChecked(control);
|
|
28867
|
+
const mixed = isFormControlMixed(control);
|
|
28868
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
28869
|
+
"button",
|
|
28870
|
+
{
|
|
28871
|
+
"aria-disabled": readOnly || control.controlIndex === void 0,
|
|
28872
|
+
"aria-checked": mixed ? "mixed" : checked,
|
|
28873
|
+
disabled: !readOnly && control.controlIndex === void 0,
|
|
28874
|
+
onClick: (event) => {
|
|
28875
|
+
event.stopPropagation();
|
|
28876
|
+
const nextState = checked && !mixed ? "unchecked" : "checked";
|
|
28877
|
+
setControlState(nextState);
|
|
28878
|
+
},
|
|
28879
|
+
onPointerDown: stopControlPointerEvent,
|
|
28880
|
+
role: "checkbox",
|
|
28881
|
+
style: {
|
|
28882
|
+
...commonStyle,
|
|
28883
|
+
background: "transparent",
|
|
28884
|
+
border: 0,
|
|
28885
|
+
boxSizing: "border-box",
|
|
28886
|
+
padding: `0 ${Math.max(1, zoomFactor)}px`
|
|
28887
|
+
},
|
|
28888
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
28889
|
+
type: "button",
|
|
28890
|
+
children: [
|
|
28891
|
+
renderCheckboxControl(checked, palette, zoomFactor, mixed),
|
|
28892
|
+
controlLabel ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: controlLabel }) : null
|
|
28893
|
+
]
|
|
28894
|
+
},
|
|
28895
|
+
`${pane}-${control.id}`
|
|
28896
|
+
);
|
|
28897
|
+
}
|
|
28898
|
+
if (control.kind === "button") {
|
|
28229
28899
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
28230
|
-
"
|
|
28900
|
+
"button",
|
|
28231
28901
|
{
|
|
28902
|
+
"aria-disabled": readOnly || !onFormControlAction,
|
|
28903
|
+
disabled: !readOnly && !onFormControlAction,
|
|
28904
|
+
onClick: (event) => {
|
|
28905
|
+
event.stopPropagation();
|
|
28906
|
+
activateControl();
|
|
28907
|
+
},
|
|
28908
|
+
onPointerDown: stopControlPointerEvent,
|
|
28232
28909
|
style: {
|
|
28233
28910
|
...commonStyle,
|
|
28234
28911
|
background: "linear-gradient(180deg, #f8fafc 0%, #e2e8f0 100%)",
|
|
@@ -28239,68 +28916,157 @@ function XlsxGrid({
|
|
|
28239
28916
|
padding: `0 ${6 * zoomFactor}px`,
|
|
28240
28917
|
textAlign: "center"
|
|
28241
28918
|
},
|
|
28919
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
28920
|
+
type: "button",
|
|
28242
28921
|
children: controlLabel
|
|
28243
28922
|
},
|
|
28244
28923
|
`${pane}-${control.id}`
|
|
28245
28924
|
);
|
|
28246
|
-
}
|
|
28925
|
+
}
|
|
28926
|
+
if (control.kind === "dropdown") {
|
|
28927
|
+
const selected = typeof control.selected === "number" ? control.selected : void 0;
|
|
28247
28928
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
28248
|
-
"
|
|
28929
|
+
"select",
|
|
28249
28930
|
{
|
|
28931
|
+
"aria-disabled": readOnly || control.controlIndex === void 0 || controlItems.length === 0,
|
|
28932
|
+
"aria-label": controlLabel || control.name || "Dropdown form control",
|
|
28933
|
+
disabled: !readOnly && (control.controlIndex === void 0 || controlItems.length === 0),
|
|
28934
|
+
onChange: (event) => {
|
|
28935
|
+
event.stopPropagation();
|
|
28936
|
+
const nextSelected = event.currentTarget.value === "" ? void 0 : Number(event.currentTarget.value);
|
|
28937
|
+
setControlSelected(nextSelected);
|
|
28938
|
+
},
|
|
28939
|
+
onClick: stopControlPointerEvent,
|
|
28940
|
+
onPointerDown: stopControlPointerEvent,
|
|
28250
28941
|
style: {
|
|
28251
28942
|
...commonStyle,
|
|
28943
|
+
backgroundColor: SHEET_SURFACE,
|
|
28252
28944
|
border: `${Math.max(1, zoomFactor)}px solid ${stroke}`,
|
|
28253
28945
|
borderRadius: 2 * zoomFactor,
|
|
28254
28946
|
boxSizing: "border-box",
|
|
28255
|
-
|
|
28256
|
-
padding: `0 ${6 * zoomFactor}px`
|
|
28947
|
+
padding: `0 ${4 * zoomFactor}px`
|
|
28257
28948
|
},
|
|
28949
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
28950
|
+
value: selected === void 0 ? "" : String(selected),
|
|
28258
28951
|
children: [
|
|
28259
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("
|
|
28260
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("
|
|
28952
|
+
selected === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: controlLabel }) : null,
|
|
28953
|
+
controlItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: index, children: item }, index))
|
|
28261
28954
|
]
|
|
28262
28955
|
},
|
|
28263
28956
|
`${pane}-${control.id}`
|
|
28264
28957
|
);
|
|
28265
|
-
}
|
|
28958
|
+
}
|
|
28959
|
+
if (control.kind === "listbox") {
|
|
28960
|
+
const selected = Array.isArray(control.selected) ? control.selected : control.selected === void 0 ? [] : [control.selected];
|
|
28961
|
+
const allowsMultipleSelection = (control.selection ?? "single") !== "single";
|
|
28266
28962
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
28267
|
-
"
|
|
28963
|
+
"select",
|
|
28268
28964
|
{
|
|
28965
|
+
"aria-disabled": readOnly || control.controlIndex === void 0 || controlItems.length === 0,
|
|
28966
|
+
"aria-label": controlLabel || control.name || "List box form control",
|
|
28967
|
+
disabled: !readOnly && (control.controlIndex === void 0 || controlItems.length === 0),
|
|
28968
|
+
multiple: allowsMultipleSelection,
|
|
28969
|
+
onChange: (event) => {
|
|
28970
|
+
event.stopPropagation();
|
|
28971
|
+
const nextSelected = Array.from(event.currentTarget.selectedOptions, (option) => Number(option.value));
|
|
28972
|
+
setControlSelected(nextSelected);
|
|
28973
|
+
},
|
|
28974
|
+
onClick: stopControlPointerEvent,
|
|
28975
|
+
onPointerDown: stopControlPointerEvent,
|
|
28976
|
+
size: Math.max(2, Math.min(controlItems.length || 2, Math.floor(rect.height / Math.max(1, fontSizePx * 1.45)))),
|
|
28269
28977
|
style: {
|
|
28270
28978
|
...commonStyle,
|
|
28979
|
+
alignItems: void 0,
|
|
28980
|
+
backgroundColor: SHEET_SURFACE,
|
|
28271
28981
|
border: `${Math.max(1, zoomFactor)}px solid ${stroke}`,
|
|
28272
28982
|
borderRadius: 2 * zoomFactor,
|
|
28273
28983
|
boxSizing: "border-box",
|
|
28274
|
-
|
|
28984
|
+
display: "block",
|
|
28985
|
+
padding: 0
|
|
28275
28986
|
},
|
|
28276
|
-
|
|
28987
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
28988
|
+
value: allowsMultipleSelection ? selected.map(String) : selected[0] === void 0 ? "" : String(selected[0]),
|
|
28989
|
+
children: controlItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: index, children: item }, index))
|
|
28277
28990
|
},
|
|
28278
28991
|
`${pane}-${control.id}`
|
|
28279
28992
|
);
|
|
28280
|
-
} else {
|
|
28281
|
-
content = null;
|
|
28282
28993
|
}
|
|
28283
|
-
|
|
28994
|
+
if (control.kind === "scrollbar") {
|
|
28995
|
+
const min = control.min ?? 0;
|
|
28996
|
+
const max = Math.max(min, control.max ?? 100);
|
|
28997
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
28998
|
+
"input",
|
|
28999
|
+
{
|
|
29000
|
+
"aria-disabled": readOnly || control.controlIndex === void 0,
|
|
29001
|
+
"aria-label": controlLabel || control.name || "Scrollbar form control",
|
|
29002
|
+
disabled: !readOnly && control.controlIndex === void 0,
|
|
29003
|
+
max,
|
|
29004
|
+
min,
|
|
29005
|
+
onChange: (event) => {
|
|
29006
|
+
event.stopPropagation();
|
|
29007
|
+
setControlValue(event.currentTarget.valueAsNumber);
|
|
29008
|
+
},
|
|
29009
|
+
onClick: stopControlPointerEvent,
|
|
29010
|
+
onPointerDown: stopControlPointerEvent,
|
|
29011
|
+
step: Math.max(1, control.increment ?? 1),
|
|
29012
|
+
style: {
|
|
29013
|
+
...commonStyle,
|
|
29014
|
+
accentColor: paletteIsDark(palette) ? "#60a5fa" : "#2563eb",
|
|
29015
|
+
boxSizing: "border-box",
|
|
29016
|
+
padding: 0,
|
|
29017
|
+
writingMode: control.horizontal === false ? "vertical-lr" : void 0
|
|
29018
|
+
},
|
|
29019
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
29020
|
+
type: "range",
|
|
29021
|
+
value: Math.max(min, Math.min(max, control.value ?? min))
|
|
29022
|
+
},
|
|
29023
|
+
`${pane}-${control.id}`
|
|
29024
|
+
);
|
|
29025
|
+
}
|
|
29026
|
+
if (control.kind === "spinner") {
|
|
29027
|
+
const min = control.min ?? 0;
|
|
29028
|
+
const max = Math.max(min, control.max ?? 100);
|
|
29029
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
29030
|
+
"input",
|
|
29031
|
+
{
|
|
29032
|
+
"aria-disabled": readOnly || control.controlIndex === void 0,
|
|
29033
|
+
"aria-label": controlLabel || control.name || "Spinner form control",
|
|
29034
|
+
disabled: !readOnly && control.controlIndex === void 0,
|
|
29035
|
+
max,
|
|
29036
|
+
min,
|
|
29037
|
+
onChange: (event) => {
|
|
29038
|
+
event.stopPropagation();
|
|
29039
|
+
setControlValue(event.currentTarget.valueAsNumber);
|
|
29040
|
+
},
|
|
29041
|
+
onClick: stopControlPointerEvent,
|
|
29042
|
+
onPointerDown: stopControlPointerEvent,
|
|
29043
|
+
step: Math.max(1, control.increment ?? 1),
|
|
29044
|
+
style: {
|
|
29045
|
+
...commonStyle,
|
|
29046
|
+
backgroundColor: SHEET_SURFACE,
|
|
29047
|
+
border: `${Math.max(1, zoomFactor)}px solid ${stroke}`,
|
|
29048
|
+
borderRadius: 2 * zoomFactor,
|
|
29049
|
+
boxSizing: "border-box",
|
|
29050
|
+
padding: `0 ${4 * zoomFactor}px`
|
|
29051
|
+
},
|
|
29052
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
29053
|
+
type: "number",
|
|
29054
|
+
value: Math.max(min, Math.min(max, control.value ?? min))
|
|
29055
|
+
},
|
|
29056
|
+
`${pane}-${control.id}`
|
|
29057
|
+
);
|
|
29058
|
+
}
|
|
29059
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
28284
29060
|
"div",
|
|
28285
29061
|
{
|
|
28286
29062
|
style: {
|
|
28287
29063
|
...commonStyle,
|
|
29064
|
+
border: control.kind === "editbox" || control.kind === "unknown" ? `${Math.max(1, zoomFactor)}px solid ${stroke}` : void 0,
|
|
29065
|
+
borderRadius: 2 * zoomFactor,
|
|
29066
|
+
boxSizing: "border-box",
|
|
28288
29067
|
padding: `0 ${Math.max(1, zoomFactor)}px`
|
|
28289
29068
|
},
|
|
28290
|
-
children:
|
|
28291
|
-
content,
|
|
28292
|
-
controlLabel ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
28293
|
-
"span",
|
|
28294
|
-
{
|
|
28295
|
-
style: {
|
|
28296
|
-
overflow: "hidden",
|
|
28297
|
-
textOverflow: "ellipsis",
|
|
28298
|
-
whiteSpace: "nowrap"
|
|
28299
|
-
},
|
|
28300
|
-
children: controlLabel
|
|
28301
|
-
}
|
|
28302
|
-
) : null
|
|
28303
|
-
]
|
|
29069
|
+
children: controlLabel ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: controlLabel }) : null
|
|
28304
29070
|
},
|
|
28305
29071
|
`${pane}-${control.id}`
|
|
28306
29072
|
);
|
|
@@ -28587,7 +29353,7 @@ function XlsxGrid({
|
|
|
28587
29353
|
};
|
|
28588
29354
|
const drawingViewportCacheSignature = `${Math.floor(drawingViewport.left / CANVAS_VIEWPORT_OVERSCAN_PX)}:${Math.floor(drawingViewport.top / CANVAS_VIEWPORT_OVERSCAN_PX)}:${drawingViewport.width}:${drawingViewport.height}`;
|
|
28589
29355
|
const previousPaneDrawingNodes = paneDrawingNodesCacheRef.current;
|
|
28590
|
-
const canReusePaneDrawingNodes = previousPaneDrawingNodes !== null && previousPaneDrawingNodes.showImages === showImages && previousPaneDrawingNodes.chartRects === chartRects && previousPaneDrawingNodes.formControlRects === domFormControlRects && previousPaneDrawingNodes.shapeRects === domShapeRects && previousPaneDrawingNodes.imageRects === domImageRects && previousPaneDrawingNodes.selectedChartId === selectedChartId && previousPaneDrawingNodes.selectedImageId === selectedImageId && previousPaneDrawingNodes.readOnly === readOnly && previousPaneDrawingNodes.selectionStroke === selectionStroke && previousPaneDrawingNodes.renderChartLoading === renderChartLoading && previousPaneDrawingNodes.renderImage === renderImage && previousPaneDrawingNodes.renderImageSelection === renderImageSelection && previousPaneDrawingNodes.isChartsLoading === isChartsLoading && previousPaneDrawingNodes.selectedChartElement === selectedChartElement && previousPaneDrawingNodes.palette === palette && previousPaneDrawingNodes.drawingViewportSignature === drawingViewportCacheSignature;
|
|
29356
|
+
const canReusePaneDrawingNodes = previousPaneDrawingNodes !== null && previousPaneDrawingNodes.showImages === showImages && previousPaneDrawingNodes.updateFormControl === updateFormControl && previousPaneDrawingNodes.chartRects === chartRects && previousPaneDrawingNodes.formControlRects === domFormControlRects && previousPaneDrawingNodes.formControlItemsById === formControlItemsById && previousPaneDrawingNodes.shapeRects === domShapeRects && previousPaneDrawingNodes.imageRects === domImageRects && previousPaneDrawingNodes.selectedChartId === selectedChartId && previousPaneDrawingNodes.selectedImageId === selectedImageId && previousPaneDrawingNodes.readOnly === readOnly && previousPaneDrawingNodes.onFormControlAction === onFormControlAction && previousPaneDrawingNodes.onFormControlChange === onFormControlChange && previousPaneDrawingNodes.selectionStroke === selectionStroke && previousPaneDrawingNodes.renderChartLoading === renderChartLoading && previousPaneDrawingNodes.renderFormControl === renderFormControl && previousPaneDrawingNodes.renderImage === renderImage && previousPaneDrawingNodes.renderImageSelection === renderImageSelection && previousPaneDrawingNodes.isChartsLoading === isChartsLoading && previousPaneDrawingNodes.selectedChartElement === selectedChartElement && previousPaneDrawingNodes.palette === palette && previousPaneDrawingNodes.drawingViewportSignature === drawingViewportCacheSignature;
|
|
28591
29357
|
const paneDrawingNodes = canReusePaneDrawingNodes ? previousPaneDrawingNodes.value : !showImages ? {
|
|
28592
29358
|
corner: null,
|
|
28593
29359
|
left: null,
|
|
@@ -28623,12 +29389,16 @@ function XlsxGrid({
|
|
|
28623
29389
|
paneDrawingNodesCacheRef.current = {
|
|
28624
29390
|
chartRects,
|
|
28625
29391
|
drawingViewportSignature: drawingViewportCacheSignature,
|
|
29392
|
+
formControlItemsById,
|
|
28626
29393
|
formControlRects: domFormControlRects,
|
|
28627
29394
|
imageRects: domImageRects,
|
|
28628
29395
|
isChartsLoading,
|
|
29396
|
+
onFormControlAction,
|
|
29397
|
+
onFormControlChange,
|
|
28629
29398
|
palette,
|
|
28630
29399
|
readOnly,
|
|
28631
29400
|
renderChartLoading,
|
|
29401
|
+
renderFormControl,
|
|
28632
29402
|
renderImage,
|
|
28633
29403
|
renderImageSelection,
|
|
28634
29404
|
selectedChartElement,
|
|
@@ -28637,6 +29407,7 @@ function XlsxGrid({
|
|
|
28637
29407
|
selectionStroke,
|
|
28638
29408
|
shapeRects: domShapeRects,
|
|
28639
29409
|
showImages,
|
|
29410
|
+
updateFormControl,
|
|
28640
29411
|
value: paneDrawingNodes
|
|
28641
29412
|
};
|
|
28642
29413
|
}
|
|
@@ -29863,7 +30634,10 @@ function XlsxViewerInner({
|
|
|
29863
30634
|
isDark = false,
|
|
29864
30635
|
loadingComponent,
|
|
29865
30636
|
loadingState,
|
|
30637
|
+
onFormControlAction,
|
|
30638
|
+
onFormControlChange,
|
|
29866
30639
|
renderChartLoading,
|
|
30640
|
+
renderFormControl,
|
|
29867
30641
|
renderImage,
|
|
29868
30642
|
renderImageSelection,
|
|
29869
30643
|
renderScroller,
|
|
@@ -29925,8 +30699,11 @@ function XlsxViewerInner({
|
|
|
29925
30699
|
getCellStyle,
|
|
29926
30700
|
loadingComponent,
|
|
29927
30701
|
loadingState,
|
|
30702
|
+
onFormControlAction,
|
|
30703
|
+
onFormControlChange,
|
|
29928
30704
|
palette,
|
|
29929
30705
|
renderChartLoading,
|
|
30706
|
+
renderFormControl,
|
|
29930
30707
|
renderImage,
|
|
29931
30708
|
renderImageSelection,
|
|
29932
30709
|
renderScroller,
|
|
@@ -30031,6 +30808,7 @@ function useXlsxViewerZoom() {
|
|
|
30031
30808
|
}
|
|
30032
30809
|
function useXlsxViewerEditing() {
|
|
30033
30810
|
const {
|
|
30811
|
+
addFormControl,
|
|
30034
30812
|
addSheet,
|
|
30035
30813
|
canRedo,
|
|
30036
30814
|
canUndo,
|
|
@@ -30038,14 +30816,18 @@ function useXlsxViewerEditing() {
|
|
|
30038
30816
|
copySelectionToClipboard,
|
|
30039
30817
|
defineNamedRange,
|
|
30040
30818
|
fillSelection,
|
|
30819
|
+
formControls,
|
|
30041
30820
|
getClipboardData,
|
|
30042
30821
|
getCellDisplayValue: getCellDisplayValue2,
|
|
30043
30822
|
getCellFormula,
|
|
30823
|
+
getFormControlItems,
|
|
30824
|
+
getSheetFormControls,
|
|
30044
30825
|
mergeSelection,
|
|
30045
30826
|
pasteFromClipboard,
|
|
30046
30827
|
pasteStructuredClipboardData,
|
|
30047
30828
|
pasteText,
|
|
30048
30829
|
removeActiveSheet,
|
|
30830
|
+
removeFormControl,
|
|
30049
30831
|
readOnly,
|
|
30050
30832
|
redo,
|
|
30051
30833
|
selectedCellFormula,
|
|
@@ -30062,10 +30844,12 @@ function useXlsxViewerEditing() {
|
|
|
30062
30844
|
setSelectedCellStyle,
|
|
30063
30845
|
setSelectedCellValue,
|
|
30064
30846
|
undo,
|
|
30065
|
-
unmergeSelection
|
|
30847
|
+
unmergeSelection,
|
|
30848
|
+
updateFormControl
|
|
30066
30849
|
} = useXlsxViewer();
|
|
30067
30850
|
return React4.useMemo(
|
|
30068
30851
|
() => ({
|
|
30852
|
+
addFormControl,
|
|
30069
30853
|
addSheet,
|
|
30070
30854
|
canRedo,
|
|
30071
30855
|
canUndo,
|
|
@@ -30073,14 +30857,18 @@ function useXlsxViewerEditing() {
|
|
|
30073
30857
|
copySelectionToClipboard,
|
|
30074
30858
|
defineNamedRange,
|
|
30075
30859
|
fillSelection,
|
|
30860
|
+
formControls,
|
|
30076
30861
|
getClipboardData,
|
|
30077
30862
|
getCellDisplayValue: getCellDisplayValue2,
|
|
30078
30863
|
getCellFormula,
|
|
30864
|
+
getFormControlItems,
|
|
30865
|
+
getSheetFormControls,
|
|
30079
30866
|
mergeSelection,
|
|
30080
30867
|
pasteFromClipboard,
|
|
30081
30868
|
pasteStructuredClipboardData,
|
|
30082
30869
|
pasteText,
|
|
30083
30870
|
removeActiveSheet,
|
|
30871
|
+
removeFormControl,
|
|
30084
30872
|
readOnly,
|
|
30085
30873
|
redo,
|
|
30086
30874
|
selectedCellFormula,
|
|
@@ -30097,9 +30885,11 @@ function useXlsxViewerEditing() {
|
|
|
30097
30885
|
setSelectedCellStyle,
|
|
30098
30886
|
setSelectedCellValue,
|
|
30099
30887
|
undo,
|
|
30100
|
-
unmergeSelection
|
|
30888
|
+
unmergeSelection,
|
|
30889
|
+
updateFormControl
|
|
30101
30890
|
}),
|
|
30102
30891
|
[
|
|
30892
|
+
addFormControl,
|
|
30103
30893
|
addSheet,
|
|
30104
30894
|
canRedo,
|
|
30105
30895
|
canUndo,
|
|
@@ -30107,14 +30897,18 @@ function useXlsxViewerEditing() {
|
|
|
30107
30897
|
copySelectionToClipboard,
|
|
30108
30898
|
defineNamedRange,
|
|
30109
30899
|
fillSelection,
|
|
30900
|
+
formControls,
|
|
30110
30901
|
getClipboardData,
|
|
30111
30902
|
getCellDisplayValue2,
|
|
30112
30903
|
getCellFormula,
|
|
30904
|
+
getFormControlItems,
|
|
30905
|
+
getSheetFormControls,
|
|
30113
30906
|
mergeSelection,
|
|
30114
30907
|
pasteFromClipboard,
|
|
30115
30908
|
pasteStructuredClipboardData,
|
|
30116
30909
|
pasteText,
|
|
30117
30910
|
removeActiveSheet,
|
|
30911
|
+
removeFormControl,
|
|
30118
30912
|
readOnly,
|
|
30119
30913
|
redo,
|
|
30120
30914
|
selectedCellFormula,
|
|
@@ -30131,7 +30925,8 @@ function useXlsxViewerEditing() {
|
|
|
30131
30925
|
setSelectedCellStyle,
|
|
30132
30926
|
setSelectedCellValue,
|
|
30133
30927
|
undo,
|
|
30134
|
-
unmergeSelection
|
|
30928
|
+
unmergeSelection,
|
|
30929
|
+
updateFormControl
|
|
30135
30930
|
]
|
|
30136
30931
|
);
|
|
30137
30932
|
}
|
|
@@ -30329,20 +31124,87 @@ function useXlsxViewerCharts() {
|
|
|
30329
31124
|
);
|
|
30330
31125
|
}
|
|
30331
31126
|
function useXlsxViewerThumbnails(options = {}) {
|
|
30332
|
-
const {
|
|
31127
|
+
const {
|
|
31128
|
+
getRowsBatchAsync,
|
|
31129
|
+
getSheetFormControls,
|
|
31130
|
+
getSheetImages,
|
|
31131
|
+
getSheetShapes,
|
|
31132
|
+
workbook,
|
|
31133
|
+
sheets
|
|
31134
|
+
} = useXlsxViewer();
|
|
30333
31135
|
const { isDark } = React4.useContext(ViewerAppearanceContext);
|
|
30334
31136
|
const palette = useViewerPalette(isDark);
|
|
30335
31137
|
const includeHeaders = options.includeHeaders ?? true;
|
|
30336
31138
|
const resolution = options.resolution;
|
|
30337
31139
|
const thumbnailImageCacheRef = React4.useRef(/* @__PURE__ */ new Map());
|
|
31140
|
+
const workerThumbnailRowBatchCacheRef = React4.useRef(/* @__PURE__ */ new Map());
|
|
31141
|
+
const workerThumbnailRowBatchRequestRef = React4.useRef(
|
|
31142
|
+
/* @__PURE__ */ new Map()
|
|
31143
|
+
);
|
|
30338
31144
|
const isMountedRef = React4.useRef(false);
|
|
30339
31145
|
const [thumbnailImageLoadVersion, setThumbnailImageLoadVersion] = React4.useState(0);
|
|
31146
|
+
const [workerThumbnailRowBatchVersion, setWorkerThumbnailRowBatchVersion] = React4.useState(0);
|
|
30340
31147
|
React4.useEffect(() => {
|
|
30341
31148
|
isMountedRef.current = true;
|
|
30342
31149
|
return () => {
|
|
30343
31150
|
isMountedRef.current = false;
|
|
30344
31151
|
};
|
|
30345
31152
|
}, []);
|
|
31153
|
+
React4.useEffect(() => {
|
|
31154
|
+
const currentSheets = new Set(sheets);
|
|
31155
|
+
for (const sheet of workerThumbnailRowBatchCacheRef.current.keys()) {
|
|
31156
|
+
if (!currentSheets.has(sheet)) {
|
|
31157
|
+
workerThumbnailRowBatchCacheRef.current.delete(sheet);
|
|
31158
|
+
}
|
|
31159
|
+
}
|
|
31160
|
+
for (const sheet of workerThumbnailRowBatchRequestRef.current.keys()) {
|
|
31161
|
+
if (!currentSheets.has(sheet)) {
|
|
31162
|
+
workerThumbnailRowBatchRequestRef.current.delete(sheet);
|
|
31163
|
+
}
|
|
31164
|
+
}
|
|
31165
|
+
}, [sheets]);
|
|
31166
|
+
const getWorkerThumbnailRowBatch = React4.useCallback((sheet, startRow, endRow) => {
|
|
31167
|
+
const cachedBatch = workerThumbnailRowBatchCacheRef.current.get(sheet);
|
|
31168
|
+
if (cachedBatch && startRow >= cachedBatch.startRow && endRow <= cachedBatch.endRow) {
|
|
31169
|
+
return cachedBatch;
|
|
31170
|
+
}
|
|
31171
|
+
if (!getRowsBatchAsync) {
|
|
31172
|
+
return null;
|
|
31173
|
+
}
|
|
31174
|
+
const pendingRequest = workerThumbnailRowBatchRequestRef.current.get(sheet);
|
|
31175
|
+
if (!pendingRequest) {
|
|
31176
|
+
const request = {
|
|
31177
|
+
endRow: Math.max(endRow, cachedBatch?.endRow ?? endRow),
|
|
31178
|
+
startRow: Math.min(startRow, cachedBatch?.startRow ?? startRow)
|
|
31179
|
+
};
|
|
31180
|
+
workerThumbnailRowBatchRequestRef.current.set(sheet, request);
|
|
31181
|
+
void getRowsBatchAsync(
|
|
31182
|
+
sheet.workbookSheetIndex,
|
|
31183
|
+
request.startRow,
|
|
31184
|
+
request.endRow - request.startRow + 1
|
|
31185
|
+
).then((rows) => {
|
|
31186
|
+
if (workerThumbnailRowBatchRequestRef.current.get(sheet) !== request) {
|
|
31187
|
+
return;
|
|
31188
|
+
}
|
|
31189
|
+
workerThumbnailRowBatchRequestRef.current.delete(sheet);
|
|
31190
|
+
if (!rows) {
|
|
31191
|
+
return;
|
|
31192
|
+
}
|
|
31193
|
+
workerThumbnailRowBatchCacheRef.current.set(
|
|
31194
|
+
sheet,
|
|
31195
|
+
buildWorksheetBatchWindow(rows, sheet, request.startRow, request.endRow)
|
|
31196
|
+
);
|
|
31197
|
+
if (isMountedRef.current) {
|
|
31198
|
+
setWorkerThumbnailRowBatchVersion((version) => version + 1);
|
|
31199
|
+
}
|
|
31200
|
+
}).catch(() => {
|
|
31201
|
+
if (workerThumbnailRowBatchRequestRef.current.get(sheet) === request) {
|
|
31202
|
+
workerThumbnailRowBatchRequestRef.current.delete(sheet);
|
|
31203
|
+
}
|
|
31204
|
+
});
|
|
31205
|
+
}
|
|
31206
|
+
return null;
|
|
31207
|
+
}, [getRowsBatchAsync]);
|
|
30346
31208
|
const getThumbnailImage = React4.useCallback((image) => {
|
|
30347
31209
|
if (typeof Image === "undefined") {
|
|
30348
31210
|
return null;
|
|
@@ -30568,6 +31430,10 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30568
31430
|
if (!canvas) {
|
|
30569
31431
|
return false;
|
|
30570
31432
|
}
|
|
31433
|
+
const workerRowBatch = worksheet ? null : getWorkerThumbnailRowBatch(sheet, sourceRange.start.row, sourceRange.end.row);
|
|
31434
|
+
if (!worksheet && !workerRowBatch) {
|
|
31435
|
+
return false;
|
|
31436
|
+
}
|
|
30571
31437
|
const context = canvas.getContext("2d", { alpha: false });
|
|
30572
31438
|
if (!context) {
|
|
30573
31439
|
return false;
|
|
@@ -30604,9 +31470,6 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30604
31470
|
context.fillRect(0, headerHeight, rowHeaderWidth, Math.max(1, rowAxis.totalSize));
|
|
30605
31471
|
context.fillRect(0, 0, rowHeaderWidth, headerHeight);
|
|
30606
31472
|
}
|
|
30607
|
-
if (!worksheet) {
|
|
30608
|
-
return true;
|
|
30609
|
-
}
|
|
30610
31473
|
const conditionalFormatMetricsCache = /* @__PURE__ */ new Map();
|
|
30611
31474
|
const cellRenderCache = /* @__PURE__ */ new Map();
|
|
30612
31475
|
const getCellData = (row, col) => {
|
|
@@ -30615,7 +31478,9 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30615
31478
|
if (cached) {
|
|
30616
31479
|
return cached;
|
|
30617
31480
|
}
|
|
30618
|
-
|
|
31481
|
+
const batchCoversRow = workerRowBatch ? row >= workerRowBatch.startRow && row <= workerRowBatch.endRow : false;
|
|
31482
|
+
const batchedCell = batchCoversRow ? workerRowBatch?.cells.get(cacheKey) : void 0;
|
|
31483
|
+
if (batchedCell?.isMergedSecondary || worksheet?.isMergedSecondary(row, col)) {
|
|
30619
31484
|
const mergedSecondaryData = {
|
|
30620
31485
|
isMergedSecondary: true,
|
|
30621
31486
|
style: {},
|
|
@@ -30624,53 +31489,34 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30624
31489
|
cellRenderCache.set(cacheKey, mergedSecondaryData);
|
|
30625
31490
|
return mergedSecondaryData;
|
|
30626
31491
|
}
|
|
30627
|
-
const merge = worksheet.getMergeSpan(row, col);
|
|
31492
|
+
const merge = worksheet ? worksheet.getMergeSpan(row, col) : batchedCell?.mergeSpan;
|
|
30628
31493
|
const inheritedStyle = resolveInheritedCellStyle2(sheet, row, col);
|
|
30629
|
-
const worksheetStyle = worksheet.getCellStyleAt(row, col) ?? null;
|
|
31494
|
+
const worksheetStyle = worksheet ? worksheet.getCellStyleAt(row, col) ?? null : batchedCell?.style ?? null;
|
|
30630
31495
|
const mergedStyle = mergeResolvedCellStyle(inheritedStyle, worksheetStyle, { replaceXfSubtrees: true });
|
|
30631
31496
|
const alignment = mergedStyle?.alignment;
|
|
30632
31497
|
const sparkline = sparklineByCell.get(cacheKey) ?? null;
|
|
31498
|
+
const getNumericValue = (targetRow, targetCol) => worksheet ? getCellNumericValue(worksheet, targetRow, targetCol) : getBatchedCellNumericValue(workerRowBatch?.cells.get(`${targetRow}:${targetCol}`));
|
|
30633
31499
|
const sparklineValues = sparkline ? sparkline.range.start.row === sparkline.range.end.row ? Array.from(
|
|
30634
31500
|
{ length: Math.abs(sparkline.range.end.col - sparkline.range.start.col) + 1 },
|
|
30635
|
-
(_, index) =>
|
|
30636
|
-
worksheet,
|
|
31501
|
+
(_, index) => getNumericValue(
|
|
30637
31502
|
sparkline.range.start.row,
|
|
30638
31503
|
Math.min(sparkline.range.start.col, sparkline.range.end.col) + index
|
|
30639
31504
|
)
|
|
30640
31505
|
) : Array.from(
|
|
30641
31506
|
{ length: Math.abs(sparkline.range.end.row - sparkline.range.start.row) + 1 },
|
|
30642
|
-
(_, index) =>
|
|
30643
|
-
worksheet,
|
|
31507
|
+
(_, index) => getNumericValue(
|
|
30644
31508
|
Math.min(sparkline.range.start.row, sparkline.range.end.row) + index,
|
|
30645
31509
|
sparkline.range.start.col
|
|
30646
31510
|
)
|
|
30647
31511
|
) : null;
|
|
30648
|
-
const checkboxState = mergedStyle?.cellControl ? getCellBooleanValue(worksheet, row, col) : null;
|
|
31512
|
+
const checkboxState = mergedStyle?.cellControl ? worksheet ? getCellBooleanValue(worksheet, row, col) : getBatchedCellBooleanValue(batchedCell) : null;
|
|
30649
31513
|
const nextData = {
|
|
30650
31514
|
canvas: void 0,
|
|
30651
31515
|
checkboxState,
|
|
30652
31516
|
colSpan: merge?.colSpan,
|
|
30653
|
-
conditionalColorScale: resolveConditionalColorScaleForCell(
|
|
30654
|
-
|
|
30655
|
-
|
|
30656
|
-
worksheet,
|
|
30657
|
-
sheet,
|
|
30658
|
-
conditionalFormatMetricsCache
|
|
30659
|
-
),
|
|
30660
|
-
conditionalDataBar: resolveConditionalDataBarForCell(
|
|
30661
|
-
row,
|
|
30662
|
-
col,
|
|
30663
|
-
worksheet,
|
|
30664
|
-
sheet,
|
|
30665
|
-
conditionalFormatMetricsCache
|
|
30666
|
-
),
|
|
30667
|
-
conditionalIcon: resolveConditionalIconForCell(
|
|
30668
|
-
row,
|
|
30669
|
-
col,
|
|
30670
|
-
worksheet,
|
|
30671
|
-
sheet,
|
|
30672
|
-
conditionalFormatMetricsCache
|
|
30673
|
-
),
|
|
31517
|
+
conditionalColorScale: worksheet ? resolveConditionalColorScaleForCell(row, col, worksheet, sheet, conditionalFormatMetricsCache) : null,
|
|
31518
|
+
conditionalDataBar: worksheet ? resolveConditionalDataBarForCell(row, col, worksheet, sheet, conditionalFormatMetricsCache) : null,
|
|
31519
|
+
conditionalIcon: worksheet ? resolveConditionalIconForCell(row, col, worksheet, sheet, conditionalFormatMetricsCache) : null,
|
|
30674
31520
|
isMergedSecondary: false,
|
|
30675
31521
|
rowSpan: merge?.rowSpan,
|
|
30676
31522
|
sparkline: sparkline && sparklineValues ? { config: sparkline, values: sparklineValues } : null,
|
|
@@ -30678,7 +31524,7 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30678
31524
|
showGridLines
|
|
30679
31525
|
}),
|
|
30680
31526
|
textRotationDeg: resolveSpreadsheetTextRotation(alignment?.textRotation),
|
|
30681
|
-
value: sparkline ? "" : checkboxState !== null ? "" : getCellDisplayValue(worksheet, row, col, sheet)
|
|
31527
|
+
value: sparkline ? "" : checkboxState !== null ? "" : worksheet ? getCellDisplayValue(worksheet, row, col, sheet) : batchedCell?.value ?? ""
|
|
30682
31528
|
};
|
|
30683
31529
|
nextData.canvas = buildCanvasCellStyleCache(nextData.style);
|
|
30684
31530
|
cellRenderCache.set(cacheKey, nextData);
|
|
@@ -30952,12 +31798,14 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30952
31798
|
getSheetFormControls,
|
|
30953
31799
|
getSheetImages,
|
|
30954
31800
|
getSheetShapes,
|
|
31801
|
+
getWorkerThumbnailRowBatch,
|
|
30955
31802
|
getThumbnailImage,
|
|
30956
31803
|
includeHeaders,
|
|
30957
31804
|
palette,
|
|
30958
31805
|
resolution,
|
|
30959
31806
|
sheets,
|
|
30960
31807
|
thumbnailImageLoadVersion,
|
|
31808
|
+
workerThumbnailRowBatchVersion,
|
|
30961
31809
|
workbook
|
|
30962
31810
|
]);
|
|
30963
31811
|
const paintThumbnail = React4.useCallback(
|