@haoxin-web/excalidraw 1.0.21 → 1.0.22

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.
package/dist/dev/index.js CHANGED
@@ -69,10 +69,10 @@ import {
69
69
  serializeLibraryAsJSON,
70
70
  strokeEllipseWithRotation,
71
71
  strokeRectWithRotation
72
- } from "./chunk-5LGCONU6.js";
72
+ } from "./chunk-6O5AECJT.js";
73
73
  import {
74
74
  define_import_meta_env_default
75
- } from "./chunk-J55ZSMLS.js";
75
+ } from "./chunk-3WZZNNEO.js";
76
76
  import {
77
77
  en_default
78
78
  } from "./chunk-ZSSURRA2.js";
@@ -86,7 +86,7 @@ import {
86
86
  } from "./chunk-XDFCUUT6.js";
87
87
 
88
88
  // index.tsx
89
- import React48, { useEffect as useEffect49 } from "react";
89
+ import React49, { useEffect as useEffect49 } from "react";
90
90
  import { DEFAULT_UI_OPTIONS, isShallowEqual as isShallowEqual9 } from "@haoxin-web/excalidraw-common";
91
91
 
92
92
  // components/App.tsx
@@ -889,19 +889,42 @@ var CalloutIcon = createIcon(
889
889
  tablerIconProps
890
890
  );
891
891
  var HollowArrowIcon = createIcon(
892
- /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", width: 24, height: 24, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
893
- /* @__PURE__ */ jsx("path", { d: "M12 4l8 8-8 8", fill: "none" }),
894
- /* @__PURE__ */ jsx("line", { x1: "4", y1: "12", x2: "20", y2: "12" })
892
+ /* @__PURE__ */ jsxs("g", { fill: "none", stroke: "currentColor", children: [
893
+ /* @__PURE__ */ jsx(
894
+ "path",
895
+ {
896
+ d: "M6 8 L6 16 L18 16 L18 18 L22 12 L18 6 L18 8 L6 8 Z",
897
+ strokeWidth: "1.5",
898
+ fill: "none"
899
+ }
900
+ ),
901
+ /* @__PURE__ */ jsx(
902
+ "path",
903
+ {
904
+ d: "M7 8.5 L7 15.5 L17 15.5 L17 17 L21 12 L17 7 L17 8.5 L7 8.5 Z",
905
+ strokeWidth: "0.5",
906
+ opacity: "0.3",
907
+ fill: "none"
908
+ }
909
+ )
895
910
  ] }),
896
- modifiedTablerIconProps
911
+ tablerIconProps
897
912
  );
898
913
  var HollowDoubleArrowIcon = createIcon(
899
- /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", width: 24, height: 24, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
900
- /* @__PURE__ */ jsx("path", { d: "M12 4L4 12l8 8", fill: "none" }),
901
- /* @__PURE__ */ jsx("path", { d: "M12 4l8 8-8 8", fill: "none" }),
902
- /* @__PURE__ */ jsx("line", { x1: "4", y1: "12", x2: "20", y2: "12" })
914
+ /* @__PURE__ */ jsxs("g", { fill: "none", stroke: "currentColor", children: [
915
+ /* @__PURE__ */ jsx("path", { d: "M8 8 L8 16 L4 12 L8 8 Z", fill: "none", strokeWidth: "1.5" }),
916
+ /* @__PURE__ */ jsx(
917
+ "path",
918
+ {
919
+ d: "M8 10 L16 10 M8 14 L16 14",
920
+ fill: "none",
921
+ strokeLinecap: "round",
922
+ strokeWidth: "1.5"
923
+ }
924
+ ),
925
+ /* @__PURE__ */ jsx("path", { d: "M16 8 L16 16 L20 12 L16 8 Z", strokeWidth: "1.5", fill: "none" })
903
926
  ] }),
904
- modifiedTablerIconProps
927
+ tablerIconProps
905
928
  );
