@a3s-lab/office 0.20.0 → 0.22.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.
@@ -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;
@@ -364,6 +364,34 @@ export declare const spreadsheetCommandCatalog: {
364
364
  readonly group: "number";
365
365
  };
366
366
  };
367
+ readonly insertCurrentDate: {
368
+ readonly id: "number.insertCurrentDate";
369
+ readonly label: "插入当前日期";
370
+ readonly location: {
371
+ readonly area: "ribbon";
372
+ readonly tab: "home";
373
+ readonly group: "number";
374
+ };
375
+ readonly shortcut: {
376
+ readonly label: "Ctrl+;";
377
+ readonly aria: "Control+;";
378
+ readonly editor: readonly ["Control-;"];
379
+ };
380
+ };
381
+ readonly insertCurrentTime: {
382
+ readonly id: "number.insertCurrentTime";
383
+ readonly label: "插入当前时间";
384
+ readonly location: {
385
+ readonly area: "ribbon";
386
+ readonly tab: "home";
387
+ readonly group: "number";
388
+ };
389
+ readonly shortcut: {
390
+ readonly label: "Ctrl+Shift+;";
391
+ readonly aria: "Control+Shift+;";
392
+ readonly editor: readonly ["Control-Shift-;"];
393
+ };
394
+ };
367
395
  readonly formatCells: {
368
396
  readonly id: "number.formatCells";
369
397
  readonly label: "设置单元格格式";
@@ -478,9 +506,18 @@ export declare const spreadsheetCommandCatalog: {
478
506
  readonly group: "font";
479
507
  };
480
508
  };
