@lumir-company/editor 0.4.4 → 0.4.6

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/index.js CHANGED
@@ -40,8 +40,8 @@ __export(index_exports, {
40
40
  module.exports = __toCommonJS(index_exports);
41
41
 
42
42
  // src/components/LumirEditor.tsx
43
- var import_react16 = require("react");
44
- var import_react17 = require("@blocknote/react");
43
+ var import_react18 = require("react");
44
+ var import_react19 = require("@blocknote/react");
45
45
  var import_mantine = require("@blocknote/mantine");
46
46
  var import_core2 = require("@blocknote/core");
47
47
 
@@ -91,7 +91,10 @@ var createS3Uploader = (config) => {
91
91
  path,
92
92
  fileNameTransform,
93
93
  appendUUID,
94
- preserveExtension = true
94
+ preserveExtension = true,
95
+ onProgress,
96
+ uploadTimeoutMs = 12e4,
97
+ maxRetries = 2
95
98
  } = config;
96
99
  if (!apiEndpoint || apiEndpoint.trim() === "") {
97
100
  throw new Error(
@@ -130,6 +133,15 @@ var createS3Uploader = (config) => {
130
133
  }
131
134
  return `${env}/${path}/${filename}`;
132
135
  };
136
+ const debugLog = (loc, msg, data) => {
137
+ const p = fetch("http://127.0.0.1:7686/ingest/1f8ee1c5-0cf0-4ae7-91ed-5ea7ed17130a", {
138
+ method: "POST",
139
+ headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "b73262" },
140
+ body: JSON.stringify({ sessionId: "b73262", location: loc, message: msg, data, timestamp: Date.now() })
141
+ });
142
+ if (p && typeof p.catch === "function") p.catch(() => {
143
+ });
144
+ };
133
145
  return async (file) => {
134
146
  try {
135
147
  if (!apiEndpoint || apiEndpoint.trim() === "") {
@@ -138,11 +150,26 @@ var createS3Uploader = (config) => {
138
150
  );
139
151
  }
140
152
  const fileName = generateHierarchicalFileName(file);
141
- const response = await fetch(
142
- `${apiEndpoint}?key=${encodeURIComponent(fileName)}`
143
- );
153
+ const contentType = file.type || "application/octet-stream";
154
+ const presignedUrlFull = `${apiEndpoint}?key=${encodeURIComponent(fileName)}&contentType=${encodeURIComponent(contentType)}`;
155
+ const tPresigned = Date.now();
156
+ debugLog("s3:step1:presignedReq", "fetching presigned URL", {
157
+ fileName,
158
+ contentType,
159
+ apiEndpoint
160
+ });
161
+ const response = await fetch(presignedUrlFull);
162
+ debugLog("s3:step2:presignedRes", "presigned response", {
163
+ ok: response.ok,
164
+ status: response.status,
165
+ elapsedMs: Date.now() - tPresigned
166
+ });
144
167
  if (!response.ok) {
145
168
  const errorText = await response.text() || "";
169
+ debugLog("s3:step2b:presignedErr", "presigned failed", {
170
+ status: response.status,
171
+ errorText: errorText.slice(0, 200)
172
+ });
146
173
  throw new Error(
147
174
  `Failed to get presigned URL: ${response.statusText}, ${errorText}`
148
175
  );
@@ -151,17 +178,64 @@ var createS3Uploader = (config) => {
151
178
  const { presignedUrl, publicUrl } = responseData;
152
179
  const validatedPresignedUrl = validateS3Url(presignedUrl, "presignedUrl");
153
180
  const validatedPublicUrl = validateS3Url(publicUrl, "publicUrl");
154
- const uploadResponse = await fetch(validatedPresignedUrl, {
155
- method: "PUT",
156
- headers: {
157
- "Content-Type": file.type || "application/octet-stream"
158
- },
159
- body: file
160
- });
161
- if (!uploadResponse.ok) {
162
- throw new Error(`Failed to upload file: ${uploadResponse.statusText}`);
181
+ const tPut = Date.now();
182
+ debugLog("s3:step3:putReq", "S3 PUT request", { publicUrlLen: validatedPublicUrl?.length });
183
+ let lastError;
184
+ const attempts = maxRetries + 1;
185
+ for (let attempt = 0; attempt < attempts; attempt++) {
186
+ try {
187
+ if (onProgress && typeof XMLHttpRequest !== "undefined") {
188
+ await new Promise((resolve, reject) => {
189
+ const xhr = new XMLHttpRequest();
190
+ xhr.timeout = uploadTimeoutMs;
191
+ xhr.upload.onprogress = (e) => {
192
+ if (e.lengthComputable) {
193
+ onProgress(Math.min(100, Math.round(e.loaded / e.total * 100)));
194
+ }
195
+ };
196
+ xhr.onload = () => {
197
+ if (xhr.status >= 200 && xhr.status < 300) resolve();
198
+ else reject(new Error(`Failed to upload file: ${xhr.statusText}`));
199
+ };
200
+ xhr.onerror = () => reject(new Error("Upload failed"));
201
+ xhr.ontimeout = () => reject(new Error("Upload timeout"));
202
+ xhr.open("PUT", validatedPresignedUrl);
203
+ xhr.setRequestHeader("Content-Type", file.type || "application/octet-stream");
204
+ xhr.send(file);
205
+ });
206
+ } else {
207
+ const controller = new AbortController();
208
+ const timeoutId = setTimeout(() => controller.abort(), uploadTimeoutMs);
209
+ const uploadResponse = await fetch(validatedPresignedUrl, {
210
+ method: "PUT",
211
+ headers: {
212
+ "Content-Type": file.type || "application/octet-stream"
213
+ },
214
+ body: file,
215
+ signal: controller.signal
216
+ });
217
+ clearTimeout(timeoutId);
218
+ debugLog("s3:step4:putRes", "S3 PUT response", {
219
+ ok: uploadResponse.ok,
220
+ status: uploadResponse.status,
221
+ putElapsedMs: Date.now() - tPut
222
+ });
223
+ if (!uploadResponse.ok) {
224
+ throw new Error(`Failed to upload file: ${uploadResponse.statusText}`);
225
+ }
226
+ }
227
+ debugLog("s3:step5:return", "returning publicUrl", { urlPrefix: validatedPublicUrl.slice(0, 80) });
228
+ return validatedPublicUrl;
229
+ } catch (err) {
230
+ lastError = err instanceof Error ? err : new Error(String(err));
231
+ if (attempt < attempts - 1) {
232
+ debugLog("s3:putRetry", "PUT failed, retrying", { attempt: attempt + 1, attempts });
233
+ } else {
234
+ throw lastError;
235
+ }
236
+ }
163
237
  }
164
- return validatedPublicUrl;
238
+ throw lastError ?? new Error("Upload failed");
165
239
  } catch (error) {
166
240
  console.error("S3 upload failed:", error);
167
241
  throw error;
@@ -170,7 +244,7 @@ var createS3Uploader = (config) => {
170
244
  };
171
245
 
172
246
  // src/blocks/HtmlPreview.tsx
173
- var import_react3 = require("@blocknote/react");
247
+ var import_react5 = require("@blocknote/react");
174
248
  var import_core = require("@blocknote/core");
175
249
 
176
250
  // src/blocks/LinkPreview.tsx
@@ -876,9 +950,254 @@ var LinkPreviewBlock = (0, import_react.createReactBlockSpec)(
876
950
  }
877
951
  );
878
952
 
879
- // src/blocks/HtmlPreview.tsx
953
+ // src/blocks/VideoBlock.tsx
954
+ var import_react3 = require("@blocknote/react");
880
955
  var import_react4 = require("react");
881
956
  var import_jsx_runtime2 = require("react/jsx-runtime");
957
+ var MIN_VIDEO_WIDTH = 200;
958
+ var MAX_VIDEO_WIDTH = 1200;
959
+ var MIN_VIDEO_HEIGHT = 120;
960
+ var MAX_VIDEO_HEIGHT = 600;
961
+ var DEFAULT_VIDEO_WIDTH = 640;
962
+ var DEFAULT_VIDEO_HEIGHT = 360;
963
+ var VideoBlockCard = ({
964
+ url,
965
+ editable,
966
+ width,
967
+ onWidthChange,
968
+ height,
969
+ onHeightChange,
970
+ onContextMenuBlock
971
+ }) => {
972
+ const [resizeParams, setResizeParams] = (0, import_react4.useState)(
973
+ void 0
974
+ );
975
+ const [localWidth, setLocalWidth] = (0, import_react4.useState)(width);
976
+ const [localHeight, setLocalHeight] = (0, import_react4.useState)(height);
977
+ const wrapperRef = (0, import_react4.useRef)(null);
978
+ (0, import_react4.useEffect)(() => {
979
+ setLocalWidth(width);
980
+ }, [width]);
981
+ (0, import_react4.useEffect)(() => {
982
+ setLocalHeight(height);
983
+ }, [height]);
984
+ (0, import_react4.useEffect)(() => {
985
+ if (!resizeParams) return;
986
+ const onMouseMove = (e) => {
987
+ if (resizeParams.handleUsed === "bottom") {
988
+ const delta = e.clientY - resizeParams.initialClientY;
989
+ setLocalHeight(
990
+ Math.min(
991
+ Math.max(resizeParams.initialHeight + delta, MIN_VIDEO_HEIGHT),
992
+ MAX_VIDEO_HEIGHT
993
+ )
994
+ );
995
+ } else {
996
+ const delta = resizeParams.handleUsed === "left" ? resizeParams.initialClientX - e.clientX : e.clientX - resizeParams.initialClientX;
997
+ setLocalWidth(
998
+ Math.min(
999
+ Math.max(resizeParams.initialWidth + delta, MIN_VIDEO_WIDTH),
1000
+ wrapperRef.current?.parentElement?.clientWidth || MAX_VIDEO_WIDTH
1001
+ )
1002
+ );
1003
+ }
1004
+ };
1005
+ const onMouseUp = () => {
1006
+ const handle = resizeParams.handleUsed;
1007
+ setResizeParams(void 0);
1008
+ if (handle === "bottom") {
1009
+ if (localHeight != null && onHeightChange) onHeightChange(localHeight);
1010
+ } else {
1011
+ if (localWidth != null && onWidthChange) onWidthChange(localWidth);
1012
+ }
1013
+ };
1014
+ window.addEventListener("mousemove", onMouseMove);
1015
+ window.addEventListener("mouseup", onMouseUp);
1016
+ return () => {
1017
+ window.removeEventListener("mousemove", onMouseMove);
1018
+ window.removeEventListener("mouseup", onMouseUp);
1019
+ };
1020
+ }, [resizeParams, localWidth, localHeight, onWidthChange, onHeightChange]);
1021
+ const handleLeftDown = (0, import_react4.useCallback)((e) => {
1022
+ e.preventDefault();
1023
+ e.stopPropagation();
1024
+ setResizeParams({
1025
+ handleUsed: "left",
1026
+ initialWidth: wrapperRef.current?.clientWidth ?? DEFAULT_VIDEO_WIDTH,
1027
+ initialHeight: localHeight ?? DEFAULT_VIDEO_HEIGHT,
1028
+ initialClientX: e.clientX,
1029
+ initialClientY: e.clientY
1030
+ });
1031
+ }, [localHeight]);
1032
+ const handleRightDown = (0, import_react4.useCallback)((e) => {
1033
+ e.preventDefault();
1034
+ e.stopPropagation();
1035
+ setResizeParams({
1036
+ handleUsed: "right",
1037
+ initialWidth: wrapperRef.current?.clientWidth ?? DEFAULT_VIDEO_WIDTH,
1038
+ initialHeight: localHeight ?? DEFAULT_VIDEO_HEIGHT,
1039
+ initialClientX: e.clientX,
1040
+ initialClientY: e.clientY
1041
+ });
1042
+ }, [localHeight]);
1043
+ const handleBottomDown = (0, import_react4.useCallback)((e) => {
1044
+ e.preventDefault();
1045
+ e.stopPropagation();
1046
+ setResizeParams({
1047
+ handleUsed: "bottom",
1048
+ initialWidth: wrapperRef.current?.clientWidth ?? DEFAULT_VIDEO_WIDTH,
1049
+ initialHeight: localHeight ?? DEFAULT_VIDEO_HEIGHT,
1050
+ initialClientX: e.clientX,
1051
+ initialClientY: e.clientY
1052
+ });
1053
+ }, [localHeight]);
1054
+ const resizeCursor = resizeParams ? resizeParams.handleUsed === "bottom" ? "ns-resize" : "ew-resize" : "default";
1055
+ const [hovered, setHovered] = (0, import_react4.useState)(false);
1056
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1057
+ "div",
1058
+ {
1059
+ ref: wrapperRef,
1060
+ className: "lumir-video-block-wrapper",
1061
+ onContextMenu: onContextMenuBlock,
1062
+ style: {
1063
+ position: "relative",
1064
+ width: localWidth != null ? `${localWidth}px` : void 0,
1065
+ maxWidth: "100%",
1066
+ cursor: resizeCursor,
1067
+ transition: resizeParams ? "none" : "box-shadow 0.2s"
1068
+ },
1069
+ onMouseEnter: () => {
1070
+ if (!resizeParams) setHovered(true);
1071
+ },
1072
+ onMouseLeave: () => {
1073
+ if (!resizeParams) setHovered(false);
1074
+ },
1075
+ children: [
1076
+ editable && (hovered || resizeParams) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
1077
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1078
+ "div",
1079
+ {
1080
+ className: "lumir-resize-handle",
1081
+ style: { left: "4px" },
1082
+ onMouseDown: handleLeftDown
1083
+ }
1084
+ ),
1085
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1086
+ "div",
1087
+ {
1088
+ className: "lumir-resize-handle",
1089
+ style: { right: "4px" },
1090
+ onMouseDown: handleRightDown
1091
+ }
1092
+ )
1093
+ ] }),
1094
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1095
+ "div",
1096
+ {
1097
+ style: {
1098
+ width: "100%",
1099
+ height: `${localHeight ?? DEFAULT_VIDEO_HEIGHT}px`,
1100
+ overflow: "hidden",
1101
+ backgroundColor: "#000",
1102
+ borderRadius: "6px"
1103
+ },
1104
+ children: [
1105
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1106
+ "video",
1107
+ {
1108
+ src: url,
1109
+ controls: true,
1110
+ playsInline: true,
1111
+ style: {
1112
+ width: "100%",
1113
+ height: "100%",
1114
+ objectFit: "contain",
1115
+ display: "block"
1116
+ },
1117
+ onContextMenu: (e) => e.preventDefault()
1118
+ }
1119
+ ),
1120
+ editable && (hovered || resizeParams) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1121
+ "div",
1122
+ {
1123
+ className: "lumir-resize-handle-bottom",
1124
+ onMouseDown: handleBottomDown
1125
+ }
1126
+ )
1127
+ ]
1128
+ }
1129
+ )
1130
+ ]
1131
+ }
1132
+ );
1133
+ };
1134
+ var VideoBlock = (0, import_react3.createReactBlockSpec)(
1135
+ {
1136
+ type: "video",
1137
+ propSchema: {
1138
+ url: { default: "" },
1139
+ previewWidth: { default: 640 },
1140
+ previewHeight: { default: 360 }
1141
+ },
1142
+ content: "none"
1143
+ },
1144
+ {
1145
+ render: (props) => {
1146
+ const url = props.block.props.url ?? "";
1147
+ const editable = props.editor.isEditable;
1148
+ const handleContextMenu = (0, import_react4.useCallback)((e) => {
1149
+ e.preventDefault();
1150
+ e.stopPropagation();
1151
+ }, []);
1152
+ if (!url) {
1153
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1154
+ "div",
1155
+ {
1156
+ className: "lumir-video-block-placeholder",
1157
+ onContextMenu: handleContextMenu,
1158
+ style: {
1159
+ width: "100%",
1160
+ maxWidth: `${DEFAULT_VIDEO_WIDTH}px`,
1161
+ height: `${DEFAULT_VIDEO_HEIGHT}px`,
1162
+ backgroundColor: "#1a1a1a",
1163
+ borderRadius: "6px",
1164
+ display: "flex",
1165
+ alignItems: "center",
1166
+ justifyContent: "center",
1167
+ color: "rgba(255,255,255,0.5)",
1168
+ fontSize: "14px"
1169
+ },
1170
+ children: "\uBE44\uB514\uC624 URL \uC5C6\uC74C"
1171
+ }
1172
+ );
1173
+ }
1174
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1175
+ VideoBlockCard,
1176
+ {
1177
+ url,
1178
+ editable,
1179
+ width: props.block.props.previewWidth,
1180
+ onWidthChange: (newWidth) => {
1181
+ props.editor.updateBlock(props.block, {
1182
+ props: { previewWidth: newWidth }
1183
+ });
1184
+ },
1185
+ height: props.block.props.previewHeight,
1186
+ onHeightChange: (newHeight) => {
1187
+ props.editor.updateBlock(props.block, {
1188
+ props: { previewHeight: newHeight }
1189
+ });
1190
+ },
1191
+ onContextMenuBlock: handleContextMenu
1192
+ }
1193
+ );
1194
+ }
1195
+ }
1196
+ );
1197
+
1198
+ // src/blocks/HtmlPreview.tsx
1199
+ var import_react6 = require("react");
1200
+ var import_jsx_runtime3 = require("react/jsx-runtime");
882
1201
  var MIN_HEIGHT = 100;
