@a3s-lab/office 0.21.0 → 0.23.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.
@@ -1,11 +1,11 @@
1
1
  import { __webpack_require__ } from "./0~rslib-runtime.js";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { Workbook } from "@fortune-sheet/react";
4
- import { AArrowDown, AArrowUp, AlignCenter, AlignLeft, AlignRight, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignVerticalJustifyStart, ArrowDown, ArrowDownToLine, ArrowLeft, ArrowLeftToLine, ArrowRight, ArrowRightToLine, ArrowUp, ArrowUpToLine, BadgeJapaneseYen, BarChart3, BetweenHorizontalEnd, BetweenHorizontalStart, BetweenVerticalEnd, BetweenVerticalStart, Bold, Bookmark, Calculator, Check, ChevronDown, ChevronLeft, ChevronRight, ClipboardPaste, Cloud, Columns3, Copy, CopyPlus, DecimalsArrowLeft, DecimalsArrowRight, Eraser, Eye, EyeOff, FileX2, Globe2, Grid2X2, Grid3X3, Hash, Italic, KeyRound, Layers2, Link2, Link2Off, ListChecks, ListFilter, LocateFixed, Merge, MessageSquareX, MoveHorizontal, MoveVertical, Paintbrush, Palette, PanelLeft, PanelTop, PanelsTopLeft, Pencil, Percent, Plus, Printer, Redo2, RefreshCw, Rows3, Save, Scissors, Search, Settings2, ShieldCheck, Sigma, SortAsc, SortDesc, Strikethrough, SwatchBook, Table2, TableProperties, Trash2, Underline, Undo2, WrapText, X } from "lucide-react";
4
+ import { AArrowDown, AArrowUp, AlignCenter, AlignLeft, AlignRight, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignVerticalJustifyStart, ArrowDown, ArrowDownToLine, ArrowLeft, ArrowLeftToLine, ArrowRight, ArrowRightToLine, ArrowUp, ArrowUpToLine, BadgeJapaneseYen, BarChart3, BetweenHorizontalEnd, BetweenHorizontalStart, BetweenVerticalEnd, BetweenVerticalStart, Bold, Bookmark, Calculator, CalendarClock, CalendarDays, Check, ChevronDown, ChevronLeft, ChevronRight, ClipboardPaste, Clock, Cloud, Columns3, Copy, CopyPlus, DecimalsArrowLeft, DecimalsArrowRight, Eraser, Eye, EyeOff, FileX2, Globe2, Grid2X2, Grid3X3, Hash, Italic, KeyRound, Layers2, Link2, Link2Off, ListChecks, ListFilter, LocateFixed, Merge, MessageSquareX, MoveHorizontal, MoveVertical, Paintbrush, Palette, PanelLeft, PanelTop, PanelsTopLeft, Pencil, Percent, Plus, Printer, Redo2, RefreshCw, Rows3, Save, Scissors, Search, Settings2, ShieldCheck, Sigma, SortAsc, SortDesc, Strikethrough, SwatchBook, Table2, TableProperties, Trash2, Underline, Undo2, WrapText, X } from "lucide-react";
5
5
  import { Fragment as external_react_Fragment, cloneElement, memo, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
6
6
  import { genarate, indexToColumnChar, update as core_update } from "@fortune-sheet/core";
7
7
  import { freezeImportedSpreadsheetCell, spreadsheetTextOrientationFromChoice, spreadsheetMatrixProfile, withoutEditableRange, spreadsheetTextOrientationFromAngle, isSpreadsheetTextOrientationId, normalizeSpreadsheetConditionalVisualOptions, spreadsheetCellValueWithDiagonalBorder, spreadsheetUnderlineCellValue, effectiveSpreadsheetPageSetup, attachSpreadsheetShownCommentCells, withEditableRange, sameSpreadsheetHistoryValue, createOfficeSpreadsheetCollaborationBinding as createWorkOfficeSpreadsheetCollaborationBinding, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconForValue, defaultSpreadsheetConditionalIconThresholds, spreadsheetUnderlineStyle, normalizeSpreadsheetDateValidationBoundary, sheetProtectionAuthority, editableRangeCellCount, unlockedCellCount, registerDerivedSpreadsheetMatrix, editableRangeRequiresCredentials, spreadsheetTextOrientationCellStyle, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, spreadsheetConditionalThresholdValue, spreadsheetTextOrientationChoiceFromCell, normalizeSheetProtectionAuthority, withSheetProtection, defaultSpreadsheetColorScaleThresholds, spreadsheetProtectionKey, spreadsheetDiagonalBorderFromCellValue, SPREADSHEET_CONDITIONAL_ICON_SETS, protectedSheetCount, withSheetSelectionPermissions, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, spreadsheetConditionalComparisonNeedsUpperValue, drawSpreadsheetConditionalIcon, spreadsheetTextOrientationFromCell, replaceOfficeSpreadsheetCollaboration as replaceWorkOfficeSpreadsheetCollaboration, readOfficeSpreadsheetCollaboration as readWorkOfficeSpreadsheetCollaboration, spreadsheetConditionalThresholdsEqual, isSpreadsheetUnderlineStyle, spreadsheetVisibleTextRotationFromCell } from "./5045.js";
8
- import { workSpreadsheetChartSupportsGrouping, createSpreadsheetChartFromSelection, normalizeWorkSpreadsheetDataLabelPosition, normalizeSpreadsheetPrintTitleColumns, normalizeSpreadsheetPrintTitleRows, formulaHasStructuredReference, normalizeWorkSpreadsheetErrorBars, defaultPivotValueCaption, workSpreadsheetChartSupportsBarSpacing, normalizeWorkSpreadsheetChartGrouping, spreadsheetGridSize, normalizeWorkSpreadsheetChartAxisGroup, normalizeWorkSpreadsheetScatterStyle, cloneSparseMatrix, spreadsheetPivotAggregationLabel, workSpreadsheetChartAxisIsCategoryAxis, reconcileSpreadsheetChartPreviews, normalizeWorkSpreadsheetChartAxes, normalizeWorkSpreadsheetDoughnutHoleSize, normalizeWorkSpreadsheetChartLegendPosition, spreadsheetChartCount, workSpreadsheetChartTypeLabel, sparseArrayEntries, normalizeWorkSpreadsheetTrendline, effectiveSpreadsheetCalculationSettings, spreadsheetPivotIntersects, normalizeWorkSpreadsheetDataLabels, spreadsheetPivotOutputContains, normalizeSpreadsheetPrintArea, spreadsheetCellAddress, formatSpreadsheetCellRanges, normalizeWorkSpreadsheetChartLayout, spreadsheetFormulaRangeForCell, workSpreadsheetChartAxisIsValueAxis, normalizeWorkSpreadsheetChartSmoothLines, spreadsheetPivotFilterValueKey, normalizeWorkSpreadsheetBubbleScale, normalizeWorkSpreadsheetChartSeriesStyle, volatileSpreadsheetFormulaFunctions, sparseArrayIndexes, normalizeWorkSpreadsheetBubbleSizeRepresents, workSpreadsheetChartSupportsTrendlines, normalizeWorkSpreadsheetChartLegendOverlay, parseSpreadsheetChartReference, workSpreadsheetChartGroupingIsStacked, normalizeWorkSpreadsheetChartGapWidth, workSpreadsheetChartSupportsSmoothLines, refreshSpreadsheetPivotTables, createSpreadsheetPivotFromSelection, reconcileSpreadsheetPivots, spreadsheetPivotCount, sparseMatrixColumnCount, workSpreadsheetChartSupportsErrorBars, formulaHasExternalReference, isValidSpreadsheetDefinedName, spreadsheetPivotValidation, deleteSpreadsheetPivotTable, workSpreadsheetChartAxisDefaultLabelPosition, workSpreadsheetChartSupportsSeriesAnalysis, parseSpreadsheetCellRanges, spreadsheetPivotFilterItems, spreadsheetPivotFields, normalizeWorkSpreadsheetChartOverlap, spreadsheetFormulaRangeConflict, spreadsheetSheetsWithChartPreviews, workSpreadsheetChartUsesNumericXAxis, workSpreadsheetChartAxisShowsMajorGridlinesByDefault, workSpreadsheetChartSupportsAxes, normalizeWorkSpreadsheetCombinationSeriesType, normalizeWorkSpreadsheetRadarStyle } from "./8715.js";
8
+ import { workSpreadsheetChartSupportsGrouping, spreadsheetFormulaRangesForSelection, createSpreadsheetChartFromSelection, normalizeWorkSpreadsheetDataLabelPosition, normalizeSpreadsheetPrintTitleColumns, normalizeSpreadsheetPrintTitleRows, formulaHasStructuredReference, normalizeWorkSpreadsheetErrorBars, defaultPivotValueCaption, workSpreadsheetChartSupportsBarSpacing, normalizeWorkSpreadsheetChartGrouping, spreadsheetGridSize, normalizeWorkSpreadsheetChartAxisGroup, normalizeWorkSpreadsheetScatterStyle, cloneSparseMatrix, spreadsheetPivotAggregationLabel, workSpreadsheetChartAxisIsCategoryAxis, reconcileSpreadsheetChartPreviews, normalizeWorkSpreadsheetChartAxes, normalizeWorkSpreadsheetDoughnutHoleSize, normalizeWorkSpreadsheetChartLegendPosition, spreadsheetChartCount, workSpreadsheetChartTypeLabel, sparseArrayEntries, normalizeWorkSpreadsheetTrendline, effectiveSpreadsheetCalculationSettings, spreadsheetPivotIntersects, normalizeWorkSpreadsheetDataLabels, spreadsheetPivotOutputContains, normalizeSpreadsheetPrintArea, spreadsheetCellAddress, formatSpreadsheetCellRanges, normalizeWorkSpreadsheetChartLayout, spreadsheetFormulaRangeForCell, workSpreadsheetChartAxisIsValueAxis, normalizeWorkSpreadsheetChartSmoothLines, spreadsheetPivotFilterValueKey, normalizeWorkSpreadsheetBubbleScale, normalizeWorkSpreadsheetChartSeriesStyle, volatileSpreadsheetFormulaFunctions, sparseArrayIndexes, normalizeWorkSpreadsheetBubbleSizeRepresents, workSpreadsheetChartSupportsTrendlines, normalizeWorkSpreadsheetChartLegendOverlay, parseSpreadsheetChartReference, workSpreadsheetChartGroupingIsStacked, normalizeWorkSpreadsheetChartGapWidth, workSpreadsheetChartSupportsSmoothLines, refreshSpreadsheetPivotTables, createSpreadsheetPivotFromSelection, reconcileSpreadsheetPivots, spreadsheetPivotCount, sparseMatrixColumnCount, workSpreadsheetChartSupportsErrorBars, formulaHasExternalReference, isValidSpreadsheetDefinedName, spreadsheetPivotValidation, deleteSpreadsheetPivotTable, workSpreadsheetChartAxisDefaultLabelPosition, workSpreadsheetChartSupportsSeriesAnalysis, parseSpreadsheetCellRanges, spreadsheetPivotFilterItems, spreadsheetPivotFields, normalizeWorkSpreadsheetChartOverlap, spreadsheetFormulaRangeConflict, spreadsheetSheetsWithChartPreviews, workSpreadsheetChartUsesNumericXAxis, workSpreadsheetChartAxisShowsMajorGridlinesByDefault, workSpreadsheetChartSupportsAxes, normalizeWorkSpreadsheetCombinationSeriesType, normalizeWorkSpreadsheetRadarStyle } from "./8715.js";
9
9
  import { moveOfficeMenuFocus, stepOfficeZoom, useOfficeRemoteParticipants, Popover, officePresenceColor, useOfficePublishPresenceLocation, button_Button, icon_button_IconButton, moveOfficeGridMenuFocus, office_text_field_OfficeTextField, useDialogFocusScope, useOfficeEditorWheelZoom } from "./0~6090.js";
10
10
  import { useOfficeTaskPaneEscape, OfficeCheckbox, CommittedOfficeNumberField, useOfficeDialog, useOfficeTaskPaneModal, createOfficeKernelClient, officeFontFamilies, CollectionState, OfficeNumberField, handleOfficeTaskPaneKeyDown } from "./0~7048.js";
11
11
  import { isOfficeShortcutBlocked, OfficeColorPicker } from "./0~3635.js";
@@ -3236,6 +3236,38 @@ const spreadsheetCommandCatalog = {
3236
3236
  group: 'number'
3237
3237
  }
3238
3238
  },