481
- readonly borderDiagonal: {
482
- readonly id: "font.borderDiagonal";
483
- readonly label: "斜线框线";
509
+ readonly borderDiagonalDown: {
510
+ readonly id: "font.borderDiagonalDown";
511
+ readonly label: "斜下框线";
512
+ readonly location: {
513
+ readonly area: "ribbon";
514
+ readonly tab: "home";
515
+ readonly group: "font";
516
+ };
517
+ };
518
+ readonly borderDiagonalUp: {
519
+ readonly id: "font.borderDiagonalUp";
520
+ readonly label: "斜上框线";
484
521
  readonly location: {
485
522
  readonly area: "ribbon";
486
523
  readonly tab: "home";
@@ -11,6 +11,7 @@ import type { SpreadsheetCellRange } from './spreadsheet-cell-range';
11
11
  import type { SpreadsheetCellStyleChoice } from './spreadsheet-cell-style';
12
12
  import type { SpreadsheetCellFillDirection } from './spreadsheet-cell-fill';
13
13
  import { type SpreadsheetFontSizeDirection } from './spreadsheet-font-size-command';
14
+ import { type SpreadsheetDateTimeKind } from './spreadsheet-date-time-command';
14
15
  import type { SpreadsheetDataValidationRequest, SpreadsheetDataValidationTarget } from './spreadsheet-data-validation';
15
16
  import { type SpreadsheetCellMergeCommand } from './spreadsheet-cell-merge';
16
17
  import type { SpreadsheetFormatPainterMode } from './spreadsheet-format-painter';
@@ -169,6 +170,7 @@ export interface SpreadsheetEditorCommands {
169
170
  fillSelectedCells: (direction: SpreadsheetCellFillDirection) => boolean;
170
171
  hideSheet: (sheetId: string) => boolean;
171
172
  insertSelectedStructure: (axis: SpreadsheetStructureAxis, position: SpreadsheetStructureInsertPosition) => boolean;
173
+ insertCurrentDateTime: (kind: SpreadsheetDateTimeKind) => boolean;
172
174
  mergeSelectedCells: (command: SpreadsheetCellMergeCommand) => boolean;
173
175
  moveSheet: (sheetId: string, direction: SpreadsheetSheetMoveDirection) => boolean;
174
176
  moveSelection: (move: SpreadsheetSelectionMove, extend: boolean) => boolean;
@@ -0,0 +1,14 @@
1
+ import type { Cell } from '@fortune-sheet/core';
2
+ import type { SpreadsheetCommandContext, SpreadsheetEditorCommands } from './spreadsheet-command-controller';
3
+ import { type OfficeEditorExtension } from './office-editor-extension';
4
+ export type SpreadsheetDateTimeKind = 'date' | 'time';
5
+ export interface SpreadsheetDateTimeEntry {
6
+ format: NonNullable<Cell['ct']> & {
7
+ fa: string;
8
+ t: string;
9
+ };
10
+ formulaBarValue: string;
11
+ value: number;
12
+ }
13
+ export declare function spreadsheetDateTimeEntry(kind: SpreadsheetDateTimeKind, now: Date): SpreadsheetDateTimeEntry | null;
14
+ export declare function createSpreadsheetDateTimeExtension(): OfficeEditorExtension<SpreadsheetCommandContext, SpreadsheetEditorCommands>;
@@ -0,0 +1,8 @@
1
+ import type { SpreadsheetEditorCanCommands, SpreadsheetEditorCommands } from './spreadsheet-command-controller';
2
+ type SpreadsheetDateTimeCanCommands = Pick<SpreadsheetEditorCanCommands, 'insertCurrentDateTime'>;
3
+ type SpreadsheetDateTimeCommands = Pick<SpreadsheetEditorCommands, 'insertCurrentDateTime'>;
4
+ export declare function SpreadsheetDateTimeMenu({ can, commands, }: {
5
+ can: SpreadsheetDateTimeCanCommands;
6
+ commands: SpreadsheetDateTimeCommands;
7
+ }): import("react").JSX.Element;
8
+ export {};
@@ -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
@@ -13885,6 +13885,41 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
13885
13885
  min-width: 94px;
13886
13886
  }
13887
13887
 
13888
+ .work-spreadsheet-number-format-stack {
13889
+ flex-direction: column;
13890
+ flex: 0 0 94px;
13891
+ gap: 2px;
13892
+ width: 94px;
13893
+ height: 51px;
13894
+ display: flex;
13895
+ }
13896
+
13897
+ .work-spreadsheet-number-format-stack > .work-spreadsheet-ribbon-menu-root {
13898
+ width: 94px;
13899
+ min-width: 0;
13900
+ }
13901
+
13902
+ .work-office-ribbon .work-office-toolbar .work-spreadsheet-number-format-stack .work-spreadsheet-date-time-trigger.with-label {
13903
+ flex-direction: row;
13904
+ justify-content: flex-start;
13905
+ gap: 4px;
13906
+ width: 94px;
13907
+ min-width: 94px;
13908
+ height: 21px;
13909
+ padding: 0 6px;
13910
+ }
13911
+
13912
+ .work-office-ribbon .work-office-toolbar .work-spreadsheet-number-format-stack .work-spreadsheet-date-time-trigger.with-label > svg {
13913
+ width: 14px;
13914
+ height: 14px;
13915
+ }
13916
+
13917
+ .work-office-ribbon .work-office-toolbar .work-spreadsheet-number-format-stack .work-spreadsheet-date-time-trigger.with-label > span {
13918
+ max-width: 66px;
13919
+ font-size: 9px;
13920
+ line-height: 11px;
13921
+ }
13922
+
13888
13923
  .work-spreadsheet-workbook-panel {
13889
13924
  z-index: 8;
13890
13925
  border-left: 1px solid var(--a3s-line);
@@ -15513,7 +15548,7 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
15513
15548
  border-style: dashed;
15514
15549
  }
15515
15550
 
15516
- .work-spreadsheet-border-glyph[data-border-target="none"]:before, .work-spreadsheet-border-glyph[data-border-target="diagonal"]:before {
15551
+ .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
15552
  border-top: 1px solid;
15518
15553
  top: 7px;
15519
15554
  left: -1px;
@@ -15521,7 +15556,7 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
15521
15556
  transform: rotate(-45deg);
15522
15557
  }
15523
15558
 
15524
- .work-spreadsheet-border-glyph[data-border-target="none"]:after {
15559
+ .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
15560
  border-top: 1px solid;
15526
15561
  top: 7px;
15527
15562
  left: -1px;
@@ -16041,13 +16076,20 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
16041
16076
  border-right: 2px solid;
16042
16077
  }
16043
16078
 
16044
- .work-spreadsheet-border-edge.diagonal > span:after {
16079
+ .work-spreadsheet-border-edge.diagonalDown > span:after, .work-spreadsheet-border-edge.diagonalUp > span:after {
16045
16080
  content: "";
16046
16081
  border-top: 2px solid;
16047
16082
  width: 20px;
16048
16083
  position: absolute;
16049
16084
  top: 8px;
16050
16085
  left: -2px;
16086
+ }
16087
+
16088
+ .work-spreadsheet-border-edge.diagonalDown > span:after {
16089
+ transform: rotate(45deg);
16090
+ }
16091
+
16092
+ .work-spreadsheet-border-edge.diagonalUp > span:after {
16051
16093
  transform: rotate(-45deg);
16052
16094
  }
16053
16095
 
@@ -16068,8 +16110,15 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
16068
16110
  inset: 10px;
16069
16111
  }
16070
16112
 
16071
- .work-spreadsheet-format-cells-border-preview > .diagonal {
16113
+ .work-spreadsheet-format-cells-border-preview > .diagonal-down, .work-spreadsheet-format-cells-border-preview > .diagonal-up {
16072
16114
  inset: 50% 5%;
16115
+ }
16116
+
16117
+ .work-spreadsheet-format-cells-border-preview > .diagonal-down {
16118
+ transform: rotate(26deg);
16119
+ }
16120
+
16121
+ .work-spreadsheet-format-cells-border-preview > .diagonal-up {
16073
16122
  transform: rotate(-26deg);
16074
16123
  }
16075
16124
 
@@ -47,17 +47,17 @@ model:
47
47
  and compacts low-priority, then normal-priority groups before exposing group
48
48
  paging. It can remain collapsed; activating a tab temporarily overlays that
49
49
  tab's commands without moving the document, and an outside pointer action
50
- returns to the compact row. Writer routes its catalogued WPS font-size,
50
+ returns to the compact row. Writer routes its catalogued Traditional Office font-size,
51
51
  alignment, line-spacing, heading, spelling, field-refresh, comment, and
52
52
  track-changes shortcuts only while the document surface owns the event. The
53
- status route uses the same catalog for WPS word count, opening live page,
53
+ status route uses the same catalog for Traditional Office word count, opening live page,
54
54
  word, character, and paragraph details from either `Ctrl+Shift+G` or the
55
- visible count. Its local formatting clipboard powers WPS copy-format and
55
+ visible count. Its local formatting clipboard powers Traditional Office copy-format and
56
56
  paste-format shortcuts
57
57
  plus a one-shot format painter without requiring browser clipboard access;
58
58
  paste replaces only direct character and paragraph formatting, preserving
59
59
  links, comments, and revision semantics in one document transaction.
60
- Header and footer TipTap surfaces register the same WPS alignment and
60
+ Header and footer TipTap surfaces register the same Traditional Office alignment and
61
61
  copy-format shortcuts. Cross-surface paste retains compatible marks and
62
62
  paragraph attributes while falling back from unsupported heading nodes.
63
63
  Writer orders Insert commands as Pages, Table, Illustrations, Links, Header
@@ -105,11 +105,11 @@ model:
105
105
  page metrics and scroll viewport. Picture, Table, and Header and Footer tabs
106
106
  carry explicit contextual semantics and disappear with their selection. The
107
107
  Spreadsheet shell now uses the same responsive ribbon contract with its own
108
- command catalog and workbook semantics. It keeps the WPS tab order, places
108
+ command catalog and workbook semantics. It keeps the Traditional Office tab order, places
109
109
  Conditional Formatting under Home and Styles, exposes real sorting under
110
110
  Data, and owns F9 workbook recalculation in the root-scoped keyboard
111
111
  controller. Paste, Cut, and Copy live in the first Home group; both button
112
- clicks and WPS shortcuts cross one clipboard command port before using the
112
+ clicks and Traditional Office shortcuts cross one clipboard command port before using the
113
113
  permission-resilient browser/local clipboard implementation. Paste Special
114
114
  extends that port with a versioned rich snapshot and a pure bounded planner
115
115
  instead of delegating mutation to rendered vendor controls. Quick All,
@@ -136,7 +136,7 @@ model:
136
136
  `Alt+ArrowDown`. The Fortune adapter only exposes the header trigger and
137
137
  value menu, adding dialog, checkbox, focus-restoration, and keyboard
138
138
  semantics without making vendor DOM text the command contract. Freeze Panes
139
- also stays controlled: a pure model translates the current WPS cell into
139
+ also stays controlled: a pure model translates the current Traditional Office cell into
140
140
  rows above and columns left or applies top-row and first-column presets, a
141
141
  typed View command performs one immutable workbook update, and the native
142
142
  Fortune/XLSX frozen-pane model remains the render and serialization
@@ -300,7 +300,7 @@ focus restoration.
300
300
  | --- | --- | --- | --- |
301
301
  | Document | One TipTap/ProseMirror body tree retained across editing and read-only preview, controlled TipTap header/footer surfaces with direct paper-margin editing and a contextual ribbon, one typography and page-chrome baseline across editing, preview, and PDF surfaces, a persistent typed heading-navigation pane with active-selection tracking, filtering and collapsible keyboard traversal, host-owned selected-text menus with full document context and range-mapped async commands, responsive and keyboard-operated paragraph-style and list galleries, typed bullet and numbering commands with restart/continue/start controls, typed physical-page and section-page descriptors, repeated first/default/even page chrome, a versioned structured model with an HTML compatibility representation, prefix-reused visual-line measurement and pages, page decorations, page-aware horizontal and vertical rulers for page margins, paragraph indents and typed tab stops, structured list-item pagination, explicit paragraph and list-item direction, compact spacing and pagination controls, typed inline/square/tight/through/top-and-bottom/no-wrap image layout and floating-image drawing layers, imported style-inherited paragraph properties, structured inline tabs, and theme-aware run font/size/color/background import | Worker plus resumable Rust/WASM flow pagination and Rustybuzz shaping across CSS-matched registered text runs; the same live result remains mounted in read-only preview and is consumed by bounded browser PDF capture, including eligible list paragraphs, Unicode bidi level segmentation, ordered per-grapheme font fallback, packaged Latin/CJK/Arabic/Hebrew faces, and structured left-to-right tabs, with explicit DOM and JavaScript fallbacks for text affected by supported floats | Language-complete font substitution, complete Word style and numbering coverage, locale-complete and bidirectional tabs, arbitrary floating-object geometry and non-image drawing layers, complex table flow, searchable/vector PDF output, and loss-preserving OOXML package state |
302
302
  | Markdown | TipTap visual editing with a resizable source-and-preview split view by default, source-aware ribbon formatting and shortcuts, bounded source-native history with coalesced typing and selection restoration, host-defined selection menus across both editing surfaces, GFM tables, strikethrough, autolinks and nested task lists, controlled source state, coalesced preview rebuilds, proportional pane scrolling, keyboard-adjustable pane sizing, a flat measure-bounded reading surface, optional visual or source-only views, and a full-workspace Source/Preview switch on phones | No kernel required for normal editing | CommonMark differential fixtures, multi-megabyte profiling, and an off-main-thread parser boundary when measurements justify it |
303
- | Spreadsheet | Fortune Sheet grid integrated with the shared Office shell, a WPS-oriented command catalog and tab order, quick-access Undo and Redo, a priority-aware adaptive and collapsible ribbon with temporary tab expansion, Home and Styles Conditional Formatting, Home and Cells row/column insertion and deletion through the shared typed structure commands, Home and Alignment Merge and Center plus Merge Cells, Merge Across, Unmerge Cells, and Unmerge and Fill through one native-model-backed controlled batch per intent and the WPS `Ctrl+M` shortcut, Home and Font native strikethrough through the same typed formatting command and WPS `Cmd/Ctrl+5`, Home and Editing Clear All, Formats, Contents, Comments, and Hyperlinks with Delete/Backspace mapped to content-only clearing and merge geometry retained, Data sorting and AutoFilter with bounded current-region discovery, controlled filter state, WPS toggle and header-menu shortcuts, and accessible vendor menu semantics, View and Window Freeze Panes with WPS current-cell, top-row, first-column, and unfreeze patterns backed by controlled state and native XLSX frozen panes, Formulas and F9 workbook recalculation, an executable Home clipboard group with permission-resilient Paste, Cut, and Copy plus a WPS-style one-shot and locked Format Painter for bounded cross-sheet native-style patterns, shared grid/formula/footer visual tokens and one spreadsheet accent across selection, sheet tabs, menus, and zoom, an A3S-owned accessible single-row workbook footer for creation, activation, rename, duplicate, color, hide, reorder, delete, selection status, and zoom, a resize-observed worksheet viewport that keeps the active tab and its touch action visible across desktop, compact, and phone-width changes, one cell/worksheet context-menu surface whose displayed accelerators remain executable while the menu owns focus, Arrow/Home/End tab navigation plus Shift+F10 and native context-menu access, typed editing and calculation command ports, A3S-owned deterministic Arrow, Enter, Tab, Home, PageUp/PageDown, extended-selection, row, column, and all-cells keyboard commands, selection-preserving focus restoration across controlled workbook remounts and F2/Escape editing transitions, Cmd/Ctrl formatting, undo/redo, clear, a permission-resilient editor-local clipboard fallback, Shift+F11 sheet creation, and Ctrl/Cmd+PageUp/PageDown sheet-navigation shortcuts, direct font-family, horizontal/vertical-alignment, text-wrap, general/number/percent, and decimal-place controls backed by native cell-style keys, live count/sum/average selection summaries, operation-driven sparse-workbook projection, guarded controlled-value remounts that reject stale engine callbacks, and no-history result patches with cell-scoped Fortune fallback | Versioned, cancellable Worker/Rust-WASM calculation sessions using the shared bounded Rust formula parser, retained formula ASTs, incremental forward/reverse dependency graphs, dirty-subgraph recalculation, cross-sheet references, and a dynamically loaded JavaScript fallback | A3S-owned virtual grid, moving replacement projection off the main thread, broader Excel formula semantics, A3S-owned custom number-format evaluation, and print layout |
303
+ | Spreadsheet | Fortune Sheet grid integrated with the shared Office shell, an Office-oriented command catalog and tab order, quick-access Undo and Redo, a priority-aware adaptive and collapsible ribbon with temporary tab expansion, Home and Styles Conditional Formatting, Home and Cells row/column insertion and deletion through the shared typed structure commands, Home and Alignment Merge and Center plus Merge Cells, Merge Across, Unmerge Cells, and Unmerge and Fill through one native-model-backed controlled batch per intent and the Traditional Office `Ctrl+M` shortcut, Home and Font native strikethrough through the same typed formatting command and Traditional Office `Cmd/Ctrl+5`, Home and Editing Clear All, Formats, Contents, Comments, and Hyperlinks with Delete/Backspace mapped to content-only clearing and merge geometry retained, Data sorting and AutoFilter with bounded current-region discovery, controlled filter state, Traditional Office toggle and header-menu shortcuts, and accessible vendor menu semantics, View and Window Freeze Panes with Traditional Office current-cell, top-row, first-column, and unfreeze patterns backed by controlled state and native XLSX frozen panes, Formulas and F9 workbook recalculation, an executable Home clipboard group with permission-resilient Paste, Cut, and Copy plus an Office-style one-shot and locked Format Painter for bounded cross-sheet native-style patterns, shared grid/formula/footer visual tokens and one spreadsheet accent across selection, sheet tabs, menus, and zoom, an A3S-owned accessible single-row workbook footer for creation, activation, rename, duplicate, color, hide, reorder, delete, selection status, and zoom, a resize-observed worksheet viewport that keeps the active tab and its touch action visible across desktop, compact, and phone-width changes, one cell/worksheet context-menu surface whose displayed accelerators remain executable while the menu owns focus, Arrow/Home/End tab navigation plus Shift+F10 and native context-menu access, typed editing and calculation command ports, A3S-owned deterministic Arrow, Enter, Tab, Home, PageUp/PageDown, extended-selection, row, column, and all-cells keyboard commands, selection-preserving focus restoration across controlled workbook remounts and F2/Escape editing transitions, Cmd/Ctrl formatting, undo/redo, clear, a permission-resilient editor-local clipboard fallback, Shift+F11 sheet creation, and Ctrl/Cmd+PageUp/PageDown sheet-navigation shortcuts, direct font-family, horizontal/vertical-alignment, text-wrap, general/number/percent, and decimal-place controls backed by native cell-style keys, live count/sum/average selection summaries, operation-driven sparse-workbook projection, guarded controlled-value remounts that reject stale engine callbacks, and no-history result patches with cell-scoped Fortune fallback | Versioned, cancellable Worker/Rust-WASM calculation sessions using the shared bounded Rust formula parser, retained formula ASTs, incremental forward/reverse dependency graphs, dirty-subgraph recalculation, cross-sheet references, and a dynamically loaded JavaScript fallback | A3S-owned virtual grid, moving replacement projection off the main thread, broader Excel formula semantics, A3S-owned custom number-format evaluation, and print layout |
304
304
  | Presentation | Scene canvas with ordered typed multi-selection, persistent nested browser groups, native PPTX group-node export, exact keyboard-accessible table-dimension insertion, native slide/object context actions with optional AI actions, a separate object/content editing state, one on-demand TipTap instance, collective move/scale/nudge/clipboard/delete/layer commands, selection-bound alignment and distribution, typed group/ungroup commands, one typed dispatcher for ribbon commands, editor-scoped shortcuts with post-command selection focus, direct beginning/current-slide playback with fullscreen fallback, frame-coalesced transactional move/resize previews that commit once on pointer release, two-level thumbnail node and scene windowing, and a phone stage that top-aligns the primary canvas while retaining one readable slide indicator beside view and zoom controls | Revisioned, cancellable Worker/Rust-WASM slide-relative alignment and object-set snapping with typed visual guides and a JavaScript fallback | Arbitrary rotated or reflected PPTX group transforms, connectors, theme resolution, text fitting, kernel-owned thumbnail layout, and slide serialization |
305
305
  | PDF | PDFium-backed page rendering with an A3S-owned responsive toolbar, a scrollable page-thumbnail rail with active-page synchronization and bounded bitmap/DOM windowing, a focus-contained phone page drawer, and typed capability controllers for navigation, zoom, search, basic annotations, annotation color, opacity, compatible stroke-width defaults and selection updates, history, and save; page and search drafts cancel without accidental commands, shortcuts remain scoped to the PDF root, and compact widths retain page status while exposing search-result traversal, navigation, zoom, and history through the keyboard-operated overflow menu | PDFium WebAssembly | Forms, redaction review, page organization, and reopen fixtures |
306
306
 
@@ -635,7 +635,7 @@ The current browser-kernel slice collects contiguous geometry-affecting text
635
635
  runs from eligible paragraphs. Each run carries an ordered registered font
636
636
  stack, size, line height, letter spacing, ligature, and kerning behavior. Font
637
637
  families and normal/italic styles remain exact; numeric weights follow the CSS
638
- Fonts matching order so WPS-style values such as 680 or 730 select a registered
638
+ Fonts matching order so Office-style values such as 680 or 730 select a registered
639
639
  700 face. When a family has only one normal-style weight, the same face
640
640
  provides deterministic metrics for browser-synthesized bold text. The kernel
641
641
  selects a face for each grapheme, joins adjacent selections that use the same
@@ -816,13 +816,13 @@ numbering settings. Reversed lists, per-item `value` overrides, native Word
816
816
  list-identity continuation, arbitrary multilevel templates, and loss-preserving
817
817
  custom numbering formats remain later fidelity gates.
818
818
 
819
- The declared direct-formatting layout slice now has a real WPS Writer reference
819
+ The declared direct-formatting layout slice now has a real Traditional Office Writer reference
820
820
  gate. Its deterministic A4 fixture uses installed Arial runs, explicit OOXML
821
821
  paragraph spacing, a fixed centered table, direct cell fills and borders, and
822
822
  physical cell margins. Automatic `w:line` values retain their original OOXML
823
- multiples for export while the browser applies the measured WPS single-line
823
+ multiples for export while the browser applies the measured Traditional Office single-line
824
824
  font metric; imported tables no longer receive editor-only block margins. The
825
- Windows parity workflow exports the same fixture through WPS, captures both
825
+ Windows parity workflow exports the same fixture through Traditional Office, captures both
826
826
  794 by 1123 CSS-pixel pages, and rejects page-size, landmark, or bounded pixel
827
827
  differences. Language-complete font substitution, variable font axes, the
828
828
  remaining character and table style properties, non-image floating-object
@@ -1181,7 +1181,7 @@ Migration to browser-native OOXML is staged:
1181
1181
  editing surfaces.
1182
1182
 
1183
1183
  Each stage needs compatibility fixtures, deterministic layout goldens, large
1184
- document performance budgets, and real Microsoft Office and WPS
1184
+ document performance budgets, and real Microsoft Office and Traditional Office
1185
1185
  interoperability evidence before it can be described as fidelity-complete.
1186
1186
 
1187
1187
  ## Delivery roadmap
@@ -1225,7 +1225,7 @@ bundle regression.
1225
1225
 
1226
1226
  Exit criteria: deterministic layout goldens for the supported feature set;
1227
1227
  incremental reflow does not rebuild unaffected pages; DOCX fixtures round-trip
1228
- through Microsoft Word and WPS without losing unsupported package parts.
1228
+ through Microsoft Word and Traditional Office without losing unsupported package parts.
1229
1229
 
1230
1230
  ### Stage 3: spreadsheet calculation and virtualization
1231
1231
 
@@ -1355,7 +1355,7 @@ window.
1355
1355
  Exit criteria: object drag and resize stay interactive on complex slides;
1356
1356
  partial rich-text formatting survives PPTX round trips; masters, layouts,
1357
1357
  themes, tables, charts, links, and notes have compatibility fixtures for
1358
- PowerPoint and WPS.
1358
+ PowerPoint and Traditional Office.
1359
1359
 
1360
1360
  ### Stage 5: PDF product surface
1361
1361
 
@@ -1415,7 +1415,7 @@ page window rather than the complete file.
1415
1415
  CLI, MCP server, and Skill.
1416
1416
 
1417
1417
  Exit criteria: import-edit-export fixtures show semantic and package-level
1418
- round-trip evidence in Microsoft Office and WPS; unsupported content is
1418
+ round-trip evidence in Microsoft Office and Traditional Office; unsupported content is
1419
1419
  retained or rejected explicitly, never silently discarded.
1420
1420
 
1421
1421
  ## Performance gates
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a3s-lab/office",
3
- "version": "0.20.0",
3
+ "version": "0.22.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,8 @@
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-date-time": "playwright test visual-tests/spreadsheet-date-time.functional.spec.ts --config playwright.config.ts",
92
+ "playground:visual:spreadsheet-diagonal-borders": "playwright test visual-tests/spreadsheet-diagonal-borders.functional.spec.ts --config playwright.config.ts",
91
93
  "playground:visual:spreadsheet-font-colors-shortcuts": "playwright test visual-tests/spreadsheet-font-colors-shortcuts.functional.spec.ts --config playwright.config.ts",
92
94
  "playground:visual:spreadsheet-hyperlink": "playwright test visual-tests/spreadsheet-hyperlink.functional.spec.ts --config playwright.config.ts",
93
95
  "playground:visual:spreadsheet-ribbon": "playwright test visual-tests/spreadsheet-ribbon.functional.spec.ts --config playwright.config.ts",
@@ -157,6 +159,10 @@
157
159
  "test:e2e:spreadsheet-go-to:check": "a3s-test check tests/e2e/spreadsheet-go-to.acl --json",
158
160
  "test:e2e:spreadsheet-data-validation": "a3s-test run tests/e2e/spreadsheet-data-validation.acl --json",
159
161
  "test:e2e:spreadsheet-data-validation:check": "a3s-test check tests/e2e/spreadsheet-data-validation.acl --json",
162
+ "test:e2e:spreadsheet-diagonal-borders": "a3s-test run tests/e2e/spreadsheet-diagonal-borders.acl --json",
163
+ "test:e2e:spreadsheet-diagonal-borders:check": "a3s-test check tests/e2e/spreadsheet-diagonal-borders.acl --json",
164
+ "test:e2e:spreadsheet-date-time": "a3s-test run tests/e2e/spreadsheet-date-time.acl --json",
165
+ "test:e2e:spreadsheet-date-time:check": "a3s-test check tests/e2e/spreadsheet-date-time.acl --json",
160
166
  "test:e2e:spreadsheet-hyperlink": "a3s-test run tests/e2e/spreadsheet-hyperlink.acl --json",
161
167
  "test:e2e:spreadsheet-hyperlink:check": "a3s-test check tests/e2e/spreadsheet-hyperlink.acl --json",
162
168
  "test:e2e:spreadsheet-maximum-sparse": "a3s-test run tests/e2e/spreadsheet-maximum-sparse.acl --json",
@@ -176,6 +182,7 @@
176
182
  "test:e2e:writer-status": "a3s-test run tests/e2e/word-status-bar.acl --json",
177
183
  "test:e2e:writer-status:check": "a3s-test check tests/e2e/word-status-bar.acl --json",
178
184
  "test:wps-layout": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/test-wps-layout-parity.ps1",
185
+ "test:office-layout": "bun run test:wps-layout",
179
186
  "test:watch": "rstest --watch",
180
187
  "typecheck": "tsc --noEmit"
181
188
  },