883
1202
  var MAX_HEIGHT = 1200;
884
1203
  var ensureCharset = (html) => {
@@ -916,7 +1235,7 @@ var createSecureBlobUrl = (htmlContent) => {
916
1235
  });
917
1236
  return URL.createObjectURL(blob);
918
1237
  };
919
- var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1238
+ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
920
1239
  {
921
1240
  type: "htmlPreview",
922
1241
  propSchema: {
@@ -934,15 +1253,15 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
934
1253
  },
935
1254
  {
936
1255
  render: (props) => {
937
- const [isExpanded, setIsExpanded] = (0, import_react4.useState)(true);
938
- const [isResizing, setIsResizing] = (0, import_react4.useState)(false);
939
- const [blobUrl, setBlobUrl] = (0, import_react4.useState)("");
940
- const containerRef = (0, import_react4.useRef)(null);
1256
+ const [isExpanded, setIsExpanded] = (0, import_react6.useState)(true);
1257
+ const [isResizing, setIsResizing] = (0, import_react6.useState)(false);
1258
+ const [blobUrl, setBlobUrl] = (0, import_react6.useState)("");
1259
+ const containerRef = (0, import_react6.useRef)(null);
941
1260
  const htmlContent = props.block.props.htmlContent || "";
942
1261
  const fileName = props.block.props.fileName || "HTML Document";
943
1262
  const savedHeight = props.block.props.height || "400px";
944
1263
  const currentHeight = parseInt(savedHeight, 10) || 400;
945
- (0, import_react4.useEffect)(() => {
1264
+ (0, import_react6.useEffect)(() => {
946
1265
  if (htmlContent) {
947
1266
  const url = createSecureBlobUrl(htmlContent);
948
1267
  setBlobUrl(url);
@@ -951,7 +1270,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
951
1270
  };
952
1271
  }
953
1272
  }, [htmlContent]);
954
- const handleResizeStart = (0, import_react4.useCallback)(
1273
+ const handleResizeStart = (0, import_react6.useCallback)(
955
1274
  (e) => {
956
1275
  e.preventDefault();
957
1276
  e.stopPropagation();
@@ -978,7 +1297,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
978
1297
  },
979
1298
  [currentHeight, props.editor, props.block]
980
1299
  );
981
- const handleExport = (0, import_react4.useCallback)(
1300
+ const handleExport = (0, import_react6.useCallback)(
982
1301
  (e) => {
983
1302
  e.stopPropagation();
984
1303
  const safeFileName = sanitizeFileName(fileName);
@@ -999,7 +1318,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
999
1318
  },
1000
1319
  [htmlContent, fileName]
1001
1320
  );
1002
- const handleOpenNewWindow = (0, import_react4.useCallback)(
1321
+ const handleOpenNewWindow = (0, import_react6.useCallback)(
1003
1322
  (e) => {
1004
1323
  e.stopPropagation();
1005
1324
  if (typeof window === "undefined") return;
@@ -1013,7 +1332,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1013
1332
  },
1014
1333
  [htmlContent]
1015
1334
  );
1016
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1335
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1017
1336
  "div",
1018
1337
  {
1019
1338
  ref: containerRef,
@@ -1029,7 +1348,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1029
1348
  boxShadow: "none"
1030
1349
  },
1031
1350
  children: [
1032
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1351
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1033
1352
  "div",
1034
1353
  {
1035
1354
  style: {
@@ -1041,7 +1360,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1041
1360
  borderBottom: isExpanded ? "1px solid #e0e0e0" : "none"
1042
1361
  },
1043
1362
  children: [
1044
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1363
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1045
1364
  "div",
1046
1365
  {
1047
1366
  style: {
@@ -1053,7 +1372,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1053
1372
  },
1054
1373
  onClick: () => setIsExpanded(!isExpanded),
1055
1374
  children: [
1056
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1375
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1057
1376
  "svg",
1058
1377
  {
1059
1378
  width: "16",
@@ -1068,15 +1387,15 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1068
1387
  transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)",
1069
1388
  transition: "transform 0.2s"
1070
1389
  },
1071
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "6 9 12 15 18 9" })
1390
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "6 9 12 15 18 9" })
1072
1391
  }
1073
1392
  ),
1074
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontWeight: 500, fontSize: "14px" }, children: fileName })
1393
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontWeight: 500, fontSize: "14px" }, children: fileName })
1075
1394
  ]
1076
1395
  }
1077
1396
  ),
1078
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
1079
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1397
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
1398
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1080
1399
  "button",
1081
1400
  {
1082
1401
  onClick: handleOpenNewWindow,
@@ -1099,7 +1418,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1099
1418
  onMouseLeave: (e) => {
1100
1419
  e.currentTarget.style.backgroundColor = "transparent";
1101
1420
  },
1102
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1421
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1103
1422
  "svg",
1104
1423
  {
1105
1424
  width: "16",
@@ -1111,15 +1430,15 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1111
1430
  strokeLinecap: "round",
1112
1431
  strokeLinejoin: "round",
1113
1432
  children: [
1114
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
1115
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "15 3 21 3 21 9" }),
1116
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
1433
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
1434
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "15 3 21 3 21 9" }),
1435
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
1117
1436
  ]
1118
1437
  }
1119
1438
  )
1120
1439
  }
1121
1440
  ),
1122
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1441
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1123
1442
  "button",
1124
1443
  {
1125
1444
  onClick: handleExport,
@@ -1142,7 +1461,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1142
1461
  onMouseLeave: (e) => {
1143
1462
  e.currentTarget.style.backgroundColor = "transparent";
1144
1463
  },
1145
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1464
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1146
1465
  "svg",
1147
1466
  {
1148
1467
  width: "16",
@@ -1154,9 +1473,9 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1154
1473
  strokeLinecap: "round",
1155
1474
  strokeLinejoin: "round",
1156
1475
  children: [
1157
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1158
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "7 10 12 15 17 10" }),
1159
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
1476
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1477
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "7 10 12 15 17 10" }),
1478
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
1160
1479
  ]
1161
1480
  }
1162
1481
  )
@@ -1166,7 +1485,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1166
1485
  ]
1167
1486
  }
1168
1487
  ),
1169
- isExpanded && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1488
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1170
1489
  "div",
1171
1490
  {
1172
1491
  style: {
@@ -1175,7 +1494,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1175
1494
  position: "relative"
1176
1495
  },
1177
1496
  children: [
1178
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1497
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1179
1498
  "iframe",
1180
1499
  {
1181
1500
  src: blobUrl || "about:blank",
@@ -1192,7 +1511,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1192
1511
  loading: "lazy"
1193
1512
  }
1194
1513
  ),
1195
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1514
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1196
1515
  "div",
1197
1516
  {
1198
1517
  onMouseDown: handleResizeStart,
@@ -1217,7 +1536,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1217
1536
  e.currentTarget.style.backgroundColor = "transparent";
1218
1537
  }
1219
1538
  },
1220
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1539
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1221
1540
  "div",
1222
1541
  {
1223
1542
  style: {
@@ -1242,6 +1561,7 @@ var HtmlPreviewBlock = (0, import_react3.createReactBlockSpec)(
1242
1561
  var schema = import_core.BlockNoteSchema.create({
1243
1562
  blockSpecs: {
1244
1563
  ...import_core.defaultBlockSpecs,
1564
+ video: VideoBlock,
1245
1565
  htmlPreview: HtmlPreviewBlock,
1246
1566
  linkPreview: LinkPreviewBlock
1247
1567
  },
@@ -1250,60 +1570,60 @@ var schema = import_core.BlockNoteSchema.create({
1250
1570
  });
1251
1571
 
1252
1572
  // src/components/FloatingMenu/index.tsx
1253
- var import_react15 = require("react");
1573
+ var import_react17 = require("react");
1254
1574
 
1255
1575
  // src/components/FloatingMenu/Icons.tsx
1256
- var import_jsx_runtime3 = require("react/jsx-runtime");
1576
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1257
1577
  var Icons = {
1258
- undo: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z" }) }),
1259
- redo: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z" }) }),
1260
- bold: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z" }) }),
1261
- italic: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z" }) }),
1262
- underline: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z" }) }),
1263
- strikethrough: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z" }) }),
1264
- alignLeft: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z" }) }),
1265
- alignCenter: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z" }) }),
1266
- alignRight: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z" }) }),
1267
- bulletList: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z" }) }),
1268
- numberedList: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
1269
- image: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z" }) }),
1270
- expandMore: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" }) }),
1271
- textColor: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z" }) }),
1272
- bgColor: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1273
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M16.56 8.94L7.62 0 6.21 1.41l2.38 2.38-5.15 5.15c-.59.59-.59 1.54 0 2.12l5.5 5.5c.29.29.68.44 1.06.44s.77-.15 1.06-.44l5.5-5.5c.59-.58.59-1.53 0-2.12zM5.21 10L10 5.21 14.79 10H5.21zM19 11.5s-2 2.17-2 3.5c0 1.1.9 2 2 2s2-.9 2-2c0-1.33-2-3.5-2-3.5z" }),
1274
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { fillOpacity: ".36", d: "M0 20h24v4H0z" })
1578
+ undo: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z" }) }),
1579
+ redo: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z" }) }),
1580
+ bold: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z" }) }),
1581
+ italic: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z" }) }),
1582
+ underline: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z" }) }),
1583
+ strikethrough: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z" }) }),
1584
+ alignLeft: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z" }) }),
1585
+ alignCenter: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z" }) }),
1586
+ alignRight: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z" }) }),
1587
+ bulletList: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z" }) }),
1588
+ numberedList: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
1589
+ image: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z" }) }),
1590
+ expandMore: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" }) }),
1591
+ textColor: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z" }) }),
1592
+ bgColor: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1593
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M16.56 8.94L7.62 0 6.21 1.41l2.38 2.38-5.15 5.15c-.59.59-.59 1.54 0 2.12l5.5 5.5c.29.29.68.44 1.06.44s.77-.15 1.06-.44l5.5-5.5c.59-.58.59-1.53 0-2.12zM5.21 10L10 5.21 14.79 10H5.21zM19 11.5s-2 2.17-2 3.5c0 1.1.9 2 2 2s2-.9 2-2c0-1.33-2-3.5-2-3.5z" }),
1594
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { fillOpacity: ".36", d: "M0 20h24v4H0z" })
1275
1595
  ] }),
1276
- link: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" }) }),
1277
- chevronRight: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) }),
1278
- chevronLeft: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }) }),
1279
- table: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M20 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM10 17H5v-2h5v2zm0-4H5v-2h5v2zm0-4H5V7h5v2zm9 8h-7v-2h7v2zm0-4h-7v-2h7v2zm0-4h-7V7h7v2z" }) }),
1280
- htmlFile: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 2v5h5l-5-5zm-4 14H7v-1h2v1zm0-2H7v-1h2v1zm-2-2h2v1H7v-1zm4 4h-2v-1h2v1zm0-2h-2v-1h2v1zm0-2h-2v-1h2v1zm6 4h-4v-1h4v1zm0-2h-4v-1h4v1zm0-2h-4v-1h4v1z" }) })
1596
+ link: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" }) }),
1597
+ chevronRight: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) }),
1598
+ chevronLeft: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }) }),
1599
+ table: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M20 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM10 17H5v-2h5v2zm0-4H5v-2h5v2zm0-4H5V7h5v2zm9 8h-7v-2h7v2zm0-4h-7v-2h7v2zm0-4h-7V7h7v2z" }) }),
1600
+ htmlFile: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 2v5h5l-5-5zm-4 14H7v-1h2v1zm0-2H7v-1h2v1zm-2-2h2v1H7v-1zm4 4h-2v-1h2v1zm0-2h-2v-1h2v1zm0-2h-2v-1h2v1zm6 4h-4v-1h4v1zm0-2h-4v-1h4v1zm0-2h-4v-1h4v1z" }) })
1281
1601
  };
