@myoc/excalidraw 0.19.542 → 0.19.544

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 (32) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/dist/dev/{chunk-2OVHIH4L.js → chunk-35XUJXYN.js} +3 -3
  3. package/dist/dev/{chunk-2OVHIH4L.js.map → chunk-35XUJXYN.js.map} +1 -1
  4. package/dist/dev/{chunk-D7VSTSAC.js → chunk-AKYL2SH7.js} +2 -2
  5. package/dist/dev/{chunk-E77EFOSN.js → chunk-DPY7NUSG.js} +15 -3
  6. package/dist/dev/{chunk-E77EFOSN.js.map → chunk-DPY7NUSG.js.map} +1 -1
  7. package/dist/dev/data/{image-7IWBMQLB.js → image-AIHWJUYD.js} +3 -3
  8. package/dist/dev/index.css +76 -40
  9. package/dist/dev/index.css.map +3 -3
  10. package/dist/dev/index.js +636 -438
  11. package/dist/dev/index.js.map +4 -4
  12. package/dist/dev/locales/{en-JINXO2V2.js → en-CBVTFJ6O.js} +2 -2
  13. package/dist/dev/subset-shared.chunk.js +1 -1
  14. package/dist/dev/subset-worker.chunk.js +1 -1
  15. package/dist/prod/{chunk-2YEDAYNK.js → chunk-SBYJFHOS.js} +1 -1
  16. package/dist/prod/{chunk-J5DZGRBF.js → chunk-TIQBOD5V.js} +2 -2
  17. package/dist/prod/{chunk-KGIBYNMP.js → chunk-VXOLR3OR.js} +4 -3
  18. package/dist/prod/data/image-P327FLYY.js +1 -0
  19. package/dist/prod/index.css +1 -1
  20. package/dist/prod/index.js +19 -19
  21. package/dist/prod/locales/{en-2ZA2LKRK.js → en-7BECMN3G.js} +1 -1
  22. package/dist/prod/subset-shared.chunk.js +1 -1
  23. package/dist/prod/subset-worker.chunk.js +1 -1
  24. package/dist/types/common/src/constants.d.ts +1 -1
  25. package/dist/types/excalidraw/actions/actionSmartZoom.d.ts +4 -0
  26. package/dist/types/excalidraw/clipboard.d.ts +1 -0
  27. package/dist/types/excalidraw/components/App.d.ts +8 -0
  28. package/package.json +4 -4
  29. package/dist/prod/data/image-I7AV73WO.js +0 -1
  30. /package/dist/dev/{chunk-D7VSTSAC.js.map → chunk-AKYL2SH7.js.map} +0 -0
  31. /package/dist/dev/data/{image-7IWBMQLB.js.map → image-AIHWJUYD.js.map} +0 -0
  32. /package/dist/dev/locales/{en-JINXO2V2.js.map → en-CBVTFJ6O.js.map} +0 -0
package/dist/dev/index.js CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  canvasToBlob,
15
15
  constrainScrollState,
16
16
  createFile,
17
+ dataURLToFile,
17
18
  dataURLToString,
18
19
  encodePngMetadata,
19
20
  exportToCanvas,
@@ -64,13 +65,13 @@ import {
64
65
  serializeAsJSON,
65
66
  strokeRectWithRotation_simple,
66
67
  zoomToFitBounds
67
- } from "./chunk-E77EFOSN.js";
68
+ } from "./chunk-DPY7NUSG.js";
68
69
  import {
69
70
  define_import_meta_env_default
70
- } from "./chunk-D7VSTSAC.js";
71
+ } from "./chunk-AKYL2SH7.js";
71
72
  import {
72
73
  en_default
73
- } from "./chunk-2OVHIH4L.js";
74
+ } from "./chunk-35XUJXYN.js";
74
75
  import {
75
76
  percentages_default
76
77
  } from "./chunk-72CYJXY3.js";
@@ -97,7 +98,7 @@ import {
97
98
  } from "@excalidraw/common";
98
99
 
99
100
  // components/App.tsx
100
- import clsx61 from "clsx";
101
+ import clsx62 from "clsx";
101
102
  import throttle3 from "lodash.throttle";
102
103
  import React41, { useContext as useContext4 } from "react";
103
104
  import { flushSync as flushSync2 } from "react-dom";