906
929
  var ArrowIcon = createIcon(
907
930
  /* @__PURE__ */ jsxs("g", { strokeWidth: "1.5", children: [
@@ -2415,18 +2438,38 @@ var ArrowRightIcon = createIcon(
2415
2438
  modifiedTablerIconProps
2416
2439
  );
2417
2440
  var OutlineArrowIcon = createIcon(
2418
- /* @__PURE__ */ jsxs("g", { strokeWidth: 1.5, fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", children: [
2419
- /* @__PURE__ */ jsx("path", { d: "M5 12h10" }),
2420
- /* @__PURE__ */ jsx("path", { d: "M11 8l4 4l-4 4" })
2421
- ] }),
2441
+ /* @__PURE__ */ jsxs(
2442
+ "g",
2443
+ {
2444
+ strokeWidth: 1.5,
2445
+ fill: "none",
2446
+ stroke: "currentColor",
2447
+ strokeLinecap: "round",
2448
+ strokeLinejoin: "round",
2449
+ children: [
2450
+ /* @__PURE__ */ jsx("path", { d: "M5 12h10" }),
2451
+ /* @__PURE__ */ jsx("path", { d: "M11 8l4 4l-4 4" })
2452
+ ]
2453
+ }
2454
+ ),
2422
2455
  tablerIconProps
2423
2456
  );
2424
2457
  var OutlineDoubleArrowIcon = createIcon(
2425
- /* @__PURE__ */ jsxs("g", { strokeWidth: 1.5, fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", children: [
2426
- /* @__PURE__ */ jsx("path", { d: "M5 12h14" }),
2427
- /* @__PURE__ */ jsx("path", { d: "M9 8l-4 4l4 4" }),
2428
- /* @__PURE__ */ jsx("path", { d: "M15 8l4 4l-4 4" })
2429
- ] }),
2458
+ /* @__PURE__ */ jsxs(
2459
+ "g",
2460
+ {
2461
+ strokeWidth: 1.5,
2462
+ fill: "none",
2463
+ stroke: "currentColor",
2464
+ strokeLinecap: "round",
2465
+ strokeLinejoin: "round",
2466
+ children: [
2467
+ /* @__PURE__ */ jsx("path", { d: "M5 12h14" }),
2468
+ /* @__PURE__ */ jsx("path", { d: "M9 8l-4 4l4 4" }),
2469
+ /* @__PURE__ */ jsx("path", { d: "M15 8l4 4l-4 4" })
2470
+ ]
2471
+ }
2472
+ ),
2430
2473
  tablerIconProps
2431
2474
  );
2432
2475
  var laserPointerToolIcon = createIcon(
@@ -9180,7 +9223,7 @@ var exportCanvas = async (type, elements, appState, files, {
9180
9223
  let blob = canvasToBlob(tempCanvas);
9181
9224
  if (appState.exportEmbedScene) {
9182
9225
  blob = blob.then(
9183
- (blob2) => import("./data/image-4T2DPV7H.js").then(
9226
+ (blob2) => import("./data/image-WA2QOHGD.js").then(
9184
9227
  ({ encodePngMetadata: encodePngMetadata2 }) => encodePngMetadata2({
9185
9228
  blob: blob2,
9186
9229
  metadata: serializeAsJSON(elements, appState, files, "local")
@@ -25763,8 +25806,16 @@ var MainMenu_default = MainMenu;
25763
25806
  import { useEffect as useEffect33, useRef as useRef28, useState as useState27 } from "react";
25764
25807
  import clsx46 from "clsx";
25765
25808
  import { isTextElement as isTextElement14 } from "@haoxin-web/excalidraw-element";
25766
- import { getBoundTextElement as getBoundTextElement9, getContainerElement as getContainerElement5, redrawTextBoundingBox as redrawTextBoundingBox7, newElementWith as newElementWith11 } from "@haoxin-web/excalidraw-element";
25767
- import { DEFAULT_ELEMENT_STROKE_COLOR_PALETTE as DEFAULT_ELEMENT_STROKE_COLOR_PALETTE2, STROKE_WIDTH as STROKE_WIDTH2 } from "@haoxin-web/excalidraw-common";
25809
+ import {
25810
+ getBoundTextElement as getBoundTextElement9,
25811
+ getContainerElement as getContainerElement5,
25812
+ redrawTextBoundingBox as redrawTextBoundingBox7,
25813
+ newElementWith as newElementWith11
25814
+ } from "@haoxin-web/excalidraw-element";
25815
+ import {
25816
+ DEFAULT_ELEMENT_STROKE_COLOR_PALETTE as DEFAULT_ELEMENT_STROKE_COLOR_PALETTE2,
25817
+ STROKE_WIDTH as STROKE_WIDTH2
25818
+ } from "@haoxin-web/excalidraw-common";
25768
25819
  import { jsx as jsx108, jsxs as jsxs60 } from "react/jsx-runtime";
25769
25820
  var LeftToolFlyouts = ({
25770
25821
  appState,
@@ -25898,7 +25949,25 @@ var LeftToolFlyouts = ({
25898
25949
  const selected = elements.find((el) => selectedIds[el.id]);
25899
25950
  const selectedType = selected?.type;
25900
25951
  const openForLineGroup = openGroup === "line" && (activeTool === "line" || activeTool === "arrow" || selectedType === "line" || selectedType === "arrow");
25901
- const openForShapesGroup = openGroup === "shapes" && ["rectangle", "diamond", "ellipse", "triangle", "pentagon", "callout", "hollow_arrow", "hollow_double_arrow"].includes(activeTool) || openGroup === "shapes" && ["rectangle", "diamond", "ellipse", "triangle", "pentagon", "callout", "hollow_arrow", "hollow_double_arrow"].includes(selectedType);
25952
+ const openForShapesGroup = openGroup === "shapes" && [
25953
+ "rectangle",
25954
+ "diamond",
25955
+ "ellipse",
25956
+ "triangle",
25957
+ "pentagon",
25958
+ "callout",
25959
+ "hollow_arrow",
25960
+ "hollow_double_arrow"
25961
+ ].includes(activeTool) || openGroup === "shapes" && [
25962
+ "rectangle",
25963
+ "diamond",
25964
+ "ellipse",
25965
+ "triangle",
25966
+ "pentagon",
25967
+ "callout",
25968
+ "hollow_arrow",
25969
+ "hollow_double_arrow"
25970
+ ].includes(selectedType);
25902
25971
  const openForText = openGroup === "text" && (activeTool === "text" || selectedType === "text");
25903
25972
  const openForFreedraw = openGroup === "freedraw" && (activeTool === "freedraw" || selectedType === "freedraw");
25904
25973
  const isHighlighter = (appState.currentItemOpacity ?? 100) < 100;
@@ -25939,14 +26008,20 @@ var LeftToolFlyouts = ({
25939
26008
  }
25940
26009
  });
25941
26010
  nextMap.set(updated.id, updated);
25942
- const container = getContainerElement5(updated, app.scene.getNonDeletedElementsMap());
26011
+ const container = getContainerElement5(
26012
+ updated,
26013
+ app.scene.getNonDeletedElementsMap()
26014
+ );
25943
26015
  redrawTextBoundingBox7(updated, container, app.scene);
25944
26016
  };
25945
26017
  for (const el of selected2) {
25946
26018
  if (isTextElement14(el)) {
25947
26019
  applyTo(el);
25948
26020
  } else {
25949
- const bound = getBoundTextElement9(el, app.scene.getNonDeletedElementsMap());
26021
+ const bound = getBoundTextElement9(
26022
+ el,
26023
+ app.scene.getNonDeletedElementsMap()
26024
+ );
25950
26025
  if (bound) {
25951
26026
  applyTo(bound);
25952
26027
  }
@@ -25973,19 +26048,31 @@ var LeftToolFlyouts = ({
25973
26048
  app.setActiveTool({ type: "line", locked: true });
25974
26049
  } else if (type === "arrow") {
25975
26050
  app.setActiveTool({ type: "arrow", locked: true });
25976
- app.setState({ currentItemStartArrowhead: null, currentItemEndArrowhead: "arrow" });
26051
+ app.setState({
26052
+ currentItemStartArrowhead: null,
26053
+ currentItemEndArrowhead: "arrow"
26054
+ });
25977
26055
  } else {
25978
26056
  app.setActiveTool({ type: "arrow", locked: true });
25979
- app.setState({ currentItemStartArrowhead: "arrow", currentItemEndArrowhead: "arrow" });
26057
+ app.setState({
26058
+ currentItemStartArrowhead: "arrow",
26059
+ currentItemEndArrowhead: "arrow"
26060
+ });
25980
26061
  }
25981
26062
  };
25982
26063
  const setArrowTypeOutline = (type) => {
25983
26064
  if (type === "arrow") {
25984
26065
  app.setActiveTool({ type: "arrow", locked: true });
25985
- app.setState({ currentItemStartArrowhead: null, currentItemEndArrowhead: "triangle_outline" });
26066
+ app.setState({
26067
+ currentItemStartArrowhead: null,
26068
+ currentItemEndArrowhead: "triangle_outline"
26069
+ });
25986
26070
  } else {
25987
26071
  app.setActiveTool({ type: "arrow", locked: true });
25988
- app.setState({ currentItemStartArrowhead: "triangle_outline", currentItemEndArrowhead: "triangle_outline" });
26072
+ app.setState({
26073
+ currentItemStartArrowhead: "triangle_outline",
26074
+ currentItemEndArrowhead: "triangle_outline"
26075
+ });
25989
26076
  }
25990
26077
  };
25991
26078
  const renderStrokeColor = () => {
@@ -26008,7 +26095,11 @@ var LeftToolFlyouts = ({
26008
26095
  elements,
26009
26096
  appState,
26010
26097
  palette: DEFAULT_ELEMENT_STROKE_COLOR_PALETTE2,
26011
- updateData: (formData) => actionManager.executeAction(actionChangeStrokeColor, "ui", formData)
26098
+ updateData: (formData) => actionManager.executeAction(
26099
+ actionChangeStrokeColor,
26100
+ "ui",
26101
+ formData
26102
+ )
26012
26103
  }
26013
26104
  );
26014
26105
  };
@@ -26060,44 +26151,63 @@ var LeftToolFlyouts = ({
26060
26151
  ] }),
26061
26152
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__separator" }),
26062
26153
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__title", children: t("labels.strokeWidth") }),
26063
- /* @__PURE__ */ jsxs60("div", { className: "buttonList", style: { display: "flex", gap: 6, justifyContent: "center" }, children: [
26064
- /* @__PURE__ */ jsx108(
26065
- ToolButton,
26066
- {
26067
- type: "icon",
26068
- "aria-label": t("labels.thin"),
26069
- icon: StrokeWidthBaseIcon,
26070
- selected: selectedStrokeWidth === STROKE_WIDTH2.thin,
26071
- name: "left-flyout-line-strokeWidth",
26072
- title: t("labels.thin"),
26073
- onClick: () => actionManager.executeAction(actionChangeStrokeWidth, "ui", STROKE_WIDTH2.thin)
26074
- }
26075
- ),
26076
- /* @__PURE__ */ jsx108(
26077
- ToolButton,
26078
- {
26079
- type: "icon",
26080
- "aria-label": t("labels.bold"),
26081
- icon: StrokeWidthBoldIcon,
26082
- selected: selectedStrokeWidth === STROKE_WIDTH2.bold,
26083
- name: "left-flyout-line-strokeWidth",
26084
- title: t("labels.bold"),
26085
- onClick: () => actionManager.executeAction(actionChangeStrokeWidth, "ui", STROKE_WIDTH2.bold)
26086
- }
26087
- ),
26088
- /* @__PURE__ */ jsx108(
26089
- ToolButton,
26090
- {
26091
- type: "icon",
26092
- "aria-label": t("labels.extraBold"),
26093
- icon: StrokeWidthExtraBoldIcon,
26094
- selected: selectedStrokeWidth === STROKE_WIDTH2.extraBold,
26095
- name: "left-flyout-line-strokeWidth",
26096
- title: t("labels.extraBold"),
26097
- onClick: () => actionManager.executeAction(actionChangeStrokeWidth, "ui", STROKE_WIDTH2.extraBold)
26098
- }
26099
- )
26100
- ] }),
26154
+ /* @__PURE__ */ jsxs60(
26155
+ "div",
26156
+ {
26157
+ className: "buttonList",
26158
+ style: { display: "flex", gap: 6, justifyContent: "center" },
26159
+ children: [
26160
+ /* @__PURE__ */ jsx108(
26161
+ ToolButton,
26162
+ {
26163
+ type: "icon",
26164
+ "aria-label": t("labels.thin"),
26165
+ icon: StrokeWidthBaseIcon,
26166
+ selected: selectedStrokeWidth === STROKE_WIDTH2.thin,
26167
+ name: "left-flyout-line-strokeWidth",
26168
+ title: t("labels.thin"),
26169
+ onClick: () => actionManager.executeAction(
26170
+ actionChangeStrokeWidth,
26171
+ "ui",
26172
+ STROKE_WIDTH2.thin
26173
+ )
26174
+ }
26175
+ ),
26176
+ /* @__PURE__ */ jsx108(
26177
+ ToolButton,
26178
+ {
26179
+ type: "icon",
26180
+ "aria-label": t("labels.bold"),
26181
+ icon: StrokeWidthBoldIcon,
26182
+ selected: selectedStrokeWidth === STROKE_WIDTH2.bold,
26183
+ name: "left-flyout-line-strokeWidth",
26184
+ title: t("labels.bold"),
26185
+ onClick: () => actionManager.executeAction(
26186
+ actionChangeStrokeWidth,
26187
+ "ui",
26188
+ STROKE_WIDTH2.bold
26189
+ )
26190
+ }
26191
+ ),
26192
+ /* @__PURE__ */ jsx108(
26193
+ ToolButton,
26194
+ {
26195
+ type: "icon",
26196
+ "aria-label": t("labels.extraBold"),
26197
+ icon: StrokeWidthExtraBoldIcon,
26198
+ selected: selectedStrokeWidth === STROKE_WIDTH2.extraBold,
26199
+ name: "left-flyout-line-strokeWidth",
26200
+ title: t("labels.extraBold"),
26201
+ onClick: () => actionManager.executeAction(
26202
+ actionChangeStrokeWidth,
26203
+ "ui",
26204
+ STROKE_WIDTH2.extraBold
26205
+ )
26206
+ }
26207
+ )
26208
+ ]
26209
+ }
26210
+ ),
26101
26211
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__title", children: "\u989C\u8272" }),
26102
26212
  renderStrokeColor()
26103
26213
  ] }) }),
@@ -26131,68 +26241,111 @@ var LeftToolFlyouts = ({
26131
26241
  };
26132
26242
  return null;
26133
26243
  })(),
26134
- /* @__PURE__ */ jsxs60("div", { className: "shapes-grid", style: { gridTemplateColumns: "repeat(5, 1fr)" }, children: [
26135
- /* @__PURE__ */ jsx108(
26136
- ToolButton,
26137
- {
26138
- type: "radio",
26139
- "aria-label": t("toolBar.rectangle"),
26140
- icon: RectangleIcon,
26141
- checked: activeTool === "rectangle",
26142
- name: "left-flyout-shapes",
26143
- title: t("toolBar.rectangle"),
26144
- onChange: () => app.setActiveTool({ type: "rectangle", locked: true })
26145
- }
26146
- ),
26147
- /* @__PURE__ */ jsx108(
26148
- ToolButton,
26149
- {
26150
- type: "radio",
26151
- "aria-label": t("toolBar.ellipse"),
26152
- icon: EllipseIcon,
26153
- checked: activeTool === "ellipse",
26154
- name: "left-flyout-shapes",
26155
- title: t("toolBar.ellipse"),
26156
- onChange: () => app.setActiveTool({ type: "ellipse", locked: true })
26157
- }
26158
- ),
26159
- /* @__PURE__ */ jsx108(
26160
- ToolButton,
26161
- {
26162
- type: "radio",
26163
- "aria-label": t("toolBar.diamond"),
26164
- icon: DiamondIcon,
26165
- checked: activeTool === "diamond",
26166
- name: "left-flyout-shapes",
26167
- title: t("toolBar.diamond"),
26168
- onChange: () => app.setActiveTool({ type: "diamond", locked: true })
26169
- }
26170
- ),
26171
- /* @__PURE__ */ jsx108(
26172
- ToolButton,
26173
- {
26174
- type: "radio",
26175
- "aria-label": t("toolBar.triangle"),
26176
- icon: TriangleIcon,
26177
- checked: activeTool === "triangle",
26178
- name: "left-flyout-shapes",
26179
- title: t("toolBar.triangle"),
26180
- onChange: () => app.setActiveTool({ type: "triangle", locked: true })
26181
- }
26182
- ),
26183
- /* @__PURE__ */ jsx108(
26184
- ToolButton,
26185
- {
26186
- type: "radio",
26187
- "aria-label": t("toolBar.pentagon"),
26188
- icon: PentagonIcon,
26189
- checked: activeTool === "pentagon",
26190
- name: "left-flyout-shapes",
26191
- title: t("toolBar.pentagon"),
26192
- onChange: () => app.setActiveTool({ type: "pentagon", locked: true })
26193
- }
26194
- )
26195
- ] }),
26244
+ /* @__PURE__ */ jsxs60(
26245
+ "div",
26246
+ {
26247
+ className: "shapes-grid",
26248
+ style: { gridTemplateColumns: "repeat(5, 1fr)" },
26249
+ children: [
26250
+ /* @__PURE__ */ jsx108(
26251
+ ToolButton,
26252
+ {
26253
+ type: "radio",
26254
+ "aria-label": t("toolBar.rectangle"),
26255
+ icon: RectangleIcon,
26256
+ checked: activeTool === "rectangle",
26257
+ name: "left-flyout-shapes",
26258
+ title: t("toolBar.rectangle"),
26259
+ onChange: () => app.setActiveTool({ type: "rectangle", locked: true })
26260
+ }
26261
+ ),
26262
+ /* @__PURE__ */ jsx108(
26263
+ ToolButton,
26264
+ {
26265
+ type: "radio",
26266
+ "aria-label": t("toolBar.ellipse"),
26267
+ icon: EllipseIcon,
26268
+ checked: activeTool === "ellipse",
26269
+ name: "left-flyout-shapes",
26270
+ title: t("toolBar.ellipse"),
26271
+ onChange: () => app.setActiveTool({ type: "ellipse", locked: true })
26272
+ }
26273
+ ),
26274
+ /* @__PURE__ */ jsx108(
26275
+ ToolButton,
26276
+ {
26277
+ type: "radio",
26278
+ "aria-label": t("toolBar.diamond"),
26279
+ icon: DiamondIcon,
26280
+ checked: activeTool === "diamond",
26281
+ name: "left-flyout-shapes",
26282
+ title: t("toolBar.diamond"),
26283
+ onChange: () => app.setActiveTool({ type: "diamond", locked: true })
26284
+ }
26285
+ ),
26286
+ /* @__PURE__ */ jsx108(
26287
+ ToolButton,
26288
+ {
26289
+ type: "radio",
26290
+ "aria-label": t("toolBar.triangle"),
26291
+ icon: TriangleIcon,
26292
+ checked: activeTool === "triangle",
26293
+ name: "left-flyout-shapes",
26294
+ title: t("toolBar.triangle"),
26295
+ onChange: () => app.setActiveTool({ type: "triangle", locked: true })
26296
+ }
26297
+ ),
26298
+ /* @__PURE__ */ jsx108(
26299
+ ToolButton,
26300
+ {
26301
+ type: "radio",
26302
+ "aria-label": t("toolBar.pentagon"),
26303
+ icon: PentagonIcon,
26304
+ checked: activeTool === "pentagon",
26305
+ name: "left-flyout-shapes",
26306
+ title: t("toolBar.pentagon"),
26307
+ onChange: () => app.setActiveTool({ type: "pentagon", locked: true })
26308
+ }
26309
+ ),
26310
+ /* @__PURE__ */ jsx108(
26311
+ ToolButton,
26312
+ {
26313
+ type: "radio",
26314
+ "aria-label": t("toolBar.callout"),
26315
+ icon: CalloutIcon,
26316
+ checked: activeTool === "callout",
26317
+ name: "left-flyout-shapes",
26318
+ title: t("toolBar.callout"),
26319
+ onChange: () => app.setActiveTool({ type: "callout" })
26320
+ }
26321
+ ),
26322
+ /* @__PURE__ */ jsx108(
26323
+ ToolButton,
26324
+ {
26325
+ type: "radio",
26326
+ "aria-label": t("toolBar.hollowArrow"),
26327
+ icon: HollowArrowIcon,
26328
+ checked: activeTool === "hollow_arrow",
26329
+ name: "left-flyout-shapes",
26330
+ title: t("toolBar.hollowArrow"),
26331
+ onChange: () => app.setActiveTool({ type: "hollow_arrow" })
26332
+ }
26333
+ ),
26334
+ /* @__PURE__ */ jsx108(
26335
+ ToolButton,
26336
+ {
26337
+ type: "radio",
26338
+ "aria-label": t("toolBar.hollowDoubleArrow"),
26339
+ icon: HollowDoubleArrowIcon,
26340
+ checked: activeTool === "hollow_double_arrow",
26341
+ name: "left-flyout-shapes",
26342
+ title: t("toolBar.hollowDoubleArrow"),
26343
+ onChange: () => app.setActiveTool({ type: "hollow_double_arrow" })
26344
+ }
26345
+ )
26346
+ ]
26347
+ }
26348
+ ),
26196
26349
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__separator" }),
26197
26350
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__title", style: { marginTop: 8 }, children: t("labels.stroke") }),
26198
26351
  renderStrokeColor(),
@@ -26209,12 +26362,20 @@ var LeftToolFlyouts = ({
26209
26362
  true,
26210
26363
  (hasSelection) => !hasSelection ? appState.currentItemBackgroundColor : null
26211
26364
  ),
26212
- onChange: (color) => actionManager.executeAction(actionChangeBackgroundColor, "ui", {
26213
- currentItemBackgroundColor: color
26214
- }),
26365
+ onChange: (color) => actionManager.executeAction(
26366
+ actionChangeBackgroundColor,
26367
+ "ui",
26368
+ {
26369
+ currentItemBackgroundColor: color
26370
+ }
26371
+ ),
26215
26372
  elements,
26216
26373
  appState,
26217
- updateData: (formData) => actionManager.executeAction(actionChangeBackgroundColor, "ui", formData)
26374
+ updateData: (formData) => actionManager.executeAction(
26375
+ actionChangeBackgroundColor,
26376
+ "ui",
26377
+ formData
26378
+ )
26218
26379
  }
26219
26380
  ),
26220
26381
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__title", style: { marginTop: 6 }, children: t("labels.fill") }),
@@ -26232,83 +26393,121 @@ var LeftToolFlyouts = ({
26232
26393
  };
26233
26394
  return null;
26234
26395
  })(),
26235
- /* @__PURE__ */ jsxs60("div", { className: "buttonList", style: { display: "flex", gap: 6, justifyContent: "center" }, children: [
26236
- /* @__PURE__ */ jsx108(
26237
- ToolButton,
26238
- {
26239
- type: "icon",
26240
- "aria-label": t("labels.hachure"),
26241
- icon: FillHachureIcon,
26242
- selected: globalThis.__leftShapesFormCache?.fillStyleValue === "hachure",
26243
- name: "left-flyout-fillStyle",
26244
- title: t("labels.hachure"),
26245
- onClick: () => actionManager.executeAction(actionChangeFillStyle, "ui", "hachure")
26246
- }
26247
- ),
26248
- /* @__PURE__ */ jsx108(
26249
- ToolButton,
26250
- {
26251
- type: "icon",
26252
- "aria-label": t("labels.crossHatch"),
26253
- icon: FillCrossHatchIcon,
26254
- selected: globalThis.__leftShapesFormCache?.fillStyleValue === "cross-hatch",
26255
- name: "left-flyout-fillStyle",
26256
- title: t("labels.crossHatch"),
26257
- onClick: () => actionManager.executeAction(actionChangeFillStyle, "ui", "cross-hatch")
26258
- }
26259
- ),
26260
- /* @__PURE__ */ jsx108(
26261
- ToolButton,
26262
- {
26263
- type: "icon",
26264
- "aria-label": t("labels.solid"),
26265
- icon: FillSolidIcon,
26266
- selected: globalThis.__leftShapesFormCache?.fillStyleValue === "solid",
26267
- name: "left-flyout-fillStyle",
26268
- title: t("labels.solid"),
26269
- onClick: () => actionManager.executeAction(actionChangeFillStyle, "ui", "solid")
26270
- }
26271
- )
26272
- ] }),
26396
+ /* @__PURE__ */ jsxs60(
26397
+ "div",
26398
+ {
26399
+ className: "buttonList",
26400
+ style: { display: "flex", gap: 6, justifyContent: "center" },
26401
+ children: [
26402
+ /* @__PURE__ */ jsx108(
26403
+ ToolButton,
26404
+ {
26405
+ type: "icon",
26406
+ "aria-label": t("labels.hachure"),
26407
+ icon: FillHachureIcon,
26408
+ selected: globalThis.__leftShapesFormCache?.fillStyleValue === "hachure",
26409
+ name: "left-flyout-fillStyle",
26410
+ title: t("labels.hachure"),
26411
+ onClick: () => actionManager.executeAction(
26412
+ actionChangeFillStyle,
26413
+ "ui",
26414
+ "hachure"
26415
+ )
26416
+ }
26417
+ ),
26418
+ /* @__PURE__ */ jsx108(
26419
+ ToolButton,
26420
+ {
26421
+ type: "icon",
26422
+ "aria-label": t("labels.crossHatch"),
26423
+ icon: FillCrossHatchIcon,
26424
+ selected: globalThis.__leftShapesFormCache?.fillStyleValue === "cross-hatch",
26425
+ name: "left-flyout-fillStyle",
26426
+ title: t("labels.crossHatch"),
26427
+ onClick: () => actionManager.executeAction(
26428
+ actionChangeFillStyle,
26429
+ "ui",
26430
+ "cross-hatch"
26431
+ )
26432
+ }
26433
+ ),
26434
+ /* @__PURE__ */ jsx108(
26435
+ ToolButton,
26436
+ {
26437
+ type: "icon",
26438
+ "aria-label": t("labels.solid"),
26439
+ icon: FillSolidIcon,
26440
+ selected: globalThis.__leftShapesFormCache?.fillStyleValue === "solid",
26441
+ name: "left-flyout-fillStyle",
26442
+ title: t("labels.solid"),
26443
+ onClick: () => actionManager.executeAction(
26444
+ actionChangeFillStyle,
26445
+ "ui",
26446
+ "solid"
26447
+ )
26448
+ }
26449
+ )
26450
+ ]
26451
+ }
26452
+ ),
26273
26453
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__title", children: t("labels.strokeWidth") }),
26274
- /* @__PURE__ */ jsxs60("div", { className: "buttonList", style: { display: "flex", gap: 6, justifyContent: "center" }, children: [
26275
- /* @__PURE__ */ jsx108(
26276
- ToolButton,
26277
- {
26278
- type: "icon",
26279
- "aria-label": t("labels.thin"),
26280
- icon: StrokeWidthBaseIcon,
26281
- selected: selectedStrokeWidth === STROKE_WIDTH2.thin,
26282
- name: "left-flyout-strokeWidth",
26283
- title: t("labels.thin"),
26284
- onClick: () => actionManager.executeAction(actionChangeStrokeWidth, "ui", STROKE_WIDTH2.thin)
26285
- }
26286
- ),
26287
- /* @__PURE__ */ jsx108(
26288
- ToolButton,
26289
- {
26290
- type: "icon",
26291
- "aria-label": t("labels.bold"),
26292
- icon: StrokeWidthBoldIcon,
26293
- selected: selectedStrokeWidth === STROKE_WIDTH2.bold,
26294
- name: "left-flyout-strokeWidth",
26295
- title: t("labels.bold"),
26296
- onClick: () => actionManager.executeAction(actionChangeStrokeWidth, "ui", STROKE_WIDTH2.bold)
26297
- }
26298
- ),
26299
- /* @__PURE__ */ jsx108(
26300
- ToolButton,
26301
- {
26302
- type: "icon",
26303
- "aria-label": t("labels.extraBold"),
26304
- icon: StrokeWidthExtraBoldIcon,
26305
- selected: selectedStrokeWidth === STROKE_WIDTH2.extraBold,
26306
- name: "left-flyout-strokeWidth",
26307
- title: t("labels.extraBold"),
26308
- onClick: () => actionManager.executeAction(actionChangeStrokeWidth, "ui", STROKE_WIDTH2.extraBold)
26309
- }
26310
- )
26311
- ] })
26454
+ /* @__PURE__ */ jsxs60(
26455
+ "div",
26456
+ {
26457
+ className: "buttonList",
26458
+ style: { display: "flex", gap: 6, justifyContent: "center" },
26459
+ children: [
26460
+ /* @__PURE__ */ jsx108(
26461
+ ToolButton,
26462
+ {
26463
+ type: "icon",
26464
+ "aria-label": t("labels.thin"),
26465
+ icon: StrokeWidthBaseIcon,
26466
+ selected: selectedStrokeWidth === STROKE_WIDTH2.thin,
26467
+ name: "left-flyout-strokeWidth",
26468
+ title: t("labels.thin"),
26469
+ onClick: () => actionManager.executeAction(
26470
+ actionChangeStrokeWidth,
26471
+ "ui",
26472
+ STROKE_WIDTH2.thin
26473
+ )
26474
+ }
26475
+ ),
26476
+ /* @__PURE__ */ jsx108(
26477
+ ToolButton,
26478
+ {
26479
+ type: "icon",
26480
+ "aria-label": t("labels.bold"),
26481
+ icon: StrokeWidthBoldIcon,
26482
+ selected: selectedStrokeWidth === STROKE_WIDTH2.bold,
26483
+ name: "left-flyout-strokeWidth",
26484
+ title: t("labels.bold"),
26485
+ onClick: () => actionManager.executeAction(
26486
+ actionChangeStrokeWidth,
26487
+ "ui",
26488
+ STROKE_WIDTH2.bold
26489
+ )
26490
+ }
26491
+ ),
26492
+ /* @__PURE__ */ jsx108(
26493
+ ToolButton,
26494
+ {
26495
+ type: "icon",
26496
+ "aria-label": t("labels.extraBold"),
26497
+ icon: StrokeWidthExtraBoldIcon,
26498
+ selected: selectedStrokeWidth === STROKE_WIDTH2.extraBold,
26499
+ name: "left-flyout-strokeWidth",
26500
+ title: t("labels.extraBold"),
26501
+ onClick: () => actionManager.executeAction(
26502
+ actionChangeStrokeWidth,
26503
+ "ui",
26504
+ STROKE_WIDTH2.extraBold
26505
+ )
26506
+ }
26507
+ )
26508
+ ]
26509
+ }
26510
+ )
26312
26511
  ] }),
26313
26512
  openForText && /* @__PURE__ */ jsx108(Island, { className: "left-flyout left-flyout--text", children: /* @__PURE__ */ jsxs60(Stack_default.Col, { gap: 2, align: "center", children: [
26314
26513
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__title", children: "\u6837\u5F0F" }),
@@ -26325,7 +26524,9 @@ var LeftToolFlyouts = ({
26325
26524
  const value = !appState.currentTextBold;
26326
26525
  app.setState({ currentTextBold: value });
26327
26526
  syncWysiwygStyle();
26328
- updateSelectedTextStyle({ bold: !appState.currentTextBold });
26527
+ updateSelectedTextStyle({
26528
+ bold: !appState.currentTextBold
26529
+ });
26329
26530
  updateCurrentTextDefaults({ bold: value });
26330
26531
  }
26331
26532
  }
@@ -26342,7 +26543,9 @@ var LeftToolFlyouts = ({
26342
26543
  const value = !appState.currentTextItalic;
26343
26544
  app.setState({ currentTextItalic: value });
26344
26545
  syncWysiwygStyle();
26345
- updateSelectedTextStyle({ italic: !appState.currentTextItalic });
26546
+ updateSelectedTextStyle({
26547
+ italic: !appState.currentTextItalic
26548
+ });
26346
26549
  updateCurrentTextDefaults({ italic: value });
26347
26550
  }
26348
26551
  }
@@ -26387,83 +26590,118 @@ var LeftToolFlyouts = ({
26387
26590
  )
26388
26591
  ] }),
26389
26592
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__title", children: "\u5B57\u53F7" }),
26390
- /* @__PURE__ */ jsx108("div", { className: "text-size-row", style: { display: "flex", gap: 6, alignItems: "center", justifyContent: "center" }, children: [10, 12, 16, 24, 36].map((size) => {
26391
- const selected2 = appState.currentItemFontSize === size;
26392
- return /* @__PURE__ */ jsx108(
26393
- "button",
26394
- {
26395
- className: clsx46("text-size-chip", { selected: selected2 }),
26396
- style: {
26397
- minWidth: 32,
26398
- height: 28,
26399
- padding: "0 10px",
26400
- borderRadius: 8,
26401
- background: selected2 ? "#2178ff" : "transparent",
26402
- color: selected2 ? "#fff" : "var(--text-primary-color)",
26403
- border: selected2 ? "1px solid #2178ff" : "1px solid var(--button-border-color)",
26404
- transition: "background 0.12s ease"
26405
- },
26406
- onMouseEnter: (e) => {
26407
- if (selected2)
26408
- e.currentTarget.style.background = "rgba(33,120,255,0.85)";
26409
- },
26410
- onMouseLeave: (e) => {
26411
- if (selected2)
26412
- e.currentTarget.style.background = "#2178ff";
26413
- },
26414
- onClick: () => {
26415
- actionManager.executeAction(actionChangeFontSize, "ui", size);
26416
- },
26417
- children: /* @__PURE__ */ jsx108("span", { style: { fontSize: 12 }, children: size })
26593
+ /* @__PURE__ */ jsx108(
26594
+ "div",
26595
+ {
26596
+ className: "text-size-row",
26597
+ style: {
26598
+ display: "flex",
26599
+ gap: 6,
26600
+ alignItems: "center",
26601
+ justifyContent: "center"
26418
26602
  },
26419
- size
26420
- );
26421
- }) }),
26603
+ children: [10, 12, 16, 24, 36].map((size) => {
26604
+ const selected2 = appState.currentItemFontSize === size;
26605
+ return /* @__PURE__ */ jsx108(
26606
+ "button",
26607
+ {
26608
+ className: clsx46("text-size-chip", { selected: selected2 }),
26609
+ style: {
26610
+ minWidth: 32,
26611
+ height: 28,
26612
+ padding: "0 10px",
26613
+ borderRadius: 8,
26614
+ background: selected2 ? "#2178ff" : "transparent",
26615
+ color: selected2 ? "#fff" : "var(--text-primary-color)",
26616
+ border: selected2 ? "1px solid #2178ff" : "1px solid var(--button-border-color)",
26617
+ transition: "background 0.12s ease"
26618
+ },
26619
+ onMouseEnter: (e) => {
26620
+ if (selected2)
26621
+ e.currentTarget.style.background = "rgba(33,120,255,0.85)";
26622
+ },
26623
+ onMouseLeave: (e) => {
26624
+ if (selected2)
26625
+ e.currentTarget.style.background = "#2178ff";
26626
+ },
26627
+ onClick: () => {
26628
+ actionManager.executeAction(
26629
+ actionChangeFontSize,
26630
+ "ui",
26631
+ size
26632
+ );
26633
+ },
26634
+ children: /* @__PURE__ */ jsx108("span", { style: { fontSize: 12 }, children: size })
26635
+ },
26636
+ size
26637
+ );
26638
+ })
26639
+ }
26640
+ ),
26422
26641
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__title", children: "\u5BF9\u9F50\u65B9\u5F0F" }),
26423
- /* @__PURE__ */ jsxs60("div", { className: "text-align-row", style: { display: "flex", gap: 6, justifyContent: "center" }, children: [
26424
- /* @__PURE__ */ jsx108(
26425
- ToolButton,
26426
- {
26427
- type: "radio",
26428
- "aria-label": t("labels.left"),
26429
- name: "text-align",
26430
- title: t("labels.left"),
26431
- icon: TextAlignLeftIcon,
26432
- checked: appState.currentItemTextAlign === "left",
26433
- onChange: () => {
26434
- actionManager.executeAction(actionChangeTextAlign, "ui", "left");
26435
- }
26436
- }
26437
- ),
26438
- /* @__PURE__ */ jsx108(
26439
- ToolButton,
26440
- {
26441
- type: "radio",
26442
- "aria-label": t("labels.center"),
26443
- name: "text-align",
26444
- title: t("labels.center"),
26445
- icon: TextAlignCenterIcon,
26446
- checked: appState.currentItemTextAlign === "center",
26447
- onChange: () => {
26448
- actionManager.executeAction(actionChangeTextAlign, "ui", "center");
26449
- }
26450
- }
26451
- ),
26452
- /* @__PURE__ */ jsx108(
26453
- ToolButton,
26454
- {
26455
- type: "radio",
26456
- "aria-label": t("labels.right"),
26457
- name: "text-align",
26458
- title: t("labels.right"),
26459
- icon: TextAlignRightIcon,
26460
- checked: appState.currentItemTextAlign === "right",
26461
- onChange: () => {
26462
- actionManager.executeAction(actionChangeTextAlign, "ui", "right");
26463
- }
26464
- }
26465
- )
26466
- ] }),
26642
+ /* @__PURE__ */ jsxs60(
26643
+ "div",
26644
+ {
26645
+ className: "text-align-row",
26646
+ style: { display: "flex", gap: 6, justifyContent: "center" },
26647
+ children: [
26648
+ /* @__PURE__ */ jsx108(
26649
+ ToolButton,
26650
+ {
26651
+ type: "radio",
26652
+ "aria-label": t("labels.left"),
26653
+ name: "text-align",
26654
+ title: t("labels.left"),
26655
+ icon: TextAlignLeftIcon,
26656
+ checked: appState.currentItemTextAlign === "left",
26657
+ onChange: () => {
26658
+ actionManager.executeAction(
26659
+ actionChangeTextAlign,
26660
+ "ui",
26661
+ "left"
26662
+ );
26663
+ }
26664
+ }
26665
+ ),
26666
+ /* @__PURE__ */ jsx108(
26667
+ ToolButton,
26668
+ {
26669
+ type: "radio",
26670
+ "aria-label": t("labels.center"),
26671
+ name: "text-align",
26672
+ title: t("labels.center"),
26673
+ icon: TextAlignCenterIcon,
26674
+ checked: appState.currentItemTextAlign === "center",
26675
+ onChange: () => {
26676
+ actionManager.executeAction(
26677
+ actionChangeTextAlign,
26678
+ "ui",
26679
+ "center"
26680
+ );
26681
+ }
26682
+ }
26683
+ ),
26684
+ /* @__PURE__ */ jsx108(
26685
+ ToolButton,
26686
+ {
26687
+ type: "radio",
26688
+ "aria-label": t("labels.right"),
26689
+ name: "text-align",
26690
+ title: t("labels.right"),
26691
+ icon: TextAlignRightIcon,
26692
+ checked: appState.currentItemTextAlign === "right",
26693
+ onChange: () => {
26694
+ actionManager.executeAction(
26695
+ actionChangeTextAlign,
26696
+ "ui",
26697
+ "right"
26698
+ );
26699
+ }
26700
+ }
26701
+ )
26702
+ ]
26703
+ }
26704
+ ),
26467
26705
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__separator" }),
26468
26706
  renderStrokeColor()
26469
26707
  ] }) }),
@@ -26495,13 +26733,38 @@ var LeftToolFlyouts = ({
26495
26733
  )
26496
26734
  ] }),
