@underverse-ui/underverse 1.0.75 → 1.0.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -889,6 +889,17 @@ var en_default = {
889
889
  undo: "Undo (Ctrl+Z)",
890
890
  redo: "Redo (Ctrl+Y)",
891
891
  textStyle: "Text Style",
892
+ fontFamily: "Font Family",
893
+ fontSize: "Font Size",
894
+ lineHeight: "Line Height",
895
+ fontDefault: "Default Font",
896
+ sizeDefault: "Default Size",
897
+ lineHeightDefault: "Default Leading",
898
+ letterSpacing: "Letter Spacing",
899
+ letterSpacingDefault: "Default Tracking",
900
+ fontSans: "Sans",
901
+ fontSerif: "Serif",
902
+ fontMono: "Mono",
892
903
  normal: "Normal text",
893
904
  heading1: "Heading 1",
894
905
  heading2: "Heading 2",
@@ -962,6 +973,8 @@ var en_default = {
962
973
  },
963
974
  tableMenu: {
964
975
  insert3x3: "Insert 3\xD73 Table",
976
+ insertTable: "Insert Table",
977
+ gridPreview: "Insert {rows}\xD7{cols} Table",
965
978
  addColumnBefore: "Add Column Before",
966
979
  addColumnAfter: "Add Column After",
967
980
  addRowBefore: "Add Row Before",
@@ -980,7 +993,10 @@ var en_default = {
980
993
  quickAddRowAfter: "Quick Add Row After",
981
994
  expandTable: "Expand Table",
982
995
  dragRow: "Drag Row",
983
- dragColumn: "Drag Column"
996
+ dragColumn: "Drag Column",
997
+ alignLeft: "Align Table Left",
998
+ alignCenter: "Align Table Center",
999
+ alignRight: "Align Table Right"
984
1000
  }
985
1001
  }
986
1002
  };
@@ -1138,6 +1154,17 @@ var vi_default = {
1138
1154
  undo: "Ho\xE0n t\xE1c (Ctrl+Z)",
1139
1155
  redo: "L\xE0m l\u1EA1i (Ctrl+Y)",
1140
1156
  textStyle: "Ki\u1EC3u ch\u1EEF",
1157
+ fontFamily: "Ph\xF4ng ch\u1EEF",
1158
+ fontSize: "C\u1EE1 ch\u1EEF",
1159
+ lineHeight: "Gi\xE3n d\xF2ng",
1160
+ fontDefault: "Ph\xF4ng m\u1EB7c \u0111\u1ECBnh",
1161
+ sizeDefault: "C\u1EE1 m\u1EB7c \u0111\u1ECBnh",
1162
+ lineHeightDefault: "Gi\xE3n d\xF2ng m\u1EB7c \u0111\u1ECBnh",
1163
+ letterSpacing: "Gi\xE3n ch\u1EEF",
1164
+ letterSpacingDefault: "Gi\xE3n ch\u1EEF m\u1EB7c \u0111\u1ECBnh",
1165
+ fontSans: "Sans",
1166
+ fontSerif: "Serif",
1167
+ fontMono: "Mono",
1141
1168
  normal: "V\u0103n b\u1EA3n th\u01B0\u1EDDng",
1142
1169
  heading1: "Ti\xEAu \u0111\u1EC1 1",
1143
1170
  heading2: "Ti\xEAu \u0111\u1EC1 2",
@@ -1211,6 +1238,8 @@ var vi_default = {
1211
1238
  },
1212
1239
  tableMenu: {
1213
1240
  insert3x3: "Ch\xE8n b\u1EA3ng 3\xD73",
1241
+ insertTable: "Ch\xE8n b\u1EA3ng",
1242
+ gridPreview: "Ch\xE8n b\u1EA3ng {rows}\xD7{cols}",
1214
1243
  addColumnBefore: "Th\xEAm c\u1ED9t tr\u01B0\u1EDBc",
1215
1244
  addColumnAfter: "Th\xEAm c\u1ED9t sau",
1216
1245
  addRowBefore: "Th\xEAm h\xE0ng tr\u01B0\u1EDBc",
@@ -1229,7 +1258,10 @@ var vi_default = {
1229
1258
  quickAddRowAfter: "Th\xEAm nhanh h\xE0ng sau",
1230
1259
  expandTable: "M\u1EDF r\u1ED9ng b\u1EA3ng",
1231
1260
  dragRow: "K\xE9o h\xE0ng",
1232
- dragColumn: "K\xE9o c\u1ED9t"
1261
+ dragColumn: "K\xE9o c\u1ED9t",
1262
+ alignLeft: "C\u0103n b\u1EA3ng tr\xE1i",
1263
+ alignCenter: "C\u0103n b\u1EA3ng gi\u1EEFa",
1264
+ alignRight: "C\u0103n b\u1EA3ng ph\u1EA3i"
1233
1265
  }
1234
1266
  }
1235
1267
  };
@@ -1387,6 +1419,17 @@ var ko_default = {
1387
1419
  undo: "\uC2E4\uD589 \uCDE8\uC18C",
1388
1420
  redo: "\uB2E4\uC2DC \uC2E4\uD589",
1389
1421
  textStyle: "\uD14D\uC2A4\uD2B8 \uC2A4\uD0C0\uC77C",
1422
+ fontFamily: "\uAE00\uAF34",
1423
+ fontSize: "\uAE00\uC790 \uD06C\uAE30",
1424
+ lineHeight: "\uC904 \uAC04\uACA9",
1425
+ fontDefault: "\uAE30\uBCF8 \uAE00\uAF34",
1426
+ sizeDefault: "\uAE30\uBCF8 \uD06C\uAE30",
1427
+ lineHeightDefault: "\uAE30\uBCF8 \uC904 \uAC04\uACA9",
1428
+ letterSpacing: "\uC790\uAC04",
1429
+ letterSpacingDefault: "\uAE30\uBCF8 \uC790\uAC04",
1430
+ fontSans: "Sans",
1431
+ fontSerif: "Serif",
1432
+ fontMono: "Mono",
1390
1433
  normal: "\uC77C\uBC18 \uD14D\uC2A4\uD2B8",
1391
1434
  heading1: "\uC81C\uBAA9 1",
1392
1435
  heading2: "\uC81C\uBAA9 2",
@@ -1459,6 +1502,8 @@ var ko_default = {
1459
1502
  },
1460
1503
  tableMenu: {
1461
1504
  insert3x3: "3x3 \uD45C \uC0BD\uC785",
1505
+ insertTable: "\uD45C \uC0BD\uC785",
1506
+ gridPreview: "{rows}\xD7{cols} \uD45C \uC0BD\uC785",
1462
1507
  addColumnBefore: "\uC55E\uC5D0 \uC5F4 \uCD94\uAC00",
1463
1508
  addColumnAfter: "\uB4A4\uC5D0 \uC5F4 \uCD94\uAC00",
1464
1509
  addRowBefore: "\uC704\uC5D0 \uD589 \uCD94\uAC00",
@@ -1477,7 +1522,10 @@ var ko_default = {
1477
1522
  quickAddRowAfter: "\uC544\uB798 \uD589 \uBE60\uB974\uAC8C \uCD94\uAC00",
1478
1523
  expandTable: "\uD45C \uD655\uC7A5",
1479
1524
  dragRow: "\uD589 \uB4DC\uB798\uADF8",
1480
- dragColumn: "\uC5F4 \uB4DC\uB798\uADF8"
1525
+ dragColumn: "\uC5F4 \uB4DC\uB798\uADF8",
1526
+ alignLeft: "\uD45C \uC67C\uCABD \uC815\uB82C",
1527
+ alignCenter: "\uD45C \uAC00\uC6B4\uB370 \uC815\uB82C",
1528
+ alignRight: "\uD45C \uC624\uB978\uCABD \uC815\uB82C"
1481
1529
  }
1482
1530
  }
1483
1531
  };
@@ -1635,6 +1683,17 @@ var ja_default = {
1635
1683
  undo: "\u5143\u306B\u623B\u3059",
1636
1684
  redo: "\u3084\u308A\u76F4\u3057",
1637
1685
  textStyle: "\u30C6\u30AD\u30B9\u30C8\u30B9\u30BF\u30A4\u30EB",
1686
+ fontFamily: "\u30D5\u30A9\u30F3\u30C8",
1687
+ fontSize: "\u6587\u5B57\u30B5\u30A4\u30BA",
1688
+ lineHeight: "\u884C\u9593",
1689
+ fontDefault: "\u6A19\u6E96\u30D5\u30A9\u30F3\u30C8",
1690
+ sizeDefault: "\u6A19\u6E96\u30B5\u30A4\u30BA",
1691
+ lineHeightDefault: "\u6A19\u6E96\u306E\u884C\u9593",
1692
+ letterSpacing: "\u6587\u5B57\u9593\u9694",
1693
+ letterSpacingDefault: "\u6A19\u6E96\u306E\u5B57\u9593",
1694
+ fontSans: "Sans",
1695
+ fontSerif: "Serif",
1696
+ fontMono: "Mono",
1638
1697
  normal: "\u6A19\u6E96\u30C6\u30AD\u30B9\u30C8",
1639
1698
  heading1: "\u898B\u51FA\u3057 1",
1640
1699
  heading2: "\u898B\u51FA\u3057 2",
@@ -1707,6 +1766,8 @@ var ja_default = {
1707
1766
  },
1708
1767
  tableMenu: {
1709
1768
  insert3x3: "3x3 \u8868\u3092\u633F\u5165",
1769
+ insertTable: "\u8868\u3092\u633F\u5165",
1770
+ gridPreview: "{rows}\xD7{cols} \u306E\u8868\u3092\u633F\u5165",
1710
1771
  addColumnBefore: "\u524D\u306B\u5217\u3092\u8FFD\u52A0",
1711
1772
  addColumnAfter: "\u5F8C\u306B\u5217\u3092\u8FFD\u52A0",
1712
1773
  addRowBefore: "\u524D\u306B\u884C\u3092\u8FFD\u52A0",
@@ -1725,7 +1786,10 @@ var ja_default = {
1725
1786
  quickAddRowAfter: "\u4E0B\u306B\u884C\u3092\u3059\u3070\u3084\u304F\u8FFD\u52A0",
1726
1787
  expandTable: "\u8868\u3092\u62E1\u5F35",
1727
1788
  dragRow: "\u884C\u3092\u30C9\u30E9\u30C3\u30B0",
1728
- dragColumn: "\u5217\u3092\u30C9\u30E9\u30C3\u30B0"
1789
+ dragColumn: "\u5217\u3092\u30C9\u30E9\u30C3\u30B0",
1790
+ alignLeft: "\u8868\u3092\u5DE6\u5BC4\u305B",
1791
+ alignCenter: "\u8868\u3092\u4E2D\u592E\u63C3\u3048",
1792
+ alignRight: "\u8868\u3092\u53F3\u5BC4\u305B"
1729
1793
  }
1730
1794
  }
1731
1795
  };