@@ -398,7 +399,7 @@ var globImport_locales_json = __glob({
398
399
  "./locales/de-CH.json": () => import("./locales/de-CH-KLWBYLGC.js"),
399
400
  "./locales/de-DE.json": () => import("./locales/de-DE-UB755M7G.js"),
400
401
  "./locales/el-GR.json": () => import("./locales/el-GR-J2BFDAEA.js"),
401
- "./locales/en.json": () => import("./locales/en-JINXO2V2.js"),
402
+ "./locales/en.json": () => import("./locales/en-CBVTFJ6O.js"),
402
403
  "./locales/es-ES.json": () => import("./locales/es-ES-GL35U3D6.js"),
403
404
  "./locales/eu-ES.json": () => import("./locales/eu-ES-5LL7P4G7.js"),
404
405
  "./locales/fa-IR.json": () => import("./locales/fa-IR-2D6AXPSB.js"),
@@ -10337,9 +10338,11 @@ import {
10337
10338
  isInitializedImageElement
10338
10339
  } from "@excalidraw/element";
10339
10340
  import { getContainingFrame } from "@excalidraw/element";
10341
+ var WEB_EXCALIDRAW_CLIPBOARD_MIME_TYPE = `web ${MIME_TYPES2.excalidrawClipboard}`;
10340
10342
  var probablySupportsClipboardReadText = "clipboard" in navigator && "readText" in navigator.clipboard;
10341
10343
  var probablySupportsClipboardWriteText = "clipboard" in navigator && "writeText" in navigator.clipboard;
10342
10344
  var probablySupportsClipboardBlob = "clipboard" in navigator && "write" in navigator.clipboard && "ClipboardItem" in window && "toBlob" in HTMLCanvasElement.prototype;
10345
+ var supportsClipboardBlob = () => "clipboard" in navigator && "write" in navigator.clipboard && "ClipboardItem" in window && "toBlob" in HTMLCanvasElement.prototype;
10343
10346
  var clipboardContainsElements = (contents) => {
10344
10347
  if ([
10345
10348
  EXPORT_DATA_TYPES.excalidraw,
@@ -10436,6 +10439,37 @@ var serializeAsClipboardJSON = ({
10436
10439
  };
10437
10440
  var copyToClipboard = async (elements, files, clipboardEvent) => {
10438
10441
  const json = serializeAsClipboardJSON({ elements, files });
10442
+ const imageFile = elements.length === 1 && isInitializedImageElement(elements[0]) ? files?.[elements[0].fileId] : null;
10443
+ const clipboardFile = imageFile && isSupportedImageFileType(imageFile.mimeType) && imageFile.dataURL ? dataURLToFile(imageFile.dataURL, imageFile.fileName) : null;
10444
+ if (clipboardFile) {
10445
+ if (supportsClipboardBlob()) {
10446
+ try {
10447
+ await navigator.clipboard.write([
10448
+ new ClipboardItem({
10449
+ [WEB_EXCALIDRAW_CLIPBOARD_MIME_TYPE]: new Blob([json], {
10450
+ type: MIME_TYPES2.excalidrawClipboard
10451
+ }),
10452
+ [clipboardFile.type]: clipboardFile
10453
+ })
10454
+ ]);
10455
+ return;
10456
+ } catch (error) {
10457
+ console.error("Error copying image with ClipboardItem", error);
10458
+ }
10459
+ }
10460
+ if (clipboardEvent?.clipboardData?.items) {
10461
+ try {
10462
+ clipboardEvent.clipboardData.items.add(clipboardFile);
10463
+ await copyTextToSystemClipboard(
10464
+ { [MIME_TYPES2.excalidrawClipboard]: json },
10465
+ clipboardEvent
10466
+ );
10467
+ return;
10468
+ } catch (error) {
10469
+ console.error("Error copying image to clipboard event", error);
10470
+ }
10471
+ }
10472
+ }
10439
10473
  await copyTextToSystemClipboard(
10440
10474
  {
10441
10475
  [MIME_TYPES2.excalidrawClipboard]: json,
@@ -10511,11 +10545,21 @@ var readSystemClipboard = async () => {
10511
10545
  }
10512
10546
  for (const item of clipboardItems) {
10513
10547
  for (const type of item.types) {
10548
+ if (type === WEB_EXCALIDRAW_CLIPBOARD_MIME_TYPE) {
10549
+ try {
10550
+ types[MIME_TYPES2.excalidrawClipboard] = await (await item.getType(type)).text();
10551
+ } catch (error) {
10552
+ console.warn(
10553
+ `Cannot retrieve ${type} from clipboardItem: ${error.message}`
10554
+ );
10555
+ }
10556
+ continue;
10557
+ }
10514
10558
  if (!isMemberOf(ALLOWED_PASTE_MIME_TYPES, type)) {
10515
10559
  continue;
10516
10560
  }
10517
10561
  try {
10518
- if (type === MIME_TYPES2.text || type === MIME_TYPES2.html) {
10562
+ if (type === MIME_TYPES2.text || type === MIME_TYPES2.html || type === MIME_TYPES2.excalidrawClipboard) {
10519
10563
  types[type] = await (await item.getType(type)).text();
10520
10564
  } else if (isSupportedImageFileType(type)) {
10521
10565
  const imageBlob = await item.getType(type);
@@ -10764,10 +10808,10 @@ var parseDataTransferEvent = async (event) => {
10764
10808
  });
10765
10809
  };
10766
10810
  var parseClipboard = async (dataList, isPlainPaste = false) => {
10767
- const parsedEventData = await parseClipboardEventTextData(
10768
- dataList,
10769
- isPlainPaste
10811
+ const excalidrawClipboardData = dataList.getData(
10812
+ MIME_TYPES2.excalidrawClipboard
10770
10813
  );
10814
+ const parsedEventData = excalidrawClipboardData ? { type: "text", value: excalidrawClipboardData } : await parseClipboardEventTextData(dataList, isPlainPaste);
10771
10815
  if (parsedEventData.type === "mixedContent") {
10772
10816
  return {
10773
10817
  mixedContent: parsedEventData.value
@@ -10970,7 +11014,7 @@ var exportCanvas = async (type, elements, appState, files, {
10970
11014
  let blob = canvasToBlob(tempCanvas);
10971
11015
  if (appState.exportEmbedScene) {
10972
11016
  blob = blob.then(
10973
- (blob2) => import("./data/image-7IWBMQLB.js").then(
11017
+ (blob2) => import("./data/image-AIHWJUYD.js").then(
10974
11018
  ({ encodePngMetadata: encodePngMetadata2 }) => encodePngMetadata2({
10975
11019
  blob: blob2,
10976
11020
  metadata: serializeAsJSON(elements, appState, files, "local")
@@ -13125,11 +13169,14 @@ var actionToggleGridMode = register({
13125
13169
  });
13126
13170
 
13127
13171
  // actions/actionSmartZoom.tsx
13172
+ import clsx23 from "clsx";
13128
13173
  import { KEYS as KEYS27 } from "@excalidraw/common";
13129
13174
  import { CaptureUpdateAction as CaptureUpdateAction22 } from "@excalidraw/element/store";
13130
13175
  import { getElementBounds } from "@excalidraw/element";
13131
13176
  import { isImageElement } from "@excalidraw/element/typeChecks";
13132
13177
  import { jsx as jsx53 } from "react/jsx-runtime";
13178
+ var SMART_ZOOM_KEY_HINT = "Press <kbd>F</kbd> quickly to smart zoom the canvas, or hold and click on an item to smart zoom to it";
13179
+ var smartZoomKeyHeldAtom = atom(false);
13133
13180
  var getNextSmartZoomImage = (elements, elementsMap, currentImageId, direction) => {
13134
13181
  const images = elements.filter(isImageElement).sort((imageA, imageB) => {
13135
13182
  const [leftA, topA] = getElementBounds(imageA, elementsMap);
@@ -13143,6 +13190,25 @@ var getNextSmartZoomImage = (elements, elementsMap, currentImageId, direction) =
13143
13190
  const nextIndex = direction === "next" ? (currentIndex + 1) % images.length : (currentIndex < 0 ? images.length - 1 : currentIndex - 1 + images.length) % images.length;
13144
13191
  return images[nextIndex];
13145
13192
  };
13193
+ var SmartZoomButton = ({ data, updateData }) => {
13194
+ const smartZoomKeyHeld = useAtomValue(smartZoomKeyHeldAtom);
13195
+ return /* @__PURE__ */ jsx53(
13196
+ IconButton,
13197
+ {
13198
+ type: "button",
13199
+ icon: arrowsToEyeIcon,
13200
+ "aria-label": t("labels.smartZoom"),
13201
+ title: `${t("labels.smartZoom")} - ${KEYS27.F.toLocaleUpperCase()}`,
13202
+ onClick: () => updateData(null),
13203
+ size: data?.size || "medium",
13204
+ "data-testid": "button-smart-zoom",
13205
+ keyBindingLabel: KEYS27.F.toLocaleUpperCase(),
13206
+ className: clsx23({
13207
+ "smart-zoom-button--key-held": smartZoomKeyHeld
13208
+ })
13209
+ }
13210
+ );
13211
+ };
13146
13212
  var actionSmartZoom = register({
13147
13213
  name: "smartZoom",
13148
13214
  label: "toolBar.smartZoom",
@@ -13166,20 +13232,7 @@ var actionSmartZoom = register({
13166
13232
  captureUpdate: CaptureUpdateAction22.NEVER
13167
13233
  };
13168
13234
  },
13169
- keyTest: (event) => !event[KEYS27.CTRL_OR_CMD] && !event.shiftKey && !event.altKey && event.key.toLocaleLowerCase() === KEYS27.F,
13170
- PanelComponent: ({ data, updateData }) => /* @__PURE__ */ jsx53(
13171
- IconButton,
13172
- {
13173
- type: "button",
13174
- icon: arrowsToEyeIcon,
13175
- "aria-label": t("labels.smartZoom"),
13176
- title: `${t("labels.smartZoom")} - ${KEYS27.F.toLocaleUpperCase()}`,
13177
- onClick: () => updateData(null),
13178
- size: data?.size || "medium",
13179
- "data-testid": "button-smart-zoom",
13180
- keyBindingLabel: KEYS27.F.toLocaleUpperCase()
13181
- }
13182
- )
13235
+ PanelComponent: SmartZoomButton
13183
13236
  });
13184
13237
 
13185
13238
  // actions/actionToggleObjectsSnapMode.tsx
@@ -13560,7 +13613,7 @@ import { CaptureUpdateAction as CaptureUpdateAction28 } from "@excalidraw/elemen
13560
13613
 
13561
13614
  // components/hyperlink/Hyperlink.tsx
13562
13615
  import { pointFrom as pointFrom3 } from "@excalidraw/math";
13563
- import clsx23 from "clsx";
13616
+ import clsx24 from "clsx";
13564
13617
  import {
13565
13618
  useCallback as useCallback6,
13566
13619
  useEffect as useEffect20,
@@ -13734,7 +13787,7 @@ var Hyperlink = ({
13734
13787
  isEditing ? /* @__PURE__ */ jsx54(
13735
13788
  "input",
13736
13789
  {
13737
- className: clsx23("excalidraw-hyperlinkContainer-input"),
13790
+ className: clsx24("excalidraw-hyperlinkContainer-input"),
13738
13791
  placeholder: t("labels.link.hint"),
13739
13792
  ref: inputRef,
13740
13793
  value: inputVal,
@@ -16971,7 +17024,7 @@ var actionTextAutoResize = register({
16971
17024
 
16972
17025
  // actions/actionToggleViewMode.tsx
16973
17026
  import { CODES as CODES10, KEYS as KEYS37 } from "@excalidraw/common";
16974
- import clsx24 from "clsx";
17027
+ import clsx25 from "clsx";
16975
17028
  import { CaptureUpdateAction as CaptureUpdateAction37 } from "@excalidraw/element";
16976
17029
  import { jsx as jsx59 } from "react/jsx-runtime";
16977
17030
  var actionToggleViewMode = register({
@@ -17014,7 +17067,7 @@ var actionToggleViewMode = register({
17014
17067
  onClick: () => updateData(null),
17015
17068
  size: data?.size || "medium",
17016
17069
  "data-testid": "button-view-mode",
17017
- className: clsx24({
17070
+ className: clsx25({
17018
17071
  enabled: appState.viewModeEnabled
17019
17072
  })
17020
17073
  }
@@ -25349,7 +25402,7 @@ var BraveMeasureTextError = () => {
25349
25402
  var BraveMeasureTextError_default = BraveMeasureTextError;
25350
25403
 
25351
25404
  // components/ContextMenu.tsx
25352
- import clsx26 from "clsx";
25405
+ import clsx27 from "clsx";
25353
25406
  import React20 from "react";
25354
25407
 
25355
25408
  // actions/shortcuts.ts
@@ -25416,7 +25469,7 @@ import { useLayoutEffect as useLayoutEffect4, useRef as useRef16, useEffect as u
25416
25469
  import { unstable_batchedUpdates as unstable_batchedUpdates2 } from "react-dom";
25417
25470
  import { KEYS as KEYS41, queryFocusableElements } from "@excalidraw/common";
25418
25471
  import { clamp as clamp10 } from "@excalidraw/math";
25419
- import clsx25 from "clsx";
25472
+ import clsx26 from "clsx";
25420
25473
  import { jsx as jsx63 } from "react/jsx-runtime";
25421
25474
  var POPOVER_CONTAINER_GAP = 10;
25422
25475
  var Popover7 = ({
@@ -25515,7 +25568,7 @@ var Popover7 = ({
25515
25568
  return () => document.removeEventListener("pointerdown", handler, false);
25516
25569
  }
25517
25570
  }, [onCloseRequest]);
25518
- return /* @__PURE__ */ jsx63("div", { className: clsx25("popover", className), ref: popoverRef, tabIndex: -1, children });
25571
+ return /* @__PURE__ */ jsx63("div", { className: clsx26("popover", className), ref: popoverRef, tabIndex: -1, children });
25519
25572
  };
25520
25573
 
25521
25574
  // components/ContextMenu.tsx
@@ -25618,7 +25671,7 @@ var ContextMenu2 = React20.memo(
25618
25671
  "button",
25619
25672
  {
25620
25673
  type: "button",
25621
- className: clsx26("context-menu-item", {
25674
+ className: clsx27("context-menu-item", {
25622
25675
  dangerous: actionName === "deleteSelectedElements",
25623
25676
  checkmark: item.checked?.(appState)
25624
25677
  }),
@@ -25641,7 +25694,7 @@ var ContextMenu2 = React20.memo(
25641
25694
 
25642
25695
  // components/ViewportStatusFrame/ViewportStatusFrame.tsx
25643
25696
  import { useId } from "react";
25644
- import clsx27 from "clsx";
25697
+ import clsx28 from "clsx";
25645
25698
  import { Fragment as Fragment8, jsx as jsx65, jsxs as jsxs33 } from "react/jsx-runtime";
25646
25699
  var ViewportStatusBorder = ({
25647
25700
  border,
@@ -25665,7 +25718,7 @@ var ViewportStatusBadge = ({
25665
25718
  return /* @__PURE__ */ jsxs33(
25666
25719
  "div",
25667
25720
  {
25668
- className: clsx27("viewport-status-frame__badge", {
25721
+ className: clsx28("viewport-status-frame__badge", {
25669
25722
  "viewport-status-frame__badge--clickable": label.onClick
25670
25723
  }),
25671
25724
  role: "status",
@@ -25707,7 +25760,7 @@ var ViewportStatusBadge = ({
25707
25760
  };
25708
25761
 
25709
25762
  // components/LayerUI.tsx
25710
- import clsx59 from "clsx";
25763
+ import clsx60 from "clsx";
25711
25764
  import React38 from "react";
25712
25765
  import {
25713
25766
  CLASSES as CLASSES9,
@@ -25743,7 +25796,7 @@ var useInitializeTunnels = () => {
25743
25796
  };
25744
25797
 
25745
25798
  // components/Actions.tsx
25746
- import clsx29 from "clsx";
25799
+ import clsx30 from "clsx";
25747
25800
  import { useRef as useRef17 } from "react";
25748
25801
  import { Popover as Popover8 } from "radix-ui";
25749
25802
  import { CLASSES as CLASSES4 } from "@excalidraw/common";
@@ -25751,14 +25804,14 @@ import { isArrowElement as isArrowElement11 } from "@excalidraw/element";
25751
25804
 
25752
25805
  // components/Stack.tsx
25753
25806
  import { forwardRef as forwardRef2 } from "react";
25754
- import clsx28 from "clsx";
25807
+ import clsx29 from "clsx";
25755
25808
  import { jsx as jsx66 } from "react/jsx-runtime";
25756
25809
  var RowStack = forwardRef2(
25757
25810
  ({ children, gap, align, justifyContent, className, style }, ref) => {
25758
25811
  return /* @__PURE__ */ jsx66(
25759
25812
  "div",
25760
25813
  {
25761
- className: clsx28("Stack Stack_horizontal", className),
25814
+ className: clsx29("Stack Stack_horizontal", className),
25762
25815
  style: {
25763
25816
  "--gap": gap,
25764
25817
  alignItems: align,
@@ -25776,7 +25829,7 @@ var ColStack = forwardRef2(
25776
25829
  return /* @__PURE__ */ jsx66(
25777
25830
  "div",
25778
25831
  {
25779
- className: clsx28("Stack Stack_vertical", className),
25832
+ className: clsx29("Stack Stack_vertical", className),
25780
25833
  style: {
25781
25834
  "--gap": gap,
25782
25835
  justifyItems: align,
@@ -25879,7 +25932,7 @@ var getShapeActionPredicates = (appState, targetElements, elementsMap, app) => {
25879
25932
 
25880
25933
  // components/Actions.tsx
25881
25934
  import { Fragment as Fragment9, jsx as jsx67, jsxs as jsxs34 } from "react/jsx-runtime";
25882
- var PROPERTIES_CLASSES = clsx29([
25935
+ var PROPERTIES_CLASSES = clsx30([
25883
25936
  CLASSES4.SHAPE_ACTIONS_THEME_SCOPE,
25884
25937
  "properties-content"
25885
25938
  ]);
@@ -26032,7 +26085,7 @@ var CombinedShapeProperties = ({
26032
26085
  "button",
26033
26086
  {
26034
26087
  type: "button",
26035
- className: clsx29("compact-action-button properties-trigger", {
26088
+ className: clsx30("compact-action-button properties-trigger", {
26036
26089
  active: isOpen
26037
26090
  }),
26038
26091
  title: t("labels.stroke"),
@@ -26102,7 +26155,7 @@ var CombinedArrowProperties = ({
26102
26155
  "button",
26103
26156
  {
26104
26157
  type: "button",
26105
- className: clsx29("compact-action-button properties-trigger", {
26158
+ className: clsx30("compact-action-button properties-trigger", {
26106
26159
  active: isOpen
26107
26160
  }),
26108
26161
  title: t("labels.arrowtypes"),
@@ -26182,7 +26235,7 @@ var CombinedTextProperties = ({
26182
26235
  "button",
26183
26236
  {
26184
26237
  type: "button",
26185
- className: clsx29("compact-action-button properties-trigger", {
26238
+ className: clsx30("compact-action-button properties-trigger", {
26186
26239
  active: isOpen
26187
26240
  }),
26188
26241
  title: t("labels.textAlign"),
@@ -26253,7 +26306,7 @@ var CombinedExtraActions = ({
26253
26306
  "button",
26254
26307
  {
26255
26308
  type: "button",
26256
- className: clsx29("compact-action-button properties-trigger", {
26309
+ className: clsx30("compact-action-button properties-trigger", {
26257
26310
  active: isOpen
26258
26311
  }),
26259
26312
  title: t("labels.actions"),
@@ -26333,7 +26386,7 @@ var CompactShapeActions = ({
26333
26386
  );
26334
26387
  const { container } = useExcalidrawContainer();
26335
26388
  return /* @__PURE__ */ jsxs34("div", { className: "compact-shape-actions", children: [
26336
- predicates.strokeColor && /* @__PURE__ */ jsx67("div", { className: clsx29("compact-action-item"), children: renderAction("changeStrokeColor") }),
26389
+ predicates.strokeColor && /* @__PURE__ */ jsx67("div", { className: clsx30("compact-action-item"), children: renderAction("changeStrokeColor") }),
26337
26390
  predicates.backgroundColor && /* @__PURE__ */ jsx67("div", { className: "compact-action-item", children: renderAction(
26338
26391
  appState.activeTool.type === "bucketfill" ? "changeBucketFillBackgroundColor" : "changeBackgroundColor"
26339
26392
  ) }),
@@ -26440,7 +26493,7 @@ var MobileShapeActions = ({
26440
26493
  flex: 1
26441
26494
  },
26442
26495
  children: [
26443
- predicates.strokeColor && /* @__PURE__ */ jsx67("div", { className: clsx29("compact-action-item"), children: renderAction("changeStrokeColor") }),
26496
+ predicates.strokeColor && /* @__PURE__ */ jsx67("div", { className: clsx30("compact-action-item"), children: renderAction("changeStrokeColor") }),
26444
26497
  predicates.backgroundColor && /* @__PURE__ */ jsx67("div", { className: "compact-action-item", children: renderAction(
26445
26498
  appState.activeTool.type === "bucketfill" ? "changeBucketFillBackgroundColor" : "changeBackgroundColor"
26446
26499
  ) }),
@@ -26544,7 +26597,7 @@ var ExitZenModeButton = ({
26544
26597
  "button",
26545
26598
  {
26546
26599
  type: "button",
26547
- className: clsx29("disable-zen-mode", {
26600
+ className: clsx30("disable-zen-mode", {
26548
26601
  "disable-zen-mode--visible": showExitZenModeBtn
26549
26602
  }),
26550
26603
  children: t("buttons.exitZenMode")
@@ -26552,7 +26605,7 @@ var ExitZenModeButton = ({
26552
26605
  );
26553
26606
 
26554
26607
  // components/LoadingMessage.tsx
26555
- import clsx30 from "clsx";
26608
+ import clsx31 from "clsx";
26556
26609
  import { useState as useState17, useEffect as useEffect24 } from "react";
26557
26610
  import { THEME as THEME23 } from "@excalidraw/common";
26558
26611
  import { jsx as jsx68, jsxs as jsxs35 } from "react/jsx-runtime";
@@ -26576,7 +26629,7 @@ var LoadingMessage = ({
26576
26629
  return /* @__PURE__ */ jsxs35(
26577
26630
  "div",
26578
26631
  {
26579
- className: clsx30("LoadingMessage", {
26632
+ className: clsx31("LoadingMessage", {
26580
26633
  "LoadingMessage--dark": theme === THEME23.DARK
26581
26634
  }),
26582
26635
  children: [
@@ -26589,7 +26642,7 @@ var LoadingMessage = ({
26589
26642
 
26590
26643
  // components/MobileToolbar.tsx
26591
26644
  import { useState as useState19, useEffect as useEffect26 } from "react";
26592
- import clsx34 from "clsx";
26645
+ import clsx35 from "clsx";
26593
26646
  import { KEYS as KEYS43, capitalizeString as capitalizeString3 } from "@excalidraw/common";
26594
26647
 
26595
26648
  // components/dropdownMenu/DropdownMenu.tsx
@@ -26598,7 +26651,7 @@ import { DropdownMenu as DropdownMenuPrimitive8 } from "radix-ui";
26598
26651
  import { CLASSES as CLASSES6 } from "@excalidraw/common";
26599
26652
 
26600
26653
  // components/dropdownMenu/DropdownMenuContent.tsx
26601
- import clsx31 from "clsx";
26654
+ import clsx32 from "clsx";
26602
26655
  import { useCallback as useCallback7, useEffect as useEffect25, useRef as useRef18 } from "react";
26603
26656
  import { CLASSES as CLASSES5, EVENT as EVENT6, KEYS as KEYS42 } from "@excalidraw/common";
26604
26657
  import { DropdownMenu as DropdownMenuPrimitive2 } from "radix-ui";
@@ -26647,7 +26700,7 @@ var MenuContent = ({
26647
26700
  document.removeEventListener(EVENT6.KEYDOWN, onKeyDown, option);
26648
26701
  };
26649
26702
  }, [callbacksRef, open]);
26650
- const classNames = clsx31(`dropdown-menu ${className}`, {
26703
+ const classNames = clsx32(`dropdown-menu ${className}`, {
26651
26704
  "dropdown-menu--mobile": editorInterface.formFactor === "phone"
26652
26705
  }).trim();
26653
26706
  return /* @__PURE__ */ jsx69(DropdownMenuContentPropsContext.Provider, { value: { onSelect }, children: /* @__PURE__ */ jsx69(
@@ -26748,7 +26801,7 @@ MenuSeparator.displayName = "DropdownMenuSeparator";
26748
26801
  import { DropdownMenu as DropdownMenuPrimitive6 } from "radix-ui";
26749
26802
 
26750
26803
  // components/dropdownMenu/DropdownMenuSubContent.tsx
26751
- import clsx32 from "clsx";
26804
+ import clsx33 from "clsx";
26752
26805
  import { DropdownMenu as DropdownMenuPrimitive4 } from "radix-ui";
26753
26806
  import { useCallback as useCallback8, useState as useState18 } from "react";
26754
26807
  import { jsx as jsx73 } from "react/jsx-runtime";
@@ -26759,7 +26812,7 @@ var DropdownMenuSubContent = ({
26759
26812
  className
26760
26813
  }) => {
26761
26814
  const editorInterface = useEditorInterface();
26762
- const classNames = clsx32(`dropdown-menu dropdown-submenu ${className}`, {
26815
+ const classNames = clsx33(`dropdown-menu dropdown-submenu ${className}`, {
26763
26816
  "dropdown-menu--mobile": editorInterface.formFactor === "phone"
26764
26817
  }).trim();
26765
26818
  const callbacksRef = useCallback8((node) => {
@@ -26865,7 +26918,7 @@ DropdownMenuSub.displayName = "DropdownMenuSub";
26865
26918
  var DropdownMenuSub_default = DropdownMenuSub;
26866
26919
 
26867
26920
  // components/dropdownMenu/DropdownMenuTrigger.tsx
26868
- import clsx33 from "clsx";
26921
+ import clsx34 from "clsx";
26869
26922
  import { DropdownMenu as DropdownMenuPrimitive7 } from "radix-ui";
26870
26923
  import { jsx as jsx75 } from "react/jsx-runtime";
26871
26924
  var MenuTrigger = ({
@@ -26876,7 +26929,7 @@ var MenuTrigger = ({
26876
26929
  ...rest
26877
26930
  }) => {
26878
26931
  const editorInterface = useEditorInterface();
26879
- const classNames = clsx33(
26932
+ const classNames = clsx34(
26880
26933
  `dropdown-menu-button ${className}`,
26881
26934
  "zen-mode-transition",
26882
26935
  {
@@ -27111,7 +27164,7 @@ var MobileToolbar = ({
27111
27164
  /* @__PURE__ */ jsx78(
27112
27165
  DropdownMenu_default.Trigger,
27113
27166
  {
27114
- className: clsx34(
27167
+ className: clsx35(
27115
27168
  "App-toolbar__extra-tools-trigger App-toolbar__extra-tools-trigger--mobile",
27116
27169
  {
27117
27170
  "App-toolbar__extra-tools-trigger--selected": extraToolSelected || isOtherShapesMenuOpen
@@ -27275,7 +27328,7 @@ var MobileToolbar = ({
27275
27328
  };
27276
27329
 
27277
27330
  // components/FixedSideContainer.tsx
27278
- import clsx35 from "clsx";
27331
+ import clsx36 from "clsx";
27279
27332
  import { jsx as jsx79 } from "react/jsx-runtime";
27280
27333
  var FixedSideContainer = ({
27281
27334
  children,
@@ -27284,7 +27337,7 @@ var FixedSideContainer = ({
27284
27337
  }) => /* @__PURE__ */ jsx79(
27285
27338
  "div",
27286
27339
  {
27287
- className: clsx35(
27340
+ className: clsx36(
27288
27341
  "FixedSideContainer",
27289
27342
  `FixedSideContainer_side_${side}`,
27290
27343
  className
@@ -27294,7 +27347,7 @@ var FixedSideContainer = ({
27294
27347
  );
27295
27348
 
27296
27349
  // components/PenModeButton.tsx
27297
- import clsx36 from "clsx";
27350
+ import clsx37 from "clsx";
27298
27351
  import { jsx as jsx80 } from "react/jsx-runtime";
27299
27352
  var PenModeButton = (props) => {
27300
27353
  if (!props.penDetected) {
@@ -27303,7 +27356,7 @@ var PenModeButton = (props) => {
27303
27356
  return /* @__PURE__ */ jsx80(
27304
27357
  IconButton,
27305
27358
  {
27306
- className: clsx36("ToolIcon__penMode", { "is-mobile": props.isMobile }),
27359
+ className: clsx37("ToolIcon__penMode", { "is-mobile": props.isMobile }),
27307
27360
  type: "toggle",
27308
27361
  icon: PenModeIcon,
27309
27362
  checked: props.checked,
@@ -27459,7 +27512,7 @@ import React27, { useLayoutEffect as useLayoutEffect5, useRef as useRef20, useSt
27459
27512
  import { newTextElement as newTextElement4 } from "@excalidraw/element";
27460
27513
 
27461
27514
  // components/Dialog.tsx
27462
- import clsx38 from "clsx";
27515
+ import clsx39 from "clsx";
27463
27516
  import { useEffect as useEffect27, useState as useState21 } from "react";
27464
27517
  import { KEYS as KEYS45, queryFocusableElements as queryFocusableElements2 } from "@excalidraw/common";
27465
27518
 
@@ -27472,7 +27525,7 @@ var useCallbackRefState = () => {
27472
27525
  };
27473
27526
 
27474
27527
  // components/Modal.tsx
27475
- import clsx37 from "clsx";
27528
+ import clsx38 from "clsx";
27476
27529
  import { useRef as useRef19 } from "react";
27477
27530
  import { createPortal as createPortal2 } from "react-dom";
27478
27531
  import { KEYS as KEYS44 } from "@excalidraw/common";
@@ -27480,7 +27533,7 @@ import { jsx as jsx82, jsxs as jsxs41 } from "react/jsx-runtime";
27480
27533
  var Modal = (props) => {
27481
27534
  const { closeOnClickOutside = true } = props;
27482
27535
  const modalRoot = useCreatePortalContainer({
27483
- className: clsx37(
27536
+ className: clsx38(
27484
27537
  "excalidraw-modal-container",
27485
27538
  props.portalContainerClassName
27486
27539
  )
@@ -27503,7 +27556,7 @@ var Modal = (props) => {
27503
27556
  /* @__PURE__ */ jsxs41(
27504
27557
  "div",
27505
27558
  {
27506
- className: clsx37("Modal", props.className, {
27559
+ className: clsx38("Modal", props.className, {
27507
27560
  "animations-disabled": animationsDisabledRef.current
27508
27561
  }),
27509
27562
  role: "dialog",
@@ -27593,7 +27646,7 @@ var Dialog = (props) => {
27593
27646
  return /* @__PURE__ */ jsx83(
27594
27647
  Modal,
27595
27648
  {
27596
- className: clsx38("Dialog", props.className, {
27649
+ className: clsx39("Dialog", props.className, {
27597
27650
  "Dialog--fullscreen": isFullscreen
27598
27651
  }),
27599
27652
  labelledBy: "dialog-title",
@@ -27853,7 +27906,7 @@ var Section = ({ heading, children, ...props }) => {
27853
27906
 
27854
27907
  // components/UserList.tsx
27855
27908
  import { Popover as Popover9 } from "radix-ui";
27856
- import clsx39 from "clsx";
27909
+ import clsx40 from "clsx";
27857
27910
  import React28, { useLayoutEffect as useLayoutEffect6 } from "react";
27858
27911
  import { supportsResizeObserver, isShallowEqual as isShallowEqual5 } from "@excalidraw/common";
27859
27912
  import { Fragment as Fragment13, jsx as jsx86, jsxs as jsxs45 } from "react/jsx-runtime";
@@ -28033,7 +28086,7 @@ var UserList = React28.memo(
28033
28086
  )
28034
28087
  ] }, collaborator.socketId);
28035
28088
  });
28036
- return mobile ? /* @__PURE__ */ jsxs45("div", { className: clsx39("UserList UserList_mobile", className), children: [
28089
+ return mobile ? /* @__PURE__ */ jsxs45("div", { className: clsx40("UserList UserList_mobile", className), children: [
28037
28090
  /* @__PURE__ */ jsx86("div", { className: "UserList_mobile__avatars", children: collaboratorsArray.map(
28038
28091
  (collaborator) => renderCollaborator({
28039
28092
  actionManager,
@@ -28050,7 +28103,7 @@ var UserList = React28.memo(
28050
28103
  ] }) : /* @__PURE__ */ jsx86("div", { className: "UserList__wrapper", ref: userListWrapper, children: /* @__PURE__ */ jsx86(
28051
28104
  "div",
28052
28105
  {
28053
- className: clsx39("UserList", className),
28106
+ className: clsx40("UserList", className),
28054
28107
  style: {
28055
28108
  [`--max-avatars`]: firstNCollaborators.length + (currentUser ? PILL_EXTRA_WIDTH / AVATAR_SLOT_WIDTH : 0)
28056
28109
  },
@@ -28080,7 +28133,7 @@ var UserList = React28.memo(
28080
28133
  );
28081
28134
 
28082
28135
  // components/footer/Footer.tsx
28083
- import clsx40 from "clsx";
28136
+ import clsx41 from "clsx";
28084
28137
 
28085
28138
  // components/HelpButton.tsx
28086
28139
  import { jsx as jsx87 } from "react/jsx-runtime";
@@ -28116,7 +28169,7 @@ var Footer = ({
28116
28169
  (defaultUIEnabled || zoomUIEnabled && app.isNavigationEnabled()) && /* @__PURE__ */ jsx88(
28117
28170
  "div",
28118
28171
  {
28119
- className: clsx40(
28172
+ className: clsx41(
28120
28173
  "layer-ui__wrapper__footer-left zen-mode-transition",
28121
28174
  {
28122
28175
  "layer-ui__wrapper__footer-left--transition-left": appState.zenModeEnabled
@@ -28127,16 +28180,16 @@ var Footer = ({
28127
28180
  Tooltip,
28128
28181
  {
28129
28182
  label: appState.viewModeEnabled ? "Edit mode" : t("labels.viewMode"),
28130
- children: /* @__PURE__ */ jsx88("div", { className: clsx40("view-mode-button"), children: actionManager.renderAction("viewMode") })
28183
+ children: /* @__PURE__ */ jsx88("div", { className: clsx41("view-mode-button"), children: actionManager.renderAction("viewMode") })
28131
28184
  }
28132
28185
  ),
28133
- /* @__PURE__ */ jsx88(Tooltip, { label: t("buttons.smartZoom"), children: /* @__PURE__ */ jsx88("div", { className: clsx40("smart-zoom-button"), children: actionManager.renderAction("smartZoom") }) }),
28186
+ /* @__PURE__ */ jsx88(Tooltip, { label: t("buttons.smartZoom"), children: /* @__PURE__ */ jsx88("div", { className: clsx41("smart-zoom-button"), children: actionManager.renderAction("smartZoom") }) }),
28134
28187
  zoomUIEnabled && app.isNavigationEnabled() && /* @__PURE__ */ jsx88(ZoomActions, { renderAction: actionManager.renderAction }),
28135
28188
  defaultUIEnabled && !appState.viewModeEnabled && /* @__PURE__ */ jsx88(
28136
28189
  UndoRedoActions,
28137
28190
  {
28138
28191
  renderAction: actionManager.renderAction,
28139
- className: clsx40("zen-mode-transition", {
28192
+ className: clsx41("zen-mode-transition", {
28140
28193
  "layer-ui__wrapper__footer-left--transition-bottom": appState.zenModeEnabled
28141
28194
  })
28142
28195
  }
@@ -28148,7 +28201,7 @@ var Footer = ({
28148
28201
  (defaultUIEnabled || renderWelcomeScreen) && /* @__PURE__ */ jsx88(
28149
28202
  "div",
28150
28203
  {
28151
- className: clsx40(
28204
+ className: clsx41(
28152
28205
  "layer-ui__wrapper__footer-right zen-mode-transition",
28153
28206
  {
28154
28207
  "transition-right": appState.zenModeEnabled
@@ -28245,7 +28298,7 @@ __export(DefaultItems_exports, {
28245
28298
  Socials: () => Socials,
28246
28299
  ToggleTheme: () => ToggleTheme
28247
28300
  });
28248
- import clsx42 from "clsx";
28301
+ import clsx43 from "clsx";
28249
28302
  import { THEME as THEME24 } from "@excalidraw/common";
28250
28303
 
28251
28304
  // components/OverwriteConfirm/OverwriteConfirmState.ts
@@ -28273,7 +28326,7 @@ async function openConfirmModal({
28273
28326
  }
28274
28327
 
28275
28328
  // components/RadioGroup.tsx
28276
- import clsx41 from "clsx";
28329
+ import clsx42 from "clsx";
28277
28330
  import { jsx as jsx90, jsxs as jsxs47 } from "react/jsx-runtime";
28278
28331
  var RadioGroup = function({
28279
28332
  onChange,
@@ -28284,7 +28337,7 @@ var RadioGroup = function({
28284
28337
  return /* @__PURE__ */ jsx90("div", { className: "RadioGroup", children: choices.map((choice) => /* @__PURE__ */ jsxs47(
28285
28338
  "div",
28286
28339
  {
28287
- className: clsx41("RadioGroup__choice", {
28340
+ className: clsx42("RadioGroup__choice", {
28288
28341
  active: choice.value === value
28289
28342
  }),
28290
28343
  title: choice.ariaLabel,
@@ -28593,7 +28646,7 @@ var LiveCollaborationTrigger = ({
28593
28646
  {
28594
28647
  "data-testid": "collab-button",
28595
28648
  icon: usersIcon,
28596
- className: clsx42({
28649
+ className: clsx43({
28597
28650
  "active-collab": isCollaborating
28598
28651
  }),
28599
28652
  onSelect,
@@ -28858,7 +28911,7 @@ var MainMenu = Object.assign(
28858
28911
  var MainMenu_default = MainMenu;
28859
28912
 
28860
28913
  // components/FilledButton.tsx
28861
- import clsx43 from "clsx";
28914
+ import clsx44 from "clsx";
28862
28915
  import { forwardRef as forwardRef3, useState as useState23 } from "react";
28863
28916
  import { isPromiseLike as isPromiseLike4 } from "@excalidraw/common";
28864
28917
  import { jsx as jsx94, jsxs as jsxs51 } from "react/jsx-runtime";
@@ -28902,7 +28955,7 @@ var FilledButton = forwardRef3(
28902
28955
  return /* @__PURE__ */ jsx94(
28903
28956
  "button",
28904
28957
  {
28905
- className: clsx43(
28958
+ className: clsx44(
28906
28959
  "ExcButton",
28907
28960
  `ExcButton--color-${color}`,
28908
28961
  `ExcButton--variant-${variant}`,
@@ -29047,7 +29100,7 @@ var OverwriteConfirmDialog = Object.assign(
29047
29100
 
29048
29101
  // components/Stats/index.tsx
29049
29102
  import { round as round4 } from "@excalidraw/math";
29050
- import clsx45 from "clsx";
29103
+ import clsx46 from "clsx";
29051
29104
  import throttle2 from "lodash.throttle";
29052
29105
  import { useEffect as useEffect29, useMemo as useMemo9, useState as useState25, memo as memo2 } from "react";
29053
29106
  import { STATS_PANELS } from "@excalidraw/common";
@@ -29064,7 +29117,7 @@ import { isArrowElement as isArrowElement12, isElbowArrow as isElbowArrow9 } fro
29064
29117
  import { updateBindings as updateBindings3 } from "@excalidraw/element";
29065
29118
 
29066
29119
  // components/Stats/DragInput.tsx
29067
- import clsx44 from "clsx";
29120
+ import clsx45 from "clsx";
29068
29121
  import { useEffect as useEffect28, useRef as useRef22, useState as useState24 } from "react";
29069
29122
  import { EVENT as EVENT7, KEYS as KEYS46, cloneJSON as cloneJSON3 } from "@excalidraw/common";
29070
29123
  import { deepCopyElement as deepCopyElement4 } from "@excalidraw/element";
@@ -29323,7 +29376,7 @@ var StatsDragInput = ({
29323
29376
  return /* @__PURE__ */ jsxs54(
29324
29377
  "div",
29325
29378
  {
29326
- className: clsx44("drag-input-container", !editable && "disabled"),
29379
+ className: clsx45("drag-input-container", !editable && "disabled"),
29327
29380
  "data-testid": label,
29328
29381
  children: [
29329
29382
  /* @__PURE__ */ jsx97(
@@ -30993,7 +31046,7 @@ var StatsRow = ({
30993
31046
  }) => /* @__PURE__ */ jsx107(
30994
31047
  "div",
30995
31048
  {
30996
- className: clsx45("exc-stats__row", { "exc-stats__row--heading": heading }),
31049
+ className: clsx46("exc-stats__row", { "exc-stats__row--heading": heading }),
30997
31050
  style: {
30998
31051
  gridTemplateColumns: `repeat(${columns}, 1fr)`,
30999
31052
  ...style
@@ -31295,7 +31348,7 @@ import {
31295
31348
  } from "@excalidraw/element";
31296
31349
 
31297
31350
  // components/DialogActionButton.tsx
31298
- import clsx46 from "clsx";
31351
+ import clsx47 from "clsx";
31299
31352
  import { jsx as jsx108, jsxs as jsxs56 } from "react/jsx-runtime";
31300
31353
  var DialogActionButton = ({
31301
31354
  label,
@@ -31311,7 +31364,7 @@ var DialogActionButton = ({
31311
31364
  return /* @__PURE__ */ jsxs56(
31312
31365
  "button",
31313
31366
  {
31314
- className: clsx46("Dialog__action-button", cs, className),
31367
+ className: clsx47("Dialog__action-button", cs, className),
31315
31368
  type,
31316
31369
  "aria-label": label,
31317
31370
  onClick,
@@ -31327,7 +31380,7 @@ var DialogActionButton = ({
31327
31380
  var DialogActionButton_default = DialogActionButton;
31328
31381
 
31329
31382
  // components/TextField.tsx
31330
- import clsx48 from "clsx";
31383
+ import clsx49 from "clsx";
31331
31384
  import {
31332
31385
  forwardRef as forwardRef4,
31333
31386
  useRef as useRef23,
@@ -31337,7 +31390,7 @@ import {
31337
31390
  } from "react";
31338
31391
 
31339
31392
  // components/Button.tsx
31340
- import clsx47 from "clsx";
31393
+ import clsx48 from "clsx";
31341
31394
  import { composeEventHandlers as composeEventHandlers3 } from "@excalidraw/common";
31342
31395
  import { jsx as jsx109 } from "react/jsx-runtime";
31343
31396
  var Button = ({
@@ -31355,7 +31408,7 @@ var Button = ({
31355
31408
  onSelect();
31356
31409
  }),
31357
31410
  type,
31358
- className: clsx47("excalidraw-button", className, { selected }),
31411
+ className: clsx48("excalidraw-button", className, { selected }),
31359
31412
  ...rest,
31360
31413
  children
31361
31414
  }
@@ -31391,7 +31444,7 @@ var TextField = forwardRef4(
31391
31444
  return /* @__PURE__ */ jsxs57(
31392
31445
  "div",
31393
31446
  {
31394
- className: clsx48("ExcTextField", className, {
31447
+ className: clsx49("ExcTextField", className, {
31395
31448
  "ExcTextField--fullWidth": fullWidth,
31396
31449
  "ExcTextField--hasIcon": !!icon
31397
31450
  }),
@@ -31404,14 +31457,14 @@ var TextField = forwardRef4(
31404
31457
  /* @__PURE__ */ jsxs57(
31405
31458
  "div",
31406
31459
  {
31407
- className: clsx48("ExcTextField__input", {
31460
+ className: clsx49("ExcTextField__input", {
31408
31461
  "ExcTextField__input--readonly": readonly
31409
31462
  }),
31410
31463
  children: [
31411
31464
  /* @__PURE__ */ jsx110(
31412
31465
  "input",
31413
31466
  {
31414
- className: clsx48({
31467
+ className: clsx49({
31415
31468
  "is-redacted": "value" in rest && rest.value && isRedacted && !isTemporarilyUnredacted
31416
31469
  }),
31417
31470
  readOnly: readonly,
@@ -31600,7 +31653,7 @@ var ErrorDialog = ({
31600
31653
  };
31601
31654
 
31602
31655
  // components/GifPlaybackControls.tsx
31603
- import clsx49 from "clsx";
31656
+ import clsx50 from "clsx";
31604
31657
  import React32 from "react";
31605
31658
  import { MIME_TYPES as MIME_TYPES10, sceneCoordsToViewportCoords as sceneCoordsToViewportCoords4 } from "@excalidraw/common";
31606
31659
  import {
@@ -31948,7 +32001,7 @@ var GifPlaybackControls = ({
31948
32001
  "button",
31949
32002
  {
31950
32003
  type: "button",
31951
- className: clsx49("gif-speed-picker__speed", {
32004
+ className: clsx50("gif-speed-picker__speed", {
31952
32005
  "gif-speed-picker__speed--selected": speed === playback.speed
31953
32006
  }),
31954
32007
  onClick: () => setSpeed(speed),
@@ -32045,7 +32098,7 @@ var GifPlaybackControls = ({
32045
32098
  liveAppState.openPopup === "gifFrameGallery" && /* @__PURE__ */ jsx113(
32046
32099
  "div",
32047
32100
  {
32048
- className: clsx49("gif-frame-gallery", {
32101
+ className: clsx50("gif-frame-gallery", {
32049
32102
  "gif-frame-gallery--dragging": isGifGalleryDragging
32050
32103
  }),
32051
32104
  style: {
@@ -32095,7 +32148,7 @@ var GifPlaybackControls = ({
32095
32148
  "button",
32096
32149
  {
32097
32150
  type: "button",
32098
- className: clsx49("gif-frame-gallery__frame", {
32151
+ className: clsx50("gif-frame-gallery__frame", {
32099
32152
  "gif-frame-gallery__frame--selected": index === frameIndex
32100
32153
  }),
32101
32154
  style: {
@@ -32136,7 +32189,7 @@ var GifPlaybackControls = ({
32136
32189
 
32137
32190
  // components/HelpDialog.tsx
32138
32191
  import React33, { useMemo as useMemo10 } from "react";
32139
- import clsx50 from "clsx";
32192
+ import clsx51 from "clsx";
32140
32193
  import { isDarwin as isDarwin4, isFirefox as isFirefox4, isWindows } from "@excalidraw/common";
32141
32194
  import { KEYS as KEYS49 } from "@excalidraw/common";
32142
32195
  import { SHAPES as SHAPES3 } from "@excalidraw/element/shapes";
@@ -32388,14 +32441,14 @@ var HelpDialog = ({ onClose }) => {
32388
32441
  () => isShowAll ? /* @__PURE__ */ jsx115(
32389
32442
  "button",
32390
32443
  {
32391
- className: clsx50("toggle-button", {}),
32444
+ className: clsx51("toggle-button", {}),
32392
32445
  onClick: () => setIsShowAll(false),
32393
32446
  children: t("helpDialog.myoc.showingAll")
32394
32447
  }
32395
32448
  ) : /* @__PURE__ */ jsx115(
32396
32449
  "button",
32397
32450
  {
32398
- className: clsx50("toggle-button", {}),
32451
+ className: clsx51("toggle-button", {}),
32399
32452
  onClick: () => setIsShowAll(true),
32400
32453
  children: t("helpDialog.myoc.showingBasic")
32401
32454
  }
@@ -32909,6 +32962,204 @@ var HelpDialog = ({ onClose }) => {
32909
32962
  ) });
32910
32963
  };
32911
32964
 
32965
+ // components/HintViewer.tsx
32966
+ import { CANVAS_SEARCH_TAB as CANVAS_SEARCH_TAB2, DEFAULT_SIDEBAR as DEFAULT_SIDEBAR2 } from "@excalidraw/common";
32967
+ import {
32968
+ isArrowElement as isArrowElement14,
32969
+ isFlowchartNodeElement as isFlowchartNodeElement3,
32970
+ isImageElement as isImageElement9,
32971
+ isLinearElement as isLinearElement10,
32972
+ isLineElement as isLineElement8,
32973
+ isTextBindableContainer as isTextBindableContainer2,
32974
+ isTextElement as isTextElement16
32975
+ } from "@excalidraw/element";
32976
+ import { isNodeInFlowchart } from "@excalidraw/element";
32977
+ import { jsx as jsx116 } from "react/jsx-runtime";
32978
+ var getTaggedShortcutKey = (key) => Array.isArray(key) ? `<kbd>${key.map(getShortcutKey).join(" + ")}</kbd>` : `<kbd>${getShortcutKey(key)}</kbd>`;
32979
+ var getHints = ({
32980
+ appState,
32981
+ isMobile,
32982
+ editorInterface,
32983
+ app
32984
+ }) => {
32985
+ const { activeTool, isResizing, isRotating, lastPointerDownWith } = appState;
32986
+ const multiMode = appState.multiElement !== null;
32987
+ if (appState.openSidebar?.name === DEFAULT_SIDEBAR2.name && appState.openSidebar.tab === CANVAS_SEARCH_TAB2 && appState.searchMatches?.matches.length) {
32988
+ return t("hints.dismissSearch", {
32989
+ shortcut: getTaggedShortcutKey("Escape")
32990
+ });
32991
+ }
32992
+ if (appState.openSidebar && !editorInterface.canFitSidebar) {
32993
+ return null;
32994
+ }
32995
+ if (isEraserActive(appState)) {
32996
+ return t("hints.eraserRevert", {
32997
+ shortcut: getTaggedShortcutKey("Alt")
32998
+ });
32999
+ }
33000
+ const selectedElements = app.scene.getSelectedElements(appState);
33001
+ if (appState.selectedLinearElement?.isDragging && selectedElements[0]?.type === "arrow") {
33002
+ return t("hints.arrowBindModifiers", {
33003
+ shortcut_1: getTaggedShortcutKey("Ctrl"),
33004
+ shortcut_2: getTaggedShortcutKey("Alt")
33005
+ });
33006
+ }
33007
+ if (activeTool.type === "arrow" || activeTool.type === "line") {
33008
+ if (multiMode) {
33009
+ return t("hints.linearElementMulti", {
33010
+ shortcut_1: getTaggedShortcutKey("Escape"),
33011
+ shortcut_2: getTaggedShortcutKey("Enter")
33012
+ });
33013
+ }
33014
+ if (activeTool.type === "arrow") {
33015
+ return t("hints.arrowTool", {
33016
+ shortcut: getTaggedShortcutKey("A")
33017
+ });
33018
+ }
33019
+ return t("hints.linearElement");
33020
+ }
33021
+ if (activeTool.type === "freedraw") {
33022
+ return t("hints.freeDraw");
33023
+ }
33024
+ if (activeTool.type === "text") {
33025
+ return t("hints.text");
33026
+ }
33027
+ if (activeTool.type === "embeddable") {
33028
+ return t("hints.embeddable");
33029
+ }
33030
+ if (activeTool.type === "autoshape") {
33031
+ return t("hints.autoshape");
33032
+ }
33033
+ if (isResizing && lastPointerDownWith === "mouse" && selectedElements.length === 1) {
33034
+ const targetElement = selectedElements[0];
33035
+ if (isLinearElement10(targetElement) && targetElement.points.length === 2) {
33036
+ return t("hints.lockAngle", {
33037
+ shortcut: getTaggedShortcutKey("Shift")
33038
+ });
33039
+ }
33040
+ return isImageElement9(targetElement) ? t("hints.resizeImage", {
33041
+ shortcut_1: getTaggedShortcutKey("Shift"),
33042
+ shortcut_2: getTaggedShortcutKey("Alt")
33043
+ }) : t("hints.resize", {
33044
+ shortcut_1: getTaggedShortcutKey("Shift"),
33045
+ shortcut_2: getTaggedShortcutKey("Alt")
33046
+ });
33047
+ }
33048
+ if (isRotating && lastPointerDownWith === "mouse") {
33049
+ return t("hints.rotate", {
33050
+ shortcut: getTaggedShortcutKey("Shift")
33051
+ });
33052
+ }
33053
+ if (selectedElements.length === 1 && isTextElement16(selectedElements[0])) {
33054
+ return t("hints.text_selected", {
33055
+ shortcut: getTaggedShortcutKey("Enter")
33056
+ });
33057
+ }
33058
+ if (appState.editingTextElement) {
33059
+ return t("hints.text_editing", {
33060
+ shortcut_1: getTaggedShortcutKey("Escape"),
33061
+ shortcut_2: getTaggedShortcutKey(["CtrlOrCmd", "Enter"])
33062
+ });
33063
+ }
33064
+ if (appState.croppingElementId) {
33065
+ return t("hints.leaveCropEditor", {
33066
+ shortcut_1: getTaggedShortcutKey("Enter"),
33067
+ shortcut_2: getTaggedShortcutKey("Escape")
33068
+ });
33069
+ }
33070
+ if (selectedElements.length === 1 && isImageElement9(selectedElements[0])) {
33071
+ return t("hints.enterCropEditor", {
33072
+ shortcut_1: getTaggedShortcutKey("double click"),
33073
+ shortcut_2: getTaggedShortcutKey("Enter")
33074
+ });
33075
+ }
33076
+ if (activeTool.type === "selection") {
33077
+ if (appState.selectionElement && !selectedElements.length && !appState.editingTextElement && !appState.selectedLinearElement?.isEditing) {
33078
+ return t("hints.deepBoxSelect", {
33079
+ shortcut: getTaggedShortcutKey("CtrlOrCmd")
33080
+ });
33081
+ }
33082
+ if (isGridModeEnabled(app) && appState.selectedElementsAreBeingDragged) {
33083
+ return t("hints.disableSnapping", {
33084
+ shortcut: getTaggedShortcutKey("CtrlOrCmd")
33085
+ });
33086
+ }
33087
+ if (!selectedElements.length && !isMobile) {
33088
+ return t("hints.canvasPanning", {
33089
+ shortcut_1: getTaggedShortcutKey(t("keys.mmb")),
33090
+ shortcut_2: getTaggedShortcutKey("Space")
33091
+ });
33092
+ }
33093
+ if (selectedElements.length === 1) {
33094
+ if (isLinearElement10(selectedElements[0])) {
33095
+ if (isArrowElement14(selectedElements[0]) && appState.selectedLinearElement?.elementId === selectedElements[0].id && (appState.selectedLinearElement.hoverPointIndex === 0 || appState.selectedLinearElement.hoverPointIndex === selectedElements[0].points.length - 1)) {
33096
+ return t("hints.toggleArrowhead");
33097
+ }
33098
+ if (appState.selectedLinearElement?.isEditing) {
33099
+ return appState.selectedLinearElement.selectedPointsIndices ? t("hints.lineEditor_pointSelected", {
33100
+ shortcut_1: getTaggedShortcutKey("Delete"),
33101
+ shortcut_2: getTaggedShortcutKey(["CtrlOrCmd", "D"])
33102
+ }) : t("hints.lineEditor_nothingSelected", {
33103
+ shortcut_1: getTaggedShortcutKey("Shift"),
33104
+ shortcut_2: getTaggedShortcutKey("Alt")
33105
+ });
33106
+ }
33107
+ return isLineElement8(selectedElements[0]) ? t("hints.lineEditor_line_info", {
33108
+ shortcut: getTaggedShortcutKey("Enter")
33109
+ }) : t("hints.lineEditor_info", {
33110
+ shortcut_1: getTaggedShortcutKey("CtrlOrCmd"),
33111
+ shortcut_2: getTaggedShortcutKey(["CtrlOrCmd", "Enter"])
33112
+ });
33113
+ }
33114
+ if (!appState.newElement && !appState.selectedElementsAreBeingDragged && isTextBindableContainer2(selectedElements[0])) {
33115
+ const bindTextToElement = t("hints.bindTextToElement", {
33116
+ shortcut: getTaggedShortcutKey("Enter")
33117
+ });
33118
+ const createFlowchart = t("hints.createFlowchart", {
33119
+ shortcut: getTaggedShortcutKey(["CtrlOrCmd", "\u2191\u2193"])
33120
+ });
33121
+ if (isFlowchartNodeElement3(selectedElements[0])) {
33122
+ if (isNodeInFlowchart(
33123
+ selectedElements[0],
33124
+ app.scene.getNonDeletedElementsMap()
33125
+ )) {
33126
+ return [bindTextToElement, createFlowchart];
33127
+ }
33128
+ return [bindTextToElement, createFlowchart];
33129
+ }
33130
+ return bindTextToElement;
33131
+ }
33132
+ }
33133
+ }
33134
+ return null;
33135
+ };
33136
+ var HintViewer = ({
33137
+ appState,
33138
+ isMobile,
33139
+ editorInterface,
33140
+ app
33141
+ }) => {
33142
+ const smartZoomKeyHeld = useAtomValue(smartZoomKeyHeldAtom);
33143
+ const hints = smartZoomKeyHeld ? SMART_ZOOM_KEY_HINT : appState.viewModeEnabled ? null : getHints({
33144
+ appState,
33145
+ isMobile,
33146
+ editorInterface,
33147
+ app
33148
+ });
33149
+ if (!hints) {
33150
+ return null;
33151
+ }
33152
+ const hint = Array.isArray(hints) ? hints.map((hint2) => hint2.replace(/\. ?$/, "")).join(", ") : hints;
33153
+ const hintJSX = hint.split(/(<kbd>[^<]+<\/kbd>)/g).map((part, index) => {
33154
+ if (index % 2 === 1) {
33155
+ const shortcutMatch = part[0] === "<" && part.match(/^<kbd>([^<]+)<\/kbd>$/);
33156
+ return /* @__PURE__ */ jsx116("kbd", { children: shortcutMatch ? shortcutMatch[1] : part }, index);
33157
+ }
33158
+ return part;
33159
+ });
33160
+ return /* @__PURE__ */ jsx116("div", { className: "HintViewer", children: /* @__PURE__ */ jsx116("span", { children: hintJSX }) });
33161
+ };
33162
+
32912
33163
  // components/ImageExportDialog.tsx
32913
33164
  import { useEffect as useEffect31, useRef as useRef25, useState as useState30 } from "react";
32914
33165
  import {
@@ -32943,11 +33194,11 @@ var useCopyStatus = () => {
32943
33194
  };
32944
33195
 
32945
33196
  // components/ImageExportDialog.tsx
32946
- import { jsx as jsx116, jsxs as jsxs62 } from "react/jsx-runtime";
33197
+ import { jsx as jsx117, jsxs as jsxs62 } from "react/jsx-runtime";
32947
33198
  var ErrorCanvasPreview = () => {
32948
33199
  return /* @__PURE__ */ jsxs62("div", { children: [
32949
- /* @__PURE__ */ jsx116("h3", { children: t("canvasError.cannotShowPreview") }),
32950
- /* @__PURE__ */ jsx116("p", { children: /* @__PURE__ */ jsx116("span", { children: t("canvasError.canvasTooBig") }) }),
33200
+ /* @__PURE__ */ jsx117("h3", { children: t("canvasError.cannotShowPreview") }),
33201
+ /* @__PURE__ */ jsx117("p", { children: /* @__PURE__ */ jsx117("span", { children: t("canvasError.canvasTooBig") }) }),
32951
33202
  /* @__PURE__ */ jsxs62("em", { children: [
32952
33203
  "(",
32953
33204
  t("canvasError.canvasTooBigTip"),
@@ -33063,10 +33314,10 @@ var ImageExportModal = ({
33063
33314
  embedScene
33064
33315
  ]);
33065
33316
  return /* @__PURE__ */ jsxs62("div", { className: "ImageExportModal", children: [
33066
- /* @__PURE__ */ jsx116("h3", { children: t("imageExportDialog.header") }),
33317
+ /* @__PURE__ */ jsx117("h3", { children: t("imageExportDialog.header") }),
33067
33318
  /* @__PURE__ */ jsxs62("div", { className: "ImageExportModal__preview", children: [
33068
- /* @__PURE__ */ jsx116("div", { className: "ImageExportModal__preview__canvas", ref: previewRef, children: renderError && /* @__PURE__ */ jsx116(ErrorCanvasPreview, {}) }),
33069
- /* @__PURE__ */ jsx116("div", { className: "ImageExportModal__preview__filename", children: !nativeFileSystemSupported && /* @__PURE__ */ jsx116(
33319
+ /* @__PURE__ */ jsx117("div", { className: "ImageExportModal__preview__canvas", ref: previewRef, children: renderError && /* @__PURE__ */ jsx117(ErrorCanvasPreview, {}) }),
33320
+ /* @__PURE__ */ jsx117("div", { className: "ImageExportModal__preview__filename", children: !nativeFileSystemSupported && /* @__PURE__ */ jsx117(
33070
33321
  "input",
33071
33322
  {
33072
33323
  type: "text",
@@ -33085,13 +33336,13 @@ var ImageExportModal = ({
33085
33336
  ) })
33086
33337
  ] }),
33087
33338
  /* @__PURE__ */ jsxs62("div", { className: "ImageExportModal__settings", children: [
33088
- /* @__PURE__ */ jsx116("h3", { children: t("imageExportDialog.header") }),
33089
- hasSelection && /* @__PURE__ */ jsx116(
33339
+ /* @__PURE__ */ jsx117("h3", { children: t("imageExportDialog.header") }),
33340
+ hasSelection && /* @__PURE__ */ jsx117(
33090
33341
  ExportSetting,
33091
33342
  {
33092
33343
  label: t("imageExportDialog.label.onlySelected"),
33093
33344
  name: "exportOnlySelected",
33094
- children: /* @__PURE__ */ jsx116(
33345
+ children: /* @__PURE__ */ jsx117(
33095
33346
  Switch,
33096
33347
  {
33097
33348
  name: "exportOnlySelected",
@@ -33103,12 +33354,12 @@ var ImageExportModal = ({
33103
33354
  )
33104
33355
  }
33105
33356
  ),
33106
- /* @__PURE__ */ jsx116(
33357
+ /* @__PURE__ */ jsx117(
33107
33358
  ExportSetting,
33108
33359
  {
33109
33360
  label: t("imageExportDialog.label.withBackground"),
33110
33361
  name: "exportBackgroundSwitch",
33111
- children: /* @__PURE__ */ jsx116(
33362
+ children: /* @__PURE__ */ jsx117(
33112
33363
  Switch,
33113
33364
  {
33114
33365
  name: "exportBackgroundSwitch",
@@ -33125,12 +33376,12 @@ var ImageExportModal = ({
33125
33376
  )
33126
33377
  }
33127
33378
  ),
33128
- /* @__PURE__ */ jsx116(
33379
+ /* @__PURE__ */ jsx117(
33129
33380
  ExportSetting,
33130
33381
  {
33131
33382
  label: t("imageExportDialog.label.darkMode"),
33132
33383
  name: "exportDarkModeSwitch",
33133
- children: /* @__PURE__ */ jsx116(
33384
+ children: /* @__PURE__ */ jsx117(
33134
33385
  Switch,
33135
33386
  {
33136
33387
  name: "exportDarkModeSwitch",
@@ -33146,13 +33397,13 @@ var ImageExportModal = ({
33146
33397
  )
33147
33398
  }
33148
33399
  ),
33149
- /* @__PURE__ */ jsx116(
33400
+ /* @__PURE__ */ jsx117(
33150
33401
  ExportSetting,
33151
33402
  {
33152
33403
  label: t("imageExportDialog.label.embedScene"),
33153
33404
  tooltip: t("imageExportDialog.tooltip.embedScene"),
33154
33405
  name: "exportEmbedSwitch",
33155
- children: /* @__PURE__ */ jsx116(
33406
+ children: /* @__PURE__ */ jsx117(
33156
33407
  Switch,
33157
33408
  {
33158
33409
  name: "exportEmbedSwitch",
@@ -33169,12 +33420,12 @@ var ImageExportModal = ({
33169
33420
  )
33170
33421
  }
33171
33422
  ),
33172
- /* @__PURE__ */ jsx116(
33423
+ /* @__PURE__ */ jsx117(
33173
33424
  ExportSetting,
33174
33425
  {
33175
33426
  label: t("imageExportDialog.label.scale"),
33176
33427
  name: "exportScale",
33177
- children: /* @__PURE__ */ jsx116(
33428
+ children: /* @__PURE__ */ jsx117(
33178
33429
  RadioGroup,
33179
33430
  {
33180
33431
  name: "exportScale",
@@ -33192,7 +33443,7 @@ var ImageExportModal = ({
33192
33443
  }
33193
33444
  ),
33194
33445
  /* @__PURE__ */ jsxs62("div", { className: "ImageExportModal__settings__buttons", children: [
33195
- /* @__PURE__ */ jsx116(
33446
+ /* @__PURE__ */ jsx117(
33196
33447
  FilledButton,
33197
33448
  {
33198
33449
  className: "ImageExportModal__settings__buttons__button",
@@ -33204,7 +33455,7 @@ var ImageExportModal = ({
33204
33455
  children: t("imageExportDialog.button.exportToPng")
33205
33456
  }
33206
33457
  ),
33207
- /* @__PURE__ */ jsx116(
33458
+ /* @__PURE__ */ jsx117(
33208
33459
  FilledButton,
33209
33460
  {
33210
33461
  className: "ImageExportModal__settings__buttons__button",
@@ -33216,7 +33467,7 @@ var ImageExportModal = ({
33216
33467
  children: t("imageExportDialog.button.exportToSvg")
33217
33468
  }
33218
33469
  ),
33219
- (probablySupportsClipboardBlob || isFirefox5) && /* @__PURE__ */ jsx116(
33470
+ (probablySupportsClipboardBlob || isFirefox5) && /* @__PURE__ */ jsx117(
33220
33471
  FilledButton,
33221
33472
  {
33222
33473
  className: "ImageExportModal__settings__buttons__button",
@@ -33254,11 +33505,11 @@ var ExportSetting = ({
33254
33505
  className: "ImageExportModal__settings__setting__label",
33255
33506
  children: [
33256
33507
  label,
33257
- tooltip && /* @__PURE__ */ jsx116(Tooltip, { label: tooltip, long: true, children: helpIcon })
33508
+ tooltip && /* @__PURE__ */ jsx117(Tooltip, { label: tooltip, long: true, children: helpIcon })
33258
33509
  ]
33259
33510
  }
33260
33511
  ),
33261
- /* @__PURE__ */ jsx116("div", { className: "ImageExportModal__settings__setting__content", children })
33512
+ /* @__PURE__ */ jsx117("div", { className: "ImageExportModal__settings__setting__content", children })
33262
33513
  ] });
33263
33514
  };
33264
33515
  var ImageExportDialog = ({
@@ -33276,7 +33527,7 @@ var ImageExportDialog = ({
33276
33527
  elementsSnapshot: cloneJSON4(elements)
33277
33528
  };
33278
33529
  });
33279
- return /* @__PURE__ */ jsx116(Dialog, { onCloseRequest, size: "wide", title: false, children: /* @__PURE__ */ jsx116(
33530
+ return /* @__PURE__ */ jsx117(Dialog, { onCloseRequest, size: "wide", title: false, children: /* @__PURE__ */ jsx117(
33280
33531
  ImageExportModal,
33281
33532
  {
33282
33533
  elementsSnapshot,
@@ -33291,11 +33542,11 @@ var ImageExportDialog = ({
33291
33542
  };
33292
33543
 
33293
33544
  // components/DefaultSidebar.tsx
33294
- import clsx55 from "clsx";
33295
- import { CANVAS_SEARCH_TAB as CANVAS_SEARCH_TAB2, DEFAULT_SIDEBAR as DEFAULT_SIDEBAR2 } from "@excalidraw/common";
33545
+ import clsx56 from "clsx";
33546
+ import { CANVAS_SEARCH_TAB as CANVAS_SEARCH_TAB3, DEFAULT_SIDEBAR as DEFAULT_SIDEBAR3 } from "@excalidraw/common";
33296
33547
 
33297
33548
  // components/SearchMenu.tsx
33298
- import clsx51 from "clsx";
33549
+ import clsx52 from "clsx";
33299
33550
  import debounce3 from "lodash.debounce";
33300
33551
  import { Fragment as Fragment21, memo as memo3, useEffect as useEffect32, useMemo as useMemo11, useRef as useRef26, useState as useState31 } from "react";
33301
33552
  import {
@@ -33317,9 +33568,9 @@ import {
33317
33568
  getFontString as getFontString15
33318
33569
  } from "@excalidraw/common";
33319
33570
  import { newTextElement as newTextElement5 } from "@excalidraw/element";
33320
- import { isTextElement as isTextElement16, isFrameLikeElement as isFrameLikeElement16 } from "@excalidraw/element";
33571
+ import { isTextElement as isTextElement17, isFrameLikeElement as isFrameLikeElement16 } from "@excalidraw/element";
33321
33572
  import { getDefaultFrameName } from "@excalidraw/element/frame";
33322
- import { Fragment as Fragment22, jsx as jsx117, jsxs as jsxs63 } from "react/jsx-runtime";
33573
+ import { Fragment as Fragment22, jsx as jsx118, jsxs as jsxs63 } from "react/jsx-runtime";
33323
33574
  var searchQueryAtom = atom("");
33324
33575
  var searchItemInFocusAtom = atom(null);
33325
33576
  var SEARCH_DEBOUNCE = 350;
@@ -33519,7 +33770,7 @@ var SearchMenu2 = () => {
33519
33770
  const matchCount = `${searchMatches.items.length} ${searchMatches.items.length === 1 ? t("search.singleResult") : t("search.multipleResults")}`;
33520
33771
  return /* @__PURE__ */ jsxs63("div", { className: "layer-ui__search", children: [
33521
33772
  /* @__PURE__ */ jsxs63("div", { className: "layer-ui__search-header", children: [
33522
- /* @__PURE__ */ jsx117(
33773
+ /* @__PURE__ */ jsx118(
33523
33774
  TextField,
33524
33775
  {
33525
33776
  className: CLASSES7.SEARCH_MENU_INPUT_WRAPPER,
@@ -33555,7 +33806,7 @@ var SearchMenu2 = () => {
33555
33806
  selectOnRender: true
33556
33807
  }
33557
33808
  ),
33558
- /* @__PURE__ */ jsx117(
33809
+ /* @__PURE__ */ jsx118(
33559
33810
  Button,
33560
33811
  {
33561
33812
  "data-testid": "sidebar-close",
@@ -33576,9 +33827,9 @@ var SearchMenu2 = () => {
33576
33827
  focusIndex + 1,
33577
33828
  " / ",
33578
33829
  matchCount
33579
- ] }) : /* @__PURE__ */ jsx117("div", { children: matchCount }),
33830
+ ] }) : /* @__PURE__ */ jsx118("div", { children: matchCount }),
33580
33831
  /* @__PURE__ */ jsxs63("div", { className: "result-nav", children: [
33581
- /* @__PURE__ */ jsx117(
33832
+ /* @__PURE__ */ jsx118(
33582
33833
  Button,
33583
33834
  {
33584
33835
  onSelect: () => {
@@ -33588,7 +33839,7 @@ var SearchMenu2 = () => {
33588
33839
  children: collapseDownIcon
33589
33840
  }
33590
33841
  ),
33591
- /* @__PURE__ */ jsx117(
33842
+ /* @__PURE__ */ jsx118(
33592
33843
  Button,
33593
33844
  {
33594
33845
  onSelect: () => {
@@ -33600,9 +33851,9 @@ var SearchMenu2 = () => {
33600
33851
  )
33601
33852
  ] })
33602
33853
  ] }),
33603
- searchMatches.items.length === 0 && searchQuery && searchedQueryRef.current && /* @__PURE__ */ jsx117("div", { style: { margin: "1rem auto" }, children: t("search.noMatch") })
33854
+ searchMatches.items.length === 0 && searchQuery && searchedQueryRef.current && /* @__PURE__ */ jsx118("div", { style: { margin: "1rem auto" }, children: t("search.noMatch") })
33604
33855
  ] }),
33605
- /* @__PURE__ */ jsx117(
33856
+ /* @__PURE__ */ jsx118(
33606
33857
  MatchList,
33607
33858
  {
33608
33859
  matches: searchMatches,
@@ -33626,11 +33877,11 @@ var ListItem = (props) => {
33626
33877
  ),
33627
33878
  props.preview.moreAfter ? "..." : ""
33628
33879
  ];
33629
- return /* @__PURE__ */ jsx117(
33880
+ return /* @__PURE__ */ jsx118(
33630
33881
  "div",
33631
33882
  {
33632
33883
  tabIndex: -1,
33633
- className: clsx51("layer-ui__result-item", {
33884
+ className: clsx52("layer-ui__result-item", {
33634
33885
  active: props.highlighted
33635
33886
  }),
33636
33887
  onClick: props.onClick,
@@ -33639,7 +33890,7 @@ var ListItem = (props) => {
33639
33890
  ref?.scrollIntoView({ behavior: "auto", block: "nearest" });
33640
33891
  }
33641
33892
  },
33642
- children: /* @__PURE__ */ jsx117("div", { className: "preview-text", children: preview.flatMap((text, idx) => /* @__PURE__ */ jsx117(Fragment21, { children: idx === 2 ? /* @__PURE__ */ jsx117("b", { children: text }) : text }, idx)) })
33893
+ children: /* @__PURE__ */ jsx118("div", { className: "preview-text", children: preview.flatMap((text, idx) => /* @__PURE__ */ jsx118(Fragment21, { children: idx === 2 ? /* @__PURE__ */ jsx118("b", { children: text }) : text }, idx)) })
33643
33894
  }
33644
33895
  );
33645
33896
  };
@@ -33649,16 +33900,16 @@ var MatchListBase = (props) => {
33649
33900
  [props.matches]
33650
33901
  );
33651
33902
  const textMatches = useMemo11(
33652
- () => props.matches.items.filter((match) => isTextElement16(match.element)),
33903
+ () => props.matches.items.filter((match) => isTextElement17(match.element)),
33653
33904
  [props.matches]
33654
33905
  );
33655
33906
  return /* @__PURE__ */ jsxs63("div", { className: "layer-ui__search-results", children: [
33656
33907
  frameNameMatches.length > 0 && /* @__PURE__ */ jsxs63("div", { className: "layer-ui__search-result-container", children: [
33657
33908
  /* @__PURE__ */ jsxs63("div", { className: "layer-ui__search-result-title", children: [
33658
- /* @__PURE__ */ jsx117("div", { className: "title-icon", children: frameToolIcon }),
33659
- /* @__PURE__ */ jsx117("div", { children: t("search.frames") })
33909
+ /* @__PURE__ */ jsx118("div", { className: "title-icon", children: frameToolIcon }),
33910
+ /* @__PURE__ */ jsx118("div", { children: t("search.frames") })
33660
33911
  ] }),
33661
- frameNameMatches.map((searchMatch, index) => /* @__PURE__ */ jsx117(
33912
+ frameNameMatches.map((searchMatch, index) => /* @__PURE__ */ jsx118(
33662
33913
  ListItem,
33663
33914
  {
33664
33915
  searchQuery: props.searchQuery,
@@ -33668,14 +33919,14 @@ var MatchListBase = (props) => {
33668
33919
  },
33669
33920
  searchMatch.element.id + searchMatch.index
33670
33921
  )),
33671
- textMatches.length > 0 && /* @__PURE__ */ jsx117("div", { className: "layer-ui__divider" })
33922
+ textMatches.length > 0 && /* @__PURE__ */ jsx118("div", { className: "layer-ui__divider" })
33672
33923
  ] }),
33673
33924
  textMatches.length > 0 && /* @__PURE__ */ jsxs63("div", { className: "layer-ui__search-result-container", children: [
33674
33925
  /* @__PURE__ */ jsxs63("div", { className: "layer-ui__search-result-title", children: [
33675
- /* @__PURE__ */ jsx117("div", { className: "title-icon", children: TextIcon }),
33676
- /* @__PURE__ */ jsx117("div", { children: t("search.texts") })
33926
+ /* @__PURE__ */ jsx118("div", { className: "title-icon", children: TextIcon }),
33927
+ /* @__PURE__ */ jsx118("div", { children: t("search.texts") })
33677
33928
  ] }),
33678
- textMatches.map((searchMatch, index) => /* @__PURE__ */ jsx117(
33929
+ textMatches.map((searchMatch, index) => /* @__PURE__ */ jsx118(
33679
33930
  ListItem,
33680
33931
  {
33681
33932
  searchQuery: props.searchQuery,
@@ -33852,7 +34103,7 @@ var handleSearch = debounce3(
33852
34103
  }
33853
34104
  const elements = app.scene.getNonDeletedElements();
33854
34105
  const texts = elements.filter(
33855
- (el) => isTextElement16(el)
34106
+ (el) => isTextElement17(el)
33856
34107
  );
33857
34108
  const frames2 = elements.filter(
33858
34109
  (el) => isFrameLikeElement16(el)
@@ -33914,7 +34165,7 @@ var handleSearch = debounce3(
33914
34165
  );
33915
34166
 
33916
34167
  // components/Sidebar/Sidebar.tsx
33917
- import clsx54 from "clsx";
34168
+ import clsx55 from "clsx";
33918
34169
  import {
33919
34170
  useEffect as useEffect33,
33920
34171
  useLayoutEffect as useLayoutEffect9,
@@ -33933,7 +34184,7 @@ import {
33933
34184
  } from "@excalidraw/common";
33934
34185
 
33935
34186
  // components/Sidebar/SidebarHeader.tsx
33936
- import clsx52 from "clsx";
34187
+ import clsx53 from "clsx";
33937
34188
  import { useContext as useContext3 } from "react";
33938
34189
 
33939
34190
  // components/Sidebar/common.ts
@@ -33941,7 +34192,7 @@ import React35 from "react";
33941
34192
  var SidebarPropsContext = React35.createContext({});
33942
34193
 
33943
34194
  // components/Sidebar/SidebarHeader.tsx
33944
- import { jsx as jsx118, jsxs as jsxs64 } from "react/jsx-runtime";
34195
+ import { jsx as jsx119, jsxs as jsxs64 } from "react/jsx-runtime";
33945
34196
  var SidebarHeader = ({
33946
34197
  children,
33947
34198
  className
@@ -33952,12 +34203,12 @@ var SidebarHeader = ({
33952
34203
  return /* @__PURE__ */ jsxs64(
33953
34204
  "div",
33954
34205
  {
33955
- className: clsx52("sidebar__header", className),
34206
+ className: clsx53("sidebar__header", className),
33956
34207
  "data-testid": "sidebar-header",
33957
34208
  children: [
33958
34209
  children,
33959
34210
  /* @__PURE__ */ jsxs64("div", { className: "sidebar__header__buttons", children: [
33960
- renderDockButton && /* @__PURE__ */ jsx118(Tooltip, { label: t("labels.sidebarLock"), children: /* @__PURE__ */ jsx118(
34211
+ renderDockButton && /* @__PURE__ */ jsx119(Tooltip, { label: t("labels.sidebarLock"), children: /* @__PURE__ */ jsx119(
33961
34212
  Button,
33962
34213
  {
33963
34214
  onSelect: () => props.onDock?.(!props.docked),
@@ -33968,7 +34219,7 @@ var SidebarHeader = ({
33968
34219
  children: PinIcon
33969
34220
  }
33970
34221
  ) }),
33971
- /* @__PURE__ */ jsx118(
34222
+ /* @__PURE__ */ jsx119(
33972
34223
  Button,
33973
34224
  {
33974
34225
  "data-testid": "sidebar-close",
@@ -33987,14 +34238,14 @@ SidebarHeader.displayName = "SidebarHeader";
33987
34238
 
33988
34239
  // components/Sidebar/SidebarTabTrigger.tsx
33989
34240
  import { Tabs as RadixTabs } from "radix-ui";
33990
- import { jsx as jsx119 } from "react/jsx-runtime";
34241
+ import { jsx as jsx120 } from "react/jsx-runtime";
33991
34242
  var SidebarTabTrigger = ({
33992
34243
  children,
33993
34244
  tab,
33994
34245
  onSelect,
33995
34246
  ...rest
33996
34247
  }) => {
33997
- return /* @__PURE__ */ jsx119(RadixTabs.Trigger, { value: tab, asChild: true, onSelect, children: /* @__PURE__ */ jsx119(
34248
+ return /* @__PURE__ */ jsx120(RadixTabs.Trigger, { value: tab, asChild: true, onSelect, children: /* @__PURE__ */ jsx120(
33998
34249
  "button",
33999
34250
  {
34000
34251
  type: "button",
@@ -34008,18 +34259,18 @@ SidebarTabTrigger.displayName = "SidebarTabTrigger";
34008
34259
 
34009
34260
  // components/Sidebar/SidebarTabTriggers.tsx
34010
34261
  import { Tabs as RadixTabs2 } from "radix-ui";
34011
- import { jsx as jsx120 } from "react/jsx-runtime";
34262
+ import { jsx as jsx121 } from "react/jsx-runtime";
34012
34263
  var SidebarTabTriggers = ({
34013
34264
  children,
34014
34265
  ...rest
34015
34266
  }) => {
34016
- return /* @__PURE__ */ jsx120(RadixTabs2.List, { className: "sidebar-triggers", ...rest, children });
34267
+ return /* @__PURE__ */ jsx121(RadixTabs2.List, { className: "sidebar-triggers", ...rest, children });
34017
34268
  };
34018
34269
  SidebarTabTriggers.displayName = "SidebarTabTriggers";
34019
34270
 
34020
34271
  // components/Sidebar/SidebarTrigger.tsx
34021
- import clsx53 from "clsx";
34022
- import { jsx as jsx121, jsxs as jsxs65 } from "react/jsx-runtime";
34272
+ import clsx54 from "clsx";
34273
+ import { jsx as jsx122, jsxs as jsxs65 } from "react/jsx-runtime";
34023
34274
  var SidebarTrigger = ({
34024
34275
  name,
34025
34276
  tab,
@@ -34033,7 +34284,7 @@ var SidebarTrigger = ({
34033
34284
  const setAppState = useExcalidrawSetAppState();
34034
34285
  const appState = useUIAppState();
34035
34286
  const isOpen = appState.openSidebar?.name === name;
34036
- return /* @__PURE__ */ jsx121(
34287
+ return /* @__PURE__ */ jsx122(
34037
34288
  "button",
34038
34289
  {
34039
34290
  type: "button",
@@ -34052,9 +34303,9 @@ var SidebarTrigger = ({
34052
34303
  });
34053
34304
  onToggle?.(nextOpen);
34054
34305
  },
34055
- children: /* @__PURE__ */ jsxs65("div", { className: clsx53("sidebar-trigger", className), style, children: [
34056
- icon && /* @__PURE__ */ jsx121("div", { children: icon }),
34057
- children && /* @__PURE__ */ jsx121("div", { className: "sidebar-trigger__label", children })
34306
+ children: /* @__PURE__ */ jsxs65("div", { className: clsx54("sidebar-trigger", className), style, children: [
34307
+ icon && /* @__PURE__ */ jsx122("div", { children: icon }),
34308
+ children && /* @__PURE__ */ jsx122("div", { className: "sidebar-trigger__label", children })
34058
34309
  ] })
34059
34310
  }
34060
34311
  );
@@ -34063,7 +34314,7 @@ SidebarTrigger.displayName = "SidebarTrigger";
34063
34314
 
34064
34315
  // components/Sidebar/SidebarTabs.tsx
34065
34316
  import { Tabs as RadixTabs3 } from "radix-ui";
34066
- import { jsx as jsx122 } from "react/jsx-runtime";
34317
+ import { jsx as jsx123 } from "react/jsx-runtime";
34067
34318
  var SidebarTabs = ({
34068
34319
  children,
34069
34320
  ...rest
@@ -34074,7 +34325,7 @@ var SidebarTabs = ({
34074
34325
  return null;
34075
34326
  }
34076
34327
  const { name } = appState.openSidebar;
34077
- return /* @__PURE__ */ jsx122(
34328
+ return /* @__PURE__ */ jsx123(
34078
34329
  RadixTabs3.Root,
34079
34330
  {
34080
34331
  className: "sidebar-tabs-root",
@@ -34092,18 +34343,18 @@ SidebarTabs.displayName = "SidebarTabs";
34092
34343
 
34093
34344
  // components/Sidebar/SidebarTab.tsx
34094
34345
  import { Tabs as RadixTabs4 } from "radix-ui";
34095
- import { jsx as jsx123 } from "react/jsx-runtime";
34346
+ import { jsx as jsx124 } from "react/jsx-runtime";
34096
34347
  var SidebarTab = ({
34097
34348
  tab,
34098
34349
  children,
34099
34350
  ...rest
34100
34351
  }) => {
34101
- return /* @__PURE__ */ jsx123(RadixTabs4.Content, { ...rest, value: tab, "data-testid": tab, children });
34352
+ return /* @__PURE__ */ jsx124(RadixTabs4.Content, { ...rest, value: tab, "data-testid": tab, children });
34102
34353
  };
34103
34354
  SidebarTab.displayName = "SidebarTab";
34104
34355
 
34105
34356
  // components/Sidebar/Sidebar.tsx
34106
- import { jsx as jsx124 } from "react/jsx-runtime";
34357
+ import { jsx as jsx125 } from "react/jsx-runtime";
34107
34358
  import { createElement } from "react";
34108
34359
  var isSidebarDockedAtom = atom(false);
34109
34360
  var SidebarInner = forwardRef5(
@@ -34177,11 +34428,11 @@ var SidebarInner = forwardRef5(
34177
34428
  document.removeEventListener(EVENT9.KEYDOWN, handleKeyDown);
34178
34429
  };
34179
34430
  }, [closeSidebar, docked, editorInterface.canFitSidebar]);
34180
- return /* @__PURE__ */ jsx124(
34431
+ return /* @__PURE__ */ jsx125(
34181
34432
  Island,
34182
34433
  {
34183
34434
  ...rest,
34184
- className: clsx54(
34435
+ className: clsx55(
34185
34436
  CLASSES8.SIDEBAR,
34186
34437
  { "sidebar--docked": docked },
34187
34438
  className
@@ -34189,7 +34440,7 @@ var SidebarInner = forwardRef5(
34189
34440
  "data-viewport-ui": editorInterface.formFactor !== "phone" ? "side" : void 0,
34190
34441
  "data-viewport-ui-name": editorInterface.formFactor !== "phone" ? "sidebar" : void 0,
34191
34442
  ref: islandRef,
34192
- children: /* @__PURE__ */ jsx124(SidebarPropsContext.Provider, { value: headerPropsRef.current, children })
34443
+ children: /* @__PURE__ */ jsx125(SidebarPropsContext.Provider, { value: headerPropsRef.current, children })
34193
34444
  }
34194
34445
  );
34195
34446
  }
@@ -34236,18 +34487,18 @@ var Sidebar = Object.assign(
34236
34487
  Sidebar.displayName = "Sidebar";
34237
34488
 
34238
34489
  // components/DefaultSidebar.tsx
34239
- import { jsx as jsx125, jsxs as jsxs66 } from "react/jsx-runtime";
34490
+ import { jsx as jsx126, jsxs as jsxs66 } from "react/jsx-runtime";
34240
34491
  import { createElement as createElement2 } from "react";
34241
34492
  var DefaultSidebarTrigger = withInternalFallback(
34242
34493
  "DefaultSidebarTrigger",
34243
34494
  (props) => {
34244
34495
  const { DefaultSidebarTriggerTunnel } = useTunnels();
34245
- return /* @__PURE__ */ jsx125(DefaultSidebarTriggerTunnel.In, { children: /* @__PURE__ */ jsx125(
34496
+ return /* @__PURE__ */ jsx126(DefaultSidebarTriggerTunnel.In, { children: /* @__PURE__ */ jsx126(
34246
34497
  Sidebar.Trigger,
34247
34498
  {
34248
34499
  ...props,
34249
34500
  className: "default-sidebar-trigger",
34250
- name: DEFAULT_SIDEBAR2.name
34501
+ name: DEFAULT_SIDEBAR3.name
34251
34502
  }
34252
34503
  ) });
34253
34504
  }
@@ -34255,7 +34506,7 @@ var DefaultSidebarTrigger = withInternalFallback(
34255
34506
  DefaultSidebarTrigger.displayName = "DefaultSidebarTrigger";
34256
34507
  var DefaultTabTriggers = ({ children }) => {
34257
34508
  const { DefaultSidebarTabTriggersTunnel } = useTunnels();
34258
- return /* @__PURE__ */ jsx125(DefaultSidebarTabTriggersTunnel.In, { children });
34509
+ return /* @__PURE__ */ jsx126(DefaultSidebarTabTriggersTunnel.In, { children });
34259
34510
  };
34260
34511
  DefaultTabTriggers.displayName = "DefaultTabTriggers";
34261
34512
  var DefaultSidebar = Object.assign(
@@ -34270,7 +34521,7 @@ var DefaultSidebar = Object.assign(
34270
34521
  }) => {
34271
34522
  const appState = useUIAppState();
34272
34523
  const setAppState = useExcalidrawSetAppState();
34273
- const isSearchSidebar = appState.openSidebar?.tab === CANVAS_SEARCH_TAB2;
34524
+ const isSearchSidebar = appState.openSidebar?.tab === CANVAS_SEARCH_TAB3;
34274
34525
  const isDocked = isSearchSidebar ? false : docked ?? appState.defaultSidebarDockedPreference;
34275
34526
  const canDock = !isSearchSidebar && docked == null && onDock !== false;
34276
34527
  return /* @__PURE__ */ createElement2(
@@ -34279,7 +34530,7 @@ var DefaultSidebar = Object.assign(
34279
34530
  ...rest,
34280
34531
  name: "default",
34281
34532
  key: "default",
34282
- className: clsx55(
34533
+ className: clsx56(
34283
34534
  "default-sidebar",
34284
34535
  { "default-sidebar--search-only": isSearchSidebar },
34285
34536
  className
@@ -34293,8 +34544,8 @@ var DefaultSidebar = Object.assign(
34293
34544
  } : void 0
34294
34545
  },
34295
34546
  /* @__PURE__ */ jsxs66(Sidebar.Tabs, { children: [
34296
- !isSearchSidebar && /* @__PURE__ */ jsx125(Sidebar.Header, {}),
34297
- /* @__PURE__ */ jsx125(Sidebar.Tab, { tab: CANVAS_SEARCH_TAB2, children: /* @__PURE__ */ jsx125(SearchMenu2, {}) }),
34547
+ !isSearchSidebar && /* @__PURE__ */ jsx126(Sidebar.Header, {}),
34548
+ /* @__PURE__ */ jsx126(Sidebar.Tab, { tab: CANVAS_SEARCH_TAB3, children: /* @__PURE__ */ jsx126(SearchMenu2, {}) }),
34298
34549
  !isSearchSidebar && children
34299
34550
  ] })
34300
34551
  );
@@ -34311,7 +34562,7 @@ import React37 from "react";
34311
34562
  import { getFrame } from "@excalidraw/common";
34312
34563
 
34313
34564
  // components/Card.tsx
34314
- import { jsx as jsx126 } from "react/jsx-runtime";
34565
+ import { jsx as jsx127 } from "react/jsx-runtime";
34315
34566
  var COLOR_MAP = {
34316
34567
  primary: {
34317
34568
  base: "var(--color-primary)",
@@ -34336,7 +34587,7 @@ var COLOR_MAP = {
34336
34587
  }
34337
34588
  };
34338
34589
  var Card = ({ children, color }) => {
34339
- return /* @__PURE__ */ jsx126(
34590
+ return /* @__PURE__ */ jsx127(
34340
34591
  "div",
34341
34592
  {
34342
34593
  className: "Card",
@@ -34351,7 +34602,7 @@ var Card = ({ children, color }) => {
34351
34602
  };
34352
34603
 
34353
34604
  // components/JSONExportDialog.tsx
34354
- import { Fragment as Fragment23, jsx as jsx127, jsxs as jsxs67 } from "react/jsx-runtime";
34605
+ import { Fragment as Fragment23, jsx as jsx128, jsxs as jsxs67 } from "react/jsx-runtime";
34355
34606
  var JSONExportModal = ({
34356
34607
  elements,
34357
34608
  appState,
@@ -34363,15 +34614,15 @@ var JSONExportModal = ({
34363
34614
  onCloseRequest
34364
34615
  }) => {
34365
34616
  const { onExportToBackend } = exportOpts;
34366
- return /* @__PURE__ */ jsx127("div", { className: "ExportDialog ExportDialog--json", children: /* @__PURE__ */ jsxs67("div", { className: "ExportDialog-cards", children: [
34617
+ return /* @__PURE__ */ jsx128("div", { className: "ExportDialog ExportDialog--json", children: /* @__PURE__ */ jsxs67("div", { className: "ExportDialog-cards", children: [
34367
34618
  exportOpts.saveFileToDisk && /* @__PURE__ */ jsxs67(Card, { color: "lime", children: [
34368
- /* @__PURE__ */ jsx127("div", { className: "Card-icon", children: exportToFileIcon }),
34369
- /* @__PURE__ */ jsx127("h2", { children: t("exportDialog.disk_title") }),
34619
+ /* @__PURE__ */ jsx128("div", { className: "Card-icon", children: exportToFileIcon }),
34620
+ /* @__PURE__ */ jsx128("h2", { children: t("exportDialog.disk_title") }),
34370
34621
  /* @__PURE__ */ jsxs67("div", { className: "Card-details", children: [
34371
34622
  t("exportDialog.disk_details"),
34372
34623
  !nativeFileSystemSupported && actionManager.renderAction("changeProjectName")
34373
34624
  ] }),
34374
- /* @__PURE__ */ jsx127(
34625
+ /* @__PURE__ */ jsx128(
34375
34626
  IconButton,
34376
34627
  {
34377
34628
  className: "Card-button",
@@ -34386,10 +34637,10 @@ var JSONExportModal = ({
34386
34637
  )
34387
34638
  ] }),
34388
34639
  onExportToBackend && /* @__PURE__ */ jsxs67(Card, { color: "pink", children: [
34389
- /* @__PURE__ */ jsx127("div", { className: "Card-icon", children: LinkIcon }),
34390
- /* @__PURE__ */ jsx127("h2", { children: t("exportDialog.link_title") }),
34391
- /* @__PURE__ */ jsx127("div", { className: "Card-details", children: t("exportDialog.link_details") }),
34392
- /* @__PURE__ */ jsx127(
34640
+ /* @__PURE__ */ jsx128("div", { className: "Card-icon", children: LinkIcon }),
34641
+ /* @__PURE__ */ jsx128("h2", { children: t("exportDialog.link_title") }),
34642
+ /* @__PURE__ */ jsx128("div", { className: "Card-details", children: t("exportDialog.link_details") }),
34643
+ /* @__PURE__ */ jsx128(
34393
34644
  IconButton,
34394
34645
  {
34395
34646
  className: "Card-button",
@@ -34424,7 +34675,7 @@ var JSONExportDialog = ({
34424
34675
  const handleClose = React37.useCallback(() => {
34425
34676
  setAppState({ openDialog: null });
34426
34677
  }, [setAppState]);
34427
- return /* @__PURE__ */ jsx127(Fragment23, { children: appState.openDialog?.name === "jsonExport" && /* @__PURE__ */ jsx127(Dialog, { onCloseRequest: handleClose, title: t("buttons.export"), children: /* @__PURE__ */ jsx127(
34678
+ return /* @__PURE__ */ jsx128(Fragment23, { children: appState.openDialog?.name === "jsonExport" && /* @__PURE__ */ jsx128(Dialog, { onCloseRequest: handleClose, title: t("buttons.export"), children: /* @__PURE__ */ jsx128(
34428
34679
  JSONExportModal,
34429
34680
  {
34430
34681
  elements,
@@ -34440,13 +34691,13 @@ var JSONExportDialog = ({
34440
34691
  };
34441
34692
 
34442
34693
  // components/LaserPointerButton.tsx
34443
- import clsx56 from "clsx";
34444
- import { jsx as jsx128 } from "react/jsx-runtime";
34694
+ import clsx57 from "clsx";
34695
+ import { jsx as jsx129 } from "react/jsx-runtime";
34445
34696
  var LaserPointerButton = (props) => {
34446
- return /* @__PURE__ */ jsx128(
34697
+ return /* @__PURE__ */ jsx129(
34447
34698
  IconButton,
34448
34699
  {
34449
- className: clsx56("ToolIcon__LaserPointer", {
34700
+ className: clsx57("ToolIcon__LaserPointer", {
34450
34701
  "is-mobile": props.isMobile
34451
34702
  }),
34452
34703
  type: "toggle",
@@ -34462,214 +34713,18 @@ var LaserPointerButton = (props) => {
34462
34713
  };
34463
34714
 
34464
34715
  // components/Toolbar.tsx
34465
- import clsx58 from "clsx";
34716
+ import clsx59 from "clsx";
34466
34717
  import { useState as useState33 } from "react";
34467
34718
  import { CANVAS_SEARCH_TAB as CANVAS_SEARCH_TAB4, DEFAULT_SIDEBAR as DEFAULT_SIDEBAR4, KEYS as KEYS52 } from "@excalidraw/common";
34468
34719
 
34469
- // components/HintViewer.tsx
34470
- import { CANVAS_SEARCH_TAB as CANVAS_SEARCH_TAB3, DEFAULT_SIDEBAR as DEFAULT_SIDEBAR3 } from "@excalidraw/common";
34471
- import {
34472
- isArrowElement as isArrowElement14,
34473
- isFlowchartNodeElement as isFlowchartNodeElement3,
34474
- isImageElement as isImageElement9,
34475
- isLinearElement as isLinearElement10,
34476
- isLineElement as isLineElement8,
34477
- isTextBindableContainer as isTextBindableContainer2,
34478
- isTextElement as isTextElement17
34479
- } from "@excalidraw/element";
34480
- import { isNodeInFlowchart } from "@excalidraw/element";
34481
- import { jsx as jsx129 } from "react/jsx-runtime";
34482
- var getTaggedShortcutKey = (key) => Array.isArray(key) ? `<kbd>${key.map(getShortcutKey).join(" + ")}</kbd>` : `<kbd>${getShortcutKey(key)}</kbd>`;
34483
- var getHints = ({
34484
- appState,
34485
- isMobile,
34486
- editorInterface,
34487
- app
34488
- }) => {
34489
- const { activeTool, isResizing, isRotating, lastPointerDownWith } = appState;
34490
- const multiMode = appState.multiElement !== null;
34491
- if (appState.openSidebar?.name === DEFAULT_SIDEBAR3.name && appState.openSidebar.tab === CANVAS_SEARCH_TAB3 && appState.searchMatches?.matches.length) {
34492
- return t("hints.dismissSearch", {
34493
- shortcut: getTaggedShortcutKey("Escape")
34494
- });
34495
- }
34496
- if (appState.openSidebar && !editorInterface.canFitSidebar) {
34497
- return null;
34498
- }
34499
- if (isEraserActive(appState)) {
34500
- return t("hints.eraserRevert", {
34501
- shortcut: getTaggedShortcutKey("Alt")
34502
- });
34503
- }
34504
- const selectedElements = app.scene.getSelectedElements(appState);
34505
- if (appState.selectedLinearElement?.isDragging && selectedElements[0]?.type === "arrow") {
34506
- return t("hints.arrowBindModifiers", {
34507
- shortcut_1: getTaggedShortcutKey("Ctrl"),
34508
- shortcut_2: getTaggedShortcutKey("Alt")
34509
- });
34510
- }
34511
- if (activeTool.type === "arrow" || activeTool.type === "line") {
34512
- if (multiMode) {
34513
- return t("hints.linearElementMulti", {
34514
- shortcut_1: getTaggedShortcutKey("Escape"),
34515
- shortcut_2: getTaggedShortcutKey("Enter")
34516
- });
34517
- }
34518
- if (activeTool.type === "arrow") {
34519
- return t("hints.arrowTool", {
34520
- shortcut: getTaggedShortcutKey("A")
34521
- });
34522
- }
34523
- return t("hints.linearElement");
34524
- }
34525
- if (activeTool.type === "freedraw") {
34526
- return t("hints.freeDraw");
34527
- }
34528
- if (activeTool.type === "text") {
34529
- return t("hints.text");
34530
- }
34531
- if (activeTool.type === "embeddable") {
34532
- return t("hints.embeddable");
34533
- }
34534
- if (activeTool.type === "autoshape") {
34535
- return t("hints.autoshape");
34536
- }
34537
- if (isResizing && lastPointerDownWith === "mouse" && selectedElements.length === 1) {
34538
- const targetElement = selectedElements[0];
34539
- if (isLinearElement10(targetElement) && targetElement.points.length === 2) {
34540
- return t("hints.lockAngle", {
34541
- shortcut: getTaggedShortcutKey("Shift")
34542
- });
34543
- }
34544
- return isImageElement9(targetElement) ? t("hints.resizeImage", {
34545
- shortcut_1: getTaggedShortcutKey("Shift"),
34546
- shortcut_2: getTaggedShortcutKey("Alt")
34547
- }) : t("hints.resize", {
34548
- shortcut_1: getTaggedShortcutKey("Shift"),
34549
- shortcut_2: getTaggedShortcutKey("Alt")
34550
- });
34551
- }
34552
- if (isRotating && lastPointerDownWith === "mouse") {
34553
- return t("hints.rotate", {
34554
- shortcut: getTaggedShortcutKey("Shift")
34555
- });
34556
- }
34557
- if (selectedElements.length === 1 && isTextElement17(selectedElements[0])) {
34558
- return t("hints.text_selected", {
34559
- shortcut: getTaggedShortcutKey("Enter")
34560
- });
34561
- }
34562
- if (appState.editingTextElement) {
34563
- return t("hints.text_editing", {
34564
- shortcut_1: getTaggedShortcutKey("Escape"),
34565
- shortcut_2: getTaggedShortcutKey(["CtrlOrCmd", "Enter"])
34566
- });
34567
- }
34568
- if (appState.croppingElementId) {
34569
- return t("hints.leaveCropEditor", {
34570
- shortcut_1: getTaggedShortcutKey("Enter"),
34571
- shortcut_2: getTaggedShortcutKey("Escape")
34572
- });
34573
- }
34574
- if (selectedElements.length === 1 && isImageElement9(selectedElements[0])) {
34575
- return t("hints.enterCropEditor", {
34576
- shortcut: getTaggedShortcutKey("Enter")
34577
- });
34578
- }
34579
- if (activeTool.type === "selection") {
34580
- if (appState.selectionElement && !selectedElements.length && !appState.editingTextElement && !appState.selectedLinearElement?.isEditing) {
34581
- return t("hints.deepBoxSelect", {
34582
- shortcut: getTaggedShortcutKey("CtrlOrCmd")
34583
- });
34584
- }
34585
- if (isGridModeEnabled(app) && appState.selectedElementsAreBeingDragged) {
34586
- return t("hints.disableSnapping", {
34587
- shortcut: getTaggedShortcutKey("CtrlOrCmd")
34588
- });
34589
- }
34590
- if (!selectedElements.length && !isMobile) {
34591
- return t("hints.canvasPanning", {
34592
- shortcut_1: getTaggedShortcutKey(t("keys.mmb")),
34593
- shortcut_2: getTaggedShortcutKey("Space")
34594
- });
34595
- }
34596
- if (selectedElements.length === 1) {
34597
- if (isLinearElement10(selectedElements[0])) {
34598
- if (isArrowElement14(selectedElements[0]) && appState.selectedLinearElement?.elementId === selectedElements[0].id && (appState.selectedLinearElement.hoverPointIndex === 0 || appState.selectedLinearElement.hoverPointIndex === selectedElements[0].points.length - 1)) {
34599
- return t("hints.toggleArrowhead");
34600
- }
34601
- if (appState.selectedLinearElement?.isEditing) {
34602
- return appState.selectedLinearElement.selectedPointsIndices ? t("hints.lineEditor_pointSelected", {
34603
- shortcut_1: getTaggedShortcutKey("Delete"),
34604
- shortcut_2: getTaggedShortcutKey(["CtrlOrCmd", "D"])
34605
- }) : t("hints.lineEditor_nothingSelected", {
34606
- shortcut_1: getTaggedShortcutKey("Shift"),
34607
- shortcut_2: getTaggedShortcutKey("Alt")
34608
- });
34609
- }
34610
- return isLineElement8(selectedElements[0]) ? t("hints.lineEditor_line_info", {
34611
- shortcut: getTaggedShortcutKey("Enter")
34612
- }) : t("hints.lineEditor_info", {
34613
- shortcut_1: getTaggedShortcutKey("CtrlOrCmd"),
34614
- shortcut_2: getTaggedShortcutKey(["CtrlOrCmd", "Enter"])
34615
- });
34616
- }
34617
- if (!appState.newElement && !appState.selectedElementsAreBeingDragged && isTextBindableContainer2(selectedElements[0])) {
34618
- const bindTextToElement = t("hints.bindTextToElement", {
34619
- shortcut: getTaggedShortcutKey("Enter")
34620
- });
34621
- const createFlowchart = t("hints.createFlowchart", {
34622
- shortcut: getTaggedShortcutKey(["CtrlOrCmd", "\u2191\u2193"])
34623
- });
34624
- if (isFlowchartNodeElement3(selectedElements[0])) {
34625
- if (isNodeInFlowchart(
34626
- selectedElements[0],
34627
- app.scene.getNonDeletedElementsMap()
34628
- )) {
34629
- return [bindTextToElement, createFlowchart];
34630
- }
34631
- return [bindTextToElement, createFlowchart];
34632
- }
34633
- return bindTextToElement;
34634
- }
34635
- }
34636
- }
34637
- return null;
34638
- };
34639
- var HintViewer = ({
34640
- appState,
34641
- isMobile,
34642
- editorInterface,
34643
- app
34644
- }) => {
34645
- const hints = getHints({
34646
- appState,
34647
- isMobile,
34648
- editorInterface,
34649
- app
34650
- });
34651
- if (!hints) {
34652
- return null;
34653
- }
34654
- const hint = Array.isArray(hints) ? hints.map((hint2) => hint2.replace(/\. ?$/, "")).join(", ") : hints;
34655
- const hintJSX = hint.split(/(<kbd>[^<]+<\/kbd>)/g).map((part, index) => {
34656
- if (index % 2 === 1) {
34657
- const shortcutMatch = part[0] === "<" && part.match(/^<kbd>([^<]+)<\/kbd>$/);
34658
- return /* @__PURE__ */ jsx129("kbd", { children: shortcutMatch ? shortcutMatch[1] : part }, index);
34659
- }
34660
- return part;
34661
- });
34662
- return /* @__PURE__ */ jsx129("div", { className: "HintViewer", children: /* @__PURE__ */ jsx129("span", { children: hintJSX }) });
34663
- };
34664
-
34665
34720
  // components/LockButton.tsx
34666
- import clsx57 from "clsx";
34721
+ import clsx58 from "clsx";
34667
34722
  import { jsx as jsx130 } from "react/jsx-runtime";
34668
34723
  var LockButton = (props) => {
34669
34724
  return /* @__PURE__ */ jsx130(
34670
34725
  IconButton,
34671
34726
  {
34672
- className: clsx57("ToolIcon__lock", { "is-mobile": props.isMobile }),
34727
+ className: clsx58("ToolIcon__lock", { "is-mobile": props.isMobile }),
34673
34728
  type: "toggle",
34674
34729
  icon: props.checked ? LockedIcon : UnlockedIcon,
34675
34730
  checked: props.checked,
@@ -34810,7 +34865,7 @@ var ExtraToolsDropdown = ({
34810
34865
  /* @__PURE__ */ jsx131(
34811
34866
  DropdownMenu_default.Trigger,
34812
34867
  {
34813
- className: clsx58("App-toolbar__extra-tools-trigger", {
34868
+ className: clsx59("App-toolbar__extra-tools-trigger", {
34814
34869
  "App-toolbar__extra-tools-trigger--selected": myocSimplifiedToolSelected || frameToolSelected || embeddableToolSelected || !isMyocSimplifiedMode && isFullStylesPanel && drawShapeToolSelected || lassoToolSelected || bucketFillToolSelected || // in collab we're already highlighting the laser button
34815
34870
  // outside toolbar, so let's not highlight extra-tools button
34816
34871
  // on top of it
@@ -34972,7 +35027,7 @@ var Toolbar = ({
34972
35027
  Island,
34973
35028
  {
34974
35029
  padding: 1,
34975
- className: clsx58("App-toolbar", {
35030
+ className: clsx59("App-toolbar", {
34976
35031
  "zen-mode": appState.zenModeEnabled,
34977
35032
  "App-toolbar--compact": isCompactStylesPanel
34978
35033
  }),
@@ -35168,13 +35223,13 @@ var LayerUI = ({
35168
35223
  Section,
35169
35224
  {
35170
35225
  heading: "selectedShapeActions",
35171
- className: clsx59("selected-shape-actions zen-mode-transition", {
35226
+ className: clsx60("selected-shape-actions zen-mode-transition", {
35172
35227
  "transition-left": appState.zenModeEnabled
35173
35228
  }),
35174
35229
  children: isCompactStylesPanel ? /* @__PURE__ */ jsx132(
35175
35230
  Island,
35176
35231
  {
35177
- className: clsx59("compact-shape-actions-island"),
35232
+ className: clsx60("compact-shape-actions-island"),
35178
35233
  padding: 0,
35179
35234
  "data-viewport-ui": "side",
35180
35235
  "data-viewport-ui-name": "stylesPanel",
@@ -35228,13 +35283,13 @@ var LayerUI = ({
35228
35283
  Stack_default.Col,
35229
35284
  {
35230
35285
  gap: spacing.menuTopGap,
35231
- className: clsx59("App-menu_top__left"),
35286
+ className: clsx60("App-menu_top__left"),
35232
35287
  children: [
35233
35288
  renderCanvasActions(),
35234
35289
  defaultUIEnabled && /* @__PURE__ */ jsx132(
35235
35290
  "div",
35236
35291
  {
35237
- className: clsx59("selected-shape-actions-container", {
35292
+ className: clsx60("selected-shape-actions-container", {
35238
35293
  "selected-shape-actions-container--compact": isCompactStylesPanel
35239
35294
  }),
35240
35295
  children: shouldRenderSelectedShapeActions && renderSelectedShapeActions()
@@ -35253,13 +35308,23 @@ var LayerUI = ({
35253
35308
  ]
35254
35309
  }
35255
35310
  ),
35311
+ defaultUIEnabled && appState.viewModeEnabled && // MyOC: Keep the held-F Smart Zoom hint visible in view mode.
35312
+ /* @__PURE__ */ jsx132("div", { className: "view-mode-hint", children: /* @__PURE__ */ jsx132(
35313
+ HintViewer,
35314
+ {
35315
+ appState,
35316
+ isMobile: editorInterface.formFactor === "phone",
35317
+ editorInterface,
35318
+ app
35319
+ }
35320
+ ) }),
35256
35321
  defaultUIEnabled && !appState.viewModeEnabled && appState.openDialog?.name !== "elementLinkSelector" && /* @__PURE__ */ jsx132(Section, { heading: "shapes", className: "shapes-section", children: (heading) => /* @__PURE__ */ jsxs69("div", { style: { position: "relative" }, children: [
35257
35322
  renderWelcomeScreen && /* @__PURE__ */ jsx132(tunnels.WelcomeScreenToolbarHintTunnel.Out, {}),
35258
35323
  /* @__PURE__ */ jsx132(Stack_default.Col, { gap: spacing.toolbarColGap, align: "start", children: /* @__PURE__ */ jsxs69(
35259
35324
  Stack_default.Row,
35260
35325
  {
35261
35326
  gap: spacing.toolbarRowGap,
35262
- className: clsx59("App-toolbar-container", {
35327
+ className: clsx60("App-toolbar-container", {
35263
35328
  "zen-mode": appState.zenModeEnabled
35264
35329
  }),
35265
35330
  children: [
@@ -35302,7 +35367,7 @@ var LayerUI = ({
35302
35367
  /* @__PURE__ */ jsxs69(
35303
35368
  "div",
35304
35369
  {
35305
- className: clsx59(
35370
+ className: clsx60(
35306
35371
  "layer-ui__wrapper__top-right zen-mode-transition",
35307
35372
  {
35308
35373
  "transition-right": appState.zenModeEnabled,
@@ -36047,7 +36112,7 @@ var NewElementCanvas = (props) => {
36047
36112
  var NewElementCanvas_default = NewElementCanvas;
36048
36113
 
36049
36114
  // components/CursorHint.tsx
36050
- import clsx60 from "clsx";
36115
+ import clsx61 from "clsx";
36051
36116
  import { useLayoutEffect as useLayoutEffect10, useEffect as useEffect38, useRef as useRef32, useState as useState34 } from "react";
36052
36117
  import { ARROW_TYPE as ARROW_TYPE2, EVENT as EVENT10 } from "@excalidraw/common";
36053
36118
  import { jsx as jsx137 } from "react/jsx-runtime";
@@ -36166,7 +36231,7 @@ var CursorHint = () => {
36166
36231
  "div",
36167
36232
  {
36168
36233
  ref: hintRef,
36169
- className: clsx60("CursorHint", {
36234
+ className: clsx61("CursorHint", {
36170
36235
  "CursorHint--fade-out": isFadingOut
36171
36236
  }),
36172
36237
  "data-testid": "cursor-hint",
@@ -36425,6 +36490,7 @@ var touchTimeout = 0;
36425
36490
  var invalidateContextMenu = false;
36426
36491
  var YOUTUBE_VIDEO_STATES = /* @__PURE__ */ new Map();
36427
36492
  var MAX_EMBEDDABLE_VIEWPORT_SCALE = 4;
36493
+ var SMART_ZOOM_KEY_RELEASE_TIMEOUT = 300;
36428
36494
  var getViewpointAwareResizeCursor = (cursor, viewpointFlip) => {
36429
36495
  if (viewpointFlip.horizontal === viewpointFlip.vertical) {
36430
36496
  return cursor;
@@ -36525,6 +36591,9 @@ var App = class _App extends React41.Component {
36525
36591
  __publicField(this, "lastPointerMoveCoords", null);
36526
36592
  __publicField(this, "lastCompletedCanvasClicks", []);
36527
36593
  __publicField(this, "lastKeyboardSmartZoomImageId", null);
36594
+ // MyOC: State for the press-and-hold Smart Zoom interaction.
36595
+ __publicField(this, "smartZoomKeyDownAt", null);
36596
+ __publicField(this, "smartZoomKeyHitElement", false);
36528
36597
  /** previous frame pointer coords */
36529
36598
  __publicField(this, "previousPointerMoveCoords", null);
36530
36599
  __publicField(this, "drawShape", new AppDrawShape(this));
@@ -36982,6 +37051,7 @@ var App = class _App extends React41.Component {
36982
37051
  // Lifecycle
36983
37052
  __publicField(this, "onBlur", withBatchedUpdates(() => {
36984
37053
  isHoldingSpace = false;
37054
+ this.resetSmartZoomKey();
36985
37055
  this.setState({
36986
37056
  isBindingEnabled: this.state.bindingPreference === "enabled"
36987
37057
  });
@@ -37046,6 +37116,7 @@ var App = class _App extends React41.Component {
37046
37116
  this.maybeCleanupAfterMissingPointerUp(null);
37047
37117
  isHoldingSpace = false;
37048
37118
  isHoldingZ = false;
37119
+ this.resetSmartZoomKey();
37049
37120
  isPanning = false;
37050
37121
  isDraggingScrollBar = false;
37051
37122
  lastPointerUp = null;
@@ -37532,9 +37603,30 @@ var App = class _App extends React41.Component {
37532
37603
  if (event && (!(elementUnderCursor instanceof HTMLCanvasElement) || isWritableElement4(target))) {
37533
37604
  return;
37534
37605
  }
37535
- const dataTransferList = await parseDataTransferEvent(event);
37536
- const filesList = dataTransferList.getFiles();
37537
- const data = await parseClipboard(dataTransferList, isPlainPaste);
37606
+ let dataTransferList = await parseDataTransferEvent(event);
37607
+ let filesList = dataTransferList.getFiles();
37608
+ let data = await parseClipboard(dataTransferList, isPlainPaste);
37609
+ if (!data.elements && filesList.length > 0 && !isPlainPaste) {
37610
+ try {
37611
+ const systemClipboard = await readSystemClipboard();
37612
+ const excalidrawJSON = systemClipboard[MIME_TYPES11.excalidrawClipboard];
37613
+ if (typeof excalidrawJSON === "string") {
37614
+ dataTransferList = await parseDataTransferEvent(
37615
+ createPasteEvent({
37616
+ types: {
37617
+ [MIME_TYPES11.excalidrawClipboard]: excalidrawJSON
37618
+ }
37619
+ })
37620
+ );
37621
+ filesList = dataTransferList.getFiles();
37622
+ data = await parseClipboard(dataTransferList, isPlainPaste);
37623
+ }
37624
+ } catch (error) {
37625
+ console.warn(
37626
+ `Could not read editable image clipboard data: ${error.message}`
37627
+ );
37628
+ }
37629
+ }
37538
37630
  if (this.state.viewModeEnabled) {
37539
37631
  if (!this.containsImagePaste(data, filesList, isPlainPaste)) {
37540
37632
  return;
@@ -38124,7 +38216,76 @@ var App = class _App extends React41.Component {
38124
38216
  this.viewport.lastPosition.y = event.clientY;
38125
38217
  }
38126
38218
  ));
38127
- // Input handling
38219
+ // MyOC Smart Zoom input handling: F is a hold gesture that can target the
38220
+ // item under the pointer, or zoom the complete scene on a quick release.
38221
+ __publicField(this, "isPlainSmartZoomKey", (event) => !event[KEYS53.CTRL_OR_CMD] && !event.shiftKey && !event.altKey && event.key.toLocaleLowerCase() === KEYS53.F);
38222
+ __publicField(this, "updateSmartZoomCursor", (scenePointer) => {
38223
+ if (this.smartZoomKeyDownAt === null) {
38224
+ return;
38225
+ }
38226
+ const hitElement = scenePointer ? this.getElementAtPosition(scenePointer.x, scenePointer.y, {
38227
+ includeLockedElements: true
38228
+ }) : null;
38229
+ this.cursor.set(hitElement ? CURSOR_TYPE2.POINTER : "zoom-in");
38230
+ });
38231
+ __publicField(this, "resetSmartZoomKey", () => {
38232
+ const wasHeld = this.smartZoomKeyDownAt !== null;
38233
+ this.smartZoomKeyDownAt = null;
38234
+ this.smartZoomKeyHitElement = false;
38235
+ if (wasHeld) {
38236
+ this.cursor.reset();
38237
+ this.updateEditorAtom(smartZoomKeyHeldAtom, false);
38238
+ }
38239
+ });
38240
+ __publicField(this, "handleSmartZoomKeyDown", (event) => {
38241
+ if (!this.isPlainSmartZoomKey(event)) {
38242
+ return false;
38243
+ }
38244
+ if (!event.repeat && this.smartZoomKeyDownAt === null) {
38245
+ this.smartZoomKeyDownAt = Date.now();
38246
+ this.smartZoomKeyHitElement = false;
38247
+ this.updateEditorAtom(smartZoomKeyHeldAtom, true);
38248
+ this.updateSmartZoomCursor(this.lastPointerMoveCoords);
38249
+ }
38250
+ event.preventDefault();
38251
+ event.stopPropagation();
38252
+ return true;
38253
+ });
38254
+ __publicField(this, "handleSmartZoomKeyUp", (event) => {
38255
+ if (event.key.toLocaleLowerCase() !== KEYS53.F || this.smartZoomKeyDownAt === null) {
38256
+ return false;
38257
+ }
38258
+ const elapsed = Date.now() - this.smartZoomKeyDownAt;
38259
+ const shouldZoomAllElements = !this.smartZoomKeyHitElement && elapsed <= SMART_ZOOM_KEY_RELEASE_TIMEOUT;
38260
+ this.resetSmartZoomKey();
38261
+ event.stopPropagation();
38262
+ if (shouldZoomAllElements) {
38263
+ this.actionManager.executeAction(
38264
+ actionSmartZoom,
38265
+ "keyboard",
38266
+ this.scene.getNonDeletedElements()
38267
+ );
38268
+ }
38269
+ return true;
38270
+ });
38271
+ __publicField(this, "handleSmartZoomPointerDown", (event, scenePointer) => {
38272
+ if (event.button !== POINTER_BUTTON2.MAIN || this.smartZoomKeyDownAt === null) {
38273
+ return false;
38274
+ }
38275
+ const hitElement = this.getElementAtPosition(
38276
+ scenePointer.x,
38277
+ scenePointer.y,
38278
+ { includeLockedElements: true }
38279
+ );
38280
+ if (!hitElement) {
38281
+ return false;
38282
+ }
38283
+ this.smartZoomKeyHitElement = true;
38284
+ event.preventDefault();
38285
+ event.stopPropagation();
38286
+ this.actionManager.executeAction(actionSmartZoom, "keyboard", [hitElement]);
38287
+ return true;
38288
+ });
38128
38289
  __publicField(this, "onKeyDown", withBatchedUpdates(
38129
38290
  (event) => {
38130
38291
  if (!this.isInteractionEnabled()) {
@@ -38250,6 +38411,9 @@ var App = class _App extends React41.Component {
38250
38411
  maybeHandleArrowPointlikeDrag({ app: this, event });
38251
38412
  }
38252
38413
  }
38414
+ if (this.handleSmartZoomKeyDown(event)) {
38415
+ return;
38416
+ }
38253
38417
  if (this.actionManager.handleKeyDown(event)) {
38254
38418
  return;
38255
38419
  }
@@ -38456,6 +38620,9 @@ var App = class _App extends React41.Component {
38456
38620
  if (!this.isInteractionEnabled()) {
38457
38621
  return;
38458
38622
  }
38623
+ if (this.handleSmartZoomKeyUp(event)) {
38624
+ return;
38625
+ }
38459
38626
  if (event.key === KEYS53.SPACE) {
38460
38627
  if (this.state.viewModeEnabled && this.state.activeTool.type !== "laser" || this.state.openDialog?.name === "elementLinkSelector") {
38461
38628
  this.cursor.set(CURSOR_TYPE2.GRAB);
@@ -38950,12 +39117,12 @@ var App = class _App extends React41.Component {
38950
39117
  event,
38951
39118
  this.state
38952
39119
  );
38953
- const hitElement = this.getElementAtPosition(sceneX2, sceneY2, {
39120
+ const hitElement2 = this.getElementAtPosition(sceneX2, sceneY2, {
38954
39121
  includeLockedElements: true
38955
39122
  });
38956
- if (hitElement) {
39123
+ if (hitElement2) {
38957
39124
  this.cursor.reset();
38958
- this.actionManager.executeAction(actionSmartZoom, "ui", [hitElement]);
39125
+ this.actionManager.executeAction(actionSmartZoom, "ui", [hitElement2]);
38959
39126
  }
38960
39127
  return;
38961
39128
  }
@@ -39027,15 +39194,18 @@ var App = class _App extends React41.Component {
39027
39194
  return;
39028
39195
  }
39029
39196
  }
39030
- if (selectedElements.length === 1 && isImageElement10(selectedElements[0])) {
39031
- this.startImageCropping(selectedElements[0]);
39197
+ const hitElement = this.getElementAtPosition(sceneX, sceneY, {
39198
+ includeLockedElements: true
39199
+ });
39200
+ if (hitElement && isImageElement10(hitElement)) {
39201
+ this.actionManager.executeAction(actionSmartZoom, "ui", [hitElement]);
39032
39202
  return;
39033
39203
  }
39034
39204
  this.cursor.reset();
39035
39205
  const selectedGroupIds = getSelectedGroupIds4(this.state);
39036
39206
  if (selectedGroupIds.length > 0) {
39037
- const hitElement = this.getElementAtPosition(sceneX, sceneY);
39038
- const selectedGroupId = hitElement && getSelectedGroupIdForElement(hitElement, this.state.selectedGroupIds);
39207
+ const hitElement2 = this.getElementAtPosition(sceneX, sceneY);
39208
+ const selectedGroupId = hitElement2 && getSelectedGroupIdForElement(hitElement2, this.state.selectedGroupIds);
39039
39209
  if (selectedGroupId) {
39040
39210
  this.store.scheduleCapture();
39041
39211
  this.setState((prevState) => ({
@@ -39043,7 +39213,7 @@ var App = class _App extends React41.Component {
39043
39213
  ...selectGroupsForSelectedElements7(
39044
39214
  {
39045
39215
  editingGroupId: selectedGroupId,
39046
- selectedElementIds: { [hitElement.id]: true }
39216
+ selectedElementIds: { [hitElement2.id]: true }
39047
39217
  },
39048
39218
  this.scene.getNonDeletedElements(),
39049
39219
  prevState,
@@ -39055,10 +39225,10 @@ var App = class _App extends React41.Component {
39055
39225
  }
39056
39226
  this.cursor.reset();
39057
39227
  if (!this.state.viewModeEnabled) {
39058
- const hitElement = this.getElementAtPosition(sceneX, sceneY);
39059
- if (isIframeLikeElement2(hitElement)) {
39228
+ const hitElement2 = this.getElementAtPosition(sceneX, sceneY);
39229
+ if (isIframeLikeElement2(hitElement2)) {
39060
39230
  this.setState({
39061
- activeEmbeddable: { element: hitElement, state: "active" }
39231
+ activeEmbeddable: { element: hitElement2, state: "active" }
39062
39232
  });
39063
39233
  return;
39064
39234
  }
@@ -39111,7 +39281,28 @@ var App = class _App extends React41.Component {
39111
39281
  this.lastCompletedCanvasClicks = [];
39112
39282
  return;
39113
39283
  }
39284
+ if (this.smartZoomKeyHitElement) {
39285
+ event.preventDefault();
39286
+ event.stopPropagation();
39287
+ return;
39288
+ }
39114
39289
  const scenePointer = viewportCoordsToSceneCoords3(event, this.state);
39290
+ if (this.smartZoomKeyDownAt !== null && !this.smartZoomKeyHitElement) {
39291
+ const hitElement = this.getElementAtPosition(
39292
+ scenePointer.x,
39293
+ scenePointer.y,
39294
+ { includeLockedElements: true }
39295
+ );
39296
+ if (hitElement) {
39297
+ this.smartZoomKeyHitElement = true;
39298
+ event.preventDefault();
39299
+ event.stopPropagation();
39300
+ this.actionManager.executeAction(actionSmartZoom, "keyboard", [
39301
+ hitElement
39302
+ ]);
39303
+ return;
39304
+ }
39305
+ }
39115
39306
  const imageStatusAction = this.getImageStatusActionAtPosition(scenePointer);
39116
39307
  if (imageStatusAction) {
39117
39308
  event.preventDefault();
@@ -39902,6 +40093,10 @@ var App = class _App extends React41.Component {
39902
40093
  hoveredElementIds: updateStable(prevState.hoveredElementIds, {})
39903
40094
  }));
39904
40095
  }
40096
+ this.updateSmartZoomCursor({
40097
+ x: scenePointerX,
40098
+ y: scenePointerY
40099
+ });
39905
40100
  });
39906
40101
  __publicField(this, "handleEraser", (event, scenePointer) => {
39907
40102
  const elementsToErase = this.eraserTrail.addPointToPath(
@@ -39945,6 +40140,9 @@ var App = class _App extends React41.Component {
39945
40140
  x: scenePointerX,
39946
40141
  y: scenePointerY
39947
40142
  };
40143
+ if (this.handleSmartZoomPointerDown(event, scenePointer)) {
40144
+ return;
40145
+ }
39948
40146
  const target = event.target;
39949
40147
  if (target.setPointerCapture) {
39950
40148
  target.setPointerCapture(event.pointerId);
@@ -43101,7 +43299,7 @@ var App = class _App extends React41.Component {
43101
43299
  return /* @__PURE__ */ jsx139(
43102
43300
  "div",
43103
43301
  {
43104
- className: clsx61("excalidraw__embeddable-container", {
43302
+ className: clsx62("excalidraw__embeddable-container", {
43105
43303
  "is-hovered": isHovered
43106
43304
  }),
43107
43305
  style: {
@@ -43218,7 +43416,7 @@ var App = class _App extends React41.Component {
43218
43416
  "div",
43219
43417
  {
43220
43418
  translate: "no",
43221
- className: clsx61(
43419
+ className: clsx62(
43222
43420
  "excalidraw excalidraw-container notranslate",
43223
43421
  this.props.className,
43224
43422
  {
@@ -43929,6 +44127,19 @@ var App = class _App extends React41.Component {
43929
44127
  return;
43930
44128
  }
43931
44129
  }
44130
+ if (data.elements) {
44131
+ const elements = data.programmaticAPI ? convertToExcalidrawElements(
44132
+ data.elements
44133
+ ) : data.elements;
44134
+ this.addElementsFromPasteOrLibrary({
44135
+ elements,
44136
+ files: data.files || null,
44137
+ position: this.editorInterface.formFactor === "desktop" ? "cursor" : "center",
44138
+ retainSeed: isPlainPaste,
44139
+ preserveFrameChildrenOrder: true
44140
+ });
44141
+ return;
44142
+ }
43932
44143
  const imageFiles = dataTransferFiles.map((data2) => data2.file);
43933
44144
  if (imageFiles.length === 0 && data.text && !isPlainPaste) {
43934
44145
  const trimmedText = data.text.trim();
@@ -43944,19 +44155,6 @@ var App = class _App extends React41.Component {
43944
44155
  }
43945
44156
  return;
43946
44157
  }
43947
- if (data.elements) {
43948
- const elements = data.programmaticAPI ? convertToExcalidrawElements(
43949
- data.elements
43950
- ) : data.elements;
43951
- this.addElementsFromPasteOrLibrary({
43952
- elements,
43953
- files: data.files || null,
43954
- position: this.editorInterface.formFactor === "desktop" ? "cursor" : "center",
43955
- retainSeed: isPlainPaste,
43956
- preserveFrameChildrenOrder: true
43957
- });
43958
- return;
43959
- }
43960
44158
  if (!data.text) {
43961
44159
  return;
43962
44160
  }
@@ -46219,7 +46417,7 @@ var InitializeApp = (props) => {
46219
46417
  };
46220
46418
 
46221
46419
  // components/footer/FooterCenter.tsx
46222
- import clsx62 from "clsx";
46420
+ import clsx63 from "clsx";
46223
46421
  import { jsx as jsx141 } from "react/jsx-runtime";
46224
46422
  var FooterCenter = ({ children }) => {
46225
46423
  const { FooterCenterTunnel } = useTunnels();
@@ -46227,7 +46425,7 @@ var FooterCenter = ({ children }) => {
46227
46425
  return /* @__PURE__ */ jsx141(FooterCenterTunnel.In, { children: /* @__PURE__ */ jsx141(
46228
46426
  "div",
46229
46427
  {
46230
- className: clsx62("footer-center zen-mode-transition", {
46428
+ className: clsx63("footer-center zen-mode-transition", {
46231
46429
  "layer-ui__wrapper__footer-left--transition-bottom": appState.zenModeEnabled
46232
46430
  }),
46233
46431
  children
@@ -46238,7 +46436,7 @@ var FooterCenter_default = FooterCenter;
46238
46436
  FooterCenter.displayName = "FooterCenter";
46239
46437
 
46240
46438
  // components/live-collaboration/LiveCollaborationTrigger.tsx
46241
- import clsx63 from "clsx";
46439
+ import clsx64 from "clsx";
46242
46440
  import { MQ_MIN_WIDTH_DESKTOP } from "@excalidraw/common";
46243
46441
  import { jsx as jsx142, jsxs as jsxs71 } from "react/jsx-runtime";
46244
46442
  var LiveCollaborationTrigger2 = ({
@@ -46253,7 +46451,7 @@ var LiveCollaborationTrigger2 = ({
46253
46451
  Button,
46254
46452
  {
46255
46453
  ...rest,
46256
- className: clsx63("collab-button", { active: isCollaborating }),
46454
+ className: clsx64("collab-button", { active: isCollaborating }),
46257
46455
  type: "button",
46258
46456
  onSelect,
46259
46457
  style: { position: "relative", width: showIconOnly ? void 0 : "auto" },