@univerjs/ui 1.0.0-rc.0 → 1.0.1

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 (111) hide show
  1. package/README.md +16 -0
  2. package/lib/cjs/facade.js +12 -6
  3. package/lib/cjs/index.js +1820 -635
  4. package/lib/cjs/locale/ar-SA.js +2 -1
  5. package/lib/cjs/locale/ca-ES.js +2 -1
  6. package/lib/cjs/locale/de-DE.js +2 -1
  7. package/lib/cjs/locale/en-US.js +2 -1
  8. package/lib/cjs/locale/es-ES.js +2 -1
  9. package/lib/cjs/locale/fa-IR.js +2 -1
  10. package/lib/cjs/locale/fr-FR.js +2 -1
  11. package/lib/cjs/locale/id-ID.js +2 -1
  12. package/lib/cjs/locale/it-IT.js +2 -1
  13. package/lib/cjs/locale/ja-JP.js +2 -1
  14. package/lib/cjs/locale/ko-KR.js +2 -1
  15. package/lib/cjs/locale/pl-PL.js +2 -1
  16. package/lib/cjs/locale/pt-BR.js +2 -1
  17. package/lib/cjs/locale/ru-RU.js +2 -1
  18. package/lib/cjs/locale/sk-SK.js +2 -1
  19. package/lib/cjs/locale/vi-VN.js +2 -1
  20. package/lib/cjs/locale/zh-CN.js +2 -1
  21. package/lib/cjs/locale/zh-HK.js +2 -1
  22. package/lib/cjs/locale/zh-TW.js +2 -1
  23. package/lib/es/facade.js +12 -6
  24. package/lib/es/index.js +1815 -638
  25. package/lib/es/locale/ar-SA.js +2 -0
  26. package/lib/es/locale/ca-ES.js +2 -0
  27. package/lib/es/locale/de-DE.js +2 -0
  28. package/lib/es/locale/en-US.js +2 -0
  29. package/lib/es/locale/es-ES.js +2 -0
  30. package/lib/es/locale/fa-IR.js +2 -0
  31. package/lib/es/locale/fr-FR.js +2 -0
  32. package/lib/es/locale/id-ID.js +2 -0
  33. package/lib/es/locale/it-IT.js +2 -0
  34. package/lib/es/locale/ja-JP.js +2 -0
  35. package/lib/es/locale/ko-KR.js +2 -0
  36. package/lib/es/locale/pl-PL.js +2 -0
  37. package/lib/es/locale/pt-BR.js +2 -0
  38. package/lib/es/locale/ru-RU.js +2 -0
  39. package/lib/es/locale/sk-SK.js +2 -0
  40. package/lib/es/locale/vi-VN.js +2 -0
  41. package/lib/es/locale/zh-CN.js +2 -0
  42. package/lib/es/locale/zh-HK.js +2 -0
  43. package/lib/es/locale/zh-TW.js +2 -0
  44. package/lib/facade.js +12 -6
  45. package/lib/index.css +102 -34
  46. package/lib/index.js +1815 -638
  47. package/lib/locale/ar-SA.js +2 -0
  48. package/lib/locale/ca-ES.js +2 -0
  49. package/lib/locale/de-DE.js +2 -0
  50. package/lib/locale/en-US.js +2 -0
  51. package/lib/locale/es-ES.js +2 -0
  52. package/lib/locale/fa-IR.js +2 -0
  53. package/lib/locale/fr-FR.js +2 -0
  54. package/lib/locale/id-ID.js +2 -0
  55. package/lib/locale/it-IT.js +2 -0
  56. package/lib/locale/ja-JP.js +2 -0
  57. package/lib/locale/ko-KR.js +2 -0
  58. package/lib/locale/pl-PL.js +2 -0
  59. package/lib/locale/pt-BR.js +2 -0
  60. package/lib/locale/ru-RU.js +2 -0
  61. package/lib/locale/sk-SK.js +2 -0
  62. package/lib/locale/vi-VN.js +2 -0
  63. package/lib/locale/zh-CN.js +2 -0
  64. package/lib/locale/zh-HK.js +2 -0
  65. package/lib/locale/zh-TW.js +2 -0
  66. package/lib/types/controllers/format-painter.controller.d.ts +25 -0
  67. package/lib/types/facade/f-menu-builder.d.ts +14 -1
  68. package/lib/types/facade/f-univer.d.ts +30 -5
  69. package/lib/types/index.d.ts +10 -0
  70. package/lib/types/locale/en-US.d.ts +2 -0
  71. package/lib/types/menu/format-painter.menu.d.ts +19 -0
  72. package/lib/types/services/contextmenu/contextmenu.service.d.ts +1 -0
  73. package/lib/types/services/format-painter/format-painter-canvas.d.ts +28 -0
  74. package/lib/types/services/format-painter/format-painter-session.service.d.ts +61 -0
  75. package/lib/types/services/menu/menu-manager.service.d.ts +13 -1
  76. package/lib/types/services/menu/menu.d.ts +6 -0
  77. package/lib/types/utils/mobile-canvas-gesture.d.ts +50 -0
  78. package/lib/types/views/components/context-menu/MobileContextMenu.d.ts +6 -0
  79. package/lib/types/views/components/dialog-part/MobileDialogPart.d.ts +5 -0
  80. package/lib/types/views/components/mobile-drawer/MobileDrawer.d.ts +2 -0
  81. package/lib/types/views/components/mobile-zoom-indicator/mobile-zoom-indicator.d.ts +26 -0
  82. package/lib/types/views/components/ribbon/ToolbarButton.d.ts +1 -1
  83. package/lib/types/views/components/sidebar/MobileSidebar.d.ts +5 -0
  84. package/lib/types/views/emoji-picker/emoji-picker-utils.d.ts +1 -1
  85. package/lib/types/views/font-family/MobileFontFamilyDropdown.d.ts +17 -0
  86. package/lib/types/views/menu/mobile/MobileMenu.d.ts +1 -1
  87. package/lib/types/views/mobile-workbench/MobileCanvasLayout.d.ts +42 -0
  88. package/lib/types/views/mobile-workbench/MobileWorkbench.d.ts +2 -0
  89. package/lib/types/views/notification/Notification.d.ts +6 -1
  90. package/lib/umd/facade.js +1 -1
  91. package/lib/umd/index.js +34 -16
  92. package/lib/umd/locale/ar-SA.js +1 -1
  93. package/lib/umd/locale/ca-ES.js +1 -1
  94. package/lib/umd/locale/de-DE.js +1 -1
  95. package/lib/umd/locale/en-US.js +1 -1
  96. package/lib/umd/locale/es-ES.js +1 -1
  97. package/lib/umd/locale/fa-IR.js +1 -1
  98. package/lib/umd/locale/fr-FR.js +1 -1
  99. package/lib/umd/locale/id-ID.js +1 -1
  100. package/lib/umd/locale/it-IT.js +1 -1
  101. package/lib/umd/locale/ja-JP.js +1 -1
  102. package/lib/umd/locale/ko-KR.js +1 -1
  103. package/lib/umd/locale/pl-PL.js +1 -1
  104. package/lib/umd/locale/pt-BR.js +1 -1
  105. package/lib/umd/locale/ru-RU.js +1 -1
  106. package/lib/umd/locale/sk-SK.js +1 -1
  107. package/lib/umd/locale/vi-VN.js +1 -1
  108. package/lib/umd/locale/zh-CN.js +1 -1
  109. package/lib/umd/locale/zh-HK.js +1 -1
  110. package/lib/umd/locale/zh-TW.js +1 -1
  111. package/package.json +12 -12
package/lib/es/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { BaselineOffset, BorderStyleTypes, ColorKit, CommandType, DependentOn, Disposable, DocumentDataModel, DocumentFlavor, EDITOR_ACTIVATED, ErrorService, FOCUSING_FX_BAR_EDITOR, FOCUSING_SHEET, FOCUSING_UNIVER_EDITOR, IAuthzIoService, ICommandService, IConfigService, IConfirmService, IContextService, ILocalStorageService, ILogService, IPermissionService, IUndoRedoService, IUniverInstanceService, Inject, Injector, LifecycleService, LifecycleStages, LifecycleUnreachableError, LocaleService, NAMED_STYLE_MAP, NamedStyleType, ObjectPermissionService, Optional, Plugin, Quantity, RedoCommand, SHEET_EDITOR_UNITS, ThemeService, Tools, UndoCommand, UniverInstanceType, UserManagerService, Workbook, createIdentifier, dedupeBy, generateRandomId, getBorderStyleType, isInternalEditorID, isRealNum, merge, mergeOverrideWithDependencies, registerDependencies, remove, throttle, toDisposable, touchDependencies } from "@univerjs/core";
2
2
  import { BehaviorSubject, EMPTY, Observable, ReplaySubject, Subject, Subscription, animationFrameScheduler, combineLatest, debounceTime, distinctUntilChanged, filter, first, fromEvent, isObservable, map, merge as merge$1, of, scan, startWith, switchMap, throttleTime } from "rxjs";