@@ -22190,7 +22254,6 @@ var import_extension_text_style = require("@tiptap/extension-text-style");
22190
22254
  var import_extension_color = __toESM(require("@tiptap/extension-color"), 1);
22191
22255
  var import_extension_highlight = __toESM(require("@tiptap/extension-highlight"), 1);
22192
22256
  var import_extension_text_align = __toESM(require("@tiptap/extension-text-align"), 1);
22193
- var import_extension_table = require("@tiptap/extension-table");
22194
22257
  var import_extension_table_cell = __toESM(require("@tiptap/extension-table-cell"), 1);
22195
22258
  var import_extension_table_header = __toESM(require("@tiptap/extension-table-header"), 1);
22196
22259
  var import_extension_character_count = __toESM(require("@tiptap/extension-character-count"), 1);
@@ -23158,6 +23221,283 @@ var UEditorTableRow = import_extension_table_row.default.extend({
23158
23221
  });
23159
23222
  var table_row_default = UEditorTableRow;
23160
23223
 
23224
+ // src/components/UEditor/font-family.ts
23225
+ var import_core6 = require("@tiptap/core");
23226
+ var FontFamily = import_core6.Extension.create({
23227
+ name: "fontFamily",
23228
+ addOptions() {
23229
+ return {
23230
+ types: ["textStyle"]
23231
+ };
23232
+ },
23233
+ addGlobalAttributes() {
23234
+ return [
23235
+ {
23236
+ types: this.options.types,
23237
+ attributes: {
23238
+ fontFamily: {
23239
+ default: null,
23240
+ parseHTML: (element) => element.style.fontFamily || null,
23241
+ renderHTML: (attributes) => {
23242
+ const fontFamily = typeof attributes.fontFamily === "string" ? attributes.fontFamily.trim() : "";
23243
+ if (!fontFamily) return {};
23244
+ return { style: `font-family: ${fontFamily}` };
23245
+ }
23246
+ }
23247
+ }
23248
+ }
23249
+ ];
23250
+ },
23251
+ addCommands() {
23252
+ return {
23253
+ setFontFamily: (fontFamily) => ({ chain }) => chain().setMark("textStyle", { fontFamily }).run(),
23254
+ unsetFontFamily: () => ({ chain }) => chain().setMark("textStyle", { fontFamily: null }).removeEmptyTextStyle().run()
23255
+ };
23256
+ }
23257
+ });
23258
+ var font_family_default = FontFamily;
23259
+
23260
+ // src/components/UEditor/font-size.ts
23261
+ var import_core7 = require("@tiptap/core");
23262
+ var FontSize = import_core7.Extension.create({
23263
+ name: "fontSize",
23264
+ addOptions() {
23265
+ return {
23266
+ types: ["textStyle"]
23267
+ };
23268
+ },
23269
+ addGlobalAttributes() {
23270
+ return [
23271
+ {
23272
+ types: this.options.types,
23273
+ attributes: {
23274
+ fontSize: {
23275
+ default: null,
23276
+ parseHTML: (element) => element.style.fontSize || null,
23277
+ renderHTML: (attributes) => {
23278
+ const fontSize = typeof attributes.fontSize === "string" ? attributes.fontSize.trim() : "";
23279
+ if (!fontSize) return {};
23280
+ return { style: `font-size: ${fontSize}` };
23281
+ }
23282
+ }
23283
+ }
23284
+ }
23285
+ ];
23286
+ },
23287
+ addCommands() {
23288
+ return {
23289
+ setFontSize: (fontSize) => ({ chain }) => chain().setMark("textStyle", { fontSize }).run(),
23290
+ unsetFontSize: () => ({ chain }) => chain().setMark("textStyle", { fontSize: null }).removeEmptyTextStyle().run()
23291
+ };
23292
+ }
23293
+ });
23294
+ var font_size_default = FontSize;
23295
+
23296
+ // src/components/UEditor/line-height.ts
23297
+ var import_core8 = require("@tiptap/core");
23298
+ var LineHeight = import_core8.Extension.create({
23299
+ name: "lineHeight",
23300
+ addOptions() {
23301
+ return {
23302
+ types: ["textStyle"]
23303
+ };
23304
+ },
23305
+ addGlobalAttributes() {
23306
+ return [
23307
+ {
23308
+ types: this.options.types,
23309
+ attributes: {
23310
+ lineHeight: {
23311
+ default: null,
23312
+ parseHTML: (element) => element.style.lineHeight || null,
23313
+ renderHTML: (attributes) => {
23314
+ const lineHeight = typeof attributes.lineHeight === "string" ? attributes.lineHeight.trim() : "";
23315
+ if (!lineHeight) return {};
23316
+ return { style: `line-height: ${lineHeight}` };
23317
+ }
23318
+ }
23319
+ }
23320
+ }
23321
+ ];
23322
+ },
23323
+ addCommands() {
23324
+ return {
23325
+ setLineHeight: (lineHeight) => ({ chain }) => chain().setMark("textStyle", { lineHeight }).run(),
23326
+ unsetLineHeight: () => ({ chain }) => chain().setMark("textStyle", { lineHeight: null }).removeEmptyTextStyle().run()
23327
+ };
23328
+ }
23329
+ });
23330
+ var line_height_default = LineHeight;
23331
+
23332
+ // src/components/UEditor/letter-spacing.ts
23333
+ var import_core9 = require("@tiptap/core");
23334
+ var LetterSpacing = import_core9.Extension.create({
23335
+ name: "letterSpacing",
23336
+ addOptions() {
23337
+ return {
23338
+ types: ["textStyle"]
23339
+ };
23340
+ },
23341
+ addGlobalAttributes() {
23342
+ return [
23343
+ {
23344
+ types: this.options.types,
23345
+ attributes: {
23346
+ letterSpacing: {
23347
+ default: null,
23348
+ parseHTML: (element) => element.style.letterSpacing || null,
23349
+ renderHTML: (attributes) => {
23350
+ const letterSpacing = typeof attributes.letterSpacing === "string" ? attributes.letterSpacing.trim() : "";
23351
+ if (!letterSpacing) return {};
23352
+ return { style: `letter-spacing: ${letterSpacing}` };
23353
+ }
23354
+ }
23355
+ }
23356
+ }
23357
+ ];
23358
+ },
23359
+ addCommands() {
23360
+ return {
23361
+ setLetterSpacing: (letterSpacing) => ({ chain }) => chain().setMark("textStyle", { letterSpacing }).run(),
23362
+ unsetLetterSpacing: () => ({ chain }) => chain().setMark("textStyle", { letterSpacing: null }).removeEmptyTextStyle().run()
23363
+ };
23364
+ }
23365
+ });
23366
+ var letter_spacing_default = LetterSpacing;
23367
+
23368
+ // src/components/UEditor/table-align.ts
23369
+ var import_extension_table = require("@tiptap/extension-table");
23370
+
23371
+ // src/components/UEditor/table-align-utils.ts
23372
+ function findTableNodeInfoAtResolvedPos($pos) {
23373
+ for (let depth = $pos.depth; depth > 0; depth -= 1) {
23374
+ const node = $pos.node(depth);
23375
+ if (node.type.name === "table") {
23376
+ return {
23377
+ depth,
23378
+ pos: $pos.before(depth),
23379
+ node
23380
+ };
23381
+ }
23382
+ }
23383
+ return null;
23384
+ }
23385
+ function findTableNodeInfoFromState(state, anchorPos) {
23386
+ if (typeof anchorPos === "number" && Number.isFinite(anchorPos)) {
23387
+ const safePos = Math.max(0, Math.min(anchorPos, state.doc.content.size));
23388
+ return findTableNodeInfoAtResolvedPos(state.doc.resolve(safePos));
23389
+ }
23390
+ return findTableNodeInfoAtResolvedPos(state.selection.$from);
23391
+ }
23392
+ function applyTableAlignment(editor, tableAlign, anchorPos) {
23393
+ const tableInfo = findTableNodeInfoFromState(editor.state, anchorPos);
23394
+ if (!tableInfo) return false;
23395
+ editor.view.dispatch(
23396
+ editor.state.tr.setNodeMarkup(tableInfo.pos, tableInfo.node.type, {
23397
+ ...tableInfo.node.attrs,
23398
+ tableAlign
23399
+ })
23400
+ );
23401
+ const tableDom = editor.view.nodeDOM(tableInfo.pos);
23402
+ const tableElement = tableDom instanceof HTMLTableElement ? tableDom : tableDom instanceof HTMLElement ? tableDom.querySelector("table") : null;
23403
+ if (tableElement instanceof HTMLTableElement) {
23404
+ if (tableAlign) {
23405
+ tableElement.setAttribute("data-table-align", tableAlign);
23406
+ tableElement.style.width = "max-content";
23407
+ tableElement.style.maxWidth = "100%";
23408
+ tableElement.style.marginLeft = tableAlign === "center" || tableAlign === "right" ? "auto" : "0";
23409
+ tableElement.style.marginRight = tableAlign === "center" ? "auto" : tableAlign === "right" ? "0" : "auto";
23410
+ } else {
23411
+ tableElement.removeAttribute("data-table-align");
23412
+ tableElement.style.removeProperty("width");
23413
+ tableElement.style.removeProperty("max-width");
23414
+ tableElement.style.removeProperty("margin-left");
23415
+ tableElement.style.removeProperty("margin-right");
23416
+ }
23417
+ }
23418
+ return true;
23419
+ }
23420
+
23421
+ // src/components/UEditor/table-align.ts
23422
+ function normalizeTableAlign(value) {
23423
+ if (value === "left" || value === "center" || value === "right") {
23424
+ return value;
23425
+ }
23426
+ return null;
23427
+ }
23428
+ function parseTableAlign(element) {
23429
+ const dataAlign = normalizeTableAlign(element.getAttribute("data-table-align"));
23430
+ if (dataAlign) return dataAlign;
23431
+ const marginLeft = element.style.marginLeft?.trim();
23432
+ const marginRight = element.style.marginRight?.trim();
23433
+ if (marginLeft === "auto" && marginRight === "auto") return "center";
23434
+ if (marginLeft === "auto" && (marginRight === "0px" || marginRight === "0")) return "right";
23435
+ if ((marginLeft === "0px" || marginLeft === "0") && marginRight === "auto") return "left";
23436
+ return null;
23437
+ }
23438
+ function renderTableAlignStyle(tableAlign) {
23439
+ switch (tableAlign) {
23440
+ case "center":
23441
+ return "width: max-content; max-width: 100%; margin-left: auto; margin-right: auto;";
23442
+ case "right":
23443
+ return "width: max-content; max-width: 100%; margin-left: auto; margin-right: 0;";
23444
+ case "left":
23445
+ return "width: max-content; max-width: 100%; margin-left: 0; margin-right: auto;";
23446
+ default:
23447
+ return "";
23448
+ }
23449
+ }
23450
+ var UEditorTable = import_extension_table.Table.extend({
23451
+ addAttributes() {
23452
+ return {
23453
+ ...this.parent?.(),
23454
+ tableAlign: {
23455
+ default: null,
23456
+ parseHTML: (element) => {
23457
+ if (!(element instanceof HTMLElement)) return null;
23458
+ return parseTableAlign(element);
23459
+ },
23460
+ renderHTML: (attributes) => {
23461
+ const tableAlign = normalizeTableAlign(attributes.tableAlign);
23462
+ if (!tableAlign) return {};
23463
+ return {
23464
+ "data-table-align": tableAlign,
23465
+ style: renderTableAlignStyle(tableAlign)
23466
+ };
23467
+ }
23468
+ }
23469
+ };
23470
+ },
23471
+ addCommands() {
23472
+ return {
23473
+ ...this.parent?.(),
23474
+ setTableAlign: (tableAlign) => ({ state, dispatch }) => {
23475
+ const tableInfo = findTableNodeInfoFromState(state);
23476
+ if (!tableInfo) return false;
23477
+ dispatch?.(
23478
+ state.tr.setNodeMarkup(tableInfo.pos, tableInfo.node.type, {
23479
+ ...tableInfo.node.attrs,
23480
+ tableAlign
23481
+ })
23482
+ );
23483
+ return true;
23484
+ },
23485
+ unsetTableAlign: () => ({ state, dispatch }) => {
23486
+ const tableInfo = findTableNodeInfoFromState(state);
23487
+ if (!tableInfo) return false;
23488
+ dispatch?.(
23489
+ state.tr.setNodeMarkup(tableInfo.pos, tableInfo.node.type, {
23490
+ ...tableInfo.node.attrs,
23491
+ tableAlign: null
23492
+ })
23493
+ );
23494
+ return true;
23495
+ }
23496
+ };
23497
+ }
23498
+ });
23499
+ var table_align_default = UEditorTable;
23500
+
23161
23501
  // src/components/UEditor/extensions.ts
