@lumir-company/editor 0.4.16 → 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/README.md +15 -0
- package/dist/index.d.mts +24 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +1491 -319
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1541 -355
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +95 -0
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -45,10 +45,10 @@ __export(index_exports, {
|
|
|
45
45
|
module.exports = __toCommonJS(index_exports);
|
|
46
46
|
|
|
47
47
|
// src/components/LumirEditor.tsx
|
|
48
|
-
var
|
|
49
|
-
var
|
|
48
|
+
var import_react37 = require("react");
|
|
49
|
+
var import_react38 = require("@blocknote/react");
|
|
50
50
|
var import_mantine = require("@blocknote/mantine");
|
|
51
|
-
var
|
|
51
|
+
var import_core9 = require("@blocknote/core");
|
|
52
52
|
var import_locales = require("@blocknote/core/locales");
|
|
53
53
|
|
|
54
54
|
// src/utils/cn.ts
|
|
@@ -286,7 +286,7 @@ var createS3Uploader = (config) => {
|
|
|
286
286
|
|
|
287
287
|
// src/blocks/HtmlPreview.tsx
|
|
288
288
|
var import_react6 = require("@blocknote/react");
|
|
289
|
-
var
|
|
289
|
+
var import_core3 = require("@blocknote/core");
|
|
290
290
|
|
|
291
291
|
// src/blocks/LinkPreview.tsx
|
|
292
292
|
var import_react = require("@blocknote/react");
|
|
@@ -1246,6 +1246,310 @@ var VideoBlock = (0, import_react3.createReactBlockSpec)(
|
|
|
1246
1246
|
}
|
|
1247
1247
|
);
|
|
1248
1248
|
|
|
1249
|
+
// src/blocks/columns/ColumnList.ts
|
|
1250
|
+
var import_core = require("@blocknote/core");
|
|
1251
|
+
|
|
1252
|
+
// src/blocks/columns/columnNormalization.ts
|
|
1253
|
+
var import_prosemirror_state = require("prosemirror-state");
|
|
1254
|
+
var columnNormalizationKey = new import_prosemirror_state.PluginKey("lumirColumnNormalization");
|
|
1255
|
+
function columnNormalization() {
|
|
1256
|
+
return new import_prosemirror_state.Plugin({
|
|
1257
|
+
key: columnNormalizationKey,
|
|
1258
|
+
appendTransaction(transactions, _oldState, newState) {
|
|
1259
|
+
if (!transactions.some((tr2) => tr2.docChanged)) {
|
|
1260
|
+
return null;
|
|
1261
|
+
}
|
|
1262
|
+
const lists = [];
|
|
1263
|
+
newState.doc.descendants((node, pos) => {
|
|
1264
|
+
if (node.type.name === "columnList") {
|
|
1265
|
+
lists.push({ pos, node });
|
|
1266
|
+
return false;
|
|
1267
|
+
}
|
|
1268
|
+
return void 0;
|
|
1269
|
+
});
|
|
1270
|
+
if (lists.length === 0) {
|
|
1271
|
+
return null;
|
|
1272
|
+
}
|
|
1273
|
+
const tr = newState.tr;
|
|
1274
|
+
let modified = false;
|
|
1275
|
+
for (let i = lists.length - 1; i >= 0; i--) {
|
|
1276
|
+
const { pos, node } = lists[i];
|
|
1277
|
+
const nonEmptyColumns = [];
|
|
1278
|
+
node.forEach((col) => {
|
|
1279
|
+
if (col.type.name === "column" && col.childCount > 0) {
|
|
1280
|
+
nonEmptyColumns.push(col);
|
|
1281
|
+
}
|
|
1282
|
+
});
|
|
1283
|
+
if (nonEmptyColumns.length >= 2) {
|
|
1284
|
+
continue;
|
|
1285
|
+
}
|
|
1286
|
+
const from = tr.mapping.map(pos);
|
|
1287
|
+
const to = tr.mapping.map(pos + node.nodeSize);
|
|
1288
|
+
const blocks = [];
|
|
1289
|
+
nonEmptyColumns.forEach((col) => {
|
|
1290
|
+
col.forEach((bc) => blocks.push(bc));
|
|
1291
|
+
});
|
|
1292
|
+
if (blocks.length > 0) {
|
|
1293
|
+
tr.replaceWith(from, to, blocks);
|
|
1294
|
+
} else {
|
|
1295
|
+
tr.delete(from, to);
|
|
1296
|
+
}
|
|
1297
|
+
modified = true;
|
|
1298
|
+
}
|
|
1299
|
+
return modified ? tr : null;
|
|
1300
|
+
}
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
// src/blocks/columns/columnDnd.ts
|
|
1305
|
+
var import_prosemirror_state2 = require("prosemirror-state");
|
|
1306
|
+
var import_prosemirror_view = require("prosemirror-view");
|
|
1307
|
+
|
|
1308
|
+
// src/blocks/columns/mergeColumns.ts
|
|
1309
|
+
function mergeBlocksIntoColumns(editor, draggedId, targetId, side) {
|
|
1310
|
+
if (!editor || !draggedId || !targetId || draggedId === targetId) {
|
|
1311
|
+
return false;
|
|
1312
|
+
}
|
|
1313
|
+
const dragged = editor.getBlock?.(draggedId);
|
|
1314
|
+
const target = editor.getBlock?.(targetId);
|
|
1315
|
+
if (!dragged || !target) {
|
|
1316
|
+
return false;
|
|
1317
|
+
}
|
|
1318
|
+
if (dragged.type === "columnList" || dragged.type === "column" || target.type === "columnList" || target.type === "column") {
|
|
1319
|
+
return false;
|
|
1320
|
+
}
|
|
1321
|
+
const columnList = {
|
|
1322
|
+
type: "columnList",
|
|
1323
|
+
children: side === "left" ? [
|
|
1324
|
+
{ type: "column", children: [dragged] },
|
|
1325
|
+
{ type: "column", children: [target] }
|
|
1326
|
+
] : [
|
|
1327
|
+
{ type: "column", children: [target] },
|
|
1328
|
+
{ type: "column", children: [dragged] }
|
|
1329
|
+
]
|
|
1330
|
+
};
|
|
1331
|
+
try {
|
|
1332
|
+
const run = () => {
|
|
1333
|
+
editor.removeBlocks([draggedId]);
|
|
1334
|
+
editor.replaceBlocks([targetId], [columnList]);
|
|
1335
|
+
};
|
|
1336
|
+
if (typeof editor.transact === "function") {
|
|
1337
|
+
editor.transact(run);
|
|
1338
|
+
} else {
|
|
1339
|
+
run();
|
|
1340
|
+
}
|
|
1341
|
+
return true;
|
|
1342
|
+
} catch {
|
|
1343
|
+
return false;
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
// src/blocks/columns/columnDnd.ts
|
|
1348
|
+
var columnDndKey = new import_prosemirror_state2.PluginKey("lumirColumnDnd");
|
|
1349
|
+
function edgeThreshold(width) {
|
|
1350
|
+
return Math.min(80, width * 0.3);
|
|
1351
|
+
}
|
|
1352
|
+
function topLevelBlockAtCoords(view, x, y) {
|
|
1353
|
+
const found = view.posAtCoords({ left: x, top: y });
|
|
1354
|
+
if (!found) {
|
|
1355
|
+
return null;
|
|
1356
|
+
}
|
|
1357
|
+
const $pos = view.state.doc.resolve(found.pos);
|
|
1358
|
+
for (let d = $pos.depth; d > 0; d--) {
|
|
1359
|
+
if ($pos.node(d).type.name === "blockContainer") {
|
|
1360
|
+
if (d !== 2 || $pos.node(d - 1).type.name !== "blockGroup") {
|
|
1361
|
+
return null;
|
|
1362
|
+
}
|
|
1363
|
+
const pos = $pos.before(d);
|
|
1364
|
+
const node = $pos.node(d);
|
|
1365
|
+
const dom = view.nodeDOM(pos);
|
|
1366
|
+
if (!dom || !node.attrs?.id) {
|
|
1367
|
+
return null;
|
|
1368
|
+
}
|
|
1369
|
+
return { pos, nodeSize: node.nodeSize, id: node.attrs.id, dom };
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
return null;
|
|
1373
|
+
}
|
|
1374
|
+
function draggedBlockId(view) {
|
|
1375
|
+
const sel = view.state.selection;
|
|
1376
|
+
return sel?.node?.attrs?.id ?? null;
|
|
1377
|
+
}
|
|
1378
|
+
function setDnd(view, next) {
|
|
1379
|
+
const cur = columnDndKey.getState(view.state);
|
|
1380
|
+
if (cur && cur.targetPos === next.targetPos && cur.side === next.side) {
|
|
1381
|
+
return;
|
|
1382
|
+
}
|
|
1383
|
+
view.dispatch(view.state.tr.setMeta(columnDndKey, next));
|
|
1384
|
+
}
|
|
1385
|
+
var CLEARED = { targetPos: null, side: null };
|
|
1386
|
+
function columnDnd() {
|
|
1387
|
+
return new import_prosemirror_state2.Plugin({
|
|
1388
|
+
key: columnDndKey,
|
|
1389
|
+
state: {
|
|
1390
|
+
init: () => CLEARED,
|
|
1391
|
+
apply(tr, prev) {
|
|
1392
|
+
const meta = tr.getMeta(columnDndKey);
|
|
1393
|
+
if (meta) {
|
|
1394
|
+
return meta;
|
|
1395
|
+
}
|
|
1396
|
+
if (tr.docChanged && prev.targetPos !== null) {
|
|
1397
|
+
return CLEARED;
|
|
1398
|
+
}
|
|
1399
|
+
return prev;
|
|
1400
|
+
}
|
|
1401
|
+
},
|
|
1402
|
+
props: {
|
|
1403
|
+
handleDOMEvents: {
|
|
1404
|
+
dragover: (view, event) => {
|
|
1405
|
+
if (!view.dragging) {
|
|
1406
|
+
return false;
|
|
1407
|
+
}
|
|
1408
|
+
const target = topLevelBlockAtCoords(
|
|
1409
|
+
view,
|
|
1410
|
+
event.clientX,
|
|
1411
|
+
event.clientY
|
|
1412
|
+
);
|
|
1413
|
+
const draggedId = draggedBlockId(view);
|
|
1414
|
+
if (!target || !draggedId || target.id === draggedId) {
|
|
1415
|
+
setDnd(view, CLEARED);
|
|
1416
|
+
view.dom.classList.remove("lumir-col-dnd-active");
|
|
1417
|
+
return false;
|
|
1418
|
+
}
|
|
1419
|
+
const rect = target.dom.getBoundingClientRect();
|
|
1420
|
+
const th = edgeThreshold(rect.width);
|
|
1421
|
+
let side = null;
|
|
1422
|
+
if (event.clientX - rect.left <= th) {
|
|
1423
|
+
side = "left";
|
|
1424
|
+
} else if (rect.right - event.clientX <= th) {
|
|
1425
|
+
side = "right";
|
|
1426
|
+
}
|
|
1427
|
+
if (side) {
|
|
1428
|
+
setDnd(view, { targetPos: target.pos, side });
|
|
1429
|
+
view.dom.classList.add("lumir-col-dnd-active");
|
|
1430
|
+
} else {
|
|
1431
|
+
setDnd(view, CLEARED);
|
|
1432
|
+
view.dom.classList.remove("lumir-col-dnd-active");
|
|
1433
|
+
}
|
|
1434
|
+
return false;
|
|
1435
|
+
},
|
|
1436
|
+
dragend: (view) => {
|
|
1437
|
+
setDnd(view, CLEARED);
|
|
1438
|
+
view.dom.classList.remove("lumir-col-dnd-active");
|
|
1439
|
+
return false;
|
|
1440
|
+
},
|
|
1441
|
+
dragleave: (view, event) => {
|
|
1442
|
+
if (!event.relatedTarget) {
|
|
1443
|
+
setDnd(view, CLEARED);
|
|
1444
|
+
view.dom.classList.remove("lumir-col-dnd-active");
|
|
1445
|
+
}
|
|
1446
|
+
return false;
|
|
1447
|
+
}
|
|
1448
|
+
},
|
|
1449
|
+
handleDrop: (view, _event, _slice, _moved) => {
|
|
1450
|
+
const st = columnDndKey.getState(view.state);
|
|
1451
|
+
view.dom.classList.remove("lumir-col-dnd-active");
|
|
1452
|
+
if (!st || st.side === null || st.targetPos === null) {
|
|
1453
|
+
return false;
|
|
1454
|
+
}
|
|
1455
|
+
const draggedId = draggedBlockId(view);
|
|
1456
|
+
const targetNode = view.state.doc.nodeAt(st.targetPos);
|
|
1457
|
+
const targetId = targetNode?.attrs?.id;
|
|
1458
|
+
view.dispatch(view.state.tr.setMeta(columnDndKey, CLEARED));
|
|
1459
|
+
if (!draggedId || !targetId) {
|
|
1460
|
+
return false;
|
|
1461
|
+
}
|
|
1462
|
+
const editor = view.__lumirEditor;
|
|
1463
|
+
if (!editor) {
|
|
1464
|
+
return false;
|
|
1465
|
+
}
|
|
1466
|
+
const ok = mergeBlocksIntoColumns(editor, draggedId, targetId, st.side);
|
|
1467
|
+
return ok;
|
|
1468
|
+
},
|
|
1469
|
+
decorations: (state) => {
|
|
1470
|
+
const st = columnDndKey.getState(state);
|
|
1471
|
+
if (!st || st.side === null || st.targetPos === null) {
|
|
1472
|
+
return null;
|
|
1473
|
+
}
|
|
1474
|
+
const node = state.doc.nodeAt(st.targetPos);
|
|
1475
|
+
if (!node) {
|
|
1476
|
+
return null;
|
|
1477
|
+
}
|
|
1478
|
+
return import_prosemirror_view.DecorationSet.create(state.doc, [
|
|
1479
|
+
import_prosemirror_view.Decoration.node(st.targetPos, st.targetPos + node.nodeSize, {
|
|
1480
|
+
class: st.side === "left" ? "lumir-col-drop-left" : "lumir-col-drop-right"
|
|
1481
|
+
})
|
|
1482
|
+
]);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
});
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
// src/blocks/columns/ColumnList.ts
|
|
1489
|
+
var ColumnList = (0, import_core.createStronglyTypedTiptapNode)({
|
|
1490
|
+
name: "columnList",
|
|
1491
|
+
group: "childContainer bnBlock blockGroupChild",
|
|
1492
|
+
content: "column column+",
|
|
1493
|
+
parseHTML() {
|
|
1494
|
+
return [{ tag: 'div[data-node-type="columnList"]' }];
|
|
1495
|
+
},
|
|
1496
|
+
renderHTML({ HTMLAttributes }) {
|
|
1497
|
+
const dom = document.createElement("div");
|
|
1498
|
+
dom.className = "bn-column-list";
|
|
1499
|
+
dom.setAttribute("data-node-type", "columnList");
|
|
1500
|
+
for (const [attribute, value] of Object.entries(HTMLAttributes)) {
|
|
1501
|
+
if (attribute !== "class") {
|
|
1502
|
+
dom.setAttribute(attribute, value);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
return { dom, contentDOM: dom };
|
|
1506
|
+
},
|
|
1507
|
+
// columnNormalization: 빈 컬럼/1단 columnList 자동 복구(unwrap).
|
|
1508
|
+
// columnDnd: 블록을 다른 블록 좌/우로 드롭하면 2단 컬럼 생성.
|
|
1509
|
+
addProseMirrorPlugins() {
|
|
1510
|
+
return [columnNormalization(), columnDnd()];
|
|
1511
|
+
}
|
|
1512
|
+
});
|
|
1513
|
+
|
|
1514
|
+
// src/blocks/columns/Column.ts
|
|
1515
|
+
var import_core2 = require("@blocknote/core");
|
|
1516
|
+
var Column = (0, import_core2.createStronglyTypedTiptapNode)({
|
|
1517
|
+
name: "column",
|
|
1518
|
+
group: "bnBlock childContainer",
|
|
1519
|
+
content: "blockContainer+",
|
|
1520
|
+
addAttributes() {
|
|
1521
|
+
return {
|
|
1522
|
+
width: {
|
|
1523
|
+
default: 1,
|
|
1524
|
+
parseHTML: (element) => {
|
|
1525
|
+
const w = parseFloat(element.getAttribute("data-column-width") || "");
|
|
1526
|
+
return Number.isFinite(w) && w > 0 ? w : 1;
|
|
1527
|
+
},
|
|
1528
|
+
renderHTML: (attributes) => {
|
|
1529
|
+
if (!attributes.width || attributes.width === 1) {
|
|
1530
|
+
return {};
|
|
1531
|
+
}
|
|
1532
|
+
return { "data-column-width": String(attributes.width) };
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
};
|
|
1536
|
+
},
|
|
1537
|
+
parseHTML() {
|
|
1538
|
+
return [{ tag: 'div[data-node-type="column"]' }];
|
|
1539
|
+
},
|
|
1540
|
+
renderHTML({ HTMLAttributes }) {
|
|
1541
|
+
const dom = document.createElement("div");
|
|
1542
|
+
dom.className = "bn-column";
|
|
1543
|
+
dom.setAttribute("data-node-type", "column");
|
|
1544
|
+
for (const [attribute, value] of Object.entries(HTMLAttributes)) {
|
|
1545
|
+
if (attribute !== "class") {
|
|
1546
|
+
dom.setAttribute(attribute, value);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
return { dom, contentDOM: dom };
|
|
1550
|
+
}
|
|
1551
|
+
});
|
|
1552
|
+
|
|
1249
1553
|
// src/styles/FontSizeStyle.tsx
|
|
1250
1554
|
var import_react5 = require("@blocknote/react");
|
|
1251
1555
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
@@ -1351,7 +1655,7 @@ var HtmlPreviewBlock = (0, import_react6.createReactBlockSpec)(
|
|
|
1351
1655
|
setIsResizing(true);
|
|
1352
1656
|
const startY = e.clientY;
|
|
1353
1657
|
const startHeight = currentHeight;
|
|
1354
|
-
const
|
|
1658
|
+
const handleMouseMove2 = (moveEvent) => {
|
|
1355
1659
|
const deltaY = moveEvent.clientY - startY;
|
|
1356
1660
|
const newHeight = Math.min(
|
|
1357
1661
|
MAX_HEIGHT,
|
|
@@ -1363,10 +1667,10 @@ var HtmlPreviewBlock = (0, import_react6.createReactBlockSpec)(
|
|
|
1363
1667
|
};
|
|
1364
1668
|
const handleMouseUp = () => {
|
|
1365
1669
|
setIsResizing(false);
|
|
1366
|
-
document.removeEventListener("mousemove",
|
|
1670
|
+
document.removeEventListener("mousemove", handleMouseMove2);
|
|
1367
1671
|
document.removeEventListener("mouseup", handleMouseUp);
|
|
1368
1672
|
};
|
|
1369
|
-
document.addEventListener("mousemove",
|
|
1673
|
+
document.addEventListener("mousemove", handleMouseMove2);
|
|
1370
1674
|
document.addEventListener("mouseup", handleMouseUp);
|
|
1371
1675
|
},
|
|
1372
1676
|
[currentHeight, props.editor, props.block]
|
|
@@ -1632,16 +1936,23 @@ var HtmlPreviewBlock = (0, import_react6.createReactBlockSpec)(
|
|
|
1632
1936
|
}
|
|
1633
1937
|
}
|
|
1634
1938
|
);
|
|
1635
|
-
var
|
|
1939
|
+
var ColumnListBlock = (0, import_core3.createBlockSpecFromStronglyTypedTiptapNode)(
|
|
1940
|
+
ColumnList,
|
|
1941
|
+
{}
|
|
1942
|
+
);
|
|
1943
|
+
var ColumnBlock = (0, import_core3.createBlockSpecFromStronglyTypedTiptapNode)(Column, {});
|
|
1944
|
+
var schema = import_core3.BlockNoteSchema.create({
|
|
1636
1945
|
blockSpecs: {
|
|
1637
|
-
...
|
|
1946
|
+
...import_core3.defaultBlockSpecs,
|
|
1638
1947
|
htmlPreview: HtmlPreviewBlock,
|
|
1639
1948
|
linkPreview: LinkPreviewBlock,
|
|
1640
|
-
video: VideoBlock
|
|
1949
|
+
video: VideoBlock,
|
|
1950
|
+
columnList: ColumnListBlock,
|
|
1951
|
+
column: ColumnBlock
|
|
1641
1952
|
},
|
|
1642
|
-
inlineContentSpecs:
|
|
1953
|
+
inlineContentSpecs: import_core3.defaultInlineContentSpecs,
|
|
1643
1954
|
styleSpecs: {
|
|
1644
|
-
...
|
|
1955
|
+
...import_core3.defaultStyleSpecs,
|
|
1645
1956
|
// 인라인 글자 크기. 저장 JSON 직렬화는 형제 키 방식(font-size-serialization.ts) 사용.
|
|
1646
1957
|
fontSize: FontSize
|
|
1647
1958
|
}
|
|
@@ -1785,7 +2096,7 @@ var UndoRedoButtons = ({ editor }) => {
|
|
|
1785
2096
|
console.error("Redo failed:", err);
|
|
1786
2097
|
}
|
|
1787
2098
|
}, [editor]);
|
|
1788
|
-
const
|
|
2099
|
+
const handleMouseDown2 = (0, import_react8.useCallback)((e) => {
|
|
1789
2100
|
e.preventDefault();
|
|
1790
2101
|
}, []);
|
|
1791
2102
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
@@ -1794,7 +2105,7 @@ var UndoRedoButtons = ({ editor }) => {
|
|
|
1794
2105
|
{
|
|
1795
2106
|
className: "lumir-toolbar-btn",
|
|
1796
2107
|
onClick: handleUndo,
|
|
1797
|
-
onMouseDown:
|
|
2108
|
+
onMouseDown: handleMouseDown2,
|
|
1798
2109
|
title: "\uC2E4\uD589 \uCDE8\uC18C",
|
|
1799
2110
|
type: "button",
|
|
1800
2111
|
children: Icons.undo
|
|
@@ -1805,7 +2116,7 @@ var UndoRedoButtons = ({ editor }) => {
|
|
|
1805
2116
|
{
|
|
1806
2117
|
className: "lumir-toolbar-btn",
|
|
1807
2118
|
onClick: handleRedo,
|
|
1808
|
-
onMouseDown:
|
|
2119
|
+
onMouseDown: handleMouseDown2,
|
|
1809
2120
|
title: "\uB2E4\uC2DC \uC2E4\uD589",
|
|
1810
2121
|
type: "button",
|
|
1811
2122
|
children: Icons.redo
|
|
@@ -1849,7 +2160,7 @@ var TextStyleButton = ({
|
|
|
1849
2160
|
console.error(`Toggle ${style} failed:`, err);
|
|
1850
2161
|
}
|
|
1851
2162
|
}, [editor, style]);
|
|
1852
|
-
const
|
|
2163
|
+
const handleMouseDown2 = (0, import_react9.useCallback)((e) => {
|
|
1853
2164
|
e.preventDefault();
|
|
1854
2165
|
}, []);
|
|
1855
2166
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
@@ -1857,7 +2168,7 @@ var TextStyleButton = ({
|
|
|
1857
2168
|
{
|
|
1858
2169
|
className: cn("lumir-toolbar-btn", isActive && "is-active"),
|
|
1859
2170
|
onClick: handleClick,
|
|
1860
|
-
onMouseDown:
|
|
2171
|
+
onMouseDown: handleMouseDown2,
|
|
1861
2172
|
title: titleMap[style],
|
|
1862
2173
|
type: "button",
|
|
1863
2174
|
children: iconMap[style]
|
|
@@ -1925,6 +2236,41 @@ function getFirstSelectedCellAttr(editor, attr) {
|
|
|
1925
2236
|
const node = tiptap.state.doc.nodeAt(positions[0]);
|
|
1926
2237
|
return node?.attrs?.[attr];
|
|
1927
2238
|
}
|
|
2239
|
+
function findTableNodePos(tiptap, blockId) {
|
|
2240
|
+
let tablePos = -1;
|
|
2241
|
+
tiptap.state.doc.descendants((node, pos) => {
|
|
2242
|
+
if (tablePos !== -1) return false;
|
|
2243
|
+
if (node.type.name === "blockContainer" && node.attrs?.id === blockId && node.firstChild?.type.name === "table") {
|
|
2244
|
+
tablePos = pos + 1;
|
|
2245
|
+
return false;
|
|
2246
|
+
}
|
|
2247
|
+
return void 0;
|
|
2248
|
+
});
|
|
2249
|
+
return tablePos;
|
|
2250
|
+
}
|
|
2251
|
+
function setTableAlignment(editor, blockId, alignment) {
|
|
2252
|
+
const tiptap = editor?._tiptapEditor;
|
|
2253
|
+
if (!tiptap || !blockId) return false;
|
|
2254
|
+
const tablePos = findTableNodePos(tiptap, blockId);
|
|
2255
|
+
if (tablePos < 0) return false;
|
|
2256
|
+
const node = tiptap.state.doc.nodeAt(tablePos);
|
|
2257
|
+
if (!node || node.type.name !== "table") return false;
|
|
2258
|
+
tiptap.view?.dispatch(
|
|
2259
|
+
tiptap.state.tr.setNodeMarkup(tablePos, void 0, {
|
|
2260
|
+
...node.attrs,
|
|
2261
|
+
tableAlignment: alignment
|
|
2262
|
+
})
|
|
2263
|
+
);
|
|
2264
|
+
return true;
|
|
2265
|
+
}
|
|
2266
|
+
function getTableAlignment(editor, blockId) {
|
|
2267
|
+
const tiptap = editor?._tiptapEditor;
|
|
2268
|
+
if (!tiptap || !blockId) return "left";
|
|
2269
|
+
const tablePos = findTableNodePos(tiptap, blockId);
|
|
2270
|
+
if (tablePos < 0) return "left";
|
|
2271
|
+
const node = tiptap.state.doc.nodeAt(tablePos);
|
|
2272
|
+
return node?.attrs?.tableAlignment || "left";
|
|
2273
|
+
}
|
|
1928
2274
|
|
|
1929
2275
|
// src/components/FloatingMenu/components/AlignButton.tsx
|
|
1930
2276
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
@@ -1967,7 +2313,7 @@ var AlignButton = ({
|
|
|
1967
2313
|
console.error(`Set alignment ${alignment} failed:`, err);
|
|
1968
2314
|
}
|
|
1969
2315
|
}, [editor, alignment]);
|
|
1970
|
-
const
|
|
2316
|
+
const handleMouseDown2 = (0, import_react10.useCallback)((e) => {
|
|
1971
2317
|
e.preventDefault();
|
|
1972
2318
|
}, []);
|
|
1973
2319
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
@@ -1975,7 +2321,7 @@ var AlignButton = ({
|
|
|
1975
2321
|
{
|
|
1976
2322
|
className: cn("lumir-toolbar-btn", isActive && "is-active"),
|
|
1977
2323
|
onClick: handleClick,
|
|
1978
|
-
onMouseDown:
|
|
2324
|
+
onMouseDown: handleMouseDown2,
|
|
1979
2325
|
title: titleMap2[alignment],
|
|
1980
2326
|
type: "button",
|
|
1981
2327
|
children: iconMap2[alignment]
|
|
@@ -2017,7 +2363,7 @@ var ListButton = ({ editor, type }) => {
|
|
|
2017
2363
|
console.error(`List toggle failed:`, err);
|
|
2018
2364
|
}
|
|
2019
2365
|
}, [editor, type]);
|
|
2020
|
-
const
|
|
2366
|
+
const handleMouseDown2 = (0, import_react11.useCallback)((e) => {
|
|
2021
2367
|
e.preventDefault();
|
|
2022
2368
|
}, []);
|
|
2023
2369
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
@@ -2025,7 +2371,7 @@ var ListButton = ({ editor, type }) => {
|
|
|
2025
2371
|
{
|
|
2026
2372
|
className: cn("lumir-toolbar-btn", isActive && "is-active"),
|
|
2027
2373
|
onClick: handleClick,
|
|
2028
|
-
onMouseDown:
|
|
2374
|
+
onMouseDown: handleMouseDown2,
|
|
2029
2375
|
title: titleMap3[type],
|
|
2030
2376
|
type: "button",
|
|
2031
2377
|
children: iconMap3[type]
|
|
@@ -2065,7 +2411,7 @@ var ImageButton = ({
|
|
|
2065
2411
|
input.click();
|
|
2066
2412
|
}
|
|
2067
2413
|
}, [editor, onImageUpload]);
|
|
2068
|
-
const
|
|
2414
|
+
const handleMouseDown2 = (0, import_react12.useCallback)((e) => {
|
|
2069
2415
|
e.preventDefault();
|
|
2070
2416
|
}, []);
|
|
2071
2417
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
@@ -2073,7 +2419,7 @@ var ImageButton = ({
|
|
|
2073
2419
|
{
|
|
2074
2420
|
className: "lumir-toolbar-btn",
|
|
2075
2421
|
onClick: handleClick,
|
|
2076
|
-
onMouseDown:
|
|
2422
|
+
onMouseDown: handleMouseDown2,
|
|
2077
2423
|
title: "\uC774\uBBF8\uC9C0 \uC0BD\uC785",
|
|
2078
2424
|
type: "button",
|
|
2079
2425
|
children: Icons.image
|
|
@@ -2172,7 +2518,7 @@ var ColorButton = ({ editor, type }) => {
|
|
|
2172
2518
|
},
|
|
2173
2519
|
[editor, type]
|
|
2174
2520
|
);
|
|
2175
|
-
const
|
|
2521
|
+
const handleMouseDown2 = (0, import_react13.useCallback)((e) => {
|
|
2176
2522
|
e.preventDefault();
|
|
2177
2523
|
}, []);
|
|
2178
2524
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
|
|
@@ -2181,7 +2527,7 @@ var ColorButton = ({ editor, type }) => {
|
|
|
2181
2527
|
{
|
|
2182
2528
|
className: "lumir-toolbar-btn lumir-color-btn",
|
|
2183
2529
|
onClick: () => setIsOpen(!isOpen),
|
|
2184
|
-
onMouseDown:
|
|
2530
|
+
onMouseDown: handleMouseDown2,
|
|
2185
2531
|
title: type === "text" ? "\uD14D\uC2A4\uD2B8 \uC0C9\uC0C1" : "\uBC30\uACBD \uC0C9\uC0C1",
|
|
2186
2532
|
type: "button",
|
|
2187
2533
|
children: [
|
|
@@ -2206,7 +2552,7 @@ var ColorButton = ({ editor, type }) => {
|
|
|
2206
2552
|
currentColor === color.value && "is-active"
|
|
2207
2553
|
),
|
|
2208
2554
|
onClick: () => handleColorSelect(color.value),
|
|
2209
|
-
onMouseDown:
|
|
2555
|
+
onMouseDown: handleMouseDown2,
|
|
2210
2556
|
title: color.name,
|
|
2211
2557
|
style: { backgroundColor: color.hex },
|
|
2212
2558
|
type: "button"
|
|
@@ -2258,7 +2604,7 @@ var FontSizeButton = ({ editor }) => {
|
|
|
2258
2604
|
},
|
|
2259
2605
|
[editor]
|
|
2260
2606
|
);
|
|
2261
|
-
const
|
|
2607
|
+
const handleMouseDown2 = (0, import_react14.useCallback)((e) => {
|
|
2262
2608
|
e.preventDefault();
|
|
2263
2609
|
}, []);
|
|
2264
2610
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
|
|
@@ -2267,7 +2613,7 @@ var FontSizeButton = ({ editor }) => {
|
|
|
2267
2613
|
{
|
|
2268
2614
|
className: "lumir-dropdown-btn lumir-font-size-btn",
|
|
2269
2615
|
onClick: () => setIsOpen(!isOpen),
|
|
2270
|
-
onMouseDown:
|
|
2616
|
+
onMouseDown: handleMouseDown2,
|
|
2271
2617
|
title: "\uAE00\uC790 \uD06C\uAE30",
|
|
2272
2618
|
type: "button",
|
|
2273
2619
|
children: [
|
|
@@ -2285,7 +2631,7 @@ var FontSizeButton = ({ editor }) => {
|
|
|
2285
2631
|
currentSize === "" && "is-active"
|
|
2286
2632
|
),
|
|
2287
2633
|
onClick: () => handleSizeSelect(""),
|
|
2288
|
-
onMouseDown:
|
|
2634
|
+
onMouseDown: handleMouseDown2,
|
|
2289
2635
|
type: "button",
|
|
2290
2636
|
children: DEFAULT_LABEL
|
|
2291
2637
|
}
|
|
@@ -2298,7 +2644,7 @@ var FontSizeButton = ({ editor }) => {
|
|
|
2298
2644
|
currentSize === size && "is-active"
|
|
2299
2645
|
),
|
|
2300
2646
|
onClick: () => handleSizeSelect(size),
|
|
2301
|
-
onMouseDown:
|
|
2647
|
+
onMouseDown: handleMouseDown2,
|
|
2302
2648
|
type: "button",
|
|
2303
2649
|
children: toLabel(size)
|
|
2304
2650
|
},
|
|
@@ -2396,7 +2742,7 @@ var LinkButton = ({ editor }) => {
|
|
|
2396
2742
|
setLinkUrl("");
|
|
2397
2743
|
setErrorMsg(null);
|
|
2398
2744
|
}, []);
|
|
2399
|
-
const
|
|
2745
|
+
const handleMouseDown2 = (0, import_react15.useCallback)((e) => {
|
|
2400
2746
|
e.preventDefault();
|
|
2401
2747
|
}, []);
|
|
2402
2748
|
const handleKeyDown = (0, import_react15.useCallback)(
|
|
@@ -2415,7 +2761,7 @@ var LinkButton = ({ editor }) => {
|
|
|
2415
2761
|
{
|
|
2416
2762
|
className: "lumir-toolbar-btn",
|
|
2417
2763
|
onClick: () => setIsOpen(!isOpen),
|
|
2418
|
-
onMouseDown:
|
|
2764
|
+
onMouseDown: handleMouseDown2,
|
|
2419
2765
|
title: "\uB9C1\uD06C \uC0BD\uC785",
|
|
2420
2766
|
type: "button",
|
|
2421
2767
|
children: Icons.link
|
|
@@ -2435,7 +2781,7 @@ var LinkButton = ({ editor }) => {
|
|
|
2435
2781
|
setErrorMsg(null);
|
|
2436
2782
|
},
|
|
2437
2783
|
onKeyDown: handleKeyDown,
|
|
2438
|
-
onMouseDown:
|
|
2784
|
+
onMouseDown: handleMouseDown2
|
|
2439
2785
|
}
|
|
2440
2786
|
),
|
|
2441
2787
|
errorMsg && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
@@ -2457,7 +2803,7 @@ var LinkButton = ({ editor }) => {
|
|
|
2457
2803
|
type: "button",
|
|
2458
2804
|
className: "lumir-link-btn lumir-link-cancel",
|
|
2459
2805
|
onClick: handleCancel,
|
|
2460
|
-
onMouseDown:
|
|
2806
|
+
onMouseDown: handleMouseDown2,
|
|
2461
2807
|
children: "\uCDE8\uC18C"
|
|
2462
2808
|
}
|
|
2463
2809
|
),
|
|
@@ -2466,7 +2812,7 @@ var LinkButton = ({ editor }) => {
|
|
|
2466
2812
|
{
|
|
2467
2813
|
type: "submit",
|
|
2468
2814
|
className: "lumir-link-btn lumir-link-submit",
|
|
2469
|
-
onMouseDown:
|
|
2815
|
+
onMouseDown: handleMouseDown2,
|
|
2470
2816
|
disabled: !linkUrl.trim(),
|
|
2471
2817
|
children: "\uD655\uC778"
|
|
2472
2818
|
}
|
|
@@ -2502,7 +2848,7 @@ var TableButton = ({ editor }) => {
|
|
|
2502
2848
|
console.error("Table insert failed:", err);
|
|
2503
2849
|
}
|
|
2504
2850
|
}, [editor]);
|
|
2505
|
-
const
|
|
2851
|
+
const handleMouseDown2 = (0, import_react16.useCallback)((e) => {
|
|
2506
2852
|
e.preventDefault();
|
|
2507
2853
|
}, []);
|
|
2508
2854
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
@@ -2510,7 +2856,7 @@ var TableButton = ({ editor }) => {
|
|
|
2510
2856
|
{
|
|
2511
2857
|
className: "lumir-toolbar-btn",
|
|
2512
2858
|
onClick: handleClick,
|
|
2513
|
-
onMouseDown:
|
|
2859
|
+
onMouseDown: handleMouseDown2,
|
|
2514
2860
|
title: "\uD14C\uC774\uBE14 \uC0BD\uC785",
|
|
2515
2861
|
type: "button",
|
|
2516
2862
|
children: Icons.table
|
|
@@ -2564,7 +2910,7 @@ var HTMLImportButton = ({
|
|
|
2564
2910
|
const handleClick = (0, import_react17.useCallback)(() => {
|
|
2565
2911
|
fileInputRef.current?.click();
|
|
2566
2912
|
}, []);
|
|
2567
|
-
const
|
|
2913
|
+
const handleMouseDown2 = (0, import_react17.useCallback)((e) => {
|
|
2568
2914
|
e.preventDefault();
|
|
2569
2915
|
}, []);
|
|
2570
2916
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
@@ -2583,7 +2929,7 @@ var HTMLImportButton = ({
|
|
|
2583
2929
|
{
|
|
2584
2930
|
className: "lumir-toolbar-btn",
|
|
2585
2931
|
onClick: handleClick,
|
|
2586
|
-
onMouseDown:
|
|
2932
|
+
onMouseDown: handleMouseDown2,
|
|
2587
2933
|
title: "HTML Import",
|
|
2588
2934
|
type: "button",
|
|
2589
2935
|
children: Icons.htmlFile
|
|
@@ -2666,7 +3012,7 @@ var BlockTypeSelect = ({ editor }) => {
|
|
|
2666
3012
|
console.error("Block type change failed:", err);
|
|
2667
3013
|
}
|
|
2668
3014
|
};
|
|
2669
|
-
const
|
|
3015
|
+
const handleMouseDown2 = (0, import_react18.useCallback)((e) => {
|
|
2670
3016
|
e.preventDefault();
|
|
2671
3017
|
}, []);
|
|
2672
3018
|
const getCurrentLabel = () => {
|
|
@@ -2703,7 +3049,7 @@ var BlockTypeSelect = ({ editor }) => {
|
|
|
2703
3049
|
{
|
|
2704
3050
|
className: "lumir-dropdown-btn lumir-block-type-btn",
|
|
2705
3051
|
onClick: () => setIsOpen(!isOpen),
|
|
2706
|
-
onMouseDown:
|
|
3052
|
+
onMouseDown: handleMouseDown2,
|
|
2707
3053
|
type: "button",
|
|
2708
3054
|
children: [
|
|
2709
3055
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "lumir-block-icon", children: BlockTypeIcons[getCurrentIcon()] }),
|
|
@@ -2722,7 +3068,7 @@ var BlockTypeSelect = ({ editor }) => {
|
|
|
2722
3068
|
isActiveItem(bt) && "is-active"
|
|
2723
3069
|
),
|
|
2724
3070
|
onClick: () => handleTypeChange(bt.type, bt.level, bt.isToggle),
|
|
2725
|
-
onMouseDown:
|
|
3071
|
+
onMouseDown: handleMouseDown2,
|
|
2726
3072
|
children: [
|
|
2727
3073
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "lumir-block-icon", children: BlockTypeIcons[bt.icon] }),
|
|
2728
3074
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "lumir-block-item-title", children: bt.label })
|
|
@@ -3032,8 +3378,8 @@ var LumirEditorError = class _LumirEditorError extends Error {
|
|
|
3032
3378
|
};
|
|
3033
3379
|
|
|
3034
3380
|
// src/extensions/VerticalAlignmentExtension.ts
|
|
3035
|
-
var
|
|
3036
|
-
var VerticalAlignmentExtension =
|
|
3381
|
+
var import_core4 = require("@tiptap/core");
|
|
3382
|
+
var VerticalAlignmentExtension = import_core4.Extension.create({
|
|
3037
3383
|
name: "verticalAlignment",
|
|
3038
3384
|
addGlobalAttributes() {
|
|
3039
3385
|
return [
|
|
@@ -3063,11 +3409,585 @@ var VerticalAlignmentExtension = import_core2.Extension.create({
|
|
|
3063
3409
|
}
|
|
3064
3410
|
});
|
|
3065
3411
|
|
|
3412
|
+
// src/extensions/RowHeightExtension.ts
|
|
3413
|
+
var import_core5 = require("@tiptap/core");
|
|
3414
|
+
|
|
3415
|
+
// src/extensions/rowResizing.ts
|
|
3416
|
+
var import_prosemirror_state3 = require("prosemirror-state");
|
|
3417
|
+
var import_prosemirror_view2 = require("prosemirror-view");
|
|
3418
|
+
var import_prosemirror_tables = require("prosemirror-tables");
|
|
3419
|
+
|
|
3420
|
+
// src/constants/limits.ts
|
|
3421
|
+
var MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
3422
|
+
var MAX_VIDEO_FILE_SIZE = 100 * 1024 * 1024;
|
|
3423
|
+
var BLOCKED_EXTENSIONS = [".svg", ".svgz"];
|
|
3424
|
+
var ALLOWED_VIDEO_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
3425
|
+
"video/mp4",
|
|
3426
|
+
"video/webm",
|
|
3427
|
+
"video/ogg",
|
|
3428
|
+
"video/quicktime"
|
|
3429
|
+
// .mov
|
|
3430
|
+
]);
|
|
3431
|
+
var ALLOWED_VIDEO_EXTENSIONS = [
|
|
3432
|
+
".mp4",
|
|
3433
|
+
".webm",
|
|
3434
|
+
".ogg",
|
|
3435
|
+
".mov"
|
|
3436
|
+
];
|
|
3437
|
+
var ROW_RESIZE_MIN_HEIGHT = 24;
|
|
3438
|
+
var ROW_RESIZE_HANDLE_WIDTH = 5;
|
|
3439
|
+
|
|
3440
|
+
// src/extensions/rowResizing.ts
|
|
3441
|
+
var rowResizingPluginKey = new import_prosemirror_state3.PluginKey(
|
|
3442
|
+
"lumirRowResizing"
|
|
3443
|
+
);
|
|
3444
|
+
var RowResizeState = class _RowResizeState {
|
|
3445
|
+
constructor(activeHandle, dragging) {
|
|
3446
|
+
this.activeHandle = activeHandle;
|
|
3447
|
+
this.dragging = dragging;
|
|
3448
|
+
}
|
|
3449
|
+
apply(tr) {
|
|
3450
|
+
const action = tr.getMeta(rowResizingPluginKey);
|
|
3451
|
+
if (action && action.setHandle != null) {
|
|
3452
|
+
return new _RowResizeState(action.setHandle, null);
|
|
3453
|
+
}
|
|
3454
|
+
if (action && action.setDragging !== void 0) {
|
|
3455
|
+
return new _RowResizeState(this.activeHandle, action.setDragging);
|
|
3456
|
+
}
|
|
3457
|
+
if (this.activeHandle > -1 && tr.docChanged) {
|
|
3458
|
+
let handle = tr.mapping.map(this.activeHandle, -1);
|
|
3459
|
+
if (!(0, import_prosemirror_tables.pointsAtCell)(tr.doc.resolve(handle))) {
|
|
3460
|
+
handle = -1;
|
|
3461
|
+
}
|
|
3462
|
+
return new _RowResizeState(handle, this.dragging);
|
|
3463
|
+
}
|
|
3464
|
+
return this;
|
|
3465
|
+
}
|
|
3466
|
+
};
|
|
3467
|
+
function rowResizing({
|
|
3468
|
+
handleWidth = ROW_RESIZE_HANDLE_WIDTH,
|
|
3469
|
+
minHeight = ROW_RESIZE_MIN_HEIGHT
|
|
3470
|
+
} = {}) {
|
|
3471
|
+
return new import_prosemirror_state3.Plugin({
|
|
3472
|
+
key: rowResizingPluginKey,
|
|
3473
|
+
state: {
|
|
3474
|
+
init() {
|
|
3475
|
+
return new RowResizeState(-1, null);
|
|
3476
|
+
},
|
|
3477
|
+
apply(tr, prev) {
|
|
3478
|
+
return prev.apply(tr);
|
|
3479
|
+
}
|
|
3480
|
+
},
|
|
3481
|
+
props: {
|
|
3482
|
+
attributes: (state) => {
|
|
3483
|
+
const pluginState = rowResizingPluginKey.getState(state);
|
|
3484
|
+
return pluginState && pluginState.activeHandle > -1 ? { class: "row-resize-cursor" } : {};
|
|
3485
|
+
},
|
|
3486
|
+
handleDOMEvents: {
|
|
3487
|
+
mousemove: (view, event) => {
|
|
3488
|
+
handleMouseMove(view, event, handleWidth);
|
|
3489
|
+
},
|
|
3490
|
+
mouseleave: (view) => {
|
|
3491
|
+
handleMouseLeave(view);
|
|
3492
|
+
},
|
|
3493
|
+
mousedown: (view, event) => {
|
|
3494
|
+
handleMouseDown(view, event, minHeight);
|
|
3495
|
+
}
|
|
3496
|
+
},
|
|
3497
|
+
decorations: (state) => {
|
|
3498
|
+
const pluginState = rowResizingPluginKey.getState(state);
|
|
3499
|
+
if (pluginState && pluginState.activeHandle > -1) {
|
|
3500
|
+
return handleDecorations(state, pluginState);
|
|
3501
|
+
}
|
|
3502
|
+
return void 0;
|
|
3503
|
+
}
|
|
3504
|
+
}
|
|
3505
|
+
});
|
|
3506
|
+
}
|
|
3507
|
+
function handleMouseMove(view, event, handleWidth) {
|
|
3508
|
+
if (!view.editable) {
|
|
3509
|
+
return;
|
|
3510
|
+
}
|
|
3511
|
+
const pluginState = rowResizingPluginKey.getState(view.state);
|
|
3512
|
+
if (!pluginState) {
|
|
3513
|
+
return;
|
|
3514
|
+
}
|
|
3515
|
+
if (!pluginState.dragging) {
|
|
3516
|
+
const target = domCellAround(event.target);
|
|
3517
|
+
let cell = -1;
|
|
3518
|
+
if (target) {
|
|
3519
|
+
const { top, bottom } = target.getBoundingClientRect();
|
|
3520
|
+
if (event.clientY - top <= handleWidth) {
|
|
3521
|
+
cell = edgeCell(view, event, "top", handleWidth);
|
|
3522
|
+
} else if (bottom - event.clientY <= handleWidth) {
|
|
3523
|
+
cell = edgeCell(view, event, "bottom", handleWidth);
|
|
3524
|
+
}
|
|
3525
|
+
}
|
|
3526
|
+
if (cell !== pluginState.activeHandle) {
|
|
3527
|
+
updateHandle(view, cell);
|
|
3528
|
+
}
|
|
3529
|
+
}
|
|
3530
|
+
}
|
|
3531
|
+
function handleMouseLeave(view) {
|
|
3532
|
+
if (!view.editable) {
|
|
3533
|
+
return;
|
|
3534
|
+
}
|
|
3535
|
+
const pluginState = rowResizingPluginKey.getState(view.state);
|
|
3536
|
+
if (pluginState && pluginState.activeHandle > -1 && !pluginState.dragging) {
|
|
3537
|
+
updateHandle(view, -1);
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3540
|
+
function handleMouseDown(view, event, minHeight) {
|
|
3541
|
+
if (!view.editable) {
|
|
3542
|
+
return false;
|
|
3543
|
+
}
|
|
3544
|
+
const win = view.dom.ownerDocument.defaultView ?? window;
|
|
3545
|
+
const pluginState = rowResizingPluginKey.getState(view.state);
|
|
3546
|
+
if (!pluginState || pluginState.activeHandle === -1 || pluginState.dragging) {
|
|
3547
|
+
return false;
|
|
3548
|
+
}
|
|
3549
|
+
const startHeight = currentRowHeight(view, pluginState.activeHandle);
|
|
3550
|
+
setDragging(view, {
|
|
3551
|
+
startY: event.clientY,
|
|
3552
|
+
startHeight,
|
|
3553
|
+
currentHeight: startHeight
|
|
3554
|
+
});
|
|
3555
|
+
function finish(finishEvent) {
|
|
3556
|
+
win.removeEventListener("mouseup", finish);
|
|
3557
|
+
win.removeEventListener("mousemove", move);
|
|
3558
|
+
const ps = rowResizingPluginKey.getState(view.state);
|
|
3559
|
+
if (ps?.dragging) {
|
|
3560
|
+
const finalHeight = draggedHeight(ps.dragging, finishEvent, minHeight);
|
|
3561
|
+
setDragging(view, null);
|
|
3562
|
+
commitRowHeight(view, ps.activeHandle, finalHeight);
|
|
3563
|
+
}
|
|
3564
|
+
}
|
|
3565
|
+
function move(moveEvent) {
|
|
3566
|
+
if (moveEvent.buttons === 0 || moveEvent.buttons === void 0 && !moveEvent.which) {
|
|
3567
|
+
return finish(moveEvent);
|
|
3568
|
+
}
|
|
3569
|
+
const ps = rowResizingPluginKey.getState(view.state);
|
|
3570
|
+
if (!ps?.dragging) {
|
|
3571
|
+
return;
|
|
3572
|
+
}
|
|
3573
|
+
const h = draggedHeight(ps.dragging, moveEvent, minHeight);
|
|
3574
|
+
if (h !== ps.dragging.currentHeight) {
|
|
3575
|
+
setDragging(view, { ...ps.dragging, currentHeight: h });
|
|
3576
|
+
}
|
|
3577
|
+
}
|
|
3578
|
+
win.addEventListener("mouseup", finish);
|
|
3579
|
+
win.addEventListener("mousemove", move);
|
|
3580
|
+
event.preventDefault();
|
|
3581
|
+
return true;
|
|
3582
|
+
}
|
|
3583
|
+
function setDragging(view, dragging) {
|
|
3584
|
+
view.dispatch(
|
|
3585
|
+
view.state.tr.setMeta(rowResizingPluginKey, { setDragging: dragging })
|
|
3586
|
+
);
|
|
3587
|
+
}
|
|
3588
|
+
function currentRowHeight(view, cellPos) {
|
|
3589
|
+
const info = targetRowInfo(view, cellPos);
|
|
3590
|
+
const tr = rowTrElement(view, cellPos, info.row);
|
|
3591
|
+
return tr ? tr.offsetHeight : ROW_RESIZE_MIN_HEIGHT;
|
|
3592
|
+
}
|
|
3593
|
+
function commitRowHeight(view, cellPos, height) {
|
|
3594
|
+
const { table, map, start, row } = targetRowInfo(view, cellPos);
|
|
3595
|
+
const tr = view.state.tr;
|
|
3596
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3597
|
+
for (let col = 0; col < map.width; col++) {
|
|
3598
|
+
const cellRelPos = map.map[row * map.width + col];
|
|
3599
|
+
if (seen.has(cellRelPos)) {
|
|
3600
|
+
continue;
|
|
3601
|
+
}
|
|
3602
|
+
seen.add(cellRelPos);
|
|
3603
|
+
const rect = map.findCell(cellRelPos);
|
|
3604
|
+
if (rect.bottom - 1 !== row) {
|
|
3605
|
+
continue;
|
|
3606
|
+
}
|
|
3607
|
+
const node = table.nodeAt(cellRelPos);
|
|
3608
|
+
if (!node || node.attrs.rowHeight === height) {
|
|
3609
|
+
continue;
|
|
3610
|
+
}
|
|
3611
|
+
tr.setNodeMarkup(start + cellRelPos, void 0, {
|
|
3612
|
+
...node.attrs,
|
|
3613
|
+
rowHeight: height
|
|
3614
|
+
});
|
|
3615
|
+
}
|
|
3616
|
+
if (tr.docChanged) {
|
|
3617
|
+
view.dispatch(tr);
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
function targetRowInfo(view, cellPos) {
|
|
3621
|
+
const $cell = view.state.doc.resolve(cellPos);
|
|
3622
|
+
const table = $cell.node(-1);
|
|
3623
|
+
const map = import_prosemirror_tables.TableMap.get(table);
|
|
3624
|
+
const start = $cell.start(-1);
|
|
3625
|
+
const rect = map.findCell($cell.pos - start);
|
|
3626
|
+
return { table, map, start, row: rect.bottom - 1, $cell };
|
|
3627
|
+
}
|
|
3628
|
+
function rowTrElement(view, cellPos, row) {
|
|
3629
|
+
let dom = view.nodeDOM(cellPos);
|
|
3630
|
+
while (dom && dom.nodeName !== "TABLE") {
|
|
3631
|
+
dom = dom.parentNode;
|
|
3632
|
+
}
|
|
3633
|
+
if (!dom) {
|
|
3634
|
+
return null;
|
|
3635
|
+
}
|
|
3636
|
+
return dom.rows[row] ?? null;
|
|
3637
|
+
}
|
|
3638
|
+
function domCellAround(target) {
|
|
3639
|
+
let node = target;
|
|
3640
|
+
while (node && node.nodeName !== "TD" && node.nodeName !== "TH") {
|
|
3641
|
+
node = node.classList?.contains("ProseMirror") ? null : node.parentNode;
|
|
3642
|
+
}
|
|
3643
|
+
return node;
|
|
3644
|
+
}
|
|
3645
|
+
function edgeCell(view, event, side, handleWidth) {
|
|
3646
|
+
const offset2 = side === "bottom" ? -handleWidth : handleWidth;
|
|
3647
|
+
const found = view.posAtCoords({
|
|
3648
|
+
left: event.clientX,
|
|
3649
|
+
top: event.clientY + offset2
|
|
3650
|
+
});
|
|
3651
|
+
if (!found) {
|
|
3652
|
+
return -1;
|
|
3653
|
+
}
|
|
3654
|
+
const $cell = (0, import_prosemirror_tables.cellAround)(view.state.doc.resolve(found.pos));
|
|
3655
|
+
if (!$cell) {
|
|
3656
|
+
return -1;
|
|
3657
|
+
}
|
|
3658
|
+
if (side === "bottom") {
|
|
3659
|
+
return $cell.pos;
|
|
3660
|
+
}
|
|
3661
|
+
const map = import_prosemirror_tables.TableMap.get($cell.node(-1));
|
|
3662
|
+
const start = $cell.start(-1);
|
|
3663
|
+
const index = map.map.indexOf($cell.pos - start);
|
|
3664
|
+
return index < map.width ? -1 : start + map.map[index - map.width];
|
|
3665
|
+
}
|
|
3666
|
+
function updateHandle(view, value) {
|
|
3667
|
+
view.dispatch(
|
|
3668
|
+
view.state.tr.setMeta(rowResizingPluginKey, { setHandle: value })
|
|
3669
|
+
);
|
|
3670
|
+
}
|
|
3671
|
+
function draggedHeight(dragging, event, minHeight) {
|
|
3672
|
+
const offset2 = event.clientY - dragging.startY;
|
|
3673
|
+
return Math.max(minHeight, dragging.startHeight + offset2);
|
|
3674
|
+
}
|
|
3675
|
+
function handleDecorations(state, pluginState) {
|
|
3676
|
+
const decorations = [];
|
|
3677
|
+
const $cell = state.doc.resolve(pluginState.activeHandle);
|
|
3678
|
+
const table = $cell.node(-1);
|
|
3679
|
+
if (!table) {
|
|
3680
|
+
return import_prosemirror_view2.DecorationSet.empty;
|
|
3681
|
+
}
|
|
3682
|
+
const map = import_prosemirror_tables.TableMap.get(table);
|
|
3683
|
+
const start = $cell.start(-1);
|
|
3684
|
+
const row = map.findCell($cell.pos - start).bottom - 1;
|
|
3685
|
+
const dragging = pluginState.dragging;
|
|
3686
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3687
|
+
for (let col = 0; col < map.width; col++) {
|
|
3688
|
+
const cellRelPos = map.map[row * map.width + col];
|
|
3689
|
+
if (seen.has(cellRelPos)) {
|
|
3690
|
+
continue;
|
|
3691
|
+
}
|
|
3692
|
+
seen.add(cellRelPos);
|
|
3693
|
+
if (map.findCell(cellRelPos).bottom - 1 !== row) {
|
|
3694
|
+
continue;
|
|
3695
|
+
}
|
|
3696
|
+
const node = table.nodeAt(cellRelPos);
|
|
3697
|
+
if (!node) {
|
|
3698
|
+
continue;
|
|
3699
|
+
}
|
|
3700
|
+
const from = start + cellRelPos;
|
|
3701
|
+
const to = from + node.nodeSize;
|
|
3702
|
+
if (dragging) {
|
|
3703
|
+
decorations.push(
|
|
3704
|
+
import_prosemirror_view2.Decoration.node(from, to, {
|
|
3705
|
+
class: "row-resize-dragging",
|
|
3706
|
+
style: `height: ${dragging.currentHeight}px`
|
|
3707
|
+
})
|
|
3708
|
+
);
|
|
3709
|
+
}
|
|
3710
|
+
const handle = document.createElement("div");
|
|
3711
|
+
handle.className = "row-resize-handle";
|
|
3712
|
+
decorations.push(import_prosemirror_view2.Decoration.widget(to - 1, handle));
|
|
3713
|
+
}
|
|
3714
|
+
return import_prosemirror_view2.DecorationSet.create(state.doc, decorations);
|
|
3715
|
+
}
|
|
3716
|
+
|
|
3717
|
+
// src/extensions/tableCellAttrPreserve.ts
|
|
3718
|
+
var import_prosemirror_state4 = require("prosemirror-state");
|
|
3719
|
+
var tableCellAttrPreserveKey = new import_prosemirror_state4.PluginKey(
|
|
3720
|
+
"lumirTableCellAttrPreserve"
|
|
3721
|
+
);
|
|
3722
|
+
var PRESERVED_ATTRS = [
|
|
3723
|
+
{ name: "rowHeight", default: null },
|
|
3724
|
+
{ name: "verticalAlignment", default: "top" }
|
|
3725
|
+
];
|
|
3726
|
+
function isMeaningful(attrName, value, def) {
|
|
3727
|
+
if (value === null || value === void 0) {
|
|
3728
|
+
return false;
|
|
3729
|
+
}
|
|
3730
|
+
return value !== def;
|
|
3731
|
+
}
|
|
3732
|
+
function meaningfulAttrs(node) {
|
|
3733
|
+
let out = null;
|
|
3734
|
+
for (const { name, default: def } of PRESERVED_ATTRS) {
|
|
3735
|
+
const v = node.attrs?.[name];
|
|
3736
|
+
if (isMeaningful(name, v, def)) {
|
|
3737
|
+
(out ?? (out = {}))[name] = v;
|
|
3738
|
+
}
|
|
3739
|
+
}
|
|
3740
|
+
return out;
|
|
3741
|
+
}
|
|
3742
|
+
function collectCellAttrs(doc) {
|
|
3743
|
+
const result = /* @__PURE__ */ new Map();
|
|
3744
|
+
doc.descendants((node) => {
|
|
3745
|
+
if (node.type.name !== "blockContainer") {
|
|
3746
|
+
return void 0;
|
|
3747
|
+
}
|
|
3748
|
+
const id = node.attrs?.id;
|
|
3749
|
+
const table = node.firstChild;
|
|
3750
|
+
if (!id || table?.type.name !== "table") {
|
|
3751
|
+
return void 0;
|
|
3752
|
+
}
|
|
3753
|
+
const cells = /* @__PURE__ */ new Map();
|
|
3754
|
+
let rowIndex = 0;
|
|
3755
|
+
table.forEach((rowNode) => {
|
|
3756
|
+
if (rowNode.type.name === "tableRow") {
|
|
3757
|
+
let cellIndex = 0;
|
|
3758
|
+
rowNode.forEach((cellNode) => {
|
|
3759
|
+
const attrs = meaningfulAttrs(cellNode);
|
|
3760
|
+
if (attrs) {
|
|
3761
|
+
cells.set(`${rowIndex}:${cellIndex}`, attrs);
|
|
3762
|
+
}
|
|
3763
|
+
cellIndex++;
|
|
3764
|
+
});
|
|
3765
|
+
rowIndex++;
|
|
3766
|
+
}
|
|
3767
|
+
});
|
|
3768
|
+
if (cells.size > 0) {
|
|
3769
|
+
result.set(id, cells);
|
|
3770
|
+
}
|
|
3771
|
+
return false;
|
|
3772
|
+
});
|
|
3773
|
+
return result;
|
|
3774
|
+
}
|
|
3775
|
+
function tableCellAttrPreserve() {
|
|
3776
|
+
return new import_prosemirror_state4.Plugin({
|
|
3777
|
+
key: tableCellAttrPreserveKey,
|
|
3778
|
+
appendTransaction(transactions, oldState, newState) {
|
|
3779
|
+
if (!transactions.some((tr2) => tr2.docChanged)) {
|
|
3780
|
+
return null;
|
|
3781
|
+
}
|
|
3782
|
+
const oldMap = collectCellAttrs(oldState.doc);
|
|
3783
|
+
if (oldMap.size === 0) {
|
|
3784
|
+
return null;
|
|
3785
|
+
}
|
|
3786
|
+
const tr = newState.tr;
|
|
3787
|
+
let changed = false;
|
|
3788
|
+
let curTableCells = null;
|
|
3789
|
+
let curRowIndex = -1;
|
|
3790
|
+
let curCellIndex = 0;
|
|
3791
|
+
newState.doc.descendants((node, pos) => {
|
|
3792
|
+
const name = node.type.name;
|
|
3793
|
+
if (name === "blockContainer") {
|
|
3794
|
+
const id = node.attrs?.id;
|
|
3795
|
+
const table = node.firstChild;
|
|
3796
|
+
if (id && table?.type.name === "table" && oldMap.has(id)) {
|
|
3797
|
+
curTableCells = oldMap.get(id);
|
|
3798
|
+
curRowIndex = -1;
|
|
3799
|
+
} else {
|
|
3800
|
+
curTableCells = null;
|
|
3801
|
+
}
|
|
3802
|
+
return void 0;
|
|
3803
|
+
}
|
|
3804
|
+
if (!curTableCells) {
|
|
3805
|
+
return void 0;
|
|
3806
|
+
}
|
|
3807
|
+
if (name === "tableRow") {
|
|
3808
|
+
curRowIndex++;
|
|
3809
|
+
curCellIndex = 0;
|
|
3810
|
+
return void 0;
|
|
3811
|
+
}
|
|
3812
|
+
if (name === "tableCell" || name === "tableHeader") {
|
|
3813
|
+
const wanted = curTableCells.get(`${curRowIndex}:${curCellIndex}`);
|
|
3814
|
+
curCellIndex++;
|
|
3815
|
+
if (wanted) {
|
|
3816
|
+
const patch = {};
|
|
3817
|
+
let needs = false;
|
|
3818
|
+
for (const { name: attrName, default: def } of PRESERVED_ATTRS) {
|
|
3819
|
+
if (!(attrName in wanted)) {
|
|
3820
|
+
continue;
|
|
3821
|
+
}
|
|
3822
|
+
const cur = node.attrs?.[attrName];
|
|
3823
|
+
if (cur === null || cur === void 0 || cur === def) {
|
|
3824
|
+
patch[attrName] = wanted[attrName];
|
|
3825
|
+
needs = true;
|
|
3826
|
+
}
|
|
3827
|
+
}
|
|
3828
|
+
if (needs) {
|
|
3829
|
+
tr.setNodeMarkup(pos, void 0, { ...node.attrs, ...patch });
|
|
3830
|
+
changed = true;
|
|
3831
|
+
}
|
|
3832
|
+
}
|
|
3833
|
+
return false;
|
|
3834
|
+
}
|
|
3835
|
+
return void 0;
|
|
3836
|
+
});
|
|
3837
|
+
return changed ? tr : null;
|
|
3838
|
+
}
|
|
3839
|
+
});
|
|
3840
|
+
}
|
|
3841
|
+
|
|
3842
|
+
// src/extensions/RowHeightExtension.ts
|
|
3843
|
+
var RowHeightExtension = import_core5.Extension.create({
|
|
3844
|
+
name: "rowHeight",
|
|
3845
|
+
addOptions() {
|
|
3846
|
+
return { resizable: true };
|
|
3847
|
+
},
|
|
3848
|
+
addGlobalAttributes() {
|
|
3849
|
+
return [
|
|
3850
|
+
{
|
|
3851
|
+
types: ["tableCell", "tableHeader"],
|
|
3852
|
+
attributes: {
|
|
3853
|
+
rowHeight: {
|
|
3854
|
+
default: null,
|
|
3855
|
+
parseHTML: (element) => {
|
|
3856
|
+
const fromStyle = parseInt(element.style?.height ?? "", 10);
|
|
3857
|
+
if (Number.isFinite(fromStyle) && fromStyle > 0) {
|
|
3858
|
+
return fromStyle;
|
|
3859
|
+
}
|
|
3860
|
+
const fromAttr = parseInt(
|
|
3861
|
+
element.getAttribute("data-row-height") ?? "",
|
|
3862
|
+
10
|
|
3863
|
+
);
|
|
3864
|
+
return Number.isFinite(fromAttr) && fromAttr > 0 ? fromAttr : null;
|
|
3865
|
+
},
|
|
3866
|
+
renderHTML: (attributes) => {
|
|
3867
|
+
const h = attributes.rowHeight;
|
|
3868
|
+
if (!h || typeof h !== "number") {
|
|
3869
|
+
return {};
|
|
3870
|
+
}
|
|
3871
|
+
return { style: `height: ${h}px` };
|
|
3872
|
+
}
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
];
|
|
3877
|
+
},
|
|
3878
|
+
addProseMirrorPlugins() {
|
|
3879
|
+
const plugins = [tableCellAttrPreserve()];
|
|
3880
|
+
if (this.options.resizable) {
|
|
3881
|
+
plugins.push(rowResizing());
|
|
3882
|
+
}
|
|
3883
|
+
return plugins;
|
|
3884
|
+
}
|
|
3885
|
+
});
|
|
3886
|
+
|
|
3887
|
+
// src/extensions/TableAlignmentExtension.ts
|
|
3888
|
+
var import_core6 = require("@tiptap/core");
|
|
3889
|
+
var import_prosemirror_state5 = require("prosemirror-state");
|
|
3890
|
+
var import_prosemirror_view3 = require("prosemirror-view");
|
|
3891
|
+
var tableAlignmentDecoKey = new import_prosemirror_state5.PluginKey("lumirTableAlignmentDeco");
|
|
3892
|
+
function tableAlignmentDecorationPlugin() {
|
|
3893
|
+
return new import_prosemirror_state5.Plugin({
|
|
3894
|
+
key: tableAlignmentDecoKey,
|
|
3895
|
+
props: {
|
|
3896
|
+
decorations(state) {
|
|
3897
|
+
const decorations = [];
|
|
3898
|
+
state.doc.descendants((node, pos) => {
|
|
3899
|
+
if (node.type.name === "table") {
|
|
3900
|
+
const align = node.attrs.tableAlignment;
|
|
3901
|
+
if (align && align !== "left") {
|
|
3902
|
+
decorations.push(
|
|
3903
|
+
import_prosemirror_view3.Decoration.node(pos, pos + node.nodeSize, {
|
|
3904
|
+
"data-table-alignment": align
|
|
3905
|
+
})
|
|
3906
|
+
);
|
|
3907
|
+
}
|
|
3908
|
+
return false;
|
|
3909
|
+
}
|
|
3910
|
+
return void 0;
|
|
3911
|
+
});
|
|
3912
|
+
return import_prosemirror_view3.DecorationSet.create(state.doc, decorations);
|
|
3913
|
+
}
|
|
3914
|
+
}
|
|
3915
|
+
});
|
|
3916
|
+
}
|
|
3917
|
+
var TableAlignmentExtension = import_core6.Extension.create({
|
|
3918
|
+
name: "tableAlignment",
|
|
3919
|
+
addGlobalAttributes() {
|
|
3920
|
+
return [
|
|
3921
|
+
{
|
|
3922
|
+
types: ["table"],
|
|
3923
|
+
attributes: {
|
|
3924
|
+
tableAlignment: {
|
|
3925
|
+
default: "left",
|
|
3926
|
+
parseHTML: (element) => element.getAttribute("data-table-alignment") || "left",
|
|
3927
|
+
renderHTML: (attributes) => {
|
|
3928
|
+
if (!attributes.tableAlignment || attributes.tableAlignment === "left") {
|
|
3929
|
+
return {};
|
|
3930
|
+
}
|
|
3931
|
+
return { "data-table-alignment": attributes.tableAlignment };
|
|
3932
|
+
}
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3936
|
+
];
|
|
3937
|
+
},
|
|
3938
|
+
addProseMirrorPlugins() {
|
|
3939
|
+
return [tableAlignmentDecorationPlugin()];
|
|
3940
|
+
}
|
|
3941
|
+
});
|
|
3942
|
+
|
|
3943
|
+
// src/blocks/columns/insertColumns.ts
|
|
3944
|
+
var import_prosemirror_state6 = require("prosemirror-state");
|
|
3945
|
+
function insertTwoColumns(editor) {
|
|
3946
|
+
const tiptap = editor?._tiptapEditor;
|
|
3947
|
+
if (!tiptap) {
|
|
3948
|
+
return false;
|
|
3949
|
+
}
|
|
3950
|
+
const { state, schema: schema2 } = tiptap;
|
|
3951
|
+
const { blockContainer, paragraph, column, columnList } = schema2.nodes;
|
|
3952
|
+
if (!blockContainer || !paragraph || !column || !columnList) {
|
|
3953
|
+
return false;
|
|
3954
|
+
}
|
|
3955
|
+
const $from = state.selection.$from;
|
|
3956
|
+
for (let d = $from.depth; d > 0; d--) {
|
|
3957
|
+
const name = $from.node(d).type.name;
|
|
3958
|
+
if (name === "column" || name === "columnList") {
|
|
3959
|
+
return false;
|
|
3960
|
+
}
|
|
3961
|
+
}
|
|
3962
|
+
let depth = $from.depth;
|
|
3963
|
+
while (depth > 0 && $from.node(depth).type.name !== "blockContainer") {
|
|
3964
|
+
depth--;
|
|
3965
|
+
}
|
|
3966
|
+
if (depth === 0) {
|
|
3967
|
+
return false;
|
|
3968
|
+
}
|
|
3969
|
+
const insertPos = $from.after(depth);
|
|
3970
|
+
const mkBlock = () => blockContainer.create(null, paragraph.create());
|
|
3971
|
+
const mkColumn = () => column.create(null, mkBlock());
|
|
3972
|
+
const list = columnList.create(null, [mkColumn(), mkColumn()]);
|
|
3973
|
+
try {
|
|
3974
|
+
let tr = state.tr.insert(insertPos, list);
|
|
3975
|
+
try {
|
|
3976
|
+
tr = tr.setSelection(import_prosemirror_state6.TextSelection.create(tr.doc, insertPos + 4));
|
|
3977
|
+
} catch {
|
|
3978
|
+
}
|
|
3979
|
+
tiptap.view.dispatch(tr.scrollIntoView());
|
|
3980
|
+
return true;
|
|
3981
|
+
} catch {
|
|
3982
|
+
return false;
|
|
3983
|
+
}
|
|
3984
|
+
}
|
|
3985
|
+
|
|
3066
3986
|
// src/components/CustomFormattingToolbar.tsx
|
|
3067
|
-
var
|
|
3987
|
+
var import_react30 = require("@blocknote/react");
|
|
3068
3988
|
|
|
3069
3989
|
// src/components/TextAlignButtonWithVA.tsx
|
|
3070
|
-
var
|
|
3990
|
+
var import_core7 = require("@blocknote/core");
|
|
3071
3991
|
var import_react20 = require("react");
|
|
3072
3992
|
var import_react21 = require("@blocknote/react");
|
|
3073
3993
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
@@ -3089,7 +4009,7 @@ var TextAlignButtonWithVA = (props) => {
|
|
|
3089
4009
|
const selectedBlocks = (0, import_react21.useSelectedBlocks)(editor);
|
|
3090
4010
|
const textAlignment = (0, import_react20.useMemo)(() => {
|
|
3091
4011
|
const block = selectedBlocks[0];
|
|
3092
|
-
if ((0,
|
|
4012
|
+
if ((0, import_core7.checkBlockHasDefaultProp)("textAlignment", block, editor)) {
|
|
3093
4013
|
return block.props.textAlignment;
|
|
3094
4014
|
}
|
|
3095
4015
|
if (block.type === "table") {
|
|
@@ -3098,7 +4018,7 @@ var TextAlignButtonWithVA = (props) => {
|
|
|
3098
4018
|
return;
|
|
3099
4019
|
}
|
|
3100
4020
|
const allCellsInTable = cellSelection.cells.map(
|
|
3101
|
-
({ row, col }) => (0,
|
|
4021
|
+
({ row, col }) => (0, import_core7.mapTableCell)(
|
|
3102
4022
|
block.content.rows[row].cells[col]
|
|
3103
4023
|
).props.textAlignment
|
|
3104
4024
|
);
|
|
@@ -3130,7 +4050,7 @@ var TextAlignButtonWithVA = (props) => {
|
|
|
3130
4050
|
}
|
|
3131
4051
|
}
|
|
3132
4052
|
tiptap.view?.dispatch(tr);
|
|
3133
|
-
} else if ((0,
|
|
4053
|
+
} else if ((0, import_core7.checkBlockTypeHasDefaultProp)("textAlignment", block.type, editor)) {
|
|
3134
4054
|
editor.updateBlock(block, {
|
|
3135
4055
|
props: { textAlignment: newAlignment }
|
|
3136
4056
|
});
|
|
@@ -3246,14 +4166,74 @@ var VerticalAlignButton = (props) => {
|
|
|
3246
4166
|
);
|
|
3247
4167
|
};
|
|
3248
4168
|
|
|
3249
|
-
// src/components/
|
|
3250
|
-
var import_react24 = require("
|
|
3251
|
-
var import_react25 = require("react");
|
|
4169
|
+
// src/components/TableAlignButton.tsx
|
|
4170
|
+
var import_react24 = require("react");
|
|
4171
|
+
var import_react25 = require("@blocknote/react");
|
|
3252
4172
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4173
|
+
var icons3 = {
|
|
4174
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
|
|
4175
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("rect", { x: "1.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
|
|
4176
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
|
|
4177
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
|
|
4178
|
+
] }),
|
|
4179
|
+
center: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
|
|
4180
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("rect", { x: "4.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
|
|
4181
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
|
|
4182
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
|
|
4183
|
+
] }),
|
|
4184
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
|
|
4185
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("rect", { x: "7.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
|
|
4186
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
|
|
4187
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
|
|
4188
|
+
] })
|
|
4189
|
+
};
|
|
4190
|
+
var tooltips2 = {
|
|
4191
|
+
left: "\uD45C \uC67C\uCABD \uC815\uB82C",
|
|
4192
|
+
center: "\uD45C \uAC00\uC6B4\uB370 \uC815\uB82C",
|
|
4193
|
+
right: "\uD45C \uC624\uB978\uCABD \uC815\uB82C"
|
|
4194
|
+
};
|
|
4195
|
+
var TableAlignButton = (props) => {
|
|
4196
|
+
const Components = (0, import_react25.useComponentsContext)();
|
|
4197
|
+
const editor = (0, import_react25.useBlockNoteEditor)();
|
|
4198
|
+
const selectedBlocks = (0, import_react25.useSelectedBlocks)(editor);
|
|
4199
|
+
const tableBlock = (0, import_react24.useMemo)(
|
|
4200
|
+
() => selectedBlocks.find((block) => block.type === "table"),
|
|
4201
|
+
[selectedBlocks]
|
|
4202
|
+
);
|
|
4203
|
+
const current = (0, import_react24.useMemo)(() => {
|
|
4204
|
+
if (!tableBlock?.id) return "left";
|
|
4205
|
+
return getTableAlignment(editor, tableBlock.id);
|
|
4206
|
+
}, [editor, tableBlock, selectedBlocks]);
|
|
4207
|
+
const apply = (0, import_react24.useCallback)(() => {
|
|
4208
|
+
if (!tableBlock?.id) return;
|
|
4209
|
+
editor.focus();
|
|
4210
|
+
setTableAlignment(editor, tableBlock.id, props.alignment);
|
|
4211
|
+
}, [editor, tableBlock, props.alignment]);
|
|
4212
|
+
if (!tableBlock || !editor.isEditable) {
|
|
4213
|
+
return null;
|
|
4214
|
+
}
|
|
4215
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4216
|
+
Components.FormattingToolbar.Button,
|
|
4217
|
+
{
|
|
4218
|
+
className: "bn-button",
|
|
4219
|
+
"data-test": `tableAlign${props.alignment.charAt(0).toUpperCase() + props.alignment.slice(1)}`,
|
|
4220
|
+
onClick: apply,
|
|
4221
|
+
isSelected: current === props.alignment,
|
|
4222
|
+
label: tooltips2[props.alignment],
|
|
4223
|
+
mainTooltip: tooltips2[props.alignment],
|
|
4224
|
+
icon: icons3[props.alignment]
|
|
4225
|
+
}
|
|
4226
|
+
);
|
|
4227
|
+
};
|
|
4228
|
+
|
|
4229
|
+
// src/components/FontSizeButton.tsx
|
|
4230
|
+
var import_react26 = require("@blocknote/react");
|
|
4231
|
+
var import_react27 = require("react");
|
|
4232
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3253
4233
|
var DEFAULT_LABEL2 = "\uAE30\uBCF8";
|
|
3254
4234
|
var toLabel2 = (size) => size.replace(/px$/, "");
|
|
3255
4235
|
function FontSizeIcon({ size }) {
|
|
3256
|
-
return /* @__PURE__ */ (0,
|
|
4236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3257
4237
|
"span",
|
|
3258
4238
|
{
|
|
3259
4239
|
style: {
|
|
@@ -3268,21 +4248,21 @@ function FontSizeIcon({ size }) {
|
|
|
3268
4248
|
);
|
|
3269
4249
|
}
|
|
3270
4250
|
function FontSizeButton2() {
|
|
3271
|
-
const Components = (0,
|
|
3272
|
-
const editor = (0,
|
|
4251
|
+
const Components = (0, import_react26.useComponentsContext)();
|
|
4252
|
+
const editor = (0, import_react26.useBlockNoteEditor)();
|
|
3273
4253
|
const ed = editor;
|
|
3274
4254
|
const styleSchema = editor.schema.styleSchema;
|
|
3275
4255
|
const fontSizeInSchema = styleSchema.fontSize?.type === "fontSize" && styleSchema.fontSize?.propSchema === "string";
|
|
3276
|
-
const selectedBlocks = (0,
|
|
3277
|
-
const [currentSize, setCurrentSize] = (0,
|
|
4256
|
+
const selectedBlocks = (0, import_react26.useSelectedBlocks)(editor);
|
|
4257
|
+
const [currentSize, setCurrentSize] = (0, import_react27.useState)(
|
|
3278
4258
|
fontSizeInSchema ? ed.getActiveStyles().fontSize || "" : ""
|
|
3279
4259
|
);
|
|
3280
|
-
(0,
|
|
4260
|
+
(0, import_react26.useEditorContentOrSelectionChange)(() => {
|
|
3281
4261
|
if (fontSizeInSchema) {
|
|
3282
4262
|
setCurrentSize(ed.getActiveStyles().fontSize || "");
|
|
3283
4263
|
}
|
|
3284
4264
|
}, editor);
|
|
3285
|
-
const setFontSize = (0,
|
|
4265
|
+
const setFontSize = (0, import_react27.useCallback)(
|
|
3286
4266
|
(size) => {
|
|
3287
4267
|
size === "" ? ed.removeStyles({ fontSize: "" }) : ed.addStyles({ fontSize: size });
|
|
3288
4268
|
setTimeout(() => editor.focus());
|
|
@@ -3290,7 +4270,7 @@ function FontSizeButton2() {
|
|
|
3290
4270
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3291
4271
|
[editor]
|
|
3292
4272
|
);
|
|
3293
|
-
const show = (0,
|
|
4273
|
+
const show = (0, import_react27.useMemo)(() => {
|
|
3294
4274
|
if (!fontSizeInSchema) {
|
|
3295
4275
|
return false;
|
|
3296
4276
|
}
|
|
@@ -3305,20 +4285,20 @@ function FontSizeButton2() {
|
|
|
3305
4285
|
return null;
|
|
3306
4286
|
}
|
|
3307
4287
|
const tooltip = "\uAE00\uC790 \uD06C\uAE30";
|
|
3308
|
-
return /* @__PURE__ */ (0,
|
|
3309
|
-
/* @__PURE__ */ (0,
|
|
4288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Components.Generic.Menu.Root, { children: [
|
|
4289
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Components.Generic.Menu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3310
4290
|
Components.FormattingToolbar.Button,
|
|
3311
4291
|
{
|
|
3312
4292
|
className: "bn-button",
|
|
3313
4293
|
"data-test": "font-size",
|
|
3314
4294
|
label: tooltip,
|
|
3315
4295
|
mainTooltip: tooltip,
|
|
3316
|
-
icon: /* @__PURE__ */ (0,
|
|
4296
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(FontSizeIcon, { size: currentSize })
|
|
3317
4297
|
}
|
|
3318
4298
|
) }),
|
|
3319
|
-
/* @__PURE__ */ (0,
|
|
3320
|
-
/* @__PURE__ */ (0,
|
|
3321
|
-
/* @__PURE__ */ (0,
|
|
4299
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Components.Generic.Menu.Dropdown, { className: "bn-menu-dropdown", children: [
|
|
4300
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Components.Generic.Menu.Label, { children: "\uAE00\uC790 \uD06C\uAE30" }),
|
|
4301
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3322
4302
|
Components.Generic.Menu.Item,
|
|
3323
4303
|
{
|
|
3324
4304
|
onClick: () => setFontSize(""),
|
|
@@ -3328,7 +4308,7 @@ function FontSizeButton2() {
|
|
|
3328
4308
|
},
|
|
3329
4309
|
"font-size-default"
|
|
3330
4310
|
),
|
|
3331
|
-
FONT_SIZE_PRESETS.map((size) => /* @__PURE__ */ (0,
|
|
4311
|
+
FONT_SIZE_PRESETS.map((size) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3332
4312
|
Components.Generic.Menu.Item,
|
|
3333
4313
|
{
|
|
3334
4314
|
onClick: () => setFontSize(size),
|
|
@@ -3343,10 +4323,10 @@ function FontSizeButton2() {
|
|
|
3343
4323
|
}
|
|
3344
4324
|
|
|
3345
4325
|
// src/components/color/LumirColorControls.tsx
|
|
3346
|
-
var
|
|
3347
|
-
var
|
|
3348
|
-
var
|
|
3349
|
-
var
|
|
4326
|
+
var import_core8 = require("@blocknote/core");
|
|
4327
|
+
var import_react28 = require("@blocknote/react");
|
|
4328
|
+
var import_react29 = require("react");
|
|
4329
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3350
4330
|
var COLORS = [
|
|
3351
4331
|
"default",
|
|
3352
4332
|
"gray",
|
|
@@ -3363,7 +4343,7 @@ function ColorIcon(props) {
|
|
|
3363
4343
|
const textColor = props.textColor || "default";
|
|
3364
4344
|
const backgroundColor = props.backgroundColor || "default";
|
|
3365
4345
|
const size = props.size || 16;
|
|
3366
|
-
return /* @__PURE__ */ (0,
|
|
4346
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3367
4347
|
"div",
|
|
3368
4348
|
{
|
|
3369
4349
|
className: "bn-color-icon",
|
|
@@ -3382,7 +4362,7 @@ function ColorIcon(props) {
|
|
|
3382
4362
|
);
|
|
3383
4363
|
}
|
|
3384
4364
|
function CellFillIcon({ size = 18 }) {
|
|
3385
|
-
return /* @__PURE__ */ (0,
|
|
4365
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3386
4366
|
"svg",
|
|
3387
4367
|
{
|
|
3388
4368
|
width: size,
|
|
@@ -3391,17 +4371,17 @@ function CellFillIcon({ size = 18 }) {
|
|
|
3391
4371
|
fill: "currentColor",
|
|
3392
4372
|
style: { pointerEvents: "none" },
|
|
3393
4373
|
"aria-hidden": "true",
|
|
3394
|
-
children: /* @__PURE__ */ (0,
|
|
4374
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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" })
|
|
3395
4375
|
}
|
|
3396
4376
|
);
|
|
3397
4377
|
}
|
|
3398
4378
|
function LumirColorPicker(props) {
|
|
3399
|
-
const Components = (0,
|
|
3400
|
-
const dict = (0,
|
|
3401
|
-
return /* @__PURE__ */ (0,
|
|
3402
|
-
props.text ? /* @__PURE__ */ (0,
|
|
3403
|
-
/* @__PURE__ */ (0,
|
|
3404
|
-
COLORS.map((color) => /* @__PURE__ */ (0,
|
|
4379
|
+
const Components = (0, import_react28.useComponentsContext)();
|
|
4380
|
+
const dict = (0, import_react28.useDictionary)();
|
|
4381
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4382
|
+
props.text ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4383
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Components.Generic.Menu.Label, { children: props.textTitle ?? dict.color_picker.text_title }),
|
|
4384
|
+
COLORS.map((color) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3405
4385
|
Components.Generic.Menu.Item,
|
|
3406
4386
|
{
|
|
3407
4387
|
onClick: () => {
|
|
@@ -3409,16 +4389,16 @@ function LumirColorPicker(props) {
|
|
|
3409
4389
|
props.text.setColor(color);
|
|
3410
4390
|
},
|
|
3411
4391
|
"data-test": "text-color-" + color,
|
|
3412
|
-
icon: /* @__PURE__ */ (0,
|
|
4392
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ColorIcon, { textColor: color, size: props.iconSize }),
|
|
3413
4393
|
checked: props.text.color === color,
|
|
3414
4394
|
children: dict.color_picker.colors[color]
|
|
3415
4395
|
},
|
|
3416
4396
|
"text-color-" + color
|
|
3417
4397
|
))
|
|
3418
4398
|
] }) : null,
|
|
3419
|
-
props.background ? /* @__PURE__ */ (0,
|
|
3420
|
-
/* @__PURE__ */ (0,
|
|
3421
|
-
COLORS.map((color) => /* @__PURE__ */ (0,
|
|
4399
|
+
props.background ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4400
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Components.Generic.Menu.Label, { children: props.backgroundTitle ?? dict.color_picker.background_title }),
|
|
4401
|
+
COLORS.map((color) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3422
4402
|
Components.Generic.Menu.Item,
|
|
3423
4403
|
{
|
|
3424
4404
|
onClick: () => {
|
|
@@ -3426,7 +4406,7 @@ function LumirColorPicker(props) {
|
|
|
3426
4406
|
props.background.setColor(color);
|
|
3427
4407
|
},
|
|
3428
4408
|
"data-test": "background-color-" + color,
|
|
3429
|
-
icon: /* @__PURE__ */ (0,
|
|
4409
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ColorIcon, { backgroundColor: color, size: props.iconSize }),
|
|
3430
4410
|
checked: props.background.color === color,
|
|
3431
4411
|
children: dict.color_picker.colors[color]
|
|
3432
4412
|
},
|
|
@@ -3436,20 +4416,20 @@ function LumirColorPicker(props) {
|
|
|
3436
4416
|
] });
|
|
3437
4417
|
}
|
|
3438
4418
|
function LumirColorStyleButton() {
|
|
3439
|
-
const Components = (0,
|
|
3440
|
-
const editor = (0,
|
|
4419
|
+
const Components = (0, import_react28.useComponentsContext)();
|
|
4420
|
+
const editor = (0, import_react28.useBlockNoteEditor)();
|
|
3441
4421
|
const ed = editor;
|
|
3442
4422
|
const styleSchema = editor.schema.styleSchema;
|
|
3443
4423
|
const textColorInSchema = styleSchema.textColor?.type === "textColor" && styleSchema.textColor?.propSchema === "string";
|
|
3444
4424
|
const backgroundColorInSchema = styleSchema.backgroundColor?.type === "backgroundColor" && styleSchema.backgroundColor?.propSchema === "string";
|
|
3445
|
-
const selectedBlocks = (0,
|
|
3446
|
-
const [currentTextColor, setCurrentTextColor] = (0,
|
|
4425
|
+
const selectedBlocks = (0, import_react28.useSelectedBlocks)(editor);
|
|
4426
|
+
const [currentTextColor, setCurrentTextColor] = (0, import_react29.useState)(
|
|
3447
4427
|
textColorInSchema ? ed.getActiveStyles().textColor || "default" : "default"
|
|
3448
4428
|
);
|
|
3449
|
-
const [currentBackgroundColor, setCurrentBackgroundColor] = (0,
|
|
4429
|
+
const [currentBackgroundColor, setCurrentBackgroundColor] = (0, import_react29.useState)(
|
|
3450
4430
|
backgroundColorInSchema ? ed.getActiveStyles().backgroundColor || "default" : "default"
|
|
3451
4431
|
);
|
|
3452
|
-
(0,
|
|
4432
|
+
(0, import_react28.useEditorContentOrSelectionChange)(() => {
|
|
3453
4433
|
const active = ed.getActiveStyles();
|
|
3454
4434
|
if (textColorInSchema) {
|
|
3455
4435
|
setCurrentTextColor(active.textColor || "default");
|
|
@@ -3458,7 +4438,7 @@ function LumirColorStyleButton() {
|
|
|
3458
4438
|
setCurrentBackgroundColor(active.backgroundColor || "default");
|
|
3459
4439
|
}
|
|
3460
4440
|
}, editor);
|
|
3461
|
-
const setTextColor = (0,
|
|
4441
|
+
const setTextColor = (0, import_react29.useCallback)(
|
|
3462
4442
|
(color) => {
|
|
3463
4443
|
color === "default" ? ed.removeStyles({ textColor: color }) : ed.addStyles({ textColor: color });
|
|
3464
4444
|
setTimeout(() => editor.focus());
|
|
@@ -3466,7 +4446,7 @@ function LumirColorStyleButton() {
|
|
|
3466
4446
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3467
4447
|
[editor]
|
|
3468
4448
|
);
|
|
3469
|
-
const setBackgroundColor = (0,
|
|
4449
|
+
const setBackgroundColor = (0, import_react29.useCallback)(
|
|
3470
4450
|
(color) => {
|
|
3471
4451
|
color === "default" ? ed.removeStyles({ backgroundColor: color }) : ed.addStyles({ backgroundColor: color });
|
|
3472
4452
|
setTimeout(() => editor.focus());
|
|
@@ -3474,7 +4454,7 @@ function LumirColorStyleButton() {
|
|
|
3474
4454
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3475
4455
|
[editor]
|
|
3476
4456
|
);
|
|
3477
|
-
const show = (0,
|
|
4457
|
+
const show = (0, import_react29.useMemo)(() => {
|
|
3478
4458
|
if (!textColorInSchema && !backgroundColorInSchema) {
|
|
3479
4459
|
return false;
|
|
3480
4460
|
}
|
|
@@ -3489,15 +4469,15 @@ function LumirColorStyleButton() {
|
|
|
3489
4469
|
return null;
|
|
3490
4470
|
}
|
|
3491
4471
|
const tooltip = "\uD14D\uC2A4\uD2B8 \uC0C9\xB7\uBC30\uACBD";
|
|
3492
|
-
return /* @__PURE__ */ (0,
|
|
3493
|
-
/* @__PURE__ */ (0,
|
|
4472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Components.Generic.Menu.Root, { children: [
|
|
4473
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Components.Generic.Menu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3494
4474
|
Components.FormattingToolbar.Button,
|
|
3495
4475
|
{
|
|
3496
4476
|
className: "bn-button",
|
|
3497
4477
|
"data-test": "colors",
|
|
3498
4478
|
label: tooltip,
|
|
3499
4479
|
mainTooltip: tooltip,
|
|
3500
|
-
icon: /* @__PURE__ */ (0,
|
|
4480
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3501
4481
|
ColorIcon,
|
|
3502
4482
|
{
|
|
3503
4483
|
textColor: currentTextColor,
|
|
@@ -3507,11 +4487,11 @@ function LumirColorStyleButton() {
|
|
|
3507
4487
|
)
|
|
3508
4488
|
}
|
|
3509
4489
|
) }),
|
|
3510
|
-
/* @__PURE__ */ (0,
|
|
4490
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3511
4491
|
Components.Generic.Menu.Dropdown,
|
|
3512
4492
|
{
|
|
3513
4493
|
className: "bn-menu-dropdown bn-color-picker-dropdown",
|
|
3514
|
-
children: /* @__PURE__ */ (0,
|
|
4494
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3515
4495
|
LumirColorPicker,
|
|
3516
4496
|
{
|
|
3517
4497
|
textTitle: "\uD14D\uC2A4\uD2B8 \uC0C9",
|
|
@@ -3525,18 +4505,18 @@ function LumirColorStyleButton() {
|
|
|
3525
4505
|
] });
|
|
3526
4506
|
}
|
|
3527
4507
|
function LumirCellColorToolbarButton() {
|
|
3528
|
-
const Components = (0,
|
|
3529
|
-
const editor = (0,
|
|
3530
|
-
const selectedBlocks = (0,
|
|
3531
|
-
const isMultiCell = (0,
|
|
4508
|
+
const Components = (0, import_react28.useComponentsContext)();
|
|
4509
|
+
const editor = (0, import_react28.useBlockNoteEditor)();
|
|
4510
|
+
const selectedBlocks = (0, import_react28.useSelectedBlocks)(editor);
|
|
4511
|
+
const isMultiCell = (0, import_react29.useMemo)(() => {
|
|
3532
4512
|
if (selectedBlocks.length !== 1 || selectedBlocks[0].type !== "table") {
|
|
3533
4513
|
return false;
|
|
3534
4514
|
}
|
|
3535
4515
|
const cs = editor.tableHandles?.getCellSelection();
|
|
3536
4516
|
return !!cs && cs.cells.length > 1;
|
|
3537
4517
|
}, [editor, selectedBlocks]);
|
|
3538
|
-
const stashRef = (0,
|
|
3539
|
-
const applyBackground = (0,
|
|
4518
|
+
const stashRef = (0, import_react29.useRef)([]);
|
|
4519
|
+
const applyBackground = (0, import_react29.useCallback)(
|
|
3540
4520
|
(color) => {
|
|
3541
4521
|
const live = getSelectedCellPositions(editor);
|
|
3542
4522
|
const positions = live.length > 0 ? live : stashRef.current;
|
|
@@ -3549,7 +4529,7 @@ function LumirCellColorToolbarButton() {
|
|
|
3549
4529
|
return null;
|
|
3550
4530
|
}
|
|
3551
4531
|
const tooltip = "\uC140 \uBC30\uACBD\uC0C9";
|
|
3552
|
-
return /* @__PURE__ */ (0,
|
|
4532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
3553
4533
|
Components.Generic.Menu.Root,
|
|
3554
4534
|
{
|
|
3555
4535
|
onOpenChange: (open) => {
|
|
@@ -3558,21 +4538,21 @@ function LumirCellColorToolbarButton() {
|
|
|
3558
4538
|
}
|
|
3559
4539
|
},
|
|
3560
4540
|
children: [
|
|
3561
|
-
/* @__PURE__ */ (0,
|
|
4541
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Components.Generic.Menu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3562
4542
|
Components.FormattingToolbar.Button,
|
|
3563
4543
|
{
|
|
3564
4544
|
className: "bn-button",
|
|
3565
4545
|
"data-test": "cell-colors",
|
|
3566
4546
|
label: tooltip,
|
|
3567
4547
|
mainTooltip: tooltip,
|
|
3568
|
-
icon: /* @__PURE__ */ (0,
|
|
4548
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CellFillIcon, { size: 18 })
|
|
3569
4549
|
}
|
|
3570
4550
|
) }),
|
|
3571
|
-
/* @__PURE__ */ (0,
|
|
4551
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3572
4552
|
Components.Generic.Menu.Dropdown,
|
|
3573
4553
|
{
|
|
3574
4554
|
className: "bn-menu-dropdown bn-color-picker-dropdown",
|
|
3575
|
-
children: /* @__PURE__ */ (0,
|
|
4555
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3576
4556
|
LumirColorPicker,
|
|
3577
4557
|
{
|
|
3578
4558
|
backgroundTitle: "\uC140 \uBC30\uACBD",
|
|
@@ -3586,12 +4566,12 @@ function LumirCellColorToolbarButton() {
|
|
|
3586
4566
|
);
|
|
3587
4567
|
}
|
|
3588
4568
|
function LumirCellColorPickerButton(props) {
|
|
3589
|
-
const Components = (0,
|
|
3590
|
-
const editor = (0,
|
|
4569
|
+
const Components = (0, import_react28.useComponentsContext)();
|
|
4570
|
+
const editor = (0, import_react28.useBlockNoteEditor)();
|
|
3591
4571
|
const updateColor = (color, type) => {
|
|
3592
4572
|
const newTable = props.block.content.rows.map((row) => ({
|
|
3593
4573
|
...row,
|
|
3594
|
-
cells: row.cells.map((cell) => (0,
|
|
4574
|
+
cells: row.cells.map((cell) => (0, import_core8.mapTableCell)(cell))
|
|
3595
4575
|
}));
|
|
3596
4576
|
if (type === "text") {
|
|
3597
4577
|
newTable[props.rowIndex].cells[props.colIndex].props.textColor = color;
|
|
@@ -3608,25 +4588,25 @@ function LumirCellColorPickerButton(props) {
|
|
|
3608
4588
|
if (!currentCell || editor.settings.tables.cellTextColor === false && editor.settings.tables.cellBackgroundColor === false) {
|
|
3609
4589
|
return null;
|
|
3610
4590
|
}
|
|
3611
|
-
return /* @__PURE__ */ (0,
|
|
3612
|
-
/* @__PURE__ */ (0,
|
|
3613
|
-
/* @__PURE__ */ (0,
|
|
4591
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Components.Generic.Menu.Root, { position: "right", sub: true, children: [
|
|
4592
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Components.Generic.Menu.Trigger, { sub: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Components.Generic.Menu.Item, { className: "bn-menu-item", subTrigger: true, children: "\uC140 \uC0C9\xB7\uBC30\uACBD" }) }),
|
|
4593
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3614
4594
|
Components.Generic.Menu.Dropdown,
|
|
3615
4595
|
{
|
|
3616
4596
|
sub: true,
|
|
3617
4597
|
className: "bn-menu-dropdown bn-color-picker-dropdown",
|
|
3618
|
-
children: /* @__PURE__ */ (0,
|
|
4598
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3619
4599
|
LumirColorPicker,
|
|
3620
4600
|
{
|
|
3621
4601
|
iconSize: 18,
|
|
3622
4602
|
textTitle: "\uC140 \uAE00\uC790\uC0C9",
|
|
3623
4603
|
backgroundTitle: "\uC140 \uBC30\uACBD",
|
|
3624
4604
|
text: editor.settings.tables.cellTextColor ? {
|
|
3625
|
-
color: (0,
|
|
4605
|
+
color: (0, import_core8.isTableCell)(currentCell) ? currentCell.props.textColor : "default",
|
|
3626
4606
|
setColor: (color) => updateColor(color, "text")
|
|
3627
4607
|
} : void 0,
|
|
3628
4608
|
background: editor.settings.tables.cellBackgroundColor ? {
|
|
3629
|
-
color: (0,
|
|
4609
|
+
color: (0, import_core8.isTableCell)(currentCell) ? currentCell.props.backgroundColor : "default",
|
|
3630
4610
|
setColor: (color) => updateColor(color, "background")
|
|
3631
4611
|
} : void 0
|
|
3632
4612
|
}
|
|
@@ -3636,21 +4616,21 @@ function LumirCellColorPickerButton(props) {
|
|
|
3636
4616
|
] });
|
|
3637
4617
|
}
|
|
3638
4618
|
function LumirTableCellMenu(props) {
|
|
3639
|
-
const Components = (0,
|
|
3640
|
-
return /* @__PURE__ */ (0,
|
|
4619
|
+
const Components = (0, import_react28.useComponentsContext)();
|
|
4620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3641
4621
|
Components.Generic.Menu.Dropdown,
|
|
3642
4622
|
{
|
|
3643
4623
|
className: "bn-menu-dropdown bn-drag-handle-menu",
|
|
3644
|
-
children: props.children || /* @__PURE__ */ (0,
|
|
3645
|
-
/* @__PURE__ */ (0,
|
|
3646
|
-
|
|
4624
|
+
children: props.children || /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4625
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4626
|
+
import_react28.SplitButton,
|
|
3647
4627
|
{
|
|
3648
4628
|
block: props.block,
|
|
3649
4629
|
rowIndex: props.rowIndex,
|
|
3650
4630
|
colIndex: props.colIndex
|
|
3651
4631
|
}
|
|
3652
4632
|
),
|
|
3653
|
-
/* @__PURE__ */ (0,
|
|
4633
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3654
4634
|
LumirCellColorPickerButton,
|
|
3655
4635
|
{
|
|
3656
4636
|
block: props.block,
|
|
@@ -3664,96 +4644,164 @@ function LumirTableCellMenu(props) {
|
|
|
3664
4644
|
}
|
|
3665
4645
|
|
|
3666
4646
|
// src/components/CustomFormattingToolbar.tsx
|
|
3667
|
-
var
|
|
4647
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
3668
4648
|
var CustomFormattingToolbar = () => {
|
|
3669
|
-
return /* @__PURE__ */ (0,
|
|
3670
|
-
/* @__PURE__ */ (0,
|
|
3671
|
-
/* @__PURE__ */ (0,
|
|
3672
|
-
/* @__PURE__ */ (0,
|
|
3673
|
-
/* @__PURE__ */ (0,
|
|
3674
|
-
/* @__PURE__ */ (0,
|
|
3675
|
-
/* @__PURE__ */ (0,
|
|
3676
|
-
/* @__PURE__ */ (0,
|
|
3677
|
-
/* @__PURE__ */ (0,
|
|
3678
|
-
/* @__PURE__ */ (0,
|
|
3679
|
-
/* @__PURE__ */ (0,
|
|
3680
|
-
|
|
4649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react30.FormattingToolbar, { children: [
|
|
4650
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.BlockTypeSelect, {}, "blockTypeSelect"),
|
|
4651
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.TableCellMergeButton, {}, "tableCellMergeButton"),
|
|
4652
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.FileCaptionButton, {}, "fileCaptionButton"),
|
|
4653
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.FileReplaceButton, {}, "replaceFileButton"),
|
|
4654
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.FileRenameButton, {}, "fileRenameButton"),
|
|
4655
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.FileDeleteButton, {}, "fileDeleteButton"),
|
|
4656
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.FileDownloadButton, {}, "fileDownloadButton"),
|
|
4657
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.FilePreviewButton, {}, "filePreviewButton"),
|
|
4658
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.BasicTextStyleButton, { basicTextStyle: "bold" }, "boldStyleButton"),
|
|
4659
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4660
|
+
import_react30.BasicTextStyleButton,
|
|
3681
4661
|
{
|
|
3682
4662
|
basicTextStyle: "italic"
|
|
3683
4663
|
},
|
|
3684
4664
|
"italicStyleButton"
|
|
3685
4665
|
),
|
|
3686
|
-
/* @__PURE__ */ (0,
|
|
3687
|
-
|
|
4666
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4667
|
+
import_react30.BasicTextStyleButton,
|
|
3688
4668
|
{
|
|
3689
4669
|
basicTextStyle: "underline"
|
|
3690
4670
|
},
|
|
3691
4671
|
"underlineStyleButton"
|
|
3692
4672
|
),
|
|
3693
|
-
/* @__PURE__ */ (0,
|
|
3694
|
-
|
|
4673
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4674
|
+
import_react30.BasicTextStyleButton,
|
|
3695
4675
|
{
|
|
3696
4676
|
basicTextStyle: "strike"
|
|
3697
4677
|
},
|
|
3698
4678
|
"strikeStyleButton"
|
|
3699
4679
|
),
|
|
3700
|
-
/* @__PURE__ */ (0,
|
|
3701
|
-
/* @__PURE__ */ (0,
|
|
4680
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TextAlignButtonWithVA, { textAlignment: "left" }, "textAlignLeftButton"),
|
|
4681
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3702
4682
|
TextAlignButtonWithVA,
|
|
3703
4683
|
{
|
|
3704
4684
|
textAlignment: "center"
|
|
3705
4685
|
},
|
|
3706
4686
|
"textAlignCenterButton"
|
|
3707
4687
|
),
|
|
3708
|
-
/* @__PURE__ */ (0,
|
|
3709
|
-
/* @__PURE__ */ (0,
|
|
4688
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TextAlignButtonWithVA, { textAlignment: "right" }, "textAlignRightButton"),
|
|
4689
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3710
4690
|
VerticalAlignButton,
|
|
3711
4691
|
{
|
|
3712
4692
|
verticalAlignment: "top"
|
|
3713
4693
|
},
|
|
3714
4694
|
"verticalAlignTop"
|
|
3715
4695
|
),
|
|
3716
|
-
/* @__PURE__ */ (0,
|
|
4696
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3717
4697
|
VerticalAlignButton,
|
|
3718
4698
|
{
|
|
3719
4699
|
verticalAlignment: "middle"
|
|
3720
4700
|
},
|
|
3721
4701
|
"verticalAlignMiddle"
|
|
3722
4702
|
),
|
|
3723
|
-
/* @__PURE__ */ (0,
|
|
4703
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3724
4704
|
VerticalAlignButton,
|
|
3725
4705
|
{
|
|
3726
4706
|
verticalAlignment: "bottom"
|
|
3727
4707
|
},
|
|
3728
4708
|
"verticalAlignBottom"
|
|
3729
4709
|
),
|
|
3730
|
-
/* @__PURE__ */ (0,
|
|
3731
|
-
/* @__PURE__ */ (0,
|
|
3732
|
-
/* @__PURE__ */ (0,
|
|
3733
|
-
/* @__PURE__ */ (0,
|
|
3734
|
-
/* @__PURE__ */ (0,
|
|
3735
|
-
/* @__PURE__ */ (0,
|
|
4710
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TableAlignButton, { alignment: "left" }, "tableAlignLeft"),
|
|
4711
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TableAlignButton, { alignment: "center" }, "tableAlignCenter"),
|
|
4712
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TableAlignButton, { alignment: "right" }, "tableAlignRight"),
|
|
4713
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(FontSizeButton2, {}, "fontSizeButton"),
|
|
4714
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(LumirColorStyleButton, {}, "colorStyleButton"),
|
|
4715
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(LumirCellColorToolbarButton, {}, "cellColorButton"),
|
|
4716
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.NestBlockButton, {}, "nestBlockButton"),
|
|
4717
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.UnnestBlockButton, {}, "unnestBlockButton"),
|
|
4718
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react30.CreateLinkButton, {}, "createLinkButton")
|
|
3736
4719
|
] });
|
|
3737
4720
|
};
|
|
3738
4721
|
|
|
3739
|
-
// src/components/
|
|
4722
|
+
// src/components/LumirDragHandleMenu.tsx
|
|
3740
4723
|
var import_react31 = require("@blocknote/react");
|
|
3741
|
-
var
|
|
3742
|
-
var
|
|
4724
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4725
|
+
var TABLE_ALIGN_ICONS = {
|
|
4726
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
|
|
4727
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("rect", { x: "1.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
|
|
4728
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
|
|
4729
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
|
|
4730
|
+
] }),
|
|
4731
|
+
center: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
|
|
4732
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("rect", { x: "4.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
|
|
4733
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
|
|
4734
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
|
|
4735
|
+
] }),
|
|
4736
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.4", children: [
|
|
4737
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("rect", { x: "7.5", y: "4", width: "7", height: "8", rx: "1", fill: "currentColor", stroke: "none" }),
|
|
4738
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("line", { x1: "1.5", y1: "1.5", x2: "14.5", y2: "1.5" }),
|
|
4739
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("line", { x1: "1.5", y1: "14.5", x2: "14.5", y2: "14.5" })
|
|
4740
|
+
] })
|
|
4741
|
+
};
|
|
4742
|
+
var TABLE_ALIGN_LABELS = {
|
|
4743
|
+
left: "\uD45C \uC67C\uCABD \uC815\uB82C",
|
|
4744
|
+
center: "\uD45C \uAC00\uC6B4\uB370 \uC815\uB82C",
|
|
4745
|
+
right: "\uD45C \uC624\uB978\uCABD \uC815\uB82C"
|
|
4746
|
+
};
|
|
4747
|
+
function TableAlignmentItems(props) {
|
|
4748
|
+
const Components = (0, import_react31.useComponentsContext)();
|
|
4749
|
+
const editor = (0, import_react31.useBlockNoteEditor)();
|
|
4750
|
+
if (props.block?.type !== "table" || !props.block?.id) {
|
|
4751
|
+
return null;
|
|
4752
|
+
}
|
|
4753
|
+
const current = getTableAlignment(editor, props.block.id);
|
|
4754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_jsx_runtime25.Fragment, { children: ["left", "center", "right"].map((align) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4755
|
+
Components.Generic.Menu.Item,
|
|
4756
|
+
{
|
|
4757
|
+
icon: TABLE_ALIGN_ICONS[align],
|
|
4758
|
+
checked: current === align,
|
|
4759
|
+
onClick: () => {
|
|
4760
|
+
setTableAlignment(editor, props.block.id, align);
|
|
4761
|
+
editor.setTextCursorPosition(props.block.id);
|
|
4762
|
+
},
|
|
4763
|
+
children: TABLE_ALIGN_LABELS[align]
|
|
4764
|
+
},
|
|
4765
|
+
`tableAlign-${align}`
|
|
4766
|
+
)) });
|
|
4767
|
+
}
|
|
4768
|
+
var LumirDragHandleMenu = (props) => {
|
|
4769
|
+
const dict = (0, import_react31.useDictionary)();
|
|
4770
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react31.DragHandleMenu, { ...props, children: [
|
|
4771
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react31.RemoveBlockItem, { ...props, children: dict.drag_handle.delete_menuitem }),
|
|
4772
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react31.BlockColorsItem, { ...props, children: dict.drag_handle.colors_menuitem }),
|
|
4773
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react31.TableRowHeaderItem, { ...props, children: dict.drag_handle.header_row_menuitem }),
|
|
4774
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react31.TableColumnHeaderItem, { ...props, children: dict.drag_handle.header_column_menuitem }),
|
|
4775
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TableAlignmentItems, { block: props.block })
|
|
4776
|
+
] });
|
|
4777
|
+
};
|
|
4778
|
+
|
|
4779
|
+
// src/components/LumirTableHandlesController.tsx
|
|
4780
|
+
var import_react34 = require("@blocknote/react");
|
|
4781
|
+
var import_react35 = require("@floating-ui/react");
|
|
4782
|
+
var import_react36 = require("react");
|
|
3743
4783
|
|
|
3744
4784
|
// src/components/hooks/useFocusedCellHandlePositioning.ts
|
|
3745
|
-
var
|
|
3746
|
-
var
|
|
4785
|
+
var import_react32 = require("@floating-ui/react");
|
|
4786
|
+
var import_react33 = require("react");
|
|
3747
4787
|
function useFocusedCellHandlePositioning(cellEl, tbodyEl, orientation, show) {
|
|
3748
|
-
const { refs, floatingStyles, context } = (0,
|
|
4788
|
+
const { refs, floatingStyles, context, update } = (0, import_react32.useFloating)({
|
|
3749
4789
|
open: show,
|
|
3750
4790
|
placement: orientation === "row" ? "left" : orientation === "col" ? "top" : "right",
|
|
3751
4791
|
// col/row: 가장자리 선(zero-size)에, cell: 셀 우측 보더에 14px hit-area 중앙 정렬(-7).
|
|
3752
|
-
middleware: [(0,
|
|
3753
|
-
whileElementsMounted:
|
|
4792
|
+
middleware: [(0, import_react32.offset)(-7)],
|
|
4793
|
+
whileElementsMounted: import_react32.autoUpdate
|
|
3754
4794
|
});
|
|
3755
|
-
const { isMounted, styles } = (0,
|
|
3756
|
-
(0,
|
|
4795
|
+
const { isMounted, styles } = (0, import_react32.useTransitionStyles)(context);
|
|
4796
|
+
(0, import_react33.useEffect)(() => {
|
|
4797
|
+
if (!show || !tbodyEl) {
|
|
4798
|
+
return;
|
|
4799
|
+
}
|
|
4800
|
+
const ro = new ResizeObserver(() => update());
|
|
4801
|
+
ro.observe(tbodyEl);
|
|
4802
|
+
return () => ro.disconnect();
|
|
4803
|
+
}, [show, tbodyEl, update]);
|
|
4804
|
+
(0, import_react33.useEffect)(() => {
|
|
3757
4805
|
if (!cellEl) {
|
|
3758
4806
|
refs.setReference(null);
|
|
3759
4807
|
return;
|
|
@@ -3773,7 +4821,7 @@ function useFocusedCellHandlePositioning(cellEl, tbodyEl, orientation, show) {
|
|
|
3773
4821
|
}
|
|
3774
4822
|
});
|
|
3775
4823
|
}, [cellEl, tbodyEl, orientation, refs]);
|
|
3776
|
-
return (0,
|
|
4824
|
+
return (0, import_react33.useMemo)(
|
|
3777
4825
|
() => ({
|
|
3778
4826
|
isMounted,
|
|
3779
4827
|
ref: refs.setFloating,
|
|
@@ -3788,7 +4836,7 @@ function useFocusedCellHandlePositioning(cellEl, tbodyEl, orientation, show) {
|
|
|
3788
4836
|
}
|
|
3789
4837
|
|
|
3790
4838
|
// src/components/LumirTableHandlesController.tsx
|
|
3791
|
-
var
|
|
4839
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3792
4840
|
function syncCoreHoverToFocusedCell(cellEl) {
|
|
3793
4841
|
const r = cellEl.getBoundingClientRect();
|
|
3794
4842
|
cellEl.dispatchEvent(
|
|
@@ -3802,15 +4850,15 @@ function syncCoreHoverToFocusedCell(cellEl) {
|
|
|
3802
4850
|
);
|
|
3803
4851
|
}
|
|
3804
4852
|
function LumirTableHandlesController() {
|
|
3805
|
-
const editor = (0,
|
|
3806
|
-
const [focused, setFocused] = (0,
|
|
3807
|
-
const [menuContainerRef, setMenuContainerRef] = (0,
|
|
3808
|
-
const [overlayEl, setOverlayEl] = (0,
|
|
3809
|
-
const [openMenu, setOpenMenu] = (0,
|
|
3810
|
-
const frozenRef = (0,
|
|
3811
|
-
const menuOpenRef = (0,
|
|
3812
|
-
const draggingRef = (0,
|
|
3813
|
-
const recompute = (0,
|
|
4853
|
+
const editor = (0, import_react34.useBlockNoteEditor)();
|
|
4854
|
+
const [focused, setFocused] = (0, import_react36.useState)(null);
|
|
4855
|
+
const [menuContainerRef, setMenuContainerRef] = (0, import_react36.useState)(null);
|
|
4856
|
+
const [overlayEl, setOverlayEl] = (0, import_react36.useState)(null);
|
|
4857
|
+
const [openMenu, setOpenMenu] = (0, import_react36.useState)(null);
|
|
4858
|
+
const frozenRef = (0, import_react36.useRef)(false);
|
|
4859
|
+
const menuOpenRef = (0, import_react36.useRef)(false);
|
|
4860
|
+
const draggingRef = (0, import_react36.useRef)(false);
|
|
4861
|
+
const recompute = (0, import_react36.useCallback)(() => {
|
|
3814
4862
|
if (frozenRef.current) {
|
|
3815
4863
|
return;
|
|
3816
4864
|
}
|
|
@@ -3858,11 +4906,11 @@ function LumirTableHandlesController() {
|
|
|
3858
4906
|
widgetContainer
|
|
3859
4907
|
});
|
|
3860
4908
|
}, [editor]);
|
|
3861
|
-
(0,
|
|
3862
|
-
(0,
|
|
4909
|
+
(0, import_react34.useEditorContentOrSelectionChange)(recompute, editor);
|
|
4910
|
+
(0, import_react36.useEffect)(() => {
|
|
3863
4911
|
recompute();
|
|
3864
4912
|
}, [recompute]);
|
|
3865
|
-
(0,
|
|
4913
|
+
(0, import_react36.useEffect)(() => {
|
|
3866
4914
|
const onUp = () => {
|
|
3867
4915
|
requestAnimationFrame(() => {
|
|
3868
4916
|
if (!menuOpenRef.current && !draggingRef.current && frozenRef.current) {
|
|
@@ -3874,7 +4922,7 @@ function LumirTableHandlesController() {
|
|
|
3874
4922
|
window.addEventListener("pointerup", onUp);
|
|
3875
4923
|
return () => window.removeEventListener("pointerup", onUp);
|
|
3876
4924
|
}, [recompute]);
|
|
3877
|
-
(0,
|
|
4925
|
+
(0, import_react36.useEffect)(() => {
|
|
3878
4926
|
const f = focused;
|
|
3879
4927
|
if (!f || !overlayEl) {
|
|
3880
4928
|
return;
|
|
@@ -3899,7 +4947,13 @@ function LumirTableHandlesController() {
|
|
|
3899
4947
|
overlayEl.style.height = `${bottom - top}px`;
|
|
3900
4948
|
};
|
|
3901
4949
|
update();
|
|
3902
|
-
|
|
4950
|
+
const stopAutoUpdate = (0, import_react35.autoUpdate)(f.cellEl, overlayEl, update);
|
|
4951
|
+
const ro = new ResizeObserver(update);
|
|
4952
|
+
ro.observe(f.tbodyEl);
|
|
4953
|
+
return () => {
|
|
4954
|
+
stopAutoUpdate();
|
|
4955
|
+
ro.disconnect();
|
|
4956
|
+
};
|
|
3903
4957
|
}, [focused, overlayEl, openMenu]);
|
|
3904
4958
|
const cellEl = focused?.cellEl ?? null;
|
|
3905
4959
|
const tbodyEl = focused?.tbodyEl ?? null;
|
|
@@ -3913,21 +4967,21 @@ function LumirTableHandlesController() {
|
|
|
3913
4967
|
show
|
|
3914
4968
|
);
|
|
3915
4969
|
const th = editor.tableHandles;
|
|
3916
|
-
const coreState = (0,
|
|
4970
|
+
const coreState = (0, import_react34.useUIPluginState)(
|
|
3917
4971
|
editor.tableHandles.onUpdate.bind(editor.tableHandles)
|
|
3918
4972
|
);
|
|
3919
|
-
const { addOrRemoveColumnsButton, addOrRemoveRowsButton } = (0,
|
|
4973
|
+
const { addOrRemoveColumnsButton, addOrRemoveRowsButton } = (0, import_react34.useExtendButtonsPositioning)(
|
|
3920
4974
|
coreState?.showAddOrRemoveColumnsButton || false,
|
|
3921
4975
|
coreState?.showAddOrRemoveRowsButton || false,
|
|
3922
4976
|
coreState?.referencePosTable || null
|
|
3923
4977
|
);
|
|
3924
|
-
const onStartExtend = (0,
|
|
4978
|
+
const onStartExtend = (0, import_react36.useCallback)(() => {
|
|
3925
4979
|
editor.tableHandles?.freezeHandles();
|
|
3926
4980
|
}, [editor]);
|
|
3927
|
-
const onEndExtend = (0,
|
|
4981
|
+
const onEndExtend = (0, import_react36.useCallback)(() => {
|
|
3928
4982
|
editor.tableHandles?.unfreezeHandles();
|
|
3929
4983
|
}, [editor]);
|
|
3930
|
-
const menuHandlers = (0,
|
|
4984
|
+
const menuHandlers = (0, import_react36.useMemo)(() => {
|
|
3931
4985
|
const mk = (kind) => ({
|
|
3932
4986
|
freeze: () => {
|
|
3933
4987
|
menuOpenRef.current = true;
|
|
@@ -3945,10 +4999,10 @@ function LumirTableHandlesController() {
|
|
|
3945
4999
|
});
|
|
3946
5000
|
return { col: mk("col"), row: mk("row"), cell: mk("cell") };
|
|
3947
5001
|
}, [editor, recompute]);
|
|
3948
|
-
const onGutterPointerDown = (0,
|
|
5002
|
+
const onGutterPointerDown = (0, import_react36.useCallback)(() => {
|
|
3949
5003
|
frozenRef.current = true;
|
|
3950
5004
|
}, []);
|
|
3951
|
-
const onGutterPointerEnter = (0,
|
|
5005
|
+
const onGutterPointerEnter = (0, import_react36.useCallback)(
|
|
3952
5006
|
(e) => {
|
|
3953
5007
|
if (e.buttons === 0 && focused) {
|
|
3954
5008
|
syncCoreHoverToFocusedCell(focused.cellEl);
|
|
@@ -3956,7 +5010,7 @@ function LumirTableHandlesController() {
|
|
|
3956
5010
|
},
|
|
3957
5011
|
[focused]
|
|
3958
5012
|
);
|
|
3959
|
-
const makeDragStart = (0,
|
|
5013
|
+
const makeDragStart = (0, import_react36.useCallback)(
|
|
3960
5014
|
(dir) => (e) => {
|
|
3961
5015
|
draggingRef.current = true;
|
|
3962
5016
|
frozenRef.current = true;
|
|
@@ -3968,19 +5022,19 @@ function LumirTableHandlesController() {
|
|
|
3968
5022
|
},
|
|
3969
5023
|
[editor]
|
|
3970
5024
|
);
|
|
3971
|
-
const onDragEnd = (0,
|
|
5025
|
+
const onDragEnd = (0, import_react36.useCallback)(() => {
|
|
3972
5026
|
editor.tableHandles?.dragEnd();
|
|
3973
5027
|
draggingRef.current = false;
|
|
3974
5028
|
frozenRef.current = false;
|
|
3975
5029
|
recompute();
|
|
3976
5030
|
}, [editor, recompute]);
|
|
3977
|
-
const noop = (0,
|
|
5031
|
+
const noop = (0, import_react36.useCallback)(() => {
|
|
3978
5032
|
}, []);
|
|
3979
|
-
return /* @__PURE__ */ (0,
|
|
3980
|
-
/* @__PURE__ */ (0,
|
|
3981
|
-
th && focused && menuContainerRef && /* @__PURE__ */ (0,
|
|
3982
|
-
/* @__PURE__ */ (0,
|
|
3983
|
-
colHandle.isMounted && /* @__PURE__ */ (0,
|
|
5033
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
5034
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref: setMenuContainerRef }),
|
|
5035
|
+
th && focused && menuContainerRef && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react35.FloatingPortal, { root: focused.widgetContainer, children: [
|
|
5036
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref: setOverlayEl, className: "lumir-tbl-cell-focus" }),
|
|
5037
|
+
colHandle.isMounted && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
3984
5038
|
"div",
|
|
3985
5039
|
{
|
|
3986
5040
|
ref: colHandle.ref,
|
|
@@ -3989,9 +5043,9 @@ function LumirTableHandlesController() {
|
|
|
3989
5043
|
onPointerEnter: onGutterPointerEnter,
|
|
3990
5044
|
onPointerDown: onGutterPointerDown,
|
|
3991
5045
|
children: [
|
|
3992
|
-
/* @__PURE__ */ (0,
|
|
3993
|
-
/* @__PURE__ */ (0,
|
|
3994
|
-
|
|
5046
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "lumir-tbl-gutter" }),
|
|
5047
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5048
|
+
import_react34.TableHandle,
|
|
3995
5049
|
{
|
|
3996
5050
|
editor,
|
|
3997
5051
|
orientation: "column",
|
|
@@ -4009,7 +5063,7 @@ function LumirTableHandlesController() {
|
|
|
4009
5063
|
]
|
|
4010
5064
|
}
|
|
4011
5065
|
),
|
|
4012
|
-
rowHandle.isMounted && /* @__PURE__ */ (0,
|
|
5066
|
+
rowHandle.isMounted && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
4013
5067
|
"div",
|
|
4014
5068
|
{
|
|
4015
5069
|
ref: rowHandle.ref,
|
|
@@ -4018,9 +5072,9 @@ function LumirTableHandlesController() {
|
|
|
4018
5072
|
onPointerEnter: onGutterPointerEnter,
|
|
4019
5073
|
onPointerDown: onGutterPointerDown,
|
|
4020
5074
|
children: [
|
|
4021
|
-
/* @__PURE__ */ (0,
|
|
4022
|
-
/* @__PURE__ */ (0,
|
|
4023
|
-
|
|
5075
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "lumir-tbl-gutter" }),
|
|
5076
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5077
|
+
import_react34.TableHandle,
|
|
4024
5078
|
{
|
|
4025
5079
|
editor,
|
|
4026
5080
|
orientation: "row",
|
|
@@ -4038,7 +5092,7 @@ function LumirTableHandlesController() {
|
|
|
4038
5092
|
]
|
|
4039
5093
|
}
|
|
4040
5094
|
),
|
|
4041
|
-
cellHandle.isMounted && openMenu !== "col" && openMenu !== "row" && /* @__PURE__ */ (0,
|
|
5095
|
+
cellHandle.isMounted && openMenu !== "col" && openMenu !== "row" && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
4042
5096
|
"div",
|
|
4043
5097
|
{
|
|
4044
5098
|
ref: cellHandle.ref,
|
|
@@ -4046,9 +5100,9 @@ function LumirTableHandlesController() {
|
|
|
4046
5100
|
className: "lumir-tbl-gutter-wrap lumir-tbl-gutter-wrap--cell" + (openMenu === "cell" ? " lumir-tbl-gutter-wrap--active" : ""),
|
|
4047
5101
|
onPointerDown: onGutterPointerDown,
|
|
4048
5102
|
children: [
|
|
4049
|
-
/* @__PURE__ */ (0,
|
|
4050
|
-
/* @__PURE__ */ (0,
|
|
4051
|
-
|
|
5103
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "lumir-tbl-gutter" }),
|
|
5104
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5105
|
+
import_react34.TableCellButton,
|
|
4052
5106
|
{
|
|
4053
5107
|
editor,
|
|
4054
5108
|
rowIndex: focused.rowIndex,
|
|
@@ -4064,9 +5118,9 @@ function LumirTableHandlesController() {
|
|
|
4064
5118
|
}
|
|
4065
5119
|
)
|
|
4066
5120
|
] }),
|
|
4067
|
-
th && coreState?.widgetContainer && /* @__PURE__ */ (0,
|
|
4068
|
-
/* @__PURE__ */ (0,
|
|
4069
|
-
|
|
5121
|
+
th && coreState?.widgetContainer && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react35.FloatingPortal, { root: coreState.widgetContainer, children: [
|
|
5122
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref: addOrRemoveRowsButton.ref, style: addOrRemoveRowsButton.style, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5123
|
+
import_react34.ExtendButton,
|
|
4070
5124
|
{
|
|
4071
5125
|
editor,
|
|
4072
5126
|
orientation: "addOrRemoveRows",
|
|
@@ -4075,13 +5129,13 @@ function LumirTableHandlesController() {
|
|
|
4075
5129
|
onMouseUp: onEndExtend
|
|
4076
5130
|
}
|
|
4077
5131
|
) }),
|
|
4078
|
-
/* @__PURE__ */ (0,
|
|
5132
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
4079
5133
|
"div",
|
|
4080
5134
|
{
|
|
4081
5135
|
ref: addOrRemoveColumnsButton.ref,
|
|
4082
5136
|
style: addOrRemoveColumnsButton.style,
|
|
4083
|
-
children: /* @__PURE__ */ (0,
|
|
4084
|
-
|
|
5137
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5138
|
+
import_react34.ExtendButton,
|
|
4085
5139
|
{
|
|
4086
5140
|
editor,
|
|
4087
5141
|
orientation: "addOrRemoveColumns",
|
|
@@ -4097,15 +5151,17 @@ function LumirTableHandlesController() {
|
|
|
4097
5151
|
}
|
|
4098
5152
|
|
|
4099
5153
|
// src/utils/table-vertical-alignment.ts
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
if (
|
|
4106
|
-
|
|
5154
|
+
var CELL_ATTR_DEFAULTS = {
|
|
5155
|
+
verticalAlignment: "top",
|
|
5156
|
+
rowHeight: null
|
|
5157
|
+
};
|
|
5158
|
+
function isMeaningful2(attr, value) {
|
|
5159
|
+
if (value === null || value === void 0) {
|
|
5160
|
+
return false;
|
|
5161
|
+
}
|
|
5162
|
+
return value !== CELL_ATTR_DEFAULTS[attr];
|
|
4107
5163
|
}
|
|
4108
|
-
function
|
|
5164
|
+
function buildTableCellAttrMap(doc, attrs) {
|
|
4109
5165
|
const result = /* @__PURE__ */ new Map();
|
|
4110
5166
|
doc.descendants((node) => {
|
|
4111
5167
|
if (node.type.name === "blockContainer") {
|
|
@@ -4118,9 +5174,15 @@ function buildTableVerticalAlignmentMap(doc) {
|
|
|
4118
5174
|
if (rowNode.type.name === "tableRow") {
|
|
4119
5175
|
let colIndex = 0;
|
|
4120
5176
|
rowNode.forEach((cellNode) => {
|
|
4121
|
-
const
|
|
4122
|
-
|
|
4123
|
-
|
|
5177
|
+
const props = {};
|
|
5178
|
+
for (const attr of attrs) {
|
|
5179
|
+
const value = cellNode.attrs?.[attr];
|
|
5180
|
+
if (isMeaningful2(attr, value)) {
|
|
5181
|
+
props[attr] = value;
|
|
5182
|
+
}
|
|
5183
|
+
}
|
|
5184
|
+
if (Object.keys(props).length > 0) {
|
|
5185
|
+
cells.push({ row: rowIndex, col: colIndex, props });
|
|
4124
5186
|
}
|
|
4125
5187
|
colIndex++;
|
|
4126
5188
|
});
|
|
@@ -4136,18 +5198,21 @@ function buildTableVerticalAlignmentMap(doc) {
|
|
|
4136
5198
|
});
|
|
4137
5199
|
return result;
|
|
4138
5200
|
}
|
|
4139
|
-
function patchBlocks(blocks,
|
|
5201
|
+
function patchBlocks(blocks, cellAttrMap) {
|
|
4140
5202
|
return blocks.map((block) => {
|
|
4141
5203
|
if (block.type !== "table" || !block.id || !block.content) {
|
|
4142
5204
|
if (block.children && block.children.length > 0) {
|
|
4143
5205
|
return {
|
|
4144
5206
|
...block,
|
|
4145
|
-
children: patchBlocks(
|
|
5207
|
+
children: patchBlocks(
|
|
5208
|
+
block.children,
|
|
5209
|
+
cellAttrMap
|
|
5210
|
+
)
|
|
4146
5211
|
};
|
|
4147
5212
|
}
|
|
4148
5213
|
return block;
|
|
4149
5214
|
}
|
|
4150
|
-
const cells =
|
|
5215
|
+
const cells = cellAttrMap.get(block.id);
|
|
4151
5216
|
if (!cells || cells.length === 0) {
|
|
4152
5217
|
return block;
|
|
4153
5218
|
}
|
|
@@ -4160,11 +5225,13 @@ function patchBlocks(blocks, tableVAMap) {
|
|
|
4160
5225
|
const match = cells.find(
|
|
4161
5226
|
(c) => c.row === rowIndex && c.col === colIndex
|
|
4162
5227
|
);
|
|
4163
|
-
if (!match)
|
|
5228
|
+
if (!match) {
|
|
5229
|
+
return cell;
|
|
5230
|
+
}
|
|
4164
5231
|
if (cell && typeof cell === "object" && cell.type === "tableCell") {
|
|
4165
5232
|
return {
|
|
4166
5233
|
...cell,
|
|
4167
|
-
props: { ...cell.props,
|
|
5234
|
+
props: { ...cell.props, ...match.props }
|
|
4168
5235
|
};
|
|
4169
5236
|
}
|
|
4170
5237
|
return cell;
|
|
@@ -4177,6 +5244,77 @@ function patchBlocks(blocks, tableVAMap) {
|
|
|
4177
5244
|
};
|
|
4178
5245
|
});
|
|
4179
5246
|
}
|
|
5247
|
+
function injectTableCellAttrs(blocks, editor, attrs) {
|
|
5248
|
+
const tiptap = editor?._tiptapEditor;
|
|
5249
|
+
if (!tiptap) {
|
|
5250
|
+
return blocks;
|
|
5251
|
+
}
|
|
5252
|
+
const { doc } = tiptap.state;
|
|
5253
|
+
const cellAttrMap = buildTableCellAttrMap(doc, attrs);
|
|
5254
|
+
if (cellAttrMap.size === 0) {
|
|
5255
|
+
return blocks;
|
|
5256
|
+
}
|
|
5257
|
+
return patchBlocks(blocks, cellAttrMap);
|
|
5258
|
+
}
|
|
5259
|
+
var TABLE_BLOCK_ATTR_DEFAULTS = {
|
|
5260
|
+
tableAlignment: "left"
|
|
5261
|
+
};
|
|
5262
|
+
function buildTableBlockAttrMap(doc, attrs) {
|
|
5263
|
+
const result = /* @__PURE__ */ new Map();
|
|
5264
|
+
doc.descendants((node) => {
|
|
5265
|
+
if (node.type.name === "blockContainer") {
|
|
5266
|
+
const blockId = node.attrs?.id;
|
|
5267
|
+
const contentNode = node.firstChild;
|
|
5268
|
+
if (blockId && contentNode?.type.name === "table") {
|
|
5269
|
+
const props = {};
|
|
5270
|
+
for (const attr of attrs) {
|
|
5271
|
+
const value = contentNode.attrs?.[attr];
|
|
5272
|
+
if (value !== null && value !== void 0 && value !== TABLE_BLOCK_ATTR_DEFAULTS[attr]) {
|
|
5273
|
+
props[attr] = value;
|
|
5274
|
+
}
|
|
5275
|
+
}
|
|
5276
|
+
if (Object.keys(props).length > 0) {
|
|
5277
|
+
result.set(blockId, props);
|
|
5278
|
+
}
|
|
5279
|
+
}
|
|
5280
|
+
return false;
|
|
5281
|
+
}
|
|
5282
|
+
return void 0;
|
|
5283
|
+
});
|
|
5284
|
+
return result;
|
|
5285
|
+
}
|
|
5286
|
+
function patchTableBlockProps(blocks, attrMap) {
|
|
5287
|
+
return blocks.map((block) => {
|
|
5288
|
+
if (block.type === "table" && block.id && attrMap.has(block.id)) {
|
|
5289
|
+
return {
|
|
5290
|
+
...block,
|
|
5291
|
+
props: { ...block.props, ...attrMap.get(block.id) }
|
|
5292
|
+
};
|
|
5293
|
+
}
|
|
5294
|
+
if (block.children && block.children.length > 0) {
|
|
5295
|
+
return {
|
|
5296
|
+
...block,
|
|
5297
|
+
children: patchTableBlockProps(
|
|
5298
|
+
block.children,
|
|
5299
|
+
attrMap
|
|
5300
|
+
)
|
|
5301
|
+
};
|
|
5302
|
+
}
|
|
5303
|
+
return block;
|
|
5304
|
+
});
|
|
5305
|
+
}
|
|
5306
|
+
function injectTableBlockAttrs(blocks, editor) {
|
|
5307
|
+
const tiptap = editor?._tiptapEditor;
|
|
5308
|
+
if (!tiptap) {
|
|
5309
|
+
return blocks;
|
|
5310
|
+
}
|
|
5311
|
+
const { doc } = tiptap.state;
|
|
5312
|
+
const attrMap = buildTableBlockAttrMap(doc, ["tableAlignment"]);
|
|
5313
|
+
if (attrMap.size === 0) {
|
|
5314
|
+
return blocks;
|
|
5315
|
+
}
|
|
5316
|
+
return patchTableBlockProps(blocks, attrMap);
|
|
5317
|
+
}
|
|
4180
5318
|
|
|
4181
5319
|
// src/utils/font-size-serialization.ts
|
|
4182
5320
|
function mapPreservingRef(arr, fn) {
|
|
@@ -4491,26 +5629,8 @@ function normalizeExcelTableHtml(html) {
|
|
|
4491
5629
|
}
|
|
4492
5630
|
}
|
|
4493
5631
|
|
|
4494
|
-
// src/constants/limits.ts
|
|
4495
|
-
var MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
4496
|
-
var MAX_VIDEO_FILE_SIZE = 100 * 1024 * 1024;
|
|
4497
|
-
var BLOCKED_EXTENSIONS = [".svg", ".svgz"];
|
|
4498
|
-
var ALLOWED_VIDEO_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
4499
|
-
"video/mp4",
|
|
4500
|
-
"video/webm",
|
|
4501
|
-
"video/ogg",
|
|
4502
|
-
"video/quicktime"
|
|
4503
|
-
// .mov
|
|
4504
|
-
]);
|
|
4505
|
-
var ALLOWED_VIDEO_EXTENSIONS = [
|
|
4506
|
-
".mp4",
|
|
4507
|
-
".webm",
|
|
4508
|
-
".ogg",
|
|
4509
|
-
".mov"
|
|
4510
|
-
];
|
|
4511
|
-
|
|
4512
5632
|
// src/components/LumirEditor.tsx
|
|
4513
|
-
var
|
|
5633
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
4514
5634
|
var DEBUG_LOG = (loc, msg, data) => {
|
|
4515
5635
|
const p = fetch("http://127.0.0.1:7686/ingest/1f8ee1c5-0cf0-4ae7-91ed-5ea7ed17130a", {
|
|
4516
5636
|
method: "POST",
|
|
@@ -4741,9 +5861,9 @@ var findBlockWithLink = (blocks, targetUrl) => {
|
|
|
4741
5861
|
return null;
|
|
4742
5862
|
};
|
|
4743
5863
|
var ConvertToPreviewButton = ({ url }) => {
|
|
4744
|
-
const editor = (0,
|
|
4745
|
-
const Components = (0,
|
|
4746
|
-
return /* @__PURE__ */ (0,
|
|
5864
|
+
const editor = (0, import_react38.useBlockNoteEditor)();
|
|
5865
|
+
const Components = (0, import_react38.useComponentsContext)();
|
|
5866
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4747
5867
|
Components.LinkToolbar.Button,
|
|
4748
5868
|
{
|
|
4749
5869
|
className: "bn-button",
|
|
@@ -4762,29 +5882,29 @@ var ConvertToPreviewButton = ({ url }) => {
|
|
|
4762
5882
|
console.error("Convert to link preview failed:", err);
|
|
4763
5883
|
}
|
|
4764
5884
|
},
|
|
4765
|
-
icon: /* @__PURE__ */ (0,
|
|
4766
|
-
/* @__PURE__ */ (0,
|
|
4767
|
-
/* @__PURE__ */ (0,
|
|
4768
|
-
/* @__PURE__ */ (0,
|
|
5885
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
5886
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("rect", { x: "1", y: "3", width: "14", height: "10", rx: "2", stroke: "currentColor", strokeWidth: "1.5", fill: "none" }),
|
|
5887
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("line", { x1: "1", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
5888
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("circle", { cx: "5", cy: "6.5", r: "1.5", stroke: "currentColor", strokeWidth: "1", fill: "none" })
|
|
4769
5889
|
] })
|
|
4770
5890
|
}
|
|
4771
5891
|
);
|
|
4772
5892
|
};
|
|
4773
5893
|
var CustomLinkToolbar = (props) => {
|
|
4774
|
-
const editor = (0,
|
|
4775
|
-
const Components = (0,
|
|
5894
|
+
const editor = (0, import_react38.useBlockNoteEditor)();
|
|
5895
|
+
const Components = (0, import_react38.useComponentsContext)();
|
|
4776
5896
|
const hasLinkPreview = !!editor?._linkPreviewApiEndpoint;
|
|
4777
|
-
return /* @__PURE__ */ (0,
|
|
5897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
4778
5898
|
Components.LinkToolbar.Root,
|
|
4779
5899
|
{
|
|
4780
5900
|
className: "bn-toolbar bn-link-toolbar",
|
|
4781
5901
|
onMouseEnter: props.stopHideTimer,
|
|
4782
5902
|
onMouseLeave: props.startHideTimer,
|
|
4783
5903
|
children: [
|
|
4784
|
-
/* @__PURE__ */ (0,
|
|
4785
|
-
/* @__PURE__ */ (0,
|
|
4786
|
-
/* @__PURE__ */ (0,
|
|
4787
|
-
hasLinkPreview && /* @__PURE__ */ (0,
|
|
5904
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react38.EditLinkButton, { url: props.url, text: props.text, editLink: props.editLink }),
|
|
5905
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react38.OpenLinkButton, { url: props.url }),
|
|
5906
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react38.DeleteLinkButton, { deleteLink: props.deleteLink }),
|
|
5907
|
+
hasLinkPreview && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ConvertToPreviewButton, { url: props.url })
|
|
4788
5908
|
]
|
|
4789
5909
|
}
|
|
4790
5910
|
);
|
|
@@ -4828,13 +5948,13 @@ function LumirEditor({
|
|
|
4828
5948
|
onError,
|
|
4829
5949
|
onImageDelete
|
|
4830
5950
|
}) {
|
|
4831
|
-
const [isUploading, setIsUploading] = (0,
|
|
4832
|
-
const [uploadProgress, setUploadProgress] = (0,
|
|
4833
|
-
const [errorMessage, setErrorMessage] = (0,
|
|
4834
|
-
const floatingMenuFileInputRef = (0,
|
|
4835
|
-
const floatingMenuBlockRef = (0,
|
|
4836
|
-
const floatingMenuUploadStartTimeRef = (0,
|
|
4837
|
-
const handleError = (0,
|
|
5951
|
+
const [isUploading, setIsUploading] = (0, import_react37.useState)(false);
|
|
5952
|
+
const [uploadProgress, setUploadProgress] = (0, import_react37.useState)(null);
|
|
5953
|
+
const [errorMessage, setErrorMessage] = (0, import_react37.useState)(null);
|
|
5954
|
+
const floatingMenuFileInputRef = (0, import_react37.useRef)(null);
|
|
5955
|
+
const floatingMenuBlockRef = (0, import_react37.useRef)(null);
|
|
5956
|
+
const floatingMenuUploadStartTimeRef = (0, import_react37.useRef)(0);
|
|
5957
|
+
const handleError = (0, import_react37.useCallback)(
|
|
4838
5958
|
(error) => {
|
|
4839
5959
|
onError?.(error);
|
|
4840
5960
|
setErrorMessage(error.getUserMessage());
|
|
@@ -4842,12 +5962,12 @@ function LumirEditor({
|
|
|
4842
5962
|
},
|
|
4843
5963
|
[onError]
|
|
4844
5964
|
);
|
|
4845
|
-
const validatedContent = (0,
|
|
5965
|
+
const validatedContent = (0, import_react37.useMemo)(() => {
|
|
4846
5966
|
return liftFontSize(
|
|
4847
5967
|
ContentUtils.validateContent(initialContent, initialEmptyBlocks)
|
|
4848
5968
|
);
|
|
4849
5969
|
}, [initialContent, initialEmptyBlocks]);
|
|
4850
|
-
const tableConfig = (0,
|
|
5970
|
+
const tableConfig = (0, import_react37.useMemo)(() => {
|
|
4851
5971
|
return EditorConfig.getDefaultTableConfig(tables);
|
|
4852
5972
|
}, [
|
|
4853
5973
|
tables?.splitCells,
|
|
@@ -4855,10 +5975,10 @@ function LumirEditor({
|
|
|
4855
5975
|
tables?.cellTextColor,
|
|
4856
5976
|
tables?.headers
|
|
4857
5977
|
]);
|
|
4858
|
-
const headingConfig = (0,
|
|
5978
|
+
const headingConfig = (0, import_react37.useMemo)(() => {
|
|
4859
5979
|
return EditorConfig.getDefaultHeadingConfig(heading);
|
|
4860
5980
|
}, [heading?.levels?.join(",") ?? ""]);
|
|
4861
|
-
const disabledExtensions = (0,
|
|
5981
|
+
const disabledExtensions = (0, import_react37.useMemo)(() => {
|
|
4862
5982
|
return EditorConfig.getDisabledExtensions(
|
|
4863
5983
|
disableExtensions,
|
|
4864
5984
|
allowVideoUpload,
|
|
@@ -4866,18 +5986,18 @@ function LumirEditor({
|
|
|
4866
5986
|
allowFileUpload
|
|
4867
5987
|
);
|
|
4868
5988
|
}, [disableExtensions, allowVideoUpload, allowAudioUpload, allowFileUpload]);
|
|
4869
|
-
(0,
|
|
5989
|
+
(0, import_react37.useEffect)(() => {
|
|
4870
5990
|
DEBUG_LOG("LumirEditor:init:disabledExtensions", "snapshot", {
|
|
4871
5991
|
allowVideoUpload,
|
|
4872
5992
|
hasVideoInDisabled: disabledExtensions.includes("video"),
|
|
4873
5993
|
disabledList: disabledExtensions.slice(0, 15)
|
|
4874
5994
|
});
|
|
4875
5995
|
}, [allowVideoUpload, disabledExtensions]);
|
|
4876
|
-
const fileNameTransformRef = (0,
|
|
4877
|
-
(0,
|
|
5996
|
+
const fileNameTransformRef = (0, import_react37.useRef)(s3Upload?.fileNameTransform);
|
|
5997
|
+
(0, import_react37.useEffect)(() => {
|
|
4878
5998
|
fileNameTransformRef.current = s3Upload?.fileNameTransform;
|
|
4879
5999
|
}, [s3Upload?.fileNameTransform]);
|
|
4880
|
-
const memoizedS3Upload = (0,
|
|
6000
|
+
const memoizedS3Upload = (0, import_react37.useMemo)(() => {
|
|
4881
6001
|
if (!s3Upload) return void 0;
|
|
4882
6002
|
return {
|
|
4883
6003
|
apiEndpoint: s3Upload.apiEndpoint,
|
|
@@ -4906,7 +6026,7 @@ function LumirEditor({
|
|
|
4906
6026
|
s3Upload?.maxRetries,
|
|
4907
6027
|
s3Upload?.onProgress
|
|
4908
6028
|
]);
|
|
4909
|
-
const editor = (0,
|
|
6029
|
+
const editor = (0, import_react38.useCreateBlockNote)(
|
|
4910
6030
|
{
|
|
4911
6031
|
// HTML 미리보기 블록이 포함된 커스텀 스키마 사용
|
|
4912
6032
|
schema,
|
|
@@ -4928,7 +6048,14 @@ function LumirEditor({
|
|
|
4928
6048
|
// 확장 비활성: 비디오/오디오/파일 제어
|
|
4929
6049
|
disableExtensions: disabledExtensions,
|
|
4930
6050
|
_tiptapOptions: {
|
|
4931
|
-
extensions: [
|
|
6051
|
+
extensions: [
|
|
6052
|
+
VerticalAlignmentExtension,
|
|
6053
|
+
// 행 높이 attr 등록은 항상(저장된 높이 렌더), 드래그 리사이즈 UI는
|
|
6054
|
+
// tableHandles prop으로 게이트(기존 grip 컨트롤러와 동일 게이트).
|
|
6055
|
+
RowHeightExtension.configure({ resizable: tableHandles }),
|
|
6056
|
+
// 표 블록 정렬(좌/가운데/우) attr.
|
|
6057
|
+
TableAlignmentExtension
|
|
6058
|
+
]
|
|
4932
6059
|
},
|
|
4933
6060
|
placeholders: placeholder ? { default: placeholder, emptyDocument: placeholder } : void 0,
|
|
4934
6061
|
tabBehavior,
|
|
@@ -5104,18 +6231,29 @@ function LumirEditor({
|
|
|
5104
6231
|
memoizedS3Upload,
|
|
5105
6232
|
allowVideoUpload,
|
|
5106
6233
|
linkPreview?.apiEndpoint,
|
|
5107
|
-
placeholder
|
|
6234
|
+
placeholder,
|
|
6235
|
+
// tableHandles 변경 시 RowHeightExtension의 resizable 게이트가 반영되도록 재생성
|
|
6236
|
+
tableHandles
|
|
5108
6237
|
]
|
|
5109
6238
|
);
|
|
5110
6239
|
if (editor && linkPreview?.apiEndpoint) {
|
|
5111
6240
|
editor._linkPreviewApiEndpoint = linkPreview.apiEndpoint;
|
|
5112
6241
|
}
|
|
5113
|
-
|
|
6242
|
+
if (editor) {
|
|
6243
|
+
try {
|
|
6244
|
+
const view = editor.prosemirrorView;
|
|
6245
|
+
if (view) {
|
|
6246
|
+
view.__lumirEditor = editor;
|
|
6247
|
+
}
|
|
6248
|
+
} catch {
|
|
6249
|
+
}
|
|
6250
|
+
}
|
|
6251
|
+
(0, import_react37.useEffect)(() => {
|
|
5114
6252
|
if (editor) {
|
|
5115
6253
|
editor.isEditable = editable;
|
|
5116
6254
|
}
|
|
5117
6255
|
}, [editor, editable]);
|
|
5118
|
-
(0,
|
|
6256
|
+
(0, import_react37.useEffect)(() => {
|
|
5119
6257
|
if (!editor || !floatingMenu) return;
|
|
5120
6258
|
const ft = editor.formattingToolbar;
|
|
5121
6259
|
if (!ft?.onUpdate) return;
|
|
@@ -5128,22 +6266,30 @@ function LumirEditor({
|
|
|
5128
6266
|
});
|
|
5129
6267
|
return unsubscribe;
|
|
5130
6268
|
}, [editor, floatingMenu]);
|
|
5131
|
-
(0,
|
|
6269
|
+
(0, import_react37.useEffect)(() => {
|
|
5132
6270
|
if (!editor || !onContentChange) return;
|
|
5133
6271
|
const handleContentChange = () => {
|
|
5134
6272
|
const blocks = editor.topLevelBlocks;
|
|
5135
|
-
const patched = lowerFontSize(
|
|
6273
|
+
const patched = lowerFontSize(
|
|
6274
|
+
injectTableBlockAttrs(
|
|
6275
|
+
injectTableCellAttrs(blocks, editor, [
|
|
6276
|
+
"verticalAlignment",
|
|
6277
|
+
"rowHeight"
|
|
6278
|
+
]),
|
|
6279
|
+
editor
|
|
6280
|
+
)
|
|
6281
|
+
);
|
|
5136
6282
|
onContentChange(patched);
|
|
5137
6283
|
};
|
|
5138
6284
|
return editor.onEditorContentChange(handleContentChange);
|
|
5139
6285
|
}, [editor, onContentChange]);
|
|
5140
|
-
const previousMediaUrlsRef = (0,
|
|
5141
|
-
(0,
|
|
6286
|
+
const previousMediaUrlsRef = (0, import_react37.useRef)(/* @__PURE__ */ new Set());
|
|
6287
|
+
(0, import_react37.useEffect)(() => {
|
|
5142
6288
|
if (!editor) return;
|
|
5143
6289
|
const initialBlocks = editor.topLevelBlocks;
|
|
5144
6290
|
previousMediaUrlsRef.current = extractMediaUrls(initialBlocks);
|
|
5145
6291
|
}, [editor]);
|
|
5146
|
-
(0,
|
|
6292
|
+
(0, import_react37.useEffect)(() => {
|
|
5147
6293
|
if (!editor || !onImageDelete) return;
|
|
5148
6294
|
const handleMediaDeleteCheck = () => {
|
|
5149
6295
|
const currentBlocks = editor.topLevelBlocks;
|
|
@@ -5157,7 +6303,7 @@ function LumirEditor({
|
|
|
5157
6303
|
};
|
|
5158
6304
|
return editor.onEditorContentChange(handleMediaDeleteCheck);
|
|
5159
6305
|
}, [editor, onImageDelete]);
|
|
5160
|
-
(0,
|
|
6306
|
+
(0, import_react37.useEffect)(() => {
|
|
5161
6307
|
const el = editor?.domElement;
|
|
5162
6308
|
if (!el) return;
|
|
5163
6309
|
const handleDragOver = (e) => {
|
|
@@ -5288,20 +6434,20 @@ function LumirEditor({
|
|
|
5288
6434
|
el.removeEventListener("drop", handleDrop, { capture: true });
|
|
5289
6435
|
};
|
|
5290
6436
|
}, [editor, allowVideoUpload]);
|
|
5291
|
-
const computedSideMenu = (0,
|
|
6437
|
+
const computedSideMenu = (0, import_react37.useMemo)(() => {
|
|
5292
6438
|
return sideMenuAddButton ? sideMenu : false;
|
|
5293
6439
|
}, [sideMenuAddButton, sideMenu]);
|
|
5294
|
-
const DragHandleOnlySideMenu = (0,
|
|
5295
|
-
return (props) => /* @__PURE__ */ (0,
|
|
6440
|
+
const DragHandleOnlySideMenu = (0, import_react37.useMemo)(() => {
|
|
6441
|
+
return (props) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react38.SideMenu, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react38.DragHandleButton, { ...props, dragHandleMenu: LumirDragHandleMenu }) });
|
|
5296
6442
|
}, []);
|
|
5297
|
-
return /* @__PURE__ */ (0,
|
|
6443
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
5298
6444
|
"div",
|
|
5299
6445
|
{
|
|
5300
6446
|
className: cn("lumirEditor", className),
|
|
5301
6447
|
style: { position: "relative", display: "flex", flexDirection: "column" },
|
|
5302
6448
|
children: [
|
|
5303
|
-
floatingMenu && editor && /* @__PURE__ */ (0,
|
|
5304
|
-
/* @__PURE__ */ (0,
|
|
6449
|
+
floatingMenu && editor && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
6450
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5305
6451
|
"input",
|
|
5306
6452
|
{
|
|
5307
6453
|
ref: floatingMenuFileInputRef,
|
|
@@ -5372,7 +6518,7 @@ function LumirEditor({
|
|
|
5372
6518
|
}
|
|
5373
6519
|
}
|
|
5374
6520
|
),
|
|
5375
|
-
/* @__PURE__ */ (0,
|
|
6521
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5376
6522
|
FloatingMenu,
|
|
5377
6523
|
{
|
|
5378
6524
|
editor,
|
|
@@ -5404,7 +6550,7 @@ function LumirEditor({
|
|
|
5404
6550
|
}
|
|
5405
6551
|
)
|
|
5406
6552
|
] }),
|
|
5407
|
-
/* @__PURE__ */ (0,
|
|
6553
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
5408
6554
|
import_mantine.BlockNoteView,
|
|
5409
6555
|
{
|
|
5410
6556
|
editor,
|
|
@@ -5419,21 +6565,21 @@ function LumirEditor({
|
|
|
5419
6565
|
tableHandles: false,
|
|
5420
6566
|
onSelectionChange,
|
|
5421
6567
|
children: [
|
|
5422
|
-
tableHandles && /* @__PURE__ */ (0,
|
|
5423
|
-
formattingToolbar && /* @__PURE__ */ (0,
|
|
5424
|
-
|
|
6568
|
+
tableHandles && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(LumirTableHandlesController, {}),
|
|
6569
|
+
formattingToolbar && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6570
|
+
import_react38.FormattingToolbarController,
|
|
5425
6571
|
{
|
|
5426
6572
|
formattingToolbar: CustomFormattingToolbar
|
|
5427
6573
|
}
|
|
5428
6574
|
),
|
|
5429
|
-
linkToolbar && (linkPreview?.apiEndpoint ? /* @__PURE__ */ (0,
|
|
5430
|
-
/* @__PURE__ */ (0,
|
|
5431
|
-
|
|
6575
|
+
linkToolbar && (linkPreview?.apiEndpoint ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react38.LinkToolbarController, { linkToolbar: CustomLinkToolbar }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react38.LinkToolbarController, {})),
|
|
6576
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6577
|
+
import_react38.SuggestionMenuController,
|
|
5432
6578
|
{
|
|
5433
6579
|
triggerCharacter: "/",
|
|
5434
|
-
getItems: (0,
|
|
6580
|
+
getItems: (0, import_react37.useCallback)(
|
|
5435
6581
|
async (query) => {
|
|
5436
|
-
const items = (0,
|
|
6582
|
+
const items = (0, import_react38.getDefaultReactSlashMenuItems)(editor);
|
|
5437
6583
|
const filtered = items.filter((item) => {
|
|
5438
6584
|
const key = (item?.key || "").toString().toLowerCase();
|
|
5439
6585
|
const title = (item?.title || "").toString().toLowerCase();
|
|
@@ -5475,7 +6621,7 @@ function LumirEditor({
|
|
|
5475
6621
|
},
|
|
5476
6622
|
aliases: ["html", "preview", "\uC6F9", "\uC6F9\uD398\uC774\uC9C0"],
|
|
5477
6623
|
group: "Embeds",
|
|
5478
|
-
icon: /* @__PURE__ */ (0,
|
|
6624
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
5479
6625
|
"svg",
|
|
5480
6626
|
{
|
|
5481
6627
|
width: "18",
|
|
@@ -5487,19 +6633,45 @@ function LumirEditor({
|
|
|
5487
6633
|
strokeLinecap: "round",
|
|
5488
6634
|
strokeLinejoin: "round",
|
|
5489
6635
|
children: [
|
|
5490
|
-
/* @__PURE__ */ (0,
|
|
5491
|
-
/* @__PURE__ */ (0,
|
|
6636
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("polyline", { points: "16 18 22 12 16 6" }),
|
|
6637
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("polyline", { points: "8 6 2 12 8 18" })
|
|
5492
6638
|
]
|
|
5493
6639
|
}
|
|
5494
6640
|
),
|
|
5495
6641
|
subtext: "HTML \uD30C\uC77C\uC744 \uBBF8\uB9AC\uBCF4\uAE30\uB85C \uC0BD\uC785"
|
|
5496
6642
|
};
|
|
5497
|
-
const
|
|
6643
|
+
const columnItem = {
|
|
6644
|
+
title: "2\uB2E8 \uCEEC\uB7FC",
|
|
6645
|
+
onItemClick: () => {
|
|
6646
|
+
insertTwoColumns(editor);
|
|
6647
|
+
},
|
|
6648
|
+
aliases: ["columns", "column", "2col", "\uB2E8", "\uCEEC\uB7FC", "\uB2E4\uB2E8", "\uBD84\uD560"],
|
|
6649
|
+
group: "Basic blocks",
|
|
6650
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
6651
|
+
"svg",
|
|
6652
|
+
{
|
|
6653
|
+
width: "18",
|
|
6654
|
+
height: "18",
|
|
6655
|
+
viewBox: "0 0 24 24",
|
|
6656
|
+
fill: "none",
|
|
6657
|
+
stroke: "currentColor",
|
|
6658
|
+
strokeWidth: "2",
|
|
6659
|
+
strokeLinecap: "round",
|
|
6660
|
+
strokeLinejoin: "round",
|
|
6661
|
+
children: [
|
|
6662
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("rect", { x: "3", y: "4", width: "7", height: "16", rx: "1" }),
|
|
6663
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("rect", { x: "14", y: "4", width: "7", height: "16", rx: "1" })
|
|
6664
|
+
]
|
|
6665
|
+
}
|
|
6666
|
+
),
|
|
6667
|
+
subtext: "\uBE14\uB85D\uC744 \uC88C\uC6B0 2\uB2E8\uC73C\uB85C \uBC30\uCE58"
|
|
6668
|
+
};
|
|
6669
|
+
const allItems = [...filtered, htmlPreviewItem, columnItem];
|
|
5498
6670
|
if (linkPreview?.apiEndpoint) {
|
|
5499
6671
|
allItems.push({
|
|
5500
6672
|
title: "Link Preview",
|
|
5501
6673
|
onItemClick: () => {
|
|
5502
|
-
(0,
|
|
6674
|
+
(0, import_core9.insertOrUpdateBlock)(editor, {
|
|
5503
6675
|
type: "linkPreview",
|
|
5504
6676
|
props: { url: "" }
|
|
5505
6677
|
});
|
|
@@ -5513,7 +6685,7 @@ function LumirEditor({
|
|
|
5513
6685
|
"\uD504\uB9AC\uBDF0"
|
|
5514
6686
|
],
|
|
5515
6687
|
group: "Embeds",
|
|
5516
|
-
icon: /* @__PURE__ */ (0,
|
|
6688
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
5517
6689
|
"svg",
|
|
5518
6690
|
{
|
|
5519
6691
|
width: "18",
|
|
@@ -5525,8 +6697,8 @@ function LumirEditor({
|
|
|
5525
6697
|
strokeLinecap: "round",
|
|
5526
6698
|
strokeLinejoin: "round",
|
|
5527
6699
|
children: [
|
|
5528
|
-
/* @__PURE__ */ (0,
|
|
5529
|
-
/* @__PURE__ */ (0,
|
|
6700
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
|
|
6701
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
|
|
5530
6702
|
]
|
|
5531
6703
|
}
|
|
5532
6704
|
),
|
|
@@ -5562,21 +6734,21 @@ function LumirEditor({
|
|
|
5562
6734
|
)
|
|
5563
6735
|
}
|
|
5564
6736
|
),
|
|
5565
|
-
!sideMenuAddButton && /* @__PURE__ */ (0,
|
|
6737
|
+
!sideMenuAddButton && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react38.SideMenuController, { sideMenu: DragHandleOnlySideMenu })
|
|
5566
6738
|
]
|
|
5567
6739
|
}
|
|
5568
6740
|
),
|
|
5569
|
-
isUploading && /* @__PURE__ */ (0,
|
|
5570
|
-
/* @__PURE__ */ (0,
|
|
5571
|
-
uploadProgress !== null && /* @__PURE__ */ (0,
|
|
6741
|
+
isUploading && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "lumirEditor-upload-overlay", children: [
|
|
6742
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "lumirEditor-spinner" }),
|
|
6743
|
+
uploadProgress !== null && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "lumirEditor-upload-progress", children: [
|
|
5572
6744
|
uploadProgress,
|
|
5573
6745
|
"%"
|
|
5574
6746
|
] })
|
|
5575
6747
|
] }),
|
|
5576
|
-
errorMessage && /* @__PURE__ */ (0,
|
|
5577
|
-
/* @__PURE__ */ (0,
|
|
5578
|
-
/* @__PURE__ */ (0,
|
|
5579
|
-
/* @__PURE__ */ (0,
|
|
6748
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "lumirEditor-error-toast", children: [
|
|
6749
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "lumirEditor-error-icon", children: "\u26A0\uFE0F" }),
|
|
6750
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "lumirEditor-error-message", children: errorMessage }),
|
|
6751
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5580
6752
|
"button",
|
|
5581
6753
|
{
|
|
5582
6754
|
className: "lumirEditor-error-close",
|