@a3s-lab/office 0.16.0 → 0.18.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 "./2180.js";
8
+ import { spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalIconSetName, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconSetCount } from "./1992.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 = {};
@@ -2092,6 +2092,64 @@ 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 spreadsheetUnderlineStyles = [
2096
+ 'none',
2097
+ 'single',
2098
+ 'double',
2099
+ 'singleAccounting',
2100
+ 'doubleAccounting'
2101
+ ];
2102
+ const underlineCellValues = {
2103
+ none: 0,
2104
+ single: 1,
2105
+ double: 2,
2106
+ singleAccounting: 3,
2107
+ doubleAccounting: 4
2108
+ };
2109
+ function isSpreadsheetUnderlineStyle(value) {
2110
+ return 'string' == typeof value && spreadsheetUnderlineStyles.includes(value);
2111
+ }
2112
+ function spreadsheetUnderlineCellValue(style) {
2113
+ return underlineCellValues[style];
2114
+ }
2115
+ function spreadsheetUnderlineStyle(value) {
2116
+ switch(Number(value)){
2117
+ case 1:
2118
+ return 'single';
2119
+ case 2:
2120
+ return 'double';
2121
+ case 3:
2122
+ case 0x21:
2123
+ return 'singleAccounting';
2124
+ case 4:
2125
+ case 0x22:
2126
+ return 'doubleAccounting';
2127
+ default:
2128
+ return 'none';
2129
+ }
2130
+ }
2131
+ function spreadsheetUnderlineCellValueFromXlsx(value) {
2132
+ switch(value?.trim()){
2133
+ case null:
2134
+ case void 0:
2135
+ case '':
2136
+ case 'single':
2137
+ return 1;
2138
+ case 'double':
2139
+ return 2;
2140
+ case 'singleAccounting':
2141
+ return 3;
2142
+ case 'doubleAccounting':
2143
+ return 4;
2144
+ default:
2145
+ return 0;
2146
+ }
2147
+ }
2148
+ function spreadsheetUnderlineCellValueFromSheetJs(value) {
2149
+ if (true === value) return 1;
2150
+ if (isSpreadsheetUnderlineStyle(value)) return spreadsheetUnderlineCellValue(value);
2151
+ return spreadsheetUnderlineCellValue(spreadsheetUnderlineStyle(value));
2152
+ }
2095
2153
  const SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS = [
2096
2154
  'greaterThan',
2097
2155
  'greaterThanOrEqual',
@@ -2585,4 +2643,4 @@ function boundedInteger(value, minimum, maximum, fallback) {
2585
2643
  function boundedNumber(value, minimum, maximum, fallback) {
2586
2644
  return 'number' == typeof value && Number.isFinite(value) && value >= minimum && value <= maximum ? value : fallback;
2587
2645
  }
2588
- 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, normalizeSheetProtectionAuthority, normalizeSpreadsheetConditionalIconSetFormat, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetDateValidationBoundary, normalizeSpreadsheetPaperSize, protectedSheetCount, readWorkOfficeSpreadsheetCollaboration as readOfficeSpreadsheetCollaboration, registerDerivedSpreadsheetMatrix, registerImportedSpreadsheetMatrix, replaceWorkOfficeSpreadsheetCollaboration as replaceOfficeSpreadsheetCollaboration, sameSpreadsheetHistoryValue, sheetHasProtectionState, sheetProtectionAuthority, spreadsheetConditionalComparisonNeedsUpperValue, spreadsheetConditionalIconForValue, spreadsheetConditionalIconSetCount, spreadsheetConditionalThresholdValue, spreadsheetConditionalThresholdsEqual, spreadsheetDateValidationFormula, spreadsheetMatrixProfile, spreadsheetProtectionKey, unlockedCellCount, withEditableRange, withSheetProtection, withSheetSelectionPermissions, withoutEditableRange };
2646
+ 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, isSpreadsheetUnderlineStyle, normalizeSheetProtectionAuthority, normalizeSpreadsheetConditionalIconSetFormat, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetDateValidationBoundary, normalizeSpreadsheetPaperSize, protectedSheetCount, readWorkOfficeSpreadsheetCollaboration as readOfficeSpreadsheetCollaboration, registerDerivedSpreadsheetMatrix, registerImportedSpreadsheetMatrix, replaceWorkOfficeSpreadsheetCollaboration as replaceOfficeSpreadsheetCollaboration, sameSpreadsheetHistoryValue, sheetHasProtectionState, sheetProtectionAuthority, spreadsheetConditionalComparisonNeedsUpperValue, spreadsheetConditionalIconForValue, spreadsheetConditionalIconSetCount, spreadsheetConditionalThresholdValue, spreadsheetConditionalThresholdsEqual, spreadsheetDateValidationFormula, spreadsheetMatrixProfile, spreadsheetProtectionKey, spreadsheetUnderlineCellValue, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetUnderlineCellValueFromXlsx, spreadsheetUnderlineStyle, unlockedCellCount, withEditableRange, withSheetProtection, withSheetSelectionPermissions, withoutEditableRange };
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 { freezeImportedSpreadsheetCell, editableRangeRequiresCredentials, spreadsheetDateValidationFormula, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetPaperSize, normalizeSheetProtectionAuthority, importedSheetProtectionAuthority, defaultSpreadsheetColorScaleThresholds, sheetHasProtectionState, spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalComparisonOperator, registerImportedSpreadsheetMatrix, defaultSpreadsheetConditionalIconThresholds, DEFAULT_PROTECTION_HINT, normalizeSpreadsheetDateValidationBoundary, isSpreadsheetConditionalIconSetName, spreadsheetConditionalThresholdsEqual, spreadsheetConditionalIconSetCount } from "./2180.js";
8
+ import { freezeImportedSpreadsheetCell, editableRangeRequiresCredentials, spreadsheetDateValidationFormula, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetPaperSize, normalizeSheetProtectionAuthority, importedSheetProtectionAuthority, defaultSpreadsheetColorScaleThresholds, spreadsheetUnderlineCellValueFromXlsx, sheetHasProtectionState, spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalComparisonOperator, registerImportedSpreadsheetMatrix, defaultSpreadsheetConditionalIconThresholds, spreadsheetUnderlineStyle, DEFAULT_PROTECTION_HINT, isSpreadsheetConditionalIconSetName, normalizeSpreadsheetDateValidationBoundary, spreadsheetConditionalThresholdsEqual, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetConditionalIconSetCount } from "./1992.js";
9
9
  import { WorkFileImportController, materializeWorkFileSource } from "./9356.js";