1282
1602
  var BlockTypeIcons = {
1283
- paragraph: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M5 5h14v2H5zM5 11h14v2H5zM5 17h10v2H5z" }) }),
1284
- h1: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lumir-block-icon-text", children: "H1" }),
1285
- h2: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lumir-block-icon-text", children: "H2" }),
1286
- h3: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lumir-block-icon-text", children: "H3" }),
1287
- h4: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lumir-block-icon-text", children: "H4" }),
1288
- h5: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lumir-block-icon-text", children: "H5" }),
1289
- h6: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lumir-block-icon-text", children: "H6" }),
1290
- toggleH1: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "lumir-block-icon-toggle", children: [
1291
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M8 5v14l11-7z" }) }),
1292
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "H1" })
1603
+ paragraph: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M5 5h14v2H5zM5 11h14v2H5zM5 17h10v2H5z" }) }),
1604
+ h1: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lumir-block-icon-text", children: "H1" }),
1605
+ h2: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lumir-block-icon-text", children: "H2" }),
1606
+ h3: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lumir-block-icon-text", children: "H3" }),
1607
+ h4: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lumir-block-icon-text", children: "H4" }),
1608
+ h5: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lumir-block-icon-text", children: "H5" }),
1609
+ h6: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lumir-block-icon-text", children: "H6" }),
1610
+ toggleH1: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "lumir-block-icon-toggle", children: [
1611
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M8 5v14l11-7z" }) }),
1612
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "H1" })
1293
1613
  ] }),
1294
- toggleH2: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "lumir-block-icon-toggle", children: [
1295
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M8 5v14l11-7z" }) }),
1296
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "H2" })
1614
+ toggleH2: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "lumir-block-icon-toggle", children: [
1615
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M8 5v14l11-7z" }) }),
1616
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "H2" })
1297
1617
  ] }),
1298
- toggleH3: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "lumir-block-icon-toggle", children: [
1299
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M8 5v14l11-7z" }) }),
1300
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "H3" })
1618
+ toggleH3: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "lumir-block-icon-toggle", children: [
1619
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M8 5v14l11-7z" }) }),
1620
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "H3" })
1301
1621
  ] }),
1302
- quote: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z" }) }),
1303
- codeBlock: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" }) }),
1304
- toggleList: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1305
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M10 6h10v2H10zM10 11h10v2H10zM10 16h10v2H10z" }),
1306
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1622
+ quote: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z" }) }),
1623
+ codeBlock: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" }) }),
1624
+ toggleList: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1625
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M10 6h10v2H10zM10 11h10v2H10zM10 16h10v2H10z" }),
1626
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1307
1627
  "path",
1308
1628
  {
1309
1629
  d: "M4 8l4 4-4 4",
@@ -1315,15 +1635,15 @@ var BlockTypeIcons = {
1315
1635
  }
1316
1636
  )
1317
1637
  ] }),
1318
- bulletList: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1319
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "4", cy: "6", r: "1.5" }),
1320
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "4", cy: "12", r: "1.5" }),
1321
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "4", cy: "18", r: "1.5" }),
1322
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M8 5h12v2H8zM8 11h12v2H8zM8 17h12v2H8z" })
1638
+ bulletList: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1639
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "4", cy: "6", r: "1.5" }),
1640
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "4", cy: "12", r: "1.5" }),
1641
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "4", cy: "18", r: "1.5" }),
1642
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M8 5h12v2H8zM8 11h12v2H8zM8 17h12v2H8z" })
1323
1643
  ] }),
1324
- numberedList: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
1325
- checkList: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1326
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1644
+ numberedList: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
1645
+ checkList: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1646
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1327
1647
  "rect",
1328
1648
  {
1329
1649
  x: "3",
@@ -1336,7 +1656,7 @@ var BlockTypeIcons = {
1336
1656
  strokeWidth: "1.5"
1337
1657
  }
1338
1658
  ),
1339
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1659
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1340
1660
  "path",
1341
1661
  {
1342
1662
  d: "M4.5 7l1.5 1.5 3-3",
@@ -1347,8 +1667,8 @@ var BlockTypeIcons = {
1347
1667
  strokeLinejoin: "round"
1348
1668
  }
1349
1669
  ),
1350
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 6h8v2h-8z" }),
1351
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1670
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 6h8v2h-8z" }),
1671
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1352
1672
  "rect",
1353
1673
  {
1354
1674
  x: "3",
@@ -1361,37 +1681,37 @@ var BlockTypeIcons = {
1361
1681
  strokeWidth: "1.5"
1362
1682
  }
1363
1683
  ),
1364
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 16h8v2h-8z" })
1684
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 16h8v2h-8z" })
1365
1685
  ] })
1366
1686
  };
1367
1687
 
1368
1688
  // src/components/FloatingMenu/components/ToolbarDivider.tsx
1369
- var import_jsx_runtime4 = require("react/jsx-runtime");
1370
- var ToolbarDivider = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "lumir-toolbar-divider" });
1689
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1690
+ var ToolbarDivider = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "lumir-toolbar-divider" });
1371
1691
 
1372
1692
  // src/components/FloatingMenu/components/UndoRedoButtons.tsx
