@lumir-company/editor 0.4.15 → 0.4.17

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.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  // src/components/LumirEditor.tsx
4
- import { useEffect as useEffect10, useMemo as useMemo6, useCallback as useCallback18, useState as useState10, useRef as useRef11 } from "react";
4
+ import { useEffect as useEffect11, useMemo as useMemo8, useCallback as useCallback21, useState as useState12, useRef as useRef12 } from "react";
5
5
  import {
6
6
  useCreateBlockNote,
7
7
  SideMenu as BlockSideMenu,
@@ -11,8 +11,8 @@ import {
11
11
  getDefaultReactSlashMenuItems,
12
12
  LinkToolbarController,
13
13
  FormattingToolbarController,
14
- useBlockNoteEditor as useBlockNoteEditor5,
15
- useComponentsContext as useComponentsContext4,
14
+ useBlockNoteEditor as useBlockNoteEditor8,
15
+ useComponentsContext as useComponentsContext7,
16
16
  EditLinkButton,
17
17
  OpenLinkButton,
18
18
  DeleteLinkButton
@@ -260,7 +260,8 @@ import {
260
260
  defaultBlockSpecs,
261
261
  BlockNoteSchema,
262
262
  defaultInlineContentSpecs,
263
- defaultStyleSpecs
263
+ defaultStyleSpecs,
264
+ createBlockSpecFromStronglyTypedTiptapNode
264
265
  } from "@blocknote/core";
265
266
 
266
267
  // src/blocks/LinkPreview.tsx
@@ -1221,9 +1222,336 @@ var VideoBlock = createReactBlockSpec2(
1221
1222
  }
1222
1223
  );
1223
1224
 
1225
+ // src/blocks/columns/ColumnList.ts
1226
+ import { createStronglyTypedTiptapNode } from "@blocknote/core";
1227
+
1228
+ // src/blocks/columns/columnNormalization.ts
1229
+ import { Plugin, PluginKey } from "prosemirror-state";
1230
+ var columnNormalizationKey = new PluginKey("lumirColumnNormalization");
1231
+ function columnNormalization() {
1232
+ return new Plugin({
1233
+ key: columnNormalizationKey,
1234
+ appendTransaction(transactions, _oldState, newState) {
1235
+ if (!transactions.some((tr2) => tr2.docChanged)) {
1236
+ return null;
1237
+ }
1238
+ const lists = [];
1239
+ newState.doc.descendants((node, pos) => {
1240
+ if (node.type.name === "columnList") {
1241
+ lists.push({ pos, node });
1242
+ return false;
1243
+ }
1244
+ return void 0;
1245
+ });
1246
+ if (lists.length === 0) {
1247
+ return null;
1248
+ }
1249
+ const tr = newState.tr;
1250
+ let modified = false;
1251
+ for (let i = lists.length - 1; i >= 0; i--) {
1252
+ const { pos, node } = lists[i];
1253
+ const nonEmptyColumns = [];
1254
+ node.forEach((col) => {
1255
+ if (col.type.name === "column" && col.childCount > 0) {
1256
+ nonEmptyColumns.push(col);
1257
+ }
1258
+ });
1259
+ if (nonEmptyColumns.length >= 2) {
1260
+ continue;
1261
+ }
1262
+ const from = tr.mapping.map(pos);
1263
+ const to = tr.mapping.map(pos + node.nodeSize);
1264
+ const blocks = [];
1265
+ nonEmptyColumns.forEach((col) => {
1266
+ col.forEach((bc) => blocks.push(bc));
1267
+ });
1268
+ if (blocks.length > 0) {
1269
+ tr.replaceWith(from, to, blocks);
1270
+ } else {
1271
+ tr.delete(from, to);
1272
+ }
1273
+ modified = true;
1274
+ }
1275
+ return modified ? tr : null;
1276
+ }
1277
+ });
1278
+ }
1279
+
1280
+ // src/blocks/columns/columnDnd.ts
1281
+ import { Plugin as Plugin2, PluginKey as PluginKey2 } from "prosemirror-state";
1282
+ import { Decoration, DecorationSet } from "prosemirror-view";
1283
+
1284
+ // src/blocks/columns/mergeColumns.ts
1285
+ function mergeBlocksIntoColumns(editor, draggedId, targetId, side) {
1286
+ if (!editor || !draggedId || !targetId || draggedId === targetId) {
1287
+ return false;
1288
+ }
1289
+ const dragged = editor.getBlock?.(draggedId);
1290
+ const target = editor.getBlock?.(targetId);
1291
+ if (!dragged || !target) {
1292
+ return false;
1293
+ }
1294
+ if (dragged.type === "columnList" || dragged.type === "column" || target.type === "columnList" || target.type === "column") {
1295
+ return false;
1296
+ }
1297
+ const columnList = {
1298
+ type: "columnList",
1299
+ children: side === "left" ? [
1300
+ { type: "column", children: [dragged] },
1301
+ { type: "column", children: [target] }
1302
+ ] : [
1303
+ { type: "column", children: [target] },
1304
+ { type: "column", children: [dragged] }
1305
+ ]
1306
+ };
1307
+ try {
1308
+ const run = () => {
1309
+ editor.removeBlocks([draggedId]);
1310
+ editor.replaceBlocks([targetId], [columnList]);
1311
+ };
1312
+ if (typeof editor.transact === "function") {
1313
+ editor.transact(run);
1314
+ } else {
1315
+ run();
1316
+ }
1317
+ return true;
1318
+ } catch {
1319
+ return false;
1320
+ }
1321
+ }
1322
+
1323
+ // src/blocks/columns/columnDnd.ts
1324
+ var columnDndKey = new PluginKey2("lumirColumnDnd");
1325
+ function edgeThreshold(width) {
1326
+ return Math.min(80, width * 0.3);
1327
+ }
1328
+ function topLevelBlockAtCoords(view, x, y) {
1329
+ const found = view.posAtCoords({ left: x, top: y });
1330
+ if (!found) {
1331
+ return null;
1332
+ }
1333
+ const $pos = view.state.doc.resolve(found.pos);
1334
+ for (let d = $pos.depth; d > 0; d--) {
1335
+ if ($pos.node(d).type.name === "blockContainer") {
1336
+ if (d !== 2 || $pos.node(d - 1).type.name !== "blockGroup") {
1337
+ return null;
1338
+ }
1339
+ const pos = $pos.before(d);
1340
+ const node = $pos.node(d);
1341
+ const dom = view.nodeDOM(pos);
1342
+ if (!dom || !node.attrs?.id) {
1343
+ return null;
1344
+ }
1345
+ return { pos, nodeSize: node.nodeSize, id: node.attrs.id, dom };
1346
+ }
1347
+ }
1348
+ return null;
1349
+ }
1350
+ function draggedBlockId(view) {
1351
+ const sel = view.state.selection;
1352
+ return sel?.node?.attrs?.id ?? null;
1353
+ }
1354
+ function setDnd(view, next) {
1355
+ const cur = columnDndKey.getState(view.state);
1356
+ if (cur && cur.targetPos === next.targetPos && cur.side === next.side) {
1357
+ return;
1358
+ }
1359
+ view.dispatch(view.state.tr.setMeta(columnDndKey, next));
1360
+ }
1361
+ var CLEARED = { targetPos: null, side: null };
1362
+ function columnDnd() {
1363
+ return new Plugin2({
1364
+ key: columnDndKey,
1365
+ state: {
1366
+ init: () => CLEARED,
1367
+ apply(tr, prev) {
1368
+ const meta = tr.getMeta(columnDndKey);
1369
+ if (meta) {
1370
+ return meta;
1371
+ }
1372
+ if (tr.docChanged && prev.targetPos !== null) {
1373
+ return CLEARED;
1374
+ }
1375
+ return prev;
1376
+ }
1377
+ },
1378
+ props: {
1379
+ handleDOMEvents: {
1380
+ dragover: (view, event) => {
1381
+ if (!view.dragging) {
1382
+ return false;
1383
+ }
1384
+ const target = topLevelBlockAtCoords(
1385
+ view,
1386
+ event.clientX,
1387
+ event.clientY
1388
+ );
1389
+ const draggedId = draggedBlockId(view);
1390
+ if (!target || !draggedId || target.id === draggedId) {
1391
+ setDnd(view, CLEARED);
1392
+ view.dom.classList.remove("lumir-col-dnd-active");
1393
+ return false;
1394
+ }
1395
+ const rect = target.dom.getBoundingClientRect();
1396
+ const th = edgeThreshold(rect.width);
1397
+ let side = null;
1398
+ if (event.clientX - rect.left <= th) {
1399
+ side = "left";
1400
+ } else if (rect.right - event.clientX <= th) {
1401
+ side = "right";
1402
+ }
1403
+ if (side) {
1404
+ setDnd(view, { targetPos: target.pos, side });
1405
+ view.dom.classList.add("lumir-col-dnd-active");
1406
+ } else {
1407
+ setDnd(view, CLEARED);
1408
+ view.dom.classList.remove("lumir-col-dnd-active");
1409
+ }
1410
+ return false;
1411
+ },
1412
+ dragend: (view) => {
1413
+ setDnd(view, CLEARED);
1414
+ view.dom.classList.remove("lumir-col-dnd-active");
1415
+ return false;
1416
+ },
1417
+ dragleave: (view, event) => {
1418
+ if (!event.relatedTarget) {
1419
+ setDnd(view, CLEARED);
1420
+ view.dom.classList.remove("lumir-col-dnd-active");
1421
+ }
1422
+ return false;
1423
+ }
1424
+ },
1425
+ handleDrop: (view, _event, _slice, _moved) => {
1426
+ const st = columnDndKey.getState(view.state);
1427
+ view.dom.classList.remove("lumir-col-dnd-active");
1428
+ if (!st || st.side === null || st.targetPos === null) {
1429
+ return false;
1430
+ }
1431
+ const draggedId = draggedBlockId(view);
1432
+ const targetNode = view.state.doc.nodeAt(st.targetPos);
1433
+ const targetId = targetNode?.attrs?.id;
1434
+ view.dispatch(view.state.tr.setMeta(columnDndKey, CLEARED));
1435
+ if (!draggedId || !targetId) {
1436
+ return false;
1437
+ }
1438
+ const editor = view.__lumirEditor;
1439
+ if (!editor) {
1440
+ return false;
1441
+ }
1442
+ const ok = mergeBlocksIntoColumns(editor, draggedId, targetId, st.side);
1443
+ return ok;
1444
+ },
1445
+ decorations: (state) => {
1446
+ const st = columnDndKey.getState(state);
1447
+ if (!st || st.side === null || st.targetPos === null) {
1448
+ return null;
1449
+ }
1450
+ const node = state.doc.nodeAt(st.targetPos);
1451
+ if (!node) {
1452
+ return null;
1453
+ }
1454
+ return DecorationSet.create(state.doc, [
1455
+ Decoration.node(st.targetPos, st.targetPos + node.nodeSize, {
1456
+ class: st.side === "left" ? "lumir-col-drop-left" : "lumir-col-drop-right"
1457
+ })
1458
+ ]);
1459
+ }
1460
+ }
1461
+ });
1462
+ }
1463
+
1464
+ // src/blocks/columns/ColumnList.ts
1465
+ var ColumnList = createStronglyTypedTiptapNode({
1466
+ name: "columnList",
1467
+ group: "childContainer bnBlock blockGroupChild",
1468
+ content: "column column+",
1469
+ parseHTML() {
1470
+ return [{ tag: 'div[data-node-type="columnList"]' }];
1471
+ },
1472
+ renderHTML({ HTMLAttributes }) {
1473
+ const dom = document.createElement("div");
1474
+ dom.className = "bn-column-list";
1475
+ dom.setAttribute("data-node-type", "columnList");
1476
+ for (const [attribute, value] of Object.entries(HTMLAttributes)) {
1477
+ if (attribute !== "class") {
1478
+ dom.setAttribute(attribute, value);
1479
+ }
1480
+ }
1481
+ return { dom, contentDOM: dom };
1482
+ },
1483
+ // columnNormalization: 빈 컬럼/1단 columnList 자동 복구(unwrap).
1484
+ // columnDnd: 블록을 다른 블록 좌/우로 드롭하면 2단 컬럼 생성.
1485
+ addProseMirrorPlugins() {
1486
+ return [columnNormalization(), columnDnd()];
1487
+ }
1488
+ });
1489
+
1490
+ // src/blocks/columns/Column.ts
1491
+ import { createStronglyTypedTiptapNode as createStronglyTypedTiptapNode2 } from "@blocknote/core";
1492
+ var Column = createStronglyTypedTiptapNode2({
1493
+ name: "column",
1494
+ group: "bnBlock childContainer",
1495
+ content: "blockContainer+",
1496
+ addAttributes() {
1497
+ return {
1498
+ width: {
1499
+ default: 1,
1500
+ parseHTML: (element) => {
1501
+ const w = parseFloat(element.getAttribute("data-column-width") || "");
1502
+ return Number.isFinite(w) && w > 0 ? w : 1;
1503
+ },
1504
+ renderHTML: (attributes) => {
1505
+ if (!attributes.width || attributes.width === 1) {
1506
+ return {};
1507
+ }
1508
+ return { "data-column-width": String(attributes.width) };
1509
+ }
1510
+ }
1511
+ };
1512
+ },
1513
+ parseHTML() {
1514
+ return [{ tag: 'div[data-node-type="column"]' }];
1515
+ },
1516
+ renderHTML({ HTMLAttributes }) {
1517
+ const dom = document.createElement("div");
1518
+ dom.className = "bn-column";
1519
+ dom.setAttribute("data-node-type", "column");
1520
+ for (const [attribute, value] of Object.entries(HTMLAttributes)) {
1521
+ if (attribute !== "class") {
1522
+ dom.setAttribute(attribute, value);
1523
+ }
1524
+ }
1525
+ return { dom, contentDOM: dom };
1526
+ }
1527
+ });
1528
+
1529
+ // src/styles/FontSizeStyle.tsx
1530
+ import { createReactStyleSpec } from "@blocknote/react";
1531
+ import { jsx as jsx3 } from "react/jsx-runtime";
1532
+ var FontSize = createReactStyleSpec(
1533
+ {
1534
+ type: "fontSize",
1535
+ propSchema: "string"
1536
+ },
1537
+ {
1538
+ render: (props) => /* @__PURE__ */ jsx3("span", { style: { fontSize: props.value }, ref: props.contentRef })
1539
+ }
1540
+ );
1541
+ var FONT_SIZE_PRESETS = [
1542
+ "10px",
1543
+ "12px",
1544
+ "14px",
1545
+ "16px",
1546
+ "18px",
1547
+ "20px",
1548
+ "24px",
1549
+ "28px"
1550
+ ];
1551
+
1224
1552
  // src/blocks/HtmlPreview.tsx
1225
1553
  import { useState as useState3, useRef as useRef3, useCallback as useCallback3, useEffect as useEffect3 } from "react";
1226
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1554
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1227
1555
  var MIN_HEIGHT = 100;
1228
1556
  var MAX_HEIGHT = 1200;
1229
1557
  var ensureCharset = (html) => {
@@ -1303,7 +1631,7 @@ var HtmlPreviewBlock = createReactBlockSpec3(
1303
1631
  setIsResizing(true);
1304
1632
  const startY = e.clientY;
1305
1633
  const startHeight = currentHeight;
1306
- const handleMouseMove = (moveEvent) => {
1634
+ const handleMouseMove2 = (moveEvent) => {
1307
1635
  const deltaY = moveEvent.clientY - startY;
1308
1636
  const newHeight = Math.min(
1309
1637
  MAX_HEIGHT,
@@ -1315,10 +1643,10 @@ var HtmlPreviewBlock = createReactBlockSpec3(
1315
1643
  };
1316
1644
  const handleMouseUp = () => {
1317
1645
  setIsResizing(false);
1318
- document.removeEventListener("mousemove", handleMouseMove);
1646
+ document.removeEventListener("mousemove", handleMouseMove2);
1319
1647
  document.removeEventListener("mouseup", handleMouseUp);
1320
1648
  };
1321
- document.addEventListener("mousemove", handleMouseMove);
1649
+ document.addEventListener("mousemove", handleMouseMove2);
1322
1650
  document.addEventListener("mouseup", handleMouseUp);
1323
1651
  },
1324
1652
  [currentHeight, props.editor, props.block]
@@ -1398,7 +1726,7 @@ var HtmlPreviewBlock = createReactBlockSpec3(
1398
1726
  },
1399
1727
  onClick: () => setIsExpanded(!isExpanded),
1400
1728
  children: [
1401
- /* @__PURE__ */ jsx3(
1729
+ /* @__PURE__ */ jsx4(
1402
1730
  "svg",
1403
1731
  {
1404
1732
  width: "16",
@@ -1413,15 +1741,15 @@ var HtmlPreviewBlock = createReactBlockSpec3(
1413
1741
  transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)",
1414
1742
  transition: "transform 0.2s"
1415
1743
  },
1416
- children: /* @__PURE__ */ jsx3("polyline", { points: "6 9 12 15 18 9" })
1744
+ children: /* @__PURE__ */ jsx4("polyline", { points: "6 9 12 15 18 9" })
1417
1745
  }
1418
1746
  ),
1419
- /* @__PURE__ */ jsx3("span", { style: { fontWeight: 500, fontSize: "14px" }, children: fileName })
1747
+ /* @__PURE__ */ jsx4("span", { style: { fontWeight: 500, fontSize: "14px" }, children: fileName })
1420
1748
  ]
1421
1749
  }
1422
1750
  ),
1423
1751
  /* @__PURE__ */ jsxs3("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
1424
- /* @__PURE__ */ jsx3(
1752
+ /* @__PURE__ */ jsx4(
1425
1753
  "button",
1426
1754
  {
1427
1755
  onClick: handleOpenNewWindow,
@@ -1456,15 +1784,15 @@ var HtmlPreviewBlock = createReactBlockSpec3(
1456
1784
  strokeLinecap: "round",
1457
1785
  strokeLinejoin: "round",
1458
1786
  children: [
1459
- /* @__PURE__ */ jsx3("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
1460
- /* @__PURE__ */ jsx3("polyline", { points: "15 3 21 3 21 9" }),
1461
- /* @__PURE__ */ jsx3("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
1787
+ /* @__PURE__ */ jsx4("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
1788
+ /* @__PURE__ */ jsx4("polyline", { points: "15 3 21 3 21 9" }),
1789
+ /* @__PURE__ */ jsx4("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
1462
1790
  ]
1463
1791
  }
1464
1792
  )
1465
1793
  }
1466
1794
  ),
1467
- /* @__PURE__ */ jsx3(
1795
+ /* @__PURE__ */ jsx4(
1468
1796
  "button",
1469
1797
  {
1470
1798
  onClick: handleExport,
@@ -1499,9 +1827,9 @@ var HtmlPreviewBlock = createReactBlockSpec3(
1499
1827
  strokeLinecap: "round",
1500
1828
  strokeLinejoin: "round",
1501
1829
  children: [
1502
- /* @__PURE__ */ jsx3("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1503
- /* @__PURE__ */ jsx3("polyline", { points: "7 10 12 15 17 10" }),
1504
- /* @__PURE__ */ jsx3("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
1830
+ /* @__PURE__ */ jsx4("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1831
+ /* @__PURE__ */ jsx4("polyline", { points: "7 10 12 15 17 10" }),
1832
+ /* @__PURE__ */ jsx4("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
1505
1833
  ]
1506
1834
  }
1507
1835
  )
@@ -1520,7 +1848,7 @@ var HtmlPreviewBlock = createReactBlockSpec3(
1520
1848
  position: "relative"
1521
1849
  },
1522
1850
  children: [
1523
- /* @__PURE__ */ jsx3(
1851
+ /* @__PURE__ */ jsx4(
1524
1852
  "iframe",
1525
1853
  {
1526
1854
  src: blobUrl || "about:blank",
@@ -1537,7 +1865,7 @@ var HtmlPreviewBlock = createReactBlockSpec3(
1537
1865
  loading: "lazy"
1538
1866
  }
1539
1867
  ),
1540
- /* @__PURE__ */ jsx3(
1868
+ /* @__PURE__ */ jsx4(
1541
1869
  "div",
1542
1870
  {
1543
1871
  onMouseDown: handleResizeStart,
@@ -1562,7 +1890,7 @@ var HtmlPreviewBlock = createReactBlockSpec3(
1562
1890
  e.currentTarget.style.backgroundColor = "transparent";
1563
1891
  }
1564
1892
  },
1565
- children: /* @__PURE__ */ jsx3(
1893
+ children: /* @__PURE__ */ jsx4(
1566
1894
  "div",
1567
1895
  {
1568
1896
  style: {
@@ -1584,72 +1912,83 @@ var HtmlPreviewBlock = createReactBlockSpec3(
1584
1912
  }
1585
1913
  }
1586
1914
  );
1915
+ var ColumnListBlock = createBlockSpecFromStronglyTypedTiptapNode(
1916
+ ColumnList,
1917
+ {}
1918
+ );
1919
+ var ColumnBlock = createBlockSpecFromStronglyTypedTiptapNode(Column, {});
1587
1920
  var schema = BlockNoteSchema.create({
1588
1921
  blockSpecs: {
1589
1922
  ...defaultBlockSpecs,
1590
1923
  htmlPreview: HtmlPreviewBlock,
1591
1924
  linkPreview: LinkPreviewBlock,
1592
- video: VideoBlock
1925
+ video: VideoBlock,
1926
+ columnList: ColumnListBlock,
1927
+ column: ColumnBlock
1593
1928
  },
1594
1929
  inlineContentSpecs: defaultInlineContentSpecs,
1595
- styleSpecs: defaultStyleSpecs
1930
+ styleSpecs: {
1931
+ ...defaultStyleSpecs,
1932
+ // 인라인 글자 크기. 저장 JSON 직렬화는 형제 키 방식(font-size-serialization.ts) 사용.
1933
+ fontSize: FontSize
1934
+ }
1596
1935
  });
1597
1936
 
1598
1937
  // src/components/FloatingMenu/index.tsx
1599
- import { useState as useState7, useEffect as useEffect7, useRef as useRef8 } from "react";
1938
+ import { useState as useState8, useEffect as useEffect8, useRef as useRef9 } from "react";
1600
1939
 
1601
1940
  // src/components/FloatingMenu/Icons.tsx
1602
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1941
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1603
1942
  var Icons = {
1604
- undo: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("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" }) }),
1605
- redo: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("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" }) }),
1606
- bold: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("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" }) }),
1607
- italic: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z" }) }),
1608
- underline: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("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" }) }),
1609
- strikethrough: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z" }) }),
1610
- alignLeft: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z" }) }),
1611
- alignCenter: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z" }) }),
1612
- alignRight: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z" }) }),
1613
- bulletList: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("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" }) }),
1614
- numberedList: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
1615
- image: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("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" }) }),
1616
- expandMore: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx4("path", { d: "M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" }) }),
1617
- textColor: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z" }) }),
1943
+ undo: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("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" }) }),
1944
+ redo: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("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" }) }),
1945
+ bold: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("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" }) }),
1946
+ italic: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z" }) }),
1947
+ underline: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("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" }) }),
1948
+ strikethrough: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z" }) }),
1949
+ alignLeft: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z" }) }),
1950
+ alignCenter: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z" }) }),
1951
+ alignRight: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z" }) }),
1952
+ bulletList: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("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" }) }),
1953
+ numberedList: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
1954
+ image: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("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" }) }),
1955
+ expandMore: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx5("path", { d: "M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" }) }),
1956
+ textColor: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z" }) }),
1618
1957
  bgColor: /* @__PURE__ */ jsxs4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1619
- /* @__PURE__ */ jsx4("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" }),
1620
- /* @__PURE__ */ jsx4("path", { fillOpacity: ".36", d: "M0 20h24v4H0z" })
1958
+ /* @__PURE__ */ jsx5("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" }),
1959
+ /* @__PURE__ */ jsx5("path", { fillOpacity: ".36", d: "M0 20h24v4H0z" })
1621
1960
  ] }),
1622
- link: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("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" }) }),
1623
- chevronRight: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) }),
1624
- chevronLeft: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }) }),
1625
- table: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("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" }) }),
1626
- htmlFile: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("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" }) })
1961
+ link: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("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" }) }),
1962
+ chevronRight: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) }),
1963
+ chevronLeft: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }) }),
1964
+ table: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("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" }) }),
1965
+ htmlFile: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("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" }) })
1627
1966
  };
