@a3s-lab/office 0.20.0 → 0.21.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 CHANGED
@@ -571,8 +571,10 @@ interaction model.
571
571
  angles, stacked vertical, rotate-up, and rotate-down choices, exact Fortune
572
572
  `rt` / `tr='3'` and OOXML 0–180 / 255 round trips, a 10,000-cell guard, and
573
573
  one-batch Undo, plus a cell-border split control with side, all,
574
- outside, inside, horizontal, vertical, clear, and diagonal targets, ten
575
- native line styles, exact color selection, compact overlapping range writes,
574
+ outside, inside, horizontal, vertical, clear, independent diagonal-down and
575
+ diagonal-up targets, crossed-border composition, ten native line styles,
576
+ exact color selection, compact overlapping range writes, exact OOXML
577
+ direction preservation through Paste Special, Yjs, XLSX export, and reopen,
576
578
  `Cmd/Ctrl+Shift+&` Outside Borders and `Cmd/Ctrl+Shift+_` Clear Borders,
577
579
  single-update undo, and grid-focus restoration, Conditional Formatting under
578
580
  Home and Styles, executable
@@ -1533,6 +1535,7 @@ without hard-coded return URLs.
1533
1535
 
1534
1536
  - [Live Playground](https://a3s-lab.github.io/Office/)
1535
1537
  - [Documentation center](https://a3s-lab.github.io/Office/docs/)
1538
+ - [A3S Office 0.21.0 documentation](https://a3s-lab.github.io/Office/docs/0.21.0/)
1536
1539
  - [A3S Office 0.20.0 documentation](https://a3s-lab.github.io/Office/docs/0.20.0/)
1537
1540
  - [A3S Office 0.19.0 documentation](https://a3s-lab.github.io/Office/docs/0.19.0/)
1538
1541
  - [A3S Office 0.18.0 documentation](https://a3s-lab.github.io/Office/docs/0.18.0/)
@@ -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, Check, ChevronDown, ChevronLeft, ChevronRight, ClipboardPaste, 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 { genarate, indexToColumnChar, update as core_update } from "@fortune-sheet/core";
7
- import { freezeImportedSpreadsheetCell, spreadsheetTextOrientationFromChoice, spreadsheetMatrixProfile, withoutEditableRange, spreadsheetTextOrientationFromAngle, isSpreadsheetTextOrientationId, normalizeSpreadsheetConditionalVisualOptions, spreadsheetUnderlineCellValue, effectiveSpreadsheetPageSetup, attachSpreadsheetShownCommentCells, withEditableRange, sameSpreadsheetHistoryValue, createOfficeSpreadsheetCollaborationBinding as createWorkOfficeSpreadsheetCollaborationBinding, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconForValue, defaultSpreadsheetConditionalIconThresholds, spreadsheetUnderlineStyle, normalizeSpreadsheetDateValidationBoundary, sheetProtectionAuthority, editableRangeCellCount, unlockedCellCount, registerDerivedSpreadsheetMatrix, editableRangeRequiresCredentials, spreadsheetTextOrientationCellStyle, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, spreadsheetConditionalThresholdValue, spreadsheetTextOrientationChoiceFromCell, normalizeSheetProtectionAuthority, withSheetProtection, defaultSpreadsheetColorScaleThresholds, spreadsheetProtectionKey, protectedSheetCount, SPREADSHEET_CONDITIONAL_ICON_SETS, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, withSheetSelectionPermissions, spreadsheetConditionalComparisonNeedsUpperValue, drawSpreadsheetConditionalIcon, spreadsheetTextOrientationFromCell, replaceOfficeSpreadsheetCollaboration as replaceWorkOfficeSpreadsheetCollaboration, readOfficeSpreadsheetCollaboration as readWorkOfficeSpreadsheetCollaboration, spreadsheetConditionalThresholdsEqual, isSpreadsheetUnderlineStyle, spreadsheetVisibleTextRotationFromCell } from "./6164.js";
7
+ import { freezeImportedSpreadsheetCell, spreadsheetTextOrientationFromChoice, spreadsheetMatrixProfile, withoutEditableRange, spreadsheetTextOrientationFromAngle, isSpreadsheetTextOrientationId, normalizeSpreadsheetConditionalVisualOptions, spreadsheetCellValueWithDiagonalBorder, spreadsheetUnderlineCellValue, effectiveSpreadsheetPageSetup, attachSpreadsheetShownCommentCells, withEditableRange, sameSpreadsheetHistoryValue, createOfficeSpreadsheetCollaborationBinding as createWorkOfficeSpreadsheetCollaborationBinding, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconForValue, defaultSpreadsheetConditionalIconThresholds, spreadsheetUnderlineStyle, normalizeSpreadsheetDateValidationBoundary, sheetProtectionAuthority, editableRangeCellCount, unlockedCellCount, registerDerivedSpreadsheetMatrix, editableRangeRequiresCredentials, spreadsheetTextOrientationCellStyle, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, spreadsheetConditionalThresholdValue, spreadsheetTextOrientationChoiceFromCell, normalizeSheetProtectionAuthority, withSheetProtection, defaultSpreadsheetColorScaleThresholds, spreadsheetProtectionKey, spreadsheetDiagonalBorderFromCellValue, SPREADSHEET_CONDITIONAL_ICON_SETS, protectedSheetCount, withSheetSelectionPermissions, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, spreadsheetConditionalComparisonNeedsUpperValue, drawSpreadsheetConditionalIcon, spreadsheetTextOrientationFromCell, replaceOfficeSpreadsheetCollaboration as replaceWorkOfficeSpreadsheetCollaboration, readOfficeSpreadsheetCollaboration as readWorkOfficeSpreadsheetCollaboration, spreadsheetConditionalThresholdsEqual, isSpreadsheetUnderlineStyle, spreadsheetVisibleTextRotationFromCell } from "./5045.js";
8
8
  import { workSpreadsheetChartSupportsGrouping, 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 { useOfficeTaskPaneEscape, OfficeCheckbox, CommittedOfficeNumberField, useOfficeDialog, useOfficeTaskPaneModal, createOfficeKernelClient, officeFontFamilies, CollectionState, OfficeNumberField, handleOfficeTaskPaneKeyDown } from "./0~7048.js";
@@ -86,6 +86,74 @@ function drawCellValue(context, bounds, cell, conditionalTextColor) {
86
86
  context.fillText(String(value), bounds.startX + 4, bounds.startY + height / 2, bounds.endX - bounds.startX - 8);
87
87
  }
88
88
  }
89
+ function drawSpreadsheetDiagonalDownBorder(context, bounds, line) {
90
+ drawSpreadsheetDiagonalBorder(context, bounds, line, 'down');
91
+ }
92
+ function drawSpreadsheetDiagonalUpBorder(context, bounds, line) {
93
+ drawSpreadsheetDiagonalBorder(context, bounds, line, 'up');
94
+ }
95
+ function drawSpreadsheetDiagonalBorder(context, bounds, line, direction) {
96
+ const left = Math.round(bounds.startX) + 0.5;
97
+ const top = Math.round(bounds.startY) + 0.5;
98
+ const right = Math.round(bounds.endX) - 1.5;
99
+ const bottom = Math.round(bounds.endY) - 1.5;
100
+ if (right <= left || bottom <= top) return;
101
+ context.save();
102
+ context.strokeStyle = line.color;
103
+ context.lineCap = 'butt';
104
+ context.lineWidth = spreadsheetDiagonalLineWidth(line.style);
105
+ context.setLineDash(spreadsheetDiagonalLineDash(line.style));
106
+ const startY = 'down' === direction ? top : bottom;
107
+ const endY = 'down' === direction ? bottom : top;
108
+ if ('7' === line.style) {
109
+ drawLine(context, left, startY - 1, right, endY - 1);
110
+ drawLine(context, left, startY + 1, right, endY + 1);
111
+ } else drawLine(context, left, startY, right, endY);
112
+ context.restore();
113
+ }
114
+ function drawLine(context, startX, startY, endX, endY) {
115
+ context.beginPath();
116
+ context.moveTo(startX, startY);
117
+ context.lineTo(endX, endY);
118
+ context.stroke();
119
+ }
120
+ function spreadsheetDiagonalLineWidth(style) {
121
+ if ('2' === style) return 0.5;
122
+ if ([
123
+ '8',
124
+ '9',
125
+ '10',
126
+ '11',
127
+ '12'
128
+ ].includes(style)) return 2;
129
+ if ('13' === style) return 3;
130
+ return 1;
131
+ }
132
+ function spreadsheetDiagonalLineDash(style) {
133
+ if ('3' === style) return [
134
+ 1,
135
+ 2
136
+ ];
137
+ if ('4' === style || '9' === style) return [
138
+ 5,
139
+ 3
140
+ ];
141
+ if ('5' === style || '10' === style || '12' === style) return [
142
+ 6,
143
+ 3,
144
+ 1,
145
+ 3
146
+ ];
147
+ if ('6' === style || '11' === style) return [
148
+ 6,
149
+ 3,
150
+ 1,
151
+ 3,
152
+ 1,
153
+ 3
154
+ ];
155
+ return [];
156
+ }
89
157
  function parseSpreadsheetConditionalColor(value) {
90
158
  const hexadecimal = /^#?([0-9a-f]{6})$/i.exec(value.trim());
91
159
  if (hexadecimal) return {
@@ -577,7 +645,8 @@ const spreadsheetCellBorderTargets = [
577
645
  'inside',
578
646
  'horizontal',
579
647
  'vertical',
580
- 'diagonal'
648
+ 'diagonalDown',
649
+ 'diagonalUp'
581
650
  ];
582
651
  const spreadsheetCellBorderStyles = [
583
652
  'thin',
@@ -615,8 +684,7 @@ const spreadsheetNativeBorderTypeByTarget = {
615
684
  outside: 'border-outside',
616
685
  inside: 'border-inside',
617
686
  horizontal: 'border-horizontal',
618
- vertical: 'border-vertical',
619
- diagonal: 'border-slash'
687
+ vertical: 'border-vertical'
620
688
  };
621
689
  const spreadsheetNativeBorderStyleByName = {
622
690
  thin: '1',
@@ -635,36 +703,29 @@ function spreadsheetNativeBorderStyle(style) {
635
703
  }
636
704
  function canSetSpreadsheetCellBorders(content, sheetId, range, format) {
637
705
  const normalizedRange = spreadsheet_cell_range_normalizeSpreadsheetCellRange(range);
638
- return Boolean(content.sheets.some((sheet)=>sheet.id === sheetId) && normalizedRange && normalizeSpreadsheetBorderFormat(format) && ('diagonal' !== format.target || spreadsheet_cell_range_spreadsheetCellRangeArea(normalizedRange) <= MAX_SPREADSHEET_DIAGONAL_BORDER_CELLS) && spreadsheetBorderInfoIsWritable(content.sheets.find((sheet)=>sheet.id === sheetId)));
706
+ return Boolean(content.sheets.some((sheet)=>sheet.id === sheetId) && normalizedRange && normalizeSpreadsheetBorderFormat(format) && (!isSpreadsheetDiagonalBorderTarget(format.target) || spreadsheet_cell_range_spreadsheetCellRangeArea(normalizedRange) <= MAX_SPREADSHEET_DIAGONAL_BORDER_CELLS) && spreadsheetBorderInfoIsWritable(content.sheets.find((sheet)=>sheet.id === sheetId)));
639
707
  }
640
708
  function setSpreadsheetCellBorders(content, sheetId, range, format) {
641
709
  const sheetIndex = content.sheets.findIndex((sheet)=>sheet.id === sheetId);
642
710
  const sheet = content.sheets[sheetIndex];
643
711
  const normalizedRange = spreadsheet_cell_range_normalizeSpreadsheetCellRange(range);
644
712
  const normalizedFormat = normalizeSpreadsheetBorderFormat(format);
645
- if (!sheet || !normalizedRange || !normalizedFormat || !spreadsheetBorderInfoIsWritable(sheet) || 'diagonal' === normalizedFormat.target && spreadsheet_cell_range_spreadsheetCellRangeArea(normalizedRange) > MAX_SPREADSHEET_DIAGONAL_BORDER_CELLS) return null;
646
- const borderType = spreadsheetNativeBorderTypeByTarget[normalizedFormat.target];
713
+ if (!sheet || !normalizedRange || !normalizedFormat || !spreadsheetBorderInfoIsWritable(sheet) || isSpreadsheetDiagonalBorderTarget(normalizedFormat.target) && spreadsheet_cell_range_spreadsheetCellRangeArea(normalizedRange) > MAX_SPREADSHEET_DIAGONAL_BORDER_CELLS) return null;
647
714
  const source = Array.isArray(sheet.config?.borderInfo) ? sheet.config.borderInfo : [];
715
+ if (isSpreadsheetDiagonalBorderTarget(normalizedFormat.target)) {
716
+ const borderInfo = [
717
+ ...compactSpreadsheetBorderInfo(source, normalizedRange, 'border-slash'),
718
+ ...spreadsheetDiagonalBorderRecords(sheet, normalizedRange, normalizedFormat.target, normalizedFormat.color, spreadsheetNativeBorderStyleByName[normalizedFormat.style])
719
+ ];
720
+ return contentWithSpreadsheetBorderInfo(content, sheetIndex, sheet, borderInfo);
721
+ }
722
+ const borderType = spreadsheetNativeBorderTypeByTarget[normalizedFormat.target];
648
723
  const compacted = compactSpreadsheetBorderInfo(source, normalizedRange, borderType);
649
724
  const borderInfo = [
650
725
  ...compacted,
651
726
  ...spreadsheetNativeBorderRecords(normalizedRange, borderType, normalizedFormat.color, spreadsheetNativeBorderStyleByName[normalizedFormat.style])
652
727
  ];
653
- const nextSheet = {
654
- ...sheet,
655
- config: {
656
- ...sheet.config,
657
- borderInfo: borderInfo
658
- }
659
- };
660
- const sheets = [
661
- ...content.sheets
662
- ];
663
- sheets[sheetIndex] = nextSheet;
664
- return {
665
- ...content,
666
- sheets
667
- };
728
+ return contentWithSpreadsheetBorderInfo(content, sheetIndex, sheet, borderInfo);
668
729
  }
669
730
  function spreadsheetCellBordersAt(sheet, row, column) {
670
731
  const borders = {};
@@ -678,7 +739,7 @@ function spreadsheetCellBordersAt(sheet, row, column) {
678
739
  applyResolvedCellBorderLine(borders, 'right', candidate.value.r);
679
740
  applyResolvedCellBorderLine(borders, 'top', candidate.value.t);
680
741
  applyResolvedCellBorderLine(borders, 'bottom', candidate.value.b);
681
- applyResolvedCellBorderLine(borders, 'diagonal', candidate.value.s);
742
+ applyResolvedCellDiagonalBorders(borders, candidate.value);
682
743
  continue;
683
744
  }
684
745
  if ('range' !== candidate.rangeType || !isSpreadsheetNativeBorderType(candidate.borderType) || !Array.isArray(candidate.range)) continue;
@@ -690,6 +751,69 @@ function spreadsheetCellBordersAt(sheet, row, column) {
690
751
  }
691
752
  return borders;
692
753
  }
754
+ function spreadsheetRenderableDiagonalBorders(sheet) {
755
+ const borders = new Map();
756
+ const source = Array.isArray(sheet.config?.borderInfo) ? sheet.config.borderInfo : [];
757
+ for (const candidate of source){
758
+ if (!spreadsheet_cell_border_isRecord(candidate)) continue;
759
+ if ('cell' === candidate.rangeType) {
760
+ if (!spreadsheet_cell_border_isRecord(candidate.value)) continue;
761
+ const row = finiteSpreadsheetBorderIndex(candidate.value.row_index);
762
+ const column = finiteSpreadsheetBorderIndex(candidate.value.col_index);
763
+ if (null === row || null === column) continue;
764
+ const key = `${row}_${column}`;
765
+ const diagonal = spreadsheetDiagonalBorderFromCellValue(candidate.value);
766
+ if (void 0 === diagonal) continue;
767
+ if (!diagonal) {
768
+ borders.delete(key);
769
+ continue;
770
+ }
771
+ const line = resolvedCellBorderLine(diagonal.line);
772
+ if (!line) {
773
+ borders.delete(key);
774
+ continue;
775
+ }
776
+ borders.set(key, {
777
+ border: {
778
+ ...diagonal.down ? {
779
+ down: line
780
+ } : {},
781
+ ...diagonal.up ? {
782
+ up: line
783
+ } : {}
784
+ },
785
+ column,
786
+ row
787
+ });
788
+ continue;
789
+ }
790
+ if ('range' !== candidate.rangeType || 'border-none' !== candidate.borderType && 'border-slash' !== candidate.borderType || !Array.isArray(candidate.range)) continue;
791
+ const line = resolvedRangeBorderLine(candidate);
792
+ for (const rangeCandidate of candidate.range){
793
+ const range = parseSpreadsheetCellRange(rangeCandidate);
794
+ if (range) {
795
+ for (const [key, entry] of borders)if (spreadsheetCellRangeContains(range, entry.row, entry.column)) {
796
+ if ('border-none' === candidate.borderType || !entry.border.up) {
797
+ borders.delete(key);
798
+ continue;
799
+ }
800
+ borders.set(key, {
801
+ ...entry,
802
+ border: {
803
+ up: line ?? entry.border.up
804
+ }
805
+ });
806
+ }
807
+ }
808
+ }
809
+ }
810
+ return new Map([
811
+ ...borders
812
+ ].map(([key, entry])=>[
813
+ key,
814
+ entry.border
815
+ ]));
816
+ }
693
817
  function normalizeSpreadsheetBorderFormat(format) {
694
818
  if (!spreadsheetCellBorderTargets.includes(format.target) || !spreadsheetCellBorderStyles.includes(format.style)) return null;
695
819
  const color = normalizeSpreadsheetBorderColor(format.color);
@@ -716,14 +840,26 @@ function compactSpreadsheetBorderInfo(formats, range, appliedType) {
716
840
  format
717
841
  ];
718
842
  if ('cell' === format.rangeType) {
719
- if (!supersedesAll || !spreadsheet_cell_border_isRecord(format.value)) return [
843
+ if (!spreadsheet_cell_border_isRecord(format.value)) return [
720
844
  format
721
845
  ];
722
846
  const row = finiteSpreadsheetBorderIndex(format.value.row_index);
723
847
  const column = finiteSpreadsheetBorderIndex(format.value.col_index);
724
- return null !== row && null !== column && spreadsheetCellRangeContains(range, row, column) ? [] : [
848
+ const selected = null !== row && null !== column && spreadsheetCellRangeContains(range, row, column);
849
+ if (!selected) return [
725
850
  format
726
851
  ];
852
+ if (supersedesAll) return [];
853
+ if ('border-slash' !== appliedType) return [
854
+ format
855
+ ];
856
+ const value = spreadsheetCellValueWithDiagonalBorder(format.value, null);
857
+ return Object.keys(value).some((key)=>'row_index' !== key && 'col_index' !== key) ? [
858
+ {
859
+ ...format,
860
+ value
861
+ }
862
+ ] : [];
727
863
  }
728
864
  if ('range' !== format.rangeType || !isSpreadsheetNativeBorderType(format.borderType) || !Array.isArray(format.range) || !supersedesAll && format.borderType !== appliedType) return [
729
865
  format
@@ -733,9 +869,14 @@ function compactSpreadsheetBorderInfo(formats, range, appliedType) {
733
869
  if (!parsed) return [
734
870
  candidate
735
871
  ];
736
- if ('border-slash' === format.borderType) return spreadsheetCellRangesIntersect(parsed, range) ? [] : [
737
- candidate
738
- ];
872
+ if ('border-slash' === format.borderType) {
873
+ if (!spreadsheetCellRangesIntersect(parsed, range)) return [
874
+ candidate
875
+ ];
876
+ return 1 === spreadsheet_cell_range_spreadsheetCellRangeArea(parsed) ? [] : [
877
+ candidate
878
+ ];
879
+ }
739
880
  return subtractSpreadsheetCellRange(parsed, range);
740
881
  });
741
882
  return remaining.length ? [
@@ -747,7 +888,7 @@ function compactSpreadsheetBorderInfo(formats, range, appliedType) {
747
888
  });
748
889
  }
749
890
  function spreadsheetNativeBorderRecords(range, borderType, color, style) {
750
- if ('border-slash' !== borderType) return [
891
+ return [
751
892
  {
752
893
  rangeType: 'range',
753
894
  borderType,
@@ -758,28 +899,91 @@ function spreadsheetNativeBorderRecords(range, borderType, color, style) {
758
899
  ]
759
900
  }
760
901
  ];
902
+ }
903
+ function spreadsheetDiagonalBorderRecords(sheet, range, target, color, style) {
761
904
  const records = [];
762
- for(let row = range.row[0]; row <= range.row[1]; row += 1)for(let column = range.column[0]; column <= range.column[1]; column += 1)records.push({
763
- rangeType: 'range',
764
- borderType,
765
- color,
766
- style,
767
- range: [
768
- {
769
- row: [
770
- row,
771
- row
772
- ],
773
- column: [
774
- column,
775
- column
776
- ],
777
- row_focus: row,
778
- column_focus: column
905
+ const existing = spreadsheetDiagonalBorderDirectionsInRange(sheet, range);
906
+ for(let row = range.row[0]; row <= range.row[1]; row += 1)for(let column = range.column[0]; column <= range.column[1]; column += 1){
907
+ const current = existing.get(`${row}_${column}`);
908
+ const border = {
909
+ down: 'diagonalDown' === target || Boolean(current?.down),
910
+ line: {
911
+ color,
912
+ style
913
+ },
914
+ up: 'diagonalUp' === target || Boolean(current?.up)
915
+ };
916
+ records.push({
917
+ rangeType: 'cell',
918
+ value: spreadsheetCellValueWithDiagonalBorder({
919
+ col_index: column,
920
+ row_index: row
921
+ }, border)
922
+ });
923
+ }
924
+ return records;
925
+ }
926
+ function spreadsheetDiagonalBorderDirectionsInRange(sheet, selection) {
927
+ const directions = new Map();
928
+ const source = Array.isArray(sheet.config?.borderInfo) ? sheet.config.borderInfo : [];
929
+ for (const candidate of source){
930
+ if (!spreadsheet_cell_border_isRecord(candidate)) continue;
931
+ if ('cell' === candidate.rangeType) {
932
+ if (!spreadsheet_cell_border_isRecord(candidate.value)) continue;
933
+ const row = finiteSpreadsheetBorderIndex(candidate.value.row_index);
934
+ const column = finiteSpreadsheetBorderIndex(candidate.value.col_index);
935
+ if (null === row || null === column || !spreadsheetCellRangeContains(selection, row, column)) continue;
936
+ const diagonal = spreadsheetDiagonalBorderFromCellValue(candidate.value);
937
+ if (void 0 === diagonal) continue;
938
+ const line = diagonal && resolvedCellBorderLine(diagonal.line);
939
+ setSpreadsheetDiagonalDirections(directions, row, column, Boolean(line && diagonal?.down), Boolean(line && diagonal?.up));
940
+ continue;
941
+ }
942
+ if ('range' !== candidate.rangeType || 'border-none' !== candidate.borderType && 'border-slash' !== candidate.borderType || !Array.isArray(candidate.range)) continue;
943
+ const line = resolvedRangeBorderLine(candidate);
944
+ for (const rangeCandidate of candidate.range){
945
+ const range = parseSpreadsheetCellRange(rangeCandidate);
946
+ if (!range || !spreadsheetCellRangesIntersect(range, selection)) continue;
947
+ const startRow = Math.max(range.row[0], selection.row[0]);
948
+ const endRow = Math.min(range.row[1], selection.row[1]);
949
+ const startColumn = Math.max(range.column[0], selection.column[0]);
950
+ const endColumn = Math.min(range.column[1], selection.column[1]);
951
+ for(let row = startRow; row <= endRow; row += 1)for(let column = startColumn; column <= endColumn; column += 1){
952
+ if ('border-none' === candidate.borderType) {
953
+ directions.delete(`${row}_${column}`);
954
+ continue;
955
+ }
956
+ const current = directions.get(`${row}_${column}`);
957
+ setSpreadsheetDiagonalDirections(directions, row, column, Boolean(line), Boolean(current?.up));
779
958
  }
780
- ]
959
+ }
960
+ }
961
+ return directions;
962
+ }
963
+ function setSpreadsheetDiagonalDirections(directions, row, column, down, up) {
964
+ const key = `${row}_${column}`;
965
+ if (!down && !up) return void directions.delete(key);
966
+ directions.set(key, {
967
+ down,
968
+ up
781
969
  });
782
- return records;
970
+ }
971
+ function contentWithSpreadsheetBorderInfo(content, sheetIndex, sheet, borderInfo) {
972
+ const nextSheet = {
973
+ ...sheet,
974
+ config: {
975
+ ...sheet.config,
976
+ borderInfo: borderInfo
977
+ }
978
+ };
979
+ const sheets = [
980
+ ...content.sheets
981
+ ];
982
+ sheets[sheetIndex] = nextSheet;
983
+ return {
984
+ ...content,
985
+ sheets
986
+ };
783
987
  }
784
988
  function applyResolvedCellBorderLine(borders, side, value) {
785
989
  if (null === value) return void delete borders[side];
@@ -791,6 +995,26 @@ function applyResolvedCellBorderLine(borders, side, value) {
791
995
  style
792
996
  };
793
997
  }
998
+ function applyResolvedCellDiagonalBorders(borders, value) {
999
+ const diagonal = spreadsheetDiagonalBorderFromCellValue(value);
1000
+ if (void 0 === diagonal) return;
1001
+ delete borders.diagonalDown;
1002
+ delete borders.diagonalUp;
1003
+ if (!diagonal) return;
1004
+ const line = resolvedCellBorderLine(diagonal.line);
1005
+ if (!line) return;
1006
+ if (diagonal.down) borders.diagonalDown = line;
1007
+ if (diagonal.up) borders.diagonalUp = line;
1008
+ }
1009
+ function resolvedCellBorderLine(value) {
1010
+ if (!spreadsheet_cell_border_isRecord(value)) return null;
1011
+ const color = 'string' == typeof value.color ? normalizeSpreadsheetBorderColor(value.color) : null;
1012
+ const style = 'string' == typeof value.style ? value.style : null;
1013
+ return color && style ? {
1014
+ color,
1015
+ style
1016
+ } : null;
1017
+ }
794
1018
  function resolvedRangeBorderLine(value) {
795
1019
  const color = 'string' == typeof value.color ? normalizeSpreadsheetBorderColor(value.color) : null;
796
1020
  const style = 'string' == typeof value.style ? value.style : null;
@@ -826,7 +1050,8 @@ function applyResolvedRangeBorder(borders, range, row, column, type, line) {
826
1050
  delete borders.bottom;
827
1051
  delete borders.left;
828
1052
  delete borders.right;
829
- delete borders.diagonal;
1053
+ delete borders.diagonalDown;
1054
+ delete borders.diagonalUp;
830
1055
  break;
831
1056
  case 'border-all':
832
1057
  set('top');
@@ -855,10 +1080,16 @@ function applyResolvedRangeBorder(borders, range, row, column, type, line) {
855
1080
  if (!onRight) set('right');
856
1081
  break;
857
1082
  case 'border-slash':
858
- set('diagonal');
1083
+ if (line) {
1084
+ borders.diagonalDown = line;
1085
+ if (borders.diagonalUp) borders.diagonalUp = line;
1086
+ } else delete borders.diagonalDown;
859
1087
  break;
860
1088
  }
861
1089
  }
1090
+ function isSpreadsheetDiagonalBorderTarget(target) {
1091
+ return 'diagonalDown' === target || 'diagonalUp' === target;
1092
+ }
862
1093
  function isSpreadsheetNativeBorderType(value) {
863
1094
  return 'string' == typeof value && spreadsheetNativeBorderTypes.has(value);
864
1095
  }
@@ -3127,9 +3358,18 @@ const spreadsheetCommandCatalog = {
3127
3358
  group: 'font'
3128
3359
  }
3129
3360
  },
3130
- borderDiagonal: {
3131
- id: 'font.borderDiagonal',
3132
- label: '斜线框线',
3361
+ borderDiagonalDown: {
3362
+ id: 'font.borderDiagonalDown',
3363
+ label: '斜下框线',
3364
+ location: {
3365
+ area: 'ribbon',
3366
+ tab: 'home',
3367
+ group: 'font'
3368
+ }
3369
+ },
3370
+ borderDiagonalUp: {
3371
+ id: 'font.borderDiagonalUp',
3372
+ label: '斜上框线',
3133
3373
  location: {
3134
3374
  area: 'ribbon',
3135
3375
  tab: 'home',
@@ -4077,14 +4317,16 @@ const MAX_SPREADSHEET_PER_CELL_BORDER_CELLS = 10000;
4077
4317
  function setSpreadsheetCellBordersPerCell(content, sheetId, range, formats) {
4078
4318
  const normalizedRange = spreadsheet_cell_range_normalizeSpreadsheetCellRange(range);
4079
4319
  const normalizedFormats = formats.map(normalizeSpreadsheetBorderFormat);
4080
- if (!normalizedRange || spreadsheet_cell_range_spreadsheetCellRangeArea(normalizedRange) > MAX_SPREADSHEET_PER_CELL_BORDER_CELLS || normalizedFormats.some((format)=>!format || ![
4320
+ const area = normalizedRange ? spreadsheet_cell_range_spreadsheetCellRangeArea(normalizedRange) : 1 / 0;
4321
+ if (!normalizedRange || area > MAX_SPREADSHEET_PER_CELL_BORDER_CELLS || normalizedFormats.some((format)=>!format || ![
4081
4322
  'top',
4082
4323
  'bottom',
4083
4324
  'left',
4084
4325
  'right',
4085
4326
  'all',
4086
- 'diagonal'
4087
- ].includes(format.target))) return null;
4327
+ 'diagonalDown',
4328
+ 'diagonalUp'
4329
+ ].includes(format.target)) || area > 4096 && normalizedFormats.some((format)=>format?.target === 'diagonalDown' || format?.target === 'diagonalUp')) return null;
4088
4330
  const next = setSpreadsheetCellBorders(content, sheetId, normalizedRange, {
4089
4331
  target: 'none',
4090
4332
  color: '#000000',
@@ -4100,6 +4342,9 @@ function setSpreadsheetCellBordersPerCell(content, sheetId, range, formats) {
4100
4342
  row_index: row,
4101
4343
  col_index: column
4102
4344
  };
4345
+ let diagonalDown = false;
4346
+ let diagonalUp = false;
4347
+ let diagonalLine = null;
4103
4348
  for (const format of normalizedFormats){
4104
4349
  if (!format) continue;
4105
4350
  const line = {
@@ -4110,11 +4355,22 @@ function setSpreadsheetCellBordersPerCell(content, sheetId, range, formats) {
4110
4355
  if ('all' === format.target || 'right' === format.target) value.r = line;
4111
4356
  if ('all' === format.target || 'top' === format.target) value.t = line;
4112
4357
  if ('all' === format.target || 'bottom' === format.target) value.b = line;
4113
- if ('diagonal' === format.target) value.s = line;
4358
+ if ('diagonalDown' === format.target) {
4359
+ diagonalDown = true;
4360
+ diagonalLine = line;
4361
+ }
4362
+ if ('diagonalUp' === format.target) {
4363
+ diagonalUp = true;
4364
+ diagonalLine = line;
4365
+ }
4114
4366
  }
4115
4367
  records.push({
4116
4368
  rangeType: 'cell',
4117
- value
4369
+ value: diagonalLine && (diagonalDown || diagonalUp) ? spreadsheetCellValueWithDiagonalBorder(value, {
4370
+ down: diagonalDown,
4371
+ line: diagonalLine,
4372
+ up: diagonalUp
4373
+ }) : value
4118
4374
  });
4119
4375
  }
4120
4376
  const borderInfo = [
@@ -4180,8 +4436,9 @@ function canApplySpreadsheetCellFormat(content, request) {
4180
4436
  'left',
4181
4437
  'right',
4182
4438
  'all',
4183
- 'diagonal'
4184
- ].includes(format.target)) || normalized.some((format)=>format?.target === 'diagonal') && spreadsheet_cell_range_spreadsheetCellRangeArea(range) > 4096) return false;
4439
+ 'diagonalDown',
4440
+ 'diagonalUp'
4441
+ ].includes(format.target)) || normalized.some((format)=>format?.target === 'diagonalDown' || format?.target === 'diagonalUp') && spreadsheet_cell_range_spreadsheetCellRangeArea(range) > 4096) return false;
4185
4442
  }
4186
4443
  return true;
4187
4444
  }
@@ -4699,14 +4956,16 @@ function sameCellStyleBorders(actual, formats) {
4699
4956
  if ('all' === format.target || 'right' === format.target) expected.right = line;
4700
4957
  if ('all' === format.target || 'top' === format.target) expected.top = line;
4701
4958
  if ('all' === format.target || 'bottom' === format.target) expected.bottom = line;
4702
- if ('diagonal' === format.target) expected.diagonal = line;
4959
+ if ('diagonalDown' === format.target) expected.diagonalDown = line;
4960
+ if ('diagonalUp' === format.target) expected.diagonalUp = line;
4703
4961
  }
4704
4962
  return [
4705
4963
  'top',
4706
4964
  'bottom',
4707
4965
  'left',
4708
4966
  'right',
4709
- 'diagonal'
4967
+ 'diagonalDown',
4968
+ 'diagonalUp'
4710
4969
  ].every((side)=>actual[side]?.color === expected[side]?.color && actual[side]?.style === expected[side]?.style);
4711
4970
  }
4712
4971
  function createSpreadsheetCellStyleExtension() {
@@ -10195,8 +10454,12 @@ const spreadsheetBorderTargetOptions = [
10195
10454
  definition: spreadsheetCommandCatalog.borderVertical
10196
10455
  },
10197
10456
  {
10198
- target: 'diagonal',
10199
- definition: spreadsheetCommandCatalog.borderDiagonal
10457
+ target: 'diagonalDown',
10458
+ definition: spreadsheetCommandCatalog.borderDiagonalDown
10459
+ },
10460
+ {
10461
+ target: 'diagonalUp',
10462
+ definition: spreadsheetCommandCatalog.borderDiagonalUp
10200
10463
  }
10201
10464
  ];
10202
10465
  function SpreadsheetBorderRibbon({ can, commands }) {
@@ -12680,8 +12943,12 @@ const borderTargets = [
12680
12943
  label: '右框线'
12681
12944
  },
12682
12945
  {
12683
- target: 'diagonal',
12684
- label: '对角线'
12946
+ target: 'diagonalDown',
12947
+ label: '斜下框线'
12948
+ },
12949
+ {
12950
+ target: 'diagonalUp',
12951
+ label: '斜上框线'
12685
12952
  }
12686
12953
  ];
12687
12954
  function SpreadsheetFormatCellsPanel(props) {
@@ -13114,10 +13381,16 @@ function BorderPreview({ draft }) {
13114
13381
  borderRight: line('right')
13115
13382
  }
13116
13383
  }),
13117
- line('diagonal') && /*#__PURE__*/ jsx("span", {
13118
- className: "diagonal",
13384
+ line('diagonalDown') && /*#__PURE__*/ jsx("span", {
13385
+ className: "diagonal-down",
13386
+ style: {
13387
+ borderTop: line('diagonalDown')
13388
+ }
13389
+ }),
13390
+ line('diagonalUp') && /*#__PURE__*/ jsx("span", {
13391
+ className: "diagonal-up",
13119
13392
  style: {
13120
- borderTop: line('diagonal')
13393
+ borderTop: line('diagonalUp')
13121
13394
  }
13122
13395
  }),
13123
13396
  /*#__PURE__*/ jsx("strong", {
@@ -13388,7 +13661,8 @@ function borderFormatsAt(sheet, row, column) {
13388
13661
  'bottom',
13389
13662
  'left',
13390
13663
  'right',
13391
- 'diagonal'
13664
+ 'diagonalDown',
13665
+ 'diagonalUp'
13392
13666
  ].flatMap((target)=>{
13393
13667
  const line = resolved[target];
13394
13668
  if (!line) return [];
@@ -20326,20 +20600,22 @@ function applySpreadsheetPasteBorders(content, sheetId, snapshot, plan, processe
20326
20600
  [
20327
20601
  'bottom',
20328
20602
  'b'
20329
- ],
20330
- [
20331
- 'diagonal',
20332
- 's'
20333
20603
  ]
20334
20604
  ];
20335
20605
  for (const [side, key] of sides){
20336
20606
  const line = source.borders[side];
20337
20607
  if (line) value[key] = structuredClone(line);
20338
20608
  }
20339
- return Object.keys(value).length > 2 ? [
20609
+ const diagonal = source.borders.diagonalUp ?? source.borders.diagonalDown ?? null;
20610
+ const withDiagonal = diagonal ? spreadsheetCellValueWithDiagonalBorder(value, {
20611
+ down: Boolean(source.borders.diagonalDown),
20612
+ line: structuredClone(diagonal),
20613
+ up: Boolean(source.borders.diagonalUp)
20614
+ }) : value;
20615
+ return Object.keys(withDiagonal).length > 2 ? [
20340
20616
  {
20341
20617
  rangeType: 'cell',
20342
- value
20618
+ value: withDiagonal
20343
20619
  }
20344
20620
  ] : [];
20345
20621
  });
@@ -22627,6 +22903,16 @@ function SpreadsheetEditorSurface({ autoFocus = true, content, collaborationHist
22627
22903
  ]);
22628
22904
  const tableStylesBySheetRef = useRef(tableStylesBySheet);
22629
22905
  tableStylesBySheetRef.current = tableStylesBySheet;
22906
+ const diagonalBordersBySheet = useMemo(()=>new Map(materializedContent.sheets.flatMap((sheet)=>sheet.id ? [
22907
+ [
22908
+ sheet.id,
22909
+ spreadsheetRenderableDiagonalBorders(sheet)
22910
+ ]
22911
+ ] : [])), [
22912
+ materializedContent.sheets
22913
+ ]);
22914
+ const diagonalBordersBySheetRef = useRef(diagonalBordersBySheet);
22915
+ diagonalBordersBySheetRef.current = diagonalBordersBySheet;
22630
22916
  useEffect(()=>{
22631
22917
  setPreviewActiveSheetId(preview ? contentActiveSheetId : null);
22632
22918
  }, [
@@ -22758,6 +23044,9 @@ function SpreadsheetEditorSurface({ autoFocus = true, content, collaborationHist
22758
23044
  }
22759
23045
  } finally{
22760
23046
  finishSpreadsheetTableCellRender(cell, cellInfo, tableStyle, context);
23047
+ const diagonal = diagonalBordersBySheetRef.current.get(activeSheetIdRef.current)?.get(`${cellInfo.row}_${cellInfo.column}`);
23048
+ if (diagonal?.down) drawSpreadsheetDiagonalDownBorder(context, cellInfo, diagonal.down);
23049
+ if (diagonal?.up) drawSpreadsheetDiagonalUpBorder(context, cellInfo, diagonal.up);
22761
23050
  }
22762
23051
  }
22763
23052
  }), [
@@ -5,7 +5,7 @@ import { markDocxParagraphShading, inspectDocxPageSize, docxCaptionBookmark, has
5
5
  import { normalizeDocumentHref } from "./0~work-document-links.js";
6
6
  import { xmlAttributeLocalName, parseDocxParagraphDefaultCollapsed, readDocxBibliography, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, createDocxThemeResolver } from "./0~2805.js";
7
7
  import { updateSpreadsheetWorksheetCompatibilitySummary, inspectXlsxPivotTables, isSupportedXlsxChartLegend, isSupportedXlsxChartPlotLayout, xlsxChartNodeUsesStackedGrouping, isSupportedXlsxChartSeriesFormatting, readXlsxFormulaFeaturesFromPackage, inspectXlsxHeaderFooterText, emptySpreadsheetWorksheetCompatibilitySummary, xlsxChartSeriesFormattingShapeProperties, MAX_XLSX_WORKSHEET_IMAGE_BYTES, isSupportedXlsxWorksheetImageContentType, xlsxWorksheetCellEntries, diagnoseXlsxProtection, isEditableXlsxPaperSizeCode, isSupportedXlsxCombinationChartNodes } from "./4104.js";
8
- import { spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalIconSetName, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconSetCount } from "./6164.js";
8
+ import { spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalIconSetName, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconSetCount } from "./5045.js";
9
9
  import { formulaHasStructuredReference, formulaHasExternalReference, parseSpreadsheetPrintTitles, volatileSpreadsheetFormulaFunctions, stripSpreadsheetSheetQualifier } from "./8715.js";
10
10
  import { unsupportedSpreadsheetFormulaFunctions } from "./0~work-spreadsheet-formula-support.js";
11
11
  var work_office_diagnostics_namespaceObject = {};
package/dist/4104.js CHANGED
@@ -5,7 +5,7 @@ import { OFFICE_COLLABORATION_PROTOCOL as WORK_OFFICE_COLLABORATION_PROTOCOL, Of
5
5
  import { contentTypeForPart, directChildren, bytesToDataUrl, OoxmlPackage as work_ooxml_package_OoxmlPackage, parseXml, firstDescendant, xmlNamespacePrefix, descendants, directChild, createArtifact as createWorkArtifact, xmlContainsAnyElement, createOfficeId as createWorkId, attribute as work_ooxml_package_attribute } from "./5184.js";
6
6
  import { mountWorkLiveDocumentCapture, materializeWorkDocumentContent as work_document_model_codec_materializeWorkDocumentContent, documentPageSurfaceGeometryForElement, createWorkDocumentModel, documentContentLayoutProperties, documentModelForContent, createWorkDocumentExtensions, positionWorkLiveDocumentCapture } from "./6282.js";
7
7
  import { normalizeWorkSpreadsheetDataLabels, workSpreadsheetChartSupportsGrouping, normalizeSpreadsheetPrintArea, normalizeWorkSpreadsheetChartLegendPosition, formatSpreadsheetCellRanges, spreadsheetCellAddress, normalizeWorkSpreadsheetChartSmoothLines, spreadsheetFormulaRangeForCell, normalizeWorkSpreadsheetChartColor, readXlsxDrawingAnchor, sparseArrayEntries, qualifySpreadsheetRange, normalizeWorkSpreadsheetBubbleScale, normalizeWorkSpreadsheetChartSeriesStyle, normalizeSpreadsheetPrintTitleRows, normalizeSpreadsheetPrintTitleColumns, spreadsheetPivotFilterValueKey, normalizeWorkSpreadsheetErrorBars, normalizeWorkSpreadsheetBubbleSizeRepresents, workSpreadsheetChartSupportsTrendlines, stripSpreadsheetSheetQualifier, normalizeWorkSpreadsheetChartLegendOverlay, normalizeWorkSpreadsheetChartGapWidth, normalizeWorkSpreadsheetChartGrouping, workSpreadsheetChartSupportsBarSpacing, workSpreadsheetChartSupportsSmoothLines, workSpreadsheetChartGroupingIsStacked, xlsxDrawingAnchorToBounds, xlsxTwoCellAnchorMarkers, workSpreadsheetChartSupportsErrorBars, sparseMatrixColumnCount, refreshSpreadsheetPivotTables, normalizeWorkSpreadsheetChartAxisGroup, isValidSpreadsheetDefinedName, normalizeWorkSpreadsheetScatterStyle, workSpreadsheetChartAxisDefaultLabelPosition, spreadsheetPivotValidation, resolveSpreadsheetChart, parseSpreadsheetCellRanges, workSpreadsheetChartAxisIsCategoryAxis, spreadsheetPivotFields, normalizeWorkSpreadsheetDoughnutHoleSize, normalizeWorkSpreadsheetChartAxes, parseSpreadsheetPrintTitles, spreadsheetFormulaRangeConflict, spreadsheetFormulaForXlsx, editableSpreadsheetFormula, workSpreadsheetChartUsesNumericXAxis, normalizeWorkSpreadsheetChartOverlap, workSpreadsheetChartSupportsAxes, workSpreadsheetChartAxisShowsMajorGridlinesByDefault, normalizeWorkSpreadsheetCombinationSeriesType, effectiveSpreadsheetCalculationSettings, normalizeWorkSpreadsheetTrendline, normalizeWorkSpreadsheetRadarStyle } from "./8715.js";
8
- import { normalizeSpreadsheetDateValidationBoundary, freezeImportedSpreadsheetCell, editableRangeRequiresCredentials, spreadsheetTextOrientationCellStyle, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetPaperSize, spreadsheetTextOrientationXlsxValueFromCell, normalizeSheetProtectionAuthority, defaultSpreadsheetColorScaleThresholds, importedSheetProtectionAuthority, spreadsheetDateValidationFormula, spreadsheetUnderlineCellValueFromXlsx, sheetHasProtectionState, spreadsheetTextOrientationFromXlsx, spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalComparisonOperator, registerImportedSpreadsheetMatrix, spreadsheetExplicitTextOrientationFromCell, spreadsheetUnderlineStyle, defaultSpreadsheetConditionalIconThresholds, isSpreadsheetConditionalIconSetName, DEFAULT_PROTECTION_HINT, spreadsheetConditionalThresholdsEqual, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetConditionalIconSetCount } from "./6164.js";
8
+ import { freezeImportedSpreadsheetCell, normalizeSpreadsheetPaperSize, spreadsheetCellValueWithDiagonalBorder, normalizeSpreadsheetConditionalVisualOptions, spreadsheetTextOrientationXlsxValueFromCell, spreadsheetTextOrientationFromXlsx, isSpreadsheetConditionalComparisonOperator, registerImportedSpreadsheetMatrix, spreadsheetExplicitTextOrientationFromCell, normalizeSpreadsheetDateValidationBoundary, spreadsheetUnderlineStyle, defaultSpreadsheetConditionalIconThresholds, DEFAULT_PROTECTION_HINT, editableRangeRequiresCredentials, spreadsheetTextOrientationCellStyle, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, normalizeSheetProtectionAuthority, importedSheetProtectionAuthority, spreadsheetDateValidationFormula, defaultSpreadsheetColorScaleThresholds, spreadsheetDiagonalBorderFromCellValue, spreadsheetUnderlineCellValueFromXlsx, sheetHasProtectionState, spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalIconSetName, spreadsheetConditionalThresholdsEqual, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetConditionalIconSetCount } from "./5045.js";
9
9
  import { WorkFileImportController, materializeWorkFileSource } from "./9356.js";
10
10
  import "./2591.js";
11
11
  import "./3818.js";
@@ -3112,7 +3112,19 @@ function fortuneBorderInfoFromXlsxCells(entries) {
3112
3112
  setFortuneBorderLine(value, 'r', border.right);
3113
3113
  setFortuneBorderLine(value, 't', border.top);
3114
3114
  setFortuneBorderLine(value, 'b', border.bottom);
3115
- if (border.diagonal) setFortuneBorderLine(value, 's', border.diagonal);
3115
+ if (border.diagonal && (true === border.diagonalDown || true === border.diagonalUp)) {
3116
+ const line = fortuneBorderLine(border.diagonal);
3117
+ if (line) return [
3118
+ {
3119
+ rangeType: 'cell',
3120
+ value: spreadsheetCellValueWithDiagonalBorder(value, {
3121
+ down: true === border.diagonalDown,
3122
+ line,
3123
+ up: true === border.diagonalUp
3124
+ })
3125
+ }
3126
+ ];
3127
+ }
3116
3128
  return Object.keys(value).length > 2 ? [
3117
3129
  {
3118
3130
  rangeType: 'cell',
@@ -3170,11 +3182,18 @@ function applySpreadsheetCellBorderRecord(record, targets, borders) {
3170
3182
  applyCellLine(border, 'right', record.value.r);
3171
3183
  applyCellLine(border, 'top', record.value.t);
3172
3184
  applyCellLine(border, 'bottom', record.value.b);
3173
- const diagonal = xlsxCellBorderLineFromFortune(record.value.s);
3174
- if (void 0 !== diagonal) {
3175
- border.diagonal = diagonal;
3176
- border.diagonalUp = null !== diagonal;
3185
+ const diagonal = spreadsheetDiagonalBorderFromCellValue(record.value);
3186
+ if (void 0 !== diagonal) if (diagonal) {
3187
+ const line = xlsxCellBorderLineFromFortune(diagonal.line);
3188
+ if (void 0 !== line) {
3189
+ border.diagonal = line;
3190
+ border.diagonalDown = null !== line && diagonal.down;
3191
+ border.diagonalUp = null !== line && diagonal.up;
3192
+ }
3193
+ } else {
3194
+ border.diagonal = null;
3177
3195
  border.diagonalDown = false;
3196
+ border.diagonalUp = false;
3178
3197
  }
3179
3198
  borders.set(key, border);
3180
3199
  }
@@ -3240,9 +3259,10 @@ function applySpreadsheetRangeBorder(borders, target, range, borderType, line) {
3240
3259
  if (!onRight) border.right = line;
3241
3260
  break;
3242
3261
  case 'border-slash':
3243
- border.diagonal = line;
3244
- border.diagonalUp = null !== line;
3245
- border.diagonalDown = false;
3262
+ border.diagonalDown = null !== line;
3263
+ border.diagonalUp = true === border.diagonalUp;
3264
+ if (line) border.diagonal = line;
3265
+ else if (!border.diagonalUp) border.diagonal = null;
3246
3266
  break;
3247
3267
  default:
3248
3268
  return;
@@ -3285,6 +3305,13 @@ function setFortuneBorderLine(target, name, line) {
3285
3305
  style: fortuneBorderStyle(line.style)
3286
3306
  };
3287
3307
  }
3308
+ function fortuneBorderLine(line) {
3309
+ const color = normalizeRgbColor(line.color);
3310
+ return color ? {
3311
+ color,
3312
+ style: fortuneBorderStyle(line.style)
3313
+ } : null;
3314
+ }
3288
3315
  function normalizeRgbColor(value) {
3289
3316
  if ('string' != typeof value) return null;
3290
3317
  const color = value.trim().toLowerCase();
@@ -2092,6 +2092,59 @@ function isoDateFromTimestamp(timestamp) {
2092
2092
  if (!Number.isFinite(timestamp) || year < 1900 || year > 9999) return null;
2093
2093
  return `${String(year).padStart(4, '0')}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`;
2094
2094
  }
2095
+ const A3S_DIAGONAL_BORDER_KEY = 'a3sDiagonal';
2096
+ function spreadsheetDiagonalBorderFromCellValue(value) {
2097
+ if (!isRecord(value)) return;
2098
+ const metadata = value[A3S_DIAGONAL_BORDER_KEY];
2099
+ if (isRecord(metadata)) {
2100
+ const up = metadata.up;
2101
+ const down = metadata.down;
2102
+ const line = spreadsheetDiagonalBorderLine(metadata.line);
2103
+ if ('boolean' == typeof up && 'boolean' == typeof down) {
2104
+ if (!up && !down) return null;
2105
+ if (line) return {
2106
+ down,
2107
+ line,
2108
+ up
2109
+ };
2110
+ }
2111
+ }
2112
+ if (null === value.s) return null;
2113
+ const legacyLine = spreadsheetDiagonalBorderLine(value.s);
2114
+ return legacyLine ? {
2115
+ down: true,
2116
+ line: legacyLine,
2117
+ up: false
2118
+ } : void 0;
2119
+ }
2120
+ function spreadsheetCellValueWithDiagonalBorder(value, border) {
2121
+ const next = {
2122
+ ...value
2123
+ };
2124
+ delete next.s;
2125
+ delete next[A3S_DIAGONAL_BORDER_KEY];
2126
+ if (!border) return next;
2127
+ const line = {
2128
+ ...border.line
2129
+ };
2130
+ next[A3S_DIAGONAL_BORDER_KEY] = {
2131
+ down: border.down,
2132
+ line,
2133
+ up: border.up
2134
+ };
2135
+ if (border.down) next.s = line;
2136
+ return next;
2137
+ }
2138
+ function spreadsheetDiagonalBorderLine(value) {
2139
+ if (!isRecord(value)) return null;
2140
+ return 'string' == typeof value.color && 'string' == typeof value.style ? {
2141
+ color: value.color,
2142
+ style: value.style
2143
+ } : null;
2144
+ }
2145
+ function isRecord(value) {
2146
+ return Boolean(value && 'object' == typeof value && !Array.isArray(value));
2147
+ }
2095
2148
  const spreadsheetTextOrientationIds = [
2096
2149
  'horizontal',
2097
2150
  'angleCounterclockwise',
@@ -2749,4 +2802,4 @@ function boundedInteger(value, minimum, maximum, fallback) {
2749
2802
  function boundedNumber(value, minimum, maximum, fallback) {
2750
2803
  return 'number' == typeof value && Number.isFinite(value) && value >= minimum && value <= maximum ? value : fallback;
2751
2804
  }
2752
- export { DEFAULT_PROTECTION_HINT, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, SPREADSHEET_CONDITIONAL_ICON_SETS, attachSpreadsheetShownCommentCells, createWorkOfficeSpreadsheetCollaborationBinding as createOfficeSpreadsheetCollaborationBinding, defaultSpreadsheetColorScaleThresholds, defaultSpreadsheetConditionalIconThresholds, defaultSpreadsheetDataBarOptions, drawSpreadsheetConditionalIcon, editableRangeCellCount, editableRangeRequiresCredentials, effectiveSpreadsheetPageSetup, freezeImportedSpreadsheetCell, importedSheetProtectionAuthority, initializeWorkOfficeSpreadsheetCollaboration as initializeOfficeSpreadsheetCollaboration, isSpreadsheetConditionalComparisonOperator, isSpreadsheetConditionalIconSetName, isSpreadsheetTextOrientationId, isSpreadsheetUnderlineStyle, normalizeSheetProtectionAuthority, normalizeSpreadsheetConditionalIconSetFormat, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetDateValidationBoundary, normalizeSpreadsheetPaperSize, protectedSheetCount, readWorkOfficeSpreadsheetCollaboration as readOfficeSpreadsheetCollaboration, registerDerivedSpreadsheetMatrix, registerImportedSpreadsheetMatrix, replaceWorkOfficeSpreadsheetCollaboration as replaceOfficeSpreadsheetCollaboration, sameSpreadsheetHistoryValue, sheetHasProtectionState, sheetProtectionAuthority, spreadsheetConditionalComparisonNeedsUpperValue, spreadsheetConditionalIconForValue, spreadsheetConditionalIconSetCount, spreadsheetConditionalThresholdValue, spreadsheetConditionalThresholdsEqual, spreadsheetDateValidationFormula, spreadsheetExplicitTextOrientationFromCell, spreadsheetMatrixProfile, spreadsheetProtectionKey, spreadsheetTextOrientationCellStyle, spreadsheetTextOrientationChoiceFromCell, spreadsheetTextOrientationFromAngle, spreadsheetTextOrientationFromCell, spreadsheetTextOrientationFromChoice, spreadsheetTextOrientationFromXlsx, spreadsheetTextOrientationXlsxValueFromCell, spreadsheetUnderlineCellValue, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetUnderlineCellValueFromXlsx, spreadsheetUnderlineStyle, spreadsheetVisibleTextRotationFromCell, unlockedCellCount, withEditableRange, withSheetProtection, withSheetSelectionPermissions, withoutEditableRange };
2805
+ export { DEFAULT_PROTECTION_HINT, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, SPREADSHEET_CONDITIONAL_ICON_SETS, attachSpreadsheetShownCommentCells, createWorkOfficeSpreadsheetCollaborationBinding as createOfficeSpreadsheetCollaborationBinding, defaultSpreadsheetColorScaleThresholds, defaultSpreadsheetConditionalIconThresholds, defaultSpreadsheetDataBarOptions, drawSpreadsheetConditionalIcon, editableRangeCellCount, editableRangeRequiresCredentials, effectiveSpreadsheetPageSetup, freezeImportedSpreadsheetCell, importedSheetProtectionAuthority, initializeWorkOfficeSpreadsheetCollaboration as initializeOfficeSpreadsheetCollaboration, isSpreadsheetConditionalComparisonOperator, isSpreadsheetConditionalIconSetName, isSpreadsheetTextOrientationId, isSpreadsheetUnderlineStyle, normalizeSheetProtectionAuthority, normalizeSpreadsheetConditionalIconSetFormat, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetDateValidationBoundary, normalizeSpreadsheetPaperSize, protectedSheetCount, readWorkOfficeSpreadsheetCollaboration as readOfficeSpreadsheetCollaboration, registerDerivedSpreadsheetMatrix, registerImportedSpreadsheetMatrix, replaceWorkOfficeSpreadsheetCollaboration as replaceOfficeSpreadsheetCollaboration, sameSpreadsheetHistoryValue, sheetHasProtectionState, sheetProtectionAuthority, spreadsheetCellValueWithDiagonalBorder, spreadsheetConditionalComparisonNeedsUpperValue, spreadsheetConditionalIconForValue, spreadsheetConditionalIconSetCount, spreadsheetConditionalThresholdValue, spreadsheetConditionalThresholdsEqual, spreadsheetDateValidationFormula, spreadsheetDiagonalBorderFromCellValue, spreadsheetExplicitTextOrientationFromCell, spreadsheetMatrixProfile, spreadsheetProtectionKey, spreadsheetTextOrientationCellStyle, spreadsheetTextOrientationChoiceFromCell, spreadsheetTextOrientationFromAngle, spreadsheetTextOrientationFromCell, spreadsheetTextOrientationFromChoice, spreadsheetTextOrientationFromXlsx, spreadsheetTextOrientationXlsxValueFromCell, spreadsheetUnderlineCellValue, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetUnderlineCellValueFromXlsx, spreadsheetUnderlineStyle, spreadsheetVisibleTextRotationFromCell, unlockedCellCount, withEditableRange, withSheetProtection, withSheetSelectionPermissions, withoutEditableRange };
package/dist/core.js CHANGED
@@ -7,6 +7,6 @@ export { createArtifact, createOfficeId, officeTemplates } from "./5184.js";
7
7
  export { createOfficeDocumentCollaborationBinding, initializeOfficeDocumentCollaboration, officeDocumentCollaborationFragment, readOfficeDocumentCollaboration } from "./6282.js";
8
8
  export { createOfficeMarkdownCollaborationBinding, initializeOfficeMarkdownCollaboration, readOfficeMarkdownCollaboration, replaceOfficeMarkdownCollaboration } from "./2591.js";
9
9
  export { createOfficePresentationCollaborationBinding, initializeOfficePresentationCollaboration, readOfficePresentationCollaboration, replaceOfficePresentationCollaboration } from "./4560.js";
10
- export { createOfficeSpreadsheetCollaborationBinding, initializeOfficeSpreadsheetCollaboration, readOfficeSpreadsheetCollaboration, replaceOfficeSpreadsheetCollaboration } from "./6164.js";
10
+ export { createOfficeSpreadsheetCollaborationBinding, initializeOfficeSpreadsheetCollaboration, readOfficeSpreadsheetCollaboration, replaceOfficeSpreadsheetCollaboration } from "./5045.js";
11
11
  export { normalizeWorkSpreadsheetBubbleScale, normalizeWorkSpreadsheetBubbleSizeRepresents, normalizeWorkSpreadsheetChartAxisGroup, normalizeWorkSpreadsheetCombinationSeriesType, normalizeWorkSpreadsheetDataLabelPosition, normalizeWorkSpreadsheetDataLabels, normalizeWorkSpreadsheetDoughnutHoleSize, normalizeWorkSpreadsheetErrorBars, normalizeWorkSpreadsheetRadarStyle, normalizeWorkSpreadsheetScatterStyle, normalizeWorkSpreadsheetTrendline, normalizeWorkSpreadsheetTrendlineType, workSpreadsheetChartSupportsAxes, workSpreadsheetChartSupportsErrorBars, workSpreadsheetChartSupportsTrendlines, workSpreadsheetChartTypeLabel, workSpreadsheetChartUsesNumericXAxis, workSpreadsheetCombinationSeriesTypeLabel, workSpreadsheetDataLabelPositionLabel, workSpreadsheetErrorBarTypeLabel, workSpreadsheetErrorBarValueTypeLabel, workSpreadsheetTrendlineTypeLabel } from "./8715.js";
12
12
  export { core_OFFICE_COLLABORATION_VERSION as OFFICE_COLLABORATION_VERSION };
package/dist/index.js CHANGED
@@ -10,6 +10,6 @@ export { createArtifact, createOfficeId, officeTemplates } from "./5184.js";
10
10
  export { createOfficeDocumentCollaborationBinding, initializeOfficeDocumentCollaboration, officeDocumentCollaborationFragment, readOfficeDocumentCollaboration } from "./6282.js";
11
11
  export { createOfficeMarkdownCollaborationBinding, initializeOfficeMarkdownCollaboration, readOfficeMarkdownCollaboration, replaceOfficeMarkdownCollaboration } from "./2591.js";
12
12
  export { createOfficePresentationCollaborationBinding, initializeOfficePresentationCollaboration, readOfficePresentationCollaboration, replaceOfficePresentationCollaboration } from "./4560.js";
13
- export { createOfficeSpreadsheetCollaborationBinding, initializeOfficeSpreadsheetCollaboration, readOfficeSpreadsheetCollaboration, replaceOfficeSpreadsheetCollaboration } from "./6164.js";
13
+ export { createOfficeSpreadsheetCollaborationBinding, initializeOfficeSpreadsheetCollaboration, readOfficeSpreadsheetCollaboration, replaceOfficeSpreadsheetCollaboration } from "./5045.js";
14
14
  export { normalizeWorkSpreadsheetBubbleScale, normalizeWorkSpreadsheetBubbleSizeRepresents, normalizeWorkSpreadsheetChartAxisGroup, normalizeWorkSpreadsheetCombinationSeriesType, normalizeWorkSpreadsheetDataLabelPosition, normalizeWorkSpreadsheetDataLabels, normalizeWorkSpreadsheetDoughnutHoleSize, normalizeWorkSpreadsheetErrorBars, normalizeWorkSpreadsheetRadarStyle, normalizeWorkSpreadsheetScatterStyle, normalizeWorkSpreadsheetTrendline, normalizeWorkSpreadsheetTrendlineType, workSpreadsheetChartSupportsAxes, workSpreadsheetChartSupportsErrorBars, workSpreadsheetChartSupportsTrendlines, workSpreadsheetChartTypeLabel, workSpreadsheetChartUsesNumericXAxis, workSpreadsheetCombinationSeriesTypeLabel, workSpreadsheetDataLabelPositionLabel, workSpreadsheetErrorBarTypeLabel, workSpreadsheetErrorBarValueTypeLabel, workSpreadsheetTrendlineTypeLabel } from "./8715.js";
15
15
  export { src_DOCUMENT_SNAPSHOT_VERSION as DOCUMENT_SNAPSHOT_VERSION, src_DOCUMENT_SOURCE_VERSION as DOCUMENT_SOURCE_VERSION, src_OFFICE_COLLABORATION_VERSION as OFFICE_COLLABORATION_VERSION };
@@ -1,6 +1,6 @@
1
1
  import type { WorkSpreadsheetContent, WorkSpreadsheetSheet } from '../work-types';
2
2
  import { type SpreadsheetCellRangeInput } from './spreadsheet-cell-range';
3
- export declare const spreadsheetCellBorderTargets: readonly ["top", "bottom", "left", "right", "none", "all", "outside", "inside", "horizontal", "vertical", "diagonal"];
3
+ export declare const spreadsheetCellBorderTargets: readonly ["top", "bottom", "left", "right", "none", "all", "outside", "inside", "horizontal", "vertical", "diagonalDown", "diagonalUp"];
4
4
  export type SpreadsheetCellBorderTarget = (typeof spreadsheetCellBorderTargets)[number];
5
5
  export declare const spreadsheetCellBorderStyles: readonly ["thin", "dotted", "dashed", "dash-dot", "dash-dot-dot", "medium", "medium-dashed", "medium-dash-dot", "medium-dash-dot-dot", "thick"];
6
6
  export type SpreadsheetCellBorderStyle = (typeof spreadsheetCellBorderStyles)[number];
@@ -15,14 +15,20 @@ export interface SpreadsheetResolvedCellBorderLine {
15
15
  }
16
16
  export interface SpreadsheetResolvedCellBorders {
17
17
  bottom?: SpreadsheetResolvedCellBorderLine;
18
- diagonal?: SpreadsheetResolvedCellBorderLine;
18
+ diagonalDown?: SpreadsheetResolvedCellBorderLine;
19
+ diagonalUp?: SpreadsheetResolvedCellBorderLine;
19
20
  left?: SpreadsheetResolvedCellBorderLine;
20
21
  right?: SpreadsheetResolvedCellBorderLine;
21
22
  top?: SpreadsheetResolvedCellBorderLine;
22
23
  }
24
+ export interface SpreadsheetRenderableDiagonalBorders {
25
+ down?: SpreadsheetResolvedCellBorderLine;
26
+ up?: SpreadsheetResolvedCellBorderLine;
27
+ }
23
28
  export declare const MAX_SPREADSHEET_DIAGONAL_BORDER_CELLS = 4096;
24
29
  export declare function spreadsheetNativeBorderStyle(style: SpreadsheetCellBorderStyle): string;
25
30
  export declare function canSetSpreadsheetCellBorders(content: WorkSpreadsheetContent, sheetId: string, range: SpreadsheetCellRangeInput, format: SpreadsheetCellBorderFormat): boolean;
26
31
  export declare function setSpreadsheetCellBorders(content: WorkSpreadsheetContent, sheetId: string, range: SpreadsheetCellRangeInput, format: SpreadsheetCellBorderFormat): WorkSpreadsheetContent | null;
27
32
  export declare function spreadsheetCellBordersAt(sheet: WorkSpreadsheetSheet | undefined, row: number, column: number): SpreadsheetResolvedCellBorders;
33
+ export declare function spreadsheetRenderableDiagonalBorders(sheet: WorkSpreadsheetSheet): ReadonlyMap<string, SpreadsheetRenderableDiagonalBorders>;
28
34
  export declare function normalizeSpreadsheetBorderFormat(format: SpreadsheetCellBorderFormat): SpreadsheetCellBorderFormat | null;
@@ -478,9 +478,18 @@ export declare const spreadsheetCommandCatalog: {
478
478
  readonly group: "font";
479
479
  };
480
480
  };
481
- readonly borderDiagonal: {
482
- readonly id: "font.borderDiagonal";
483
- readonly label: "斜线框线";
481
+ readonly borderDiagonalDown: {
482
+ readonly id: "font.borderDiagonalDown";
483
+ readonly label: "斜下框线";
484
+ readonly location: {
485
+ readonly area: "ribbon";
486
+ readonly tab: "home";
487
+ readonly group: "font";
488
+ };
489
+ };
490
+ readonly borderDiagonalUp: {
491
+ readonly id: "font.borderDiagonalUp";
492
+ readonly label: "斜上框线";
484
493
  readonly location: {
485
494
  readonly area: "ribbon";
486
495
  readonly tab: "home";
@@ -0,0 +1,12 @@
1
+ export interface SpreadsheetDiagonalBorderBounds {
2
+ endX: number;
3
+ endY: number;
4
+ startX: number;
5
+ startY: number;
6
+ }
7
+ export interface SpreadsheetDiagonalCanvasLine {
8
+ color: string;
9
+ style: string;
10
+ }
11
+ export declare function drawSpreadsheetDiagonalDownBorder(context: CanvasRenderingContext2D, bounds: SpreadsheetDiagonalBorderBounds, line: SpreadsheetDiagonalCanvasLine): void;
12
+ export declare function drawSpreadsheetDiagonalUpBorder(context: CanvasRenderingContext2D, bounds: SpreadsheetDiagonalBorderBounds, line: SpreadsheetDiagonalCanvasLine): void;
@@ -0,0 +1,13 @@
1
+ export interface WorkSpreadsheetDiagonalBorderLine {
2
+ color: string;
3
+ style: string;
4
+ }
5
+ export interface WorkSpreadsheetDiagonalBorder {
6
+ down: boolean;
7
+ line: WorkSpreadsheetDiagonalBorderLine;
8
+ up: boolean;
9
+ }
10
+ type UnknownRecord = Record<string, unknown>;
11
+ export declare function spreadsheetDiagonalBorderFromCellValue(value: unknown): WorkSpreadsheetDiagonalBorder | null | undefined;
12
+ export declare function spreadsheetCellValueWithDiagonalBorder(value: UnknownRecord, border: WorkSpreadsheetDiagonalBorder | null): UnknownRecord;
13
+ export {};
Binary file
package/dist/styles.css CHANGED
@@ -15513,7 +15513,7 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
15513
15513
  border-style: dashed;
15514
15514
  }
15515
15515
 
15516
- .work-spreadsheet-border-glyph[data-border-target="none"]:before, .work-spreadsheet-border-glyph[data-border-target="diagonal"]:before {
15516
+ .work-spreadsheet-border-glyph[data-border-target="none"]:before, .work-spreadsheet-border-glyph[data-border-target="diagonal-up"]:before, .work-spreadsheet-border-glyph[data-border-target="diagonalUp"]:before {
15517
15517
  border-top: 1px solid;
15518
15518
  top: 7px;
15519
15519
  left: -1px;
@@ -15521,7 +15521,7 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
15521
15521
  transform: rotate(-45deg);
15522
15522
  }
15523
15523
 
15524
- .work-spreadsheet-border-glyph[data-border-target="none"]:after {
15524
+ .work-spreadsheet-border-glyph[data-border-target="diagonal-down"]:before, .work-spreadsheet-border-glyph[data-border-target="diagonalDown"]:before, .work-spreadsheet-border-glyph[data-border-target="none"]:after {
15525
15525
  border-top: 1px solid;
15526
15526
  top: 7px;
15527
15527
  left: -1px;
@@ -16041,13 +16041,20 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
16041
16041
  border-right: 2px solid;
16042
16042
  }
16043
16043
 
16044
- .work-spreadsheet-border-edge.diagonal > span:after {
16044
+ .work-spreadsheet-border-edge.diagonalDown > span:after, .work-spreadsheet-border-edge.diagonalUp > span:after {
16045
16045
  content: "";
16046
16046
  border-top: 2px solid;
16047
16047
  width: 20px;
16048
16048
  position: absolute;
16049
16049
  top: 8px;
16050
16050
  left: -2px;
16051
+ }
16052
+
16053
+ .work-spreadsheet-border-edge.diagonalDown > span:after {
16054
+ transform: rotate(45deg);
16055
+ }
16056
+
16057
+ .work-spreadsheet-border-edge.diagonalUp > span:after {
16051
16058
  transform: rotate(-45deg);
16052
16059
  }
16053
16060
 
@@ -16068,8 +16075,15 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
16068
16075
  inset: 10px;
16069
16076
  }
16070
16077
 
16071
- .work-spreadsheet-format-cells-border-preview > .diagonal {
16078
+ .work-spreadsheet-format-cells-border-preview > .diagonal-down, .work-spreadsheet-format-cells-border-preview > .diagonal-up {
16072
16079
  inset: 50% 5%;
16080
+ }
16081
+
16082
+ .work-spreadsheet-format-cells-border-preview > .diagonal-down {
16083
+ transform: rotate(26deg);
16084
+ }
16085
+
16086
+ .work-spreadsheet-format-cells-border-preview > .diagonal-up {
16073
16087
  transform: rotate(-26deg);
16074
16088
  }
16075
16089
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a3s-lab/office",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "Open-source collaborative browser editors for documents, Markdown, spreadsheets, presentations, and PDFs.",
5
5
  "keywords": [
6
6
  "office",
@@ -88,6 +88,7 @@
88
88
  "playground:typecheck": "tsc --noEmit -p playground/tsconfig.json",
89
89
  "playground:visual": "playwright test --config playwright.config.ts",
90
90
  "playground:visual:spreadsheet-data-validation": "playwright test visual-tests/spreadsheet-data-validation.functional.spec.ts --config playwright.config.ts",
91
+ "playground:visual:spreadsheet-diagonal-borders": "playwright test visual-tests/spreadsheet-diagonal-borders.functional.spec.ts --config playwright.config.ts",
91
92
  "playground:visual:spreadsheet-font-colors-shortcuts": "playwright test visual-tests/spreadsheet-font-colors-shortcuts.functional.spec.ts --config playwright.config.ts",
92
93
  "playground:visual:spreadsheet-hyperlink": "playwright test visual-tests/spreadsheet-hyperlink.functional.spec.ts --config playwright.config.ts",
93
94
  "playground:visual:spreadsheet-ribbon": "playwright test visual-tests/spreadsheet-ribbon.functional.spec.ts --config playwright.config.ts",
@@ -157,6 +158,8 @@
157
158
  "test:e2e:spreadsheet-go-to:check": "a3s-test check tests/e2e/spreadsheet-go-to.acl --json",
158
159
  "test:e2e:spreadsheet-data-validation": "a3s-test run tests/e2e/spreadsheet-data-validation.acl --json",
159
160
  "test:e2e:spreadsheet-data-validation:check": "a3s-test check tests/e2e/spreadsheet-data-validation.acl --json",
161
+ "test:e2e:spreadsheet-diagonal-borders": "a3s-test run tests/e2e/spreadsheet-diagonal-borders.acl --json",
162
+ "test:e2e:spreadsheet-diagonal-borders:check": "a3s-test check tests/e2e/spreadsheet-diagonal-borders.acl --json",
160
163
  "test:e2e:spreadsheet-hyperlink": "a3s-test run tests/e2e/spreadsheet-hyperlink.acl --json",
161
164
  "test:e2e:spreadsheet-hyperlink:check": "a3s-test check tests/e2e/spreadsheet-hyperlink.acl --json",
162
165
  "test:e2e:spreadsheet-maximum-sparse": "a3s-test run tests/e2e/spreadsheet-maximum-sparse.acl --json",