3
3
  import { Fragment, cloneElement, createContext, createElement, forwardRef, memo, useCallback, useContext, useDeferredValue, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
4
- import { Avatar, Button, Checkbox, ColorPicker, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, ConfigContext, ConfigProvider, Confirm, Dialog, Dropdown, DropdownMenu, FormLayout, Gallery, HoverCard, Input, InputNumber, KBD, MessageType, Messager, MobileActionRowGroup, MobileColorPicker, MobileConfirm, MobileDropdown, MobileDropdownMenu, Popup, Radio, RadioGroup, StateIconButton, Toaster, Tooltip, borderBottomClassName, borderClassName, borderLeftBottomClassName, borderRightClassName, borderTopClassName, clsx, cva, divideXClassName, divideYClassName, isBrowser, message, removeMessage, render, resetButtonClassName, scrollbarClassName, toast, unmount } from "@univerjs/design";
4
+ import { Avatar, Button, Checkbox, ColorPicker, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, ConfigContext, ConfigProvider, Confirm, Dialog, Dropdown, DropdownMenu, FormLayout, Gallery, HoverCard, Input, InputNumber, KBD, MessageType, Messager, MobileActionRowGroup, MobileColorPicker, MobileConfirm, MobileDropdown, MobileDropdownMenu, MobileOverlayContext, MobileSelect, Popup, Radio, RadioGroup, StateIconButton, Toaster, Tooltip, borderBottomClassName, borderClassName, borderLeftBottomClassName, borderRightClassName, borderTopClassName, clsx, cva, divideXClassName, divideYClassName, isBrowser, message, removeMessage, render, resetButtonClassName, revealFocusedElementInMobileViewport, scrollbarClassName, toast, unmount, useMobileKeyboardViewportLayout } from "@univerjs/design";
5
5
  import { IRenderManagerService, UniverRenderEnginePlugin, ptToPx } from "@univerjs/engine-render";
6
6
  import { distinctUntilChanged as distinctUntilChanged$1, map as map$1, scan as scan$1, startWith as startWith$1, switchMap as switchMap$1 } from "rxjs/operators";
7
7
  import { RediConsumer, RediContext, RediProvider, WithDependency, connectDependencies, connectInjector, connectInjector as connectInjector$1, useDependency, useDependency as useDependency$1, useInjector, useObservable, useObservable as useObservable$1, useUpdateBinder } from "@wendellhu/redi/react-bindings";
8
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
9
  import { createPortal } from "react-dom";
10
- import { ActivityIcon, CheckMarkIcon, CloseIcon, DatabaseIcon, ExpandIcon, EyeIcon, FeatureSearchIcon, FoodsIcon, FunctionIcon, HomeIcon, IncreaseIcon, InfoIcon, InsertIcon, KeyboardIcon, MoreDownIcon, MoreHorizontalIcon, MoreLeftIcon, MoreRightIcon, MoreVerticalIcon, NatureIcon, ObjectsIcon, PeopleIcon, PlacesIcon, ProtectIcon, RandomIcon, RecentIcon, RedoIcon, ReduceIcon, SearchIcon, ShortcutIcon, ShrinkIcon, SymbolsIcon, UndoIcon } from "@univerjs/icons";
10
+ import { ActivityIcon, BrushIcon, CheckMarkIcon, ClearFormatDoubleIcon, CloseIcon, DatabaseIcon, ExpandIcon, EyeIcon, FeatureSearchIcon, FoodsIcon, FunctionIcon, HomeIcon, IncreaseIcon, InfoIcon, InsertIcon, KeyboardIcon, MoreDownIcon, MoreHorizontalIcon, MoreLeftIcon, MoreRightIcon, MoreVerticalIcon, NatureIcon, ObjectsIcon, PeopleIcon, PlacesIcon, ProtectIcon, RandomIcon, RecentIcon, RedoIcon, ReduceIcon, SearchIcon, ShortcutIcon, ShrinkIcon, SymbolsIcon, UndoIcon } from "@univerjs/icons";
11
11
  import { UnitAction, UnitObject, UnitRole } from "@univerjs/protocol";
12
12
 
13
13
  //#region src/utils/embed-boundary.ts
@@ -55,7 +55,7 @@ function getAttributeValue(target, name) {
55
55
  }
56
56
 
57
57
  //#endregion
58
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/typeof.js
58
+ //#region \0@oxc-project+runtime@0.149.0/helpers/esm/typeof.js
59
59
  function _typeof(o) {
60
60
  "@babel/helpers - typeof";
61
61
  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
@@ -66,7 +66,7 @@ function _typeof(o) {
66
66
  }
67
67
 
68
68
  //#endregion
69
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/toPrimitive.js
69
+ //#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPrimitive.js
70
70
  function toPrimitive(t, r) {
71
71
  if ("object" != _typeof(t) || !t) return t;
72
72
  var e = t[Symbol.toPrimitive];
@@ -79,14 +79,14 @@ function toPrimitive(t, r) {
79
79
  }
80
80
 
81
81
  //#endregion
82
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/toPropertyKey.js
82
+ //#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPropertyKey.js
83
83
  function toPropertyKey(t) {
84
84
  var i = toPrimitive(t, "string");
85
85
  return "symbol" == _typeof(i) ? i : i + "";
86
86
  }
87
87
 
88
88
  //#endregion
89
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/defineProperty.js
89
+ //#region \0@oxc-project+runtime@0.149.0/helpers/esm/defineProperty.js
90
90
  function _defineProperty(e, r, t) {
91
91
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
92
92
  value: t,
@@ -97,7 +97,7 @@ function _defineProperty(e, r, t) {
97
97
  }
98
98
 
99
99
  //#endregion
100
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/decorateParam.js
100
+ //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorateParam.js
101
101
  function __decorateParam(paramIndex, decorator) {
102
102
  return function(target, key) {
103
103
  decorator(target, key, paramIndex);
@@ -105,7 +105,7 @@ function __decorateParam(paramIndex, decorator) {
105
105
  }
106
106
 
107
107
  //#endregion
108
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/decorate.js
108
+ //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorate.js
109
109
  function __decorate(decorators, target, key, desc) {
110
110
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
111
111
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -523,10 +523,12 @@ function mergeMenuConfigs(baseConfig, additionalConfig) {
523
523
  return baseConfig;
524
524
  }
525
525
  function updateReactiveProperty(baseConfig, key, value) {
526
- if (value !== void 0) if (baseConfig[key]) baseConfig[key] = baseConfig[key].pipe(switchMap(() => new BehaviorSubject(value)));
527
- else baseConfig[key] = new Observable((subscriber) => {
528
- subscriber.next(value);
529
- });
526
+ if (value !== void 0) {
527
+ if (baseConfig[key]) baseConfig[key] = baseConfig[key].pipe(switchMap(() => new BehaviorSubject(value)));
528
+ else baseConfig[key] = new Observable((subscriber) => {
529
+ subscriber.next(value);
530
+ });
531
+ }
530
532
  }
531
533
 
532
534
  //#endregion
@@ -672,21 +674,6 @@ const IMessageService = createIdentifier("ui.message.service");
672
674
 
673
675
  //#endregion
674
676
  //#region src/controllers/error/error.controller.ts
675
- /**
676
- * Copyright 2023-present DreamNum Co., Ltd.
677
- *
678
- * Licensed under the Apache License, Version 2.0 (the "License");
679
- * you may not use this file except in compliance with the License.
680
- * You may obtain a copy of the License at
681
- *
682
- * http://www.apache.org/licenses/LICENSE-2.0
683
- *
684
- * Unless required by applicable law or agreed to in writing, software
685
- * distributed under the License is distributed on an "AS IS" BASIS,
686
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
687
- * See the License for the specific language governing permissions and
688
- * limitations under the License.
689
- */
690
677
  const PERMISSION_MESSAGE_ID = "ui.permission-denied";
691
678
  const PERMISSION_MESSAGE_DURATION = 3e3;
692
679
  let ErrorController = class ErrorController extends Disposable {
@@ -1103,7 +1090,7 @@ let ShortcutService = class ShortcutService extends Disposable {
1103
1090
  }
1104
1091
  dispatch(e) {
1105
1092
  if (e.isComposing) return;
1106
- if ((e.keyCode === 8 || e.keyCode === 46) && e.target instanceof HTMLInputElement && e.target.closest("[data-u-command]")) return;
1093
+ if (e.target instanceof HTMLInputElement && e.target.closest("[data-u-command]")) return;
1107
1094
  if (!e.ctrlKey && !e.metaKey && !e.altKey && MENU_NAVIGATION_KEYS.has(e.keyCode) && e.target instanceof HTMLElement && (e.target.matches("button[data-u-command], [data-u-command][role=\"button\"], [data-embed-floating-menu=\"true\"] button, [data-u-command] input") || e.target.closest("[role=\"menu\"]"))) return;
1108
1095
  if (this._forceEscapeCount > 0 || this._forceDisabled) return;
1109
1096
  if (this._layoutService && !this._layoutService.checkElementInCurrentContainers(e.target)) return;
@@ -1477,6 +1464,7 @@ let MenuManagerService = _MenuManagerService = class MenuManagerService extends
1477
1464
  }
1478
1465
  dispose() {
1479
1466
  this.menuChanged$.complete();
1467
+ super.dispose();
1480
1468
  }
1481
1469
  /**
1482
1470
  * Merge source menu to target menu recursively
@@ -1496,46 +1484,48 @@ let MenuManagerService = _MenuManagerService = class MenuManagerService extends
1496
1484
  this._menu = merge({}, this._menu, source);
1497
1485
  this.menuChanged$.next();
1498
1486
  }
1487
+ updateMenuConfig(config) {
1488
+ this._configService.setConfig("menu", config, { merge: true });
1489
+ this.menuChanged$.next();
1490
+ }
1499
1491
  createScoped(injector) {
1500
- const root = this;
1501
1492
  const createScopedBuilder = () => {
1502
- const service = new _MenuManagerService(injector, root._configService);
1503
- service._menu = root._menu;
1493
+ const service = new _MenuManagerService(injector, this._configService);
1494
+ service._menu = this._menu;
1504
1495
  return service;
1505
1496
  };
1506
1497
  return {
1507
- menuChanged$: root.menuChanged$,
1508
- mergeMenu: (source, target) => root.mergeMenu(source, target),
1509
- appendRootMenu: (source) => root.appendRootMenu(source),
1498
+ menuChanged$: this.menuChanged$,
1499
+ mergeMenu: (source, target) => this.mergeMenu(source, target),
1500
+ appendRootMenu: (source) => this.appendRootMenu(source),
1501
+ updateMenuConfig: (config) => this.updateMenuConfig(config),
1510
1502
  getMenuByPositionKey: (position) => createScopedBuilder().getMenuByPositionKey(position),
1511
1503
  getFlatMenuByPositionKey: (position) => createScopedBuilder().getFlatMenuByPositionKey(position)
1512
1504
  };
1513
1505
  }
1514
1506
  _buildMenuSchema(data) {
1515
1507
  const result = [];
1508
+ const menuConfig = this._configService.getConfig("menu");
1516
1509
  for (const [key, value] of Object.entries(data)) {
1517
1510
  if (key === "replace") continue;
1511
+ const item = value.menuItemFactory ? this._injector.invoke(value.menuItemFactory) : void 0;
1512
+ const config = menuConfig === null || menuConfig === void 0 ? void 0 : menuConfig[(item === null || item === void 0 ? void 0 : item.id) ?? key];
1518
1513
  const menuItem = {
1519
1514
  key,
1520
- order: value.order,
1515
+ order: (config === null || config === void 0 ? void 0 : config.order) ?? value.order,
1521
1516
  title: value.title,
1522
1517
  contextual: value.contextual,
1523
1518
  quickLayout: value.quickLayout,
1524
1519
  quickColumns: value.quickColumns,
1525
1520
  quickLayoutVariant: value.quickLayoutVariant,
1521
+ mobileLayout: value.mobileLayout,
1526
1522
  tiny: value.tiny,
1527
- gridLayout: value.gridLayout
1523
+ gridLayout: (config === null || config === void 0 ? void 0 : config.gridLayout) ? {
1524
+ ...value.gridLayout,
1525
+ ...config.gridLayout
1526
+ } : value.gridLayout
1528
1527
  };
1529
- if (value.menuItemFactory) {
1530
- const item = this._injector.invoke(value.menuItemFactory);
1531
- if (item) {
1532
- const menuItemConfig = this._configService.getConfig("menu");
1533
- if (menuItemConfig && item.id in menuItemConfig) {
1534
- const _key = item.id;
1535
- menuItem.item = mergeMenuConfigs(item, menuItemConfig[_key]);
1536
- } else menuItem.item = item;
1537
- }
1538
- }
1528
+ if (item) menuItem.item = config ? mergeMenuConfigs(item, config) : item;
1539
1529
  if (value.headerActionMenuItemFactory) menuItem.headerActionItem = this._injector.invoke(value.headerActionMenuItemFactory);
1540
1530
  if (typeof value === "object") {
1541
1531
  const children = this._buildMenuSchema(value);
@@ -1831,7 +1821,7 @@ function FeatureSearch() {
1831
1821
  const dialogService = useDependency(IDialogService);
1832
1822
  const layoutService = useDependency(ILayoutService);
1833
1823
  const ribbonService = useDependency(IRibbonService);
1834
- const items = useObservable(useMemo(() => {
1824
+ const items$ = useMemo(() => {
1835
1825
  function getItemTitle(item) {
1836
1826
  const titleKey = item.title ?? item.tooltip ?? item.description;
1837
1827
  return titleKey ? localeService.t(titleKey) : "";
@@ -1866,15 +1856,17 @@ function FeatureSearch() {
1866
1856
  const hasOptions = item.type === 1 || item.type === 2;
1867
1857
  const selections = hasOptions ? item.selections : void 0;
1868
1858
  const selections$ = isObservable(selections) ? selections.pipe(startWith$1([])) : of(selections ?? []);
1859
+ const ancestorHidden$ = candidate.ancestors.length ? combineLatest(candidate.ancestors.map((ancestor) => {
1860
+ var _ancestor$hidden$;
1861
+ return ((_ancestor$hidden$ = ancestor.hidden$) === null || _ancestor$hidden$ === void 0 ? void 0 : _ancestor$hidden$.pipe(startWith$1(true))) ?? of(false);
1862
+ })).pipe(map$1((states) => states.some(Boolean))) : of(false);
1863
+ const ancestorDisabled$ = candidate.ancestors.length ? combineLatest(candidate.ancestors.map((ancestor) => {
1864
+ var _ancestor$disabled$;
1865
+ return ((_ancestor$disabled$ = ancestor.disabled$) === null || _ancestor$disabled$ === void 0 ? void 0 : _ancestor$disabled$.pipe(startWith$1(true))) ?? of(false);
1866
+ })).pipe(map$1((states) => states.some(Boolean))) : of(false);
1869
1867
  return combineLatest([
1870
- candidate.ancestors.length ? combineLatest(candidate.ancestors.map((ancestor) => {
1871
- var _ancestor$hidden$;
1872
- return ((_ancestor$hidden$ = ancestor.hidden$) === null || _ancestor$hidden$ === void 0 ? void 0 : _ancestor$hidden$.pipe(startWith$1(true))) ?? of(false);
1873
- })).pipe(map$1((states) => states.some(Boolean))) : of(false),
1874
- candidate.ancestors.length ? combineLatest(candidate.ancestors.map((ancestor) => {
1875
- var _ancestor$disabled$;
1876
- return ((_ancestor$disabled$ = ancestor.disabled$) === null || _ancestor$disabled$ === void 0 ? void 0 : _ancestor$disabled$.pipe(startWith$1(true))) ?? of(false);
1877
- })).pipe(map$1((states) => states.some(Boolean))) : of(false),
1868
+ ancestorHidden$,
1869
+ ancestorDisabled$,
1878
1870
  ((_item$hidden$ = item.hidden$) === null || _item$hidden$ === void 0 ? void 0 : _item$hidden$.pipe(startWith$1(true))) ?? of(false),
1879
1871
  ((_item$disabled$ = item.disabled$) === null || _item$disabled$ === void 0 ? void 0 : _item$disabled$.pipe(startWith$1(true))) ?? of(false),
1880
1872
  ((_item$value$ = item.value$) === null || _item$value$ === void 0 ? void 0 : _item$value$.pipe(startWith$1(void 0))) ?? of(void 0),
@@ -1920,7 +1912,8 @@ function FeatureSearch() {
1920
1912
  localeService,
1921
1913
  menuManagerService,
1922
1914
  ribbonService
1923
- ]), []);
1915
+ ]);
1916
+ const items = useObservable(items$, []);
1924
1917
  async function execute(item) {
1925
1918
  layoutService.focus();
1926
1919
  if (await commandService.executeCommand(item.commandId, item.getParams())) dialogService.close(FEATURE_SEARCH_DIALOG_ID);
@@ -1979,6 +1972,260 @@ const OpenFeatureSearchOperation = {
1979
1972
  }
1980
1973
  };
1981
1974
 
1975
+ //#endregion
1976
+ //#region src/services/format-painter/format-painter-canvas.ts
1977
+ const FORMAT_PAINTER_CURSOR_CSS = `
1978
+ /* Keep the brush visible while the render engine updates its usual object/text cursors. */
1979
+ canvas[data-format-painter="available"] {
1980
+ cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'%3E%3Cpath d='M2 1v18l4-4 3 7 3-2-3-6h6z' fill='white' stroke='black'/%3E%3Cpath d='m17 13 8-10 2 2-8 10z' fill='white' stroke='black'/%3E%3Cpath d='M17 14c-4 0-2 5-6 6 5 2 10-1 8-5z' fill='black' stroke='white'/%3E%3C/svg%3E") 2 1, crosshair !important;
1981
+ }
1982
+ canvas[data-format-painter="unavailable"] {
1983
+ cursor: not-allowed !important;
1984
+ }
1985
+ `;
1986
+ function bindFormatPainterCanvas(canvas, session, options) {
1987
+ let pressed = false;
1988
+ let applyTask;
1989
+ const active = () => {
1990
+ var _options$getUnitId;
1991
+ return session.isActive(options.adapterId) && session.unitId === (((_options$getUnitId = options.getUnitId) === null || _options$getUnitId === void 0 ? void 0 : _options$getUnitId.call(options)) ?? options.unitId);
1992
+ };
1993
+ const updateCursor = (event) => {
1994
+ if (active()) canvas.dataset.formatPainter = event && !options.getTarget(event) ? "unavailable" : "available";
1995
+ };
1996
+ const subscription = session.state$.subscribe(() => {
1997
+ if (active()) updateCursor();
1998
+ else if (session.mode === "off") {
1999
+ delete canvas.dataset.formatPainter;
2000
+ pressed = false;
2001
+ clearTimeout(applyTask);
2002
+ }
2003
+ });
2004
+ const down = (event) => {
2005
+ if (!active() || event.button !== 0) return;
2006
+ pressed = !!options.getTarget(event);
2007
+ if (options.intercept || !pressed) {
2008
+ canvas.focus();
2009
+ event.preventDefault();
2010
+ event.stopImmediatePropagation();
2011
+ }
2012
+ };
2013
+ const up = (event) => {
2014
+ if (!active() || !pressed || event.button !== 0) return;
2015
+ pressed = false;
2016
+ if (options.intercept) {
2017
+ event.preventDefault();
2018
+ event.stopImmediatePropagation();
2019
+ }
2020
+ clearTimeout(applyTask);
2021
+ applyTask = setTimeout(() => {
2022
+ const target = active() ? options.getTarget(event) : null;
2023
+ if (target) session.apply(options.adapterId, target).catch((error) => console.error("[FormatPainter]", error));
2024
+ }, 0);
2025
+ };
2026
+ const cancel = () => {
2027
+ pressed = false;
2028
+ };
2029
+ const doubleClick = (event) => {
2030
+ if (active() && options.intercept) {
2031
+ event.preventDefault();
2032
+ event.stopImmediatePropagation();
2033
+ }
2034
+ };
2035
+ canvas.addEventListener("pointerdown", down, true);
2036
+ canvas.addEventListener("pointerup", up, true);
2037
+ canvas.addEventListener("pointermove", updateCursor, true);
2038
+ canvas.addEventListener("pointercancel", cancel, true);
2039
+ canvas.addEventListener("pointerleave", cancel, true);
2040
+ canvas.addEventListener("dblclick", doubleClick, true);
2041
+ return { dispose: () => {
2042
+ clearTimeout(applyTask);
2043
+ subscription.unsubscribe();
2044
+ canvas.removeEventListener("pointerdown", down, true);
2045
+ canvas.removeEventListener("pointerup", up, true);
2046
+ canvas.removeEventListener("pointermove", updateCursor, true);
2047
+ canvas.removeEventListener("pointercancel", cancel, true);
2048
+ canvas.removeEventListener("pointerleave", cancel, true);
2049
+ canvas.removeEventListener("dblclick", doubleClick, true);
2050
+ delete canvas.dataset.formatPainter;
2051
+ } };
2052
+ }
2053
+
2054
+ //#endregion
2055
+ //#region src/services/format-painter/format-painter-session.service.ts
2056
+ /** One local interaction session; domain commands retain ownership of persisted formatting. */
2057
+ var FormatPainterSessionService = class extends Disposable {
2058
+ constructor(..._args) {
2059
+ super(..._args);
2060
+ _defineProperty(this, "_adapters", []);
2061
+ _defineProperty(this, "_state$", new BehaviorSubject("off"));
2062
+ _defineProperty(this, "state$", this._state$.asObservable());
2063
+ _defineProperty(this, "_session", null);
2064
+ _defineProperty(this, "_applying", false);
2065
+ }
2066
+ get mode() {
2067
+ return this._state$.value;
2068
+ }
2069
+ get unitId() {
2070
+ var _this$_session;
2071
+ return (_this$_session = this._session) === null || _this$_session === void 0 ? void 0 : _this$_session.source.unitId;
2072
+ }
2073
+ register(adapter) {
2074
+ this._adapters.push(adapter);
2075
+ this._adapters.sort((a, b) => b.priority - a.priority);
2076
+ const subscription = adapter.changes$.subscribe(() => this.refresh());
2077
+ this.refresh();
2078
+ return this.disposeWithMe(() => {
2079
+ subscription.unsubscribe();
2080
+ const index = this._adapters.indexOf(adapter);
2081
+ if (index >= 0) this._adapters.splice(index, 1);
2082
+ if (this.isActive(adapter.id)) this.cancel();
2083
+ this.refresh();
2084
+ });
2085
+ }
2086
+ refresh() {
2087
+ this._state$.next(this.mode);
2088
+ }
2089
+ canStart() {
2090
+ var _this$_adapters$find;
2091
+ return ((_this$_adapters$find = this._adapters.find((adapter) => adapter.isActive())) === null || _this$_adapters$find === void 0 ? void 0 : _this$_adapters$find.canStart()) ?? false;
2092
+ }
2093
+ isActive(adapterId) {
2094
+ var _this$_session2;
2095
+ return ((_this$_session2 = this._session) === null || _this$_session2 === void 0 ? void 0 : _this$_session2.adapterId) === adapterId;
2096
+ }
2097
+ canClear() {
2098
+ const adapter = this._adapters.find((candidate) => candidate.isActive());
2099
+ return !!(adapter === null || adapter === void 0 ? void 0 : adapter.clear) && adapter.canStart();
2100
+ }
2101
+ async clearFormatting() {
2102
+ const adapter = this._adapters.find((candidate) => candidate.isActive());
2103
+ if (!(adapter === null || adapter === void 0 ? void 0 : adapter.clear) || !adapter.canStart() || this._applying) return false;
2104
+ this.cancel();
2105
+ this._applying = true;
2106
+ try {
2107
+ return await adapter.clear();
2108
+ } finally {
2109
+ this._applying = false;
2110
+ this.refresh();
2111
+ }
2112
+ }
2113
+ activate(continuous = false) {
2114
+ if (this._session) {
2115
+ if (continuous) this._setMode("continuous");
2116
+ else this.cancel();
2117
+ return true;
2118
+ }
2119
+ const adapter = this._adapters.find((candidate) => candidate.isActive());
2120
+ if (!(adapter === null || adapter === void 0 ? void 0 : adapter.canStart())) return false;
2121
+ const source = adapter.capture();
2122
+ if (!source) return false;
2123
+ this._session = {
2124
+ adapterId: adapter.id,
2125
+ source
2126
+ };
2127
+ this._setMode(continuous ? "continuous" : "once");
2128
+ return true;
2129
+ }
2130
+ async apply(adapterId, target) {
2131
+ const session = this._session;
2132
+ if (!session || session.adapterId !== adapterId || target.unitId !== session.source.unitId || this._applying) return false;
2133
+ this._applying = true;
2134
+ try {
2135
+ const applied = await session.source.apply(target);
2136
+ if (applied && this._session === session && this.mode === "once") this.cancel();
2137
+ return applied;
2138
+ } finally {
2139
+ this._applying = false;
2140
+ }
2141
+ }
2142
+ cancel() {
2143
+ var _session$source, _session$source$onMod;
2144
+ const session = this._session;
2145
+ this._session = null;
2146
+ session === null || session === void 0 || (_session$source$onMod = (_session$source = session.source).onModeChange) === null || _session$source$onMod === void 0 || _session$source$onMod.call(_session$source, "off");
2147
+ this._state$.next("off");
2148
+ }
2149
+ _setMode(mode) {
2150
+ var _this$_session3, _this$_session3$sourc, _this$_session3$sourc2;
2151
+ (_this$_session3 = this._session) === null || _this$_session3 === void 0 || (_this$_session3$sourc2 = (_this$_session3$sourc = _this$_session3.source).onModeChange) === null || _this$_session3$sourc2 === void 0 || _this$_session3$sourc2.call(_this$_session3$sourc, mode);
2152
+ this._state$.next(mode);
2153
+ }
2154
+ dispose() {
2155
+ this.cancel();
2156
+ this._adapters.length = 0;
2157
+ this._state$.complete();
2158
+ super.dispose();
2159
+ }
2160
+ };
2161
+
2162
+ //#endregion
2163
+ //#region src/controllers/format-painter.controller.ts
2164
+ const ActivateFormatPainterOperation = {
2165
+ id: "ui.operation.activate-format-painter",
2166
+ type: CommandType.OPERATION,
2167
+ handler: (accessor) => accessor.get(FormatPainterSessionService).activate()
2168
+ };
2169
+ const ContinuousFormatPainterOperation = {
2170
+ id: "ui.operation.continuous-format-painter",
2171
+ type: CommandType.OPERATION,
2172
+ handler: (accessor) => accessor.get(FormatPainterSessionService).activate(true)
2173
+ };
2174
+ const ClearFormattingCommand = {
2175
+ id: "ui.command.clear-formatting",
2176
+ type: CommandType.COMMAND,
2177
+ handler: (accessor) => accessor.get(FormatPainterSessionService).clearFormatting()
2178
+ };
2179
+ const CancelFormatPainterOperation = {
2180
+ id: "ui.operation.cancel-format-painter",
2181
+ type: CommandType.OPERATION,
2182
+ handler: (accessor) => {
2183
+ accessor.get(FormatPainterSessionService).cancel();
2184
+ return true;
2185
+ }
2186
+ };
2187
+ let FormatPainterController = class FormatPainterController extends Disposable {
2188
+ constructor(session, commandService, shortcutService, instanceService) {
2189
+ super();
2190
+ const cursorStyle = document.createElement("style");
2191
+ cursorStyle.textContent = FORMAT_PAINTER_CURSOR_CSS;
2192
+ document.head.appendChild(cursorStyle);
2193
+ this.disposeWithMe({ dispose: () => cursorStyle.remove() });
2194
+ for (const command of [
2195
+ ActivateFormatPainterOperation,
2196
+ ContinuousFormatPainterOperation,
2197
+ CancelFormatPainterOperation,
2198
+ ClearFormattingCommand
2199
+ ]) this.disposeWithMe(commandService.registerCommand(command));
2200
+ this.disposeWithMe(shortcutService.registerShortcut({
2201
+ id: CancelFormatPainterOperation.id,
2202
+ binding: 27,
2203
+ priority: 1e3,
2204
+ preconditions: () => session.mode !== "off"
2205
+ }));
2206
+ this.disposeWithMe(fromGlobalEvent("keydown", (event) => {
2207
+ if (event.key === "Escape" && session.mode !== "off" && event.target instanceof HTMLElement && event.target.closest(`[data-u-command="${ActivateFormatPainterOperation.id}"]`)) {
2208
+ commandService.syncExecuteCommand(CancelFormatPainterOperation.id);
2209
+ event.preventDefault();
2210
+ event.stopPropagation();
2211
+ }
2212
+ }, { capture: true }));
2213
+ this.disposeWithMe(instanceService.unitDisposed$.subscribe((unit) => {
2214
+ if (unit.getUnitId() === session.unitId) session.cancel();
2215
+ }));
2216
+ this.disposeWithMe(instanceService.focused$.subscribe((unitId) => {
2217
+ if (unitId && session.unitId && unitId !== session.unitId) session.cancel();
2218
+ session.refresh();
2219
+ }));
2220
+ }
2221
+ };
2222
+ FormatPainterController = __decorate([
2223
+ __decorateParam(0, Inject(FormatPainterSessionService)),
2224
+ __decorateParam(1, ICommandService),
2225
+ __decorateParam(2, IShortcutService),
2226
+ __decorateParam(3, IUniverInstanceService)
2227
+ ], FormatPainterController);
2228
+
1982
2229
  //#endregion
1983
2230
  //#region src/menu/feature-search.menu.ts
1984
2231
  function FeatureSearchMenuItemFactory() {
@@ -1991,6 +2238,33 @@ function FeatureSearchMenuItemFactory() {
1991
2238
  };
1992
2239
  }
1993
2240
 
2241
+ //#endregion
2242
+ //#region src/menu/format-painter.menu.ts
2243
+ function FormatPainterMenuItemFactory(accessor) {
2244
+ const session = accessor.get(FormatPainterSessionService);
2245
+ return {
2246
+ id: ActivateFormatPainterOperation.id,
2247
+ subId: ContinuousFormatPainterOperation.id,
2248
+ type: 0,
2249
+ icon: "BrushIcon",
2250
+ title: "ui.formatPainter",
2251
+ tooltip: "ui.formatPainter",
2252
+ activated$: session.state$.pipe(map((mode) => mode !== "off")),
2253
+ disabled$: session.state$.pipe(map((mode) => mode === "off" && !session.canStart()))
2254
+ };
2255
+ }
2256
+ function ClearFormattingMenuItemFactory(accessor) {
2257
+ const session = accessor.get(FormatPainterSessionService);
2258
+ return {
2259
+ id: ClearFormattingCommand.id,
2260
+ type: 0,
2261
+ icon: "ClearFormatDoubleIcon",
2262
+ title: "ui.clearFormatting",
2263
+ tooltip: "ui.clearFormatting",
2264
+ disabled$: session.state$.pipe(map(() => !session.canClear()))
2265
+ };
2266
+ }
2267
+
1994
2268
  //#endregion
1995
2269
  //#region src/menu/history.menu.ts
1996
2270
  const undoRedoDisableFactory$ = (accessor, isUndo) => {
@@ -2040,6 +2314,24 @@ function ShortcutPanelMenuItemFactory() {
2040
2314
  //#region src/menu/schema.ts
2041
2315
  const menuSchema = {
2042
2316
  ["ribbon.start.history"]: {
2317
+ [ActivateFormatPainterOperation.id]: {
2318
+ order: 2,
2319
+ gridLayout: {
2320
+ row: 1,
2321
+ column: 2,
2322
+ showLabel: false
2323
+ },
2324
+ menuItemFactory: FormatPainterMenuItemFactory
2325
+ },
2326
+ [ClearFormattingCommand.id]: {
2327
+ order: 3,
2328
+ gridLayout: {
2329
+ row: 2,
2330
+ column: 2,
2331
+ showLabel: false
2332
+ },
2333
+ menuItemFactory: ClearFormattingMenuItemFactory
2334
+ },
2043
2335
  [UndoCommand.id]: {
2044
2336
  order: 0,
2045
2337
  gridLayout: {
@@ -2636,7 +2928,7 @@ function RectPopup(props) {
2636
2928
  const containerBottom = Math.min((boundaryRect === null || boundaryRect === void 0 ? void 0 : boundaryRect.bottom) ?? window.innerHeight, window.innerHeight);
2637
2929
  const containerWidth = Math.max(containerRight - containerLeft, 0);
2638
2930
  const containerHeight = Math.max(containerBottom - containerTop, 0);
2639
- const minimumGap = noPushMinimumGap ? 0 : PUSHING_MINIMUM_GAP * 2;
2931
+ const minimumGap = noPushMinimumGap ? 0 : 16;
2640
2932
  const cannotFitBoundary = boundaryElement != null && (containerWidth <= 0 || containerHeight <= 0 || containerWidth < clientWidth + minimumGap || containerHeight < clientHeight + minimumGap);
2641
2933
  nodeRef.current.style.visibility = cannotFitBoundary ? "hidden" : "";
2642
2934
  if (cannotFitBoundary) return;
@@ -2712,7 +3004,8 @@ function RectPopup(props) {
2712
3004
  window.removeEventListener("contextmenu", handleContextMenu);
2713
3005
  };
2714
3006
  }, [contextMenuFn]);
2715
- const dir = useObservable(useDependency(LocaleService).direction$);
3007
+ const localeService = useDependency(LocaleService);
3008
+ const dir = useObservable(localeService.direction$);
2716
3009
  const ele = /* @__PURE__ */ jsxs(Fragment$1, { children: [mask && /* @__PURE__ */ jsx("div", {
2717
3010
  "data-u-comp": "rect-popup-mask",
2718
3011
  className: "univer-fixed univer-inset-0 univer-z-[100]",
@@ -2765,10 +3058,11 @@ const SingleCanvasPopup = ({ popup, children }) => {
2765
3058
  var _popup$hiddenRects$;
2766
3059
  return ((_popup$hiddenRects$ = popup.hiddenRects$) === null || _popup$hiddenRects$ === void 0 ? void 0 : _popup$hiddenRects$.pipe(throttleTime(0, animationFrameScheduler))) ?? of([]);
2767
3060
  }, [popup.hiddenRects$]);
2768
- const excludeRectsRef = useObservableRef(useMemo(() => {
3061
+ const excludeRects$ = useMemo(() => {
2769
3062
  var _popup$excludeRects$;
2770
3063
  return (_popup$excludeRects$ = popup.excludeRects$) === null || _popup$excludeRects$ === void 0 ? void 0 : _popup$excludeRects$.pipe(throttleTime(0, animationFrameScheduler));
2771
- }, [popup.excludeRects$]), popup.excludeRects);
3064
+ }, [popup.excludeRects$]);
3065
+ const excludeRectsRef = useObservableRef(excludeRects$, popup.excludeRects);
2772
3066
  const { boundaryInsets, canvasElement, constrainToCanvas = false, hideOnInvisible = true, hiddenType = "destroy" } = popup;
2773
3067
  const hidden = useObservable(hideOnInvisible ? () => combineLatest([anchorRect$, hiddenRects$]).pipe(map(([rectWithOffset, hiddenRects]) => {
2774
3068
  const { top, left, bottom, right } = canvasElement.getBoundingClientRect();
@@ -2817,16 +3111,20 @@ const SingleCanvasPopup = ({ popup, children }) => {
2817
3111
  };
2818
3112
  function CanvasPopup() {
2819
3113
  const popupService = useDependency(ICanvasPopupService);
2820
- const componentManager = useDependency(ComponentManager);
2821
- return useObservable(popupService.popups$, void 0, true).map((item) => {
2822
- const [key, popup] = item;
2823
- const Component = componentManager.get(popup.componentKey);
2824
- const PopupComponent = Component && popup.connectorInjector ? connectInjector(Component, popup.connectorInjector) : Component;
2825
- return /* @__PURE__ */ jsx(SingleCanvasPopup, {
2826
- popup,
2827
- children: PopupComponent && /* @__PURE__ */ jsx(PopupComponent, { popup })
2828
- }, key);
2829
- });
3114
+ return useObservable(popupService.popups$, void 0, true).map(([key, popup]) => /* @__PURE__ */ jsx(SingleCanvasPopup, {
3115
+ popup,
3116
+ children: /* @__PURE__ */ jsx(CanvasPopupContent, { popup })
3117
+ }, key));
3118
+ }
3119
+ function CanvasPopupContent({ popup }) {
3120
+ const Component = useDependency(ComponentManager).get(popup.componentKey);
3121
+ const connectorContext = useMemo(() => ({ injector: popup.connectorInjector ?? null }), [popup.connectorInjector]);
3122
+ if (!Component) return null;
3123
+ const content = /* @__PURE__ */ jsx(Component, { popup });
3124
+ return popup.connectorInjector ? /* @__PURE__ */ jsx(RediContext.Provider, {
3125
+ value: connectorContext,
3126
+ children: content
3127
+ }) : content;
2830
3128
  }
2831
3129
 
2832
3130
  //#endregion
@@ -2878,13 +3176,15 @@ function ComponentContainer(props) {
2878
3176
  function useComponentsOfPart(part, injector) {
2879
3177
  const injectedUIPartsService = useDependency(IUIPartsService);
2880
3178
  const uiPartsService = (injector === null || injector === void 0 ? void 0 : injector.get(IUIPartsService)) ?? injectedUIPartsService;
2881
- const changeInfo = useObservable(useMemo(() => uiPartsService.uiVisibleChange$.pipe(filter((ui) => ui.ui === part)), [part, uiPartsService]));
3179
+ const uiVisibleChange$ = useMemo(() => uiPartsService.uiVisibleChange$.pipe(filter((ui) => ui.ui === part)), [part, uiPartsService]);
3180
+ const changeInfo = useObservable(uiVisibleChange$);
2882
3181
  const updateCounterRef = useRef(0);
2883
- return useMemo(() => uiPartsService.isUIVisible(part) ? uiPartsService.getComponents(part) : /* @__PURE__ */ new Set(), [useObservable(() => uiPartsService.componentRegistered$.pipe(filter((key) => key === part), debounceTime(200), map(() => updateCounterRef.current += 1), startWith(updateCounterRef.current += 1)), void 0, void 0, [
3182
+ const componentPartUpdateCount = useObservable(() => uiPartsService.componentRegistered$.pipe(filter((key) => key === part), debounceTime(200), map(() => updateCounterRef.current += 1), startWith(updateCounterRef.current += 1)), void 0, void 0, [
2884
3183
  uiPartsService,
2885
3184
  part,
2886
3185
  changeInfo
2887
- ])]);
3186
+ ]);
3187
+ return useMemo(() => uiPartsService.isUIVisible(part) ? uiPartsService.getComponents(part) : /* @__PURE__ */ new Set(), [componentPartUpdateCount]);
2888
3188
  }
2889
3189
 
2890
3190
  //#endregion
@@ -2990,7 +3290,7 @@ function RibbonGridMenu({ ribbon, activatedTab, onSelectTab }) {
2990
3290
  "aria-selected": isActive,
2991
3291
  title,
2992
3292
  onClick: () => onSelectTab(group),
2993
- className: clsx("univer-relative univer-flex univer-h-9 univer-cursor-pointer univer-items-center univer-whitespace-nowrap univer-border-0 univer-border-b-[3px] univer-bg-transparent univer-px-3 univer-text-base univer-font-semibold univer-text-gray-700 univer-transition-colors hover:univer-text-gray-900 focus-visible:univer-outline-none focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 dark:!univer-text-gray-200 dark:hover:!univer-text-gray-0", isActive ? "univer-border-primary-600 univer-text-primary-700 dark:!univer-text-primary-300" : "univer-border-transparent"),
3293
+ className: clsx("univer-relative univer-flex univer-h-8 univer-cursor-pointer univer-items-center univer-whitespace-nowrap univer-border-0 univer-border-b-[3px] univer-bg-transparent univer-px-3 univer-text-sm univer-font-semibold univer-text-gray-700 univer-transition-colors hover:univer-text-gray-900 focus-visible:univer-outline-none focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 dark:!univer-text-gray-200 dark:hover:!univer-text-gray-0", isActive ? "univer-border-primary-600 univer-text-primary-700 dark:!univer-text-primary-300" : "univer-border-transparent"),
2994
3294
  children: title
2995
3295
  }, group.key);
2996
3296
  })
@@ -3092,7 +3392,8 @@ function CustomLabel(props) {
3092
3392
  const componentManager = useDependency(ComponentManager);
3093
3393
  const iconManager = useDependency(IconManager);
3094
3394
  const subscribedValue = useObservable(value$ ?? null, value);
3095
- const subscribedIcon = useObservable(isObservable(icon) ? icon : null, "");
3395
+ const observableIcon = isObservable(icon) ? icon : null;
3396
+ const subscribedIcon = useObservable(observableIcon, "");
3096
3397
  const realIcon = isObservable(icon) ? subscribedIcon : icon ?? "";
3097
3398
  const nodes = [];
3098
3399
  let index = 0;
@@ -3160,9 +3461,10 @@ function useToolbarItemStatus(menuItem) {
3160
3461
  const disabled = useObservable(disabled$ ?? null, false);
3161
3462
  const activated = useObservable(activated$ ?? null, false);
3162
3463
  const hidden = useObservable(hidden$ ?? null, false);
3464
+ const valueObservable = useMemo(() => merge$1(value$ ?? EMPTY, selectionsValue$ ?? EMPTY), [selectionsValue$, value$]);
3163
3465
  return {
3164
3466
  disabled,
3165
- value: useObservable(useMemo(() => merge$1(value$ ?? EMPTY, selectionsValue$ ?? EMPTY), [selectionsValue$, value$])),
3467
+ value: useObservable(valueObservable),
3166
3468
  activated,
3167
3469
  hidden,
3168
3470
  selectionsValue: useObservable(selectionsValue$ ?? null)
@@ -3171,11 +3473,12 @@ function useToolbarItemStatus(menuItem) {
3171
3473
  function useToolbarShortcutDisplay({ id, commandId, shortcut }) {
3172
3474
  const shortcutService = useDependency(IShortcutService);
3173
3475
  const shortcutCommandId = commandId ?? id;
3174
- return useObservable(useMemo(() => shortcut ? of(shortcut) : shortcutService.shortcutChanged$.pipe(map(() => shortcutService.getShortcutDisplayOfCommand(shortcutCommandId)), startWith(shortcutService.getShortcutDisplayOfCommand(shortcutCommandId))), [
3476
+ const shortcut$ = useMemo(() => shortcut ? of(shortcut) : shortcutService.shortcutChanged$.pipe(map(() => shortcutService.getShortcutDisplayOfCommand(shortcutCommandId)), startWith(shortcutService.getShortcutDisplayOfCommand(shortcutCommandId))), [
3175
3477
  shortcut,
3176
3478
  shortcutService,
3177
3479
  shortcutCommandId
3178
- ]), null, true);
3480
+ ]);
3481
+ return useObservable(shortcut$, null, true);
3179
3482
  }
3180
3483
 
3181
3484
  //#endregion
@@ -3202,6 +3505,7 @@ univer-text-gray-900 univer-outline-none univer-transition-colors univer-animate
3202
3505
  dark:!univer-text-gray-0 dark:hover:!univer-bg-gray-700 dark:disabled:!univer-text-gray-600
3203
3506
  disabled:univer-cursor-not-allowed disabled:univer-text-gray-300 disabled:hover:univer-bg-transparent
3204
3507
  hover:univer-bg-gray-100 whitespace-nowrap univer-w-max
3508
+ [&_svg]:univer-shrink-0
3205
3509
  `;
3206
3510
  const toolbarButtonVariants = cva(toolbarButtonClassName, {
3207
3511
  variants: {
@@ -3240,11 +3544,11 @@ function ToolbarButton(props) {
3240
3544
  };
3241
3545
  return /* @__PURE__ */ jsx("button", {
3242
3546
  type: "button",
3243
- className: toolbarButtonVariants({
3547
+ className: clsx(toolbarButtonVariants({
3244
3548
  noIcon,
3245
3549
  active,
3246
3550
  className
3247
- }),
3551
+ })),
3248
3552
  style,
3249
3553
  disabled,
3250
3554
  onClick: handleClick,
@@ -3453,7 +3757,7 @@ function DropdownMenuWrapper({ menuId, slot, value, options, children, disabled,
3453
3757
  const menuManagerService = useDependency(IMenuManagerService);
3454
3758
  const resolveMenuItems = () => menuId ? menuManagerService.getMenuByPositionKey(menuId) : [];
3455
3759
  const menuItems = useObservable(() => menuManagerService.menuChanged$.pipe(map(resolveMenuItems), startWith(resolveMenuItems())), resolveMenuItems(), false, [menuId, menuManagerService]);
3456
- const hiddenStates = useObservable(useMemo(() => {
3760
+ const hiddenStates$ = useMemo(() => {
3457
3761
  const itemStates = menuItems.map((item) => {
3458
3762
  var _item$item;
3459
3763
  return (item.children ? combineLatest(item.children.map((subItem) => {
@@ -3465,7 +3769,8 @@ function DropdownMenuWrapper({ menuId, slot, value, options, children, disabled,
3465
3769
  ...states,
3466
3770
  [key]: hidden
3467
3771
  }), {}), startWith({})) : of({});
3468
- }, [menuItems]), {});
3772
+ }, [menuItems]);
3773
+ const hiddenStates = useObservable(hiddenStates$, {});
3469
3774
  const filteredMenuItems = useMemo(() => {
3470
3775
  return menuItems.filter((item) => {
3471
3776
  var _item$key;
@@ -3767,13 +4072,14 @@ const ToolbarItem = forwardRef((props, ref) => {
3767
4072
  let tooltipTitle = tooltip ? localeService.t(tooltip) : "";
3768
4073
  if (shortcutDisplay) tooltipTitle += ` (${shortcutDisplay})`;
3769
4074
  const { selections } = props;
3770
- const options = useObservable(useMemo(() => {
4075
+ const selections$ = useMemo(() => {
3771
4076
  if (isObservable(selections)) return selections;
3772
4077
  else return new Observable((subscribe) => {
3773
4078
  subscribe.next(selections);
3774
4079
  });
3775
- }, [selections]));
3776
- const iconToDisplay = useObservable(useMemo(() => {
4080
+ }, [selections]);
4081
+ const options = useObservable(selections$);
4082
+ const icon$ = useMemo(() => {
3777
4083
  if (isObservable(icon)) return icon;
3778
4084
  else return new Observable((subscribe) => {
3779
4085
  var _options$find;
@@ -3784,7 +4090,8 @@ const ToolbarItem = forwardRef((props, ref) => {
3784
4090
  icon,
3785
4091
  options,
3786
4092
  value
3787
- ]), void 0, true);
4093
+ ]);
4094
+ const iconToDisplay = useObservable(icon$, void 0, true);
3788
4095
  function renderSelectorType(menuType) {
3789
4096
  const selectionsCommandId = props.selectionsCommandId;
3790
4097
  const bId = commandId ?? id;
@@ -3814,6 +4121,7 @@ const ToolbarItem = forwardRef((props, ref) => {
3814
4121
  if (menuType === 2) return /* @__PURE__ */ jsxs("div", {
3815
4122
  "data-u-command": id,
3816
4123
  "data-disabled": disabled,
4124
+ "aria-disabled": disabled,
3817
4125
  className: clsx(toolbarButtonSelectorRootVariants({ disabled }), {
3818
4126
  "univer-box-border univer-h-full univer-min-w-14 univer-flex-col !univer-pr-0": grid && large,
3819
4127
  "univer-box-border univer-h-full": grid && !large
@@ -3823,7 +4131,7 @@ const ToolbarItem = forwardRef((props, ref) => {
3823
4131
  active: activated,
3824
4132
  disabled
3825
4133
  }), {
3826
- "univer-h-full univer-w-full univer-flex-col univer-justify-center univer-rounded univer-px-1 univer-pb-4 [&>svg]:univer-size-8": grid && large,
4134
+ "univer-h-full univer-w-full univer-flex-col univer-justify-center univer-rounded univer-px-1 univer-pb-4 [&>svg]:univer-size-6": grid && large,
3827
4135
  "[&>svg]:univer-size-4": grid && !large
3828
4136
  }),
3829
4137
  onClick: handleClick,
@@ -3879,7 +4187,7 @@ const ToolbarItem = forwardRef((props, ref) => {
3879
4187
  disabled,
3880
4188
  active: activated
3881
4189
  }), {
3882
- "univer-box-border univer-h-full univer-min-w-14 univer-flex-col univer-justify-center univer-gap-1 univer-px-1.5 univer-py-1 univer-text-xs [&>svg]:univer-size-8": grid && large,
4190
+ "univer-box-border univer-h-full univer-min-w-14 univer-flex-col univer-justify-center univer-gap-1 univer-px-1.5 univer-py-1 univer-text-xs [&>svg]:univer-size-6": grid && large,
3883
4191
  "univer-box-border univer-h-full": grid && !large,
3884
4192
  "univer-bg-gray-0 dark:!univer-bg-gray-800": grid && !large && !icon,
3885
4193
  "[&>svg]:univer-size-4": grid && !large
@@ -3914,7 +4222,7 @@ const ToolbarItem = forwardRef((props, ref) => {
3914
4222
  function renderButtonType() {
3915
4223
  const isCustomComponent = componentManager.get(typeof label === "string" ? label : (label === null || label === void 0 ? void 0 : label.name) ?? "");
3916
4224
  const buttonAriaLabel = tooltip ? localeService.t(tooltip) : typeof title === "string" ? localeService.t(title) : void 0;
3917
- const buttonClassName = clsx(grid && !large && "univer-h-full univer-min-w-8 [&>svg]:univer-size-4", grid && large ? "univer-h-full univer-min-w-14 univer-flex-col univer-gap-1 univer-px-1.5 univer-py-1 univer-text-xs [&>svg]:univer-size-8" : showLabel ? "univer-gap-1 univer-px-1.5 univer-text-sm" : "univer-text-sm", grid && fullWidth && isCustomComponent && "!univer-px-0");
4225
+ const buttonClassName = clsx(grid && !large && "[&>svg]:univer-size-4", grid && large ? "univer-h-full univer-min-w-14 univer-flex-col univer-gap-1 univer-px-1.5 univer-py-1 univer-text-xs [&>svg]:univer-size-6" : showLabel ? "univer-gap-1 univer-px-1.5 univer-text-sm" : "univer-text-sm", grid && fullWidth && isCustomComponent && "!univer-px-0");
3918
4226
  const buttonStyle = grid && large ? {
3919
4227
  textAlign: "center",
3920
4228
  whiteSpace: "normal"
@@ -3923,11 +4231,11 @@ const ToolbarItem = forwardRef((props, ref) => {
3923
4231
  const hoverable = typeof label === "string" || (label === null || label === void 0 ? void 0 : label.hoverable) !== false;
3924
4232
  return /* @__PURE__ */ jsx("span", {
3925
4233
  "data-u-command": id,
3926
- className: toolbarButtonVariants({
4234
+ className: clsx(toolbarButtonVariants({
3927
4235
  noIcon: !icon,
3928
4236
  active: activated,
3929
4237
  className: clsx(buttonClassName, !hoverable && "univer-cursor-default !univer-bg-transparent hover:!univer-bg-transparent dark:hover:!univer-bg-transparent")
3930
- }),
4238
+ })),
3931
4239
  style: buttonStyle,
3932
4240
  "aria-disabled": disabled,
3933
4241
  children: /* @__PURE__ */ jsx(CustomLabel, {
@@ -3945,8 +4253,10 @@ const ToolbarItem = forwardRef((props, ref) => {
3945
4253
  style: buttonStyle,
3946
4254
  noIcon: !icon,
3947
4255
  active: activated,
4256
+ "aria-pressed": props.activated$ ? activated : void 0,
3948
4257
  disabled,
3949
- onClick: () => {
4258
+ onClick: (event) => {
4259
+ if (props.subId && event.detail > 1) return;
3950
4260
  const commandParams = typeof params === "function" ? params() : params;
3951
4261
  executeCommand(props.commandId ?? props.id, commandParams ?? (typeof value === "undefined" ? void 0 : { value }));
3952
4262
  },
@@ -3985,17 +4295,18 @@ function RibbonGrid({ groups, title, className, ...props }) {
3985
4295
  ...props,
3986
4296
  "data-testid": "ribbon-grid-toolbar",
3987
4297
  "data-u-comp": "ribbon-grid-toolbar",
3988
- className: clsx("univer-box-border univer-flex univer-h-[88px] univer-overflow-x-auto univer-overflow-y-hidden univer-bg-gray-50 univer-px-2 univer-text-sm dark:!univer-bg-gray-900", borderBottomClassName, scrollbarClassName, className),
4298
+ className: clsx("univer-box-border univer-flex univer-overflow-x-auto univer-overflow-y-hidden univer-bg-gray-50 univer-px-2 univer-text-sm dark:!univer-bg-gray-900", borderBottomClassName, scrollbarClassName, className),
3989
4299
  role: "toolbar",
3990
4300
  "aria-label": localeService.t(title),
3991
4301
  children: /* @__PURE__ */ jsx(ToolbarDropdownProvider, { children: groups.map((group) => {
4302
+ const placements = placeRibbonGridItems(group.children ?? []);
3992
4303
  return /* @__PURE__ */ jsxs("div", {
3993
4304
  "data-u-comp": "ribbon-grid-group",
3994
4305
  className: "univer-relative univer-box-border univer-flex univer-min-w-16 univer-shrink-0 univer-flex-col univer-px-2",
3995
4306
  children: [/* @__PURE__ */ jsx("div", {
3996
4307
  "data-testid": "ribbon-grid-group-grid",
3997
- className: "univer-grid univer-min-h-0 univer-flex-1 univer-grid-flow-col univer-grid-rows-2 univer-content-center univer-gap-x-1 univer-gap-y-2 univer-py-2 [&>div>span>span]:univer-h-full",
3998
- children: placeRibbonGridItems(group.children ?? []).map((placement) => placement.item.item && /* @__PURE__ */ jsx("div", {
4308
+ className: "univer-grid univer-min-h-0 univer-flex-1 univer-grid-flow-col univer-grid-rows-[repeat(2,1.5rem)] univer-content-center univer-gap-2 univer-py-2 [&>div>span>span]:univer-h-full",
4309
+ children: placements.map((placement) => placement.item.item && /* @__PURE__ */ jsx("div", {
3999
4310
  className: clsx("univer-flex univer-items-stretch [&>span>button]:univer-h-full [&>span]:univer-h-full", placement.width && "[&>span>span]:univer-w-full [&>span]:univer-w-full [&_[data-u-command]]:univer-w-full"),
4000
4311
  style: {
4001
4312
  gridRow: `${placement.row} / span ${placement.rowSpan}`,
@@ -4171,108 +4482,110 @@ function Ribbon(props) {
4171
4482
  "data-embed-ribbon-override": "true",
4172
4483
  "data-embed-id": ribbonOverride.id
4173
4484
  } : {};
4174
- return /* @__PURE__ */ jsx(RibbonOverrideRuntimeProvider, {
4175
- override: ribbonOverride,
4176
- children: /* @__PURE__ */ jsxs(Fragment$1, { children: [
4177
- /* @__PURE__ */ jsxs("div", {
4178
- "data-u-comp": "ribbon-header-menu",
4179
- ...embedRibbonOverrideAttributes,
4180
- className: clsx("univer-relative univer-select-none", headerClassName, {
4181
- "univer-hidden": toolbarOnly,
4182
- "univer-h-9": !toolbarOnly && (ribbonType === "classic" || ribbonType === "grid" || headerMenuComponents && headerMenuComponents.size > 0)
4183
- }),
4184
- children: [
4185
- !toolbarOnly && (ribbonOverride === null || ribbonOverride === void 0 ? void 0 : ribbonOverride.placeholderTitle) && ribbon.length === 0 && /* @__PURE__ */ jsx("div", {
4186
- className: clsx("univer-flex univer-h-9 univer-items-end univer-px-3", { "univer-justify-center": hideToolbar }),
4187
- children: /* @__PURE__ */ jsx("span", {
4188
- className: "univer-relative univer-inline-flex univer-h-8 univer-items-center univer-justify-center univer-rounded-t univer-bg-primary-50 univer-px-3 univer-text-sm univer-font-medium univer-text-primary-600",
4189
- children: ribbonOverride.placeholderTitle
4190
- })
4191
- }),
4192
- !toolbarOnly && ribbonType === "classic" && ribbon.length >= 1 && /* @__PURE__ */ jsx(ClassicMenu, {
4193
- ribbon,
4194
- activatedTab,
4195
- onSelectTab: handleSelectTab
4196
- }),
4197
- !toolbarOnly && ribbonType === "grid" && ribbon.length >= 1 && /* @__PURE__ */ jsx(RibbonGridMenu, {
4198
- ribbon,
4199
- activatedTab,
4200
- onSelectTab: handleSelectTab
4201
- }),
4202
- headerMenu && headerMenuComponents && headerMenuComponents.size > 0 && /* @__PURE__ */ jsx("div", {
4203
- className: "univer-absolute univer-right-2 univer-top-0 univer-flex univer-h-full univer-flex-row univer-items-center univer-gap-2 rtl:univer-left-2 rtl:univer-right-auto [&>*]:univer-inline-flex [&>*]:univer-h-6 [&>*]:univer-items-center [&>*]:univer-rounded [&>*]:univer-px-1 [&>*]:univer-transition-colors hover:[&>*]:univer-bg-gray-100",
4204
- children: /* @__PURE__ */ jsx(ComponentContainer, { components: headerMenuComponents })
4205
- })
4206
- ]
4207
- }),
4208
- !hideToolbar && ribbonType === "grid" && /* @__PURE__ */ jsx(RibbonGrid, {
4209
- ...embedRibbonOverrideAttributes,
4210
- groups: activeGroup.allGroups,
4211
- title: activatedTabTitle
4485
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
4486
+ /* @__PURE__ */ jsxs("div", {
4487
+ "data-u-comp": "ribbon-header-menu",
4488
+ ...embedRibbonOverrideAttributes,
4489
+ className: clsx("univer-relative univer-select-none", headerClassName, {
4490
+ "univer-hidden": toolbarOnly,
4491
+ "univer-h-8": !toolbarOnly && ribbonType === "grid",
4492
+ "univer-h-9": !toolbarOnly && ribbonType !== "grid" && (ribbonType === "classic" || headerMenuComponents && headerMenuComponents.size > 0)
4212
4493
  }),
4213
- !hideToolbar && ribbonType !== "grid" && /* @__PURE__ */ jsxs("div", {
4214
- ...embedRibbonOverrideAttributes,
4215
- className: clsx("univer-box-border univer-grid univer-h-10 univer-grid-flow-col univer-items-center univer-px-3 univer-text-sm", {
4216
- "univer-grid-cols-[1fr] univer-justify-center": ribbonType === "classic" || ribbon.length === 1,
4217
- "univer-grid-cols-[auto,1fr]": ribbon.length > 1 && ribbonType !== "classic"
4218
- }, borderBottomClassName),
4219
- children: [ribbonType === "collapsed" && ribbon.length >= 1 && /* @__PURE__ */ jsx(DefaultMenu, {
4494
+ children: [
4495
+ !toolbarOnly && (ribbonOverride === null || ribbonOverride === void 0 ? void 0 : ribbonOverride.placeholderTitle) && ribbon.length === 0 && /* @__PURE__ */ jsx("div", {
4496
+ className: clsx("univer-flex univer-h-9 univer-items-end univer-px-3", { "univer-justify-center": hideToolbar }),
4497
+ children: /* @__PURE__ */ jsx("span", {
4498
+ className: "univer-relative univer-inline-flex univer-h-8 univer-items-center univer-justify-center univer-rounded-t univer-bg-primary-50 univer-px-3 univer-text-sm univer-font-medium univer-text-primary-600",
4499
+ children: ribbonOverride.placeholderTitle
4500
+ })
4501
+ }),
4502
+ !toolbarOnly && ribbonType === "classic" && ribbon.length >= 1 && /* @__PURE__ */ jsx(ClassicMenu, {
4220
4503
  ribbon,
4221
4504
  activatedTab,
4222
4505
  onSelectTab: handleSelectTab
4223
- }), /* @__PURE__ */ jsx("div", {
4224
- "data-u-comp": "ribbon-toolbar",
4225
- ref: containerRef,
4226
- className: clsx("univer-flex univer-overflow-hidden", divideXClassName, { "univer-justify-center": ribbonType === "classic" }),
4227
- role: "toolbar",
4228
- "aria-label": localeService.t(activatedTabTitle),
4229
- children: /* @__PURE__ */ jsxs(ToolbarDropdownProvider, { children: [activeGroup.visibleGroups.map((groupItem) => {
4230
- var _groupItem$children3, _groupItem$children4;
4231
- return (((_groupItem$children3 = groupItem.children) === null || _groupItem$children3 === void 0 ? void 0 : _groupItem$children3.length) || groupItem.item) && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("div", {
4232
- className: "univer-grid univer-shrink-0 univer-grid-flow-col univer-gap-2 univer-px-2 empty:univer-hidden",
4233
- children: groupItem.children && ((_groupItem$children4 = groupItem.children) === null || _groupItem$children4 === void 0 ? void 0 : _groupItem$children4.map((child) => child.item && /* @__PURE__ */ jsx(ToolbarItem, {
4234
- ...child.item,
4235
- preserveStrokeWidth: true
4236
- }, child.key)))
4237
- }) }, groupItem.key);
4238
- }), collapsedIds.length > 0 && /* @__PURE__ */ jsx("div", {
4239
- className: "univer-pl-2 rtl:univer-pr-2",
4240
- children: /* @__PURE__ */ jsx(Dropdown, {
4241
- collisionPadding: {
4242
- right: 12,
4243
- left: 12
4244
- },
4245
- onOpenAutoFocus: (e) => e.preventDefault(),
4246
- overlay: /* @__PURE__ */ jsx("div", {
4247
- className: "univer-box-border univer-grid univer-max-w-[--radix-popper-available-width] univer-gap-2 univer-p-2",
4248
- children: activeGroup.hiddenGroups.map((groupItem) => {
4249
- var _groupItem$children5;
4250
- return /* @__PURE__ */ jsx("div", {
4251
- className: "univer-flex univer-items-center univer-gap-2",
4252
- children: /* @__PURE__ */ jsx("div", {
4253
- className: "univer-flex univer-flex-wrap univer-gap-2",
4254
- children: groupItem.children ? (_groupItem$children5 = groupItem.children) === null || _groupItem$children5 === void 0 ? void 0 : _groupItem$children5.map((child) => child.item && /* @__PURE__ */ jsx(ToolbarItem, {
4255
- ...child.item,
4256
- preserveStrokeWidth: true
4257
- }, child.key)) : groupItem.item && /* @__PURE__ */ jsx(ToolbarItem, {
4258
- ...groupItem.item,
4259
- preserveStrokeWidth: true
4260
- }, groupItem.key)
4261
- })
4262
- }, groupItem.key);
4263
- })
4264
- }),
4265
- children: /* @__PURE__ */ jsx("button", {
4266
- type: "button",
4267
- className: toolbarButtonClassName,
4268
- children: /* @__PURE__ */ jsx(MoreVerticalIcon, { preserveStrokeWidth: true })
4506
+ }),
4507
+ !toolbarOnly && ribbonType === "grid" && ribbon.length >= 1 && /* @__PURE__ */ jsx(RibbonGridMenu, {
4508
+ ribbon,
4509
+ activatedTab,
4510
+ onSelectTab: handleSelectTab
4511
+ }),
4512
+ headerMenu && headerMenuComponents && headerMenuComponents.size > 0 && /* @__PURE__ */ jsx("div", {
4513
+ className: "univer-absolute univer-right-2 univer-top-0 univer-flex univer-h-full univer-flex-row univer-items-center univer-gap-2 rtl:univer-left-2 rtl:univer-right-auto [&>*]:univer-inline-flex [&>*]:univer-h-6 [&>*]:univer-items-center [&>*]:univer-rounded [&>*]:univer-px-1 [&>*]:univer-transition-colors hover:[&>*]:univer-bg-gray-100",
4514
+ children: /* @__PURE__ */ jsx(ComponentContainer, { components: headerMenuComponents })
4515
+ })
4516
+ ]
4517
+ }),
4518
+ !hideToolbar && ribbonType === "grid" && /* @__PURE__ */ jsx(RibbonGrid, {
4519
+ ...embedRibbonOverrideAttributes,
4520
+ groups: activeGroup.allGroups,
4521
+ title: activatedTabTitle
4522
+ }),
4523
+ !hideToolbar && ribbonType !== "grid" && /* @__PURE__ */ jsxs("div", {
4524
+ ...embedRibbonOverrideAttributes,
4525
+ className: clsx("univer-box-border univer-grid univer-h-10 univer-grid-flow-col univer-items-center univer-px-3 univer-text-sm", {
4526
+ "univer-grid-cols-[1fr] univer-justify-center": ribbonType === "classic" || ribbon.length === 1,
4527
+ "univer-grid-cols-[auto,1fr]": ribbon.length > 1 && ribbonType !== "classic"
4528
+ }, borderBottomClassName),
4529
+ children: [ribbonType === "collapsed" && ribbon.length >= 1 && /* @__PURE__ */ jsx(DefaultMenu, {
4530
+ ribbon,
4531
+ activatedTab,
4532
+ onSelectTab: handleSelectTab
4533
+ }), /* @__PURE__ */ jsx("div", {
4534
+ "data-u-comp": "ribbon-toolbar",
4535
+ ref: containerRef,
4536
+ className: clsx("univer-flex univer-overflow-hidden", divideXClassName, { "univer-justify-center": ribbonType === "classic" }),
4537
+ role: "toolbar",
4538
+ "aria-label": localeService.t(activatedTabTitle),
4539
+ children: /* @__PURE__ */ jsxs(ToolbarDropdownProvider, { children: [activeGroup.visibleGroups.map((groupItem) => {
4540
+ var _groupItem$children3, _groupItem$children4;
4541
+ return (((_groupItem$children3 = groupItem.children) === null || _groupItem$children3 === void 0 ? void 0 : _groupItem$children3.length) || groupItem.item) && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("div", {
4542
+ className: "univer-grid univer-shrink-0 univer-grid-flow-col univer-gap-2 univer-px-2 empty:univer-hidden",
4543
+ children: groupItem.children && ((_groupItem$children4 = groupItem.children) === null || _groupItem$children4 === void 0 ? void 0 : _groupItem$children4.map((child) => child.item && /* @__PURE__ */ jsx(ToolbarItem, {
4544
+ ...child.item,
4545
+ preserveStrokeWidth: true
4546
+ }, child.key)))
4547
+ }) }, groupItem.key);
4548
+ }), collapsedIds.length > 0 && /* @__PURE__ */ jsx("div", {
4549
+ className: "univer-pl-2 rtl:univer-pr-2",
4550
+ children: /* @__PURE__ */ jsx(Dropdown, {
4551
+ collisionPadding: {
4552
+ right: 12,
4553
+ left: 12
4554
+ },
4555
+ onOpenAutoFocus: (e) => e.preventDefault(),
4556
+ overlay: /* @__PURE__ */ jsx("div", {
4557
+ className: "univer-box-border univer-grid univer-max-w-[--radix-popper-available-width] univer-gap-2 univer-p-2",
4558
+ children: activeGroup.hiddenGroups.map((groupItem) => {
4559
+ var _groupItem$children5;
4560
+ return /* @__PURE__ */ jsx("div", {
4561
+ className: "univer-flex univer-items-center univer-gap-2",
4562
+ children: /* @__PURE__ */ jsx("div", {
4563
+ className: "univer-flex univer-flex-wrap univer-gap-2",
4564
+ children: groupItem.children ? (_groupItem$children5 = groupItem.children) === null || _groupItem$children5 === void 0 ? void 0 : _groupItem$children5.map((child) => child.item && /* @__PURE__ */ jsx(ToolbarItem, {
4565
+ ...child.item,
4566
+ preserveStrokeWidth: true
4567
+ }, child.key)) : groupItem.item && /* @__PURE__ */ jsx(ToolbarItem, {
4568
+ ...groupItem.item,
4569
+ preserveStrokeWidth: true
4570
+ }, groupItem.key)
4571
+ })
4572
+ }, groupItem.key);
4269
4573
  })
4574
+ }),
4575
+ children: /* @__PURE__ */ jsx("button", {
4576
+ type: "button",
4577
+ className: toolbarButtonClassName,
4578
+ children: /* @__PURE__ */ jsx(MoreVerticalIcon, { preserveStrokeWidth: true })
4270
4579
  })
4271
- })] }, effectiveActivatedTab)
4272
- })]
4273
- }),
4274
- ribbonType !== "grid" && fakeToolbar
4275
- ] })
4580
+ })
4581
+ })] }, effectiveActivatedTab)
4582
+ })]
4583
+ }),
4584
+ ribbonType !== "grid" && fakeToolbar
4585
+ ] });
4586
+ return /* @__PURE__ */ jsx(RibbonOverrideRuntimeProvider, {
4587
+ override: ribbonOverride,
4588
+ children: content
4276
4589
  });
4277
4590
  }
4278
4591
  function RibbonOverrideRuntimeProvider(props) {
@@ -4719,35 +5032,36 @@ function UITinyMenuGroup(props) {
4719
5032
  item.children
4720
5033
  ]);
4721
5034
  if (!item.children) return null;
5035
+ const items = visibleChildren.map((child) => {
5036
+ var _child$item4, _child$item12, _child$item13, _child$item14, _child$item15;
5037
+ const Icon = ((_child$item4 = child.item) === null || _child$item4 === void 0 ? void 0 : _child$item4.icon) ? iconManager.get(child.item.icon) : void 0;
5038
+ if (!Icon) return null;
5039
+ return {
5040
+ key: child.key,
5041
+ onClick: () => {
5042
+ var _child$item5, _child$item6, _child$item7, _child$item8, _child$item9, _child$item10, _child$item11;
5043
+ onOptionSelect === null || onOptionSelect === void 0 || onOptionSelect({
5044
+ label: ((_child$item5 = child.item) === null || _child$item5 === void 0 ? void 0 : _child$item5.id) ?? child.key,
5045
+ commandId: (_child$item6 = child.item) === null || _child$item6 === void 0 ? void 0 : _child$item6.commandId,
5046
+ id: (_child$item7 = child.item) === null || _child$item7 === void 0 ? void 0 : _child$item7.id,
5047
+ params: (_child$item8 = child.item) === null || _child$item8 === void 0 ? void 0 : _child$item8.params,
5048
+ value: (_child$item9 = child.item) === null || _child$item9 === void 0 ? void 0 : _child$item9.value,
5049
+ tooltip: ((_child$item10 = child.item) === null || _child$item10 === void 0 ? void 0 : _child$item10.tooltip) && localeService.t((_child$item11 = child.item) === null || _child$item11 === void 0 ? void 0 : _child$item11.tooltip)
5050
+ });
5051
+ },
5052
+ className: "",
5053
+ iconClassName: ((_child$item12 = child.item) === null || _child$item12 === void 0 ? void 0 : _child$item12.icon) === "TextTypeIcon" ? sizeVariant === "paragraph-t" ? "!univer-size-4" : "!univer-size-3.5" : void 0,
5054
+ Icon,
5055
+ active: resolveMenuItemActiveState((_child$item13 = child.item) === null || _child$item13 === void 0 ? void 0 : _child$item13.id, activeItems.includes(((_child$item14 = child.item) === null || _child$item14 === void 0 ? void 0 : _child$item14.id) ?? ""), activeItemIds),
5056
+ tooltip: ((_child$item15 = child.item) === null || _child$item15 === void 0 ? void 0 : _child$item15.tooltip) ? localeService.t(child.item.tooltip) : void 0
5057
+ };
5058
+ }).filter((child) => child != null);
4722
5059
  return /* @__PURE__ */ jsx(DesignTinyMenuGroup, {
4723
5060
  columns,
4724
5061
  sizeVariant,
4725
5062
  layoutVariant,
4726
5063
  hoverSuppressed,
4727
- items: visibleChildren.map((child) => {
4728
- var _child$item4, _child$item12, _child$item13, _child$item14, _child$item15;
4729
- const Icon = ((_child$item4 = child.item) === null || _child$item4 === void 0 ? void 0 : _child$item4.icon) ? iconManager.get(child.item.icon) : void 0;
4730
- if (!Icon) return null;
4731
- return {
4732
- key: child.key,
4733
- onClick: () => {
4734
- var _child$item5, _child$item6, _child$item7, _child$item8, _child$item9, _child$item10, _child$item11;
4735
- onOptionSelect === null || onOptionSelect === void 0 || onOptionSelect({
4736
- label: ((_child$item5 = child.item) === null || _child$item5 === void 0 ? void 0 : _child$item5.id) ?? child.key,
4737
- commandId: (_child$item6 = child.item) === null || _child$item6 === void 0 ? void 0 : _child$item6.commandId,
4738
- id: (_child$item7 = child.item) === null || _child$item7 === void 0 ? void 0 : _child$item7.id,
4739
- params: (_child$item8 = child.item) === null || _child$item8 === void 0 ? void 0 : _child$item8.params,
4740
- value: (_child$item9 = child.item) === null || _child$item9 === void 0 ? void 0 : _child$item9.value,
4741
- tooltip: ((_child$item10 = child.item) === null || _child$item10 === void 0 ? void 0 : _child$item10.tooltip) && localeService.t((_child$item11 = child.item) === null || _child$item11 === void 0 ? void 0 : _child$item11.tooltip)
4742
- });
4743
- },
4744
- className: "",
4745
- iconClassName: ((_child$item12 = child.item) === null || _child$item12 === void 0 ? void 0 : _child$item12.icon) === "TextTypeIcon" ? sizeVariant === "paragraph-t" ? "!univer-size-4" : "!univer-size-3.5" : void 0,
4746
- Icon,
4747
- active: resolveMenuItemActiveState((_child$item13 = child.item) === null || _child$item13 === void 0 ? void 0 : _child$item13.id, activeItems.includes(((_child$item14 = child.item) === null || _child$item14 === void 0 ? void 0 : _child$item14.id) ?? ""), activeItemIds),
4748
- tooltip: ((_child$item15 = child.item) === null || _child$item15 === void 0 ? void 0 : _child$item15.tooltip) ? localeService.t(child.item.tooltip) : void 0
4749
- };
4750
- }).filter((child) => child != null)
5064
+ items
4751
5065
  });
4752
5066
  }
4753
5067
  function UIQuickTileMenuGroup(props) {
@@ -5106,13 +5420,15 @@ function ContextMenuPanel(props) {
5106
5420
  const [menuElement, setMenuElement] = useState(null);
5107
5421
  const [maxMenuHeight, setMaxMenuHeight] = useState(() => {
5108
5422
  if (typeof window === "undefined") return 240;
5109
- return Math.max(120, window.innerHeight - menuViewportPadding * 2);
5423
+ return Math.max(120, window.innerHeight - 16);
5110
5424
  });
5111
5425
  const [hoverSuppressed, setHoverSuppressed] = useState(suppressHoverUntilPointerMove);
5426
+ const menuSchemaVersion$ = useMemo(() => menuManagerService.menuChanged$.pipe(startWith(void 0), scan((version) => version + 1, 0)), [menuManagerService]);
5427
+ const menuSchemaVersion = useObservable(menuSchemaVersion$, 0);
5112
5428
  const menuItems = useMemo(() => menuType ? menuManagerService.getMenuByPositionKey(menuType) : [], [
5113
5429
  menuManagerService,
5114
5430
  menuType,
5115
- useObservable(useMemo(() => menuManagerService.menuChanged$.pipe(startWith(void 0), scan((version) => version + 1, 0)), [menuManagerService]), 0),
5431
+ menuSchemaVersion,
5116
5432
  menuSessionVersion
5117
5433
  ]);
5118
5434
  const submenuPortalContainer = ((_layoutService$rootCo = layoutService.rootContainerElement) === null || _layoutService$rootCo === void 0 || (_layoutService$rootCo = _layoutService$rootCo.ownerDocument) === null || _layoutService$rootCo === void 0 ? void 0 : _layoutService$rootCo.body) ?? (typeof document !== "undefined" ? document.body : null);
@@ -5186,7 +5502,7 @@ function ContextMenuPanel(props) {
5186
5502
  const updateMaxHeight = () => {
5187
5503
  if (frameId) defaultView.cancelAnimationFrame(frameId);
5188
5504
  frameId = defaultView.requestAnimationFrame(() => {
5189
- setMaxMenuHeight(Math.max(120, defaultView.innerHeight - menuViewportPadding * 2));
5505
+ setMaxMenuHeight(Math.max(120, defaultView.innerHeight - 16));
5190
5506
  });
5191
5507
  };
5192
5508
  updateMaxHeight();
@@ -5728,7 +6044,7 @@ function ContextMenuMenuItem(props) {
5728
6044
  });
5729
6045
  }
5730
6046
  function useContextGroupHiddenStates$1(menuSchemas) {
5731
- return useObservable(useMemo(() => {
6047
+ const hiddenStates$ = useMemo(() => {
5732
6048
  const groupStates = menuSchemas.flatMap((menuSchema) => {
5733
6049
  var _menuSchema$children3;
5734
6050
  const hiddenObservables = ((_menuSchema$children3 = menuSchema.children) === null || _menuSchema$children3 === void 0 ? void 0 : _menuSchema$children3.map((childSchema) => {
@@ -5741,7 +6057,8 @@ function useContextGroupHiddenStates$1(menuSchemas) {
5741
6057
  ...states,
5742
6058
  [key]: hidden
5743
6059
  }), {}), startWith({})) : of({});
5744
- }, [menuSchemas]), {});
6060
+ }, [menuSchemas]);
6061
+ return useObservable(hiddenStates$, {});
5745
6062
  }
5746
6063
 
5747
6064
  //#endregion
@@ -6403,7 +6720,8 @@ function DesktopWorkbench(props) {
6403
6720
  });
6404
6721
  }
6405
6722
  function mountDesktopWorkbench(injector, options, mountContainer, onRendered) {
6406
- render(/* @__PURE__ */ jsx(connectInjector(DesktopWorkbench, injector), {
6723
+ const ConnectedApp = connectInjector(DesktopWorkbench, injector);
6724
+ render(/* @__PURE__ */ jsx(ConnectedApp, {
6407
6725
  ...options,
6408
6726
  mountContainer,
6409
6727
  onRendered
@@ -6538,7 +6856,8 @@ function DesktopWorkbenchContent(props) {
6538
6856
  }
6539
6857
  function FloatingContainer() {
6540
6858
  const { mountContainer } = useContext(ConfigContext);
6541
- return createPortal(/* @__PURE__ */ jsx(ComponentContainer, { components: useComponentsOfPart("floating") }, "floating"), mountContainer);
6859
+ const floatingComponents = useComponentsOfPart("floating");
6860
+ return createPortal(/* @__PURE__ */ jsx(ComponentContainer, { components: floatingComponents }, "floating"), mountContainer);
6542
6861
  }
6543
6862
 
6544
6863
  //#endregion
@@ -6686,7 +7005,7 @@ const IUIController = createIdentifier("univer.ui.ui-controller");
6686
7005
  //#endregion
6687
7006
  //#region package.json
6688
7007
  var name = "@univerjs/ui";
6689
- var version = "1.0.0-rc.0";
7008
+ var version = "1.0.1";
6690
7009
 
6691
7010
  //#endregion
6692
7011
  //#region src/views/color-picker/interface.ts
@@ -6727,13 +7046,14 @@ const COLOR_PICKER_COMPONENT = "UI_COLOR_PICKER_COMPONENT";
6727
7046
  const CommonLabel = (props) => {
6728
7047
  const { value, selections } = props;
6729
7048
  const localeService = useDependency(LocaleService);
7049
+ const viewValue = useMemo(() => {
7050
+ var _selections$find;
7051
+ if (value == null) return "";
7052
+ return localeService.t(((_selections$find = selections.find((item) => item.value === value)) === null || _selections$find === void 0 ? void 0 : _selections$find.label) ?? "");
7053
+ }, [value, selections]);
6730
7054
  return /* @__PURE__ */ jsx("div", {
6731
7055
  className: "univer-truncate univer-text-sm",
6732
- children: useMemo(() => {
6733
- var _selections$find;
6734
- if (value == null) return "";
6735
- return localeService.t(((_selections$find = selections.find((item) => item.value === value)) === null || _selections$find === void 0 ? void 0 : _selections$find.label) ?? "");
6736
- }, [value, selections])
7056
+ children: viewValue
6737
7057
  });
6738
7058
  };
6739
7059
  const COMMON_LABEL_COMPONENT = "UI_PLUGIN_COMMON_LABEL_COMPONENT";
@@ -22937,10 +23257,11 @@ let FontService = class FontService {
22937
23257
  _defineProperty(this, "fonts$", new BehaviorSubject([]));
22938
23258
  const { customFontFamily } = this._configService.getConfig("ui.config") ?? {};
22939
23259
  let fonts = [];
22940
- if (customFontFamily) if (Array.isArray(customFontFamily)) fonts = [...DEFAULT_FONT_LIST, ...customFontFamily];
22941
- else if (customFontFamily.override) fonts = [...customFontFamily.list];
22942
- else fonts = [...DEFAULT_FONT_LIST, ...customFontFamily.list];
22943
- else fonts = [...DEFAULT_FONT_LIST];
23260
+ if (customFontFamily) {
23261
+ if (Array.isArray(customFontFamily)) fonts = [...DEFAULT_FONT_LIST, ...customFontFamily];
23262
+ else if (customFontFamily.override) fonts = [...customFontFamily.list];
23263
+ else fonts = [...DEFAULT_FONT_LIST, ...customFontFamily.list];
23264
+ } else fonts = [...DEFAULT_FONT_LIST];
22944
23265
  this.fonts$.next(fonts);
22945
23266
  }
22946
23267
  dispose() {
@@ -23486,11 +23807,12 @@ function SymbolPicker(props) {
23486
23807
  });
23487
23808
  }
23488
23809
  function SymbolSection(props) {
23810
+ const localeService = useDependency(LocaleService);
23489
23811
  return /* @__PURE__ */ jsxs("section", {
23490
23812
  className: "univer-flex univer-flex-col univer-gap-2",
23491
23813
  children: [/* @__PURE__ */ jsx("div", {
23492
23814
  className: "univer-text-sm univer-font-semibold univer-text-gray-900 dark:!univer-text-gray-100",
23493
- children: useDependency(LocaleService).t(props.category.titleKey)
23815
+ children: localeService.t(props.category.titleKey)
23494
23816
  }), /* @__PURE__ */ jsx("div", {
23495
23817
  className: "univer-grid univer-grid-cols-10 univer-gap-1",
23496
23818
  children: props.category.symbols.map((symbol, index) => {
@@ -23607,7 +23929,8 @@ function MobileRibbon(props) {
23607
23929
  const workbenchService = useDependency(IWorkbenchService);
23608
23930
  const ribbon = useObservable(ribbonService.ribbon$, []);
23609
23931
  const activatedTab = useObservable(ribbonService.activatedTab$, "ribbon.start");
23610
- if (useObservable(workbenchService.rootUnitType$, null, true) === UniverInstanceType.UNIVER_SHEET) return /* @__PURE__ */ jsx(MobileSheetTopBar, {
23932
+ const rootUnitType = useObservable(workbenchService.rootUnitType$, null, true);
23933
+ if (rootUnitType === UniverInstanceType.UNIVER_SHEET || rootUnitType === UniverInstanceType.UNIVER_DOC) return /* @__PURE__ */ jsx(MobileCompactTopBar, {
23611
23934
  ribbon,
23612
23935
  headerMenu,
23613
23936
  headerMenuComponents
@@ -23648,11 +23971,12 @@ function MobileRibbonToolbar(props) {
23648
23971
  setCanScrollLeft(scrollLeft > 4);
23649
23972
  setCanScrollRight(scrollLeft + clientWidth < scrollWidth - 4);
23650
23973
  };
23651
- updateScrollState();
23974
+ const animationFrame = requestAnimationFrame(updateScrollState);
23652
23975
  const resizeObserver = new ResizeObserver(updateScrollState);
23653
23976
  resizeObserver.observe(container);
23654
23977
  container.addEventListener("scroll", updateScrollState, { passive: true });
23655
23978
  return () => {
23979
+ cancelAnimationFrame(animationFrame);
23656
23980
  resizeObserver.disconnect();
23657
23981
  container.removeEventListener("scroll", updateScrollState);
23658
23982
  };
@@ -23792,7 +24116,7 @@ function MobileRibbonToolbar(props) {
23792
24116
  })]
23793
24117
  });
23794
24118
  }
23795
- function MobileSheetTopBar(props) {
24119
+ function MobileCompactTopBar(props) {
23796
24120
  var _startGroup$children, _startGroup$children2, _moreTriggerRef$curre, _moreTriggerRef$curre2;
23797
24121
  const { headerMenuComponents, headerMenu = true, ribbon } = props;
23798
24122
  const [moreOpen, setMoreOpen] = useState(false);
@@ -23817,7 +24141,7 @@ function MobileSheetTopBar(props) {
23817
24141
  className: clsx(resetButtonClassName, "univer-fixed univer-inset-0 univer-z-[1390] !univer-rounded-none !univer-bg-transparent"),
23818
24142
  onClick: () => setMoreOpen(false)
23819
24143
  }), /* @__PURE__ */ jsx("div", {
23820
- "data-u-comp": "mobile-sheet-more-menu",
24144
+ "data-u-comp": "mobile-more-menu",
23821
24145
  className: clsx("univer-fixed univer-z-[1400] univer-flex univer-w-60 univer-max-w-[calc(100vw-24px)] univer-flex-col univer-gap-1 univer-rounded-2xl univer-bg-gray-0 univer-p-2 univer-shadow-lg dark:!univer-bg-gray-800", borderClassName),
23822
24146
  style: {
23823
24147
  top: ((triggerRect === null || triggerRect === void 0 ? void 0 : triggerRect.bottom) ?? 48) + 8,
@@ -23835,21 +24159,17 @@ function MobileSheetTopBar(props) {
23835
24159
  }, schema.key))
23836
24160
  })] }), mountContainer);
23837
24161
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
23838
- "data-u-comp": "mobile-sheet-top-bar",
24162
+ "data-u-comp": "mobile-compact-top-bar",
23839
24163
  className: clsx("univer-flex univer-h-12 univer-items-center univer-justify-end univer-gap-1 univer-bg-gray-0 univer-px-3 dark:!univer-bg-gray-800", borderBottomClassName),
23840
24164
  children: [
23841
24165
  /* @__PURE__ */ jsx("div", {
23842
24166
  className: "univer-flex univer-items-center univer-gap-1 [&_button]:!univer-min-h-10 [&_button]:!univer-min-w-10 [&_button]:!univer-rounded-lg [&_button_svg]:!univer-size-5",
23843
24167
  children: items.map((schema) => /* @__PURE__ */ jsx(MobileToolbarItem, { ...schema.item }, schema.key))
23844
24168
  }),
23845
- hasHeaderMenu && /* @__PURE__ */ jsx("div", {
23846
- className: "univer-flex univer-items-center univer-gap-1 [&>*]:univer-m-0 [&>*]:univer-inline-flex [&>*]:univer-min-h-10 [&>*]:univer-min-w-10 [&>*]:univer-items-center [&>*]:univer-justify-center [&>*]:univer-rounded-lg",
23847
- children: /* @__PURE__ */ jsx(ComponentContainer, { components: headerMenuComponents })
23848
- }),
23849
24169
  moreItems.length > 0 && /* @__PURE__ */ jsx("button", {
23850
24170
  ref: moreTriggerRef,
23851
24171
  type: "button",
23852
- "data-u-comp": "mobile-sheet-more-trigger",
24172
+ "data-u-comp": "mobile-more-trigger",
23853
24173
  "aria-label": localeService.t("ui.ribbon.more"),
23854
24174
  "aria-expanded": moreOpen,
23855
24175
  className: clsx(resetButtonClassName, "univer-flex univer-size-10 univer-items-center univer-justify-center univer-rounded-lg univer-text-gray-700 univer-transition-colors active:univer-bg-gray-100 dark:!univer-text-gray-200 dark:active:!univer-bg-gray-700"),
@@ -23858,230 +24178,33 @@ function MobileSheetTopBar(props) {
23858
24178
  className: "univer-size-5",
23859
24179
  preserveStrokeWidth: true
23860
24180
  })
24181
+ }),
24182
+ hasHeaderMenu && /* @__PURE__ */ jsx("div", {
24183
+ className: "univer-flex univer-items-center univer-gap-1 [&>*]:univer-m-0 [&>*]:univer-inline-flex [&>*]:univer-min-h-10 [&>*]:univer-min-w-10 [&>*]:univer-items-center [&>*]:univer-justify-center [&>*]:univer-rounded-lg",
24184
+ children: /* @__PURE__ */ jsx(ComponentContainer, { components: headerMenuComponents })
23861
24185
  })
23862
24186
  ]
23863
24187
  }), moreMenu] });
23864
24188
  }
23865
24189
 
23866
24190
  //#endregion
23867
- //#region src/views/components/mobile-drawer/MobileDrawerCoordinator.tsx
23868
- const MobileDrawerCoordinatorContext = createContext(null);
23869
- function MobileDrawerCoordinatorProvider(props) {
23870
- const entriesRef = useRef([]);
23871
- const [activeDrawerId, setActiveDrawerId] = useState(null);
23872
- const setEntries = useCallback((entries) => {
23873
- entriesRef.current = entries;
23874
- setActiveDrawerId(entries.length ? entries[entries.length - 1].id : null);
23875
- }, []);
23876
- const unregister = useCallback((id) => {
23877
- setEntries(entriesRef.current.filter((entry) => entry.id !== id));
23878
- }, [setEntries]);
23879
- const close = useCallback((id) => {
23880
- const entry = entriesRef.current.find((item) => item.id === id);
23881
- if (!entry) return;
23882
- unregister(id);
23883
- entry.onClose();
23884
- }, [unregister]);
23885
- const register = useCallback((id, mode, onClose) => {
23886
- const entry = {
23887
- id,
23888
- onClose
23889
- };
23890
- if (mode === "push") {
23891
- setEntries([...entriesRef.current, entry]);
23892
- return;
23893
- }
23894
- const previousEntries = entriesRef.current;
23895
- setEntries([entry]);
23896
- for (let i = previousEntries.length - 1; i >= 0; i--) previousEntries[i].onClose();
23897
- }, [setEntries]);
23898
- const value = useMemo(() => ({
23899
- activeDrawerId,
23900
- close,
23901
- register,
23902
- unregister
23903
- }), [
23904
- activeDrawerId,
23905
- close,
23906
- register,
23907
- unregister
23908
- ]);
23909
- return /* @__PURE__ */ jsx(MobileDrawerCoordinatorContext.Provider, {
23910
- value,
23911
- children: props.children
23912
- });
24191
+ //#region src/views/menu/mobile/MobileMenu.tsx
24192
+ function MobileMenu(props) {
24193
+ var _props$schemas;
24194
+ const schemaKey = ((_props$schemas = props.schemas) === null || _props$schemas === void 0 ? void 0 : _props$schemas.map((schema) => schema.key).join("|")) ?? "";
24195
+ return /* @__PURE__ */ jsx(MobileMenuContent, { ...props }, `${props.menuType ?? ""}:${schemaKey}`);
23913
24196
  }
23914
-
23915
- //#endregion
23916
- //#region src/views/components/mobile-drawer/MobileDrawer.tsx
23917
- const MOBILE_DRAWER_COMPACT_PERCENT = 40;
23918
- const MOBILE_DRAWER_EXPANDED_PERCENT = 80;
23919
- function resolveMobileDrawerRelease(params) {
23920
- const { snap, deltaY, durationMs, percent } = params;
23921
- const velocity = deltaY / Math.max(durationMs, 1);
23922
- if (deltaY > 48 && velocity > .55 || percent < 20) return "closed";
23923
- if (snap === "expanded" && deltaY > 24) return "compact";
23924
- if (snap === "compact" && deltaY < -24) return "expanded";
23925
- return percent >= 60 ? "expanded" : "compact";
23926
- }
23927
- function MobileDrawer(props) {
23928
- var _globalThis$CSS;
23929
- const { snap, expandLabel, collapseLabel, onSnapChange, onClose, children, header, floatingActions, componentName = "mobile-drawer", panelRef, contentRef, layerRef, openMode = "replace", panelClassName, contentClassName, footer, role, ariaLabel } = props;
23930
- const coordinator = useContext(MobileDrawerCoordinatorContext);
23931
- const registerDrawer = coordinator === null || coordinator === void 0 ? void 0 : coordinator.register;
23932
- const unregisterDrawer = coordinator === null || coordinator === void 0 ? void 0 : coordinator.unregister;
23933
- const panelElementRef = useRef(null);
23934
- const drawerIdRef = useRef(null);
23935
- const onCloseRef = useRef(onClose);
23936
- onCloseRef.current = onClose;
23937
- if (!drawerIdRef.current) drawerIdRef.current = Symbol(componentName);
23938
- const drawerId = drawerIdRef.current;
23939
- const active = !coordinator || coordinator.activeDrawerId === drawerId;
23940
- const [dragPercent, setDragPercent] = useState(null);
23941
- const suppressHandleClickRef = useRef(false);
23942
- const dragRef = useRef(null);
23943
- const drawerPercent = dragPercent ?? (snap === "compact" ? MOBILE_DRAWER_COMPACT_PERCENT : MOBILE_DRAWER_EXPANDED_PERCENT);
23944
- const viewportHeightUnit = ((_globalThis$CSS = globalThis.CSS) === null || _globalThis$CSS === void 0 ? void 0 : _globalThis$CSS.supports("height", "1dvh")) ? "dvh" : "vh";
23945
- useImperativeHandle(panelRef, () => panelElementRef.current);
23946
- useLayoutEffect(() => {
23947
- if (!registerDrawer || !unregisterDrawer) return;
23948
- registerDrawer(drawerId, openMode, () => onCloseRef.current());
23949
- return () => unregisterDrawer(drawerId);
23950
- }, [
23951
- drawerId,
23952
- openMode,
23953
- registerDrawer,
23954
- unregisterDrawer
23955
- ]);
23956
- useLayoutEffect(() => {
23957
- var _panelElementRef$curr;
23958
- const layer = (layerRef === null || layerRef === void 0 ? void 0 : layerRef.current) ?? (layerRef ? (_panelElementRef$curr = panelElementRef.current) === null || _panelElementRef$curr === void 0 ? void 0 : _panelElementRef$curr.parentElement : null);
23959
- if (!layer) return;
23960
- layer.toggleAttribute("hidden", !active);
23961
- }, [active, layerRef]);
23962
- function beginDrag(clientY) {
23963
- dragRef.current = {
23964
- startY: clientY,
23965
- startTime: performance.now(),
23966
- startPercent: drawerPercent,
23967
- currentPercent: drawerPercent,
23968
- moved: false
23969
- };
23970
- }
23971
- function moveDrag(clientY) {
23972
- const drag = dragRef.current;
23973
- if (!drag) return;
23974
- const deltaY = clientY - drag.startY;
23975
- const nextPercent = Math.max(0, Math.min(MOBILE_DRAWER_EXPANDED_PERCENT, drag.startPercent - deltaY / Math.max(window.innerHeight, 1) * 100));
23976
- drag.currentPercent = nextPercent;
23977
- drag.moved ||= Math.abs(deltaY) > 6;
23978
- setDragPercent(nextPercent);
23979
- }
23980
- function endDrag(clientY) {
23981
- const drag = dragRef.current;
23982
- if (!drag) return;
23983
- const result = resolveMobileDrawerRelease({
23984
- snap,
23985
- deltaY: clientY - drag.startY,
23986
- durationMs: performance.now() - drag.startTime,
23987
- percent: drag.currentPercent
23988
- });
23989
- suppressHandleClickRef.current = drag.moved;
23990
- dragRef.current = null;
23991
- setDragPercent(null);
23992
- if (result === "closed") if (coordinator) coordinator.close(drawerId);
23993
- else onClose();
23994
- else onSnapChange(result);
23995
- }
23996
- function handlePointerDown(event) {
23997
- try {
23998
- event.currentTarget.setPointerCapture(event.pointerId);
23999
- } catch {}
24000
- beginDrag(event.clientY);
24001
- }
24002
- function handlePointerMove(event) {
24003
- moveDrag(event.clientY);
24004
- }
24005
- function handlePointerUp(event) {
24006
- endDrag(event.clientY);
24007
- }
24008
- function handlePointerCancel() {
24009
- dragRef.current = null;
24010
- setDragPercent(null);
24011
- }
24012
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [floatingActions && /* @__PURE__ */ jsx("div", {
24013
- className: "univer-pointer-events-none univer-absolute univer-right-4 univer-z-30",
24014
- style: { bottom: `calc(${drawerPercent}${viewportHeightUnit} + 12px)` },
24015
- children: floatingActions
24016
- }), /* @__PURE__ */ jsxs("section", {
24017
- ref: panelElementRef,
24018
- hidden: !active,
24019
- role,
24020
- "aria-modal": role === "dialog" || void 0,
24021
- "aria-label": ariaLabel,
24022
- "data-u-comp": componentName,
24023
- "data-snap": snap,
24024
- className: clsx("univer-absolute univer-inset-x-0 univer-bottom-0 univer-z-20 univer-flex univer-flex-col univer-overflow-hidden univer-rounded-t-[24px] univer-bg-gray-50 univer-shadow-2xl univer-transition-[height] univer-duration-200 dark:!univer-bg-gray-900", dragPercent != null && "!univer-transition-none", panelClassName),
24025
- style: {
24026
- height: `${drawerPercent}${viewportHeightUnit}`,
24027
- paddingBottom: "env(safe-area-inset-bottom, 0px)"
24028
- },
24029
- children: [
24030
- /* @__PURE__ */ jsxs("div", {
24031
- className: "univer-relative univer-flex univer-h-14 univer-shrink-0 univer-items-end univer-bg-gray-0 dark:!univer-bg-gray-800",
24032
- children: [/* @__PURE__ */ jsx("button", {
24033
- type: "button",
24034
- "aria-label": snap === "compact" ? expandLabel : collapseLabel,
24035
- className: clsx(resetButtonClassName, "univer-absolute univer-left-1/2 univer-top-0 univer-z-10 univer-flex univer-h-6 univer-w-16 -univer-translate-x-1/2 univer-touch-none univer-items-center univer-justify-center"),
24036
- style: { touchAction: "none" },
24037
- onPointerDown: handlePointerDown,
24038
- onPointerMove: handlePointerMove,
24039
- onPointerUp: handlePointerUp,
24040
- onPointerCancel: handlePointerCancel,
24041
- onClick: () => {
24042
- if (suppressHandleClickRef.current) {
24043
- suppressHandleClickRef.current = false;
24044
- return;
24045
- }
24046
- onSnapChange(snap === "compact" ? "expanded" : "compact");
24047
- },
24048
- children: /* @__PURE__ */ jsx("span", { className: "univer-h-1 univer-w-10 univer-rounded-full univer-bg-gray-300 dark:!univer-bg-gray-600" })
24049
- }), header]
24050
- }),
24051
- /* @__PURE__ */ jsx("div", {
24052
- ref: contentRef,
24053
- className: clsx("univer-flex-1 univer-overflow-y-auto univer-overflow-x-hidden univer-p-3", scrollbarClassName, contentClassName),
24054
- children
24055
- }),
24056
- footer
24057
- ]
24058
- })] });
24059
- }
24060
-
24061
- //#endregion
24062
- //#region src/views/menu/mobile/MobileMenu.tsx
24063
- function MobileMenu(props) {
24197
+ function MobileMenuContent(props) {
24064
24198
  const { menuType, onOptionSelect, schemas: providedSchemas, menuManagerService: providedMenuManagerService, showHeader = true, presentation = "drawer", onNavigationChange } = props;
24065
24199
  const rootMenuManagerService = useDependency(IMenuManagerService);
24066
24200
  const localeService = useDependency(LocaleService);
24067
24201
  const menuManagerService = providedMenuManagerService ?? rootMenuManagerService;
24068
24202
  const [viewStack, setViewStack] = useState([]);
24069
- const providedSchemaKey = providedSchemas === null || providedSchemas === void 0 ? void 0 : providedSchemas.map((schema) => schema.key).join("|");
24070
- const menuSchemas = useMemo(() => {
24071
- if (providedSchemas) return providedSchemas;
24072
- if (!menuType) return [];
24073
- return menuManagerService.getMenuByPositionKey(menuType);
24074
- }, [
24075
- providedSchemas,
24076
- menuManagerService,
24077
- useObservable(useMemo(() => {
24078
- return menuManagerService.menuChanged$.pipe(scan$1((version) => version + 1, 0), startWith$1(0));
24079
- }, [menuManagerService]), 0),
24080
- menuType
24081
- ]);
24082
- useEffect(() => {
24083
- setViewStack([]);
24084
- }, [menuType, providedSchemaKey]);
24203
+ const menuSchemaVersion$ = useMemo(() => {
24204
+ return menuManagerService.menuChanged$.pipe(scan$1((version) => version + 1, 0), startWith$1(0));
24205
+ }, [menuManagerService]);
24206
+ useObservable(menuSchemaVersion$, 0);
24207
+ const menuSchemas = providedSchemas ?? (menuType ? menuManagerService.getMenuByPositionKey(menuType) : []);
24085
24208
  const currentView = viewStack[viewStack.length - 1] ?? null;
24086
24209
  const closeView = useCallback(() => setViewStack((stack) => stack.slice(0, -1)), []);
24087
24210
  useEffect(() => {
@@ -24112,7 +24235,7 @@ function MobileMenu(props) {
24112
24235
  /* @__PURE__ */ jsx("button", {
24113
24236
  type: "button",
24114
24237
  "aria-label": localeService.t("ui.navigation.back"),
24115
- className: "univer-flex univer-size-8 univer-appearance-none univer-items-center univer-justify-center univer-rounded-full univer-border-0 univer-bg-transparent univer-p-0 univer-text-gray-700 hover:univer-bg-gray-100 active:univer-bg-gray-200 dark:!univer-text-gray-300 dark:hover:!univer-bg-gray-700 dark:active:!univer-bg-gray-600",
24238
+ className: "univer-flex univer-size-8 univer-appearance-none univer-items-center univer-justify-center univer-rounded-full univer-border-0 univer-bg-transparent univer-p-0 univer-text-gray-700 active:univer-bg-gray-200 dark:!univer-text-gray-300 dark:active:!univer-bg-gray-600",
24116
24239
  onClick: closeView,
24117
24240
  children: /* @__PURE__ */ jsx(MoreLeftIcon, { className: "univer-text-base" })
24118
24241
  }),
@@ -24184,15 +24307,17 @@ function MobileContextMenuBar(props) {
24184
24307
  behavior: "smooth"
24185
24308
  });
24186
24309
  };
24310
+ const showLeft = Boolean(currentView) || scrollState.left;
24187
24311
  return /* @__PURE__ */ jsxs("div", {
24188
24312
  role: "menu",
24189
24313
  "data-u-comp": "mobile-context-menu-bar",
24190
- className: "univer-flex univer-h-12 univer-max-w-full univer-items-stretch univer-overflow-hidden univer-rounded-lg univer-bg-gray-0 univer-text-sm univer-text-gray-900 univer-shadow-lg dark:!univer-bg-gray-700 dark:!univer-text-gray-0",
24314
+ style: { maxWidth: "min(100%, calc(100vw - 16px))" },
24315
+ className: "univer-flex univer-h-10 univer-max-w-full univer-items-stretch univer-overflow-hidden univer-rounded-lg univer-bg-gray-0 univer-text-xs univer-text-gray-900 univer-shadow-lg dark:!univer-bg-gray-700 dark:!univer-text-gray-0",
24191
24316
  children: [
24192
- (Boolean(currentView) || scrollState.left) && /* @__PURE__ */ jsx("button", {
24317
+ showLeft && /* @__PURE__ */ jsx("button", {
24193
24318
  type: "button",
24194
24319
  "aria-label": localeService.t("ui.navigation.back"),
24195
- className: "univer-flex univer-w-11 univer-shrink-0 univer-items-center univer-justify-center univer-border-0 univer-border-r univer-border-solid univer-border-gray-200 univer-bg-transparent univer-text-base univer-text-gray-700 univer-outline-none focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 active:univer-bg-gray-100 dark:!univer-border-gray-600 dark:!univer-text-gray-200 dark:active:!univer-bg-gray-600",
24320
+ className: "univer-flex univer-w-9 univer-shrink-0 univer-items-center univer-justify-center univer-border-0 univer-border-r univer-border-solid univer-border-gray-200 univer-bg-transparent univer-text-base univer-text-gray-700 univer-outline-none focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 active:univer-bg-gray-100 dark:!univer-border-gray-600 dark:!univer-text-gray-200 dark:active:!univer-bg-gray-600",
24196
24321
  onClick: () => scrollState.left ? scroll(-1) : onBack(),
24197
24322
  children: /* @__PURE__ */ jsx(MoreLeftIcon, {})
24198
24323
  }),
@@ -24219,7 +24344,7 @@ function MobileContextMenuBar(props) {
24219
24344
  scrollState.right && /* @__PURE__ */ jsx("button", {
24220
24345
  type: "button",
24221
24346
  "aria-label": localeService.t("ui.navigation.next"),
24222
- className: "univer-flex univer-w-11 univer-shrink-0 univer-items-center univer-justify-center univer-border-0 univer-border-l univer-border-solid univer-border-gray-200 univer-bg-transparent univer-text-base univer-text-gray-700 univer-outline-none focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 active:univer-bg-gray-100 dark:!univer-border-gray-600 dark:!univer-text-gray-200 dark:active:!univer-bg-gray-600",
24347
+ className: "univer-flex univer-w-9 univer-shrink-0 univer-items-center univer-justify-center univer-border-0 univer-border-l univer-border-solid univer-border-gray-200 univer-bg-transparent univer-text-base univer-text-gray-700 univer-outline-none focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 active:univer-bg-gray-100 dark:!univer-border-gray-600 dark:!univer-text-gray-200 dark:active:!univer-bg-gray-600",
24223
24348
  onClick: () => scroll(1),
24224
24349
  children: /* @__PURE__ */ jsx(MoreRightIcon, {})
24225
24350
  })
@@ -24240,7 +24365,7 @@ function MobileContextMenuItem(props) {
24240
24365
  type: "button",
24241
24366
  role: "menuitem",
24242
24367
  disabled: interaction.disabled,
24243
- className: "univer-flex univer-min-w-[72px] univer-shrink-0 univer-snap-start univer-items-center univer-justify-center univer-border-0 univer-border-r univer-border-solid univer-border-gray-200 univer-bg-transparent univer-px-4 univer-text-sm univer-text-gray-900 univer-outline-none focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 enabled:active:univer-bg-gray-100 disabled:univer-opacity-40 dark:!univer-border-gray-600 dark:!univer-text-gray-0 dark:enabled:active:!univer-bg-gray-600",
24368
+ className: "univer-flex univer-min-w-[60px] univer-shrink-0 univer-snap-start univer-items-center univer-justify-center univer-border-0 univer-border-r univer-border-solid univer-border-gray-200 univer-bg-transparent univer-px-3 univer-text-xs univer-text-gray-900 univer-outline-none focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 enabled:active:univer-bg-gray-100 disabled:univer-opacity-40 dark:!univer-border-gray-600 dark:!univer-text-gray-0 dark:enabled:active:!univer-bg-gray-600",
24244
24369
  onClick: () => interaction.onPress(onExecute),
24245
24370
  children: /* @__PURE__ */ jsx("span", {
24246
24371
  className: "univer-whitespace-nowrap",
@@ -24259,13 +24384,13 @@ function MobileContextMenuOption(props) {
24259
24384
  role: "menuitem",
24260
24385
  "aria-pressed": displayValue === currentValue,
24261
24386
  disabled,
24262
- className: "univer-flex univer-min-w-[72px] univer-shrink-0 univer-snap-start univer-items-center univer-justify-center univer-border-0 univer-border-r univer-border-solid univer-border-gray-200 univer-bg-transparent univer-px-4 univer-text-sm univer-text-gray-900 univer-outline-none focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 enabled:active:univer-bg-gray-100 disabled:univer-opacity-40 dark:!univer-border-gray-600 dark:!univer-text-gray-0 dark:enabled:active:!univer-bg-gray-600",
24387
+ className: "univer-flex univer-min-w-[60px] univer-shrink-0 univer-snap-start univer-items-center univer-justify-center univer-border-0 univer-border-r univer-border-solid univer-border-gray-200 univer-bg-transparent univer-px-3 univer-text-xs univer-text-gray-900 univer-outline-none focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 enabled:active:univer-bg-gray-100 disabled:univer-opacity-40 dark:!univer-border-gray-600 dark:!univer-text-gray-0 dark:enabled:active:!univer-bg-gray-600",
24263
24388
  onClick: () => onExecute === null || onExecute === void 0 ? void 0 : onExecute({
24264
24389
  ...option,
24265
24390
  value: displayValue,
24266
24391
  id: menuItem.id,
24267
24392
  label: menuKey,
24268
- commandId: option.commandId
24393
+ commandId: option.commandId ?? menuItem.selectionsCommandId
24269
24394
  }),
24270
24395
  children: /* @__PURE__ */ jsx(CustomLabel, {
24271
24396
  value$: option.value$,
@@ -24300,6 +24425,14 @@ function MobileSchemaList(props) {
24300
24425
  bordered: index !== visibleSchemas.length - 1
24301
24426
  }, schema.key);
24302
24427
  if (!((_schema$children2 = schema.children) === null || _schema$children2 === void 0 ? void 0 : _schema$children2.length)) return null;
24428
+ if (schema.mobileLayout === "grid" || schema.mobileLayout === void 0 && Boolean(schema.quickLayout)) return /* @__PURE__ */ jsx(MobileQuickSchemaGroup, {
24429
+ schema,
24430
+ menuManagerService,
24431
+ onExecute,
24432
+ onOpenView,
24433
+ inheritedDisabled$,
24434
+ bordered: index !== visibleSchemas.length - 1
24435
+ }, schema.key);
24303
24436
  return /* @__PURE__ */ jsxs("section", {
24304
24437
  className: clsx("univer-grid", index !== visibleSchemas.length - 1 && borderBottomClassName),
24305
24438
  children: [schema.title && /* @__PURE__ */ jsx("div", {
@@ -24316,6 +24449,54 @@ function MobileSchemaList(props) {
24316
24449
  }, schema.key);
24317
24450
  }) });
24318
24451
  }
24452
+ function MobileQuickSchemaGroup(props) {
24453
+ var _schema$children3;
24454
+ const { schema, menuManagerService, onExecute, onOpenView, inheritedDisabled$, bordered } = props;
24455
+ const localeService = useDependency(LocaleService);
24456
+ const columns = Math.max(2, Math.min(schema.quickColumns ?? 4, 5));
24457
+ return /* @__PURE__ */ jsxs("section", {
24458
+ className: clsx("univer-p-3", bordered && borderBottomClassName),
24459
+ children: [schema.title && /* @__PURE__ */ jsx("div", {
24460
+ className: "univer-px-1 univer-pb-2 univer-text-sm univer-font-semibold univer-text-gray-900 dark:!univer-text-gray-100",
24461
+ children: localeService.t(schema.title)
24462
+ }), /* @__PURE__ */ jsx("div", {
24463
+ className: "univer-grid univer-gap-2",
24464
+ style: { gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` },
24465
+ children: (_schema$children3 = schema.children) === null || _schema$children3 === void 0 ? void 0 : _schema$children3.map((childSchema) => /* @__PURE__ */ jsx(MobileQuickSchemaItem, {
24466
+ schema: childSchema,
24467
+ menuManagerService,
24468
+ onExecute,
24469
+ onOpenView,
24470
+ inheritedDisabled$,
24471
+ compact: schema.quickLayoutVariant === "compact"
24472
+ }, childSchema.key))
24473
+ })]
24474
+ });
24475
+ }
24476
+ function MobileQuickSchemaItem(props) {
24477
+ const { schema, menuManagerService, onExecute, onOpenView, inheritedDisabled$, compact } = props;
24478
+ const interaction = useMobileSchemaInteraction({
24479
+ schema,
24480
+ menuManagerService,
24481
+ onOpenView,
24482
+ inheritedDisabled$
24483
+ });
24484
+ if (!interaction || interaction.hidden) return null;
24485
+ const { menuItem, activated, disabled, value, onPress } = interaction;
24486
+ return /* @__PURE__ */ jsxs("button", {
24487
+ type: "button",
24488
+ disabled,
24489
+ "aria-pressed": menuItem.type === 2 ? activated : void 0,
24490
+ className: clsx("univer-relative univer-flex univer-w-full univer-appearance-none univer-flex-col univer-items-center univer-justify-center univer-gap-1 univer-rounded-xl univer-border-0 univer-bg-gray-50 univer-p-2 univer-text-center univer-text-gray-900 univer-outline-none focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 enabled:active:univer-scale-[0.98] enabled:active:univer-bg-gray-100 disabled:univer-opacity-40 dark:!univer-bg-gray-700 dark:!univer-text-gray-100 dark:enabled:active:!univer-bg-gray-600 [&>span]:univer-line-clamp-2 [&>span]:univer-text-xs [&>span]:univer-font-medium [&>svg]:univer-size-6 [&>svg]:univer-shrink-0", compact ? "univer-min-h-12" : "univer-min-h-20", activated && "univer-bg-primary-50 univer-text-primary-600 dark:!univer-bg-primary-900 dark:!univer-text-primary-300"),
24491
+ onClick: () => onPress(onExecute),
24492
+ children: [/* @__PURE__ */ jsx(CustomLabel, {
24493
+ value,
24494
+ title: menuItem.title ?? menuItem.tooltip,
24495
+ label: menuItem.label,
24496
+ icon: menuItem.icon
24497
+ }), activated && /* @__PURE__ */ jsx(CheckMarkIcon, { className: "univer-absolute univer-right-1.5 univer-top-1.5 univer-size-3.5" })]
24498
+ });
24499
+ }
24319
24500
  function MobileSchemaRow(props) {
24320
24501
  const { schema, menuManagerService, onExecute, onOpenView, inheritedDisabled$, bordered } = props;
24321
24502
  const interaction = useMobileSchemaInteraction({
@@ -24353,7 +24534,7 @@ function MobileSchemaRow(props) {
24353
24534
  });
24354
24535
  return /* @__PURE__ */ jsxs("button", {
24355
24536
  type: "button",
24356
- className: clsx("univer-flex univer-min-h-12 univer-w-full univer-appearance-none univer-items-center univer-gap-3 univer-border-0 univer-bg-gray-0 univer-px-4 univer-py-2 univer-text-left univer-outline-none univer-transition-colors focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 enabled:hover:univer-bg-gray-50 enabled:active:univer-bg-gray-100 disabled:univer-cursor-not-allowed disabled:univer-opacity-40 dark:!univer-bg-gray-800 dark:hover:!univer-bg-gray-700 dark:active:!univer-bg-gray-600", bordered && borderBottomClassName),
24537
+ className: clsx("univer-flex univer-min-h-12 univer-w-full univer-appearance-none univer-items-center univer-gap-3 univer-border-0 univer-bg-gray-0 univer-px-4 univer-py-2 univer-text-left univer-outline-none univer-transition-colors focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 enabled:active:univer-bg-gray-100 disabled:univer-cursor-not-allowed disabled:univer-opacity-40 dark:!univer-bg-gray-800 dark:active:!univer-bg-gray-600", bordered && borderBottomClassName),
24357
24538
  "data-u-command": menuItem.id,
24358
24539
  disabled,
24359
24540
  "aria-pressed": menuItem.type === 2 ? activated : void 0,
@@ -24413,7 +24594,7 @@ function MobileSelectionOptionRow(props) {
24413
24594
  value: nextValue,
24414
24595
  id: menuItem.id,
24415
24596
  label: menuKey,
24416
- commandId: option.commandId
24597
+ commandId: option.commandId ?? menuItem.selectionsCommandId
24417
24598
  });
24418
24599
  }
24419
24600
  })
@@ -24421,7 +24602,7 @@ function MobileSelectionOptionRow(props) {
24421
24602
  return /* @__PURE__ */ jsxs("button", {
24422
24603
  type: "button",
24423
24604
  "aria-pressed": selected,
24424
- className: clsx("univer-relative univer-flex univer-min-h-12 univer-w-full univer-appearance-none univer-items-center univer-gap-3 univer-border-0 univer-bg-gray-0 univer-px-4 univer-py-2 univer-text-left univer-outline-none univer-transition-colors focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 enabled:hover:univer-bg-gray-50 enabled:active:univer-bg-gray-100 disabled:univer-cursor-not-allowed disabled:univer-opacity-40 dark:!univer-bg-gray-800 dark:hover:!univer-bg-gray-700 dark:active:!univer-bg-gray-600", bordered && borderBottomClassName),
24605
+ className: clsx("univer-relative univer-flex univer-min-h-12 univer-w-full univer-appearance-none univer-items-center univer-gap-3 univer-border-0 univer-bg-gray-0 univer-px-4 univer-py-2 univer-text-left univer-outline-none univer-transition-colors focus-visible:univer-ring-2 focus-visible:univer-ring-inset focus-visible:univer-ring-primary-500 enabled:active:univer-bg-gray-100 disabled:univer-cursor-not-allowed disabled:univer-opacity-40 dark:!univer-bg-gray-800 dark:active:!univer-bg-gray-600", bordered && borderBottomClassName),
24425
24606
  disabled: optionDisabled,
24426
24607
  onClick: () => {
24427
24608
  if (optionDisabled) return;
@@ -24430,7 +24611,7 @@ function MobileSelectionOptionRow(props) {
24430
24611
  value: displayValue,
24431
24612
  id: menuItem.id,
24432
24613
  label: menuKey,
24433
- commandId: option.commandId
24614
+ commandId: option.commandId ?? menuItem.selectionsCommandId
24434
24615
  });
24435
24616
  },
24436
24617
  children: [/* @__PURE__ */ jsx("div", {
@@ -24459,7 +24640,8 @@ function useMobileSchemaInteraction(props) {
24459
24640
  const value = useObservable(menuItem === null || menuItem === void 0 ? void 0 : menuItem.value$);
24460
24641
  const selectionsFromObservable = useObservable(selectorItem && isObservable(selectorItem.selections) ? selectorItem.selections : void 0);
24461
24642
  const schemaChildren = useMemo(() => schema.children ?? [], [schema.children]);
24462
- const visibleSchemaChildren = useObservable(useMemo(() => getVisibleSchemaCount$(schemaChildren), [schemaChildren]), schemaChildren.length);
24643
+ const visibleSchemaChildren$ = useMemo(() => getVisibleSchemaCount$(schemaChildren), [schemaChildren]);
24644
+ const visibleSchemaChildren = useObservable(visibleSchemaChildren$, schemaChildren.length);
24463
24645
  const selections = useMemo(() => {
24464
24646
  if (!selectorItem || (menuItem === null || menuItem === void 0 ? void 0 : menuItem.type) !== 1 && (menuItem === null || menuItem === void 0 ? void 0 : menuItem.type) !== 2) return [];
24465
24647
  if (selectionsFromObservable) return selectionsFromObservable;
@@ -24476,11 +24658,14 @@ function useMobileSchemaInteraction(props) {
24476
24658
  if (!menuItem) return null;
24477
24659
  const hasSubmenu = visibleSchemaChildren > 0 || selections.length > 0 || subMenuItems.length > 0;
24478
24660
  const effectivelyDisabled = disabled || menuItem.type === 3 && !hasSubmenu;
24479
- const currentValueText = typeof value === "string" || typeof value === "number" ? String(value) : "";
24661
+ const selectedOption = selections.find((option) => option.value === value);
24662
+ let currentValueText = "";
24663
+ if (typeof (selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) === "string") currentValueText = localeService.t(selectedOption.label);
24664
+ else if (selections.length === 0 && (typeof value === "string" || typeof value === "number")) currentValueText = String(value);
24480
24665
  const onPress = (onExecute) => {
24481
24666
  if (effectivelyDisabled) return;
24482
24667
  if (schemaChildren.length > 0) {
24483
- const schemas = menuItem.type === 2 && selections.length === 0 ? [{
24668
+ const schemas = menuItem.type === 2 ? [{
24484
24669
  ...schema,
24485
24670
  children: void 0
24486
24671
  }, ...schemaChildren] : schemaChildren;
@@ -24513,65 +24698,500 @@ function useMobileSchemaInteraction(props) {
24513
24698
  });
24514
24699
  return;
24515
24700
  }
24516
- if (menuItem.type !== 0 && menuItem.type !== 2) return;
24517
- onExecute === null || onExecute === void 0 || onExecute({
24518
- commandId: menuItem.commandId,
24519
- value,
24520
- id: menuItem.id,
24521
- label: schema.key,
24522
- params: menuItem.params
24523
- });
24524
- };
24525
- return {
24526
- menuItem,
24527
- activated,
24528
- disabled: effectivelyDisabled,
24529
- hidden,
24530
- value,
24531
- currentValueText,
24532
- hasSubmenu,
24533
- onPress
24534
- };
24535
- }
24536
- function getVisibleSchemaCount$(schemas) {
24537
- const leafSchemas = getLeafItemSchemas(schemas);
24538
- if (leafSchemas.length === 0) return of(0);
24539
- return combineLatest(leafSchemas.map((schema) => {
24540
- var _schema$item;
24541
- return (((_schema$item = schema.item) === null || _schema$item === void 0 ? void 0 : _schema$item.hidden$) ?? of(false)).pipe(startWith$1(false));
24542
- })).pipe(map((hiddenStates) => hiddenStates.filter((hidden) => !hidden).length));
24543
- }
24544
- function getMenuSchemaTitle(schema, localeService) {
24545
- const menuItem = schema.item;
24546
- if (typeof (menuItem === null || menuItem === void 0 ? void 0 : menuItem.title) === "string") return localeService.t(menuItem.title);
24547
- if (typeof (menuItem === null || menuItem === void 0 ? void 0 : menuItem.label) === "string") return localeService.t(menuItem.label);
24548
- if (typeof (menuItem === null || menuItem === void 0 ? void 0 : menuItem.tooltip) === "string") return localeService.t(menuItem.tooltip);
24549
- if (typeof schema.title === "string") return localeService.t(schema.title);
24550
- return schema.key;
24551
- }
24552
- function useContextGroupHiddenStates(menuSchemas) {
24553
- return useObservable(useMemo(() => {
24554
- const groupStates = menuSchemas.flatMap((menuSchema) => {
24555
- var _menuSchema$children;
24556
- const hiddenObservables = ((_menuSchema$children = menuSchema.children) === null || _menuSchema$children === void 0 ? void 0 : _menuSchema$children.length) ? getLeafItemSchemas(menuSchema.children).map((childSchema) => {
24557
- var _childSchema$item;
24558
- return ((_childSchema$item = childSchema.item) === null || _childSchema$item === void 0 ? void 0 : _childSchema$item.hidden$) ?? of(false);
24559
- }) : [];
24560
- return hiddenObservables.length ? [combineLatest(hiddenObservables).pipe(map((values) => [menuSchema.key, values.every(Boolean)]))] : [];
24561
- });
24562
- return groupStates.length ? merge$1(...groupStates).pipe(scan$1((states, [key, hidden]) => ({
24563
- ...states,
24564
- [key]: hidden
24565
- }), {}), startWith$1({})) : of({});
24566
- }, [menuSchemas]), {});
24567
- }
24568
- function getLeafItemSchemas(schemas) {
24569
- return schemas.reduce((acc, schema) => {
24570
- var _schema$children3;
24571
- if ((_schema$children3 = schema.children) === null || _schema$children3 === void 0 ? void 0 : _schema$children3.length) return [...acc, ...getLeafItemSchemas(schema.children)];
24572
- if (schema.item) return [...acc, schema];
24573
- return acc;
24574
- }, []);
24701
+ if (menuItem.type !== 0 && menuItem.type !== 2) return;
24702
+ onExecute === null || onExecute === void 0 || onExecute({
24703
+ commandId: menuItem.commandId,
24704
+ value,
24705
+ id: menuItem.id,
24706
+ label: schema.key,
24707
+ params: menuItem.params
24708
+ });
24709
+ };
24710
+ return {
24711
+ menuItem,
24712
+ activated,
24713
+ disabled: effectivelyDisabled,
24714
+ hidden,
24715
+ value,
24716
+ currentValueText,
24717
+ hasSubmenu,
24718
+ onPress
24719
+ };
24720
+ }
24721
+ function getVisibleSchemaCount$(schemas) {
24722
+ const leafSchemas = getLeafItemSchemas(schemas);
24723
+ if (leafSchemas.length === 0) return of(0);
24724
+ return combineLatest(leafSchemas.map((schema) => {
24725
+ var _schema$item;
24726
+ return (((_schema$item = schema.item) === null || _schema$item === void 0 ? void 0 : _schema$item.hidden$) ?? of(false)).pipe(startWith$1(false));
24727
+ })).pipe(map((hiddenStates) => hiddenStates.filter((hidden) => !hidden).length));
24728
+ }
24729
+ function getMenuSchemaTitle(schema, localeService) {
24730
+ const menuItem = schema.item;
24731
+ if (typeof (menuItem === null || menuItem === void 0 ? void 0 : menuItem.title) === "string") return localeService.t(menuItem.title);
24732
+ if (typeof (menuItem === null || menuItem === void 0 ? void 0 : menuItem.label) === "string") return localeService.t(menuItem.label);
24733
+ if (typeof (menuItem === null || menuItem === void 0 ? void 0 : menuItem.tooltip) === "string") return localeService.t(menuItem.tooltip);
24734
+ if (typeof schema.title === "string") return localeService.t(schema.title);
24735
+ return schema.key;
24736
+ }
24737
+ function useContextGroupHiddenStates(menuSchemas) {
24738
+ const hiddenStates$ = useMemo(() => {
24739
+ const groupStates = menuSchemas.flatMap((menuSchema) => {
24740
+ var _menuSchema$children;
24741
+ const hiddenObservables = ((_menuSchema$children = menuSchema.children) === null || _menuSchema$children === void 0 ? void 0 : _menuSchema$children.length) ? getLeafItemSchemas(menuSchema.children).map((childSchema) => {
24742
+ var _childSchema$item;
24743
+ return ((_childSchema$item = childSchema.item) === null || _childSchema$item === void 0 ? void 0 : _childSchema$item.hidden$) ?? of(false);
24744
+ }) : [];
24745
+ return hiddenObservables.length ? [combineLatest(hiddenObservables).pipe(map((values) => [menuSchema.key, values.every(Boolean)]))] : [];
24746
+ });
24747
+ return groupStates.length ? merge$1(...groupStates).pipe(scan$1((states, [key, hidden]) => ({
24748
+ ...states,
24749
+ [key]: hidden
24750
+ }), {}), startWith$1({})) : of({});
24751
+ }, [menuSchemas]);
24752
+ return useObservable(hiddenStates$, {});
24753
+ }
24754
+ function getLeafItemSchemas(schemas) {
24755
+ return schemas.reduce((acc, schema) => {
24756
+ var _schema$children4;
24757
+ if ((_schema$children4 = schema.children) === null || _schema$children4 === void 0 ? void 0 : _schema$children4.length) return [...acc, ...getLeafItemSchemas(schema.children)];
24758
+ if (schema.item) return [...acc, schema];
24759
+ return acc;
24760
+ }, []);
24761
+ }
24762
+
24763
+ //#endregion
24764
+ //#region src/views/mobile-workbench/MobileCanvasLayout.tsx
24765
+ const MobileCanvasLayoutContext = createContext(null);
24766
+ function MobileCanvasLayoutProvider({ children }) {
24767
+ const [panels, setPanels] = useState([]);
24768
+ const register = useCallback((panel) => {
24769
+ setPanels((current) => [...current, panel]);
24770
+ return () => setPanels((current) => current.filter((item) => item !== panel));
24771
+ }, []);
24772
+ const value = useMemo(() => ({
24773
+ panels,
24774
+ register
24775
+ }), [panels, register]);
24776
+ return /* @__PURE__ */ jsx(MobileCanvasLayoutContext.Provider, {
24777
+ value,
24778
+ children
24779
+ });
24780
+ }
24781
+ /** Register the actual surface, not its full-screen portal container. */
24782
+ function useMobileCanvasPanel(ref, layout, dragging = false) {
24783
+ var _useContext;
24784
+ const register = (_useContext = useContext(MobileCanvasLayoutContext)) === null || _useContext === void 0 ? void 0 : _useContext.register;
24785
+ useLayoutEffect(() => {
24786
+ if (ref.current && register) return register({
24787
+ ref,
24788
+ layout,
24789
+ dragging
24790
+ });
24791
+ }, [
24792
+ ref,
24793
+ register,
24794
+ layout,
24795
+ dragging
24796
+ ]);
24797
+ }
24798
+ /** Connect design-layer overlay surfaces to the current workbench layout. */
24799
+ function useMobileOverlayRegistration(layout) {
24800
+ var _useContext2;
24801
+ const register = (_useContext2 = useContext(MobileCanvasLayoutContext)) === null || _useContext2 === void 0 ? void 0 : _useContext2.register;
24802
+ return useCallback((element) => register === null || register === void 0 ? void 0 : register({
24803
+ ref: { current: element },
24804
+ layout,
24805
+ dragging: false
24806
+ }), [register, layout]);
24807
+ }
24808
+ /** Minimal viewport translation in CSS pixels. Large objects keep their leading edge visible. */
24809
+ function getMobileCanvasPanDelta(target, viewport) {
24810
+ const reveal = (start, size, available) => {
24811
+ const margin = Math.min(16, available / 4);
24812
+ const end = start + Math.min(size, available - margin * 2);
24813
+ if (start < margin) return margin - start;
24814
+ return end > available - margin ? available - margin - end : 0;
24815
+ };
24816
+ return {
24817
+ x: reveal(target.left, target.width, viewport.width),
24818
+ y: reveal(target.top, target.height, viewport.height)
24819
+ };
24820
+ }
24821
+ /**
24822
+ * Opt-in canvas host. Panels remain outside the resizable inner element so their
24823
+ * measurement cannot feed back into their own containing block. No focus or zoom
24824
+ * changes are performed here; each renderer owns its viewport translation.
24825
+ */
24826
+ function useMobileCanvasViewport(options) {
24827
+ const { containerRef, canvasRef, enabled = true, panelsOnly = false, onReveal } = options;
24828
+ const context = useContext(MobileCanvasLayoutContext);
24829
+ const revealRef = useRef(onReveal);
24830
+ useLayoutEffect(() => {
24831
+ revealRef.current = onReveal;
24832
+ }, [onReveal]);
24833
+ const previousHeightRef = useRef(null);
24834
+ const needsRevealRef = useRef(false);
24835
+ useLayoutEffect(() => {
24836
+ const container = containerRef.current;
24837
+ const canvas = canvasRef.current;
24838
+ if (!context || !enabled || !container || !canvas) return;
24839
+ const panels = context.panels.flatMap(({ ref, layout, dragging }) => ref.current ? [{
24840
+ element: ref.current,
24841
+ layout,
24842
+ dragging
24843
+ }] : []);
24844
+ if (panelsOnly && !panels.some((panel) => panel.layout === "canvas")) {
24845
+ previousHeightRef.current = null;
24846
+ needsRevealRef.current = false;
24847
+ return;
24848
+ }
24849
+ const viewport = window.visualViewport;
24850
+ let frame = 0;
24851
+ let settleFrame = 0;
24852
+ const originalHeight = canvas.style.height;
24853
+ const originalBottom = canvas.style.bottom;
24854
+ const originalTop = canvas.style.top;
24855
+ const panelStyles = panels.map(({ element }) => ({
24856
+ element,
24857
+ bottom: element.style.bottom,
24858
+ maxHeight: element.style.maxHeight
24859
+ }));
24860
+ const settle = () => {
24861
+ cancelAnimationFrame(settleFrame);
24862
+ settleFrame = requestAnimationFrame(() => {
24863
+ settleFrame = requestAnimationFrame(() => {
24864
+ if (needsRevealRef.current && !panels.some((panel) => panel.dragging)) {
24865
+ needsRevealRef.current = false;
24866
+ revealRef.current();
24867
+ }
24868
+ });
24869
+ });
24870
+ };
24871
+ const measure = () => {
24872
+ const bounds = container.getBoundingClientRect();
24873
+ const modal = panels.some((panel) => panel.layout === "modal");
24874
+ const visibleBottom = viewport ? viewport.offsetTop + viewport.height : window.innerHeight;
24875
+ const top = modal ? bounds.top : Math.max(bounds.top, (viewport === null || viewport === void 0 ? void 0 : viewport.offsetTop) ?? 0);
24876
+ let bottom = modal ? bounds.bottom : Math.min(bounds.bottom, visibleBottom);
24877
+ const panelMaxHeight = Math.max(0, bottom - top) * .6;
24878
+ if (!modal) for (const { element, layout } of panels) {
24879
+ if (layout !== "canvas") continue;
24880
+ const containingBlock = element.offsetParent;
24881
+ const parentBottom = getComputedStyle(element).position === "fixed" || !containingBlock ? window.innerHeight : containingBlock.getBoundingClientRect().bottom;
24882
+ element.style.bottom = `${Math.max(0, parentBottom - visibleBottom)}px`;
24883
+ element.style.maxHeight = `${panelMaxHeight}px`;
24884
+ const rect = element.getBoundingClientRect();
24885
+ if (rect.right > bounds.left && rect.left < bounds.right && rect.bottom > bounds.top) bottom = Math.min(bottom, rect.top);
24886
+ }
24887
+ const height = Math.max(0, bottom - top);
24888
+ const oldHeight = previousHeightRef.current ?? bounds.height;
24889
+ if (modal || height > oldHeight + 1) needsRevealRef.current = false;
24890
+ needsRevealRef.current ||= !modal && height < oldHeight - 1;
24891
+ previousHeightRef.current = height;
24892
+ canvas.style.bottom = "auto";
24893
+ canvas.style.top = `${top - bounds.top}px`;
24894
+ canvas.style.height = `${height}px`;
24895
+ settle();
24896
+ };
24897
+ const schedule = () => {
24898
+ cancelAnimationFrame(frame);
24899
+ frame = requestAnimationFrame(measure);
24900
+ };
24901
+ const observer = new ResizeObserver(schedule);
24902
+ const cancelReveal = () => {
24903
+ needsRevealRef.current = false;
24904
+ };
24905
+ canvas.addEventListener("pointerdown", cancelReveal);
24906
+ observer.observe(container);
24907
+ panels.forEach(({ element }) => observer.observe(element));
24908
+ viewport === null || viewport === void 0 || viewport.addEventListener("resize", schedule);
24909
+ viewport === null || viewport === void 0 || viewport.addEventListener("scroll", schedule);
24910
+ window.addEventListener("resize", schedule);
24911
+ measure();
24912
+ return () => {
24913
+ observer.disconnect();
24914
+ canvas.removeEventListener("pointerdown", cancelReveal);
24915
+ cancelAnimationFrame(frame);
24916
+ cancelAnimationFrame(settleFrame);
24917
+ viewport === null || viewport === void 0 || viewport.removeEventListener("resize", schedule);
24918
+ viewport === null || viewport === void 0 || viewport.removeEventListener("scroll", schedule);
24919
+ window.removeEventListener("resize", schedule);
24920
+ canvas.style.height = originalHeight;
24921
+ canvas.style.bottom = originalBottom;
24922
+ canvas.style.top = originalTop;
24923
+ panelStyles.forEach(({ element, bottom, maxHeight }) => {
24924
+ element.style.bottom = bottom;
24925
+ element.style.maxHeight = maxHeight;
24926
+ });
24927
+ };
24928
+ }, [
24929
+ context,
24930
+ enabled,
24931
+ panelsOnly,
24932
+ containerRef,
24933
+ canvasRef
24934
+ ]);
24935
+ }
24936
+
24937
+ //#endregion
24938
+ //#region src/views/components/mobile-drawer/MobileDrawerCoordinator.tsx
24939
+ const MobileDrawerCoordinatorContext = createContext(null);
24940
+ function MobileDrawerCoordinatorProvider(props) {
24941
+ const entriesRef = useRef([]);
24942
+ const [activeDrawerId, setActiveDrawerId] = useState(null);
24943
+ const setEntries = useCallback((entries) => {
24944
+ entriesRef.current = entries;
24945
+ setActiveDrawerId(entries.length ? entries[entries.length - 1].id : null);
24946
+ }, []);
24947
+ const unregister = useCallback((id) => {
24948
+ setEntries(entriesRef.current.filter((entry) => entry.id !== id));
24949
+ }, [setEntries]);
24950
+ const close = useCallback((id) => {
24951
+ const entry = entriesRef.current.find((item) => item.id === id);
24952
+ if (!entry) return;
24953
+ unregister(id);
24954
+ entry.onClose();
24955
+ }, [unregister]);
24956
+ const register = useCallback((id, mode, onClose) => {
24957
+ const entry = {
24958
+ id,
24959
+ onClose
24960
+ };
24961
+ if (mode === "push") {
24962
+ setEntries([...entriesRef.current, entry]);
24963
+ return;
24964
+ }
24965
+ const previousEntries = entriesRef.current;
24966
+ setEntries([entry]);
24967
+ for (let i = previousEntries.length - 1; i >= 0; i--) previousEntries[i].onClose();
24968
+ }, [setEntries]);
24969
+ const value = useMemo(() => ({
24970
+ activeDrawerId,
24971
+ close,
24972
+ register,
24973
+ unregister
24974
+ }), [
24975
+ activeDrawerId,
24976
+ close,
24977
+ register,
24978
+ unregister
24979
+ ]);
24980
+ return /* @__PURE__ */ jsx(MobileDrawerCoordinatorContext.Provider, {
24981
+ value,
24982
+ children: props.children
24983
+ });
24984
+ }
24985
+
24986
+ //#endregion
24987
+ //#region src/views/components/mobile-drawer/MobileDrawer.tsx
24988
+ function assignDrawerRef(ref, element) {
24989
+ if (typeof ref === "function") ref(element);
24990
+ else if (ref) ref.current = element;
24991
+ }
24992
+ const MOBILE_DRAWER_COMPACT_PERCENT = 40;
24993
+ const MOBILE_DRAWER_EXPANDED_PERCENT = 80;
24994
+ const MobileDrawerLayoutContext = createContext("modal");
24995
+ function resolveMobileDrawerRelease(params) {
24996
+ const { snap, deltaY, durationMs, percent } = params;
24997
+ const velocity = deltaY / Math.max(durationMs, 1);
24998
+ if (deltaY > 48 && (snap === "compact" || velocity > .55) || percent < 20) return "closed";
24999
+ if (snap === "expanded" && deltaY > 24) return "compact";
25000
+ if (snap === "compact" && deltaY < -24) return "expanded";
25001
+ return percent >= 60 ? "expanded" : "compact";
25002
+ }
25003
+ function MobileDrawer(props) {
25004
+ var _globalThis$CSS;
25005
+ const { snap, expandLabel, collapseLabel, onSnapChange, onClose, children, header, floatingActions, componentName = "mobile-drawer", panelRef, contentRef, layerRef, openMode = "replace", panelClassName, contentClassName, footer, role, ariaLabel, layout: requestedLayout } = props;
25006
+ const coordinator = useContext(MobileDrawerCoordinatorContext);
25007
+ const registerDrawer = coordinator === null || coordinator === void 0 ? void 0 : coordinator.register;
25008
+ const unregisterDrawer = coordinator === null || coordinator === void 0 ? void 0 : coordinator.unregister;
25009
+ const panelElementRef = useRef(null);
25010
+ const drawerIdRef = useRef(null);
25011
+ const onCloseRef = useRef(onClose);
25012
+ onCloseRef.current = onClose;
25013
+ if (!drawerIdRef.current) drawerIdRef.current = Symbol(componentName);
25014
+ const drawerId = drawerIdRef.current;
25015
+ const active = !coordinator || coordinator.activeDrawerId === drawerId;
25016
+ const inheritedLayout = useContext(MobileDrawerLayoutContext);
25017
+ const layout = requestedLayout ?? inheritedLayout;
25018
+ const registerOverlay = useMobileOverlayRegistration(layout);
25019
+ const viewportHeightUnit = ((_globalThis$CSS = globalThis.CSS) === null || _globalThis$CSS === void 0 ? void 0 : _globalThis$CSS.supports("height", "1dvh")) ? "dvh" : "vh";
25020
+ const overlay = useMemo(() => ({
25021
+ modal: layout === "modal",
25022
+ contentProps: {
25023
+ style: layout === "canvas" ? {
25024
+ height: `${MOBILE_DRAWER_COMPACT_PERCENT}${viewportHeightUnit}`,
25025
+ maxHeight: `${MOBILE_DRAWER_COMPACT_PERCENT}${viewportHeightUnit}`
25026
+ } : void 0,
25027
+ onOpenAutoFocus: layout === "canvas" ? (event) => event.preventDefault() : void 0,
25028
+ onCloseAutoFocus: layout === "canvas" ? (event) => event.preventDefault() : void 0
25029
+ },
25030
+ onMount: registerOverlay
25031
+ }), [
25032
+ layout,
25033
+ registerOverlay,
25034
+ viewportHeightUnit
25035
+ ]);
25036
+ const [dragPercent, setDragPercent] = useState(null);
25037
+ const surfaceRef = useRef(null);
25038
+ const setPanelRef = useCallback((element) => {
25039
+ surfaceRef.current = element;
25040
+ panelElementRef.current = element;
25041
+ assignDrawerRef(panelRef, element);
25042
+ }, [panelRef]);
25043
+ useMobileCanvasPanel(surfaceRef, layout, dragPercent !== null);
25044
+ const suppressHandleClickRef = useRef(false);
25045
+ const dragRef = useRef(null);
25046
+ const drawerPercent = dragPercent ?? (snap === "compact" ? MOBILE_DRAWER_COMPACT_PERCENT : MOBILE_DRAWER_EXPANDED_PERCENT);
25047
+ const keyboardLayout = useMobileKeyboardViewportLayout(panelElementRef);
25048
+ useLayoutEffect(() => {
25049
+ if (!registerDrawer || !unregisterDrawer) return;
25050
+ registerDrawer(drawerId, openMode, () => onCloseRef.current());
25051
+ return () => unregisterDrawer(drawerId);
25052
+ }, [
25053
+ drawerId,
25054
+ openMode,
25055
+ registerDrawer,
25056
+ unregisterDrawer
25057
+ ]);
25058
+ useLayoutEffect(() => {
25059
+ var _panelElementRef$curr;
25060
+ const layer = (layerRef === null || layerRef === void 0 ? void 0 : layerRef.current) ?? (layerRef ? (_panelElementRef$curr = panelElementRef.current) === null || _panelElementRef$curr === void 0 ? void 0 : _panelElementRef$curr.parentElement : null);
25061
+ if (!layer) return;
25062
+ layer.toggleAttribute("hidden", !active);
25063
+ }, [active, layerRef]);
25064
+ function beginDrag(clientY) {
25065
+ dragRef.current = {
25066
+ startY: clientY,
25067
+ startTime: performance.now(),
25068
+ startPercent: drawerPercent,
25069
+ currentPercent: drawerPercent,
25070
+ currentY: clientY,
25071
+ moved: false
25072
+ };
25073
+ }
25074
+ function moveDrag(clientY) {
25075
+ const drag = dragRef.current;
25076
+ if (!drag) return;
25077
+ const deltaY = clientY - drag.startY;
25078
+ const nextPercent = Math.max(0, Math.min(MOBILE_DRAWER_EXPANDED_PERCENT, drag.startPercent - deltaY / Math.max(window.innerHeight, 1) * 100));
25079
+ drag.currentPercent = nextPercent;
25080
+ drag.currentY = clientY;
25081
+ drag.moved ||= Math.abs(deltaY) > 6;
25082
+ setDragPercent(nextPercent);
25083
+ }
25084
+ function endDrag(clientY) {
25085
+ const drag = dragRef.current;
25086
+ if (!drag) return;
25087
+ const result = resolveMobileDrawerRelease({
25088
+ snap,
25089
+ deltaY: clientY - drag.startY,
25090
+ durationMs: performance.now() - drag.startTime,
25091
+ percent: drag.currentPercent
25092
+ });
25093
+ suppressHandleClickRef.current = drag.moved;
25094
+ dragRef.current = null;
25095
+ setDragPercent(null);
25096
+ if (result === "closed") {
25097
+ if (coordinator) coordinator.close(drawerId);
25098
+ else onClose();
25099
+ } else onSnapChange(result);
25100
+ }
25101
+ function handlePointerDown(event) {
25102
+ try {
25103
+ event.currentTarget.setPointerCapture(event.pointerId);
25104
+ } catch {}
25105
+ beginDrag(event.clientY);
25106
+ }
25107
+ function handlePointerMove(event) {
25108
+ moveDrag(event.clientY);
25109
+ }
25110
+ function handlePointerUp(event) {
25111
+ endDrag(event.clientY);
25112
+ }
25113
+ function handlePointerCancel() {
25114
+ const drag = dragRef.current;
25115
+ if (!(drag === null || drag === void 0 ? void 0 : drag.moved)) {
25116
+ dragRef.current = null;
25117
+ setDragPercent(null);
25118
+ return;
25119
+ }
25120
+ endDrag(drag.currentY);
25121
+ }
25122
+ function handleTouchStart(event) {
25123
+ const touch = event.touches[0];
25124
+ if (touch) beginDrag(touch.clientY);
25125
+ }
25126
+ function handleTouchMove(event) {
25127
+ const touch = event.touches[0];
25128
+ if (touch) moveDrag(touch.clientY);
25129
+ }
25130
+ function handleTouchEnd() {
25131
+ const drag = dragRef.current;
25132
+ if (drag) endDrag(drag.currentY);
25133
+ }
25134
+ function handleTouchCancel() {
25135
+ handlePointerCancel();
25136
+ }
25137
+ return /* @__PURE__ */ jsx(MobileDrawerLayoutContext.Provider, {
25138
+ value: layout,
25139
+ children: /* @__PURE__ */ jsxs(MobileOverlayContext.Provider, {
25140
+ value: overlay,
25141
+ children: [floatingActions && /* @__PURE__ */ jsx("div", {
25142
+ className: "univer-pointer-events-none univer-absolute univer-right-4 univer-z-30",
25143
+ style: { bottom: `calc(${drawerPercent}${viewportHeightUnit} + 12px)` },
25144
+ children: floatingActions
25145
+ }), /* @__PURE__ */ jsxs("section", {
25146
+ ref: setPanelRef,
25147
+ hidden: !active,
25148
+ role,
25149
+ "aria-modal": layout === "modal" && role === "dialog" || void 0,
25150
+ "aria-label": ariaLabel,
25151
+ "data-u-comp": componentName,
25152
+ "data-snap": snap,
25153
+ className: clsx("univer-absolute univer-inset-x-0 univer-bottom-0 univer-z-20 univer-flex univer-flex-col univer-overflow-hidden univer-rounded-t-[24px] univer-bg-gray-50 univer-shadow-2xl univer-transition-[height] univer-duration-200 dark:!univer-bg-gray-900 [&_input]:!univer-text-base [&_select]:!univer-text-base [&_textarea]:!univer-text-base", "univer-pointer-events-auto", dragPercent != null && "!univer-transition-none", panelClassName),
25154
+ style: {
25155
+ height: `${drawerPercent}${viewportHeightUnit}`,
25156
+ paddingBottom: "env(safe-area-inset-bottom, 0px)"
25157
+ },
25158
+ children: [
25159
+ /* @__PURE__ */ jsxs("div", {
25160
+ className: "univer-relative univer-flex univer-h-14 univer-shrink-0 univer-items-end univer-bg-gray-0 dark:!univer-bg-gray-800",
25161
+ children: [/* @__PURE__ */ jsx("button", {
25162
+ type: "button",
25163
+ "aria-label": snap === "compact" ? expandLabel : collapseLabel,
25164
+ className: clsx(resetButtonClassName, "univer-absolute univer-left-1/2 univer-top-0 univer-z-10 univer-flex univer-h-6 univer-w-16 -univer-translate-x-1/2 univer-touch-none univer-items-center univer-justify-center"),
25165
+ style: { touchAction: "none" },
25166
+ onPointerDown: handlePointerDown,
25167
+ onPointerMove: handlePointerMove,
25168
+ onPointerUp: handlePointerUp,
25169
+ onPointerCancel: handlePointerCancel,
25170
+ onTouchStart: handleTouchStart,
25171
+ onTouchMove: handleTouchMove,
25172
+ onTouchEnd: handleTouchEnd,
25173
+ onTouchCancel: handleTouchCancel,
25174
+ onClick: () => {
25175
+ if (suppressHandleClickRef.current) {
25176
+ suppressHandleClickRef.current = false;
25177
+ return;
25178
+ }
25179
+ onSnapChange(snap === "compact" ? "expanded" : "compact");
25180
+ },
25181
+ children: /* @__PURE__ */ jsx("span", { className: "univer-h-1 univer-w-10 univer-rounded-full univer-bg-gray-300 dark:!univer-bg-gray-600" })
25182
+ }), header]
25183
+ }),
25184
+ /* @__PURE__ */ jsx("div", {
25185
+ ref: contentRef,
25186
+ className: clsx("univer-flex-1 univer-overflow-y-auto univer-overflow-x-hidden univer-p-3", scrollbarClassName, contentClassName),
25187
+ style: { paddingBottom: keyboardLayout ? `calc(0.75rem + ${keyboardLayout.bottom}px)` : void 0 },
25188
+ children
25189
+ }),
25190
+ footer
25191
+ ]
25192
+ })]
25193
+ })
25194
+ });
24575
25195
  }
24576
25196
 
24577
25197
  //#endregion
@@ -24651,9 +25271,27 @@ function MobileMenuDrawerContent(props) {
24651
25271
  //#endregion
24652
25272
  //#region src/views/components/context-menu/MobileContextMenu.tsx
24653
25273
  const MOBILE_CONTEXT_MENU_HOST_ID = "mobile-context-menu";
25274
+ const MOBILE_CONTEXT_MENU_POINTER_SIZE = 8;
25275
+ const MOBILE_CONTEXT_MENU_POINTER_EDGE_GAP = 12;
25276
+ function resolveMobileCaretMenuPlacement(anchorX, containerLeft, containerWidth, menuWidth) {
25277
+ const relativeAnchorX = anchorX - containerLeft;
25278
+ const menuLeft = Math.min(Math.max(relativeAnchorX - menuWidth / 2, 0), Math.max(containerWidth - menuWidth, 0));
25279
+ return {
25280
+ menuLeft,
25281
+ pointerLeft: Math.min(Math.max(relativeAnchorX - menuLeft - MOBILE_CONTEXT_MENU_POINTER_SIZE / 2, MOBILE_CONTEXT_MENU_POINTER_EDGE_GAP), Math.max(menuWidth - MOBILE_CONTEXT_MENU_POINTER_EDGE_GAP - MOBILE_CONTEXT_MENU_POINTER_SIZE, MOBILE_CONTEXT_MENU_POINTER_EDGE_GAP))
25282
+ };
25283
+ }
25284
+ function shouldUseFloatingMobileContextMenu(_menuType, context) {
25285
+ return (context === null || context === void 0 ? void 0 : context.caretAnchor) === true;
25286
+ }
24654
25287
  function MobileContextMenu() {
24655
25288
  const [visible, setVisible] = useState(false);
24656
25289
  const [menuType, setMenuType] = useState("");
25290
+ const [anchor, setAnchor] = useState({
25291
+ x: 0,
25292
+ y: 0
25293
+ });
25294
+ const floatingMenuRef = useRef(null);
24657
25295
  const [menuContext, setMenuContext] = useState();
24658
25296
  const visibleRef = useRef(visible);
24659
25297
  const contextMenuHostService = useDependency(IContextMenuHostService);
@@ -24664,11 +25302,17 @@ function MobileContextMenu() {
24664
25302
  const runtimeScopeService = useDependency(IUIRuntimeScopeService);
24665
25303
  const localeService = useDependency(LocaleService);
24666
25304
  const { mountContainer } = useContext(ConfigContext);
25305
+ const isCaretAnchor = (menuContext === null || menuContext === void 0 ? void 0 : menuContext.caretAnchor) === true;
25306
+ const isFloatingContextMenu = shouldUseFloatingMobileContextMenu(menuType, menuContext);
24667
25307
  visibleRef.current = visible;
24668
- const handleContextMenu = useCallback((_event, nextMenuType, context) => {
25308
+ const handleContextMenu = useCallback((event, nextMenuType, context) => {
24669
25309
  contextMenuHostService.activateMenu(MOBILE_CONTEXT_MENU_HOST_ID);
24670
25310
  setMenuType(nextMenuType);
24671
25311
  setMenuContext(context);
25312
+ setAnchor({
25313
+ x: event.clientX,
25314
+ y: event.clientY
25315
+ });
24672
25316
  setVisible(true);
24673
25317
  }, [contextMenuHostService]);
24674
25318
  const handleClose = useCallback(() => {
@@ -24699,6 +25343,50 @@ function MobileContextMenu() {
24699
25343
  handleClose,
24700
25344
  handleContextMenu
24701
25345
  ]);
25346
+ useEffect(() => {
25347
+ if (!visible || !isFloatingContextMenu || !mountContainer) return;
25348
+ const ownerDocument = mountContainer.ownerDocument;
25349
+ const handleOutsidePointerDown = (event) => {
25350
+ var _floatingMenuRef$curr;
25351
+ if (!(event.target instanceof Node) || !((_floatingMenuRef$curr = floatingMenuRef.current) === null || _floatingMenuRef$curr === void 0 ? void 0 : _floatingMenuRef$curr.contains(event.target))) {
25352
+ setVisible(false);
25353
+ contextMenuHostService.deactivateMenu(MOBILE_CONTEXT_MENU_HOST_ID);
25354
+ }
25355
+ };
25356
+ ownerDocument.addEventListener("pointerdown", handleOutsidePointerDown, true);
25357
+ return () => ownerDocument.removeEventListener("pointerdown", handleOutsidePointerDown, true);
25358
+ }, [
25359
+ contextMenuHostService,
25360
+ isFloatingContextMenu,
25361
+ mountContainer,
25362
+ visible
25363
+ ]);
25364
+ useLayoutEffect(() => {
25365
+ if (!visible || !isCaretAnchor) return;
25366
+ const menu = floatingMenuRef.current;
25367
+ const container = menu === null || menu === void 0 ? void 0 : menu.parentElement;
25368
+ if (!menu || !container) return;
25369
+ const updatePlacement = () => {
25370
+ const containerRect = container.getBoundingClientRect();
25371
+ const menuWidth = menu.getBoundingClientRect().width;
25372
+ const { menuLeft, pointerLeft } = resolveMobileCaretMenuPlacement(anchor.x, containerRect.left, containerRect.width, menuWidth);
25373
+ menu.style.left = `${menuLeft}px`;
25374
+ menu.style.setProperty("--univer-mobile-context-menu-pointer-left", `${pointerLeft}px`);
25375
+ };
25376
+ updatePlacement();
25377
+ const resizeObserver = new ResizeObserver(updatePlacement);
25378
+ resizeObserver.observe(container);
25379
+ resizeObserver.observe(menu);
25380
+ return () => {
25381
+ resizeObserver.disconnect();
25382
+ menu.style.removeProperty("left");
25383
+ menu.style.removeProperty("--univer-mobile-context-menu-pointer-left");
25384
+ };
25385
+ }, [
25386
+ anchor.x,
25387
+ isCaretAnchor,
25388
+ visible
25389
+ ]);
24702
25390
  const sheetTitle = useMemo(() => {
24703
25391
  switch (menuType) {
24704
25392
  case "contextMenu.rowHeader": return localeService.t("ui.row");
@@ -24724,6 +25412,40 @@ function MobileContextMenu() {
24724
25412
  activeCommandService.executeCommand(commandId, commandParams);
24725
25413
  handleClose();
24726
25414
  };
25415
+ if (isFloatingContextMenu) {
25416
+ var _mountContainer$owner;
25417
+ const viewportHeight = ((_mountContainer$owner = mountContainer.ownerDocument.defaultView) === null || _mountContainer$owner === void 0 ? void 0 : _mountContainer$owner.innerHeight) ?? 0;
25418
+ const placeBelow = anchor.y < 72;
25419
+ const top = placeBelow ? anchor.y + 12 : Math.min(anchor.y - 56, Math.max(8, viewportHeight - 56));
25420
+ const pointerLeft = `clamp(20px, ${anchor.x - 8}px, calc(100% - 20px))`;
25421
+ return createPortal(/* @__PURE__ */ jsx("div", {
25422
+ className: "univer-pointer-events-none univer-fixed univer-inset-x-3 univer-z-[1080] univer-flex univer-justify-center",
25423
+ style: { top },
25424
+ children: /* @__PURE__ */ jsxs("div", {
25425
+ ref: floatingMenuRef,
25426
+ className: `
25427
+ univer-pointer-events-auto univer-min-w-0 univer-max-w-[560px]
25428
+ ${isCaretAnchor ? "univer-absolute univer-left-0 univer-top-0 univer-w-fit" : "univer-relative univer-flex-1"}
25429
+ `,
25430
+ children: [/* @__PURE__ */ jsx(MobileMenu, {
25431
+ menuType,
25432
+ menuManagerService: activeMenuManagerService,
25433
+ presentation: "context-bar",
25434
+ onOptionSelect: handleOptionSelect
25435
+ }), /* @__PURE__ */ jsx("div", {
25436
+ "aria-hidden": "true",
25437
+ className: placeBelow ? `
25438
+ univer-absolute -univer-top-1 univer-size-2 univer-rotate-45 univer-bg-gray-0
25439
+ dark:!univer-bg-gray-700
25440
+ ` : `
25441
+ univer-absolute -univer-bottom-1 univer-size-2 univer-rotate-45 univer-bg-gray-0
25442
+ dark:!univer-bg-gray-700
25443
+ `,
25444
+ style: { left: isCaretAnchor ? "var(--univer-mobile-context-menu-pointer-left, calc(50% - 4px))" : pointerLeft }
25445
+ })]
25446
+ })
25447
+ }), mountContainer);
25448
+ }
24727
25449
  return /* @__PURE__ */ jsx(MobileMenuDrawer, {
24728
25450
  visible: true,
24729
25451
  title: sheetTitle,
@@ -24743,14 +25465,18 @@ function MobileSidebar() {
24743
25465
  const layerRef = useRef(null);
24744
25466
  const scrollRef = useRef(null);
24745
25467
  const closeButtonRef = useRef(null);
24746
- const [drawerSnap, setDrawerSnap] = useState("expanded");
25468
+ const [snapOverride, setSnapOverride] = useState(null);
24747
25469
  const options = useMemo(() => renderSidebarOptions(sidebarOptions), [sidebarOptions]);
24748
25470
  useEffect(() => {
24749
- if (options === null || options === void 0 ? void 0 : options.visible) {
25471
+ if ((options === null || options === void 0 ? void 0 : options.visible) && options.layout !== "canvas") {
24750
25472
  var _closeButtonRef$curre;
24751
25473
  (_closeButtonRef$curre = closeButtonRef.current) === null || _closeButtonRef$curre === void 0 || _closeButtonRef$curre.focus();
24752
25474
  }
24753
- }, [options === null || options === void 0 ? void 0 : options.visible]);
25475
+ }, [
25476
+ options === null || options === void 0 ? void 0 : options.visible,
25477
+ options === null || options === void 0 ? void 0 : options.layout,
25478
+ options === null || options === void 0 ? void 0 : options.id
25479
+ ]);
24754
25480
  useEffect(() => {
24755
25481
  const scrollElement = scrollRef.current;
24756
25482
  sidebarService.setContainer(scrollElement ?? void 0);
@@ -24762,23 +25488,28 @@ function MobileSidebar() {
24762
25488
  };
24763
25489
  }, [options === null || options === void 0 ? void 0 : options.visible, sidebarService]);
24764
25490
  if (!(options === null || options === void 0 ? void 0 : options.visible)) return null;
25491
+ const defaultSnap = options.layout === "canvas" ? "compact" : "expanded";
24765
25492
  const close = () => sidebarService.close(sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.id);
24766
25493
  return /* @__PURE__ */ jsxs("div", {
24767
25494
  ref: layerRef,
24768
- className: "univer-fixed univer-inset-0 univer-z-[1100]",
25495
+ className: "univer-pointer-events-none univer-fixed univer-inset-0 univer-z-[1100]",
24769
25496
  "data-u-comp": "mobile-sidebar",
24770
- children: [/* @__PURE__ */ jsx("button", {
25497
+ children: [options.layout !== "canvas" && /* @__PURE__ */ jsx("button", {
24771
25498
  type: "button",
24772
25499
  "aria-label": localeService.t("ui.sidebar.close"),
24773
- className: "univer-absolute univer-inset-0 univer-m-0 univer-appearance-none univer-rounded-none univer-border-0 univer-bg-black/35 univer-p-0",
25500
+ className: "univer-pointer-events-auto univer-absolute univer-inset-0 univer-m-0 univer-appearance-none univer-rounded-none univer-border-0 univer-bg-black/35 univer-p-0",
24774
25501
  onClick: close
24775
25502
  }), /* @__PURE__ */ jsx(MobileDrawer, {
24776
25503
  layerRef,
25504
+ layout: options.layout,
24777
25505
  componentName: "mobile-sidebar-drawer",
24778
- snap: drawerSnap,
25506
+ snap: snapOverride && snapOverride.id === options.id ? snapOverride.snap : defaultSnap,
24779
25507
  expandLabel: localeService.t("ui.ribbon.more"),
24780
25508
  collapseLabel: localeService.t("ui.ribbon.more"),
24781
- onSnapChange: setDrawerSnap,
25509
+ onSnapChange: (snap) => setSnapOverride({
25510
+ id: options.id,
25511
+ snap
25512
+ }),
24782
25513
  onClose: close,
24783
25514
  role: "dialog",
24784
25515
  ariaLabel: localeService.t("ui.sidebar.panel"),
@@ -24829,8 +25560,17 @@ const MobileKeyboardInsetContext = createContext(0);
24829
25560
 
24830
25561
  //#endregion
24831
25562
  //#region src/views/mobile-workbench/MobileWorkbench.tsx
25563
+ const MOBILE_KEYBOARD_THRESHOLD = 80;
25564
+ function resolveMobileKeyboardInset(stableHeight, visibleBottom, baselineInset) {
25565
+ const keyboardInset = Math.max(0, Math.round(stableHeight - visibleBottom) - baselineInset);
25566
+ return keyboardInset >= MOBILE_KEYBOARD_THRESHOLD ? keyboardInset : 0;
25567
+ }
25568
+ function shouldUpdateMobileStableHeight(stableHeight, nextHeight, stableWidth, nextWidth, editing, keyboardVisible) {
25569
+ return nextWidth !== stableWidth || !editing && !keyboardVisible && stableHeight - nextHeight < MOBILE_KEYBOARD_THRESHOLD;
25570
+ }
24832
25571
  function mountMobileWorkbench(injector, options, mountContainer, onRendered) {
24833
- render(/* @__PURE__ */ jsx(connectInjector$1(MobileWorkbench, injector), {
25572
+ const ConnectedApp = connectInjector$1(MobileWorkbench, injector);
25573
+ render(/* @__PURE__ */ jsx(ConnectedApp, {
24834
25574
  ...options,
24835
25575
  mountContainer,
24836
25576
  onRendered
@@ -24844,8 +25584,10 @@ function MobileWorkbench(props) {
24844
25584
  const themeService = useDependency$1(ThemeService);
24845
25585
  const themeSwitcherService = useDependency$1(ThemeSwitcherService);
24846
25586
  const contentRef = useRef(null);
25587
+ const canvasContainerRef = useRef(null);
24847
25588
  const viewportRef = useRef(null);
24848
25589
  const [keyboardInset, setKeyboardInset] = useState(0);
25590
+ const [keyboardViewport, setKeyboardViewport] = useState(null);
24849
25591
  const footerComponents = useComponentsOfPart("footer");
24850
25592
  const headerComponents = useComponentsOfPart("header");
24851
25593
  const headerMenuComponents = useComponentsOfPart("header-menu");
@@ -24889,36 +25631,97 @@ function MobileWorkbench(props) {
24889
25631
  if (!viewportElement) return;
24890
25632
  let stableHeight = Math.round(mountContainer.getBoundingClientRect().height || window.innerHeight);
24891
25633
  let stableWidth = Math.round(mountContainer.getBoundingClientRect().width || window.innerWidth);
24892
- const updateKeyboardInset = () => {
24893
- const visibleBottom = visualViewport ? visualViewport.offsetTop + visualViewport.height : window.innerHeight;
24894
- setKeyboardInset(Math.max(0, Math.round(stableHeight - visibleBottom)));
25634
+ let baselineInset = Math.max(0, stableHeight - Math.round(visualViewport ? visualViewport.offsetTop + visualViewport.height : window.innerHeight));
25635
+ let keyboardVisible = false;
25636
+ let initialViewportFrame = null;
25637
+ let revealFrame = null;
25638
+ let revealInnerFrame = null;
25639
+ const isEditing = () => {
25640
+ const activeElement = document.activeElement;
25641
+ return activeElement instanceof HTMLInputElement || activeElement instanceof HTMLTextAreaElement || (activeElement === null || activeElement === void 0 ? void 0 : activeElement.getAttribute("contenteditable")) === "true";
25642
+ };
25643
+ const cancelReveal = () => {
25644
+ if (revealFrame != null) {
25645
+ cancelAnimationFrame(revealFrame);
25646
+ revealFrame = null;
25647
+ }
25648
+ if (revealInnerFrame != null) {
25649
+ cancelAnimationFrame(revealInnerFrame);
25650
+ revealInnerFrame = null;
25651
+ }
25652
+ };
25653
+ const scheduleReveal = (viewport) => {
25654
+ cancelReveal();
25655
+ if (!viewport) return;
25656
+ revealFrame = requestAnimationFrame(() => {
25657
+ revealFrame = null;
25658
+ revealInnerFrame = requestAnimationFrame(() => {
25659
+ revealInnerFrame = null;
25660
+ revealFocusedElementInMobileViewport(document.body, viewport);
25661
+ });
25662
+ });
25663
+ };
25664
+ const updateKeyboardViewport = () => {
25665
+ const visibleTop = (visualViewport === null || visualViewport === void 0 ? void 0 : visualViewport.offsetTop) ?? 0;
25666
+ const visibleHeight = (visualViewport === null || visualViewport === void 0 ? void 0 : visualViewport.height) ?? window.innerHeight;
25667
+ const visibleBottom = visualViewport ? visibleTop + visibleHeight : window.innerHeight;
25668
+ const viewportInset = Math.max(0, Math.round(stableHeight - visibleBottom));
25669
+ const keyboardInset = resolveMobileKeyboardInset(stableHeight, visibleBottom, baselineInset);
25670
+ if (!isEditing()) {
25671
+ keyboardVisible = false;
25672
+ if (keyboardInset === 0) baselineInset = viewportInset;
25673
+ } else if (keyboardInset > 0) keyboardVisible = true;
25674
+ else if (keyboardVisible && keyboardInset === 0) {
25675
+ keyboardVisible = false;
25676
+ baselineInset = viewportInset;
25677
+ }
25678
+ viewportElement.style.setProperty("--univer-mobile-keyboard-inset", `${keyboardVisible ? keyboardInset : 0}px`);
25679
+ const nextKeyboardInset = keyboardVisible ? keyboardInset : 0;
25680
+ const nextKeyboardViewport = keyboardVisible ? {
25681
+ top: Math.round(visibleTop),
25682
+ bottom: Math.round(visibleBottom),
25683
+ height: Math.round(visibleHeight),
25684
+ stableHeight
25685
+ } : null;
25686
+ setKeyboardInset(nextKeyboardInset);
25687
+ setKeyboardViewport(nextKeyboardViewport);
25688
+ scheduleReveal(nextKeyboardViewport);
24895
25689
  };
24896
25690
  const updateStableViewport = () => {
25691
+ const height = Math.round(mountContainer.getBoundingClientRect().height || window.innerHeight);
24897
25692
  const width = Math.round(mountContainer.getBoundingClientRect().width || window.innerWidth);
24898
- const activeElement = document.activeElement;
24899
- if (!(activeElement instanceof HTMLInputElement || activeElement instanceof HTMLTextAreaElement || (activeElement === null || activeElement === void 0 ? void 0 : activeElement.getAttribute("contenteditable")) === "true") || width !== stableWidth) {
24900
- stableHeight = Math.round(mountContainer.getBoundingClientRect().height || window.innerHeight);
25693
+ const editing = isEditing();
25694
+ if (shouldUpdateMobileStableHeight(stableHeight, height, stableWidth, width, editing, keyboardVisible)) {
25695
+ stableHeight = height;
24901
25696
  stableWidth = width;
24902
25697
  viewportElement.style.height = `${stableHeight}px`;
24903
25698
  }
24904
- updateKeyboardInset();
25699
+ updateKeyboardViewport();
24905
25700
  };
24906
25701
  viewportElement.style.height = `${stableHeight}px`;
24907
- updateKeyboardInset();
25702
+ initialViewportFrame = requestAnimationFrame(() => {
25703
+ initialViewportFrame = null;
25704
+ updateKeyboardViewport();
25705
+ });
24908
25706
  window.addEventListener("resize", updateStableViewport);
24909
- visualViewport === null || visualViewport === void 0 || visualViewport.addEventListener("resize", updateKeyboardInset);
24910
- visualViewport === null || visualViewport === void 0 || visualViewport.addEventListener("scroll", updateKeyboardInset);
25707
+ visualViewport === null || visualViewport === void 0 || visualViewport.addEventListener("resize", updateKeyboardViewport);
25708
+ visualViewport === null || visualViewport === void 0 || visualViewport.addEventListener("scroll", updateKeyboardViewport);
25709
+ document.addEventListener("focusin", updateKeyboardViewport);
24911
25710
  return () => {
25711
+ if (initialViewportFrame != null) cancelAnimationFrame(initialViewportFrame);
25712
+ cancelReveal();
24912
25713
  window.removeEventListener("resize", updateStableViewport);
24913
- visualViewport === null || visualViewport === void 0 || visualViewport.removeEventListener("resize", updateKeyboardInset);
24914
- visualViewport === null || visualViewport === void 0 || visualViewport.removeEventListener("scroll", updateKeyboardInset);
25714
+ visualViewport === null || visualViewport === void 0 || visualViewport.removeEventListener("resize", updateKeyboardViewport);
25715
+ visualViewport === null || visualViewport === void 0 || visualViewport.removeEventListener("scroll", updateKeyboardViewport);
25716
+ document.removeEventListener("focusin", updateKeyboardViewport);
24915
25717
  };
24916
25718
  }, [mountContainer]);
24917
25719
  return /* @__PURE__ */ jsx(ConfigProvider, {
24918
25720
  locale: locale === null || locale === void 0 ? void 0 : locale.design,
24919
25721
  direction,
24920
25722
  mountContainer: portalContainer,
24921
- children: /* @__PURE__ */ jsx(MobileKeyboardInsetContext.Provider, {
25723
+ mobileKeyboardViewport: keyboardViewport,
25724
+ children: /* @__PURE__ */ jsx(MobileCanvasLayoutProvider, { children: /* @__PURE__ */ jsx(MobileKeyboardInsetContext.Provider, {
24922
25725
  value: keyboardInset,
24923
25726
  children: /* @__PURE__ */ jsxs(MobileDrawerCoordinatorProvider, { children: [/* @__PURE__ */ jsxs("div", {
24924
25727
  ref: viewportRef,
@@ -24944,7 +25747,7 @@ function MobileWorkbench(props) {
24944
25747
  }), /* @__PURE__ */ jsxs("section", {
24945
25748
  className: "univer-relative univer-flex univer-min-h-0 univer-flex-1 univer-flex-col",
24946
25749
  children: [/* @__PURE__ */ jsxs("div", {
24947
- className: "univer-grid univer-h-full univer-grid-cols-[auto_1fr_auto] univer-grid-rows-[100%] univer-overflow-hidden",
25750
+ className: "univer-grid univer-min-h-0 univer-flex-1 univer-grid-cols-[auto_1fr_auto] univer-grid-rows-[100%] univer-overflow-hidden",
24948
25751
  children: [
24949
25752
  /* @__PURE__ */ jsx("aside", {
24950
25753
  className: "univer-h-full",
@@ -24956,16 +25759,29 @@ function MobileWorkbench(props) {
24956
25759
  className: "univer-w-screen",
24957
25760
  children: header && /* @__PURE__ */ jsx(ComponentContainer, { components: headerComponents }, "header")
24958
25761
  }), /* @__PURE__ */ jsx("section", {
24959
- ref: contentRef,
24960
- className: "univer-relative univer-overflow-hidden",
24961
- "data-range-selector": true,
24962
- onContextMenu: (e) => e.preventDefault(),
24963
- children: /* @__PURE__ */ jsx(ComponentContainer, { components: contentComponents }, "content")
25762
+ ref: canvasContainerRef,
25763
+ className: "univer-relative univer-min-h-0 univer-overflow-hidden",
25764
+ children: /* @__PURE__ */ jsx("div", {
25765
+ ref: contentRef,
25766
+ className: "univer-absolute univer-inset-0 univer-overflow-hidden",
25767
+ "data-range-selector": true,
25768
+ onContextMenu: (e) => e.preventDefault(),
25769
+ children: /* @__PURE__ */ jsx(ComponentContainer, {
25770
+ components: contentComponents,
25771
+ sharedProps: {
25772
+ containerRef: canvasContainerRef,
25773
+ canvasRef: contentRef
25774
+ }
25775
+ }, "content")
25776
+ })
24964
25777
  })]
24965
25778
  }),
24966
25779
  /* @__PURE__ */ jsx("aside", { className: "univer-h-full" })
24967
25780
  ]
24968
- }), footer && /* @__PURE__ */ jsx("footer", { children: /* @__PURE__ */ jsx(ComponentContainer, { components: footerComponents }, "footer") })]
25781
+ }), footer && /* @__PURE__ */ jsx("footer", {
25782
+ className: "univer-shrink-0",
25783
+ children: /* @__PURE__ */ jsx(ComponentContainer, { components: footerComponents }, "footer")
25784
+ })]
24969
25785
  })]
24970
25786
  }), (!ready || externalSkeletonVisible) && /* @__PURE__ */ jsx(WorkbenchSkeleton, {
24971
25787
  darkMode,
@@ -24981,7 +25797,7 @@ function MobileWorkbench(props) {
24981
25797
  /* @__PURE__ */ jsx(MobileSidebar, {})
24982
25798
  ]
24983
25799
  })] })
24984
- })
25800
+ }) })
24985
25801
  });
24986
25802
  }
24987
25803
 
@@ -25531,7 +26347,8 @@ function MobileContextConfirm(props) {
25531
26347
  });
25532
26348
  }
25533
26349
  function MobileConfirmPart() {
25534
- return useObservable(useDependency(IConfirmService).confirmOptions$, []).map((options) => {
26350
+ const confirmService = useDependency(IConfirmService);
26351
+ return useObservable(confirmService.confirmOptions$, []).map((options) => {
25535
26352
  const { children, title, ...restProps } = options;
25536
26353
  const confirmProps = restProps;
25537
26354
  for (const key of ["children", "title"]) {
@@ -25615,16 +26432,26 @@ function toMobileDialogOptions(options) {
25615
26432
  function MobileDialogPart() {
25616
26433
  const dialogService = useDependency(IDialogService);
25617
26434
  const localeService = useDependency(LocaleService);
26435
+ const { locale } = useContext(ConfigContext);
25618
26436
  const dialogOptions = useObservable(dialogService.getDialogs$(), []);
25619
26437
  const options = useMemo(() => {
25620
26438
  const activeDialogs = dialogOptions.filter((item) => item.open !== false);
25621
26439
  const active = activeDialogs[activeDialogs.length - 1];
25622
26440
  return active ? toMobileDialogOptions(active) : null;
25623
26441
  }, [dialogOptions]);
25624
- const [drawerSnap, setDrawerSnap] = useState("expanded");
26442
+ const [snapOverride, setSnapOverride] = useState(null);
25625
26443
  const layerRef = useRef(null);
25626
26444
  const backdropPointerIdRef = useRef(null);
25627
26445
  if (!options) return null;
26446
+ const defaultSnap = options.layout === "canvas" ? "compact" : "expanded";
26447
+ const footer = options.footer ?? (options.showOk || options.showCancel ? /* @__PURE__ */ jsxs(Fragment$1, { children: [options.showCancel && /* @__PURE__ */ jsx(Button, {
26448
+ onClick: options.onCancel,
26449
+ children: locale === null || locale === void 0 ? void 0 : locale.Confirm.cancel
26450
+ }), options.showOk && /* @__PURE__ */ jsx(Button, {
26451
+ variant: "primary",
26452
+ onClick: options.onOk,
26453
+ children: locale === null || locale === void 0 ? void 0 : locale.Confirm.confirm
26454
+ })] }) : null);
25628
26455
  const close = () => {
25629
26456
  var _options$onClose, _options$onOpenChange;
25630
26457
  dialogService.close(options.id);
@@ -25633,12 +26460,12 @@ function MobileDialogPart() {
25633
26460
  };
25634
26461
  return /* @__PURE__ */ jsxs("div", {
25635
26462
  ref: layerRef,
25636
- className: "univer-fixed univer-inset-0 univer-z-[1200]",
26463
+ className: "univer-pointer-events-none univer-fixed univer-inset-0 univer-z-[1200]",
25637
26464
  "data-u-comp": "mobile-dialog",
25638
- children: [/* @__PURE__ */ jsx("button", {
26465
+ children: [options.layout !== "canvas" && /* @__PURE__ */ jsx("button", {
25639
26466
  type: "button",
25640
26467
  "aria-label": localeService.t("ui.sidebar.close"),
25641
- className: "univer-absolute univer-inset-0 univer-m-0 univer-appearance-none univer-rounded-none univer-border-0 univer-bg-black/35 univer-p-0",
26468
+ className: "univer-pointer-events-auto univer-absolute univer-inset-0 univer-m-0 univer-appearance-none univer-rounded-none univer-border-0 univer-bg-black/35 univer-p-0",
25642
26469
  onPointerDown: options.maskClosable === false ? void 0 : (event) => {
25643
26470
  backdropPointerIdRef.current = event.pointerId;
25644
26471
  },
@@ -25652,11 +26479,15 @@ function MobileDialogPart() {
25652
26479
  }
25653
26480
  }), /* @__PURE__ */ jsx(MobileDrawer, {
25654
26481
  layerRef,
26482
+ layout: options.layout,
25655
26483
  componentName: "mobile-dialog-drawer",
25656
- snap: drawerSnap,
26484
+ snap: (snapOverride === null || snapOverride === void 0 ? void 0 : snapOverride.id) === options.id ? snapOverride.snap : defaultSnap,
25657
26485
  expandLabel: localeService.t("ui.sidebar.resize"),
25658
26486
  collapseLabel: localeService.t("ui.sidebar.resize"),
25659
- onSnapChange: setDrawerSnap,
26487
+ onSnapChange: (snap) => setSnapOverride({
26488
+ id: options.id,
26489
+ snap
26490
+ }),
25660
26491
  onClose: close,
25661
26492
  role: "dialog",
25662
26493
  panelClassName: "\n univer-bg-gray-0 univer-text-gray-900\n dark:!univer-bg-gray-900 dark:!univer-text-gray-0\n ",
@@ -25674,9 +26505,9 @@ function MobileDialogPart() {
25674
26505
  children: /* @__PURE__ */ jsx(CloseIcon, {})
25675
26506
  })]
25676
26507
  }),
25677
- footer: options.footer ? /* @__PURE__ */ jsx("footer", {
26508
+ footer: footer ? /* @__PURE__ */ jsx("footer", {
25678
26509
  className: "univer-shrink-0 univer-border-0 univer-border-t univer-border-solid univer-border-gray-200 univer-p-4 dark:!univer-border-gray-700",
25679
- children: /* @__PURE__ */ jsx(MobileActionRowGroup, { children: options.footer })
26510
+ children: /* @__PURE__ */ jsx(MobileActionRowGroup, { children: footer })
25680
26511
  }) : void 0,
25681
26512
  children: options.children
25682
26513
  })]
@@ -25728,7 +26559,8 @@ function DialogItem(props) {
25728
26559
  });
25729
26560
  }
25730
26561
  function DialogPart() {
25731
- const dialogOptions = useObservable(useDependency(IDialogService).getDialogs$(), []);
26562
+ const dialogService = useDependency(IDialogService);
26563
+ const dialogOptions = useObservable(dialogService.getDialogs$(), []);
25732
26564
  const attrs = useMemo(() => dialogOptions.map((options) => {
25733
26565
  const { children, title, footer, ...restProps } = options;
25734
26566
  const dialogProps = restProps;
@@ -25858,7 +26690,8 @@ const IGalleryService = createIdentifier("univer.ui.gallery-service");
25858
26690
  * limitations under the License.
25859
26691
  */
25860
26692
  function GalleryPart() {
25861
- const gallery = useObservable(useDependency(IGalleryService).gallery$);
26693
+ const galleryService = useDependency(IGalleryService);
26694
+ const gallery = useObservable(galleryService.gallery$);
25862
26695
  if (!gallery) return null;
25863
26696
  return /* @__PURE__ */ jsx(Gallery, { ...gallery });
25864
26697
  }
@@ -26207,7 +27040,8 @@ var DesktopLocalStorageService = class {
26207
27040
  */
26208
27041
  function MessageContainer() {
26209
27042
  const localeService = useDependency(LocaleService);
26210
- const darkMode = useObservable(useDependency(ThemeService).darkMode$);
27043
+ const themeService = useDependency(ThemeService);
27044
+ const darkMode = useObservable(themeService.darkMode$);
26211
27045
  const direction = useObservable(localeService.direction$);
26212
27046
  return /* @__PURE__ */ jsx(Messager, {
26213
27047
  theme: darkMode ? "dark" : "light",
@@ -26235,7 +27069,8 @@ let DesktopMessageService = class DesktopMessageService extends Disposable {
26235
27069
  show(options) {
26236
27070
  const id = options.id ?? `message-${Date.now()}-${messageId}`;
26237
27071
  messageId += 1;
26238
- message(Object.assign({}, options, { id }));
27072
+ const op = Object.assign({}, options, { id });
27073
+ message(op);
26239
27074
  return toDisposable(() => removeMessage(id));
26240
27075
  }
26241
27076
  remove(id) {
@@ -26251,22 +27086,28 @@ DesktopMessageService = __decorate([__decorateParam(0, Inject(Injector)), __deco
26251
27086
  //#region src/views/notification/Notification.tsx
26252
27087
  function Notification() {
26253
27088
  const localeService = useDependency(LocaleService);
26254
- const darkMode = useObservable(useDependency(ThemeService).darkMode$);
27089
+ const themeService = useDependency(ThemeService);
27090
+ const darkMode = useObservable(themeService.darkMode$);
26255
27091
  const direction = useObservable(localeService.direction$);
26256
27092
  return /* @__PURE__ */ jsx(Toaster, {
26257
27093
  theme: darkMode ? "dark" : "light",
26258
27094
  dir: direction
26259
27095
  });
26260
27096
  }
26261
- const notification = { show: (options) => {
26262
- const { type = "message", title, content, duration, closable = true, position = "top-right" } = options;
26263
- toast[type](title, {
26264
- position,
26265
- description: content,
26266
- duration,
26267
- closeButton: closable
26268
- });
26269
- } };
27097
+ const notification = {
27098
+ show: (options) => {
27099
+ const { type = "message", title, content, duration, closable = true, dismissible = true, position = "top-right", action } = options;
27100
+ return toast[type](title, {
27101
+ position,
27102
+ description: content,
27103
+ duration,
27104
+ closeButton: closable,
27105
+ dismissible,
27106
+ action
27107
+ });
27108
+ },
27109
+ dismiss: (id) => toast.dismiss(id)
27110
+ };
26270
27111
 
26271
27112
  //#endregion
26272
27113
  //#region src/services/notification/desktop-notification.service.ts
@@ -26278,8 +27119,8 @@ let DesktopNotificationService = class DesktopNotificationService extends Dispos
26278
27119
  this._initUIPart();
26279
27120
  }
26280
27121
  show(params) {
26281
- notification.show(params);
26282
- return toDisposable(() => {});
27122
+ const notificationID = notification.show(params);
27123
+ return toDisposable(() => notification.dismiss(notificationID));
26283
27124
  }
26284
27125
  _initUIPart() {
26285
27126
  this.disposeWithMe(this._uiPartsService.registerComponent("global", () => connectInjector(Notification, this._injector)));
@@ -26512,10 +27353,7 @@ let UniverMobileUIPlugin = class UniverMobileUIPlugin extends Plugin {
26512
27353
  useClass: DesktopSidebarService,
26513
27354
  lazy: true
26514
27355
  }],
26515
- [IMessageService, {
26516
- useClass: DesktopMessageService,
26517
- lazy: true
26518
- }],
27356
+ [IMessageService, { useClass: DesktopMessageService }],
26519
27357
  [ILocalStorageService, {
26520
27358
  useClass: DesktopLocalStorageService,
26521
27359
  lazy: true
@@ -26530,6 +27368,8 @@ let UniverMobileUIPlugin = class UniverMobileUIPlugin extends Plugin {
26530
27368
  useFactory: (injector) => injector.createInstance(MobileUIController, this._config),
26531
27369
  deps: [Injector]
26532
27370
  }],
27371
+ [FormatPainterSessionService],
27372
+ [FormatPainterController],
26533
27373
  [SharedController],
26534
27374
  [ErrorController]
26535
27375
  ], this._config.override));
@@ -26540,7 +27380,7 @@ let UniverMobileUIPlugin = class UniverMobileUIPlugin extends Plugin {
26540
27380
  ]);
26541
27381
  }
26542
27382
  onReady() {
26543
- touchDependencies(this._injector, [[SharedController]]);
27383
+ touchDependencies(this._injector, [[SharedController], [FormatPainterController]]);
26544
27384
  }
26545
27385
  };
26546
27386
  _defineProperty(UniverMobileUIPlugin, "pluginName", "UNIVER_MOBILE_UI_PLUGIN");
@@ -27273,8 +28113,10 @@ function ObjectPermissionDialog({ target, name, commandId, actions = DEFAULT_ACT
27273
28113
  useEffect(() => {
27274
28114
  const subscription = permissions.unitChanges$.subscribe((changedUnitId) => {
27275
28115
  if (changedUnitId !== unitId) return;
27276
- if (!saving) if (dirty) setConflict(true);
27277
- else setAttempt((value) => value + 1);
28116
+ if (!saving) {
28117
+ if (dirty) setConflict(true);
28118
+ else setAttempt((value) => value + 1);
28119
+ }
27278
28120
  });
27279
28121
  return () => subscription.unsubscribe();
27280
28122
  }, [
@@ -27597,6 +28439,8 @@ let ComponentsController = class ComponentsController extends Disposable {
27597
28439
  }
27598
28440
  _registerIcons() {
27599
28441
  this.disposeWithMe(this._iconManager.register({
28442
+ BrushIcon,
28443
+ ClearFormatDoubleIcon,
27600
28444
  ExpandIcon,
27601
28445
  IncreaseIcon,
27602
28446
  KeyboardIcon,
@@ -27681,7 +28525,8 @@ const ContextConfirm = (props) => {
27681
28525
  });
27682
28526
  };
27683
28527
  function ConfirmPart() {
27684
- const props = useObservable(useDependency(IConfirmService).confirmOptions$, []).map((options) => {
28528
+ const confirmService = useDependency(IConfirmService);
28529
+ const props = useObservable(confirmService.confirmOptions$, []).map((options) => {
27685
28530
  const { children, title, ...restProps } = options;
27686
28531
  const confirmProps = restProps;
27687
28532
  for (const key of ["children", "title"]) {
@@ -27811,10 +28656,7 @@ let UniverUIPlugin = class UniverUIPlugin extends Plugin {
27811
28656
  useClass: DesktopSidebarService,
27812
28657
  lazy: true
27813
28658
  }],
27814
- [IMessageService, {
27815
- useClass: DesktopMessageService,
27816
- lazy: true
27817
- }],
28659
+ [IMessageService, { useClass: DesktopMessageService }],
27818
28660
  [ILocalStorageService, {
27819
28661
  useClass: DesktopLocalStorageService,
27820
28662
  lazy: true
@@ -27829,6 +28671,8 @@ let UniverUIPlugin = class UniverUIPlugin extends Plugin {
27829
28671
  useFactory: (injector) => injector.createInstance(DesktopUIController, this._config),
27830
28672
  deps: [Injector]
27831
28673
  }],
28674
+ [FormatPainterSessionService],
28675
+ [FormatPainterController],
27832
28676
  [SharedController],
27833
28677
  [ErrorController],
27834
28678
  [FeatureSearchController],
@@ -27841,7 +28685,11 @@ let UniverUIPlugin = class UniverUIPlugin extends Plugin {
27841
28685
  ]);
27842
28686
  }
27843
28687
  onReady() {
27844
- touchDependencies(this._injector, [[SharedController], [FeatureSearchController]]);
28688
+ touchDependencies(this._injector, [
28689
+ [SharedController],
28690
+ [FormatPainterController],
28691
+ [FeatureSearchController]
28692
+ ]);
27845
28693
  }
27846
28694
  onSteady() {
27847
28695
  touchDependencies(this._injector, [[ShortcutPanelController]]);
@@ -28002,11 +28850,13 @@ function handleStringToStyle($dom, cssStyle = "") {
28002
28850
  const s = originStr.toLowerCase();
28003
28851
  const key = textTrim(s.substr(0, s.indexOf(":")));
28004
28852
  const value = textTrim(s.substr(s.indexOf(":") + 1));
28005
- if (key === "font-weight") if (value === "bold" || value === "700") styleList.bl = 1;
28006
- else styleList.bl = 0;
28007
- else if (key === "font-style") if (value === "italic") styleList.it = 1;
28008
- else styleList.it = 0;
28009
- else if (key === "font-family") {
28853
+ if (key === "font-weight") {
28854
+ if (value === "bold" || value === "700") styleList.bl = 1;
28855
+ else styleList.bl = 0;
28856
+ } else if (key === "font-style") {
28857
+ if (value === "italic") styleList.it = 1;
28858
+ else styleList.it = 0;
28859
+ } else if (key === "font-family") {
28010
28860
  const fontFamily = extractFontFamily(textTrim(originStr));
28011
28861
  styleList.ff = fontFamily;
28012
28862
  } else if (key === "font-size") {
@@ -28090,12 +28940,14 @@ function handleStringToStyle($dom, cssStyle = "") {
28090
28940
  }
28091
28941
  }
28092
28942
  if (key === "univer-underline") styleList.ul = { s: 1 };
28093
- if (key === "vertical-align") if (value === "sub") styleList.va = BaselineOffset.SUBSCRIPT;
28094
- else if (value === "super") styleList.va = BaselineOffset.SUPERSCRIPT;
28095
- else if (value === "top") styleList.vt = 1;
28096
- else if (value === "middle") styleList.vt = 2;
28097
- else if (value === "bottom") styleList.vt = 3;
28098
- else styleList.va = BaselineOffset.NORMAL;
28943
+ if (key === "vertical-align") {
28944
+ if (value === "sub") styleList.va = BaselineOffset.SUBSCRIPT;
28945
+ else if (value === "super") styleList.va = BaselineOffset.SUPERSCRIPT;
28946
+ else if (value === "top") styleList.vt = 1;
28947
+ else if (value === "middle") styleList.vt = 2;
28948
+ else if (value === "bottom") styleList.vt = 3;
28949
+ else styleList.va = BaselineOffset.NORMAL;
28950
+ }
28099
28951
  if (key === "transform") {
28100
28952
  const values = value.split(")");
28101
28953
  const index = values.findIndex((item) => item.includes("rotate"));
@@ -28111,11 +28963,13 @@ function handleStringToStyle($dom, cssStyle = "") {
28111
28963
  };
28112
28964
  }
28113
28965
  }
28114
- if (key === "text-align") if (value === "left") styleList.ht = 1;
28115
- else if (value === "center") styleList.ht = 2;
28116
- else if (value === "right") styleList.ht = 3;
28117
- else if (value === "justify") styleList.ht = 4;
28118
- else styleList.ht = 0;
28966
+ if (key === "text-align") {
28967
+ if (value === "left") styleList.ht = 1;
28968
+ else if (value === "center") styleList.ht = 2;
28969
+ else if (value === "right") styleList.ht = 3;
28970
+ else if (value === "justify") styleList.ht = 4;
28971
+ else styleList.ht = 0;
28972
+ }
28119
28973
  if (styleList.tb !== 1) {
28120
28974
  if (key === "overflow-wrap" || key === "word-wrap") {
28121
28975
  if (value === "break-word") styleList.tb = 3;
@@ -28388,20 +29242,22 @@ function handleTableMergeData(data, selection) {
28388
29242
  minC + copyC - 1;
28389
29243
  }
28390
29244
  const mergeData = [];
28391
- for (let i = 0; i < data.length; i++) for (let j = 0; j < data[i].length; j++) if (data[i][j] && typeof data[i][j] === "object" && "mc" in data[i][j]) if (data[i][j].mc) {
28392
- const mc = data[i][j].mc;
28393
- const startRow = mc.r + minH;
28394
- const endRow = startRow + mc.rs;
28395
- const startColumn = mc.c + minC;
28396
- const endColumn = startColumn + mc.cs;
28397
- mergeData.push({
28398
- startRow,
28399
- endRow,
28400
- startColumn,
28401
- endColumn
28402
- });
28403
- delete data[i][j].mc;
28404
- } else data[i][j] = null;
29245
+ for (let i = 0; i < data.length; i++) for (let j = 0; j < data[i].length; j++) if (data[i][j] && typeof data[i][j] === "object" && "mc" in data[i][j]) {
29246
+ if (data[i][j].mc) {
29247
+ const mc = data[i][j].mc;
29248
+ const startRow = mc.r + minH;
29249
+ const endRow = startRow + mc.rs;
29250
+ const startColumn = mc.c + minC;
29251
+ const endColumn = startColumn + mc.cs;
29252
+ mergeData.push({
29253
+ startRow,
29254
+ endRow,
29255
+ startColumn,
29256
+ endColumn
29257
+ });
29258
+ delete data[i][j].mc;
29259
+ } else data[i][j] = null;
29260
+ }
28405
29261
  return {
28406
29262
  data,
28407
29263
  mergeData
@@ -28476,7 +29332,8 @@ function getStyles(styleText) {
28476
29332
  if (!style[i]) continue;
28477
29333
  let attr = style[i].split("{")[0].trim();
28478
29334
  if (attr.includes(".")) attr = attr.slice(1);
28479
- output[attr] = style[i].split("{")[1].trim();
29335
+ const value = style[i].split("{")[1].trim();
29336
+ output[attr] = value;
28480
29337
  }
28481
29338
  return output;
28482
29339
  }
@@ -28491,6 +29348,221 @@ function extractFontFamily(styleStr) {
28491
29348
  return matches ? (matches[1] || matches[2] || matches[3]).trim() : null;
28492
29349
  }
28493
29350
 
29351
+ //#endregion
29352
+ //#region src/utils/mobile-canvas-gesture.ts
29353
+ /** Routes touch browsing separately from the canvas's existing object manipulation. */
29354
+ var MobileCanvasGesture = class extends Disposable {
29355
+ constructor(_canvas, _options) {
29356
+ super();
29357
+ this._canvas = _canvas;
29358
+ this._options = _options;
29359
+ _defineProperty(this, "_points", /* @__PURE__ */ new Map());
29360
+ _defineProperty(this, "_objectPointerId", null);
29361
+ _defineProperty(this, "_cancellingObject", false);
29362
+ _defineProperty(this, "_startPoint", null);
29363
+ _defineProperty(this, "_moved", false);
29364
+ _defineProperty(this, "_pinching", false);
29365
+ _defineProperty(this, "_suppressClick", false);
29366
+ _defineProperty(this, "_lastMoveTime", 0);
29367
+ _defineProperty(this, "_velocity", {
29368
+ x: 0,
29369
+ y: 0
29370
+ });
29371
+ _defineProperty(this, "_frame", null);
29372
+ const touchAction = _canvas.style.touchAction;
29373
+ _canvas.style.touchAction = "none";
29374
+ const down = (event) => this._onDown(event);
29375
+ const move = (event) => this._onMove(event);
29376
+ const up = (event) => this._onEnd(event);
29377
+ const blur = () => this._reset();
29378
+ const click = (event) => {
29379
+ if (event.target === _canvas && this._suppressClick) {
29380
+ event.preventDefault();
29381
+ event.stopImmediatePropagation();
29382
+ }
29383
+ };
29384
+ window.addEventListener("pointerdown", down, true);
29385
+ window.addEventListener("pointermove", move, true);
29386
+ window.addEventListener("pointerup", up, true);
29387
+ window.addEventListener("pointercancel", up, true);
29388
+ window.addEventListener("click", click, true);
29389
+ window.addEventListener("blur", blur);
29390
+ this.disposeWithMe(toDisposable(() => {
29391
+ this._reset();
29392
+ _canvas.style.touchAction = touchAction;
29393
+ window.removeEventListener("pointerdown", down, true);
29394
+ window.removeEventListener("pointermove", move, true);
29395
+ window.removeEventListener("pointerup", up, true);
29396
+ window.removeEventListener("pointercancel", up, true);
29397
+ window.removeEventListener("click", click, true);
29398
+ window.removeEventListener("blur", blur);
29399
+ }));
29400
+ }
29401
+ _point(event) {
29402
+ const rect = this._canvas.getBoundingClientRect();
29403
+ return {
29404
+ x: event.clientX - rect.left,
29405
+ y: event.clientY - rect.top
29406
+ };
29407
+ }
29408
+ _consume(event) {
29409
+ event.preventDefault();
29410
+ event.stopImmediatePropagation();
29411
+ }
29412
+ _onDown(event) {
29413
+ this._stopInertia();
29414
+ if (event.target !== this._canvas || event.pointerType !== "touch") {
29415
+ this._suppressClick = false;
29416
+ return;
29417
+ }
29418
+ const point = this._point(event);
29419
+ if (this._points.size === 0) {
29420
+ this._suppressClick = false;
29421
+ const action = this._options.start(point);
29422
+ if (action === "ignore") return;
29423
+ this._startPoint = point;
29424
+ this._moved = false;
29425
+ this._lastMoveTime = event.timeStamp;
29426
+ this._points.set(event.pointerId, point);
29427
+ if (action === "object") {
29428
+ this._objectPointerId = event.pointerId;
29429
+ return;
29430
+ }
29431
+ } else {
29432
+ this._points.set(event.pointerId, point);
29433
+ if (!this._pinching) {
29434
+ this._options.finishObjectTransform();
29435
+ this._cancelObjectPointer();
29436
+ this._pinching = true;
29437
+ this._moved = true;
29438
+ }
29439
+ }
29440
+ this._suppressClick = true;
29441
+ this._consume(event);
29442
+ }
29443
+ _onMove(event) {
29444
+ const previous = this._points.get(event.pointerId);
29445
+ if (!previous) return;
29446
+ const point = this._point(event);
29447
+ const previousPoints = Array.from(this._points.values());
29448
+ this._points.set(event.pointerId, point);
29449
+ if (this._pinching) {
29450
+ const points = Array.from(this._points.values());
29451
+ if (points.length >= 2) {
29452
+ const [a, b] = previousPoints;
29453
+ const [c, d] = points;
29454
+ const distance = Math.hypot(a.x - b.x, a.y - b.y);
29455
+ if (distance > 0) this._options.pinch(Math.hypot(c.x - d.x, c.y - d.y) / distance, {
29456
+ x: (a.x + b.x) / 2,
29457
+ y: (a.y + b.y) / 2
29458
+ }, {
29459
+ x: (c.x + d.x) / 2,
29460
+ y: (c.y + d.y) / 2
29461
+ });
29462
+ }
29463
+ this._consume(event);
29464
+ return;
29465
+ }
29466
+ if (this._objectPointerId !== null) return;
29467
+ if (!this._moved && this._startPoint && Math.hypot(point.x - this._startPoint.x, point.y - this._startPoint.y) >= 8) {
29468
+ this._moved = true;
29469
+ this._options.pan({
29470
+ x: point.x - this._startPoint.x,
29471
+ y: point.y - this._startPoint.y
29472
+ });
29473
+ } else if (this._moved) this._options.pan({
29474
+ x: point.x - previous.x,
29475
+ y: point.y - previous.y
29476
+ });
29477
+ const elapsed = Math.max(1, event.timeStamp - this._lastMoveTime);
29478
+ this._velocity = {
29479
+ x: (point.x - previous.x) / elapsed,
29480
+ y: (point.y - previous.y) / elapsed
29481
+ };
29482
+ this._lastMoveTime = event.timeStamp;
29483
+ this._consume(event);
29484
+ }
29485
+ _onEnd(event) {
29486
+ if (this._cancellingObject) return;
29487
+ if (!this._points.has(event.pointerId)) return;
29488
+ this._points.delete(event.pointerId);
29489
+ const objectPointer = this._objectPointerId === event.pointerId;
29490
+ if (objectPointer) this._objectPointerId = null;
29491
+ else this._consume(event);
29492
+ if (this._points.size !== 0) return;
29493
+ if (this._pinching) this._options.endPinch();
29494
+ else if (!objectPointer && event.type !== "pointercancel") {
29495
+ if (!this._moved) this._options.tap(this._point(event));
29496
+ else if (event.timeStamp - this._lastMoveTime < 80) this._startInertia();
29497
+ }
29498
+ this._pinching = false;
29499
+ this._startPoint = null;
29500
+ }
29501
+ _startInertia() {
29502
+ let velocity = {
29503
+ x: Math.max(-3, Math.min(3, this._velocity.x)),
29504
+ y: Math.max(-3, Math.min(3, this._velocity.y))
29505
+ };
29506
+ let previousTime = performance.now();
29507
+ const frame = (time) => {
29508
+ const elapsed = Math.min(32, time - previousTime);
29509
+ previousTime = time;
29510
+ const decay = Math.exp(-.005 * elapsed);
29511
+ this._options.pan({
29512
+ x: velocity.x * (1 - decay) / .005,
29513
+ y: velocity.y * (1 - decay) / .005
29514
+ });
29515
+ velocity = {
29516
+ x: velocity.x * decay,
29517
+ y: velocity.y * decay
29518
+ };
29519
+ this._frame = Math.hypot(velocity.x, velocity.y) > .02 ? requestAnimationFrame(frame) : null;
29520
+ };
29521
+ if (Math.hypot(velocity.x, velocity.y) > .04) this._frame = requestAnimationFrame(frame);
29522
+ }
29523
+ _stopInertia() {
29524
+ if (this._frame !== null) {
29525
+ cancelAnimationFrame(this._frame);
29526
+ this._frame = null;
29527
+ }
29528
+ this._velocity = {
29529
+ x: 0,
29530
+ y: 0
29531
+ };
29532
+ }
29533
+ _reset() {
29534
+ this._stopInertia();
29535
+ if (this._objectPointerId !== null) {
29536
+ this._options.finishObjectTransform();
29537
+ this._cancelObjectPointer();
29538
+ }
29539
+ if (this._pinching) this._options.endPinch();
29540
+ this._points.clear();
29541
+ this._objectPointerId = null;
29542
+ this._pinching = false;
29543
+ this._startPoint = null;
29544
+ }
29545
+ _cancelObjectPointer() {
29546
+ const pointerId = this._objectPointerId;
29547
+ const point = pointerId === null ? null : this._points.get(pointerId);
29548
+ if (pointerId === null || !point) return;
29549
+ const rect = this._canvas.getBoundingClientRect();
29550
+ this._objectPointerId = null;
29551
+ this._cancellingObject = true;
29552
+ try {
29553
+ this._canvas.dispatchEvent(new PointerEvent("pointercancel", {
29554
+ bubbles: true,
29555
+ pointerId,
29556
+ pointerType: "touch",
29557
+ clientX: rect.left + point.x,
29558
+ clientY: rect.top + point.y
29559
+ }));
29560
+ } finally {
29561
+ this._cancellingObject = false;
29562
+ }
29563
+ }
29564
+ };
29565
+
28494
29566
  //#endregion
28495
29567
  //#region src/views/components/dom/Print.tsx
28496
29568
  const PrintFloatDomSingle = memo((props) => {
@@ -28594,6 +29666,104 @@ function HoverTrack(props) {
28594
29666
  });
28595
29667
  }
28596
29668
 
29669
+ //#endregion
29670
+ //#region src/views/components/mobile-zoom-indicator/mobile-zoom-indicator.ts
29671
+ /**
29672
+ * Copyright 2023-present DreamNum Co., Ltd.
29673
+ *
29674
+ * Licensed under the Apache License, Version 2.0 (the "License");
29675
+ * you may not use this file except in compliance with the License.
29676
+ * You may obtain a copy of the License at
29677
+ *
29678
+ * http://www.apache.org/licenses/LICENSE-2.0
29679
+ *
29680
+ * Unless required by applicable law or agreed to in writing, software
29681
+ * distributed under the License is distributed on an "AS IS" BASIS,
29682
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29683
+ * See the License for the specific language governing permissions and
29684
+ * limitations under the License.
29685
+ */
29686
+ var MobileZoomIndicator = class extends Disposable {
29687
+ constructor(_canvasElement) {
29688
+ super();
29689
+ this._canvasElement = _canvasElement;
29690
+ _defineProperty(this, "_element", void 0);
29691
+ _defineProperty(this, "_hideTimer", null);
29692
+ const element = document.createElement("div");
29693
+ element.className = [
29694
+ "univer-absolute",
29695
+ "univer-left-1/2",
29696
+ "univer-top-1/2",
29697
+ "-univer-translate-x-1/2",
29698
+ "-univer-translate-y-1/2",
29699
+ "univer-select-none",
29700
+ "univer-rounded-lg",
29701
+ "univer-bg-gray-900",
29702
+ "univer-px-6",
29703
+ "univer-py-3",
29704
+ "univer-text-2xl",
29705
+ "univer-font-bold",
29706
+ "univer-text-gray-0",
29707
+ "univer-shadow-lg"
29708
+ ].join(" ");
29709
+ element.style.opacity = "0";
29710
+ element.style.pointerEvents = "none";
29711
+ element.style.transition = "opacity 150ms ease-in-out";
29712
+ element.style.zIndex = "10000";
29713
+ this._element = element;
29714
+ this._mount();
29715
+ }
29716
+ show(percentage) {
29717
+ this._mount();
29718
+ if (this._hideTimer != null) {
29719
+ window.clearTimeout(this._hideTimer);
29720
+ this._hideTimer = null;
29721
+ }
29722
+ this._element.textContent = `${percentage}%`;
29723
+ this._element.style.opacity = "1";
29724
+ }
29725
+ hide() {
29726
+ if (this._hideTimer != null) window.clearTimeout(this._hideTimer);
29727
+ this._hideTimer = window.setTimeout(() => {
29728
+ this._hideTimer = null;
29729
+ this._element.style.opacity = "0";
29730
+ }, 300);
29731
+ }
29732
+ dispose() {
29733
+ if (this._hideTimer != null) {
29734
+ window.clearTimeout(this._hideTimer);
29735
+ this._hideTimer = null;
29736
+ }
29737
+ this._element.remove();
29738
+ super.dispose();
29739
+ }
29740
+ _mount() {
29741
+ const container = this._canvasElement.parentElement;
29742
+ if (container == null || this._element.parentElement === container) return;
29743
+ if (window.getComputedStyle(container).position === "static") container.style.position = "relative";
29744
+ container.appendChild(this._element);
29745
+ }
29746
+ };
29747
+
29748
+ //#endregion
29749
+ //#region src/views/font-family/MobileFontFamilyDropdown.tsx
29750
+ function MobileFontFamilyDropdown(props) {
29751
+ const localeService = useDependency(LocaleService);
29752
+ const disabled = useObservable(props.disabled$);
29753
+ const { fonts } = useFontList();
29754
+ return /* @__PURE__ */ jsx(MobileSelect, {
29755
+ "aria-label": props.ariaLabel,
29756
+ className: clsx("univer-h-12 univer-w-full univer-min-w-0 univer-text-base", props.className),
29757
+ value: props.value,
29758
+ disabled: !!(props.disabled || disabled),
29759
+ options: fonts.map((font) => ({
29760
+ value: font.value,
29761
+ label: localeService.t(font.label)
29762
+ })),
29763
+ onChange: props.onChange
29764
+ });
29765
+ }
29766
+
28597
29767
  //#endregion
28598
29768
  //#region src/views/progress-bar/ProgressBar.tsx
28599
29769
  /**
@@ -28615,19 +29785,20 @@ function ProgressBar(props) {
28615
29785
  const { barColor, progress, onTerminate, onClearProgress } = props;
28616
29786
  const { count, done, label = "" } = progress;
28617
29787
  const progressBarInnerRef = useRef(null);
28618
- const [visible, setVisible] = useState(false);
29788
+ const [completedProgress, setCompletedProgress] = useState();
29789
+ const visible = count > 0 && completedProgress !== progress;
28619
29790
  useEffect(() => {
28620
29791
  const progressBarInner = progressBarInnerRef.current;
29792
+ let animationFrame;
28621
29793
  if (count === 0 && done === 0) {
28622
- setVisible(false);
28623
29794
  progressBarInner.style.width = "0%";
28624
29795
  return;
28625
- } else if (count > 0) {
28626
- setVisible(true);
29796
+ }
29797
+ if (count > 0) {
28627
29798
  const width = Math.floor(done / count * 100);
28628
- if (done === count) requestAnimationFrame(() => {
29799
+ if (done === count) animationFrame = requestAnimationFrame(() => {
28629
29800
  progressBarInner.style.width = `${width - 1}%`;
28630
- requestAnimationFrame(() => {
29801
+ animationFrame = requestAnimationFrame(() => {
28631
29802
  progressBarInner.style.width = `${width}%`;
28632
29803
  });
28633
29804
  });
@@ -28635,15 +29806,21 @@ function ProgressBar(props) {
28635
29806
  }
28636
29807
  const handleTransitionEnd = () => {
28637
29808
  if (done === count) {
28638
- setVisible(false);
29809
+ setCompletedProgress(progress);
28639
29810
  onClearProgress && onClearProgress();
28640
29811
  }
28641
29812
  };
28642
29813
  progressBarInner.addEventListener("transitionend", handleTransitionEnd);
28643
29814
  return () => {
29815
+ if (animationFrame !== void 0) cancelAnimationFrame(animationFrame);
28644
29816
  progressBarInner.removeEventListener("transitionend", handleTransitionEnd);
28645
29817
  };
28646
- }, [count, done]);
29818
+ }, [
29819
+ count,
29820
+ done,
29821
+ progress,
29822
+ onClearProgress
29823
+ ]);
28647
29824
  return /* @__PURE__ */ jsxs("div", {
28648
29825
  className: clsx("univer-mx-2 univer-flex univer-items-center univer-gap-2", {
28649
29826
  "univer-flex": visible,
@@ -28677,4 +29854,4 @@ function ProgressBar(props) {
28677
29854
  }
28678
29855
 
28679
29856
  //#endregion
28680
- export { AnchoredContextMenu, BrowserClipboardService, BuiltInUIPart, COLOR_PICKER_COMPONENT, COMMON_LABEL_COMPONENT, CanvasFloatDomPreviewService, CanvasFloatDomService, CanvasPopup, CanvasPopupService, CommonLabel, ComponentContainer, ComponentManager, DesktopContextMenu as ContextMenu, ContextMenuGroup, ContextMenuHostService, ContextMenuPanel, ContextMenuPosition, ContextMenuService, CopyCommand, CopyShortcutItem, CustomLabel, CutCommand, CutShortcutItem, DISABLE_AUTO_FOCUS_KEY, DesktopBeforeCloseService, DesktopConfirmService, DesktopDialogService, DesktopGalleryService, DesktopLayoutService, DesktopLocalFileService, DesktopLocalStorageService, DesktopMessageService, DesktopNotificationService, DesktopRibbonService, DesktopSidebarService, DesktopUIController, EMBED_CHILD_UNIT_ID_ATTRIBUTE, EMBED_INTERACTION_BOUNDARY_OWNER_ATTRIBUTE, EMOJI_CATEGORIES, EMOJI_PICKER_COMPONENT, EMOJI_RECENT_LIMIT, EmojiPicker, ErrorController, FILE_PNG_CLIPBOARD_MIME_TYPE, FILE_SVG_XML_CLIPBOARD_MIME_TYPE, FILE__BMP_CLIPBOARD_MIME_TYPE, FILE__JPEG_CLIPBOARD_MIME_TYPE, FILE__WEBP_CLIPBOARD_MIME_TYPE, FONT_FAMILY_COMPONENT, FONT_FAMILY_ITEM_COMPONENT, FONT_SIZE_COMPONENT, FONT_SIZE_LIST, FloatDom, FloatDomSingle, FloatingObjectToolbarPosition, FontFamily, FontFamilyDropdown, FontFamilyItem, FontService, FontSize, HEADING_ITEM_COMPONENT, HEADING_LIST, HOVER_TRACK_HOST_CLASS_NAME, HTML_CLIPBOARD_MIME_TYPE, HeadingItem, HoverTrack, IBeforeCloseService, ICanvasPopupService, IClipboardInterfaceService, IContextMenuHostService, IContextMenuService, IDialogService, IFontService, IGalleryService, ILayoutService, ILeftSidebarService, ILocalFileService, IMenuManagerService, IMessageService, INotificationService, IPlatformService, IRibbonOverrideService, IRibbonService, IShortcutService, ISidebarService, IUIController, IUIPartsService, IUIRuntimeScopeService, IUnitPresenceUIAdapterRegistry, IWorkbenchService, IconManager, KeyCode, MOBILE_UI_MODE, MenuItemType, MenuManagerPosition, MenuManagerService, MetaKeys, MobileContextMenu, MobileDialogService, MobileDrawer, MobileKeyboardInsetContext, MobileMenu, MockMessageService, NativeTextEditorShortcutBehavior, ObjectPermissionButton, ObjectPermissionPanelButton, PLAIN_TEXT_CLIPBOARD_MIME_TYPE, PasteCommand, PlatformService, PrintFloatDomSingle, ProgressBar, RectPopup, RediConsumer, RediContext, RediProvider, RedoShortcutItem, Ribbon, RibbonDataGroup, RibbonFormulasGroup, RibbonInsertGroup, RibbonOthersGroup, RibbonOverrideService, RibbonPosition, RibbonStartGroup, RibbonViewGroup, SYMBOL_CATEGORIES, SYMBOL_PICKER_COMPONENT, SharedController, SheetPasteShortKeyCommandName, ShortcutPanelController, ShortcutPanelService, ShortcutService, Sidebar, SingleCanvasPopup, SingleUnitUIController, Slider, SymbolPicker, ThemeSwitcherService, ToggleFullscreenOperation, ToggleShortcutPanelOperation, ToolbarButton, ToolbarItem, menuSchema as UIMenuSchema, UIPartsService, UIRuntimeScopeService, UI_PLUGIN_CONFIG_KEY, UNI_DISABLE_CHANGING_FOCUS_KEY, UndoRedoGroupService, UndoShortcutItem, UnitPresenceUIAdapterRegistry, UniverMobileUIPlugin, UniverUIPlugin, WithDependency, WorkbenchService, ZIndexManager, ZoomInput, connectDependencies, connectInjector, getAllEmojis, getDefaultRecentEmojis, getEmbedBoundaryOwner, getEmbedChildUnitId, getEmojiLocaleData, getHeaderFooterMenuHiddenObservable, getLocalizedEmojiTitle, getMenuHiddenObservable, getRandomEmoji, handelExcelToJson, handelTableToJson, handleDomToJson, handlePlainToJson, handleStringToStyle, handleTableColgroup, handleTableMergeData, handleTableRowGroup, imageMimeTypeSet, isEmbedBoundaryTarget, keepInteractionInsideSameEmbedBoundary, mergeMenuConfigs, objectPermissionMenuItemFactory, openObjectPermissionDialog, openObjectPermissionPanel, parseHtmlDocument, parseHtmlFragment, parseStoredRecentEmojis, preventBrowserZoomInContainers, promoteRecentEmoji, sanitizeParsedHtml, searchEmojis, splitSpanText, supportClipboardAPI, textTrim, useClickOutSide, useComponentsOfPart, useConfigValue, useDebounceFn, useDependency, useEvent, useInjector, useObservable, useObservableRef, useScrollYOverContainer, useSidebarClick, useToolbarItemStatus, useUpdateBinder, useUpdateEffect, useVirtualList };
29857
+ export { AnchoredContextMenu, BrowserClipboardService, BuiltInUIPart, COLOR_PICKER_COMPONENT, COMMON_LABEL_COMPONENT, CanvasFloatDomPreviewService, CanvasFloatDomService, CanvasPopup, CanvasPopupService, CommonLabel, ComponentContainer, ComponentManager, DesktopContextMenu as ContextMenu, ContextMenuGroup, ContextMenuHostService, ContextMenuPanel, ContextMenuPosition, ContextMenuService, CopyCommand, CopyShortcutItem, CustomLabel, CutCommand, CutShortcutItem, DISABLE_AUTO_FOCUS_KEY, DesktopBeforeCloseService, DesktopConfirmService, DesktopDialogService, DesktopGalleryService, DesktopLayoutService, DesktopLocalFileService, DesktopLocalStorageService, DesktopMessageService, DesktopNotificationService, DesktopRibbonService, DesktopSidebarService, DesktopUIController, EMBED_CHILD_UNIT_ID_ATTRIBUTE, EMBED_INTERACTION_BOUNDARY_OWNER_ATTRIBUTE, EMOJI_CATEGORIES, EMOJI_PICKER_COMPONENT, EMOJI_RECENT_LIMIT, EmojiPicker, ErrorController, FILE_PNG_CLIPBOARD_MIME_TYPE, FILE_SVG_XML_CLIPBOARD_MIME_TYPE, FILE__BMP_CLIPBOARD_MIME_TYPE, FILE__JPEG_CLIPBOARD_MIME_TYPE, FILE__WEBP_CLIPBOARD_MIME_TYPE, FONT_FAMILY_COMPONENT, FONT_FAMILY_ITEM_COMPONENT, FONT_SIZE_COMPONENT, FONT_SIZE_LIST, FloatDom, FloatDomSingle, FloatingObjectToolbarPosition, FontFamily, FontFamilyDropdown, FontFamilyItem, FontService, FontSize, FormatPainterSessionService, HEADING_ITEM_COMPONENT, HEADING_LIST, HOVER_TRACK_HOST_CLASS_NAME, HTML_CLIPBOARD_MIME_TYPE, HeadingItem, HoverTrack, IBeforeCloseService, ICanvasPopupService, IClipboardInterfaceService, IContextMenuHostService, IContextMenuService, IDialogService, IFontService, IGalleryService, ILayoutService, ILeftSidebarService, ILocalFileService, IMenuManagerService, IMessageService, INotificationService, IPlatformService, IRibbonOverrideService, IRibbonService, IShortcutService, ISidebarService, IUIController, IUIPartsService, IUIRuntimeScopeService, IUnitPresenceUIAdapterRegistry, IWorkbenchService, IconManager, KeyCode, MOBILE_UI_MODE, MenuItemType, MenuManagerPosition, MenuManagerService, MetaKeys, MobileCanvasGesture, MobileContextMenu, MobileDialogService, MobileDrawer, MobileFontFamilyDropdown, MobileKeyboardInsetContext, MobileMenu, MobileZoomIndicator, MockMessageService, NativeTextEditorShortcutBehavior, ObjectPermissionButton, ObjectPermissionPanelButton, PLAIN_TEXT_CLIPBOARD_MIME_TYPE, PasteCommand, PlatformService, PrintFloatDomSingle, ProgressBar, RectPopup, RediConsumer, RediContext, RediProvider, RedoShortcutItem, Ribbon, RibbonDataGroup, RibbonFormulasGroup, RibbonInsertGroup, RibbonOthersGroup, RibbonOverrideService, RibbonPosition, RibbonStartGroup, RibbonViewGroup, SYMBOL_CATEGORIES, SYMBOL_PICKER_COMPONENT, SharedController, SheetPasteShortKeyCommandName, ShortcutPanelController, ShortcutPanelService, ShortcutService, Sidebar, SingleCanvasPopup, SingleUnitUIController, Slider, SymbolPicker, ThemeSwitcherService, ToggleFullscreenOperation, ToggleShortcutPanelOperation, ToolbarButton, ToolbarItem, menuSchema as UIMenuSchema, UIPartsService, UIRuntimeScopeService, UI_PLUGIN_CONFIG_KEY, UNI_DISABLE_CHANGING_FOCUS_KEY, UndoRedoGroupService, UndoShortcutItem, UnitPresenceUIAdapterRegistry, UniverMobileUIPlugin, UniverUIPlugin, WithDependency, WorkbenchService, ZIndexManager, ZoomInput, bindFormatPainterCanvas, connectDependencies, connectInjector, getAllEmojis, getDefaultRecentEmojis, getEmbedBoundaryOwner, getEmbedChildUnitId, getEmojiLocaleData, getHeaderFooterMenuHiddenObservable, getLocalizedEmojiTitle, getMenuHiddenObservable, getMobileCanvasPanDelta, getRandomEmoji, handelExcelToJson, handelTableToJson, handleDomToJson, handlePlainToJson, handleStringToStyle, handleTableColgroup, handleTableMergeData, handleTableRowGroup, imageMimeTypeSet, isEmbedBoundaryTarget, keepInteractionInsideSameEmbedBoundary, mergeMenuConfigs, objectPermissionMenuItemFactory, openObjectPermissionDialog, openObjectPermissionPanel, parseHtmlDocument, parseHtmlFragment, parseStoredRecentEmojis, preventBrowserZoomInContainers, promoteRecentEmoji, sanitizeParsedHtml, searchEmojis, splitSpanText, supportClipboardAPI, textTrim, useClickOutSide, useComponentsOfPart, useConfigValue, useDebounceFn, useDependency, useEvent, useInjector, useMobileCanvasPanel, useMobileCanvasViewport, useObservable, useObservableRef, useScrollYOverContainer, useSidebarClick, useToolbarItemStatus, useUpdateBinder, useUpdateEffect, useVirtualList };