1628
1967
  var BlockTypeIcons = {
1629
- paragraph: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M5 5h14v2H5zM5 11h14v2H5zM5 17h10v2H5z" }) }),
1630
- h1: /* @__PURE__ */ jsx4("span", { className: "lumir-block-icon-text", children: "H1" }),
1631
- h2: /* @__PURE__ */ jsx4("span", { className: "lumir-block-icon-text", children: "H2" }),
1632
- h3: /* @__PURE__ */ jsx4("span", { className: "lumir-block-icon-text", children: "H3" }),
1633
- h4: /* @__PURE__ */ jsx4("span", { className: "lumir-block-icon-text", children: "H4" }),
1634
- h5: /* @__PURE__ */ jsx4("span", { className: "lumir-block-icon-text", children: "H5" }),
1635
- h6: /* @__PURE__ */ jsx4("span", { className: "lumir-block-icon-text", children: "H6" }),
1968
+ paragraph: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M5 5h14v2H5zM5 11h14v2H5zM5 17h10v2H5z" }) }),
1969
+ h1: /* @__PURE__ */ jsx5("span", { className: "lumir-block-icon-text", children: "H1" }),
1970
+ h2: /* @__PURE__ */ jsx5("span", { className: "lumir-block-icon-text", children: "H2" }),
1971
+ h3: /* @__PURE__ */ jsx5("span", { className: "lumir-block-icon-text", children: "H3" }),
1972
+ h4: /* @__PURE__ */ jsx5("span", { className: "lumir-block-icon-text", children: "H4" }),
1973
+ h5: /* @__PURE__ */ jsx5("span", { className: "lumir-block-icon-text", children: "H5" }),
1974
+ h6: /* @__PURE__ */ jsx5("span", { className: "lumir-block-icon-text", children: "H6" }),
1636
1975
  toggleH1: /* @__PURE__ */ jsxs4("span", { className: "lumir-block-icon-toggle", children: [
1637
- /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ jsx4("path", { d: "M8 5v14l11-7z" }) }),
1638
- /* @__PURE__ */ jsx4("span", { children: "H1" })
1976
+ /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ jsx5("path", { d: "M8 5v14l11-7z" }) }),
1977
+ /* @__PURE__ */ jsx5("span", { children: "H1" })
1639
1978
  ] }),
1640
1979
  toggleH2: /* @__PURE__ */ jsxs4("span", { className: "lumir-block-icon-toggle", children: [
1641
- /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ jsx4("path", { d: "M8 5v14l11-7z" }) }),
1642
- /* @__PURE__ */ jsx4("span", { children: "H2" })
1980
+ /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ jsx5("path", { d: "M8 5v14l11-7z" }) }),
1981
+ /* @__PURE__ */ jsx5("span", { children: "H2" })
1643
1982
  ] }),
1644
1983
  toggleH3: /* @__PURE__ */ jsxs4("span", { className: "lumir-block-icon-toggle", children: [
1645
- /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ jsx4("path", { d: "M8 5v14l11-7z" }) }),
1646
- /* @__PURE__ */ jsx4("span", { children: "H3" })
1984
+ /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ jsx5("path", { d: "M8 5v14l11-7z" }) }),
1985
+ /* @__PURE__ */ jsx5("span", { children: "H3" })
1647
1986
  ] }),
1648
- quote: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z" }) }),
1649
- codeBlock: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("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" }) }),
1987
+ quote: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z" }) }),
1988
+ codeBlock: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("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" }) }),
1650
1989
  toggleList: /* @__PURE__ */ jsxs4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1651
- /* @__PURE__ */ jsx4("path", { d: "M10 6h10v2H10zM10 11h10v2H10zM10 16h10v2H10z" }),
1652
- /* @__PURE__ */ jsx4(
1990
+ /* @__PURE__ */ jsx5("path", { d: "M10 6h10v2H10zM10 11h10v2H10zM10 16h10v2H10z" }),
1991
+ /* @__PURE__ */ jsx5(
1653
1992
  "path",
1654
1993
  {
1655
1994
  d: "M4 8l4 4-4 4",
@@ -1662,14 +2001,14 @@ var BlockTypeIcons = {
1662
2001
  )
1663
2002
  ] }),
1664
2003
  bulletList: /* @__PURE__ */ jsxs4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1665
- /* @__PURE__ */ jsx4("circle", { cx: "4", cy: "6", r: "1.5" }),
1666
- /* @__PURE__ */ jsx4("circle", { cx: "4", cy: "12", r: "1.5" }),
1667
- /* @__PURE__ */ jsx4("circle", { cx: "4", cy: "18", r: "1.5" }),
1668
- /* @__PURE__ */ jsx4("path", { d: "M8 5h12v2H8zM8 11h12v2H8zM8 17h12v2H8z" })
2004
+ /* @__PURE__ */ jsx5("circle", { cx: "4", cy: "6", r: "1.5" }),
2005
+ /* @__PURE__ */ jsx5("circle", { cx: "4", cy: "12", r: "1.5" }),
2006
+ /* @__PURE__ */ jsx5("circle", { cx: "4", cy: "18", r: "1.5" }),
2007
+ /* @__PURE__ */ jsx5("path", { d: "M8 5h12v2H8zM8 11h12v2H8zM8 17h12v2H8z" })
1669
2008
  ] }),