1373
- var import_react5 = require("react");
1374
- var import_jsx_runtime5 = require("react/jsx-runtime");
1693
+ var import_react7 = require("react");
1694
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1375
1695
  var UndoRedoButtons = ({ editor }) => {
1376
- const handleUndo = (0, import_react5.useCallback)(() => {
1696
+ const handleUndo = (0, import_react7.useCallback)(() => {
1377
1697
  try {
1378
1698
  editor?.undo?.();
1379
1699
  } catch (err) {
1380
1700
  console.error("Undo failed:", err);
1381
1701
  }
1382
1702
  }, [editor]);
1383
- const handleRedo = (0, import_react5.useCallback)(() => {
1703
+ const handleRedo = (0, import_react7.useCallback)(() => {
1384
1704
  try {
1385
1705
  editor?.redo?.();
1386
1706
  } catch (err) {
1387
1707
  console.error("Redo failed:", err);
1388
1708
  }
1389
1709
  }, [editor]);
1390
- const handleMouseDown = (0, import_react5.useCallback)((e) => {
1710
+ const handleMouseDown = (0, import_react7.useCallback)((e) => {
1391
1711
  e.preventDefault();
1392
1712
  }, []);
1393
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "lumir-toolbar-group", children: [
1394
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1713
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "lumir-toolbar-group", children: [
1714
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1395
1715
  "button",
1396
1716
  {
1397
1717
  className: "lumir-toolbar-btn",
@@ -1402,7 +1722,7 @@ var UndoRedoButtons = ({ editor }) => {
1402
1722
  children: Icons.undo
1403
1723
  }
1404
1724
  ),
1405
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1725
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1406
1726
  "button",
1407
1727
  {
1408
1728
  className: "lumir-toolbar-btn",
@@ -1417,8 +1737,8 @@ var UndoRedoButtons = ({ editor }) => {
1417
1737
  };
1418
1738
 
1419
1739
  // src/components/FloatingMenu/components/TextStyleButton.tsx
1420
- var import_react6 = require("react");
1421
- var import_jsx_runtime6 = require("react/jsx-runtime");
1740
+ var import_react8 = require("react");
1741
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1422
1742
  var iconMap = {
1423
1743
  bold: Icons.bold,
1424
1744
  italic: Icons.italic,
@@ -1444,17 +1764,17 @@ var TextStyleButton = ({
1444
1764
  }
1445
1765
  };
1446
1766
  const isActive = getIsActive();
1447
- const handleClick = (0, import_react6.useCallback)(() => {
1767
+ const handleClick = (0, import_react8.useCallback)(() => {
1448
1768
  try {
1449
1769
  editor?.toggleStyles?.({ [style]: true });
1450
1770
  } catch (err) {
1451
1771
  console.error(`Toggle ${style} failed:`, err);
1452
1772
  }
1453
1773
  }, [editor, style]);
1454
- const handleMouseDown = (0, import_react6.useCallback)((e) => {
1774
+ const handleMouseDown = (0, import_react8.useCallback)((e) => {
1455
1775
  e.preventDefault();
1456
1776
  }, []);
1457
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1777
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1458
1778
  "button",
1459
1779
  {
1460
1780
  className: cn("lumir-toolbar-btn", isActive && "is-active"),
@@ -1468,8 +1788,8 @@ var TextStyleButton = ({
1468
1788
  };
1469
1789
 
1470
1790
  // src/components/FloatingMenu/components/AlignButton.tsx
1471
- var import_react7 = require("react");
1472
- var import_jsx_runtime7 = require("react/jsx-runtime");
1791
+ var import_react9 = require("react");
1792
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1473
1793
  var iconMap2 = {
1474
1794
  left: Icons.alignLeft,
1475
1795
  center: Icons.alignCenter,
@@ -1493,7 +1813,7 @@ var AlignButton = ({
1493
1813
  }
1494
1814
  };
1495
1815
  const isActive = getCurrentAlignment() === alignment;
1496
- const handleClick = (0, import_react7.useCallback)(() => {
1816
+ const handleClick = (0, import_react9.useCallback)(() => {
1497
1817
  try {
1498
1818
  const block = editor?.getTextCursorPosition()?.block;
1499
1819
  if (block && editor?.updateBlock) {
@@ -1503,10 +1823,10 @@ var AlignButton = ({
1503
1823
  console.error(`Set alignment ${alignment} failed:`, err);
1504
1824
  }
1505
1825
  }, [editor, alignment]);
1506
- const handleMouseDown = (0, import_react7.useCallback)((e) => {
1826
+ const handleMouseDown = (0, import_react9.useCallback)((e) => {
1507
1827
  e.preventDefault();
1508
1828
  }, []);
1509
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1829
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1510
1830
  "button",
1511
1831
  {
1512
1832
  className: cn("lumir-toolbar-btn", isActive && "is-active"),
@@ -1520,8 +1840,8 @@ var AlignButton = ({
1520
1840
  };
1521
1841
 
1522
1842
  // src/components/FloatingMenu/components/ListButton.tsx
1523
- var import_react8 = require("react");
1524
- var import_jsx_runtime8 = require("react/jsx-runtime");
1843
+ var import_react10 = require("react");
1844
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1525
1845
  var iconMap3 = {
1526
1846
  bullet: Icons.bulletList,
1527
1847
  numbered: Icons.numberedList
@@ -1541,7 +1861,7 @@ var ListButton = ({ editor, type }) => {
1541
1861
  }
1542
1862
  };
1543
1863
  const isActive = getIsActive();
1544
- const handleClick = (0, import_react8.useCallback)(() => {
1864
+ const handleClick = (0, import_react10.useCallback)(() => {
1545
1865
  try {
1546
1866
  const block = editor?.getTextCursorPosition()?.block;
1547
1867
  if (block && editor?.updateBlock) {
@@ -1553,10 +1873,10 @@ var ListButton = ({ editor, type }) => {
1553
1873
  console.error(`List toggle failed:`, err);
1554
1874
  }
1555
1875
  }, [editor, type]);
1556
- const handleMouseDown = (0, import_react8.useCallback)((e) => {
1876
+ const handleMouseDown = (0, import_react10.useCallback)((e) => {
1557
1877
  e.preventDefault();
1558
1878
  }, []);
1559
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1879
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1560
1880
  "button",
1561
1881
  {
1562
1882
  className: cn("lumir-toolbar-btn", isActive && "is-active"),
@@ -1570,13 +1890,13 @@ var ListButton = ({ editor, type }) => {
1570
1890
  };
1571
1891
 
1572
1892
  // src/components/FloatingMenu/components/ImageButton.tsx
1573
- var import_react9 = require("react");
1574
- var import_jsx_runtime9 = require("react/jsx-runtime");
1893
+ var import_react11 = require("react");
1894
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1575
1895
  var ImageButton = ({
1576
1896
  editor,
1577
1897
  onImageUpload
1578
1898
  }) => {
1579
- const handleClick = (0, import_react9.useCallback)(() => {
1899
+ const handleClick = (0, import_react11.useCallback)(() => {
1580
1900
  if (onImageUpload) {
1581
1901
  onImageUpload();
1582
1902
  } else {
@@ -1601,10 +1921,10 @@ var ImageButton = ({
1601
1921
  input.click();
1602
1922
  }
1603
1923
  }, [editor, onImageUpload]);
1604
- const handleMouseDown = (0, import_react9.useCallback)((e) => {
1924
+ const handleMouseDown = (0, import_react11.useCallback)((e) => {
1605
1925
  e.preventDefault();
1606
1926
  }, []);
1607
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1927
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1608
1928
  "button",
1609
1929
  {
1610
1930
  className: "lumir-toolbar-btn",
@@ -1618,7 +1938,7 @@ var ImageButton = ({
1618
1938
  };
1619
1939
 
1620
1940
  // src/components/FloatingMenu/components/ColorButton.tsx
1621
- var import_react10 = require("react");
1941
+ var import_react12 = require("react");
1622
1942
 
1623
1943
  // src/constants/colors.ts
1624
1944
  var TEXT_COLORS = [
@@ -1652,13 +1972,13 @@ var getHexFromColorValue = (value, type) => {
1652
1972
  };
1653
1973
 
1654
1974
  // src/components/FloatingMenu/components/ColorButton.tsx
1655
- var import_jsx_runtime10 = require("react/jsx-runtime");
1975
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1656
1976
  var ColorButton = ({ editor, type }) => {
1657
- const [isOpen, setIsOpen] = (0, import_react10.useState)(false);
1658
- const [currentColor, setCurrentColor] = (0, import_react10.useState)("default");
1659
- const dropdownRef = (0, import_react10.useRef)(null);
1977
+ const [isOpen, setIsOpen] = (0, import_react12.useState)(false);
1978
+ const [currentColor, setCurrentColor] = (0, import_react12.useState)("default");
1979
+ const dropdownRef = (0, import_react12.useRef)(null);
1660
1980
  const colors = type === "text" ? TEXT_COLORS : BACKGROUND_COLORS;
1661
- const getCurrentColor = (0, import_react10.useCallback)(() => {
1981
+ const getCurrentColor = (0, import_react12.useCallback)(() => {
1662
1982
  try {
1663
1983
  const activeStyles = editor?.getActiveStyles?.() || {};
1664
1984
  if (type === "text" && activeStyles.textColor) {
@@ -1670,13 +1990,13 @@ var ColorButton = ({ editor, type }) => {
1670
1990
  }
1671
1991
  return "default";
1672
1992
  }, [editor, type]);
1673
- (0, import_react10.useEffect)(() => {
1993
+ (0, import_react12.useEffect)(() => {
1674
1994
  if (isOpen) {
1675
1995
  const color = getCurrentColor();
1676
1996
  setCurrentColor(color);
1677
1997
  }
1678
1998
  }, [isOpen, getCurrentColor]);
1679
- (0, import_react10.useEffect)(() => {
1999
+ (0, import_react12.useEffect)(() => {
1680
2000
  const handleClickOutside = (e) => {
1681
2001
  if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
1682
2002
  setIsOpen(false);
@@ -1685,7 +2005,7 @@ var ColorButton = ({ editor, type }) => {
1685
2005
  document.addEventListener("mousedown", handleClickOutside);
1686
2006
  return () => document.removeEventListener("mousedown", handleClickOutside);
1687
2007
  }, []);
1688
- const handleColorSelect = (0, import_react10.useCallback)(
2008
+ const handleColorSelect = (0, import_react12.useCallback)(
1689
2009
  (color) => {
1690
2010
  try {
1691
2011
  if (!editor) return;
@@ -1702,11 +2022,11 @@ var ColorButton = ({ editor, type }) => {
1702
2022
  },
1703
2023
  [editor, type]
1704
2024
  );
1705
- const handleMouseDown = (0, import_react10.useCallback)((e) => {
2025
+ const handleMouseDown = (0, import_react12.useCallback)((e) => {
1706
2026
  e.preventDefault();
1707
2027
  }, []);
1708
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
1709
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2028
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
2029
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1710
2030
  "button",
1711
2031
  {
1712
2032
  className: "lumir-toolbar-btn lumir-color-btn",
@@ -1716,7 +2036,7 @@ var ColorButton = ({ editor, type }) => {
1716
2036
  type: "button",
1717
2037
  children: [
1718
2038
  type === "text" ? Icons.textColor : Icons.bgColor,
1719
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2039
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1720
2040
  "span",
1721
2041
  {
1722
2042
  className: "lumir-color-indicator",
@@ -1728,7 +2048,7 @@ var ColorButton = ({ editor, type }) => {
1728
2048
  ]
1729
2049
  }
1730
2050
  ),
1731
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "lumir-dropdown-menu lumir-color-menu", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "lumir-color-grid", children: colors.map((color) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2051
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "lumir-dropdown-menu lumir-color-menu", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "lumir-color-grid", children: colors.map((color) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1732
2052
  "button",
1733
2053
  {
1734
2054
  className: cn(
@@ -1747,8 +2067,8 @@ var ColorButton = ({ editor, type }) => {
1747
2067
  };
1748
2068
 
1749
2069
  // src/components/FloatingMenu/components/LinkButton.tsx
1750
- var import_react11 = require("react");
1751
- var import_jsx_runtime11 = require("react/jsx-runtime");
2070
+ var import_react13 = require("react");
2071
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1752
2072
  var isDangerousProtocol = (url) => {
1753
2073
  const trimmedUrl = url.trim().toLowerCase();
1754
2074
  const dangerousPatterns = [
@@ -1774,13 +2094,13 @@ var normalizeUrl = (url) => {
1774
2094
  return `https://${trimmedUrl}`;
1775
2095
  };
1776
2096
  var LinkButton = ({ editor }) => {
1777
- const [isOpen, setIsOpen] = (0, import_react11.useState)(false);
1778
- const [linkUrl, setLinkUrl] = (0, import_react11.useState)("");
1779
- const [errorMsg, setErrorMsg] = (0, import_react11.useState)(null);
1780
- const dropdownRef = (0, import_react11.useRef)(null);
1781
- const inputRef = (0, import_react11.useRef)(null);
1782
- const hasSelectionRef = (0, import_react11.useRef)(false);
1783
- (0, import_react11.useEffect)(() => {
2097
+ const [isOpen, setIsOpen] = (0, import_react13.useState)(false);
2098
+ const [linkUrl, setLinkUrl] = (0, import_react13.useState)("");
2099
+ const [errorMsg, setErrorMsg] = (0, import_react13.useState)(null);
2100
+ const dropdownRef = (0, import_react13.useRef)(null);
2101
+ const inputRef = (0, import_react13.useRef)(null);
2102
+ const hasSelectionRef = (0, import_react13.useRef)(false);
2103
+ (0, import_react13.useEffect)(() => {
1784
2104
  const handleClickOutside = (e) => {
1785
2105
  if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
1786
2106
  setIsOpen(false);
@@ -1791,7 +2111,7 @@ var LinkButton = ({ editor }) => {
1791
2111
  document.addEventListener("mousedown", handleClickOutside);
1792
2112
  return () => document.removeEventListener("mousedown", handleClickOutside);
1793
2113
  }, []);
1794
- (0, import_react11.useEffect)(() => {
2114
+ (0, import_react13.useEffect)(() => {
1795
2115
  if (isOpen && inputRef.current) {
1796
2116
  try {
1797
2117
  const selectedText = editor?.getSelectedText?.() || "";
@@ -1802,7 +2122,7 @@ var LinkButton = ({ editor }) => {
1802
2122
  setTimeout(() => inputRef.current?.focus(), 0);
1803
2123
  }
1804
2124
  }, [isOpen, editor]);
1805
- const handleSubmit = (0, import_react11.useCallback)(
2125
+ const handleSubmit = (0, import_react13.useCallback)(
1806
2126
  (e) => {
1807
2127
  e?.preventDefault();
1808
2128
  setErrorMsg(null);
@@ -1829,15 +2149,15 @@ var LinkButton = ({ editor }) => {
1829
2149
  },
1830
2150
  [editor, linkUrl]
1831
2151
  );
1832
- const handleCancel = (0, import_react11.useCallback)(() => {
2152
+ const handleCancel = (0, import_react13.useCallback)(() => {
1833
2153
  setIsOpen(false);
1834
2154
  setLinkUrl("");
1835
2155
  setErrorMsg(null);
1836
2156
  }, []);
1837
- const handleMouseDown = (0, import_react11.useCallback)((e) => {
2157
+ const handleMouseDown = (0, import_react13.useCallback)((e) => {
1838
2158
  e.preventDefault();
1839
2159
  }, []);
1840
- const handleKeyDown = (0, import_react11.useCallback)(
2160
+ const handleKeyDown = (0, import_react13.useCallback)(
1841
2161
  (e) => {
1842
2162
  if (e.key === "Enter") {
1843
2163
  handleSubmit();
@@ -1847,8 +2167,8 @@ var LinkButton = ({ editor }) => {
1847
2167
  },
1848
2168
  [handleSubmit, handleCancel]
1849
2169
  );
1850
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
1851
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2170
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
2171
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1852
2172
  "button",
1853
2173
  {
1854
2174
  className: "lumir-toolbar-btn",
@@ -1859,8 +2179,8 @@ var LinkButton = ({ editor }) => {
1859
2179
  children: Icons.link
1860
2180
  }
1861
2181
  ),
1862
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "lumir-dropdown-menu lumir-link-menu", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("form", { onSubmit: handleSubmit, className: "lumir-link-form", children: [
1863
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2182
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "lumir-dropdown-menu lumir-link-menu", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("form", { onSubmit: handleSubmit, className: "lumir-link-form", children: [
2183
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1864
2184
  "input",
1865
2185
  {
1866
2186
  ref: inputRef,
@@ -1876,7 +2196,7 @@ var LinkButton = ({ editor }) => {
1876
2196
  onMouseDown: handleMouseDown
1877
2197
  }
1878
2198
  ),
1879
- errorMsg && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2199
+ errorMsg && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1880
2200
  "div",
1881
2201
  {
1882
2202
  style: {
@@ -1888,8 +2208,8 @@ var LinkButton = ({ editor }) => {
1888
2208
  children: errorMsg
1889
2209
  }
1890
2210
  ),
1891
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "lumir-link-actions", children: [
1892
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2211
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "lumir-link-actions", children: [
2212
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1893
2213
  "button",
1894
2214
  {
1895
2215
  type: "button",
@@ -1899,7 +2219,7 @@ var LinkButton = ({ editor }) => {
1899
2219
  children: "\uCDE8\uC18C"
1900
2220
  }
1901
2221
  ),
1902
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2222
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1903
2223
  "button",
1904
2224
  {
1905
2225
  type: "submit",
@@ -1915,10 +2235,10 @@ var LinkButton = ({ editor }) => {
1915
2235
  };
1916
2236
 
1917
2237
  // src/components/FloatingMenu/components/TableButton.tsx
1918
- var import_react12 = require("react");
1919
- var import_jsx_runtime12 = require("react/jsx-runtime");
2238
+ var import_react14 = require("react");
2239
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1920
2240
  var TableButton = ({ editor }) => {
1921
- const handleClick = (0, import_react12.useCallback)(() => {
2241
+ const handleClick = (0, import_react14.useCallback)(() => {
1922
2242
  try {
1923
2243
  const block = editor?.getTextCursorPosition()?.block;
1924
2244
  if (!block || !editor?.insertBlocks) return;
@@ -1940,10 +2260,10 @@ var TableButton = ({ editor }) => {
1940
2260
  console.error("Table insert failed:", err);
1941
2261
  }
1942
2262
  }, [editor]);
1943
- const handleMouseDown = (0, import_react12.useCallback)((e) => {
2263
+ const handleMouseDown = (0, import_react14.useCallback)((e) => {
1944
2264
  e.preventDefault();
1945
2265
  }, []);
1946
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2266
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1947
2267
  "button",
1948
2268
  {
1949
2269
  className: "lumir-toolbar-btn",
@@ -1957,13 +2277,13 @@ var TableButton = ({ editor }) => {
1957
2277
  };
1958
2278
 
1959
2279
  // src/components/FloatingMenu/components/HTMLImportButton.tsx
1960
- var import_react13 = require("react");
1961
- var import_jsx_runtime13 = require("react/jsx-runtime");
2280
+ var import_react15 = require("react");
2281
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1962
2282
  var HTMLImportButton = ({
1963
2283
  editor
1964
2284
  }) => {
1965
- const fileInputRef = (0, import_react13.useRef)(null);
1966
- const handleFileUpload = (0, import_react13.useCallback)(
2285
+ const fileInputRef = (0, import_react15.useRef)(null);
2286
+ const handleFileUpload = (0, import_react15.useCallback)(
1967
2287
  (e) => {
1968
2288
  const file = e.target.files?.[0];
1969
2289
  if (!file) return;
@@ -1999,14 +2319,14 @@ var HTMLImportButton = ({
1999
2319
  },
2000
2320
  [editor]
2001
2321
  );
2002
- const handleClick = (0, import_react13.useCallback)(() => {
2322
+ const handleClick = (0, import_react15.useCallback)(() => {
2003
2323
  fileInputRef.current?.click();
2004
2324
  }, []);
2005
- const handleMouseDown = (0, import_react13.useCallback)((e) => {
2325
+ const handleMouseDown = (0, import_react15.useCallback)((e) => {
2006
2326
  e.preventDefault();
2007
2327
  }, []);
2008
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2009
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2328
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
2329
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2010
2330
  "input",
2011
2331
  {
2012
2332
  ref: fileInputRef,
@@ -2016,7 +2336,7 @@ var HTMLImportButton = ({
2016
2336
  style: { display: "none" }
2017
2337
  }
2018
2338
  ),
2019
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2339
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2020
2340
  "button",
2021
2341
  {
2022
2342
  className: "lumir-toolbar-btn",
@@ -2031,8 +2351,8 @@ var HTMLImportButton = ({
2031
2351
  };
2032
2352
 
2033
2353
  // src/components/FloatingMenu/components/BlockTypeSelect.tsx
2034
- var import_react14 = require("react");
2035
- var import_jsx_runtime14 = require("react/jsx-runtime");
2354
+ var import_react16 = require("react");
2355
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2036
2356
  var blockTypeCategories = [
2037
2357
  {
2038
2358
  category: "Headings",
@@ -2062,8 +2382,8 @@ var blockTypes = blockTypeCategories.flatMap(
2062
2382
  (cat) => cat.items
2063
2383
  );
2064
2384
  var BlockTypeSelect = ({ editor }) => {
2065
- const [isOpen, setIsOpen] = (0, import_react14.useState)(false);
2066
- const dropdownRef = (0, import_react14.useRef)(null);
2385
+ const [isOpen, setIsOpen] = (0, import_react16.useState)(false);
2386
+ const dropdownRef = (0, import_react16.useRef)(null);
2067
2387
  const getCurrentBlock = () => {
2068
2388
  try {
2069
2389
  return editor?.getTextCursorPosition()?.block;
@@ -2075,7 +2395,7 @@ var BlockTypeSelect = ({ editor }) => {
2075
2395
  const currentType = currentBlock?.type || "paragraph";
2076
2396
  const currentLevel = currentBlock?.props?.level;
2077
2397
  const isCurrentToggle = currentType === "heading" && currentBlock?.props?.isToggleable === true;
2078
- (0, import_react14.useEffect)(() => {
2398
+ (0, import_react16.useEffect)(() => {
2079
2399
  const handleClickOutside = (e) => {
2080
2400
  if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
2081
2401
  setIsOpen(false);
@@ -2104,7 +2424,7 @@ var BlockTypeSelect = ({ editor }) => {
2104
2424
  console.error("Block type change failed:", err);
2105
2425
  }
2106
2426
  };
2107
- const handleMouseDown = (0, import_react14.useCallback)((e) => {
2427
+ const handleMouseDown = (0, import_react16.useCallback)((e) => {
2108
2428
  e.preventDefault();
2109
2429
  }, []);
2110
2430
  const getCurrentLabel = () => {
@@ -2135,8 +2455,8 @@ var BlockTypeSelect = ({ editor }) => {
2135
2455
  }
2136
2456
  return currentType === bt.type;
2137
2457
  };
2138
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
2139
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2458
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
2459
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2140
2460
  "button",
2141
2461
  {
2142
2462
  className: "lumir-dropdown-btn lumir-block-type-btn",
@@ -2144,15 +2464,15 @@ var BlockTypeSelect = ({ editor }) => {
2144
2464
  onMouseDown: handleMouseDown,
2145
2465
  type: "button",
2146
2466
  children: [
2147
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "lumir-block-icon", children: BlockTypeIcons[getCurrentIcon()] }),
2148
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "lumir-block-label", children: getCurrentLabel() }),
2467
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "lumir-block-icon", children: BlockTypeIcons[getCurrentIcon()] }),
2468
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "lumir-block-label", children: getCurrentLabel() }),
2149
2469
  Icons.expandMore
2150
2470
  ]
2151
2471
  }
2152
2472
  ),
2153
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "lumir-dropdown-menu lumir-block-menu", children: blockTypeCategories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "lumir-block-category", children: [
2154
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "lumir-block-category-title", children: category.category }),
2155
- category.items.map((bt) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2473
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "lumir-dropdown-menu lumir-block-menu", children: blockTypeCategories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-block-category", children: [
2474
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "lumir-block-category-title", children: category.category }),
2475
+ category.items.map((bt) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2156
2476
  "button",
2157
2477
  {
2158
2478
  className: cn(
@@ -2162,8 +2482,8 @@ var BlockTypeSelect = ({ editor }) => {
2162
2482
  onClick: () => handleTypeChange(bt.type, bt.level, bt.isToggle),
2163
2483
  onMouseDown: handleMouseDown,
2164
2484
  children: [
2165
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "lumir-block-icon", children: BlockTypeIcons[bt.icon] }),
2166
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "lumir-block-item-title", children: bt.label })
2485
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "lumir-block-icon", children: BlockTypeIcons[bt.icon] }),
2486
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "lumir-block-item-title", children: bt.label })
2167
2487
  ]
2168
2488
  },
2169
2489
  bt.icon
@@ -2173,7 +2493,7 @@ var BlockTypeSelect = ({ editor }) => {
2173
2493
  };
2174
2494
 
2175
2495
  // src/components/FloatingMenu/index.tsx
2176
- var import_jsx_runtime15 = require("react/jsx-runtime");
2496
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2177
2497
  var COMPACT_BREAKPOINT = 700;
2178
2498
  var MINIMIZED_BREAKPOINT = 400;
2179
2499
  var FloatingMenu = ({
@@ -2182,12 +2502,12 @@ var FloatingMenu = ({
2182
2502
  className,
2183
2503
  onImageUpload
2184
2504
  }) => {
2185
- const wrapperRef = (0, import_react15.useRef)(null);
2186
- const [isCompact, setIsCompact] = (0, import_react15.useState)(false);
2187
- const [isMinimizable, setIsMinimizable] = (0, import_react15.useState)(false);
2188
- const [isMinimized, setIsMinimized] = (0, import_react15.useState)(false);
2189
- const [, setSelectionTick] = (0, import_react15.useState)(0);
2190
- (0, import_react15.useEffect)(() => {
2505
+ const wrapperRef = (0, import_react17.useRef)(null);
2506
+ const [isCompact, setIsCompact] = (0, import_react17.useState)(false);
2507
+ const [isMinimizable, setIsMinimizable] = (0, import_react17.useState)(false);
2508
+ const [isMinimized, setIsMinimized] = (0, import_react17.useState)(false);
2509
+ const [, setSelectionTick] = (0, import_react17.useState)(0);
2510
+ (0, import_react17.useEffect)(() => {
2191
2511
  if (!editor) return;
2192
2512
  let debounceTimer = null;
2193
2513
  const DEBOUNCE_DELAY = 150;
@@ -2211,7 +2531,7 @@ var FloatingMenu = ({
2211
2531
  unsubscribeContent?.();
2212
2532
  };
2213
2533
  }, [editor]);
2214
- (0, import_react15.useEffect)(() => {
2534
+ (0, import_react17.useEffect)(() => {
2215
2535
  const checkWidth = () => {
2216
2536
  if (wrapperRef.current) {
2217
2537
  const width = wrapperRef.current.offsetWidth;
@@ -2226,8 +2546,8 @@ var FloatingMenu = ({
2226
2546
  }
2227
2547
  return () => resizeObserver.disconnect();
2228
2548
  }, []);
2229
- const MinimizedLayout = () => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
2230
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2549
+ const MinimizedLayout = () => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
2550
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2231
2551
  "button",
2232
2552
  {
2233
2553
  className: "lumir-toolbar-button lumir-toggle-button",
@@ -2238,117 +2558,117 @@ var FloatingMenu = ({
2238
2558
  children: isMinimized ? Icons.chevronRight : Icons.chevronLeft
2239
2559
  }
2240
2560
  ),
2241
- !isMinimized && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
2242
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2243
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(UndoRedoButtons, { editor }),
2244
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2245
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(BlockTypeSelect, { editor }) }),
2246
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2247
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2248
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "bold" }),
2249
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "italic" }),
2250
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "underline" }),
2251
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "strike" })
2561
+ !isMinimized && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
2562
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2563
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(UndoRedoButtons, { editor }),
2564
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2565
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(BlockTypeSelect, { editor }) }),
2566
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2567
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2568
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "bold" }),
2569
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "italic" }),
2570
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "underline" }),
2571
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "strike" })
2252
2572
  ] }),
2253
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2254
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2255
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AlignButton, { editor, alignment: "left" }),
2256
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AlignButton, { editor, alignment: "center" }),
2257
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AlignButton, { editor, alignment: "right" })
2573
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2574
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2575
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AlignButton, { editor, alignment: "left" }),
2576
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AlignButton, { editor, alignment: "center" }),
2577
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AlignButton, { editor, alignment: "right" })
2258
2578
  ] }),
2259
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2260
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2261
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ListButton, { editor, type: "bullet" }),
2262
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ListButton, { editor, type: "numbered" })
2579
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2580
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2581
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ListButton, { editor, type: "bullet" }),
2582
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ListButton, { editor, type: "numbered" })
2263
2583
  ] }),
2264
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2265
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2266
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ColorButton, { editor, type: "text" }),
2267
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ColorButton, { editor, type: "background" })
2584
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2585
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2586
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ColorButton, { editor, type: "text" }),
2587
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ColorButton, { editor, type: "background" })
2268
2588
  ] }),
2269
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2270
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2271
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ImageButton, { editor, onImageUpload }),
2272
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(LinkButton, { editor }),
2273
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TableButton, { editor }),
2274
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(HTMLImportButton, { editor })
2589
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2590
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2591
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ImageButton, { editor, onImageUpload }),
2592
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(LinkButton, { editor }),
2593
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TableButton, { editor }),
2594
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(HTMLImportButton, { editor })
2275
2595
  ] })
2276
2596
  ] })
2277
2597
  ] });
2278
- const SingleRowLayout = () => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
2279
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(UndoRedoButtons, { editor }),
2280
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2281
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(BlockTypeSelect, { editor }) }),
2282
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2283
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2284
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "bold" }),
2285
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "italic" }),
2286
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "underline" }),
2287
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "strike" })
2598
+ const SingleRowLayout = () => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
2599
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(UndoRedoButtons, { editor }),
2600
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2601
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(BlockTypeSelect, { editor }) }),
2602
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2603
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2604
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "bold" }),
2605
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "italic" }),
2606
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "underline" }),
2607
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "strike" })
2288
2608
  ] }),
2289
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2290
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2291
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AlignButton, { editor, alignment: "left" }),
2292
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AlignButton, { editor, alignment: "center" }),
2293
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AlignButton, { editor, alignment: "right" })
2609
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2610
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2611
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AlignButton, { editor, alignment: "left" }),
2612
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AlignButton, { editor, alignment: "center" }),
2613
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AlignButton, { editor, alignment: "right" })
2294
2614
  ] }),
2295
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2296
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2297
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ListButton, { editor, type: "bullet" }),
2298
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ListButton, { editor, type: "numbered" })
2615
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2616
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2617
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ListButton, { editor, type: "bullet" }),
2618
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ListButton, { editor, type: "numbered" })
2299
2619
  ] }),
2300
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2301
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2302
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ColorButton, { editor, type: "text" }),
2303
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ColorButton, { editor, type: "background" })
2620
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2621
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2622
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ColorButton, { editor, type: "text" }),
2623
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ColorButton, { editor, type: "background" })
2304
2624
  ] }),
2305
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2306
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2307
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ImageButton, { editor, onImageUpload }),
2308
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(LinkButton, { editor }),
2309
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TableButton, { editor }),
2310
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(HTMLImportButton, { editor })
2625
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2626
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2627
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ImageButton, { editor, onImageUpload }),
2628
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(LinkButton, { editor }),
2629
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TableButton, { editor }),
2630
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(HTMLImportButton, { editor })
2311
2631
  ] })
2312
2632
  ] });
2313
- const TwoRowLayout = () => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
2314
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-row", children: [
2315
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(UndoRedoButtons, { editor }),
2316
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2317
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2318
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "bold" }),
2319
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "italic" }),
2320
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "underline" }),
2321
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextStyleButton, { editor, style: "strike" })
2633
+ const TwoRowLayout = () => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
2634
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-row", children: [
2635
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(UndoRedoButtons, { editor }),
2636
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2637
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2638
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "bold" }),
2639
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "italic" }),
2640
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "underline" }),
2641
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TextStyleButton, { editor, style: "strike" })
2322
2642
  ] }),