23162
23502
  var lowlight = (0, import_lowlight.createLowlight)(import_lowlight.common);
23163
23503
  function buildUEditorExtensions({
@@ -23213,7 +23553,7 @@ function buildUEditorExtensions({
23213
23553
  import_extension_code_block_lowlight.default.configure({
23214
23554
  lowlight,
23215
23555
  HTMLAttributes: {
23216
- class: "rounded-lg bg-[#1e1e1e] p-4 font-mono text-sm overflow-x-auto"
23556
+ class: "rounded-lg border border-border/60 bg-muted/40 text-foreground p-4 font-mono text-sm overflow-x-auto"
23217
23557
  }
23218
23558
  }),
23219
23559
  import_extension_horizontal_rule.default,
@@ -23226,6 +23566,10 @@ function buildUEditorExtensions({
23226
23566
  resizable_image_default,
23227
23567
  ClipboardImages.configure({ upload: uploadImage, insertMode: imageInsertMode }),
23228
23568
  import_extension_text_style.TextStyle,
23569
+ font_family_default,
23570
+ font_size_default,
23571
+ line_height_default,
23572
+ letter_spacing_default,
23229
23573
  import_extension_color.default,
23230
23574
  import_extension_highlight.default.configure({
23231
23575
  multicolor: true
@@ -23233,7 +23577,7 @@ function buildUEditorExtensions({
23233
23577
  import_extension_text_align.default.configure({
23234
23578
  types: ["heading", "paragraph", "image"]
23235
23579
  }),
23236
- import_extension_table.Table.configure({
23580
+ table_align_default.configure({
23237
23581
  resizable: true,
23238
23582
  handleWidth: 10,
23239
23583
  allowTableNodeSelection: true,
@@ -23541,6 +23885,48 @@ var EmojiPicker2 = ({ onSelect }) => {
23541
23885
  return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(EmojiPicker, { onEmojiSelect: onSelect });
23542
23886
  };
23543
23887
 
23888
+ // src/components/UEditor/typography-options.ts
23889
+ function normalizeStyleValue(value) {
23890
+ return typeof value === "string" ? value.trim().replace(/^['"]|['"]$/g, "") : "";
23891
+ }
23892
+ function getDefaultFontFamilies(t) {
23893
+ return [
23894
+ { label: "Inter", value: "Inter, ui-sans-serif, system-ui, sans-serif" },
23895
+ { label: "System UI", value: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif" },
23896
+ { label: "Georgia", value: "Georgia, 'Times New Roman', serif" },
23897
+ { label: "Palatino", value: "'Palatino Linotype', Palatino, Georgia, serif" },
23898
+ { label: "Times", value: "'Times New Roman', Times, serif" },
23899
+ { label: "JetBrains Mono", value: "'JetBrains Mono', 'Fira Code', 'SFMono-Regular', Consolas, monospace" }
23900
+ ];
23901
+ }
23902
+ function getDefaultFontSizes() {
23903
+ return [
23904
+ { label: "12", value: "12px" },
23905
+ { label: "14", value: "14px" },
23906
+ { label: "16", value: "16px" },
23907
+ { label: "18", value: "18px" },
23908
+ { label: "24", value: "24px" },
23909
+ { label: "32", value: "32px" }
23910
+ ];
23911
+ }
23912
+ function getDefaultLineHeights() {
23913
+ return [
23914
+ { label: "1.2", value: "1.2" },
23915
+ { label: "1.5", value: "1.5" },
23916
+ { label: "1.75", value: "1.75" },
23917
+ { label: "2", value: "2" }
23918
+ ];
23919
+ }
23920
+ function getDefaultLetterSpacings() {
23921
+ return [
23922
+ { label: "-0.02em", value: "-0.02em" },
23923
+ { label: "0", value: "0" },
23924
+ { label: "0.02em", value: "0.02em" },
23925
+ { label: "0.05em", value: "0.05em" },
23926
+ { label: "0.08em", value: "0.08em" }
23927
+ ];
23928
+ }
23929
+
23544
23930
  // src/components/UEditor/toolbar.tsx
23545
23931
  var import_jsx_runtime80 = require("react/jsx-runtime");
23546
23932
  function fileToDataUrl2(file) {
@@ -23551,12 +23937,16 @@ function fileToDataUrl2(file) {
23551
23937
  reader.readAsDataURL(file);
23552
23938
  });
23553
23939
  }
23940
+ function formatTableInsertLabel(template, rows, cols) {
23941
+ return template.replace("{rows}", String(rows)).replace("{cols}", String(cols));
23942
+ }
23554
23943
  var ToolbarButton = import_react49.default.forwardRef(({ onClick, onMouseDown, active, disabled, children, title, className }, ref) => {
23555
23944
  const button = /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
23556
23945
  "button",
23557
23946
  {
23558
23947
  ref,
23559
23948
  type: "button",
23949
+ "aria-label": title,
23560
23950
  onMouseDown: (e) => {
23561
23951
  onMouseDown?.(e);
23562
23952
  e.preventDefault();
@@ -23581,22 +23971,115 @@ var ToolbarButton = import_react49.default.forwardRef(({ onClick, onMouseDown, a
23581
23971
  });
23582
23972
  ToolbarButton.displayName = "ToolbarButton";
23583
23973
  var ToolbarDivider = () => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" });
23974
+ var TableInsertGrid = ({
23975
+ insertLabel,
23976
+ previewTemplate,
23977
+ onInsert
23978
+ }) => {
23979
+ const [selection, setSelection] = import_react49.default.useState({ rows: 3, cols: 3 });
23980
+ const maxRows = 8;
23981
+ const maxCols = 8;
23982
+ return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "mb-2 rounded-xl border border-border/60 bg-muted/20 p-2", children: [
23983
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "mb-2 text-sm font-medium text-foreground", children: formatTableInsertLabel(previewTemplate, selection.rows, selection.cols) }),
23984
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
23985
+ "div",
23986
+ {
23987
+ className: "grid grid-cols-8 gap-1",
23988
+ onMouseLeave: () => setSelection((prev) => prev),
23989
+ children: Array.from({ length: maxRows }).map(
23990
+ (_, rowIndex) => Array.from({ length: maxCols }).map((__, colIndex) => {
23991
+ const rows = rowIndex + 1;
23992
+ const cols = colIndex + 1;
23993
+ const active = rows <= selection.rows && cols <= selection.cols;
23994
+ return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
23995
+ "button",
23996
+ {
23997
+ type: "button",
23998
+ "aria-label": formatTableInsertLabel(previewTemplate, rows, cols),
23999
+ onMouseDown: (e) => e.preventDefault(),
24000
+ onMouseEnter: () => setSelection({ rows, cols }),
24001
+ onFocus: () => setSelection({ rows, cols }),
24002
+ onClick: () => onInsert(rows, cols),
24003
+ className: cn(
24004
+ "h-5 w-5 rounded-[4px] border transition-colors",
24005
+ active ? "border-primary bg-primary/20" : "border-border/70 bg-background hover:border-primary/60 hover:bg-primary/10"
24006
+ )
24007
+ },
24008
+ `${rows}-${cols}`
24009
+ );
24010
+ })
24011
+ )
24012
+ }
24013
+ ),
24014
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "mt-2 text-xs text-muted-foreground", children: insertLabel })
24015
+ ] });
24016
+ };
23584
24017
  var EditorToolbar = ({
23585
24018
  editor,
23586
24019
  variant,
23587
24020
  uploadImage,
23588
- imageInsertMode = "base64"
24021
+ imageInsertMode = "base64",
24022
+ fontFamilies,
24023
+ fontSizes,
24024
+ lineHeights,
24025
+ letterSpacings
23589
24026
  }) => {
23590
24027
  const t = useSmartTranslations("UEditor");
23591
24028
  const { textColors, highlightColors } = useEditorColors();
23592
24029
  const [showImageInput, setShowImageInput] = (0, import_react49.useState)(false);
24030
+ const [isTableMenuOpen, setIsTableMenuOpen] = (0, import_react49.useState)(false);
24031
+ const tableCommandAnchorPosRef = (0, import_react49.useRef)(null);
23593
24032
  const fileInputRef = (0, import_react49.useRef)(null);
23594
24033
  const [isUploadingImage, setIsUploadingImage] = (0, import_react49.useState)(false);
23595
24034
  const [imageUploadError, setImageUploadError] = (0, import_react49.useState)(null);
24035
+ const [fontSizeDraft, setFontSizeDraft] = (0, import_react49.useState)("");
23596
24036
  const isImageSelected = editor.isActive("image");
23597
24037
  const imageAttrs = editor.getAttributes("image");
24038
+ const tableAttrs = editor.getAttributes("table");
24039
+ const textStyleAttrs = editor.getAttributes("textStyle");
23598
24040
  const imageLayout = imageAttrs.imageLayout === "left" || imageAttrs.imageLayout === "right" ? imageAttrs.imageLayout : "block";
23599
24041
  const imageWidthPreset = imageAttrs.imageWidthPreset === "sm" || imageAttrs.imageWidthPreset === "md" || imageAttrs.imageWidthPreset === "lg" ? imageAttrs.imageWidthPreset : null;
24042
+ const currentTableAlign = tableAttrs.tableAlign === "center" || tableAttrs.tableAlign === "right" ? tableAttrs.tableAlign : "left";
24043
+ const isTableSelected = editor.isActive("table");
24044
+ const hasTableContext = isTableSelected || tableCommandAnchorPosRef.current !== null;
24045
+ const currentFontFamily = normalizeStyleValue(textStyleAttrs.fontFamily);
24046
+ const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
24047
+ const currentLineHeight = normalizeStyleValue(textStyleAttrs.lineHeight);
24048
+ const currentLetterSpacing = normalizeStyleValue(textStyleAttrs.letterSpacing);
24049
+ const availableFontFamilies = import_react49.default.useMemo(
24050
+ () => fontFamilies ?? getDefaultFontFamilies(t),
24051
+ [fontFamilies, t]
24052
+ );
24053
+ const availableFontSizes = import_react49.default.useMemo(
24054
+ () => fontSizes ?? getDefaultFontSizes(),
24055
+ [fontSizes]
24056
+ );
24057
+ const availableLineHeights = import_react49.default.useMemo(
24058
+ () => lineHeights ?? getDefaultLineHeights(),
24059
+ [lineHeights]
24060
+ );
24061
+ const availableLetterSpacings = import_react49.default.useMemo(
24062
+ () => letterSpacings ?? getDefaultLetterSpacings(),
24063
+ [letterSpacings]
24064
+ );
24065
+ const currentFontFamilyLabel = availableFontFamilies.find((option) => normalizeStyleValue(option.value) === currentFontFamily)?.label ?? t("toolbar.fontDefault");
24066
+ const currentFontSizeLabel = availableFontSizes.find((option) => normalizeStyleValue(option.value) === currentFontSize)?.label ?? t("toolbar.sizeDefault");
24067
+ const currentLineHeightLabel = availableLineHeights.find((option) => normalizeStyleValue(option.value) === currentLineHeight)?.label ?? t("toolbar.lineHeightDefault");
24068
+ const currentLetterSpacingLabel = availableLetterSpacings.find((option) => normalizeStyleValue(option.value) === currentLetterSpacing)?.label ?? t("toolbar.letterSpacingDefault");
24069
+ import_react49.default.useEffect(() => {
24070
+ setFontSizeDraft(currentFontSize.replace(/px$/i, ""));
24071
+ }, [currentFontSize]);
24072
+ const applyFontSizeDraft = () => {
24073
+ const normalized = fontSizeDraft.trim();
24074
+ if (!normalized) {
24075
+ editor.chain().focus().unsetFontSize().run();
24076
+ return;
24077
+ }
24078
+ const parsed = Number.parseFloat(normalized);
24079
+ if (!Number.isFinite(parsed) || parsed <= 0) return;
24080
+ const clamped = Math.min(96, Math.max(8, parsed));
24081
+ editor.chain().focus().setFontSize(`${clamped}px`).run();
24082
+ };
23600
24083
  const insertImageFiles = async (files) => {
23601
24084
  if (files.length === 0) return;
23602
24085
  setIsUploadingImage(true);
@@ -23633,6 +24116,7 @@ var EditorToolbar = ({
23633
24116
  /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
23634
24117
  DropdownMenu,
23635
24118
  {
24119
+ contentClassName: "p-2",
23636
24120
  trigger: /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(ToolbarButton, { onClick: () => {
23637
24121
  }, title: t("toolbar.textStyle"), className: "px-2 w-auto gap-1", children: [
23638
24122
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_lucide_react44.Type, { className: "w-4 h-4" }),
@@ -23681,6 +24165,183 @@ var EditorToolbar = ({
23681
24165
  ]
23682
24166
  }
23683
24167
  ),
24168
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
24169
+ DropdownMenu,
24170
+ {
24171
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24172
+ ToolbarButton,
24173
+ {
24174
+ onClick: () => {
24175
+ },
24176
+ title: t("toolbar.fontFamily"),
24177
+ className: "relative",
24178
+ children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_lucide_react44.Type, { className: "w-4 h-4" })
24179
+ }
24180
+ ),
24181
+ contentClassName: "max-h-80 overflow-y-auto min-w-56 p-2",
24182
+ children: [
24183
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24184
+ DropdownMenuItem,
24185
+ {
24186
+ icon: import_lucide_react44.Type,
24187
+ label: t("toolbar.fontDefault"),
24188
+ onClick: () => editor.chain().focus().unsetFontFamily().run(),
24189
+ active: !currentFontFamily
24190
+ }
24191
+ ),
24192
+ availableFontFamilies.map((option) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24193
+ DropdownMenuItem,
24194
+ {
24195
+ label: option.label,
24196
+ onClick: () => editor.chain().focus().setFontFamily(option.value).run(),
24197
+ active: normalizeStyleValue(option.value) === currentFontFamily,
24198
+ className: "font-medium"
24199
+ },
24200
+ option.value
24201
+ ))
24202
+ ]
24203
+ }
24204
+ ),
24205
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
24206
+ DropdownMenu,
24207
+ {
24208
+ closeOnSelect: false,
24209
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24210
+ ToolbarButton,
24211
+ {
24212
+ onClick: () => {
24213
+ },
24214
+ title: t("toolbar.fontSize"),
24215
+ className: "px-2 w-auto min-w-9",
24216
+ children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "text-[10px] font-semibold leading-none", children: currentFontSize.replace(/px$/i, "") || "T" })
24217
+ }
24218
+ ),
24219
+ contentClassName: "max-h-80 overflow-y-auto min-w-44 p-2",
24220
+ children: [
24221
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "mb-2 rounded-lg border border-border/60 bg-muted/30 p-2", children: /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("label", { className: "flex items-center gap-2", children: [
24222
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24223
+ "input",
24224
+ {
24225
+ type: "number",
24226
+ min: 8,
24227
+ max: 96,
24228
+ step: 1,
24229
+ value: fontSizeDraft,
24230
+ onChange: (e) => setFontSizeDraft(e.target.value),
24231
+ onMouseDown: (e) => e.stopPropagation(),
24232
+ onClick: (e) => e.stopPropagation(),
24233
+ onKeyDown: (e) => {
24234
+ e.stopPropagation();
24235
+ if (e.key === "Enter") {
24236
+ e.preventDefault();
24237
+ applyFontSizeDraft();
24238
+ }
24239
+ },
24240
+ "aria-label": t("toolbar.fontSize"),
24241
+ className: "h-8 w-full rounded-md border border-border bg-background px-2 text-sm outline-none focus:ring-2 focus:ring-primary/20"
24242
+ }
24243
+ ),
24244
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "text-xs text-muted-foreground", children: "px" })
24245
+ ] }) }),
24246
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24247
+ DropdownMenuItem,
24248
+ {
24249
+ icon: import_lucide_react44.Type,
24250
+ label: t("toolbar.sizeDefault"),
24251
+ onClick: () => editor.chain().focus().unsetFontSize().run(),
24252
+ active: !currentFontSize
24253
+ }
24254
+ ),
24255
+ availableFontSizes.map((option) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24256
+ DropdownMenuItem,
24257
+ {
24258
+ label: option.label,
24259
+ onClick: () => editor.chain().focus().setFontSize(option.value).run(),
24260
+ active: normalizeStyleValue(option.value) === currentFontSize
24261
+ },
24262
+ option.value
24263
+ ))
24264
+ ]
24265
+ }
24266
+ ),
24267
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
24268
+ DropdownMenu,
24269
+ {
24270
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
24271
+ ToolbarButton,
24272
+ {
24273
+ onClick: () => {
24274
+ },
24275
+ title: t("toolbar.lineHeight"),
24276
+ className: "gap-0.5",
24277
+ children: [
24278
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_lucide_react44.ArrowUp, { className: "w-3 h-3" }),
24279
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_lucide_react44.ArrowDown, { className: "w-3 h-3" })
24280
+ ]
24281
+ }
24282
+ ),
24283
+ contentClassName: "max-h-72 overflow-y-auto p-2",
24284
+ children: [
24285
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24286
+ DropdownMenuItem,
24287
+ {
24288
+ icon: import_lucide_react44.Type,
24289
+ label: t("toolbar.lineHeightDefault"),
24290
+ onClick: () => editor.chain().focus().unsetLineHeight().run(),
24291
+ active: !currentLineHeight
24292
+ }
24293
+ ),
24294
+ availableLineHeights.map((option) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24295
+ DropdownMenuItem,
24296
+ {
24297
+ label: option.label,
24298
+ onClick: () => editor.chain().focus().setLineHeight(option.value).run(),
24299
+ active: normalizeStyleValue(option.value) === currentLineHeight
24300
+ },
24301
+ option.value
24302
+ ))
24303
+ ]
24304
+ }
24305
+ ),
24306
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
24307
+ DropdownMenu,
24308
+ {
24309
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
24310
+ ToolbarButton,
24311
+ {
24312
+ onClick: () => {
24313
+ },
24314
+ title: t("toolbar.letterSpacing"),
24315
+ className: "gap-0.5",
24316
+ children: [
24317
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_lucide_react44.ArrowLeft, { className: "w-3 h-3" }),
24318
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_lucide_react44.ArrowRight, { className: "w-3 h-3" })
24319
+ ]
24320
+ }
24321
+ ),
24322
+ contentClassName: "max-h-72 overflow-y-auto p-2",
24323
+ children: [
24324
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24325
+ DropdownMenuItem,
24326
+ {
24327
+ icon: import_lucide_react44.Type,
24328
+ label: t("toolbar.letterSpacingDefault"),
24329
+ onClick: () => editor.chain().focus().unsetLetterSpacing().run(),
24330
+ active: !currentLetterSpacing
24331
+ }
24332
+ ),
24333
+ availableLetterSpacings.map((option) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24334
+ DropdownMenuItem,
24335
+ {
24336
+ label: option.label,
24337
+ onClick: () => editor.chain().focus().setLetterSpacing(option.value).run(),
24338
+ active: normalizeStyleValue(option.value) === currentLetterSpacing
24339
+ },
24340
+ option.value
24341
+ ))
24342
+ ]
24343
+ }
24344
+ ),
23684
24345
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ToolbarDivider, {}),
23685
24346
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_lucide_react44.Bold, { className: "w-4 h-4" }) }),
23686
24347
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_lucide_react44.Italic, { className: "w-4 h-4" }) }),
@@ -24015,18 +24676,58 @@ var EditorToolbar = ({
24015
24676
  /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
24016
24677
  DropdownMenu,
24017
24678
  {
24679
+ isOpen: isTableMenuOpen,
24680
+ onOpenChange: (open) => {
24681
+ setIsTableMenuOpen(open);
24682
+ tableCommandAnchorPosRef.current = open && editor.isActive("table") ? editor.state.selection.$from.pos : null;
24683
+ },
24018
24684
  trigger: /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(ToolbarButton, { onClick: () => {
24019
24685
  }, title: t("toolbar.table"), children: [
24020
24686
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_lucide_react44.Table, { className: "w-4 h-4" }),
24021
24687
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_lucide_react44.ChevronDown, { className: "w-3 h-3" })
24022
24688
  ] }),
24689
+ contentClassName: "p-2 min-w-56",
24023
24690
  children: [
24691
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24692
+ TableInsertGrid,
24693
+ {
24694
+ insertLabel: t("tableMenu.insertTable"),
24695
+ previewTemplate: t("tableMenu.gridPreview"),
24696
+ onInsert: (rows, cols) => {
24697
+ editor.chain().focus().insertTable({ rows, cols, withHeaderRow: true }).run();
24698
+ setIsTableMenuOpen(false);
24699
+ }
24700
+ }
24701
+ ),
24702
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "my-1 border-t" }),
24024
24703
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24025
24704
  DropdownMenuItem,