3239
+ insertCurrentDate: {
3240
+ id: 'number.insertCurrentDate',
3241
+ label: '插入当前日期',
3242
+ location: {
3243
+ area: 'ribbon',
3244
+ tab: 'home',
3245
+ group: 'number'
3246
+ },
3247
+ shortcut: {
3248
+ label: 'Ctrl+;',
3249
+ aria: 'Control+;',
3250
+ editor: [
3251
+ 'Control-;'
3252
+ ]
3253
+ }
3254
+ },
3255
+ insertCurrentTime: {
3256
+ id: 'number.insertCurrentTime',
3257
+ label: '插入当前时间',
3258
+ location: {
3259
+ area: 'ribbon',
3260
+ tab: 'home',
3261
+ group: 'number'
3262
+ },
3263
+ shortcut: {
3264
+ label: 'Ctrl+Shift+;',
3265
+ aria: 'Control+Shift+;',
3266
+ editor: [
3267
+ 'Control-Shift-;'
3268
+ ]
3269
+ }
3270
+ },
3239
3271
  formatCells: {
3240
3272
  id: 'number.formatCells',
3241
3273
  label: '设置单元格格式',
@@ -3720,6 +3752,38 @@ const spreadsheetCommandCatalog = {
3720
3752
  group: 'editing'
3721
3753
  }
3722
3754
  },
