@lumir-company/editor 0.4.14 → 0.4.16
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 +135 -8
- package/dist/index.d.mts +81 -1
- package/dist/index.d.ts +81 -1
- package/dist/index.js +1548 -457
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1492 -379
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +258 -41
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -24,7 +24,10 @@ __export(index_exports, {
|
|
|
24
24
|
BACKGROUND_COLORS: () => BACKGROUND_COLORS,
|
|
25
25
|
ContentUtils: () => ContentUtils,
|
|
26
26
|
EditorConfig: () => EditorConfig,
|
|
27
|
+
FONT_SIZE_PRESETS: () => FONT_SIZE_PRESETS,
|
|
27
28
|
FloatingMenu: () => FloatingMenu,
|
|
29
|
+
FontSize: () => FontSize,
|
|
30
|
+
FontSizeButton: () => FontSizeButton2,
|
|
28
31
|
HtmlPreviewBlock: () => HtmlPreviewBlock,
|
|
29
32
|
HtmlPreviewSchema: () => schema,
|
|
30
33
|
LinkPreviewBlock: () => LinkPreviewBlock,
|
|
@@ -35,15 +38,18 @@ __export(index_exports, {
|
|
|
35
38
|
cn: () => cn,
|
|
36
39
|
createS3Uploader: () => createS3Uploader,
|
|
37
40
|
fetchLinkMetadata: () => fetchLinkMetadata,
|
|
38
|
-
getHexFromColorValue: () => getHexFromColorValue
|
|
41
|
+
getHexFromColorValue: () => getHexFromColorValue,
|
|
42
|
+
liftFontSize: () => liftFontSize,
|
|
43
|
+
lowerFontSize: () => lowerFontSize
|
|
39
44
|
});
|
|
40
45
|
module.exports = __toCommonJS(index_exports);
|
|
41
46
|
|
|
42
47
|
// src/components/LumirEditor.tsx
|
|
43
|
-
var
|
|
44
|
-
var
|
|
48
|
+
var import_react34 = require("react");
|
|
49
|
+
var import_react35 = require("@blocknote/react");
|
|
45
50
|
var import_mantine = require("@blocknote/mantine");
|
|
46
|
-
var
|
|
51
|
+
var import_core5 = require("@blocknote/core");
|
|
52
|
+
var import_locales = require("@blocknote/core/locales");
|
|
47
53
|
|
|
48
54
|
// src/utils/cn.ts
|
|
49
55
|
function cn(...inputs) {
|
|
@@ -279,7 +285,7 @@ var createS3Uploader = (config) => {
|
|
|
279
285
|
};
|
|
280
286
|
|
|
281
287
|
// src/blocks/HtmlPreview.tsx
|
|
282
|
-
var
|
|
288
|
+
var import_react6 = require("@blocknote/react");
|
|
283
289
|
var import_core = require("@blocknote/core");
|
|
284
290
|
|
|
285
291
|
// src/blocks/LinkPreview.tsx
|
|
@@ -1240,9 +1246,32 @@ var VideoBlock = (0, import_react3.createReactBlockSpec)(
|
|
|
1240
1246
|
}
|
|
1241
1247
|
);
|
|
1242
1248
|
|
|
1243
|
-
// src/
|
|
1244
|
-
var
|
|
1249
|
+
// src/styles/FontSizeStyle.tsx
|
|
1250
|
+
var import_react5 = require("@blocknote/react");
|
|
1245
1251
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1252
|
+
var FontSize = (0, import_react5.createReactStyleSpec)(
|
|
1253
|
+
{
|
|
1254
|
+
type: "fontSize",
|
|
1255
|
+
propSchema: "string"
|
|
1256
|
+
},
|
|
1257
|
+
{
|
|
1258
|
+
render: (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontSize: props.value }, ref: props.contentRef })
|
|
1259
|
+
}
|
|
1260
|
+
);
|
|
1261
|
+
var FONT_SIZE_PRESETS = [
|
|
1262
|
+
"10px",
|
|
1263
|
+
"12px",
|
|
1264
|
+
"14px",
|
|
1265
|
+
"16px",
|
|
1266
|
+
"18px",
|
|
1267
|
+
"20px",
|
|
1268
|
+
"24px",
|
|
1269
|
+
"28px"
|
|
1270
|
+
];
|
|
1271
|
+
|
|
1272
|
+
// src/blocks/HtmlPreview.tsx
|
|
1273
|
+
var import_react7 = require("react");
|
|
1274
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1246
1275
|
var MIN_HEIGHT = 100;
|
|
1247
1276
|
var MAX_HEIGHT = 1200;
|
|
1248
1277
|
var ensureCharset = (html) => {
|
|
@@ -1280,7 +1309,7 @@ var createSecureBlobUrl = (htmlContent) => {
|
|
|
1280
1309
|
});
|
|
1281
1310
|
return URL.createObjectURL(blob);
|
|
1282
1311
|
};
|
|
1283
|
-
var HtmlPreviewBlock = (0,
|
|
1312
|
+
var HtmlPreviewBlock = (0, import_react6.createReactBlockSpec)(
|
|
1284
1313
|
{
|
|
1285
1314
|
type: "htmlPreview",
|
|
1286
1315
|
propSchema: {
|
|
@@ -1298,15 +1327,15 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1298
1327
|
},
|
|
1299
1328
|
{
|
|
1300
1329
|
render: (props) => {
|
|
1301
|
-
const [isExpanded, setIsExpanded] = (0,
|
|
1302
|
-
const [isResizing, setIsResizing] = (0,
|
|
1303
|
-
const [blobUrl, setBlobUrl] = (0,
|
|
1304
|
-
const containerRef = (0,
|
|
1330
|
+
const [isExpanded, setIsExpanded] = (0, import_react7.useState)(true);
|
|
1331
|
+
const [isResizing, setIsResizing] = (0, import_react7.useState)(false);
|
|
1332
|
+
const [blobUrl, setBlobUrl] = (0, import_react7.useState)("");
|
|
1333
|
+
const containerRef = (0, import_react7.useRef)(null);
|
|
1305
1334
|
const htmlContent = props.block.props.htmlContent || "";
|
|
1306
1335
|
const fileName = props.block.props.fileName || "HTML Document";
|
|
1307
1336
|
const savedHeight = props.block.props.height || "400px";
|
|
1308
1337
|
const currentHeight = parseInt(savedHeight, 10) || 400;
|
|
1309
|
-
(0,
|
|
1338
|
+
(0, import_react7.useEffect)(() => {
|
|
1310
1339
|
if (htmlContent) {
|
|
1311
1340
|
const url = createSecureBlobUrl(htmlContent);
|
|
1312
1341
|
setBlobUrl(url);
|
|
@@ -1315,7 +1344,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1315
1344
|
};
|
|
1316
1345
|
}
|
|
1317
1346
|
}, [htmlContent]);
|
|
1318
|
-
const handleResizeStart = (0,
|
|
1347
|
+
const handleResizeStart = (0, import_react7.useCallback)(
|
|
1319
1348
|
(e) => {
|
|
1320
1349
|
e.preventDefault();
|
|
1321
1350
|
e.stopPropagation();
|
|
@@ -1342,7 +1371,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1342
1371
|
},
|
|
1343
1372
|
[currentHeight, props.editor, props.block]
|
|
1344
1373
|
);
|
|
1345
|
-
const handleExport = (0,
|
|
1374
|
+
const handleExport = (0, import_react7.useCallback)(
|
|
1346
1375
|
(e) => {
|
|
1347
1376
|
e.stopPropagation();
|
|
1348
1377
|
const safeFileName = sanitizeFileName(fileName);
|
|
@@ -1363,7 +1392,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1363
1392
|
},
|
|
1364
1393
|
[htmlContent, fileName]
|
|
1365
1394
|
);
|
|
1366
|
-
const handleOpenNewWindow = (0,
|
|
1395
|
+
const handleOpenNewWindow = (0, import_react7.useCallback)(
|
|
1367
1396
|
(e) => {
|
|
1368
1397
|
e.stopPropagation();
|
|
1369
1398
|
if (typeof window === "undefined") return;
|
|
@@ -1377,7 +1406,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1377
1406
|
},
|
|
1378
1407
|
[htmlContent]
|
|
1379
1408
|
);
|
|
1380
|
-
return /* @__PURE__ */ (0,
|
|
1409
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1381
1410
|
"div",
|
|
1382
1411
|
{
|
|
1383
1412
|
ref: containerRef,
|
|
@@ -1393,7 +1422,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1393
1422
|
boxShadow: "none"
|
|
1394
1423
|
},
|
|
1395
1424
|
children: [
|
|
1396
|
-
/* @__PURE__ */ (0,
|
|
1425
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1397
1426
|
"div",
|
|
1398
1427
|
{
|
|
1399
1428
|
style: {
|
|
@@ -1405,7 +1434,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1405
1434
|
borderBottom: isExpanded ? "1px solid #e0e0e0" : "none"
|
|
1406
1435
|
},
|
|
1407
1436
|
children: [
|
|
1408
|
-
/* @__PURE__ */ (0,
|
|
1437
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1409
1438
|
"div",
|
|
1410
1439
|
{
|
|
1411
1440
|
style: {
|
|
@@ -1417,7 +1446,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1417
1446
|
},
|
|
1418
1447
|
onClick: () => setIsExpanded(!isExpanded),
|
|
1419
1448
|
children: [
|
|
1420
|
-
/* @__PURE__ */ (0,
|
|
1449
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1421
1450
|
"svg",
|
|
1422
1451
|
{
|
|
1423
1452
|
width: "16",
|
|
@@ -1432,15 +1461,15 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1432
1461
|
transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)",
|
|
1433
1462
|
transition: "transform 0.2s"
|
|
1434
1463
|
},
|
|
1435
|
-
children: /* @__PURE__ */ (0,
|
|
1464
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("polyline", { points: "6 9 12 15 18 9" })
|
|
1436
1465
|
}
|
|
1437
1466
|
),
|
|
1438
|
-
/* @__PURE__ */ (0,
|
|
1467
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { fontWeight: 500, fontSize: "14px" }, children: fileName })
|
|
1439
1468
|
]
|
|
1440
1469
|
}
|
|
1441
1470
|
),
|
|
1442
|
-
/* @__PURE__ */ (0,
|
|
1443
|
-
/* @__PURE__ */ (0,
|
|
1471
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
|
|
1472
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1444
1473
|
"button",
|
|
1445
1474
|
{
|
|
1446
1475
|
onClick: handleOpenNewWindow,
|
|
@@ -1463,7 +1492,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1463
1492
|
onMouseLeave: (e) => {
|
|
1464
1493
|
e.currentTarget.style.backgroundColor = "transparent";
|
|
1465
1494
|
},
|
|
1466
|
-
children: /* @__PURE__ */ (0,
|
|
1495
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1467
1496
|
"svg",
|
|
1468
1497
|
{
|
|
1469
1498
|
width: "16",
|
|
@@ -1475,15 +1504,15 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1475
1504
|
strokeLinecap: "round",
|
|
1476
1505
|
strokeLinejoin: "round",
|
|
1477
1506
|
children: [
|
|
1478
|
-
/* @__PURE__ */ (0,
|
|
1479
|
-
/* @__PURE__ */ (0,
|
|
1480
|
-
/* @__PURE__ */ (0,
|
|
1507
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
1508
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("polyline", { points: "15 3 21 3 21 9" }),
|
|
1509
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
1481
1510
|
]
|
|
1482
1511
|
}
|
|
1483
1512
|
)
|
|
1484
1513
|
}
|
|
1485
1514
|
),
|
|
1486
|
-
/* @__PURE__ */ (0,
|
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1487
1516
|
"button",
|
|
1488
1517
|
{
|
|
1489
1518
|
onClick: handleExport,
|
|
@@ -1506,7 +1535,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1506
1535
|
onMouseLeave: (e) => {
|
|
1507
1536
|
e.currentTarget.style.backgroundColor = "transparent";
|
|
1508
1537
|
},
|
|
1509
|
-
children: /* @__PURE__ */ (0,
|
|
1538
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1510
1539
|
"svg",
|
|
1511
1540
|
{
|
|
1512
1541
|
width: "16",
|
|
@@ -1518,9 +1547,9 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1518
1547
|
strokeLinecap: "round",
|
|
1519
1548
|
strokeLinejoin: "round",
|
|
1520
1549
|
children: [
|
|
1521
|
-
/* @__PURE__ */ (0,
|
|
1522
|
-
/* @__PURE__ */ (0,
|
|
1523
|
-
/* @__PURE__ */ (0,
|
|
1550
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
1551
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("polyline", { points: "7 10 12 15 17 10" }),
|
|
1552
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
|
|
1524
1553
|
]
|
|
1525
1554
|
}
|
|
1526
1555
|
)
|
|
@@ -1530,7 +1559,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1530
1559
|
]
|
|
1531
1560
|
}
|
|
1532
1561
|
),
|
|
1533
|
-
isExpanded && /* @__PURE__ */ (0,
|
|
1562
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1534
1563
|
"div",
|
|
1535
1564
|
{
|
|
1536
1565
|
style: {
|
|
@@ -1539,7 +1568,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1539
1568
|
position: "relative"
|
|
1540
1569
|
},
|
|
1541
1570
|
children: [
|
|
1542
|
-
/* @__PURE__ */ (0,
|
|
1571
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1543
1572
|
"iframe",
|
|
1544
1573
|
{
|
|
1545
1574
|
src: blobUrl || "about:blank",
|
|
@@ -1556,7 +1585,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1556
1585
|
loading: "lazy"
|
|
1557
1586
|
}
|
|
1558
1587
|
),
|
|
1559
|
-
/* @__PURE__ */ (0,
|
|
1588
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1560
1589
|
"div",
|
|
1561
1590
|
{
|
|
1562
1591
|
onMouseDown: handleResizeStart,
|
|
@@ -1581,7 +1610,7 @@ var HtmlPreviewBlock = (0, import_react5.createReactBlockSpec)(
|
|
|
1581
1610
|
e.currentTarget.style.backgroundColor = "transparent";
|
|
1582
1611
|
}
|
|
1583
1612
|
},
|
|
1584
|
-
children: /* @__PURE__ */ (0,
|
|
1613
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1585
1614
|
"div",
|
|
1586
1615
|
{
|
|
1587
1616
|
style: {
|
|
@@ -1611,64 +1640,68 @@ var schema = import_core.BlockNoteSchema.create({
|
|
|
1611
1640
|
video: VideoBlock
|
|
1612
1641
|
},
|
|
1613
1642
|
inlineContentSpecs: import_core.defaultInlineContentSpecs,
|
|
1614
|
-
styleSpecs:
|
|
1643
|
+
styleSpecs: {
|
|
1644
|
+
...import_core.defaultStyleSpecs,
|
|
1645
|
+
// 인라인 글자 크기. 저장 JSON 직렬화는 형제 키 방식(font-size-serialization.ts) 사용.
|
|
1646
|
+
fontSize: FontSize
|
|
1647
|
+
}
|
|
1615
1648
|
});
|
|
1616
1649
|
|
|
1617
1650
|
// src/components/FloatingMenu/index.tsx
|
|
1618
|
-
var
|
|
1651
|
+
var import_react19 = require("react");
|
|
1619
1652
|
|
|
1620
1653
|
// src/components/FloatingMenu/Icons.tsx
|
|
1621
|
-
var
|
|
1654
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1622
1655
|
var Icons = {
|
|
1623
|
-
undo: /* @__PURE__ */ (0,
|
|
1624
|
-
redo: /* @__PURE__ */ (0,
|
|
1625
|
-
bold: /* @__PURE__ */ (0,
|
|
1626
|
-
italic: /* @__PURE__ */ (0,
|
|
1627
|
-
underline: /* @__PURE__ */ (0,
|
|
1628
|
-
strikethrough: /* @__PURE__ */ (0,
|
|
1629
|
-
alignLeft: /* @__PURE__ */ (0,
|
|
1630
|
-
alignCenter: /* @__PURE__ */ (0,
|
|
1631
|
-
alignRight: /* @__PURE__ */ (0,
|
|
1632
|
-
bulletList: /* @__PURE__ */ (0,
|
|
1633
|
-
numberedList: /* @__PURE__ */ (0,
|
|
1634
|
-
image: /* @__PURE__ */ (0,
|
|
1635
|
-
expandMore: /* @__PURE__ */ (0,
|
|
1636
|
-
textColor: /* @__PURE__ */ (0,
|
|
1637
|
-
bgColor: /* @__PURE__ */ (0,
|
|
1638
|
-
/* @__PURE__ */ (0,
|
|
1639
|
-
/* @__PURE__ */ (0,
|
|
1656
|
+
undo: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z" }) }),
|
|
1657
|
+
redo: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z" }) }),
|
|
1658
|
+
bold: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z" }) }),
|
|
1659
|
+
italic: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z" }) }),
|
|
1660
|
+
underline: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z" }) }),
|
|
1661
|
+
strikethrough: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z" }) }),
|
|
1662
|
+
alignLeft: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z" }) }),
|
|
1663
|
+
alignCenter: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z" }) }),
|
|
1664
|
+
alignRight: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z" }) }),
|
|
1665
|
+
bulletList: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z" }) }),
|
|
1666
|
+
numberedList: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
|
|
1667
|
+
image: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z" }) }),
|
|
1668
|
+
expandMore: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" }) }),
|
|
1669
|
+
textColor: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z" }) }),
|
|
1670
|
+
bgColor: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
|
|
1671
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M16.56 8.94L7.62 0 6.21 1.41l2.38 2.38-5.15 5.15c-.59.59-.59 1.54 0 2.12l5.5 5.5c.29.29.68.44 1.06.44s.77-.15 1.06-.44l5.5-5.5c.59-.58.59-1.53 0-2.12zM5.21 10L10 5.21 14.79 10H5.21zM19 11.5s-2 2.17-2 3.5c0 1.1.9 2 2 2s2-.9 2-2c0-1.33-2-3.5-2-3.5z" }),
|
|
1672
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { fillOpacity: ".36", d: "M0 20h24v4H0z" })
|
|
1640
1673
|
] }),
|
|
1641
|
-
link: /* @__PURE__ */ (0,
|
|
1642
|
-
chevronRight: /* @__PURE__ */ (0,
|
|
1643
|
-
chevronLeft: /* @__PURE__ */ (0,
|
|
1644
|
-
table: /* @__PURE__ */ (0,
|
|
1645
|
-
htmlFile: /* @__PURE__ */ (0,
|
|
1674
|
+
link: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" }) }),
|
|
1675
|
+
chevronRight: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) }),
|
|
1676
|
+
chevronLeft: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }) }),
|
|
1677
|
+
table: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M20 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM10 17H5v-2h5v2zm0-4H5v-2h5v2zm0-4H5V7h5v2zm9 8h-7v-2h7v2zm0-4h-7v-2h7v2zm0-4h-7V7h7v2z" }) }),
|
|
1678
|
+
htmlFile: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 2v5h5l-5-5zm-4 14H7v-1h2v1zm0-2H7v-1h2v1zm-2-2h2v1H7v-1zm4 4h-2v-1h2v1zm0-2h-2v-1h2v1zm0-2h-2v-1h2v1zm6 4h-4v-1h4v1zm0-2h-4v-1h4v1zm0-2h-4v-1h4v1z" }) })
|
|
1646
1679
|
};
|
|
1647
1680
|
var BlockTypeIcons = {
|
|
1648
|
-
paragraph: /* @__PURE__ */ (0,
|
|
1649
|
-
h1: /* @__PURE__ */ (0,
|
|
1650
|
-
h2: /* @__PURE__ */ (0,
|
|
1651
|
-
h3: /* @__PURE__ */ (0,
|
|
1652
|
-
h4: /* @__PURE__ */ (0,
|
|
1653
|
-
h5: /* @__PURE__ */ (0,
|
|
1654
|
-
h6: /* @__PURE__ */ (0,
|
|
1655
|
-
toggleH1: /* @__PURE__ */ (0,
|
|
1656
|
-
/* @__PURE__ */ (0,
|
|
1657
|
-
/* @__PURE__ */ (0,
|
|
1681
|
+
paragraph: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M5 5h14v2H5zM5 11h14v2H5zM5 17h10v2H5z" }) }),
|
|
1682
|
+
h1: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lumir-block-icon-text", children: "H1" }),
|
|
1683
|
+
h2: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lumir-block-icon-text", children: "H2" }),
|
|
1684
|
+
h3: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lumir-block-icon-text", children: "H3" }),
|
|
1685
|
+
h4: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lumir-block-icon-text", children: "H4" }),
|
|
1686
|
+
h5: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lumir-block-icon-text", children: "H5" }),
|
|
1687
|
+
h6: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lumir-block-icon-text", children: "H6" }),
|
|
1688
|
+
toggleH1: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "lumir-block-icon-toggle", children: [
|
|
1689
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 5v14l11-7z" }) }),
|
|
1690
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "H1" })
|
|
1658
1691
|
] }),
|
|
1659
|
-
toggleH2: /* @__PURE__ */ (0,
|
|
1660
|
-
/* @__PURE__ */ (0,
|
|
1661
|
-
/* @__PURE__ */ (0,
|
|
1692
|
+
toggleH2: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "lumir-block-icon-toggle", children: [
|
|
1693
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 5v14l11-7z" }) }),
|
|
1694
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "H2" })
|
|
1662
1695
|
] }),
|
|
1663
|
-
toggleH3: /* @__PURE__ */ (0,
|
|
1664
|
-
/* @__PURE__ */ (0,
|
|
1665
|
-
/* @__PURE__ */ (0,
|
|
1696
|
+
toggleH3: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "lumir-block-icon-toggle", children: [
|
|
1697
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 5v14l11-7z" }) }),
|
|
1698
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "H3" })
|
|
1666
1699
|
] }),
|
|
1667
|
-
quote: /* @__PURE__ */ (0,
|
|
1668
|
-
codeBlock: /* @__PURE__ */ (0,
|
|
1669
|
-
toggleList: /* @__PURE__ */ (0,
|
|
1670
|
-
/* @__PURE__ */ (0,
|
|
1671
|
-
/* @__PURE__ */ (0,
|
|
1700
|
+
quote: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z" }) }),
|
|
1701
|
+
codeBlock: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" }) }),
|
|
1702
|
+
toggleList: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
|
|
1703
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 6h10v2H10zM10 11h10v2H10zM10 16h10v2H10z" }),
|
|
1704
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1672
1705
|
"path",
|
|
1673
1706
|
{
|
|
1674
1707
|
d: "M4 8l4 4-4 4",
|
|
@@ -1680,15 +1713,15 @@ var BlockTypeIcons = {
|
|
|
1680
1713
|
}
|
|
1681
1714
|
)
|
|
1682
1715
|
] }),
|
|
1683
|
-
bulletList: /* @__PURE__ */ (0,
|
|
1684
|
-
/* @__PURE__ */ (0,
|
|
1685
|
-
/* @__PURE__ */ (0,
|
|
1686
|
-
/* @__PURE__ */ (0,
|
|
1687
|
-
/* @__PURE__ */ (0,
|
|
1716
|
+
bulletList: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
|
|
1717
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "4", cy: "6", r: "1.5" }),
|
|
1718
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "4", cy: "12", r: "1.5" }),
|
|
1719
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "4", cy: "18", r: "1.5" }),
|
|
1720
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 5h12v2H8zM8 11h12v2H8zM8 17h12v2H8z" })
|
|
1688
1721
|
] }),
|
|
1689
|
-
numberedList: /* @__PURE__ */ (0,
|
|
1690
|
-
checkList: /* @__PURE__ */ (0,
|
|
1691
|
-
/* @__PURE__ */ (0,
|
|
1722
|
+
numberedList: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
|
|
1723
|
+
checkList: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
|
|
1724
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1692
1725
|
"rect",
|
|
1693
1726
|
{
|
|
1694
1727
|
x: "3",
|
|
@@ -1701,7 +1734,7 @@ var BlockTypeIcons = {
|
|
|
1701
1734
|
strokeWidth: "1.5"
|
|
1702
1735
|
}
|
|
1703
1736
|
),
|
|
1704
|
-
/* @__PURE__ */ (0,
|
|
1737
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1705
1738
|
"path",
|
|
1706
1739
|
{
|
|
1707
1740
|
d: "M4.5 7l1.5 1.5 3-3",
|
|
@@ -1712,8 +1745,8 @@ var BlockTypeIcons = {
|
|
|
1712
1745
|
strokeLinejoin: "round"
|
|
1713
1746
|
}
|
|
1714
1747
|
),
|
|
1715
|
-
/* @__PURE__ */ (0,
|
|
1716
|
-
/* @__PURE__ */ (0,
|
|
1748
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 6h8v2h-8z" }),
|
|
1749
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1717
1750
|
"rect",
|
|
1718
1751
|
{
|
|
1719
1752
|
x: "3",
|
|
@@ -1726,37 +1759,37 @@ var BlockTypeIcons = {
|
|
|
1726
1759
|
strokeWidth: "1.5"
|
|
1727
1760
|
}
|
|
1728
1761
|
),
|
|
1729
|
-
/* @__PURE__ */ (0,
|
|
1762
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 16h8v2h-8z" })
|
|
1730
1763
|
] })
|
|
1731
1764
|
};
|
|
1732
1765
|
|
|
1733
1766
|
// src/components/FloatingMenu/components/ToolbarDivider.tsx
|
|
1734
|
-
var
|
|
1735
|
-
var ToolbarDivider = () => /* @__PURE__ */ (0,
|
|
1767
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1768
|
+
var ToolbarDivider = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "lumir-toolbar-divider" });
|
|
1736
1769
|
|
|
1737
1770
|
// src/components/FloatingMenu/components/UndoRedoButtons.tsx
|
|
1738
|
-
var
|
|
1739
|
-
var
|
|
1771
|
+
var import_react8 = require("react");
|
|
1772
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1740
1773
|
var UndoRedoButtons = ({ editor }) => {
|
|
1741
|
-
const handleUndo = (0,
|
|
1774
|
+
const handleUndo = (0, import_react8.useCallback)(() => {
|
|
1742
1775
|
try {
|
|
1743
1776
|
editor?.undo?.();
|
|
1744
1777
|
} catch (err) {
|
|
1745
1778
|
console.error("Undo failed:", err);
|
|
1746
1779
|
}
|
|
1747
1780
|
}, [editor]);
|
|
1748
|
-
const handleRedo = (0,
|
|
1781
|
+
const handleRedo = (0, import_react8.useCallback)(() => {
|
|
1749
1782
|
try {
|
|
1750
1783
|
editor?.redo?.();
|
|
1751
1784
|
} catch (err) {
|
|
1752
1785
|
console.error("Redo failed:", err);
|
|
1753
1786
|
}
|
|
1754
1787
|
}, [editor]);
|
|
1755
|
-
const handleMouseDown = (0,
|
|
1788
|
+
const handleMouseDown = (0, import_react8.useCallback)((e) => {
|
|
1756
1789
|
e.preventDefault();
|
|
1757
1790
|
}, []);
|
|
1758
|
-
return /* @__PURE__ */ (0,
|
|
1759
|
-
/* @__PURE__ */ (0,
|
|
1791
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
1792
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1760
1793
|
"button",
|
|
1761
1794
|
{
|
|
1762
1795
|
className: "lumir-toolbar-btn",
|
|
@@ -1767,7 +1800,7 @@ var UndoRedoButtons = ({ editor }) => {
|
|
|
1767
1800
|
children: Icons.undo
|
|
1768
1801
|
}
|
|
1769
1802
|
),
|
|
1770
|
-
/* @__PURE__ */ (0,
|
|
1803
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1771
1804
|
"button",
|
|
1772
1805
|
{
|
|
1773
1806
|
className: "lumir-toolbar-btn",
|
|
@@ -1782,8 +1815,8 @@ var UndoRedoButtons = ({ editor }) => {
|
|
|
1782
1815
|
};
|
|
1783
1816
|
|
|
1784
1817
|
// src/components/FloatingMenu/components/TextStyleButton.tsx
|
|
1785
|
-
var
|
|
1786
|
-
var
|
|
1818
|
+
var import_react9 = require("react");
|
|
1819
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1787
1820
|
var iconMap = {
|
|
1788
1821
|
bold: Icons.bold,
|
|
1789
1822
|
italic: Icons.italic,
|
|
@@ -1809,17 +1842,17 @@ var TextStyleButton = ({
|
|
|
1809
1842
|
}
|
|
1810
1843
|
};
|
|
1811
1844
|
const isActive = getIsActive();
|
|
1812
|
-
const handleClick = (0,
|
|
1845
|
+
const handleClick = (0, import_react9.useCallback)(() => {
|
|
1813
1846
|
try {
|
|
1814
1847
|
editor?.toggleStyles?.({ [style]: true });
|
|
1815
1848
|
} catch (err) {
|
|
1816
1849
|
console.error(`Toggle ${style} failed:`, err);
|
|
1817
1850
|
}
|
|
1818
1851
|
}, [editor, style]);
|
|
1819
|
-
const handleMouseDown = (0,
|
|
1852
|
+
const handleMouseDown = (0, import_react9.useCallback)((e) => {
|
|
1820
1853
|
e.preventDefault();
|
|
1821
1854
|
}, []);
|
|
1822
|
-
return /* @__PURE__ */ (0,
|
|
1855
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1823
1856
|
"button",
|
|
1824
1857
|
{
|
|
1825
1858
|
className: cn("lumir-toolbar-btn", isActive && "is-active"),
|
|
@@ -1833,8 +1866,68 @@ var TextStyleButton = ({
|
|
|
1833
1866
|
};
|
|
1834
1867
|
|
|
1835
1868
|
// src/components/FloatingMenu/components/AlignButton.tsx
|
|
1836
|
-
var
|
|
1837
|
-
|
|
1869
|
+
var import_react10 = require("react");
|
|
1870
|
+
|
|
1871
|
+
// src/utils/prosemirror-table-utils.ts
|
|
1872
|
+
function getSelectedCellPositions(editor) {
|
|
1873
|
+
const tiptap = editor._tiptapEditor;
|
|
1874
|
+
if (!tiptap) return [];
|
|
1875
|
+
const { state } = tiptap;
|
|
1876
|
+
const { selection } = state;
|
|
1877
|
+
if (typeof selection.forEachCell === "function") {
|
|
1878
|
+
const positions = [];
|
|
1879
|
+
selection.forEachCell((_node, pos) => {
|
|
1880
|
+
positions.push(pos);
|
|
1881
|
+
});
|
|
1882
|
+
return positions;
|
|
1883
|
+
}
|
|
1884
|
+
const $pos = selection.$from;
|
|
1885
|
+
for (let depth = $pos.depth; depth > 0; depth--) {
|
|
1886
|
+
const node = $pos.node(depth);
|
|
1887
|
+
if (node.type.name === "tableCell" || node.type.name === "tableHeader") {
|
|
1888
|
+
return [$pos.before(depth)];
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
return [];
|
|
1892
|
+
}
|
|
1893
|
+
function setCellAttrAtPositions(editor, positions, attr, value) {
|
|
1894
|
+
const tiptap = editor?._tiptapEditor;
|
|
1895
|
+
if (!tiptap || positions.length === 0) return false;
|
|
1896
|
+
let tr = tiptap.state.tr;
|
|
1897
|
+
let changed = false;
|
|
1898
|
+
for (const pos of positions) {
|
|
1899
|
+
const node = tr.doc.nodeAt(pos);
|
|
1900
|
+
if (node && (node.type.name === "tableCell" || node.type.name === "tableHeader")) {
|
|
1901
|
+
tr = tr.setNodeMarkup(pos, void 0, { ...node.attrs, [attr]: value });
|
|
1902
|
+
changed = true;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
if (changed) {
|
|
1906
|
+
tiptap.view?.dispatch(tr);
|
|
1907
|
+
}
|
|
1908
|
+
return changed;
|
|
1909
|
+
}
|
|
1910
|
+
function setSelectedCellsAttr(editor, attr, value) {
|
|
1911
|
+
return setCellAttrAtPositions(
|
|
1912
|
+
editor,
|
|
1913
|
+
getSelectedCellPositions(editor),
|
|
1914
|
+
attr,
|
|
1915
|
+
value
|
|
1916
|
+
);
|
|
1917
|
+
}
|
|
1918
|
+
function isInTableCell(editor) {
|
|
1919
|
+
return getSelectedCellPositions(editor).length > 0;
|
|
1920
|
+
}
|
|
1921
|
+
function getFirstSelectedCellAttr(editor, attr) {
|
|
1922
|
+
const tiptap = editor?._tiptapEditor;
|
|
1923
|
+
const positions = getSelectedCellPositions(editor);
|
|
1924
|
+
if (!tiptap || positions.length === 0) return void 0;
|
|
1925
|
+
const node = tiptap.state.doc.nodeAt(positions[0]);
|
|
1926
|
+
return node?.attrs?.[attr];
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
// src/components/FloatingMenu/components/AlignButton.tsx
|
|
1930
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1838
1931
|
var iconMap2 = {
|
|
1839
1932
|
left: Icons.alignLeft,
|
|
1840
1933
|
center: Icons.alignCenter,
|
|
@@ -1851,6 +1944,9 @@ var AlignButton = ({
|
|
|
1851
1944
|
}) => {
|
|
1852
1945
|
const getCurrentAlignment = () => {
|
|
1853
1946
|
try {
|
|
1947
|
+
if (isInTableCell(editor)) {
|
|
1948
|
+
return getFirstSelectedCellAttr(editor, "textAlignment") || "left";
|
|
1949
|
+
}
|
|
1854
1950
|
const block = editor?.getTextCursorPosition()?.block;
|
|
1855
1951
|
return block?.props?.textAlignment || "left";
|
|
1856
1952
|
} catch {
|
|
@@ -1858,8 +1954,11 @@ var AlignButton = ({
|
|
|
1858
1954
|
}
|
|
1859
1955
|
};
|
|
1860
1956
|
const isActive = getCurrentAlignment() === alignment;
|
|
1861
|
-
const handleClick = (0,
|
|
1957
|
+
const handleClick = (0, import_react10.useCallback)(() => {
|
|
1862
1958
|
try {
|
|
1959
|
+
if (setSelectedCellsAttr(editor, "textAlignment", alignment)) {
|
|
1960
|
+
return;
|
|
1961
|
+
}
|
|
1863
1962
|
const block = editor?.getTextCursorPosition()?.block;
|
|
1864
1963
|
if (block && editor?.updateBlock) {
|
|
1865
1964
|
editor.updateBlock(block, { props: { textAlignment: alignment } });
|
|
@@ -1868,10 +1967,10 @@ var AlignButton = ({
|
|
|
1868
1967
|
console.error(`Set alignment ${alignment} failed:`, err);
|
|
1869
1968
|
}
|
|
1870
1969
|
}, [editor, alignment]);
|
|
1871
|
-
const handleMouseDown = (0,
|
|
1970
|
+
const handleMouseDown = (0, import_react10.useCallback)((e) => {
|
|
1872
1971
|
e.preventDefault();
|
|
1873
1972
|
}, []);
|
|
1874
|
-
return /* @__PURE__ */ (0,
|
|
1973
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1875
1974
|
"button",
|
|
1876
1975
|
{
|
|
1877
1976
|
className: cn("lumir-toolbar-btn", isActive && "is-active"),
|
|
@@ -1885,8 +1984,8 @@ var AlignButton = ({
|
|
|
1885
1984
|
};
|
|
1886
1985
|
|
|
1887
1986
|
// src/components/FloatingMenu/components/ListButton.tsx
|
|
1888
|
-
var
|
|
1889
|
-
var
|
|
1987
|
+
var import_react11 = require("react");
|
|
1988
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1890
1989
|
var iconMap3 = {
|
|
1891
1990
|
bullet: Icons.bulletList,
|
|
1892
1991
|
numbered: Icons.numberedList
|
|
@@ -1906,7 +2005,7 @@ var ListButton = ({ editor, type }) => {
|
|
|
1906
2005
|
}
|
|
1907
2006
|
};
|
|
1908
2007
|
const isActive = getIsActive();
|
|
1909
|
-
const handleClick = (0,
|
|
2008
|
+
const handleClick = (0, import_react11.useCallback)(() => {
|
|
1910
2009
|
try {
|
|
1911
2010
|
const block = editor?.getTextCursorPosition()?.block;
|
|
1912
2011
|
if (block && editor?.updateBlock) {
|
|
@@ -1918,10 +2017,10 @@ var ListButton = ({ editor, type }) => {
|
|
|
1918
2017
|
console.error(`List toggle failed:`, err);
|
|
1919
2018
|
}
|
|
1920
2019
|
}, [editor, type]);
|
|
1921
|
-
const handleMouseDown = (0,
|
|
2020
|
+
const handleMouseDown = (0, import_react11.useCallback)((e) => {
|
|
1922
2021
|
e.preventDefault();
|
|
1923
2022
|
}, []);
|
|
1924
|
-
return /* @__PURE__ */ (0,
|
|
2023
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1925
2024
|
"button",
|
|
1926
2025
|
{
|
|
1927
2026
|
className: cn("lumir-toolbar-btn", isActive && "is-active"),
|
|
@@ -1935,13 +2034,13 @@ var ListButton = ({ editor, type }) => {
|
|
|
1935
2034
|
};
|
|
1936
2035
|
|
|
1937
2036
|
// src/components/FloatingMenu/components/ImageButton.tsx
|
|
1938
|
-
var
|
|
1939
|
-
var
|
|
2037
|
+
var import_react12 = require("react");
|
|
2038
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1940
2039
|
var ImageButton = ({
|
|
1941
2040
|
editor,
|
|
1942
2041
|
onImageUpload
|
|
1943
2042
|
}) => {
|
|
1944
|
-
const handleClick = (0,
|
|
2043
|
+
const handleClick = (0, import_react12.useCallback)(() => {
|
|
1945
2044
|
if (onImageUpload) {
|
|
1946
2045
|
onImageUpload();
|
|
1947
2046
|
} else {
|
|
@@ -1966,10 +2065,10 @@ var ImageButton = ({
|
|
|
1966
2065
|
input.click();
|
|
1967
2066
|
}
|
|
1968
2067
|
}, [editor, onImageUpload]);
|
|
1969
|
-
const handleMouseDown = (0,
|
|
2068
|
+
const handleMouseDown = (0, import_react12.useCallback)((e) => {
|
|
1970
2069
|
e.preventDefault();
|
|
1971
2070
|
}, []);
|
|
1972
|
-
return /* @__PURE__ */ (0,
|
|
2071
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1973
2072
|
"button",
|
|
1974
2073
|
{
|
|
1975
2074
|
className: "lumir-toolbar-btn",
|
|
@@ -1983,7 +2082,7 @@ var ImageButton = ({
|
|
|
1983
2082
|
};
|
|
1984
2083
|
|
|
1985
2084
|
// src/components/FloatingMenu/components/ColorButton.tsx
|
|
1986
|
-
var
|
|
2085
|
+
var import_react13 = require("react");
|
|
1987
2086
|
|
|
1988
2087
|
// src/constants/colors.ts
|
|
1989
2088
|
var TEXT_COLORS = [
|
|
@@ -2017,14 +2116,18 @@ var getHexFromColorValue = (value, type) => {
|
|
|
2017
2116
|
};
|
|
2018
2117
|
|
|
2019
2118
|
// src/components/FloatingMenu/components/ColorButton.tsx
|
|
2020
|
-
var
|
|
2119
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2021
2120
|
var ColorButton = ({ editor, type }) => {
|
|
2022
|
-
const [isOpen, setIsOpen] = (0,
|
|
2023
|
-
const [currentColor, setCurrentColor] = (0,
|
|
2024
|
-
const dropdownRef = (0,
|
|
2121
|
+
const [isOpen, setIsOpen] = (0, import_react13.useState)(false);
|
|
2122
|
+
const [currentColor, setCurrentColor] = (0, import_react13.useState)("default");
|
|
2123
|
+
const dropdownRef = (0, import_react13.useRef)(null);
|
|
2025
2124
|
const colors = type === "text" ? TEXT_COLORS : BACKGROUND_COLORS;
|
|
2026
|
-
const getCurrentColor = (0,
|
|
2125
|
+
const getCurrentColor = (0, import_react13.useCallback)(() => {
|
|
2027
2126
|
try {
|
|
2127
|
+
if (isInTableCell(editor)) {
|
|
2128
|
+
const attr = type === "text" ? "textColor" : "backgroundColor";
|
|
2129
|
+
return getFirstSelectedCellAttr(editor, attr) || "default";
|
|
2130
|
+
}
|
|
2028
2131
|
const activeStyles = editor?.getActiveStyles?.() || {};
|
|
2029
2132
|
if (type === "text" && activeStyles.textColor) {
|
|
2030
2133
|
return activeStyles.textColor;
|
|
@@ -2035,13 +2138,13 @@ var ColorButton = ({ editor, type }) => {
|
|
|
2035
2138
|
}
|
|
2036
2139
|
return "default";
|
|
2037
2140
|
}, [editor, type]);
|
|
2038
|
-
(0,
|
|
2141
|
+
(0, import_react13.useEffect)(() => {
|
|
2039
2142
|
if (isOpen) {
|
|
2040
2143
|
const color = getCurrentColor();
|
|
2041
2144
|
setCurrentColor(color);
|
|
2042
2145
|
}
|
|
2043
2146
|
}, [isOpen, getCurrentColor]);
|
|
2044
|
-
(0,
|
|
2147
|
+
(0, import_react13.useEffect)(() => {
|
|
2045
2148
|
const handleClickOutside = (e) => {
|
|
2046
2149
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
2047
2150
|
setIsOpen(false);
|
|
@@ -2050,28 +2153,30 @@ var ColorButton = ({ editor, type }) => {
|
|
|
2050
2153
|
document.addEventListener("mousedown", handleClickOutside);
|
|
2051
2154
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2052
2155
|
}, []);
|
|
2053
|
-
const handleColorSelect = (0,
|
|
2156
|
+
const handleColorSelect = (0, import_react13.useCallback)(
|
|
2054
2157
|
(color) => {
|
|
2055
2158
|
try {
|
|
2056
2159
|
if (!editor) return;
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2160
|
+
const attr = type === "text" ? "textColor" : "backgroundColor";
|
|
2161
|
+
if (!setSelectedCellsAttr(editor, attr, color)) {
|
|
2162
|
+
editor.toggleStyles(
|
|
2163
|
+
type === "text" ? { textColor: color } : { backgroundColor: color }
|
|
2164
|
+
);
|
|
2061
2165
|
}
|
|
2062
2166
|
setCurrentColor(color);
|
|
2063
2167
|
setIsOpen(false);
|
|
2168
|
+
setTimeout(() => editor.focus?.());
|
|
2064
2169
|
} catch (err) {
|
|
2065
2170
|
console.error(`Color apply failed:`, err);
|
|
2066
2171
|
}
|
|
2067
2172
|
},
|
|
2068
2173
|
[editor, type]
|
|
2069
2174
|
);
|
|
2070
|
-
const handleMouseDown = (0,
|
|
2175
|
+
const handleMouseDown = (0, import_react13.useCallback)((e) => {
|
|
2071
2176
|
e.preventDefault();
|
|
2072
2177
|
}, []);
|
|
2073
|
-
return /* @__PURE__ */ (0,
|
|
2074
|
-
/* @__PURE__ */ (0,
|
|
2178
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
|
|
2179
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2075
2180
|
"button",
|
|
2076
2181
|
{
|
|
2077
2182
|
className: "lumir-toolbar-btn lumir-color-btn",
|
|
@@ -2081,7 +2186,7 @@ var ColorButton = ({ editor, type }) => {
|
|
|
2081
2186
|
type: "button",
|
|
2082
2187
|
children: [
|
|
2083
2188
|
type === "text" ? Icons.textColor : Icons.bgColor,
|
|
2084
|
-
/* @__PURE__ */ (0,
|
|
2189
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2085
2190
|
"span",
|
|
2086
2191
|
{
|
|
2087
2192
|
className: "lumir-color-indicator",
|
|
@@ -2093,7 +2198,7 @@ var ColorButton = ({ editor, type }) => {
|
|
|
2093
2198
|
]
|
|
2094
2199
|
}
|
|
2095
2200
|
),
|
|
2096
|
-
isOpen && /* @__PURE__ */ (0,
|
|
2201
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "lumir-dropdown-menu lumir-color-menu", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "lumir-color-grid", children: colors.map((color) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2097
2202
|
"button",
|
|
2098
2203
|
{
|
|
2099
2204
|
className: cn(
|
|
@@ -2111,9 +2216,101 @@ var ColorButton = ({ editor, type }) => {
|
|
|
2111
2216
|
] });
|
|
2112
2217
|
};
|
|
2113
2218
|
|
|
2219
|
+
// src/components/FloatingMenu/components/FontSizeButton.tsx
|
|
2220
|
+
var import_react14 = require("react");
|
|
2221
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2222
|
+
var DEFAULT_LABEL = "\uAE30\uBCF8";
|
|
2223
|
+
var toLabel = (size) => size.replace(/px$/, "");
|
|
2224
|
+
var FontSizeButton = ({ editor }) => {
|
|
2225
|
+
const [isOpen, setIsOpen] = (0, import_react14.useState)(false);
|
|
2226
|
+
const dropdownRef = (0, import_react14.useRef)(null);
|
|
2227
|
+
const getCurrentSize = () => {
|
|
2228
|
+
try {
|
|
2229
|
+
return editor?.getActiveStyles?.()?.fontSize || "";
|
|
2230
|
+
} catch {
|
|
2231
|
+
return "";
|
|
2232
|
+
}
|
|
2233
|
+
};
|
|
2234
|
+
const currentSize = getCurrentSize();
|
|
2235
|
+
(0, import_react14.useEffect)(() => {
|
|
2236
|
+
const handleClickOutside = (e) => {
|
|
2237
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
2238
|
+
setIsOpen(false);
|
|
2239
|
+
}
|
|
2240
|
+
};
|
|
2241
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
2242
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2243
|
+
}, []);
|
|
2244
|
+
const handleSizeSelect = (0, import_react14.useCallback)(
|
|
2245
|
+
(size) => {
|
|
2246
|
+
try {
|
|
2247
|
+
if (!editor) return;
|
|
2248
|
+
if (size === "") {
|
|
2249
|
+
editor.removeStyles?.({ fontSize: "" });
|
|
2250
|
+
} else {
|
|
2251
|
+
editor.addStyles?.({ fontSize: size });
|
|
2252
|
+
}
|
|
2253
|
+
setIsOpen(false);
|
|
2254
|
+
setTimeout(() => editor.focus?.());
|
|
2255
|
+
} catch (err) {
|
|
2256
|
+
console.error("Font size apply failed:", err);
|
|
2257
|
+
}
|
|
2258
|
+
},
|
|
2259
|
+
[editor]
|
|
2260
|
+
);
|
|
2261
|
+
const handleMouseDown = (0, import_react14.useCallback)((e) => {
|
|
2262
|
+
e.preventDefault();
|
|
2263
|
+
}, []);
|
|
2264
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
|
|
2265
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2266
|
+
"button",
|
|
2267
|
+
{
|
|
2268
|
+
className: "lumir-dropdown-btn lumir-font-size-btn",
|
|
2269
|
+
onClick: () => setIsOpen(!isOpen),
|
|
2270
|
+
onMouseDown: handleMouseDown,
|
|
2271
|
+
title: "\uAE00\uC790 \uD06C\uAE30",
|
|
2272
|
+
type: "button",
|
|
2273
|
+
children: [
|
|
2274
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "lumir-font-size-label", children: currentSize ? toLabel(currentSize) : DEFAULT_LABEL }),
|
|
2275
|
+
Icons.expandMore
|
|
2276
|
+
]
|
|
2277
|
+
}
|
|
2278
|
+
),
|
|
2279
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "lumir-dropdown-menu lumir-font-size-menu", children: [
|
|
2280
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2281
|
+
"button",
|
|
2282
|
+
{
|
|
2283
|
+
className: cn(
|
|
2284
|
+
"lumir-dropdown-item",
|
|
2285
|
+
currentSize === "" && "is-active"
|
|
2286
|
+
),
|
|
2287
|
+
onClick: () => handleSizeSelect(""),
|
|
2288
|
+
onMouseDown: handleMouseDown,
|
|
2289
|
+
type: "button",
|
|
2290
|
+
children: DEFAULT_LABEL
|
|
2291
|
+
}
|
|
2292
|
+
),
|
|
2293
|
+
FONT_SIZE_PRESETS.map((size) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2294
|
+
"button",
|
|
2295
|
+
{
|
|
2296
|
+
className: cn(
|
|
2297
|
+
"lumir-dropdown-item",
|
|
2298
|
+
currentSize === size && "is-active"
|
|
2299
|
+
),
|
|
2300
|
+
onClick: () => handleSizeSelect(size),
|
|
2301
|
+
onMouseDown: handleMouseDown,
|
|
2302
|
+
type: "button",
|
|
2303
|
+
children: toLabel(size)
|
|
2304
|
+
},
|
|
2305
|
+
size
|
|
2306
|
+
))
|
|
2307
|
+
] })
|
|
2308
|
+
] });
|
|
2309
|
+
};
|
|
2310
|
+
|
|
2114
2311
|
// src/components/FloatingMenu/components/LinkButton.tsx
|
|
2115
|
-
var
|
|
2116
|
-
var
|
|
2312
|
+
var import_react15 = require("react");
|
|
2313
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2117
2314
|
var isDangerousProtocol = (url) => {
|
|
2118
2315
|
const trimmedUrl = url.trim().toLowerCase();
|
|
2119
2316
|
const dangerousPatterns = [
|
|
@@ -2139,13 +2336,13 @@ var normalizeUrl = (url) => {
|
|
|
2139
2336
|
return `https://${trimmedUrl}`;
|
|
2140
2337
|
};
|
|
2141
2338
|
var LinkButton = ({ editor }) => {
|
|
2142
|
-
const [isOpen, setIsOpen] = (0,
|
|
2143
|
-
const [linkUrl, setLinkUrl] = (0,
|
|
2144
|
-
const [errorMsg, setErrorMsg] = (0,
|
|
2145
|
-
const dropdownRef = (0,
|
|
2146
|
-
const inputRef = (0,
|
|
2147
|
-
const hasSelectionRef = (0,
|
|
2148
|
-
(0,
|
|
2339
|
+
const [isOpen, setIsOpen] = (0, import_react15.useState)(false);
|
|
2340
|
+
const [linkUrl, setLinkUrl] = (0, import_react15.useState)("");
|
|
2341
|
+
const [errorMsg, setErrorMsg] = (0, import_react15.useState)(null);
|
|
2342
|
+
const dropdownRef = (0, import_react15.useRef)(null);
|
|
2343
|
+
const inputRef = (0, import_react15.useRef)(null);
|
|
2344
|
+
const hasSelectionRef = (0, import_react15.useRef)(false);
|
|
2345
|
+
(0, import_react15.useEffect)(() => {
|
|
2149
2346
|
const handleClickOutside = (e) => {
|
|
2150
2347
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
2151
2348
|
setIsOpen(false);
|
|
@@ -2156,7 +2353,7 @@ var LinkButton = ({ editor }) => {
|
|
|
2156
2353
|
document.addEventListener("mousedown", handleClickOutside);
|
|
2157
2354
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2158
2355
|
}, []);
|
|
2159
|
-
(0,
|
|
2356
|
+
(0, import_react15.useEffect)(() => {
|
|
2160
2357
|
if (isOpen && inputRef.current) {
|
|
2161
2358
|
try {
|
|
2162
2359
|
const selectedText = editor?.getSelectedText?.() || "";
|
|
@@ -2167,7 +2364,7 @@ var LinkButton = ({ editor }) => {
|
|
|
2167
2364
|
setTimeout(() => inputRef.current?.focus(), 0);
|
|
2168
2365
|
}
|
|
2169
2366
|
}, [isOpen, editor]);
|
|
2170
|
-
const handleSubmit = (0,
|
|
2367
|
+
const handleSubmit = (0, import_react15.useCallback)(
|
|
2171
2368
|
(e) => {
|
|
2172
2369
|
e?.preventDefault();
|
|
2173
2370
|
setErrorMsg(null);
|
|
@@ -2194,15 +2391,15 @@ var LinkButton = ({ editor }) => {
|
|
|
2194
2391
|
},
|
|
2195
2392
|
[editor, linkUrl]
|
|
2196
2393
|
);
|
|
2197
|
-
const handleCancel = (0,
|
|
2394
|
+
const handleCancel = (0, import_react15.useCallback)(() => {
|
|
2198
2395
|
setIsOpen(false);
|
|
2199
2396
|
setLinkUrl("");
|
|
2200
2397
|
setErrorMsg(null);
|
|
2201
2398
|
}, []);
|
|
2202
|
-
const handleMouseDown = (0,
|
|
2399
|
+
const handleMouseDown = (0, import_react15.useCallback)((e) => {
|
|
2203
2400
|
e.preventDefault();
|
|
2204
2401
|
}, []);
|
|
2205
|
-
const handleKeyDown = (0,
|
|
2402
|
+
const handleKeyDown = (0, import_react15.useCallback)(
|
|
2206
2403
|
(e) => {
|
|
2207
2404
|
if (e.key === "Enter") {
|
|
2208
2405
|
handleSubmit();
|
|
@@ -2212,8 +2409,8 @@ var LinkButton = ({ editor }) => {
|
|
|
2212
2409
|
},
|
|
2213
2410
|
[handleSubmit, handleCancel]
|
|
2214
2411
|
);
|
|
2215
|
-
return /* @__PURE__ */ (0,
|
|
2216
|
-
/* @__PURE__ */ (0,
|
|
2412
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
|
|
2413
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2217
2414
|
"button",
|
|
2218
2415
|
{
|
|
2219
2416
|
className: "lumir-toolbar-btn",
|
|
@@ -2224,8 +2421,8 @@ var LinkButton = ({ editor }) => {
|
|
|
2224
2421
|
children: Icons.link
|
|
2225
2422
|
}
|
|
2226
2423
|
),
|
|
2227
|
-
isOpen && /* @__PURE__ */ (0,
|
|
2228
|
-
/* @__PURE__ */ (0,
|
|
2424
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "lumir-dropdown-menu lumir-link-menu", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("form", { onSubmit: handleSubmit, className: "lumir-link-form", children: [
|
|
2425
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2229
2426
|
"input",
|
|
2230
2427
|
{
|
|
2231
2428
|
ref: inputRef,
|
|
@@ -2241,7 +2438,7 @@ var LinkButton = ({ editor }) => {
|
|
|
2241
2438
|
onMouseDown: handleMouseDown
|
|
2242
2439
|
}
|
|
2243
2440
|
),
|
|
2244
|
-
errorMsg && /* @__PURE__ */ (0,
|
|
2441
|
+
errorMsg && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2245
2442
|
"div",
|
|
2246
2443
|
{
|
|
2247
2444
|
style: {
|
|
@@ -2253,8 +2450,8 @@ var LinkButton = ({ editor }) => {
|
|
|
2253
2450
|
children: errorMsg
|
|
2254
2451
|
}
|
|
2255
2452
|
),
|
|
2256
|
-
/* @__PURE__ */ (0,
|
|
2257
|
-
/* @__PURE__ */ (0,
|
|
2453
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "lumir-link-actions", children: [
|
|
2454
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2258
2455
|
"button",
|
|
2259
2456
|
{
|
|
2260
2457
|
type: "button",
|
|
@@ -2264,7 +2461,7 @@ var LinkButton = ({ editor }) => {
|
|
|
2264
2461
|
children: "\uCDE8\uC18C"
|
|
2265
2462
|
}
|
|
2266
2463
|
),
|
|
2267
|
-
/* @__PURE__ */ (0,
|
|
2464
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2268
2465
|
"button",
|
|
2269
2466
|
{
|
|
2270
2467
|
type: "submit",
|
|
@@ -2280,10 +2477,10 @@ var LinkButton = ({ editor }) => {
|
|
|
2280
2477
|
};
|
|
2281
2478
|
|
|
2282
2479
|
// src/components/FloatingMenu/components/TableButton.tsx
|
|
2283
|
-
var
|
|
2284
|
-
var
|
|
2480
|
+
var import_react16 = require("react");
|
|
2481
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2285
2482
|
var TableButton = ({ editor }) => {
|
|
2286
|
-
const handleClick = (0,
|
|
2483
|
+
const handleClick = (0, import_react16.useCallback)(() => {
|
|
2287
2484
|
try {
|
|
2288
2485
|
const block = editor?.getTextCursorPosition()?.block;
|
|
2289
2486
|
if (!block || !editor?.insertBlocks) return;
|
|
@@ -2305,10 +2502,10 @@ var TableButton = ({ editor }) => {
|
|
|
2305
2502
|
console.error("Table insert failed:", err);
|
|
2306
2503
|
}
|
|
2307
2504
|
}, [editor]);
|
|
2308
|
-
const handleMouseDown = (0,
|
|
2505
|
+
const handleMouseDown = (0, import_react16.useCallback)((e) => {
|
|
2309
2506
|
e.preventDefault();
|
|
2310
2507
|
}, []);
|
|
2311
|
-
return /* @__PURE__ */ (0,
|
|
2508
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2312
2509
|
"button",
|
|
2313
2510
|
{
|
|
2314
2511
|
className: "lumir-toolbar-btn",
|
|
@@ -2322,13 +2519,13 @@ var TableButton = ({ editor }) => {
|
|
|
2322
2519
|
};
|
|
2323
2520
|
|
|
2324
2521
|
// src/components/FloatingMenu/components/HTMLImportButton.tsx
|
|
2325
|
-
var
|
|
2326
|
-
var
|
|
2522
|
+
var import_react17 = require("react");
|
|
2523
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2327
2524
|
var HTMLImportButton = ({
|
|
2328
2525
|
editor
|
|
2329
2526
|
}) => {
|
|
2330
|
-
const fileInputRef = (0,
|
|
2331
|
-
const handleFileUpload = (0,
|
|
2527
|
+
const fileInputRef = (0, import_react17.useRef)(null);
|
|
2528
|
+
const handleFileUpload = (0, import_react17.useCallback)(
|
|
2332
2529
|
(e) => {
|
|
2333
2530
|
const file = e.target.files?.[0];
|
|
2334
2531
|
if (!file) return;
|
|
@@ -2364,14 +2561,14 @@ var HTMLImportButton = ({
|
|
|
2364
2561
|
},
|
|
2365
2562
|
[editor]
|
|
2366
2563
|
);
|
|
2367
|
-
const handleClick = (0,
|
|
2564
|
+
const handleClick = (0, import_react17.useCallback)(() => {
|
|
2368
2565
|
fileInputRef.current?.click();
|
|
2369
2566
|
}, []);
|
|
2370
|
-
const handleMouseDown = (0,
|
|
2567
|
+
const handleMouseDown = (0, import_react17.useCallback)((e) => {
|
|
2371
2568
|
e.preventDefault();
|
|
2372
2569
|
}, []);
|
|
2373
|
-
return /* @__PURE__ */ (0,
|
|
2374
|
-
/* @__PURE__ */ (0,
|
|
2570
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
2571
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2375
2572
|
"input",
|
|
2376
2573
|
{
|
|
2377
2574
|
ref: fileInputRef,
|
|
@@ -2381,7 +2578,7 @@ var HTMLImportButton = ({
|
|
|
2381
2578
|
style: { display: "none" }
|
|
2382
2579
|
}
|
|
2383
2580
|
),
|
|
2384
|
-
/* @__PURE__ */ (0,
|
|
2581
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2385
2582
|
"button",
|
|
2386
2583
|
{
|
|
2387
2584
|
className: "lumir-toolbar-btn",
|
|
@@ -2396,8 +2593,8 @@ var HTMLImportButton = ({
|
|
|
2396
2593
|
};
|
|
2397
2594
|
|
|
2398
2595
|
// src/components/FloatingMenu/components/BlockTypeSelect.tsx
|
|
2399
|
-
var
|
|
2400
|
-
var
|
|
2596
|
+
var import_react18 = require("react");
|
|
2597
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2401
2598
|
var blockTypeCategories = [
|
|
2402
2599
|
{
|
|
2403
2600
|
category: "Headings",
|
|
@@ -2427,8 +2624,8 @@ var blockTypes = blockTypeCategories.flatMap(
|
|
|
2427
2624
|
(cat) => cat.items
|
|
2428
2625
|
);
|
|
2429
2626
|
var BlockTypeSelect = ({ editor }) => {
|
|
2430
|
-
const [isOpen, setIsOpen] = (0,
|
|
2431
|
-
const dropdownRef = (0,
|
|
2627
|
+
const [isOpen, setIsOpen] = (0, import_react18.useState)(false);
|
|
2628
|
+
const dropdownRef = (0, import_react18.useRef)(null);
|
|
2432
2629
|
const getCurrentBlock = () => {
|
|
2433
2630
|
try {
|
|
2434
2631
|
return editor?.getTextCursorPosition()?.block;
|
|
@@ -2440,7 +2637,7 @@ var BlockTypeSelect = ({ editor }) => {
|
|
|
2440
2637
|
const currentType = currentBlock?.type || "paragraph";
|
|
2441
2638
|
const currentLevel = currentBlock?.props?.level;
|
|
2442
2639
|
const isCurrentToggle = currentType === "heading" && currentBlock?.props?.isToggleable === true;
|
|
2443
|
-
(0,
|
|
2640
|
+
(0, import_react18.useEffect)(() => {
|
|
2444
2641
|
const handleClickOutside = (e) => {
|
|
2445
2642
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
2446
2643
|
setIsOpen(false);
|
|
@@ -2469,7 +2666,7 @@ var BlockTypeSelect = ({ editor }) => {
|
|
|
2469
2666
|
console.error("Block type change failed:", err);
|
|
2470
2667
|
}
|
|
2471
2668
|
};
|
|
2472
|
-
const handleMouseDown = (0,
|
|
2669
|
+
const handleMouseDown = (0, import_react18.useCallback)((e) => {
|
|
2473
2670
|
e.preventDefault();
|
|
2474
2671
|
}, []);
|
|
2475
2672
|
const getCurrentLabel = () => {
|
|
@@ -2500,8 +2697,8 @@ var BlockTypeSelect = ({ editor }) => {
|
|
|
2500
2697
|
}
|
|
2501
2698
|
return currentType === bt.type;
|
|
2502
2699
|
};
|
|
2503
|
-
return /* @__PURE__ */ (0,
|
|
2504
|
-
/* @__PURE__ */ (0,
|
|
2700
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
|
|
2701
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
2505
2702
|
"button",
|
|
2506
2703
|
{
|
|
2507
2704
|
className: "lumir-dropdown-btn lumir-block-type-btn",
|
|
@@ -2509,15 +2706,15 @@ var BlockTypeSelect = ({ editor }) => {
|
|
|
2509
2706
|
onMouseDown: handleMouseDown,
|
|
2510
2707
|
type: "button",
|
|
2511
2708
|
children: [
|
|
2512
|
-
/* @__PURE__ */ (0,
|
|
2513
|
-
/* @__PURE__ */ (0,
|
|
2709
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "lumir-block-icon", children: BlockTypeIcons[getCurrentIcon()] }),
|
|
2710
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "lumir-block-label", children: getCurrentLabel() }),
|
|
2514
2711
|
Icons.expandMore
|
|
2515
2712
|
]
|
|
2516
2713
|
}
|
|
2517
2714
|
),
|
|
2518
|
-
isOpen && /* @__PURE__ */ (0,
|
|
2519
|
-
/* @__PURE__ */ (0,
|
|
2520
|
-
category.items.map((bt) => /* @__PURE__ */ (0,
|
|
2715
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "lumir-dropdown-menu lumir-block-menu", children: blockTypeCategories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "lumir-block-category", children: [
|
|
2716
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "lumir-block-category-title", children: category.category }),
|
|
2717
|
+
category.items.map((bt) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
2521
2718
|
"button",
|
|
2522
2719
|
{
|
|
2523
2720
|
className: cn(
|
|
@@ -2527,8 +2724,8 @@ var BlockTypeSelect = ({ editor }) => {
|
|
|
2527
2724
|
onClick: () => handleTypeChange(bt.type, bt.level, bt.isToggle),
|
|
2528
2725
|
onMouseDown: handleMouseDown,
|
|
2529
2726
|
children: [
|
|
2530
|
-
/* @__PURE__ */ (0,
|
|
2531
|
-
/* @__PURE__ */ (0,
|
|
2727
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "lumir-block-icon", children: BlockTypeIcons[bt.icon] }),
|
|
2728
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "lumir-block-item-title", children: bt.label })
|
|
2532
2729
|
]
|
|
2533
2730
|
},
|
|
2534
2731
|
bt.icon
|
|
@@ -2538,7 +2735,7 @@ var BlockTypeSelect = ({ editor }) => {
|
|
|
2538
2735
|
};
|
|
2539
2736
|
|
|
2540
2737
|
// src/components/FloatingMenu/index.tsx
|
|
2541
|
-
var
|
|
2738
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2542
2739
|
var COMPACT_BREAKPOINT = 700;
|
|
2543
2740
|
var MINIMIZED_BREAKPOINT = 400;
|
|
2544
2741
|
var FloatingMenu = ({
|
|
@@ -2547,12 +2744,12 @@ var FloatingMenu = ({
|
|
|
2547
2744
|
className,
|
|
2548
2745
|
onImageUpload
|
|
2549
2746
|
}) => {
|
|
2550
|
-
const wrapperRef = (0,
|
|
2551
|
-
const [isCompact, setIsCompact] = (0,
|
|
2552
|
-
const [isMinimizable, setIsMinimizable] = (0,
|
|
2553
|
-
const [isMinimized, setIsMinimized] = (0,
|
|
2554
|
-
const [, setSelectionTick] = (0,
|
|
2555
|
-
(0,
|
|
2747
|
+
const wrapperRef = (0, import_react19.useRef)(null);
|
|
2748
|
+
const [isCompact, setIsCompact] = (0, import_react19.useState)(false);
|
|
2749
|
+
const [isMinimizable, setIsMinimizable] = (0, import_react19.useState)(false);
|
|
2750
|
+
const [isMinimized, setIsMinimized] = (0, import_react19.useState)(false);
|
|
2751
|
+
const [, setSelectionTick] = (0, import_react19.useState)(0);
|
|
2752
|
+
(0, import_react19.useEffect)(() => {
|
|
2556
2753
|
if (!editor) return;
|
|
2557
2754
|
let debounceTimer = null;
|
|
2558
2755
|
const DEBOUNCE_DELAY = 150;
|
|
@@ -2576,7 +2773,7 @@ var FloatingMenu = ({
|
|
|
2576
2773
|
unsubscribeContent?.();
|
|
2577
2774
|
};
|
|
2578
2775
|
}, [editor]);
|
|
2579
|
-
(0,
|
|
2776
|
+
(0, import_react19.useEffect)(() => {
|
|
2580
2777
|
const checkWidth = () => {
|
|
2581
2778
|
if (wrapperRef.current) {
|
|
2582
2779
|
const width = wrapperRef.current.offsetWidth;
|
|
@@ -2591,8 +2788,8 @@ var FloatingMenu = ({
|
|
|
2591
2788
|
}
|
|
2592
2789
|
return () => resizeObserver.disconnect();
|
|
2593
2790
|
}, []);
|
|
2594
|
-
const MinimizedLayout = () => /* @__PURE__ */ (0,
|
|
2595
|
-
/* @__PURE__ */ (0,
|
|
2791
|
+
const MinimizedLayout = () => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
2792
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2596
2793
|
"button",
|
|
2597
2794
|
{
|
|
2598
2795
|
className: "lumir-toolbar-button lumir-toggle-button",
|
|
@@ -2603,117 +2800,120 @@ var FloatingMenu = ({
|
|
|
2603
2800
|
children: isMinimized ? Icons.chevronRight : Icons.chevronLeft
|
|
2604
2801
|
}
|
|
2605
2802
|
),
|
|
2606
|
-
!isMinimized && /* @__PURE__ */ (0,
|
|
2607
|
-
/* @__PURE__ */ (0,
|
|
2608
|
-
/* @__PURE__ */ (0,
|
|
2609
|
-
/* @__PURE__ */ (0,
|
|
2610
|
-
/* @__PURE__ */ (0,
|
|
2611
|
-
/* @__PURE__ */ (0,
|
|
2612
|
-
/* @__PURE__ */ (0,
|
|
2613
|
-
/* @__PURE__ */ (0,
|
|
2614
|
-
/* @__PURE__ */ (0,
|
|
2615
|
-
/* @__PURE__ */ (0,
|
|
2616
|
-
/* @__PURE__ */ (0,
|
|
2803
|
+
!isMinimized && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
2804
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2805
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(UndoRedoButtons, { editor }),
|
|
2806
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2807
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(BlockTypeSelect, { editor }) }),
|
|
2808
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2809
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2810
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "bold" }),
|
|
2811
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "italic" }),
|
|
2812
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "underline" }),
|
|
2813
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "strike" })
|
|
2617
2814
|
] }),
|
|
2618
|
-
/* @__PURE__ */ (0,
|
|
2619
|
-
/* @__PURE__ */ (0,
|
|
2620
|
-
/* @__PURE__ */ (0,
|
|
2621
|
-
/* @__PURE__ */ (0,
|
|
2622
|
-
/* @__PURE__ */ (0,
|
|
2815
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2816
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2817
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AlignButton, { editor, alignment: "left" }),
|
|
2818
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AlignButton, { editor, alignment: "center" }),
|
|
2819
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AlignButton, { editor, alignment: "right" })
|
|
2623
2820
|
] }),
|
|
2624
|
-
/* @__PURE__ */ (0,
|
|
2625
|
-
/* @__PURE__ */ (0,
|
|
2626
|
-
/* @__PURE__ */ (0,
|
|
2627
|
-
/* @__PURE__ */ (0,
|
|
2821
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2822
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2823
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ListButton, { editor, type: "bullet" }),
|
|
2824
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ListButton, { editor, type: "numbered" })
|
|
2628
2825
|
] }),
|
|
2629
|
-
/* @__PURE__ */ (0,
|
|
2630
|
-
/* @__PURE__ */ (0,
|
|
2631
|
-
/* @__PURE__ */ (0,
|
|
2632
|
-
/* @__PURE__ */ (0,
|
|
2826
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2827
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2828
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(FontSizeButton, { editor }),
|
|
2829
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ColorButton, { editor, type: "text" }),
|
|
2830
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ColorButton, { editor, type: "background" })
|
|
2633
2831
|
] }),
|
|
2634
|
-
/* @__PURE__ */ (0,
|
|
2635
|
-
/* @__PURE__ */ (0,
|
|
2636
|
-
/* @__PURE__ */ (0,
|
|
2637
|
-
/* @__PURE__ */ (0,
|
|
2638
|
-
/* @__PURE__ */ (0,
|
|
2639
|
-
/* @__PURE__ */ (0,
|
|
2832
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2833
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2834
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ImageButton, { editor, onImageUpload }),
|
|
2835
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(LinkButton, { editor }),
|
|
2836
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableButton, { editor }),
|
|
2837
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(HTMLImportButton, { editor })
|
|
2640
2838
|
] })
|
|
2641
2839
|
] })
|
|
2642
2840
|
] });
|
|
2643
|
-
const SingleRowLayout = () => /* @__PURE__ */ (0,
|
|
2644
|
-
/* @__PURE__ */ (0,
|
|
2645
|
-
/* @__PURE__ */ (0,
|
|
2646
|
-
/* @__PURE__ */ (0,
|
|
2647
|
-
/* @__PURE__ */ (0,
|
|
2648
|
-
/* @__PURE__ */ (0,
|
|
2649
|
-
/* @__PURE__ */ (0,
|
|
2650
|
-
/* @__PURE__ */ (0,
|
|
2651
|
-
/* @__PURE__ */ (0,
|
|
2652
|
-
/* @__PURE__ */ (0,
|
|
2841
|
+
const SingleRowLayout = () => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
2842
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(UndoRedoButtons, { editor }),
|
|
2843
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2844
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(BlockTypeSelect, { editor }) }),
|
|
2845
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2846
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2847
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "bold" }),
|
|
2848
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "italic" }),
|
|
2849
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "underline" }),
|
|
2850
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "strike" })
|
|
2653
2851
|
] }),
|
|
2654
|
-
/* @__PURE__ */ (0,
|
|
2655
|
-
/* @__PURE__ */ (0,
|
|
2656
|
-
/* @__PURE__ */ (0,
|
|
2657
|
-
/* @__PURE__ */ (0,
|
|
2658
|
-
/* @__PURE__ */ (0,
|
|
2852
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2853
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2854
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AlignButton, { editor, alignment: "left" }),
|
|
2855
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AlignButton, { editor, alignment: "center" }),
|
|
2856
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AlignButton, { editor, alignment: "right" })
|
|
2659
2857
|
] }),
|
|
2660
|
-
/* @__PURE__ */ (0,
|
|
2661
|
-
/* @__PURE__ */ (0,
|
|
2662
|
-
/* @__PURE__ */ (0,
|
|
2663
|
-
/* @__PURE__ */ (0,
|
|
2858
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2859
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2860
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ListButton, { editor, type: "bullet" }),
|
|
2861
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ListButton, { editor, type: "numbered" })
|
|
2664
2862
|
] }),
|
|
2665
|
-
/* @__PURE__ */ (0,
|
|
2666
|
-
/* @__PURE__ */ (0,
|
|
2667
|
-
/* @__PURE__ */ (0,
|
|
2668
|
-
/* @__PURE__ */ (0,
|
|
2863
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2864
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2865
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(FontSizeButton, { editor }),
|
|
2866
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ColorButton, { editor, type: "text" }),
|
|
2867
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ColorButton, { editor, type: "background" })
|
|
2669
2868
|
] }),
|
|
2670
|
-
/* @__PURE__ */ (0,
|
|
2671
|
-
/* @__PURE__ */ (0,
|
|
2672
|
-
/* @__PURE__ */ (0,
|
|
2673
|
-
/* @__PURE__ */ (0,
|
|
2674
|
-
/* @__PURE__ */ (0,
|
|
2675
|
-
/* @__PURE__ */ (0,
|
|
2869
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2870
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2871
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ImageButton, { editor, onImageUpload }),
|
|
2872
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(LinkButton, { editor }),
|
|
2873
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableButton, { editor }),
|
|
2874
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(HTMLImportButton, { editor })
|
|
2676
2875
|
] })
|
|
2677
2876
|
] });
|
|
2678
|
-
const TwoRowLayout = () => /* @__PURE__ */ (0,
|
|
2679
|
-
/* @__PURE__ */ (0,
|
|
2680
|
-
/* @__PURE__ */ (0,
|
|
2681
|
-
/* @__PURE__ */ (0,
|
|
2682
|
-
/* @__PURE__ */ (0,
|
|
2683
|
-
/* @__PURE__ */ (0,
|
|
2684
|
-
/* @__PURE__ */ (0,
|
|
2685
|
-
/* @__PURE__ */ (0,
|
|
2686
|
-
/* @__PURE__ */ (0,
|
|
2877
|
+
const TwoRowLayout = () => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
2878
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-row", children: [
|
|
2879
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(UndoRedoButtons, { editor }),
|
|
2880
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2881
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2882
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "bold" }),
|
|
2883
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "italic" }),
|
|
2884
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "underline" }),
|
|
2885
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextStyleButton, { editor, style: "strike" })
|
|
2687
2886
|
] }),
|
|
2688
|
-
/* @__PURE__ */ (0,
|
|
2689
|
-
/* @__PURE__ */ (0,
|
|
2690
|
-
/* @__PURE__ */ (0,
|
|
2691
|
-
/* @__PURE__ */ (0,
|
|
2692
|
-
/* @__PURE__ */ (0,
|
|
2887
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2888
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2889
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AlignButton, { editor, alignment: "left" }),
|
|
2890
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AlignButton, { editor, alignment: "center" }),
|
|
2891
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AlignButton, { editor, alignment: "right" })
|
|
2693
2892
|
] }),
|
|
2694
|
-
/* @__PURE__ */ (0,
|
|
2695
|
-
/* @__PURE__ */ (0,
|
|
2696
|
-
/* @__PURE__ */ (0,
|
|
2697
|
-
/* @__PURE__ */ (0,
|
|
2893
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2894
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2895
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ListButton, { editor, type: "bullet" }),
|
|
2896
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ListButton, { editor, type: "numbered" })
|
|
2698
2897
|
] })
|
|
2699
2898
|
] }),
|
|
2700
|
-
/* @__PURE__ */ (0,
|
|
2701
|
-
/* @__PURE__ */ (0,
|
|
2702
|
-
/* @__PURE__ */ (0,
|
|
2703
|
-
/* @__PURE__ */ (0,
|
|
2704
|
-
/* @__PURE__ */ (0,
|
|
2705
|
-
/* @__PURE__ */ (0,
|
|
2899
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-row", children: [
|
|
2900
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(BlockTypeSelect, { editor }) }),
|
|
2901
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2902
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2903
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(FontSizeButton, { editor }),
|
|
2904
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ColorButton, { editor, type: "text" }),
|
|
2905
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ColorButton, { editor, type: "background" })
|
|
2706
2906
|
] }),
|
|
2707
|
-
/* @__PURE__ */ (0,
|
|
2708
|
-
/* @__PURE__ */ (0,
|
|
2709
|
-
/* @__PURE__ */ (0,
|
|
2710
|
-
/* @__PURE__ */ (0,
|
|
2711
|
-
/* @__PURE__ */ (0,
|
|
2712
|
-
/* @__PURE__ */ (0,
|
|
2907
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToolbarDivider, {}),
|
|
2908
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "lumir-toolbar-group", children: [
|
|
2909
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ImageButton, { editor, onImageUpload }),
|
|
2910
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(LinkButton, { editor }),
|
|
2911
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableButton, { editor }),
|
|
2912
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(HTMLImportButton, { editor })
|
|
2713
2913
|
] })
|
|
2714
2914
|
] })
|
|
2715
2915
|
] });
|
|
2716
|
-
return /* @__PURE__ */ (0,
|
|
2916
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2717
2917
|
"div",
|
|
2718
2918
|
{
|
|
2719
2919
|
ref: wrapperRef,
|
|
@@ -2723,7 +2923,7 @@ var FloatingMenu = ({
|
|
|
2723
2923
|
className
|
|
2724
2924
|
),
|
|
2725
2925
|
"data-position": position,
|
|
2726
|
-
children: /* @__PURE__ */ (0,
|
|
2926
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2727
2927
|
"div",
|
|
2728
2928
|
{
|
|
2729
2929
|
className: cn(
|
|
@@ -2732,7 +2932,7 @@ var FloatingMenu = ({
|
|
|
2732
2932
|
isMinimizable && "is-minimizable",
|
|
2733
2933
|
isMinimized && "is-minimized"
|
|
2734
2934
|
),
|
|
2735
|
-
children: isMinimizable ? /* @__PURE__ */ (0,
|
|
2935
|
+
children: isMinimizable ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(MinimizedLayout, {}) : isCompact ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TwoRowLayout, {}) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SingleRowLayout, {})
|
|
2736
2936
|
}
|
|
2737
2937
|
)
|
|
2738
2938
|
}
|
|
@@ -2864,43 +3064,18 @@ var VerticalAlignmentExtension = import_core2.Extension.create({
|
|
|
2864
3064
|
});
|
|
2865
3065
|
|
|
2866
3066
|
// src/components/CustomFormattingToolbar.tsx
|
|
2867
|
-
var
|
|
3067
|
+
var import_react28 = require("@blocknote/react");
|
|
2868
3068
|
|
|
2869
3069
|
// src/components/TextAlignButtonWithVA.tsx
|
|
2870
3070
|
var import_core3 = require("@blocknote/core");
|
|
2871
|
-
var
|
|
2872
|
-
var
|
|
2873
|
-
|
|
2874
|
-
// src/utils/prosemirror-table-utils.ts
|
|
2875
|
-
function getSelectedCellPositions(editor) {
|
|
2876
|
-
const tiptap = editor._tiptapEditor;
|
|
2877
|
-
if (!tiptap) return [];
|
|
2878
|
-
const { state } = tiptap;
|
|
2879
|
-
const { selection } = state;
|
|
2880
|
-
if (typeof selection.forEachCell === "function") {
|
|
2881
|
-
const positions = [];
|
|
2882
|
-
selection.forEachCell((_node, pos) => {
|
|
2883
|
-
positions.push(pos);
|
|
2884
|
-
});
|
|
2885
|
-
return positions;
|
|
2886
|
-
}
|
|
2887
|
-
const $pos = selection.$from;
|
|
2888
|
-
for (let depth = $pos.depth; depth > 0; depth--) {
|
|
2889
|
-
const node = $pos.node(depth);
|
|
2890
|
-
if (node.type.name === "tableCell" || node.type.name === "tableHeader") {
|
|
2891
|
-
return [$pos.before(depth)];
|
|
2892
|
-
}
|
|
2893
|
-
}
|
|
2894
|
-
return [];
|
|
2895
|
-
}
|
|
2896
|
-
|
|
2897
|
-
// src/components/TextAlignButtonWithVA.tsx
|
|
2898
|
-
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3071
|
+
var import_react20 = require("react");
|
|
3072
|
+
var import_react21 = require("@blocknote/react");
|
|
3073
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2899
3074
|
var icons = {
|
|
2900
|
-
left: /* @__PURE__ */ (0,
|
|
2901
|
-
center: /* @__PURE__ */ (0,
|
|
2902
|
-
right: /* @__PURE__ */ (0,
|
|
2903
|
-
justify: /* @__PURE__ */ (0,
|
|
3075
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("path", { d: "M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z" }) }),
|
|
3076
|
+
center: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("path", { d: "M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z" }) }),
|
|
3077
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("path", { d: "M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z" }) }),
|
|
3078
|
+
justify: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("path", { d: "M3 21h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18V7H3v2zM3 3v2h18V3H3z" }) })
|
|
2904
3079
|
};
|
|
2905
3080
|
var tooltipMap = {
|
|
2906
3081
|
left: "\uC67C\uCABD \uC815\uB82C",
|
|
@@ -2909,10 +3084,10 @@ var tooltipMap = {
|
|
|
2909
3084
|
justify: "\uC591\uCABD \uC815\uB82C"
|
|
2910
3085
|
};
|
|
2911
3086
|
var TextAlignButtonWithVA = (props) => {
|
|
2912
|
-
const Components = (0,
|
|
2913
|
-
const editor = (0,
|
|
2914
|
-
const selectedBlocks = (0,
|
|
2915
|
-
const textAlignment = (0,
|
|
3087
|
+
const Components = (0, import_react21.useComponentsContext)();
|
|
3088
|
+
const editor = (0, import_react21.useBlockNoteEditor)();
|
|
3089
|
+
const selectedBlocks = (0, import_react21.useSelectedBlocks)(editor);
|
|
3090
|
+
const textAlignment = (0, import_react20.useMemo)(() => {
|
|
2916
3091
|
const block = selectedBlocks[0];
|
|
2917
3092
|
if ((0, import_core3.checkBlockHasDefaultProp)("textAlignment", block, editor)) {
|
|
2918
3093
|
return block.props.textAlignment;
|
|
@@ -2934,7 +3109,7 @@ var TextAlignButtonWithVA = (props) => {
|
|
|
2934
3109
|
}
|
|
2935
3110
|
return;
|
|
2936
3111
|
}, [editor, selectedBlocks]);
|
|
2937
|
-
const setTextAlignment = (0,
|
|
3112
|
+
const setTextAlignment = (0, import_react20.useCallback)(
|
|
2938
3113
|
(newAlignment) => {
|
|
2939
3114
|
editor.focus();
|
|
2940
3115
|
for (const block of selectedBlocks) {
|
|
@@ -2964,7 +3139,7 @@ var TextAlignButtonWithVA = (props) => {
|
|
|
2964
3139
|
},
|
|
2965
3140
|
[editor, selectedBlocks]
|
|
2966
3141
|
);
|
|
2967
|
-
const show = (0,
|
|
3142
|
+
const show = (0, import_react20.useMemo)(() => {
|
|
2968
3143
|
return !!selectedBlocks.find(
|
|
2969
3144
|
(block) => "textAlignment" in block.props || block.type === "table" && block.children
|
|
2970
3145
|
);
|
|
@@ -2972,7 +3147,7 @@ var TextAlignButtonWithVA = (props) => {
|
|
|
2972
3147
|
if (!show || !editor.isEditable) {
|
|
2973
3148
|
return null;
|
|
2974
3149
|
}
|
|
2975
|
-
return /* @__PURE__ */ (0,
|
|
3150
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2976
3151
|
Components.FormattingToolbar.Button,
|
|
2977
3152
|
{
|
|
2978
3153
|
className: "bn-button",
|
|
@@ -2987,21 +3162,21 @@ var TextAlignButtonWithVA = (props) => {
|
|
|
2987
3162
|
};
|
|
2988
3163
|
|
|
2989
3164
|
// src/components/VerticalAlignButton.tsx
|
|
2990
|
-
var
|
|
2991
|
-
var
|
|
2992
|
-
var
|
|
3165
|
+
var import_react22 = require("react");
|
|
3166
|
+
var import_react23 = require("@blocknote/react");
|
|
3167
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2993
3168
|
var icons2 = {
|
|
2994
|
-
top: /* @__PURE__ */ (0,
|
|
2995
|
-
/* @__PURE__ */ (0,
|
|
2996
|
-
/* @__PURE__ */ (0,
|
|
3169
|
+
top: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
|
|
3170
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("rect", { x: "2", y: "2", width: "12", height: "12", rx: "1" }),
|
|
3171
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("line", { x1: "5", y1: "5", x2: "11", y2: "5" })
|
|
2997
3172
|
] }),
|
|
2998
|
-
middle: /* @__PURE__ */ (0,
|
|
2999
|
-
/* @__PURE__ */ (0,
|
|
3000
|
-
/* @__PURE__ */ (0,
|
|
3173
|
+
middle: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
|
|
3174
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("rect", { x: "2", y: "2", width: "12", height: "12", rx: "1" }),
|
|
3175
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("line", { x1: "5", y1: "8", x2: "11", y2: "8" })
|
|
3001
3176
|
] }),
|
|
3002
|
-
bottom: /* @__PURE__ */ (0,
|
|
3003
|
-
/* @__PURE__ */ (0,
|
|
3004
|
-
/* @__PURE__ */ (0,
|
|
3177
|
+
bottom: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
|
|
3178
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("rect", { x: "2", y: "2", width: "12", height: "12", rx: "1" }),
|
|
3179
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("line", { x1: "5", y1: "11", x2: "11", y2: "11" })
|
|
3005
3180
|
] })
|
|
3006
3181
|
};
|
|
3007
3182
|
var tooltips = {
|
|
@@ -3023,13 +3198,13 @@ function getCurrentVerticalAlignment(editor) {
|
|
|
3023
3198
|
return alignments.every((a) => a === first) ? first : void 0;
|
|
3024
3199
|
}
|
|
3025
3200
|
var VerticalAlignButton = (props) => {
|
|
3026
|
-
const Components = (0,
|
|
3027
|
-
const editor = (0,
|
|
3028
|
-
const selectedBlocks = (0,
|
|
3029
|
-
const currentAlignment = (0,
|
|
3201
|
+
const Components = (0, import_react23.useComponentsContext)();
|
|
3202
|
+
const editor = (0, import_react23.useBlockNoteEditor)();
|
|
3203
|
+
const selectedBlocks = (0, import_react23.useSelectedBlocks)(editor);
|
|
3204
|
+
const currentAlignment = (0, import_react22.useMemo)(() => {
|
|
3030
3205
|
return getCurrentVerticalAlignment(editor);
|
|
3031
3206
|
}, [editor, selectedBlocks]);
|
|
3032
|
-
const setVerticalAlignment = (0,
|
|
3207
|
+
const setVerticalAlignment = (0, import_react22.useCallback)(
|
|
3033
3208
|
(alignment) => {
|
|
3034
3209
|
const tiptap = editor._tiptapEditor;
|
|
3035
3210
|
if (!tiptap) return;
|
|
@@ -3051,13 +3226,13 @@ var VerticalAlignButton = (props) => {
|
|
|
3051
3226
|
},
|
|
3052
3227
|
[editor]
|
|
3053
3228
|
);
|
|
3054
|
-
const isInTable = (0,
|
|
3229
|
+
const isInTable = (0, import_react22.useMemo)(() => {
|
|
3055
3230
|
return selectedBlocks.some((block) => block.type === "table");
|
|
3056
3231
|
}, [selectedBlocks]);
|
|
3057
3232
|
if (!isInTable || !editor.isEditable) {
|
|
3058
3233
|
return null;
|
|
3059
3234
|
}
|
|
3060
|
-
return /* @__PURE__ */ (0,
|
|
3235
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3061
3236
|
Components.FormattingToolbar.Button,
|
|
3062
3237
|
{
|
|
3063
3238
|
className: "bn-button",
|
|
@@ -3071,77 +3246,856 @@ var VerticalAlignButton = (props) => {
|
|
|
3071
3246
|
);
|
|
3072
3247
|
};
|
|
3073
3248
|
|
|
3074
|
-
// src/components/
|
|
3075
|
-
var
|
|
3076
|
-
var
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3249
|
+
// src/components/FontSizeButton.tsx
|
|
3250
|
+
var import_react24 = require("@blocknote/react");
|
|
3251
|
+
var import_react25 = require("react");
|
|
3252
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3253
|
+
var DEFAULT_LABEL2 = "\uAE30\uBCF8";
|
|
3254
|
+
var toLabel2 = (size) => size.replace(/px$/, "");
|
|
3255
|
+
function FontSizeIcon({ size }) {
|
|
3256
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3257
|
+
"span",
|
|
3258
|
+
{
|
|
3259
|
+
style: {
|
|
3260
|
+
pointerEvents: "none",
|
|
3261
|
+
fontSize: "12px",
|
|
3262
|
+
fontWeight: 600,
|
|
3263
|
+
lineHeight: "20px",
|
|
3264
|
+
whiteSpace: "nowrap"
|
|
3265
|
+
},
|
|
3266
|
+
children: size ? toLabel2(size) : "\uAC00A"
|
|
3267
|
+
}
|
|
3268
|
+
);
|
|
3269
|
+
}
|
|
3270
|
+
function FontSizeButton2() {
|
|
3271
|
+
const Components = (0, import_react24.useComponentsContext)();
|
|
3272
|
+
const editor = (0, import_react24.useBlockNoteEditor)();
|
|
3273
|
+
const ed = editor;
|
|
3274
|
+
const styleSchema = editor.schema.styleSchema;
|
|
3275
|
+
const fontSizeInSchema = styleSchema.fontSize?.type === "fontSize" && styleSchema.fontSize?.propSchema === "string";
|
|
3276
|
+
const selectedBlocks = (0, import_react24.useSelectedBlocks)(editor);
|
|
3277
|
+
const [currentSize, setCurrentSize] = (0, import_react25.useState)(
|
|
3278
|
+
fontSizeInSchema ? ed.getActiveStyles().fontSize || "" : ""
|
|
3279
|
+
);
|
|
3280
|
+
(0, import_react24.useEditorContentOrSelectionChange)(() => {
|
|
3281
|
+
if (fontSizeInSchema) {
|
|
3282
|
+
setCurrentSize(ed.getActiveStyles().fontSize || "");
|
|
3283
|
+
}
|
|
3284
|
+
}, editor);
|
|
3285
|
+
const setFontSize = (0, import_react25.useCallback)(
|
|
3286
|
+
(size) => {
|
|
3287
|
+
size === "" ? ed.removeStyles({ fontSize: "" }) : ed.addStyles({ fontSize: size });
|
|
3288
|
+
setTimeout(() => editor.focus());
|
|
3289
|
+
},
|
|
3290
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3291
|
+
[editor]
|
|
3292
|
+
);
|
|
3293
|
+
const show = (0, import_react25.useMemo)(() => {
|
|
3294
|
+
if (!fontSizeInSchema) {
|
|
3295
|
+
return false;
|
|
3296
|
+
}
|
|
3297
|
+
for (const block of selectedBlocks) {
|
|
3298
|
+
if (block.content !== void 0) {
|
|
3299
|
+
return true;
|
|
3300
|
+
}
|
|
3301
|
+
}
|
|
3302
|
+
return false;
|
|
3303
|
+
}, [fontSizeInSchema, selectedBlocks]);
|
|
3304
|
+
if (!show || !editor.isEditable) {
|
|
3305
|
+
return null;
|
|
3306
|
+
}
|
|
3307
|
+
const tooltip = "\uAE00\uC790 \uD06C\uAE30";
|
|
3308
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Components.Generic.Menu.Root, { children: [
|
|
3309
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Components.Generic.Menu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3310
|
+
Components.FormattingToolbar.Button,
|
|
3311
|
+
{
|
|
3312
|
+
className: "bn-button",
|
|
3313
|
+
"data-test": "font-size",
|
|
3314
|
+
label: tooltip,
|
|
3315
|
+
mainTooltip: tooltip,
|
|
3316
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(FontSizeIcon, { size: currentSize })
|
|
3317
|
+
}
|
|
3318
|
+
) }),
|
|
3319
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Components.Generic.Menu.Dropdown, { className: "bn-menu-dropdown", children: [
|
|
3320
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Components.Generic.Menu.Label, { children: "\uAE00\uC790 \uD06C\uAE30" }),
|
|
3321
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3322
|
+
Components.Generic.Menu.Item,
|
|
3323
|
+
{
|
|
3324
|
+
onClick: () => setFontSize(""),
|
|
3325
|
+
checked: currentSize === "",
|
|
3326
|
+
"data-test": "font-size-default",
|
|
3327
|
+
children: DEFAULT_LABEL2
|
|
3328
|
+
},
|
|
3329
|
+
"font-size-default"
|
|
3330
|
+
),
|
|
3331
|
+
FONT_SIZE_PRESETS.map((size) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3332
|
+
Components.Generic.Menu.Item,
|
|
3333
|
+
{
|
|
3334
|
+
onClick: () => setFontSize(size),
|
|
3335
|
+
checked: currentSize === size,
|
|
3336
|
+
"data-test": "font-size-" + toLabel2(size),
|
|
3337
|
+
children: toLabel2(size)
|
|
3338
|
+
},
|
|
3339
|
+
"font-size-" + size
|
|
3340
|
+
))
|
|
3341
|
+
] })
|
|
3342
|
+
] });
|
|
3343
|
+
}
|
|
3344
|
+
|
|
3345
|
+
// src/components/color/LumirColorControls.tsx
|
|
3346
|
+
var import_core4 = require("@blocknote/core");
|
|
3347
|
+
var import_react26 = require("@blocknote/react");
|
|
3348
|
+
var import_react27 = require("react");
|
|
3349
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3350
|
+
var COLORS = [
|
|
3351
|
+
"default",
|
|
3352
|
+
"gray",
|
|
3353
|
+
"brown",
|
|
3354
|
+
"red",
|
|
3355
|
+
"orange",
|
|
3356
|
+
"yellow",
|
|
3357
|
+
"green",
|
|
3358
|
+
"blue",
|
|
3359
|
+
"purple",
|
|
3360
|
+
"pink"
|
|
3361
|
+
];
|
|
3362
|
+
function ColorIcon(props) {
|
|
3363
|
+
const textColor = props.textColor || "default";
|
|
3364
|
+
const backgroundColor = props.backgroundColor || "default";
|
|
3365
|
+
const size = props.size || 16;
|
|
3366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3367
|
+
"div",
|
|
3368
|
+
{
|
|
3369
|
+
className: "bn-color-icon",
|
|
3370
|
+
"data-background-color": backgroundColor,
|
|
3371
|
+
"data-text-color": textColor,
|
|
3372
|
+
style: {
|
|
3373
|
+
pointerEvents: "none",
|
|
3374
|
+
fontSize: `${size * 0.75}px`,
|
|
3375
|
+
height: `${size}px`,
|
|
3376
|
+
lineHeight: `${size}px`,
|
|
3377
|
+
textAlign: "center",
|
|
3378
|
+
width: `${size}px`
|
|
3379
|
+
},
|
|
3380
|
+
children: "A"
|
|
3381
|
+
}
|
|
3382
|
+
);
|
|
3383
|
+
}
|
|
3384
|
+
function CellFillIcon({ size = 18 }) {
|
|
3385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3386
|
+
"svg",
|
|
3387
|
+
{
|
|
3388
|
+
width: size,
|
|
3389
|
+
height: size,
|
|
3390
|
+
viewBox: "0 0 24 24",
|
|
3391
|
+
fill: "currentColor",
|
|
3392
|
+
style: { pointerEvents: "none" },
|
|
3393
|
+
"aria-hidden": "true",
|
|
3394
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.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
|
+
}
|
|
3396
|
+
);
|
|
3397
|
+
}
|
|
3398
|
+
function LumirColorPicker(props) {
|
|
3399
|
+
const Components = (0, import_react26.useComponentsContext)();
|
|
3400
|
+
const dict = (0, import_react26.useDictionary)();
|
|
3401
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
3402
|
+
props.text ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
3403
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Components.Generic.Menu.Label, { children: props.textTitle ?? dict.color_picker.text_title }),
|
|
3404
|
+
COLORS.map((color) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3405
|
+
Components.Generic.Menu.Item,
|
|
3406
|
+
{
|
|
3407
|
+
onClick: () => {
|
|
3408
|
+
props.onClick?.();
|
|
3409
|
+
props.text.setColor(color);
|
|
3410
|
+
},
|
|
3411
|
+
"data-test": "text-color-" + color,
|
|
3412
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ColorIcon, { textColor: color, size: props.iconSize }),
|
|
3413
|
+
checked: props.text.color === color,
|
|
3414
|
+
children: dict.color_picker.colors[color]
|
|
3415
|
+
},
|
|
3416
|
+
"text-color-" + color
|
|
3417
|
+
))
|
|
3418
|
+
] }) : null,
|
|
3419
|
+
props.background ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
3420
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Components.Generic.Menu.Label, { children: props.backgroundTitle ?? dict.color_picker.background_title }),
|
|
3421
|
+
COLORS.map((color) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3422
|
+
Components.Generic.Menu.Item,
|
|
3423
|
+
{
|
|
3424
|
+
onClick: () => {
|
|
3425
|
+
props.onClick?.();
|
|
3426
|
+
props.background.setColor(color);
|
|
3427
|
+
},
|
|
3428
|
+
"data-test": "background-color-" + color,
|
|
3429
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ColorIcon, { backgroundColor: color, size: props.iconSize }),
|
|
3430
|
+
checked: props.background.color === color,
|
|
3431
|
+
children: dict.color_picker.colors[color]
|
|
3432
|
+
},
|
|
3433
|
+
"background-color-" + color
|
|
3434
|
+
))
|
|
3435
|
+
] }) : null
|
|
3436
|
+
] });
|
|
3437
|
+
}
|
|
3438
|
+
function LumirColorStyleButton() {
|
|
3439
|
+
const Components = (0, import_react26.useComponentsContext)();
|
|
3440
|
+
const editor = (0, import_react26.useBlockNoteEditor)();
|
|
3441
|
+
const ed = editor;
|
|
3442
|
+
const styleSchema = editor.schema.styleSchema;
|
|
3443
|
+
const textColorInSchema = styleSchema.textColor?.type === "textColor" && styleSchema.textColor?.propSchema === "string";
|
|
3444
|
+
const backgroundColorInSchema = styleSchema.backgroundColor?.type === "backgroundColor" && styleSchema.backgroundColor?.propSchema === "string";
|
|
3445
|
+
const selectedBlocks = (0, import_react26.useSelectedBlocks)(editor);
|
|
3446
|
+
const [currentTextColor, setCurrentTextColor] = (0, import_react27.useState)(
|
|
3447
|
+
textColorInSchema ? ed.getActiveStyles().textColor || "default" : "default"
|
|
3448
|
+
);
|
|
3449
|
+
const [currentBackgroundColor, setCurrentBackgroundColor] = (0, import_react27.useState)(
|
|
3450
|
+
backgroundColorInSchema ? ed.getActiveStyles().backgroundColor || "default" : "default"
|
|
3451
|
+
);
|
|
3452
|
+
(0, import_react26.useEditorContentOrSelectionChange)(() => {
|
|
3453
|
+
const active = ed.getActiveStyles();
|
|
3454
|
+
if (textColorInSchema) {
|
|
3455
|
+
setCurrentTextColor(active.textColor || "default");
|
|
3456
|
+
}
|
|
3457
|
+
if (backgroundColorInSchema) {
|
|
3458
|
+
setCurrentBackgroundColor(active.backgroundColor || "default");
|
|
3459
|
+
}
|
|
3460
|
+
}, editor);
|
|
3461
|
+
const setTextColor = (0, import_react27.useCallback)(
|
|
3462
|
+
(color) => {
|
|
3463
|
+
color === "default" ? ed.removeStyles({ textColor: color }) : ed.addStyles({ textColor: color });
|
|
3464
|
+
setTimeout(() => editor.focus());
|
|
3465
|
+
},
|
|
3466
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3467
|
+
[editor]
|
|
3468
|
+
);
|
|
3469
|
+
const setBackgroundColor = (0, import_react27.useCallback)(
|
|
3470
|
+
(color) => {
|
|
3471
|
+
color === "default" ? ed.removeStyles({ backgroundColor: color }) : ed.addStyles({ backgroundColor: color });
|
|
3472
|
+
setTimeout(() => editor.focus());
|
|
3473
|
+
},
|
|
3474
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3475
|
+
[editor]
|
|
3476
|
+
);
|
|
3477
|
+
const show = (0, import_react27.useMemo)(() => {
|
|
3478
|
+
if (!textColorInSchema && !backgroundColorInSchema) {
|
|
3479
|
+
return false;
|
|
3480
|
+
}
|
|
3481
|
+
for (const block of selectedBlocks) {
|
|
3482
|
+
if (block.content !== void 0) {
|
|
3483
|
+
return true;
|
|
3484
|
+
}
|
|
3485
|
+
}
|
|
3486
|
+
return false;
|
|
3487
|
+
}, [backgroundColorInSchema, selectedBlocks, textColorInSchema]);
|
|
3488
|
+
if (!show || !editor.isEditable) {
|
|
3489
|
+
return null;
|
|
3490
|
+
}
|
|
3491
|
+
const tooltip = "\uD14D\uC2A4\uD2B8 \uC0C9\xB7\uBC30\uACBD";
|
|
3492
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Components.Generic.Menu.Root, { children: [
|
|
3493
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Components.Generic.Menu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3494
|
+
Components.FormattingToolbar.Button,
|
|
3495
|
+
{
|
|
3496
|
+
className: "bn-button",
|
|
3497
|
+
"data-test": "colors",
|
|
3498
|
+
label: tooltip,
|
|
3499
|
+
mainTooltip: tooltip,
|
|
3500
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3501
|
+
ColorIcon,
|
|
3502
|
+
{
|
|
3503
|
+
textColor: currentTextColor,
|
|
3504
|
+
backgroundColor: currentBackgroundColor,
|
|
3505
|
+
size: 20
|
|
3506
|
+
}
|
|
3507
|
+
)
|
|
3508
|
+
}
|
|
3509
|
+
) }),
|
|
3510
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3511
|
+
Components.Generic.Menu.Dropdown,
|
|
3512
|
+
{
|
|
3513
|
+
className: "bn-menu-dropdown bn-color-picker-dropdown",
|
|
3514
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3515
|
+
LumirColorPicker,
|
|
3516
|
+
{
|
|
3517
|
+
textTitle: "\uD14D\uC2A4\uD2B8 \uC0C9",
|
|
3518
|
+
backgroundTitle: "\uD14D\uC2A4\uD2B8 \uBC30\uACBD",
|
|
3519
|
+
text: textColorInSchema ? { color: currentTextColor, setColor: setTextColor } : void 0,
|
|
3520
|
+
background: backgroundColorInSchema ? { color: currentBackgroundColor, setColor: setBackgroundColor } : void 0
|
|
3521
|
+
}
|
|
3522
|
+
)
|
|
3523
|
+
}
|
|
3524
|
+
)
|
|
3525
|
+
] });
|
|
3526
|
+
}
|
|
3527
|
+
function LumirCellColorToolbarButton() {
|
|
3528
|
+
const Components = (0, import_react26.useComponentsContext)();
|
|
3529
|
+
const editor = (0, import_react26.useBlockNoteEditor)();
|
|
3530
|
+
const selectedBlocks = (0, import_react26.useSelectedBlocks)(editor);
|
|
3531
|
+
const isMultiCell = (0, import_react27.useMemo)(() => {
|
|
3532
|
+
if (selectedBlocks.length !== 1 || selectedBlocks[0].type !== "table") {
|
|
3533
|
+
return false;
|
|
3534
|
+
}
|
|
3535
|
+
const cs = editor.tableHandles?.getCellSelection();
|
|
3536
|
+
return !!cs && cs.cells.length > 1;
|
|
3537
|
+
}, [editor, selectedBlocks]);
|
|
3538
|
+
const stashRef = (0, import_react27.useRef)([]);
|
|
3539
|
+
const applyBackground = (0, import_react27.useCallback)(
|
|
3540
|
+
(color) => {
|
|
3541
|
+
const live = getSelectedCellPositions(editor);
|
|
3542
|
+
const positions = live.length > 0 ? live : stashRef.current;
|
|
3543
|
+
setCellAttrAtPositions(editor, positions, "backgroundColor", color);
|
|
3544
|
+
setTimeout(() => editor.focus());
|
|
3545
|
+
},
|
|
3546
|
+
[editor]
|
|
3547
|
+
);
|
|
3548
|
+
if (!editor.isEditable || !isMultiCell) {
|
|
3549
|
+
return null;
|
|
3550
|
+
}
|
|
3551
|
+
const tooltip = "\uC140 \uBC30\uACBD\uC0C9";
|
|
3552
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
3553
|
+
Components.Generic.Menu.Root,
|
|
3554
|
+
{
|
|
3555
|
+
onOpenChange: (open) => {
|
|
3556
|
+
if (open) {
|
|
3557
|
+
stashRef.current = getSelectedCellPositions(editor);
|
|
3558
|
+
}
|
|
3559
|
+
},
|
|
3560
|
+
children: [
|
|
3561
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Components.Generic.Menu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3562
|
+
Components.FormattingToolbar.Button,
|
|
3563
|
+
{
|
|
3564
|
+
className: "bn-button",
|
|
3565
|
+
"data-test": "cell-colors",
|
|
3566
|
+
label: tooltip,
|
|
3567
|
+
mainTooltip: tooltip,
|
|
3568
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CellFillIcon, { size: 18 })
|
|
3569
|
+
}
|
|
3570
|
+
) }),
|
|
3571
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3572
|
+
Components.Generic.Menu.Dropdown,
|
|
3573
|
+
{
|
|
3574
|
+
className: "bn-menu-dropdown bn-color-picker-dropdown",
|
|
3575
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3576
|
+
LumirColorPicker,
|
|
3577
|
+
{
|
|
3578
|
+
backgroundTitle: "\uC140 \uBC30\uACBD",
|
|
3579
|
+
background: { color: "default", setColor: applyBackground }
|
|
3580
|
+
}
|
|
3581
|
+
)
|
|
3582
|
+
}
|
|
3583
|
+
)
|
|
3584
|
+
]
|
|
3585
|
+
}
|
|
3586
|
+
);
|
|
3587
|
+
}
|
|
3588
|
+
function LumirCellColorPickerButton(props) {
|
|
3589
|
+
const Components = (0, import_react26.useComponentsContext)();
|
|
3590
|
+
const editor = (0, import_react26.useBlockNoteEditor)();
|
|
3591
|
+
const updateColor = (color, type) => {
|
|
3592
|
+
const newTable = props.block.content.rows.map((row) => ({
|
|
3593
|
+
...row,
|
|
3594
|
+
cells: row.cells.map((cell) => (0, import_core4.mapTableCell)(cell))
|
|
3595
|
+
}));
|
|
3596
|
+
if (type === "text") {
|
|
3597
|
+
newTable[props.rowIndex].cells[props.colIndex].props.textColor = color;
|
|
3598
|
+
} else {
|
|
3599
|
+
newTable[props.rowIndex].cells[props.colIndex].props.backgroundColor = color;
|
|
3600
|
+
}
|
|
3601
|
+
editor.updateBlock(props.block, {
|
|
3602
|
+
type: "table",
|
|
3603
|
+
content: { ...props.block.content, rows: newTable }
|
|
3604
|
+
});
|
|
3605
|
+
editor.setTextCursorPosition(props.block);
|
|
3606
|
+
};
|
|
3607
|
+
const currentCell = props.block.content.rows[props.rowIndex]?.cells?.[props.colIndex];
|
|
3608
|
+
if (!currentCell || editor.settings.tables.cellTextColor === false && editor.settings.tables.cellBackgroundColor === false) {
|
|
3609
|
+
return null;
|
|
3610
|
+
}
|
|
3611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Components.Generic.Menu.Root, { position: "right", sub: true, children: [
|
|
3612
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Components.Generic.Menu.Trigger, { sub: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Components.Generic.Menu.Item, { className: "bn-menu-item", subTrigger: true, children: "\uC140 \uC0C9\xB7\uBC30\uACBD" }) }),
|
|
3613
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3614
|
+
Components.Generic.Menu.Dropdown,
|
|
3615
|
+
{
|
|
3616
|
+
sub: true,
|
|
3617
|
+
className: "bn-menu-dropdown bn-color-picker-dropdown",
|
|
3618
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3619
|
+
LumirColorPicker,
|
|
3620
|
+
{
|
|
3621
|
+
iconSize: 18,
|
|
3622
|
+
textTitle: "\uC140 \uAE00\uC790\uC0C9",
|
|
3623
|
+
backgroundTitle: "\uC140 \uBC30\uACBD",
|
|
3624
|
+
text: editor.settings.tables.cellTextColor ? {
|
|
3625
|
+
color: (0, import_core4.isTableCell)(currentCell) ? currentCell.props.textColor : "default",
|
|
3626
|
+
setColor: (color) => updateColor(color, "text")
|
|
3627
|
+
} : void 0,
|
|
3628
|
+
background: editor.settings.tables.cellBackgroundColor ? {
|
|
3629
|
+
color: (0, import_core4.isTableCell)(currentCell) ? currentCell.props.backgroundColor : "default",
|
|
3630
|
+
setColor: (color) => updateColor(color, "background")
|
|
3631
|
+
} : void 0
|
|
3632
|
+
}
|
|
3633
|
+
)
|
|
3634
|
+
}
|
|
3635
|
+
)
|
|
3636
|
+
] });
|
|
3637
|
+
}
|
|
3638
|
+
function LumirTableCellMenu(props) {
|
|
3639
|
+
const Components = (0, import_react26.useComponentsContext)();
|
|
3640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3641
|
+
Components.Generic.Menu.Dropdown,
|
|
3642
|
+
{
|
|
3643
|
+
className: "bn-menu-dropdown bn-drag-handle-menu",
|
|
3644
|
+
children: props.children || /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
3645
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3646
|
+
import_react26.SplitButton,
|
|
3647
|
+
{
|
|
3648
|
+
block: props.block,
|
|
3649
|
+
rowIndex: props.rowIndex,
|
|
3650
|
+
colIndex: props.colIndex
|
|
3651
|
+
}
|
|
3652
|
+
),
|
|
3653
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3654
|
+
LumirCellColorPickerButton,
|
|
3655
|
+
{
|
|
3656
|
+
block: props.block,
|
|
3657
|
+
rowIndex: props.rowIndex,
|
|
3658
|
+
colIndex: props.colIndex
|
|
3659
|
+
}
|
|
3660
|
+
)
|
|
3661
|
+
] })
|
|
3662
|
+
}
|
|
3663
|
+
);
|
|
3664
|
+
}
|
|
3665
|
+
|
|
3666
|
+
// src/components/CustomFormattingToolbar.tsx
|
|
3667
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3668
|
+
var CustomFormattingToolbar = () => {
|
|
3669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react28.FormattingToolbar, { children: [
|
|
3670
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.BlockTypeSelect, {}, "blockTypeSelect"),
|
|
3671
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.TableCellMergeButton, {}, "tableCellMergeButton"),
|
|
3672
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.FileCaptionButton, {}, "fileCaptionButton"),
|
|
3673
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.FileReplaceButton, {}, "replaceFileButton"),
|
|
3674
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.FileRenameButton, {}, "fileRenameButton"),
|
|
3675
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.FileDeleteButton, {}, "fileDeleteButton"),
|
|
3676
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.FileDownloadButton, {}, "fileDownloadButton"),
|
|
3677
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.FilePreviewButton, {}, "filePreviewButton"),
|
|
3678
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.BasicTextStyleButton, { basicTextStyle: "bold" }, "boldStyleButton"),
|
|
3679
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3680
|
+
import_react28.BasicTextStyleButton,
|
|
3681
|
+
{
|
|
3682
|
+
basicTextStyle: "italic"
|
|
3091
3683
|
},
|
|
3092
3684
|
"italicStyleButton"
|
|
3093
3685
|
),
|
|
3094
|
-
/* @__PURE__ */ (0,
|
|
3095
|
-
|
|
3686
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3687
|
+
import_react28.BasicTextStyleButton,
|
|
3096
3688
|
{
|
|
3097
3689
|
basicTextStyle: "underline"
|
|
3098
3690
|
},
|
|
3099
3691
|
"underlineStyleButton"
|
|
3100
3692
|
),
|
|
3101
|
-
/* @__PURE__ */ (0,
|
|
3102
|
-
|
|
3693
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3694
|
+
import_react28.BasicTextStyleButton,
|
|
3103
3695
|
{
|
|
3104
3696
|
basicTextStyle: "strike"
|
|
3105
3697
|
},
|
|
3106
3698
|
"strikeStyleButton"
|
|
3107
3699
|
),
|
|
3108
|
-
/* @__PURE__ */ (0,
|
|
3109
|
-
/* @__PURE__ */ (0,
|
|
3700
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TextAlignButtonWithVA, { textAlignment: "left" }, "textAlignLeftButton"),
|
|
3701
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3110
3702
|
TextAlignButtonWithVA,
|
|
3111
3703
|
{
|
|
3112
3704
|
textAlignment: "center"
|
|
3113
3705
|
},
|
|
3114
3706
|
"textAlignCenterButton"
|
|
3115
3707
|
),
|
|
3116
|
-
/* @__PURE__ */ (0,
|
|
3117
|
-
/* @__PURE__ */ (0,
|
|
3708
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TextAlignButtonWithVA, { textAlignment: "right" }, "textAlignRightButton"),
|
|
3709
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3118
3710
|
VerticalAlignButton,
|
|
3119
3711
|
{
|
|
3120
3712
|
verticalAlignment: "top"
|
|
3121
3713
|
},
|
|
3122
3714
|
"verticalAlignTop"
|
|
3123
3715
|
),
|
|
3124
|
-
/* @__PURE__ */ (0,
|
|
3716
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3125
3717
|
VerticalAlignButton,
|
|
3126
3718
|
{
|
|
3127
3719
|
verticalAlignment: "middle"
|
|
3128
3720
|
},
|
|
3129
3721
|
"verticalAlignMiddle"
|
|
3130
3722
|
),
|
|
3131
|
-
/* @__PURE__ */ (0,
|
|
3723
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3132
3724
|
VerticalAlignButton,
|
|
3133
3725
|
{
|
|
3134
3726
|
verticalAlignment: "bottom"
|
|
3135
3727
|
},
|
|
3136
3728
|
"verticalAlignBottom"
|
|
3137
3729
|
),
|
|
3138
|
-
/* @__PURE__ */ (0,
|
|
3139
|
-
/* @__PURE__ */ (0,
|
|
3140
|
-
/* @__PURE__ */ (0,
|
|
3141
|
-
/* @__PURE__ */ (0,
|
|
3730
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(FontSizeButton2, {}, "fontSizeButton"),
|
|
3731
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LumirColorStyleButton, {}, "colorStyleButton"),
|
|
3732
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LumirCellColorToolbarButton, {}, "cellColorButton"),
|
|
3733
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.NestBlockButton, {}, "nestBlockButton"),
|
|
3734
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.UnnestBlockButton, {}, "unnestBlockButton"),
|
|
3735
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react28.CreateLinkButton, {}, "createLinkButton")
|
|
3142
3736
|
] });
|
|
3143
3737
|
};
|
|
3144
3738
|
|
|
3739
|
+
// src/components/LumirTableHandlesController.tsx
|
|
3740
|
+
var import_react31 = require("@blocknote/react");
|
|
3741
|
+
var import_react32 = require("@floating-ui/react");
|
|
3742
|
+
var import_react33 = require("react");
|
|
3743
|
+
|
|
3744
|
+
// src/components/hooks/useFocusedCellHandlePositioning.ts
|
|
3745
|
+
var import_react29 = require("@floating-ui/react");
|
|
3746
|
+
var import_react30 = require("react");
|
|
3747
|
+
function useFocusedCellHandlePositioning(cellEl, tbodyEl, orientation, show) {
|
|
3748
|
+
const { refs, floatingStyles, context } = (0, import_react29.useFloating)({
|
|
3749
|
+
open: show,
|
|
3750
|
+
placement: orientation === "row" ? "left" : orientation === "col" ? "top" : "right",
|
|
3751
|
+
// col/row: 가장자리 선(zero-size)에, cell: 셀 우측 보더에 14px hit-area 중앙 정렬(-7).
|
|
3752
|
+
middleware: [(0, import_react29.offset)(-7)],
|
|
3753
|
+
whileElementsMounted: import_react29.autoUpdate
|
|
3754
|
+
});
|
|
3755
|
+
const { isMounted, styles } = (0, import_react29.useTransitionStyles)(context);
|
|
3756
|
+
(0, import_react30.useEffect)(() => {
|
|
3757
|
+
if (!cellEl) {
|
|
3758
|
+
refs.setReference(null);
|
|
3759
|
+
return;
|
|
3760
|
+
}
|
|
3761
|
+
refs.setReference({
|
|
3762
|
+
contextElement: cellEl,
|
|
3763
|
+
getBoundingClientRect: () => {
|
|
3764
|
+
const c = cellEl.getBoundingClientRect();
|
|
3765
|
+
const t = tbodyEl?.getBoundingClientRect() ?? c;
|
|
3766
|
+
if (orientation === "col") {
|
|
3767
|
+
return new DOMRect(c.left, t.top, c.width, 0);
|
|
3768
|
+
}
|
|
3769
|
+
if (orientation === "row") {
|
|
3770
|
+
return new DOMRect(t.left, c.top, 0, c.height);
|
|
3771
|
+
}
|
|
3772
|
+
return c;
|
|
3773
|
+
}
|
|
3774
|
+
});
|
|
3775
|
+
}, [cellEl, tbodyEl, orientation, refs]);
|
|
3776
|
+
return (0, import_react30.useMemo)(
|
|
3777
|
+
() => ({
|
|
3778
|
+
isMounted,
|
|
3779
|
+
ref: refs.setFloating,
|
|
3780
|
+
// display는 CSS 클래스에서 제어한다(absolute 자식 stacking).
|
|
3781
|
+
style: {
|
|
3782
|
+
...styles,
|
|
3783
|
+
...floatingStyles
|
|
3784
|
+
}
|
|
3785
|
+
}),
|
|
3786
|
+
[floatingStyles, isMounted, refs.setFloating, styles]
|
|
3787
|
+
);
|
|
3788
|
+
}
|
|
3789
|
+
|
|
3790
|
+
// src/components/LumirTableHandlesController.tsx
|
|
3791
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
3792
|
+
function syncCoreHoverToFocusedCell(cellEl) {
|
|
3793
|
+
const r = cellEl.getBoundingClientRect();
|
|
3794
|
+
cellEl.dispatchEvent(
|
|
3795
|
+
new MouseEvent("mousemove", {
|
|
3796
|
+
bubbles: true,
|
|
3797
|
+
cancelable: true,
|
|
3798
|
+
view: window,
|
|
3799
|
+
clientX: r.left + r.width / 2,
|
|
3800
|
+
clientY: r.top + r.height / 2
|
|
3801
|
+
})
|
|
3802
|
+
);
|
|
3803
|
+
}
|
|
3804
|
+
function LumirTableHandlesController() {
|
|
3805
|
+
const editor = (0, import_react31.useBlockNoteEditor)();
|
|
3806
|
+
const [focused, setFocused] = (0, import_react33.useState)(null);
|
|
3807
|
+
const [menuContainerRef, setMenuContainerRef] = (0, import_react33.useState)(null);
|
|
3808
|
+
const [overlayEl, setOverlayEl] = (0, import_react33.useState)(null);
|
|
3809
|
+
const [openMenu, setOpenMenu] = (0, import_react33.useState)(null);
|
|
3810
|
+
const frozenRef = (0, import_react33.useRef)(false);
|
|
3811
|
+
const menuOpenRef = (0, import_react33.useRef)(false);
|
|
3812
|
+
const draggingRef = (0, import_react33.useRef)(false);
|
|
3813
|
+
const recompute = (0, import_react33.useCallback)(() => {
|
|
3814
|
+
if (frozenRef.current) {
|
|
3815
|
+
return;
|
|
3816
|
+
}
|
|
3817
|
+
const th2 = editor.tableHandles;
|
|
3818
|
+
const view = editor.prosemirrorView;
|
|
3819
|
+
if (!th2 || !view) {
|
|
3820
|
+
setFocused(null);
|
|
3821
|
+
return;
|
|
3822
|
+
}
|
|
3823
|
+
let cellEl2 = null;
|
|
3824
|
+
try {
|
|
3825
|
+
const { node } = view.domAtPos(view.state.selection.from);
|
|
3826
|
+
const el = node.nodeType === Node.TEXT_NODE ? node.parentElement : node;
|
|
3827
|
+
cellEl2 = el?.closest?.("td, th") ?? null;
|
|
3828
|
+
} catch {
|
|
3829
|
+
cellEl2 = null;
|
|
3830
|
+
}
|
|
3831
|
+
if (!cellEl2 || !cellEl2.isConnected) {
|
|
3832
|
+
setFocused(null);
|
|
3833
|
+
return;
|
|
3834
|
+
}
|
|
3835
|
+
const blockId = cellEl2.closest("[data-id]")?.getAttribute("data-id");
|
|
3836
|
+
const block = blockId ? editor.getBlock(blockId) : void 0;
|
|
3837
|
+
if (!block || block.type !== "table") {
|
|
3838
|
+
setFocused(null);
|
|
3839
|
+
return;
|
|
3840
|
+
}
|
|
3841
|
+
const cellSel = th2.getCellSelection();
|
|
3842
|
+
if (!cellSel) {
|
|
3843
|
+
setFocused(null);
|
|
3844
|
+
return;
|
|
3845
|
+
}
|
|
3846
|
+
const widgetContainer = cellEl2.closest(".tableWrapper")?.querySelector(".table-widgets-container");
|
|
3847
|
+
const tbodyEl2 = cellEl2.closest("tbody");
|
|
3848
|
+
if (!widgetContainer || !tbodyEl2) {
|
|
3849
|
+
setFocused(null);
|
|
3850
|
+
return;
|
|
3851
|
+
}
|
|
3852
|
+
setFocused({
|
|
3853
|
+
block,
|
|
3854
|
+
rowIndex: cellSel.from.row,
|
|
3855
|
+
colIndex: cellSel.from.col,
|
|
3856
|
+
cellEl: cellEl2,
|
|
3857
|
+
tbodyEl: tbodyEl2,
|
|
3858
|
+
widgetContainer
|
|
3859
|
+
});
|
|
3860
|
+
}, [editor]);
|
|
3861
|
+
(0, import_react31.useEditorContentOrSelectionChange)(recompute, editor);
|
|
3862
|
+
(0, import_react33.useEffect)(() => {
|
|
3863
|
+
recompute();
|
|
3864
|
+
}, [recompute]);
|
|
3865
|
+
(0, import_react33.useEffect)(() => {
|
|
3866
|
+
const onUp = () => {
|
|
3867
|
+
requestAnimationFrame(() => {
|
|
3868
|
+
if (!menuOpenRef.current && !draggingRef.current && frozenRef.current) {
|
|
3869
|
+
frozenRef.current = false;
|
|
3870
|
+
recompute();
|
|
3871
|
+
}
|
|
3872
|
+
});
|
|
3873
|
+
};
|
|
3874
|
+
window.addEventListener("pointerup", onUp);
|
|
3875
|
+
return () => window.removeEventListener("pointerup", onUp);
|
|
3876
|
+
}, [recompute]);
|
|
3877
|
+
(0, import_react33.useEffect)(() => {
|
|
3878
|
+
const f = focused;
|
|
3879
|
+
if (!f || !overlayEl) {
|
|
3880
|
+
return;
|
|
3881
|
+
}
|
|
3882
|
+
const PAD = 1;
|
|
3883
|
+
const update = () => {
|
|
3884
|
+
const cr = f.cellEl.getBoundingClientRect();
|
|
3885
|
+
const tr = f.tbodyEl.getBoundingClientRect();
|
|
3886
|
+
const kr = f.widgetContainer.getBoundingClientRect();
|
|
3887
|
+
const x1 = openMenu === "row" ? tr.left : cr.left;
|
|
3888
|
+
const y1 = openMenu === "col" ? tr.top : cr.top;
|
|
3889
|
+
const x2 = openMenu === "row" ? tr.right : cr.right;
|
|
3890
|
+
const y2 = openMenu === "col" ? tr.bottom : cr.bottom;
|
|
3891
|
+
const dpr = window.devicePixelRatio || 1;
|
|
3892
|
+
const rd = (v) => Math.round(v * dpr) / dpr;
|
|
3893
|
+
const left = rd(x1 - kr.left) - PAD;
|
|
3894
|
+
const top = rd(y1 - kr.top) - PAD;
|
|
3895
|
+
const right = rd(x2 - kr.left) + PAD;
|
|
3896
|
+
const bottom = rd(y2 - kr.top) + PAD;
|
|
3897
|
+
overlayEl.style.transform = `translate(${left}px, ${top}px)`;
|
|
3898
|
+
overlayEl.style.width = `${right - left}px`;
|
|
3899
|
+
overlayEl.style.height = `${bottom - top}px`;
|
|
3900
|
+
};
|
|
3901
|
+
update();
|
|
3902
|
+
return (0, import_react32.autoUpdate)(f.cellEl, overlayEl, update);
|
|
3903
|
+
}, [focused, overlayEl, openMenu]);
|
|
3904
|
+
const cellEl = focused?.cellEl ?? null;
|
|
3905
|
+
const tbodyEl = focused?.tbodyEl ?? null;
|
|
3906
|
+
const show = focused !== null;
|
|
3907
|
+
const rowHandle = useFocusedCellHandlePositioning(cellEl, tbodyEl, "row", show);
|
|
3908
|
+
const colHandle = useFocusedCellHandlePositioning(cellEl, tbodyEl, "col", show);
|
|
3909
|
+
const cellHandle = useFocusedCellHandlePositioning(
|
|
3910
|
+
cellEl,
|
|
3911
|
+
tbodyEl,
|
|
3912
|
+
"cell",
|
|
3913
|
+
show
|
|
3914
|
+
);
|
|
3915
|
+
const th = editor.tableHandles;
|
|
3916
|
+
const coreState = (0, import_react31.useUIPluginState)(
|
|
3917
|
+
editor.tableHandles.onUpdate.bind(editor.tableHandles)
|
|
3918
|
+
);
|
|
3919
|
+
const { addOrRemoveColumnsButton, addOrRemoveRowsButton } = (0, import_react31.useExtendButtonsPositioning)(
|
|
3920
|
+
coreState?.showAddOrRemoveColumnsButton || false,
|
|
3921
|
+
coreState?.showAddOrRemoveRowsButton || false,
|
|
3922
|
+
coreState?.referencePosTable || null
|
|
3923
|
+
);
|
|
3924
|
+
const onStartExtend = (0, import_react33.useCallback)(() => {
|
|
3925
|
+
editor.tableHandles?.freezeHandles();
|
|
3926
|
+
}, [editor]);
|
|
3927
|
+
const onEndExtend = (0, import_react33.useCallback)(() => {
|
|
3928
|
+
editor.tableHandles?.unfreezeHandles();
|
|
3929
|
+
}, [editor]);
|
|
3930
|
+
const menuHandlers = (0, import_react33.useMemo)(() => {
|
|
3931
|
+
const mk = (kind) => ({
|
|
3932
|
+
freeze: () => {
|
|
3933
|
+
menuOpenRef.current = true;
|
|
3934
|
+
frozenRef.current = true;
|
|
3935
|
+
setOpenMenu(kind);
|
|
3936
|
+
editor.tableHandles?.freezeHandles();
|
|
3937
|
+
},
|
|
3938
|
+
unfreeze: () => {
|
|
3939
|
+
menuOpenRef.current = false;
|
|
3940
|
+
frozenRef.current = false;
|
|
3941
|
+
setOpenMenu(null);
|
|
3942
|
+
editor.tableHandles?.unfreezeHandles();
|
|
3943
|
+
recompute();
|
|
3944
|
+
}
|
|
3945
|
+
});
|
|
3946
|
+
return { col: mk("col"), row: mk("row"), cell: mk("cell") };
|
|
3947
|
+
}, [editor, recompute]);
|
|
3948
|
+
const onGutterPointerDown = (0, import_react33.useCallback)(() => {
|
|
3949
|
+
frozenRef.current = true;
|
|
3950
|
+
}, []);
|
|
3951
|
+
const onGutterPointerEnter = (0, import_react33.useCallback)(
|
|
3952
|
+
(e) => {
|
|
3953
|
+
if (e.buttons === 0 && focused) {
|
|
3954
|
+
syncCoreHoverToFocusedCell(focused.cellEl);
|
|
3955
|
+
}
|
|
3956
|
+
},
|
|
3957
|
+
[focused]
|
|
3958
|
+
);
|
|
3959
|
+
const makeDragStart = (0, import_react33.useCallback)(
|
|
3960
|
+
(dir) => (e) => {
|
|
3961
|
+
draggingRef.current = true;
|
|
3962
|
+
frozenRef.current = true;
|
|
3963
|
+
if (dir === "row") {
|
|
3964
|
+
editor.tableHandles?.rowDragStart(e);
|
|
3965
|
+
} else {
|
|
3966
|
+
editor.tableHandles?.colDragStart(e);
|
|
3967
|
+
}
|
|
3968
|
+
},
|
|
3969
|
+
[editor]
|
|
3970
|
+
);
|
|
3971
|
+
const onDragEnd = (0, import_react33.useCallback)(() => {
|
|
3972
|
+
editor.tableHandles?.dragEnd();
|
|
3973
|
+
draggingRef.current = false;
|
|
3974
|
+
frozenRef.current = false;
|
|
3975
|
+
recompute();
|
|
3976
|
+
}, [editor, recompute]);
|
|
3977
|
+
const noop = (0, import_react33.useCallback)(() => {
|
|
3978
|
+
}, []);
|
|
3979
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
3980
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: setMenuContainerRef }),
|
|
3981
|
+
th && focused && menuContainerRef && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react32.FloatingPortal, { root: focused.widgetContainer, children: [
|
|
3982
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: setOverlayEl, className: "lumir-tbl-cell-focus" }),
|
|
3983
|
+
colHandle.isMounted && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
3984
|
+
"div",
|
|
3985
|
+
{
|
|
3986
|
+
ref: colHandle.ref,
|
|
3987
|
+
style: colHandle.style,
|
|
3988
|
+
className: "lumir-tbl-gutter-wrap lumir-tbl-gutter-wrap--col" + (openMenu === "col" ? " lumir-tbl-gutter-wrap--active" : ""),
|
|
3989
|
+
onPointerEnter: onGutterPointerEnter,
|
|
3990
|
+
onPointerDown: onGutterPointerDown,
|
|
3991
|
+
children: [
|
|
3992
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "lumir-tbl-gutter" }),
|
|
3993
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3994
|
+
import_react31.TableHandle,
|
|
3995
|
+
{
|
|
3996
|
+
editor,
|
|
3997
|
+
orientation: "column",
|
|
3998
|
+
index: focused.colIndex,
|
|
3999
|
+
block: focused.block,
|
|
4000
|
+
dragStart: makeDragStart("col"),
|
|
4001
|
+
dragEnd: onDragEnd,
|
|
4002
|
+
freezeHandles: menuHandlers.col.freeze,
|
|
4003
|
+
unfreezeHandles: menuHandlers.col.unfreeze,
|
|
4004
|
+
menuContainer: menuContainerRef,
|
|
4005
|
+
showOtherSide: noop,
|
|
4006
|
+
hideOtherSide: noop
|
|
4007
|
+
}
|
|
4008
|
+
) })
|
|
4009
|
+
]
|
|
4010
|
+
}
|
|
4011
|
+
),
|
|
4012
|
+
rowHandle.isMounted && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
4013
|
+
"div",
|
|
4014
|
+
{
|
|
4015
|
+
ref: rowHandle.ref,
|
|
4016
|
+
style: rowHandle.style,
|
|
4017
|
+
className: "lumir-tbl-gutter-wrap lumir-tbl-gutter-wrap--row" + (openMenu === "row" ? " lumir-tbl-gutter-wrap--active" : ""),
|
|
4018
|
+
onPointerEnter: onGutterPointerEnter,
|
|
4019
|
+
onPointerDown: onGutterPointerDown,
|
|
4020
|
+
children: [
|
|
4021
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "lumir-tbl-gutter" }),
|
|
4022
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4023
|
+
import_react31.TableHandle,
|
|
4024
|
+
{
|
|
4025
|
+
editor,
|
|
4026
|
+
orientation: "row",
|
|
4027
|
+
index: focused.rowIndex,
|
|
4028
|
+
block: focused.block,
|
|
4029
|
+
dragStart: makeDragStart("row"),
|
|
4030
|
+
dragEnd: onDragEnd,
|
|
4031
|
+
freezeHandles: menuHandlers.row.freeze,
|
|
4032
|
+
unfreezeHandles: menuHandlers.row.unfreeze,
|
|
4033
|
+
menuContainer: menuContainerRef,
|
|
4034
|
+
showOtherSide: noop,
|
|
4035
|
+
hideOtherSide: noop
|
|
4036
|
+
}
|
|
4037
|
+
) })
|
|
4038
|
+
]
|
|
4039
|
+
}
|
|
4040
|
+
),
|
|
4041
|
+
cellHandle.isMounted && openMenu !== "col" && openMenu !== "row" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
4042
|
+
"div",
|
|
4043
|
+
{
|
|
4044
|
+
ref: cellHandle.ref,
|
|
4045
|
+
style: cellHandle.style,
|
|
4046
|
+
className: "lumir-tbl-gutter-wrap lumir-tbl-gutter-wrap--cell" + (openMenu === "cell" ? " lumir-tbl-gutter-wrap--active" : ""),
|
|
4047
|
+
onPointerDown: onGutterPointerDown,
|
|
4048
|
+
children: [
|
|
4049
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "lumir-tbl-gutter" }),
|
|
4050
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "lumir-tbl-grip", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4051
|
+
import_react31.TableCellButton,
|
|
4052
|
+
{
|
|
4053
|
+
editor,
|
|
4054
|
+
rowIndex: focused.rowIndex,
|
|
4055
|
+
colIndex: focused.colIndex,
|
|
4056
|
+
block: focused.block,
|
|
4057
|
+
tableCellMenu: LumirTableCellMenu,
|
|
4058
|
+
menuContainer: menuContainerRef,
|
|
4059
|
+
freezeHandles: menuHandlers.cell.freeze,
|
|
4060
|
+
unfreezeHandles: menuHandlers.cell.unfreeze
|
|
4061
|
+
}
|
|
4062
|
+
) })
|
|
4063
|
+
]
|
|
4064
|
+
}
|
|
4065
|
+
)
|
|
4066
|
+
] }),
|
|
4067
|
+
th && coreState?.widgetContainer && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react32.FloatingPortal, { root: coreState.widgetContainer, children: [
|
|
4068
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: addOrRemoveRowsButton.ref, style: addOrRemoveRowsButton.style, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4069
|
+
import_react31.ExtendButton,
|
|
4070
|
+
{
|
|
4071
|
+
editor,
|
|
4072
|
+
orientation: "addOrRemoveRows",
|
|
4073
|
+
block: coreState.block,
|
|
4074
|
+
onMouseDown: onStartExtend,
|
|
4075
|
+
onMouseUp: onEndExtend
|
|
4076
|
+
}
|
|
4077
|
+
) }),
|
|
4078
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4079
|
+
"div",
|
|
4080
|
+
{
|
|
4081
|
+
ref: addOrRemoveColumnsButton.ref,
|
|
4082
|
+
style: addOrRemoveColumnsButton.style,
|
|
4083
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4084
|
+
import_react31.ExtendButton,
|
|
4085
|
+
{
|
|
4086
|
+
editor,
|
|
4087
|
+
orientation: "addOrRemoveColumns",
|
|
4088
|
+
block: coreState.block,
|
|
4089
|
+
onMouseDown: onStartExtend,
|
|
4090
|
+
onMouseUp: onEndExtend
|
|
4091
|
+
}
|
|
4092
|
+
)
|
|
4093
|
+
}
|
|
4094
|
+
)
|
|
4095
|
+
] })
|
|
4096
|
+
] });
|
|
4097
|
+
}
|
|
4098
|
+
|
|
3145
4099
|
// src/utils/table-vertical-alignment.ts
|
|
3146
4100
|
function injectVerticalAlignment(blocks, editor) {
|
|
3147
4101
|
const tiptap = editor?._tiptapEditor;
|
|
@@ -3224,6 +4178,90 @@ function patchBlocks(blocks, tableVAMap) {
|
|
|
3224
4178
|
});
|
|
3225
4179
|
}
|
|
3226
4180
|
|
|
4181
|
+
// src/utils/font-size-serialization.ts
|
|
4182
|
+
function mapPreservingRef(arr, fn) {
|
|
4183
|
+
let changed = false;
|
|
4184
|
+
const next = arr.map((item) => {
|
|
4185
|
+
const mapped = fn(item);
|
|
4186
|
+
if (mapped !== item) changed = true;
|
|
4187
|
+
return mapped;
|
|
4188
|
+
});
|
|
4189
|
+
return changed ? next : arr;
|
|
4190
|
+
}
|
|
4191
|
+
function mapStyledItem(item, dir) {
|
|
4192
|
+
if (!item || typeof item !== "object" || item.type !== "text") {
|
|
4193
|
+
return item;
|
|
4194
|
+
}
|
|
4195
|
+
if (dir === "lower") {
|
|
4196
|
+
const fs2 = item.styles?.fontSize;
|
|
4197
|
+
if (fs2 == null) return item;
|
|
4198
|
+
const { fontSize: _removed, ...restStyles } = item.styles;
|
|
4199
|
+
return { ...item, styles: restStyles, fontSize: fs2 };
|
|
4200
|
+
}
|
|
4201
|
+
const fs = item.fontSize;
|
|
4202
|
+
if (fs == null) return item;
|
|
4203
|
+
const { fontSize: _lifted, ...rest } = item;
|
|
4204
|
+
return { ...rest, styles: { ...item.styles ?? {}, fontSize: fs } };
|
|
4205
|
+
}
|
|
4206
|
+
function mapInlineItem(node, dir) {
|
|
4207
|
+
if (!node || typeof node !== "object") return node;
|
|
4208
|
+
if (node.type === "link" && Array.isArray(node.content)) {
|
|
4209
|
+
const content = mapPreservingRef(
|
|
4210
|
+
node.content,
|
|
4211
|
+
(n) => mapStyledItem(n, dir)
|
|
4212
|
+
);
|
|
4213
|
+
return content === node.content ? node : { ...node, content };
|
|
4214
|
+
}
|
|
4215
|
+
return mapStyledItem(node, dir);
|
|
4216
|
+
}
|
|
4217
|
+
function mapCell(cell, dir) {
|
|
4218
|
+
if (cell && typeof cell === "object" && cell.type === "tableCell") {
|
|
4219
|
+
if (!Array.isArray(cell.content)) return cell;
|
|
4220
|
+
const content = mapPreservingRef(
|
|
4221
|
+
cell.content,
|
|
4222
|
+
(n) => mapInlineItem(n, dir)
|
|
4223
|
+
);
|
|
4224
|
+
return content === cell.content ? cell : { ...cell, content };
|
|
4225
|
+
}
|
|
4226
|
+
if (Array.isArray(cell)) {
|
|
4227
|
+
return mapPreservingRef(cell, (n) => mapInlineItem(n, dir));
|
|
4228
|
+
}
|
|
4229
|
+
return cell;
|
|
4230
|
+
}
|
|
4231
|
+
function mapBlock(block, dir) {
|
|
4232
|
+
if (!block || typeof block !== "object") return block;
|
|
4233
|
+
let next = block;
|
|
4234
|
+
const content = block.content;
|
|
4235
|
+
if (Array.isArray(content)) {
|
|
4236
|
+
const mapped = mapPreservingRef(content, (n) => mapInlineItem(n, dir));
|
|
4237
|
+
if (mapped !== content) next = { ...next, content: mapped };
|
|
4238
|
+
} else if (content && typeof content === "object" && content.type === "tableContent" && Array.isArray(content.rows)) {
|
|
4239
|
+
const rows = mapPreservingRef(content.rows, (row) => {
|
|
4240
|
+
if (!row || !Array.isArray(row.cells)) return row;
|
|
4241
|
+
const cells = mapPreservingRef(
|
|
4242
|
+
row.cells,
|
|
4243
|
+
(cell) => mapCell(cell, dir)
|
|
4244
|
+
);
|
|
4245
|
+
return cells === row.cells ? row : { ...row, cells };
|
|
4246
|
+
});
|
|
4247
|
+
if (rows !== content.rows) next = { ...next, content: { ...content, rows } };
|
|
4248
|
+
}
|
|
4249
|
+
if (Array.isArray(block.children) && block.children.length > 0) {
|
|
4250
|
+
const children = mapPreservingRef(
|
|
4251
|
+
block.children,
|
|
4252
|
+
(b) => mapBlock(b, dir)
|
|
4253
|
+
);
|
|
4254
|
+
if (children !== block.children) next = { ...next, children };
|
|
4255
|
+
}
|
|
4256
|
+
return next;
|
|
4257
|
+
}
|
|
4258
|
+
function lowerFontSize(blocks) {
|
|
4259
|
+
return mapPreservingRef(blocks, (b) => mapBlock(b, "lower"));
|
|
4260
|
+
}
|
|
4261
|
+
function liftFontSize(blocks) {
|
|
4262
|
+
return mapPreservingRef(blocks, (b) => mapBlock(b, "lift"));
|
|
4263
|
+
}
|
|
4264
|
+
|
|
3227
4265
|
// src/utils/excel-paste.ts
|
|
3228
4266
|
var NAMED_COLORS = {
|
|
3229
4267
|
black: "#000000",
|
|
@@ -3472,7 +4510,7 @@ var ALLOWED_VIDEO_EXTENSIONS = [
|
|
|
3472
4510
|
];
|
|
3473
4511
|
|
|
3474
4512
|
// src/components/LumirEditor.tsx
|
|
3475
|
-
var
|
|
4513
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
3476
4514
|
var DEBUG_LOG = (loc, msg, data) => {
|
|
3477
4515
|
const p = fetch("http://127.0.0.1:7686/ingest/1f8ee1c5-0cf0-4ae7-91ed-5ea7ed17130a", {
|
|
3478
4516
|
method: "POST",
|
|
@@ -3637,6 +4675,12 @@ var isVideoFile = (file, maxSize) => {
|
|
|
3637
4675
|
});
|
|
3638
4676
|
return result;
|
|
3639
4677
|
};
|
|
4678
|
+
var isSuppressiblePopupSelection = (editor, selection) => {
|
|
4679
|
+
if (!selection) return false;
|
|
4680
|
+
if (selection.node) return false;
|
|
4681
|
+
if (isInTableCell(editor)) return false;
|
|
4682
|
+
return true;
|
|
4683
|
+
};
|
|
3640
4684
|
var isHtmlFile = (file) => {
|
|
3641
4685
|
return file.size > 0 && (file.type === "text/html" || file.name?.toLowerCase().endsWith(".html") || file.name?.toLowerCase().endsWith(".htm"));
|
|
3642
4686
|
};
|
|
@@ -3697,9 +4741,9 @@ var findBlockWithLink = (blocks, targetUrl) => {
|
|
|
3697
4741
|
return null;
|
|
3698
4742
|
};
|
|
3699
4743
|
var ConvertToPreviewButton = ({ url }) => {
|
|
3700
|
-
const editor = (0,
|
|
3701
|
-
const Components = (0,
|
|
3702
|
-
return /* @__PURE__ */ (0,
|
|
4744
|
+
const editor = (0, import_react35.useBlockNoteEditor)();
|
|
4745
|
+
const Components = (0, import_react35.useComponentsContext)();
|
|
4746
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3703
4747
|
Components.LinkToolbar.Button,
|
|
3704
4748
|
{
|
|
3705
4749
|
className: "bn-button",
|
|
@@ -3718,29 +4762,29 @@ var ConvertToPreviewButton = ({ url }) => {
|
|
|
3718
4762
|
console.error("Convert to link preview failed:", err);
|
|
3719
4763
|
}
|
|
3720
4764
|
},
|
|
3721
|
-
icon: /* @__PURE__ */ (0,
|
|
3722
|
-
/* @__PURE__ */ (0,
|
|
3723
|
-
/* @__PURE__ */ (0,
|
|
3724
|
-
/* @__PURE__ */ (0,
|
|
4765
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
4766
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("rect", { x: "1", y: "3", width: "14", height: "10", rx: "2", stroke: "currentColor", strokeWidth: "1.5", fill: "none" }),
|
|
4767
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("line", { x1: "1", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
4768
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("circle", { cx: "5", cy: "6.5", r: "1.5", stroke: "currentColor", strokeWidth: "1", fill: "none" })
|
|
3725
4769
|
] })
|
|
3726
4770
|
}
|
|
3727
4771
|
);
|
|
3728
4772
|
};
|
|
3729
4773
|
var CustomLinkToolbar = (props) => {
|
|
3730
|
-
const editor = (0,
|
|
3731
|
-
const Components = (0,
|
|
4774
|
+
const editor = (0, import_react35.useBlockNoteEditor)();
|
|
4775
|
+
const Components = (0, import_react35.useComponentsContext)();
|
|
3732
4776
|
const hasLinkPreview = !!editor?._linkPreviewApiEndpoint;
|
|
3733
|
-
return /* @__PURE__ */ (0,
|
|
4777
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
3734
4778
|
Components.LinkToolbar.Root,
|
|
3735
4779
|
{
|
|
3736
4780
|
className: "bn-toolbar bn-link-toolbar",
|
|
3737
4781
|
onMouseEnter: props.stopHideTimer,
|
|
3738
4782
|
onMouseLeave: props.startHideTimer,
|
|
3739
4783
|
children: [
|
|
3740
|
-
/* @__PURE__ */ (0,
|
|
3741
|
-
/* @__PURE__ */ (0,
|
|
3742
|
-
/* @__PURE__ */ (0,
|
|
3743
|
-
hasLinkPreview && /* @__PURE__ */ (0,
|
|
4784
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react35.EditLinkButton, { url: props.url, text: props.text, editLink: props.editLink }),
|
|
4785
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react35.OpenLinkButton, { url: props.url }),
|
|
4786
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react35.DeleteLinkButton, { deleteLink: props.deleteLink }),
|
|
4787
|
+
hasLinkPreview && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ConvertToPreviewButton, { url: props.url })
|
|
3744
4788
|
]
|
|
3745
4789
|
}
|
|
3746
4790
|
);
|
|
@@ -3784,13 +4828,13 @@ function LumirEditor({
|
|
|
3784
4828
|
onError,
|
|
3785
4829
|
onImageDelete
|
|
3786
4830
|
}) {
|
|
3787
|
-
const [isUploading, setIsUploading] = (0,
|
|
3788
|
-
const [uploadProgress, setUploadProgress] = (0,
|
|
3789
|
-
const [errorMessage, setErrorMessage] = (0,
|
|
3790
|
-
const floatingMenuFileInputRef = (0,
|
|
3791
|
-
const floatingMenuBlockRef = (0,
|
|
3792
|
-
const floatingMenuUploadStartTimeRef = (0,
|
|
3793
|
-
const handleError = (0,
|
|
4831
|
+
const [isUploading, setIsUploading] = (0, import_react34.useState)(false);
|
|
4832
|
+
const [uploadProgress, setUploadProgress] = (0, import_react34.useState)(null);
|
|
4833
|
+
const [errorMessage, setErrorMessage] = (0, import_react34.useState)(null);
|
|
4834
|
+
const floatingMenuFileInputRef = (0, import_react34.useRef)(null);
|
|
4835
|
+
const floatingMenuBlockRef = (0, import_react34.useRef)(null);
|
|
4836
|
+
const floatingMenuUploadStartTimeRef = (0, import_react34.useRef)(0);
|
|
4837
|
+
const handleError = (0, import_react34.useCallback)(
|
|
3794
4838
|
(error) => {
|
|
3795
4839
|
onError?.(error);
|
|
3796
4840
|
setErrorMessage(error.getUserMessage());
|
|
@@ -3798,10 +4842,12 @@ function LumirEditor({
|
|
|
3798
4842
|
},
|
|
3799
4843
|
[onError]
|
|
3800
4844
|
);
|
|
3801
|
-
const validatedContent = (0,
|
|
3802
|
-
return
|
|
4845
|
+
const validatedContent = (0, import_react34.useMemo)(() => {
|
|
4846
|
+
return liftFontSize(
|
|
4847
|
+
ContentUtils.validateContent(initialContent, initialEmptyBlocks)
|
|
4848
|
+
);
|
|
3803
4849
|
}, [initialContent, initialEmptyBlocks]);
|
|
3804
|
-
const tableConfig = (0,
|
|
4850
|
+
const tableConfig = (0, import_react34.useMemo)(() => {
|
|
3805
4851
|
return EditorConfig.getDefaultTableConfig(tables);
|
|
3806
4852
|
}, [
|
|
3807
4853
|
tables?.splitCells,
|
|
@@ -3809,10 +4855,10 @@ function LumirEditor({
|
|
|
3809
4855
|
tables?.cellTextColor,
|
|
3810
4856
|
tables?.headers
|
|
3811
4857
|
]);
|
|
3812
|
-
const headingConfig = (0,
|
|
4858
|
+
const headingConfig = (0, import_react34.useMemo)(() => {
|
|
3813
4859
|
return EditorConfig.getDefaultHeadingConfig(heading);
|
|
3814
4860
|
}, [heading?.levels?.join(",") ?? ""]);
|
|
3815
|
-
const disabledExtensions = (0,
|
|
4861
|
+
const disabledExtensions = (0, import_react34.useMemo)(() => {
|
|
3816
4862
|
return EditorConfig.getDisabledExtensions(
|
|
3817
4863
|
disableExtensions,
|
|
3818
4864
|
allowVideoUpload,
|
|
@@ -3820,18 +4866,18 @@ function LumirEditor({
|
|
|
3820
4866
|
allowFileUpload
|
|
3821
4867
|
);
|
|
3822
4868
|
}, [disableExtensions, allowVideoUpload, allowAudioUpload, allowFileUpload]);
|
|
3823
|
-
(0,
|
|
4869
|
+
(0, import_react34.useEffect)(() => {
|
|
3824
4870
|
DEBUG_LOG("LumirEditor:init:disabledExtensions", "snapshot", {
|
|
3825
4871
|
allowVideoUpload,
|
|
3826
4872
|
hasVideoInDisabled: disabledExtensions.includes("video"),
|
|
3827
4873
|
disabledList: disabledExtensions.slice(0, 15)
|
|
3828
4874
|
});
|
|
3829
4875
|
}, [allowVideoUpload, disabledExtensions]);
|
|
3830
|
-
const fileNameTransformRef = (0,
|
|
3831
|
-
(0,
|
|
4876
|
+
const fileNameTransformRef = (0, import_react34.useRef)(s3Upload?.fileNameTransform);
|
|
4877
|
+
(0, import_react34.useEffect)(() => {
|
|
3832
4878
|
fileNameTransformRef.current = s3Upload?.fileNameTransform;
|
|
3833
4879
|
}, [s3Upload?.fileNameTransform]);
|
|
3834
|
-
const memoizedS3Upload = (0,
|
|
4880
|
+
const memoizedS3Upload = (0, import_react34.useMemo)(() => {
|
|
3835
4881
|
if (!s3Upload) return void 0;
|
|
3836
4882
|
return {
|
|
3837
4883
|
apiEndpoint: s3Upload.apiEndpoint,
|
|
@@ -3860,10 +4906,19 @@ function LumirEditor({
|
|
|
3860
4906
|
s3Upload?.maxRetries,
|
|
3861
4907
|
s3Upload?.onProgress
|
|
3862
4908
|
]);
|
|
3863
|
-
const editor = (0,
|
|
4909
|
+
const editor = (0, import_react35.useCreateBlockNote)(
|
|
3864
4910
|
{
|
|
3865
4911
|
// HTML 미리보기 블록이 포함된 커스텀 스키마 사용
|
|
3866
4912
|
schema,
|
|
4913
|
+
// 모든 BlockNote UI 텍스트(테이블 드롭다운 등) 한글 적용 + "색깔"→"색"
|
|
4914
|
+
dictionary: {
|
|
4915
|
+
...import_locales.ko,
|
|
4916
|
+
drag_handle: { ...import_locales.ko.drag_handle, colors_menuitem: "\uC0C9" },
|
|
4917
|
+
formatting_toolbar: {
|
|
4918
|
+
...import_locales.ko.formatting_toolbar,
|
|
4919
|
+
colors: { ...import_locales.ko.formatting_toolbar.colors, tooltip: "\uC0C9" }
|
|
4920
|
+
}
|
|
4921
|
+
},
|
|
3867
4922
|
initialContent: validatedContent,
|
|
3868
4923
|
tables: tableConfig,
|
|
3869
4924
|
heading: headingConfig,
|
|
@@ -4055,27 +5110,40 @@ function LumirEditor({
|
|
|
4055
5110
|
if (editor && linkPreview?.apiEndpoint) {
|
|
4056
5111
|
editor._linkPreviewApiEndpoint = linkPreview.apiEndpoint;
|
|
4057
5112
|
}
|
|
4058
|
-
(0,
|
|
5113
|
+
(0, import_react34.useEffect)(() => {
|
|
4059
5114
|
if (editor) {
|
|
4060
5115
|
editor.isEditable = editable;
|
|
4061
5116
|
}
|
|
4062
5117
|
}, [editor, editable]);
|
|
4063
|
-
(0,
|
|
5118
|
+
(0, import_react34.useEffect)(() => {
|
|
5119
|
+
if (!editor || !floatingMenu) return;
|
|
5120
|
+
const ft = editor.formattingToolbar;
|
|
5121
|
+
if (!ft?.onUpdate) return;
|
|
5122
|
+
const unsubscribe = ft.onUpdate((state) => {
|
|
5123
|
+
if (!state?.show) return;
|
|
5124
|
+
const selection = editor._tiptapEditor?.state?.selection;
|
|
5125
|
+
if (isSuppressiblePopupSelection(editor, selection)) {
|
|
5126
|
+
ft.closeMenu();
|
|
5127
|
+
}
|
|
5128
|
+
});
|
|
5129
|
+
return unsubscribe;
|
|
5130
|
+
}, [editor, floatingMenu]);
|
|
5131
|
+
(0, import_react34.useEffect)(() => {
|
|
4064
5132
|
if (!editor || !onContentChange) return;
|
|
4065
5133
|
const handleContentChange = () => {
|
|
4066
5134
|
const blocks = editor.topLevelBlocks;
|
|
4067
|
-
const patched = injectVerticalAlignment(blocks, editor);
|
|
5135
|
+
const patched = lowerFontSize(injectVerticalAlignment(blocks, editor));
|
|
4068
5136
|
onContentChange(patched);
|
|
4069
5137
|
};
|
|
4070
5138
|
return editor.onEditorContentChange(handleContentChange);
|
|
4071
5139
|
}, [editor, onContentChange]);
|
|
4072
|
-
const previousMediaUrlsRef = (0,
|
|
4073
|
-
(0,
|
|
5140
|
+
const previousMediaUrlsRef = (0, import_react34.useRef)(/* @__PURE__ */ new Set());
|
|
5141
|
+
(0, import_react34.useEffect)(() => {
|
|
4074
5142
|
if (!editor) return;
|
|
4075
5143
|
const initialBlocks = editor.topLevelBlocks;
|
|
4076
5144
|
previousMediaUrlsRef.current = extractMediaUrls(initialBlocks);
|
|
4077
5145
|
}, [editor]);
|
|
4078
|
-
(0,
|
|
5146
|
+
(0, import_react34.useEffect)(() => {
|
|
4079
5147
|
if (!editor || !onImageDelete) return;
|
|
4080
5148
|
const handleMediaDeleteCheck = () => {
|
|
4081
5149
|
const currentBlocks = editor.topLevelBlocks;
|
|
@@ -4089,7 +5157,7 @@ function LumirEditor({
|
|
|
4089
5157
|
};
|
|
4090
5158
|
return editor.onEditorContentChange(handleMediaDeleteCheck);
|
|
4091
5159
|
}, [editor, onImageDelete]);
|
|
4092
|
-
(0,
|
|
5160
|
+
(0, import_react34.useEffect)(() => {
|
|
4093
5161
|
const el = editor?.domElement;
|
|
4094
5162
|
if (!el) return;
|
|
4095
5163
|
const handleDragOver = (e) => {
|
|
@@ -4220,20 +5288,20 @@ function LumirEditor({
|
|
|
4220
5288
|
el.removeEventListener("drop", handleDrop, { capture: true });
|
|
4221
5289
|
};
|
|
4222
5290
|
}, [editor, allowVideoUpload]);
|
|
4223
|
-
const computedSideMenu = (0,
|
|
5291
|
+
const computedSideMenu = (0, import_react34.useMemo)(() => {
|
|
4224
5292
|
return sideMenuAddButton ? sideMenu : false;
|
|
4225
5293
|
}, [sideMenuAddButton, sideMenu]);
|
|
4226
|
-
const DragHandleOnlySideMenu = (0,
|
|
4227
|
-
return (props) => /* @__PURE__ */ (0,
|
|
5294
|
+
const DragHandleOnlySideMenu = (0, import_react34.useMemo)(() => {
|
|
5295
|
+
return (props) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react35.SideMenu, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react35.DragHandleButton, { ...props }) });
|
|
4228
5296
|
}, []);
|
|
4229
|
-
return /* @__PURE__ */ (0,
|
|
5297
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
4230
5298
|
"div",
|
|
4231
5299
|
{
|
|
4232
5300
|
className: cn("lumirEditor", className),
|
|
4233
5301
|
style: { position: "relative", display: "flex", flexDirection: "column" },
|
|
4234
5302
|
children: [
|
|
4235
|
-
floatingMenu && editor && /* @__PURE__ */ (0,
|
|
4236
|
-
/* @__PURE__ */ (0,
|
|
5303
|
+
floatingMenu && editor && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
5304
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4237
5305
|
"input",
|
|
4238
5306
|
{
|
|
4239
5307
|
ref: floatingMenuFileInputRef,
|
|
@@ -4304,7 +5372,7 @@ function LumirEditor({
|
|
|
4304
5372
|
}
|
|
4305
5373
|
}
|
|
4306
5374
|
),
|
|
4307
|
-
/* @__PURE__ */ (0,
|
|
5375
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4308
5376
|
FloatingMenu,
|
|
4309
5377
|
{
|
|
4310
5378
|
editor,
|
|
@@ -4336,7 +5404,7 @@ function LumirEditor({
|
|
|
4336
5404
|
}
|
|
4337
5405
|
)
|
|
4338
5406
|
] }),
|
|
4339
|
-
/* @__PURE__ */ (0,
|
|
5407
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
4340
5408
|
import_mantine.BlockNoteView,
|
|
4341
5409
|
{
|
|
4342
5410
|
editor,
|
|
@@ -4348,23 +5416,24 @@ function LumirEditor({
|
|
|
4348
5416
|
slashMenu: false,
|
|
4349
5417
|
emojiPicker,
|
|
4350
5418
|
filePanel,
|
|
4351
|
-
tableHandles,
|
|
5419
|
+
tableHandles: false,
|
|
4352
5420
|
onSelectionChange,
|
|
4353
5421
|
children: [
|
|
4354
|
-
|
|
4355
|
-
|
|
5422
|
+
tableHandles && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(LumirTableHandlesController, {}),
|
|
5423
|
+
formattingToolbar && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5424
|
+
import_react35.FormattingToolbarController,
|
|
4356
5425
|
{
|
|
4357
5426
|
formattingToolbar: CustomFormattingToolbar
|
|
4358
5427
|
}
|
|
4359
5428
|
),
|
|
4360
|
-
linkToolbar && (linkPreview?.apiEndpoint ? /* @__PURE__ */ (0,
|
|
4361
|
-
/* @__PURE__ */ (0,
|
|
4362
|
-
|
|
5429
|
+
linkToolbar && (linkPreview?.apiEndpoint ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react35.LinkToolbarController, { linkToolbar: CustomLinkToolbar }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react35.LinkToolbarController, {})),
|
|
5430
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5431
|
+
import_react35.SuggestionMenuController,
|
|
4363
5432
|
{
|
|
4364
5433
|
triggerCharacter: "/",
|
|
4365
|
-
getItems: (0,
|
|
5434
|
+
getItems: (0, import_react34.useCallback)(
|
|
4366
5435
|
async (query) => {
|
|
4367
|
-
const items = (0,
|
|
5436
|
+
const items = (0, import_react35.getDefaultReactSlashMenuItems)(editor);
|
|
4368
5437
|
const filtered = items.filter((item) => {
|
|
4369
5438
|
const key = (item?.key || "").toString().toLowerCase();
|
|
4370
5439
|
const title = (item?.title || "").toString().toLowerCase();
|
|
@@ -4406,7 +5475,7 @@ function LumirEditor({
|
|
|
4406
5475
|
},
|
|
4407
5476
|
aliases: ["html", "preview", "\uC6F9", "\uC6F9\uD398\uC774\uC9C0"],
|
|
4408
5477
|
group: "Embeds",
|
|
4409
|
-
icon: /* @__PURE__ */ (0,
|
|
5478
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
4410
5479
|
"svg",
|
|
4411
5480
|
{
|
|
4412
5481
|
width: "18",
|
|
@@ -4418,8 +5487,8 @@ function LumirEditor({
|
|
|
4418
5487
|
strokeLinecap: "round",
|
|
4419
5488
|
strokeLinejoin: "round",
|
|
4420
5489
|
children: [
|
|
4421
|
-
/* @__PURE__ */ (0,
|
|
4422
|
-
/* @__PURE__ */ (0,
|
|
5490
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("polyline", { points: "16 18 22 12 16 6" }),
|
|
5491
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("polyline", { points: "8 6 2 12 8 18" })
|
|
4423
5492
|
]
|
|
4424
5493
|
}
|
|
4425
5494
|
),
|
|
@@ -4430,7 +5499,7 @@ function LumirEditor({
|
|
|
4430
5499
|
allItems.push({
|
|
4431
5500
|
title: "Link Preview",
|
|
4432
5501
|
onItemClick: () => {
|
|
4433
|
-
(0,
|
|
5502
|
+
(0, import_core5.insertOrUpdateBlock)(editor, {
|
|
4434
5503
|
type: "linkPreview",
|
|
4435
5504
|
props: { url: "" }
|
|
4436
5505
|
});
|
|
@@ -4444,7 +5513,7 @@ function LumirEditor({
|
|
|
4444
5513
|
"\uD504\uB9AC\uBDF0"
|
|
4445
5514
|
],
|
|
4446
5515
|
group: "Embeds",
|
|
4447
|
-
icon: /* @__PURE__ */ (0,
|
|
5516
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
4448
5517
|
"svg",
|
|
4449
5518
|
{
|
|
4450
5519
|
width: "18",
|
|
@@ -4456,14 +5525,31 @@ function LumirEditor({
|
|
|
4456
5525
|
strokeLinecap: "round",
|
|
4457
5526
|
strokeLinejoin: "round",
|
|
4458
5527
|
children: [
|
|
4459
|
-
/* @__PURE__ */ (0,
|
|
4460
|
-
/* @__PURE__ */ (0,
|
|
5528
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.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" }),
|
|
5529
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.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" })
|
|
4461
5530
|
]
|
|
4462
5531
|
}
|
|
4463
5532
|
),
|
|
4464
5533
|
subtext: "URL\uC758 \uBBF8\uB9AC\uBCF4\uAE30 \uCE74\uB4DC\uB97C \uC0BD\uC785"
|
|
4465
5534
|
});
|
|
4466
5535
|
}
|
|
5536
|
+
const enSlash = import_locales.en.slash_menu;
|
|
5537
|
+
for (const it of allItems) {
|
|
5538
|
+
const enEntry = it.key ? enSlash[it.key] : void 0;
|
|
5539
|
+
if (!enEntry) continue;
|
|
5540
|
+
const extra = [...enEntry.aliases ?? [], enEntry.title].filter((s) => Boolean(s)).map((s) => s.toLowerCase());
|
|
5541
|
+
it.aliases = Array.from(
|
|
5542
|
+
/* @__PURE__ */ new Set([...it.aliases ?? [], ...extra])
|
|
5543
|
+
);
|
|
5544
|
+
}
|
|
5545
|
+
const groupOrder = [];
|
|
5546
|
+
for (const it of allItems) {
|
|
5547
|
+
const g = it.group ?? "";
|
|
5548
|
+
if (!groupOrder.includes(g)) groupOrder.push(g);
|
|
5549
|
+
}
|
|
5550
|
+
allItems.sort(
|
|
5551
|
+
(a, b) => groupOrder.indexOf(a.group ?? "") - groupOrder.indexOf(b.group ?? "")
|
|
5552
|
+
);
|
|
4467
5553
|
if (!query) return allItems;
|
|
4468
5554
|
const q = query.toLowerCase();
|
|
4469
5555
|
return allItems.filter(
|
|
@@ -4476,21 +5562,21 @@ function LumirEditor({
|
|
|
4476
5562
|
)
|
|
4477
5563
|
}
|
|
4478
5564
|
),
|
|
4479
|
-
!sideMenuAddButton && /* @__PURE__ */ (0,
|
|
5565
|
+
!sideMenuAddButton && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react35.SideMenuController, { sideMenu: DragHandleOnlySideMenu })
|
|
4480
5566
|
]
|
|
4481
5567
|
}
|
|
4482
5568
|
),
|
|
4483
|
-
isUploading && /* @__PURE__ */ (0,
|
|
4484
|
-
/* @__PURE__ */ (0,
|
|
4485
|
-
uploadProgress !== null && /* @__PURE__ */ (0,
|
|
5569
|
+
isUploading && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "lumirEditor-upload-overlay", children: [
|
|
5570
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "lumirEditor-spinner" }),
|
|
5571
|
+
uploadProgress !== null && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "lumirEditor-upload-progress", children: [
|
|
4486
5572
|
uploadProgress,
|
|
4487
5573
|
"%"
|
|
4488
5574
|
] })
|
|
4489
5575
|
] }),
|
|
4490
|
-
errorMessage && /* @__PURE__ */ (0,
|
|
4491
|
-
/* @__PURE__ */ (0,
|
|
4492
|
-
/* @__PURE__ */ (0,
|
|
4493
|
-
/* @__PURE__ */ (0,
|
|
5576
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "lumirEditor-error-toast", children: [
|
|
5577
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "lumirEditor-error-icon", children: "\u26A0\uFE0F" }),
|
|
5578
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "lumirEditor-error-message", children: errorMessage }),
|
|
5579
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4494
5580
|
"button",
|
|
4495
5581
|
{
|
|
4496
5582
|
className: "lumirEditor-error-close",
|
|
@@ -4509,7 +5595,10 @@ function LumirEditor({
|
|
|
4509
5595
|
BACKGROUND_COLORS,
|
|
4510
5596
|
ContentUtils,
|
|
4511
5597
|
EditorConfig,
|
|
5598
|
+
FONT_SIZE_PRESETS,
|
|
4512
5599
|
FloatingMenu,
|
|
5600
|
+
FontSize,
|
|
5601
|
+
FontSizeButton,
|
|
4513
5602
|
HtmlPreviewBlock,
|
|
4514
5603
|
HtmlPreviewSchema,
|
|
4515
5604
|
LinkPreviewBlock,
|
|
@@ -4520,6 +5609,8 @@ function LumirEditor({
|
|
|
4520
5609
|
cn,
|
|
4521
5610
|
createS3Uploader,
|
|
4522
5611
|
fetchLinkMetadata,
|
|
4523
|
-
getHexFromColorValue
|
|
5612
|
+
getHexFromColorValue,
|
|
5613
|
+
liftFontSize,
|
|
5614
|
+
lowerFontSize
|
|
4524
5615
|
});
|
|
4525
5616
|
//# sourceMappingURL=index.js.map
|