24026
24705
  {
24027
- icon: import_lucide_react44.Table,
24028
- label: t("tableMenu.insert3x3"),
24029
- onClick: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()
24706
+ icon: import_lucide_react44.AlignLeft,
24707
+ label: t("tableMenu.alignLeft"),
24708
+ onClick: () => applyTableAlignment(editor, "left", tableCommandAnchorPosRef.current ?? void 0),
24709
+ active: hasTableContext && currentTableAlign === "left",
24710
+ disabled: !hasTableContext
24711
+ }
24712
+ ),
24713
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24714
+ DropdownMenuItem,
24715
+ {
24716
+ icon: import_lucide_react44.AlignCenter,
24717
+ label: t("tableMenu.alignCenter"),
24718
+ onClick: () => applyTableAlignment(editor, "center", tableCommandAnchorPosRef.current ?? void 0),
24719
+ active: hasTableContext && currentTableAlign === "center",
24720
+ disabled: !hasTableContext
24721
+ }
24722
+ ),
24723
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
24724
+ DropdownMenuItem,
24725
+ {
24726
+ icon: import_lucide_react44.AlignRight,
24727
+ label: t("tableMenu.alignRight"),
24728
+ onClick: () => applyTableAlignment(editor, "right", tableCommandAnchorPosRef.current ?? void 0),
24729
+ active: hasTableContext && currentTableAlign === "right",
24730
+ disabled: !hasTableContext
24030
24731
  }