1670
- numberedList: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx4("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
2009
+ numberedList: /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx5("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
1671
2010
  checkList: /* @__PURE__ */ jsxs4("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
1672
- /* @__PURE__ */ jsx4(
2011
+ /* @__PURE__ */ jsx5(
1673
2012
  "rect",
1674
2013
  {
1675
2014
  x: "3",
@@ -1682,7 +2021,7 @@ var BlockTypeIcons = {
1682
2021
  strokeWidth: "1.5"
1683
2022
  }
1684
2023
  ),
1685
- /* @__PURE__ */ jsx4(
2024
+ /* @__PURE__ */ jsx5(
1686
2025
  "path",
1687
2026
  {
1688
2027
  d: "M4.5 7l1.5 1.5 3-3",
@@ -1693,8 +2032,8 @@ var BlockTypeIcons = {
1693
2032
  strokeLinejoin: "round"
1694
2033
  }
1695
2034
  ),
1696
- /* @__PURE__ */ jsx4("path", { d: "M12 6h8v2h-8z" }),
1697
- /* @__PURE__ */ jsx4(
2035
+ /* @__PURE__ */ jsx5("path", { d: "M12 6h8v2h-8z" }),
2036
+ /* @__PURE__ */ jsx5(
1698
2037
  "rect",
1699
2038
  {
1700
2039
  x: "3",
@@ -1707,17 +2046,17 @@ var BlockTypeIcons = {
1707
2046
  strokeWidth: "1.5"
1708
2047
  }
1709
2048
  ),
1710
- /* @__PURE__ */ jsx4("path", { d: "M12 16h8v2h-8z" })
2049
+ /* @__PURE__ */ jsx5("path", { d: "M12 16h8v2h-8z" })
1711
2050
  ] })
1712
2051
  };
1713
2052
 
1714
2053
  // src/components/FloatingMenu/components/ToolbarDivider.tsx
1715
- import { jsx as jsx5 } from "react/jsx-runtime";
1716
- var ToolbarDivider = () => /* @__PURE__ */ jsx5("div", { className: "lumir-toolbar-divider" });
2054
+ import { jsx as jsx6 } from "react/jsx-runtime";
2055
+ var ToolbarDivider = () => /* @__PURE__ */ jsx6("div", { className: "lumir-toolbar-divider" });
1717
2056
 
1718
2057
  // src/components/FloatingMenu/components/UndoRedoButtons.tsx
1719
2058
  import { useCallback as useCallback4 } from "react";
1720
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2059
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1721
2060
  var UndoRedoButtons = ({ editor }) => {
1722
2061
  const handleUndo = useCallback4(() => {
1723
2062
  try {
@@ -1733,27 +2072,27 @@ var UndoRedoButtons = ({ editor }) => {
1733
2072
  console.error("Redo failed:", err);
1734
2073
  }
1735
2074
  }, [editor]);
1736
- const handleMouseDown = useCallback4((e) => {
2075
+ const handleMouseDown2 = useCallback4((e) => {
1737
2076
  e.preventDefault();
1738
2077
  }, []);
1739
2078
  return /* @__PURE__ */ jsxs5("div", { className: "lumir-toolbar-group", children: [
1740
- /* @__PURE__ */ jsx6(
2079
+ /* @__PURE__ */ jsx7(
1741
2080
  "button",
1742
2081
  {
1743
2082
  className: "lumir-toolbar-btn",
1744
2083
  onClick: handleUndo,
1745
- onMouseDown: handleMouseDown,
2084
+ onMouseDown: handleMouseDown2,
1746
2085
  title: "\uC2E4\uD589 \uCDE8\uC18C",
1747
2086
  type: "button",
1748
2087
  children: Icons.undo
1749
2088
  }
1750
2089
  ),
1751
- /* @__PURE__ */ jsx6(
2090
+ /* @__PURE__ */ jsx7(
1752
2091
  "button",
1753
2092
  {
1754
2093
  className: "lumir-toolbar-btn",
1755
2094
  onClick: handleRedo,
1756
- onMouseDown: handleMouseDown,
2095
+ onMouseDown: handleMouseDown2,
1757
2096
  title: "\uB2E4\uC2DC \uC2E4\uD589",
1758
2097
  type: "button",
1759
2098
  children: Icons.redo
@@ -1764,7 +2103,7 @@ var UndoRedoButtons = ({ editor }) => {
1764
2103
 
1765
2104
  // src/components/FloatingMenu/components/TextStyleButton.tsx
1766
2105
  import { useCallback as useCallback5 } from "react";
1767
- import { jsx as jsx7 } from "react/jsx-runtime";
2106
+ import { jsx as jsx8 } from "react/jsx-runtime";
1768
2107
  var iconMap = {
1769
2108
  bold: Icons.bold,
1770
2109
  italic: Icons.italic,
@@ -1797,15 +2136,15 @@ var TextStyleButton = ({
1797
2136
  console.error(`Toggle ${style} failed:`, err);
1798
2137
  }
1799
2138
  }, [editor, style]);
1800
- const handleMouseDown = useCallback5((e) => {
2139
+ const handleMouseDown2 = useCallback5((e) => {
1801
2140
  e.preventDefault();
1802
2141
  }, []);
1803
- return /* @__PURE__ */ jsx7(
2142
+ return /* @__PURE__ */ jsx8(
1804
2143
  "button",
1805
2144
  {
1806
2145
  className: cn("lumir-toolbar-btn", isActive && "is-active"),
1807
2146
  onClick: handleClick,
1808
- onMouseDown: handleMouseDown,
2147
+ onMouseDown: handleMouseDown2,
1809
2148
  title: titleMap[style],
1810
2149
  type: "button",
1811
2150
  children: iconMap[style]
@@ -1873,9 +2212,44 @@ function getFirstSelectedCellAttr(editor, attr) {
1873
2212
  const node = tiptap.state.doc.nodeAt(positions[0]);
1874
2213
  return node?.attrs?.[attr];
1875
2214
  }
2215
+ function findTableNodePos(tiptap, blockId) {
2216
+ let tablePos = -1;
2217
+ tiptap.state.doc.descendants((node, pos) => {
2218
+ if (tablePos !== -1) return false;
2219
+ if (node.type.name === "blockContainer" && node.attrs?.id === blockId && node.firstChild?.type.name === "table") {
2220
+ tablePos = pos + 1;
2221
+ return false;
2222
+ }
2223
+ return void 0;
2224
+ });
2225
+ return tablePos;
2226
+ }
2227
+ function setTableAlignment(editor, blockId, alignment) {
2228
+ const tiptap = editor?._tiptapEditor;
2229
+ if (!tiptap || !blockId) return false;
2230
+ const tablePos = findTableNodePos(tiptap, blockId);
2231
+ if (tablePos < 0) return false;
2232
+ const node = tiptap.state.doc.nodeAt(tablePos);
2233
+ if (!node || node.type.name !== "table") return false;
2234
+ tiptap.view?.dispatch(
2235
+ tiptap.state.tr.setNodeMarkup(tablePos, void 0, {
2236
+ ...node.attrs,
2237
+ tableAlignment: alignment
2238
+ })
2239
+ );
2240
+ return true;
2241
+ }
2242
+ function getTableAlignment(editor, blockId) {
2243
+ const tiptap = editor?._tiptapEditor;
2244
+ if (!tiptap || !blockId) return "left";
2245
+ const tablePos = findTableNodePos(tiptap, blockId);
2246
+ if (tablePos < 0) return "left";
2247
+ const node = tiptap.state.doc.nodeAt(tablePos);
2248
+ return node?.attrs?.tableAlignment || "left";
2249
+ }
1876
2250
 
1877
2251
  // src/components/FloatingMenu/components/AlignButton.tsx
1878
- import { jsx as jsx8 } from "react/jsx-runtime";
2252
+ import { jsx as jsx9 } from "react/jsx-runtime";
1879
2253
  var iconMap2 = {
1880
2254
  left: Icons.alignLeft,
1881
2255
  center: Icons.alignCenter,
@@ -1915,15 +2289,15 @@ var AlignButton = ({
1915
2289
  console.error(`Set alignment ${alignment} failed:`, err);
1916
2290
  }
1917
2291
  }, [editor, alignment]);
1918
- const handleMouseDown = useCallback6((e) => {
2292
+ const handleMouseDown2 = useCallback6((e) => {
1919
2293
  e.preventDefault();
1920
2294
  }, []);
1921
- return /* @__PURE__ */ jsx8(
2295
+ return /* @__PURE__ */ jsx9(
1922
2296
  "button",
1923
2297
  {
1924
2298
  className: cn("lumir-toolbar-btn", isActive && "is-active"),
1925
2299
  onClick: handleClick,
1926
- onMouseDown: handleMouseDown,
2300
+ onMouseDown: handleMouseDown2,
1927
2301
  title: titleMap2[alignment],
1928
2302
  type: "button",
1929
2303
  children: iconMap2[alignment]
@@ -1933,7 +2307,7 @@ var AlignButton = ({
1933
2307
 
1934
2308
  // src/components/FloatingMenu/components/ListButton.tsx
1935
2309
  import { useCallback as useCallback7 } from "react";
1936
- import { jsx as jsx9 } from "react/jsx-runtime";
2310
+ import { jsx as jsx10 } from "react/jsx-runtime";
1937
2311
  var iconMap3 = {
1938
2312
  bullet: Icons.bulletList,
1939
2313
  numbered: Icons.numberedList
@@ -1965,15 +2339,15 @@ var ListButton = ({ editor, type }) => {
1965
2339
  console.error(`List toggle failed:`, err);
1966
2340
  }
1967
2341
  }, [editor, type]);
1968
- const handleMouseDown = useCallback7((e) => {
2342
+ const handleMouseDown2 = useCallback7((e) => {
1969
2343
  e.preventDefault();
1970
2344
  }, []);
1971
- return /* @__PURE__ */ jsx9(
2345
+ return /* @__PURE__ */ jsx10(
1972
2346
  "button",
1973
2347
  {
1974
2348
  className: cn("lumir-toolbar-btn", isActive && "is-active"),
1975
2349
  onClick: handleClick,
1976
- onMouseDown: handleMouseDown,
2350
+ onMouseDown: handleMouseDown2,
1977
2351
  title: titleMap3[type],
1978
2352
  type: "button",
1979
2353
  children: iconMap3[type]
@@ -1983,7 +2357,7 @@ var ListButton = ({ editor, type }) => {
1983
2357
 
1984
2358
  // src/components/FloatingMenu/components/ImageButton.tsx
1985
2359
  import { useCallback as useCallback8 } from "react";
1986
- import { jsx as jsx10 } from "react/jsx-runtime";
2360
+ import { jsx as jsx11 } from "react/jsx-runtime";
1987
2361
  var ImageButton = ({
1988
2362
  editor,
1989
2363
  onImageUpload
@@ -2013,15 +2387,15 @@ var ImageButton = ({
2013
2387
  input.click();
2014
2388
  }
2015
2389
  }, [editor, onImageUpload]);
2016
- const handleMouseDown = useCallback8((e) => {
2390
+ const handleMouseDown2 = useCallback8((e) => {
2017
2391
  e.preventDefault();
2018
2392
  }, []);
2019
- return /* @__PURE__ */ jsx10(
2393
+ return /* @__PURE__ */ jsx11(
2020
2394
  "button",
2021
2395
  {
2022
2396
  className: "lumir-toolbar-btn",
2023
2397
  onClick: handleClick,
2024
- onMouseDown: handleMouseDown,
2398
+ onMouseDown: handleMouseDown2,
2025
2399
  title: "\uC774\uBBF8\uC9C0 \uC0BD\uC785",
2026
2400
  type: "button",
2027
2401
  children: Icons.image
@@ -2064,7 +2438,7 @@ var getHexFromColorValue = (value, type) => {
2064
2438
  };
2065
2439
 
2066
2440
  // src/components/FloatingMenu/components/ColorButton.tsx
2067
- import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
2441
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
2068
2442
  var ColorButton = ({ editor, type }) => {
2069
2443
  const [isOpen, setIsOpen] = useState4(false);
2070
2444
  const [currentColor, setCurrentColor] = useState4("default");
@@ -2120,7 +2494,7 @@ var ColorButton = ({ editor, type }) => {
2120
2494
  },
2121
2495
  [editor, type]
2122
2496
  );
2123
- const handleMouseDown = useCallback9((e) => {
2497
+ const handleMouseDown2 = useCallback9((e) => {
2124
2498
  e.preventDefault();
2125
2499
  }, []);
2126
2500
  return /* @__PURE__ */ jsxs6("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
@@ -2129,12 +2503,12 @@ var ColorButton = ({ editor, type }) => {
2129
2503
  {
2130
2504
  className: "lumir-toolbar-btn lumir-color-btn",
2131
2505
  onClick: () => setIsOpen(!isOpen),
2132
- onMouseDown: handleMouseDown,
2506
+ onMouseDown: handleMouseDown2,
2133
2507
  title: type === "text" ? "\uD14D\uC2A4\uD2B8 \uC0C9\uC0C1" : "\uBC30\uACBD \uC0C9\uC0C1",
2134
2508
  type: "button",
2135
2509
  children: [
2136
2510
  type === "text" ? Icons.textColor : Icons.bgColor,
2137
- /* @__PURE__ */ jsx11(
2511
+ /* @__PURE__ */ jsx12(
2138
2512
  "span",
2139
2513
  {
2140
2514
  className: "lumir-color-indicator",
@@ -2146,7 +2520,7 @@ var ColorButton = ({ editor, type }) => {
2146
2520
  ]
2147
2521
  }
2148
2522
  ),
2149
- isOpen && /* @__PURE__ */ jsx11("div", { className: "lumir-dropdown-menu lumir-color-menu", children: /* @__PURE__ */ jsx11("div", { className: "lumir-color-grid", children: colors.map((color) => /* @__PURE__ */ jsx11(
2523
+ isOpen && /* @__PURE__ */ jsx12("div", { className: "lumir-dropdown-menu lumir-color-menu", children: /* @__PURE__ */ jsx12("div", { className: "lumir-color-grid", children: colors.map((color) => /* @__PURE__ */ jsx12(
2150
2524
  "button",
2151
2525
  {
2152
2526
  className: cn(
@@ -2154,7 +2528,7 @@ var ColorButton = ({ editor, type }) => {
2154
2528
  currentColor === color.value && "is-active"
2155
2529
  ),
2156
2530
  onClick: () => handleColorSelect(color.value),
2157
- onMouseDown: handleMouseDown,
2531
+ onMouseDown: handleMouseDown2,
2158
2532
  title: color.name,
2159
2533
  style: { backgroundColor: color.hex },
2160
2534
  type: "button"
@@ -2164,9 +2538,101 @@ var ColorButton = ({ editor, type }) => {
2164
2538
  ] });
2165
2539
  };
2166
2540
 
2167
- // src/components/FloatingMenu/components/LinkButton.tsx
2541
+ // src/components/FloatingMenu/components/FontSizeButton.tsx
2168
2542
  import { useState as useState5, useEffect as useEffect5, useRef as useRef5, useCallback as useCallback10 } from "react";
2169
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
2543
+ import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
2544
+ var DEFAULT_LABEL = "\uAE30\uBCF8";
2545
+ var toLabel = (size) => size.replace(/px$/, "");
2546
+ var FontSizeButton = ({ editor }) => {
2547
+ const [isOpen, setIsOpen] = useState5(false);
2548
+ const dropdownRef = useRef5(null);
2549
+ const getCurrentSize = () => {
2550
+ try {
2551
+ return editor?.getActiveStyles?.()?.fontSize || "";
2552
+ } catch {
2553
+ return "";
2554
+ }
2555
+ };
2556
+ const currentSize = getCurrentSize();
2557
+ useEffect5(() => {
2558
+ const handleClickOutside = (e) => {
2559
+ if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
2560
+ setIsOpen(false);
2561
+ }
2562
+ };
2563
+ document.addEventListener("mousedown", handleClickOutside);
2564
+ return () => document.removeEventListener("mousedown", handleClickOutside);
2565
+ }, []);
2566
+ const handleSizeSelect = useCallback10(
2567
+ (size) => {
2568
+ try {
2569
+ if (!editor) return;
2570
+ if (size === "") {
2571
+ editor.removeStyles?.({ fontSize: "" });
2572
+ } else {
2573
+ editor.addStyles?.({ fontSize: size });
2574
+ }
2575
+ setIsOpen(false);
2576
+ setTimeout(() => editor.focus?.());
2577
+ } catch (err) {
2578
+ console.error("Font size apply failed:", err);
2579
+ }
2580
+ },
2581
+ [editor]
2582
+ );
2583
+ const handleMouseDown2 = useCallback10((e) => {
2584
+ e.preventDefault();
2585
+ }, []);
2586
+ return /* @__PURE__ */ jsxs7("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
2587
+ /* @__PURE__ */ jsxs7(
2588
+ "button",
2589
+ {
2590
+ className: "lumir-dropdown-btn lumir-font-size-btn",
2591
+ onClick: () => setIsOpen(!isOpen),
2592
+ onMouseDown: handleMouseDown2,
2593
+ title: "\uAE00\uC790 \uD06C\uAE30",
2594
+ type: "button",
2595
+ children: [
2596
+ /* @__PURE__ */ jsx13("span", { className: "lumir-font-size-label", children: currentSize ? toLabel(currentSize) : DEFAULT_LABEL }),
2597
+ Icons.expandMore
2598
+ ]
2599
+ }
2600
+ ),
2601
+ isOpen && /* @__PURE__ */ jsxs7("div", { className: "lumir-dropdown-menu lumir-font-size-menu", children: [
2602
+ /* @__PURE__ */ jsx13(
2603
+ "button",
2604
+ {
2605
+ className: cn(
2606
+ "lumir-dropdown-item",
2607
+ currentSize === "" && "is-active"
2608
+ ),
2609
+ onClick: () => handleSizeSelect(""),
2610
+ onMouseDown: handleMouseDown2,
2611
+ type: "button",
2612
+ children: DEFAULT_LABEL
2613
+ }
2614
+ ),
2615
+ FONT_SIZE_PRESETS.map((size) => /* @__PURE__ */ jsx13(
2616
+ "button",
2617
+ {
2618
+ className: cn(
2619
+ "lumir-dropdown-item",
2620
+ currentSize === size && "is-active"
2621
+ ),
2622
+ onClick: () => handleSizeSelect(size),
2623
+ onMouseDown: handleMouseDown2,
2624
+ type: "button",
2625
+ children: toLabel(size)
2626
+ },
2627
+ size
2628
+ ))
2629
+ ] })
2630
+ ] });
2631
+ };
2632
+
2633
+ // src/components/FloatingMenu/components/LinkButton.tsx
2634
+ import { useState as useState6, useEffect as useEffect6, useRef as useRef6, useCallback as useCallback11 } from "react";
2635
+ import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
2170
2636
  var isDangerousProtocol = (url) => {
2171
2637
  const trimmedUrl = url.trim().toLowerCase();
2172
2638
  const dangerousPatterns = [
@@ -2192,13 +2658,13 @@ var normalizeUrl = (url) => {
2192
2658
  return `https://${trimmedUrl}`;
2193
2659
  };
2194
2660
  var LinkButton = ({ editor }) => {
2195
- const [isOpen, setIsOpen] = useState5(false);
2196
- const [linkUrl, setLinkUrl] = useState5("");
2197
- const [errorMsg, setErrorMsg] = useState5(null);
2198
- const dropdownRef = useRef5(null);
2199
- const inputRef = useRef5(null);
2200
- const hasSelectionRef = useRef5(false);
2201
- useEffect5(() => {
2661
+ const [isOpen, setIsOpen] = useState6(false);
2662
+ const [linkUrl, setLinkUrl] = useState6("");
2663
+ const [errorMsg, setErrorMsg] = useState6(null);
2664
+ const dropdownRef = useRef6(null);
2665
+ const inputRef = useRef6(null);
2666
+ const hasSelectionRef = useRef6(false);
2667
+ useEffect6(() => {
2202
2668
  const handleClickOutside = (e) => {
2203
2669
  if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
2204
2670
  setIsOpen(false);
@@ -2209,7 +2675,7 @@ var LinkButton = ({ editor }) => {
2209
2675
  document.addEventListener("mousedown", handleClickOutside);
2210
2676
  return () => document.removeEventListener("mousedown", handleClickOutside);
2211
2677
  }, []);
2212
- useEffect5(() => {
2678
+ useEffect6(() => {
2213
2679
  if (isOpen && inputRef.current) {
2214
2680
  try {
2215
2681
  const selectedText = editor?.getSelectedText?.() || "";
@@ -2220,7 +2686,7 @@ var LinkButton = ({ editor }) => {
2220
2686
  setTimeout(() => inputRef.current?.focus(), 0);
2221
2687
  }
2222
2688
  }, [isOpen, editor]);
2223
- const handleSubmit = useCallback10(
2689
+ const handleSubmit = useCallback11(
2224
2690
  (e) => {
2225
2691
  e?.preventDefault();
2226
2692
  setErrorMsg(null);
@@ -2247,15 +2713,15 @@ var LinkButton = ({ editor }) => {
2247
2713
  },
2248
2714
  [editor, linkUrl]
2249
2715
  );
2250
- const handleCancel = useCallback10(() => {
2716
+ const handleCancel = useCallback11(() => {
2251
2717
  setIsOpen(false);
2252
2718
  setLinkUrl("");
2253
2719
  setErrorMsg(null);
2254
2720
  }, []);
2255
- const handleMouseDown = useCallback10((e) => {
2721
+ const handleMouseDown2 = useCallback11((e) => {
2256
2722
  e.preventDefault();
2257
2723
  }, []);
2258
- const handleKeyDown = useCallback10(
2724
+ const handleKeyDown = useCallback11(
2259
2725
  (e) => {
2260
2726
  if (e.key === "Enter") {
2261
2727
  handleSubmit();
@@ -2265,20 +2731,20 @@ var LinkButton = ({ editor }) => {
2265
2731
  },
2266
2732
  [handleSubmit, handleCancel]
2267
2733
  );
2268
- return /* @__PURE__ */ jsxs7("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
2269
- /* @__PURE__ */ jsx12(
2734
+ return /* @__PURE__ */ jsxs8("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
2735
+ /* @__PURE__ */ jsx14(
2270
2736
  "button",
2271
2737
  {
2272
2738
  className: "lumir-toolbar-btn",
2273
2739
  onClick: () => setIsOpen(!isOpen),
2274
- onMouseDown: handleMouseDown,
2740
+ onMouseDown: handleMouseDown2,
2275
2741
  title: "\uB9C1\uD06C \uC0BD\uC785",
2276
2742
  type: "button",
2277
2743
  children: Icons.link
2278
2744
  }
2279
2745
  ),
2280
- isOpen && /* @__PURE__ */ jsx12("div", { className: "lumir-dropdown-menu lumir-link-menu", children: /* @__PURE__ */ jsxs7("form", { onSubmit: handleSubmit, className: "lumir-link-form", children: [
2281
- /* @__PURE__ */ jsx12(
2746
+ isOpen && /* @__PURE__ */ jsx14("div", { className: "lumir-dropdown-menu lumir-link-menu", children: /* @__PURE__ */ jsxs8("form", { onSubmit: handleSubmit, className: "lumir-link-form", children: [
2747
+ /* @__PURE__ */ jsx14(
2282
2748
  "input",
2283
2749
  {
2284
2750
  ref: inputRef,
@@ -2291,10 +2757,10 @@ var LinkButton = ({ editor }) => {
2291
2757
  setErrorMsg(null);
2292
2758
  },
2293
2759
  onKeyDown: handleKeyDown,
2294
- onMouseDown: handleMouseDown
2760
+ onMouseDown: handleMouseDown2
2295
2761
  }
2296
2762
  ),
2297
- errorMsg && /* @__PURE__ */ jsx12(
2763
+ errorMsg && /* @__PURE__ */ jsx14(
2298
2764
  "div",
2299
2765
  {
2300
2766
  style: {
@@ -2306,23 +2772,23 @@ var LinkButton = ({ editor }) => {
2306
2772
  children: errorMsg
2307
2773
  }
2308
2774
  ),
2309
- /* @__PURE__ */ jsxs7("div", { className: "lumir-link-actions", children: [
2310
- /* @__PURE__ */ jsx12(
2775
+ /* @__PURE__ */ jsxs8("div", { className: "lumir-link-actions", children: [
2776
+ /* @__PURE__ */ jsx14(
2311
2777
  "button",
2312
2778
  {
2313
2779
  type: "button",
2314
2780
  className: "lumir-link-btn lumir-link-cancel",
2315
2781
  onClick: handleCancel,
2316
- onMouseDown: handleMouseDown,
2782
+ onMouseDown: handleMouseDown2,
2317
2783
  children: "\uCDE8\uC18C"
2318
2784
  }
2319
2785
  ),
2320
- /* @__PURE__ */ jsx12(
2786
+ /* @__PURE__ */ jsx14(
2321
2787
  "button",
2322
2788
  {
2323
2789
  type: "submit",
2324
2790
  className: "lumir-link-btn lumir-link-submit",
2325
- onMouseDown: handleMouseDown,
2791
+ onMouseDown: handleMouseDown2,
2326
2792
  disabled: !linkUrl.trim(),
2327
2793
  children: "\uD655\uC778"
2328
2794
  }
@@ -2333,10 +2799,10 @@ var LinkButton = ({ editor }) => {
2333
2799
  };
2334
2800
 
2335
2801
  // src/components/FloatingMenu/components/TableButton.tsx
2336
- import { useCallback as useCallback11 } from "react";
2337
- import { jsx as jsx13 } from "react/jsx-runtime";
2802
+ import { useCallback as useCallback12 } from "react";
2803
+ import { jsx as jsx15 } from "react/jsx-runtime";
2338
2804
  var TableButton = ({ editor }) => {
2339
- const handleClick = useCallback11(() => {
2805
+ const handleClick = useCallback12(() => {
2340
2806
  try {
2341
2807
  const block = editor?.getTextCursorPosition()?.block;
2342
2808
  if (!block || !editor?.insertBlocks) return;
@@ -2358,15 +2824,15 @@ var TableButton = ({ editor }) => {
2358
2824
  console.error("Table insert failed:", err);
2359
2825
  }
2360
2826
  }, [editor]);
2361
- const handleMouseDown = useCallback11((e) => {
2827
+ const handleMouseDown2 = useCallback12((e) => {
2362
2828
  e.preventDefault();
2363
2829
  }, []);
2364
- return /* @__PURE__ */ jsx13(
2830
+ return /* @__PURE__ */ jsx15(
2365
2831
  "button",
2366
2832
  {
2367
2833
  className: "lumir-toolbar-btn",
2368
2834
  onClick: handleClick,
2369
- onMouseDown: handleMouseDown,
2835
+ onMouseDown: handleMouseDown2,
2370
2836
  title: "\uD14C\uC774\uBE14 \uC0BD\uC785",
2371
2837
  type: "button",
2372
2838
  children: Icons.table
@@ -2375,13 +2841,13 @@ var TableButton = ({ editor }) => {
2375
2841
  };
2376
2842
 
2377
2843
  // src/components/FloatingMenu/components/HTMLImportButton.tsx
2378
- import { useCallback as useCallback12, useRef as useRef6 } from "react";
2379
- import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
2844
+ import { useCallback as useCallback13, useRef as useRef7 } from "react";
2845
+ import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
2380
2846
  var HTMLImportButton = ({
2381
2847
  editor
2382
2848
  }) => {
2383
- const fileInputRef = useRef6(null);
2384
- const handleFileUpload = useCallback12(
2849
+ const fileInputRef = useRef7(null);
2850
+ const handleFileUpload = useCallback13(
2385
2851
  (e) => {
2386
2852
  const file = e.target.files?.[0];
2387
2853
  if (!file) return;
@@ -2417,14 +2883,14 @@ var HTMLImportButton = ({
2417
2883
  },
2418
2884
  [editor]
2419
2885
  );
2420
- const handleClick = useCallback12(() => {
2886
+ const handleClick = useCallback13(() => {
2421
2887
  fileInputRef.current?.click();
2422
2888
  }, []);
2423
- const handleMouseDown = useCallback12((e) => {
2889
+ const handleMouseDown2 = useCallback13((e) => {
2424
2890
  e.preventDefault();
2425
2891
  }, []);
2426
- return /* @__PURE__ */ jsxs8(Fragment3, { children: [
2427
- /* @__PURE__ */ jsx14(
2892
+ return /* @__PURE__ */ jsxs9(Fragment3, { children: [
2893
+ /* @__PURE__ */ jsx16(
2428
2894
  "input",
2429
2895
  {
2430
2896
  ref: fileInputRef,
@@ -2434,12 +2900,12 @@ var HTMLImportButton = ({
2434
2900
  style: { display: "none" }
2435
2901
  }
2436
2902
  ),
2437
- /* @__PURE__ */ jsx14(
2903
+ /* @__PURE__ */ jsx16(
2438
2904
  "button",
2439
2905
  {
2440
2906
  className: "lumir-toolbar-btn",
2441
2907
  onClick: handleClick,
2442
- onMouseDown: handleMouseDown,
2908
+ onMouseDown: handleMouseDown2,
2443
2909
  title: "HTML Import",
2444
2910
  type: "button",
2445
2911
  children: Icons.htmlFile
@@ -2449,8 +2915,8 @@ var HTMLImportButton = ({
2449
2915
  };
2450
2916
 
2451
2917
  // src/components/FloatingMenu/components/BlockTypeSelect.tsx
2452
- import { useState as useState6, useEffect as useEffect6, useRef as useRef7, useCallback as useCallback13 } from "react";
2453
- import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
2918
+ import { useState as useState7, useEffect as useEffect7, useRef as useRef8, useCallback as useCallback14 } from "react";
2919
+ import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
2454
2920
  var blockTypeCategories = [
2455
2921
  {
2456
2922
  category: "Headings",
@@ -2480,8 +2946,8 @@ var blockTypes = blockTypeCategories.flatMap(
2480
2946
  (cat) => cat.items
2481
2947
  );
2482
2948
  var BlockTypeSelect = ({ editor }) => {
2483
- const [isOpen, setIsOpen] = useState6(false);
2484
- const dropdownRef = useRef7(null);
2949
+ const [isOpen, setIsOpen] = useState7(false);
2950
+ const dropdownRef = useRef8(null);
2485
2951
  const getCurrentBlock = () => {
2486
2952
  try {
2487
2953
  return editor?.getTextCursorPosition()?.block;
@@ -2493,7 +2959,7 @@ var BlockTypeSelect = ({ editor }) => {
2493
2959
  const currentType = currentBlock?.type || "paragraph";
2494
2960
  const currentLevel = currentBlock?.props?.level;
2495
2961
  const isCurrentToggle = currentType === "heading" && currentBlock?.props?.isToggleable === true;
2496
- useEffect6(() => {
2962
+ useEffect7(() => {
2497
2963
  const handleClickOutside = (e) => {
2498
2964
  if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
2499
2965
  setIsOpen(false);
@@ -2522,7 +2988,7 @@ var BlockTypeSelect = ({ editor }) => {
2522
2988
  console.error("Block type change failed:", err);
2523
2989
  }
2524
2990
  };
2525
- const handleMouseDown = useCallback13((e) => {
2991
+ const handleMouseDown2 = useCallback14((e) => {
2526
2992
  e.preventDefault();
2527
2993
  }, []);
2528
2994
  const getCurrentLabel = () => {
@@ -2553,24 +3019,24 @@ var BlockTypeSelect = ({ editor }) => {
2553
3019
  }
2554
3020
  return currentType === bt.type;
2555
3021
  };
2556
- return /* @__PURE__ */ jsxs9("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
2557
- /* @__PURE__ */ jsxs9(
3022
+ return /* @__PURE__ */ jsxs10("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
3023
+ /* @__PURE__ */ jsxs10(
2558
3024
  "button",
2559
3025
  {
2560
3026
  className: "lumir-dropdown-btn lumir-block-type-btn",
2561
3027
  onClick: () => setIsOpen(!isOpen),
2562
- onMouseDown: handleMouseDown,
3028
+ onMouseDown: handleMouseDown2,
2563
3029
  type: "button",
2564
3030
  children: [
2565
- /* @__PURE__ */ jsx15("span", { className: "lumir-block-icon", children: BlockTypeIcons[getCurrentIcon()] }),
2566
- /* @__PURE__ */ jsx15("span", { className: "lumir-block-label", children: getCurrentLabel() }),
3031
+ /* @__PURE__ */ jsx17("span", { className: "lumir-block-icon", children: BlockTypeIcons[getCurrentIcon()] }),
3032
+ /* @__PURE__ */ jsx17("span", { className: "lumir-block-label", children: getCurrentLabel() }),
2567
3033
  Icons.expandMore
2568
3034
  ]
2569
3035
  }
2570
3036
  ),
2571
- isOpen && /* @__PURE__ */ jsx15("div", { className: "lumir-dropdown-menu lumir-block-menu", children: blockTypeCategories.map((category) => /* @__PURE__ */ jsxs9("div", { className: "lumir-block-category", children: [
2572
- /* @__PURE__ */ jsx15("div", { className: "lumir-block-category-title", children: category.category }),
2573
- category.items.map((bt) => /* @__PURE__ */ jsxs9(
3037
+ isOpen && /* @__PURE__ */ jsx17("div", { className: "lumir-dropdown-menu lumir-block-menu", children: blockTypeCategories.map((category) => /* @__PURE__ */ jsxs10("div", { className: "lumir-block-category", children: [
3038
+ /* @__PURE__ */ jsx17("div", { className: "lumir-block-category-title", children: category.category }),
3039
+ category.items.map((bt) => /* @__PURE__ */ jsxs10(
2574
3040
  "button",
2575
3041
  {
2576
3042
  className: cn(
@@ -2578,10 +3044,10 @@ var BlockTypeSelect = ({ editor }) => {
2578
3044
  isActiveItem(bt) && "is-active"
2579
3045
  ),
2580
3046
  onClick: () => handleTypeChange(bt.type, bt.level, bt.isToggle),
2581
- onMouseDown: handleMouseDown,
3047
+ onMouseDown: handleMouseDown2,
2582
3048
  children: [
2583
- /* @__PURE__ */ jsx15("span", { className: "lumir-block-icon", children: BlockTypeIcons[bt.icon] }),
2584
- /* @__PURE__ */ jsx15("span", { className: "lumir-block-item-title", children: bt.label })
3049
+ /* @__PURE__ */ jsx17("span", { className: "lumir-block-icon", children: BlockTypeIcons[bt.icon] }),
3050
+ /* @__PURE__ */ jsx17("span", { className: "lumir-block-item-title", children: bt.label })
2585
3051
  ]
2586
3052
  },
2587
3053
  bt.icon
@@ -2591,7 +3057,7 @@ var BlockTypeSelect = ({ editor }) => {
2591
3057
  };
2592
3058
 
2593
3059
  // src/components/FloatingMenu/index.tsx
2594
- import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
3060
+ import { Fragment as Fragment4, jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
2595
3061
  var COMPACT_BREAKPOINT = 700;
2596
3062
  var MINIMIZED_BREAKPOINT = 400;
2597
3063
  var FloatingMenu = ({
@@ -2600,12 +3066,12 @@ var FloatingMenu = ({
2600
3066
  className,
2601
3067
  onImageUpload
2602
3068
  }) => {
2603
- const wrapperRef = useRef8(null);
2604
- const [isCompact, setIsCompact] = useState7(false);
2605
- const [isMinimizable, setIsMinimizable] = useState7(false);
2606
- const [isMinimized, setIsMinimized] = useState7(false);
2607
- const [, setSelectionTick] = useState7(0);
2608
- useEffect7(() => {
3069
+ const wrapperRef = useRef9(null);
3070
+ const [isCompact, setIsCompact] = useState8(false);
3071
+ const [isMinimizable, setIsMinimizable] = useState8(false);
3072
+ const [isMinimized, setIsMinimized] = useState8(false);
3073
+ const [, setSelectionTick] = useState8(0);
3074
+ useEffect8(() => {
2609
3075
  if (!editor) return;
2610
3076
  let debounceTimer = null;
2611
3077
  const DEBOUNCE_DELAY = 150;
@@ -2629,7 +3095,7 @@ var FloatingMenu = ({
2629
3095
  unsubscribeContent?.();
2630
3096
  };
2631
3097
  }, [editor]);
2632
- useEffect7(() => {
3098
+ useEffect8(() => {
2633
3099
  const checkWidth = () => {
2634
3100
  if (wrapperRef.current) {
2635
3101
  const width = wrapperRef.current.offsetWidth;
@@ -2644,8 +3110,8 @@ var FloatingMenu = ({
2644
3110
  }
2645
3111
  return () => resizeObserver.disconnect();
2646
3112
  }, []);
2647
- const MinimizedLayout = () => /* @__PURE__ */ jsxs10(Fragment4, { children: [
2648
- /* @__PURE__ */ jsx16(
3113
+ const MinimizedLayout = () => /* @__PURE__ */ jsxs11(Fragment4, { children: [
3114
+ /* @__PURE__ */ jsx18(
2649
3115
  "button",
2650
3116
  {
2651
3117
  className: "lumir-toolbar-button lumir-toggle-button",
@@ -2656,117 +3122,120 @@ var FloatingMenu = ({
2656
3122
  children: isMinimized ? Icons.chevronRight : Icons.chevronLeft
2657
3123
  }
2658
3124
  ),
2659
- !isMinimized && /* @__PURE__ */ jsxs10(Fragment4, { children: [
2660
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2661
- /* @__PURE__ */ jsx16(UndoRedoButtons, { editor }),
2662
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2663
- /* @__PURE__ */ jsx16("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ jsx16(BlockTypeSelect, { editor }) }),
2664
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2665
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2666
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "bold" }),
2667
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "italic" }),
2668
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "underline" }),
2669
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "strike" })
3125
+ !isMinimized && /* @__PURE__ */ jsxs11(Fragment4, { children: [
3126
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3127
+ /* @__PURE__ */ jsx18(UndoRedoButtons, { editor }),
3128
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3129
+ /* @__PURE__ */ jsx18("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ jsx18(BlockTypeSelect, { editor }) }),
3130
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3131
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3132
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "bold" }),
3133
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "italic" }),
3134
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "underline" }),
3135
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "strike" })
2670
3136
  ] }),
2671
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2672
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2673
- /* @__PURE__ */ jsx16(AlignButton, { editor, alignment: "left" }),
2674
- /* @__PURE__ */ jsx16(AlignButton, { editor, alignment: "center" }),
2675
- /* @__PURE__ */ jsx16(AlignButton, { editor, alignment: "right" })
3137
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3138
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3139
+ /* @__PURE__ */ jsx18(AlignButton, { editor, alignment: "left" }),
3140
+ /* @__PURE__ */ jsx18(AlignButton, { editor, alignment: "center" }),
3141
+ /* @__PURE__ */ jsx18(AlignButton, { editor, alignment: "right" })
2676
3142
  ] }),
2677
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2678
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2679
- /* @__PURE__ */ jsx16(ListButton, { editor, type: "bullet" }),
2680
- /* @__PURE__ */ jsx16(ListButton, { editor, type: "numbered" })
3143
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3144
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3145
+ /* @__PURE__ */ jsx18(ListButton, { editor, type: "bullet" }),
3146
+ /* @__PURE__ */ jsx18(ListButton, { editor, type: "numbered" })
2681
3147
  ] }),
2682
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2683
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2684
- /* @__PURE__ */ jsx16(ColorButton, { editor, type: "text" }),
2685
- /* @__PURE__ */ jsx16(ColorButton, { editor, type: "background" })
3148
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3149
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3150
+ /* @__PURE__ */ jsx18(FontSizeButton, { editor }),
3151
+ /* @__PURE__ */ jsx18(ColorButton, { editor, type: "text" }),
3152
+ /* @__PURE__ */ jsx18(ColorButton, { editor, type: "background" })
2686
3153
  ] }),
2687
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2688
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2689
- /* @__PURE__ */ jsx16(ImageButton, { editor, onImageUpload }),
2690
- /* @__PURE__ */ jsx16(LinkButton, { editor }),
2691
- /* @__PURE__ */ jsx16(TableButton, { editor }),
2692
- /* @__PURE__ */ jsx16(HTMLImportButton, { editor })
3154
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3155
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3156
+ /* @__PURE__ */ jsx18(ImageButton, { editor, onImageUpload }),
3157
+ /* @__PURE__ */ jsx18(LinkButton, { editor }),
3158
+ /* @__PURE__ */ jsx18(TableButton, { editor }),
3159
+ /* @__PURE__ */ jsx18(HTMLImportButton, { editor })
2693
3160
  ] })
2694
3161
  ] })
2695
3162
  ] });
2696
- const SingleRowLayout = () => /* @__PURE__ */ jsxs10(Fragment4, { children: [
2697
- /* @__PURE__ */ jsx16(UndoRedoButtons, { editor }),
2698
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2699
- /* @__PURE__ */ jsx16("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ jsx16(BlockTypeSelect, { editor }) }),
2700
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2701
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2702
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "bold" }),
2703
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "italic" }),
2704
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "underline" }),
2705
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "strike" })
3163
+ const SingleRowLayout = () => /* @__PURE__ */ jsxs11(Fragment4, { children: [
3164
+ /* @__PURE__ */ jsx18(UndoRedoButtons, { editor }),
3165
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3166
+ /* @__PURE__ */ jsx18("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ jsx18(BlockTypeSelect, { editor }) }),
3167
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3168
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3169
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "bold" }),
3170
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "italic" }),
3171
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "underline" }),
3172
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "strike" })
2706
3173
  ] }),
2707
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2708
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2709
- /* @__PURE__ */ jsx16(AlignButton, { editor, alignment: "left" }),
2710
- /* @__PURE__ */ jsx16(AlignButton, { editor, alignment: "center" }),
2711
- /* @__PURE__ */ jsx16(AlignButton, { editor, alignment: "right" })
3174
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3175
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3176
+ /* @__PURE__ */ jsx18(AlignButton, { editor, alignment: "left" }),
3177
+ /* @__PURE__ */ jsx18(AlignButton, { editor, alignment: "center" }),
3178
+ /* @__PURE__ */ jsx18(AlignButton, { editor, alignment: "right" })
2712
3179
  ] }),
2713
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2714
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2715
- /* @__PURE__ */ jsx16(ListButton, { editor, type: "bullet" }),
2716
- /* @__PURE__ */ jsx16(ListButton, { editor, type: "numbered" })
3180
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3181
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3182
+ /* @__PURE__ */ jsx18(ListButton, { editor, type: "bullet" }),
3183
+ /* @__PURE__ */ jsx18(ListButton, { editor, type: "numbered" })
2717
3184
  ] }),
2718
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2719
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2720
- /* @__PURE__ */ jsx16(ColorButton, { editor, type: "text" }),
2721
- /* @__PURE__ */ jsx16(ColorButton, { editor, type: "background" })
3185
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3186
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3187
+ /* @__PURE__ */ jsx18(FontSizeButton, { editor }),
3188
+ /* @__PURE__ */ jsx18(ColorButton, { editor, type: "text" }),
3189
+ /* @__PURE__ */ jsx18(ColorButton, { editor, type: "background" })
2722
3190
  ] }),
2723
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2724
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2725
- /* @__PURE__ */ jsx16(ImageButton, { editor, onImageUpload }),
2726
- /* @__PURE__ */ jsx16(LinkButton, { editor }),
2727
- /* @__PURE__ */ jsx16(TableButton, { editor }),
2728
- /* @__PURE__ */ jsx16(HTMLImportButton, { editor })
3191
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3192
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3193
+ /* @__PURE__ */ jsx18(ImageButton, { editor, onImageUpload }),
3194
+ /* @__PURE__ */ jsx18(LinkButton, { editor }),
3195
+ /* @__PURE__ */ jsx18(TableButton, { editor }),
3196
+ /* @__PURE__ */ jsx18(HTMLImportButton, { editor })
2729
3197
  ] })
2730
3198
  ] });
2731
- const TwoRowLayout = () => /* @__PURE__ */ jsxs10(Fragment4, { children: [
2732
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-row", children: [
2733
- /* @__PURE__ */ jsx16(UndoRedoButtons, { editor }),
2734
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2735
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2736
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "bold" }),
2737
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "italic" }),
2738
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "underline" }),
2739
- /* @__PURE__ */ jsx16(TextStyleButton, { editor, style: "strike" })
3199
+ const TwoRowLayout = () => /* @__PURE__ */ jsxs11(Fragment4, { children: [
3200
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-row", children: [
3201
+ /* @__PURE__ */ jsx18(UndoRedoButtons, { editor }),
3202
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3203
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3204
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "bold" }),
3205
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "italic" }),
3206
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "underline" }),
3207
+ /* @__PURE__ */ jsx18(TextStyleButton, { editor, style: "strike" })
2740
3208
  ] }),
2741
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2742
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2743
- /* @__PURE__ */ jsx16(AlignButton, { editor, alignment: "left" }),
2744
- /* @__PURE__ */ jsx16(AlignButton, { editor, alignment: "center" }),
2745
- /* @__PURE__ */ jsx16(AlignButton, { editor, alignment: "right" })
3209
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3210
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3211
+ /* @__PURE__ */ jsx18(AlignButton, { editor, alignment: "left" }),
3212
+ /* @__PURE__ */ jsx18(AlignButton, { editor, alignment: "center" }),
3213
+ /* @__PURE__ */ jsx18(AlignButton, { editor, alignment: "right" })
2746
3214
  ] }),
2747
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2748
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2749
- /* @__PURE__ */ jsx16(ListButton, { editor, type: "bullet" }),
2750
- /* @__PURE__ */ jsx16(ListButton, { editor, type: "numbered" })
3215
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3216
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3217
+ /* @__PURE__ */ jsx18(ListButton, { editor, type: "bullet" }),
3218
+ /* @__PURE__ */ jsx18(ListButton, { editor, type: "numbered" })
2751
3219
  ] })
2752
3220
  ] }),
2753
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-row", children: [
2754
- /* @__PURE__ */ jsx16("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ jsx16(BlockTypeSelect, { editor }) }),
2755
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2756
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2757
- /* @__PURE__ */ jsx16(ColorButton, { editor, type: "text" }),
2758
- /* @__PURE__ */ jsx16(ColorButton, { editor, type: "background" })
3221
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-row", children: [
3222
+ /* @__PURE__ */ jsx18("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ jsx18(BlockTypeSelect, { editor }) }),
3223
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3224
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3225
+ /* @__PURE__ */ jsx18(FontSizeButton, { editor }),
3226
+ /* @__PURE__ */ jsx18(ColorButton, { editor, type: "text" }),
3227
+ /* @__PURE__ */ jsx18(ColorButton, { editor, type: "background" })
2759
3228
  ] }),
2760
- /* @__PURE__ */ jsx16(ToolbarDivider, {}),
2761
- /* @__PURE__ */ jsxs10("div", { className: "lumir-toolbar-group", children: [
2762
- /* @__PURE__ */ jsx16(ImageButton, { editor, onImageUpload }),
2763
- /* @__PURE__ */ jsx16(LinkButton, { editor }),
2764
- /* @__PURE__ */ jsx16(TableButton, { editor }),
2765
- /* @__PURE__ */ jsx16(HTMLImportButton, { editor })
3229
+ /* @__PURE__ */ jsx18(ToolbarDivider, {}),
3230
+ /* @__PURE__ */ jsxs11("div", { className: "lumir-toolbar-group", children: [
3231
+ /* @__PURE__ */ jsx18(ImageButton, { editor, onImageUpload }),
3232
+ /* @__PURE__ */ jsx18(LinkButton, { editor }),
3233
+ /* @__PURE__ */ jsx18(TableButton, { editor }),
3234
+ /* @__PURE__ */ jsx18(HTMLImportButton, { editor })
2766
3235
  ] })
2767
3236
  ] })
2768
3237
  ] });
2769
- return /* @__PURE__ */ jsx16(
3238
+ return /* @__PURE__ */ jsx18(
2770
3239
  "div",
2771
3240
  {
2772
3241
  ref: wrapperRef,
@@ -2776,7 +3245,7 @@ var FloatingMenu = ({
2776
3245
  className
2777
3246
  ),
2778
3247
  "data-position": position,
2779
- children: /* @__PURE__ */ jsx16(
3248
+ children: /* @__PURE__ */ jsx18(
2780
3249
  "div",
2781
3250
  {
2782
3251
  className: cn(
@@ -2785,7 +3254,7 @@ var FloatingMenu = ({
2785
3254
  isMinimizable && "is-minimizable",
2786
3255
  isMinimized && "is-minimized"
2787
3256
  ),
2788
- children: isMinimizable ? /* @__PURE__ */ jsx16(MinimizedLayout, {}) : isCompact ? /* @__PURE__ */ jsx16(TwoRowLayout, {}) : /* @__PURE__ */ jsx16(SingleRowLayout, {})
3257
+ children: isMinimizable ? /* @__PURE__ */ jsx18(MinimizedLayout, {}) : isCompact ? /* @__PURE__ */ jsx18(TwoRowLayout, {}) : /* @__PURE__ */ jsx18(SingleRowLayout, {})
2789
3258
  }
2790
3259
  )
2791
3260
  }
@@ -2916,60 +3385,634 @@ var VerticalAlignmentExtension = Extension.create({
2916
3385
  }
2917
3386
  });
2918
3387
 
2919
- // src/components/CustomFormattingToolbar.tsx
2920
- import {
2921
- BasicTextStyleButton,
2922
- BlockTypeSelect as BlockTypeSelect2,
2923
- CreateLinkButton,
2924
- FileCaptionButton,
2925
- FileDeleteButton,
2926
- FileRenameButton,
2927
- FileReplaceButton,
2928
- FileDownloadButton,
2929
- FilePreviewButton,
2930
- FormattingToolbar,
2931
- NestBlockButton,
2932
- UnnestBlockButton,
2933
- TableCellMergeButton
2934
- } from "@blocknote/react";
3388
+ // src/extensions/RowHeightExtension.ts
3389
+ import { Extension as Extension2 } from "@tiptap/core";
2935
3390
 
2936
- // src/components/TextAlignButtonWithVA.tsx
2937
- import {
2938
- checkBlockHasDefaultProp,
2939
- checkBlockTypeHasDefaultProp,
2940
- mapTableCell
2941
- } from "@blocknote/core";
2942
- import { useCallback as useCallback14, useMemo } from "react";
2943
- import {
2944
- useComponentsContext,
2945
- useBlockNoteEditor,
2946
- useSelectedBlocks
2947
- } from "@blocknote/react";
2948
- import { jsx as jsx17 } from "react/jsx-runtime";
2949
- var icons = {
2950
- left: /* @__PURE__ */ jsx17("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx17("path", { d: "M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z" }) }),
2951
- center: /* @__PURE__ */ jsx17("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx17("path", { d: "M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z" }) }),
2952
- right: /* @__PURE__ */ jsx17("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx17("path", { d: "M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z" }) }),
2953
- justify: /* @__PURE__ */ jsx17("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx17("path", { d: "M3 21h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18V7H3v2zM3 3v2h18V3H3z" }) })
2954
- };
2955
- var tooltipMap = {
2956
- left: "\uC67C\uCABD \uC815\uB82C",
2957
- center: "\uAC00\uC6B4\uB370 \uC815\uB82C",
2958
- right: "\uC624\uB978\uCABD \uC815\uB82C",
2959
- justify: "\uC591\uCABD \uC815\uB82C"
2960
- };
2961
- var TextAlignButtonWithVA = (props) => {
2962
- const Components = useComponentsContext();
2963
- const editor = useBlockNoteEditor();
2964
- const selectedBlocks = useSelectedBlocks(editor);
2965
- const textAlignment = useMemo(() => {
2966
- const block = selectedBlocks[0];
2967
- if (checkBlockHasDefaultProp("textAlignment", block, editor)) {
2968
- return block.props.textAlignment;
2969
- }
2970
- if (block.type === "table") {
2971
- const cellSelection = editor.tableHandles?.getCellSelection();
2972
- if (!cellSelection) {
3391
+ // src/extensions/rowResizing.ts
3392
+ import { Plugin as Plugin3, PluginKey as PluginKey3 } from "prosemirror-state";
3393
+ import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "prosemirror-view";
3394
+ import { TableMap, cellAround, pointsAtCell } from "prosemirror-tables";
3395
+
3396
+ // src/constants/limits.ts
3397
+ var MAX_FILE_SIZE = 10 * 1024 * 1024;
3398
+ var MAX_VIDEO_FILE_SIZE = 100 * 1024 * 1024;
3399
+ var BLOCKED_EXTENSIONS = [".svg", ".svgz"];
3400
+ var ALLOWED_VIDEO_MIME_TYPES = /* @__PURE__ */ new Set([
3401
+ "video/mp4",
3402
+ "video/webm",
3403
+ "video/ogg",
3404
+ "video/quicktime"
3405
+ // .mov
3406
+ ]);
3407
+ var ALLOWED_VIDEO_EXTENSIONS = [
3408
+ ".mp4",
3409
+ ".webm",
3410
+ ".ogg",
3411
+ ".mov"
3412
+ ];
3413
+ var ROW_RESIZE_MIN_HEIGHT = 24;
3414
+ var ROW_RESIZE_HANDLE_WIDTH = 5;
3415
+
3416
+ // src/extensions/rowResizing.ts
3417
+ var rowResizingPluginKey = new PluginKey3(
3418
+ "lumirRowResizing"
3419
+ );
3420
+ var RowResizeState = class _RowResizeState {
3421
+ constructor(activeHandle, dragging) {
3422
+ this.activeHandle = activeHandle;
3423
+ this.dragging = dragging;
3424
+ }
3425
+ apply(tr) {
3426
+ const action = tr.getMeta(rowResizingPluginKey);
3427
+ if (action && action.setHandle != null) {
3428
+ return new _RowResizeState(action.setHandle, null);
3429
+ }
3430
+ if (action && action.setDragging !== void 0) {
3431
+ return new _RowResizeState(this.activeHandle, action.setDragging);
3432
+ }
3433
+ if (this.activeHandle > -1 && tr.docChanged) {
3434
+ let handle = tr.mapping.map(this.activeHandle, -1);
3435
+ if (!pointsAtCell(tr.doc.resolve(handle))) {
3436
+ handle = -1;
3437
+ }
3438
+ return new _RowResizeState(handle, this.dragging);
3439
+ }
3440
+ return this;
3441
+ }
3442
+ };
3443
+ function rowResizing({
3444
+ handleWidth = ROW_RESIZE_HANDLE_WIDTH,
3445
+ minHeight = ROW_RESIZE_MIN_HEIGHT
3446
+ } = {}) {
3447
+ return new Plugin3({
3448
+ key: rowResizingPluginKey,
3449
+ state: {
3450
+ init() {
3451
+ return new RowResizeState(-1, null);
3452
+ },
3453
+ apply(tr, prev) {
3454
+ return prev.apply(tr);
3455
+ }
3456
+ },
3457
+ props: {
3458
+ attributes: (state) => {
3459
+ const pluginState = rowResizingPluginKey.getState(state);
3460
+ return pluginState && pluginState.activeHandle > -1 ? { class: "row-resize-cursor" } : {};
3461
+ },
3462
+ handleDOMEvents: {
3463
+ mousemove: (view, event) => {
3464
+ handleMouseMove(view, event, handleWidth);
3465
+ },
3466
+ mouseleave: (view) => {
3467
+ handleMouseLeave(view);
3468
+ },
3469
+ mousedown: (view, event) => {
3470
+ handleMouseDown(view, event, minHeight);
3471
+ }
3472
+ },
3473
+ decorations: (state) => {
3474
+ const pluginState = rowResizingPluginKey.getState(state);
3475
+ if (pluginState && pluginState.activeHandle > -1) {
3476
+ return handleDecorations(state, pluginState);
3477
+ }
3478
+ return void 0;
3479
+ }
3480
+ }
3481
+ });
3482
+ }
3483
+ function handleMouseMove(view, event, handleWidth) {
3484
+ if (!view.editable) {
3485
+ return;
3486
+ }
3487
+ const pluginState = rowResizingPluginKey.getState(view.state);
3488
+ if (!pluginState) {
3489
+ return;
3490
+ }
3491
+ if (!pluginState.dragging) {
3492
+ const target = domCellAround(event.target);
3493
+ let cell = -1;
3494
+ if (target) {
3495
+ const { top, bottom } = target.getBoundingClientRect();
3496
+ if (event.clientY - top <= handleWidth) {
3497
+ cell = edgeCell(view, event, "top", handleWidth);
3498
+ } else if (bottom - event.clientY <= handleWidth) {
3499
+ cell = edgeCell(view, event, "bottom", handleWidth);
3500
+ }
3501
+ }
3502
+ if (cell !== pluginState.activeHandle) {
3503
+ updateHandle(view, cell);
3504
+ }
3505
+ }
3506
+ }
3507
+ function handleMouseLeave(view) {
3508
+ if (!view.editable) {
3509
+ return;
3510
+ }
3511
+ const pluginState = rowResizingPluginKey.getState(view.state);
3512
+ if (pluginState && pluginState.activeHandle > -1 && !pluginState.dragging) {
3513
+ updateHandle(view, -1);
3514
+ }
3515
+ }
3516
+ function handleMouseDown(view, event, minHeight) {
3517
+ if (!view.editable) {
3518
+ return false;
3519
+ }
3520
+ const win = view.dom.ownerDocument.defaultView ?? window;
3521
+ const pluginState = rowResizingPluginKey.getState(view.state);
3522
+ if (!pluginState || pluginState.activeHandle === -1 || pluginState.dragging) {
3523
+ return false;
3524
+ }
3525
+ const startHeight = currentRowHeight(view, pluginState.activeHandle);
3526
+ setDragging(view, {
3527
+ startY: event.clientY,
3528
+ startHeight,
3529
+ currentHeight: startHeight
3530
+ });
3531
+ function finish(finishEvent) {
3532
+ win.removeEventListener("mouseup", finish);
3533
+ win.removeEventListener("mousemove", move);
3534
+ const ps = rowResizingPluginKey.getState(view.state);
3535
+ if (ps?.dragging) {
3536
+ const finalHeight = draggedHeight(ps.dragging, finishEvent, minHeight);
3537
+ setDragging(view, null);
3538
+ commitRowHeight(view, ps.activeHandle, finalHeight);
3539
+ }
3540
+ }
3541
+ function move(moveEvent) {
3542
+ if (moveEvent.buttons === 0 || moveEvent.buttons === void 0 && !moveEvent.which) {
3543
+ return finish(moveEvent);
3544
+ }
3545
+ const ps = rowResizingPluginKey.getState(view.state);
3546
+ if (!ps?.dragging) {
3547
+ return;
3548
+ }
3549
+ const h = draggedHeight(ps.dragging, moveEvent, minHeight);
3550
+ if (h !== ps.dragging.currentHeight) {
3551
+ setDragging(view, { ...ps.dragging, currentHeight: h });
3552
+ }
3553
+ }
3554
+ win.addEventListener("mouseup", finish);
3555
+ win.addEventListener("mousemove", move);
3556
+ event.preventDefault();
3557
+ return true;
3558
+ }
3559
+ function setDragging(view, dragging) {
3560
+ view.dispatch(
3561
+ view.state.tr.setMeta(rowResizingPluginKey, { setDragging: dragging })
3562
+ );
3563
+ }
3564
+ function currentRowHeight(view, cellPos) {
3565
+ const info = targetRowInfo(view, cellPos);
3566
+ const tr = rowTrElement(view, cellPos, info.row);
3567
+ return tr ? tr.offsetHeight : ROW_RESIZE_MIN_HEIGHT;
3568
+ }
3569
+ function commitRowHeight(view, cellPos, height) {
3570
+ const { table, map, start, row } = targetRowInfo(view, cellPos);
3571
+ const tr = view.state.tr;
3572
+ const seen = /* @__PURE__ */ new Set();
3573
+ for (let col = 0; col < map.width; col++) {
3574
+ const cellRelPos = map.map[row * map.width + col];
3575
+ if (seen.has(cellRelPos)) {
3576
+ continue;
3577
+ }
3578
+ seen.add(cellRelPos);
3579
+ const rect = map.findCell(cellRelPos);
3580
+ if (rect.bottom - 1 !== row) {
3581
+ continue;
3582
+ }
3583
+ const node = table.nodeAt(cellRelPos);
3584
+ if (!node || node.attrs.rowHeight === height) {
3585
+ continue;
3586
+ }
3587
+ tr.setNodeMarkup(start + cellRelPos, void 0, {
3588
+ ...node.attrs,
3589
+ rowHeight: height
3590
+ });
3591
+ }
3592
+ if (tr.docChanged) {
3593
+ view.dispatch(tr);
3594
+ }
3595
+ }
3596
+ function targetRowInfo(view, cellPos) {
3597
+ const $cell = view.state.doc.resolve(cellPos);
3598
+ const table = $cell.node(-1);
3599
+ const map = TableMap.get(table);
3600
+ const start = $cell.start(-1);
3601
+ const rect = map.findCell($cell.pos - start);
3602
+ return { table, map, start, row: rect.bottom - 1, $cell };
3603
+ }
3604
+ function rowTrElement(view, cellPos, row) {
3605
+ let dom = view.nodeDOM(cellPos);
3606
+ while (dom && dom.nodeName !== "TABLE") {
3607
+ dom = dom.parentNode;
3608
+ }
3609
+ if (!dom) {
3610
+ return null;
3611
+ }
3612
+ return dom.rows[row] ?? null;
3613
+ }
3614
+ function domCellAround(target) {
3615
+ let node = target;
3616
+ while (node && node.nodeName !== "TD" && node.nodeName !== "TH") {
3617
+ node = node.classList?.contains("ProseMirror") ? null : node.parentNode;
3618
+ }
3619
+ return node;
3620
+ }
3621
+ function edgeCell(view, event, side, handleWidth) {
3622
+ const offset2 = side === "bottom" ? -handleWidth : handleWidth;
3623
+ const found = view.posAtCoords({
3624
+ left: event.clientX,
3625
+ top: event.clientY + offset2
3626
+ });
3627
+ if (!found) {
3628
+ return -1;
3629
+ }
3630
+ const $cell = cellAround(view.state.doc.resolve(found.pos));
3631
+ if (!$cell) {
3632
+ return -1;
3633
+ }
3634
+ if (side === "bottom") {
3635
+ return $cell.pos;
3636
+ }
3637
+ const map = TableMap.get($cell.node(-1));
3638
+ const start = $cell.start(-1);
3639
+ const index = map.map.indexOf($cell.pos - start);
3640
+ return index < map.width ? -1 : start + map.map[index - map.width];
3641
+ }
3642
+ function updateHandle(view, value) {
3643
+ view.dispatch(
3644
+ view.state.tr.setMeta(rowResizingPluginKey, { setHandle: value })
3645
+ );
3646
+ }
3647
+ function draggedHeight(dragging, event, minHeight) {
3648
+ const offset2 = event.clientY - dragging.startY;
3649
+ return Math.max(minHeight, dragging.startHeight + offset2);
3650
+ }
3651
+ function handleDecorations(state, pluginState) {
3652
+ const decorations = [];
3653
+ const $cell = state.doc.resolve(pluginState.activeHandle);
3654
+ const table = $cell.node(-1);
3655
+ if (!table) {
3656
+ return DecorationSet2.empty;
3657
+ }
3658
+ const map = TableMap.get(table);
3659
+ const start = $cell.start(-1);
3660
+ const row = map.findCell($cell.pos - start).bottom - 1;
3661
+ const dragging = pluginState.dragging;
3662
+ const seen = /* @__PURE__ */ new Set();
3663
+ for (let col = 0; col < map.width; col++) {
3664
+ const cellRelPos = map.map[row * map.width + col];
3665
+ if (seen.has(cellRelPos)) {
3666
+ continue;
3667
+ }
3668
+ seen.add(cellRelPos);
3669
+ if (map.findCell(cellRelPos).bottom - 1 !== row) {
3670
+ continue;
3671
+ }
3672
+ const node = table.nodeAt(cellRelPos);
3673
+ if (!node) {
3674
+ continue;
3675
+ }
3676
+ const from = start + cellRelPos;
3677
+ const to = from + node.nodeSize;
3678
+ if (dragging) {
3679
+ decorations.push(
3680
+ Decoration2.node(from, to, {
3681
+ class: "row-resize-dragging",
3682
+ style: `height: ${dragging.currentHeight}px`
3683
+ })
3684
+ );
3685
+ }
3686
+ const handle = document.createElement("div");
3687
+ handle.className = "row-resize-handle";
3688
+ decorations.push(Decoration2.widget(to - 1, handle));
3689
+ }
3690
+ return DecorationSet2.create(state.doc, decorations);
3691
+ }
3692
+
3693
+ // src/extensions/tableCellAttrPreserve.ts
3694
+ import { Plugin as Plugin4, PluginKey as PluginKey4 } from "prosemirror-state";
3695
+ var tableCellAttrPreserveKey = new PluginKey4(
3696
+ "lumirTableCellAttrPreserve"
3697
+ );
3698
+ var PRESERVED_ATTRS = [
3699
+ { name: "rowHeight", default: null },
3700
+ { name: "verticalAlignment", default: "top" }
3701
+ ];
3702
+ function isMeaningful(attrName, value, def) {
3703
+ if (value === null || value === void 0) {
3704
+ return false;
3705
+ }
3706
+ return value !== def;
3707
+ }
3708
+ function meaningfulAttrs(node) {
3709
+ let out = null;
3710
+ for (const { name, default: def } of PRESERVED_ATTRS) {
3711
+ const v = node.attrs?.[name];
3712
+ if (isMeaningful(name, v, def)) {
3713
+ (out ?? (out = {}))[name] = v;
3714
+ }
3715
+ }
3716
+ return out;
3717
+ }
3718
+ function collectCellAttrs(doc) {
3719
+ const result = /* @__PURE__ */ new Map();
3720
+ doc.descendants((node) => {
3721
+ if (node.type.name !== "blockContainer") {
3722
+ return void 0;
3723
+ }
3724
+ const id = node.attrs?.id;
3725
+ const table = node.firstChild;
3726
+ if (!id || table?.type.name !== "table") {
3727
+ return void 0;
3728
+ }
3729
+ const cells = /* @__PURE__ */ new Map();
3730
+ let rowIndex = 0;
3731
+ table.forEach((rowNode) => {
3732
+ if (rowNode.type.name === "tableRow") {
3733
+ let cellIndex = 0;
3734
+ rowNode.forEach((cellNode) => {
3735
+ const attrs = meaningfulAttrs(cellNode);
3736
+ if (attrs) {
3737
+ cells.set(`${rowIndex}:${cellIndex}`, attrs);
3738
+ }
3739
+ cellIndex++;
3740
+ });
3741
+ rowIndex++;
3742
+ }
3743
+ });
3744
+ if (cells.size > 0) {
3745
+ result.set(id, cells);
3746
+ }
3747
+ return false;
3748
+ });
3749
+ return result;
3750
+ }
3751
+ function tableCellAttrPreserve() {
3752
+ return new Plugin4({
3753
+ key: tableCellAttrPreserveKey,
3754
+ appendTransaction(transactions, oldState, newState) {
3755
+ if (!transactions.some((tr2) => tr2.docChanged)) {
3756
+ return null;
3757
+ }
3758
+ const oldMap = collectCellAttrs(oldState.doc);
3759
+ if (oldMap.size === 0) {
3760
+ return null;
3761
+ }
3762
+ const tr = newState.tr;
3763
+ let changed = false;
3764
+ let curTableCells = null;
3765
+ let curRowIndex = -1;
3766
+ let curCellIndex = 0;
3767
+ newState.doc.descendants((node, pos) => {
3768
+ const name = node.type.name;
3769
+ if (name === "blockContainer") {
3770
+ const id = node.attrs?.id;
3771
+ const table = node.firstChild;
3772
+ if (id && table?.type.name === "table" && oldMap.has(id)) {
3773
+ curTableCells = oldMap.get(id);
3774
+ curRowIndex = -1;
3775
+ } else {
3776
+ curTableCells = null;
3777
+ }
3778
+ return void 0;
3779
+ }
3780
+ if (!curTableCells) {
3781
+ return void 0;
3782
+ }
3783
+ if (name === "tableRow") {
3784
+ curRowIndex++;
3785
+ curCellIndex = 0;
3786
+ return void 0;
3787
+ }
3788
+ if (name === "tableCell" || name === "tableHeader") {
3789
+ const wanted = curTableCells.get(`${curRowIndex}:${curCellIndex}`);
3790
+ curCellIndex++;
3791
+ if (wanted) {
3792
+ const patch = {};
3793
+ let needs = false;
3794
+ for (const { name: attrName, default: def } of PRESERVED_ATTRS) {
3795
+ if (!(attrName in wanted)) {
3796
+ continue;
3797
+ }
3798
+ const cur = node.attrs?.[attrName];
3799
+ if (cur === null || cur === void 0 || cur === def) {
3800
+ patch[attrName] = wanted[attrName];
3801
+ needs = true;
3802
+ }
3803
+ }
3804
+ if (needs) {
3805
+ tr.setNodeMarkup(pos, void 0, { ...node.attrs, ...patch });
3806
+ changed = true;
3807
+ }
3808
+ }
3809
+ return false;
3810
+ }
3811
+ return void 0;
3812
+ });
3813
+ return changed ? tr : null;
3814
+ }
3815
+ });
3816
+ }
3817
+
3818
+ // src/extensions/RowHeightExtension.ts
3819
+ var RowHeightExtension = Extension2.create({
3820
+ name: "rowHeight",
3821
+ addOptions() {
3822
+ return { resizable: true };
3823
+ },
3824
+ addGlobalAttributes() {
3825
+ return [
3826
+ {
3827
+ types: ["tableCell", "tableHeader"],
3828
+ attributes: {
3829
+ rowHeight: {
3830
+ default: null,
3831
+ parseHTML: (element) => {
3832
+ const fromStyle = parseInt(element.style?.height ?? "", 10);
3833
+ if (Number.isFinite(fromStyle) && fromStyle > 0) {
3834
+ return fromStyle;
3835
+ }
3836
+ const fromAttr = parseInt(
3837
+ element.getAttribute("data-row-height") ?? "",
3838
+ 10
3839
+ );
3840
+ return Number.isFinite(fromAttr) && fromAttr > 0 ? fromAttr : null;
3841
+ },
3842
+ renderHTML: (attributes) => {
3843
+ const h = attributes.rowHeight;
3844
+ if (!h || typeof h !== "number") {
3845
+ return {};
3846
+ }
3847
+ return { style: `height: ${h}px` };
3848
+ }
3849
+ }
3850
+ }
3851
+ }
3852
+ ];
3853
+ },
3854
+ addProseMirrorPlugins() {
3855
+ const plugins = [tableCellAttrPreserve()];
3856
+ if (this.options.resizable) {
3857
+ plugins.push(rowResizing());
3858
+ }
3859
+ return plugins;
3860
+ }
3861
+ });
3862
+
3863
+ // src/extensions/TableAlignmentExtension.ts
3864
+ import { Extension as Extension3 } from "@tiptap/core";
3865
+ import { Plugin as Plugin5, PluginKey as PluginKey5 } from "prosemirror-state";
3866
+ import { Decoration as Decoration3, DecorationSet as DecorationSet3 } from "prosemirror-view";
3867
+ var tableAlignmentDecoKey = new PluginKey5("lumirTableAlignmentDeco");
3868
+ function tableAlignmentDecorationPlugin() {
3869
+ return new Plugin5({
3870
+ key: tableAlignmentDecoKey,
3871
+ props: {
3872
+ decorations(state) {
3873
+ const decorations = [];
3874
+ state.doc.descendants((node, pos) => {
3875
+ if (node.type.name === "table") {
3876
+ const align = node.attrs.tableAlignment;
3877
+ if (align && align !== "left") {
3878
+ decorations.push(
3879
+ Decoration3.node(pos, pos + node.nodeSize, {
3880
+ "data-table-alignment": align
3881
+ })
3882
+ );
3883
+ }
3884
+ return false;
3885
+ }
3886
+ return void 0;
3887
+ });
3888
+ return DecorationSet3.create(state.doc, decorations);
3889
+ }
3890
+ }
3891
+ });
3892
+ }
3893
+ var TableAlignmentExtension = Extension3.create({
3894
+ name: "tableAlignment",
3895
+ addGlobalAttributes() {
3896
+ return [
3897
+ {
3898
+ types: ["table"],
3899
+ attributes: {
3900
+ tableAlignment: {
3901
+ default: "left",
3902
+ parseHTML: (element) => element.getAttribute("data-table-alignment") || "left",
3903
+ renderHTML: (attributes) => {
3904
+ if (!attributes.tableAlignment || attributes.tableAlignment === "left") {
3905
+ return {};
3906
+ }
3907
+ return { "data-table-alignment": attributes.tableAlignment };
3908
+ }
3909
+ }
3910
+ }
3911
+ }
3912
+ ];
3913
+ },
3914
+ addProseMirrorPlugins() {
3915
+ return [tableAlignmentDecorationPlugin()];
3916
+ }
3917
+ });
3918
+
3919
+ // src/blocks/columns/insertColumns.ts
3920
+ import { TextSelection } from "prosemirror-state";
3921
+ function insertTwoColumns(editor) {
3922
+ const tiptap = editor?._tiptapEditor;
3923
+ if (!tiptap) {
3924
+ return false;
3925
+ }
3926
+ const { state, schema: schema2 } = tiptap;
3927
+ const { blockContainer, paragraph, column, columnList } = schema2.nodes;
3928
+ if (!blockContainer || !paragraph || !column || !columnList) {
3929
+ return false;
3930
+ }
3931
+ const $from = state.selection.$from;
3932
+ for (let d = $from.depth; d > 0; d--) {
3933
+ const name = $from.node(d).type.name;
3934
+ if (name === "column" || name === "columnList") {
3935
+ return false;
3936
+ }
3937
+ }
3938
+ let depth = $from.depth;
3939
+ while (depth > 0 && $from.node(depth).type.name !== "blockContainer") {
3940
+ depth--;
3941
+ }
3942
+ if (depth === 0) {
3943
+ return false;
3944
+ }
3945
+ const insertPos = $from.after(depth);
3946
+ const mkBlock = () => blockContainer.create(null, paragraph.create());
3947
+ const mkColumn = () => column.create(null, mkBlock());
3948
+ const list = columnList.create(null, [mkColumn(), mkColumn()]);
3949
+ try {
3950
+ let tr = state.tr.insert(insertPos, list);
3951
+ try {
3952
+ tr = tr.setSelection(TextSelection.create(tr.doc, insertPos + 4));
3953
+ } catch {
3954
+ }
3955
+ tiptap.view.dispatch(tr.scrollIntoView());
3956
+ return true;
3957
+ } catch {
3958
+ return false;
3959
+ }
3960
+ }
3961
+
3962
+ // src/components/CustomFormattingToolbar.tsx
3963
+ import {
3964
+ BasicTextStyleButton,
3965
+ BlockTypeSelect as BlockTypeSelect2,
3966
+ CreateLinkButton,
3967
+ FileCaptionButton,
3968
+ FileDeleteButton,
3969
+ FileRenameButton,
3970
+ FileReplaceButton,
3971
+ FileDownloadButton,
3972
+ FilePreviewButton,
3973
+ FormattingToolbar,
3974
+ NestBlockButton,
3975
+ UnnestBlockButton,
3976
+ TableCellMergeButton
3977
+ } from "@blocknote/react";
3978
+
3979
+ // src/components/TextAlignButtonWithVA.tsx
3980
+ import {
3981
+ checkBlockHasDefaultProp,
3982
+ checkBlockTypeHasDefaultProp,
3983
+ mapTableCell
3984
+ } from "@blocknote/core";
3985
+ import { useCallback as useCallback15, useMemo } from "react";
3986
+ import {
3987
+ useComponentsContext,
3988
+ useBlockNoteEditor,
3989
+ useSelectedBlocks
3990
+ } from "@blocknote/react";
3991
+ import { jsx as jsx19 } from "react/jsx-runtime";
3992
+ var icons = {
3993
+ left: /* @__PURE__ */ jsx19("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx19("path", { d: "M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z" }) }),
3994
+ center: /* @__PURE__ */ jsx19("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx19("path", { d: "M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z" }) }),
3995
+ right: /* @__PURE__ */ jsx19("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx19("path", { d: "M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z" }) }),
3996
+ justify: /* @__PURE__ */ jsx19("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx19("path", { d: "M3 21h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18V7H3v2zM3 3v2h18V3H3z" }) })
3997
+ };
3998
+ var tooltipMap = {
3999
+ left: "\uC67C\uCABD \uC815\uB82C",
4000
+ center: "\uAC00\uC6B4\uB370 \uC815\uB82C",
4001
+ right: "\uC624\uB978\uCABD \uC815\uB82C",
4002
+ justify: "\uC591\uCABD \uC815\uB82C"
4003
+ };
4004
+ var TextAlignButtonWithVA = (props) => {
4005
+ const Components = useComponentsContext();
4006
+ const editor = useBlockNoteEditor();
4007
+ const selectedBlocks = useSelectedBlocks(editor);
4008
+ const textAlignment = useMemo(() => {
4009
+ const block = selectedBlocks[0];
4010
+ if (checkBlockHasDefaultProp("textAlignment", block, editor)) {
4011
+ return block.props.textAlignment;
4012
+ }
4013
+ if (block.type === "table") {
4014
+ const cellSelection = editor.tableHandles?.getCellSelection();
4015
+ if (!cellSelection) {
2973
4016
  return;
2974
4017
  }
2975
4018
  const allCellsInTable = cellSelection.cells.map(
@@ -2984,7 +4027,7 @@ var TextAlignButtonWithVA = (props) => {
2984
4027
  }
2985
4028
  return;
2986
4029
  }, [editor, selectedBlocks]);
2987
- const setTextAlignment = useCallback14(
4030
+ const setTextAlignment = useCallback15(
2988
4031
  (newAlignment) => {
2989
4032
  editor.focus();
2990
4033
  for (const block of selectedBlocks) {
@@ -3022,7 +4065,7 @@ var TextAlignButtonWithVA = (props) => {
3022
4065
  if (!show || !editor.isEditable) {
3023
4066
  return null;
3024
4067
  }
3025
- return /* @__PURE__ */ jsx17(
4068
+ return /* @__PURE__ */ jsx19(
3026
4069
  Components.FormattingToolbar.Button,
3027
4070
  {
3028
4071
  className: "bn-button",
@@ -3037,25 +4080,25 @@ var TextAlignButtonWithVA = (props) => {
3037
4080
  };
3038
4081
 
3039
4082
  // src/components/VerticalAlignButton.tsx
3040
- import { useCallback as useCallback15, useMemo as useMemo2 } from "react";
4083
+ import { useCallback as useCallback16, useMemo as useMemo2 } from "react";
3041
4084
  import {
3042
4085
  useBlockNoteEditor as useBlockNoteEditor2,
3043
4086
  useComponentsContext as useComponentsContext2,
3044
4087
  useSelectedBlocks as useSelectedBlocks2
3045
4088
  } from "@blocknote/react";
3046
- import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
4089
+ import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
3047
4090
  var icons2 = {
3048
- top: /* @__PURE__ */ jsxs11("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
3049
- /* @__PURE__ */ jsx18("rect", { x: "2", y: "2", width: "12", height: "12", rx: "1" }),
3050
- /* @__PURE__ */ jsx18("line", { x1: "5", y1: "5", x2: "11", y2: "5" })
4091
+ top: /* @__PURE__ */ jsxs12("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
4092
+ /* @__PURE__ */ jsx20("rect", { x: "2", y: "2", width: "12", height: "12", rx: "1" }),
4093
+ /* @__PURE__ */ jsx20("line", { x1: "5", y1: "5", x2: "11", y2: "5" })
3051
4094
  ] }),
3052
- middle: /* @__PURE__ */ jsxs11("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
3053
- /* @__PURE__ */ jsx18("rect", { x: "2", y: "2", width: "12", height: "12", rx: "1" }),
3054
- /* @__PURE__ */ jsx18("line", { x1: "5", y1: "8", x2: "11", y2: "8" })
4095
+ middle: /* @__PURE__ */ jsxs12("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
4096
+ /* @__PURE__ */ jsx20("rect", { x: "2", y: "2", width: "12", height: "12", rx: "1" }),
4097
+ /* @__PURE__ */ jsx20("line", { x1: "5", y1: "8", x2: "11", y2: "8" })
3055
4098
  ] }),
3056
- bottom: /* @__PURE__ */ jsxs11("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
3057
- /* @__PURE__ */ jsx18("rect", { x: "2", y: "2", width: "12", height: "12", rx: "1" }),
3058
- /* @__PURE__ */ jsx18("line", { x1: "5", y1: "11", x2: "11", y2: "11" })
4099
+ bottom: /* @__PURE__ */ jsxs12("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
4100
+ /* @__PURE__ */ jsx20("rect", { x: "2", y: "2", width: "12", height: "12", rx: "1" }),
4101
+ /* @__PURE__ */ jsx20("line", { x1: "5", y1: "11", x2: "11", y2: "11" })
3059
4102
  ] })
3060
4103
  };
3061
4104
  var tooltips = {
@@ -3083,7 +4126,7 @@ var VerticalAlignButton = (props) => {
3083
4126
  const currentAlignment = useMemo2(() => {
3084
4127
  return getCurrentVerticalAlignment(editor);
3085
4128
  }, [editor, selectedBlocks]);
3086
- const setVerticalAlignment = useCallback15(
4129
+ const setVerticalAlignment = useCallback16(
3087
4130
  (alignment) => {
3088
4131
  const tiptap = editor._tiptapEditor;
3089
4132
  if (!tiptap) return;
@@ -3105,26 +4148,191 @@ var VerticalAlignButton = (props) => {
3105
4148
  },
3106
4149
  [editor]
3107
4150
  );
3108
- const isInTable = useMemo2(() => {
3109
- return selectedBlocks.some((block) => block.type === "table");
3110
- }, [selectedBlocks]);
3111
- if (!isInTable || !editor.isEditable) {
4151
+ const isInTable = useMemo2(() => {
4152
+ return selectedBlocks.some((block) => block.type === "table");
4153
+ }, [selectedBlocks]);
4154
+ if (!isInTable || !editor.isEditable) {
4155
+ return null;
4156
+ }
4157
+ return /* @__PURE__ */ jsx20(
4158
+ Components.FormattingToolbar.Button,
4159
+ {
4160
+ className: "bn-button",
4161
+ "data-test": `verticalAlign${props.verticalAlignment.charAt(0).toUpperCase() + props.verticalAlignment.slice(1)}`,
4162
+ onClick: () => setVerticalAlignment(props.verticalAlignment),
4163
+ isSelected: currentAlignment === props.verticalAlignment,
4164
+ label: tooltips[props.verticalAlignment],
4165
+ mainTooltip: tooltips[props.verticalAlignment],
4166
+ icon: icons2[props.verticalAlignment]
4167
+ }
4168
+ );
4169
+ };
4170
+
4171
+ // src/components/TableAlignButton.tsx
4172
+ import { useCallback as useCallback17, useMemo as useMemo3 } from "react";
4173
+ import {
4174
+ useBlockNoteEditor as useBlockNoteEditor3,
4175
+ useComponentsContext as useComponentsContext3,
4176
+ useSelectedBlocks as useSelectedBlocks3
4177
+ } from "@blocknote/react";
4178
+ import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
4179
+ var icons3 = {
4180
+ left: /* @__PURE__ */ jsxs13("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
4181
+ /* @__PURE__ */ jsx21("rect", { x: "1.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
4182
+ /* @__PURE__ */ jsx21("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
4183
+ /* @__PURE__ */ jsx21("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
4184
+ ] }),
4185
+ center: /* @__PURE__ */ jsxs13("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
4186
+ /* @__PURE__ */ jsx21("rect", { x: "4.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
4187
+ /* @__PURE__ */ jsx21("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
4188
+ /* @__PURE__ */ jsx21("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
4189
+ ] }),
4190
+ right: /* @__PURE__ */ jsxs13("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
4191
+ /* @__PURE__ */ jsx21("rect", { x: "7.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
4192
+ /* @__PURE__ */ jsx21("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
4193
+ /* @__PURE__ */ jsx21("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
4194
+ ] })
4195
+ };
4196
+ var tooltips2 = {
4197
+ left: "\uD45C \uC67C\uCABD \uC815\uB82C",
4198
+ center: "\uD45C \uAC00\uC6B4\uB370 \uC815\uB82C",
4199
+ right: "\uD45C \uC624\uB978\uCABD \uC815\uB82C"
4200
+ };
4201
+ var TableAlignButton = (props) => {
4202
+ const Components = useComponentsContext3();
4203
+ const editor = useBlockNoteEditor3();
4204
+ const selectedBlocks = useSelectedBlocks3(editor);
4205
+ const tableBlock = useMemo3(
4206
+ () => selectedBlocks.find((block) => block.type === "table"),
4207
+ [selectedBlocks]
4208
+ );
4209
+ const current = useMemo3(() => {
4210
+ if (!tableBlock?.id) return "left";
4211
+ return getTableAlignment(editor, tableBlock.id);
4212
+ }, [editor, tableBlock, selectedBlocks]);
4213
+ const apply = useCallback17(() => {
4214
+ if (!tableBlock?.id) return;
4215
+ editor.focus();
4216
+ setTableAlignment(editor, tableBlock.id, props.alignment);
4217
+ }, [editor, tableBlock, props.alignment]);
4218
+ if (!tableBlock || !editor.isEditable) {
3112
4219
  return null;
3113
4220
  }
3114
- return /* @__PURE__ */ jsx18(
4221
+ return /* @__PURE__ */ jsx21(
3115
4222
  Components.FormattingToolbar.Button,
3116
4223
  {
3117
4224
  className: "bn-button",
3118
- "data-test": `verticalAlign${props.verticalAlignment.charAt(0).toUpperCase() + props.verticalAlignment.slice(1)}`,
3119
- onClick: () => setVerticalAlignment(props.verticalAlignment),
3120
- isSelected: currentAlignment === props.verticalAlignment,
3121
- label: tooltips[props.verticalAlignment],
3122
- mainTooltip: tooltips[props.verticalAlignment],
3123
- icon: icons2[props.verticalAlignment]
4225
+ "data-test": `tableAlign${props.alignment.charAt(0).toUpperCase() + props.alignment.slice(1)}`,
4226
+ onClick: apply,
4227
+ isSelected: current === props.alignment,
4228
+ label: tooltips2[props.alignment],
4229
+ mainTooltip: tooltips2[props.alignment],
4230
+ icon: icons3[props.alignment]
3124
4231
  }
3125
4232
  );
3126
4233
  };
3127
4234
 
4235
+ // src/components/FontSizeButton.tsx
4236
+ import {
4237
+ useBlockNoteEditor as useBlockNoteEditor4,
4238
+ useComponentsContext as useComponentsContext4,
4239
+ useEditorContentOrSelectionChange,
4240
+ useSelectedBlocks as useSelectedBlocks4
4241
+ } from "@blocknote/react";
4242
+ import { useCallback as useCallback18, useMemo as useMemo4, useState as useState9 } from "react";
4243
+ import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
4244
+ var DEFAULT_LABEL2 = "\uAE30\uBCF8";
4245
+ var toLabel2 = (size) => size.replace(/px$/, "");
4246
+ function FontSizeIcon({ size }) {
4247
+ return /* @__PURE__ */ jsx22(
4248
+ "span",
4249
+ {
4250
+ style: {
4251
+ pointerEvents: "none",
4252
+ fontSize: "12px",
4253
+ fontWeight: 600,
4254
+ lineHeight: "20px",
4255
+ whiteSpace: "nowrap"
4256
+ },
4257
+ children: size ? toLabel2(size) : "\uAC00A"
4258
+ }
4259
+ );
4260
+ }
4261
+ function FontSizeButton2() {
4262
+ const Components = useComponentsContext4();
4263
+ const editor = useBlockNoteEditor4();
4264
+ const ed = editor;
4265
+ const styleSchema = editor.schema.styleSchema;
4266
+ const fontSizeInSchema = styleSchema.fontSize?.type === "fontSize" && styleSchema.fontSize?.propSchema === "string";
4267
+ const selectedBlocks = useSelectedBlocks4(editor);
4268
+ const [currentSize, setCurrentSize] = useState9(
4269
+ fontSizeInSchema ? ed.getActiveStyles().fontSize || "" : ""
4270
+ );
4271
+ useEditorContentOrSelectionChange(() => {
4272
+ if (fontSizeInSchema) {
4273
+ setCurrentSize(ed.getActiveStyles().fontSize || "");
4274
+ }
4275
+ }, editor);
4276
+ const setFontSize = useCallback18(
4277
+ (size) => {
4278
+ size === "" ? ed.removeStyles({ fontSize: "" }) : ed.addStyles({ fontSize: size });
4279
+ setTimeout(() => editor.focus());
4280
+ },
4281
+ // eslint-disable-next-line react-hooks/exhaustive-deps
4282
+ [editor]
4283
+ );
4284
+ const show = useMemo4(() => {
4285
+ if (!fontSizeInSchema) {
4286
+ return false;
4287
+ }
4288
+ for (const block of selectedBlocks) {
4289
+ if (block.content !== void 0) {
4290
+ return true;
4291
+ }
4292
+ }
4293
+ return false;
4294
+ }, [fontSizeInSchema, selectedBlocks]);
4295
+ if (!show || !editor.isEditable) {
4296
+ return null;
4297
+ }
4298
+ const tooltip = "\uAE00\uC790 \uD06C\uAE30";
4299
+ return /* @__PURE__ */ jsxs14(Components.Generic.Menu.Root, { children: [
4300
+ /* @__PURE__ */ jsx22(Components.Generic.Menu.Trigger, { children: /* @__PURE__ */ jsx22(
4301
+ Components.FormattingToolbar.Button,
4302
+ {
4303
+ className: "bn-button",
4304
+ "data-test": "font-size",
4305
+ label: tooltip,
4306
+ mainTooltip: tooltip,
4307
+ icon: /* @__PURE__ */ jsx22(FontSizeIcon, { size: currentSize })
4308
+ }
4309
+ ) }),
4310
+ /* @__PURE__ */ jsxs14(Components.Generic.Menu.Dropdown, { className: "bn-menu-dropdown", children: [
4311
+ /* @__PURE__ */ jsx22(Components.Generic.Menu.Label, { children: "\uAE00\uC790 \uD06C\uAE30" }),
4312
+ /* @__PURE__ */ jsx22(
4313
+ Components.Generic.Menu.Item,
4314
+ {
4315
+ onClick: () => setFontSize(""),
4316
+ checked: currentSize === "",
4317
+ "data-test": "font-size-default",
4318
+ children: DEFAULT_LABEL2
4319
+ },
4320
+ "font-size-default"
4321
+ ),
4322
+ FONT_SIZE_PRESETS.map((size) => /* @__PURE__ */ jsx22(
4323
+ Components.Generic.Menu.Item,
4324
+ {
4325
+ onClick: () => setFontSize(size),
4326
+ checked: currentSize === size,
4327
+ "data-test": "font-size-" + toLabel2(size),
4328
+ children: toLabel2(size)
4329
+ },
4330
+ "font-size-" + size
4331
+ ))
4332
+ ] })
4333
+ ] });
4334
+ }
4335
+
3128
4336
  // src/components/color/LumirColorControls.tsx
3129
4337
  import {
3130
4338
  isTableCell,
@@ -3132,14 +4340,14 @@ import {
3132
4340
  } from "@blocknote/core";
3133
4341
  import {
3134
4342
  SplitButton,
3135
- useBlockNoteEditor as useBlockNoteEditor3,
3136
- useComponentsContext as useComponentsContext3,
4343
+ useBlockNoteEditor as useBlockNoteEditor5,
4344
+ useComponentsContext as useComponentsContext5,
3137
4345
  useDictionary,
3138
- useEditorContentOrSelectionChange,
3139
- useSelectedBlocks as useSelectedBlocks3
4346
+ useEditorContentOrSelectionChange as useEditorContentOrSelectionChange2,
4347
+ useSelectedBlocks as useSelectedBlocks5
3140
4348
  } from "@blocknote/react";
3141
- import { useCallback as useCallback16, useMemo as useMemo3, useRef as useRef9, useState as useState8 } from "react";
3142
- import { Fragment as Fragment5, jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
4349
+ import { useCallback as useCallback19, useMemo as useMemo5, useRef as useRef10, useState as useState10 } from "react";
4350
+ import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
3143
4351
  var COLORS = [
3144
4352
  "default",
3145
4353
  "gray",
@@ -3156,7 +4364,7 @@ function ColorIcon(props) {
3156
4364
  const textColor = props.textColor || "default";
3157
4365
  const backgroundColor = props.backgroundColor || "default";
3158
4366
  const size = props.size || 16;
3159
- return /* @__PURE__ */ jsx19(
4367
+ return /* @__PURE__ */ jsx23(
3160
4368
  "div",
3161
4369
  {
3162
4370
  className: "bn-color-icon",
@@ -3175,7 +4383,7 @@ function ColorIcon(props) {
3175
4383
  );
3176
4384
  }
3177
4385
  function CellFillIcon({ size = 18 }) {
3178
- return /* @__PURE__ */ jsx19(
4386
+ return /* @__PURE__ */ jsx23(
3179
4387
  "svg",
3180
4388
  {
3181
4389
  width: size,
@@ -3184,17 +4392,17 @@ function CellFillIcon({ size = 18 }) {
3184
4392
  fill: "currentColor",
3185
4393
  style: { pointerEvents: "none" },
3186
4394
  "aria-hidden": "true",
3187
- children: /* @__PURE__ */ jsx19("path", { d: "M16.56 8.94 7.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 10 10 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" })
4395
+ children: /* @__PURE__ */ jsx23("path", { d: "M16.56 8.94 7.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 10 10 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" })
3188
4396
  }
3189
4397
  );
3190
4398
  }
3191
4399
  function LumirColorPicker(props) {
3192
- const Components = useComponentsContext3();
4400
+ const Components = useComponentsContext5();
3193
4401
  const dict = useDictionary();
3194
- return /* @__PURE__ */ jsxs12(Fragment5, { children: [
3195
- props.text ? /* @__PURE__ */ jsxs12(Fragment5, { children: [
3196
- /* @__PURE__ */ jsx19(Components.Generic.Menu.Label, { children: props.textTitle ?? dict.color_picker.text_title }),
3197
- COLORS.map((color) => /* @__PURE__ */ jsx19(
4402
+ return /* @__PURE__ */ jsxs15(Fragment5, { children: [
4403
+ props.text ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
4404
+ /* @__PURE__ */ jsx23(Components.Generic.Menu.Label, { children: props.textTitle ?? dict.color_picker.text_title }),
4405
+ COLORS.map((color) => /* @__PURE__ */ jsx23(
3198
4406
  Components.Generic.Menu.Item,
3199
4407
  {
3200
4408
  onClick: () => {
@@ -3202,16 +4410,16 @@ function LumirColorPicker(props) {
3202
4410
  props.text.setColor(color);
3203
4411
  },
3204
4412
  "data-test": "text-color-" + color,
3205
- icon: /* @__PURE__ */ jsx19(ColorIcon, { textColor: color, size: props.iconSize }),
4413
+ icon: /* @__PURE__ */ jsx23(ColorIcon, { textColor: color, size: props.iconSize }),
3206
4414
  checked: props.text.color === color,
3207
4415
  children: dict.color_picker.colors[color]
3208
4416
  },
3209
4417
  "text-color-" + color
3210
4418
  ))
3211
4419
  ] }) : null,
3212
- props.background ? /* @__PURE__ */ jsxs12(Fragment5, { children: [
3213
- /* @__PURE__ */ jsx19(Components.Generic.Menu.Label, { children: props.backgroundTitle ?? dict.color_picker.background_title }),
3214
- COLORS.map((color) => /* @__PURE__ */ jsx19(
4420
+ props.background ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
4421
+ /* @__PURE__ */ jsx23(Components.Generic.Menu.Label, { children: props.backgroundTitle ?? dict.color_picker.background_title }),
4422
+ COLORS.map((color) => /* @__PURE__ */ jsx23(
3215
4423
  Components.Generic.Menu.Item,
3216
4424
  {
3217
4425
  onClick: () => {
@@ -3219,7 +4427,7 @@ function LumirColorPicker(props) {
3219
4427
  props.background.setColor(color);
3220
4428
  },
3221
4429
  "data-test": "background-color-" + color,
3222
- icon: /* @__PURE__ */ jsx19(ColorIcon, { backgroundColor: color, size: props.iconSize }),
4430
+ icon: /* @__PURE__ */ jsx23(ColorIcon, { backgroundColor: color, size: props.iconSize }),
3223
4431
  checked: props.background.color === color,
3224
4432
  children: dict.color_picker.colors[color]
3225
4433
  },
@@ -3229,20 +4437,20 @@ function LumirColorPicker(props) {
3229
4437
  ] });
3230
4438
  }
3231
4439
  function LumirColorStyleButton() {
3232
- const Components = useComponentsContext3();
3233
- const editor = useBlockNoteEditor3();
4440
+ const Components = useComponentsContext5();
4441
+ const editor = useBlockNoteEditor5();
3234
4442
  const ed = editor;
3235
4443
  const styleSchema = editor.schema.styleSchema;
3236
4444
  const textColorInSchema = styleSchema.textColor?.type === "textColor" && styleSchema.textColor?.propSchema === "string";
3237
4445
  const backgroundColorInSchema = styleSchema.backgroundColor?.type === "backgroundColor" && styleSchema.backgroundColor?.propSchema === "string";
3238
- const selectedBlocks = useSelectedBlocks3(editor);
3239
- const [currentTextColor, setCurrentTextColor] = useState8(
4446
+ const selectedBlocks = useSelectedBlocks5(editor);
4447
+ const [currentTextColor, setCurrentTextColor] = useState10(
3240
4448
  textColorInSchema ? ed.getActiveStyles().textColor || "default" : "default"
3241
4449
  );
3242
- const [currentBackgroundColor, setCurrentBackgroundColor] = useState8(
4450
+ const [currentBackgroundColor, setCurrentBackgroundColor] = useState10(
3243
4451
  backgroundColorInSchema ? ed.getActiveStyles().backgroundColor || "default" : "default"
3244
4452
  );
3245
- useEditorContentOrSelectionChange(() => {
4453
+ useEditorContentOrSelectionChange2(() => {
3246
4454
  const active = ed.getActiveStyles();
3247
4455
  if (textColorInSchema) {
3248
4456
  setCurrentTextColor(active.textColor || "default");
@@ -3251,7 +4459,7 @@ function LumirColorStyleButton() {
3251
4459
  setCurrentBackgroundColor(active.backgroundColor || "default");
3252
4460
  }
3253
4461
  }, editor);
3254
- const setTextColor = useCallback16(
4462
+ const setTextColor = useCallback19(
3255
4463
  (color) => {
3256
4464
  color === "default" ? ed.removeStyles({ textColor: color }) : ed.addStyles({ textColor: color });
3257
4465
  setTimeout(() => editor.focus());
@@ -3259,7 +4467,7 @@ function LumirColorStyleButton() {
3259
4467
  // eslint-disable-next-line react-hooks/exhaustive-deps
3260
4468
  [editor]
3261
4469
  );
3262
- const setBackgroundColor = useCallback16(
4470
+ const setBackgroundColor = useCallback19(
3263
4471
  (color) => {
3264
4472
  color === "default" ? ed.removeStyles({ backgroundColor: color }) : ed.addStyles({ backgroundColor: color });
3265
4473
  setTimeout(() => editor.focus());
@@ -3267,7 +4475,7 @@ function LumirColorStyleButton() {
3267
4475
  // eslint-disable-next-line react-hooks/exhaustive-deps
3268
4476
  [editor]
3269
4477
  );
3270
- const show = useMemo3(() => {
4478
+ const show = useMemo5(() => {
3271
4479
  if (!textColorInSchema && !backgroundColorInSchema) {
3272
4480
  return false;
3273
4481
  }
@@ -3282,15 +4490,15 @@ function LumirColorStyleButton() {
3282
4490
  return null;
3283
4491
  }
3284
4492
  const tooltip = "\uD14D\uC2A4\uD2B8 \uC0C9\xB7\uBC30\uACBD";
3285
- return /* @__PURE__ */ jsxs12(Components.Generic.Menu.Root, { children: [
3286
- /* @__PURE__ */ jsx19(Components.Generic.Menu.Trigger, { children: /* @__PURE__ */ jsx19(
4493
+ return /* @__PURE__ */ jsxs15(Components.Generic.Menu.Root, { children: [
4494
+ /* @__PURE__ */ jsx23(Components.Generic.Menu.Trigger, { children: /* @__PURE__ */ jsx23(
3287
4495
  Components.FormattingToolbar.Button,
3288
4496
  {
3289
4497
  className: "bn-button",
3290
4498
  "data-test": "colors",
3291
4499
  label: tooltip,
3292
4500
  mainTooltip: tooltip,
3293
- icon: /* @__PURE__ */ jsx19(
4501
+ icon: /* @__PURE__ */ jsx23(
3294
4502
  ColorIcon,
3295
4503
  {
3296
4504
  textColor: currentTextColor,
@@ -3300,11 +4508,11 @@ function LumirColorStyleButton() {
3300
4508
  )
3301
4509
  }
3302
4510
  ) }),
3303
- /* @__PURE__ */ jsx19(
4511
+ /* @__PURE__ */ jsx23(
3304
4512
  Components.Generic.Menu.Dropdown,
3305
4513
  {
3306
4514
  className: "bn-menu-dropdown bn-color-picker-dropdown",
3307
- children: /* @__PURE__ */ jsx19(
4515
+ children: /* @__PURE__ */ jsx23(
3308
4516
  LumirColorPicker,
3309
4517
  {
3310
4518
  textTitle: "\uD14D\uC2A4\uD2B8 \uC0C9",
@@ -3318,18 +4526,18 @@ function LumirColorStyleButton() {
3318
4526
  ] });
3319
4527
  }
3320
4528
  function LumirCellColorToolbarButton() {
3321
- const Components = useComponentsContext3();
3322
- const editor = useBlockNoteEditor3();
3323
- const selectedBlocks = useSelectedBlocks3(editor);
3324
- const isMultiCell = useMemo3(() => {
4529
+ const Components = useComponentsContext5();
4530
+ const editor = useBlockNoteEditor5();
4531
+ const selectedBlocks = useSelectedBlocks5(editor);
4532
+ const isMultiCell = useMemo5(() => {
3325
4533
  if (selectedBlocks.length !== 1 || selectedBlocks[0].type !== "table") {
3326
4534
  return false;
3327
4535
  }
3328
4536
  const cs = editor.tableHandles?.getCellSelection();
3329
4537
  return !!cs && cs.cells.length > 1;
3330
4538
  }, [editor, selectedBlocks]);
3331
- const stashRef = useRef9([]);
3332
- const applyBackground = useCallback16(
4539
+ const stashRef = useRef10([]);
4540
+ const applyBackground = useCallback19(
3333
4541
  (color) => {
3334
4542
  const live = getSelectedCellPositions(editor);
3335
4543
  const positions = live.length > 0 ? live : stashRef.current;
@@ -3342,7 +4550,7 @@ function LumirCellColorToolbarButton() {
3342
4550
  return null;
3343
4551
  }
3344
4552
  const tooltip = "\uC140 \uBC30\uACBD\uC0C9";
3345
- return /* @__PURE__ */ jsxs12(
4553
+ return /* @__PURE__ */ jsxs15(
3346
4554
  Components.Generic.Menu.Root,
3347
4555
  {
3348
4556
  onOpenChange: (open) => {
@@ -3351,21 +4559,21 @@ function LumirCellColorToolbarButton() {
3351
4559
  }
3352
4560
  },
3353
4561
  children: [
3354
- /* @__PURE__ */ jsx19(Components.Generic.Menu.Trigger, { children: /* @__PURE__ */ jsx19(
4562
+ /* @__PURE__ */ jsx23(Components.Generic.Menu.Trigger, { children: /* @__PURE__ */ jsx23(
3355
4563
  Components.FormattingToolbar.Button,
3356
4564
  {
3357
4565
  className: "bn-button",
3358
4566
  "data-test": "cell-colors",
3359
4567
  label: tooltip,
3360
4568
  mainTooltip: tooltip,
3361
- icon: /* @__PURE__ */ jsx19(CellFillIcon, { size: 18 })
4569
+ icon: /* @__PURE__ */ jsx23(CellFillIcon, { size: 18 })
3362
4570
  }
3363
4571
  ) }),
3364
- /* @__PURE__ */ jsx19(
4572
+ /* @__PURE__ */ jsx23(
3365
4573
  Components.Generic.Menu.Dropdown,
3366
4574
  {
3367
4575
  className: "bn-menu-dropdown bn-color-picker-dropdown",
3368
- children: /* @__PURE__ */ jsx19(
4576
+ children: /* @__PURE__ */ jsx23(
3369
4577
  LumirColorPicker,
3370
4578
  {
3371
4579
  backgroundTitle: "\uC140 \uBC30\uACBD",
@@ -3379,8 +4587,8 @@ function LumirCellColorToolbarButton() {
3379
4587
  );
3380
4588
  }
3381
4589
  function LumirCellColorPickerButton(props) {
3382
- const Components = useComponentsContext3();
3383
- const editor = useBlockNoteEditor3();
4590
+ const Components = useComponentsContext5();
4591
+ const editor = useBlockNoteEditor5();
3384
4592
  const updateColor = (color, type) => {
3385
4593
  const newTable = props.block.content.rows.map((row) => ({
3386
4594
  ...row,
@@ -3401,14 +4609,14 @@ function LumirCellColorPickerButton(props) {
3401
4609
  if (!currentCell || editor.settings.tables.cellTextColor === false && editor.settings.tables.cellBackgroundColor === false) {
3402
4610
  return null;
3403
4611
  }
3404
- return /* @__PURE__ */ jsxs12(Components.Generic.Menu.Root, { position: "right", sub: true, children: [
3405
- /* @__PURE__ */ jsx19(Components.Generic.Menu.Trigger, { sub: true, children: /* @__PURE__ */ jsx19(Components.Generic.Menu.Item, { className: "bn-menu-item", subTrigger: true, children: "\uC140 \uC0C9\xB7\uBC30\uACBD" }) }),
3406
- /* @__PURE__ */ jsx19(
4612
+ return /* @__PURE__ */ jsxs15(Components.Generic.Menu.Root, { position: "right", sub: true, children: [
4613
+ /* @__PURE__ */ jsx23(Components.Generic.Menu.Trigger, { sub: true, children: /* @__PURE__ */ jsx23(Components.Generic.Menu.Item, { className: "bn-menu-item", subTrigger: true, children: "\uC140 \uC0C9\xB7\uBC30\uACBD" }) }),
4614
+ /* @__PURE__ */ jsx23(
3407
4615
  Components.Generic.Menu.Dropdown,
3408
4616
  {
3409
4617
  sub: true,
3410
4618
  className: "bn-menu-dropdown bn-color-picker-dropdown",
3411
- children: /* @__PURE__ */ jsx19(
4619
+ children: /* @__PURE__ */ jsx23(
3412
4620
  LumirColorPicker,
3413
4621
  {
3414
4622
  iconSize: 18,
@@ -3429,13 +4637,13 @@ function LumirCellColorPickerButton(props) {
3429
4637
  ] });
3430
4638
  }
3431
4639
  function LumirTableCellMenu(props) {
3432
- const Components = useComponentsContext3();
3433
- return /* @__PURE__ */ jsx19(
4640
+ const Components = useComponentsContext5();
4641
+ return /* @__PURE__ */ jsx23(
3434
4642
  Components.Generic.Menu.Dropdown,
3435
4643
  {
3436
4644
  className: "bn-menu-dropdown bn-drag-handle-menu",
3437
- children: props.children || /* @__PURE__ */ jsxs12(Fragment5, { children: [
3438
- /* @__PURE__ */ jsx19(
4645
+ children: props.children || /* @__PURE__ */ jsxs15(Fragment5, { children: [
4646
+ /* @__PURE__ */ jsx23(
3439
4647
  SplitButton,
3440
4648
  {
3441
4649
  block: props.block,
@@ -3443,7 +4651,7 @@ function LumirTableCellMenu(props) {
3443
4651
  colIndex: props.colIndex
3444
4652
  }
3445
4653
  ),
3446
- /* @__PURE__ */ jsx19(
4654
+ /* @__PURE__ */ jsx23(
3447
4655
  LumirCellColorPickerButton,
3448
4656
  {
3449
4657
  block: props.block,
@@ -3457,74 +4665,144 @@ function LumirTableCellMenu(props) {
3457
4665
  }
3458
4666
 
3459
4667
  // src/components/CustomFormattingToolbar.tsx
3460
- import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
4668
+ import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
3461
4669
  var CustomFormattingToolbar = () => {
3462
- return /* @__PURE__ */ jsxs13(FormattingToolbar, { children: [
3463
- /* @__PURE__ */ jsx20(BlockTypeSelect2, {}, "blockTypeSelect"),
3464
- /* @__PURE__ */ jsx20(TableCellMergeButton, {}, "tableCellMergeButton"),
3465
- /* @__PURE__ */ jsx20(FileCaptionButton, {}, "fileCaptionButton"),
3466
- /* @__PURE__ */ jsx20(FileReplaceButton, {}, "replaceFileButton"),
3467
- /* @__PURE__ */ jsx20(FileRenameButton, {}, "fileRenameButton"),
3468
- /* @__PURE__ */ jsx20(FileDeleteButton, {}, "fileDeleteButton"),
3469
- /* @__PURE__ */ jsx20(FileDownloadButton, {}, "fileDownloadButton"),
3470
- /* @__PURE__ */ jsx20(FilePreviewButton, {}, "filePreviewButton"),
3471
- /* @__PURE__ */ jsx20(BasicTextStyleButton, { basicTextStyle: "bold" }, "boldStyleButton"),
3472
- /* @__PURE__ */ jsx20(
4670
+ return /* @__PURE__ */ jsxs16(FormattingToolbar, { children: [
4671
+ /* @__PURE__ */ jsx24(BlockTypeSelect2, {}, "blockTypeSelect"),
4672
+ /* @__PURE__ */ jsx24(TableCellMergeButton, {}, "tableCellMergeButton"),
4673
+ /* @__PURE__ */ jsx24(FileCaptionButton, {}, "fileCaptionButton"),
4674
+ /* @__PURE__ */ jsx24(FileReplaceButton, {}, "replaceFileButton"),
4675
+ /* @__PURE__ */ jsx24(FileRenameButton, {}, "fileRenameButton"),
4676
+ /* @__PURE__ */ jsx24(FileDeleteButton, {}, "fileDeleteButton"),
4677
+ /* @__PURE__ */ jsx24(FileDownloadButton, {}, "fileDownloadButton"),
4678
+ /* @__PURE__ */ jsx24(FilePreviewButton, {}, "filePreviewButton"),
4679
+ /* @__PURE__ */ jsx24(BasicTextStyleButton, { basicTextStyle: "bold" }, "boldStyleButton"),
4680
+ /* @__PURE__ */ jsx24(
3473
4681
  BasicTextStyleButton,
3474
4682
  {
3475
4683
  basicTextStyle: "italic"
3476
4684
  },
3477
4685
  "italicStyleButton"
3478
4686
  ),
3479
- /* @__PURE__ */ jsx20(
4687
+ /* @__PURE__ */ jsx24(
3480
4688
  BasicTextStyleButton,
3481
4689
  {
3482
4690
  basicTextStyle: "underline"
3483
4691
  },
3484
4692
  "underlineStyleButton"
3485
4693
  ),
3486
- /* @__PURE__ */ jsx20(
4694
+ /* @__PURE__ */ jsx24(
3487
4695
  BasicTextStyleButton,
3488
4696
  {
3489
4697
  basicTextStyle: "strike"
3490
4698
  },
3491
4699
  "strikeStyleButton"
3492
4700
  ),
3493
- /* @__PURE__ */ jsx20(TextAlignButtonWithVA, { textAlignment: "left" }, "textAlignLeftButton"),
3494
- /* @__PURE__ */ jsx20(
4701
+ /* @__PURE__ */ jsx24(TextAlignButtonWithVA, { textAlignment: "left" }, "textAlignLeftButton"),
4702
+ /* @__PURE__ */ jsx24(
3495
4703
  TextAlignButtonWithVA,
3496
4704
  {
3497
4705
  textAlignment: "center"
3498
4706
  },
3499
4707
  "textAlignCenterButton"
3500
4708
  ),
3501
- /* @__PURE__ */ jsx20(TextAlignButtonWithVA, { textAlignment: "right" }, "textAlignRightButton"),
3502
- /* @__PURE__ */ jsx20(
4709
+ /* @__PURE__ */ jsx24(TextAlignButtonWithVA, { textAlignment: "right" }, "textAlignRightButton"),
4710
+ /* @__PURE__ */ jsx24(
3503
4711
  VerticalAlignButton,
3504
4712
  {
3505
4713
  verticalAlignment: "top"
3506
4714
  },
3507
4715
  "verticalAlignTop"
3508
4716
  ),
3509
- /* @__PURE__ */ jsx20(
4717
+ /* @__PURE__ */ jsx24(
3510
4718
  VerticalAlignButton,
3511
4719
  {
3512
4720
  verticalAlignment: "middle"
3513
4721
  },
3514
4722
  "verticalAlignMiddle"
3515
4723
  ),
3516
- /* @__PURE__ */ jsx20(
4724
+ /* @__PURE__ */ jsx24(
3517
4725
  VerticalAlignButton,
3518
4726
  {
3519
4727
  verticalAlignment: "bottom"
3520
4728
  },
3521
4729
  "verticalAlignBottom"
3522
4730
  ),
3523
- /* @__PURE__ */ jsx20(LumirColorStyleButton, {}, "colorStyleButton"),
3524
- /* @__PURE__ */ jsx20(LumirCellColorToolbarButton, {}, "cellColorButton"),
3525
- /* @__PURE__ */ jsx20(NestBlockButton, {}, "nestBlockButton"),
3526
- /* @__PURE__ */ jsx20(UnnestBlockButton, {}, "unnestBlockButton"),
3527
- /* @__PURE__ */ jsx20(CreateLinkButton, {}, "createLinkButton")
4731
+ /* @__PURE__ */ jsx24(TableAlignButton, { alignment: "left" }, "tableAlignLeft"),
4732
+ /* @__PURE__ */ jsx24(TableAlignButton, { alignment: "center" }, "tableAlignCenter"),
4733
+ /* @__PURE__ */ jsx24(TableAlignButton, { alignment: "right" }, "tableAlignRight"),
4734
+ /* @__PURE__ */ jsx24(FontSizeButton2, {}, "fontSizeButton"),
4735
+ /* @__PURE__ */ jsx24(LumirColorStyleButton, {}, "colorStyleButton"),
4736
+ /* @__PURE__ */ jsx24(LumirCellColorToolbarButton, {}, "cellColorButton"),
4737
+ /* @__PURE__ */ jsx24(NestBlockButton, {}, "nestBlockButton"),
4738
+ /* @__PURE__ */ jsx24(UnnestBlockButton, {}, "unnestBlockButton"),
4739
+ /* @__PURE__ */ jsx24(CreateLinkButton, {}, "createLinkButton")
4740
+ ] });
4741
+ };
4742
+
4743
+ // src/components/LumirDragHandleMenu.tsx
4744
+ import {
4745
+ DragHandleMenu,
4746
+ RemoveBlockItem,
4747
+ BlockColorsItem,
4748
+ TableRowHeaderItem,
4749
+ TableColumnHeaderItem,
4750
+ useComponentsContext as useComponentsContext6,
4751
+ useBlockNoteEditor as useBlockNoteEditor6,
4752
+ useDictionary as useDictionary2
4753
+ } from "@blocknote/react";
4754
+ import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
4755
+ var TABLE_ALIGN_ICONS = {
4756
+ left: /* @__PURE__ */ jsxs17("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
4757
+ /* @__PURE__ */ jsx25("rect", { x: "1.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
4758
+ /* @__PURE__ */ jsx25("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
4759
+ /* @__PURE__ */ jsx25("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
4760
+ ] }),
4761
+ center: /* @__PURE__ */ jsxs17("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
4762
+ /* @__PURE__ */ jsx25("rect", { x: "4.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
4763
+ /* @__PURE__ */ jsx25("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
4764
+ /* @__PURE__ */ jsx25("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
4765
+ ] }),
4766
+ right: /* @__PURE__ */ jsxs17("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
4767
+ /* @__PURE__ */ jsx25("rect", { x: "7.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
4768
+ /* @__PURE__ */ jsx25("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
4769
+ /* @__PURE__ */ jsx25("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
4770
+ ] })
4771
+ };
4772
+ var TABLE_ALIGN_LABELS = {
4773
+ left: "\uD45C \uC67C\uCABD \uC815\uB82C",
4774
+ center: "\uD45C \uAC00\uC6B4\uB370 \uC815\uB82C",
4775
+ right: "\uD45C \uC624\uB978\uCABD \uC815\uB82C"
4776
+ };
4777
+ function TableAlignmentItems(props) {
4778
+ const Components = useComponentsContext6();
4779
+ const editor = useBlockNoteEditor6();
4780
+ if (props.block?.type !== "table" || !props.block?.id) {
4781
+ return null;
4782
+ }
4783
+ const current = getTableAlignment(editor, props.block.id);
4784
+ return /* @__PURE__ */ jsx25(Fragment6, { children: ["left", "center", "right"].map((align) => /* @__PURE__ */ jsx25(
4785
+ Components.Generic.Menu.Item,
4786
+ {
4787
+ icon: TABLE_ALIGN_ICONS[align],
4788
+ checked: current === align,
4789
+ onClick: () => {
4790
+ setTableAlignment(editor, props.block.id, align);
4791
+ editor.setTextCursorPosition(props.block.id);
4792
+ },
4793
+ children: TABLE_ALIGN_LABELS[align]
4794
+ },
4795
+ `tableAlign-${align}`
4796
+ )) });
4797
+ }
4798
+ var LumirDragHandleMenu = (props) => {
4799
+ const dict = useDictionary2();
4800
+ return /* @__PURE__ */ jsxs17(DragHandleMenu, { ...props, children: [
4801
+ /* @__PURE__ */ jsx25(RemoveBlockItem, { ...props, children: dict.drag_handle.delete_menuitem }),
4802
+ /* @__PURE__ */ jsx25(BlockColorsItem, { ...props, children: dict.drag_handle.colors_menuitem }),
4803
+ /* @__PURE__ */ jsx25(TableRowHeaderItem, { ...props, children: dict.drag_handle.header_row_menuitem }),
4804
+ /* @__PURE__ */ jsx25(TableColumnHeaderItem, { ...props, children: dict.drag_handle.header_column_menuitem }),
4805
+ /* @__PURE__ */ jsx25(TableAlignmentItems, { block: props.block })
3528
4806
  ] });
3529
4807
  };
3530
4808
 
@@ -3533,13 +4811,13 @@ import {
3533
4811
  ExtendButton,
3534
4812
  TableCellButton,
3535
4813
  TableHandle,
3536
- useBlockNoteEditor as useBlockNoteEditor4,
3537
- useEditorContentOrSelectionChange as useEditorContentOrSelectionChange2,
4814
+ useBlockNoteEditor as useBlockNoteEditor7,
4815
+ useEditorContentOrSelectionChange as useEditorContentOrSelectionChange3,
3538
4816
  useExtendButtonsPositioning,
3539
4817
  useUIPluginState
3540
4818
  } from "@blocknote/react";
3541
4819
  import { autoUpdate as autoUpdate2, FloatingPortal } from "@floating-ui/react";
3542
- import { useCallback as useCallback17, useEffect as useEffect9, useMemo as useMemo5, useRef as useRef10, useState as useState9 } from "react";
4820
+ import { useCallback as useCallback20, useEffect as useEffect10, useMemo as useMemo7, useRef as useRef11, useState as useState11 } from "react";
3543
4821
 
3544
4822
  // src/components/hooks/useFocusedCellHandlePositioning.ts
3545
4823
  import {
@@ -3548,9 +4826,9 @@ import {
3548
4826
  useFloating,
3549
4827
  useTransitionStyles
3550
4828
  } from "@floating-ui/react";
3551
- import { useEffect as useEffect8, useMemo as useMemo4 } from "react";
4829
+ import { useEffect as useEffect9, useMemo as useMemo6 } from "react";
3552
4830
  function useFocusedCellHandlePositioning(cellEl, tbodyEl, orientation, show) {
3553
- const { refs, floatingStyles, context } = useFloating({
4831
+ const { refs, floatingStyles, context, update } = useFloating({
3554
4832
  open: show,
3555
4833
  placement: orientation === "row" ? "left" : orientation === "col" ? "top" : "right",
3556
4834
  // col/row: 가장자리 선(zero-size)에, cell: 셀 우측 보더에 14px hit-area 중앙 정렬(-7).
@@ -3558,7 +4836,15 @@ function useFocusedCellHandlePositioning(cellEl, tbodyEl, orientation, show) {
3558
4836
  whileElementsMounted: autoUpdate
3559
4837
  });
3560
4838
  const { isMounted, styles } = useTransitionStyles(context);
3561
- useEffect8(() => {
4839
+ useEffect9(() => {
4840
+ if (!show || !tbodyEl) {
4841
+ return;
4842
+ }
4843
+ const ro = new ResizeObserver(() => update());
4844
+ ro.observe(tbodyEl);
4845
+ return () => ro.disconnect();
4846
+ }, [show, tbodyEl, update]);
4847
+ useEffect9(() => {
3562
4848
  if (!cellEl) {
3563
4849
  refs.setReference(null);
3564
4850
  return;
@@ -3578,7 +4864,7 @@ function useFocusedCellHandlePositioning(cellEl, tbodyEl, orientation, show) {
3578
4864
  }
3579
4865
  });
3580
4866
  }, [cellEl, tbodyEl, orientation, refs]);
3581
- return useMemo4(
4867
+ return useMemo6(
3582
4868
  () => ({
3583
4869
  isMounted,
3584
4870
  ref: refs.setFloating,
@@ -3593,7 +4879,7 @@ function useFocusedCellHandlePositioning(cellEl, tbodyEl, orientation, show) {
3593
4879
  }
3594
4880
 
3595
4881
  // src/components/LumirTableHandlesController.tsx
3596
- import { Fragment as Fragment6, jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
4882
+ import { Fragment as Fragment7, jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
3597
4883
  function syncCoreHoverToFocusedCell(cellEl) {
3598
4884
  const r = cellEl.getBoundingClientRect();
3599
4885
  cellEl.dispatchEvent(
@@ -3607,15 +4893,15 @@ function syncCoreHoverToFocusedCell(cellEl) {
3607
4893
  );
3608
4894
  }
3609
4895
  function LumirTableHandlesController() {
3610
- const editor = useBlockNoteEditor4();
3611
- const [focused, setFocused] = useState9(null);
3612
- const [menuContainerRef, setMenuContainerRef] = useState9(null);
3613
- const [overlayEl, setOverlayEl] = useState9(null);
3614
- const [openMenu, setOpenMenu] = useState9(null);
3615
- const frozenRef = useRef10(false);
3616
- const menuOpenRef = useRef10(false);
3617
- const draggingRef = useRef10(false);
3618
- const recompute = useCallback17(() => {
4896
+ const editor = useBlockNoteEditor7();
4897
+ const [focused, setFocused] = useState11(null);
4898
+ const [menuContainerRef, setMenuContainerRef] = useState11(null);
4899
+ const [overlayEl, setOverlayEl] = useState11(null);
4900
+ const [openMenu, setOpenMenu] = useState11(null);
4901
+ const frozenRef = useRef11(false);
4902
+ const menuOpenRef = useRef11(false);
4903
+ const draggingRef = useRef11(false);
4904
+ const recompute = useCallback20(() => {
3619
4905
  if (frozenRef.current) {
3620
4906
  return;
3621
4907
  }
@@ -3663,11 +4949,11 @@ function LumirTableHandlesController() {
3663
4949
  widgetContainer
3664
4950
  });
3665
4951
  }, [editor]);
3666
- useEditorContentOrSelectionChange2(recompute, editor);
3667
- useEffect9(() => {
4952
+ useEditorContentOrSelectionChange3(recompute, editor);
4953
+ useEffect10(() => {
3668
4954
  recompute();
3669
4955
  }, [recompute]);
3670
- useEffect9(() => {
4956
+ useEffect10(() => {
3671
4957
  const onUp = () => {
3672
4958
  requestAnimationFrame(() => {
3673
4959
  if (!menuOpenRef.current && !draggingRef.current && frozenRef.current) {
@@ -3679,7 +4965,7 @@ function LumirTableHandlesController() {
3679
4965
  window.addEventListener("pointerup", onUp);
3680
4966
  return () => window.removeEventListener("pointerup", onUp);
3681
4967
  }, [recompute]);
3682
- useEffect9(() => {
4968
+ useEffect10(() => {
3683
4969
  const f = focused;
3684
4970
  if (!f || !overlayEl) {
3685
4971
  return;
@@ -3704,7 +4990,13 @@ function LumirTableHandlesController() {
3704
4990
  overlayEl.style.height = `${bottom - top}px`;
3705
4991
  };
3706
4992
  update();
3707
- return autoUpdate2(f.cellEl, overlayEl, update);
4993
+ const stopAutoUpdate = autoUpdate2(f.cellEl, overlayEl, update);
4994
+ const ro = new ResizeObserver(update);
4995
+ ro.observe(f.tbodyEl);
4996
+ return () => {
4997
+ stopAutoUpdate();
4998
+ ro.disconnect();
4999
+ };
3708
5000
  }, [focused, overlayEl, openMenu]);
3709
5001
  const cellEl = focused?.cellEl ?? null;
3710
5002
  const tbodyEl = focused?.tbodyEl ?? null;
@@ -3726,13 +5018,13 @@ function LumirTableHandlesController() {
3726
5018
  coreState?.showAddOrRemoveRowsButton || false,
3727
5019
  coreState?.referencePosTable || null
3728
5020
  );
3729
- const onStartExtend = useCallback17(() => {
5021
+ const onStartExtend = useCallback20(() => {
3730
5022
  editor.tableHandles?.freezeHandles();
3731
5023
  }, [editor]);
3732
- const onEndExtend = useCallback17(() => {
5024
+ const onEndExtend = useCallback20(() => {
3733
5025
  editor.tableHandles?.unfreezeHandles();
3734
5026
  }, [editor]);
3735
- const menuHandlers = useMemo5(() => {
5027
+ const menuHandlers = useMemo7(() => {
3736
5028
  const mk = (kind) => ({
3737
5029
  freeze: () => {
3738
5030
  menuOpenRef.current = true;
@@ -3750,10 +5042,10 @@ function LumirTableHandlesController() {
3750
5042
  });
3751
5043
  return { col: mk("col"), row: mk("row"), cell: mk("cell") };
3752
5044
  }, [editor, recompute]);
3753
- const onGutterPointerDown = useCallback17(() => {
5045
+ const onGutterPointerDown = useCallback20(() => {
3754
5046
  frozenRef.current = true;
3755
5047
  }, []);
3756
- const onGutterPointerEnter = useCallback17(
5048
+ const onGutterPointerEnter = useCallback20(
3757
5049
  (e) => {
3758
5050
  if (e.buttons === 0 && focused) {
3759
5051
  syncCoreHoverToFocusedCell(focused.cellEl);
@@ -3761,7 +5053,7 @@ function LumirTableHandlesController() {
3761
5053
  },
3762
5054
  [focused]
3763
5055
  );
3764
- const makeDragStart = useCallback17(
5056
+ const makeDragStart = useCallback20(
3765
5057
  (dir) => (e) => {
3766
5058
  draggingRef.current = true;
3767
5059
  frozenRef.current = true;
@@ -3773,19 +5065,19 @@ function LumirTableHandlesController() {
3773
5065
  },
3774
5066
  [editor]
3775
5067
  );
3776
- const onDragEnd = useCallback17(() => {
5068
+ const onDragEnd = useCallback20(() => {
3777
5069
  editor.tableHandles?.dragEnd();
3778
5070
  draggingRef.current = false;
3779
5071
  frozenRef.current = false;
3780
5072
  recompute();
3781
5073
  }, [editor, recompute]);
3782
- const noop = useCallback17(() => {
5074
+ const noop = useCallback20(() => {
3783
5075
  }, []);
3784
- return /* @__PURE__ */ jsxs14(Fragment6, { children: [
3785
- /* @__PURE__ */ jsx21("div", { ref: setMenuContainerRef }),
3786
- th && focused && menuContainerRef && /* @__PURE__ */ jsxs14(FloatingPortal, { root: focused.widgetContainer, children: [
3787
- /* @__PURE__ */ jsx21("div", { ref: setOverlayEl, className: "lumir-tbl-cell-focus" }),
3788
- colHandle.isMounted && /* @__PURE__ */ jsxs14(
5076
+ return /* @__PURE__ */ jsxs18(Fragment7, { children: [
5077
+ /* @__PURE__ */ jsx26("div", { ref: setMenuContainerRef }),
5078
+ th && focused && menuContainerRef && /* @__PURE__ */ jsxs18(FloatingPortal, { root: focused.widgetContainer, children: [
5079
+ /* @__PURE__ */ jsx26("div", { ref: setOverlayEl, className: "lumir-tbl-cell-focus" }),
5080
+ colHandle.isMounted && /* @__PURE__ */ jsxs18(
3789
5081
  "div",
3790
5082
  {
3791
5083
  ref: colHandle.ref,
@@ -3794,8 +5086,8 @@ function LumirTableHandlesController() {
3794
5086
  onPointerEnter: onGutterPointerEnter,
3795
5087
  onPointerDown: onGutterPointerDown,
3796
5088
  children: [
3797
- /* @__PURE__ */ jsx21("span", { className: "lumir-tbl-gutter" }),
3798
- /* @__PURE__ */ jsx21("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ jsx21(
5089
+ /* @__PURE__ */ jsx26("span", { className: "lumir-tbl-gutter" }),
5090
+ /* @__PURE__ */ jsx26("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ jsx26(
3799
5091
  TableHandle,
3800
5092
  {
3801
5093
  editor,
@@ -3814,7 +5106,7 @@ function LumirTableHandlesController() {
3814
5106
  ]
3815
5107
  }
3816
5108
  ),
3817
- rowHandle.isMounted && /* @__PURE__ */ jsxs14(
5109
+ rowHandle.isMounted && /* @__PURE__ */ jsxs18(
3818
5110
  "div",
3819
5111
  {
3820
5112
  ref: rowHandle.ref,
@@ -3823,8 +5115,8 @@ function LumirTableHandlesController() {
3823
5115
  onPointerEnter: onGutterPointerEnter,
3824
5116
  onPointerDown: onGutterPointerDown,
3825
5117
  children: [
3826
- /* @__PURE__ */ jsx21("span", { className: "lumir-tbl-gutter" }),
3827
- /* @__PURE__ */ jsx21("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ jsx21(
5118
+ /* @__PURE__ */ jsx26("span", { className: "lumir-tbl-gutter" }),
5119
+ /* @__PURE__ */ jsx26("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ jsx26(
3828
5120
  TableHandle,
3829
5121
  {
3830
5122
  editor,
@@ -3843,7 +5135,7 @@ function LumirTableHandlesController() {
3843
5135
  ]
3844
5136
  }
3845
5137
  ),
3846
- cellHandle.isMounted && openMenu !== "col" && openMenu !== "row" && /* @__PURE__ */ jsxs14(
5138
+ cellHandle.isMounted && openMenu !== "col" && openMenu !== "row" && /* @__PURE__ */ jsxs18(
3847
5139
  "div",
3848
5140
  {
3849
5141
  ref: cellHandle.ref,
@@ -3851,8 +5143,8 @@ function LumirTableHandlesController() {
3851
5143
  className: "lumir-tbl-gutter-wrap lumir-tbl-gutter-wrap--cell" + (openMenu === "cell" ? " lumir-tbl-gutter-wrap--active" : ""),
3852
5144
  onPointerDown: onGutterPointerDown,
3853
5145
  children: [
3854
- /* @__PURE__ */ jsx21("span", { className: "lumir-tbl-gutter" }),
3855
- /* @__PURE__ */ jsx21("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ jsx21(
5146
+ /* @__PURE__ */ jsx26("span", { className: "lumir-tbl-gutter" }),
5147
+ /* @__PURE__ */ jsx26("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ jsx26(
3856
5148
  TableCellButton,
3857
5149
  {
3858
5150
  editor,
@@ -3869,8 +5161,8 @@ function LumirTableHandlesController() {
3869
5161
  }
3870
5162
  )
3871
5163
  ] }),
3872
- th && coreState?.widgetContainer && /* @__PURE__ */ jsxs14(FloatingPortal, { root: coreState.widgetContainer, children: [
3873
- /* @__PURE__ */ jsx21("div", { ref: addOrRemoveRowsButton.ref, style: addOrRemoveRowsButton.style, children: /* @__PURE__ */ jsx21(
5164
+ th && coreState?.widgetContainer && /* @__PURE__ */ jsxs18(FloatingPortal, { root: coreState.widgetContainer, children: [
5165
+ /* @__PURE__ */ jsx26("div", { ref: addOrRemoveRowsButton.ref, style: addOrRemoveRowsButton.style, children: /* @__PURE__ */ jsx26(
3874
5166
  ExtendButton,
3875
5167
  {
3876
5168
  editor,
@@ -3880,12 +5172,12 @@ function LumirTableHandlesController() {
3880
5172
  onMouseUp: onEndExtend
3881
5173
  }
3882
5174
  ) }),
3883
- /* @__PURE__ */ jsx21(
5175
+ /* @__PURE__ */ jsx26(
3884
5176
  "div",
3885
5177
  {
3886
5178
  ref: addOrRemoveColumnsButton.ref,
3887
5179
  style: addOrRemoveColumnsButton.style,
3888
- children: /* @__PURE__ */ jsx21(
5180
+ children: /* @__PURE__ */ jsx26(
3889
5181
  ExtendButton,
3890
5182
  {
3891
5183
  editor,
@@ -3902,15 +5194,17 @@ function LumirTableHandlesController() {
3902
5194
  }
3903
5195
 
3904
5196
  // src/utils/table-vertical-alignment.ts
3905
- function injectVerticalAlignment(blocks, editor) {
3906
- const tiptap = editor?._tiptapEditor;
3907
- if (!tiptap) return blocks;
3908
- const { doc } = tiptap.state;
3909
- const tableVAMap = buildTableVerticalAlignmentMap(doc);
3910
- if (tableVAMap.size === 0) return blocks;
3911
- return patchBlocks(blocks, tableVAMap);
5197
+ var CELL_ATTR_DEFAULTS = {
5198
+ verticalAlignment: "top",
5199
+ rowHeight: null
5200
+ };
5201
+ function isMeaningful2(attr, value) {
5202
+ if (value === null || value === void 0) {
5203
+ return false;
5204
+ }
5205
+ return value !== CELL_ATTR_DEFAULTS[attr];
3912
5206
  }
3913
- function buildTableVerticalAlignmentMap(doc) {
5207
+ function buildTableCellAttrMap(doc, attrs) {
3914
5208
  const result = /* @__PURE__ */ new Map();
3915
5209
  doc.descendants((node) => {
3916
5210
  if (node.type.name === "blockContainer") {
@@ -3923,9 +5217,15 @@ function buildTableVerticalAlignmentMap(doc) {
3923
5217
  if (rowNode.type.name === "tableRow") {
3924
5218
  let colIndex = 0;
3925
5219
  rowNode.forEach((cellNode) => {
3926
- const va = cellNode.attrs?.verticalAlignment;
3927
- if (va && va !== "top") {
3928
- cells.push({ row: rowIndex, col: colIndex, va });
5220
+ const props = {};
5221
+ for (const attr of attrs) {
5222
+ const value = cellNode.attrs?.[attr];
5223
+ if (isMeaningful2(attr, value)) {
5224
+ props[attr] = value;
5225
+ }
5226
+ }
5227
+ if (Object.keys(props).length > 0) {
5228
+ cells.push({ row: rowIndex, col: colIndex, props });
3929
5229
  }
3930
5230
  colIndex++;
3931
5231
  });
@@ -3941,18 +5241,21 @@ function buildTableVerticalAlignmentMap(doc) {
3941
5241
  });
3942
5242
  return result;
3943
5243
  }
3944
- function patchBlocks(blocks, tableVAMap) {
5244
+ function patchBlocks(blocks, cellAttrMap) {
3945
5245
  return blocks.map((block) => {
3946
5246
  if (block.type !== "table" || !block.id || !block.content) {
3947
5247
  if (block.children && block.children.length > 0) {
3948
5248
  return {
3949
5249
  ...block,
3950
- children: patchBlocks(block.children, tableVAMap)
5250
+ children: patchBlocks(
5251
+ block.children,
5252
+ cellAttrMap
5253
+ )
3951
5254
  };
3952
5255
  }
3953
5256
  return block;
3954
5257
  }
3955
- const cells = tableVAMap.get(block.id);
5258
+ const cells = cellAttrMap.get(block.id);
3956
5259
  if (!cells || cells.length === 0) {
3957
5260
  return block;
3958
5261
  }
@@ -3965,11 +5268,13 @@ function patchBlocks(blocks, tableVAMap) {
3965
5268
  const match = cells.find(
3966
5269
  (c) => c.row === rowIndex && c.col === colIndex
3967
5270
  );
3968
- if (!match) return cell;
5271
+ if (!match) {
5272
+ return cell;
5273
+ }
3969
5274
  if (cell && typeof cell === "object" && cell.type === "tableCell") {
3970
5275
  return {
3971
5276
  ...cell,
3972
- props: { ...cell.props, verticalAlignment: match.va }
5277
+ props: { ...cell.props, ...match.props }
3973
5278
  };
3974
5279
  }
3975
5280
  return cell;
@@ -3982,6 +5287,161 @@ function patchBlocks(blocks, tableVAMap) {
3982
5287
  };
3983
5288
  });
3984
5289
  }
5290
+ function injectTableCellAttrs(blocks, editor, attrs) {
5291
+ const tiptap = editor?._tiptapEditor;
5292
+ if (!tiptap) {
5293
+ return blocks;
5294
+ }
5295
+ const { doc } = tiptap.state;
5296
+ const cellAttrMap = buildTableCellAttrMap(doc, attrs);
5297
+ if (cellAttrMap.size === 0) {
5298
+ return blocks;
5299
+ }
5300
+ return patchBlocks(blocks, cellAttrMap);
5301
+ }
5302
+ var TABLE_BLOCK_ATTR_DEFAULTS = {
5303
+ tableAlignment: "left"
5304
+ };
5305
+ function buildTableBlockAttrMap(doc, attrs) {
5306
+ const result = /* @__PURE__ */ new Map();
5307
+ doc.descendants((node) => {
5308
+ if (node.type.name === "blockContainer") {
5309
+ const blockId = node.attrs?.id;
5310
+ const contentNode = node.firstChild;
5311
+ if (blockId && contentNode?.type.name === "table") {
5312
+ const props = {};
5313
+ for (const attr of attrs) {
5314
+ const value = contentNode.attrs?.[attr];
5315
+ if (value !== null && value !== void 0 && value !== TABLE_BLOCK_ATTR_DEFAULTS[attr]) {
5316
+ props[attr] = value;
5317
+ }
5318
+ }
5319
+ if (Object.keys(props).length > 0) {
5320
+ result.set(blockId, props);
5321
+ }
5322
+ }
5323
+ return false;
5324
+ }
5325
+ return void 0;
5326
+ });
5327
+ return result;
5328
+ }
5329
+ function patchTableBlockProps(blocks, attrMap) {
5330
+ return blocks.map((block) => {
5331
+ if (block.type === "table" && block.id && attrMap.has(block.id)) {
5332
+ return {
5333
+ ...block,
5334
+ props: { ...block.props, ...attrMap.get(block.id) }
5335
+ };
5336
+ }
5337
+ if (block.children && block.children.length > 0) {
5338
+ return {
5339
+ ...block,
5340
+ children: patchTableBlockProps(
5341
+ block.children,
5342
+ attrMap
5343
+ )
5344
+ };
5345
+ }
5346
+ return block;
5347
+ });
5348
+ }
5349
+ function injectTableBlockAttrs(blocks, editor) {
5350
+ const tiptap = editor?._tiptapEditor;
5351
+ if (!tiptap) {
5352
+ return blocks;
5353
+ }
5354
+ const { doc } = tiptap.state;
5355
+ const attrMap = buildTableBlockAttrMap(doc, ["tableAlignment"]);
5356
+ if (attrMap.size === 0) {
5357
+ return blocks;
5358
+ }
5359
+ return patchTableBlockProps(blocks, attrMap);
5360
+ }
5361
+
5362
+ // src/utils/font-size-serialization.ts
5363
+ function mapPreservingRef(arr, fn) {
5364
+ let changed = false;
5365
+ const next = arr.map((item) => {
5366
+ const mapped = fn(item);
5367
+ if (mapped !== item) changed = true;
5368
+ return mapped;
5369
+ });
5370
+ return changed ? next : arr;
5371
+ }
5372
+ function mapStyledItem(item, dir) {
5373
+ if (!item || typeof item !== "object" || item.type !== "text") {
5374
+ return item;
5375
+ }
5376
+ if (dir === "lower") {
5377
+ const fs2 = item.styles?.fontSize;
5378
+ if (fs2 == null) return item;
5379
+ const { fontSize: _removed, ...restStyles } = item.styles;
5380
+ return { ...item, styles: restStyles, fontSize: fs2 };
5381
+ }
5382
+ const fs = item.fontSize;
5383
+ if (fs == null) return item;
5384
+ const { fontSize: _lifted, ...rest } = item;
5385
+ return { ...rest, styles: { ...item.styles ?? {}, fontSize: fs } };
5386
+ }
5387
+ function mapInlineItem(node, dir) {
5388
+ if (!node || typeof node !== "object") return node;
5389
+ if (node.type === "link" && Array.isArray(node.content)) {
5390
+ const content = mapPreservingRef(
5391
+ node.content,
5392
+ (n) => mapStyledItem(n, dir)
5393
+ );
5394
+ return content === node.content ? node : { ...node, content };
5395
+ }
5396
+ return mapStyledItem(node, dir);
5397
+ }
5398
+ function mapCell(cell, dir) {
5399
+ if (cell && typeof cell === "object" && cell.type === "tableCell") {
5400
+ if (!Array.isArray(cell.content)) return cell;
5401
+ const content = mapPreservingRef(
5402
+ cell.content,
5403
+ (n) => mapInlineItem(n, dir)
5404
+ );
5405
+ return content === cell.content ? cell : { ...cell, content };
5406
+ }
5407
+ if (Array.isArray(cell)) {
5408
+ return mapPreservingRef(cell, (n) => mapInlineItem(n, dir));
5409
+ }
5410
+ return cell;
5411
+ }
5412
+ function mapBlock(block, dir) {
5413
+ if (!block || typeof block !== "object") return block;
5414
+ let next = block;
5415
+ const content = block.content;
5416
+ if (Array.isArray(content)) {
5417
+ const mapped = mapPreservingRef(content, (n) => mapInlineItem(n, dir));
5418
+ if (mapped !== content) next = { ...next, content: mapped };
5419
+ } else if (content && typeof content === "object" && content.type === "tableContent" && Array.isArray(content.rows)) {
5420
+ const rows = mapPreservingRef(content.rows, (row) => {
5421
+ if (!row || !Array.isArray(row.cells)) return row;
5422
+ const cells = mapPreservingRef(
5423
+ row.cells,
5424
+ (cell) => mapCell(cell, dir)
5425
+ );
5426
+ return cells === row.cells ? row : { ...row, cells };
5427
+ });
5428
+ if (rows !== content.rows) next = { ...next, content: { ...content, rows } };
5429
+ }
5430
+ if (Array.isArray(block.children) && block.children.length > 0) {
5431
+ const children = mapPreservingRef(
5432
+ block.children,
5433
+ (b) => mapBlock(b, dir)
5434
+ );
5435
+ if (children !== block.children) next = { ...next, children };
5436
+ }
5437
+ return next;
5438
+ }
5439
+ function lowerFontSize(blocks) {
5440
+ return mapPreservingRef(blocks, (b) => mapBlock(b, "lower"));
5441
+ }
5442
+ function liftFontSize(blocks) {
5443
+ return mapPreservingRef(blocks, (b) => mapBlock(b, "lift"));
5444
+ }
3985
5445
 
3986
5446
  // src/utils/excel-paste.ts
3987
5447
  var NAMED_COLORS = {
@@ -4212,26 +5672,8 @@ function normalizeExcelTableHtml(html) {
4212
5672
  }
4213
5673
  }
4214
5674
 
4215
- // src/constants/limits.ts
4216
- var MAX_FILE_SIZE = 10 * 1024 * 1024;
4217
- var MAX_VIDEO_FILE_SIZE = 100 * 1024 * 1024;
4218
- var BLOCKED_EXTENSIONS = [".svg", ".svgz"];
4219
- var ALLOWED_VIDEO_MIME_TYPES = /* @__PURE__ */ new Set([
4220
- "video/mp4",
4221
- "video/webm",
4222
- "video/ogg",
4223
- "video/quicktime"
4224
- // .mov
4225
- ]);
4226
- var ALLOWED_VIDEO_EXTENSIONS = [
4227
- ".mp4",
4228
- ".webm",
4229
- ".ogg",
4230
- ".mov"
4231
- ];
4232
-
4233
5675
  // src/components/LumirEditor.tsx
4234
- import { Fragment as Fragment7, jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
5676
+ import { Fragment as Fragment8, jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
4235
5677
  var DEBUG_LOG = (loc, msg, data) => {
4236
5678
  const p = fetch("http://127.0.0.1:7686/ingest/1f8ee1c5-0cf0-4ae7-91ed-5ea7ed17130a", {
4237
5679
  method: "POST",
@@ -4396,6 +5838,12 @@ var isVideoFile = (file, maxSize) => {
4396
5838
  });
4397
5839
  return result;
4398
5840
  };
5841
+ var isSuppressiblePopupSelection = (editor, selection) => {
5842
+ if (!selection) return false;
5843
+ if (selection.node) return false;
5844
+ if (isInTableCell(editor)) return false;
5845
+ return true;
5846
+ };
4399
5847
  var isHtmlFile = (file) => {
4400
5848
  return file.size > 0 && (file.type === "text/html" || file.name?.toLowerCase().endsWith(".html") || file.name?.toLowerCase().endsWith(".htm"));
4401
5849
  };
@@ -4456,9 +5904,9 @@ var findBlockWithLink = (blocks, targetUrl) => {
4456
5904
  return null;
4457
5905
  };
4458
5906
  var ConvertToPreviewButton = ({ url }) => {
4459
- const editor = useBlockNoteEditor5();
4460
- const Components = useComponentsContext4();
4461
- return /* @__PURE__ */ jsx22(
5907
+ const editor = useBlockNoteEditor8();
5908
+ const Components = useComponentsContext7();
5909
+ return /* @__PURE__ */ jsx27(
4462
5910
  Components.LinkToolbar.Button,
4463
5911
  {
4464
5912
  className: "bn-button",
@@ -4477,29 +5925,29 @@ var ConvertToPreviewButton = ({ url }) => {
4477
5925
  console.error("Convert to link preview failed:", err);
4478
5926
  }
4479
5927
  },
4480
- icon: /* @__PURE__ */ jsxs15("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
4481
- /* @__PURE__ */ jsx22("rect", { x: "1", y: "3", width: "14", height: "10", rx: "2", stroke: "currentColor", strokeWidth: "1.5", fill: "none" }),
4482
- /* @__PURE__ */ jsx22("line", { x1: "1", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "1.5" }),
4483
- /* @__PURE__ */ jsx22("circle", { cx: "5", cy: "6.5", r: "1.5", stroke: "currentColor", strokeWidth: "1", fill: "none" })
5928
+ icon: /* @__PURE__ */ jsxs19("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
5929
+ /* @__PURE__ */ jsx27("rect", { x: "1", y: "3", width: "14", height: "10", rx: "2", stroke: "currentColor", strokeWidth: "1.5", fill: "none" }),
5930
+ /* @__PURE__ */ jsx27("line", { x1: "1", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "1.5" }),
5931
+ /* @__PURE__ */ jsx27("circle", { cx: "5", cy: "6.5", r: "1.5", stroke: "currentColor", strokeWidth: "1", fill: "none" })
4484
5932
  ] })
4485
5933
  }
4486
5934
  );
4487
5935
  };
4488
5936
  var CustomLinkToolbar = (props) => {
4489
- const editor = useBlockNoteEditor5();
4490
- const Components = useComponentsContext4();
5937
+ const editor = useBlockNoteEditor8();
5938
+ const Components = useComponentsContext7();
4491
5939
  const hasLinkPreview = !!editor?._linkPreviewApiEndpoint;
4492
- return /* @__PURE__ */ jsxs15(
5940
+ return /* @__PURE__ */ jsxs19(
4493
5941
  Components.LinkToolbar.Root,
4494
5942
  {
4495
5943
  className: "bn-toolbar bn-link-toolbar",
4496
5944
  onMouseEnter: props.stopHideTimer,
4497
5945
  onMouseLeave: props.startHideTimer,
4498
5946
  children: [
4499
- /* @__PURE__ */ jsx22(EditLinkButton, { url: props.url, text: props.text, editLink: props.editLink }),
4500
- /* @__PURE__ */ jsx22(OpenLinkButton, { url: props.url }),
4501
- /* @__PURE__ */ jsx22(DeleteLinkButton, { deleteLink: props.deleteLink }),
4502
- hasLinkPreview && /* @__PURE__ */ jsx22(ConvertToPreviewButton, { url: props.url })
5947
+ /* @__PURE__ */ jsx27(EditLinkButton, { url: props.url, text: props.text, editLink: props.editLink }),
5948
+ /* @__PURE__ */ jsx27(OpenLinkButton, { url: props.url }),
5949
+ /* @__PURE__ */ jsx27(DeleteLinkButton, { deleteLink: props.deleteLink }),
5950
+ hasLinkPreview && /* @__PURE__ */ jsx27(ConvertToPreviewButton, { url: props.url })
4503
5951
  ]
4504
5952
  }
4505
5953
  );
@@ -4543,13 +5991,13 @@ function LumirEditor({
4543
5991
  onError,
4544
5992
  onImageDelete
4545
5993
  }) {
4546
- const [isUploading, setIsUploading] = useState10(false);
4547
- const [uploadProgress, setUploadProgress] = useState10(null);
4548
- const [errorMessage, setErrorMessage] = useState10(null);
4549
- const floatingMenuFileInputRef = useRef11(null);
4550
- const floatingMenuBlockRef = useRef11(null);
4551
- const floatingMenuUploadStartTimeRef = useRef11(0);
4552
- const handleError = useCallback18(
5994
+ const [isUploading, setIsUploading] = useState12(false);
5995
+ const [uploadProgress, setUploadProgress] = useState12(null);
5996
+ const [errorMessage, setErrorMessage] = useState12(null);
5997
+ const floatingMenuFileInputRef = useRef12(null);
5998
+ const floatingMenuBlockRef = useRef12(null);
5999
+ const floatingMenuUploadStartTimeRef = useRef12(0);
6000
+ const handleError = useCallback21(
4553
6001
  (error) => {
4554
6002
  onError?.(error);
4555
6003
  setErrorMessage(error.getUserMessage());
@@ -4557,10 +6005,12 @@ function LumirEditor({
4557
6005
  },
4558
6006
  [onError]
4559
6007
  );
4560
- const validatedContent = useMemo6(() => {
4561
- return ContentUtils.validateContent(initialContent, initialEmptyBlocks);
6008
+ const validatedContent = useMemo8(() => {
6009
+ return liftFontSize(
6010
+ ContentUtils.validateContent(initialContent, initialEmptyBlocks)
6011
+ );
4562
6012
  }, [initialContent, initialEmptyBlocks]);
4563
- const tableConfig = useMemo6(() => {
6013
+ const tableConfig = useMemo8(() => {
4564
6014
  return EditorConfig.getDefaultTableConfig(tables);
4565
6015
  }, [
4566
6016
  tables?.splitCells,
@@ -4568,10 +6018,10 @@ function LumirEditor({
4568
6018
  tables?.cellTextColor,
4569
6019
  tables?.headers
4570
6020
  ]);
4571
- const headingConfig = useMemo6(() => {
6021
+ const headingConfig = useMemo8(() => {
4572
6022
  return EditorConfig.getDefaultHeadingConfig(heading);
4573
6023
  }, [heading?.levels?.join(",") ?? ""]);
4574
- const disabledExtensions = useMemo6(() => {
6024
+ const disabledExtensions = useMemo8(() => {
4575
6025
  return EditorConfig.getDisabledExtensions(
4576
6026
  disableExtensions,
4577
6027
  allowVideoUpload,
@@ -4579,18 +6029,18 @@ function LumirEditor({
4579
6029
  allowFileUpload
4580
6030
  );
4581
6031
  }, [disableExtensions, allowVideoUpload, allowAudioUpload, allowFileUpload]);
4582
- useEffect10(() => {
6032
+ useEffect11(() => {
4583
6033
  DEBUG_LOG("LumirEditor:init:disabledExtensions", "snapshot", {
4584
6034
  allowVideoUpload,
4585
6035
  hasVideoInDisabled: disabledExtensions.includes("video"),
4586
6036
  disabledList: disabledExtensions.slice(0, 15)
4587
6037
  });
4588
6038
  }, [allowVideoUpload, disabledExtensions]);
4589
- const fileNameTransformRef = useRef11(s3Upload?.fileNameTransform);
4590
- useEffect10(() => {
6039
+ const fileNameTransformRef = useRef12(s3Upload?.fileNameTransform);
6040
+ useEffect11(() => {
4591
6041
  fileNameTransformRef.current = s3Upload?.fileNameTransform;
4592
6042
  }, [s3Upload?.fileNameTransform]);
4593
- const memoizedS3Upload = useMemo6(() => {
6043
+ const memoizedS3Upload = useMemo8(() => {
4594
6044
  if (!s3Upload) return void 0;
4595
6045
  return {
4596
6046
  apiEndpoint: s3Upload.apiEndpoint,
@@ -4641,7 +6091,14 @@ function LumirEditor({
4641
6091
  // 확장 비활성: 비디오/오디오/파일 제어
4642
6092
  disableExtensions: disabledExtensions,
4643
6093
  _tiptapOptions: {
4644
- extensions: [VerticalAlignmentExtension]
6094
+ extensions: [
6095
+ VerticalAlignmentExtension,
6096
+ // 행 높이 attr 등록은 항상(저장된 높이 렌더), 드래그 리사이즈 UI는
6097
+ // tableHandles prop으로 게이트(기존 grip 컨트롤러와 동일 게이트).
6098
+ RowHeightExtension.configure({ resizable: tableHandles }),
6099
+ // 표 블록 정렬(좌/가운데/우) attr.
6100
+ TableAlignmentExtension
6101
+ ]
4645
6102
  },
4646
6103
  placeholders: placeholder ? { default: placeholder, emptyDocument: placeholder } : void 0,
4647
6104
  tabBehavior,
@@ -4817,33 +6274,65 @@ function LumirEditor({
4817
6274
  memoizedS3Upload,
4818
6275
  allowVideoUpload,
4819
6276
  linkPreview?.apiEndpoint,
4820
- placeholder
6277
+ placeholder,
6278
+ // tableHandles 변경 시 RowHeightExtension의 resizable 게이트가 반영되도록 재생성
6279
+ tableHandles
4821
6280
  ]
4822
6281
  );
4823
6282
  if (editor && linkPreview?.apiEndpoint) {
4824
6283
  editor._linkPreviewApiEndpoint = linkPreview.apiEndpoint;
4825
6284
  }
4826
- useEffect10(() => {
6285
+ if (editor) {
6286
+ try {
6287
+ const view = editor.prosemirrorView;
6288
+ if (view) {
6289
+ view.__lumirEditor = editor;
6290
+ }
6291
+ } catch {
6292
+ }
6293
+ }
6294
+ useEffect11(() => {
4827
6295
  if (editor) {
4828
6296
  editor.isEditable = editable;
4829
6297
  }
4830
6298
  }, [editor, editable]);
4831
- useEffect10(() => {
6299
+ useEffect11(() => {
6300
+ if (!editor || !floatingMenu) return;
6301
+ const ft = editor.formattingToolbar;
6302
+ if (!ft?.onUpdate) return;
6303
+ const unsubscribe = ft.onUpdate((state) => {
6304
+ if (!state?.show) return;
6305
+ const selection = editor._tiptapEditor?.state?.selection;
6306
+ if (isSuppressiblePopupSelection(editor, selection)) {
6307
+ ft.closeMenu();
6308
+ }
6309
+ });
6310
+ return unsubscribe;
6311
+ }, [editor, floatingMenu]);
6312
+ useEffect11(() => {
4832
6313
  if (!editor || !onContentChange) return;
4833
6314
  const handleContentChange = () => {
4834
6315
  const blocks = editor.topLevelBlocks;
4835
- const patched = injectVerticalAlignment(blocks, editor);
6316
+ const patched = lowerFontSize(
6317
+ injectTableBlockAttrs(
6318
+ injectTableCellAttrs(blocks, editor, [
6319
+ "verticalAlignment",
6320
+ "rowHeight"
6321
+ ]),
6322
+ editor
6323
+ )
6324
+ );
4836
6325
  onContentChange(patched);
4837
6326
  };
4838
6327
  return editor.onEditorContentChange(handleContentChange);
4839
6328
  }, [editor, onContentChange]);
4840
- const previousMediaUrlsRef = useRef11(/* @__PURE__ */ new Set());
4841
- useEffect10(() => {
6329
+ const previousMediaUrlsRef = useRef12(/* @__PURE__ */ new Set());
6330
+ useEffect11(() => {
4842
6331
  if (!editor) return;
4843
6332
  const initialBlocks = editor.topLevelBlocks;
4844
6333
  previousMediaUrlsRef.current = extractMediaUrls(initialBlocks);
4845
6334
  }, [editor]);
4846
- useEffect10(() => {
6335
+ useEffect11(() => {
4847
6336
  if (!editor || !onImageDelete) return;
4848
6337
  const handleMediaDeleteCheck = () => {
4849
6338
  const currentBlocks = editor.topLevelBlocks;
@@ -4857,7 +6346,7 @@ function LumirEditor({
4857
6346
  };
4858
6347
  return editor.onEditorContentChange(handleMediaDeleteCheck);
4859
6348
  }, [editor, onImageDelete]);
4860
- useEffect10(() => {
6349
+ useEffect11(() => {
4861
6350
  const el = editor?.domElement;
4862
6351
  if (!el) return;
4863
6352
  const handleDragOver = (e) => {
@@ -4988,20 +6477,20 @@ function LumirEditor({
4988
6477
  el.removeEventListener("drop", handleDrop, { capture: true });
4989
6478
  };
4990
6479
  }, [editor, allowVideoUpload]);
4991
- const computedSideMenu = useMemo6(() => {
6480
+ const computedSideMenu = useMemo8(() => {
4992
6481
  return sideMenuAddButton ? sideMenu : false;
4993
6482
  }, [sideMenuAddButton, sideMenu]);
4994
- const DragHandleOnlySideMenu = useMemo6(() => {
4995
- return (props) => /* @__PURE__ */ jsx22(BlockSideMenu, { ...props, children: /* @__PURE__ */ jsx22(DragHandleButton, { ...props }) });
6483
+ const DragHandleOnlySideMenu = useMemo8(() => {
6484
+ return (props) => /* @__PURE__ */ jsx27(BlockSideMenu, { ...props, children: /* @__PURE__ */ jsx27(DragHandleButton, { ...props, dragHandleMenu: LumirDragHandleMenu }) });
4996
6485
  }, []);
4997
- return /* @__PURE__ */ jsxs15(
6486
+ return /* @__PURE__ */ jsxs19(
4998
6487
  "div",
4999
6488
  {
5000
6489
  className: cn("lumirEditor", className),
5001
6490
  style: { position: "relative", display: "flex", flexDirection: "column" },
5002
6491
  children: [
5003
- floatingMenu && editor && /* @__PURE__ */ jsxs15(Fragment7, { children: [
5004
- /* @__PURE__ */ jsx22(
6492
+ floatingMenu && editor && /* @__PURE__ */ jsxs19(Fragment8, { children: [
6493
+ /* @__PURE__ */ jsx27(
5005
6494
  "input",
5006
6495
  {
5007
6496
  ref: floatingMenuFileInputRef,
@@ -5072,7 +6561,7 @@ function LumirEditor({
5072
6561
  }
5073
6562
  }
5074
6563
  ),
5075
- /* @__PURE__ */ jsx22(
6564
+ /* @__PURE__ */ jsx27(
5076
6565
  FloatingMenu,
5077
6566
  {
5078
6567
  editor,
@@ -5104,7 +6593,7 @@ function LumirEditor({
5104
6593
  }
5105
6594
  )
5106
6595
  ] }),
5107
- /* @__PURE__ */ jsxs15(
6596
+ /* @__PURE__ */ jsxs19(
5108
6597
  BlockNoteView,
5109
6598
  {
5110
6599
  editor,
@@ -5119,19 +6608,19 @@ function LumirEditor({
5119
6608
  tableHandles: false,
5120
6609
  onSelectionChange,
5121
6610
  children: [
5122
- tableHandles && /* @__PURE__ */ jsx22(LumirTableHandlesController, {}),
5123
- formattingToolbar && /* @__PURE__ */ jsx22(
6611
+ tableHandles && /* @__PURE__ */ jsx27(LumirTableHandlesController, {}),
6612
+ formattingToolbar && /* @__PURE__ */ jsx27(
5124
6613
  FormattingToolbarController,
5125
6614
  {
5126
6615
  formattingToolbar: CustomFormattingToolbar
5127
6616
  }
5128
6617
  ),
5129
- linkToolbar && (linkPreview?.apiEndpoint ? /* @__PURE__ */ jsx22(LinkToolbarController, { linkToolbar: CustomLinkToolbar }) : /* @__PURE__ */ jsx22(LinkToolbarController, {})),
5130
- /* @__PURE__ */ jsx22(
6618
+ linkToolbar && (linkPreview?.apiEndpoint ? /* @__PURE__ */ jsx27(LinkToolbarController, { linkToolbar: CustomLinkToolbar }) : /* @__PURE__ */ jsx27(LinkToolbarController, {})),
6619
+ /* @__PURE__ */ jsx27(
5131
6620
  SuggestionMenuController,
5132
6621
  {
5133
6622
  triggerCharacter: "/",
5134
- getItems: useCallback18(
6623
+ getItems: useCallback21(
5135
6624
  async (query) => {
5136
6625
  const items = getDefaultReactSlashMenuItems(editor);
5137
6626
  const filtered = items.filter((item) => {
@@ -5175,7 +6664,7 @@ function LumirEditor({
5175
6664
  },
5176
6665
  aliases: ["html", "preview", "\uC6F9", "\uC6F9\uD398\uC774\uC9C0"],
5177
6666
  group: "Embeds",
5178
- icon: /* @__PURE__ */ jsxs15(
6667
+ icon: /* @__PURE__ */ jsxs19(
5179
6668
  "svg",
5180
6669
  {
5181
6670
  width: "18",
@@ -5187,14 +6676,40 @@ function LumirEditor({
5187
6676
  strokeLinecap: "round",
5188
6677
  strokeLinejoin: "round",
5189
6678
  children: [
5190
- /* @__PURE__ */ jsx22("polyline", { points: "16 18 22 12 16 6" }),
5191
- /* @__PURE__ */ jsx22("polyline", { points: "8 6 2 12 8 18" })
6679
+ /* @__PURE__ */ jsx27("polyline", { points: "16 18 22 12 16 6" }),
6680
+ /* @__PURE__ */ jsx27("polyline", { points: "8 6 2 12 8 18" })
5192
6681
  ]
5193
6682
  }
5194
6683
  ),
5195
6684
  subtext: "HTML \uD30C\uC77C\uC744 \uBBF8\uB9AC\uBCF4\uAE30\uB85C \uC0BD\uC785"
5196
6685
  };
5197
- const allItems = [...filtered, htmlPreviewItem];
6686
+ const columnItem = {
6687
+ title: "2\uB2E8 \uCEEC\uB7FC",
6688
+ onItemClick: () => {
6689
+ insertTwoColumns(editor);
6690
+ },
6691
+ aliases: ["columns", "column", "2col", "\uB2E8", "\uCEEC\uB7FC", "\uB2E4\uB2E8", "\uBD84\uD560"],
6692
+ group: "Basic blocks",
6693
+ icon: /* @__PURE__ */ jsxs19(
6694
+ "svg",
6695
+ {
6696
+ width: "18",
6697
+ height: "18",
6698
+ viewBox: "0 0 24 24",
6699
+ fill: "none",
6700
+ stroke: "currentColor",
6701
+ strokeWidth: "2",
6702
+ strokeLinecap: "round",
6703
+ strokeLinejoin: "round",
6704
+ children: [
6705
+ /* @__PURE__ */ jsx27("rect", { x: "3", y: "4", width: "7", height: "16", rx: "1" }),
6706
+ /* @__PURE__ */ jsx27("rect", { x: "14", y: "4", width: "7", height: "16", rx: "1" })
6707
+ ]
6708
+ }
6709
+ ),
6710
+ subtext: "\uBE14\uB85D\uC744 \uC88C\uC6B0 2\uB2E8\uC73C\uB85C \uBC30\uCE58"
6711
+ };
6712
+ const allItems = [...filtered, htmlPreviewItem, columnItem];
5198
6713
  if (linkPreview?.apiEndpoint) {
5199
6714
  allItems.push({
5200
6715
  title: "Link Preview",
@@ -5213,7 +6728,7 @@ function LumirEditor({
5213
6728
  "\uD504\uB9AC\uBDF0"
5214
6729
  ],
5215
6730
  group: "Embeds",
5216
- icon: /* @__PURE__ */ jsxs15(
6731
+ icon: /* @__PURE__ */ jsxs19(
5217
6732
  "svg",
5218
6733
  {
5219
6734
  width: "18",
@@ -5225,8 +6740,8 @@ function LumirEditor({
5225
6740
  strokeLinecap: "round",
5226
6741
  strokeLinejoin: "round",
5227
6742
  children: [
5228
- /* @__PURE__ */ jsx22("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
5229
- /* @__PURE__ */ jsx22("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
6743
+ /* @__PURE__ */ jsx27("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
6744
+ /* @__PURE__ */ jsx27("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
5230
6745
  ]
5231
6746
  }
5232
6747
  ),
@@ -5262,21 +6777,21 @@ function LumirEditor({
5262
6777
  )
5263
6778
  }
5264
6779
  ),
5265
- !sideMenuAddButton && /* @__PURE__ */ jsx22(SideMenuController, { sideMenu: DragHandleOnlySideMenu })
6780
+ !sideMenuAddButton && /* @__PURE__ */ jsx27(SideMenuController, { sideMenu: DragHandleOnlySideMenu })
5266
6781
  ]
5267
6782
  }
5268
6783
  ),
5269
- isUploading && /* @__PURE__ */ jsxs15("div", { className: "lumirEditor-upload-overlay", children: [
5270
- /* @__PURE__ */ jsx22("div", { className: "lumirEditor-spinner" }),
5271
- uploadProgress !== null && /* @__PURE__ */ jsxs15("span", { className: "lumirEditor-upload-progress", children: [
6784
+ isUploading && /* @__PURE__ */ jsxs19("div", { className: "lumirEditor-upload-overlay", children: [
6785
+ /* @__PURE__ */ jsx27("div", { className: "lumirEditor-spinner" }),
6786
+ uploadProgress !== null && /* @__PURE__ */ jsxs19("span", { className: "lumirEditor-upload-progress", children: [
5272
6787
  uploadProgress,
5273
6788
  "%"
5274
6789
  ] })
5275
6790
  ] }),
5276
- errorMessage && /* @__PURE__ */ jsxs15("div", { className: "lumirEditor-error-toast", children: [
5277
- /* @__PURE__ */ jsx22("span", { className: "lumirEditor-error-icon", children: "\u26A0\uFE0F" }),
5278
- /* @__PURE__ */ jsx22("span", { className: "lumirEditor-error-message", children: errorMessage }),
5279
- /* @__PURE__ */ jsx22(
6791
+ errorMessage && /* @__PURE__ */ jsxs19("div", { className: "lumirEditor-error-toast", children: [
6792
+ /* @__PURE__ */ jsx27("span", { className: "lumirEditor-error-icon", children: "\u26A0\uFE0F" }),
6793
+ /* @__PURE__ */ jsx27("span", { className: "lumirEditor-error-message", children: errorMessage }),
6794
+ /* @__PURE__ */ jsx27(
5280
6795
  "button",
5281
6796
  {
5282
6797
  className: "lumirEditor-error-close",
@@ -5294,7 +6809,10 @@ export {
5294
6809
  BACKGROUND_COLORS,
5295
6810
  ContentUtils,
5296
6811
  EditorConfig,
6812
+ FONT_SIZE_PRESETS,
5297
6813
  FloatingMenu,
6814
+ FontSize,
6815
+ FontSizeButton2 as FontSizeButton,
5298
6816
  HtmlPreviewBlock,
5299
6817
  schema as HtmlPreviewSchema,
5300
6818
  LinkPreviewBlock,
@@ -5305,6 +6823,8 @@ export {
5305
6823
  cn,
5306
6824
  createS3Uploader,
5307
6825
  fetchLinkMetadata,
5308
- getHexFromColorValue
6826
+ getHexFromColorValue,
6827
+ liftFontSize,
6828
+ lowerFontSize
5309
6829
  };
5310
6830
  //# sourceMappingURL=index.mjs.map