3755
+ copyFormulaFromAbove: {
3756
+ id: 'editing.copyFormulaFromAbove',
3757
+ label: '复制上方公式',
3758
+ location: {
3759
+ area: 'ribbon',
3760
+ tab: 'home',
3761
+ group: 'editing'
3762
+ },
3763
+ shortcut: {
3764
+ label: "Ctrl+'",
3765
+ aria: "Control+'",
3766
+ editor: [
3767
+ "Control-'"
3768
+ ]
3769
+ }
3770
+ },
3771
+ copyValueFromAbove: {
3772
+ id: 'editing.copyValueFromAbove',
3773
+ label: '复制上方值',
3774
+ location: {
3775
+ area: 'ribbon',
3776
+ tab: 'home',
3777
+ group: 'editing'
3778
+ },
3779
+ shortcut: {
3780
+ label: "Ctrl+Shift+'",
3781
+ aria: "Control+Shift+'",
3782
+ editor: [
3783
+ "Control-Shift-'"
3784
+ ]
3785
+ }
3786
+ },
3723
3787
  clearAll: {
3724
3788
  id: 'editing.clearAll',
3725
3789
  label: '清除全部',
@@ -5191,6 +5255,213 @@ function spreadsheetSelectedCellFillPlan(context, direction) {
5191
5255
  const sheet = context.content.sheets.find((candidate)=>candidate.id === context.targetSheetId);
5192
5256
  return canApplySpreadsheetCellFill(sheet, plan) ? plan : null;
5193
5257
  }
5258
+ const MAX_SPREADSHEET_ROWS = 1048576;
5259
+ const spreadsheetPasteContentOptions = [
5260
+ {
5261
+ value: 'all',
5262
+ label: '全部',
5263
+ richOnly: false
5264
+ },
5265
+ {
5266
+ value: 'formulas',
5267
+ label: '公式',
5268
+ richOnly: false
5269
+ },
5270
+ {
5271
+ value: 'values',
5272
+ label: '值',
5273
+ richOnly: false
5274
+ },
5275
+ {
5276
+ value: 'formats',
5277
+ label: '格式',
5278
+ richOnly: true
5279
+ },
5280
+ {
5281
+ value: 'comments',
5282
+ label: '批注',
5283
+ richOnly: true
5284
+ },
5285
+ {
5286
+ value: 'validation',
5287
+ label: '数据验证',
5288
+ richOnly: true
5289
+ },
5290
+ {
5291
+ value: 'all-except-borders',
5292
+ label: '边框除外的全部',
5293
+ richOnly: true
5294
+ },
5295
+ {
5296
+ value: 'formulas-and-number-formats',
5297
+ label: '公式和数字格式',
5298
+ richOnly: true
5299
+ },
5300
+ {
5301
+ value: 'values-and-number-formats',
5302
+ label: '值和数字格式',
5303
+ richOnly: true
5304
+ },
5305
+ {
5306
+ value: 'column-widths',
5307
+ label: '列宽',
5308
+ richOnly: true
5309
+ }
5310
+ ];
5311
+ const spreadsheetPasteOperationOptions = [
5312
+ {
5313
+ value: 'none',
5314
+ label: '无'
5315
+ },
5316
+ {
5317
+ value: 'add',
5318
+ label: '加'
5319
+ },
5320
+ {
5321
+ value: 'subtract',
5322
+ label: '减'
5323
+ },
5324
+ {
5325
+ value: 'multiply',
5326
+ label: '乘'
5327
+ },
5328
+ {
5329
+ value: 'divide',
5330
+ label: '除'
5331
+ }
5332
+ ];
5333
+ function planSpreadsheetCopyFromAbove(sheet, target, kind) {
5334
+ if (!sheet || !isSpreadsheetCopyFromAboveKind(kind) || !spreadsheetCellCoordinateIsSupported(target.row, target.column) || 0 === target.row) return null;
5335
+ const targetRange = {
5336
+ row: [
5337
+ target.row,
5338
+ target.row
5339
+ ],
5340
+ column: [
5341
+ target.column,
5342
+ target.column
5343
+ ]
5344
+ };
5345
+ if (!canMutateSpreadsheetCellRange(sheet, targetRange)) return null;
5346
+ const source = {
5347
+ row: target.row - 1,
5348
+ column: target.column
5349
+ };
5350
+ const sourceCell = spreadsheetCopyFromAboveCellAt(sheet, source.row, source.column);
5351
+ const targetCell = spreadsheetCopyFromAboveCellAt(sheet, target.row, target.column);
5352
+ const formula = spreadsheetCopyableFormula(sheet, sourceCell, source.row, source.column);
5353
+ if ('formula' === kind && sourceCell?.f && null === formula) return null;
5354
+ const copiesFormula = 'formula' === kind && null !== formula;
5355
+ const value = copiesFormula ? formula : spreadsheetCopyFromAboveCellValue(sourceCell);
5356
+ if (copiesFormula ? targetCell?.f === value : !targetCell?.f && Object.is(spreadsheetCopyFromAboveCellValue(targetCell), value)) return null;
5357
+ return {
5358
+ formulaBarValue: value ?? '',
5359
+ kind,
5360
+ source,
5361
+ targetRange,
5362
+ value
5363
+ };
5364
+ }
5365
+ function spreadsheetCopyableFormula(sheet, cell, row, column) {
5366
+ if ('string' != typeof cell?.f || !cell.f.trim()) return null;
5367
+ const formula = cell.f.trim();
5368
+ if (!formula.startsWith('=') || formulaHasExternalReference(formula) || void 0 !== cell.spl || spreadsheetFormulaRangesForSelection(sheet, {
5369
+ startRow: row,
5370
+ endRow: row,
5371
+ startColumn: column,
5372
+ endColumn: column
5373
+ }).length > 0) return null;
5374
+ return formula;
5375
+ }
5376
+ function spreadsheetCopyFromAboveCellValue(cell) {
5377
+ if (cell?.v !== void 0 && null !== cell.v) return cell.v;
5378
+ const inlineText = spreadsheet_copy_from_above_spreadsheetInlineCellText(cell);
5379
+ if (null !== inlineText) return inlineText;
5380
+ if (cell?.m !== void 0 && null !== cell.m) return cell.m;
5381
+ return null;
5382
+ }
5383
+ function spreadsheet_copy_from_above_spreadsheetInlineCellText(cell) {
5384
+ const format = cell?.ct;
5385
+ if (format?.t !== 'inlineStr' || !Array.isArray(format.s)) return null;
5386
+ return format.s.map((run)=>spreadsheet_copy_from_above_isRecord(run) && ('string' == typeof run.v || 'number' == typeof run.v) ? String(run.v) : '').join('');
5387
+ }
5388
+ function spreadsheetCopyFromAboveCellAt(sheet, row, column) {
5389
+ if (void 0 !== sheet.data) return sheet.data[row]?.[column];
5390
+ return sheet.celldata?.find((entry)=>entry.r === row && entry.c === column)?.v;
5391
+ }
5392
+ function spreadsheetCellCoordinateIsSupported(row, column) {
5393
+ return Number.isSafeInteger(row) && row >= 0 && row < MAX_SPREADSHEET_ROWS && Number.isSafeInteger(column) && column >= 0 && column < 16384;
5394
+ }
5395
+ function isSpreadsheetCopyFromAboveKind(value) {
5396
+ return 'formula' === value || 'value' === value;
5397
+ }
5398
+ function spreadsheet_copy_from_above_isRecord(value) {
5399
+ return Boolean(value && 'object' == typeof value && !Array.isArray(value));
5400
+ }
5401
+ function createSpreadsheetCopyFromAboveExtension() {
5402
+ return createOfficeEditorExtension({
5403
+ name: 'spreadsheetCopyFromAbove',
5404
+ addCommands: ()=>({
5405
+ copyCellFromAbove: {
5406
+ canExecute: (context, kind)=>null !== spreadsheetSelectedCopyFromAbovePlan(context, kind),
5407
+ execute: copySpreadsheetCellFromAbove
5408
+ }
5409
+ }),
5410
+ addKeyboardShortcuts: ()=>({
5411
+ [spreadsheetCommandCatalog.copyFormulaFromAbove.shortcut.editor["0"]]: ({ can, commands }, event)=>runSpreadsheetCopyFromAboveShortcut(event, 'formula', can.copyCellFromAbove, commands.copyCellFromAbove),
5412
+ [spreadsheetCommandCatalog.copyValueFromAbove.shortcut.editor["0"]]: ({ can, commands }, event)=>runSpreadsheetCopyFromAboveShortcut(event, 'value', can.copyCellFromAbove, commands.copyCellFromAbove)
5413
+ })
5414
+ });
5415
+ }
5416
+ function copySpreadsheetCellFromAbove(context, kind) {
5417
+ const plan = spreadsheetSelectedCopyFromAbovePlan(context, kind);
5418
+ if (!plan || !context.workbook || !context.targetSheetId) return false;
5419
+ try {
5420
+ context.workbook.batchCallApis([
5421
+ {
5422
+ name: 'setCellValuesByRange',
5423
+ args: [
5424
+ [
5425
+ [
5426
+ plan.value
5427
+ ]
5428
+ ],
5429
+ plan.targetRange,
5430
+ {
5431
+ id: context.targetSheetId
5432
+ }
5433
+ ]
5434
+ }
5435
+ ]);
5436
+ } catch {
5437
+ return false;
5438
+ }
5439
+ try {
5440
+ context.formulaBar?.setValue(plan.formulaBarValue);
5441
+ } catch {}
5442
+ return true;
5443
+ }
5444
+ function spreadsheetSelectedCopyFromAbovePlan(context, kind) {
5445
+ const workbook = context.workbook;
5446
+ const sheetId = context.targetSheetId;
5447
+ if (!context.editable || !workbook || !sheetId || sheetId !== context.activeSheetId) return null;
5448
+ try {
5449
+ const selection = finiteSpreadsheetSelection(workbook.getSelection()?.at(-1) ?? context.fallbackRange);
5450
+ const row = selection.row_focus ?? selection.row[0] ?? 0;
5451
+ const column = selection.column_focus ?? selection.column[0] ?? 0;
5452
+ const sheet = context.content.sheets.find((candidate)=>candidate.id === sheetId);
5453
+ return planSpreadsheetCopyFromAbove(sheet, {
5454
+ row,
5455
+ column
5456
+ }, kind);
5457
+ } catch {
5458
+ return null;
5459
+ }
5460
+ }
5461
+ function runSpreadsheetCopyFromAboveShortcut(event, kind, canExecute, execute) {
5462
+ if (event.repeat || event.isComposing || isOfficeShortcutBlocked(event.target) || isSpreadsheetNativeTextUndoTarget(event.target) || !isSpreadsheetGridKeyboardTarget(event.target) || !canExecute(kind)) return false;
5463
+ return execute(kind);
5464
+ }
5194
5465
  function canEditSpreadsheetSelection(context) {
5195
5466
  return Boolean(context.editable && context.workbook && context.targetSheetId);
5196
5467
  }
@@ -6036,6 +6307,132 @@ function clampSpreadsheetDataValidationFocus(value, range) {
6036
6307
  const focus = 'number' == typeof value && Number.isFinite(value) ? Math.trunc(value) : minimum;
6037
6308
  return Math.min(maximum, Math.max(minimum, focus));
6038
6309
  }
6310
+ const MILLISECONDS_PER_DAY = 86400000;
6311
+ const MINUTES_PER_DAY = 1440;
6312
+ const EXCEL_1900_EPOCH_UTC = Date.UTC(1899, 11, 30);
6313
+ function spreadsheetDateTimeEntry(kind, now) {
6314
+ if (!Number.isFinite(now.getTime())) return null;
6315
+ if ('date' === kind) {
6316
+ const year = now.getFullYear();
6317
+ const month = now.getMonth();
6318
+ const day = now.getDate();
6319
+ const value = (Date.UTC(year, month, day) - EXCEL_1900_EPOCH_UTC) / MILLISECONDS_PER_DAY;
6320
+ if (!Number.isFinite(value)) return null;
6321
+ return {
6322
+ format: {
6323
+ fa: 'yyyy-MM-dd',
6324
+ t: 'd'
6325
+ },
6326
+ formulaBarValue: `${padDatePart(year, 4)}-${padDatePart(month + 1)}-${padDatePart(day)}`,
6327
+ value
6328
+ };
6329
+ }
6330
+ if ('time' !== kind) return null;
6331
+ const hours = now.getHours();
6332
+ const minutes = now.getMinutes();
6333
+ return {
6334
+ format: {
6335
+ fa: 'hh:mm',
6336
+ t: 'd'
6337
+ },
6338
+ formulaBarValue: `${padDatePart(hours)}:${padDatePart(minutes)}`,
6339
+ value: (60 * hours + minutes) / MINUTES_PER_DAY
6340
+ };
6341
+ }
6342
+ function createSpreadsheetDateTimeExtension() {
6343
+ return createOfficeEditorExtension({
6344
+ name: 'spreadsheetDateTime',
6345
+ addCommands: ()=>({
6346
+ insertCurrentDateTime: {
6347
+ canExecute: (context, kind)=>isSpreadsheetDateTimeKind(kind) && null !== spreadsheetDateTimeTarget(context),
6348
+ execute: insertCurrentSpreadsheetDateTime
6349
+ }
6350
+ }),
6351
+ addKeyboardShortcuts: ()=>({
6352
+ [spreadsheetCommandCatalog.insertCurrentDate.shortcut.editor["0"]]: ({ can, commands }, event)=>runSpreadsheetDateTimeShortcut(event, 'date', can.insertCurrentDateTime, commands.insertCurrentDateTime),
6353
+ [spreadsheetCommandCatalog.insertCurrentTime.shortcut.editor["0"]]: ({ can, commands }, event)=>runSpreadsheetDateTimeShortcut(event, 'time', can.insertCurrentDateTime, commands.insertCurrentDateTime)
6354
+ })
6355
+ });
6356
+ }
6357
+ function insertCurrentSpreadsheetDateTime(context, kind) {
6358
+ if (!isSpreadsheetDateTimeKind(kind)) return false;
6359
+ const target = spreadsheetDateTimeTarget(context);
6360
+ const entry = spreadsheetDateTimeEntry(kind, new Date());
6361
+ if (!target || !entry || !context.workbook) return false;
6362
+ try {
6363
+ context.workbook.batchCallApis([
6364
+ {
6365
+ name: 'setCellValuesByRange',
6366
+ args: [
6367
+ [
6368
+ [
6369
+ entry.value
6370
+ ]
6371
+ ],
6372
+ target.range,
6373
+ {
6374
+ id: target.sheetId
6375
+ }
6376
+ ]
6377
+ },
6378
+ {
6379
+ name: 'setCellFormatByRange',
6380
+ args: [
6381
+ 'ct',
6382
+ entry.format,
6383
+ target.range,
6384
+ {
6385
+ id: target.sheetId
6386
+ }
6387
+ ]
6388
+ }
6389
+ ]);
6390
+ } catch {
6391
+ return false;
6392
+ }
6393
+ try {
6394
+ context.formulaBar?.setValue(entry.formulaBarValue);
6395
+ } catch {}
6396
+ return true;
6397
+ }
6398
+ function spreadsheetDateTimeTarget(context) {
6399
+ const workbook = context.workbook;
6400
+ const sheetId = context.targetSheetId;
6401
+ if (!context.editable || !workbook || !sheetId || sheetId !== context.activeSheetId) return null;
6402
+ try {
6403
+ const selection = finiteSpreadsheetSelection(workbook.getSelection()?.at(-1) ?? context.fallbackRange);
6404
+ const row = selection.row_focus ?? selection.row[0] ?? 0;
6405
+ const column = selection.column_focus ?? selection.column[0] ?? 0;
6406
+ if (!Number.isSafeInteger(row) || row < 0 || row >= MAX_SPREADSHEET_ROWS || !Number.isSafeInteger(column) || column < 0 || column >= 16384) return null;
6407
+ const range = {
6408
+ row: [
6409
+ row,
6410
+ row
6411
+ ],
6412
+ column: [
6413
+ column,
6414
+ column
6415
+ ]
6416
+ };
6417
+ const sheet = context.content.sheets.find((candidate)=>candidate.id === sheetId);
6418
+ return canMutateSpreadsheetCellRange(sheet, range) ? {
6419
+ range,
6420
+ sheetId
6421
+ } : null;
6422
+ } catch {
6423
+ return null;
6424
+ }
6425
+ }
6426
+ function runSpreadsheetDateTimeShortcut(event, kind, canExecute, execute) {
6427
+ if (event.repeat || event.isComposing || isOfficeShortcutBlocked(event.target) || isSpreadsheetNativeTextUndoTarget(event.target) || !isSpreadsheetGridKeyboardTarget(event.target) || !canExecute(kind)) return false;
6428
+ return execute(kind);
6429
+ }
6430
+ function isSpreadsheetDateTimeKind(value) {
6431
+ return 'date' === value || 'time' === value;
6432
+ }
6433
+ function padDatePart(value, length = 2) {
6434
+ return String(value).padStart(length, '0');
6435
+ }
6039
6436
  function canApplySpreadsheetCellMerge(sheet, range, command) {
6040
6437
  if (!sheet) return false;
6041
6438
  const normalized = normalizeSpreadsheetCellMergeRange(range);
@@ -8368,12 +8765,14 @@ function createSpreadsheetEditorExtensions() {
8368
8765
  createSpreadsheetCellBorderExtension(),
8369
8766
  createSpreadsheetCellStyleExtension(),
8370
8767
  createSpreadsheetNumberFormatExtension(),
8768
+ createSpreadsheetDateTimeExtension(),
8371
8769
  createSpreadsheetNavigationExtension(),
8372
8770
  createSpreadsheetDataValidationExtension(),
8373
8771
  createSpreadsheetHyperlinkExtension(),
8374
8772
  createSpreadsheetTableExtension(),
8375
8773
  createSpreadsheetAutoSumExtension(),
8376
8774
  createSpreadsheetCellFillExtension(),
8775
+ createSpreadsheetCopyFromAboveExtension(),
8377
8776
  createSpreadsheetVisibilityShortcutExtension(),
8378
8777
  createOfficeEditorExtension({
8379
8778
  name: 'spreadsheetFormatPainter',
@@ -10721,6 +11120,73 @@ function SpreadsheetUnderlineGlyph({ style }) {
10721
11120
  })
10722
11121
  });
10723
11122
  }
11123
+ function SpreadsheetDateTimeMenu({ can, commands }) {
11124
+ const items = [
11125
+ {
11126
+ definition: spreadsheetCommandCatalog.insertCurrentDate,
11127
+ icon: /*#__PURE__*/ jsx(CalendarDays, {
11128
+ size: 16
11129
+ }),
11130
+ kind: 'date'
11131
+ },
11132
+ {
11133
+ definition: spreadsheetCommandCatalog.insertCurrentTime,
11134
+ icon: /*#__PURE__*/ jsx(Clock, {
11135
+ size: 16
11136
+ }),
11137
+ kind: 'time'
11138
+ }
11139
+ ];
11140
+ const disabled = items.every(({ kind })=>!can.insertCurrentDateTime(kind));
11141
+ return /*#__PURE__*/ jsx(Popover, {
11142
+ label: "日期和时间",
11143
+ panelLabel: "插入日期和时间",
11144
+ panelRole: "menu",
11145
+ portal: true,
11146
+ className: "work-spreadsheet-ribbon-menu-root",
11147
+ panelClassName: "work-office-context-menu work-spreadsheet-ribbon-menu",
11148
+ disabled: disabled,
11149
+ focusFirstOnOpen: true,
11150
+ onPanelKeyDown: moveOfficeMenuFocus,
11151
+ trigger: (triggerProps, { open })=>/*#__PURE__*/ jsxs("button", {
11152
+ ...triggerProps,
11153
+ className: `with-label work-spreadsheet-ribbon-menu-trigger work-spreadsheet-date-time-trigger${open ? ' active' : ''}`,
11154
+ title: "插入当前日期或时间(Ctrl+; / Ctrl+Shift+;)",
11155
+ children: [
11156
+ /*#__PURE__*/ jsx(CalendarClock, {
11157
+ size: 19
11158
+ }),
11159
+ /*#__PURE__*/ jsx("span", {
11160
+ children: "日期和时间"
11161
+ })
11162
+ ]
11163
+ }),
11164
+ children: (close)=>items.map(({ definition, icon, kind })=>/*#__PURE__*/ jsxs("button", {
11165
+ type: "button",
11166
+ role: "menuitem",
11167
+ tabIndex: -1,
11168
+ "aria-label": definition.label,
11169
+ "aria-keyshortcuts": definition.shortcut.aria,
11170
+ disabled: !can.insertCurrentDateTime(kind),
11171
+ onClick: ()=>{
11172
+ close();
11173
+ commands.insertCurrentDateTime(kind);
11174
+ },
11175
+ children: [
11176
+ /*#__PURE__*/ jsx("span", {
11177
+ className: "work-spreadsheet-ribbon-menu-item-icon",
11178
+ children: icon
11179
+ }),
11180
+ /*#__PURE__*/ jsx("span", {
11181
+ children: definition.label
11182
+ }),
11183
+ /*#__PURE__*/ jsx("kbd", {
11184
+ children: definition.shortcut.label
11185
+ })
11186
+ ]
11187
+ }, definition.id))
11188
+ });
11189
+ }
10724
11190
  const spreadsheetNumberFormatOptions = [
10725
11191
  {
10726
11192
  value: 'general',
@@ -10918,16 +11384,25 @@ function SpreadsheetNumberRibbonGroup({ can, commands, toolbarCell }) {
10918
11384
  label: "数字",
10919
11385
  priority: "high",
10920
11386
  children: [
10921
- /*#__PURE__*/ jsx(OfficeSelect, {
10922
- className: "work-spreadsheet-number-format",
10923
- ariaLabel: "数字格式",
10924
- value: numberFormatPreset,
10925
- disabled: !can.setCellFormat('ct', currentNumberFormatValue),
10926
- options: spreadsheetNumberFormatOptions,
10927
- onValueChange: (preset)=>{
10928
- if ('custom' === preset) return;
10929
- commands.setCellFormat('ct', spreadsheetNumberFormatValue(spreadsheetNumberFormatCode(preset), toolbarCell));
10930
- }
11387
+ /*#__PURE__*/ jsxs("div", {
11388
+ className: "work-spreadsheet-number-format-stack",
11389
+ children: [
11390
+ /*#__PURE__*/ jsx(OfficeSelect, {
11391
+ className: "work-spreadsheet-number-format",
11392
+ ariaLabel: "数字格式",
11393
+ value: numberFormatPreset,
11394
+ disabled: !can.setCellFormat('ct', currentNumberFormatValue),
11395
+ options: spreadsheetNumberFormatOptions,
11396
+ onValueChange: (preset)=>{
11397
+ if ('custom' === preset) return;
11398
+ commands.setCellFormat('ct', spreadsheetNumberFormatValue(spreadsheetNumberFormatCode(preset), toolbarCell));
11399
+ }
11400
+ }),
11401
+ /*#__PURE__*/ jsx(SpreadsheetDateTimeMenu, {
11402
+ can: can,
11403
+ commands: commands
11404
+ })
11405
+ ]
10931
11406
  }),
10932
11407
  /*#__PURE__*/ jsx(WorkOfficeRibbonButton, {
10933
11408
  label: `${currencyDefinition.label}格式`,
@@ -13784,81 +14259,6 @@ function formatCellsSelectionDescription(source) {
13784
14259
  const columns = source.range.column[1] - source.range.column[0] + 1;
13785
14260
  return `设置当前选区的数字、对齐、字体、边框、填充和保护属性(${rows} 行 × ${columns} 列)。`;
13786
14261
  }
13787
- const MAX_SPREADSHEET_ROWS = 1048576;
13788
- const spreadsheetPasteContentOptions = [
13789
- {
13790
- value: 'all',
13791
- label: '全部',
13792
- richOnly: false
13793
- },
13794
- {
13795
- value: 'formulas',
13796
- label: '公式',
13797
- richOnly: false
13798
- },
13799
- {
13800
- value: 'values',
13801
- label: '值',
13802
- richOnly: false
13803
- },
13804
- {
13805
- value: 'formats',
13806
- label: '格式',
13807
- richOnly: true
13808
- },
13809
- {
13810
- value: 'comments',
13811
- label: '批注',
13812
- richOnly: true
13813
- },
13814
- {
13815
- value: 'validation',
13816
- label: '数据验证',
13817
- richOnly: true
13818
- },
13819
- {
13820
- value: 'all-except-borders',
13821
- label: '边框除外的全部',
13822
- richOnly: true
13823
- },
13824
- {
13825
- value: 'formulas-and-number-formats',
13826
- label: '公式和数字格式',
13827
- richOnly: true
13828
- },
13829
- {
13830
- value: 'values-and-number-formats',
13831
- label: '值和数字格式',
13832
- richOnly: true
13833
- },
13834
- {
13835
- value: 'column-widths',
13836
- label: '列宽',
13837
- richOnly: true
13838
- }
13839
- ];
13840
- const spreadsheetPasteOperationOptions = [
13841
- {
13842
- value: 'none',
13843
- label: '无'
13844
- },
13845
- {
13846
- value: 'add',
13847
- label: '加'
13848
- },
13849
- {
13850
- value: 'subtract',
13851
- label: '减'
13852
- },
13853
- {
13854
- value: 'multiply',
13855
- label: '乘'
13856
- },
13857
- {
13858
- value: 'divide',
13859
- label: '除'
13860
- }
13861
- ];
13862
14262
  function captureSpreadsheetClipboardSnapshot(content, sheetId, selection, plainText) {
13863
14263
  const range = spreadsheet_cell_range_normalizeSpreadsheetCellRange(selection);
13864
14264
  const sheet = content.sheets.find((candidate)=>candidate.id === sheetId);
@@ -23982,12 +24382,14 @@ function spreadsheetCommandsWithGridFocus(commands, restoreFocus) {
23982
24382
  activateFormatPainter: afterSuccessfulCommand(commands.activateFormatPainter),
23983
24383
  cancelFormatPainter: afterSuccessfulCommand(commands.cancelFormatPainter),
23984
24384
  clearSelectedCells: afterSuccessfulCommand(commands.clearSelectedCells),
24385
+ copyCellFromAbove: afterSuccessfulCommand(commands.copyCellFromAbove),
23985
24386
  copySelection: afterSuccessfulCommand(commands.copySelection),
23986
24387
  convertTableToRange: afterSuccessfulCommand(commands.convertTableToRange),
23987
24388
  cutSelection: afterSuccessfulCommand(commands.cutSelection),
23988
24389
  deleteSelectedStructure: afterSuccessfulCommand(commands.deleteSelectedStructure),
23989
24390
  fillSelectedCells: afterSuccessfulCommand(commands.fillSelectedCells),
23990
24391
  insertSelectedStructure: afterSuccessfulCommand(commands.insertSelectedStructure),
24392
+ insertCurrentDateTime: afterSuccessfulCommand(commands.insertCurrentDateTime),
23991
24393
  mergeSelectedCells: afterSuccessfulCommand(commands.mergeSelectedCells),
23992
24394
  openPasteSpecial: afterSuccessfulCommand(commands.openPasteSpecial),
23993
24395
  pasteSelection: afterSuccessfulCommand(commands.pasteSelection),