2323
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2324
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2325
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AlignButton, { editor, alignment: "left" }),
2326
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AlignButton, { editor, alignment: "center" }),
2327
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AlignButton, { editor, alignment: "right" })
2643
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2644
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2645
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AlignButton, { editor, alignment: "left" }),
2646
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AlignButton, { editor, alignment: "center" }),
2647
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AlignButton, { editor, alignment: "right" })
2328
2648
  ] }),
2329
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2330
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2331
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ListButton, { editor, type: "bullet" }),
2332
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ListButton, { editor, type: "numbered" })
2649
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2650
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2651
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ListButton, { editor, type: "bullet" }),
2652
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ListButton, { editor, type: "numbered" })
2333
2653
  ] })
2334
2654
  ] }),
2335
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-row", children: [
2336
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(BlockTypeSelect, { editor }) }),
2337
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2338
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2339
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ColorButton, { editor, type: "text" }),
2340
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ColorButton, { editor, type: "background" })
2655
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-row", children: [
2656
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(BlockTypeSelect, { editor }) }),
2657
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2658
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2659
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ColorButton, { editor, type: "text" }),
2660
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ColorButton, { editor, type: "background" })
2341
2661
  ] }),
2342
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolbarDivider, {}),
2343
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lumir-toolbar-group", children: [
2344
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ImageButton, { editor, onImageUpload }),
2345
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(LinkButton, { editor }),
2346
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TableButton, { editor }),
2347
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(HTMLImportButton, { editor })
2662
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToolbarDivider, {}),
2663
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumir-toolbar-group", children: [
2664
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ImageButton, { editor, onImageUpload }),
2665
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(LinkButton, { editor }),
2666
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TableButton, { editor }),
2667
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(HTMLImportButton, { editor })
2348
2668
  ] })