24031
24732
  ),
24032
24733
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "my-1 border-t" }),
@@ -24036,7 +24737,7 @@ var EditorToolbar = ({
24036
24737
  icon: import_lucide_react44.ArrowLeft,
24037
24738
  label: t("tableMenu.addColumnBefore"),
24038
24739
  onClick: () => editor.chain().focus().addColumnBefore().run(),
24039
- disabled: !editor.can().addColumnBefore()
24740
+ disabled: !hasTableContext || !editor.can().addColumnBefore()
24040
24741
  }
24041
24742
  ),
24042
24743
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
@@ -24045,7 +24746,7 @@ var EditorToolbar = ({
24045
24746
  icon: import_lucide_react44.ArrowDown,
24046
24747
  label: t("tableMenu.addColumnAfter"),
24047
24748
  onClick: () => editor.chain().focus().addColumnAfter().run(),
24048
- disabled: !editor.can().addColumnAfter()
24749
+ disabled: !hasTableContext || !editor.can().addColumnAfter()
24049
24750
  }
24050
24751
  ),
24051
24752
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
@@ -24054,7 +24755,7 @@ var EditorToolbar = ({
24054
24755
  icon: import_lucide_react44.ArrowUp,
24055
24756
  label: t("tableMenu.addRowBefore"),
24056
24757
  onClick: () => editor.chain().focus().addRowBefore().run(),
24057
- disabled: !editor.can().addRowBefore()
24758
+ disabled: !hasTableContext || !editor.can().addRowBefore()
24058
24759
  }
24059
24760
  ),
24060
24761
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
@@ -24063,7 +24764,7 @@ var EditorToolbar = ({
24063
24764
  icon: import_lucide_react44.ArrowRight,
24064
24765
  label: t("tableMenu.addRowAfter"),
24065
24766
  onClick: () => editor.chain().focus().addRowAfter().run(),
24066
- disabled: !editor.can().addRowAfter()
24767
+ disabled: !hasTableContext || !editor.can().addRowAfter()
24067
24768
  }
24068
24769
  ),
24069
24770
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "my-1 border-t" }),
@@ -24073,7 +24774,7 @@ var EditorToolbar = ({
24073
24774
  icon: import_lucide_react44.Table,
24074
24775
  label: t("tableMenu.toggleHeaderRow"),
24075
24776
  onClick: () => editor.chain().focus().toggleHeaderRow().run(),
24076
- disabled: !editor.can().toggleHeaderRow()
24777
+ disabled: !hasTableContext || !editor.can().toggleHeaderRow()
24077
24778
  }
24078
24779
  ),
24079
24780
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
@@ -24082,7 +24783,7 @@ var EditorToolbar = ({
24082
24783
  icon: import_lucide_react44.Table,
24083
24784
  label: t("tableMenu.toggleHeaderColumn"),
24084
24785
  onClick: () => editor.chain().focus().toggleHeaderColumn().run(),
24085
- disabled: !editor.can().toggleHeaderColumn()
24786
+ disabled: !hasTableContext || !editor.can().toggleHeaderColumn()
24086
24787
  }
24087
24788
  ),
