ooxml-ui 1.2.0 → 1.4.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.
Files changed (156) hide show
  1. package/custom-elements.json +262 -2
  2. package/dist/chrome/find-bar.d.ts +85 -0
  3. package/dist/chrome/find-bar.d.ts.map +1 -1
  4. package/dist/chrome/find-replace-fields.d.ts +21 -0
  5. package/dist/chrome/find-replace-fields.d.ts.map +1 -0
  6. package/dist/{chunk-XNCWB2X6.js → chunk-2WLRFPMW.js} +4 -0
  7. package/dist/{chunk-JAJFLFAV.js → chunk-56A2JK63.js} +1 -1
  8. package/dist/{chunk-7FNDOWTX.js → chunk-BOIZWKM7.js} +226 -53
  9. package/dist/{chunk-YK2DPYMU.js → chunk-IY7QJLQG.js} +1 -1
  10. package/dist/{chunk-AYXFLBSV.js → chunk-L4XGRNHF.js} +6 -6
  11. package/dist/{chunk-BOX43CZD.js → chunk-M6GF5ED2.js} +2 -1
  12. package/dist/{chunk-Y2E22JVO.js → chunk-NYRRH2MD.js} +1 -1
  13. package/dist/{chunk-YP5S7DTT.js → chunk-R3LV6SGC.js} +6 -5
  14. package/dist/{chunk-VUB44CAJ.js → chunk-TWQ45BFL.js} +1 -1
  15. package/dist/clipboard-worker.js +21 -0
  16. package/dist/controls.d.ts +5 -3
  17. package/dist/controls.d.ts.map +1 -1
  18. package/dist/controls.js +5 -5
  19. package/dist/docx/editor-chrome.d.ts +8 -1
  20. package/dist/docx/file-commands.d.ts +1 -1
  21. package/dist/docx/locales/en-app.d.ts +1 -0
  22. package/dist/docx/locales/en.d.ts +1 -0
  23. package/dist/docx/localization-strings.d.ts +1 -0
  24. package/dist/docx/ribbon-actions.d.ts +22 -0
  25. package/dist/docx/title-bar.d.ts +3 -5
  26. package/dist/docx.js +66 -46
  27. package/dist/icons.d.ts.map +1 -1
  28. package/dist/icons.js +1 -1
  29. package/dist/index.d.ts +1 -1
  30. package/dist/index.js +9 -9
  31. package/dist/keytips.d.ts.map +1 -1
  32. package/dist/menu/menu-button.d.ts +11 -1
  33. package/dist/menu/menu-button.d.ts.map +1 -1
  34. package/dist/pptx/{chart-3d-view-scene-6B5TOWB6.mjs → chart-3d-view-scene-OYJ4CDCO.mjs} +3 -4
  35. package/dist/pptx/{chart-3d-view-scene-MJ6YNT56.cjs → chart-3d-view-scene-SE2Y6QRE.cjs} +38 -39
  36. package/dist/pptx/{chunk-AWKKC3VW.mjs → chunk-CIVA3MLN.mjs} +1 -1
  37. package/dist/pptx/{chunk-ZK344LOB.cjs → chunk-FPE5PZMI.cjs} +303 -155
  38. package/dist/pptx/{chunk-YRHK45AB.cjs → chunk-IURZJAWP.cjs} +233 -127
  39. package/dist/pptx/{chunk-XIQMFSNG.cjs → chunk-KRMMJUCO.cjs} +83 -1
  40. package/dist/pptx/{chunk-YI5LH5NN.mjs → chunk-MWHGUEIJ.mjs} +162 -16
  41. package/dist/pptx/{chunk-XQVKQD5Z.mjs → chunk-STLXPKJJ.mjs} +230 -128
  42. package/dist/pptx/{chunk-YMTQLZ2I.mjs → chunk-TC7HCF5M.mjs} +76 -2
  43. package/dist/pptx/{chunk-STKGUT5S.cjs → chunk-WKLHJEPD.cjs} +13 -13
  44. package/dist/pptx/dom/element-styles.d.ts.map +1 -1
  45. package/dist/pptx/dom/elements/connector.d.ts.map +1 -1
  46. package/dist/pptx/dom/elements/shape-filter-defs.d.ts.map +1 -1
  47. package/dist/pptx/dom/elements/table.d.ts.map +1 -1
  48. package/dist/pptx/dom/index.cjs +254 -254
  49. package/dist/pptx/dom/index.mjs +26 -26
  50. package/dist/pptx/dom/slide-stage.d.ts.map +1 -1
  51. package/dist/pptx/export/html2canvas-clone.cjs +2 -2
  52. package/dist/pptx/export/html2canvas-clone.mjs +1 -1
  53. package/dist/pptx/index.cjs +3041 -3001
  54. package/dist/pptx/index.mjs +4 -4
  55. package/dist/pptx/render/chart-3d-oblique-layout.d.ts.map +1 -1
  56. package/dist/pptx/render/chart-3d-persp-bars.d.ts.map +1 -1
  57. package/dist/pptx/render/chart-3d-persp-layout.d.ts.map +1 -1
  58. package/dist/pptx/render/chart-bar-cluster-geometry.d.ts +1 -1
  59. package/dist/pptx/render/chart-bar-cluster-geometry.d.ts.map +1 -1
  60. package/dist/pptx/render/chart-cartesian-area.d.ts.map +1 -1
  61. package/dist/pptx/render/chart-cartesian-bars.d.ts.map +1 -1
  62. package/dist/pptx/render/chart-cartesian-line-area.d.ts.map +1 -1
  63. package/dist/pptx/render/chart-cartesian-stacked-labels.d.ts +11 -7
  64. package/dist/pptx/render/chart-cartesian-stacked-labels.d.ts.map +1 -1
  65. package/dist/pptx/render/chart-combo-stock.cjs +3 -3
  66. package/dist/pptx/render/chart-combo-stock.mjs +1 -1
  67. package/dist/pptx/render/chart-data-label-anchor.d.ts +4 -1
  68. package/dist/pptx/render/chart-data-label-anchor.d.ts.map +1 -1
  69. package/dist/pptx/render/chart-horizontal-bars.d.ts.map +1 -1
  70. package/dist/pptx/render/chart-line-path.d.ts +9 -0
  71. package/dist/pptx/render/chart-line-path.d.ts.map +1 -1
  72. package/dist/pptx/render/chart-overlays.cjs +7 -7
  73. package/dist/pptx/render/chart-overlays.mjs +1 -1
  74. package/dist/pptx/render/chart-plot-clip.d.ts +37 -0
  75. package/dist/pptx/render/chart-plot-clip.d.ts.map +1 -0
  76. package/dist/pptx/render/chart-surface-treemap.cjs +4 -4
  77. package/dist/pptx/render/chart-surface-treemap.mjs +1 -1
  78. package/dist/pptx/render/chart-view-model-bars.d.ts +3 -2
  79. package/dist/pptx/render/chart-view-model-bars.d.ts.map +1 -1
  80. package/dist/pptx/render/chart-view-model.cjs +44 -44
  81. package/dist/pptx/render/chart-view-model.mjs +1 -1
  82. package/dist/pptx/render/chart-waterfall-map.cjs +6 -6
  83. package/dist/pptx/render/chart-waterfall-map.mjs +1 -1
  84. package/dist/pptx/render/device-pixel-stroke.d.ts +101 -0
  85. package/dist/pptx/render/device-pixel-stroke.d.ts.map +1 -0
  86. package/dist/pptx/render/export-clone.d.ts +4 -0
  87. package/dist/pptx/render/export-clone.d.ts.map +1 -1
  88. package/dist/pptx/render/foreign-object-svg-document.d.ts.map +1 -1
  89. package/dist/pptx/render/index.d.ts +2 -0
  90. package/dist/pptx/render/index.d.ts.map +1 -1
  91. package/dist/pptx/render/stroke-outline.d.ts +6 -0
  92. package/dist/pptx/render/stroke-outline.d.ts.map +1 -1
  93. package/dist/pptx/render/stroke-style.d.ts +8 -2
  94. package/dist/pptx/render/stroke-style.d.ts.map +1 -1
  95. package/dist/pptx/render/tab-row-actions.d.ts +40 -0
  96. package/dist/pptx/render/tab-row-actions.d.ts.map +1 -0
  97. package/dist/pptx/render/table-style-borders.d.ts.map +1 -1
  98. package/dist/pptx/render/table-style.d.ts.map +1 -1
  99. package/dist/pptx/web-components/index.d.ts.map +1 -1
  100. package/dist/pptx/web-components/office-token-bridge.d.ts +1 -1
  101. package/dist/pptx/web-components/office-token-bridge.d.ts.map +1 -1
  102. package/dist/pptx/web-components/ribbon-actions.d.ts +8 -0
  103. package/dist/pptx/web-components/ribbon-actions.d.ts.map +1 -0
  104. package/dist/presence.js +3 -3
  105. package/dist/ribbon/ribbon-actions.d.ts +119 -0
  106. package/dist/ribbon/ribbon-actions.d.ts.map +1 -0
  107. package/dist/smartart.js +3 -3
  108. package/dist/teams.js +7 -7
  109. package/dist/theme.js +2 -2
  110. package/dist/tokens.d.ts +4 -0
  111. package/dist/tokens.d.ts.map +1 -1
  112. package/dist/visio/binding.d.ts +10 -2
  113. package/dist/visio/clipboard-capture.d.ts +39 -0
  114. package/dist/visio/clipboard-worker.d.ts +1 -0
  115. package/dist/visio/controller.d.ts +45 -8
  116. package/dist/visio/creation-token.d.ts +26 -0
  117. package/dist/visio/index.d.ts +3 -1
  118. package/dist/visio/replacement-token.d.ts +56 -0
  119. package/dist/visio/ribbon-action.d.ts +61 -2
  120. package/dist/visio/ribbon-parts.d.ts +3 -2
  121. package/dist/visio/ribbon-router.d.ts +14 -1
  122. package/dist/visio/ribbon-style-options.d.ts +5 -0
  123. package/dist/visio/viewer-arrangement.d.ts +13 -0
  124. package/dist/visio/viewer-backstage.d.ts +1 -0
  125. package/dist/visio/viewer-clipboard.d.ts +21 -0
  126. package/dist/visio/viewer-commands.d.ts +5 -0
  127. package/dist/visio/viewer-draw-tool.d.ts +9 -29
  128. package/dist/visio/viewer-drawing-gesture.d.ts +36 -0
  129. package/dist/visio/viewer-duplication.d.ts +11 -0
  130. package/dist/visio/viewer-element.d.ts +11 -1
  131. package/dist/visio/viewer-formatting.d.ts +12 -0
  132. package/dist/visio/viewer-gesture-overlays.d.ts +2 -0
  133. package/dist/visio/viewer-handle-events.d.ts +3 -0
  134. package/dist/visio/viewer-layers.d.ts +1 -2
  135. package/dist/visio/viewer-movement-preview.d.ts +7 -0
  136. package/dist/visio/viewer-new-drawing.d.ts +5 -0
  137. package/dist/visio/viewer-page-point.d.ts +6 -0
  138. package/dist/visio/viewer-paint-dialog.d.ts +28 -0
  139. package/dist/visio/viewer-paint-menu.d.ts +4 -0
  140. package/dist/visio/viewer-paint-properties.d.ts +13 -0
  141. package/dist/visio/viewer-pointer-gestures.d.ts +14 -0
  142. package/dist/visio/viewer-replace-status.d.ts +6 -0
  143. package/dist/visio/viewer-replace.d.ts +14 -0
  144. package/dist/visio/viewer-resize-frame.d.ts +9 -0
  145. package/dist/visio/viewer-resize-handles.d.ts +14 -0
  146. package/dist/visio/viewer-search.d.ts +15 -0
  147. package/dist/visio/viewer-size-position.d.ts +13 -0
  148. package/dist/visio/viewer-text-draft.d.ts +9 -0
  149. package/dist/visio/viewer-text-tool.d.ts +17 -0
  150. package/dist/visio/worker-clipboard.d.ts +16 -0
  151. package/dist/visio.js +5953 -2623
  152. package/dist/xlsx/calc-preparation.d.ts +44 -0
  153. package/dist/xlsx/editor-core.d.ts +3 -0
  154. package/dist/xlsx/ribbon-actions.d.ts +5 -4
  155. package/dist/xlsx.js +131 -44
  156. package/package.json +2 -2
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Builds the open workbook's formula dependency graph while the editor is idle. Opening a large
3
+ * workbook paints without it, and without this the first edit would wait for every formula to be
4
+ * parsed and indexed (half a second on a 66,000-formula workbook). After the first paint the work
5
+ * runs in `requestIdleCallback` slices of at most 8 ms (a `setTimeout` fallback elsewhere),
6
+ * pauses while the user types, scrolls or edits a cell, and stops when another workbook loads.
7
+ * An edit made before it finishes is still correct: the core completes what is left first.
8
+ */
9
+ import type { EditSession } from 'ooxml-core/xlsx';
10
+ /** The longest slice of work, so a frame is never held up noticeably. */
11
+ export declare const SLICE_MS = 8;
12
+ /** How long after the last key, wheel or pointer event the work stays paused. */
13
+ export declare const QUIET_MS = 250;
14
+ /** What a slice is told about the time it has (the part of `IdleDeadline` used here). */
15
+ export interface IdleTime {
16
+ timeRemaining(): number;
17
+ }
18
+ /** The timers the preparation runs on (the window's, replaced in tests). */
19
+ export interface IdleScheduler {
20
+ now(): number;
21
+ idle(run: (deadline: IdleTime) => void): () => void;
22
+ later(run: () => void, ms: number): () => void;
23
+ /** Runs `run` once the next frame has been painted. */
24
+ afterPaint(run: () => void): () => void;
25
+ }
26
+ export declare function windowScheduler(view: (Window & typeof globalThis) | null): IdleScheduler;
27
+ export declare class CalcPreparation {
28
+ /** True while a cell is being edited: no slice runs then. */
29
+ private readonly busy;
30
+ private readonly scheduler;
31
+ private session;
32
+ private cancel;
33
+ private lastActivity;
34
+ constructor(host: HTMLElement,
35
+ /** True while a cell is being edited: no slice runs then. */
36
+ busy: () => boolean, scheduler?: IdleScheduler);
37
+ /** Prepares `session` (the workbook just opened) after the next paint; stops earlier work. */
38
+ start(session: EditSession | undefined): void;
39
+ stop(): void;
40
+ /** Whether work is still waiting (tests and diagnostics). */
41
+ get pending(): boolean;
42
+ private next;
43
+ private slice;
44
+ }
@@ -11,6 +11,7 @@ import { type DialogRegistry } from 'ooxml-core/xlsx/ui';
11
11
  import { DirtyState } from 'ooxml-core/xlsx/ui';
