@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.js
CHANGED
|
@@ -3592,7 +3592,6 @@ var SPREADSHEET_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
|
3592
3592
|
var CONTENT_TYPES_NS = "http://schemas.openxmlformats.org/package/2006/content-types";
|
|
3593
3593
|
var DRAWING_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing";
|
|
3594
3594
|
var VML_DRAWING_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing";
|
|
3595
|
-
var CTRL_PROP_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp";
|
|
3596
3595
|
var IMAGE_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
3597
3596
|
var DRAWING_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.drawing+xml";
|
|
3598
3597
|
var EMU_PER_PIXEL2 = 9525;
|
|
@@ -5035,6 +5034,124 @@ function parseSpreadsheetBooleanNode(node) {
|
|
|
5035
5034
|
}
|
|
5036
5035
|
return parseSpreadsheetBooleanValue(node.getAttribute("val") ?? node.textContent);
|
|
5037
5036
|
}
|
|
5037
|
+
function mapDukeFormControlAnchor(anchor) {
|
|
5038
|
+
return {
|
|
5039
|
+
from: {
|
|
5040
|
+
col: anchor.fromCol,
|
|
5041
|
+
colOffsetEmu: anchor.fromColOffset,
|
|
5042
|
+
row: anchor.fromRow,
|
|
5043
|
+
rowOffsetEmu: anchor.fromRowOffset
|
|
5044
|
+
},
|
|
5045
|
+
kind: "two-cell",
|
|
5046
|
+
to: {
|
|
5047
|
+
col: anchor.toCol,
|
|
5048
|
+
colOffsetEmu: anchor.toColOffset,
|
|
5049
|
+
row: anchor.toRow,
|
|
5050
|
+
rowOffsetEmu: anchor.toRowOffset
|
|
5051
|
+
}
|
|
5052
|
+
};
|
|
5053
|
+
}
|
|
5054
|
+
function mapDukeFormControlKind(kind) {
|
|
5055
|
+
switch (kind.kind) {
|
|
5056
|
+
case "button":
|
|
5057
|
+
return { caption: kind.caption, kind: "button", label: normalizeControlLabel(kind.caption) };
|
|
5058
|
+
case "checkbox":
|
|
5059
|
+
return {
|
|
5060
|
+
caption: kind.caption,
|
|
5061
|
+
checked: kind.state === "checked",
|
|
5062
|
+
kind: "checkbox",
|
|
5063
|
+
label: normalizeControlLabel(kind.caption),
|
|
5064
|
+
linkedCell: kind.cellLink,
|
|
5065
|
+
no3D: kind.no3D,
|
|
5066
|
+
state: kind.state
|
|
5067
|
+
};
|
|
5068
|
+
case "optionButton":
|
|
5069
|
+
return {
|
|
5070
|
+
caption: kind.caption,
|
|
5071
|
+
checked: kind.state === "checked",
|
|
5072
|
+
firstInGroup: kind.firstInGroup,
|
|
5073
|
+
kind: "radio",
|
|
5074
|
+
label: normalizeControlLabel(kind.caption),
|
|
5075
|
+
linkedCell: kind.cellLink,
|
|
5076
|
+
no3D: kind.no3D,
|
|
5077
|
+
state: kind.state
|
|
5078
|
+
};
|
|
5079
|
+
case "label":
|
|
5080
|
+
return { caption: kind.caption, kind: "label", label: normalizeControlLabel(kind.caption) };
|
|
5081
|
+
case "groupBox":
|
|
5082
|
+
return {
|
|
5083
|
+
caption: kind.caption,
|
|
5084
|
+
kind: "group-box",
|
|
5085
|
+
label: normalizeControlLabel(kind.caption),
|
|
5086
|
+
no3D: kind.no3D
|
|
5087
|
+
};
|
|
5088
|
+
case "listBox":
|
|
5089
|
+
return {
|
|
5090
|
+
inputRange: kind.inputRange,
|
|
5091
|
+
kind: "listbox",
|
|
5092
|
+
linkedCell: kind.cellLink,
|
|
5093
|
+
no3D: kind.no3D,
|
|
5094
|
+
selected: [...kind.selected],
|
|
5095
|
+
selection: kind.selection
|
|
5096
|
+
};
|
|
5097
|
+
case "dropdown":
|
|
5098
|
+
return {
|
|
5099
|
+
inputRange: kind.inputRange,
|
|
5100
|
+
kind: "dropdown",
|
|
5101
|
+
lines: kind.lines,
|
|
5102
|
+
linkedCell: kind.cellLink,
|
|
5103
|
+
no3D: kind.no3D,
|
|
5104
|
+
selected: kind.selected
|
|
5105
|
+
};
|
|
5106
|
+
case "scrollbar":
|
|
5107
|
+
return {
|
|
5108
|
+
horizontal: kind.horizontal,
|
|
5109
|
+
increment: kind.increment,
|
|
5110
|
+
kind: "scrollbar",
|
|
5111
|
+
linkedCell: kind.cellLink,
|
|
5112
|
+
max: kind.max,
|
|
5113
|
+
min: kind.min,
|
|
5114
|
+
page: kind.page,
|
|
5115
|
+
value: kind.value
|
|
5116
|
+
};
|
|
5117
|
+
case "spinner":
|
|
5118
|
+
return {
|
|
5119
|
+
increment: kind.increment,
|
|
5120
|
+
kind: "spinner",
|
|
5121
|
+
linkedCell: kind.cellLink,
|
|
5122
|
+
max: kind.max,
|
|
5123
|
+
min: kind.min,
|
|
5124
|
+
value: kind.value
|
|
5125
|
+
};
|
|
5126
|
+
}
|
|
5127
|
+
}
|
|
5128
|
+
function mapDukeFormControl(control, controlIndex, workbookSheetIndex) {
|
|
5129
|
+
return {
|
|
5130
|
+
anchor: mapDukeFormControlAnchor(control.anchor),
|
|
5131
|
+
controlIndex,
|
|
5132
|
+
dukeAnchor: { ...control.anchor },
|
|
5133
|
+
editAs: control.anchor.editAs,
|
|
5134
|
+
hidden: false,
|
|
5135
|
+
id: `form-control-${workbookSheetIndex}-${controlIndex}`,
|
|
5136
|
+
locked: control.locked,
|
|
5137
|
+
name: control.name,
|
|
5138
|
+
printable: control.printable,
|
|
5139
|
+
sheetIndex: workbookSheetIndex,
|
|
5140
|
+
workbookSheetIndex,
|
|
5141
|
+
zIndex: controlIndex + 1,
|
|
5142
|
+
...mapDukeFormControlKind(control.kind)
|
|
5143
|
+
};
|
|
5144
|
+
}
|
|
5145
|
+
function collectWorkbookFormControls(workbook) {
|
|
5146
|
+
return Array.from({ length: workbook.sheetCount }, (_, workbookSheetIndex) => {
|
|
5147
|
+
try {
|
|
5148
|
+
const controls = workbook.getSheet(workbookSheetIndex).formControls;
|
|
5149
|
+
return Array.isArray(controls) ? controls.map((control, controlIndex) => mapDukeFormControl(control, controlIndex, workbookSheetIndex)) : [];
|
|
5150
|
+
} catch {
|
|
5151
|
+
return [];
|
|
5152
|
+
}
|
|
5153
|
+
});
|
|
5154
|
+
}
|
|
5038
5155
|
function parseFormControlKind(rawType) {
|
|
5039
5156
|
const normalized = (rawType ?? "").trim().toLowerCase();
|
|
5040
5157
|
switch (normalized) {
|
|
@@ -5800,27 +5917,10 @@ function parseSheetFormControlNodes(archive, sheetPath) {
|
|
|
5800
5917
|
}
|
|
5801
5918
|
return getLocalElements(sheetDocument, "control").map((controlNode) => ({
|
|
5802
5919
|
anchor: parseAnchor(getFirstDescendant(controlNode, "anchor") ?? controlNode),
|
|
5803
|
-
controlRelationshipId: getRelationshipId(controlNode),
|
|
5804
5920
|
name: controlNode.getAttribute("name") ?? void 0,
|
|
5805
5921
|
shapeId: parseFormControlShapeId(controlNode.getAttribute("shapeId"))
|
|
5806
5922
|
}));
|
|
5807
5923
|
}
|
|
5808
|
-
function parseCtrlPropDocument(archive, ctrlPropPath) {
|
|
5809
|
-
const xml = readArchiveText2(archive, ctrlPropPath);
|
|
5810
|
-
if (!xml) {
|
|
5811
|
-
return null;
|
|
5812
|
-
}
|
|
5813
|
-
const document2 = parseXml2(xml);
|
|
5814
|
-
const root = document2?.documentElement;
|
|
5815
|
-
if (!root) {
|
|
5816
|
-
return null;
|
|
5817
|
-
}
|
|
5818
|
-
return {
|
|
5819
|
-
checked: parseSpreadsheetBooleanValue(root.getAttribute("checked")),
|
|
5820
|
-
linkedCell: root.getAttribute("fmlaLink") ?? void 0,
|
|
5821
|
-
objectType: root.getAttribute("objectType") ?? void 0
|
|
5822
|
-
};
|
|
5823
|
-
}
|
|
5824
5924
|
function parseVmlFormControls(archive, vmlDrawingPath) {
|
|
5825
5925
|
const xml = readArchiveText2(archive, vmlDrawingPath);
|
|
5826
5926
|
if (!xml) {
|
|
@@ -5878,21 +5978,18 @@ function parseSheetFormControls(archive, sheetPath, sheetRelationships, workbook
|
|
|
5878
5978
|
if (!controlNode.anchor) {
|
|
5879
5979
|
return;
|
|
5880
5980
|
}
|
|
5881
|
-
const ctrlPropRelationship = controlNode.controlRelationshipId ? sheetRelationships.get(controlNode.controlRelationshipId) ?? null : null;
|
|
5882
|
-
const ctrlPropPath = ctrlPropRelationship?.type === CTRL_PROP_REL_TYPE ? ctrlPropRelationship.target : null;
|
|
5883
|
-
const ctrlProp = ctrlPropPath ? parseCtrlPropDocument(archive, ctrlPropPath) : null;
|
|
5884
5981
|
const vmlControl = controlNode.shapeId !== null ? vmlControlsByShapeId.get(controlNode.shapeId) ?? null : null;
|
|
5885
|
-
const kind = parseFormControlKind(
|
|
5982
|
+
const kind = parseFormControlKind(vmlControl?.objectType);
|
|
5886
5983
|
parsedControls.push({
|
|
5887
5984
|
anchor: controlNode.anchor,
|
|
5888
|
-
checked:
|
|
5985
|
+
checked: vmlControl?.checked,
|
|
5889
5986
|
fontFamily: vmlControl?.fontFamily,
|
|
5890
5987
|
fontSizePt: vmlControl?.fontSizePt,
|
|
5891
5988
|
hidden: vmlControl?.hidden ?? false,
|
|
5892
5989
|
id: `form-control-${workbookSheetIndex}-${index}`,
|
|
5893
5990
|
kind,
|
|
5894
5991
|
label: vmlControl?.label,
|
|
5895
|
-
linkedCell:
|
|
5992
|
+
linkedCell: vmlControl?.linkedCell,
|
|
5896
5993
|
name: controlNode.name,
|
|
5897
5994
|
sheetIndex: workbookSheetIndex,
|
|
5898
5995
|
textAlign: vmlControl?.textAlign,
|
|
@@ -5978,6 +6075,92 @@ function enrichFormControlsWithHiddenShapes(formControls, shapes, sheetState) {
|
|
|
5978
6075
|
};
|
|
5979
6076
|
});
|
|
5980
6077
|
}
|
|
6078
|
+
function getFormControlAnchorStart(anchor) {
|
|
6079
|
+
return anchor.kind === "absolute" ? null : { col: anchor.from.col, row: anchor.from.row };
|
|
6080
|
+
}
|
|
6081
|
+
function scoreParsedFormControlMatch(dukeControl, parsedControl, parsedIndex) {
|
|
6082
|
+
if (dukeControl.kind !== parsedControl.kind && parsedControl.kind !== "unknown") {
|
|
6083
|
+
return Number.NEGATIVE_INFINITY;
|
|
6084
|
+
}
|
|
6085
|
+
let score = 10;
|
|
6086
|
+
const dukeName = normalizeControlLabel(dukeControl.name)?.toLowerCase();
|
|
6087
|
+
const parsedName = normalizeControlLabel(parsedControl.name)?.toLowerCase();
|
|
6088
|
+
if (dukeName && parsedName) {
|
|
6089
|
+
if (dukeName !== parsedName) {
|
|
6090
|
+
return Number.NEGATIVE_INFINITY;
|
|
6091
|
+
}
|
|
6092
|
+
score += 100;
|
|
6093
|
+
}
|
|
6094
|
+
const dukeStart = getFormControlAnchorStart(dukeControl.anchor);
|
|
6095
|
+
const parsedStart = getFormControlAnchorStart(parsedControl.anchor);
|
|
6096
|
+
if (dukeStart && parsedStart && dukeStart.col === parsedStart.col && dukeStart.row === parsedStart.row) {
|
|
6097
|
+
score += 40;
|
|
6098
|
+
}
|
|
6099
|
+
if (dukeControl.controlIndex === parsedIndex) {
|
|
6100
|
+
score += 5;
|
|
6101
|
+
}
|
|
6102
|
+
return score;
|
|
6103
|
+
}
|
|
6104
|
+
function areDukeFormControlAnchorsEqual(left, right) {
|
|
6105
|
+
if (!left || !right) {
|
|
6106
|
+
return true;
|
|
6107
|
+
}
|
|
6108
|
+
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;
|
|
6109
|
+
}
|
|
6110
|
+
function mergeDukeAndParsedFormControls(dukeControls, parsedControls, keepUnmatchedParsedControl = () => true) {
|
|
6111
|
+
const usedParsedIndexes = /* @__PURE__ */ new Set();
|
|
6112
|
+
const mergedControls = dukeControls.map((dukeControl) => {
|
|
6113
|
+
let bestIndex = -1;
|
|
6114
|
+
let bestScore = Number.NEGATIVE_INFINITY;
|
|
6115
|
+
parsedControls.forEach((parsedControl2, parsedIndex) => {
|
|
6116
|
+
if (usedParsedIndexes.has(parsedIndex)) {
|
|
6117
|
+
return;
|
|
6118
|
+
}
|
|
6119
|
+
const score = scoreParsedFormControlMatch(dukeControl, parsedControl2, parsedIndex);
|
|
6120
|
+
if (score > bestScore) {
|
|
6121
|
+
bestIndex = parsedIndex;
|
|
6122
|
+
bestScore = score;
|
|
6123
|
+
}
|
|
6124
|
+
});
|
|
6125
|
+
const parsedControl = bestIndex >= 0 && bestScore >= 10 ? parsedControls[bestIndex] : null;
|
|
6126
|
+
if (!parsedControl) {
|
|
6127
|
+
return dukeControl;
|
|
6128
|
+
}
|
|
6129
|
+
usedParsedIndexes.add(bestIndex);
|
|
6130
|
+
const dukeAnchorChanged = !areDukeFormControlAnchorsEqual(
|
|
6131
|
+
parsedControl.dukeAnchor,
|
|
6132
|
+
dukeControl.dukeAnchor
|
|
6133
|
+
);
|
|
6134
|
+
return {
|
|
6135
|
+
...parsedControl,
|
|
6136
|
+
...dukeControl,
|
|
6137
|
+
anchor: dukeAnchorChanged ? dukeControl.anchor : parsedControl.anchor,
|
|
6138
|
+
fontFamily: parsedControl.fontFamily,
|
|
6139
|
+
fontSizePt: parsedControl.fontSizePt,
|
|
6140
|
+
hidden: parsedControl.hidden,
|
|
6141
|
+
id: parsedControl.id,
|
|
6142
|
+
label: dukeControl.label ?? parsedControl.label,
|
|
6143
|
+
name: dukeControl.name ?? parsedControl.name,
|
|
6144
|
+
textAlign: parsedControl.textAlign,
|
|
6145
|
+
textColor: parsedControl.textColor,
|
|
6146
|
+
zIndex: parsedControl.zIndex
|
|
6147
|
+
};
|
|
6148
|
+
});
|
|
6149
|
+
parsedControls.forEach((parsedControl, parsedIndex) => {
|
|
6150
|
+
if (!usedParsedIndexes.has(parsedIndex) && keepUnmatchedParsedControl(parsedControl)) {
|
|
6151
|
+
mergedControls.push(parsedControl);
|
|
6152
|
+
}
|
|
6153
|
+
});
|
|
6154
|
+
return mergedControls.sort((left, right) => left.zIndex - right.zIndex);
|
|
6155
|
+
}
|
|
6156
|
+
function refreshWorkbookFormControls(workbook, currentControlsByWorkbookSheetIndex) {
|
|
6157
|
+
const dukeControlsByWorkbookSheetIndex = collectWorkbookFormControls(workbook);
|
|
6158
|
+
return dukeControlsByWorkbookSheetIndex.map((dukeControls, workbookSheetIndex) => mergeDukeAndParsedFormControls(
|
|
6159
|
+
dukeControls,
|
|
6160
|
+
currentControlsByWorkbookSheetIndex[workbookSheetIndex] ?? [],
|
|
6161
|
+
(control) => control.controlIndex === void 0
|
|
6162
|
+
));
|
|
6163
|
+
}
|
|
5981
6164
|
function revokeWorkbookImageAssets(assets) {
|
|
5982
6165
|
if (!assets) {
|
|
5983
6166
|
return;
|
|
@@ -6010,7 +6193,7 @@ function parseWorkbookStructureAssetsFromArchive(archive, options) {
|
|
|
6010
6193
|
workbookSheets
|
|
6011
6194
|
};
|
|
6012
6195
|
}
|
|
6013
|
-
function parseWorkbookImageAssets(bytes) {
|
|
6196
|
+
function parseWorkbookImageAssets(bytes, workbookOrFormControls) {
|
|
6014
6197
|
const archive = unzipSync(bytes);
|
|
6015
6198
|
const {
|
|
6016
6199
|
contentTypes,
|
|
@@ -6029,6 +6212,7 @@ function parseWorkbookImageAssets(bytes) {
|
|
|
6029
6212
|
const shapesByWorkbookSheetIndex = [];
|
|
6030
6213
|
const sheetOrigins = [];
|
|
6031
6214
|
const imageOriginsById = /* @__PURE__ */ new Map();
|
|
6215
|
+
const dukeFormControlsByWorkbookSheetIndex = Array.isArray(workbookOrFormControls) ? workbookOrFormControls : collectWorkbookFormControls(workbookOrFormControls);
|
|
6032
6216
|
workbookSheets.forEach((sheet, workbookSheetIndex) => {
|
|
6033
6217
|
const sheetRelationships = parseRelationships(archive, relsPathForDocument(sheet.path), sheet.path);
|
|
6034
6218
|
const attachments = [];
|
|
@@ -6074,7 +6258,10 @@ function parseWorkbookImageAssets(bytes) {
|
|
|
6074
6258
|
shapeList,
|
|
6075
6259
|
sheetStatesByWorkbookSheetIndex[workbookSheetIndex] ?? null
|
|
6076
6260
|
);
|
|
6077
|
-
formControlsByWorkbookSheetIndex[workbookSheetIndex] =
|
|
6261
|
+
formControlsByWorkbookSheetIndex[workbookSheetIndex] = mergeDukeAndParsedFormControls(
|
|
6262
|
+
dukeFormControlsByWorkbookSheetIndex[workbookSheetIndex] ?? [],
|
|
6263
|
+
enrichedFormControlList
|
|
6264
|
+
);
|
|
6078
6265
|
imagesByWorkbookSheetIndex[workbookSheetIndex] = imageList;
|
|
6079
6266
|
shapesByWorkbookSheetIndex[workbookSheetIndex] = visibleShapeList;
|
|
6080
6267
|
sheetOrigins[workbookSheetIndex] = attachments.length > 0 ? {
|
|
@@ -7148,6 +7335,144 @@ function parseA1RangeReference2(reference) {
|
|
|
7148
7335
|
}
|
|
7149
7336
|
return normalizeRange({ start, end });
|
|
7150
7337
|
}
|
|
7338
|
+
function resolveWorkbookReference(workbook, defaultWorkbookSheetIndex, rawReference, resolvingNamedRange = false) {
|
|
7339
|
+
const reference = rawReference.trim().replace(/^=/, "");
|
|
7340
|
+
if (!reference) {
|
|
7341
|
+
return null;
|
|
7342
|
+
}
|
|
7343
|
+
let workbookSheetIndex = defaultWorkbookSheetIndex;
|
|
7344
|
+
let rangeReference = reference;
|
|
7345
|
+
const bangIndex = reference.lastIndexOf("!");
|
|
7346
|
+
if (bangIndex >= 0) {
|
|
7347
|
+
let sheetName = reference.slice(0, bangIndex).trim();
|
|
7348
|
+
rangeReference = reference.slice(bangIndex + 1).trim();
|
|
7349
|
+
if (sheetName.startsWith("'") && sheetName.endsWith("'")) {
|
|
7350
|
+
sheetName = sheetName.slice(1, -1).replace(/''/g, "'");
|
|
7351
|
+
}
|
|
7352
|
+
const resolvedSheetIndex = workbook.sheetIndex(sheetName);
|
|
7353
|
+
if (resolvedSheetIndex === void 0) {
|
|
7354
|
+
return null;
|
|
7355
|
+
}
|
|
7356
|
+
workbookSheetIndex = resolvedSheetIndex;
|
|
7357
|
+
} else if (!resolvingNamedRange) {
|
|
7358
|
+
const namedRange = workbook.getNamedRange(reference);
|
|
7359
|
+
if (namedRange) {
|
|
7360
|
+
return resolveWorkbookReference(workbook, defaultWorkbookSheetIndex, namedRange, true);
|
|
7361
|
+
}
|
|
7362
|
+
}
|
|
7363
|
+
const range = parseA1RangeReference2(rangeReference.replace(/\$/g, ""));
|
|
7364
|
+
if (!range || workbookSheetIndex < 0 || workbookSheetIndex >= workbook.sheetCount) {
|
|
7365
|
+
return null;
|
|
7366
|
+
}
|
|
7367
|
+
try {
|
|
7368
|
+
return {
|
|
7369
|
+
range,
|
|
7370
|
+
workbookSheetIndex,
|
|
7371
|
+
worksheet: workbook.getSheet(workbookSheetIndex)
|
|
7372
|
+
};
|
|
7373
|
+
} catch {
|
|
7374
|
+
return null;
|
|
7375
|
+
}
|
|
7376
|
+
}
|
|
7377
|
+
function formControlInputFromDukeControl(control) {
|
|
7378
|
+
return {
|
|
7379
|
+
anchor: { ...control.anchor },
|
|
7380
|
+
kind: { ...control.kind },
|
|
7381
|
+
locked: control.locked,
|
|
7382
|
+
name: control.name,
|
|
7383
|
+
printable: control.printable
|
|
7384
|
+
};
|
|
7385
|
+
}
|
|
7386
|
+
function getFormControlCellLink(kind) {
|
|
7387
|
+
return "cellLink" in kind ? kind.cellLink : void 0;
|
|
7388
|
+
}
|
|
7389
|
+
function anchorContainsControl(group, control) {
|
|
7390
|
+
const groupAnchor = group.anchor;
|
|
7391
|
+
const controlAnchor = control.anchor;
|
|
7392
|
+
return controlAnchor.fromCol >= groupAnchor.fromCol && controlAnchor.fromCol <= groupAnchor.toCol && controlAnchor.fromRow >= groupAnchor.fromRow && controlAnchor.fromRow <= groupAnchor.toRow;
|
|
7393
|
+
}
|
|
7394
|
+
function resolveOptionButtonGroupIndexes(controls, targetIndex) {
|
|
7395
|
+
const target = controls[targetIndex];
|
|
7396
|
+
if (!target || target.kind.kind !== "optionButton") {
|
|
7397
|
+
return [];
|
|
7398
|
+
}
|
|
7399
|
+
if (target.kind.cellLink) {
|
|
7400
|
+
const targetCellLink = target.kind.cellLink;
|
|
7401
|
+
return controls.flatMap((control, index) => control.kind.kind === "optionButton" && control.kind.cellLink === targetCellLink ? [index] : []);
|
|
7402
|
+
}
|
|
7403
|
+
const containingGroups = controls.map((control, index) => ({ control, index })).filter(({ control }) => control.kind.kind === "groupBox" && anchorContainsControl(control, target)).sort((left, right) => {
|
|
7404
|
+
const leftArea = (left.control.anchor.toCol - left.control.anchor.fromCol) * (left.control.anchor.toRow - left.control.anchor.fromRow);
|
|
7405
|
+
const rightArea = (right.control.anchor.toCol - right.control.anchor.fromCol) * (right.control.anchor.toRow - right.control.anchor.fromRow);
|
|
7406
|
+
return leftArea - rightArea;
|
|
7407
|
+
});
|
|
7408
|
+
const containingGroup = containingGroups[0]?.control;
|
|
7409
|
+
if (containingGroup) {
|
|
7410
|
+
return controls.flatMap((control, index) => control.kind.kind === "optionButton" && anchorContainsControl(containingGroup, control) ? [index] : []);
|
|
7411
|
+
}
|
|
7412
|
+
const optionIndexes = controls.flatMap((control, index) => control.kind.kind === "optionButton" ? [index] : []);
|
|
7413
|
+
const targetPosition = optionIndexes.indexOf(targetIndex);
|
|
7414
|
+
if (targetPosition < 0) {
|
|
7415
|
+
return [];
|
|
7416
|
+
}
|
|
7417
|
+
let startPosition = targetPosition;
|
|
7418
|
+
while (startPosition > 0) {
|
|
7419
|
+
const control = controls[optionIndexes[startPosition] ?? -1];
|
|
7420
|
+
if (control?.kind.kind === "optionButton" && control.kind.firstInGroup) {
|
|
7421
|
+
break;
|
|
7422
|
+
}
|
|
7423
|
+
startPosition -= 1;
|
|
7424
|
+
}
|
|
7425
|
+
let endPosition = targetPosition + 1;
|
|
7426
|
+
while (endPosition < optionIndexes.length) {
|
|
7427
|
+
const control = controls[optionIndexes[endPosition] ?? -1];
|
|
7428
|
+
if (control?.kind.kind === "optionButton" && control.kind.firstInGroup) {
|
|
7429
|
+
break;
|
|
7430
|
+
}
|
|
7431
|
+
endPosition += 1;
|
|
7432
|
+
}
|
|
7433
|
+
return optionIndexes.slice(startPosition, endPosition);
|
|
7434
|
+
}
|
|
7435
|
+
function resolveLinkedCellValue(controls, controlIndex) {
|
|
7436
|
+
const control = controls[controlIndex];
|
|
7437
|
+
if (!control) {
|
|
7438
|
+
return void 0;
|
|
7439
|
+
}
|
|
7440
|
+
switch (control.kind.kind) {
|
|
7441
|
+
case "checkbox":
|
|
7442
|
+
return control.kind.state === "mixed" ? "#N/A" : control.kind.state === "checked";
|
|
7443
|
+
case "optionButton": {
|
|
7444
|
+
const groupIndexes = resolveOptionButtonGroupIndexes(controls, controlIndex);
|
|
7445
|
+
const checkedIndex = groupIndexes.find((index) => controls[index]?.kind.kind === "optionButton" && controls[index]?.kind.state === "checked");
|
|
7446
|
+
const groupPosition = checkedIndex === void 0 ? -1 : groupIndexes.indexOf(checkedIndex);
|
|
7447
|
+
return groupPosition >= 0 ? groupPosition + 1 : "";
|
|
7448
|
+
}
|
|
7449
|
+
case "dropdown":
|
|
7450
|
+
return control.kind.selected === void 0 ? "" : control.kind.selected + 1;
|
|
7451
|
+
case "listBox":
|
|
7452
|
+
return control.kind.selection === "single" && control.kind.selected.length === 1 ? (control.kind.selected[0] ?? -1) + 1 : "";
|
|
7453
|
+
case "scrollbar":
|
|
7454
|
+
case "spinner":
|
|
7455
|
+
return control.kind.value;
|
|
7456
|
+
default:
|
|
7457
|
+
return void 0;
|
|
7458
|
+
}
|
|
7459
|
+
}
|
|
7460
|
+
function syncFormControlLinkedCell(workbook, workbookSheetIndex, controls, controlIndex) {
|
|
7461
|
+
const control = controls[controlIndex];
|
|
7462
|
+
if (!control) {
|
|
7463
|
+
return;
|
|
7464
|
+
}
|
|
7465
|
+
const cellLink = getFormControlCellLink(control.kind);
|
|
7466
|
+
const value = resolveLinkedCellValue(controls, controlIndex);
|
|
7467
|
+
if (!cellLink || value === void 0) {
|
|
7468
|
+
return;
|
|
7469
|
+
}
|
|
7470
|
+
const target = resolveWorkbookReference(workbook, workbookSheetIndex, cellLink);
|
|
7471
|
+
if (!target || target.range.start.row !== target.range.end.row || target.range.start.col !== target.range.end.col) {
|
|
7472
|
+
return;
|
|
7473
|
+
}
|
|
7474
|
+
target.worksheet.setCell(cellAddressToA1(target.range.start), value);
|
|
7475
|
+
}
|
|
7151
7476
|
function parseWorksheetFreezePanes(worksheet) {
|
|
7152
7477
|
const rawFreezePanes = worksheet.freezePanes;
|
|
7153
7478
|
const row = typeof rawFreezePanes?.row === "number" && rawFreezePanes.row >= 0 ? rawFreezePanes.row : null;
|
|
@@ -7914,7 +8239,7 @@ function createBasicWorkbookAssets(workbook) {
|
|
|
7914
8239
|
const objectUrls = [];
|
|
7915
8240
|
return {
|
|
7916
8241
|
archive: {},
|
|
7917
|
-
formControlsByWorkbookSheetIndex:
|
|
8242
|
+
formControlsByWorkbookSheetIndex: collectWorkbookFormControls(workbook),
|
|
7918
8243
|
imageOriginsById: /* @__PURE__ */ new Map(),
|
|
7919
8244
|
imagesByWorkbookSheetIndex: collectWorksheetApiImages(workbook, objectUrls),
|
|
7920
8245
|
namedCellStyleByName: {},
|
|
@@ -7932,7 +8257,7 @@ function loadWorkbookImageAssets(bytes, workbook, skipXmlParsing = false) {
|
|
|
7932
8257
|
if (shouldSkipXmlParsingForWorkbook(bytes, skipXmlParsing) || !isZipWorkbook(bytes)) {
|
|
7933
8258
|
return createBasicWorkbookAssets(workbook);
|
|
7934
8259
|
}
|
|
7935
|
-
const parsedAssets = parseWorkbookImageAssets(bytes);
|
|
8260
|
+
const parsedAssets = parseWorkbookImageAssets(bytes, workbook);
|
|
7936
8261
|
const apiImagesByWorkbookSheetIndex = collectWorksheetApiImages(workbook, parsedAssets.objectUrls);
|
|
7937
8262
|
const imagesByWorkbookSheetIndex = Array.from(
|
|
7938
8263
|
{ length: Math.max(workbook.sheetCount, parsedAssets.imagesByWorkbookSheetIndex.length, apiImagesByWorkbookSheetIndex.length) },
|
|
@@ -8249,6 +8574,12 @@ function useXlsxViewerController(options) {
|
|
|
8249
8574
|
};
|
|
8250
8575
|
}, [skipXmlParsing]);
|
|
8251
8576
|
const refreshWorkbookState = React.useCallback((targetWorkbook) => {
|
|
8577
|
+
const currentFormControls = imageAssetsRef.current?.formControlsByWorkbookSheetIndex ?? [];
|
|
8578
|
+
const nextFormControls = refreshWorkbookFormControls(targetWorkbook, currentFormControls);
|
|
8579
|
+
if (imageAssetsRef.current) {
|
|
8580
|
+
imageAssetsRef.current.formControlsByWorkbookSheetIndex = nextFormControls;
|
|
8581
|
+
}
|
|
8582
|
+
setFormControlsByWorkbookSheetIndex(nextFormControls);
|
|
8252
8583
|
const nextSheets = buildSheetList(
|
|
8253
8584
|
targetWorkbook,
|
|
8254
8585
|
imageAssetsRef.current?.sheetStatesByWorkbookSheetIndex,
|
|
@@ -8370,12 +8701,24 @@ function useXlsxViewerController(options) {
|
|
|
8370
8701
|
if (!effectiveSkipXmlParsing && hasIncompleteWorkerChartSnapshot(snapshot)) {
|
|
8371
8702
|
throw new Error("Worker chart payload incomplete");
|
|
8372
8703
|
}
|
|
8704
|
+
const workerImageAssets = effectiveSkipXmlParsing ? null : parseWorkbookImageAssets(
|
|
8705
|
+
new Uint8Array(buffer),
|
|
8706
|
+
snapshot.formControlsByWorkbookSheetIndex
|
|
8707
|
+
);
|
|
8708
|
+
if (!isCurrent || abortController.signal.aborted) {
|
|
8709
|
+
revokeWorkbookImageAssets(workerImageAssets);
|
|
8710
|
+
return;
|
|
8711
|
+
}
|
|
8712
|
+
setImageAssets(workerImageAssets);
|
|
8373
8713
|
setWorkbook(null);
|
|
8374
8714
|
setSheets(snapshot.sheets);
|
|
8375
8715
|
setChartsByWorkbookSheetIndex(snapshot.chartsByWorkbookSheetIndex);
|
|
8376
8716
|
setChartsheets(snapshot.chartsheets);
|
|
8377
8717
|
setTabs(snapshot.tabs);
|
|
8378
8718
|
chartAssetsRef.current = null;
|
|
8719
|
+
if (!workerImageAssets) {
|
|
8720
|
+
setFormControlsByWorkbookSheetIndex(snapshot.formControlsByWorkbookSheetIndex);
|
|
8721
|
+
}
|
|
8379
8722
|
setWorkerTablesByWorkbookSheetIndex(snapshot.tablesByWorkbookSheetIndex);
|
|
8380
8723
|
setShouldAutoCalculate(false);
|
|
8381
8724
|
setIsWorkerBacked(true);
|
|
@@ -8595,6 +8938,7 @@ function useXlsxViewerController(options) {
|
|
|
8595
8938
|
setChartsheets(snapshot.chartsheets);
|
|
8596
8939
|
setTabs(snapshot.tabs);
|
|
8597
8940
|
chartAssetsRef.current = null;
|
|
8941
|
+
setFormControlsByWorkbookSheetIndex(snapshot.formControlsByWorkbookSheetIndex);
|
|
8598
8942
|
setWorkerTablesByWorkbookSheetIndex(snapshot.tablesByWorkbookSheetIndex);
|
|
8599
8943
|
setShouldAutoCalculate(false);
|
|
8600
8944
|
setIsWorkerBacked(true);
|
|
@@ -8716,6 +9060,20 @@ function useXlsxViewerController(options) {
|
|
|
8716
9060
|
}
|
|
8717
9061
|
return workbook.getSheet(activeSheet.workbookSheetIndex);
|
|
8718
9062
|
}, [activeSheet, workbook]);
|
|
9063
|
+
const getFormControlWorksheet = React.useCallback((sheetIndex = activeSheetIndex) => {
|
|
9064
|
+
const targetSheet = sheets[sheetIndex];
|
|
9065
|
+
if (!workbook || !targetSheet) {
|
|
9066
|
+
return null;
|
|
9067
|
+
}
|
|
9068
|
+
try {
|
|
9069
|
+
return {
|
|
9070
|
+
workbookSheetIndex: targetSheet.workbookSheetIndex,
|
|
9071
|
+
worksheet: workbook.getSheet(targetSheet.workbookSheetIndex)
|
|
9072
|
+
};
|
|
9073
|
+
} catch {
|
|
9074
|
+
return null;
|
|
9075
|
+
}
|
|
9076
|
+
}, [activeSheetIndex, sheets, workbook]);
|
|
8719
9077
|
const tables = React.useMemo(
|
|
8720
9078
|
() => isWorkerBacked ? workerTablesByWorkbookSheetIndex[activeSheet?.workbookSheetIndex ?? -1] ?? [] : mapWorksheetTables(getActiveWorksheet()),
|
|
8721
9079
|
[activeSheet?.workbookSheetIndex, getActiveWorksheet, isWorkerBacked, revision, workerTablesByWorkbookSheetIndex]
|
|
@@ -8855,6 +9213,33 @@ function useXlsxViewerController(options) {
|
|
|
8855
9213
|
return (formControlsByWorkbookSheetIndex[targetSheet.workbookSheetIndex] ?? []).map(mapPublicFormControl);
|
|
8856
9214
|
}, [activeSheetIndex, formControlsByWorkbookSheetIndex, mapPublicFormControl, sheets]);
|
|
8857
9215
|
const formControls = React.useMemo(() => getSheetFormControls(activeSheetIndex), [activeSheetIndex, getSheetFormControls]);
|
|
9216
|
+
const getFormControlItems = React.useCallback((controlIndex, sheetIndex = activeSheetIndex) => {
|
|
9217
|
+
const target = getFormControlWorksheet(sheetIndex);
|
|
9218
|
+
if (!workbook || !target) {
|
|
9219
|
+
const targetSheet = sheets[sheetIndex];
|
|
9220
|
+
if (!targetSheet) {
|
|
9221
|
+
return [];
|
|
9222
|
+
}
|
|
9223
|
+
const control2 = (formControlsByWorkbookSheetIndex[targetSheet.workbookSheetIndex] ?? []).find((entry) => entry.controlIndex === controlIndex);
|
|
9224
|
+
return control2?.items?.slice() ?? [];
|
|
9225
|
+
}
|
|
9226
|
+
const control = target.worksheet.formControls[controlIndex];
|
|
9227
|
+
const inputRange = control?.kind.kind === "listBox" || control?.kind.kind === "dropdown" ? control.kind.inputRange : void 0;
|
|
9228
|
+
if (!inputRange) {
|
|
9229
|
+
return [];
|
|
9230
|
+
}
|
|
9231
|
+
const source = resolveWorkbookReference(workbook, target.workbookSheetIndex, inputRange);
|
|
9232
|
+
if (!source) {
|
|
9233
|
+
return [];
|
|
9234
|
+
}
|
|
9235
|
+
const items = [];
|
|
9236
|
+
for (let row = source.range.start.row; row <= source.range.end.row; row += 1) {
|
|
9237
|
+
for (let col = source.range.start.col; col <= source.range.end.col; col += 1) {
|
|
9238
|
+
items.push(source.worksheet.getFormattedValueAt(row, col));
|
|
9239
|
+
}
|
|
9240
|
+
}
|
|
9241
|
+
return items;
|
|
9242
|
+
}, [activeSheetIndex, formControlsByWorkbookSheetIndex, getFormControlWorksheet, sheets, workbook]);
|
|
8858
9243
|
const getSheetShapes = React.useCallback((sheetIndex = activeSheetIndex) => {
|
|
8859
9244
|
const targetSheet = sheets[sheetIndex];
|
|
8860
9245
|
if (!targetSheet) {
|
|
@@ -9252,6 +9637,89 @@ function useXlsxViewerController(options) {
|
|
|
9252
9637
|
redoStackRef.current = [];
|
|
9253
9638
|
setHistoryRevision((current) => current + 1);
|
|
9254
9639
|
}, [createHistoryEntry]);
|
|
9640
|
+
const addFormControl = React.useCallback((input, sheetIndex = activeSheetIndex) => {
|
|
9641
|
+
const target = getFormControlWorksheet(sheetIndex);
|
|
9642
|
+
if (readOnly || !workbook || !target) {
|
|
9643
|
+
return null;
|
|
9644
|
+
}
|
|
9645
|
+
recordHistoryBeforeMutation();
|
|
9646
|
+
const controlIndex = target.worksheet.addFormControl(input);
|
|
9647
|
+
const controls = target.worksheet.formControls;
|
|
9648
|
+
const addedControl = controls[controlIndex];
|
|
9649
|
+
if (addedControl?.kind.kind === "optionButton" && addedControl.kind.state === "checked") {
|
|
9650
|
+
const groupIndexes = resolveOptionButtonGroupIndexes(controls, controlIndex);
|
|
9651
|
+
for (const siblingIndex of groupIndexes) {
|
|
9652
|
+
if (siblingIndex === controlIndex) {
|
|
9653
|
+
continue;
|
|
9654
|
+
}
|
|
9655
|
+
const sibling = target.worksheet.formControls[siblingIndex];
|
|
9656
|
+
if (sibling?.kind.kind === "optionButton" && sibling.kind.state !== "unchecked") {
|
|
9657
|
+
target.worksheet.setFormControl(siblingIndex, {
|
|
9658
|
+
...formControlInputFromDukeControl(sibling),
|
|
9659
|
+
kind: { ...sibling.kind, state: "unchecked" }
|
|
9660
|
+
});
|
|
9661
|
+
}
|
|
9662
|
+
}
|
|
9663
|
+
}
|
|
9664
|
+
syncFormControlLinkedCell(
|
|
9665
|
+
workbook,
|
|
9666
|
+
target.workbookSheetIndex,
|
|
9667
|
+
target.worksheet.formControls,
|
|
9668
|
+
controlIndex
|
|
9669
|
+
);
|
|
9670
|
+
maybeRecalculateWorkbook(workbook);
|
|
9671
|
+
refreshWorkbookState(workbook);
|
|
9672
|
+
return controlIndex;
|
|
9673
|
+
}, [activeSheetIndex, getFormControlWorksheet, maybeRecalculateWorkbook, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
9674
|
+
const updateFormControl = React.useCallback((controlIndex, patch, sheetIndex = activeSheetIndex) => {
|
|
9675
|
+
const target = getFormControlWorksheet(sheetIndex);
|
|
9676
|
+
const currentControl = target?.worksheet.formControls[controlIndex];
|
|
9677
|
+
if (readOnly || !workbook || !target || !currentControl) {
|
|
9678
|
+
return false;
|
|
9679
|
+
}
|
|
9680
|
+
recordHistoryBeforeMutation();
|
|
9681
|
+
const nextInput = {
|
|
9682
|
+
...formControlInputFromDukeControl(currentControl),
|
|
9683
|
+
...patch,
|
|
9684
|
+
anchor: patch.anchor ? { ...patch.anchor } : { ...currentControl.anchor },
|
|
9685
|
+
kind: patch.kind ? { ...patch.kind } : { ...currentControl.kind }
|
|
9686
|
+
};
|
|
9687
|
+
if (nextInput.kind.kind === "optionButton" && nextInput.kind.state === "checked") {
|
|
9688
|
+
const groupIndexes = resolveOptionButtonGroupIndexes(target.worksheet.formControls, controlIndex);
|
|
9689
|
+
for (const siblingIndex of groupIndexes) {
|
|
9690
|
+
if (siblingIndex === controlIndex) {
|
|
9691
|
+
continue;
|
|
9692
|
+
}
|
|
9693
|
+
const sibling = target.worksheet.formControls[siblingIndex];
|
|
9694
|
+
if (sibling?.kind.kind === "optionButton" && sibling.kind.state !== "unchecked") {
|
|
9695
|
+
target.worksheet.setFormControl(siblingIndex, {
|
|
9696
|
+
...formControlInputFromDukeControl(sibling),
|
|
9697
|
+
kind: { ...sibling.kind, state: "unchecked" }
|
|
9698
|
+
});
|
|
9699
|
+
}
|
|
9700
|
+
}
|
|
9701
|
+
}
|
|
9702
|
+
target.worksheet.setFormControl(controlIndex, nextInput);
|
|
9703
|
+
syncFormControlLinkedCell(
|
|
9704
|
+
workbook,
|
|
9705
|
+
target.workbookSheetIndex,
|
|
9706
|
+
target.worksheet.formControls,
|
|
9707
|
+
controlIndex
|
|
9708
|
+
);
|
|
9709
|
+
maybeRecalculateWorkbook(workbook);
|
|
9710
|
+
refreshWorkbookState(workbook);
|
|
9711
|
+
return true;
|
|
9712
|
+
}, [activeSheetIndex, getFormControlWorksheet, maybeRecalculateWorkbook, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
9713
|
+
const removeFormControl = React.useCallback((controlIndex, sheetIndex = activeSheetIndex) => {
|
|
9714
|
+
const target = getFormControlWorksheet(sheetIndex);
|
|
9715
|
+
if (readOnly || !workbook || !target || !target.worksheet.formControls[controlIndex]) {
|
|
9716
|
+
return false;
|
|
9717
|
+
}
|
|
9718
|
+
recordHistoryBeforeMutation();
|
|
9719
|
+
target.worksheet.removeFormControl(controlIndex);
|
|
9720
|
+
refreshWorkbookState(workbook);
|
|
9721
|
+
return true;
|
|
9722
|
+
}, [activeSheetIndex, getFormControlWorksheet, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
9255
9723
|
const recordCellEditHistory = React.useCallback((cell, before, after) => {
|
|
9256
9724
|
if (!activeSheet || isApplyingHistoryRef.current) {
|
|
9257
9725
|
return;
|
|
@@ -10060,8 +10528,15 @@ function useXlsxViewerController(options) {
|
|
|
10060
10528
|
}
|
|
10061
10529
|
workbook.addSheet(candidate);
|
|
10062
10530
|
sheetOriginsRef.current = [...sheetOriginsRef.current, null];
|
|
10531
|
+
setFormControlsByWorkbookSheetIndex((current) => [...current, []]);
|
|
10063
10532
|
setImagesByWorkbookSheetIndex((current) => [...current, []]);
|
|
10064
10533
|
setShapesByWorkbookSheetIndex((current) => [...current, []]);
|
|
10534
|
+
if (imageAssetsRef.current) {
|
|
10535
|
+
imageAssetsRef.current.formControlsByWorkbookSheetIndex = [
|
|
10536
|
+
...imageAssetsRef.current.formControlsByWorkbookSheetIndex,
|
|
10537
|
+
[]
|
|
10538
|
+
];
|
|
10539
|
+
}
|
|
10065
10540
|
const nextSheets = buildSheetList(
|
|
10066
10541
|
workbook,
|
|
10067
10542
|
imageAssetsRef.current?.sheetStatesByWorkbookSheetIndex,
|
|
@@ -10091,9 +10566,13 @@ function useXlsxViewerController(options) {
|
|
|
10091
10566
|
recordHistoryBeforeMutation();
|
|
10092
10567
|
workbook.removeSheet(activeSheet.workbookSheetIndex);
|
|
10093
10568
|
sheetOriginsRef.current = sheetOriginsRef.current.filter((_, index) => index !== activeSheet.workbookSheetIndex);
|
|
10569
|
+
setFormControlsByWorkbookSheetIndex((current) => current.filter((_, index) => index !== activeSheet.workbookSheetIndex));
|
|
10094
10570
|
setImagesByWorkbookSheetIndex((current) => current.filter((_, index) => index !== activeSheet.workbookSheetIndex));
|
|
10095
10571
|
setShapesByWorkbookSheetIndex((current) => current.filter((_, index) => index !== activeSheet.workbookSheetIndex));
|
|
10096
10572
|
if (imageAssetsRef.current) {
|
|
10573
|
+
imageAssetsRef.current.formControlsByWorkbookSheetIndex = imageAssetsRef.current.formControlsByWorkbookSheetIndex.filter(
|
|
10574
|
+
(_, index) => index !== activeSheet.workbookSheetIndex
|
|
10575
|
+
);
|
|
10097
10576
|
imageAssetsRef.current.sheetStatesByWorkbookSheetIndex = imageAssetsRef.current.sheetStatesByWorkbookSheetIndex.filter(
|
|
10098
10577
|
(_, index) => index !== activeSheet.workbookSheetIndex
|
|
10099
10578
|
);
|
|
@@ -10394,6 +10873,7 @@ function useXlsxViewerController(options) {
|
|
|
10394
10873
|
activeSheetIndex,
|
|
10395
10874
|
activeTab,
|
|
10396
10875
|
activeTabIndex,
|
|
10876
|
+
addFormControl,
|
|
10397
10877
|
addSheet,
|
|
10398
10878
|
canRedo,
|
|
10399
10879
|
canDownload: Boolean(file ?? src),
|
|
@@ -10433,6 +10913,7 @@ function useXlsxViewerController(options) {
|
|
|
10433
10913
|
getClipboardData,
|
|
10434
10914
|
getCellDisplayValue: getCellDisplayValue2,
|
|
10435
10915
|
getCellFormula,
|
|
10916
|
+
getFormControlItems,
|
|
10436
10917
|
getCellSnapshotAsync: isWorkerBacked ? getCellSnapshotAsync : void 0,
|
|
10437
10918
|
getActiveWorksheet,
|
|
10438
10919
|
getRowsBatchAsync: isWorkerBacked ? getRowsBatchAsync : void 0,
|
|
@@ -10450,6 +10931,7 @@ function useXlsxViewerController(options) {
|
|
|
10450
10931
|
pasteStructuredClipboardData,
|
|
10451
10932
|
pasteText,
|
|
10452
10933
|
removeActiveSheet,
|
|
10934
|
+
removeFormControl,
|
|
10453
10935
|
readOnly,
|
|
10454
10936
|
recalculate,
|
|
10455
10937
|
redo,
|
|
@@ -10500,6 +10982,7 @@ function useXlsxViewerController(options) {
|
|
|
10500
10982
|
undo,
|
|
10501
10983
|
unmergeSelection,
|
|
10502
10984
|
updateChart,
|
|
10985
|
+
updateFormControl,
|
|
10503
10986
|
workbook,
|
|
10504
10987
|
zoomIn,
|
|
10505
10988
|
zoomOut,
|
|
@@ -10512,6 +10995,7 @@ function useXlsxViewerController(options) {
|
|
|
10512
10995
|
activeSheetIndex,
|
|
10513
10996
|
activeTab,
|
|
10514
10997
|
activeTabIndex,
|
|
10998
|
+
addFormControl,
|
|
10515
10999
|
addSheet,
|
|
10516
11000
|
canLoadDeferred,
|
|
10517
11001
|
canRedo,
|
|
@@ -10548,6 +11032,7 @@ function useXlsxViewerController(options) {
|
|
|
10548
11032
|
getClipboardData,
|
|
10549
11033
|
getCellDisplayValue2,
|
|
10550
11034
|
getCellFormula,
|
|
11035
|
+
getFormControlItems,
|
|
10551
11036
|
getCellSnapshotAsync,
|
|
10552
11037
|
getActiveWorksheet,
|
|
10553
11038
|
historyRevision,
|
|
@@ -10565,6 +11050,7 @@ function useXlsxViewerController(options) {
|
|
|
10565
11050
|
pasteStructuredClipboardData,
|
|
10566
11051
|
pasteText,
|
|
10567
11052
|
removeActiveSheet,
|
|
11053
|
+
removeFormControl,
|
|
10568
11054
|
readOnly,
|
|
10569
11055
|
recalculate,
|
|
10570
11056
|
redo,
|
|
@@ -10615,6 +11101,7 @@ function useXlsxViewerController(options) {
|
|
|
10615
11101
|
undo,
|
|
10616
11102
|
unmergeSelection,
|
|
10617
11103
|
updateChart,
|
|
11104
|
+
updateFormControl,
|
|
10618
11105
|
workbook,
|
|
10619
11106
|
zoomIn,
|
|
10620
11107
|
zoomOut,
|
|
@@ -20304,6 +20791,40 @@ function getCellBooleanValue(worksheet, row, col) {
|
|
|
20304
20791
|
}
|
|
20305
20792
|
return null;
|
|
20306
20793
|
}
|
|
20794
|
+
function getBatchedCellNumericValue(cell) {
|
|
20795
|
+
if (!cell) {
|
|
20796
|
+
return null;
|
|
20797
|
+
}
|
|
20798
|
+
const text = cell.value.trim();
|
|
20799
|
+
if (text.length === 0) {
|
|
20800
|
+
return null;
|
|
20801
|
+
}
|
|
20802
|
+
if (text.toLowerCase() === "true") {
|
|
20803
|
+
return 1;
|
|
20804
|
+
}
|
|
20805
|
+
if (text.toLowerCase() === "false") {
|
|
20806
|
+
return 0;
|
|
20807
|
+
}
|
|
20808
|
+
const value = Number(text.replace(/,/g, ""));
|
|
20809
|
+
return Number.isFinite(value) ? value : null;
|
|
20810
|
+
}
|
|
20811
|
+
function getBatchedCellBooleanValue(cell) {
|
|
20812
|
+
if (!cell) {
|
|
20813
|
+
return null;
|
|
20814
|
+
}
|
|
20815
|
+
const text = cell.value.trim().toLowerCase();
|
|
20816
|
+
if (text.length === 0) {
|
|
20817
|
+
return null;
|
|
20818
|
+
}
|
|
20819
|
+
if (text === "true") {
|
|
20820
|
+
return true;
|
|
20821
|
+
}
|
|
20822
|
+
if (text === "false") {
|
|
20823
|
+
return false;
|
|
20824
|
+
}
|
|
20825
|
+
const value = Number(text);
|
|
20826
|
+
return Number.isFinite(value) ? value !== 0 : null;
|
|
20827
|
+
}
|
|
20307
20828
|
function parseA1RangeReference3(reference) {
|
|
20308
20829
|
const [startRef, endRef = startRef] = reference.split(":");
|
|
20309
20830
|
const start = parseA1CellReference3(startRef ?? "");
|
|
@@ -21603,13 +22124,90 @@ function renderConditionalIcon(icon, scale = 1) {
|
|
|
21603
22124
|
}
|
|
21604
22125
|
);
|
|
21605
22126
|
}
|
|
21606
|
-
function
|
|
22127
|
+
function isFormControlChecked(control) {
|
|
22128
|
+
return control.state ? control.state === "checked" : Boolean(control.checked);
|
|
22129
|
+
}
|
|
22130
|
+
function isFormControlMixed(control) {
|
|
22131
|
+
return control.state === "mixed";
|
|
22132
|
+
}
|
|
22133
|
+
function buildFormControlKindInput(control) {
|
|
22134
|
+
switch (control.kind) {
|
|
22135
|
+
case "button":
|
|
22136
|
+
return { caption: control.caption ?? control.label ?? "", kind: "button" };
|
|
22137
|
+
case "checkbox":
|
|
22138
|
+
return {
|
|
22139
|
+
caption: control.caption ?? control.label ?? "",
|
|
22140
|
+
cellLink: control.linkedCell,
|
|
22141
|
+
kind: "checkbox",
|
|
22142
|
+
no3D: control.no3D ?? false,
|
|
22143
|
+
state: control.state ?? (control.checked ? "checked" : "unchecked")
|
|
22144
|
+
};
|
|
22145
|
+
case "radio":
|
|
22146
|
+
return {
|
|
22147
|
+
caption: control.caption ?? control.label ?? "",
|
|
22148
|
+
cellLink: control.linkedCell,
|
|
22149
|
+
firstInGroup: control.firstInGroup,
|
|
22150
|
+
kind: "optionButton",
|
|
22151
|
+
no3D: control.no3D ?? false,
|
|
22152
|
+
state: control.state === "checked" ? "checked" : "unchecked"
|
|
22153
|
+
};
|
|
22154
|
+
case "label":
|
|
22155
|
+
return { caption: control.caption ?? control.label ?? "", kind: "label" };
|
|
22156
|
+
case "group-box":
|
|
22157
|
+
return {
|
|
22158
|
+
caption: control.caption ?? control.label ?? "",
|
|
22159
|
+
kind: "groupBox",
|
|
22160
|
+
no3D: control.no3D ?? false
|
|
22161
|
+
};
|
|
22162
|
+
case "listbox":
|
|
22163
|
+
return {
|
|
22164
|
+
cellLink: control.linkedCell,
|
|
22165
|
+
inputRange: control.inputRange,
|
|
22166
|
+
kind: "listBox",
|
|
22167
|
+
no3D: control.no3D ?? false,
|
|
22168
|
+
selected: Array.isArray(control.selected) ? control.selected : control.selected === void 0 ? [] : [control.selected],
|
|
22169
|
+
selection: control.selection ?? "single"
|
|
22170
|
+
};
|
|
22171
|
+
case "dropdown":
|
|
22172
|
+
return {
|
|
22173
|
+
cellLink: control.linkedCell,
|
|
22174
|
+
inputRange: control.inputRange,
|
|
22175
|
+
kind: "dropdown",
|
|
22176
|
+
lines: control.lines ?? 8,
|
|
22177
|
+
no3D: control.no3D ?? false,
|
|
22178
|
+
selected: typeof control.selected === "number" ? control.selected : void 0
|
|
22179
|
+
};
|
|
22180
|
+
case "scrollbar":
|
|
22181
|
+
return {
|
|
22182
|
+
cellLink: control.linkedCell,
|
|
22183
|
+
horizontal: control.horizontal ?? true,
|
|
22184
|
+
increment: control.increment ?? 1,
|
|
22185
|
+
kind: "scrollbar",
|
|
22186
|
+
max: control.max ?? 100,
|
|
22187
|
+
min: control.min ?? 0,
|
|
22188
|
+
page: control.page ?? 10,
|
|
22189
|
+
value: control.value ?? control.min ?? 0
|
|
22190
|
+
};
|
|
22191
|
+
case "spinner":
|
|
22192
|
+
return {
|
|
22193
|
+
cellLink: control.linkedCell,
|
|
22194
|
+
increment: control.increment ?? 1,
|
|
22195
|
+
kind: "spinner",
|
|
22196
|
+
max: control.max ?? 100,
|
|
22197
|
+
min: control.min ?? 0,
|
|
22198
|
+
value: control.value ?? control.min ?? 0
|
|
22199
|
+
};
|
|
22200
|
+
default:
|
|
22201
|
+
return null;
|
|
22202
|
+
}
|
|
22203
|
+
}
|
|
22204
|
+
function renderCheckboxControl(checked, palette, scale = 1, mixed = false) {
|
|
21607
22205
|
const stroke = paletteIsDark(palette) ? "#cbd5e1" : "#475569";
|
|
21608
|
-
const fill = checked ? paletteIsDark(palette) ? "#60a5fa" : "#2563eb" : "transparent";
|
|
22206
|
+
const fill = checked || mixed ? paletteIsDark(palette) ? "#60a5fa" : "#2563eb" : "transparent";
|
|
21609
22207
|
const check = paletteIsDark(palette) ? "#020617" : "#ffffff";
|
|
21610
22208
|
return /* @__PURE__ */ jsxs3("svg", { "aria-hidden": "true", height: 14 * scale, style: { display: "block" }, viewBox: "0 0 16 16", width: 14 * scale, children: [
|
|
21611
22209
|
/* @__PURE__ */ jsx3("rect", { fill, height: 11, rx: 2, ry: 2, stroke, strokeWidth: 1.2, width: 11, x: 2.5, y: 2.5 }),
|
|
21612
|
-
checked ? /* @__PURE__ */ jsx3(
|
|
22210
|
+
mixed ? /* @__PURE__ */ jsx3("path", { d: "M5 8h6", fill: "none", stroke: check, strokeLinecap: "round", strokeWidth: 1.8 }) : checked ? /* @__PURE__ */ jsx3(
|
|
21613
22211
|
"path",
|
|
21614
22212
|
{
|
|
21615
22213
|
d: "M5 8.1 7.1 10.2 11.3 5.8",
|
|
@@ -21779,6 +22377,8 @@ function drawStaticFormControl(context, control, rect, palette, zoomFactor, shee
|
|
|
21779
22377
|
const textColor = control.textColor ?? "#000000";
|
|
21780
22378
|
const fontSizePx = Math.max(9 * zoomFactor, (control.fontSizePt ?? 9) * 96 / 72 * zoomFactor);
|
|
21781
22379
|
const iconSize = Math.min(14 * zoomFactor, Math.max(0, rect.height - 4 * zoomFactor));
|
|
22380
|
+
const controlChecked = isFormControlChecked(control);
|
|
22381
|
+
const controlMixed = isFormControlMixed(control);
|
|
21782
22382
|
context.save();
|
|
21783
22383
|
context.font = `400 ${fontSizePx}px ${control.fontFamily ?? "Calibri, sans-serif"}`;
|
|
21784
22384
|
context.textBaseline = "middle";
|
|
@@ -21819,14 +22419,19 @@ function drawStaticFormControl(context, control, rect, palette, zoomFactor, shee
|
|
|
21819
22419
|
const textRightInset = control.kind === "dropdown" ? 18 * zoomFactor : 6 * zoomFactor;
|
|
21820
22420
|
if (control.kind === "checkbox") {
|
|
21821
22421
|
context.strokeRect(rect.left + 2 * zoomFactor, rect.top + (rect.height - iconSize) / 2, iconSize, iconSize);
|
|
21822
|
-
if (
|
|
22422
|
+
if (controlChecked || controlMixed) {
|
|
21823
22423
|
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
21824
22424
|
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));
|
|
21825
22425
|
context.strokeStyle = paletteIsDark(palette) ? "#020617" : "#ffffff";
|
|
21826
22426
|
context.beginPath();
|
|
21827
|
-
|
|
21828
|
-
|
|
21829
|
-
|
|
22427
|
+
if (controlMixed) {
|
|
22428
|
+
context.moveTo(rect.left + 2 * zoomFactor + iconSize * 0.25, rect.top + rect.height / 2);
|
|
22429
|
+
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.75, rect.top + rect.height / 2);
|
|
22430
|
+
} else {
|
|
22431
|
+
context.moveTo(rect.left + 2 * zoomFactor + iconSize * 0.24, rect.top + rect.height / 2 + iconSize * 0.06);
|
|
22432
|
+
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.45, rect.top + rect.height / 2 + iconSize * 0.26);
|
|
22433
|
+
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.8, rect.top + rect.height / 2 - iconSize * 0.2);
|
|
22434
|
+
}
|
|
21830
22435
|
context.stroke();
|
|
21831
22436
|
}
|
|
21832
22437
|
textLeft += iconSize + 4 * zoomFactor;
|
|
@@ -21834,7 +22439,7 @@ function drawStaticFormControl(context, control, rect, palette, zoomFactor, shee
|
|
|
21834
22439
|
context.beginPath();
|
|
21835
22440
|
context.arc(rect.left + 2 * zoomFactor + iconSize / 2, rect.top + rect.height / 2, iconSize / 2, 0, Math.PI * 2);
|
|
21836
22441
|
context.stroke();
|
|
21837
|
-
if (
|
|
22442
|
+
if (controlChecked) {
|
|
21838
22443
|
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
21839
22444
|
context.beginPath();
|
|
21840
22445
|
context.arc(rect.left + 2 * zoomFactor + iconSize / 2, rect.top + rect.height / 2, iconSize * 0.25, 0, Math.PI * 2);
|
|
@@ -22470,7 +23075,10 @@ function XlsxGrid({
|
|
|
22470
23075
|
getCellStyle,
|
|
22471
23076
|
loadingComponent,
|
|
22472
23077
|
loadingState,
|
|
23078
|
+
onFormControlAction,
|
|
23079
|
+
onFormControlChange,
|
|
22473
23080
|
renderChartLoading,
|
|
23081
|
+
renderFormControl,
|
|
22474
23082
|
palette,
|
|
22475
23083
|
renderImage,
|
|
22476
23084
|
renderImageSelection,
|
|
@@ -22507,6 +23115,7 @@ function XlsxGrid({
|
|
|
22507
23115
|
getRowsBatchAsync,
|
|
22508
23116
|
getClipboardData,
|
|
22509
23117
|
getCellDisplayValue: getControllerCellDisplayValue,
|
|
23118
|
+
getFormControlItems,
|
|
22510
23119
|
images,
|
|
22511
23120
|
shapes,
|
|
22512
23121
|
isLoadDeferred,
|
|
@@ -22544,9 +23153,13 @@ function XlsxGrid({
|
|
|
22544
23153
|
sortTable,
|
|
22545
23154
|
tables,
|
|
22546
23155
|
undo,
|
|
23156
|
+
updateFormControl,
|
|
22547
23157
|
workbook,
|
|
22548
23158
|
zoomScale
|
|
22549
23159
|
} = controller;
|
|
23160
|
+
const formControlItemsById = React4.useMemo(() => new Map(
|
|
23161
|
+
formControls.flatMap((control) => control.controlIndex !== void 0 && (control.kind === "dropdown" || control.kind === "listbox") ? [[control.id, getFormControlItems(control.controlIndex, control.sheetIndex)]] : [])
|
|
23162
|
+
), [formControls, getFormControlItems]);
|
|
22550
23163
|
const canResizeHeaders = !readOnly || allowResizeInReadOnly;
|
|
22551
23164
|
const scrollRef = React4.useRef(null);
|
|
22552
23165
|
const wrapperRef = React4.useRef(null);
|
|
@@ -25030,14 +25643,7 @@ function XlsxGrid({
|
|
|
25030
25643
|
() => shouldBakeCanvasStaticDrawings ? shapeRects.filter(({ shape }) => shape.hyperlink) : shapeRects,
|
|
25031
25644
|
[shapeRects, shouldBakeCanvasStaticDrawings]
|
|
25032
25645
|
);
|
|
25033
|
-
const
|
|
25034
|
-
() => shouldBakeCanvasStaticDrawings ? formControlRects : [],
|
|
25035
|
-
[formControlRects, shouldBakeCanvasStaticDrawings]
|
|
25036
|
-
);
|
|
25037
|
-
const domFormControlRects = React4.useMemo(
|
|
25038
|
-
() => shouldBakeCanvasStaticDrawings ? [] : formControlRects,
|
|
25039
|
-
[formControlRects, shouldBakeCanvasStaticDrawings]
|
|
25040
|
-
);
|
|
25646
|
+
const domFormControlRects = formControlRects;
|
|
25041
25647
|
const bakedImageRects = React4.useMemo(
|
|
25042
25648
|
() => shouldBakeCanvasImages ? imageRects.filter(({ image }) => !image.hyperlink && selectedImageId !== image.id) : [],
|
|
25043
25649
|
[imageRects, selectedImageId, shouldBakeCanvasImages]
|
|
@@ -25054,11 +25660,9 @@ function XlsxGrid({
|
|
|
25054
25660
|
return "";
|
|
25055
25661
|
}
|
|
25056
25662
|
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("|");
|
|
25057
|
-
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("|");
|
|
25058
25663
|
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("|");
|
|
25059
|
-
return `${revision}:${canvasImageLoadVersion}:${shapeSignature}:${
|
|
25664
|
+
return `${revision}:${canvasImageLoadVersion}:${shapeSignature}:${imageSignature}`;
|
|
25060
25665
|
}, [
|
|
25061
|
-
bakedFormControlRects,
|
|
25062
25666
|
bakedImageRects,
|
|
25063
25667
|
bakedShapeRects,
|
|
25064
25668
|
canvasImageLoadVersion,
|
|
@@ -26593,12 +27197,6 @@ function XlsxGrid({
|
|
|
26593
27197
|
shape,
|
|
26594
27198
|
zIndex: shape.zIndex
|
|
26595
27199
|
})),
|
|
26596
|
-
...bakedFormControlRects.map(({ control, rect }) => ({
|
|
26597
|
-
control,
|
|
26598
|
-
kind: "formControl",
|
|
26599
|
-
rect,
|
|
26600
|
-
zIndex: control.zIndex
|
|
26601
|
-
})),
|
|
26602
27200
|
...bakedImageRects.map(({ image, rect }) => ({
|
|
26603
27201
|
image,
|
|
26604
27202
|
kind: "image",
|
|
@@ -26749,90 +27347,6 @@ function XlsxGrid({
|
|
|
26749
27347
|
drawBakedShapeText(context, shape, localLeft, localTop, rect.width, rect.height);
|
|
26750
27348
|
context.restore();
|
|
26751
27349
|
};
|
|
26752
|
-
const drawBakedFormControl = (context, control, rect) => {
|
|
26753
|
-
const label = resolveFormControlLabel(control);
|
|
26754
|
-
const stroke = paletteIsDark(palette) ? "#cbd5e1" : "#475569";
|
|
26755
|
-
const textColor = control.textColor ?? "#000000";
|
|
26756
|
-
const fontSizePx = Math.max(9 * zoomFactor, (control.fontSizePt ?? 9) * 96 / 72 * zoomFactor);
|
|
26757
|
-
const iconSize = Math.min(14 * zoomFactor, Math.max(0, rect.height - 4 * zoomFactor));
|
|
26758
|
-
context.save();
|
|
26759
|
-
context.font = `400 ${fontSizePx}px ${control.fontFamily ?? "Calibri, sans-serif"}`;
|
|
26760
|
-
context.textBaseline = "middle";
|
|
26761
|
-
context.fillStyle = textColor;
|
|
26762
|
-
context.strokeStyle = stroke;
|
|
26763
|
-
context.lineWidth = Math.max(1, zoomFactor);
|
|
26764
|
-
if (control.kind === "group-box") {
|
|
26765
|
-
const labelInset = label ? Math.max(7, fontSizePx * 0.5) : 0;
|
|
26766
|
-
drawCanvasRoundedRect(context, rect.left, rect.top + labelInset, rect.width, Math.max(0, rect.height - labelInset), 2 * zoomFactor);
|
|
26767
|
-
context.stroke();
|
|
26768
|
-
if (label) {
|
|
26769
|
-
context.fillStyle = SHEET_SURFACE;
|
|
26770
|
-
const labelWidth = Math.min(rect.width - 16 * zoomFactor, measureCanvasTextWidth(context, label) + 8 * zoomFactor);
|
|
26771
|
-
context.fillRect(rect.left + 8 * zoomFactor, rect.top, labelWidth, fontSizePx * 1.2);
|
|
26772
|
-
context.fillStyle = textColor;
|
|
26773
|
-
context.textAlign = "left";
|
|
26774
|
-
context.fillText(label, rect.left + 12 * zoomFactor, rect.top + fontSizePx * 0.55);
|
|
26775
|
-
}
|
|
26776
|
-
context.restore();
|
|
26777
|
-
return;
|
|
26778
|
-
}
|
|
26779
|
-
if (control.kind === "button" || control.kind === "dropdown" || control.kind === "editbox" || control.kind === "listbox" || control.kind === "scrollbar" || control.kind === "spinner" || control.kind === "unknown") {
|
|
26780
|
-
if (control.kind === "button") {
|
|
26781
|
-
const gradient = context.createLinearGradient(rect.left, rect.top, rect.left, rect.top + rect.height);
|
|
26782
|
-
gradient.addColorStop(0, "#f8fafc");
|
|
26783
|
-
gradient.addColorStop(1, "#e2e8f0");
|
|
26784
|
-
context.fillStyle = gradient;
|
|
26785
|
-
} else {
|
|
26786
|
-
context.fillStyle = "transparent";
|
|
26787
|
-
}
|
|
26788
|
-
drawCanvasRoundedRect(context, rect.left, rect.top, rect.width, rect.height, control.kind === "button" ? 4 * zoomFactor : 2 * zoomFactor);
|
|
26789
|
-
if (control.kind === "button") {
|
|
26790
|
-
context.fill();
|
|
26791
|
-
}
|
|
26792
|
-
context.stroke();
|
|
26793
|
-
}
|
|
26794
|
-
let textLeft = rect.left + 2 * zoomFactor;
|
|
26795
|
-
const textRightInset = control.kind === "dropdown" ? 18 * zoomFactor : 6 * zoomFactor;
|
|
26796
|
-
if (control.kind === "checkbox") {
|
|
26797
|
-
context.strokeRect(rect.left + 2 * zoomFactor, rect.top + (rect.height - iconSize) / 2, iconSize, iconSize);
|
|
26798
|
-
if (control.checked) {
|
|
26799
|
-
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
26800
|
-
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));
|
|
26801
|
-
context.strokeStyle = paletteIsDark(palette) ? "#020617" : "#ffffff";
|
|
26802
|
-
context.beginPath();
|
|
26803
|
-
context.moveTo(rect.left + 2 * zoomFactor + iconSize * 0.24, rect.top + rect.height / 2 + iconSize * 0.06);
|
|
26804
|
-
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.45, rect.top + rect.height / 2 + iconSize * 0.26);
|
|
26805
|
-
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.8, rect.top + rect.height / 2 - iconSize * 0.2);
|
|
26806
|
-
context.stroke();
|
|
26807
|
-
}
|
|
26808
|
-
textLeft += iconSize + 4 * zoomFactor;
|
|
26809
|
-
} else if (control.kind === "radio") {
|
|
26810
|
-
context.beginPath();
|
|
26811
|
-
context.arc(rect.left + 2 * zoomFactor + iconSize / 2, rect.top + rect.height / 2, iconSize / 2, 0, Math.PI * 2);
|
|
26812
|
-
context.stroke();
|
|
26813
|
-
if (control.checked) {
|
|
26814
|
-
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
26815
|
-
context.beginPath();
|
|
26816
|
-
context.arc(rect.left + 2 * zoomFactor + iconSize / 2, rect.top + rect.height / 2, iconSize * 0.25, 0, Math.PI * 2);
|
|
26817
|
-
context.fill();
|
|
26818
|
-
}
|
|
26819
|
-
textLeft += iconSize + 4 * zoomFactor;
|
|
26820
|
-
}
|
|
26821
|
-
if (label) {
|
|
26822
|
-
const maxTextWidth = Math.max(0, rect.left + rect.width - textLeft - textRightInset);
|
|
26823
|
-
const text = truncateCanvasText(context, label, maxTextWidth);
|
|
26824
|
-
context.fillStyle = textColor;
|
|
26825
|
-
context.textAlign = control.textAlign === "right" ? "right" : control.textAlign === "center" ? "center" : "left";
|
|
26826
|
-
const textX = context.textAlign === "right" ? rect.left + rect.width - textRightInset : context.textAlign === "center" ? textLeft + maxTextWidth / 2 : textLeft;
|
|
26827
|
-
context.fillText(text, textX, rect.top + rect.height / 2);
|
|
26828
|
-
}
|
|
26829
|
-
if (control.kind === "dropdown") {
|
|
26830
|
-
context.fillStyle = textColor;
|
|
26831
|
-
context.textAlign = "center";
|
|
26832
|
-
context.fillText("\u25BC", rect.left + rect.width - 10 * zoomFactor, rect.top + rect.height / 2);
|
|
26833
|
-
}
|
|
26834
|
-
context.restore();
|
|
26835
|
-
};
|
|
26836
27350
|
const drawBakedCanvasDrawings = (pane, context, dirtyRects) => {
|
|
26837
27351
|
if (bakedCanvasDrawingEntries.length === 0 || dirtyRects.length === 0) {
|
|
26838
27352
|
return;
|
|
@@ -26847,8 +27361,6 @@ function XlsxGrid({
|
|
|
26847
27361
|
}
|
|
26848
27362
|
if (entry.kind === "shape") {
|
|
26849
27363
|
drawBakedShape(context, entry.shape, localRect);
|
|
26850
|
-
} else if (entry.kind === "formControl") {
|
|
26851
|
-
drawBakedFormControl(context, entry.control, localRect);
|
|
26852
27364
|
} else {
|
|
26853
27365
|
const imageElement = getCanvasImage(entry.image);
|
|
26854
27366
|
if (imageElement) {
|
|
@@ -27542,7 +28054,6 @@ function XlsxGrid({
|
|
|
27542
28054
|
activeSheet,
|
|
27543
28055
|
applyCanvasViewportCompensation,
|
|
27544
28056
|
bakedCanvasDrawingSignature,
|
|
27545
|
-
bakedFormControlRects,
|
|
27546
28057
|
bakedImageRects,
|
|
27547
28058
|
bakedShapeRects,
|
|
27548
28059
|
canvasColumnHeaderCells,
|
|
@@ -28125,10 +28636,22 @@ function XlsxGrid({
|
|
|
28125
28636
|
const fontSizePx = Math.max(9 * zoomFactor, (control.fontSizePt ?? 9) * 96 / 72 * zoomFactor);
|
|
28126
28637
|
const stroke = paletteIsDark(palette) ? "#cbd5e1" : "#475569";
|
|
28127
28638
|
const textColor = control.textColor ?? "#000000";
|
|
28639
|
+
const canMutateControl = !readOnly && control.controlIndex !== void 0 && [
|
|
28640
|
+
"checkbox",
|
|
28641
|
+
"dropdown",
|
|
28642
|
+
"listbox",
|
|
28643
|
+
"radio",
|
|
28644
|
+
"scrollbar",
|
|
28645
|
+
"spinner"
|
|
28646
|
+
].includes(control.kind);
|
|
28647
|
+
const canActivateButton = !readOnly && control.kind === "button" && Boolean(onFormControlAction);
|
|
28648
|
+
const isInteractiveControl = canMutateControl || canActivateButton;
|
|
28649
|
+
const controlItems = formControlItemsById.get(control.id) ?? [];
|
|
28128
28650
|
const commonStyle = {
|
|
28129
28651
|
alignItems: control.kind === "group-box" ? "stretch" : "center",
|
|
28130
28652
|
color: textColor,
|
|
28131
28653
|
contain: "layout paint",
|
|
28654
|
+
cursor: isInteractiveControl ? "pointer" : void 0,
|
|
28132
28655
|
display: "flex",
|
|
28133
28656
|
fontFamily: control.fontFamily ?? "Calibri, sans-serif",
|
|
28134
28657
|
fontSize: fontSizePx,
|
|
@@ -28139,12 +28662,98 @@ function XlsxGrid({
|
|
|
28139
28662
|
left: rect.left,
|
|
28140
28663
|
lineHeight: 1.2,
|
|
28141
28664
|
overflow: "hidden",
|
|
28142
|
-
pointerEvents: "none",
|
|
28665
|
+
pointerEvents: isInteractiveControl ? "auto" : "none",
|
|
28143
28666
|
position: "absolute",
|
|
28144
28667
|
top: rect.top,
|
|
28145
28668
|
width: rect.width,
|
|
28146
28669
|
zIndex: isFrozenDrawing ? control.zIndex + 20 : control.zIndex
|
|
28147
28670
|
};
|
|
28671
|
+
const stopControlPointerEvent = (event) => {
|
|
28672
|
+
event.stopPropagation();
|
|
28673
|
+
};
|
|
28674
|
+
const commitControlKind = (kind, nextControl) => {
|
|
28675
|
+
if (readOnly || control.controlIndex === void 0) {
|
|
28676
|
+
return false;
|
|
28677
|
+
}
|
|
28678
|
+
const didUpdate = updateFormControl(control.controlIndex, { kind }, control.sheetIndex);
|
|
28679
|
+
if (didUpdate) {
|
|
28680
|
+
onFormControlChange?.({
|
|
28681
|
+
control: { ...control, ...nextControl },
|
|
28682
|
+
previousControl: control,
|
|
28683
|
+
type: "change"
|
|
28684
|
+
});
|
|
28685
|
+
}
|
|
28686
|
+
return didUpdate;
|
|
28687
|
+
};
|
|
28688
|
+
const setControlState = (state = "unchecked") => {
|
|
28689
|
+
const kind = buildFormControlKindInput(control);
|
|
28690
|
+
if (kind?.kind === "checkbox") {
|
|
28691
|
+
return commitControlKind(
|
|
28692
|
+
{ ...kind, state },
|
|
28693
|
+
{ checked: state === "checked", state }
|
|
28694
|
+
);
|
|
28695
|
+
}
|
|
28696
|
+
if (kind?.kind === "optionButton" && state !== "mixed") {
|
|
28697
|
+
return commitControlKind(
|
|
28698
|
+
{ ...kind, state },
|
|
28699
|
+
{ checked: state === "checked", state }
|
|
28700
|
+
);
|
|
28701
|
+
}
|
|
28702
|
+
return false;
|
|
28703
|
+
};
|
|
28704
|
+
const setControlSelected = (selected) => {
|
|
28705
|
+
const kind = buildFormControlKindInput(control);
|
|
28706
|
+
if (kind?.kind === "dropdown") {
|
|
28707
|
+
const nextSelected = typeof selected === "number" ? selected : void 0;
|
|
28708
|
+
return commitControlKind(
|
|
28709
|
+
{ ...kind, selected: nextSelected },
|
|
28710
|
+
{ selected: nextSelected }
|
|
28711
|
+
);
|
|
28712
|
+
}
|
|
28713
|
+
if (kind?.kind === "listBox") {
|
|
28714
|
+
const nextSelected = Array.isArray(selected) ? selected : typeof selected === "number" ? [selected] : [];
|
|
28715
|
+
return commitControlKind(
|
|
28716
|
+
{ ...kind, selected: nextSelected },
|
|
28717
|
+
{ selected: nextSelected }
|
|
28718
|
+
);
|
|
28719
|
+
}
|
|
28720
|
+
return false;
|
|
28721
|
+
};
|
|
28722
|
+
const setControlValue = (value) => {
|
|
28723
|
+
if (!Number.isFinite(value)) {
|
|
28724
|
+
return false;
|
|
28725
|
+
}
|
|
28726
|
+
const kind = buildFormControlKindInput(control);
|
|
28727
|
+
if (kind?.kind !== "scrollbar" && kind?.kind !== "spinner") {
|
|
28728
|
+
return false;
|
|
28729
|
+
}
|
|
28730
|
+
const nextValue = Math.max(kind.min, Math.min(kind.max, value));
|
|
28731
|
+
return commitControlKind({ ...kind, value: nextValue }, { value: nextValue });
|
|
28732
|
+
};
|
|
28733
|
+
const activateControl = () => {
|
|
28734
|
+
if (!readOnly && control.kind === "button") {
|
|
28735
|
+
onFormControlAction?.({ control, type: "activate" });
|
|
28736
|
+
}
|
|
28737
|
+
};
|
|
28738
|
+
if (renderFormControl) {
|
|
28739
|
+
return /* @__PURE__ */ jsx3(React4.Fragment, { children: renderFormControl({
|
|
28740
|
+
activate: activateControl,
|
|
28741
|
+
checked: isFormControlChecked(control),
|
|
28742
|
+
control,
|
|
28743
|
+
disabled: !isInteractiveControl,
|
|
28744
|
+
items: controlItems,
|
|
28745
|
+
label: controlLabel,
|
|
28746
|
+
mixed: isFormControlMixed(control),
|
|
28747
|
+
readOnly,
|
|
28748
|
+
rect,
|
|
28749
|
+
setSelected: setControlSelected,
|
|
28750
|
+
setState: setControlState,
|
|
28751
|
+
setValue: setControlValue,
|
|
28752
|
+
stopPropagation: stopControlPointerEvent,
|
|
28753
|
+
style: commonStyle,
|
|
28754
|
+
zoomFactor
|
|
28755
|
+
}) }, `${pane}-${control.id}`);
|
|
28756
|
+
}
|
|
28148
28757
|
if (control.kind === "group-box") {
|
|
28149
28758
|
const hasLabel = controlLabel.length > 0;
|
|
28150
28759
|
return /* @__PURE__ */ jsx3(
|
|
@@ -28186,15 +28795,83 @@ function XlsxGrid({
|
|
|
28186
28795
|
`${pane}-${control.id}`
|
|
28187
28796
|
);
|
|
28188
28797
|
}
|
|
28189
|
-
let content;
|
|
28190
28798
|
if (control.kind === "radio") {
|
|
28191
|
-
|
|
28192
|
-
|
|
28193
|
-
|
|
28194
|
-
|
|
28799
|
+
const checked = isFormControlChecked(control);
|
|
28800
|
+
return /* @__PURE__ */ jsxs3(
|
|
28801
|
+
"button",
|
|
28802
|
+
{
|
|
28803
|
+
"aria-disabled": readOnly || control.controlIndex === void 0,
|
|
28804
|
+
"aria-checked": checked,
|
|
28805
|
+
disabled: !readOnly && control.controlIndex === void 0,
|
|
28806
|
+
onClick: (event) => {
|
|
28807
|
+
event.stopPropagation();
|
|
28808
|
+
if (!checked) {
|
|
28809
|
+
setControlState("checked");
|
|
28810
|
+
}
|
|
28811
|
+
},
|
|
28812
|
+
onPointerDown: stopControlPointerEvent,
|
|
28813
|
+
role: "radio",
|
|
28814
|
+
style: {
|
|
28815
|
+
...commonStyle,
|
|
28816
|
+
background: "transparent",
|
|
28817
|
+
border: 0,
|
|
28818
|
+
boxSizing: "border-box",
|
|
28819
|
+
padding: `0 ${Math.max(1, zoomFactor)}px`
|
|
28820
|
+
},
|
|
28821
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
28822
|
+
type: "button",
|
|
28823
|
+
children: [
|
|
28824
|
+
renderRadioControl(checked, palette, zoomFactor),
|
|
28825
|
+
controlLabel ? /* @__PURE__ */ jsx3("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: controlLabel }) : null
|
|
28826
|
+
]
|
|
28827
|
+
},
|
|
28828
|
+
`${pane}-${control.id}`
|
|
28829
|
+
);
|
|
28830
|
+
}
|
|
28831
|
+
if (control.kind === "checkbox") {
|
|
28832
|
+
const checked = isFormControlChecked(control);
|
|
28833
|
+
const mixed = isFormControlMixed(control);
|
|
28834
|
+
return /* @__PURE__ */ jsxs3(
|
|
28835
|
+
"button",
|
|
28836
|
+
{
|
|
28837
|
+
"aria-disabled": readOnly || control.controlIndex === void 0,
|
|
28838
|
+
"aria-checked": mixed ? "mixed" : checked,
|
|
28839
|
+
disabled: !readOnly && control.controlIndex === void 0,
|
|
28840
|
+
onClick: (event) => {
|
|
28841
|
+
event.stopPropagation();
|
|
28842
|
+
const nextState = checked && !mixed ? "unchecked" : "checked";
|
|
28843
|
+
setControlState(nextState);
|
|
28844
|
+
},
|
|
28845
|
+
onPointerDown: stopControlPointerEvent,
|
|
28846
|
+
role: "checkbox",
|
|
28847
|
+
style: {
|
|
28848
|
+
...commonStyle,
|
|
28849
|
+
background: "transparent",
|
|
28850
|
+
border: 0,
|
|
28851
|
+
boxSizing: "border-box",
|
|
28852
|
+
padding: `0 ${Math.max(1, zoomFactor)}px`
|
|
28853
|
+
},
|
|
28854
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
28855
|
+
type: "button",
|
|
28856
|
+
children: [
|
|
28857
|
+
renderCheckboxControl(checked, palette, zoomFactor, mixed),
|
|
28858
|
+
controlLabel ? /* @__PURE__ */ jsx3("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: controlLabel }) : null
|
|
28859
|
+
]
|
|
28860
|
+
},
|
|
28861
|
+
`${pane}-${control.id}`
|
|
28862
|
+
);
|
|
28863
|
+
}
|
|
28864
|
+
if (control.kind === "button") {
|
|
28195
28865
|
return /* @__PURE__ */ jsx3(
|
|
28196
|
-
"
|
|
28866
|
+
"button",
|
|
28197
28867
|
{
|
|
28868
|
+
"aria-disabled": readOnly || !onFormControlAction,
|
|
28869
|
+
disabled: !readOnly && !onFormControlAction,
|
|
28870
|
+
onClick: (event) => {
|
|
28871
|
+
event.stopPropagation();
|
|
28872
|
+
activateControl();
|
|
28873
|
+
},
|
|
28874
|
+
onPointerDown: stopControlPointerEvent,
|
|
28198
28875
|
style: {
|
|
28199
28876
|
...commonStyle,
|
|
28200
28877
|
background: "linear-gradient(180deg, #f8fafc 0%, #e2e8f0 100%)",
|
|
@@ -28205,68 +28882,157 @@ function XlsxGrid({
|
|
|
28205
28882
|
padding: `0 ${6 * zoomFactor}px`,
|
|
28206
28883
|
textAlign: "center"
|
|
28207
28884
|
},
|
|
28885
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
28886
|
+
type: "button",
|
|
28208
28887
|
children: controlLabel
|
|
28209
28888
|
},
|
|
28210
28889
|
`${pane}-${control.id}`
|
|
28211
28890
|
);
|
|
28212
|
-
}
|
|
28891
|
+
}
|
|
28892
|
+
if (control.kind === "dropdown") {
|
|
28893
|
+
const selected = typeof control.selected === "number" ? control.selected : void 0;
|
|
28213
28894
|
return /* @__PURE__ */ jsxs3(
|
|
28214
|
-
"
|
|
28895
|
+
"select",
|
|
28215
28896
|
{
|
|
28897
|
+
"aria-disabled": readOnly || control.controlIndex === void 0 || controlItems.length === 0,
|
|
28898
|
+
"aria-label": controlLabel || control.name || "Dropdown form control",
|
|
28899
|
+
disabled: !readOnly && (control.controlIndex === void 0 || controlItems.length === 0),
|
|
28900
|
+
onChange: (event) => {
|
|
28901
|
+
event.stopPropagation();
|
|
28902
|
+
const nextSelected = event.currentTarget.value === "" ? void 0 : Number(event.currentTarget.value);
|
|
28903
|
+
setControlSelected(nextSelected);
|
|
28904
|
+
},
|
|
28905
|
+
onClick: stopControlPointerEvent,
|
|
28906
|
+
onPointerDown: stopControlPointerEvent,
|
|
28216
28907
|
style: {
|
|
28217
28908
|
...commonStyle,
|
|
28909
|
+
backgroundColor: SHEET_SURFACE,
|
|
28218
28910
|
border: `${Math.max(1, zoomFactor)}px solid ${stroke}`,
|
|
28219
28911
|
borderRadius: 2 * zoomFactor,
|
|
28220
28912
|
boxSizing: "border-box",
|
|
28221
|
-
|
|
28222
|
-
padding: `0 ${6 * zoomFactor}px`
|
|
28913
|
+
padding: `0 ${4 * zoomFactor}px`
|
|
28223
28914
|
},
|
|
28915
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
28916
|
+
value: selected === void 0 ? "" : String(selected),
|
|
28224
28917
|
children: [
|
|
28225
|
-
/* @__PURE__ */ jsx3("
|
|
28226
|
-
/* @__PURE__ */ jsx3("
|
|
28918
|
+
selected === void 0 ? /* @__PURE__ */ jsx3("option", { value: "", children: controlLabel }) : null,
|
|
28919
|
+
controlItems.map((item, index) => /* @__PURE__ */ jsx3("option", { value: index, children: item }, index))
|
|
28227
28920
|
]
|
|
28228
28921
|
},
|
|
28229
28922
|
`${pane}-${control.id}`
|
|
28230
28923
|
);
|
|
28231
|
-
}
|
|
28924
|
+
}
|
|
28925
|
+
if (control.kind === "listbox") {
|
|
28926
|
+
const selected = Array.isArray(control.selected) ? control.selected : control.selected === void 0 ? [] : [control.selected];
|
|
28927
|
+
const allowsMultipleSelection = (control.selection ?? "single") !== "single";
|
|
28232
28928
|
return /* @__PURE__ */ jsx3(
|
|
28233
|
-
"
|
|
28929
|
+
"select",
|
|
28234
28930
|
{
|
|
28931
|
+
"aria-disabled": readOnly || control.controlIndex === void 0 || controlItems.length === 0,
|
|
28932
|
+
"aria-label": controlLabel || control.name || "List box form control",
|
|
28933
|
+
disabled: !readOnly && (control.controlIndex === void 0 || controlItems.length === 0),
|
|
28934
|
+
multiple: allowsMultipleSelection,
|
|
28935
|
+
onChange: (event) => {
|
|
28936
|
+
event.stopPropagation();
|
|
28937
|
+
const nextSelected = Array.from(event.currentTarget.selectedOptions, (option) => Number(option.value));
|
|
28938
|
+
setControlSelected(nextSelected);
|
|
28939
|
+
},
|
|
28940
|
+
onClick: stopControlPointerEvent,
|
|
28941
|
+
onPointerDown: stopControlPointerEvent,
|
|
28942
|
+
size: Math.max(2, Math.min(controlItems.length || 2, Math.floor(rect.height / Math.max(1, fontSizePx * 1.45)))),
|
|
28235
28943
|
style: {
|
|
28236
28944
|
...commonStyle,
|
|
28945
|
+
alignItems: void 0,
|
|
28946
|
+
backgroundColor: SHEET_SURFACE,
|
|
28237
28947
|
border: `${Math.max(1, zoomFactor)}px solid ${stroke}`,
|
|
28238
28948
|
borderRadius: 2 * zoomFactor,
|
|
28239
28949
|
boxSizing: "border-box",
|
|
28240
|
-
|
|
28950
|
+
display: "block",
|
|
28951
|
+
padding: 0
|
|
28241
28952
|
},
|
|
28242
|
-
|
|
28953
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
28954
|
+
value: allowsMultipleSelection ? selected.map(String) : selected[0] === void 0 ? "" : String(selected[0]),
|
|
28955
|
+
children: controlItems.map((item, index) => /* @__PURE__ */ jsx3("option", { value: index, children: item }, index))
|
|
28243
28956
|
},
|
|
28244
28957
|
`${pane}-${control.id}`
|
|
28245
28958
|
);
|
|
28246
|
-
} else {
|
|
28247
|
-
content = null;
|
|
28248
28959
|
}
|
|
28249
|
-
|
|
28960
|
+
if (control.kind === "scrollbar") {
|
|
28961
|
+
const min = control.min ?? 0;
|
|
28962
|
+
const max = Math.max(min, control.max ?? 100);
|
|
28963
|
+
return /* @__PURE__ */ jsx3(
|
|
28964
|
+
"input",
|
|
28965
|
+
{
|
|
28966
|
+
"aria-disabled": readOnly || control.controlIndex === void 0,
|
|
28967
|
+
"aria-label": controlLabel || control.name || "Scrollbar form control",
|
|
28968
|
+
disabled: !readOnly && control.controlIndex === void 0,
|
|
28969
|
+
max,
|
|
28970
|
+
min,
|
|
28971
|
+
onChange: (event) => {
|
|
28972
|
+
event.stopPropagation();
|
|
28973
|
+
setControlValue(event.currentTarget.valueAsNumber);
|
|
28974
|
+
},
|
|
28975
|
+
onClick: stopControlPointerEvent,
|
|
28976
|
+
onPointerDown: stopControlPointerEvent,
|
|
28977
|
+
step: Math.max(1, control.increment ?? 1),
|
|
28978
|
+
style: {
|
|
28979
|
+
...commonStyle,
|
|
28980
|
+
accentColor: paletteIsDark(palette) ? "#60a5fa" : "#2563eb",
|
|
28981
|
+
boxSizing: "border-box",
|
|
28982
|
+
padding: 0,
|
|
28983
|
+
writingMode: control.horizontal === false ? "vertical-lr" : void 0
|
|
28984
|
+
},
|
|
28985
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
28986
|
+
type: "range",
|
|
28987
|
+
value: Math.max(min, Math.min(max, control.value ?? min))
|
|
28988
|
+
},
|
|
28989
|
+
`${pane}-${control.id}`
|
|
28990
|
+
);
|
|
28991
|
+
}
|
|
28992
|
+
if (control.kind === "spinner") {
|
|
28993
|
+
const min = control.min ?? 0;
|
|
28994
|
+
const max = Math.max(min, control.max ?? 100);
|
|
28995
|
+
return /* @__PURE__ */ jsx3(
|
|
28996
|
+
"input",
|
|
28997
|
+
{
|
|
28998
|
+
"aria-disabled": readOnly || control.controlIndex === void 0,
|
|
28999
|
+
"aria-label": controlLabel || control.name || "Spinner form control",
|
|
29000
|
+
disabled: !readOnly && control.controlIndex === void 0,
|
|
29001
|
+
max,
|
|
29002
|
+
min,
|
|
29003
|
+
onChange: (event) => {
|
|
29004
|
+
event.stopPropagation();
|
|
29005
|
+
setControlValue(event.currentTarget.valueAsNumber);
|
|
29006
|
+
},
|
|
29007
|
+
onClick: stopControlPointerEvent,
|
|
29008
|
+
onPointerDown: stopControlPointerEvent,
|
|
29009
|
+
step: Math.max(1, control.increment ?? 1),
|
|
29010
|
+
style: {
|
|
29011
|
+
...commonStyle,
|
|
29012
|
+
backgroundColor: SHEET_SURFACE,
|
|
29013
|
+
border: `${Math.max(1, zoomFactor)}px solid ${stroke}`,
|
|
29014
|
+
borderRadius: 2 * zoomFactor,
|
|
29015
|
+
boxSizing: "border-box",
|
|
29016
|
+
padding: `0 ${4 * zoomFactor}px`
|
|
29017
|
+
},
|
|
29018
|
+
tabIndex: readOnly ? -1 : void 0,
|
|
29019
|
+
type: "number",
|
|
29020
|
+
value: Math.max(min, Math.min(max, control.value ?? min))
|
|
29021
|
+
},
|
|
29022
|
+
`${pane}-${control.id}`
|
|
29023
|
+
);
|
|
29024
|
+
}
|
|
29025
|
+
return /* @__PURE__ */ jsx3(
|
|
28250
29026
|
"div",
|
|
28251
29027
|
{
|
|
28252
29028
|
style: {
|
|
28253
29029
|
...commonStyle,
|
|
29030
|
+
border: control.kind === "editbox" || control.kind === "unknown" ? `${Math.max(1, zoomFactor)}px solid ${stroke}` : void 0,
|
|
29031
|
+
borderRadius: 2 * zoomFactor,
|
|
29032
|
+
boxSizing: "border-box",
|
|
28254
29033
|
padding: `0 ${Math.max(1, zoomFactor)}px`
|
|
28255
29034
|
},
|
|
28256
|
-
children:
|
|
28257
|
-
content,
|
|
28258
|
-
controlLabel ? /* @__PURE__ */ jsx3(
|
|
28259
|
-
"span",
|
|
28260
|
-
{
|
|
28261
|
-
style: {
|
|
28262
|
-
overflow: "hidden",
|
|
28263
|
-
textOverflow: "ellipsis",
|
|
28264
|
-
whiteSpace: "nowrap"
|
|
28265
|
-
},
|
|
28266
|
-
children: controlLabel
|
|
28267
|
-
}
|
|
28268
|
-
) : null
|
|
28269
|
-
]
|
|
29035
|
+
children: controlLabel ? /* @__PURE__ */ jsx3("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: controlLabel }) : null
|
|
28270
29036
|
},
|
|
28271
29037
|
`${pane}-${control.id}`
|
|
28272
29038
|
);
|
|
@@ -28553,7 +29319,7 @@ function XlsxGrid({
|
|
|
28553
29319
|
};
|
|
28554
29320
|
const drawingViewportCacheSignature = `${Math.floor(drawingViewport.left / CANVAS_VIEWPORT_OVERSCAN_PX)}:${Math.floor(drawingViewport.top / CANVAS_VIEWPORT_OVERSCAN_PX)}:${drawingViewport.width}:${drawingViewport.height}`;
|
|
28555
29321
|
const previousPaneDrawingNodes = paneDrawingNodesCacheRef.current;
|
|
28556
|
-
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;
|
|
29322
|
+
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;
|
|
28557
29323
|
const paneDrawingNodes = canReusePaneDrawingNodes ? previousPaneDrawingNodes.value : !showImages ? {
|
|
28558
29324
|
corner: null,
|
|
28559
29325
|
left: null,
|
|
@@ -28589,12 +29355,16 @@ function XlsxGrid({
|
|
|
28589
29355
|
paneDrawingNodesCacheRef.current = {
|
|
28590
29356
|
chartRects,
|
|
28591
29357
|
drawingViewportSignature: drawingViewportCacheSignature,
|
|
29358
|
+
formControlItemsById,
|
|
28592
29359
|
formControlRects: domFormControlRects,
|
|
28593
29360
|
imageRects: domImageRects,
|
|
28594
29361
|
isChartsLoading,
|
|
29362
|
+
onFormControlAction,
|
|
29363
|
+
onFormControlChange,
|
|
28595
29364
|
palette,
|
|
28596
29365
|
readOnly,
|
|
28597
29366
|
renderChartLoading,
|
|
29367
|
+
renderFormControl,
|
|
28598
29368
|
renderImage,
|
|
28599
29369
|
renderImageSelection,
|
|
28600
29370
|
selectedChartElement,
|
|
@@ -28603,6 +29373,7 @@ function XlsxGrid({
|
|
|
28603
29373
|
selectionStroke,
|
|
28604
29374
|
shapeRects: domShapeRects,
|
|
28605
29375
|
showImages,
|
|
29376
|
+
updateFormControl,
|
|
28606
29377
|
value: paneDrawingNodes
|
|
28607
29378
|
};
|
|
28608
29379
|
}
|
|
@@ -29829,7 +30600,10 @@ function XlsxViewerInner({
|
|
|
29829
30600
|
isDark = false,
|
|
29830
30601
|
loadingComponent,
|
|
29831
30602
|
loadingState,
|
|
30603
|
+
onFormControlAction,
|
|
30604
|
+
onFormControlChange,
|
|
29832
30605
|
renderChartLoading,
|
|
30606
|
+
renderFormControl,
|
|
29833
30607
|
renderImage,
|
|
29834
30608
|
renderImageSelection,
|
|
29835
30609
|
renderScroller,
|
|
@@ -29891,8 +30665,11 @@ function XlsxViewerInner({
|
|
|
29891
30665
|
getCellStyle,
|
|
29892
30666
|
loadingComponent,
|
|
29893
30667
|
loadingState,
|
|
30668
|
+
onFormControlAction,
|
|
30669
|
+
onFormControlChange,
|
|
29894
30670
|
palette,
|
|
29895
30671
|
renderChartLoading,
|
|
30672
|
+
renderFormControl,
|
|
29896
30673
|
renderImage,
|
|
29897
30674
|
renderImageSelection,
|
|
29898
30675
|
renderScroller,
|
|
@@ -29997,6 +30774,7 @@ function useXlsxViewerZoom() {
|
|
|
29997
30774
|
}
|
|
29998
30775
|
function useXlsxViewerEditing() {
|
|
29999
30776
|
const {
|
|
30777
|
+
addFormControl,
|
|
30000
30778
|
addSheet,
|
|
30001
30779
|
canRedo,
|
|
30002
30780
|
canUndo,
|
|
@@ -30004,14 +30782,18 @@ function useXlsxViewerEditing() {
|
|
|
30004
30782
|
copySelectionToClipboard,
|
|
30005
30783
|
defineNamedRange,
|
|
30006
30784
|
fillSelection,
|
|
30785
|
+
formControls,
|
|
30007
30786
|
getClipboardData,
|
|
30008
30787
|
getCellDisplayValue: getCellDisplayValue2,
|
|
30009
30788
|
getCellFormula,
|
|
30789
|
+
getFormControlItems,
|
|
30790
|
+
getSheetFormControls,
|
|
30010
30791
|
mergeSelection,
|
|
30011
30792
|
pasteFromClipboard,
|
|
30012
30793
|
pasteStructuredClipboardData,
|
|
30013
30794
|
pasteText,
|
|
30014
30795
|
removeActiveSheet,
|
|
30796
|
+
removeFormControl,
|
|
30015
30797
|
readOnly,
|
|
30016
30798
|
redo,
|
|
30017
30799
|
selectedCellFormula,
|
|
@@ -30028,10 +30810,12 @@ function useXlsxViewerEditing() {
|
|
|
30028
30810
|
setSelectedCellStyle,
|
|
30029
30811
|
setSelectedCellValue,
|
|
30030
30812
|
undo,
|
|
30031
|
-
unmergeSelection
|
|
30813
|
+
unmergeSelection,
|
|
30814
|
+
updateFormControl
|
|
30032
30815
|
} = useXlsxViewer();
|
|
30033
30816
|
return React4.useMemo(
|
|
30034
30817
|
() => ({
|
|
30818
|
+
addFormControl,
|
|
30035
30819
|
addSheet,
|
|
30036
30820
|
canRedo,
|
|
30037
30821
|
canUndo,
|
|
@@ -30039,14 +30823,18 @@ function useXlsxViewerEditing() {
|
|
|
30039
30823
|
copySelectionToClipboard,
|
|
30040
30824
|
defineNamedRange,
|
|
30041
30825
|
fillSelection,
|
|
30826
|
+
formControls,
|
|
30042
30827
|
getClipboardData,
|
|
30043
30828
|
getCellDisplayValue: getCellDisplayValue2,
|
|
30044
30829
|
getCellFormula,
|
|
30830
|
+
getFormControlItems,
|
|
30831
|
+
getSheetFormControls,
|
|
30045
30832
|
mergeSelection,
|
|
30046
30833
|
pasteFromClipboard,
|
|
30047
30834
|
pasteStructuredClipboardData,
|
|
30048
30835
|
pasteText,
|
|
30049
30836
|
removeActiveSheet,
|
|
30837
|
+
removeFormControl,
|
|
30050
30838
|
readOnly,
|
|
30051
30839
|
redo,
|
|
30052
30840
|
selectedCellFormula,
|
|
@@ -30063,9 +30851,11 @@ function useXlsxViewerEditing() {
|
|
|
30063
30851
|
setSelectedCellStyle,
|
|
30064
30852
|
setSelectedCellValue,
|
|
30065
30853
|
undo,
|
|
30066
|
-
unmergeSelection
|
|
30854
|
+
unmergeSelection,
|
|
30855
|
+
updateFormControl
|
|
30067
30856
|
}),
|
|
30068
30857
|
[
|
|
30858
|
+
addFormControl,
|
|
30069
30859
|
addSheet,
|
|
30070
30860
|
canRedo,
|
|
30071
30861
|
canUndo,
|
|
@@ -30073,14 +30863,18 @@ function useXlsxViewerEditing() {
|
|
|
30073
30863
|
copySelectionToClipboard,
|
|
30074
30864
|
defineNamedRange,
|
|
30075
30865
|
fillSelection,
|
|
30866
|
+
formControls,
|
|
30076
30867
|
getClipboardData,
|
|
30077
30868
|
getCellDisplayValue2,
|
|
30078
30869
|
getCellFormula,
|
|
30870
|
+
getFormControlItems,
|
|
30871
|
+
getSheetFormControls,
|
|
30079
30872
|
mergeSelection,
|
|
30080
30873
|
pasteFromClipboard,
|
|
30081
30874
|
pasteStructuredClipboardData,
|
|
30082
30875
|
pasteText,
|
|
30083
30876
|
removeActiveSheet,
|
|
30877
|
+
removeFormControl,
|
|
30084
30878
|
readOnly,
|
|
30085
30879
|
redo,
|
|
30086
30880
|
selectedCellFormula,
|
|
@@ -30097,7 +30891,8 @@ function useXlsxViewerEditing() {
|
|
|
30097
30891
|
setSelectedCellStyle,
|
|
30098
30892
|
setSelectedCellValue,
|
|
30099
30893
|
undo,
|
|
30100
|
-
unmergeSelection
|
|
30894
|
+
unmergeSelection,
|
|
30895
|
+
updateFormControl
|
|
30101
30896
|
]
|
|
30102
30897
|
);
|
|
30103
30898
|
}
|
|
@@ -30295,20 +31090,87 @@ function useXlsxViewerCharts() {
|
|
|
30295
31090
|
);
|
|
30296
31091
|
}
|
|
30297
31092
|
function useXlsxViewerThumbnails(options = {}) {
|
|
30298
|
-
const {
|
|
31093
|
+
const {
|
|
31094
|
+
getRowsBatchAsync,
|
|
31095
|
+
getSheetFormControls,
|
|
31096
|
+
getSheetImages,
|
|
31097
|
+
getSheetShapes,
|
|
31098
|
+
workbook,
|
|
31099
|
+
sheets
|
|
31100
|
+
} = useXlsxViewer();
|
|
30299
31101
|
const { isDark } = React4.useContext(ViewerAppearanceContext);
|
|
30300
31102
|
const palette = useViewerPalette(isDark);
|
|
30301
31103
|
const includeHeaders = options.includeHeaders ?? true;
|
|
30302
31104
|
const resolution = options.resolution;
|
|
30303
31105
|
const thumbnailImageCacheRef = React4.useRef(/* @__PURE__ */ new Map());
|
|
31106
|
+
const workerThumbnailRowBatchCacheRef = React4.useRef(/* @__PURE__ */ new Map());
|
|
31107
|
+
const workerThumbnailRowBatchRequestRef = React4.useRef(
|
|
31108
|
+
/* @__PURE__ */ new Map()
|
|
31109
|
+
);
|
|
30304
31110
|
const isMountedRef = React4.useRef(false);
|
|
30305
31111
|
const [thumbnailImageLoadVersion, setThumbnailImageLoadVersion] = React4.useState(0);
|
|
31112
|
+
const [workerThumbnailRowBatchVersion, setWorkerThumbnailRowBatchVersion] = React4.useState(0);
|
|
30306
31113
|
React4.useEffect(() => {
|
|
30307
31114
|
isMountedRef.current = true;
|
|
30308
31115
|
return () => {
|
|
30309
31116
|
isMountedRef.current = false;
|
|
30310
31117
|
};
|
|
30311
31118
|
}, []);
|
|
31119
|
+
React4.useEffect(() => {
|
|
31120
|
+
const currentSheets = new Set(sheets);
|
|
31121
|
+
for (const sheet of workerThumbnailRowBatchCacheRef.current.keys()) {
|
|
31122
|
+
if (!currentSheets.has(sheet)) {
|
|
31123
|
+
workerThumbnailRowBatchCacheRef.current.delete(sheet);
|
|
31124
|
+
}
|
|
31125
|
+
}
|
|
31126
|
+
for (const sheet of workerThumbnailRowBatchRequestRef.current.keys()) {
|
|
31127
|
+
if (!currentSheets.has(sheet)) {
|
|
31128
|
+
workerThumbnailRowBatchRequestRef.current.delete(sheet);
|
|
31129
|
+
}
|
|
31130
|
+
}
|
|
31131
|
+
}, [sheets]);
|
|
31132
|
+
const getWorkerThumbnailRowBatch = React4.useCallback((sheet, startRow, endRow) => {
|
|
31133
|
+
const cachedBatch = workerThumbnailRowBatchCacheRef.current.get(sheet);
|
|
31134
|
+
if (cachedBatch && startRow >= cachedBatch.startRow && endRow <= cachedBatch.endRow) {
|
|
31135
|
+
return cachedBatch;
|
|
31136
|
+
}
|
|
31137
|
+
if (!getRowsBatchAsync) {
|
|
31138
|
+
return null;
|
|
31139
|
+
}
|
|
31140
|
+
const pendingRequest = workerThumbnailRowBatchRequestRef.current.get(sheet);
|
|
31141
|
+
if (!pendingRequest) {
|
|
31142
|
+
const request = {
|
|
31143
|
+
endRow: Math.max(endRow, cachedBatch?.endRow ?? endRow),
|
|
31144
|
+
startRow: Math.min(startRow, cachedBatch?.startRow ?? startRow)
|
|
31145
|
+
};
|
|
31146
|
+
workerThumbnailRowBatchRequestRef.current.set(sheet, request);
|
|
31147
|
+
void getRowsBatchAsync(
|
|
31148
|
+
sheet.workbookSheetIndex,
|
|
31149
|
+
request.startRow,
|
|
31150
|
+
request.endRow - request.startRow + 1
|
|
31151
|
+
).then((rows) => {
|
|
31152
|
+
if (workerThumbnailRowBatchRequestRef.current.get(sheet) !== request) {
|
|
31153
|
+
return;
|
|
31154
|
+
}
|
|
31155
|
+
workerThumbnailRowBatchRequestRef.current.delete(sheet);
|
|
31156
|
+
if (!rows) {
|
|
31157
|
+
return;
|
|
31158
|
+
}
|
|
31159
|
+
workerThumbnailRowBatchCacheRef.current.set(
|
|
31160
|
+
sheet,
|
|
31161
|
+
buildWorksheetBatchWindow(rows, sheet, request.startRow, request.endRow)
|
|
31162
|
+
);
|
|
31163
|
+
if (isMountedRef.current) {
|
|
31164
|
+
setWorkerThumbnailRowBatchVersion((version) => version + 1);
|
|
31165
|
+
}
|
|
31166
|
+
}).catch(() => {
|
|
31167
|
+
if (workerThumbnailRowBatchRequestRef.current.get(sheet) === request) {
|
|
31168
|
+
workerThumbnailRowBatchRequestRef.current.delete(sheet);
|
|
31169
|
+
}
|
|
31170
|
+
});
|
|
31171
|
+
}
|
|
31172
|
+
return null;
|
|
31173
|
+
}, [getRowsBatchAsync]);
|
|
30312
31174
|
const getThumbnailImage = React4.useCallback((image) => {
|
|
30313
31175
|
if (typeof Image === "undefined") {
|
|
30314
31176
|
return null;
|
|
@@ -30534,6 +31396,10 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30534
31396
|
if (!canvas) {
|
|
30535
31397
|
return false;
|
|
30536
31398
|
}
|
|
31399
|
+
const workerRowBatch = worksheet ? null : getWorkerThumbnailRowBatch(sheet, sourceRange.start.row, sourceRange.end.row);
|
|
31400
|
+
if (!worksheet && !workerRowBatch) {
|
|
31401
|
+
return false;
|
|
31402
|
+
}
|
|
30537
31403
|
const context = canvas.getContext("2d", { alpha: false });
|
|
30538
31404
|
if (!context) {
|
|
30539
31405
|
return false;
|
|
@@ -30570,9 +31436,6 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30570
31436
|
context.fillRect(0, headerHeight, rowHeaderWidth, Math.max(1, rowAxis.totalSize));
|
|
30571
31437
|
context.fillRect(0, 0, rowHeaderWidth, headerHeight);
|
|
30572
31438
|
}
|
|
30573
|
-
if (!worksheet) {
|
|
30574
|
-
return true;
|
|
30575
|
-
}
|
|
30576
31439
|
const conditionalFormatMetricsCache = /* @__PURE__ */ new Map();
|
|
30577
31440
|
const cellRenderCache = /* @__PURE__ */ new Map();
|
|
30578
31441
|
const getCellData = (row, col) => {
|
|
@@ -30581,7 +31444,9 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30581
31444
|
if (cached) {
|
|
30582
31445
|
return cached;
|
|
30583
31446
|
}
|
|
30584
|
-
|
|
31447
|
+
const batchCoversRow = workerRowBatch ? row >= workerRowBatch.startRow && row <= workerRowBatch.endRow : false;
|
|
31448
|
+
const batchedCell = batchCoversRow ? workerRowBatch?.cells.get(cacheKey) : void 0;
|
|
31449
|
+
if (batchedCell?.isMergedSecondary || worksheet?.isMergedSecondary(row, col)) {
|
|
30585
31450
|
const mergedSecondaryData = {
|
|
30586
31451
|
isMergedSecondary: true,
|
|
30587
31452
|
style: {},
|
|
@@ -30590,53 +31455,34 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30590
31455
|
cellRenderCache.set(cacheKey, mergedSecondaryData);
|
|
30591
31456
|
return mergedSecondaryData;
|
|
30592
31457
|
}
|
|
30593
|
-
const merge = worksheet.getMergeSpan(row, col);
|
|
31458
|
+
const merge = worksheet ? worksheet.getMergeSpan(row, col) : batchedCell?.mergeSpan;
|
|
30594
31459
|
const inheritedStyle = resolveInheritedCellStyle2(sheet, row, col);
|
|
30595
|
-
const worksheetStyle = worksheet.getCellStyleAt(row, col) ?? null;
|
|
31460
|
+
const worksheetStyle = worksheet ? worksheet.getCellStyleAt(row, col) ?? null : batchedCell?.style ?? null;
|
|
30596
31461
|
const mergedStyle = mergeResolvedCellStyle(inheritedStyle, worksheetStyle, { replaceXfSubtrees: true });
|
|
30597
31462
|
const alignment = mergedStyle?.alignment;
|
|
30598
31463
|
const sparkline = sparklineByCell.get(cacheKey) ?? null;
|
|
31464
|
+
const getNumericValue = (targetRow, targetCol) => worksheet ? getCellNumericValue(worksheet, targetRow, targetCol) : getBatchedCellNumericValue(workerRowBatch?.cells.get(`${targetRow}:${targetCol}`));
|
|
30599
31465
|
const sparklineValues = sparkline ? sparkline.range.start.row === sparkline.range.end.row ? Array.from(
|
|
30600
31466
|
{ length: Math.abs(sparkline.range.end.col - sparkline.range.start.col) + 1 },
|
|
30601
|
-
(_, index) =>
|
|
30602
|
-
worksheet,
|
|
31467
|
+
(_, index) => getNumericValue(
|
|
30603
31468
|
sparkline.range.start.row,
|
|
30604
31469
|
Math.min(sparkline.range.start.col, sparkline.range.end.col) + index
|
|
30605
31470
|
)
|
|
30606
31471
|
) : Array.from(
|
|
30607
31472
|
{ length: Math.abs(sparkline.range.end.row - sparkline.range.start.row) + 1 },
|
|
30608
|
-
(_, index) =>
|
|
30609
|
-
worksheet,
|
|
31473
|
+
(_, index) => getNumericValue(
|
|
30610
31474
|
Math.min(sparkline.range.start.row, sparkline.range.end.row) + index,
|
|
30611
31475
|
sparkline.range.start.col
|
|
30612
31476
|
)
|
|
30613
31477
|
) : null;
|
|
30614
|
-
const checkboxState = mergedStyle?.cellControl ? getCellBooleanValue(worksheet, row, col) : null;
|
|
31478
|
+
const checkboxState = mergedStyle?.cellControl ? worksheet ? getCellBooleanValue(worksheet, row, col) : getBatchedCellBooleanValue(batchedCell) : null;
|
|
30615
31479
|
const nextData = {
|
|
30616
31480
|
canvas: void 0,
|
|
30617
31481
|
checkboxState,
|
|
30618
31482
|
colSpan: merge?.colSpan,
|
|
30619
|
-
conditionalColorScale: resolveConditionalColorScaleForCell(
|
|
30620
|
-
|
|
30621
|
-
|
|
30622
|
-
worksheet,
|
|
30623
|
-
sheet,
|
|
30624
|
-
conditionalFormatMetricsCache
|
|
30625
|
-
),
|
|
30626
|
-
conditionalDataBar: resolveConditionalDataBarForCell(
|
|
30627
|
-
row,
|
|
30628
|
-
col,
|
|
30629
|
-
worksheet,
|
|
30630
|
-
sheet,
|
|
30631
|
-
conditionalFormatMetricsCache
|
|
30632
|
-
),
|
|
30633
|
-
conditionalIcon: resolveConditionalIconForCell(
|
|
30634
|
-
row,
|
|
30635
|
-
col,
|
|
30636
|
-
worksheet,
|
|
30637
|
-
sheet,
|
|
30638
|
-
conditionalFormatMetricsCache
|
|
30639
|
-
),
|
|
31483
|
+
conditionalColorScale: worksheet ? resolveConditionalColorScaleForCell(row, col, worksheet, sheet, conditionalFormatMetricsCache) : null,
|
|
31484
|
+
conditionalDataBar: worksheet ? resolveConditionalDataBarForCell(row, col, worksheet, sheet, conditionalFormatMetricsCache) : null,
|
|
31485
|
+
conditionalIcon: worksheet ? resolveConditionalIconForCell(row, col, worksheet, sheet, conditionalFormatMetricsCache) : null,
|
|
30640
31486
|
isMergedSecondary: false,
|
|
30641
31487
|
rowSpan: merge?.rowSpan,
|
|
30642
31488
|
sparkline: sparkline && sparklineValues ? { config: sparkline, values: sparklineValues } : null,
|
|
@@ -30644,7 +31490,7 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30644
31490
|
showGridLines
|
|
30645
31491
|
}),
|
|
30646
31492
|
textRotationDeg: resolveSpreadsheetTextRotation(alignment?.textRotation),
|
|
30647
|
-
value: sparkline ? "" : checkboxState !== null ? "" : getCellDisplayValue(worksheet, row, col, sheet)
|
|
31493
|
+
value: sparkline ? "" : checkboxState !== null ? "" : worksheet ? getCellDisplayValue(worksheet, row, col, sheet) : batchedCell?.value ?? ""
|
|
30648
31494
|
};
|
|
30649
31495
|
nextData.canvas = buildCanvasCellStyleCache(nextData.style);
|
|
30650
31496
|
cellRenderCache.set(cacheKey, nextData);
|
|
@@ -30918,12 +31764,14 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
30918
31764
|
getSheetFormControls,
|
|
30919
31765
|
getSheetImages,
|
|
30920
31766
|
getSheetShapes,
|
|
31767
|
+
getWorkerThumbnailRowBatch,
|
|
30921
31768
|
getThumbnailImage,
|
|
30922
31769
|
includeHeaders,
|
|
30923
31770
|
palette,
|
|
30924
31771
|
resolution,
|
|
30925
31772
|
sheets,
|
|
30926
31773
|
thumbnailImageLoadVersion,
|
|
31774
|
+
workerThumbnailRowBatchVersion,
|
|
30927
31775
|
workbook
|
|
30928
31776
|
]);
|
|
30929
31777
|
const paintThumbnail = React4.useCallback(
|