26497
26735
  /* @__PURE__ */ jsx108("div", { className: "left-flyout__title", children: t("labels.strokeWidth") }),
26498
- /* @__PURE__ */ jsx108("div", { className: "width-choices", children: [STROKE_WIDTH2.thin, STROKE_WIDTH2.bold, STROKE_WIDTH2.extraBold, 6].map((w) => /* @__PURE__ */ jsx108(
26736
+ /* @__PURE__ */ jsx108("div", { className: "width-choices", children: [
26737
+ STROKE_WIDTH2.thin,
26738
+ STROKE_WIDTH2.bold,
26739
+ STROKE_WIDTH2.extraBold,
26740
+ 6
26741
+ ].map((w) => /* @__PURE__ */ jsx108(
26499
26742
  "button",
26500
26743
  {
26501
- className: clsx46("stroke-width-preview", { selected: appState.currentItemStrokeWidth === w }),
26744
+ className: clsx46("stroke-width-preview", {
26745
+ selected: appState.currentItemStrokeWidth === w
26746
+ }),
26502
26747
  title: `${t("labels.strokeWidth")} ${w}`,
26503
26748
  onClick: () => setStrokeWidth(w),
26504
- children: /* @__PURE__ */ jsx108("svg", { width: "24", height: "16", viewBox: "0 0 24 16", "aria-hidden": "true", children: /* @__PURE__ */ jsx108("path", { d: "M2 12 C 6 2, 14 14, 22 6", fill: "none", stroke: "currentColor", strokeWidth: Math.max(1, Number(w)), strokeLinecap: "round" }) })
26749
+ children: /* @__PURE__ */ jsx108(
26750
+ "svg",
26751
+ {
26752
+ width: "24",
26753
+ height: "16",
26754
+ viewBox: "0 0 24 16",
26755
+ "aria-hidden": "true",
26756
+ children: /* @__PURE__ */ jsx108(
26757
+ "path",
26758
+ {
26759
+ d: "M2 12 C 6 2, 14 14, 22 6",
26760
+ fill: "none",
26761
+ stroke: "currentColor",
26762
+ strokeWidth: Math.max(1, Number(w)),
26763
+ strokeLinecap: "round"
26764
+ }
26765
+ )
26766
+ }
26767
+ )
26505
26768
  },
26506
26769
  String(w)
26507
26770
  )) }),
@@ -37574,6 +37837,168 @@ var App = class _App extends React46.Component {
37574
37837
  this.store = new Store(this);
37575
37838
  this.history = new History(this.store);
37576
37839
  if (excalidrawAPI) {
37840
+ const updateLeftToolbarStyle = (patch) => {
37841
+ this.setState(patch);
37842
+ };
37843
+ const selectLineVariant = (variant = "line") => {
37844
+ if (variant === "line") {
37845
+ this.setActiveTool({ type: TOOL_TYPE4.line });
37846
+ return;
37847
+ }
37848
+ this.setActiveTool({ type: TOOL_TYPE4.arrow });
37849
+ if (variant === "arrow") {
37850
+ updateLeftToolbarStyle({
37851
+ currentItemStartArrowhead: null,
37852
+ currentItemEndArrowhead: "arrow"
37853
+ });
37854
+ return;
37855
+ }
37856
+ if (variant === "doubleArrow") {
37857
+ updateLeftToolbarStyle({
37858
+ currentItemStartArrowhead: "arrow",
37859
+ currentItemEndArrowhead: "arrow"
37860
+ });
37861
+ return;
37862
+ }
37863
+ if (variant === "outlineArrow") {
37864
+ updateLeftToolbarStyle({
37865
+ currentItemStartArrowhead: null,
37866
+ currentItemEndArrowhead: "triangle_outline"
37867
+ });
37868
+ return;
37869
+ }
37870
+ updateLeftToolbarStyle({
37871
+ currentItemStartArrowhead: "triangle_outline",
37872
+ currentItemEndArrowhead: "triangle_outline"
37873
+ });
37874
+ };
37875
+ const leftToolbarApi = {
37876
+ selectSelection: () => {
37877
+ this.setActiveTool({ type: TOOL_TYPE4.selection });
37878
+ },
37879
+ selectFreedraw: (opts) => {
37880
+ this.setActiveTool({ type: TOOL_TYPE4.freedraw });
37881
+ if (!opts) {
37882
+ return;
37883
+ }
37884
+ const patch = {};
37885
+ const variant = opts.variant ?? "pen";
37886
+ patch.currentItemOpacity = variant === "highlighter" ? 50 : 100;
37887
+ if (typeof opts.strokeWidth === "number") {
37888
+ patch.currentItemStrokeWidth = opts.strokeWidth;
37889
+ }
37890
+ if (typeof opts.strokeColor === "string") {
37891
+ patch.currentItemStrokeColor = opts.strokeColor;
37892
+ }
37893
+ updateLeftToolbarStyle(patch);
37894
+ },
37895
+ selectLine: (opts) => {
37896
+ const variant = opts?.variant ?? "line";
37897
+ selectLineVariant(variant);
37898
+ if (!opts) {
37899
+ return;
37900
+ }
37901
+ const patch = {};
37902
+ if (typeof opts.strokeWidth === "number") {
37903
+ patch.currentItemStrokeWidth = opts.strokeWidth;
37904
+ }
37905
+ if (typeof opts.strokeColor === "string") {
37906
+ patch.currentItemStrokeColor = opts.strokeColor;
37907
+ }
37908
+ updateLeftToolbarStyle(patch);
37909
+ },
37910
+ selectShape: (shape, opts) => {
37911
+ const nextShape = shape ?? "rectangle";
37912
+ this.setActiveTool({ type: nextShape });
37913
+ if (!opts) {
37914
+ return;
37915
+ }
37916
+ const patch = {};
37917
+ if (typeof opts.strokeWidth === "number") {
37918
+ patch.currentItemStrokeWidth = opts.strokeWidth;
37919
+ }
37920
+ if (typeof opts.strokeColor === "string") {
37921
+ patch.currentItemStrokeColor = opts.strokeColor;
37922
+ }
37923
+ if (typeof opts.backgroundColor === "string") {
37924
+ patch.currentItemBackgroundColor = opts.backgroundColor;
37925
+ }
37926
+ if (opts.fillStyle) {
37927
+ patch.currentItemFillStyle = opts.fillStyle;
37928
+ }
37929
+ updateLeftToolbarStyle(patch);
37930
+ },
37931
+ selectText: (opts) => {
37932
+ this.setActiveTool({ type: TOOL_TYPE4.text });
37933
+ if (!opts) {
37934
+ return;
37935
+ }
37936
+ const patch = {};
37937
+ if (typeof opts.fontSize === "number") {
37938
+ patch.currentItemFontSize = opts.fontSize;
37939
+ }
37940
+ if (opts.textAlign) {
37941
+ patch.currentItemTextAlign = opts.textAlign;
37942
+ }
37943
+ if (typeof opts.strokeColor === "string") {
37944
+ patch.currentItemStrokeColor = opts.strokeColor;
37945
+ }
37946
+ if (typeof opts.bold === "boolean") {
37947
+ patch.currentTextBold = opts.bold;
37948
+ }
37949
+ if (typeof opts.italic === "boolean") {
37950
+ patch.currentTextItalic = opts.italic;
37951
+ }
37952
+ if (typeof opts.underline === "boolean") {
37953
+ patch.currentTextUnderline = opts.underline;
37954
+ }
37955
+ if (typeof opts.strikethrough === "boolean") {
37956
+ patch.currentTextStrikethrough = opts.strikethrough;
37957
+ }
37958
+ updateLeftToolbarStyle(patch);
37959
+ },
37960
+ selectEraser: () => {
37961
+ this.setActiveTool({ type: TOOL_TYPE4.eraser });
37962
+ },
37963
+ updateStyle: (patch) => {
37964
+ updateLeftToolbarStyle(patch);
37965
+ },
37966
+ dispatch: (command) => {
37967
+ switch (command.type) {
37968
+ case "selectSelection":
37969
+ leftToolbarApi.selectSelection();
37970
+ return;
37971
+ case "selectFreedraw":
37972
+ leftToolbarApi.selectFreedraw(command.payload);
37973
+ return;
37974
+ case "selectLine":
37975
+ leftToolbarApi.selectLine(command.payload);
37976
+ return;
37977
+ case "selectShape":
37978
+ leftToolbarApi.selectShape(
37979
+ command.payload?.shape,
37980
+ command.payload && {
37981
+ strokeWidth: command.payload.strokeWidth,
37982
+ strokeColor: command.payload.strokeColor,
37983
+ backgroundColor: command.payload.backgroundColor,
37984
+ fillStyle: command.payload.fillStyle
37985
+ }
37986
+ );
37987
+ return;
37988
+ case "selectText":
37989
+ leftToolbarApi.selectText(command.payload);
37990
+ return;
37991
+ case "selectEraser":
37992
+ leftToolbarApi.selectEraser();
37993
+ return;
37994
+ case "updateStyle":
37995
+ leftToolbarApi.updateStyle(command.payload);
37996
+ return;
37997
+ default:
37998
+ return;
37999
+ }
38000
+ }
38001
+ };
37577
38002
  const api = {
37578
38003
  updateScene: this.updateScene,
37579
38004
  updateSceneSilently: this.updateSceneSilently,
@@ -37600,6 +38025,7 @@ var App = class _App extends React46.Component {
37600
38025
  setToast: this.setToast,
37601
38026
  id: this.id,
37602
38027
  setActiveTool: this.setActiveTool,
38028
+ leftToolbar: leftToolbarApi,
37603
38029
  setCursor: this.setCursor,
37604
38030
  resetCursor: this.resetCursor,
37605
38031
  updateFrameRendering: this.updateFrameRendering,
@@ -41291,15 +41717,207 @@ import {
41291
41717
  viewportCoordsToSceneCoords as viewportCoordsToSceneCoords5
41292
41718
  } from "@haoxin-web/excalidraw-common";
41293
41719
 
41294
- // components/TTDDialog/TTDDialogTrigger.tsx
41720
+ // components/ExternalLeftToolbar.tsx
41721
+ import { useState as useState40 } from "react";
41295
41722
  import { jsx as jsx161, jsxs as jsxs88 } from "react/jsx-runtime";
41723
+ var SHAPE_OPTIONS = [
41724
+ "rectangle",
41725
+ "ellipse",
41726
+ "diamond",
41727
+ "triangle",
41728
+ "pentagon",
41729
+ "callout",
41730
+ "hollow_arrow",
41731
+ "hollow_double_arrow"
41732
+ ];
41733
+ var LINE_VARIANTS = [
41734
+ "line",
41735
+ "arrow",
41736
+ "doubleArrow",
41737
+ "outlineArrow",
41738
+ "outlineDoubleArrow"
41739
+ ];
41740
+ var FREEDRAW_VARIANTS = ["pen", "highlighter"];
41741
+ var ExternalLeftToolbar = ({
41742
+ excalidrawAPI,
41743
+ className,
41744
+ style
41745
+ }) => {
41746
+ const [shape, setShape] = useState40("rectangle");
41747
+ const [lineVariant, setLineVariant] = useState40("line");
41748
+ const [freedrawVariant, setFreedrawVariant] = useState40("pen");
41749
+ const [strokeWidth, setStrokeWidth] = useState40(2);
41750
+ const [strokeColor, setStrokeColor] = useState40("#1f1f1f");
41751
+ const disabled = !excalidrawAPI;
41752
+ return /* @__PURE__ */ jsxs88(
41753
+ "div",
41754
+ {
41755
+ className,
41756
+ style: {
41757
+ display: "flex",
41758
+ flexDirection: "column",
41759
+ gap: 8,
41760
+ padding: 10,
41761
+ border: "1px solid #e5e7eb",
41762
+ borderRadius: 10,
41763
+ width: 220,
41764
+ background: "#fff",
41765
+ ...style
41766
+ },
41767
+ children: [
41768
+ /* @__PURE__ */ jsxs88("div", { style: { display: "flex", gap: 8 }, children: [
41769
+ /* @__PURE__ */ jsx161(
41770
+ "button",
41771
+ {
41772
+ type: "button",
41773
+ disabled,
41774
+ onClick: () => excalidrawAPI?.leftToolbar.selectSelection(),
41775
+ children: "Selection"
41776
+ }
41777
+ ),
41778
+ /* @__PURE__ */ jsx161(
41779
+ "button",
41780
+ {
41781
+ type: "button",
41782
+ disabled,
41783
+ onClick: () => excalidrawAPI?.leftToolbar.selectEraser(),
41784
+ children: "Eraser"
41785
+ }
41786
+ )
41787
+ ] }),
41788
+ /* @__PURE__ */ jsxs88("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
41789
+ /* @__PURE__ */ jsx161("label", { style: { minWidth: 70 }, children: "Freedraw" }),
41790
+ /* @__PURE__ */ jsx161(
41791
+ "select",
41792
+ {
41793
+ value: freedrawVariant,
41794
+ onChange: (e) => setFreedrawVariant(e.target.value),
41795
+ children: FREEDRAW_VARIANTS.map((item) => /* @__PURE__ */ jsx161("option", { value: item, children: item }, item))
41796
+ }
41797
+ ),
41798
+ /* @__PURE__ */ jsx161(
41799
+ "button",
41800
+ {
41801
+ type: "button",
41802
+ disabled,
41803
+ onClick: () => excalidrawAPI?.leftToolbar.selectFreedraw({
41804
+ variant: freedrawVariant,
41805
+ strokeWidth,
41806
+ strokeColor
41807
+ }),
41808
+ children: "Apply"
41809
+ }
41810
+ )
41811
+ ] }),
41812
+ /* @__PURE__ */ jsxs88("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
41813
+ /* @__PURE__ */ jsx161("label", { style: { minWidth: 70 }, children: "Line" }),
41814
+ /* @__PURE__ */ jsx161(
41815
+ "select",
41816
+ {
41817
+ value: lineVariant,
41818
+ onChange: (e) => setLineVariant(e.target.value),
41819
+ children: LINE_VARIANTS.map((item) => /* @__PURE__ */ jsx161("option", { value: item, children: item }, item))
41820
+ }
41821
+ ),
41822
+ /* @__PURE__ */ jsx161(
41823
+ "button",
41824
+ {
41825
+ type: "button",
41826
+ disabled,
41827
+ onClick: () => excalidrawAPI?.leftToolbar.selectLine({
41828
+ variant: lineVariant,
41829
+ strokeWidth,
41830
+ strokeColor
41831
+ }),
41832
+ children: "Apply"
41833
+ }
41834
+ )
41835
+ ] }),
41836
+ /* @__PURE__ */ jsxs88("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
41837
+ /* @__PURE__ */ jsx161("label", { style: { minWidth: 70 }, children: "Shape" }),
41838
+ /* @__PURE__ */ jsx161(
41839
+ "select",
41840
+ {
41841
+ value: shape,
41842
+ onChange: (e) => setShape(e.target.value),
41843
+ children: SHAPE_OPTIONS.map((item) => /* @__PURE__ */ jsx161("option", { value: item, children: item }, item))
41844
+ }
41845
+ ),
41846
+ /* @__PURE__ */ jsx161(
41847
+ "button",
41848
+ {
41849
+ type: "button",
41850
+ disabled,
41851
+ onClick: () => excalidrawAPI?.leftToolbar.selectShape(shape, {
41852
+ strokeWidth,
41853
+ strokeColor
41854
+ }),
41855
+ children: "Apply"
41856
+ }
41857
+ )
41858
+ ] }),
41859
+ /* @__PURE__ */ jsxs88("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
41860
+ /* @__PURE__ */ jsx161("label", { style: { minWidth: 70 }, children: "Text" }),
41861
+ /* @__PURE__ */ jsx161(
41862
+ "button",
41863
+ {
41864
+ type: "button",
41865
+ disabled,
41866
+ onClick: () => excalidrawAPI?.leftToolbar.selectText({
41867
+ strokeColor
41868
+ }),
41869
+ children: "Text Tool"
41870
+ }
41871
+ )
41872
+ ] }),
41873
+ /* @__PURE__ */ jsxs88("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
41874
+ /* @__PURE__ */ jsx161("label", { style: { minWidth: 70 }, children: "Stroke" }),
41875
+ /* @__PURE__ */ jsx161(
41876
+ "input",
41877
+ {
41878
+ type: "number",
41879
+ min: 1,
41880
+ max: 20,
41881
+ value: strokeWidth,
41882
+ onChange: (e) => setStrokeWidth(Number(e.target.value || 1)),
41883
+ style: { width: 60 }
41884
+ }
41885
+ ),
41886
+ /* @__PURE__ */ jsx161(
41887
+ "input",
41888
+ {
41889
+ type: "color",
41890
+ value: strokeColor,
41891
+ onChange: (e) => setStrokeColor(e.target.value)
41892
+ }
41893
+ ),
41894
+ /* @__PURE__ */ jsx161(
41895
+ "button",
41896
+ {
41897
+ type: "button",
41898
+ disabled,
41899
+ onClick: () => excalidrawAPI?.leftToolbar.updateStyle({
41900
+ currentItemStrokeWidth: strokeWidth,
41901
+ currentItemStrokeColor: strokeColor
41902
+ }),
41903
+ children: "Sync"
41904
+ }
41905
+ )
41906
+ ] })
41907
+ ]
41908
+ }
41909
+ );
41910
+ };
41911
+
41912
+ // components/TTDDialog/TTDDialogTrigger.tsx
41913
+ import { jsx as jsx162, jsxs as jsxs89 } from "react/jsx-runtime";
41296
41914
  var TTDDialogTrigger = ({
41297
41915
  children,
41298
41916
  icon
41299
41917
  }) => {
41300
41918
  const { TTDDialogTriggerTunnel } = useTunnels();
41301
41919
  const setAppState = useExcalidrawSetAppState();
41302
- return /* @__PURE__ */ jsx161(TTDDialogTriggerTunnel.In, { children: /* @__PURE__ */ jsxs88(
41920
+ return /* @__PURE__ */ jsx162(TTDDialogTriggerTunnel.In, { children: /* @__PURE__ */ jsxs89(
41303
41921
  DropdownMenu_default.Item,
41304
41922
  {
41305
41923
  onSelect: () => {
@@ -41309,7 +41927,7 @@ var TTDDialogTrigger = ({
41309
41927
  icon: icon ?? brainIcon,
41310
41928
  children: [
41311
41929
  children ?? t("labels.textToDiagram"),
41312
- /* @__PURE__ */ jsx161(DropdownMenu_default.Item.Badge, { children: "AI" })
41930
+ /* @__PURE__ */ jsx162(DropdownMenu_default.Item.Badge, { children: "AI" })
41313
41931
  ]
41314
41932
  }
41315
41933
  ) });
@@ -41334,7 +41952,7 @@ var DiagramToCodePlugin = (props) => {
41334
41952
  // index.tsx
41335
41953
  import { isElementLink as isElementLink3 } from "@haoxin-web/excalidraw-element";
41336
41954
  import { setCustomTextMetricsProvider } from "@haoxin-web/excalidraw-element";
41337
- import { jsx as jsx162 } from "react/jsx-runtime";
41955
+ import { jsx as jsx163 } from "react/jsx-runtime";
41338
41956
  polyfill_default();
41339
41957
  var ExcalidrawBase = (props) => {
41340
41958
  console.log("\u4F7F\u7528\u4E86\u7EC4\u4EF6=====Excalidraw component initialized");
@@ -41410,7 +42028,7 @@ var ExcalidrawBase = (props) => {
41410
42028
  document.removeEventListener("touchmove", handleTouchMove);
41411
42029
  };
41412
42030
  }, []);
41413
- return /* @__PURE__ */ jsx162(EditorJotaiProvider, { store: editorJotaiStore, children: /* @__PURE__ */ jsx162(InitializeApp, { langCode, theme, children: /* @__PURE__ */ jsx162(
42031
+ return /* @__PURE__ */ jsx163(EditorJotaiProvider, { store: editorJotaiStore, children: /* @__PURE__ */ jsx163(InitializeApp, { langCode, theme, children: /* @__PURE__ */ jsx163(
41414
42032
  App_default,
41415
42033
  {
41416
42034
  onChange,
@@ -41488,7 +42106,7 @@ var areEqual5 = (prevProps, nextProps) => {
41488
42106
  });
41489
42107
  return isUIOptionsSame && isShallowEqual9(prev, next);
41490
42108
  };
41491
- var Excalidraw = React48.memo(ExcalidrawBase, areEqual5);
42109
+ var Excalidraw = React49.memo(ExcalidrawBase, areEqual5);
41492
42110
  Excalidraw.displayName = "Excalidraw";
41493
42111
  export {
41494
42112
  Button,
@@ -41498,6 +42116,7 @@ export {
41498
42116
  DiagramToCodePlugin,
41499
42117
  Ellipsify,
41500
42118
  Excalidraw,
42119
+ ExternalLeftToolbar,
41501
42120
  FONT_FAMILY5 as FONT_FAMILY,
41502
42121
  FooterCenter_default as Footer,
41503
42122
  LiveCollaborationTrigger_default as LiveCollaborationTrigger,
@@ -41510,6 +42129,7 @@ export {
41510
42129
  TTDDialog,
41511
42130
  TTDDialogTrigger,
41512
42131
  UserIdleState2 as UserIdleState,
42132
+ UserList,
41513
42133
  WelcomeScreen_default as WelcomeScreen,
41514
42134
  bumpVersion,
41515
42135
  convertToExcalidrawElements,