12
12
  import { type EditorLocale } from 'ooxml-core/xlsx/ui';
13
13
  import type { CalculationMode } from './backstage/index.js';
14
+ import { CalcPreparation } from './calc-preparation.js';
14
15
  import { type XlsxCollaboration } from './collaboration.js';
15
16
  import type { EditorThemeMode, XlsxTheme } from './theme/index.js';
16
17
  /** What the shell exposes back to the core (filled in when the element connects). */
@@ -44,6 +45,8 @@ export declare class EditorCore {
44
45
  readonly ctx: EditorContext;
45
46
  /** Co-editing over `ooxml-core/collab`; undo and redo go through it while shared. */
46
47
  readonly collab: XlsxCollaboration;
48
+ /** Builds the formula graph in idle time after a workbook opens. */
49
+ readonly calcPreparation: CalcPreparation;
47
50
  private gridController;
48
51
  private readonly modelListeners;
49
52
  private stopSession;
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * The controls at the right end of Excel's ribbon tab row: the Editing / Viewing selector, the
3
- * Comments toggle and Share, in that order, as Excel 365 places them. They sit in the shared
4
- * ribbon's `actions` slot; the title bar keeps the file name, search and the people in a shared
5
- * session.
3
+ * Comments toggle and Share, in that order, as Excel 365 places them. The shared
4
+ * `office-ui-ribbon-actions` element draws them (Word uses the same one) in the shared ribbon's
5
+ * `actions` slot; the title bar keeps the file name, search and the people in a shared session.
6
6
  */
7
7
  import type { EditorContext } from 'ooxml-core/xlsx/ui';
8
+ import { type OfficeUiRibbonActions } from '../ribbon/ribbon-actions.js';
8
9
  import type { XlsxCollaborationState } from './collaboration-types.js';
9
10
  export interface RibbonActionsHandlers {
10
11
  setReadOnly(readOnly: boolean): void;
@@ -13,7 +14,7 @@ export interface RibbonActionsHandlers {
13
14
  collaboration?(): XlsxCollaborationState;
14
15
  }
15
16
  export interface RibbonActions {
16
- readonly element: HTMLElement;
17
+ readonly element: OfficeUiRibbonActions;
17
18
  /** Re-reads read-only, sharing and the comments pane state. */
18
19
  refresh(): void;
19
20
  relocalize(): void;
package/dist/xlsx.js CHANGED
@@ -1,24 +1,24 @@
1
- import './chunk-YP5S7DTT.js';
2
- import { defineSmartArt } from './chunk-Y2E22JVO.js';
3
- import { withExtension, saveExtension, downloadBytes, emit, emitEvent, blobFor, announceFileCommand, pickFile } from './chunk-AYXFLBSV.js';
4
- export { XLSX_EDITOR_EVENTS } from './chunk-AYXFLBSV.js';
1
+ import './chunk-R3LV6SGC.js';
2
+ import { defineSmartArt } from './chunk-NYRRH2MD.js';
3
+ import { withExtension, saveExtension, downloadBytes, emit, emitEvent, blobFor, announceFileCommand, pickFile } from './chunk-L4XGRNHF.js';
4
+ export { XLSX_EDITOR_EVENTS } from './chunk-L4XGRNHF.js';
5
5
  import './chunk-SNV6YKPC.js';
6
- import { shadcnBridge } from './chunk-JAJFLFAV.js';
7
- import { range_control_default, createRibbonOverflow, defineBackstage, defineRibbon, defineTitleBar, defineStatusBar, defineZoomSlider, rangeControl, defineDialog, runKeyTips, assignKeyTips, defineCheckbox, defineGallery, defineContextMenu, defineCommentsPane, parseSvgPreview } from './chunk-7FNDOWTX.js';
8
- import { getIcon, registerIcon } from './chunk-BOX43CZD.js';
9
- import { definePresence } from './chunk-VUB44CAJ.js';
10
- import { withTokens } from './chunk-YK2DPYMU.js';
11
- import './chunk-XNCWB2X6.js';
6
+ import { shadcnBridge } from './chunk-56A2JK63.js';
7
+ import { range_control_default, createRibbonOverflow, defineBackstage, defineRibbon, defineRibbonActions, defineTitleBar, defineStatusBar, defineZoomSlider, rangeControl, defineDialog, runKeyTips, assignKeyTips, defineCheckbox, defineGallery, defineContextMenu, defineCommentsPane, parseSvgPreview } from './chunk-BOIZWKM7.js';
8
+ import { getIcon, registerIcon } from './chunk-M6GF5ED2.js';
9
+ import { definePresence } from './chunk-TWQ45BFL.js';
10
+ import { withTokens } from './chunk-IY7QJLQG.js';
11
+ import './chunk-2WLRFPMW.js';
12
12
  import { SPECIAL_CODES, FRACTION_CODES, AUTOSUM_FUNCTIONS, themeToCssVars, lightTheme, darkTheme, ICON_ACCENTS, ICON_PATHS, normalizeThemeMode, applyThemeColors, parseSelectionRef, selectionRef, normalizeEditorLocale, DirtyState, createCommandRegistry, createDialogRegistry, activeRef, createSelectionModel, SheetSelections, translator, initialSelection, sheetBaseName, historyOf, onRibbonTabsChange, activeChart, editChart, ribbonTabs, isTabHidden, selectTab, setTabHidden, tabButton, searchCommands, formatNumber, TEMPLATES, createTemplateWorkbook, isMenuSeparator, registerRibbonTabs, installFormatPainter, SHEET_ICONS, clipboardCommands, fontCommands, alignmentCommands, numberCommands, cellCommands, editingCommands, pageLayoutCommands, formulaCommands, dataCommands, contextualCommands, reviewTab, viewTab, helpTab, editBridge, CellViewCache, QUADRANTS, columnHeaderHeight, rowHeaderWidth, GridGeometry, cellRange, scrollToReveal, buildItems, fitNumber, cssFont, clampAddress, selectCell, movingEnd, extendSelection, moveWithinSelection, rowsRange, colsRange, ALL_RANGE, tabMenu, editing, icon, DATA_BAR_COLORS, dataBarRule, COLOR_SCALES, colorScaleRule, iconSetRule, target, tableAt, viewing, activeTable, numberFormatOptions, FONT_NAMES, FONT_SIZES, BORDER_PRESETS, ORIENTATIONS, ACCOUNTING_FORMATS, themePaletteItems, MARGIN_PRESETS, PAPER_SIZES, FUNCTION_MENUS, MORE_FUNCTION_CATEGORIES, functionsIn, isSingleCell, spanRange, selectionCellCount, addRange, activeStyle, selectSpecial, insertFunctionCall, guessHeader, regionOf, HIGHLIGHT_STYLES, ICON_SETS, TABLE_STYLES, tableStylePreview, resolveNameBox, absoluteReference, nameForRange, fillPaint, iconSvg, colSelected, rowSelected, rowHeaderMenu, columnHeaderMenu, cellMenu, recentFunctions, evaluateRef, buildChart, detectCategory, CATEGORIES, TIME_CODES, DATE_CODES, DEFAULT_OPTIONS, cellStyleItems, textDecoration, justify, alignItems, textAlign, hasBorders, edgeCss, diagonalSvg, SYMBOLS, buildCode, UNSET, dxfCss, negativeCodes, iconCount, iconThresholds, rowsOf, colsOf } from 'ooxml-core/xlsx/ui';
13
13
  export { EDITOR_LOCALES, THEME_KEYS, normalizeEditorLocale, registerRibbonTabs, themeToCssVars, darkTheme as xlsxDarkTheme, lightTheme as xlsxLightTheme } from 'ooxml-core/xlsx/ui';
14
- import { createWorksheet, createEditSession, approximateMeasure, createWorkbook, MAX_ROW, MAX_COL, chartView, createRefEvaluator, chartBarSpacing, CHART_FILL_PARTS, selectionStats, formatRange, chartSeriesTransparencyPatch, chartSeriesTransparency, chartSeriesGradientPatch, chartSeriesSolidFillPatch, chartSeriesFillPatch, chartWithElementFills, chartElementTransparencyPatch, chartElementTransparency, chartElementGradientPatch, chartElementSolidFillPatch, chartElementFillPatch, chartElementFill, usedRange, chartGradientStopTransparency, createGridMetrics, mergeView, cellView, DEFAULT_THEME, resolveColor, nextSheetName, FUNCTION_CATALOG, mergeAt, visibleCells, getCell, cellInputText, closeParens, isFormulaText, parseCellInput, referenceTarget, formatAddress, navigate, anchorToPixelBox, renderChartSvg, pixelBoxToAnchor, listValidationOptions, validationAt, getValue, resolvePasteOptions, DEFAULT_COL_WIDTH, nameAtCaret, functionMatches, callAtCaret, splice, acceptsReference, translateFormula, isCellError, layoutRemoteSelections, parseHtmlTable, toggleAbsolute, rangeContains, formatValue, isDateFormat, pictureAnchorAt, validateDefinedName, parseAddress, styleAt, parseRange, rangesIntersect, chartColorScheme, coloredReferences, syntaxParams, activeParam, columnLabel, THEME_SLOTS, normalizeRange, currentRegion, autoFitColumnWidth, validateSheetName, dateToSerial, IMAGE_EXTENSIONS, verifySheetPassword, verifyWorkbookPassword, sheetByName, quoteSheetName, serialToDate, BUILTIN_NUMBER_FORMATS, pixelsToColumnWidth, validateTableName } from 'ooxml-core/xlsx';
14
+ import { createWorksheet, createEditSession, approximateMeasure, createWorkbook, MAX_ROW, MAX_COL, chartView, createRefEvaluator, chartBarSpacing, CHART_FILL_PARTS, selectionStats, formatSelectionStat, formatRange, chartSeriesTransparencyPatch, chartSeriesTransparency, chartSeriesGradientPatch, chartSeriesSolidFillPatch, chartSeriesFillPatch, chartWithElementFills, chartElementTransparencyPatch, chartElementTransparency, chartElementGradientPatch, chartElementSolidFillPatch, chartElementFillPatch, chartElementFill, usedRange, chartGradientStopTransparency, createGridMetrics, mergeView, cellView, DEFAULT_THEME, resolveColor, nextSheetName, FUNCTION_CATALOG, mergeAt, visibleCells, getCell, cellInputText, closeParens, isFormulaText, parseCellInput, referenceTarget, formatAddress, navigate, anchorToPixelBox, renderChartSvg, pixelBoxToAnchor, listValidationOptions, validationAt, getValue, resolvePasteOptions, DEFAULT_COL_WIDTH, nameAtCaret, functionMatches, callAtCaret, splice, acceptsReference, translateFormula, isCellError, layoutRemoteSelections, parseHtmlTable, toggleAbsolute, rangeContains, formatValue, isDateFormat, pictureAnchorAt, validateDefinedName, parseAddress, styleAt, parseRange, rangesIntersect, chartColorScheme, coloredReferences, syntaxParams, activeParam, columnLabel, THEME_SLOTS, normalizeRange, currentRegion, autoFitColumnWidth, validateSheetName, dateToSerial, IMAGE_EXTENSIONS, verifySheetPassword, verifyWorkbookPassword, sheetByName, quoteSheetName, serialToDate, BUILTIN_NUMBER_FORMATS, pixelsToColumnWidth, validateTableName } from 'ooxml-core/xlsx';
15
15
  import { hyperlinkPolicy } from 'ooxml-core/opc';
16
16
  import { resolveChartGradient, sortGradientStops, withChartGradientDirection, buildChartGradientDef, chartGradientMarkup, CHART_COLOR_PALETTES, chartPaletteColors } from 'ooxml-core/chart';
17
17
  import { render } from 'lit';
18
18
  import { RECT_GRADIENT_DIRECTIONS, OFFICE_GRADIENT_PRESETS, officeGradientPresetId, officeGradientPresetFill, resolveDrawingColor, drawingColorBrightness, drawingColorCss, rectGradientDirection } from 'ooxml-core/diagram';
19
19
 
20
20
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/xlsx/theme/shell.css?raw
21
- var shell_default = "/* Frame, title bar and status bar. Mirrors docx-viewer's chrome (styles/base.css,\n chrome-titlebar.css, status-dialogs.css) with --xve-* tokens. */\n:host {\n --xl: var(--xve-primary);\n --xl-strong: color-mix(in srgb, var(--xve-primary) 70%, #000);\n --xl-soft: color-mix(in srgb, var(--xve-primary) 12%, transparent);\n --accent-soft: var(--xl-soft);\n --ink: var(--xve-foreground);\n --muted: var(--xve-muted-foreground);\n --line: var(--xve-border);\n --surface: var(--xve-card);\n --chrome: var(--xve-background);\n display: block;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n min-height: 0;\n color: var(--ink);\n font:\n 13px/1.35 'Segoe UI',\n Arial,\n sans-serif;\n}\n.xve-frame {\n position: relative;\n display: flex;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n min-height: 0;\n min-width: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--surface);\n}\n:focus-visible {\n outline: 2px solid var(--xve-ring);\n outline-offset: 1px;\n}\n[hidden],\n[data-xve-hidden] {\n display: none !important;\n}\n.xve-icon {\n flex: none;\n}\n.xve-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 28px;\n height: 28px;\n padding: 0 6px;\n border: 0;\n border-radius: 4px;\n background: none;\n color: inherit;\n font: inherit;\n cursor: pointer;\n}\n.xve-icon-button:hover:not(:disabled),\n.xve-icon-button[aria-pressed='true'] {\n background: var(--xl-soft);\n}\n.xve-icon-button:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n/* Workspace: formula bar, grid and sheet tabs between the ribbon and the status bar. */\n.xve-workspace {\n position: relative;\n display: flex;\n flex: 1;\n min-height: 0;\n min-width: 0;\n flex-direction: column;\n background: var(--xve-sheet-bg);\n}\n.xve-formula-row {\n flex: none;\n min-width: 0;\n border-bottom: 1px solid var(--line);\n background: var(--surface);\n}\n.xve-grid-host {\n position: relative;\n display: flex;\n flex: 1;\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n background: var(--xve-sheet-bg);\n color-scheme: light;\n}\n.xve-grid-host > * {\n flex: 1;\n min-width: 0;\n}\n.xve-tabs-row {\n flex: none;\n min-width: 0;\n border-top: 1px solid var(--line);\n background: var(--chrome);\n}\n.xve-empty {\n position: absolute;\n z-index: 5;\n inset: 0;\n display: grid;\n place-items: center;\n color: var(--muted);\n background: var(--chrome);\n}\n:host([show-formula-bar='false']) .xve-formula-row,\n:host([show-toolbar='false']) .xve-ribbon {\n display: none;\n}\n\n/* Title bar: drawn by the shared office-ui-title-bar; the mark, background and borders come from its tokens. */\n.xve-titlebar {\n display: block;\n flex: none;\n --office-title-bar-background: var(--chrome);\n --office-title-bar-foreground: var(--ink);\n --office-title-bar-border: var(--line);\n --office-title-bar-mark-background: var(--xl);\n --office-title-bar-mark-foreground: var(--xve-primary-foreground);\n}\n\n/* Ribbon tab row, right end (the shared ribbon's actions slot): Editing / Viewing, Comments and\n Share, as Excel 365 places them. */\n.xve-ribbon-actions {\n display: flex;\n align-items: center;\n gap: 6px;\n padding-inline-start: 8px;\n}\n.xve-mode {\n position: relative;\n display: inline-flex;\n align-items: center;\n height: 28px;\n border-radius: 4px;\n color: var(--ink);\n}\n.xve-mode > .ribbon-icon {\n position: absolute;\n inset-inline-start: 8px;\n pointer-events: none;\n}\n.xve-mode-select {\n height: 28px;\n padding: 0 6px 0 30px;\n border: 1px solid var(--line);\n border-radius: 4px;\n background: var(--surface);\n color: var(--ink);\n font: inherit;\n cursor: pointer;\n}\n.xve-comments-button {\n gap: 6px;\n border: 1px solid var(--line);\n}\n.xve-share-button {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 28px;\n padding: 0 12px;\n border: 1px solid var(--xl);\n border-radius: 4px;\n background: var(--xl);\n color: var(--xve-primary-foreground);\n font: inherit;\n cursor: pointer;\n}\n.xve-share-button:hover,\n.xve-share-button[aria-pressed='true'] {\n border-color: var(--xl-strong);\n background: var(--xl-strong);\n}\n.xve-mode-select:focus-visible,\n.xve-comments-button:focus-visible,\n.xve-share-button:focus-visible {\n outline: 2px solid var(--xl);\n outline-offset: 1px;\n}\n/* Narrow windows keep the icons and drop the labels, as Office's simplified layout does. */\n@media (max-width: 900px) {\n .xve-action-label {\n display: none;\n }\n}\n\n/* Status bar: drawn by the shared office-ui-status-bar; this places it and styles the slotted stats. */\n.xve-status {\n display: block;\n flex: none;\n min-width: 0;\n border-top: 1px solid var(--line);\n}\n.xve-status-stats {\n margin-inline-end: 10px;\n overflow: hidden;\n color: var(--ink);\n font-size: 11px;\n white-space: nowrap;\n}\n\n@media (max-width: 760px) {\n .xve-status-stats {\n display: none;\n }\n}\n";
21
+ var shell_default = "/* Frame, title bar and status bar. Mirrors docx-viewer's chrome (styles/base.css,\n chrome-titlebar.css, status-dialogs.css) with --xve-* tokens. */\n:host {\n --xl: var(--xve-primary);\n --xl-strong: color-mix(in srgb, var(--xve-primary) 70%, #000);\n --xl-soft: color-mix(in srgb, var(--xve-primary) 12%, transparent);\n --accent-soft: var(--xl-soft);\n --ink: var(--xve-foreground);\n --muted: var(--xve-muted-foreground);\n --line: var(--xve-border);\n --surface: var(--xve-card);\n --chrome: var(--xve-background);\n display: block;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n min-height: 0;\n color: var(--ink);\n font:\n 13px/1.35 'Segoe UI',\n Arial,\n sans-serif;\n}\n.xve-frame {\n position: relative;\n display: flex;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n min-height: 0;\n min-width: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--surface);\n}\n:focus-visible {\n outline: 2px solid var(--xve-ring);\n outline-offset: 1px;\n}\n[hidden],\n[data-xve-hidden] {\n display: none !important;\n}\n.xve-icon {\n flex: none;\n}\n.xve-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 28px;\n height: 28px;\n padding: 0 6px;\n border: 0;\n border-radius: 4px;\n background: none;\n color: inherit;\n font: inherit;\n cursor: pointer;\n}\n.xve-icon-button:hover:not(:disabled),\n.xve-icon-button[aria-pressed='true'] {\n background: var(--xl-soft);\n}\n.xve-icon-button:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n/* Workspace: formula bar, grid and sheet tabs between the ribbon and the status bar. */\n.xve-workspace {\n position: relative;\n display: flex;\n flex: 1;\n min-height: 0;\n min-width: 0;\n flex-direction: column;\n background: var(--xve-sheet-bg);\n}\n.xve-formula-row {\n flex: none;\n min-width: 0;\n border-bottom: 1px solid var(--line);\n background: var(--surface);\n}\n.xve-grid-host {\n position: relative;\n display: flex;\n flex: 1;\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n background: var(--xve-sheet-bg);\n color-scheme: light;\n}\n.xve-grid-host > * {\n flex: 1;\n min-width: 0;\n}\n.xve-tabs-row {\n flex: none;\n min-width: 0;\n border-top: 1px solid var(--line);\n background: var(--chrome);\n}\n.xve-empty {\n position: absolute;\n z-index: 5;\n inset: 0;\n display: grid;\n place-items: center;\n color: var(--muted);\n background: var(--chrome);\n}\n:host([show-formula-bar='false']) .xve-formula-row,\n:host([show-toolbar='false']) .xve-ribbon {\n display: none;\n}\n\n/* Title bar: drawn by the shared office-ui-title-bar; the mark, background and borders come from its tokens. */\n.xve-titlebar {\n display: block;\n flex: none;\n --office-title-bar-background: var(--chrome);\n --office-title-bar-foreground: var(--ink);\n --office-title-bar-border: var(--line);\n --office-title-bar-mark-background: var(--xl);\n --office-title-bar-mark-foreground: var(--xve-primary-foreground);\n}\n\n/* Status bar: drawn by the shared office-ui-status-bar; this places it and styles the slotted stats. */\n.xve-status {\n display: block;\n flex: none;\n min-width: 0;\n border-top: 1px solid var(--line);\n}\n.xve-status-stats {\n margin-inline-end: 10px;\n overflow: hidden;\n color: var(--ink);\n font-size: 11px;\n white-space: nowrap;\n}\n\n@media (max-width: 760px) {\n .xve-status-stats {\n display: none;\n }\n}\n";
22
22
 
23
23
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/xlsx/theme/ribbon.css?raw
24
24
  var ribbon_default = "/* Ribbon: tabs, panels, groups and controls. Mirrors docx-viewer's styles/ribbon*.css. */\n.xve-ribbon-gallery[data-office-gallery] .trigger {\n flex-direction: column;\n justify-content: center;\n min-width: 56px;\n height: 78px;\n white-space: normal;\n text-align: center;\n}\n.xve-ribbon-gallery[data-office-gallery] .trigger > svg {\n width: 28px;\n height: 28px;\n}\n.xve-ribbon-gallery[data-office-gallery] .trigger > span:not([aria-hidden]) {\n max-width: 56px;\n}\n.xve-ribbon {\n position: relative;\n display: flex;\n flex: none;\n min-width: 0;\n flex-direction: column;\n background: var(--surface);\n border-bottom: 1px solid var(--line);\n}\n/* The tab row, File button and collapse button are the shared office-ui-ribbon; these colour it. */\n.xve-ribbon {\n --office-ribbon-contextual: #0f7b6c;\n}\n.xve-ribbon::part(file) {\n font-weight: 600;\n}\n.ribbon-panel {\n display: flex;\n flex: none;\n box-sizing: border-box;\n height: 104px;\n min-width: 0;\n align-items: stretch;\n gap: 4px;\n padding: 6px 10px 4px;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: thin;\n}\n.ribbon-group {\n position: relative;\n display: flex;\n flex: 0 0 auto;\n align-items: flex-start;\n min-width: 0;\n gap: 2px;\n padding: 2px 10px 18px 2px;\n border-right: 1px solid var(--line);\n}\n.ribbon-group:last-child {\n border: 0;\n}\n.ribbon-group::after {\n position: absolute;\n right: 0;\n bottom: 2px;\n left: 0;\n color: var(--muted);\n font-size: 10px;\n line-height: 1.1;\n text-align: center;\n white-space: nowrap;\n content: attr(data-caption);\n}\n.ribbon-caption-sizer {\n position: absolute;\n visibility: hidden;\n font-size: 10px;\n white-space: nowrap;\n}\n.ribbon-stack {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n}\n.ribbon-stack > .ribbon-stack {\n flex-direction: row;\n align-items: center;\n}\n.ribbon-separator {\n align-self: stretch;\n width: 1px;\n margin: 2px 3px;\n background: var(--line);\n}\n.ribbon-stack > .ribbon-separator {\n width: auto;\n height: 1px;\n}\n.ribbon-stack > .ribbon-stack > .ribbon-separator {\n width: 1px;\n height: 20px;\n}\n\n/* Buttons */\n.ribbon-group button {\n flex: none;\n min-width: 28px;\n height: 28px;\n max-width: 100%;\n padding: 0 4px;\n overflow: hidden;\n border: 1px solid transparent;\n border-radius: 4px;\n background: transparent;\n color: var(--ink);\n font:\n 400 12px 'Segoe UI',\n Arial,\n sans-serif;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n}\n.ribbon-group button:hover:not(:disabled) {\n border-color: var(--line);\n background: var(--accent-soft);\n}\n.ribbon-group button[aria-pressed='true'],\n.ribbon-group button[aria-expanded='true'] {\n border-color: color-mix(in srgb, var(--xl) 45%, transparent);\n background: color-mix(in srgb, var(--xl) 20%, transparent);\n}\n.ribbon-group button:active:not(:disabled) {\n background: color-mix(in srgb, var(--xl) 28%, transparent);\n}\n.ribbon-group button:focus-visible {\n outline: 2px solid var(--xl);\n outline-offset: -2px;\n}\n.ribbon-group button:disabled,\n.ribbon-group input:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.ribbon-group button.ribbon-small {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n height: 24px;\n padding: 0 3px;\n}\n.ribbon-group button.ribbon-small.ribbon-labelled {\n justify-content: flex-start;\n padding: 0 6px 0 4px;\n}\n.ribbon-group button.ribbon-large {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-start;\n gap: 2px;\n width: auto;\n min-width: 48px;\n height: 76px;\n padding: 3px 3px 2px;\n font-size: 11px;\n line-height: 1.15;\n white-space: normal;\n text-align: center;\n}\n.ribbon-large > .ribbon-icon:last-child:not(:first-child) {\n margin-top: auto;\n}\n.ribbon-large > span,\n.ribbon-caption {\n /* Two balanced lines (see ribbon/caption.ts); the button grows to the widest. */\n white-space: pre;\n}\n.ribbon-icon {\n flex: none;\n}\n.ribbon-icon[data-icon$='-caret'],\n.ribbon-icon[data-icon='caret'] {\n opacity: 0.8;\n}\n\n/* Split buttons: a main half and a caret that opens a menu or the colour grid. */\n.ribbon-split {\n display: inline-flex;\n align-items: stretch;\n}\n.ribbon-split.ribbon-split-large {\n flex-direction: column;\n}\n.ribbon-group .ribbon-split > button:first-child {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.ribbon-group .ribbon-split > .ribbon-caret {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n min-width: 14px;\n padding: 0;\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.ribbon-group .ribbon-split-large > button:first-child {\n height: 46px;\n border-radius: 4px 4px 0 0;\n}\n.ribbon-group .ribbon-split-large > .ribbon-caret {\n width: auto;\n height: 26px;\n border-radius: 0 0 4px 4px;\n font-size: 11px;\n flex-direction: column;\n gap: 0;\n}\n.ribbon-color {\n position: relative;\n}\n.ribbon-group button.ribbon-color::after {\n position: absolute;\n right: 4px;\n bottom: 2px;\n left: 4px;\n height: 3px;\n background: var(--bar, transparent);\n outline: 1px solid var(--line);\n content: '';\n}\n\n/* Editable combo boxes (font name and size) and plain selects. */\n.ribbon-combo {\n display: inline-flex;\n align-items: stretch;\n height: 24px;\n border: 1px solid var(--line);\n border-radius: 3px;\n background: var(--surface);\n}\n.ribbon-combo:focus-within {\n border-color: var(--xl);\n outline: 1px solid var(--xl);\n}\n.ribbon-combo input {\n flex: 1;\n min-width: 0;\n padding: 0 6px;\n border: 0;\n background: transparent;\n color: var(--ink);\n font:\n 12px 'Segoe UI',\n Arial,\n sans-serif;\n outline: none;\n}\n.ribbon-group .ribbon-combo .ribbon-caret {\n width: 18px;\n min-width: 18px;\n height: 100%;\n padding: 0;\n border: 0;\n border-radius: 0;\n}\n\n/* Plain drop-downs (Number Format) and gallery previews. */\n.ribbon-group select.ribbon-select {\n height: 24px;\n padding: 0 6px;\n border: 1px solid var(--line);\n border-radius: 3px;\n background: var(--surface);\n color: var(--ink);\n font:\n 12px 'Segoe UI',\n Arial,\n sans-serif;\n text-overflow: ellipsis;\n}\n.ribbon-group select.ribbon-select:focus-visible {\n outline: 2px solid var(--xl);\n outline-offset: -1px;\n}\n.ribbon-gallery-preview {\n display: block;\n height: 36px;\n margin-bottom: 3px;\n border: 1px solid var(--line);\n border-radius: 2px;\n background: #fff;\n color: #1f1f1f;\n font-size: 11px;\n line-height: 36px;\n text-align: center;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.ribbon-gallery-preview > svg {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n/* Dialog launcher: the corner arrow of a group. */\n.ribbon-group button.ribbon-launcher {\n position: absolute;\n right: 2px;\n bottom: 0;\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n min-width: 14px;\n height: 14px;\n padding: 0;\n color: var(--muted);\n}\n\n/* Collapsed groups: a narrow ribbon folds its rightmost groups into one dropdown each. */\n.ribbon-group > .ribbon-overflow-button {\n display: none;\n}\n.ribbon-group[data-collapsed] {\n padding-right: 4px;\n}\n.ribbon-group[data-collapsed] > :not(.ribbon-overflow-button) {\n display: none !important;\n}\n.ribbon-group[data-collapsed] > button.ribbon-overflow-button {\n display: flex;\n}\n.ribbon-group[data-collapsed]::after {\n display: none;\n}\n.ribbon-overflow-panel .ribbon-group {\n height: 84px;\n padding-right: 2px;\n border: 0;\n}\n\n/* KeyTips */\n.xve-keytip {\n position: absolute;\n bottom: -2px;\n left: 50%;\n z-index: 70;\n min-width: 16px;\n padding: 1px 4px;\n border: 1px solid var(--line);\n border-radius: 3px;\n background: #1f1f1f;\n color: #fff;\n font:\n 600 11px/14px 'Segoe UI',\n Arial,\n sans-serif;\n text-align: center;\n pointer-events: none;\n transform: translateX(-50%);\n}\n.xve-keytip-command {\n position: fixed;\n bottom: auto;\n}\n\n/* Accent hues on command icons, as in Office. */\n:host {\n --ribbon-accent-blue: #2b7cd3;\n --ribbon-accent-green: #2f9e5f;\n --ribbon-accent-red: #d13438;\n --ribbon-accent-orange: #d9822b;\n}\n@media (prefers-color-scheme: dark) {\n :host(:not([theme='light'])) {\n --ribbon-accent-blue: #5ea5f0;\n --ribbon-accent-green: #5cc98a;\n --ribbon-accent-red: #f07a7d;\n --ribbon-accent-orange: #f0a35e;\n }\n}\n:host([theme='dark']) {\n --ribbon-accent-blue: #5ea5f0;\n --ribbon-accent-green: #5cc98a;\n --ribbon-accent-red: #f07a7d;\n --ribbon-accent-orange: #f0a35e;\n}\n.ribbon-icon[data-accent='blue'] {\n color: var(--ribbon-accent-blue);\n}\n.ribbon-icon[data-accent='green'] {\n color: var(--ribbon-accent-green);\n}\n.ribbon-icon[data-accent='red'] {\n color: var(--ribbon-accent-red);\n}\n.ribbon-icon[data-accent='orange'] {\n color: var(--ribbon-accent-orange);\n}\n";
@@ -14605,42 +14605,36 @@ function createRibbon(ctx, handlers) {
14605
14605
  // src/xlsx/ribbon-actions.ts
14606
14606
  function createRibbonActions(ctx, handlers) {
14607
14607
  const doc = ctx.host.ownerDocument;
14608
- const element = el2(doc, "div", "xve-ribbon-actions");
14608
+ defineRibbonActions(doc.defaultView?.customElements);
14609
+ const element = doc.createElement("office-ui-ribbon-actions");
14610
+ element.className = "xve-ribbon-actions";
14609
14611
  element.slot = "actions";
14610
- const modeBox = el2(doc, "label", "xve-mode");
14611
- const mode = el2(doc, "select", "xve-mode-select");
14612
- mode.append(new Option("", "editing"), new Option("", "viewing"));
14613
- mode.addEventListener("change", () => handlers.setReadOnly(mode.value === "viewing"));
14614
- modeBox.append(ribbonIcon(doc, "pencil", 16), mode);
14615
- const labelled2 = (className, icon7) => {
14616
- const button2 = el2(doc, "button", className);
14617
- button2.type = "button";
14618
- const text3 = el2(doc, "span", "xve-action-label");
14619
- button2.append(ribbonIcon(doc, icon7, 16), text3);
14620
- return { button: button2, text: text3 };
14621
- };
14622
- const comments = labelled2("xve-icon-button xve-comments-button", "comments");
14623
- comments.button.addEventListener("click", () => void ctx.commands.run("review.show-comments"));
14624
- const share = labelled2("xve-share-button", "share");
14625
- share.button.addEventListener("click", () => void ctx.commands.run("file.share"));
14626
- element.append(modeBox, comments.button, share.button);
14612
+ element.addEventListener(
14613
+ "office-ribbon-mode",
14614
+ (event) => handlers.setReadOnly(event.detail.mode === "viewing")
14615
+ );
14616
+ element.addEventListener("office-ribbon-comments", () => {
14617
+ void ctx.commands.run("review.show-comments");
14618
+ });
14619
+ element.addEventListener("office-ribbon-share", () => void ctx.commands.run("file.share"));
14627
14620
  const relocalize = () => {
14628
- mode.setAttribute("aria-label", ctx.t("Editing mode"));
14629
- mode.title = ctx.t("Editing mode");
14630
- mode.options[0].textContent = ctx.t("Editing");
14631
- mode.options[1].textContent = ctx.t("Viewing");
14632
- comments.text.textContent = ctx.t("Comments");
14633
- comments.button.title = ctx.t("Show comments");
14634
- share.text.textContent = ctx.t("Share");
14635
- share.button.title = ctx.t("Share");
14621
+ element.modeLabel = ctx.t("Editing mode");
14622
+ element.modes = [
14623
+ { value: "editing", label: ctx.t("Editing") },
14624
+ { value: "viewing", label: ctx.t("Viewing") }
14625
+ ];
14626
+ element.commentsLabel = ctx.t("Comments");
14627
+ element.commentsTitle = ctx.t("Show comments");
14628
+ element.shareLabel = ctx.t("Share");
14629
+ element.shareTitle = ctx.t("Share");
14636
14630
  refresh();
14637
14631
  };
14638
14632
  const refresh = () => {
14639
- mode.value = ctx.readOnly() ? "viewing" : "editing";
14640
- share.button.hidden = !ctx.commands.get("file.share") || handlers.isHidden("file.share");
14641
- share.button.setAttribute("aria-pressed", String(Boolean(handlers.collaboration?.().active)));
14633
+ element.mode = ctx.readOnly() ? "viewing" : "editing";
14634
+ element.noShare = !ctx.commands.get("file.share") || handlers.isHidden("file.share");
14635
+ element.sharePressed = Boolean(handlers.collaboration?.().active);
14642
14636
  const showComments = ctx.commands.get("review.show-comments");
14643
- comments.button.hidden = !showComments;
14637
+ element.noComments = !showComments;
14644
14638
  if (!showComments) return;
14645
14639
  let pressed = false;
14646
14640
  try {
@@ -14648,7 +14642,7 @@ function createRibbonActions(ctx, handlers) {
14648
14642
  } catch {
14649
14643
  pressed = false;
14650
14644
  }
14651
- comments.button.setAttribute("aria-pressed", String(pressed));
14645
+ element.commentsPressed = pressed;
14652
14646
  };
14653
14647
  relocalize();
14654
14648
  return { element, refresh, relocalize };
@@ -14821,7 +14815,8 @@ function statisticsText(ctx, shown2) {
14821
14815
  if (!shown2.has(key)) continue;
14822
14816
  const value = key === "count" ? stats.count : key === "numericCount" ? stats.numericCount : key === "sum" ? stats.numericCount ? stats.sum : void 0 : stats[key];
14823
14817
  if (value === void 0) continue;
14824
- parts.push(`${ctx.t(STAT_LABELS[key])}: ${formatNumber(locale, value)}`);
14818
+ const text3 = key === "count" || key === "numericCount" ? formatNumber(locale, value) : formatSelectionStat(workbook, stats, value);
14819
+ parts.push(`${ctx.t(STAT_LABELS[key])}: ${text3}`);
14825
14820
  }
14826
14821
  return parts.join(" ");
14827
14822
  }
@@ -15284,6 +15279,94 @@ function buildShell(core) {
15284
15279
  };
15285
15280
  }
15286
15281
 
15282
+ // src/xlsx/calc-preparation.ts
15283
+ var SLICE_MS = 8;
15284
+ var QUIET_MS = 250;
15285
+ var ACTIVITY = ["keydown", "wheel", "pointerdown", "touchmove"];
15286
+ function windowScheduler(view) {
15287
+ const clock = () => (view?.performance ?? performance).now();
15288
+ const later = (run, ms) => {
15289
+ const id = setTimeout(run, ms);
15290
+ return () => clearTimeout(id);
15291
+ };
15292
+ return {
15293
+ now: clock,
15294
+ later,
15295
+ afterPaint(run) {
15296
+ if (!view || typeof view.requestAnimationFrame !== "function") return later(run, 0);
15297
+ let cancelTimer;
15298
+ const id = view.requestAnimationFrame(() => {
15299
+ cancelTimer = later(run, 0);
15300
+ });
15301
+ return () => {
15302
+ view.cancelAnimationFrame(id);
15303
+ cancelTimer?.();
15304
+ };
15305
+ },
15306
+ idle(run) {
15307
+ if (view && typeof view.requestIdleCallback === "function") {
15308
+ const id = view.requestIdleCallback(run);
15309
+ return () => view.cancelIdleCallback(id);
15310
+ }
15311
+ const start = clock();
15312
+ return later(() => run({ timeRemaining: () => SLICE_MS - (clock() - start) }), 1);
15313
+ }
15314
+ };
15315
+ }
15316
+ var CalcPreparation = class {
15317
+ constructor(host, busy, scheduler = windowScheduler(host.ownerDocument.defaultView)) {
15318
+ this.busy = busy;
15319
+ this.scheduler = scheduler;
15320
+ const active2 = () => {
15321
+ this.lastActivity = this.scheduler.now();
15322
+ };
15323
+ for (const type of ACTIVITY) host.addEventListener(type, active2, { passive: true });
15324
+ }
15325
+ busy;
15326
+ scheduler;
15327
+ session;
15328
+ cancel;
15329
+ lastActivity = Number.NEGATIVE_INFINITY;
15330
+ /** Prepares `session` (the workbook just opened) after the next paint; stops earlier work. */
15331
+ start(session) {
15332
+ this.stop();
15333
+ if (!session) return;
15334
+ this.session = session;
15335
+ this.cancel = this.scheduler.afterPaint(() => this.next());
15336
+ }
15337
+ stop() {
15338
+ this.cancel?.();
15339
+ this.cancel = void 0;
15340
+ this.session = void 0;
15341
+ }
15342
+ /** Whether work is still waiting (tests and diagnostics). */
15343
+ get pending() {
15344
+ return this.session !== void 0;
15345
+ }
15346
+ next() {
15347
+ this.cancel = this.scheduler.idle((deadline) => this.slice(deadline));
15348
+ }
15349
+ slice(deadline) {
15350
+ this.cancel = void 0;
15351
+ const session = this.session;
15352
+ if (!session) return;
15353
+ const quietFor = this.scheduler.now() - this.lastActivity;
15354
+ if (this.busy() || quietFor < QUIET_MS) {
15355
+ const wait = Math.max(QUIET_MS - quietFor, 50);
15356
+ this.cancel = this.scheduler.later(() => this.next(), wait);
15357
+ return;
15358
+ }
15359
+ const end = this.scheduler.now() + Math.min(SLICE_MS, Math.max(deadline.timeRemaining(), 1));
15360
+ let done = true;
15361
+ try {
15362
+ done = session.prepareCalculation({ timeRemaining: () => end - this.scheduler.now() });
15363
+ } catch {
15364
+ }
15365
+ if (done) this.session = void 0;
15366
+ else this.next();
15367
+ }
15368
+ };
15369
+
15287
15370
  // src/xlsx/collaboration-session.ts
15288
15371
  function createRoomSession(collab, xlsx, options, defaultName) {
15289
15372
  const roomId = options.roomId ?? "";
@@ -15583,6 +15666,7 @@ var EditorCore = class {
15583
15666
  });
15584
15667
  this.ctx = this.createContext();
15585
15668
  this.collab = collaborationFor(this);
15669
+ this.calcPreparation = new CalcPreparation(host, () => !!this.gridController?.isEditing());
15586
15670
  }
15587
15671
  host;
15588
15672
  workbook;
@@ -15608,6 +15692,8 @@ var EditorCore = class {
15608
15692
  ctx;
15609
15693
  /** Co-editing over `ooxml-core/collab`; undo and redo go through it while shared. */
15610
15694
  collab;
15695
+ /** Builds the formula graph in idle time after a workbook opens. */
15696
+ calcPreparation;
15611
15697
  gridController;
15612
15698
  modelListeners = /* @__PURE__ */ new Set();
15613
15699
  stopSession;
@@ -15704,6 +15790,7 @@ var EditorCore = class {
15704
15790
  }
15705
15791
  }
15706
15792
  this.stopSession = this.session?.onChange((change) => this.onSessionChange(change));
15793
+ this.calcPreparation.start(this.session);
15707
15794
  const sheets = workbook?.sheets.length ?? 0;
15708
15795
  const preferred = workbook?.activeSheet ?? 0;
15709
15796
  this.activeSheet = Math.min(Math.max(0, preferred), Math.max(0, sheets - 1));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ooxml-ui",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Shared, format-neutral web components and styles for the Office viewers (Word, PowerPoint, Excel)",
5
5
  "keywords": [
6
6
  "custom-elements",
@@ -146,7 +146,7 @@
146
146
  "dompurify": "^3.4.16",
147
147
  "emf-converter": "4.8.21",
148
148
  "lit": "^3.3.3",
149
- "ooxml-core": "^1.2.0",
149
+ "ooxml-core": "^1.3.0",
150
150
  "opentype.js": "^2.0.0",
151
151
  "prosemirror-collab": "^1.3.1",
152
152
  "prosemirror-commands": "^1.7.2",