@a3s-lab/office 0.26.0 → 0.27.0
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 +75 -2
- package/dist/0~4595.js +16 -2
- package/dist/0~5093.js +463 -201
- package/dist/0~6090.js +77 -77
- package/dist/{0~2805.js → 0~7043.js} +305 -2
- package/dist/0~document-editor.js +2451 -985
- package/dist/0~spreadsheet-editor.js +1324 -378
- package/dist/0~work-docx-export.js +492 -10
- package/dist/0~work-docx-import.js +171 -98
- package/dist/0~work-office-diagnostics.js +198 -4
- package/dist/{164.js → 1544.js} +1083 -785
- package/dist/4104.js +145 -29
- package/dist/6282.js +1774 -384
- package/dist/core.js +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/features/work/editors/document-command-catalog.d.ts +102 -0
- package/dist/internal/features/work/editors/document-font-dialog-model.d.ts +83 -0
- package/dist/internal/features/work/editors/document-font-dialog-script-font-model.d.ts +18 -0
- package/dist/internal/features/work/editors/document-font-dialog.d.ts +9 -0
- package/dist/internal/features/work/editors/document-home-ribbon.d.ts +2 -1
- package/dist/internal/features/work/editors/document-page-chrome-editor.d.ts +6 -0
- package/dist/internal/features/work/editors/document-page-chrome-ribbon.d.ts +2 -1
- package/dist/internal/features/work/editors/document-strike-ribbon.d.ts +7 -0
- package/dist/internal/features/work/editors/document-text-case-ribbon.d.ts +4 -0
- package/dist/internal/features/work/editors/document-toolbar.d.ts +3 -1
- package/dist/internal/features/work/editors/document-underline-ribbon.d.ts +9 -0
- package/dist/internal/features/work/editors/document-wps-shortcuts.d.ts +1 -0
- package/dist/internal/features/work/editors/spreadsheet-cell-fill-format.d.ts +11 -0
- package/dist/internal/features/work/editors/spreadsheet-cell-format.d.ts +2 -1
- package/dist/internal/features/work/editors/spreadsheet-format-cells-dialog-model.d.ts +13 -2
- package/dist/internal/features/work/editors/spreadsheet-format-cells-fill-panel.d.ts +13 -0
- package/dist/internal/features/work/editors/spreadsheet-format-cells-fill-preview.d.ts +6 -0
- package/dist/internal/features/work/editors/spreadsheet-format-painter.d.ts +1 -1
- package/dist/internal/features/work/editors/work-office-chrome.d.ts +9 -1
- package/dist/internal/features/work/work-document-character-formatting.d.ts +16 -1
- package/dist/internal/features/work/work-document-character-position.d.ts +9 -0
- package/dist/internal/features/work/work-document-character-scale.d.ts +8 -0
- package/dist/internal/features/work/work-document-character-spacing.d.ts +8 -0
- package/dist/internal/features/work/work-document-emphasis.d.ts +7 -0
- package/dist/internal/features/work/work-document-equations.d.ts +2 -1
- package/dist/internal/features/work/work-document-format-changes.d.ts +16 -2
- package/dist/internal/features/work/work-document-hidden-text.d.ts +5 -0
- package/dist/internal/features/work/work-document-kerning.d.ts +10 -0
- package/dist/internal/features/work/work-document-script-font-extension.d.ts +2 -0
- package/dist/internal/features/work/work-document-script-fonts.d.ts +51 -0
- package/dist/internal/features/work/work-document-strike.d.ts +21 -0
- package/dist/internal/features/work/work-document-text-case.d.ts +10 -0
- package/dist/internal/features/work/work-document-underline.d.ts +37 -0
- package/dist/internal/features/work/work-document-word-line-metrics.d.ts +12 -0
- package/dist/internal/features/work/work-docx-character-position.d.ts +2 -0
- package/dist/internal/features/work/work-docx-character-scale.d.ts +2 -0
- package/dist/internal/features/work/work-docx-character-spacing.d.ts +4 -0
- package/dist/internal/features/work/work-docx-emphasis-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-emphasis.d.ts +14 -0
- package/dist/internal/features/work/work-docx-hidden-text-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-hidden-text-export.d.ts +16 -0
- package/dist/internal/features/work/work-docx-hidden-text.d.ts +11 -0
- package/dist/internal/features/work/work-docx-kerning-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-kerning.d.ts +14 -0
- package/dist/internal/features/work/work-docx-run-fonts-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-run-fonts-export.d.ts +14 -0
- package/dist/internal/features/work/work-docx-run-fonts.d.ts +13 -0
- package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +23 -2
- package/dist/internal/features/work/work-docx-run-script-font-import.d.ts +9 -0
- package/dist/internal/features/work/work-docx-strike.d.ts +8 -0
- package/dist/internal/features/work/work-docx-theme-reference.d.ts +1 -1
- package/dist/internal/features/work/work-docx-twips.d.ts +6 -0
- package/dist/internal/features/work/work-docx-underline.d.ts +3 -0
- package/dist/internal/features/work/work-spreadsheet-gradient-fill-canvas.d.ts +10 -0
- package/dist/internal/features/work/work-spreadsheet-native-fill-canvas.d.ts +8 -0
- package/dist/internal/features/work/work-spreadsheet-pattern-fill-canvas.d.ts +8 -0
- package/dist/internal/features/work/work-xlsx-cell-style-origin.d.ts +2 -1
- package/dist/internal/features/work/work-xlsx-cell-style-writer.d.ts +3 -0
- package/dist/internal/features/work/work-xlsx-cell-styles.d.ts +4 -0
- package/dist/internal/features/work/work-xlsx-gradient-fill.d.ts +31 -0
- package/dist/internal/features/work/work-xlsx-native-fill.d.ts +17 -0
- package/dist/internal/features/work/work-xlsx-pattern-fill.d.ts +21 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +770 -80
- package/docs/latest/en/browser-editor-architecture.md +10 -0
- package/package.json +32 -1
|
@@ -4,7 +4,7 @@ import { Workbook } from "@fortune-sheet/react";
|
|
|
4
4
|
import { AArrowDown, AArrowUp, AlignCenter, AlignLeft, AlignRight, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignVerticalJustifyStart, ArrowDown, ArrowDownToLine, ArrowLeft, ArrowLeftToLine, ArrowRight, ArrowRightToLine, ArrowUp, ArrowUpToLine, BadgeJapaneseYen, BarChart3, BetweenHorizontalEnd, BetweenHorizontalStart, BetweenVerticalEnd, BetweenVerticalStart, Bold, Bookmark, Calculator, CalendarClock, CalendarDays, Check, ChevronDown, ChevronLeft, ChevronRight, ClipboardPaste, Clock, Cloud, Columns3, Copy, CopyPlus, DecimalsArrowLeft, DecimalsArrowRight, Eraser, Eye, EyeOff, FileX2, Globe2, Grid2X2, Grid3X3, Hash, Italic, KeyRound, Layers2, Link2, Link2Off, ListChecks, ListFilter, LocateFixed, Merge, MessageSquareX, MoveHorizontal, MoveVertical, Paintbrush, Palette, PanelLeft, PanelTop, PanelsTopLeft, Pencil, Percent, Plus, Printer, Redo2, RefreshCw, Rows3, Save, Scissors, Search, Settings2, ShieldCheck, Sigma, SortAsc, SortDesc, Strikethrough, SwatchBook, Table2, TableProperties, Trash2, Underline, Undo2, WrapText, X } from "lucide-react";
|
|
5
5
|
import { Fragment as external_react_Fragment, cloneElement, memo, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
6
6
|
import { convertSpanToShareString, genarate, indexToColumnChar, update as core_update } from "@fortune-sheet/core";
|
|
7
|
-
import { freezeImportedSpreadsheetCell, spreadsheetMatrixProfile, xlsxRichTextCellText, spreadsheetTextOrientationFromAngle, spreadsheetCellValueWithDiagonalBorder, xlsxSemanticColorMatchesValue, spreadsheetUnderlineCellValue, normalizeXlsxRichTextEditSource, attachSpreadsheetShownCommentCells, sameSpreadsheetHistoryValue, isSpreadsheetConditionalComparisonOperator, defaultSpreadsheetConditionalIconThresholds, normalizeXlsxRichTextCell, normalizeSpreadsheetDateValidationBoundary, unlockedCellCount, editableRangeRequiresCredentials, spreadsheetTextOrientationChoiceFromCell, spreadsheetConditionalThresholdValue, withSheetProtection, defaultSpreadsheetColorScaleThresholds, protectedSheetCount, sameXlsxRichTextRunStyle, withSheetSelectionPermissions, spreadsheetTextOrientationFromCell, patchSpreadsheetRichTextFontRuns, readOfficeSpreadsheetCollaboration as readWorkOfficeSpreadsheetCollaboration, spreadsheetConditionalThresholdsEqual, spreadsheetVisibleTextRotationFromCell, spreadsheetTextOrientationFromChoice, normalizeXlsxSemanticColorOrigin, withoutEditableRange, isSpreadsheetTextOrientationId, normalizeSpreadsheetConditionalVisualOptions, effectiveSpreadsheetPageSetup, normalizeXlsxRichTextColor, isHighSurrogate, withEditableRange, createOfficeSpreadsheetCollaborationBinding as createWorkOfficeSpreadsheetCollaborationBinding, spreadsheetConditionalIconForValue, spreadsheetUnderlineStyle, sheetProtectionAuthority, editableRangeCellCount, registerDerivedSpreadsheetMatrix,
|
|
7
|
+
import { freezeImportedSpreadsheetCell, withXlsxPatternFill, spreadsheetMatrixProfile, xlsxRichTextCellText, spreadsheetTextOrientationFromAngle, spreadsheetCellValueWithDiagonalBorder, xlsxSemanticColorMatchesValue, spreadsheetUnderlineCellValue, normalizeXlsxRichTextEditSource, attachSpreadsheetShownCommentCells, sameSpreadsheetHistoryValue, isSpreadsheetConditionalComparisonOperator, defaultSpreadsheetConditionalIconThresholds, normalizeXlsxRichTextCell, activeXlsxNativeFill, xlsxPatternFillTypes, normalizeSpreadsheetDateValidationBoundary, unlockedCellCount, editableRangeRequiresCredentials, spreadsheetTextOrientationChoiceFromCell, spreadsheetConditionalThresholdValue, withSheetProtection, defaultSpreadsheetColorScaleThresholds, protectedSheetCount, sameXlsxRichTextRunStyle, withSheetSelectionPermissions, spreadsheetTextOrientationFromCell, patchSpreadsheetRichTextFontRuns, readOfficeSpreadsheetCollaboration as readWorkOfficeSpreadsheetCollaboration, spreadsheetConditionalThresholdsEqual, spreadsheetVisibleTextRotationFromCell, spreadsheetTextOrientationFromChoice, normalizeXlsxSemanticColorOrigin, withoutEditableRange, isSpreadsheetTextOrientationId, normalizeSpreadsheetConditionalVisualOptions, withXlsxGradientFill, effectiveSpreadsheetPageSetup, normalizeXlsxPatternFill, normalizeXlsxRichTextColor, isHighSurrogate, xlsxNativeFillCellKeys, withEditableRange, createOfficeSpreadsheetCollaborationBinding as createWorkOfficeSpreadsheetCollaborationBinding, spreadsheetConditionalIconForValue, spreadsheetUnderlineStyle, sheetProtectionAuthority, normalizeXlsxGradientFill, xlsxGradientFillFallbackColor, editableRangeCellCount, registerDerivedSpreadsheetMatrix, deleteXlsxNativeFills, spreadsheetTextOrientationCellStyle, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, normalizeSheetProtectionAuthority, spreadsheetProtectionKey, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, normalizeXlsxRichTextRun, spreadsheetDiagonalBorderFromCellValue, SPREADSHEET_CONDITIONAL_ICON_SETS, isLowSurrogate, spreadsheetConditionalComparisonNeedsUpperValue, drawSpreadsheetConditionalIcon, coalesceXlsxRichTextRuns, replaceOfficeSpreadsheetCollaboration as replaceWorkOfficeSpreadsheetCollaboration, validXlsxRichText, isSpreadsheetUnderlineStyle } from "./1544.js";
|
|
8
8
|
import { workSpreadsheetChartSupportsGrouping, spreadsheetFormulaRangesForSelection, createSpreadsheetChartFromSelection, normalizeWorkSpreadsheetDataLabelPosition, normalizeSpreadsheetPrintTitleColumns, normalizeSpreadsheetPrintTitleRows, formulaHasStructuredReference, normalizeWorkSpreadsheetErrorBars, defaultPivotValueCaption, workSpreadsheetChartSupportsBarSpacing, normalizeWorkSpreadsheetChartGrouping, spreadsheetGridSize, normalizeWorkSpreadsheetChartAxisGroup, normalizeWorkSpreadsheetScatterStyle, cloneSparseMatrix, spreadsheetPivotAggregationLabel, workSpreadsheetChartAxisIsCategoryAxis, reconcileSpreadsheetChartPreviews, normalizeWorkSpreadsheetChartAxes, normalizeWorkSpreadsheetDoughnutHoleSize, normalizeWorkSpreadsheetChartLegendPosition, spreadsheetChartCount, workSpreadsheetChartTypeLabel, sparseArrayEntries, normalizeWorkSpreadsheetTrendline, effectiveSpreadsheetCalculationSettings, spreadsheetPivotIntersects, normalizeWorkSpreadsheetDataLabels, spreadsheetPivotOutputContains, normalizeSpreadsheetPrintArea, spreadsheetCellAddress, formatSpreadsheetCellRanges, normalizeWorkSpreadsheetChartLayout, spreadsheetFormulaRangeForCell, workSpreadsheetChartAxisIsValueAxis, normalizeWorkSpreadsheetChartSmoothLines, spreadsheetPivotFilterValueKey, normalizeWorkSpreadsheetBubbleScale, normalizeWorkSpreadsheetChartSeriesStyle, volatileSpreadsheetFormulaFunctions, sparseArrayIndexes, normalizeWorkSpreadsheetBubbleSizeRepresents, workSpreadsheetChartSupportsTrendlines, normalizeWorkSpreadsheetChartLegendOverlay, parseSpreadsheetChartReference, workSpreadsheetChartGroupingIsStacked, normalizeWorkSpreadsheetChartGapWidth, workSpreadsheetChartSupportsSmoothLines, refreshSpreadsheetPivotTables, createSpreadsheetPivotFromSelection, reconcileSpreadsheetPivots, spreadsheetPivotCount, sparseMatrixColumnCount, workSpreadsheetChartSupportsErrorBars, formulaHasExternalReference, isValidSpreadsheetDefinedName, spreadsheetPivotValidation, deleteSpreadsheetPivotTable, workSpreadsheetChartAxisDefaultLabelPosition, workSpreadsheetChartSupportsSeriesAnalysis, parseSpreadsheetCellRanges, spreadsheetPivotFilterItems, spreadsheetPivotFields, normalizeWorkSpreadsheetChartOverlap, spreadsheetFormulaRangeConflict, spreadsheetSheetsWithChartPreviews, workSpreadsheetChartUsesNumericXAxis, workSpreadsheetChartAxisShowsMajorGridlinesByDefault, workSpreadsheetChartSupportsAxes, normalizeWorkSpreadsheetCombinationSeriesType, normalizeWorkSpreadsheetRadarStyle } from "./8715.js";
|
|
9
9
|
import { moveOfficeMenuFocus, stepOfficeZoom, useOfficeRemoteParticipants, Popover, officePresenceColor, useOfficePublishPresenceLocation, button_Button, icon_button_IconButton, moveOfficeGridMenuFocus, office_text_field_OfficeTextField, useDialogFocusScope, useOfficeEditorWheelZoom } from "./0~6090.js";
|
|
10
10
|
import { normalizeCssColor } from "./9424.js";
|
|
@@ -544,6 +544,248 @@ function spreadsheetDiagonalLineDash(style) {
|
|
|
544
544
|
];
|
|
545
545
|
return [];
|
|
546
546
|
}
|
|
547
|
+
const MAX_PATH_GRADIENT_CONTOURS = 96;
|
|
548
|
+
function drawSpreadsheetGradientFill(context, bounds, fill, fillRect = context.fillRect) {
|
|
549
|
+
const left = Math.min(bounds.startX, bounds.endX);
|
|
550
|
+
const top = Math.min(bounds.startY, bounds.endY);
|
|
551
|
+
const right = Math.max(bounds.startX, bounds.endX);
|
|
552
|
+
const bottom = Math.max(bounds.startY, bounds.endY);
|
|
553
|
+
const width = right - left;
|
|
554
|
+
const height = bottom - top;
|
|
555
|
+
if (width <= 0 || height <= 0) return;
|
|
556
|
+
context.save();
|
|
557
|
+
if ('linear' === fill.type) drawLinearGradient(context, left, top, width, height, fill, fillRect);
|
|
558
|
+
else drawPathGradient(context, left, top, width, height, fill, fillRect);
|
|
559
|
+
context.restore();
|
|
560
|
+
}
|
|
561
|
+
function drawLinearGradient(context, left, top, width, height, fill, fillRect) {
|
|
562
|
+
if ('function' != typeof context.createLinearGradient) {
|
|
563
|
+
context.fillStyle = fill.stops[0]?.color ?? '#ffffff';
|
|
564
|
+
fillRect.call(context, left, top, width, height);
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
const radians = fill.degree * Math.PI / 180;
|
|
568
|
+
const horizontal = Math.cos(radians);
|
|
569
|
+
const vertical = Math.sin(radians);
|
|
570
|
+
const centerX = left + width / 2;
|
|
571
|
+
const centerY = top + height / 2;
|
|
572
|
+
const span = Math.abs(width * horizontal) + Math.abs(height * vertical);
|
|
573
|
+
const gradient = context.createLinearGradient(centerX - horizontal * span / 2, centerY - vertical * span / 2, centerX + horizontal * span / 2, centerY + vertical * span / 2);
|
|
574
|
+
for (const stop of fill.stops)gradient.addColorStop(stop.position, stop.color);
|
|
575
|
+
context.fillStyle = gradient;
|
|
576
|
+
fillRect.call(context, left, top, width, height);
|
|
577
|
+
}
|
|
578
|
+
function drawPathGradient(context, left, top, width, height, fill, fillRect) {
|
|
579
|
+
const innerLeft = left + width * fill.left;
|
|
580
|
+
const innerRight = left + width * fill.right;
|
|
581
|
+
const innerTop = top + height * fill.top;
|
|
582
|
+
const innerBottom = top + height * fill.bottom;
|
|
583
|
+
const contours = Math.min(MAX_PATH_GRADIENT_CONTOURS, Math.max(2, Math.ceil(Math.max(width, height))));
|
|
584
|
+
for(let index = contours; index >= 0; index -= 1){
|
|
585
|
+
const progress = index / contours;
|
|
586
|
+
const contourLeft = interpolate(innerLeft, left, progress);
|
|
587
|
+
const contourRight = interpolate(innerRight, left + width, progress);
|
|
588
|
+
const contourTop = interpolate(innerTop, top, progress);
|
|
589
|
+
const contourBottom = interpolate(innerBottom, top + height, progress);
|
|
590
|
+
context.fillStyle = gradientColorAt(fill.stops, progress);
|
|
591
|
+
fillRect.call(context, contourLeft, contourTop, contourRight - contourLeft, contourBottom - contourTop);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
function gradientColorAt(stops, position) {
|
|
595
|
+
const first = stops[0];
|
|
596
|
+
const last = stops.at(-1);
|
|
597
|
+
if (!first || !last || position <= first.position) return first?.color ?? '#ffffff';
|
|
598
|
+
if (position >= last.position) return last.color;
|
|
599
|
+
for(let index = 1; index < stops.length; index += 1){
|
|
600
|
+
const right = stops[index];
|
|
601
|
+
const left = stops[index - 1];
|
|
602
|
+
if (!left || !right || position > right.position) continue;
|
|
603
|
+
const span = right.position - left.position;
|
|
604
|
+
const progress = span > 0 ? (position - left.position) / span : 1;
|
|
605
|
+
return interpolateRgb(left.color, right.color, progress);
|
|
606
|
+
}
|
|
607
|
+
return last.color;
|
|
608
|
+
}
|
|
609
|
+
function interpolateRgb(left, right, progress) {
|
|
610
|
+
const leftRgb = rgbChannels(left);
|
|
611
|
+
const rightRgb = rgbChannels(right);
|
|
612
|
+
if (!leftRgb || !rightRgb) return progress < 0.5 ? left : right;
|
|
613
|
+
return `#${leftRgb.map((channel, index)=>Math.round(interpolate(channel, rightRgb[index] ?? channel, progress)).toString(16).padStart(2, '0')).join('')}`;
|
|
614
|
+
}
|
|
615
|
+
function rgbChannels(color) {
|
|
616
|
+
if (!/^#[0-9a-f]{6}$/i.test(color)) return null;
|
|
617
|
+
return [
|
|
618
|
+
Number.parseInt(color.slice(1, 3), 16),
|
|
619
|
+
Number.parseInt(color.slice(3, 5), 16),
|
|
620
|
+
Number.parseInt(color.slice(5, 7), 16)
|
|
621
|
+
];
|
|
622
|
+
}
|
|
623
|
+
function interpolate(left, right, progress) {
|
|
624
|
+
return left + (right - left) * progress;
|
|
625
|
+
}
|
|
626
|
+
function drawSpreadsheetPatternFillOverlay(context, bounds, fill) {
|
|
627
|
+
const left = Math.min(bounds.startX, bounds.endX) + 1;
|
|
628
|
+
const top = Math.min(bounds.startY, bounds.endY) + 1;
|
|
629
|
+
const right = Math.max(bounds.startX, bounds.endX) - 1;
|
|
630
|
+
const bottom = Math.max(bounds.startY, bounds.endY) - 1;
|
|
631
|
+
if (right <= left || bottom <= top) return;
|
|
632
|
+
context.save();
|
|
633
|
+
context.beginPath();
|
|
634
|
+
context.rect(left, top, right - left, bottom - top);
|
|
635
|
+
context.clip();
|
|
636
|
+
context.strokeStyle = fill.foregroundColor;
|
|
637
|
+
context.fillStyle = fill.foregroundColor;
|
|
638
|
+
context.setLineDash([]);
|
|
639
|
+
switch(fill.patternType){
|
|
640
|
+
case 'darkHorizontal':
|
|
641
|
+
drawHorizontalLines(context, left, top, right, bottom, 4, 2);
|
|
642
|
+
break;
|
|
643
|
+
case 'lightHorizontal':
|
|
644
|
+
drawHorizontalLines(context, left, top, right, bottom, 7, 1);
|
|
645
|
+
break;
|
|
646
|
+
case 'darkVertical':
|
|
647
|
+
drawVerticalLines(context, left, top, right, bottom, 4, 2);
|
|
648
|
+
break;
|
|
649
|
+
case 'lightVertical':
|
|
650
|
+
drawVerticalLines(context, left, top, right, bottom, 7, 1);
|
|
651
|
+
break;
|
|
652
|
+
case 'darkDown':
|
|
653
|
+
drawDiagonalLines(context, left, top, right, bottom, 5, 2, 'down');
|
|
654
|
+
break;
|
|
655
|
+
case 'lightDown':
|
|
656
|
+
drawDiagonalLines(context, left, top, right, bottom, 8, 1, 'down');
|
|
657
|
+
break;
|
|
658
|
+
case 'darkUp':
|
|
659
|
+
drawDiagonalLines(context, left, top, right, bottom, 5, 2, 'up');
|
|
660
|
+
break;
|
|
661
|
+
case 'lightUp':
|
|
662
|
+
drawDiagonalLines(context, left, top, right, bottom, 8, 1, 'up');
|
|
663
|
+
break;
|
|
664
|
+
case 'darkGrid':
|
|
665
|
+
drawHorizontalLines(context, left, top, right, bottom, 5, 1.5);
|
|
666
|
+
drawVerticalLines(context, left, top, right, bottom, 5, 1.5);
|
|
667
|
+
break;
|
|
668
|
+
case 'lightGrid':
|
|
669
|
+
drawHorizontalLines(context, left, top, right, bottom, 8, 1);
|
|
670
|
+
drawVerticalLines(context, left, top, right, bottom, 8, 1);
|
|
671
|
+
break;
|
|
672
|
+
case 'darkTrellis':
|
|
673
|
+
drawDiagonalLines(context, left, top, right, bottom, 6, 1.5, 'down');
|
|
674
|
+
drawDiagonalLines(context, left, top, right, bottom, 6, 1.5, 'up');
|
|
675
|
+
break;
|
|
676
|
+
case 'lightTrellis':
|
|
677
|
+
drawDiagonalLines(context, left, top, right, bottom, 10, 1, 'down');
|
|
678
|
+
drawDiagonalLines(context, left, top, right, bottom, 10, 1, 'up');
|
|
679
|
+
break;
|
|
680
|
+
case 'gray0625':
|
|
681
|
+
drawPatternDots(context, left, top, right, bottom, 8, 1);
|
|
682
|
+
break;
|
|
683
|
+
case 'gray125':
|
|
684
|
+
drawPatternDots(context, left, top, right, bottom, 6, 1);
|
|
685
|
+
break;
|
|
686
|
+
case 'lightGray':
|
|
687
|
+
drawPatternDots(context, left, top, right, bottom, 4, 1.5);
|
|
688
|
+
break;
|
|
689
|
+
case 'mediumGray':
|
|
690
|
+
drawDiagonalLines(context, left, top, right, bottom, 4, 1, 'down');
|
|
691
|
+
drawDiagonalLines(context, left, top, right, bottom, 4, 1, 'up');
|
|
692
|
+
break;
|
|
693
|
+
case 'darkGray':
|
|
694
|
+
context.fillRect(left, top, right - left, bottom - top);
|
|
695
|
+
context.fillStyle = fill.backgroundColor;
|
|
696
|
+
drawPatternDots(context, left, top, right, bottom, 4, 1.5);
|
|
697
|
+
break;
|
|
698
|
+
}
|
|
699
|
+
context.restore();
|
|
700
|
+
}
|
|
701
|
+
function drawHorizontalLines(context, left, top, right, bottom, requestedSpacing, lineWidth) {
|
|
702
|
+
const spacing = boundedLineSpacing(bottom - top, requestedSpacing);
|
|
703
|
+
context.lineWidth = lineWidth;
|
|
704
|
+
context.beginPath();
|
|
705
|
+
for(let y = alignedPatternStart(top, spacing); y <= bottom; y += spacing){
|
|
706
|
+
context.moveTo(left, crispPatternCoordinate(y, lineWidth));
|
|
707
|
+
context.lineTo(right, crispPatternCoordinate(y, lineWidth));
|
|
708
|
+
}
|
|
709
|
+
context.stroke();
|
|
710
|
+
}
|
|
711
|
+
function drawVerticalLines(context, left, top, right, bottom, requestedSpacing, lineWidth) {
|
|
712
|
+
const spacing = boundedLineSpacing(right - left, requestedSpacing);
|
|
713
|
+
context.lineWidth = lineWidth;
|
|
714
|
+
context.beginPath();
|
|
715
|
+
for(let x = alignedPatternStart(left, spacing); x <= right; x += spacing){
|
|
716
|
+
context.moveTo(crispPatternCoordinate(x, lineWidth), top);
|
|
717
|
+
context.lineTo(crispPatternCoordinate(x, lineWidth), bottom);
|
|
718
|
+
}
|
|
719
|
+
context.stroke();
|
|
720
|
+
}
|
|
721
|
+
function drawDiagonalLines(context, left, top, right, bottom, requestedSpacing, lineWidth, direction) {
|
|
722
|
+
const height = bottom - top;
|
|
723
|
+
const spacing = boundedLineSpacing(right - left + height, requestedSpacing);
|
|
724
|
+
context.lineWidth = lineWidth;
|
|
725
|
+
context.beginPath();
|
|
726
|
+
const first = alignedPatternStart(left - height, spacing);
|
|
727
|
+
for(let x = first; x <= right; x += spacing)if ('down' === direction) {
|
|
728
|
+
context.moveTo(x, top);
|
|
729
|
+
context.lineTo(x + height, bottom);
|
|
730
|
+
} else {
|
|
731
|
+
context.moveTo(x, bottom);
|
|
732
|
+
context.lineTo(x + height, top);
|
|
733
|
+
}
|
|
734
|
+
context.stroke();
|
|
735
|
+
}
|
|
736
|
+
function drawPatternDots(context, left, top, right, bottom, requestedSpacing, size) {
|
|
737
|
+
const area = Math.max(1, (right - left) * (bottom - top));
|
|
738
|
+
const spacing = Math.max(requestedSpacing, Math.sqrt(area / 2048));
|
|
739
|
+
const startX = alignedPatternStart(left, spacing);
|
|
740
|
+
const startY = alignedPatternStart(top, spacing);
|
|
741
|
+
for(let y = startY; y <= bottom; y += spacing){
|
|
742
|
+
const offset = Math.round(y / spacing) % 2 ? spacing / 2 : 0;
|
|
743
|
+
for(let x = startX + offset; x <= right; x += spacing)context.fillRect(x, y, size, size);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
function alignedPatternStart(value, spacing) {
|
|
747
|
+
return Math.floor(value / spacing) * spacing;
|
|
748
|
+
}
|
|
749
|
+
function boundedLineSpacing(span, requested) {
|
|
750
|
+
return Math.max(requested, span / 512);
|
|
751
|
+
}
|
|
752
|
+
function crispPatternCoordinate(value, lineWidth) {
|
|
753
|
+
return Math.round(value) + (Math.round(lineWidth) % 2 ? 0.5 : 0);
|
|
754
|
+
}
|
|
755
|
+
const pendingContextRestores = new WeakMap();
|
|
756
|
+
function beginSpreadsheetNativeFillRender(fill, context) {
|
|
757
|
+
finishSpreadsheetNativeFillRender(context);
|
|
758
|
+
if (!fill || 'function' != typeof context.fillRect) return;
|
|
759
|
+
context.fillStyle = 'gradient' === fill.kind ? fill.value.stops[0]?.color ?? '#ffffff' : fill.value.backgroundColor;
|
|
760
|
+
const fillRect = context.fillRect;
|
|
761
|
+
pendingContextRestores.set(context, {
|
|
762
|
+
fillRect,
|
|
763
|
+
fillRectOwned: Object.hasOwn(context, 'fillRect')
|
|
764
|
+
});
|
|
765
|
+
context.fillRect = (x, y, width, height)=>{
|
|
766
|
+
restoreSpreadsheetNativeFillContext(context);
|
|
767
|
+
const bounds = {
|
|
768
|
+
endX: x + width,
|
|
769
|
+
endY: y + height,
|
|
770
|
+
startX: x,
|
|
771
|
+
startY: y
|
|
772
|
+
};
|
|
773
|
+
if ('gradient' === fill.kind) return void drawSpreadsheetGradientFill(context, bounds, fill.value, fillRect);
|
|
774
|
+
context.fillStyle = fill.value.backgroundColor;
|
|
775
|
+
fillRect.call(context, x, y, width, height);
|
|
776
|
+
drawSpreadsheetPatternFillOverlay(context, bounds, fill.value);
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
function finishSpreadsheetNativeFillRender(context) {
|
|
780
|
+
restoreSpreadsheetNativeFillContext(context);
|
|
781
|
+
}
|
|
782
|
+
function restoreSpreadsheetNativeFillContext(context) {
|
|
783
|
+
const restore = pendingContextRestores.get(context);
|
|
784
|
+
if (!restore) return;
|
|
785
|
+
if (restore.fillRectOwned) context.fillRect = restore.fillRect;
|
|
786
|
+
else delete context.fillRect;
|
|
787
|
+
pendingContextRestores.delete(context);
|
|
788
|
+
}
|
|
547
789
|
function spreadsheet_cell_range_normalizeSpreadsheetCellRange(value) {
|
|
548
790
|
const row = normalizeSpreadsheetCellRangeAxis(value.row);
|
|
549
791
|
const column = normalizeSpreadsheetCellRangeAxis(value.column);
|
|
@@ -4701,7 +4943,8 @@ const spreadsheetCellFormatProperties = [
|
|
|
4701
4943
|
'rt',
|
|
4702
4944
|
'ct',
|
|
4703
4945
|
'lo',
|
|
4704
|
-
'hi'
|
|
4946
|
+
'hi',
|
|
4947
|
+
...xlsxNativeFillCellKeys
|
|
4705
4948
|
];
|
|
4706
4949
|
function clearSpreadsheetSheetSelection(sheet, selection, mode) {
|
|
4707
4950
|
const range = normalizeClearRange(selection);
|
|
@@ -5208,6 +5451,79 @@ function setSpreadsheetCellBordersPerCell(content, sheetId, range, formats) {
|
|
|
5208
5451
|
sheets
|
|
5209
5452
|
};
|
|
5210
5453
|
}
|
|
5454
|
+
function spreadsheetCellFillFormat(cell) {
|
|
5455
|
+
const nativeFill = activeXlsxNativeFill(cell);
|
|
5456
|
+
if (nativeFill) return nativeFill;
|
|
5457
|
+
const color = normalizeSpreadsheetFillColor(cell?.bg);
|
|
5458
|
+
return color ? {
|
|
5459
|
+
color,
|
|
5460
|
+
kind: 'solid'
|
|
5461
|
+
} : {
|
|
5462
|
+
kind: 'none'
|
|
5463
|
+
};
|
|
5464
|
+
}
|
|
5465
|
+
function normalizeSpreadsheetCellFillFormat(value) {
|
|
5466
|
+
if (!spreadsheet_cell_fill_format_isRecord(value)) return null;
|
|
5467
|
+
if ('none' === value.kind) return {
|
|
5468
|
+
kind: 'none'
|
|
5469
|
+
};
|
|
5470
|
+
if ('solid' === value.kind) {
|
|
5471
|
+
const color = normalizeSpreadsheetFillColor(value.color);
|
|
5472
|
+
return color ? {
|
|
5473
|
+
color,
|
|
5474
|
+
kind: 'solid'
|
|
5475
|
+
} : null;
|
|
5476
|
+
}
|
|
5477
|
+
if ('pattern' === value.kind) {
|
|
5478
|
+
const fill = normalizeXlsxPatternFill(value.value);
|
|
5479
|
+
return fill ? {
|
|
5480
|
+
kind: 'pattern',
|
|
5481
|
+
value: fill
|
|
5482
|
+
} : null;
|
|
5483
|
+
}
|
|
5484
|
+
if ('gradient' === value.kind) {
|
|
5485
|
+
const fill = normalizeXlsxGradientFill(value.value);
|
|
5486
|
+
return fill ? {
|
|
5487
|
+
kind: 'gradient',
|
|
5488
|
+
value: fill
|
|
5489
|
+
} : null;
|
|
5490
|
+
}
|
|
5491
|
+
return null;
|
|
5492
|
+
}
|
|
5493
|
+
function withSpreadsheetCellFillFormat(cell, fill) {
|
|
5494
|
+
const normalized = normalizeSpreadsheetCellFillFormat(fill);
|
|
5495
|
+
if (!normalized) return null;
|
|
5496
|
+
const next = {
|
|
5497
|
+
...cell
|
|
5498
|
+
};
|
|
5499
|
+
deleteXlsxNativeFills(next);
|
|
5500
|
+
if ('none' === normalized.kind) {
|
|
5501
|
+
delete next.bg;
|
|
5502
|
+
return next;
|
|
5503
|
+
}
|
|
5504
|
+
if ('solid' === normalized.kind) {
|
|
5505
|
+
next.bg = normalized.color;
|
|
5506
|
+
return next;
|
|
5507
|
+
}
|
|
5508
|
+
if ('pattern' === normalized.kind) {
|
|
5509
|
+
next.bg = normalized.value.backgroundColor;
|
|
5510
|
+
return withXlsxPatternFill(next, normalized.value);
|
|
5511
|
+
}
|
|
5512
|
+
next.bg = xlsxGradientFillFallbackColor(normalized.value);
|
|
5513
|
+
return withXlsxGradientFill(next, normalized.value);
|
|
5514
|
+
}
|
|
5515
|
+
function normalizeSpreadsheetFillColor(value) {
|
|
5516
|
+
if ('string' != typeof value) return null;
|
|
5517
|
+
const color = value.trim().toLowerCase();
|
|
5518
|
+
if (/^#[0-9a-f]{6}$/.test(color)) return color;
|
|
5519
|
+
if (!/^#[0-9a-f]{3}$/.test(color)) return null;
|
|
5520
|
+
return `#${[
|
|
5521
|
+
...color.slice(1)
|
|
5522
|
+
].map((character)=>character.repeat(2)).join('')}`;
|
|
5523
|
+
}
|
|
5524
|
+
function spreadsheet_cell_fill_format_isRecord(value) {
|
|
5525
|
+
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
5526
|
+
}
|
|
5211
5527
|
const MAX_SPREADSHEET_CELL_FORMAT_CELLS = 10000;
|
|
5212
5528
|
const patchKeys = new Set([
|
|
5213
5529
|
'numberFormat',
|
|
@@ -5223,7 +5539,7 @@ const patchKeys = new Set([
|
|
|
5223
5539
|
'italic',
|
|
5224
5540
|
'underline',
|
|
5225
5541
|
'strike',
|
|
5226
|
-
'
|
|
5542
|
+
'fill',
|
|
5227
5543
|
'borders',
|
|
5228
5544
|
'locked',
|
|
5229
5545
|
'hidden'
|
|
@@ -5243,7 +5559,7 @@ function canApplySpreadsheetCellFormat(content, request) {
|
|
|
5243
5559
|
'top',
|
|
5244
5560
|
'middle',
|
|
5245
5561
|
'bottom'
|
|
5246
|
-
].includes(patch.verticalAlignment) || void 0 !== patch.wrapText && 'boolean' != typeof patch.wrapText || void 0 !== patch.rotation && (!Number.isInteger(patch.rotation) || patch.rotation < -90 || patch.rotation > 90) || void 0 !== patch.textOrientation && !isSpreadsheetTextOrientationId(patch.textOrientation) || void 0 !== patch.rotation && void 0 !== patch.textOrientation || void 0 !== patch.fontFamily && !validTrimmedString(patch.fontFamily, 128) || void 0 !== patch.fontSize && (!Number.isFinite(patch.fontSize) || patch.fontSize < 1 || patch.fontSize > 409) || void 0 !== patch.fontColor && !normalizeColor(patch.fontColor) || void 0 !== patch.
|
|
5562
|
+
].includes(patch.verticalAlignment) || void 0 !== patch.wrapText && 'boolean' != typeof patch.wrapText || void 0 !== patch.rotation && (!Number.isInteger(patch.rotation) || patch.rotation < -90 || patch.rotation > 90) || void 0 !== patch.textOrientation && !isSpreadsheetTextOrientationId(patch.textOrientation) || void 0 !== patch.rotation && void 0 !== patch.textOrientation || void 0 !== patch.fontFamily && !validTrimmedString(patch.fontFamily, 128) || void 0 !== patch.fontSize && (!Number.isFinite(patch.fontSize) || patch.fontSize < 1 || patch.fontSize > 409) || void 0 !== patch.fontColor && !normalizeColor(patch.fontColor) || void 0 !== patch.fill && !normalizeSpreadsheetCellFillFormat(patch.fill) || !validOptionalBoolean(patch.bold) || !validOptionalBoolean(patch.italic) || void 0 !== patch.underline && !isSpreadsheetUnderlineStyle(patch.underline) || !validOptionalBoolean(patch.strike) || !validOptionalBoolean(patch.locked) || !validOptionalBoolean(patch.hidden)) return false;
|
|
5247
5563
|
if (void 0 !== patch.borders) {
|
|
5248
5564
|
const normalized = patch.borders.map(normalizeSpreadsheetBorderFormat);
|
|
5249
5565
|
if (normalized.some((format)=>!format || ![
|
|
@@ -5376,7 +5692,7 @@ function formatSparseCells(sheet, range, patch) {
|
|
|
5376
5692
|
};
|
|
5377
5693
|
}
|
|
5378
5694
|
function formatCell(source, patch) {
|
|
5379
|
-
|
|
5695
|
+
let next = {
|
|
5380
5696
|
...source ?? {}
|
|
5381
5697
|
};
|
|
5382
5698
|
const writable = next;
|
|
@@ -5418,8 +5734,10 @@ function formatCell(source, patch) {
|
|
|
5418
5734
|
if (void 0 !== patch.italic) next.it = patch.italic ? 1 : 0;
|
|
5419
5735
|
if (void 0 !== patch.underline) next.un = spreadsheetUnderlineCellValue(patch.underline);
|
|
5420
5736
|
if (void 0 !== patch.strike) next.cl = patch.strike ? 1 : 0;
|
|
5421
|
-
if (void 0 !== patch.
|
|
5422
|
-
|
|
5737
|
+
if (void 0 !== patch.fill) {
|
|
5738
|
+
const filled = withSpreadsheetCellFillFormat(next, patch.fill);
|
|
5739
|
+
if (filled) next = filled;
|
|
5740
|
+
}
|
|
5423
5741
|
if (void 0 !== patch.locked || void 0 !== patch.hidden) {
|
|
5424
5742
|
delete next.lo;
|
|
5425
5743
|
delete next.hi;
|
|
@@ -5910,10 +6228,14 @@ function applySpreadsheetCellStyle(content, sheetId, range, preset) {
|
|
|
5910
6228
|
for(let row = normalizedRange.row[0]; row <= normalizedRange.row[1]; row += 1){
|
|
5911
6229
|
const values = data[row] ?? [];
|
|
5912
6230
|
data[row] = values;
|
|
5913
|
-
for(let column = normalizedRange.column[0]; column <= normalizedRange.column[1]; column += 1)
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
6231
|
+
for(let column = normalizedRange.column[0]; column <= normalizedRange.column[1]; column += 1){
|
|
6232
|
+
const cell = {
|
|
6233
|
+
...values[column] ?? {},
|
|
6234
|
+
...definition.format
|
|
6235
|
+
};
|
|
6236
|
+
deleteXlsxNativeFills(cell);
|
|
6237
|
+
values[column] = cell;
|
|
6238
|
+
}
|
|
5917
6239
|
}
|
|
5918
6240
|
const nextSheet = {
|
|
5919
6241
|
...sheet,
|
|
@@ -9675,10 +9997,35 @@ function formatCells(context, attribute, value) {
|
|
|
9675
9997
|
if (context.richTextFormat?.canApply(attribute, value)) return context.richTextFormat.apply(attribute, value);
|
|
9676
9998
|
if (!context.workbook || !context.targetSheetId) return false;
|
|
9677
9999
|
if ('ct' === attribute && !isSpreadsheetCellTypeFormat(value)) return false;
|
|
10000
|
+
const range = spreadsheetLiveCommandRange(context);
|
|
10001
|
+
const options = {
|
|
10002
|
+
id: context.targetSheetId
|
|
10003
|
+
};
|
|
9678
10004
|
try {
|
|
9679
|
-
|
|
9680
|
-
|
|
9681
|
-
|
|
10005
|
+
if ('bg' === attribute) {
|
|
10006
|
+
context.workbook.batchCallApis([
|
|
10007
|
+
{
|
|
10008
|
+
name: 'setCellFormatByRange',
|
|
10009
|
+
args: [
|
|
10010
|
+
attribute,
|
|
10011
|
+
value,
|
|
10012
|
+
range,
|
|
10013
|
+
options
|
|
10014
|
+
]
|
|
10015
|
+
},
|
|
10016
|
+
...xlsxNativeFillCellKeys.map((fillAttribute)=>({
|
|
10017
|
+
name: 'setCellFormatByRange',
|
|
10018
|
+
args: [
|
|
10019
|
+
fillAttribute,
|
|
10020
|
+
void 0,
|
|
10021
|
+
range,
|
|
10022
|
+
options
|
|
10023
|
+
]
|
|
10024
|
+
}))
|
|
10025
|
+
]);
|
|
10026
|
+
return true;
|
|
10027
|
+
}
|
|
10028
|
+
context.workbook.setCellFormatByRange(attribute, value, range, options);
|
|
9682
10029
|
return true;
|
|
9683
10030
|
} catch {
|
|
9684
10031
|
return false;
|
|
@@ -13963,146 +14310,950 @@ function SpreadsheetFindBar({ sheet, focusRequest, onClose, onSelectMatch }) {
|
|
|
13963
14310
|
]
|
|
13964
14311
|
});
|
|
13965
14312
|
}
|
|
13966
|
-
|
|
13967
|
-
const
|
|
13968
|
-
|
|
13969
|
-
|
|
13970
|
-
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
|
|
13974
|
-
|
|
13975
|
-
|
|
13976
|
-
|
|
13977
|
-
|
|
13978
|
-
|
|
13979
|
-
|
|
13980
|
-
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
|
|
13986
|
-
|
|
13987
|
-
|
|
13988
|
-
|
|
13989
|
-
|
|
13990
|
-
|
|
13991
|
-
|
|
13992
|
-
|
|
13993
|
-
|
|
13994
|
-
|
|
13995
|
-
|
|
13996
|
-
|
|
13997
|
-
|
|
13998
|
-
|
|
13999
|
-
|
|
14000
|
-
|
|
14001
|
-
|
|
14002
|
-
|
|
14003
|
-
|
|
14004
|
-
|
|
14005
|
-
|
|
14006
|
-
|
|
14007
|
-
|
|
14008
|
-
|
|
14009
|
-
|
|
14010
|
-
|
|
14011
|
-
|
|
14012
|
-
|
|
14013
|
-
|
|
14014
|
-
];
|
|
14015
|
-
const
|
|
14016
|
-
{
|
|
14017
|
-
|
|
14018
|
-
|
|
14019
|
-
|
|
14020
|
-
|
|
14021
|
-
|
|
14022
|
-
|
|
14023
|
-
|
|
14024
|
-
|
|
14025
|
-
|
|
14026
|
-
|
|
14027
|
-
|
|
14028
|
-
|
|
14029
|
-
|
|
14030
|
-
|
|
14031
|
-
|
|
14032
|
-
{
|
|
14033
|
-
|
|
14034
|
-
|
|
14035
|
-
|
|
14036
|
-
|
|
14037
|
-
|
|
14038
|
-
|
|
14039
|
-
|
|
14040
|
-
|
|
14041
|
-
|
|
14042
|
-
|
|
14043
|
-
|
|
14044
|
-
|
|
14045
|
-
|
|
14046
|
-
|
|
14047
|
-
|
|
14048
|
-
|
|
14049
|
-
|
|
14050
|
-
|
|
14051
|
-
|
|
14052
|
-
|
|
14053
|
-
|
|
14054
|
-
|
|
14055
|
-
|
|
14056
|
-
|
|
14057
|
-
}
|
|
14058
|
-
|
|
14059
|
-
|
|
14060
|
-
|
|
14061
|
-
|
|
14062
|
-
|
|
14063
|
-
|
|
14064
|
-
|
|
14065
|
-
|
|
14066
|
-
|
|
14067
|
-
|
|
14068
|
-
|
|
14069
|
-
|
|
14070
|
-
|
|
14071
|
-
|
|
14072
|
-
|
|
14073
|
-
|
|
14074
|
-
|
|
14075
|
-
|
|
14076
|
-
|
|
14077
|
-
|
|
14078
|
-
|
|
14079
|
-
|
|
14080
|
-
|
|
14081
|
-
|
|
14082
|
-
|
|
14083
|
-
|
|
14084
|
-
|
|
14085
|
-
|
|
14086
|
-
|
|
14087
|
-
|
|
14088
|
-
|
|
14089
|
-
|
|
14090
|
-
|
|
14091
|
-
|
|
14092
|
-
|
|
14093
|
-
|
|
14094
|
-
|
|
14095
|
-
|
|
14096
|
-
|
|
14097
|
-
|
|
14098
|
-
|
|
14099
|
-
|
|
14100
|
-
|
|
14101
|
-
|
|
14102
|
-
|
|
14103
|
-
|
|
14104
|
-
|
|
14105
|
-
|
|
14313
|
+
function SegmentedControl({ ariaLabel, value, items, onChange, size = 'standard', layout = 'fit', disabled = false, className = '' }) {
|
|
14314
|
+
const groupName = useId();
|
|
14315
|
+
return /*#__PURE__*/ jsx("div", {
|
|
14316
|
+
className: `ds-segmented-control ${size} ${layout}${className ? ` ${className}` : ''}`,
|
|
14317
|
+
role: "radiogroup",
|
|
14318
|
+
"aria-label": ariaLabel,
|
|
14319
|
+
"aria-disabled": disabled || void 0,
|
|
14320
|
+
"aria-orientation": "horizontal",
|
|
14321
|
+
children: items.map((item)=>{
|
|
14322
|
+
const selected = item.id === value;
|
|
14323
|
+
const itemDisabled = disabled || item.disabled;
|
|
14324
|
+
return /*#__PURE__*/ jsxs("label", {
|
|
14325
|
+
className: `ds-segmented-control-item${selected ? ' selected' : ''}`,
|
|
14326
|
+
title: item.description,
|
|
14327
|
+
children: [
|
|
14328
|
+
/*#__PURE__*/ jsx("input", {
|
|
14329
|
+
type: "radio",
|
|
14330
|
+
name: groupName,
|
|
14331
|
+
value: item.id,
|
|
14332
|
+
checked: selected,
|
|
14333
|
+
disabled: itemDisabled,
|
|
14334
|
+
"aria-label": item.ariaLabel,
|
|
14335
|
+
onChange: ()=>onChange(item.id)
|
|
14336
|
+
}),
|
|
14337
|
+
/*#__PURE__*/ jsxs("span", {
|
|
14338
|
+
className: "ds-segmented-control-content",
|
|
14339
|
+
children: [
|
|
14340
|
+
item.icon && /*#__PURE__*/ jsx("span", {
|
|
14341
|
+
className: "ds-segmented-control-icon",
|
|
14342
|
+
"aria-hidden": "true",
|
|
14343
|
+
children: item.icon
|
|
14344
|
+
}),
|
|
14345
|
+
/*#__PURE__*/ jsx("span", {
|
|
14346
|
+
className: "ds-segmented-control-label",
|
|
14347
|
+
children: item.label
|
|
14348
|
+
})
|
|
14349
|
+
]
|
|
14350
|
+
})
|
|
14351
|
+
]
|
|
14352
|
+
}, item.id);
|
|
14353
|
+
})
|
|
14354
|
+
});
|
|
14355
|
+
}
|
|
14356
|
+
function createSpreadsheetFormatCellsDialogSource(content, sheetId, rangeInput, cells, requestedActiveCell) {
|
|
14357
|
+
const range = spreadsheet_cell_range_normalizeSpreadsheetCellRange(rangeInput);
|
|
14358
|
+
const sheet = content.sheets.find((candidate)=>candidate.id === sheetId);
|
|
14359
|
+
if (!range || !sheet || spreadsheet_cell_range_spreadsheetCellRangeArea(range) > 10000) return null;
|
|
14360
|
+
const activeRow = clampIndex(requestedActiveCell.row, range.row[0], range.row[1]);
|
|
14361
|
+
const activeColumn = clampIndex(requestedActiveCell.column, range.column[0], range.column[1]);
|
|
14362
|
+
const activeCell = cells[activeRow - range.row[0]]?.[activeColumn - range.column[0]] ?? null;
|
|
14363
|
+
const values = (resolve)=>{
|
|
14364
|
+
const activeValue = resolve(activeCell, activeRow, activeColumn);
|
|
14365
|
+
let mixed = false;
|
|
14366
|
+
for(let row = range.row[0]; row <= range.row[1] && !mixed; row += 1)for(let column = range.column[0]; column <= range.column[1]; column += 1){
|
|
14367
|
+
const cell = cells[row - range.row[0]]?.[column - range.column[0]] ?? null;
|
|
14368
|
+
if (!sameDialogValue(resolve(cell, row, column), activeValue)) {
|
|
14369
|
+
mixed = true;
|
|
14370
|
+
break;
|
|
14371
|
+
}
|
|
14372
|
+
}
|
|
14373
|
+
return {
|
|
14374
|
+
value: activeValue,
|
|
14375
|
+
mixed
|
|
14376
|
+
};
|
|
14377
|
+
};
|
|
14378
|
+
const borders = borderFormatsAt(sheet, activeRow, activeColumn);
|
|
14379
|
+
return {
|
|
14380
|
+
sheetId,
|
|
14381
|
+
range,
|
|
14382
|
+
activeCell,
|
|
14383
|
+
fields: {
|
|
14384
|
+
numberFormat: values((cell)=>cell?.ct?.fa?.trim() || 'General'),
|
|
14385
|
+
horizontalAlignment: values((cell)=>spreadsheet_format_cells_dialog_model_horizontalAlignment(cell?.ht)),
|
|
14386
|
+
verticalAlignment: values((cell)=>verticalAlignment(cell?.vt)),
|
|
14387
|
+
wrapText: values((cell)=>'2' === String(cell?.tb)),
|
|
14388
|
+
rotation: values((cell)=>spreadsheetVisibleTextRotationFromCell(cell)),
|
|
14389
|
+
fontFamily: values((cell)=>'string' == typeof cell?.ff && cell.ff.trim() ? cell.ff.trim() : 'Aptos'),
|
|
14390
|
+
fontSize: values((cell)=>'number' == typeof cell?.fs && Number.isFinite(cell.fs) ? cell.fs : 10),
|
|
14391
|
+
fontColor: values((cell)=>normalizedColor(cell?.fc, '#172033')),
|
|
14392
|
+
bold: values((cell)=>1 === Number(cell?.bl)),
|
|
14393
|
+
italic: values((cell)=>1 === Number(cell?.it)),
|
|
14394
|
+
underline: values((cell)=>spreadsheetUnderlineStyle(cell?.un)),
|
|
14395
|
+
strike: values((cell)=>1 === Number(cell?.cl)),
|
|
14396
|
+
fill: values((cell)=>spreadsheetCellFillFormat(cell)),
|
|
14397
|
+
borders: {
|
|
14398
|
+
value: borders,
|
|
14399
|
+
mixed: spreadsheet_cell_range_spreadsheetCellRangeArea(range) > 1
|
|
14400
|
+
},
|
|
14401
|
+
locked: values((cell, row, column)=>spreadsheetCellProtectionAt(sheet, row, column, cell).locked),
|
|
14402
|
+
hidden: values((cell, row, column)=>spreadsheetCellProtectionAt(sheet, row, column, cell).hidden)
|
|
14403
|
+
}
|
|
14404
|
+
};
|
|
14405
|
+
}
|
|
14406
|
+
function createSpreadsheetFormatCellsDraft(source) {
|
|
14407
|
+
const borders = source.fields.borders.value.map((format)=>({
|
|
14408
|
+
...format
|
|
14409
|
+
}));
|
|
14410
|
+
return {
|
|
14411
|
+
numberFormat: source.fields.numberFormat.value,
|
|
14412
|
+
horizontalAlignment: source.fields.horizontalAlignment.value,
|
|
14413
|
+
verticalAlignment: source.fields.verticalAlignment.value,
|
|
14414
|
+
wrapText: source.fields.wrapText.value,
|
|
14415
|
+
rotation: source.fields.rotation.value,
|
|
14416
|
+
fontFamily: source.fields.fontFamily.value,
|
|
14417
|
+
fontSize: source.fields.fontSize.value,
|
|
14418
|
+
fontColor: source.fields.fontColor.value,
|
|
14419
|
+
bold: source.fields.bold.value,
|
|
14420
|
+
italic: source.fields.italic.value,
|
|
14421
|
+
underline: source.fields.underline.value,
|
|
14422
|
+
strike: source.fields.strike.value,
|
|
14423
|
+
fill: createSpreadsheetFormatCellsFillDraft(source.fields.fill.value),
|
|
14424
|
+
borders,
|
|
14425
|
+
borderColor: borders[0]?.color ?? '#172033',
|
|
14426
|
+
borderStyle: borders[0]?.style ?? 'thin',
|
|
14427
|
+
locked: source.fields.locked.value,
|
|
14428
|
+
hidden: source.fields.hidden.value
|
|
14429
|
+
};
|
|
14430
|
+
}
|
|
14431
|
+
function spreadsheetFormatCellsPatch(source, draft, touched) {
|
|
14432
|
+
const patch = {};
|
|
14433
|
+
if (shouldEmit(source.fields.numberFormat, draft.numberFormat, touched.numberFormat)) patch.numberFormat = draft.numberFormat.trim();
|
|
14434
|
+
if (shouldEmit(source.fields.horizontalAlignment, draft.horizontalAlignment, touched.horizontalAlignment)) patch.horizontalAlignment = draft.horizontalAlignment;
|
|
14435
|
+
if (shouldEmit(source.fields.verticalAlignment, draft.verticalAlignment, touched.verticalAlignment)) patch.verticalAlignment = draft.verticalAlignment;
|
|
14436
|
+
if (shouldEmit(source.fields.wrapText, draft.wrapText, touched.wrapText)) patch.wrapText = draft.wrapText;
|
|
14437
|
+
if (shouldEmit(source.fields.rotation, draft.rotation, touched.rotation)) patch.rotation = draft.rotation;
|
|
14438
|
+
if (shouldEmit(source.fields.fontFamily, draft.fontFamily, touched.fontFamily)) patch.fontFamily = draft.fontFamily.trim();
|
|
14439
|
+
if (shouldEmit(source.fields.fontSize, draft.fontSize, touched.fontSize)) patch.fontSize = draft.fontSize;
|
|
14440
|
+
if (shouldEmit(source.fields.fontColor, draft.fontColor, touched.fontColor)) patch.fontColor = draft.fontColor;
|
|
14441
|
+
if (shouldEmit(source.fields.bold, draft.bold, touched.bold)) patch.bold = draft.bold;
|
|
14442
|
+
if (shouldEmit(source.fields.italic, draft.italic, touched.italic)) patch.italic = draft.italic;
|
|
14443
|
+
if (shouldEmit(source.fields.underline, draft.underline, touched.underline)) patch.underline = draft.underline;
|
|
14444
|
+
if (shouldEmit(source.fields.strike, draft.strike, touched.strike)) patch.strike = draft.strike;
|
|
14445
|
+
const fill = spreadsheetFormatCellsActiveFill(draft);
|
|
14446
|
+
if (shouldEmit(source.fields.fill, fill, touched.fill)) patch.fill = fill;
|
|
14447
|
+
if (shouldEmit(source.fields.borders, draft.borders, touched.borders)) patch.borders = draft.borders.map((format)=>({
|
|
14448
|
+
...format
|
|
14449
|
+
}));
|
|
14450
|
+
if (shouldEmit(source.fields.locked, draft.locked, touched.locked)) patch.locked = draft.locked;
|
|
14451
|
+
if (shouldEmit(source.fields.hidden, draft.hidden, touched.hidden)) patch.hidden = draft.hidden;
|
|
14452
|
+
return patch;
|
|
14453
|
+
}
|
|
14454
|
+
function spreadsheetFormatCellsDraftErrors(draft) {
|
|
14455
|
+
const errors = {};
|
|
14456
|
+
if (draft.numberFormat.trim()) {
|
|
14457
|
+
if (draft.numberFormat.trim().length > 255) errors.numberFormat = '数字格式代码不能超过 255 个字符。';
|
|
14458
|
+
} else errors.numberFormat = '请输入数字格式代码。';
|
|
14459
|
+
if (!Number.isFinite(draft.fontSize) || draft.fontSize < 1 || draft.fontSize > 409) errors.fontSize = '字号需为 1–409 之间的数字。';
|
|
14460
|
+
if (!Number.isInteger(draft.rotation) || draft.rotation < -90 || draft.rotation > 90) errors.rotation = '文字旋转角度需为 -90–90 之间的整数。';
|
|
14461
|
+
if (!normalizeSpreadsheetCellFillFormat(spreadsheetFormatCellsActiveFill(draft))) errors.fill = '请检查填充设置。渐变色标需按位置从小到大排列,位置和路径边界需保持在 0%–100%。';
|
|
14462
|
+
return errors;
|
|
14463
|
+
}
|
|
14464
|
+
function spreadsheetFormatCellsActiveFill(draft) {
|
|
14465
|
+
if ('none' === draft.fill.mode) return {
|
|
14466
|
+
kind: 'none'
|
|
14467
|
+
};
|
|
14468
|
+
if ('solid' === draft.fill.mode) return {
|
|
14469
|
+
color: draft.fill.solidColor,
|
|
14470
|
+
kind: 'solid'
|
|
14471
|
+
};
|
|
14472
|
+
if ('pattern' === draft.fill.mode) return {
|
|
14473
|
+
kind: 'pattern',
|
|
14474
|
+
value: draft.fill.pattern
|
|
14475
|
+
};
|
|
14476
|
+
return {
|
|
14477
|
+
kind: 'gradient',
|
|
14478
|
+
value: draft.fill.gradient
|
|
14479
|
+
};
|
|
14480
|
+
}
|
|
14481
|
+
function shouldEmit(source, value, touched) {
|
|
14482
|
+
return Boolean(touched && (source.mixed || !sameDialogValue(source.value, value)));
|
|
14483
|
+
}
|
|
14484
|
+
function createSpreadsheetFormatCellsFillDraft(source) {
|
|
14485
|
+
const fill = normalizeSpreadsheetCellFillFormat(source) ?? {
|
|
14486
|
+
kind: 'none'
|
|
14487
|
+
};
|
|
14488
|
+
const solidColor = spreadsheetFillFallbackColor(fill);
|
|
14489
|
+
return {
|
|
14490
|
+
gradient: 'gradient' === fill.kind ? fill.value : {
|
|
14491
|
+
degree: 0,
|
|
14492
|
+
stops: [
|
|
14493
|
+
{
|
|
14494
|
+
color: solidColor,
|
|
14495
|
+
position: 0
|
|
14496
|
+
},
|
|
14497
|
+
{
|
|
14498
|
+
color: '#ffffff' === solidColor ? '#4472c4' : '#ffffff',
|
|
14499
|
+
position: 1
|
|
14500
|
+
}
|
|
14501
|
+
],
|
|
14502
|
+
type: 'linear'
|
|
14503
|
+
},
|
|
14504
|
+
mode: fill.kind,
|
|
14505
|
+
pattern: 'pattern' === fill.kind ? fill.value : {
|
|
14506
|
+
backgroundColor: solidColor,
|
|
14507
|
+
foregroundColor: '#ffffff' === solidColor ? '#4472c4' : '#ffffff',
|
|
14508
|
+
patternType: 'lightGrid'
|
|
14509
|
+
},
|
|
14510
|
+
solidColor
|
|
14511
|
+
};
|
|
14512
|
+
}
|
|
14513
|
+
function spreadsheetFillFallbackColor(fill) {
|
|
14514
|
+
if ('solid' === fill.kind) return fill.color;
|
|
14515
|
+
if ('pattern' === fill.kind) return fill.value.backgroundColor;
|
|
14516
|
+
if ('gradient' === fill.kind) return fill.value.stops[0]?.color ?? '#ffffff';
|
|
14517
|
+
return '#ffffff';
|
|
14518
|
+
}
|
|
14519
|
+
function spreadsheet_format_cells_dialog_model_horizontalAlignment(value) {
|
|
14520
|
+
if ('0' === String(value)) return 'center';
|
|
14521
|
+
if ('1' === String(value)) return 'left';
|
|
14522
|
+
if ('2' === String(value)) return 'right';
|
|
14523
|
+
return 'general';
|
|
14524
|
+
}
|
|
14525
|
+
function verticalAlignment(value) {
|
|
14526
|
+
if (0 === Number(value)) return 'middle';
|
|
14527
|
+
if (2 === Number(value)) return 'bottom';
|
|
14528
|
+
return 'top';
|
|
14529
|
+
}
|
|
14530
|
+
function borderFormatsAt(sheet, row, column) {
|
|
14531
|
+
const resolved = spreadsheetCellBordersAt(sheet, row, column);
|
|
14532
|
+
return [
|
|
14533
|
+
'top',
|
|
14534
|
+
'bottom',
|
|
14535
|
+
'left',
|
|
14536
|
+
'right',
|
|
14537
|
+
'diagonalDown',
|
|
14538
|
+
'diagonalUp'
|
|
14539
|
+
].flatMap((target)=>{
|
|
14540
|
+
const line = resolved[target];
|
|
14541
|
+
if (!line) return [];
|
|
14542
|
+
return [
|
|
14543
|
+
{
|
|
14544
|
+
target,
|
|
14545
|
+
color: normalizedColor(line.color, '#172033') ?? '#172033',
|
|
14546
|
+
style: borderStyle(line.style)
|
|
14547
|
+
}
|
|
14548
|
+
];
|
|
14549
|
+
});
|
|
14550
|
+
}
|
|
14551
|
+
function borderStyle(value) {
|
|
14552
|
+
return ({
|
|
14553
|
+
1: 'thin',
|
|
14554
|
+
3: 'dotted',
|
|
14555
|
+
4: 'dashed',
|
|
14556
|
+
5: 'dash-dot',
|
|
14557
|
+
6: 'dash-dot-dot',
|
|
14558
|
+
8: 'medium',
|
|
14559
|
+
9: 'medium-dashed',
|
|
14560
|
+
10: 'medium-dash-dot',
|
|
14561
|
+
11: 'medium-dash-dot-dot',
|
|
14562
|
+
13: 'thick'
|
|
14563
|
+
})[value] ?? 'thin';
|
|
14564
|
+
}
|
|
14565
|
+
function normalizedColor(value, fallback) {
|
|
14566
|
+
if ('string' != typeof value) return fallback;
|
|
14567
|
+
const color = value.trim().toLowerCase();
|
|
14568
|
+
if (/^#[0-9a-f]{6}$/.test(color)) return color;
|
|
14569
|
+
if (/^#[0-9a-f]{3}$/.test(color)) return `#${[
|
|
14570
|
+
...color.slice(1)
|
|
14571
|
+
].map((character)=>character.repeat(2)).join('')}`;
|
|
14572
|
+
return fallback;
|
|
14573
|
+
}
|
|
14574
|
+
function sameDialogValue(left, right) {
|
|
14575
|
+
if (Object.is(left, right)) return true;
|
|
14576
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
14577
|
+
}
|
|
14578
|
+
function clampIndex(value, minimum, maximum) {
|
|
14579
|
+
return Math.min(maximum, Math.max(minimum, Math.trunc(value)));
|
|
14580
|
+
}
|
|
14581
|
+
function SpreadsheetFormatCellsFillPreview({ fill, patternLabels }) {
|
|
14582
|
+
const canvasRef = useRef(null);
|
|
14583
|
+
useEffect(()=>{
|
|
14584
|
+
const canvas = canvasRef.current;
|
|
14585
|
+
if (!canvas) return;
|
|
14586
|
+
const render = ()=>renderSpreadsheetFillPreview(canvas, fill);
|
|
14587
|
+
render();
|
|
14588
|
+
if ("u" < typeof ResizeObserver) return;
|
|
14589
|
+
const observer = new ResizeObserver(render);
|
|
14590
|
+
observer.observe(canvas);
|
|
14591
|
+
return ()=>observer.disconnect();
|
|
14592
|
+
}, [
|
|
14593
|
+
fill
|
|
14594
|
+
]);
|
|
14595
|
+
return /*#__PURE__*/ jsxs("figure", {
|
|
14596
|
+
className: `work-spreadsheet-format-cells-fill-preview ${fill.kind}`,
|
|
14597
|
+
children: [
|
|
14598
|
+
/*#__PURE__*/ jsx("canvas", {
|
|
14599
|
+
ref: canvasRef,
|
|
14600
|
+
role: "img",
|
|
14601
|
+
"aria-label": spreadsheetFillPreviewLabel(fill, patternLabels)
|
|
14602
|
+
}),
|
|
14603
|
+
/*#__PURE__*/ jsx("figcaption", {
|
|
14604
|
+
children: spreadsheetFillPreviewCaption(fill, patternLabels)
|
|
14605
|
+
})
|
|
14606
|
+
]
|
|
14607
|
+
});
|
|
14608
|
+
}
|
|
14609
|
+
function renderSpreadsheetFillPreview(canvas, fill) {
|
|
14610
|
+
let context = null;
|
|
14611
|
+
try {
|
|
14612
|
+
context = canvas.getContext('2d');
|
|
14613
|
+
} catch {
|
|
14614
|
+
return;
|
|
14615
|
+
}
|
|
14616
|
+
if (!context) return;
|
|
14617
|
+
const bounds = canvas.getBoundingClientRect();
|
|
14618
|
+
const width = Math.max(1, Math.round(bounds.width || 220));
|
|
14619
|
+
const height = Math.max(1, Math.round(bounds.height || 132));
|
|
14620
|
+
const scale = Math.min(2, Math.max(1, window.devicePixelRatio || 1));
|
|
14621
|
+
const pixelWidth = Math.round(width * scale);
|
|
14622
|
+
const pixelHeight = Math.round(height * scale);
|
|
14623
|
+
if (canvas.width !== pixelWidth) canvas.width = pixelWidth;
|
|
14624
|
+
if (canvas.height !== pixelHeight) canvas.height = pixelHeight;
|
|
14625
|
+
context.setTransform(scale, 0, 0, scale, 0, 0);
|
|
14626
|
+
context.clearRect(0, 0, width, height);
|
|
14627
|
+
if ('none' === fill.kind) return;
|
|
14628
|
+
if ('solid' === fill.kind) {
|
|
14629
|
+
context.fillStyle = fill.color;
|
|
14630
|
+
context.fillRect(0, 0, width, height);
|
|
14631
|
+
return;
|
|
14632
|
+
}
|
|
14633
|
+
if ('pattern' === fill.kind) {
|
|
14634
|
+
context.fillStyle = fill.value.backgroundColor;
|
|
14635
|
+
context.fillRect(0, 0, width, height);
|
|
14636
|
+
drawSpreadsheetPatternFillOverlay(context, {
|
|
14637
|
+
endX: width,
|
|
14638
|
+
endY: height,
|
|
14639
|
+
startX: 0,
|
|
14640
|
+
startY: 0
|
|
14641
|
+
}, fill.value);
|
|
14642
|
+
return;
|
|
14643
|
+
}
|
|
14644
|
+
drawSpreadsheetGradientFill(context, {
|
|
14645
|
+
endX: width,
|
|
14646
|
+
endY: height,
|
|
14647
|
+
startX: 0,
|
|
14648
|
+
startY: 0
|
|
14649
|
+
}, fill.value);
|
|
14650
|
+
}
|
|
14651
|
+
function spreadsheetFillPreviewLabel(fill, patternLabels) {
|
|
14652
|
+
if ('none' === fill.kind) return '无填充预览';
|
|
14653
|
+
if ('solid' === fill.kind) return `纯色填充预览 ${fill.color}`;
|
|
14654
|
+
if ('pattern' === fill.kind) return `图案填充预览 ${patternLabels[fill.value.patternType]}`;
|
|
14655
|
+
return `${'linear' === fill.value.type ? '线性' : '路径'}渐变填充预览,共 ${fill.value.stops.length} 个色标`;
|
|
14656
|
+
}
|
|
14657
|
+
function spreadsheetFillPreviewCaption(fill, patternLabels) {
|
|
14658
|
+
if ('none' === fill.kind) return '无填充';
|
|
14659
|
+
if ('solid' === fill.kind) return fill.color.toUpperCase();
|
|
14660
|
+
if ('pattern' === fill.kind) return patternLabels[fill.value.patternType];
|
|
14661
|
+
return 'linear' === fill.value.type ? `线性 · ${formatNumber(fill.value.degree)}° · ${fill.value.stops.length} 个色标` : `路径 · ${fill.value.stops.length} 个色标`;
|
|
14662
|
+
}
|
|
14663
|
+
function formatNumber(value) {
|
|
14664
|
+
return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(4)));
|
|
14665
|
+
}
|
|
14666
|
+
const fillModeItems = [
|
|
14667
|
+
{
|
|
14668
|
+
id: 'none',
|
|
14669
|
+
label: '无填充'
|
|
14670
|
+
},
|
|
14671
|
+
{
|
|
14672
|
+
id: 'solid',
|
|
14673
|
+
label: '纯色'
|
|
14674
|
+
},
|
|
14675
|
+
{
|
|
14676
|
+
id: 'pattern',
|
|
14677
|
+
label: '图案'
|
|
14678
|
+
},
|
|
14679
|
+
{
|
|
14680
|
+
id: 'gradient',
|
|
14681
|
+
label: '渐变'
|
|
14682
|
+
}
|
|
14683
|
+
];
|
|
14684
|
+
const gradientTypeOptions = [
|
|
14685
|
+
{
|
|
14686
|
+
value: 'linear',
|
|
14687
|
+
label: '线性'
|
|
14688
|
+
},
|
|
14689
|
+
{
|
|
14690
|
+
value: 'path',
|
|
14691
|
+
label: '路径'
|
|
14692
|
+
}
|
|
14693
|
+
];
|
|
14694
|
+
const spreadsheet_format_cells_fill_panel_patternLabels = {
|
|
14695
|
+
darkDown: '深色下斜线',
|
|
14696
|
+
darkGray: '深灰',
|
|
14697
|
+
darkGrid: '深色网格',
|
|
14698
|
+
darkHorizontal: '深色横线',
|
|
14699
|
+
darkTrellis: '深色菱形网格',
|
|
14700
|
+
darkUp: '深色上斜线',
|
|
14701
|
+
darkVertical: '深色竖线',
|
|
14702
|
+
gray0625: '6.25% 灰度',
|
|
14703
|
+
gray125: '12.5% 灰度',
|
|
14704
|
+
lightDown: '浅色下斜线',
|
|
14705
|
+
lightGray: '浅灰',
|
|
14706
|
+
lightGrid: '浅色网格',
|
|
14707
|
+
lightHorizontal: '浅色横线',
|
|
14708
|
+
lightTrellis: '浅色菱形网格',
|
|
14709
|
+
lightUp: '浅色上斜线',
|
|
14710
|
+
lightVertical: '浅色竖线',
|
|
14711
|
+
mediumGray: '中灰'
|
|
14712
|
+
};
|
|
14713
|
+
const patternOptions = xlsxPatternFillTypes.map((value)=>({
|
|
14714
|
+
label: spreadsheet_format_cells_fill_panel_patternLabels[value],
|
|
14715
|
+
value
|
|
14716
|
+
}));
|
|
14717
|
+
function SpreadsheetFormatCellsFillPanel({ source, draft, errors, touched, setDraft, touch }) {
|
|
14718
|
+
const updateFill = (update)=>{
|
|
14719
|
+
touch('fill');
|
|
14720
|
+
setDraft((current)=>({
|
|
14721
|
+
...current,
|
|
14722
|
+
fill: update(current.fill)
|
|
14723
|
+
}));
|
|
14724
|
+
};
|
|
14725
|
+
const activeFill = spreadsheetFormatCellsActiveFill(draft);
|
|
14726
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
14727
|
+
className: "work-spreadsheet-format-cells-fill",
|
|
14728
|
+
children: [
|
|
14729
|
+
/*#__PURE__*/ jsx(SegmentedControl, {
|
|
14730
|
+
ariaLabel: "填充类型",
|
|
14731
|
+
className: "work-spreadsheet-format-cells-fill-modes",
|
|
14732
|
+
value: draft.fill.mode,
|
|
14733
|
+
items: fillModeItems,
|
|
14734
|
+
layout: "equal",
|
|
14735
|
+
size: "compact",
|
|
14736
|
+
onChange: (mode)=>updateFill((current)=>({
|
|
14737
|
+
...current,
|
|
14738
|
+
mode
|
|
14739
|
+
}))
|
|
14740
|
+
}),
|
|
14741
|
+
/*#__PURE__*/ jsxs("div", {
|
|
14742
|
+
className: "work-spreadsheet-format-cells-fill-layout",
|
|
14743
|
+
children: [
|
|
14744
|
+
/*#__PURE__*/ jsxs("div", {
|
|
14745
|
+
className: "work-spreadsheet-format-cells-fill-controls",
|
|
14746
|
+
children: [
|
|
14747
|
+
'none' === draft.fill.mode && /*#__PURE__*/ jsx("p", {
|
|
14748
|
+
className: "work-spreadsheet-format-cells-fill-empty-copy",
|
|
14749
|
+
children: "应用后会移除选区中的纯色、图案和渐变填充。"
|
|
14750
|
+
}),
|
|
14751
|
+
'solid' === draft.fill.mode && /*#__PURE__*/ jsx(FillField, {
|
|
14752
|
+
label: "背景色",
|
|
14753
|
+
children: /*#__PURE__*/ jsx(OfficeColorPicker, {
|
|
14754
|
+
ariaLabel: "单元格填充颜色",
|
|
14755
|
+
value: draft.fill.solidColor,
|
|
14756
|
+
onValueChange: (solidColor)=>updateFill((current)=>({
|
|
14757
|
+
...current,
|
|
14758
|
+
solidColor
|
|
14759
|
+
}))
|
|
14760
|
+
})
|
|
14761
|
+
}),
|
|
14762
|
+
'pattern' === draft.fill.mode && /*#__PURE__*/ jsx(PatternFillControls, {
|
|
14763
|
+
fill: draft.fill.pattern,
|
|
14764
|
+
onChange: (pattern)=>updateFill((current)=>({
|
|
14765
|
+
...current,
|
|
14766
|
+
pattern
|
|
14767
|
+
}))
|
|
14768
|
+
}),
|
|
14769
|
+
'gradient' === draft.fill.mode && /*#__PURE__*/ jsx(GradientFillControls, {
|
|
14770
|
+
fill: draft.fill.gradient,
|
|
14771
|
+
onChange: (gradient)=>updateFill((current)=>({
|
|
14772
|
+
...current,
|
|
14773
|
+
gradient
|
|
14774
|
+
}))
|
|
14775
|
+
}),
|
|
14776
|
+
errors.fill && /*#__PURE__*/ jsx("p", {
|
|
14777
|
+
role: "alert",
|
|
14778
|
+
children: errors.fill
|
|
14779
|
+
}),
|
|
14780
|
+
source.fields.fill.mixed && !touched.fill && /*#__PURE__*/ jsx("p", {
|
|
14781
|
+
className: "work-spreadsheet-format-cells-mixed",
|
|
14782
|
+
children: "选区包含多种填充;只有选择新的填充类型或参数后才会统一应用。"
|
|
14783
|
+
})
|
|
14784
|
+
]
|
|
14785
|
+
}),
|
|
14786
|
+
/*#__PURE__*/ jsx(SpreadsheetFormatCellsFillPreview, {
|
|
14787
|
+
fill: activeFill,
|
|
14788
|
+
patternLabels: spreadsheet_format_cells_fill_panel_patternLabels
|
|
14789
|
+
})
|
|
14790
|
+
]
|
|
14791
|
+
})
|
|
14792
|
+
]
|
|
14793
|
+
});
|
|
14794
|
+
}
|
|
14795
|
+
function PatternFillControls({ fill, onChange }) {
|
|
14796
|
+
const updateColor = (field, color)=>{
|
|
14797
|
+
const next = {
|
|
14798
|
+
...fill,
|
|
14799
|
+
[field]: color
|
|
14800
|
+
};
|
|
14801
|
+
if ('backgroundColor' === field) delete next.backgroundColorOrigin;
|
|
14802
|
+
else delete next.foregroundColorOrigin;
|
|
14803
|
+
onChange(next);
|
|
14804
|
+
};
|
|
14805
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
14806
|
+
className: "work-spreadsheet-format-cells-pattern-controls",
|
|
14807
|
+
children: [
|
|
14808
|
+
/*#__PURE__*/ jsx(FillField, {
|
|
14809
|
+
label: "图案样式",
|
|
14810
|
+
children: /*#__PURE__*/ jsx(OfficeSelect, {
|
|
14811
|
+
ariaLabel: "填充图案样式",
|
|
14812
|
+
value: fill.patternType,
|
|
14813
|
+
options: patternOptions,
|
|
14814
|
+
onValueChange: (patternType)=>onChange({
|
|
14815
|
+
...fill,
|
|
14816
|
+
patternType
|
|
14817
|
+
})
|
|
14818
|
+
})
|
|
14819
|
+
}),
|
|
14820
|
+
/*#__PURE__*/ jsx(FillField, {
|
|
14821
|
+
label: "图案颜色",
|
|
14822
|
+
children: /*#__PURE__*/ jsx(OfficeColorPicker, {
|
|
14823
|
+
ariaLabel: "填充图案颜色",
|
|
14824
|
+
value: fill.foregroundColor,
|
|
14825
|
+
onValueChange: (color)=>updateColor('foregroundColor', color)
|
|
14826
|
+
})
|
|
14827
|
+
}),
|
|
14828
|
+
/*#__PURE__*/ jsx(FillField, {
|
|
14829
|
+
label: "背景色",
|
|
14830
|
+
children: /*#__PURE__*/ jsx(OfficeColorPicker, {
|
|
14831
|
+
ariaLabel: "填充图案背景色",
|
|
14832
|
+
value: fill.backgroundColor,
|
|
14833
|
+
onValueChange: (color)=>updateColor('backgroundColor', color)
|
|
14834
|
+
})
|
|
14835
|
+
})
|
|
14836
|
+
]
|
|
14837
|
+
});
|
|
14838
|
+
}
|
|
14839
|
+
function GradientFillControls({ fill, onChange }) {
|
|
14840
|
+
const changeType = (type)=>{
|
|
14841
|
+
if (type === fill.type) return;
|
|
14842
|
+
const stops = fill.stops.map((stop)=>({
|
|
14843
|
+
...stop
|
|
14844
|
+
}));
|
|
14845
|
+
onChange('linear' === type ? {
|
|
14846
|
+
degree: 0,
|
|
14847
|
+
stops,
|
|
14848
|
+
type
|
|
14849
|
+
} : {
|
|
14850
|
+
bottom: 0.75,
|
|
14851
|
+
left: 0.25,
|
|
14852
|
+
right: 0.75,
|
|
14853
|
+
stops,
|
|
14854
|
+
top: 0.25,
|
|
14855
|
+
type
|
|
14856
|
+
});
|
|
14857
|
+
};
|
|
14858
|
+
const changeStops = (stops)=>onChange({
|
|
14859
|
+
...fill,
|
|
14860
|
+
stops
|
|
14861
|
+
});
|
|
14862
|
+
const updateStop = (index, update)=>changeStops(fill.stops.map((stop, stopIndex)=>stopIndex === index ? update(stop) : stop));
|
|
14863
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
14864
|
+
className: "work-spreadsheet-format-cells-gradient-controls",
|
|
14865
|
+
"data-gradient-type": fill.type,
|
|
14866
|
+
children: [
|
|
14867
|
+
/*#__PURE__*/ jsxs("div", {
|
|
14868
|
+
className: "work-spreadsheet-format-cells-gradient-geometry",
|
|
14869
|
+
children: [
|
|
14870
|
+
/*#__PURE__*/ jsx(FillField, {
|
|
14871
|
+
label: "渐变类型",
|
|
14872
|
+
children: /*#__PURE__*/ jsx(OfficeSelect, {
|
|
14873
|
+
ariaLabel: "渐变类型",
|
|
14874
|
+
value: fill.type,
|
|
14875
|
+
options: gradientTypeOptions,
|
|
14876
|
+
onValueChange: changeType
|
|
14877
|
+
})
|
|
14878
|
+
}),
|
|
14879
|
+
'linear' === fill.type ? /*#__PURE__*/ jsx(PercentField, {
|
|
14880
|
+
label: "角度(\xb0)",
|
|
14881
|
+
ariaLabel: "线性渐变角度",
|
|
14882
|
+
value: fill.degree,
|
|
14883
|
+
step: 1,
|
|
14884
|
+
onChange: (degree)=>onChange({
|
|
14885
|
+
...fill,
|
|
14886
|
+
degree
|
|
14887
|
+
})
|
|
14888
|
+
}) : /*#__PURE__*/ jsx(PathGeometryFields, {
|
|
14889
|
+
fill: fill,
|
|
14890
|
+
onChange: onChange
|
|
14891
|
+
})
|
|
14892
|
+
]
|
|
14893
|
+
}),
|
|
14894
|
+
/*#__PURE__*/ jsxs("div", {
|
|
14895
|
+
className: "work-spreadsheet-format-cells-gradient-stops-heading",
|
|
14896
|
+
children: [
|
|
14897
|
+
/*#__PURE__*/ jsxs("div", {
|
|
14898
|
+
children: [
|
|
14899
|
+
/*#__PURE__*/ jsx("strong", {
|
|
14900
|
+
children: "渐变色标"
|
|
14901
|
+
}),
|
|
14902
|
+
/*#__PURE__*/ jsxs("span", {
|
|
14903
|
+
children: [
|
|
14904
|
+
fill.stops.length,
|
|
14905
|
+
" / ",
|
|
14906
|
+
256
|
|
14907
|
+
]
|
|
14908
|
+
})
|
|
14909
|
+
]
|
|
14910
|
+
}),
|
|
14911
|
+
/*#__PURE__*/ jsxs(button_Button, {
|
|
14912
|
+
size: "compact",
|
|
14913
|
+
tone: "quiet",
|
|
14914
|
+
disabled: fill.stops.length >= 256,
|
|
14915
|
+
onClick: ()=>changeStops(addGradientStop(fill.stops)),
|
|
14916
|
+
children: [
|
|
14917
|
+
/*#__PURE__*/ jsx(Plus, {
|
|
14918
|
+
size: 13,
|
|
14919
|
+
"aria-hidden": "true"
|
|
14920
|
+
}),
|
|
14921
|
+
"添加色标"
|
|
14922
|
+
]
|
|
14923
|
+
})
|
|
14924
|
+
]
|
|
14925
|
+
}),
|
|
14926
|
+
/*#__PURE__*/ jsx("ol", {
|
|
14927
|
+
className: "work-spreadsheet-format-cells-gradient-stops",
|
|
14928
|
+
"aria-label": "渐变色标列表",
|
|
14929
|
+
"data-stop-count": fill.stops.length,
|
|
14930
|
+
children: fill.stops.map((stop, index)=>/*#__PURE__*/ jsxs("li", {
|
|
14931
|
+
className: "work-spreadsheet-format-cells-gradient-stop",
|
|
14932
|
+
children: [
|
|
14933
|
+
/*#__PURE__*/ jsx("span", {
|
|
14934
|
+
className: "work-spreadsheet-format-cells-gradient-stop-index",
|
|
14935
|
+
children: index + 1
|
|
14936
|
+
}),
|
|
14937
|
+
/*#__PURE__*/ jsx(OfficeColorPicker, {
|
|
14938
|
+
ariaLabel: `色标 ${index + 1} 颜色`,
|
|
14939
|
+
value: stop.color,
|
|
14940
|
+
onValueChange: (color)=>updateStop(index, (current)=>{
|
|
14941
|
+
const next = {
|
|
14942
|
+
...current,
|
|
14943
|
+
color
|
|
14944
|
+
};
|
|
14945
|
+
delete next.colorOrigin;
|
|
14946
|
+
return next;
|
|
14947
|
+
})
|
|
14948
|
+
}),
|
|
14949
|
+
/*#__PURE__*/ jsxs("div", {
|
|
14950
|
+
className: "work-spreadsheet-format-cells-stop-position",
|
|
14951
|
+
children: [
|
|
14952
|
+
/*#__PURE__*/ jsxs("span", {
|
|
14953
|
+
className: "sr-only",
|
|
14954
|
+
children: [
|
|
14955
|
+
"色标 ",
|
|
14956
|
+
index + 1,
|
|
14957
|
+
" 位置"
|
|
14958
|
+
]
|
|
14959
|
+
}),
|
|
14960
|
+
/*#__PURE__*/ jsx(OfficeNumberField, {
|
|
14961
|
+
ariaLabel: `色标 ${index + 1} 位置`,
|
|
14962
|
+
value: formatPercentage(stop.position),
|
|
14963
|
+
min: 0,
|
|
14964
|
+
max: 100,
|
|
14965
|
+
step: 1,
|
|
14966
|
+
validationInvalid: stop.position < 0 || stop.position > 1 || index > 0 && (fill.stops[index - 1]?.position ?? 0) > stop.position,
|
|
14967
|
+
onValueChange: (value)=>{
|
|
14968
|
+
const percentage = Number(value);
|
|
14969
|
+
if (!Number.isFinite(percentage)) return;
|
|
14970
|
+
updateStop(index, (current)=>({
|
|
14971
|
+
...current,
|
|
14972
|
+
position: percentage / 100
|
|
14973
|
+
}));
|
|
14974
|
+
}
|
|
14975
|
+
}),
|
|
14976
|
+
/*#__PURE__*/ jsx("span", {
|
|
14977
|
+
"aria-hidden": "true",
|
|
14978
|
+
children: "%"
|
|
14979
|
+
})
|
|
14980
|
+
]
|
|
14981
|
+
}),
|
|
14982
|
+
/*#__PURE__*/ jsx(icon_button_IconButton, {
|
|
14983
|
+
className: "work-spreadsheet-format-cells-gradient-stop-remove",
|
|
14984
|
+
label: `删除色标 ${index + 1}`,
|
|
14985
|
+
disabled: fill.stops.length <= 2,
|
|
14986
|
+
onClick: ()=>changeStops(fill.stops.filter((_, stopIndex)=>stopIndex !== index)),
|
|
14987
|
+
children: /*#__PURE__*/ jsx(Trash2, {
|
|
14988
|
+
size: 13
|
|
14989
|
+
})
|
|
14990
|
+
})
|
|
14991
|
+
]
|
|
14992
|
+
}, index))
|
|
14993
|
+
}),
|
|
14994
|
+
/*#__PURE__*/ jsx("small", {
|
|
14995
|
+
className: "work-spreadsheet-format-cells-gradient-help",
|
|
14996
|
+
children: "色标按列表顺序写入 XLSX;位置需从小到大排列。编辑颜色后会改用显式 RGB,未修改的主题色语义会继续保留。"
|
|
14997
|
+
})
|
|
14998
|
+
]
|
|
14999
|
+
});
|
|
15000
|
+
}
|
|
15001
|
+
function PathGeometryFields({ fill, onChange }) {
|
|
15002
|
+
const fields = [
|
|
15003
|
+
[
|
|
15004
|
+
'left',
|
|
15005
|
+
'左边界'
|
|
15006
|
+
],
|
|
15007
|
+
[
|
|
15008
|
+
'right',
|
|
15009
|
+
'右边界'
|
|
15010
|
+
],
|
|
15011
|
+
[
|
|
15012
|
+
'top',
|
|
15013
|
+
'上边界'
|
|
15014
|
+
],
|
|
15015
|
+
[
|
|
15016
|
+
'bottom',
|
|
15017
|
+
'下边界'
|
|
15018
|
+
]
|
|
15019
|
+
];
|
|
15020
|
+
return /*#__PURE__*/ jsx("div", {
|
|
15021
|
+
className: "work-spreadsheet-format-cells-path-geometry",
|
|
15022
|
+
children: fields.map(([field, label])=>/*#__PURE__*/ jsx(PercentField, {
|
|
15023
|
+
label: `${label}(%)`,
|
|
15024
|
+
ariaLabel: `路径渐变${label}`,
|
|
15025
|
+
value: 100 * fill[field],
|
|
15026
|
+
min: 0,
|
|
15027
|
+
max: 100,
|
|
15028
|
+
step: 1,
|
|
15029
|
+
invalid: 'left' === field && fill.left > fill.right || 'right' === field && fill.right < fill.left || 'top' === field && fill.top > fill.bottom || 'bottom' === field && fill.bottom < fill.top,
|
|
15030
|
+
onChange: (value)=>onChange({
|
|
15031
|
+
...fill,
|
|
15032
|
+
[field]: value / 100
|
|
15033
|
+
})
|
|
15034
|
+
}, field))
|
|
15035
|
+
});
|
|
15036
|
+
}
|
|
15037
|
+
function PercentField({ label, ariaLabel, value, min, max, step, invalid = false, onChange }) {
|
|
15038
|
+
return /*#__PURE__*/ jsx(FillField, {
|
|
15039
|
+
label: label,
|
|
15040
|
+
children: /*#__PURE__*/ jsx(OfficeNumberField, {
|
|
15041
|
+
ariaLabel: ariaLabel,
|
|
15042
|
+
value: spreadsheet_format_cells_fill_panel_formatNumber(value),
|
|
15043
|
+
min: min,
|
|
15044
|
+
max: max,
|
|
15045
|
+
step: step,
|
|
15046
|
+
validationInvalid: invalid,
|
|
15047
|
+
onValueChange: (rawValue)=>{
|
|
15048
|
+
const next = Number(rawValue);
|
|
15049
|
+
if (Number.isFinite(next)) onChange(next);
|
|
15050
|
+
}
|
|
15051
|
+
})
|
|
15052
|
+
});
|
|
15053
|
+
}
|
|
15054
|
+
function FillField({ label, children }) {
|
|
15055
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
15056
|
+
className: "work-spreadsheet-format-cells-field",
|
|
15057
|
+
children: [
|
|
15058
|
+
/*#__PURE__*/ jsx("span", {
|
|
15059
|
+
children: label
|
|
15060
|
+
}),
|
|
15061
|
+
children
|
|
15062
|
+
]
|
|
15063
|
+
});
|
|
15064
|
+
}
|
|
15065
|
+
function addGradientStop(source) {
|
|
15066
|
+
if (source.length >= 256) return [
|
|
15067
|
+
...source
|
|
15068
|
+
];
|
|
15069
|
+
let insertAfter = 0;
|
|
15070
|
+
let largestGap = -1 / 0;
|
|
15071
|
+
for(let index = 0; index < source.length - 1; index += 1){
|
|
15072
|
+
const left = source[index];
|
|
15073
|
+
const right = source[index + 1];
|
|
15074
|
+
if (!left || !right) continue;
|
|
15075
|
+
const gap = right.position - left.position;
|
|
15076
|
+
if (gap > largestGap) {
|
|
15077
|
+
insertAfter = index;
|
|
15078
|
+
largestGap = gap;
|
|
15079
|
+
}
|
|
15080
|
+
}
|
|
15081
|
+
const left = source[insertAfter] ?? {
|
|
15082
|
+
color: '#4472c4',
|
|
15083
|
+
position: 0
|
|
15084
|
+
};
|
|
15085
|
+
const right = source[insertAfter + 1] ?? {
|
|
15086
|
+
color: '#ffffff',
|
|
15087
|
+
position: 1
|
|
15088
|
+
};
|
|
15089
|
+
const stop = {
|
|
15090
|
+
color: interpolateHexColor(left.color, right.color),
|
|
15091
|
+
position: (left.position + right.position) / 2
|
|
15092
|
+
};
|
|
15093
|
+
return [
|
|
15094
|
+
...source.slice(0, insertAfter + 1).map((item)=>({
|
|
15095
|
+
...item
|
|
15096
|
+
})),
|
|
15097
|
+
stop,
|
|
15098
|
+
...source.slice(insertAfter + 1).map((item)=>({
|
|
15099
|
+
...item
|
|
15100
|
+
}))
|
|
15101
|
+
];
|
|
15102
|
+
}
|
|
15103
|
+
function interpolateHexColor(left, right) {
|
|
15104
|
+
const channels = [
|
|
15105
|
+
1,
|
|
15106
|
+
3,
|
|
15107
|
+
5
|
|
15108
|
+
].map((offset)=>Math.round((Number.parseInt(left.slice(offset, offset + 2), 16) + Number.parseInt(right.slice(offset, offset + 2), 16)) / 2));
|
|
15109
|
+
return `#${channels.map((channel)=>channel.toString(16).padStart(2, '0')).join('')}`;
|
|
15110
|
+
}
|
|
15111
|
+
function formatPercentage(value) {
|
|
15112
|
+
return spreadsheet_format_cells_fill_panel_formatNumber(100 * value);
|
|
15113
|
+
}
|
|
15114
|
+
function spreadsheet_format_cells_fill_panel_formatNumber(value) {
|
|
15115
|
+
return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(4)));
|
|
15116
|
+
}
|
|
15117
|
+
const MIXED_VALUE = '__mixed__';
|
|
15118
|
+
const numberFormatOptions = [
|
|
15119
|
+
'general',
|
|
15120
|
+
'number',
|
|
15121
|
+
'currency',
|
|
15122
|
+
'accounting',
|
|
15123
|
+
'percent',
|
|
15124
|
+
'date',
|
|
15125
|
+
'time',
|
|
15126
|
+
'scientific',
|
|
15127
|
+
'fraction',
|
|
15128
|
+
'text',
|
|
15129
|
+
'custom'
|
|
15130
|
+
].map((value)=>({
|
|
15131
|
+
value: value,
|
|
15132
|
+
label: spreadsheetNumberFormatPresetLabels[value]
|
|
15133
|
+
}));
|
|
15134
|
+
const horizontalOptions = [
|
|
15135
|
+
{
|
|
15136
|
+
value: 'general',
|
|
15137
|
+
label: '常规'
|
|
15138
|
+
},
|
|
15139
|
+
{
|
|
15140
|
+
value: 'left',
|
|
15141
|
+
label: '左对齐'
|
|
15142
|
+
},
|
|
15143
|
+
{
|
|
15144
|
+
value: 'center',
|
|
15145
|
+
label: '居中'
|
|
15146
|
+
},
|
|
15147
|
+
{
|
|
15148
|
+
value: 'right',
|
|
15149
|
+
label: '右对齐'
|
|
15150
|
+
}
|
|
15151
|
+
];
|
|
15152
|
+
const verticalOptions = [
|
|
15153
|
+
{
|
|
15154
|
+
value: 'top',
|
|
15155
|
+
label: '顶端对齐'
|
|
15156
|
+
},
|
|
15157
|
+
{
|
|
15158
|
+
value: 'middle',
|
|
15159
|
+
label: '垂直居中'
|
|
15160
|
+
},
|
|
15161
|
+
{
|
|
15162
|
+
value: 'bottom',
|
|
15163
|
+
label: '底端对齐'
|
|
15164
|
+
}
|
|
15165
|
+
];
|
|
15166
|
+
const spreadsheet_format_cells_dialog_panels_underlineOptions = [
|
|
15167
|
+
{
|
|
15168
|
+
value: 'none',
|
|
15169
|
+
label: '无'
|
|
15170
|
+
},
|
|
15171
|
+
{
|
|
15172
|
+
value: 'single',
|
|
15173
|
+
label: '单下划线'
|
|
15174
|
+
},
|
|
15175
|
+
{
|
|
15176
|
+
value: 'double',
|
|
15177
|
+
label: '双下划线'
|
|
15178
|
+
},
|
|
15179
|
+
{
|
|
15180
|
+
value: 'singleAccounting',
|
|
15181
|
+
label: '单会计用下划线'
|
|
15182
|
+
},
|
|
15183
|
+
{
|
|
15184
|
+
value: 'doubleAccounting',
|
|
15185
|
+
label: '双会计用下划线'
|
|
15186
|
+
}
|
|
15187
|
+
];
|
|
15188
|
+
const borderStyleOptions = [
|
|
15189
|
+
{
|
|
15190
|
+
value: 'thin',
|
|
15191
|
+
label: '细实线'
|
|
15192
|
+
},
|
|
15193
|
+
{
|
|
15194
|
+
value: 'dotted',
|
|
15195
|
+
label: '点线'
|
|
15196
|
+
},
|
|
15197
|
+
{
|
|
15198
|
+
value: 'dashed',
|
|
15199
|
+
label: '虚线'
|
|
15200
|
+
},
|
|
15201
|
+
{
|
|
15202
|
+
value: 'dash-dot',
|
|
15203
|
+
label: '点划线'
|
|
15204
|
+
},
|
|
15205
|
+
{
|
|
15206
|
+
value: 'medium',
|
|
15207
|
+
label: '中等实线'
|
|
15208
|
+
},
|
|
15209
|
+
{
|
|
15210
|
+
value: 'medium-dashed',
|
|
15211
|
+
label: '中等虚线'
|
|
15212
|
+
},
|
|
15213
|
+
{
|
|
15214
|
+
value: 'thick',
|
|
15215
|
+
label: '粗实线'
|
|
15216
|
+
}
|
|
15217
|
+
];
|
|
15218
|
+
const borderTargets = [
|
|
15219
|
+
{
|
|
15220
|
+
target: 'top',
|
|
15221
|
+
label: '上框线'
|
|
15222
|
+
},
|
|
15223
|
+
{
|
|
15224
|
+
target: 'bottom',
|
|
15225
|
+
label: '下框线'
|
|
15226
|
+
},
|
|
15227
|
+
{
|
|
15228
|
+
target: 'left',
|
|
15229
|
+
label: '左框线'
|
|
15230
|
+
},
|
|
15231
|
+
{
|
|
15232
|
+
target: 'right',
|
|
15233
|
+
label: '右框线'
|
|
15234
|
+
},
|
|
15235
|
+
{
|
|
15236
|
+
target: 'diagonalDown',
|
|
15237
|
+
label: '斜下框线'
|
|
15238
|
+
},
|
|
15239
|
+
{
|
|
15240
|
+
target: 'diagonalUp',
|
|
15241
|
+
label: '斜上框线'
|
|
15242
|
+
}
|
|
15243
|
+
];
|
|
15244
|
+
function SpreadsheetFormatCellsPanel(props) {
|
|
15245
|
+
return /*#__PURE__*/ jsxs("section", {
|
|
15246
|
+
id: `${props.idBase}-${props.activeTab}-panel`,
|
|
15247
|
+
className: "work-spreadsheet-format-cells-panel",
|
|
15248
|
+
role: "tabpanel",
|
|
15249
|
+
"aria-labelledby": `${props.idBase}-${props.activeTab}-tab`,
|
|
15250
|
+
tabIndex: -1,
|
|
15251
|
+
children: [
|
|
15252
|
+
'number' === props.activeTab && /*#__PURE__*/ jsx(NumberPanel, {
|
|
15253
|
+
...props
|
|
15254
|
+
}),
|
|
15255
|
+
'alignment' === props.activeTab && /*#__PURE__*/ jsx(AlignmentPanel, {
|
|
15256
|
+
...props
|
|
14106
15257
|
}),
|
|
14107
15258
|
'font' === props.activeTab && /*#__PURE__*/ jsx(FontPanel, {
|
|
14108
15259
|
...props
|
|
@@ -14110,7 +15261,7 @@ function SpreadsheetFormatCellsPanel(props) {
|
|
|
14110
15261
|
'border' === props.activeTab && /*#__PURE__*/ jsx(BorderPanel, {
|
|
14111
15262
|
...props
|
|
14112
15263
|
}),
|
|
14113
|
-
'fill' === props.activeTab && /*#__PURE__*/ jsx(
|
|
15264
|
+
'fill' === props.activeTab && /*#__PURE__*/ jsx(SpreadsheetFormatCellsFillPanel, {
|
|
14114
15265
|
...props
|
|
14115
15266
|
}),
|
|
14116
15267
|
'protection' === props.activeTab && /*#__PURE__*/ jsx(ProtectionPanel, {
|
|
@@ -14558,47 +15709,6 @@ function BorderPreview({ draft }) {
|
|
|
14558
15709
|
]
|
|
14559
15710
|
});
|
|
14560
15711
|
}
|
|
14561
|
-
function FillPanel({ source, draft, touched, setDraft, touch }) {
|
|
14562
|
-
return /*#__PURE__*/ jsxs("div", {
|
|
14563
|
-
className: "work-spreadsheet-format-cells-fill",
|
|
14564
|
-
children: [
|
|
14565
|
-
/*#__PURE__*/ jsx(Field, {
|
|
14566
|
-
label: "背景色",
|
|
14567
|
-
children: /*#__PURE__*/ jsx(OfficeColorPicker, {
|
|
14568
|
-
ariaLabel: "单元格填充颜色",
|
|
14569
|
-
value: draft.fillColor ?? '#ffffff',
|
|
14570
|
-
onValueChange: (fillColor)=>{
|
|
14571
|
-
touch('fillColor');
|
|
14572
|
-
setDraft((current)=>({
|
|
14573
|
-
...current,
|
|
14574
|
-
fillColor
|
|
14575
|
-
}));
|
|
14576
|
-
}
|
|
14577
|
-
})
|
|
14578
|
-
}),
|
|
14579
|
-
/*#__PURE__*/ jsx(button_Button, {
|
|
14580
|
-
size: "compact",
|
|
14581
|
-
tone: "quiet",
|
|
14582
|
-
onClick: ()=>{
|
|
14583
|
-
touch('fillColor');
|
|
14584
|
-
setDraft((current)=>({
|
|
14585
|
-
...current,
|
|
14586
|
-
fillColor: null
|
|
14587
|
-
}));
|
|
14588
|
-
},
|
|
14589
|
-
children: "无填充"
|
|
14590
|
-
}),
|
|
14591
|
-
/*#__PURE__*/ jsx("div", {
|
|
14592
|
-
className: `work-spreadsheet-format-cells-fill-preview${draft.fillColor ? '' : ' empty'}`,
|
|
14593
|
-
style: {
|
|
14594
|
-
backgroundColor: draft.fillColor ?? void 0
|
|
14595
|
-
},
|
|
14596
|
-
children: draft.fillColor ? draft.fillColor.toUpperCase() : '无填充'
|
|
14597
|
-
}),
|
|
14598
|
-
source.fields.fillColor.mixed && !touched.fillColor && /*#__PURE__*/ jsx(MixedHint, {})
|
|
14599
|
-
]
|
|
14600
|
-
});
|
|
14601
|
-
}
|
|
14602
15712
|
function ProtectionPanel({ source, draft, touched, setDraft, touch }) {
|
|
14603
15713
|
return /*#__PURE__*/ jsxs("div", {
|
|
14604
15714
|
className: "work-spreadsheet-format-cells-protection",
|
|
@@ -14667,177 +15777,6 @@ function borderCss(format) {
|
|
|
14667
15777
|
const style = 'dotted' === format.style ? 'dotted' : format.style.includes('dash') ? 'dashed' : 'solid';
|
|
14668
15778
|
return `${width}px ${style} ${format.color}`;
|
|
14669
15779
|
}
|
|
14670
|
-
function createSpreadsheetFormatCellsDialogSource(content, sheetId, rangeInput, cells, requestedActiveCell) {
|
|
14671
|
-
const range = spreadsheet_cell_range_normalizeSpreadsheetCellRange(rangeInput);
|
|
14672
|
-
const sheet = content.sheets.find((candidate)=>candidate.id === sheetId);
|
|
14673
|
-
if (!range || !sheet || spreadsheet_cell_range_spreadsheetCellRangeArea(range) > 10000) return null;
|
|
14674
|
-
const activeRow = clampIndex(requestedActiveCell.row, range.row[0], range.row[1]);
|
|
14675
|
-
const activeColumn = clampIndex(requestedActiveCell.column, range.column[0], range.column[1]);
|
|
14676
|
-
const activeCell = cells[activeRow - range.row[0]]?.[activeColumn - range.column[0]] ?? null;
|
|
14677
|
-
const values = (resolve)=>{
|
|
14678
|
-
const activeValue = resolve(activeCell, activeRow, activeColumn);
|
|
14679
|
-
let mixed = false;
|
|
14680
|
-
for(let row = range.row[0]; row <= range.row[1] && !mixed; row += 1)for(let column = range.column[0]; column <= range.column[1]; column += 1){
|
|
14681
|
-
const cell = cells[row - range.row[0]]?.[column - range.column[0]] ?? null;
|
|
14682
|
-
if (!sameDialogValue(resolve(cell, row, column), activeValue)) {
|
|
14683
|
-
mixed = true;
|
|
14684
|
-
break;
|
|
14685
|
-
}
|
|
14686
|
-
}
|
|
14687
|
-
return {
|
|
14688
|
-
value: activeValue,
|
|
14689
|
-
mixed
|
|
14690
|
-
};
|
|
14691
|
-
};
|
|
14692
|
-
const borders = borderFormatsAt(sheet, activeRow, activeColumn);
|
|
14693
|
-
return {
|
|
14694
|
-
sheetId,
|
|
14695
|
-
range,
|
|
14696
|
-
activeCell,
|
|
14697
|
-
fields: {
|
|
14698
|
-
numberFormat: values((cell)=>cell?.ct?.fa?.trim() || 'General'),
|
|
14699
|
-
horizontalAlignment: values((cell)=>spreadsheet_format_cells_dialog_model_horizontalAlignment(cell?.ht)),
|
|
14700
|
-
verticalAlignment: values((cell)=>verticalAlignment(cell?.vt)),
|
|
14701
|
-
wrapText: values((cell)=>'2' === String(cell?.tb)),
|
|
14702
|
-
rotation: values((cell)=>spreadsheetVisibleTextRotationFromCell(cell)),
|
|
14703
|
-
fontFamily: values((cell)=>'string' == typeof cell?.ff && cell.ff.trim() ? cell.ff.trim() : 'Aptos'),
|
|
14704
|
-
fontSize: values((cell)=>'number' == typeof cell?.fs && Number.isFinite(cell.fs) ? cell.fs : 10),
|
|
14705
|
-
fontColor: values((cell)=>normalizedColor(cell?.fc, '#172033')),
|
|
14706
|
-
bold: values((cell)=>1 === Number(cell?.bl)),
|
|
14707
|
-
italic: values((cell)=>1 === Number(cell?.it)),
|
|
14708
|
-
underline: values((cell)=>spreadsheetUnderlineStyle(cell?.un)),
|
|
14709
|
-
strike: values((cell)=>1 === Number(cell?.cl)),
|
|
14710
|
-
fillColor: values((cell)=>'string' == typeof cell?.bg && cell.bg.trim() ? normalizedColor(cell.bg, null) : null),
|
|
14711
|
-
borders: {
|
|
14712
|
-
value: borders,
|
|
14713
|
-
mixed: spreadsheet_cell_range_spreadsheetCellRangeArea(range) > 1
|
|
14714
|
-
},
|
|
14715
|
-
locked: values((cell, row, column)=>spreadsheetCellProtectionAt(sheet, row, column, cell).locked),
|
|
14716
|
-
hidden: values((cell, row, column)=>spreadsheetCellProtectionAt(sheet, row, column, cell).hidden)
|
|
14717
|
-
}
|
|
14718
|
-
};
|
|
14719
|
-
}
|
|
14720
|
-
function createSpreadsheetFormatCellsDraft(source) {
|
|
14721
|
-
const borders = source.fields.borders.value.map((format)=>({
|
|
14722
|
-
...format
|
|
14723
|
-
}));
|
|
14724
|
-
return {
|
|
14725
|
-
numberFormat: source.fields.numberFormat.value,
|
|
14726
|
-
horizontalAlignment: source.fields.horizontalAlignment.value,
|
|
14727
|
-
verticalAlignment: source.fields.verticalAlignment.value,
|
|
14728
|
-
wrapText: source.fields.wrapText.value,
|
|
14729
|
-
rotation: source.fields.rotation.value,
|
|
14730
|
-
fontFamily: source.fields.fontFamily.value,
|
|
14731
|
-
fontSize: source.fields.fontSize.value,
|
|
14732
|
-
fontColor: source.fields.fontColor.value,
|
|
14733
|
-
bold: source.fields.bold.value,
|
|
14734
|
-
italic: source.fields.italic.value,
|
|
14735
|
-
underline: source.fields.underline.value,
|
|
14736
|
-
strike: source.fields.strike.value,
|
|
14737
|
-
fillColor: source.fields.fillColor.value,
|
|
14738
|
-
borders,
|
|
14739
|
-
borderColor: borders[0]?.color ?? '#172033',
|
|
14740
|
-
borderStyle: borders[0]?.style ?? 'thin',
|
|
14741
|
-
locked: source.fields.locked.value,
|
|
14742
|
-
hidden: source.fields.hidden.value
|
|
14743
|
-
};
|
|
14744
|
-
}
|
|
14745
|
-
function spreadsheetFormatCellsPatch(source, draft, touched) {
|
|
14746
|
-
const patch = {};
|
|
14747
|
-
if (shouldEmit(source.fields.numberFormat, draft.numberFormat, touched.numberFormat)) patch.numberFormat = draft.numberFormat.trim();
|
|
14748
|
-
if (shouldEmit(source.fields.horizontalAlignment, draft.horizontalAlignment, touched.horizontalAlignment)) patch.horizontalAlignment = draft.horizontalAlignment;
|
|
14749
|
-
if (shouldEmit(source.fields.verticalAlignment, draft.verticalAlignment, touched.verticalAlignment)) patch.verticalAlignment = draft.verticalAlignment;
|
|
14750
|
-
if (shouldEmit(source.fields.wrapText, draft.wrapText, touched.wrapText)) patch.wrapText = draft.wrapText;
|
|
14751
|
-
if (shouldEmit(source.fields.rotation, draft.rotation, touched.rotation)) patch.rotation = draft.rotation;
|
|
14752
|
-
if (shouldEmit(source.fields.fontFamily, draft.fontFamily, touched.fontFamily)) patch.fontFamily = draft.fontFamily.trim();
|
|
14753
|
-
if (shouldEmit(source.fields.fontSize, draft.fontSize, touched.fontSize)) patch.fontSize = draft.fontSize;
|
|
14754
|
-
if (shouldEmit(source.fields.fontColor, draft.fontColor, touched.fontColor)) patch.fontColor = draft.fontColor;
|
|
14755
|
-
if (shouldEmit(source.fields.bold, draft.bold, touched.bold)) patch.bold = draft.bold;
|
|
14756
|
-
if (shouldEmit(source.fields.italic, draft.italic, touched.italic)) patch.italic = draft.italic;
|
|
14757
|
-
if (shouldEmit(source.fields.underline, draft.underline, touched.underline)) patch.underline = draft.underline;
|
|
14758
|
-
if (shouldEmit(source.fields.strike, draft.strike, touched.strike)) patch.strike = draft.strike;
|
|
14759
|
-
if (shouldEmit(source.fields.fillColor, draft.fillColor, touched.fillColor)) patch.fillColor = draft.fillColor;
|
|
14760
|
-
if (shouldEmit(source.fields.borders, draft.borders, touched.borders)) patch.borders = draft.borders.map((format)=>({
|
|
14761
|
-
...format
|
|
14762
|
-
}));
|
|
14763
|
-
if (shouldEmit(source.fields.locked, draft.locked, touched.locked)) patch.locked = draft.locked;
|
|
14764
|
-
if (shouldEmit(source.fields.hidden, draft.hidden, touched.hidden)) patch.hidden = draft.hidden;
|
|
14765
|
-
return patch;
|
|
14766
|
-
}
|
|
14767
|
-
function spreadsheetFormatCellsDraftErrors(draft) {
|
|
14768
|
-
const errors = {};
|
|
14769
|
-
if (draft.numberFormat.trim()) {
|
|
14770
|
-
if (draft.numberFormat.trim().length > 255) errors.numberFormat = '数字格式代码不能超过 255 个字符。';
|
|
14771
|
-
} else errors.numberFormat = '请输入数字格式代码。';
|
|
14772
|
-
if (!Number.isFinite(draft.fontSize) || draft.fontSize < 1 || draft.fontSize > 409) errors.fontSize = '字号需为 1–409 之间的数字。';
|
|
14773
|
-
if (!Number.isInteger(draft.rotation) || draft.rotation < -90 || draft.rotation > 90) errors.rotation = '文字旋转角度需为 -90–90 之间的整数。';
|
|
14774
|
-
return errors;
|
|
14775
|
-
}
|
|
14776
|
-
function shouldEmit(source, value, touched) {
|
|
14777
|
-
return Boolean(touched && (source.mixed || !sameDialogValue(source.value, value)));
|
|
14778
|
-
}
|
|
14779
|
-
function spreadsheet_format_cells_dialog_model_horizontalAlignment(value) {
|
|
14780
|
-
if ('0' === String(value)) return 'center';
|
|
14781
|
-
if ('1' === String(value)) return 'left';
|
|
14782
|
-
if ('2' === String(value)) return 'right';
|
|
14783
|
-
return 'general';
|
|
14784
|
-
}
|
|
14785
|
-
function verticalAlignment(value) {
|
|
14786
|
-
if (0 === Number(value)) return 'middle';
|
|
14787
|
-
if (2 === Number(value)) return 'bottom';
|
|
14788
|
-
return 'top';
|
|
14789
|
-
}
|
|
14790
|
-
function borderFormatsAt(sheet, row, column) {
|
|
14791
|
-
const resolved = spreadsheetCellBordersAt(sheet, row, column);
|
|
14792
|
-
return [
|
|
14793
|
-
'top',
|
|
14794
|
-
'bottom',
|
|
14795
|
-
'left',
|
|
14796
|
-
'right',
|
|
14797
|
-
'diagonalDown',
|
|
14798
|
-
'diagonalUp'
|
|
14799
|
-
].flatMap((target)=>{
|
|
14800
|
-
const line = resolved[target];
|
|
14801
|
-
if (!line) return [];
|
|
14802
|
-
return [
|
|
14803
|
-
{
|
|
14804
|
-
target,
|
|
14805
|
-
color: normalizedColor(line.color, '#172033') ?? '#172033',
|
|
14806
|
-
style: borderStyle(line.style)
|
|
14807
|
-
}
|
|
14808
|
-
];
|
|
14809
|
-
});
|
|
14810
|
-
}
|
|
14811
|
-
function borderStyle(value) {
|
|
14812
|
-
return ({
|
|
14813
|
-
1: 'thin',
|
|
14814
|
-
3: 'dotted',
|
|
14815
|
-
4: 'dashed',
|
|
14816
|
-
5: 'dash-dot',
|
|
14817
|
-
6: 'dash-dot-dot',
|
|
14818
|
-
8: 'medium',
|
|
14819
|
-
9: 'medium-dashed',
|
|
14820
|
-
10: 'medium-dash-dot',
|
|
14821
|
-
11: 'medium-dash-dot-dot',
|
|
14822
|
-
13: 'thick'
|
|
14823
|
-
})[value] ?? 'thin';
|
|
14824
|
-
}
|
|
14825
|
-
function normalizedColor(value, fallback) {
|
|
14826
|
-
if ('string' != typeof value) return fallback;
|
|
14827
|
-
const color = value.trim().toLowerCase();
|
|
14828
|
-
if (/^#[0-9a-f]{6}$/.test(color)) return color;
|
|
14829
|
-
if (/^#[0-9a-f]{3}$/.test(color)) return `#${[
|
|
14830
|
-
...color.slice(1)
|
|
14831
|
-
].map((character)=>character.repeat(2)).join('')}`;
|
|
14832
|
-
return fallback;
|
|
14833
|
-
}
|
|
14834
|
-
function sameDialogValue(left, right) {
|
|
14835
|
-
if (Object.is(left, right)) return true;
|
|
14836
|
-
return JSON.stringify(left) === JSON.stringify(right);
|
|
14837
|
-
}
|
|
14838
|
-
function clampIndex(value, minimum, maximum) {
|
|
14839
|
-
return Math.min(maximum, Math.max(minimum, Math.trunc(value)));
|
|
14840
|
-
}
|
|
14841
15780
|
function SpreadsheetFormatCellsDialog({ source, restoreFocusTarget, openIntent = defaultSpreadsheetFormatCellsOpenIntent, onApply, onClose }) {
|
|
14842
15781
|
const [draft, setDraft] = useState(()=>createSpreadsheetFormatCellsDraft(source));
|
|
14843
15782
|
const [touched, setTouched] = useState({});
|
|
@@ -16240,13 +17179,13 @@ function SheetMenuButton({ icon, label, danger = false, disabled = false, onClic
|
|
|
16240
17179
|
]
|
|
16241
17180
|
});
|
|
16242
17181
|
}
|
|
16243
|
-
const
|
|
17182
|
+
const spreadsheet_table_render_pendingContextRestores = new WeakMap();
|
|
16244
17183
|
function beginSpreadsheetTableCellRender(_cell, tableStyle, conditionalStyle, context) {
|
|
16245
17184
|
if (tableStyle) context.fillStyle = tableStyle.background;
|
|
16246
17185
|
if (conditionalStyle?.cellColor) context.fillStyle = conditionalStyle.cellColor;
|
|
16247
|
-
if (!tableStyle ||
|
|
17186
|
+
if (!tableStyle || spreadsheet_table_render_pendingContextRestores.has(context) || 'function' != typeof context.fillText) return;
|
|
16248
17187
|
const fillText = context.fillText;
|
|
16249
|
-
|
|
17188
|
+
spreadsheet_table_render_pendingContextRestores.set(context, {
|
|
16250
17189
|
fillText,
|
|
16251
17190
|
fillTextOwned: Object.hasOwn(context, 'fillText')
|
|
16252
17191
|
});
|
|
@@ -16267,11 +17206,11 @@ function beginSpreadsheetTableCellRender(_cell, tableStyle, conditionalStyle, co
|
|
|
16267
17206
|
}
|
|
16268
17207
|
function finishSpreadsheetTableCellRender(_cell, cellInfo, tableStyle, context) {
|
|
16269
17208
|
if (tableStyle) drawSpreadsheetTableCellBorder(cellInfo, tableStyle, context);
|
|
16270
|
-
const restore =
|
|
17209
|
+
const restore = spreadsheet_table_render_pendingContextRestores.get(context);
|
|
16271
17210
|
if (!restore) return;
|
|
16272
17211
|
if (restore.fillTextOwned) context.fillText = restore.fillText;
|
|
16273
17212
|
else delete context.fillText;
|
|
16274
|
-
|
|
17213
|
+
spreadsheet_table_render_pendingContextRestores.delete(context);
|
|
16275
17214
|
}
|
|
16276
17215
|
function boldSpreadsheetTableCanvasFont(font) {
|
|
16277
17216
|
return /(?:^|\s)(?:bold|[6-9]00)(?:\s|$)/i.test(font) ? font : `bold ${font}`;
|
|
@@ -21715,7 +22654,8 @@ const spreadsheetCellFormatKeys = [
|
|
|
21715
22654
|
'cl',
|
|
21716
22655
|
'un',
|
|
21717
22656
|
'tr',
|
|
21718
|
-
'rt'
|
|
22657
|
+
'rt',
|
|
22658
|
+
...xlsxNativeFillCellKeys
|
|
21719
22659
|
];
|
|
21720
22660
|
function pasteSpreadsheetSpecialCell({ source, destination, content, operation, rowOffset, columnOffset }) {
|
|
21721
22661
|
let next;
|
|
@@ -21862,8 +22802,9 @@ function clearCellContent(cell) {
|
|
|
21862
22802
|
}
|
|
21863
22803
|
}
|
|
21864
22804
|
function replaceCellFormatting(target, source) {
|
|
21865
|
-
|
|
21866
|
-
|
|
22805
|
+
const sourceCell = source;
|
|
22806
|
+
for (const key of spreadsheetCellFormatKeys)if (sourceCell?.[key] === void 0) delete target[key];
|
|
22807
|
+
else target[key] = cloneValue(sourceCell[key]);
|
|
21867
22808
|
const inline = Array.isArray(target.ct?.s) ? structuredClone(target.ct.s) : void 0;
|
|
21868
22809
|
const format = source?.ct ? structuredClone(source.ct) : void 0;
|
|
21869
22810
|
if (format) delete format.s;
|
|
@@ -21913,7 +22854,8 @@ function spreadsheetLiteralCellValue(source) {
|
|
|
21913
22854
|
}
|
|
21914
22855
|
function spreadsheetCellHasFormatting(cell) {
|
|
21915
22856
|
if (!cell) return false;
|
|
21916
|
-
|
|
22857
|
+
const formattedCell = cell;
|
|
22858
|
+
return Boolean(spreadsheetCellFormatKeys.some((key)=>void 0 !== formattedCell[key]) || void 0 !== cell.lo || void 0 !== cell.hi || cell.ct?.fa !== void 0 || cell.ct?.t !== void 0);
|
|
21917
22859
|
}
|
|
21918
22860
|
function spreadsheetPasteOperationValue(destination, source, operation) {
|
|
21919
22861
|
if ('divide' === operation && 0 === source) return null;
|
|
@@ -23345,7 +24287,8 @@ const spreadsheetCellFormatAttributes = [
|
|
|
23345
24287
|
'un',
|
|
23346
24288
|
'tr',
|
|
23347
24289
|
'ct',
|
|
23348
|
-
'bg'
|
|
24290
|
+
'bg',
|
|
24291
|
+
...xlsxNativeFillCellKeys
|
|
23349
24292
|
];
|
|
23350
24293
|
function captureSpreadsheetFormatPattern(cells) {
|
|
23351
24294
|
const rowCount = cells.length;
|
|
@@ -23410,7 +24353,8 @@ function spreadsheetFormatPainterBatches(pattern, target) {
|
|
|
23410
24353
|
}
|
|
23411
24354
|
function spreadsheetCellFormatSnapshot(cell) {
|
|
23412
24355
|
const snapshot = {};
|
|
23413
|
-
|
|
24356
|
+
const source = cell;
|
|
24357
|
+
for (const attribute of spreadsheetCellFormatAttributes)snapshot[attribute] = 'ct' === attribute ? spreadsheetNumberFormatSnapshot(cell?.ct) : cloneSpreadsheetFormatValue(source?.[attribute]);
|
|
23414
24358
|
return snapshot;
|
|
23415
24359
|
}
|
|
23416
24360
|
function spreadsheetNumberFormatSnapshot(value) {
|
|
@@ -24523,6 +25467,7 @@ function SpreadsheetEditorSurface({ autoFocus = true, content, collaborationHist
|
|
|
24523
25467
|
const tableStyle = tableStylesBySheetRef.current.get(activeSheetIdRef.current)?.(cellInfo.row, cellInfo.column) ?? null;
|
|
24524
25468
|
const style = conditionalStylesBySheetRef.current.get(activeSheetIdRef.current)?.get(`${cellInfo.row}_${cellInfo.column}`);
|
|
24525
25469
|
beginSpreadsheetTableCellRender(cell, tableStyle, style, context);
|
|
25470
|
+
beginSpreadsheetNativeFillRender(tableStyle || style?.cellColor ? void 0 : activeXlsxNativeFill(cell), context);
|
|
24526
25471
|
return true;
|
|
24527
25472
|
},
|
|
24528
25473
|
afterRenderCell: (cell, cellInfo, context)=>{
|
|
@@ -24539,6 +25484,7 @@ function SpreadsheetEditorSurface({ autoFocus = true, content, collaborationHist
|
|
|
24539
25484
|
if (cell?.ps) drawSpreadsheetCommentMarker(context, cellInfo);
|
|
24540
25485
|
}
|
|
24541
25486
|
} finally{
|
|
25487
|
+
finishSpreadsheetNativeFillRender(context);
|
|
24542
25488
|
finishSpreadsheetTableCellRender(cell, cellInfo, tableStyle, context);
|
|
24543
25489
|
const diagonal = diagonalBordersBySheetRef.current.get(activeSheetIdRef.current)?.get(`${cellInfo.row}_${cellInfo.column}`);
|
|
24544
25490
|
if (diagonal?.down) drawSpreadsheetDiagonalDownBorder(context, cellInfo, diagonal.down);
|