10
10
  import "./2591.js";
11
11
  import "./3818.js";
@@ -3385,11 +3385,11 @@ function setXlsxToggleChild(document1, parent, name, enabled, order) {
3385
3385
  child.setAttribute('val', '1');
3386
3386
  insertXlsxOrderedChild(parent, child, order);
3387
3387
  }
3388
- function setXlsxUnderlineChild(document1, parent, enabled, order) {
3388
+ function setXlsxUnderlineChild(document1, parent, style, order) {
3389
3389
  removeXlsxChildren(parent, 'u');
3390
- if (!enabled) return;
3390
+ if ('none' === style) return;
3391
3391
  const child = document1.createElementNS(document1.documentElement.namespaceURI, 'u');
3392
- child.setAttribute('val', 'single');
3392
+ child.setAttribute('val', style);
3393
3393
  insertXlsxOrderedChild(parent, child, order);
3394
3394
  }
3395
3395
  function xlsxRgbColor(value) {
@@ -3651,7 +3651,7 @@ function directFontStyle(cell) {
3651
3651
  strike: 1 === Number(cell.cl)
3652
3652
  } : {},
3653
3653
  ...void 0 !== cell.un ? {
3654
- underline: 1 === Number(cell.un)
3654
+ underline: spreadsheetUnderlineStyle(cell.un)
3655
3655
  } : {}
3656
3656
  };
3657
3657
  }