2349
2669
  ] })
2350
2670
  ] });
2351
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2671
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2352
2672
  "div",
2353
2673
  {
2354
2674
  ref: wrapperRef,
@@ -2358,7 +2678,7 @@ var FloatingMenu = ({
2358
2678
  className
2359
2679
  ),
2360
2680
  "data-position": position,
2361
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2681
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2362
2682
  "div",
2363
2683
  {
2364
2684
  className: cn(
@@ -2367,7 +2687,7 @@ var FloatingMenu = ({
2367
2687
  isMinimizable && "is-minimizable",
2368
2688
  isMinimized && "is-minimized"
2369
2689
  ),
2370
- children: isMinimizable ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MinimizedLayout, {}) : isCompact ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TwoRowLayout, {}) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SingleRowLayout, {})
2690
+ children: isMinimizable ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MinimizedLayout, {}) : isCompact ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TwoRowLayout, {}) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SingleRowLayout, {})
2371
2691
  }
2372
2692
  )
2373
2693
  }
@@ -2438,15 +2758,14 @@ var LumirEditorError = class _LumirEditorError extends Error {
2438
2758
  }
2439
2759
  /**
2440
2760
  * 잘못된 파일 형식 에러 생성
2761
+ * @param allowVideoUpload true이면 "image and video" 메시지 사용
2441
2762
  */
2442
- static invalidFileType(fileName) {
2443
- return new _LumirEditorError(
2444
- `Invalid file type: ${fileName}. Only image files are allowed.`,
2445
- {
2446
- code: "INVALID_FILE_TYPE",
2447
- context: { fileName }
2448
- }
2449
- );
2763
+ static invalidFileType(fileName, allowVideoUpload) {
2764
+ const message = allowVideoUpload === true ? `Invalid file type: ${fileName}. Only image and video files are allowed.` : `Invalid file type: ${fileName}. Only image files are allowed.`;
2765
+ return new _LumirEditorError(message, {
2766
+ code: "INVALID_FILE_TYPE",
2767
+ context: { fileName }
2768
+ });
2450
2769
  }
2451
2770
  /**
2452
2771
  * S3 설정 에러 생성
@@ -2469,10 +2788,38 @@ var LumirEditorError = class _LumirEditorError extends Error {
2469
2788
 
2470
2789
  // src/constants/limits.ts
2471
2790
  var MAX_FILE_SIZE = 10 * 1024 * 1024;
2791
+ var MAX_VIDEO_FILE_SIZE = 100 * 1024 * 1024;
2472
2792
  var BLOCKED_EXTENSIONS = [".svg", ".svgz"];
2793
+ var ALLOWED_VIDEO_MIME_TYPES = /* @__PURE__ */ new Set([
2794
+ "video/mp4",
2795
+ "video/webm",
2796
+ "video/ogg",
2797
+ "video/quicktime"
2798
+ // .mov
2799
+ ]);
2800
+ var ALLOWED_VIDEO_EXTENSIONS = [
2801
+ ".mp4",
2802
+ ".webm",
2803
+ ".ogg",
2804
+ ".mov"
2805
+ ];
2473
2806
 
2474
2807
  // src/components/LumirEditor.tsx
2475
- var import_jsx_runtime16 = require("react/jsx-runtime");
2808
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2809
+ var DEBUG_LOG = (loc, msg, data) => {
2810
+ fetch("http://127.0.0.1:7686/ingest/1f8ee1c5-0cf0-4ae7-91ed-5ea7ed17130a", {
2811
+ method: "POST",
2812
+ headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "b73262" },
2813
+ body: JSON.stringify({
2814
+ sessionId: "b73262",
2815
+ location: loc,
2816
+ message: msg,
2817
+ data,
2818
+ timestamp: Date.now()
2819
+ })
2820
+ }).catch(() => {
2821
+ });
2822
+ };
2476
2823
  var ContentUtils = class {
2477
2824
  /**
2478
2825
  * JSON 문자열의 유효성을 검증합니다
@@ -2601,6 +2948,25 @@ var isImageFile = (file) => {
2601
2948
  }
2602
2949
  return file.type?.startsWith("image/") || !file.type && /\.(png|jpe?g|gif|webp|bmp)$/i.test(fileName);
2603
2950
  };
2951
+ var isVideoFile = (file) => {
2952
+ const sizeOk = file.size > 0 && file.size <= MAX_VIDEO_FILE_SIZE;
2953
+ const fileName = file.name?.toLowerCase() || "";
2954
+ const mimeMatch = ALLOWED_VIDEO_MIME_TYPES.has(file.type);
2955
+ const videoPrefix = typeof file.type === "string" && file.type.startsWith("video/");
2956
+ const extMatch = !file.type && ALLOWED_VIDEO_EXTENSIONS.some((ext) => fileName.endsWith(ext));
2957
+ const result = sizeOk && (mimeMatch || videoPrefix || extMatch);
2958
+ DEBUG_LOG("isVideoFile:check", "result", {
2959
+ fileName: file.name,
2960
+ fileType: file.type,
2961
+ fileSize: file.size,
2962
+ sizeOk,
2963
+ mimeMatch,
2964
+ videoPrefix,
2965
+ extMatch,
2966
+ result
2967
+ });
2968
+ return result;
2969
+ };
2604
2970
  var isHtmlFile = (file) => {
2605
2971
  return file.size > 0 && (file.type === "text/html" || file.name?.toLowerCase().endsWith(".html") || file.name?.toLowerCase().endsWith(".htm"));
2606
2972
  };
@@ -2614,15 +2980,17 @@ var escapeHtml = (str) => {
2614
2980
  };
2615
2981
  return str.replace(/[&<>"']/g, (char) => htmlEscapes[char]);
2616
2982
  };
2617
- var extractImageUrls = (blocks) => {
2983
+ var extractMediaUrls = (blocks) => {
2618
2984
  const urls = /* @__PURE__ */ new Set();
2619
2985
  const traverse = (blockList) => {
2620
2986
  for (const block of blockList) {
2621
2987
  if (block.type === "image" && block.props?.url) {
2622
2988
  const url = block.props.url;
2623
- if (typeof url === "string" && url.trim()) {
2624
- urls.add(url);
2625
- }
2989
+ if (typeof url === "string" && url.trim()) urls.add(url);
2990
+ }
2991
+ if (block.type === "video" && block.props?.url) {
2992
+ const url = block.props.url;
2993
+ if (typeof url === "string" && url.trim()) urls.add(url);
2626
2994
  }
2627
2995
  if (block.children && Array.isArray(block.children)) {
2628
2996
  traverse(block.children);
@@ -2632,12 +3000,10 @@ var extractImageUrls = (blocks) => {
2632
3000
  traverse(blocks);
2633
3001
  return urls;
2634
3002
  };
2635
- var findDeletedImageUrls = (previousUrls, currentUrls) => {
3003
+ var findDeletedMediaUrls = (previousUrls, currentUrls) => {
2636
3004
  const deleted = [];
2637
3005
  previousUrls.forEach((url) => {
2638
- if (!currentUrls.has(url)) {
2639
- deleted.push(url);
2640
- }
3006
+ if (!currentUrls.has(url)) deleted.push(url);
2641
3007
  });
2642
3008
  return deleted;
2643
3009
  };
@@ -2661,9 +3027,9 @@ var findBlockWithLink = (blocks, targetUrl) => {
2661
3027
  return null;
2662
3028
  };
2663
3029
  var ConvertToPreviewButton = ({ url }) => {
2664
- const editor = (0, import_react17.useBlockNoteEditor)();
2665
- const Components = (0, import_react17.useComponentsContext)();
2666
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3030
+ const editor = (0, import_react19.useBlockNoteEditor)();
3031
+ const Components = (0, import_react19.useComponentsContext)();
3032
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2667
3033
  Components.LinkToolbar.Button,
2668
3034
  {
2669
3035
  className: "bn-button",
@@ -2682,29 +3048,29 @@ var ConvertToPreviewButton = ({ url }) => {
2682
3048
  console.error("Convert to link preview failed:", err);
2683
3049
  }
2684
3050
  },
2685
- icon: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
2686
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("rect", { x: "1", y: "3", width: "14", height: "10", rx: "2", stroke: "currentColor", strokeWidth: "1.5", fill: "none" }),
2687
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("line", { x1: "1", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "1.5" }),
2688
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "5", cy: "6.5", r: "1.5", stroke: "currentColor", strokeWidth: "1", fill: "none" })
3051
+ icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
3052
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("rect", { x: "1", y: "3", width: "14", height: "10", rx: "2", stroke: "currentColor", strokeWidth: "1.5", fill: "none" }),
3053
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("line", { x1: "1", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "1.5" }),
3054
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "5", cy: "6.5", r: "1.5", stroke: "currentColor", strokeWidth: "1", fill: "none" })
2689
3055
  ] })
2690
3056
  }
2691
3057
  );
2692
3058
  };
2693
3059
  var CustomLinkToolbar = (props) => {
2694
- const editor = (0, import_react17.useBlockNoteEditor)();
2695
- const Components = (0, import_react17.useComponentsContext)();
3060
+ const editor = (0, import_react19.useBlockNoteEditor)();
3061
+ const Components = (0, import_react19.useComponentsContext)();
2696
3062
  const hasLinkPreview = !!editor?._linkPreviewApiEndpoint;
2697
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3063
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2698
3064
  Components.LinkToolbar.Root,
2699
3065
  {
2700
3066
  className: "bn-toolbar bn-link-toolbar",
2701
3067
  onMouseEnter: props.stopHideTimer,
2702
3068
  onMouseLeave: props.startHideTimer,
2703
3069
  children: [
2704
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react17.EditLinkButton, { url: props.url, text: props.text, editLink: props.editLink }),
2705
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react17.OpenLinkButton, { url: props.url }),
2706
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react17.DeleteLinkButton, { deleteLink: props.deleteLink }),
2707
- hasLinkPreview && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ConvertToPreviewButton, { url: props.url })
3070
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react19.EditLinkButton, { url: props.url, text: props.text, editLink: props.editLink }),
3071
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react19.OpenLinkButton, { url: props.url }),
3072
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react19.DeleteLinkButton, { deleteLink: props.deleteLink }),
3073
+ hasLinkPreview && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ConvertToPreviewButton, { url: props.url })
2708
3074
  ]
2709
3075
  }
2710
3076
  );