24088
24789
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "my-1 border-t" }),
@@ -24092,7 +24793,7 @@ var EditorToolbar = ({
24092
24793
  icon: import_lucide_react44.Trash2,
24093
24794
  label: t("tableMenu.deleteColumn"),
24094
24795
  onClick: () => editor.chain().focus().deleteColumn().run(),
24095
- disabled: !editor.can().deleteColumn()
24796
+ disabled: !hasTableContext || !editor.can().deleteColumn()
24096
24797
  }
24097
24798
  ),
24098
24799
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
@@ -24101,7 +24802,7 @@ var EditorToolbar = ({
24101
24802
  icon: import_lucide_react44.Trash2,
24102
24803
  label: t("tableMenu.deleteRow"),
24103
24804
  onClick: () => editor.chain().focus().deleteRow().run(),
24104
- disabled: !editor.can().deleteRow()
24805
+ disabled: !hasTableContext || !editor.can().deleteRow()
24105
24806
  }
24106
24807
  ),
24107
24808
  /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
@@ -24110,7 +24811,7 @@ var EditorToolbar = ({
24110
24811
  icon: import_lucide_react44.Trash2,
24111
24812
  label: t("tableMenu.deleteTable"),
24112
24813
  onClick: () => editor.chain().focus().deleteTable().run(),
24113
- disabled: !editor.can().deleteTable()
24814
+ disabled: !hasTableContext || !editor.can().deleteTable()
24114
24815
  }
24115
24816
  )
24116
24817
  ]
@@ -24200,7 +24901,9 @@ var FloatingMenuContent = ({ editor }) => {
24200
24901
  };
24201
24902
  var BubbleMenuContent = ({
24202
24903
  editor,
24203
- onKeepOpenChange
24904
+ onKeepOpenChange,
24905
+ fontSizes,
24906
+ lineHeights
24204
24907
  }) => {
24205
24908
  const t = useSmartTranslations("UEditor");
24206
24909
  const { textColors, highlightColors } = useEditorColors();
@@ -24210,6 +24913,17 @@ var BubbleMenuContent = ({
24210
24913
  const imageAttrs = editor.getAttributes("image");
24211
24914
  const imageLayout = imageAttrs.imageLayout === "left" || imageAttrs.imageLayout === "right" ? imageAttrs.imageLayout : "block";
24212
24915
  const imageWidthPreset = imageAttrs.imageWidthPreset === "sm" || imageAttrs.imageWidthPreset === "md" || imageAttrs.imageWidthPreset === "lg" ? imageAttrs.imageWidthPreset : null;
24916
+ const textStyleAttrs = editor.getAttributes("textStyle");
24917
+ const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
24918
+ const currentLineHeight = normalizeStyleValue(textStyleAttrs.lineHeight);
24919
+ const quickFontSizes = (0, import_react50.useMemo)(
24920
+ () => (fontSizes ?? getDefaultFontSizes()).filter((option) => ["14px", "16px", "24px"].includes(option.value)),
24921
+ [fontSizes]
24922
+ );
24923
+ const quickLineHeights = (0, import_react50.useMemo)(
24924
+ () => (lineHeights ?? getDefaultLineHeights()).filter((option) => ["1.2", "1.5", "1.75"].includes(option.value)),
24925
+ [lineHeights]
24926
+ );
24213
24927
  (0, import_react50.useEffect)(() => {
24214
24928
  onKeepOpenChange?.(showLinkInput);
24215
24929
  }, [onKeepOpenChange, showLinkInput]);
@@ -24329,6 +25043,50 @@ var BubbleMenuContent = ({
24329
25043
  ),
24330
25044
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ToolbarButton, { onClick: () => setShowEditorColorPalette(true), title: t("colors.textColor"), children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react45.Palette, { className: "w-4 h-4" }) }),
24331
25045
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" }),
25046
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25047
+ ToolbarButton,
25048
+ {
25049
+ onClick: () => editor.chain().focus().unsetFontSize().run(),
25050
+ active: !currentFontSize,
25051
+ title: t("toolbar.sizeDefault"),
25052
+ className: "px-2 w-auto",
25053
+ children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "text-[10px] font-semibold", children: "A" })
25054
+ }
25055
+ ),
25056
+ quickFontSizes.map((option) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25057
+ ToolbarButton,
25058
+ {
25059
+ onClick: () => editor.chain().focus().setFontSize(option.value).run(),
25060
+ active: normalizeStyleValue(option.value) === currentFontSize,
25061
+ title: `${t("toolbar.fontSize")} ${option.label}`,
25062
+ className: "px-2 w-auto",
25063
+ children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "text-[10px] font-semibold", children: option.label })
25064
+ },
25065
+ option.value
25066
+ )),
25067
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" }),
25068
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25069
+ ToolbarButton,
25070
+ {
25071
+ onClick: () => editor.chain().focus().unsetLineHeight().run(),
25072
+ active: !currentLineHeight,
25073
+ title: t("toolbar.lineHeightDefault"),
25074
+ className: "px-2 w-auto",
25075
+ children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "text-[10px] font-semibold leading-none", children: "LH" })
25076
+ }
25077
+ ),
25078
+ quickLineHeights.map((option) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25079
+ ToolbarButton,
25080
+ {
25081
+ onClick: () => editor.chain().focus().setLineHeight(option.value).run(),
25082
+ active: normalizeStyleValue(option.value) === currentLineHeight,
25083
+ title: `${t("toolbar.lineHeight")} ${option.label}`,
25084
+ className: "px-2 w-auto",
25085
+ children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "text-[10px] font-semibold", children: option.label })
25086
+ },
25087
+ option.value
25088
+ )),
25089
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" }),
24332
25090
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
24333
25091
  ToolbarButton,
24334
25092
  {
@@ -24349,8 +25107,13 @@ var BubbleMenuContent = ({
24349
25107
  )
24350
25108
  ] });
24351
25109
  };