@@ -3971,7 +3971,10 @@ function readDirectFontStyle(style, font, colors) {
3971
3971
  const strike = directChild(font, 'strike');
3972
3972
  if (strike && toggleEnabled(strike)) style.cl = 1;
3973
3973
  const underline = directChild(font, 'u');
3974
- if (underline && underlineEnabled(underline)) style.un = 1;
3974
+ if (underline) {
3975
+ const value = spreadsheetUnderlineCellValueFromXlsx(work_ooxml_package_attribute(underline, 'val'));
3976
+ if (value) style.un = value;
3977
+ }
3975
3978
  const name = work_ooxml_package_attribute(directChild(font, 'name') ?? font, 'val')?.trim();
3976
3979
  if (name) style.ff = name;
3977
3980
  const size = Number(work_ooxml_package_attribute(directChild(font, 'sz') ?? font, 'val'));
@@ -4027,10 +4030,6 @@ function toggleEnabled(element) {
4027
4030
  const value = work_ooxml_package_attribute(element, 'val')?.trim().toLowerCase();
4028
4031
  return '0' !== value && 'false' !== value && 'off' !== value;
4029
4032
  }
4030
- function underlineEnabled(element) {
4031
- const value = work_ooxml_package_attribute(element, 'val')?.trim().toLowerCase();
4032
- return '0' !== value && 'false' !== value && 'none' !== value;
4033
- }
4034
4033
  function work_xlsx_cell_styles_booleanAttribute(element, name) {
4035
4034
  const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
4036
4035
  return '1' === value || 'true' === value || 'on' === value;
@@ -8566,7 +8565,7 @@ function fortuneCellStyle(source) {
8566
8565
  if (font?.bold) target.bl = 1;
8567
8566
  if (font?.italic) target.it = 1;
8568
8567
  if (font?.strike) target.cl = 1;
8569
- if (font?.underline) target.un = 1;
8568
+ if (font?.underline) target.un = spreadsheetUnderlineCellValueFromSheetJs(font.underline);
8570
8569
  if (font?.name) target.ff = font.name;
8571
8570
  if (font?.sz !== void 0) target.fs = font.sz;
8572
8571
  const fontColor = spreadsheetColor(font?.color?.rgb);
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 "./2180.js";
10
+ export { createOfficeSpreadsheetCollaborationBinding, initializeOfficeSpreadsheetCollaboration, readOfficeSpreadsheetCollaboration, replaceOfficeSpreadsheetCollaboration } from "./1992.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 "./2180.js";
13
+ export { createOfficeSpreadsheetCollaborationBinding, initializeOfficeSpreadsheetCollaboration, readOfficeSpreadsheetCollaboration, replaceOfficeSpreadsheetCollaboration } from "./1992.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,5 +1,6 @@
1
1
  import type { Cell } from '@fortune-sheet/core';
2
2
  import type { WorkSpreadsheetContent, WorkSpreadsheetSheet } from '../work-types';
3
+ import { type SpreadsheetUnderlineStyle } from '../work-spreadsheet-underline';
3
4
  import { type SpreadsheetCellBorderFormat } from './spreadsheet-cell-border';
4
5
  import { type SpreadsheetCellRange } from './spreadsheet-cell-range';
5
6
  export declare const MAX_SPREADSHEET_CELL_FORMAT_CELLS = 10000;
@@ -16,7 +17,7 @@ export interface SpreadsheetCellFormatPatch {
16
17
  fontColor?: string;
17
18
  bold?: boolean;
18
19
  italic?: boolean;
19
- underline?: boolean;
20
+ underline?: SpreadsheetUnderlineStyle;
20
21
  strike?: boolean;
21
22
  fillColor?: string | null;
22
23
  borders?: readonly SpreadsheetCellBorderFormat[];
@@ -193,6 +193,34 @@ export declare const spreadsheetCommandCatalog: {
193
193
  readonly editor: readonly ["Mod-5"];
194
194
  };
195
195
  };
196
+ readonly growFont: {
197
+ readonly id: "font.grow";
198
+ readonly label: "增大字号";
199
+ readonly location: {
200
+ readonly area: "ribbon";
201
+ readonly tab: "home";
202
+ readonly group: "font";
203
+ };
204
+ readonly shortcut: {
205
+ readonly label: "Cmd/Ctrl+Shift+. 或 Cmd/Ctrl+]";
206
+ readonly aria: "Control+Shift+. Meta+Shift+. Control+] Meta+]";
207
+ readonly editor: readonly ["Mod-Shift-.", "Mod-]"];
208
+ };
209
+ };
210
+ readonly shrinkFont: {
211
+ readonly id: "font.shrink";
212
+ readonly label: "减小字号";
213
+ readonly location: {
214
+ readonly area: "ribbon";
215
+ readonly tab: "home";
216
+ readonly group: "font";
217
+ };
218
+ readonly shortcut: {
219
+ readonly label: "Cmd/Ctrl+Shift+, 或 Cmd/Ctrl+[";
220
+ readonly aria: "Control+Shift+, Meta+Shift+, Control+[ Meta+[";
221
+ readonly editor: readonly ["Mod-Shift-,", "Mod-["];
222
+ };
223
+ };
196
224
  readonly numberFormatGeneral: {
197
225
  readonly id: "number.general";
198
226
  readonly label: "常规";
@@ -394,6 +422,11 @@ export declare const spreadsheetCommandCatalog: {
394
422
  readonly tab: "home";
395
423
  readonly group: "font";
396
424
  };
425
+ readonly shortcut: {
426
+ readonly label: "Cmd/Ctrl+Shift+_";
427
+ readonly aria: "Control+Shift+_ Meta+Shift+_";
428
+ readonly editor: readonly ["Mod-Shift-_", "Mod-Shift-Minus"];
429
+ };
397
430
  };
398
431
  readonly borderAll: {
399
432
  readonly id: "font.borderAll";
@@ -412,6 +445,11 @@ export declare const spreadsheetCommandCatalog: {
412
445
  readonly tab: "home";
413
446
  readonly group: "font";
414
447
  };
448
+ readonly shortcut: {
449
+ readonly label: "Cmd/Ctrl+Shift+&";
450
+ readonly aria: "Control+Shift+& Meta+Shift+&";
451
+ readonly editor: readonly ["Mod-Shift-&", "Mod-Shift-7"];
452
+ };
415
453
  };
416
454
  readonly borderInside: {
417
455
  readonly id: "font.borderInside";
@@ -9,6 +9,7 @@ import type { SpreadsheetCellFormatRequest } from './spreadsheet-cell-format';
9
9
  import type { SpreadsheetCellRange } from './spreadsheet-cell-range';
10
10
  import type { SpreadsheetCellStyleChoice } from './spreadsheet-cell-style';
11
11
  import type { SpreadsheetCellFillDirection } from './spreadsheet-cell-fill';
12
+ import { type SpreadsheetFontSizeDirection } from './spreadsheet-font-size-command';
12
13
  import type { SpreadsheetDataValidationRequest, SpreadsheetDataValidationTarget } from './spreadsheet-data-validation';
13
14
  import { type SpreadsheetCellMergeCommand } from './spreadsheet-cell-merge';
14
15
  import type { SpreadsheetFormatPainterMode } from './spreadsheet-format-painter';
@@ -149,6 +150,7 @@ export interface SpreadsheetEditorCommands {
149
150
  activateFormatPainter: (mode: SpreadsheetFormatPainterMode) => boolean;
150
151
  addSheet: () => boolean;
151
152
  adjustDecimalPlaces: (direction: SpreadsheetDecimalPlacesDirection) => boolean;
153
+ adjustFontSize: (direction: SpreadsheetFontSizeDirection) => boolean;
152
154
  applyCellStyle: (preset: SpreadsheetCellStyleChoice) => boolean;
153
155
  applyCellFormat: (request: SpreadsheetCellFormatRequest) => boolean;
154
156
  applyDataValidation: (request: SpreadsheetDataValidationRequest) => boolean;
@@ -0,0 +1,18 @@
1
+ import type { Cell } from '@fortune-sheet/core';
2
+ import type { WorkSpreadsheetContent } from '../work-types';
3
+ import type { SpreadsheetCommandContext, SpreadsheetEditorCommands } from './spreadsheet-command-controller';
4
+ import { type SpreadsheetCellRange, type SpreadsheetCellRangeInput } from './spreadsheet-cell-range';
5
+ import { type SpreadsheetFontSizeDirection } from './spreadsheet-font-size';
6
+ import { type OfficeEditorExtension } from './office-editor-extension';
7
+ export { nextSpreadsheetFontSize } from './spreadsheet-font-size';
8
+ export type { SpreadsheetFontSizeDirection } from './spreadsheet-font-size';
9
+ export declare const MAX_SPREADSHEET_FONT_SIZE_CELLS = 10000;
10
+ export interface SpreadsheetFontSizeApiCall {
11
+ name: 'setCellFormatByRange';
12
+ args: ['fs', number, SpreadsheetCellRange, {
13
+ id: string;
14
+ }];
15
+ }
16
+ export declare function createSpreadsheetFontSizeExtension(): OfficeEditorExtension<SpreadsheetCommandContext, SpreadsheetEditorCommands>;
17
+ export declare function canAdjustSpreadsheetFontSize(content: WorkSpreadsheetContent, sheetId: string, range: SpreadsheetCellRangeInput, direction: SpreadsheetFontSizeDirection): boolean;
18
+ export declare function spreadsheetFontSizeApiCalls(cells: readonly (readonly (Cell | null)[])[], range: SpreadsheetCellRangeInput, sheetId: string, direction: SpreadsheetFontSizeDirection): SpreadsheetFontSizeApiCall[];
@@ -0,0 +1,4 @@
1
+ export declare const DEFAULT_SPREADSHEET_FONT_SIZE = 10;
2
+ export declare const spreadsheetFontSizes: readonly [9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 36, 48, 72];
3
+ export type SpreadsheetFontSizeDirection = 'grow' | 'shrink';
4
+ export declare function nextSpreadsheetFontSize(current: number, direction: SpreadsheetFontSizeDirection): number | null;
@@ -1,5 +1,6 @@
1
1
  import type { Cell } from '@fortune-sheet/core';
2
2
  import type { WorkSpreadsheetContent } from '../work-types';
3
+ import { type SpreadsheetUnderlineStyle } from '../work-spreadsheet-underline';
3
4
  import { type SpreadsheetCellBorderFormat, type SpreadsheetCellBorderStyle } from './spreadsheet-cell-border';
4
5
  import { type SpreadsheetCellFormatPatch, type SpreadsheetHorizontalAlignment, type SpreadsheetVerticalAlignment } from './spreadsheet-cell-format';
5
6
  import { type SpreadsheetCellRange } from './spreadsheet-cell-range';
@@ -38,7 +39,7 @@ export interface SpreadsheetFormatCellsFields {
38
39
  fontColor: SpreadsheetFormatCellsField<string>;
39
40
  bold: SpreadsheetFormatCellsField<boolean>;
40
41
  italic: SpreadsheetFormatCellsField<boolean>;
41
- underline: SpreadsheetFormatCellsField<boolean>;
42
+ underline: SpreadsheetFormatCellsField<SpreadsheetUnderlineStyle>;
42
43
  strike: SpreadsheetFormatCellsField<boolean>;
43
44
  fillColor: SpreadsheetFormatCellsField<string | null>;
44
45
  borders: SpreadsheetFormatCellsField<readonly SpreadsheetCellBorderFormat[]>;
@@ -62,7 +63,7 @@ export interface SpreadsheetFormatCellsDraft {
62
63
  fontColor: string;
63
64
  bold: boolean;
64
65
  italic: boolean;
65
- underline: boolean;
66
+ underline: SpreadsheetUnderlineStyle;
66
67
  strike: boolean;
67
68
  fillColor: string | null;
68
69
  borders: SpreadsheetCellBorderFormat[];
@@ -0,0 +1,6 @@
1
+ import type { SpreadsheetEditorCanCommands, SpreadsheetEditorCommands } from './spreadsheet-command-controller';
2
+ export declare function SpreadsheetUnderlineRibbon({ can, commands, value, }: {
3
+ can: SpreadsheetEditorCanCommands;
4
+ commands: SpreadsheetEditorCommands;
5
+ value: unknown;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1,8 @@
1
+ export declare const spreadsheetUnderlineStyles: readonly ["none", "single", "double", "singleAccounting", "doubleAccounting"];
2
+ export type SpreadsheetUnderlineStyle = (typeof spreadsheetUnderlineStyles)[number];
3
+ export type SpreadsheetUnderlineCellValue = 0 | 1 | 2 | 3 | 4;
4
+ export declare function isSpreadsheetUnderlineStyle(value: unknown): value is SpreadsheetUnderlineStyle;
5
+ export declare function spreadsheetUnderlineCellValue(style: SpreadsheetUnderlineStyle): SpreadsheetUnderlineCellValue;
6
+ export declare function spreadsheetUnderlineStyle(value: unknown): SpreadsheetUnderlineStyle;
7
+ export declare function spreadsheetUnderlineCellValueFromXlsx(value: string | null): SpreadsheetUnderlineCellValue;
8
+ export declare function spreadsheetUnderlineCellValueFromSheetJs(value: unknown): SpreadsheetUnderlineCellValue;
@@ -1,4 +1,5 @@
1
1
  import type { XlsxCellBorderLine } from './work-xlsx-cell-borders';
2
+ import type { SpreadsheetUnderlineStyle } from './work-spreadsheet-underline';
2
3
  export interface XlsxDirectAlignmentStyle {
3
4
  horizontal?: 'center' | 'left' | 'right';
4
5
  textRotation?: number;
@@ -13,5 +14,5 @@ export declare function writeXlsxAlignment(document: Document, xf: Element, styl
13
14
  export declare function setXlsxValueChild(document: Document, parent: Element, name: string, value: string, order: readonly string[]): void;
14
15
  export declare function setXlsxColorChild(document: Document, parent: Element, color: string, order: readonly string[]): void;
15
16
  export declare function setXlsxToggleChild(document: Document, parent: Element, name: string, enabled: boolean, order: readonly string[]): void;
16
- export declare function setXlsxUnderlineChild(document: Document, parent: Element, enabled: boolean, order: readonly string[]): void;
17
+ export declare function setXlsxUnderlineChild(document: Document, parent: Element, style: SpreadsheetUnderlineStyle, order: readonly string[]): void;
17
18
  export declare function xlsxRgbColor(value: unknown): string | null;
Binary file
package/dist/styles.css CHANGED
@@ -15138,7 +15138,7 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
15138
15138
  }
15139
15139
  }
15140
15140
 
15141
- .work-spreadsheet-border-split-root {
15141
+ .work-spreadsheet-border-split-root, .work-spreadsheet-underline-split-root {
15142
15142
  border-radius: 6px;
15143
15143
  flex: none;
15144
15144
  align-items: stretch;
@@ -15146,6 +15146,118 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
15146
15146
  display: inline-flex;
15147
15147
  }
15148
15148
 
15149
+ .work-office-ribbon .work-office-toolbar .work-spreadsheet-underline-primary, .work-office-ribbon .work-office-toolbar .work-spreadsheet-underline-disclosure {
15150
+ border-radius: 0;
15151
+ height: 29px;
15152
+ padding: 0;
15153
+ }
15154
+
15155
+ .work-office-ribbon .work-office-toolbar .work-spreadsheet-underline-primary {
15156
+ border-radius: 6px 0 0 6px;
15157
+ width: 29px;
15158
+ min-width: 29px;
15159
+ }
15160
+
15161
+ .work-office-ribbon .work-office-toolbar .work-spreadsheet-underline-disclosure {
15162
+ border-left: 1px solid color-mix(in srgb, var(--a3s-line) 72%, transparent);
15163
+ border-radius: 0 6px 6px 0;
15164
+ width: 16px;
15165
+ min-width: 16px;
15166
+ }
15167
+
15168
+ .work-spreadsheet-underline-disclosure svg {
15169
+ transition: transform .12s;
15170
+ }
15171
+
15172
+ .work-spreadsheet-underline-disclosure[aria-expanded="true"] svg {
15173
+ transform: rotate(180deg);
15174
+ }
15175
+
15176
+ .work-spreadsheet-underline-primary:focus-visible, .work-spreadsheet-underline-disclosure:focus-visible {
15177
+ box-shadow: inset 0 0 0 1px var(--work-spreadsheet-accent);
15178
+ outline: 0;
15179
+ }
15180
+
15181
+ .work-spreadsheet-underline-menu {
15182
+ width: min(252px, 100vw - 32px);
15183
+ }
15184
+
15185
+ .work-spreadsheet-underline-menu > button {
15186
+ grid-template-columns: 22px minmax(0, 1fr) 14px;
15187
+ }
15188
+
15189
+ .work-spreadsheet-underline-menu > button[aria-checked="true"] {
15190
+ background: color-mix(in srgb,
15191
+ var(--work-office-menu-accent) 9%,
15192
+ transparent);
15193
+ }
15194
+
15195
+ .work-spreadsheet-underline-menu > button[aria-checked="true"]:after {
15196
+ color: var(--work-office-menu-accent);
15197
+ content: "✓";
15198
+ text-align: center;
15199
+ grid-column: 3;
15200
+ font-size: 12px;
15201
+ font-weight: 700;
15202
+ }
15203
+
15204
+ .work-spreadsheet-underline-glyph {
15205
+ width: 20px;
15206
+ height: 20px;
15207
+ color: var(--work-office-menu-accent);
15208
+ place-items: center;
15209
+ display: grid;
15210
+ position: relative;
15211
+ }
15212
+
15213
+ .work-spreadsheet-underline-glyph[data-underline-style="none"] {
15214
+ opacity: .42;
15215
+ }
15216
+
15217
+ .work-spreadsheet-underline-glyph[data-underline-style="none"]:after {
15218
+ content: "";
15219
+ background: currentColor;
15220
+ width: 18px;
15221
+ height: 1px;
15222
+ position: absolute;
15223
+ transform: rotate(-38deg);
15224
+ }
15225
+
15226
+ .work-spreadsheet-underline-glyph[data-underline-style="double"]:before {
15227
+ content: "";
15228
+ background: currentColor;
15229
+ height: 1px;
15230
+ position: absolute;
15231
+ bottom: 1px;
15232
+ left: 2px;
15233
+ right: 2px;
15234
+ }
15235
+
15236
+ .work-spreadsheet-underline-glyph[data-underline-style="singleAccounting"] svg line, .work-spreadsheet-underline-glyph[data-underline-style="doubleAccounting"] svg line {
15237
+ display: none;
15238
+ }
15239
+
15240
+ .work-spreadsheet-underline-glyph[data-underline-style="singleAccounting"]:after, .work-spreadsheet-underline-glyph[data-underline-style="doubleAccounting"]:before, .work-spreadsheet-underline-glyph[data-underline-style="doubleAccounting"]:after {
15241
+ content: "";
15242
+ background: currentColor;
15243
+ height: 1px;
15244
+ position: absolute;
15245
+ left: 0;
15246
+ right: 0;
15247
+ }
15248
+
15249
+ .work-spreadsheet-underline-glyph[data-underline-style="singleAccounting"]:after {
15250
+ bottom: 1px;
15251
+ }
15252
+
15253
+ .work-spreadsheet-underline-glyph[data-underline-style="doubleAccounting"]:before {
15254
+ bottom: 3px;
15255
+ }
15256
+
15257
+ .work-spreadsheet-underline-glyph[data-underline-style="doubleAccounting"]:after {
15258
+ bottom: 0;
15259
+ }
15260
+
15149
15261
  .work-office-ribbon .work-office-toolbar .work-spreadsheet-border-primary, .work-office-ribbon .work-office-toolbar .work-spreadsheet-border-disclosure {
15150
15262
  border-radius: 0;
15151
15263
  height: 29px;
@@ -15180,7 +15292,7 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
15180
15292
 
15181
15293
  .work-spreadsheet-border-panel {
15182
15294
  --work-office-menu-accent: var(--work-office-control-accent, #159469);
15183
- width: min(292px, 100vw - 32px);
15295
+ width: min(360px, 100vw - 32px);
15184
15296
  padding: 8px;
15185
15297
  }
15186
15298
 
@@ -15207,7 +15319,7 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
15207
15319
  background: none;
15208
15320
  border: 0;
15209
15321
  border-radius: 6px;
15210
- grid-template-columns: 22px minmax(0, 1fr);
15322
+ grid-template-columns: 22px minmax(0, 1fr) auto;
15211
15323
  align-items: center;
15212
15324
  gap: 7px;
15213
15325
  padding: 4px 7px;
@@ -15231,13 +15343,20 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
15231
15343
  opacity: .4;
15232
15344
  }
15233
15345
 
15234
- .work-spreadsheet-border-targets > button > span:last-child {
15346
+ .work-spreadsheet-border-target-label {
15235
15347
  text-overflow: ellipsis;
15236
15348
  white-space: nowrap;
15237
15349
  font-size: 11px;
15238
15350
  overflow: hidden;
15239
15351
  }
15240
15352
 
15353
+ .work-spreadsheet-border-targets kbd {
15354
+ color: var(--a3s-faint);
15355
+ font: inherit;
15356
+ white-space: nowrap;
15357
+ font-size: 8px;
15358
+ }
15359
+
15241
15360
  .work-spreadsheet-border-glyph {
15242
15361
  border: 1px solid color-mix(in srgb, currentcolor 34%, transparent);
15243
15362
  width: 17px;
@@ -15377,9 +15496,14 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
15377
15496
  }
15378
15497
 
15379
15498
  .work-spreadsheet-border-targets > button {
15499
+ grid-template-columns: 22px minmax(0, 1fr);
15380
15500
  min-height: 44px;
15381
15501
  }
15382
15502
 
15503
+ .work-spreadsheet-border-targets kbd {
15504
+ display: none;
15505
+ }
15506
+
15383
15507
  .work-spreadsheet-border-settings {
15384
15508
  grid-template-columns: 1fr;
15385
15509
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a3s-lab/office",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "description": "Open-source collaborative browser editors for documents, Markdown, spreadsheets, presentations, and PDFs.",
5
5
  "keywords": [
6
6
  "office",
@@ -90,6 +90,7 @@
90
90
  "playground:visual:spreadsheet-data-validation": "playwright test visual-tests/spreadsheet-data-validation.functional.spec.ts --config playwright.config.ts",
91
91
  "playground:visual:spreadsheet-hyperlink": "playwright test visual-tests/spreadsheet-hyperlink.functional.spec.ts --config playwright.config.ts",
92
92
  "playground:visual:spreadsheet-ribbon": "playwright test visual-tests/spreadsheet-ribbon.functional.spec.ts --config playwright.config.ts",
93
+ "playground:visual:spreadsheet-underline": "playwright test visual-tests/spreadsheet-underline.functional.spec.ts --config playwright.config.ts",
93
94
  "playground:visual:spreadsheet-table": "playwright test visual-tests/spreadsheet-table.functional.spec.ts --config playwright.config.ts",
94
95
  "playground:visual:update": "playwright test --config playwright.config.ts --update-snapshots",
95
96
  "performance:fixtures": "bun .a3s-test/performance/generate-fixtures.ts",
@@ -135,6 +136,10 @@
135
136
  "test:e2e:spreadsheet-ribbon:check": "a3s-test check tests/e2e/spreadsheet-ribbon-alignment.acl --json",
136
137
  "test:e2e:spreadsheet-cell-style": "a3s-test run tests/e2e/spreadsheet-cell-style.acl --json",
137
138
  "test:e2e:spreadsheet-cell-style:check": "a3s-test check tests/e2e/spreadsheet-cell-style.acl --json",
139
+ "test:e2e:spreadsheet-font-size-border-shortcuts": "a3s-test run tests/e2e/spreadsheet-font-size-border-shortcuts.acl --json",
140
+ "test:e2e:spreadsheet-font-size-border-shortcuts:check": "a3s-test check tests/e2e/spreadsheet-font-size-border-shortcuts.acl --json",
141
+ "test:e2e:spreadsheet-underline-styles": "a3s-test run tests/e2e/spreadsheet-underline-styles.acl --json",
142
+ "test:e2e:spreadsheet-underline-styles:check": "a3s-test check tests/e2e/spreadsheet-underline-styles.acl --json",
138
143
  "test:e2e:spreadsheet-table": "a3s-test run tests/e2e/spreadsheet-table.acl --json",
139
144
  "test:e2e:spreadsheet-table:check": "a3s-test check tests/e2e/spreadsheet-table.acl --json",
140
145
  "test:e2e:spreadsheet-cell-fill": "a3s-test run tests/e2e/spreadsheet-cell-fill.acl --json",