@@ -2746,9 +3112,13 @@ function LumirEditor({
2746
3112
  onError,
2747
3113
  onImageDelete
2748
3114
  }) {
2749
- const [isUploading, setIsUploading] = (0, import_react16.useState)(false);
2750
- const [errorMessage, setErrorMessage] = (0, import_react16.useState)(null);
2751
- const handleError = (0, import_react16.useCallback)(
3115
+ const [isUploading, setIsUploading] = (0, import_react18.useState)(false);
3116
+ const [uploadProgress, setUploadProgress] = (0, import_react18.useState)(null);
3117
+ const [errorMessage, setErrorMessage] = (0, import_react18.useState)(null);
3118
+ const floatingMenuFileInputRef = (0, import_react18.useRef)(null);
3119
+ const floatingMenuBlockRef = (0, import_react18.useRef)(null);
3120
+ const floatingMenuUploadStartTimeRef = (0, import_react18.useRef)(0);
3121
+ const handleError = (0, import_react18.useCallback)(
2752
3122
  (error) => {
2753
3123
  onError?.(error);
2754
3124
  setErrorMessage(error.getUserMessage());
@@ -2756,10 +3126,10 @@ function LumirEditor({
2756
3126
  },
2757
3127
  [onError]
2758
3128
  );
2759
- const validatedContent = (0, import_react16.useMemo)(() => {
3129
+ const validatedContent = (0, import_react18.useMemo)(() => {
2760
3130
  return ContentUtils.validateContent(initialContent, initialEmptyBlocks);
2761
3131
  }, [initialContent, initialEmptyBlocks]);
2762
- const tableConfig = (0, import_react16.useMemo)(() => {
3132
+ const tableConfig = (0, import_react18.useMemo)(() => {
2763
3133
  return EditorConfig.getDefaultTableConfig(tables);
2764
3134
  }, [
2765
3135
  tables?.splitCells,
@@ -2767,10 +3137,10 @@ function LumirEditor({
2767
3137
  tables?.cellTextColor,
2768
3138
  tables?.headers
2769
3139
  ]);
2770
- const headingConfig = (0, import_react16.useMemo)(() => {
3140
+ const headingConfig = (0, import_react18.useMemo)(() => {
2771
3141
  return EditorConfig.getDefaultHeadingConfig(heading);
2772
3142
  }, [heading?.levels?.join(",") ?? ""]);
2773
- const disabledExtensions = (0, import_react16.useMemo)(() => {
3143
+ const disabledExtensions = (0, import_react18.useMemo)(() => {
2774
3144
  return EditorConfig.getDisabledExtensions(
2775
3145
  disableExtensions,
2776
3146
  allowVideoUpload,
@@ -2778,11 +3148,18 @@ function LumirEditor({
2778
3148
  allowFileUpload
2779
3149
  );
2780
3150
  }, [disableExtensions, allowVideoUpload, allowAudioUpload, allowFileUpload]);
2781
- const fileNameTransformRef = (0, import_react16.useRef)(s3Upload?.fileNameTransform);
2782
- (0, import_react16.useEffect)(() => {
3151
+ (0, import_react18.useEffect)(() => {
3152
+ DEBUG_LOG("LumirEditor:init:disabledExtensions", "snapshot", {
3153
+ allowVideoUpload,
3154
+ hasVideoInDisabled: disabledExtensions.includes("video"),
3155
+ disabledList: disabledExtensions.slice(0, 15)
3156
+ });
3157
+ }, [allowVideoUpload, disabledExtensions]);
3158
+ const fileNameTransformRef = (0, import_react18.useRef)(s3Upload?.fileNameTransform);
3159
+ (0, import_react18.useEffect)(() => {
2783
3160
  fileNameTransformRef.current = s3Upload?.fileNameTransform;
2784
3161
  }, [s3Upload?.fileNameTransform]);
2785
- const memoizedS3Upload = (0, import_react16.useMemo)(() => {
3162
+ const memoizedS3Upload = (0, import_react18.useMemo)(() => {
2786
3163
  if (!s3Upload) return void 0;
2787
3164
  return {
2788
3165
  apiEndpoint: s3Upload.apiEndpoint,
@@ -2790,6 +3167,12 @@ function LumirEditor({
2790
3167
  path: s3Upload.path,
2791
3168
  appendUUID: s3Upload.appendUUID,
2792
3169
  preserveExtension: s3Upload.preserveExtension,
3170
+ uploadTimeoutMs: s3Upload.uploadTimeoutMs,
3171
+ maxRetries: s3Upload.maxRetries,
3172
+ onProgress: (percent) => {
3173
+ setUploadProgress(percent);
3174
+ s3Upload.onProgress?.(percent);
3175
+ },
2793
3176
  // 최신 콜백을 항상 사용하도록 ref를 통해 접근
2794
3177
  fileNameTransform: (originalName, file) => {
2795
3178
  return fileNameTransformRef.current ? fileNameTransformRef.current(originalName, file) : originalName;
@@ -2800,9 +3183,12 @@ function LumirEditor({
2800
3183
  s3Upload?.env,
2801
3184
  s3Upload?.path,
2802
3185
  s3Upload?.appendUUID,
2803
- s3Upload?.preserveExtension
3186
+ s3Upload?.preserveExtension,
3187
+ s3Upload?.uploadTimeoutMs,
3188
+ s3Upload?.maxRetries,
3189
+ s3Upload?.onProgress
2804
3190
  ]);
2805
- const editor = (0, import_react17.useCreateBlockNote)(
3191
+ const editor = (0, import_react19.useCreateBlockNote)(
2806
3192
  {
2807
3193
  // HTML 미리보기 블록이 포함된 커스텀 스키마 사용
2808
3194
  schema,
@@ -2818,18 +3204,44 @@ function LumirEditor({
2818
3204
  tabBehavior,
2819
3205
  trailingBlock,
2820
3206
  uploadFile: async (file) => {
2821
- if (!isImageFile(file)) {
2822
- const error = LumirEditorError.invalidFileType(file.name);
3207
+ const allowedImage = isImageFile(file);
3208
+ const allowedVideo = allowVideoUpload && isVideoFile(file);
3209
+ DEBUG_LOG("uploadFile:step1:entry", "editor uploadFile callback invoked", {
3210
+ fileName: file.name,
3211
+ fileType: file.type,
3212
+ fileSize: file.size,
3213
+ allowVideoUpload,
3214
+ allowedImage,
3215
+ allowedVideo
3216
+ });
3217
+ if (!allowedImage && !allowedVideo) {
3218
+ const error = LumirEditorError.invalidFileType(
3219
+ file.name,
3220
+ allowVideoUpload
3221
+ );
2823
3222
  handleError(error);
2824
3223
  throw error;
2825
3224
  }
2826
3225
  try {
2827
- let imageUrl;
3226
+ setUploadProgress(0);
3227
+ let fileUrl;
3228
+ const branch = uploadFile ? "custom" : memoizedS3Upload?.apiEndpoint ? "s3" : "none";
3229
+ DEBUG_LOG("uploadFile:step2:branch", "upload path", {
3230
+ branch,
3231
+ hasCustomUploadFile: !!uploadFile,
3232
+ hasS3ApiEndpoint: !!memoizedS3Upload?.apiEndpoint
3233
+ });
2828
3234
  if (uploadFile) {
2829
- imageUrl = await uploadFile(file);
3235
+ const t0 = Date.now();
3236
+ DEBUG_LOG("uploadFile:step3a:custom", "calling custom uploadFile", { fileName: file.name });
3237
+ fileUrl = await uploadFile(file);
3238
+ DEBUG_LOG("uploadFile:step3a:done", "custom uploadFile returned", { urlLen: fileUrl?.length, elapsedMs: Date.now() - t0 });
2830
3239
  } else if (memoizedS3Upload?.apiEndpoint) {
3240
+ const t0 = Date.now();
3241
+ DEBUG_LOG("uploadFile:step3b:s3", "calling S3 uploader", { fileName: file.name });
2831
3242
  const s3Uploader = createS3Uploader(memoizedS3Upload);
2832
- imageUrl = await s3Uploader(file);
3243
+ fileUrl = await s3Uploader(file);
3244
+ DEBUG_LOG("uploadFile:step3b:done", "S3 uploader returned", { urlLen: fileUrl?.length, elapsedMs: Date.now() - t0 });
2833
3245
  } else {
2834
3246
  const error = LumirEditorError.s3ConfigError(
2835
3247
  "No upload method available. Please provide uploadFile or s3Upload configuration."
@@ -2837,8 +3249,16 @@ function LumirEditor({
2837
3249
  handleError(error);
2838
3250
  throw error;
2839
3251
  }
2840
- return imageUrl;
3252
+ DEBUG_LOG("uploadFile:step4:success", "returning URL", {
3253
+ fileName: file.name,
3254
+ urlPrefix: fileUrl.slice(0, 80)
3255
+ });
3256
+ return fileUrl;
2841
3257
  } catch (error) {
3258
+ DEBUG_LOG("uploadFile:step5:catch", "uploadFile threw", {
3259
+ fileName: file.name,
3260
+ errorMessage: error instanceof Error ? error.message : String(error)
3261
+ });
2842
3262
  if (error instanceof LumirEditorError) {
2843
3263
  throw error;
2844
3264
  }
@@ -2848,6 +3268,8 @@ function LumirEditor({
2848
3268
  );
2849
3269
  handleError(lumirError);
2850
3270
  throw lumirError;
3271
+ } finally {
3272
+ setUploadProgress(null);
2851
3273
  }
2852
3274
  },
2853
3275
  pasteHandler: (ctx) => {
@@ -2876,7 +3298,15 @@ function LumirEditor({
2876
3298
  }
2877
3299
  const fileList = event?.clipboardData?.files ?? null;
2878
3300
  const files = fileList ? Array.from(fileList) : [];
2879
- const acceptedFiles = files.filter(isImageFile);
3301
+ const acceptedFiles = files.filter(
3302
+ (f) => isImageFile(f) || allowVideoUpload && isVideoFile(f)
3303
+ );
3304
+ DEBUG_LOG("paste:step1:files", "paste clipboard files", {
3305
+ filesCount: files.length,
3306
+ acceptedCount: acceptedFiles.length,
3307
+ fileNames: files.map((f) => f.name),
3308
+ acceptedNames: acceptedFiles.map((f) => f.name)
3309
+ });
2880
3310
  if (files.length > 0 && acceptedFiles.length === 0) {
2881
3311
  event.preventDefault();
2882
3312
  return true;
@@ -2890,13 +3320,26 @@ function LumirEditor({
2890
3320
  try {
2891
3321
  for (const file of acceptedFiles) {
2892
3322
  try {
3323
+ DEBUG_LOG("paste:step2:upload", "calling uploadFile for paste", {
3324
+ fileName: file.name,
3325
+ fileType: file.type
3326
+ });
2893
3327
  const url = await editor2.uploadFile(file);
2894
- editor2.pasteHTML(
2895
- `<img src="${escapeHtml(url)}" alt="image" />`
2896
- );
3328
+ if (isImageFile(file)) {
3329
+ editor2.pasteHTML(
3330
+ `<img src="${escapeHtml(url)}" alt="image" />`
3331
+ );
3332
+ } else if (isVideoFile(file)) {
3333
+ const currentBlock = editor2.getTextCursorPosition().block;
3334
+ editor2.insertBlocks(
3335
+ [{ type: "video", props: { url } }],
3336
+ currentBlock,
3337
+ "after"
3338
+ );
3339
+ }
2897
3340
  } catch (err) {
2898
3341
  console.warn(
2899
- "Image upload failed, skipped:",
3342
+ "Upload failed, skipped:",
2900
3343
  file.name || "",
2901
3344
  err
2902
3345
  );
@@ -2919,6 +3362,7 @@ function LumirEditor({
2919
3362
  trailingBlock,
2920
3363
  uploadFile,
2921
3364
  memoizedS3Upload,
3365
+ allowVideoUpload,
2922
3366
  linkPreview?.apiEndpoint,
2923
3367
  placeholder
2924
3368
  ]
@@ -2926,12 +3370,12 @@ function LumirEditor({
2926
3370
  if (editor && linkPreview?.apiEndpoint) {
2927
3371
  editor._linkPreviewApiEndpoint = linkPreview.apiEndpoint;
2928
3372
  }
2929
- (0, import_react16.useEffect)(() => {
3373
+ (0, import_react18.useEffect)(() => {
2930
3374
  if (editor) {
2931
3375
  editor.isEditable = editable;
2932
3376
  }
2933
3377
  }, [editor, editable]);
2934
- (0, import_react16.useEffect)(() => {
3378
+ (0, import_react18.useEffect)(() => {
2935
3379
  if (!editor || !onContentChange) return;
2936
3380
  const handleContentChange = () => {
2937
3381
  const blocks = editor.topLevelBlocks;
@@ -2939,27 +3383,27 @@ function LumirEditor({
2939
3383
  };
2940
3384
  return editor.onEditorContentChange(handleContentChange);
2941
3385
  }, [editor, onContentChange]);
2942
- const previousImageUrlsRef = (0, import_react16.useRef)(/* @__PURE__ */ new Set());
2943
- (0, import_react16.useEffect)(() => {
3386
+ const previousMediaUrlsRef = (0, import_react18.useRef)(/* @__PURE__ */ new Set());
3387
+ (0, import_react18.useEffect)(() => {
2944
3388
  if (!editor) return;
2945
3389
  const initialBlocks = editor.topLevelBlocks;
2946
- previousImageUrlsRef.current = extractImageUrls(initialBlocks);
3390
+ previousMediaUrlsRef.current = extractMediaUrls(initialBlocks);
2947
3391
  }, [editor]);
2948
- (0, import_react16.useEffect)(() => {
3392
+ (0, import_react18.useEffect)(() => {
2949
3393
  if (!editor || !onImageDelete) return;
2950
- const handleImageDeleteCheck = () => {
3394
+ const handleMediaDeleteCheck = () => {
2951
3395
  const currentBlocks = editor.topLevelBlocks;
2952
- const currentUrls = extractImageUrls(currentBlocks);
2953
- const previousUrls = previousImageUrlsRef.current;
2954
- const deletedUrls = findDeletedImageUrls(previousUrls, currentUrls);
3396
+ const currentUrls = extractMediaUrls(currentBlocks);
3397
+ const previousUrls = previousMediaUrlsRef.current;
3398
+ const deletedUrls = findDeletedMediaUrls(previousUrls, currentUrls);
2955
3399
  deletedUrls.forEach((url) => {
2956
3400
  onImageDelete(url);
2957
3401
  });
2958
- previousImageUrlsRef.current = currentUrls;
3402
+ previousMediaUrlsRef.current = currentUrls;
2959
3403
  };
2960
- return editor.onEditorContentChange(handleImageDeleteCheck);
3404
+ return editor.onEditorContentChange(handleMediaDeleteCheck);
2961
3405
  }, [editor, onImageDelete]);
2962
- (0, import_react16.useEffect)(() => {
3406
+ (0, import_react18.useEffect)(() => {
2963
3407
  const el = editor?.domElement;
2964
3408
  if (!el) return;
2965
3409
  const handleDragOver = (e) => {
@@ -2979,11 +3423,31 @@ function LumirEditor({
2979
3423
  const items = Array.from(e.dataTransfer.items ?? []);
2980
3424
  const files = items.filter((it) => it.kind === "file").map((it) => it.getAsFile()).filter((f) => !!f);
2981
3425
  const imageFiles = files.filter(isImageFile);
3426
+ const videoFiles = allowVideoUpload ? files.filter(isVideoFile) : [];
2982
3427
  const htmlFiles = files.filter(isHtmlFile);
2983
- if (imageFiles.length === 0 && htmlFiles.length === 0) return;
3428
+ DEBUG_LOG("drop:step1:files", "drop received", {
3429
+ filesCount: files.length,
3430
+ imageCount: imageFiles.length,
3431
+ videoCount: videoFiles.length,
3432
+ htmlCount: htmlFiles.length,
3433
+ allowVideoUpload,
3434
+ firstFile: files[0] ? {
3435
+ name: files[0].name,
3436
+ type: files[0].type,
3437
+ size: files[0].size,
3438
+ isImage: isImageFile(files[0]),
3439
+ isVideo: isVideoFile(files[0])
3440
+ } : null
3441
+ });
3442
+ if (imageFiles.length === 0 && htmlFiles.length === 0 && videoFiles.length === 0)
3443
+ return;
2984
3444
  (async () => {
2985
3445
  setIsUploading(true);
2986
3446
  try {
3447
+ DEBUG_LOG("drop:step2:async", "drop async started", {
3448
+ imageCount: imageFiles.length,
3449
+ videoCount: videoFiles.length
3450
+ });
2987
3451
  for (const file of imageFiles) {
2988
3452
  try {
2989
3453
  if (editor?.uploadFile) {
@@ -3002,6 +3466,34 @@ function LumirEditor({
3002
3466
  );
3003
3467
  }
3004
3468
  }
3469
+ DEBUG_LOG("drop:step3:videoLoop", "video loop start", {
3470
+ videoCount: videoFiles.length,
3471
+ names: videoFiles.map((f) => f.name)
3472
+ });
3473
+ for (const file of videoFiles) {
3474
+ try {
3475
+ if (editor?.uploadFile) {
3476
+ DEBUG_LOG("drop:step4:videoUpload", "calling uploadFile for video", {
3477
+ fileName: file.name
3478
+ });
3479
+ const url = await editor.uploadFile(file);
3480
+ if (url && typeof url === "string") {
3481
+ const currentBlock = editor.getTextCursorPosition().block;
3482
+ editor.insertBlocks(
3483
+ [{ type: "video", props: { url } }],
3484
+ currentBlock,
3485
+ "after"
3486
+ );
3487
+ }
3488
+ }
3489
+ } catch (err) {
3490
+ console.warn(
3491
+ "Video upload failed, skipped:",
3492
+ file.name || "",
3493
+ err
3494
+ );
3495
+ }
3496
+ }
3005
3497
  for (const file of htmlFiles) {
3006
3498
  try {
3007
3499
  const htmlContent = await file.text();
@@ -3041,56 +3533,124 @@ function LumirEditor({
3041
3533
  });
3042
3534
  el.removeEventListener("drop", handleDrop, { capture: true });
3043
3535
  };
3044
- }, [editor]);
3045
- const computedSideMenu = (0, import_react16.useMemo)(() => {
3536
+ }, [editor, allowVideoUpload]);
3537
+ const computedSideMenu = (0, import_react18.useMemo)(() => {
3046
3538
  return sideMenuAddButton ? sideMenu : false;
3047
3539
  }, [sideMenuAddButton, sideMenu]);
3048
- const DragHandleOnlySideMenu = (0, import_react16.useMemo)(() => {
3049
- return (props) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react17.SideMenu, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react17.DragHandleButton, { ...props }) });
3540
+ const DragHandleOnlySideMenu = (0, import_react18.useMemo)(() => {
3541
+ return (props) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react19.SideMenu, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react19.DragHandleButton, { ...props }) });
3050
3542
  }, []);
3051
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3543
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3052
3544
  "div",
3053
3545
  {
3054
3546
  className: cn("lumirEditor", className),
3055
3547
  style: { position: "relative", display: "flex", flexDirection: "column" },
3056
3548
  children: [
3057
- floatingMenu && editor && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3058
- FloatingMenu,
3059
- {
3060
- editor,
3061
- position: floatingMenuPosition,
3062
- onImageUpload: async () => {
3063
- const input = document.createElement("input");
3064
- input.type = "file";
3065
- input.accept = "image/*";
3066
- input.onchange = async (e) => {
3067
- const file = e.target.files?.[0];
3068
- if (file && editor.uploadFile) {
3069
- try {
3070
- setIsUploading(true);
3071
- const url = await editor.uploadFile(file);
3072
- editor.insertBlocks(
3073
- [
3074
- {
3075
- type: "image",
3076
- props: { url }
3077
- }
3078
- ],
3079
- editor.getTextCursorPosition().block,
3080
- "after"
3081
- );
3082
- } catch (err) {
3083
- console.error("Image upload failed:", err);
3084
- } finally {
3085
- setIsUploading(false);
3549
+ floatingMenu && editor && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3550
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3551
+ "input",
3552
+ {
3553
+ ref: floatingMenuFileInputRef,
3554
+ type: "file",
3555
+ accept: allowVideoUpload ? "image/*,video/mp4,video/webm,video/ogg,video/quicktime,.mov" : "image/*",
3556
+ style: {
3557
+ position: "absolute",
3558
+ left: "-9999px",
3559
+ opacity: 0,
3560
+ pointerEvents: "none"
3561
+ },
3562
+ onChange: async (e) => {
3563
+ const inputEl = e.target;
3564
+ const file = inputEl.files?.[0];
3565
+ DEBUG_LOG("FloatingMenu:step3:onchange", "file input onchange fired", {
3566
+ hasFile: !!file,
3567
+ fileName: file?.name,
3568
+ fileType: file?.type,
3569
+ fileSize: file?.size,
3570
+ hasUploadFile: !!editor?.uploadFile
3571
+ });
3572
+ const blockToInsertAfter = floatingMenuBlockRef.current;
3573
+ if (file && editor.uploadFile && blockToInsertAfter) {
3574
+ const allowedImage = isImageFile(file);
3575
+ const allowedVideo = allowVideoUpload && isVideoFile(file);
3576
+ DEBUG_LOG("FloatingMenu:step4:fileCheck", "allowed check", {
3577
+ fileName: file.name,
3578
+ allowedImage,
3579
+ allowedVideo
3580
+ });
3581
+ if (allowedImage || allowedVideo) {
3582
+ try {
3583
+ setIsUploading(true);
3584
+ floatingMenuUploadStartTimeRef.current = Date.now();
3585
+ DEBUG_LOG("FloatingMenu:step5:uploadStart", "calling editor.uploadFile", {
3586
+ fileName: file.name
3587
+ });
3588
+ const url = await editor.uploadFile(file);
3589
+ const blockType = allowedVideo ? "video" : "image";
3590
+ const elapsedMs = Date.now() - floatingMenuUploadStartTimeRef.current;
3591
+ DEBUG_LOG("FloatingMenu:step6:uploadDone", "upload returned, inserting block", {
3592
+ blockType,
3593
+ blockId: blockToInsertAfter.id,
3594
+ urlLen: url?.length,
3595
+ elapsedMs
3596
+ });
3597
+ editor.insertBlocks(
3598
+ [
3599
+ {
3600
+ type: blockType,
3601
+ props: { url }
3602
+ }
3603
+ ],
3604
+ blockToInsertAfter,
3605
+ "after"
3606
+ );
3607
+ } catch (err) {
3608
+ DEBUG_LOG("FloatingMenu:step7:catch", "upload or insert failed", {
3609
+ errMsg: err instanceof Error ? err.message : String(err)
3610
+ });
3611
+ console.error("Upload failed:", err);
3612
+ } finally {
3613
+ setIsUploading(false);
3614
+ }
3086
3615
  }
3087
3616
  }
3088
- };
3089
- input.click();
3617
+ inputEl.value = "";
3618
+ }
3090
3619
  }
3091
- }
3092
- ),
3093
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3620
+ ),
3621
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3622
+ FloatingMenu,
3623
+ {
3624
+ editor,
3625
+ position: floatingMenuPosition,
3626
+ onImageUpload: () => {
3627
+ DEBUG_LOG("FloatingMenu:step1:click", "upload button clicked", {
3628
+ allowVideoUpload
3629
+ });
3630
+ let blockToInsertAfter;
3631
+ try {
3632
+ blockToInsertAfter = editor.getTextCursorPosition().block;
3633
+ } catch (err) {
3634
+ DEBUG_LOG("FloatingMenu:step1b:error", "getTextCursorPosition failed", {
3635
+ err: err instanceof Error ? err.message : String(err)
3636
+ });
3637
+ return;
3638
+ }
3639
+ floatingMenuBlockRef.current = blockToInsertAfter;
3640
+ const input = floatingMenuFileInputRef.current;
3641
+ if (!input) return;
3642
+ input.accept = allowVideoUpload ? "image/*,video/mp4,video/webm,video/ogg,video/quicktime,.mov" : "image/*";
3643
+ input.value = "";
3644
+ DEBUG_LOG("FloatingMenu:step2:inputReady", "persistent input ref, about to click", {
3645
+ accept: input.accept
3646
+ });
3647
+ DEBUG_LOG("FloatingMenu:step2b:click", "input.click() about to be called", {});
3648
+ input.click();
3649
+ }
3650
+ }
3651
+ )
3652
+ ] }),
3653
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3094
3654
  import_mantine.BlockNoteView,
3095
3655
  {
3096
3656
  editor,
@@ -3105,19 +3665,21 @@ function LumirEditor({
3105
3665
  tableHandles,
3106
3666
  onSelectionChange,
3107
3667
  children: [
3108
- linkToolbar && (linkPreview?.apiEndpoint ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react17.LinkToolbarController, { linkToolbar: CustomLinkToolbar }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react17.LinkToolbarController, {})),
3109
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3110
- import_react17.SuggestionMenuController,
3668
+ linkToolbar && (linkPreview?.apiEndpoint ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react19.LinkToolbarController, { linkToolbar: CustomLinkToolbar }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react19.LinkToolbarController, {})),
3669
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3670
+ import_react19.SuggestionMenuController,
3111
3671
  {
3112
3672
  triggerCharacter: "/",
3113
- getItems: (0, import_react16.useCallback)(
3673
+ getItems: (0, import_react18.useCallback)(
3114
3674
  async (query) => {
3115
- const items = (0, import_react17.getDefaultReactSlashMenuItems)(editor);
3675
+ const items = (0, import_react19.getDefaultReactSlashMenuItems)(editor);
3116
3676
  const filtered = items.filter((item) => {
3117
3677
  const key = (item?.key || "").toString().toLowerCase();
3118
3678
  const title = (item?.title || "").toString().toLowerCase();
3119
- if (["video", "audio", "file"].includes(key)) return false;
3120
- if (title.includes("video") || title.includes("audio") || title.includes("file"))
3679
+ if (key === "video" || title.includes("video"))
3680
+ return allowVideoUpload;
3681
+ if (["audio", "file"].includes(key)) return false;
3682
+ if (title.includes("audio") || title.includes("file"))
3121
3683
  return false;
3122
3684
  return true;
3123
3685
  });
@@ -3152,7 +3714,7 @@ function LumirEditor({
3152
3714
  },
3153
3715
  aliases: ["html", "preview", "\uC6F9", "\uC6F9\uD398\uC774\uC9C0"],
3154
3716
  group: "Embeds",
3155
- icon: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3717
+ icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3156
3718
  "svg",
3157
3719
  {
3158
3720
  width: "18",
@@ -3164,8 +3726,8 @@ function LumirEditor({
3164
3726
  strokeLinecap: "round",
3165
3727
  strokeLinejoin: "round",
3166
3728
  children: [
3167
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("polyline", { points: "16 18 22 12 16 6" }),
3168
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("polyline", { points: "8 6 2 12 8 18" })
3729
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("polyline", { points: "16 18 22 12 16 6" }),
3730
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("polyline", { points: "8 6 2 12 8 18" })
3169
3731
  ]
3170
3732
  }
3171
3733
  ),
@@ -3190,7 +3752,7 @@ function LumirEditor({
3190
3752
  "\uD504\uB9AC\uBDF0"
3191
3753
  ],
3192
3754
  group: "Embeds",
3193
- icon: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3755
+ icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3194
3756
  "svg",
3195
3757
  {
3196
3758
  width: "18",
@@ -3202,8 +3764,8 @@ function LumirEditor({
3202
3764
  strokeLinecap: "round",
3203
3765
  strokeLinejoin: "round",
3204
3766
  children: [
3205
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
3206
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
3767
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
3768
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
3207
3769
  ]
3208
3770
  }
3209
3771
  ),
@@ -3218,19 +3780,25 @@ function LumirEditor({
3218
3780
  )
3219
3781
  );
3220
3782
  },
3221
- [editor, linkPreview?.apiEndpoint]
3783
+ [editor, allowVideoUpload, linkPreview?.apiEndpoint]
3222
3784
  )
3223
3785
  }
3224
3786
  ),
3225
- !sideMenuAddButton && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react17.SideMenuController, { sideMenu: DragHandleOnlySideMenu })
3787
+ !sideMenuAddButton && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react19.SideMenuController, { sideMenu: DragHandleOnlySideMenu })
3226
3788
  ]
3227
3789
  }
3228
3790
  ),
3229
- isUploading && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "lumirEditor-upload-overlay", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "lumirEditor-spinner" }) }),
3230
- errorMessage && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "lumirEditor-error-toast", children: [
3231
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "lumirEditor-error-icon", children: "\u26A0\uFE0F" }),
3232
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "lumirEditor-error-message", children: errorMessage }),
3233
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3791
+ isUploading && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "lumirEditor-upload-overlay", children: [
3792
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "lumirEditor-spinner" }),
3793
+ uploadProgress !== null && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "lumirEditor-upload-progress", children: [
3794
+ uploadProgress,
3795
+ "%"
3796
+ ] })
3797
+ ] }),
3798
+ errorMessage && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "lumirEditor-error-toast", children: [
3799
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "lumirEditor-error-icon", children: "\u26A0\uFE0F" }),
3800
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "lumirEditor-error-message", children: errorMessage }),
3801
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3234
3802
  "button",
3235
3803
  {
3236
3804
  className: "lumirEditor-error-close",