24352
- var CustomBubbleMenu = ({ editor }) => {
25110
+ var CustomBubbleMenu = ({
25111
+ editor,
25112
+ fontSizes,
25113
+ lineHeights
25114
+ }) => {
24353
25115
  const SHOW_DELAY_MS = 180;
25116
+ const BUBBLE_MENU_OFFSET = 16;
24354
25117
  const [isVisible, setIsVisible] = (0, import_react50.useState)(false);
24355
25118
  const [position, setPosition] = (0, import_react50.useState)({ top: 0, left: 0 });
24356
25119
  const menuRef = (0, import_react50.useRef)(null);
@@ -24378,7 +25141,7 @@ var CustomBubbleMenu = ({ editor }) => {
24378
25141
  const start = view.coordsAtPos(from);
24379
25142
  const end = view.coordsAtPos(to);
24380
25143
  const left = (start.left + end.left) / 2;
24381
- const top = start.top - 10;
25144
+ const top = start.top - BUBBLE_MENU_OFFSET;
24382
25145
  setPosition({ top, left });
24383
25146
  if (keepOpenRef.current) {
24384
25147
  clearShowTimeout();
@@ -24424,7 +25187,9 @@ var CustomBubbleMenu = ({ editor }) => {
24424
25187
  BubbleMenuContent,
24425
25188
  {
24426
25189
  editor,
24427
- onKeepOpenChange: setKeepOpen
25190
+ onKeepOpenChange: setKeepOpen,
25191
+ fontSizes,
25192
+ lineHeights
24428
25193
  }
24429
25194
  )
24430
25195
  }
@@ -24433,6 +25198,7 @@ var CustomBubbleMenu = ({ editor }) => {
24433
25198
  );
24434
25199
  };
24435
25200
  var CustomFloatingMenu = ({ editor }) => {
25201
+ const FLOATING_MENU_OFFSET = 16;
24436
25202
  const [isVisible, setIsVisible] = (0, import_react50.useState)(false);
24437
25203
  const [position, setPosition] = (0, import_react50.useState)({ top: 0, left: 0 });
24438
25204
  (0, import_react50.useEffect)(() => {
@@ -24445,7 +25211,7 @@ var CustomFloatingMenu = ({ editor }) => {
24445
25211
  return;
24446
25212
  }
24447
25213
  const coords = view.coordsAtPos($from.pos);
24448
- setPosition({ top: coords.top - 10, left: coords.left });
25214
+ setPosition({ top: coords.top - FLOATING_MENU_OFFSET, left: coords.left });
24449
25215
  setIsVisible(true);
24450
25216
  };
24451
25217
  const handleBlur = () => setIsVisible(false);
@@ -28921,9 +29687,16 @@ var FALLBACK_TABLE_COLUMN_WIDTH = 160;
28921
29687
  var MENU_HOVER_PADDING = 18;
28922
29688
  var ROW_HANDLE_HOVER_WIDTH = 28;
28923
29689
  var COLUMN_HANDLE_HOVER_HEIGHT = 28;
29690
+ var ROW_HANDLE_GUTTER = 20;
29691
+ var TABLE_MENU_TOP_OFFSET = 10;
29692
+ var COLUMN_HANDLE_TOP_OFFSET = 8;
29693
+ var ADD_COLUMN_RAIL_GAP = 4;
29694
+ var ADD_ROW_RAIL_GAP = 4;
28924
29695
  var ADD_COLUMN_HOVER_WIDTH = 24;
28925
29696
  var ADD_ROW_HOVER_HEIGHT = 24;
28926
29697
  var HANDLE_HOVER_RADIUS = 14;
29698
+ var IDLE_HANDLE_OPACITY = "0.4";
29699
+ var IDLE_HANDLE_SCALE = "0.78";
28927
29700
  var DEFAULT_HOVER_STATE = {
28928
29701
  menuVisible: false,
28929
29702
  addColumnVisible: false,
@@ -29165,8 +29938,8 @@ function TableControls({ editor, containerRef }) {
29165
29938
  const rowHandleIndex = Number.isFinite(directRowHandleIndex) ? directRowHandleIndex : activeLayout.rowHandles.find((rowHandle) => relativeX >= activeLayout.tableLeft - ROW_HANDLE_HOVER_WIDTH && relativeX <= activeLayout.tableLeft && Math.abs(relativeY - rowHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
29166
29939
  const columnHandleIndex = Number.isFinite(directColumnHandleIndex) ? directColumnHandleIndex : activeLayout.columnHandles.find((columnHandle) => relativeY >= activeLayout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= activeLayout.tableTop && Math.abs(relativeX - columnHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
29167
29940
  const menuVisible = Boolean(directTableMenu) || relativeX >= activeLayout.tableLeft - MENU_HOVER_PADDING && relativeX <= activeLayout.tableLeft + 42 && relativeY >= activeLayout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= activeLayout.tableTop + MENU_HOVER_PADDING;
29168
- const addColumnVisible = Boolean(directAddColumn) || relativeX >= activeLayout.wrapperLeft + visibleTableWidth2 && relativeX <= activeLayout.wrapperLeft + visibleTableWidth2 + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.wrapperTop && relativeY <= activeLayout.wrapperTop + visibleTableHeight2;
29169
- const addRowVisible = Boolean(directAddRow) || relativeY >= activeLayout.wrapperTop + activeLayout.wrapperHeight && relativeY <= activeLayout.wrapperTop + activeLayout.wrapperHeight + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.wrapperLeft && relativeX <= activeLayout.wrapperLeft + visibleTableWidth2;
29941
+ const addColumnVisible = Boolean(directAddColumn) || relativeX >= activeLayout.tableLeft + visibleTableWidth2 && relativeX <= activeLayout.tableLeft + visibleTableWidth2 + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + visibleTableHeight2;
29942
+ const addRowVisible = Boolean(directAddRow) || relativeY >= activeLayout.tableTop + visibleTableHeight2 && relativeY <= activeLayout.tableTop + visibleTableHeight2 + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + visibleTableWidth2;
29170
29943
  setHoverState((prev) => {
29171
29944
  if (prev.menuVisible === menuVisible && prev.addColumnVisible === addColumnVisible && prev.addRowVisible === addRowVisible && prev.rowHandleIndex === rowHandleIndex && prev.columnHandleIndex === columnHandleIndex) {
29172
29945
  return prev;
@@ -29406,6 +30179,21 @@ function TableControls({ editor, containerRef }) {
29406
30179
  const menuItems = import_react51.default.useMemo(() => {
29407
30180
  if (!layout) return [];
29408
30181
  return [
30182
+ {
30183
+ label: t("tableMenu.alignLeft"),
30184
+ icon: import_lucide_react46.AlignLeft,
30185
+ onClick: () => applyTableAlignment(editor, "left", layout.cellPos)
30186
+ },
30187
+ {
30188
+ label: t("tableMenu.alignCenter"),
30189
+ icon: import_lucide_react46.AlignCenter,
30190
+ onClick: () => applyTableAlignment(editor, "center", layout.cellPos)
30191
+ },
30192
+ {
30193
+ label: t("tableMenu.alignRight"),
30194
+ icon: import_lucide_react46.AlignRight,
30195
+ onClick: () => applyTableAlignment(editor, "right", layout.cellPos)
30196
+ },
29409
30197
  {
29410
30198
  label: t("tableMenu.addColumnBefore"),
29411
30199
  icon: import_lucide_react46.ArrowLeft,
@@ -29515,16 +30303,16 @@ function TableControls({ editor, containerRef }) {
29515
30303
  if (!layout) {
29516
30304
  return null;
29517
30305
  }
29518
- const menuTop = Math.max(8, layout.tableTop - 16);
30306
+ const menuTop = Math.max(8, layout.tableTop - TABLE_MENU_TOP_OFFSET);
29519
30307
  const menuLeft = Math.max(8, layout.tableLeft);
29520
- const rowHandleLeft = Math.max(8, layout.tableLeft - 66);
29521
- const columnHandleTop = Math.max(8, layout.tableTop - 14);
30308
+ const rowHandleLeft = Math.max(8, layout.tableLeft - ROW_HANDLE_GUTTER);
30309
+ const columnHandleTop = Math.max(8, layout.tableTop - COLUMN_HANDLE_TOP_OFFSET);
29522
30310
  const visibleTableWidth = Math.min(layout.tableWidth, layout.viewportWidth);
29523
30311
  const visibleTableHeight = Math.min(layout.tableHeight, layout.viewportHeight);
29524
- const columnRailTop = layout.wrapperTop;
29525
- const columnRailLeft = layout.wrapperLeft + visibleTableWidth + 8;
29526
- const rowRailTop = layout.wrapperTop + layout.wrapperHeight + 8;
29527
- const rowRailLeft = layout.wrapperLeft;
30312
+ const columnRailTop = layout.tableTop;
30313
+ const columnRailLeft = layout.tableLeft + visibleTableWidth + ADD_COLUMN_RAIL_GAP;
30314
+ const rowRailTop = layout.tableTop + visibleTableHeight + ADD_ROW_RAIL_GAP;
30315
+ const rowRailLeft = layout.tableLeft;
29528
30316
  const expandPreviewWidth = dragPreview?.kind === "add-column" ? layout.tableWidth + dragPreview.previewCols * layout.avgColumnWidth : layout.tableWidth;
29529
30317
  const expandPreviewHeight = dragPreview?.kind === "add-row" ? layout.tableHeight + dragPreview.previewRows * layout.avgRowHeight : layout.tableHeight;
29530
30318
  const dragStatusText = dragPreview?.kind === "row" ? `${t("tableMenu.dragRow")} ${dragPreview.originIndex + 1} -> ${dragPreview.targetIndex + 1}` : dragPreview?.kind === "column" ? `${t("tableMenu.dragColumn")} ${dragPreview.originIndex + 1} -> ${dragPreview.targetIndex + 1}` : dragPreview?.kind === "add-row" ? `+${dragPreview.previewRows}R` : dragPreview?.kind === "add-column" ? `+${dragPreview.previewCols}C` : null;
@@ -29532,7 +30320,6 @@ function TableControls({ editor, containerRef }) {
29532
30320
  layout.rowHandles.map((rowHandle) => {
29533
30321
  const menuKey = getRowMenuKey(rowHandle.index);
29534
30322
  const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index || openMenuKey === menuKey;
29535
- if (!visible) return null;
29536
30323
  return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
29537
30324
  "div",
29538
30325
  {
@@ -29546,6 +30333,7 @@ function TableControls({ editor, containerRef }) {
29546
30333
  Tooltip,
29547
30334
  {
29548
30335
  placement: "right",
30336
+ disabled: openMenuKey === menuKey,
29549
30337
  content: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "text-xs font-medium", children: `${t("tableMenu.dragRow")} ${rowHandle.index + 1}` }),
29550
30338
  children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
29551
30339
  DropdownMenu,
@@ -29555,6 +30343,7 @@ function TableControls({ editor, containerRef }) {
29555
30343
  onOpenChange: (open) => {
29556
30344
  setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
29557
30345
  },
30346
+ contentClassName: "p-2",
29558
30347
  items: getRowHandleMenuItems(rowHandle),
29559
30348
  trigger: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
29560
30349
  "button",
@@ -29583,8 +30372,13 @@ function TableControls({ editor, containerRef }) {
29583
30372
  className: cn(
29584
30373
  "inline-flex h-6 w-6 items-center justify-center rounded-full",
29585
30374
  "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
30375
+ "cursor-grab active:cursor-grabbing",
29586
30376
  "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29587
30377
  ),
30378
+ style: {
30379
+ opacity: visible ? 1 : Number(IDLE_HANDLE_OPACITY),
30380
+ transform: visible ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`
30381
+ },
29588
30382
  children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_lucide_react46.GripVertical, { className: "h-3.5 w-3.5" })
29589
30383
  }
29590
30384
  )
@@ -29599,7 +30393,6 @@ function TableControls({ editor, containerRef }) {
29599
30393
  layout.columnHandles.map((columnHandle) => {
29600
30394
  const menuKey = getColumnMenuKey(columnHandle.index);
29601
30395
  const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index || openMenuKey === menuKey;
29602
- if (!visible) return null;
29603
30396
  return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
29604
30397
  "div",
29605
30398
  {
@@ -29613,6 +30406,7 @@ function TableControls({ editor, containerRef }) {
29613
30406
  Tooltip,
29614
30407
  {
29615
30408
  placement: "top",
30409
+ disabled: openMenuKey === menuKey,
29616
30410
  content: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "text-xs font-medium", children: `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}` }),
29617
30411
  children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
29618
30412
  DropdownMenu,
@@ -29622,6 +30416,7 @@ function TableControls({ editor, containerRef }) {
29622
30416
  onOpenChange: (open) => {
29623
30417
  setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
29624
30418
  },
30419
+ contentClassName: "p-2",
29625
30420
  items: getColumnHandleMenuItems(columnHandle),
29626
30421
  trigger: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
29627
30422
  "button",
@@ -29650,8 +30445,13 @@ function TableControls({ editor, containerRef }) {
29650
30445
  className: cn(
29651
30446
  "inline-flex h-6 w-6 items-center justify-center rounded-full",
29652
30447
  "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
30448
+ "cursor-grab active:cursor-grabbing",
29653
30449
  "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29654
30450
  ),
30451
+ style: {
30452
+ opacity: visible ? 1 : Number(IDLE_HANDLE_OPACITY),
30453
+ transform: visible ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`
30454
+ },
29655
30455
  children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_lucide_react46.GripHorizontal, { className: "h-3.5 w-3.5" })
29656
30456
  }
29657
30457
  )
@@ -29663,7 +30463,7 @@ function TableControls({ editor, containerRef }) {
29663
30463
  `column-handle-${columnHandle.index}`
29664
30464
  );
29665
30465
  }),
29666
- (controlsVisible || hoverState.menuVisible || tableMenuOpen) && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
30466
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
29667
30467
  "div",
29668
30468
  {
29669
30469
  className: "absolute z-30",
@@ -29676,6 +30476,7 @@ function TableControls({ editor, containerRef }) {
29676
30476
  Tooltip,
29677
30477
  {
29678
30478
  placement: "top",
30479
+ disabled: tableMenuOpen,
29679
30480
  content: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "text-xs font-medium", children: t("tableMenu.openControls") }),
29680
30481
  children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
29681
30482
  DropdownMenu,
@@ -29685,6 +30486,7 @@ function TableControls({ editor, containerRef }) {
29685
30486
  onOpenChange: (open) => {
29686
30487
  setOpenMenuKey((prev) => open ? "table" : prev === "table" ? null : prev);
29687
30488
  },
30489
+ contentClassName: "p-2",
29688
30490
  items: menuItems,
29689
30491
  trigger: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
29690
30492
  "button",
@@ -29697,6 +30499,10 @@ function TableControls({ editor, containerRef }) {
29697
30499
  "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29698
30500
  "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29699
30501
  ),
30502
+ style: {
30503
+ opacity: controlsVisible || hoverState.menuVisible || tableMenuOpen ? 1 : 0.5,
30504
+ transform: controlsVisible || hoverState.menuVisible || tableMenuOpen ? "scale(1)" : "scale(0.82)"
30505
+ },
29700
30506
  children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_lucide_react46.MoreHorizontal, { className: "h-4 w-4" })
29701
30507
  }
29702
30508
  )
@@ -29706,7 +30512,7 @@ function TableControls({ editor, containerRef }) {
29706
30512
  )
29707
30513
  }
29708
30514
  ),
29709
- (controlsVisible || hoverState.addColumnVisible) && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
30515
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
29710
30516
  Tooltip,
29711
30517
  {
29712
30518
  placement: "right",
@@ -29733,17 +30539,19 @@ function TableControls({ editor, containerRef }) {
29733
30539
  "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
29734
30540
  ),
29735
30541
  style: {
29736
- top: columnRailTop,
30542
+ top: controlsVisible || hoverState.addColumnVisible ? columnRailTop : columnRailTop + Math.max(0, visibleTableHeight / 2 - 24),
29737
30543
  left: columnRailLeft,
29738
- width: 18,
29739
- height: visibleTableHeight
30544
+ width: controlsVisible || hoverState.addColumnVisible ? 18 : 12,
30545
+ height: controlsVisible || hoverState.addColumnVisible ? visibleTableHeight : 48,
30546
+ opacity: controlsVisible || hoverState.addColumnVisible ? 1 : 0.45,
30547
+ transform: controlsVisible || hoverState.addColumnVisible ? "scale(1)" : "scale(0.92)"
29740
30548
  },
29741
30549
  children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
29742
30550
  }
29743
30551
  )
29744
30552
  }
29745
30553
  ),
29746
- (controlsVisible || hoverState.addRowVisible) && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
30554
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
29747
30555
  Tooltip,
29748
30556
  {
29749
30557
  placement: "bottom",
@@ -29771,9 +30579,11 @@ function TableControls({ editor, containerRef }) {
29771
30579
  ),
29772
30580
  style: {
29773
30581
  top: rowRailTop,
29774
- left: rowRailLeft,
29775
- width: visibleTableWidth,
29776
- height: 16
30582
+ left: controlsVisible || hoverState.addRowVisible ? rowRailLeft : rowRailLeft + Math.max(0, visibleTableWidth / 2 - 24),
30583
+ width: controlsVisible || hoverState.addRowVisible ? visibleTableWidth : 48,
30584
+ height: controlsVisible || hoverState.addRowVisible ? 16 : 12,
30585
+ opacity: controlsVisible || hoverState.addRowVisible ? 1 : 0.45,
30586
+ transform: controlsVisible || hoverState.addRowVisible ? "scale(1)" : "scale(0.92)"
29777
30587
  },
29778
30588
  children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
29779
30589
  }
@@ -29960,6 +30770,32 @@ function getRelativeCellMetrics(surface, cell) {
29960
30770
  height: cellRect.height
29961
30771
  };
29962
30772
  }
30773
+ function getRelativeSelectedCellsMetrics(surface) {
30774
+ const selectedCells = Array.from(
30775
+ surface.querySelectorAll("td.selectedCell, th.selectedCell")
30776
+ );
30777
+ if (selectedCells.length === 0) {
30778
+ return null;
30779
+ }
30780
+ const surfaceRect = surface.getBoundingClientRect();
30781
+ let left = Number.POSITIVE_INFINITY;
30782
+ let top = Number.POSITIVE_INFINITY;
30783
+ let right = Number.NEGATIVE_INFINITY;
30784
+ let bottom = Number.NEGATIVE_INFINITY;
30785
+ selectedCells.forEach((cell) => {
30786
+ const rect = cell.getBoundingClientRect();
30787
+ left = Math.min(left, rect.left);
30788
+ top = Math.min(top, rect.top);
30789
+ right = Math.max(right, rect.right);
30790
+ bottom = Math.max(bottom, rect.bottom);
30791
+ });
30792
+ return {
30793
+ left: left - surfaceRect.left + surface.scrollLeft,
30794
+ top: top - surfaceRect.top + surface.scrollTop,
30795
+ width: right - left,
30796
+ height: bottom - top
30797
+ };
30798
+ }
29963
30799
  var UEditor = import_react52.default.forwardRef(({
29964
30800
  content = "",
29965
30801
  onChange,
@@ -29979,7 +30815,11 @@ var UEditor = import_react52.default.forwardRef(({
29979
30815
  maxCharacters,
29980
30816
  minHeight = "200px",
29981
30817
  maxHeight = "auto",
29982
- variant = "default"
30818
+ variant = "default",
30819
+ fontFamilies,
30820
+ fontSizes,
30821
+ lineHeights,
30822
+ letterSpacings
29983
30823
  }, ref) => {
29984
30824
  const t = useSmartTranslations("UEditor");
29985
30825
  const effectivePlaceholder = placeholder ?? t("placeholder");
@@ -30024,7 +30864,7 @@ var UEditor = import_react52.default.forwardRef(({
30024
30864
  highlight.style.display = "none";
30025
30865
  return;
30026
30866
  }
30027
- const metrics = getRelativeCellMetrics(surface, cell);
30867
+ const metrics = getRelativeSelectedCellsMetrics(surface) ?? getRelativeCellMetrics(surface, cell);
30028
30868
  highlight.style.display = "block";
30029
30869
  highlight.style.left = `${metrics.left}px`;
30030
30870
  highlight.style.top = `${metrics.top}px`;
@@ -30127,8 +30967,10 @@ var UEditor = import_react52.default.forwardRef(({
30127
30967
  "[&_ul[data-type='taskList']_li>label>input]:border-2",
30128
30968
  "[&_ul[data-type='taskList']_li>label>input]:border-primary/50",
30129
30969
  "[&_ul[data-type='taskList']_li>label>input]:accent-primary",
30130
- "[&_pre]:bg-[#1e1e1e]!",
30131
- "[&_pre]:text-[#d4d4d4]!",
30970
+ "[&_pre]:bg-muted/40!",
30971
+ "[&_pre]:text-foreground!",
30972
+ "[&_pre]:border!",
30973
+ "[&_pre]:border-border/60!",
30132
30974
  "[&_pre_code]:bg-transparent!",
30133
30975
  "[&_.tableWrapper]:overflow-x-auto",
30134
30976
  "[&_.tableWrapper]:pb-1.5",
@@ -30148,6 +30990,11 @@ var UEditor = import_react52.default.forwardRef(({
30148
30990
  "[&_table]:table-fixed",
30149
30991
  "[&_table]:overflow-hidden",
30150
30992
  "[&_table]:select-text",
30993
+ "[&_table[data-table-align]]:w-max",
30994
+ "[&_table[data-table-align]]:max-w-full",
30995
+ "[&_table[data-table-align='center']]:mx-auto",
30996
+ "[&_table[data-table-align='right']]:ml-auto",
30997
+ "[&_table[data-table-align='right']]:mr-0",
30151
30998
  "[&_td]:relative",
30152
30999
  "[&_td]:align-top",
30153
31000
  "[&_td]:box-border",
@@ -30510,8 +31357,27 @@ var UEditor = import_react52.default.forwardRef(({
30510
31357
  className
30511
31358
  ),
30512
31359
  children: [
30513
- editable && showToolbar && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(EditorToolbar, { editor, variant, uploadImage, imageInsertMode }),
30514
- editable && showBubbleMenu && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(CustomBubbleMenu, { editor }),
31360
+ editable && showToolbar && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
31361
+ EditorToolbar,
31362
+ {
31363
+ editor,
31364
+ variant,
31365
+ uploadImage,
31366
+ imageInsertMode,
31367
+ fontFamilies,
31368
+ fontSizes,
31369
+ lineHeights,
31370
+ letterSpacings
31371
+ }
31372
+ ),
31373
+ editable && showBubbleMenu && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
31374
+ CustomBubbleMenu,
31375
+ {
31376
+ editor,
31377
+ fontSizes,
31378
+ lineHeights
31379
+ }
31380
+ ),
30515
31381
  editable && showFloatingMenu && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(CustomFloatingMenu, { editor }),
30516
31382
  /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
30517
31383
  "div",
@@ -30544,7 +31410,7 @@ var UEditor = import_react52.default.forwardRef(({
30544
31410
  {
30545
31411
  ref: activeTableCellHighlightRef,
30546
31412
  "aria-hidden": "true",
30547
- className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-[#2383e2] bg-[#2383e2]/[0.06] transition-[left,top,width,height] duration-100"
31413
+ className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10 transition-[left,top,width,height] duration-100"
30548
31414
  }
30549
31415
  ),
30550
31416
  editable && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(TableControls, { editor, containerRef: editorContentRef }),