@underverse-ui/underverse 0.2.75 → 0.2.77

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
@@ -159,6 +159,7 @@ __export(index_exports, {
159
159
  ToastProvider: () => Toast_default,
160
160
  Tooltip: () => Tooltip,
161
161
  TranslationProvider: () => TranslationProvider,
162
+ UEditor: () => UEditor_default,
162
163
  UnderverseProvider: () => UnderverseProvider,
163
164
  VARIANT_STYLES_ALERT: () => VARIANT_STYLES_ALERT,
164
165
  VARIANT_STYLES_BTN: () => VARIANT_STYLES_BTN,
@@ -13143,6 +13144,103 @@ function DataTablePagination({
13143
13144
  ] });
13144
13145
  }
13145
13146
 
13147
+ // ../../components/ui/DataTable/utils/headers.ts
13148
+ function isLeafColumn(col) {
13149
+ return !col.children || col.children.length === 0;
13150
+ }
13151
+ function getLeafColumns(columns) {
13152
+ const leaves = [];
13153
+ function traverse(cols) {
13154
+ for (const col of cols) {
13155
+ if (isLeafColumn(col)) {
13156
+ leaves.push(col);
13157
+ } else if (col.children) {
13158
+ traverse(col.children);
13159
+ }
13160
+ }
13161
+ }
13162
+ traverse(columns);
13163
+ return leaves;
13164
+ }
13165
+ function getHeaderDepth(columns) {
13166
+ function getDepth(cols) {
13167
+ if (!cols || cols.length === 0) return 0;
13168
+ let maxDepth = 1;
13169
+ for (const col of cols) {
13170
+ if (col.children && col.children.length > 0) {
13171
+ maxDepth = Math.max(maxDepth, 1 + getDepth(col.children));
13172
+ }
13173
+ }
13174
+ return maxDepth;
13175
+ }
13176
+ return getDepth(columns);
13177
+ }
13178
+ function getColSpan(col) {
13179
+ if (col.colSpan !== void 0) return col.colSpan;
13180
+ if (isLeafColumn(col)) return 1;
13181
+ return col.children.reduce((sum, child) => sum + getColSpan(child), 0);
13182
+ }
13183
+ function getRowSpan(col, maxDepth, currentDepth) {
13184
+ if (col.rowSpan !== void 0) return col.rowSpan;
13185
+ if (isLeafColumn(col)) {
13186
+ return maxDepth - currentDepth + 1;
13187
+ }
13188
+ return 1;
13189
+ }
13190
+ function buildHeaderRows(columns) {
13191
+ const maxDepth = getHeaderDepth(columns);
13192
+ const rows = Array.from({ length: maxDepth }, () => []);
13193
+ function buildCell(col, rowIndex, colIndex) {
13194
+ const colSpan = getColSpan(col);
13195
+ const rowSpan = getRowSpan(col, maxDepth, rowIndex + 1);
13196
+ const isLeaf = isLeafColumn(col);
13197
+ rows[rowIndex].push({
13198
+ column: col,
13199
+ colSpan,
13200
+ rowSpan,
13201
+ isLeaf,
13202
+ rowIndex,
13203
+ colIndex
13204
+ });
13205
+ if (col.children && col.children.length > 0) {
13206
+ let childColIndex = colIndex;
13207
+ for (const child of col.children) {
13208
+ childColIndex = buildCell(child, rowIndex + 1, childColIndex);
13209
+ }
13210
+ }
13211
+ return colIndex + colSpan;
13212
+ }
13213
+ let currentColIndex = 0;
13214
+ for (const col of columns) {
13215
+ currentColIndex = buildCell(col, 0, currentColIndex);
13216
+ }
13217
+ return rows;
13218
+ }
13219
+ function filterVisibleColumns(columns, visibleKeys) {
13220
+ return columns.map((col) => {
13221
+ if (col.children) {
13222
+ const visibleChildren = filterVisibleColumns(col.children, visibleKeys);
13223
+ if (visibleChildren.length > 0) {
13224
+ return { ...col, children: visibleChildren };
13225
+ }
13226
+ return null;
13227
+ }
13228
+ return visibleKeys.has(col.key) ? col : null;
13229
+ }).filter((col) => col !== null);
13230
+ }
13231
+ function getLeafColumnsWithFixedInheritance(columns, inheritedFixed) {
13232
+ const leaves = [];
13233
+ for (const col of columns) {
13234
+ const effectiveFixed = col.fixed ?? inheritedFixed;
13235
+ if (isLeafColumn(col)) {
13236
+ leaves.push({ ...col, fixed: effectiveFixed });
13237
+ } else if (col.children) {
13238
+ leaves.push(...getLeafColumnsWithFixedInheritance(col.children, effectiveFixed));
13239
+ }
13240
+ }
13241
+ return leaves;
13242
+ }
13243
+
13146
13244
  // ../../components/ui/DataTable/components/Toolbar.tsx
13147
13245
  var import_jsx_runtime58 = require("react/jsx-runtime");
13148
13246
  function DataTableToolbar({
@@ -13177,36 +13275,39 @@ function DataTableToolbar({
13177
13275
  ]
13178
13276
  }
13179
13277
  ),
13180
- enableColumnVisibilityToggle && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13181
- DropdownMenu_default,
13182
- {
13183
- trigger: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
13184
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13185
- "path",
13278
+ enableColumnVisibilityToggle && (() => {
13279
+ const leafCols = getLeafColumns(columns);
13280
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13281
+ DropdownMenu_default,
13282
+ {
13283
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
13284
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13285
+ "path",
13286
+ {
13287
+ strokeLinecap: "round",
13288
+ strokeLinejoin: "round",
13289
+ strokeWidth: 2,
13290
+ d: "M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2"
13291
+ }
13292
+ ) }),
13293
+ labels?.columns || t("columns")
13294
+ ] }),
13295
+ children: leafCols.map((c) => /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
13296
+ DropdownMenuItem,
13186
13297
  {
13187
- strokeLinecap: "round",
13188
- strokeLinejoin: "round",
13189
- strokeWidth: 2,
13190
- d: "M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2"
13191
- }
13192
- ) }),
13193
- labels?.columns || t("columns")
13194
- ] }),
13195
- children: columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
13196
- DropdownMenuItem,
13197
- {
13198
- onClick: () => {
13199
- setVisibleCols((prev) => prev.includes(c.key) ? prev.filter((k) => k !== c.key) : [...prev, c.key]);
13298
+ onClick: () => {
13299
+ setVisibleCols((prev) => prev.includes(c.key) ? prev.filter((k) => k !== c.key) : [...prev, c.key]);
13300
+ },
13301
+ children: [
13302
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("input", { type: "checkbox", className: "mr-2 rounded-md border-border", readOnly: true, checked: visibleCols.includes(c.key) }),
13303
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "truncate", children: c.title })
13304
+ ]
13200
13305
  },
13201
- children: [
13202
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("input", { type: "checkbox", className: "mr-2 rounded-md border-border", readOnly: true, checked: visibleCols.includes(c.key) }),
13203
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "truncate", children: c.title })
13204
- ]
13205
- },
13206
- c.key
13207
- ))
13208
- }
13209
- ),
13306
+ c.key
13307
+ ))
13308
+ }
13309
+ );
13310
+ })(),
13210
13311
  enableHeaderAlignToggle && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13211
13312
  DropdownMenu_default,
13212
13313
  {
@@ -13281,32 +13382,40 @@ var import_react34 = __toESM(require("react"), 1);
13281
13382
  // ../../components/ui/DataTable/utils/columns.ts
13282
13383
  function getColumnWidth(col, fallback = 150) {
13283
13384
  if (typeof col.width === "number") return col.width;
13284
- const raw = col.width ? String(col.width) : String(fallback);
13285
- const parsed = parseInt(raw, 10);
13286
- return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
13385
+ if (col.width) {
13386
+ const raw = String(col.width);
13387
+ const parsed = parseInt(raw, 10);
13388
+ if (Number.isFinite(parsed) && parsed > 0) return parsed;
13389
+ }
13390
+ if (col.children && col.children.length > 0) {
13391
+ return col.children.reduce((sum, child) => sum + getColumnWidth(child, fallback), 0);
13392
+ }
13393
+ return fallback;
13287
13394
  }
13288
13395
 
13289
13396
  // ../../components/ui/DataTable/hooks/useStickyColumns.ts
13290
- function useStickyColumns(visibleColumns) {
13397
+ function useStickyColumns(columns, visibleKeys) {
13398
+ const visibleColumns = import_react34.default.useMemo(() => filterVisibleColumns(columns, visibleKeys), [columns, visibleKeys]);
13399
+ const leafColumns = import_react34.default.useMemo(() => getLeafColumnsWithFixedInheritance(visibleColumns), [visibleColumns]);
13291
13400
  const stickyPositions = import_react34.default.useMemo(() => {
13292
13401
  const positions = {};
13293
13402
  let leftOffset = 0;
13294
- for (const col of visibleColumns) {
13403
+ for (const col of leafColumns) {
13295
13404
  if (col.fixed === "left") {
13296
13405
  positions[col.key] = { left: leftOffset };
13297
13406
  leftOffset += getColumnWidth(col);
13298
13407
  }
13299
13408
  }
13300
13409
  let rightOffset = 0;
13301
- for (let i = visibleColumns.length - 1; i >= 0; i--) {
13302
- const col = visibleColumns[i];
13410
+ for (let i = leafColumns.length - 1; i >= 0; i--) {
13411
+ const col = leafColumns[i];
13303
13412
  if (col.fixed === "right") {
13304
13413
  positions[col.key] = { right: rightOffset };
13305
13414
  rightOffset += getColumnWidth(col);
13306
13415
  }
13307
13416
  }
13308
13417
  return positions;
13309
- }, [visibleColumns]);
13418
+ }, [leafColumns]);
13310
13419
  const getStickyColumnStyle = import_react34.default.useCallback(
13311
13420
  (col) => {
13312
13421
  if (!col.fixed) return {};
@@ -13336,7 +13445,109 @@ function useStickyColumns(visibleColumns) {
13336
13445
  isStripedRow ? "bg-muted!" : "bg-card!"
13337
13446
  );
13338
13447
  }, []);
13339
- return { getStickyColumnStyle, getStickyHeaderClass, getStickyCellClass };
13448
+ const getStickyHeaderCellStyle = import_react34.default.useCallback(
13449
+ (headerCell) => {
13450
+ const col = headerCell.column;
13451
+ if (headerCell.isLeaf) {
13452
+ return getStickyColumnStyle(col);
13453
+ }
13454
+ const descendants = getLeafColumns([col]);
13455
+ const stickyDescendants = descendants.filter((d) => d.fixed);
13456
+ if (stickyDescendants.length === 0) return {};
13457
+ const firstSticky = stickyDescendants[0];
13458
+ const lastSticky = stickyDescendants[stickyDescendants.length - 1];
13459
+ if (firstSticky.fixed === "left") {
13460
+ const pos = stickyPositions[firstSticky.key];
13461
+ return pos?.left !== void 0 ? { left: pos.left } : {};
13462
+ }
13463
+ if (lastSticky.fixed === "right") {
13464
+ const pos = stickyPositions[lastSticky.key];
13465
+ return pos?.right !== void 0 ? { right: pos.right } : {};
13466
+ }
13467
+ return {};
13468
+ },
13469
+ [stickyPositions, getStickyColumnStyle]
13470
+ );
13471
+ return {
13472
+ getStickyColumnStyle,
13473
+ getStickyHeaderClass,
13474
+ getStickyCellClass,
13475
+ getStickyHeaderCellStyle
13476
+ };
13477
+ }
13478
+
13479
+ // ../../components/ui/DataTable/utils/validation.ts
13480
+ function validateColumns(columns) {
13481
+ const warnings = [];
13482
+ const keys = /* @__PURE__ */ new Set();
13483
+ function validate(cols, path = "") {
13484
+ for (const col of cols) {
13485
+ const fullPath = path ? `${path}.${col.key}` : col.key;
13486
+ if (keys.has(col.key)) {
13487
+ warnings.push(`Duplicate key "${col.key}" at ${fullPath}`);
13488
+ }
13489
+ keys.add(col.key);
13490
+ const isGroup = col.children && col.children.length > 0;
13491
+ if (isGroup) {
13492
+ if (col.dataIndex) {
13493
+ warnings.push(`Group column "${fullPath}" has dataIndex (will be ignored)`);
13494
+ }
13495
+ if (col.sortable) {
13496
+ warnings.push(`Group column "${fullPath}" has sortable (will be ignored)`);
13497
+ }
13498
+ if (col.filter) {
13499
+ warnings.push(`Group column "${fullPath}" has filter (will be ignored)`);
13500
+ }
13501
+ if (col.render) {
13502
+ warnings.push(`Group column "${fullPath}" has render function (will be ignored)`);
13503
+ }
13504
+ if (col.colSpan !== void 0) {
13505
+ const actualColSpan = getColSpan(col);
13506
+ if (col.colSpan !== actualColSpan) {
13507
+ warnings.push(
13508
+ `Column "${fullPath}" has colSpan=${col.colSpan} but structure suggests ${actualColSpan} (based on ${col.children.length} children)`
13509
+ );
13510
+ }
13511
+ }
13512
+ if (col.fixed) {
13513
+ const conflictingChildren = col.children.filter((c) => c.fixed && c.fixed !== col.fixed);
13514
+ if (conflictingChildren.length > 0) {
13515
+ warnings.push(
13516
+ `Group column "${fullPath}" has fixed="${col.fixed}" but children have different fixed values: ${conflictingChildren.map((c) => c.key).join(", ")}`
13517
+ );
13518
+ }
13519
+ }
13520
+ validate(col.children, fullPath);
13521
+ } else {
13522
+ if (col.children !== void 0) {
13523
+ warnings.push(`Leaf column "${fullPath}" has children property (should be omitted for leaf columns)`);
13524
+ }
13525
+ }
13526
+ }
13527
+ }
13528
+ validate(columns);
13529
+ const depth = getHeaderDepth(columns);
13530
+ if (depth > 4) {
13531
+ warnings.push(`Header depth is ${depth} rows. Consider simplifying - too many header rows may impact user experience.`);
13532
+ }
13533
+ function checkMixedSticky(cols, parentPath = "") {
13534
+ for (const col of cols) {
13535
+ if (col.children && col.children.length > 0) {
13536
+ const childrenFixed = col.children.map((c) => c.fixed);
13537
+ const hasStickyChild = childrenFixed.some((f) => f !== void 0);
13538
+ const hasNonStickyChild = childrenFixed.some((f) => f === void 0);
13539
+ if (hasStickyChild && hasNonStickyChild) {
13540
+ const fullPath = parentPath ? `${parentPath}.${col.key}` : col.key;
13541
+ warnings.push(
13542
+ `Group column "${fullPath}" has mixed sticky children (some fixed, some not). This may cause visual separation when scrolling.`
13543
+ );
13544
+ }
13545
+ checkMixedSticky(col.children, parentPath ? `${parentPath}.${col.key}` : col.key);
13546
+ }
13547
+ }
13548
+ }
13549
+ checkMixedSticky(columns);
13550
+ return warnings;
13340
13551
  }
13341
13552
 
13342
13553
  // ../../components/ui/DataTable/DataTable.tsx
@@ -13372,6 +13583,12 @@ function DataTable({
13372
13583
  const [density, setDensity] = import_react35.default.useState("normal");
13373
13584
  const [curPage, setCurPage] = import_react35.default.useState(page);
13374
13585
  const { curPageSize, setCurPageSize } = usePageSizeStorage({ pageSize, storageKey });
13586
+ import_react35.default.useEffect(() => {
13587
+ if (process.env.NODE_ENV === "development") {
13588
+ const warnings = validateColumns(columns);
13589
+ warnings.forEach((w) => console.warn(`[DataTable] ${w}`));
13590
+ }
13591
+ }, [columns]);
13375
13592
  import_react35.default.useEffect(() => {
13376
13593
  const newColKeys = columns.filter((c) => c.visible !== false).map((c) => c.key);
13377
13594
  setVisibleCols((prev) => {
@@ -13396,11 +13613,19 @@ function DataTable({
13396
13613
  const densityRowClass = density === "compact" ? "h-9" : density === "comfortable" ? "h-14" : "h-12";
13397
13614
  const cellPadding = density === "compact" ? "py-1.5 px-3" : density === "comfortable" ? "py-3 px-4" : "py-2.5 px-4";
13398
13615
  const visibleColsSet = import_react35.default.useMemo(() => new Set(visibleCols), [visibleCols]);
13399
- const visibleColumns = columns.filter((c) => visibleColsSet.has(c.key));
13400
- const totalColumnsWidth = import_react35.default.useMemo(() => {
13401
- return visibleColumns.reduce((sum, col) => sum + getColumnWidth(col), 0);
13616
+ const visibleColumns = import_react35.default.useMemo(() => {
13617
+ return filterVisibleColumns(columns, visibleColsSet);
13618
+ }, [columns, visibleColsSet]);
13619
+ const leafColumns = import_react35.default.useMemo(() => {
13620
+ return getLeafColumns(visibleColumns);
13402
13621
  }, [visibleColumns]);
13403
- const { getStickyCellClass, getStickyColumnStyle, getStickyHeaderClass } = useStickyColumns(visibleColumns);
13622
+ const totalColumnsWidth = import_react35.default.useMemo(() => {
13623
+ return leafColumns.reduce((sum, col) => sum + getColumnWidth(col), 0);
13624
+ }, [leafColumns]);
13625
+ const { getStickyCellClass, getStickyColumnStyle, getStickyHeaderClass, getStickyHeaderCellStyle } = useStickyColumns(
13626
+ columns,
13627
+ visibleColsSet
13628
+ );
13404
13629
  const getRowKey = (row, idx) => {
13405
13630
  if (!rowKey) return String(idx);
13406
13631
  if (typeof rowKey === "function") return String(rowKey(row));
@@ -13456,127 +13681,150 @@ function DataTable({
13456
13681
  }
13457
13682
  return null;
13458
13683
  };
13459
- const renderHeader = /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableRow, { children: visibleColumns.map((col, colIdx) => {
13460
- const prevCol = colIdx > 0 ? visibleColumns[colIdx - 1] : null;
13684
+ const headerRows = import_react35.default.useMemo(() => buildHeaderRows(visibleColumns), [visibleColumns]);
13685
+ const renderHeaderContent = (col, isLeaf) => {
13686
+ if (!isLeaf) {
13687
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13688
+ "div",
13689
+ {
13690
+ className: cn(
13691
+ "flex items-center gap-1 min-h-10",
13692
+ col.align === "right" && "justify-end",
13693
+ col.align === "center" && "justify-center",
13694
+ !col.align && "justify-start"
13695
+ ),
13696
+ children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "font-medium text-sm whitespace-nowrap", children: col.title })
13697
+ }
13698
+ );
13699
+ }
13700
+ const isRightAlign = col.align === "right" || !col.align && headerAlign === "right";
13701
+ const isCenterAlign = col.align === "center" || !col.align && headerAlign === "center";
13702
+ const titleContent = /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex items-center gap-1", children: [
13703
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "font-medium text-sm whitespace-nowrap", children: col.title }),
13704
+ col.sortable && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13705
+ "button",
13706
+ {
13707
+ className: cn(
13708
+ "p-1 rounded-lg transition-all duration-200 hover:bg-accent",
13709
+ sort?.key === col.key ? "opacity-100 bg-accent" : "opacity-60 hover:opacity-100"
13710
+ ),
13711
+ onClick: () => {
13712
+ setCurPage(1);
13713
+ setSort((s) => {
13714
+ if (!s || s.key !== col.key) return { key: col.key, order: "asc" };
13715
+ if (s.order === "asc") return { key: col.key, order: "desc" };
13716
+ return null;
13717
+ });
13718
+ },
13719
+ "aria-label": "Sort",
13720
+ title: `Sort by ${String(col.title)}`,
13721
+ children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", className: "inline-block", children: [
13722
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13723
+ "path",
13724
+ {
13725
+ d: "M7 8l3-3 3 3",
13726
+ stroke: "currentColor",
13727
+ strokeWidth: "1.5",
13728
+ strokeLinecap: "round",
13729
+ strokeLinejoin: "round",
13730
+ opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
13731
+ }
13732
+ ),
13733
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13734
+ "path",
13735
+ {
13736
+ d: "M7 12l3 3 3-3",
13737
+ stroke: "currentColor",
13738
+ strokeWidth: "1.5",
13739
+ strokeLinecap: "round",
13740
+ strokeLinejoin: "round",
13741
+ opacity: sort?.key === col.key && sort.order === "desc" ? 1 : 0.4
13742
+ }
13743
+ )
13744
+ ] })
13745
+ }
13746
+ )
13747
+ ] });
13748
+ const filterContent = col.filter ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13749
+ Popover,
13750
+ {
13751
+ placement: "bottom-start",
13752
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13753
+ "button",
13754
+ {
13755
+ className: cn(
13756
+ "p-1.5 rounded-lg transition-all duration-200 hover:bg-accent",
13757
+ filters[col.key] ? "bg-accent text-primary" : "text-muted-foreground"
13758
+ ),
13759
+ "aria-label": "Filter",
13760
+ title: `Filter by ${String(col.title)}`,
13761
+ children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_lucide_react27.Filter, { className: "w-4 h-4" })
13762
+ }
13763
+ ),
13764
+ children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "p-3 w-64 space-y-3", children: [
13765
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex items-center justify-between", children: [
13766
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "text-sm font-medium", children: col.title }),
13767
+ filters[col.key] !== void 0 && filters[col.key] !== null && filters[col.key] !== "" && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13768
+ "button",
13769
+ {
13770
+ onClick: () => {
13771
+ setCurPage(1);
13772
+ setFilters((f) => ({ ...f, [col.key]: void 0 }));
13773
+ },
13774
+ className: "text-xs text-destructive hover:underline",
13775
+ children: t("clearFilter")
13776
+ }
13777
+ )
13778
+ ] }),
13779
+ renderFilterControl(col)
13780
+ ] })
13781
+ }
13782
+ ) : null;
13783
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13784
+ "div",
13785
+ {
13786
+ className: cn(
13787
+ "flex items-center gap-2 select-none min-h-10",
13788
+ isRightAlign && "justify-end",
13789
+ isCenterAlign && "justify-center",
13790
+ !isRightAlign && !isCenterAlign && "justify-start"
13791
+ ),
13792
+ children: isRightAlign ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_jsx_runtime59.Fragment, { children: [
13793
+ filterContent,
13794
+ titleContent
13795
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_jsx_runtime59.Fragment, { children: [
13796
+ titleContent,
13797
+ filterContent
13798
+ ] })
13799
+ }
13800
+ );
13801
+ };
13802
+ const renderHeader = /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_jsx_runtime59.Fragment, { children: headerRows.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableRow, { children: row.map((headerCell, cellIndex) => {
13803
+ const { column: col, colSpan, rowSpan, isLeaf } = headerCell;
13804
+ const prevCell = cellIndex > 0 ? row[cellIndex - 1] : null;
13805
+ const prevCol = prevCell?.column;
13461
13806
  const isAfterFixedLeft = prevCol?.fixed === "left";
13462
- const showBorderLeft = columnDividers && colIdx > 0 && !isAfterFixedLeft && !col.fixed;
13807
+ const showBorderLeft = columnDividers && cellIndex > 0 && !isAfterFixedLeft && !col.fixed;
13463
13808
  return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13464
13809
  TableHead,
13465
13810
  {
13466
- style: { width: col.width, ...getStickyColumnStyle(col) },
13811
+ colSpan,
13812
+ rowSpan,
13813
+ style: {
13814
+ width: col.width,
13815
+ ...getStickyHeaderCellStyle(headerCell)
13816
+ },
13467
13817
  className: cn(
13468
13818
  (col.align === "right" || !col.align && headerAlign === "right") && "text-right",
13469
13819
  (col.align === "center" || !col.align && headerAlign === "center") && "text-center",
13470
13820
  showBorderLeft && "border-l border-border/60",
13471
13821
  getStickyHeaderClass(col)
13472
13822
  ),
13473
- children: (() => {
13474
- const isRightAlign = col.align === "right" || !col.align && headerAlign === "right";
13475
- const isCenterAlign = col.align === "center" || !col.align && headerAlign === "center";
13476
- const titleContent = /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: cn("flex items-center gap-1", !col.fixed && "min-w-0 shrink"), children: [
13477
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: cn("font-medium text-sm", !col.fixed && "truncate"), children: col.title }),
13478
- col.sortable && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13479
- "button",
13480
- {
13481
- className: cn(
13482
- "p-1 rounded-lg transition-all duration-200 hover:bg-accent",
13483
- sort?.key === col.key ? "opacity-100 bg-accent" : "opacity-60 hover:opacity-100"
13484
- ),
13485
- onClick: () => {
13486
- setCurPage(1);
13487
- setSort((s) => {
13488
- if (!s || s.key !== col.key) return { key: col.key, order: "asc" };
13489
- if (s.order === "asc") return { key: col.key, order: "desc" };
13490
- return null;
13491
- });
13492
- },
13493
- "aria-label": "Sort",
13494
- title: `Sort by ${String(col.title)}`,
13495
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", className: "inline-block", children: [
13496
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13497
- "path",
13498
- {
13499
- d: "M7 8l3-3 3 3",
13500
- stroke: "currentColor",
13501
- strokeWidth: "1.5",
13502
- strokeLinecap: "round",
13503
- strokeLinejoin: "round",
13504
- opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
13505
- }
13506
- ),
13507
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13508
- "path",
13509
- {
13510
- d: "M7 12l3 3 3-3",
13511
- stroke: "currentColor",
13512
- strokeWidth: "1.5",
13513
- strokeLinecap: "round",
13514
- strokeLinejoin: "round",
13515
- opacity: sort?.key === col.key && sort.order === "desc" ? 1 : 0.4
13516
- }
13517
- )
13518
- ] })
13519
- }
13520
- )
13521
- ] });
13522
- const filterContent = col.filter ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13523
- Popover,
13524
- {
13525
- placement: "bottom-start",
13526
- trigger: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13527
- "button",
13528
- {
13529
- className: cn(
13530
- "p-1.5 rounded-lg transition-all duration-200 hover:bg-accent",
13531
- filters[col.key] ? "bg-accent text-primary" : "text-muted-foreground"
13532
- ),
13533
- "aria-label": "Filter",
13534
- title: `Filter by ${String(col.title)}`,
13535
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_lucide_react27.Filter, { className: "w-4 h-4" })
13536
- }
13537
- ),
13538
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "p-3 w-64 space-y-3", children: [
13539
- /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex items-center justify-between", children: [
13540
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "text-sm font-medium", children: col.title }),
13541
- filters[col.key] !== void 0 && filters[col.key] !== null && filters[col.key] !== "" && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13542
- "button",
13543
- {
13544
- onClick: () => {
13545
- setCurPage(1);
13546
- setFilters((f) => ({ ...f, [col.key]: void 0 }));
13547
- },
13548
- className: "text-xs text-destructive hover:underline",
13549
- children: t("clearFilter")
13550
- }
13551
- )
13552
- ] }),
13553
- renderFilterControl(col)
13554
- ] })
13555
- }
13556
- ) : null;
13557
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13558
- "div",
13559
- {
13560
- className: cn(
13561
- "flex items-center gap-2 select-none min-h-10",
13562
- isRightAlign && "justify-end",
13563
- isCenterAlign && "justify-center",
13564
- !isRightAlign && !isCenterAlign && "justify-start"
13565
- ),
13566
- children: isRightAlign ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_jsx_runtime59.Fragment, { children: [
13567
- filterContent,
13568
- titleContent
13569
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_jsx_runtime59.Fragment, { children: [
13570
- titleContent,
13571
- filterContent
13572
- ] })
13573
- }
13574
- );
13575
- })()
13823
+ children: renderHeaderContent(col, isLeaf)
13576
13824
  },
13577
13825
  col.key
13578
13826
  );
13579
- }) });
13827
+ }) }, `header-row-${rowIndex}`)) });
13580
13828
  const processedData = import_react35.default.useMemo(() => {
13581
13829
  if (isServerMode) return data;
13582
13830
  let result = [...data];
@@ -13652,7 +13900,7 @@ function DataTable({
13652
13900
  style: { minWidth: totalColumnsWidth > 0 ? `${totalColumnsWidth}px` : void 0 },
13653
13901
  children: [
13654
13902
  /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableHeader, { children: renderHeader }),
13655
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableBody, { children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableCell, { colSpan: visibleColumns.length, className: "text-center py-8", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex items-center justify-center gap-2 text-muted-foreground", children: [
13903
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableBody, { children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableCell, { colSpan: leafColumns.length, className: "text-center py-8", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex items-center justify-center gap-2 text-muted-foreground", children: [
13656
13904
  /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
13657
13905
  /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
13658
13906
  /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
@@ -13668,7 +13916,7 @@ function DataTable({
13668
13916
  t("loading"),
13669
13917
  "\u2026"
13670
13918
  ] })
13671
- ] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableCell, { colSpan: visibleColumns.length, className: "text-center py-6 text-muted-foreground", children: t("noData") }) }) : displayedData.map((row, idx) => {
13919
+ ] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TableCell, { colSpan: leafColumns.length, className: "text-center py-6 text-muted-foreground", children: t("noData") }) }) : displayedData.map((row, idx) => {
13672
13920
  const isLastRow = idx === displayedData.length - 1;
13673
13921
  return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13674
13922
  TableRow,
@@ -13678,10 +13926,10 @@ function DataTable({
13678
13926
  contentVisibility: "auto",
13679
13927
  containIntrinsicSize: density === "compact" ? "0 36px" : density === "comfortable" ? "0 56px" : "0 48px"
13680
13928
  },
13681
- children: visibleColumns.map((col, colIdx) => {
13929
+ children: leafColumns.map((col, colIdx) => {
13682
13930
  const value = col.dataIndex ? row[col.dataIndex] : void 0;
13683
13931
  const isStripedRow = striped && idx % 2 === 0;
13684
- const prevCol = colIdx > 0 ? visibleColumns[colIdx - 1] : null;
13932
+ const prevCol = colIdx > 0 ? leafColumns[colIdx - 1] : null;
13685
13933
  const isAfterFixedLeft = prevCol?.fixed === "left";
13686
13934
  const showBorderLeft = columnDividers && colIdx > 0 && !isAfterFixedLeft && !col.fixed;
13687
13935
  return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
@@ -13693,8 +13941,8 @@ function DataTable({
13693
13941
  col.align === "right" && "text-right",
13694
13942
  col.align === "center" && "text-center",
13695
13943
  showBorderLeft && "border-l border-border/60",
13696
- isLastRow && col === visibleColumns[0] && "rounded-bl-2xl md:rounded-bl-3xl",
13697
- isLastRow && col === visibleColumns[visibleColumns.length - 1] && "rounded-br-2xl md:rounded-br-3xl",
13944
+ isLastRow && col === leafColumns[0] && "rounded-bl-2xl md:rounded-bl-3xl",
13945
+ isLastRow && col === leafColumns[leafColumns.length - 1] && "rounded-br-2xl md:rounded-br-3xl",
13698
13946
  getStickyCellClass(col, isStripedRow),
13699
13947
  !col.fixed && isStripedRow && "bg-muted/50"
13700
13948
  ),
@@ -15057,6 +15305,1511 @@ function useSmartLocale() {
15057
15305
  }
15058
15306
  }
15059
15307
 
15308
+ // ../../components/ui/UEditor/UEditor.tsx
15309
+ var import_react44 = require("react");
15310
+ var import_next_intl6 = require("next-intl");
15311
+ var import_react45 = require("@tiptap/react");
15312
+
15313
+ // ../../components/ui/UEditor/extensions.ts
15314
+ var import_extension_document = __toESM(require("@tiptap/extension-document"), 1);
15315
+ var import_extension_paragraph = __toESM(require("@tiptap/extension-paragraph"), 1);
15316
+ var import_extension_text = __toESM(require("@tiptap/extension-text"), 1);
15317
+ var import_extension_bold = __toESM(require("@tiptap/extension-bold"), 1);
15318
+ var import_extension_italic = __toESM(require("@tiptap/extension-italic"), 1);
15319
+ var import_extension_strike = __toESM(require("@tiptap/extension-strike"), 1);
15320
+ var import_extension_underline = __toESM(require("@tiptap/extension-underline"), 1);
15321
+ var import_extension_heading = __toESM(require("@tiptap/extension-heading"), 1);
15322
+ var import_extension_bullet_list = __toESM(require("@tiptap/extension-bullet-list"), 1);
15323
+ var import_extension_ordered_list = __toESM(require("@tiptap/extension-ordered-list"), 1);
15324
+ var import_extension_list_item = __toESM(require("@tiptap/extension-list-item"), 1);
15325
+ var import_extension_task_list = __toESM(require("@tiptap/extension-task-list"), 1);
15326
+ var import_extension_task_item = __toESM(require("@tiptap/extension-task-item"), 1);
15327
+ var import_extension_blockquote = __toESM(require("@tiptap/extension-blockquote"), 1);
15328
+ var import_extension_code = __toESM(require("@tiptap/extension-code"), 1);
15329
+ var import_extension_code_block_lowlight = __toESM(require("@tiptap/extension-code-block-lowlight"), 1);
15330
+ var import_extension_history = __toESM(require("@tiptap/extension-history"), 1);
15331
+ var import_extension_placeholder = __toESM(require("@tiptap/extension-placeholder"), 1);
15332
+ var import_extension_link = __toESM(require("@tiptap/extension-link"), 1);
15333
+ var import_extension_image = __toESM(require("@tiptap/extension-image"), 1);
15334
+ var import_extension_text_style = require("@tiptap/extension-text-style");
15335
+ var import_extension_color = __toESM(require("@tiptap/extension-color"), 1);
15336
+ var import_extension_highlight = __toESM(require("@tiptap/extension-highlight"), 1);
15337
+ var import_extension_text_align = __toESM(require("@tiptap/extension-text-align"), 1);
15338
+ var import_extension_table = require("@tiptap/extension-table");
15339
+ var import_extension_table_row = __toESM(require("@tiptap/extension-table-row"), 1);
15340
+ var import_extension_table_cell = __toESM(require("@tiptap/extension-table-cell"), 1);
15341
+ var import_extension_table_header = __toESM(require("@tiptap/extension-table-header"), 1);
15342
+ var import_extension_character_count = __toESM(require("@tiptap/extension-character-count"), 1);
15343
+ var import_extension_typography = __toESM(require("@tiptap/extension-typography"), 1);
15344
+ var import_extension_subscript = __toESM(require("@tiptap/extension-subscript"), 1);
15345
+ var import_extension_superscript = __toESM(require("@tiptap/extension-superscript"), 1);
15346
+ var import_extension_horizontal_rule = __toESM(require("@tiptap/extension-horizontal-rule"), 1);
15347
+ var import_lowlight = require("lowlight");
15348
+
15349
+ // ../../components/ui/UEditor/slash-command.tsx
15350
+ var import_core = require("@tiptap/core");
15351
+ var import_suggestion = __toESM(require("@tiptap/suggestion"), 1);
15352
+ var import_react38 = require("@tiptap/react");
15353
+ var import_react39 = require("react");
15354
+ var import_lucide_react33 = require("lucide-react");
15355
+ var import_tippy = __toESM(require("tippy.js"), 1);
15356
+ var import_jsx_runtime68 = require("react/jsx-runtime");
15357
+ var CommandList = (0, import_react39.forwardRef)((props, ref) => {
15358
+ const [selectedIndex, setSelectedIndex] = (0, import_react39.useState)(0);
15359
+ const listRef = (0, import_react39.useRef)(null);
15360
+ (0, import_react39.useEffect)(() => {
15361
+ setSelectedIndex(0);
15362
+ }, [props.items]);
15363
+ (0, import_react39.useEffect)(() => {
15364
+ const selectedElement = listRef.current?.querySelector(`[data-index="${selectedIndex}"]`);
15365
+ selectedElement?.scrollIntoView({ block: "nearest" });
15366
+ }, [selectedIndex, props.items]);
15367
+ (0, import_react39.useImperativeHandle)(ref, () => ({
15368
+ onKeyDown: ({ event }) => {
15369
+ if (event.key === "ArrowUp") {
15370
+ setSelectedIndex((prev) => (prev + props.items.length - 1) % props.items.length);
15371
+ return true;
15372
+ }
15373
+ if (event.key === "ArrowDown") {
15374
+ setSelectedIndex((prev) => (prev + 1) % props.items.length);
15375
+ return true;
15376
+ }
15377
+ if (event.key === "Enter") {
15378
+ const item = props.items[selectedIndex];
15379
+ if (item) {
15380
+ props.command(item);
15381
+ }
15382
+ return true;
15383
+ }
15384
+ return false;
15385
+ }
15386
+ }));
15387
+ if (props.items.length === 0) {
15388
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "w-72 p-4 text-center text-sm text-muted-foreground", children: "No results" });
15389
+ }
15390
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { ref: listRef, className: "w-72 max-h-80 overflow-y-auto bg-card border border-border rounded-2xl shadow-lg", children: [
15391
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Basic Blocks" }) }),
15392
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "p-1", children: props.items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
15393
+ "button",
15394
+ {
15395
+ type: "button",
15396
+ "data-index": index,
15397
+ onClick: () => props.command(item),
15398
+ className: cn(
15399
+ "flex items-center w-full px-3 py-2.5 rounded-lg transition-colors group",
15400
+ selectedIndex === index ? "bg-accent" : "hover:bg-accent/50"
15401
+ ),
15402
+ children: [
15403
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
15404
+ "div",
15405
+ {
15406
+ className: cn(
15407
+ "flex items-center justify-center w-10 h-10 rounded-lg mr-3 transition-colors",
15408
+ selectedIndex === index ? "bg-primary/10" : "bg-muted/50 group-hover:bg-muted"
15409
+ ),
15410
+ children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(item.icon, { className: cn("w-5 h-5", selectedIndex === index ? "text-primary" : "text-muted-foreground") })
15411
+ }
15412
+ ),
15413
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "text-left", children: [
15414
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: cn("text-sm font-medium", selectedIndex === index && "text-primary"), children: item.title }),
15415
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "text-xs text-muted-foreground", children: item.description })
15416
+ ] })
15417
+ ]
15418
+ },
15419
+ item.title
15420
+ )) })
15421
+ ] });
15422
+ });
15423
+ CommandList.displayName = "CommandList";
15424
+ var getSuggestionItems = ({ query }) => {
15425
+ return [
15426
+ {
15427
+ icon: import_lucide_react33.Type,
15428
+ title: "Text",
15429
+ description: "Start writing with plain text",
15430
+ command: ({ editor, range }) => {
15431
+ editor.chain().focus().deleteRange(range).setParagraph().run();
15432
+ }
15433
+ },
15434
+ {
15435
+ icon: import_lucide_react33.Heading1,
15436
+ title: "Heading 1",
15437
+ description: "Large section heading",
15438
+ command: ({ editor, range }) => {
15439
+ editor.chain().focus().deleteRange(range).setNode("heading", { level: 1 }).run();
15440
+ }
15441
+ },
15442
+ {
15443
+ icon: import_lucide_react33.Heading2,
15444
+ title: "Heading 2",
15445
+ description: "Medium section heading",
15446
+ command: ({ editor, range }) => {
15447
+ editor.chain().focus().deleteRange(range).setNode("heading", { level: 2 }).run();
15448
+ }
15449
+ },
15450
+ {
15451
+ icon: import_lucide_react33.Heading3,
15452
+ title: "Heading 3",
15453
+ description: "Small section heading",
15454
+ command: ({ editor, range }) => {
15455
+ editor.chain().focus().deleteRange(range).setNode("heading", { level: 3 }).run();
15456
+ }
15457
+ },
15458
+ {
15459
+ icon: import_lucide_react33.List,
15460
+ title: "Bullet List",
15461
+ description: "Create a simple bullet list",
15462
+ command: ({ editor, range }) => {
15463
+ editor.chain().focus().deleteRange(range).toggleBulletList().run();
15464
+ }
15465
+ },
15466
+ {
15467
+ icon: import_lucide_react33.ListOrdered,
15468
+ title: "Numbered List",
15469
+ description: "Create a list with numbering",
15470
+ command: ({ editor, range }) => {
15471
+ editor.chain().focus().deleteRange(range).toggleOrderedList().run();
15472
+ }
15473
+ },
15474
+ {
15475
+ icon: import_lucide_react33.ListTodo,
15476
+ title: "Todo List",
15477
+ description: "Track tasks with a todo list",
15478
+ command: ({ editor, range }) => {
15479
+ editor.chain().focus().deleteRange(range).toggleTaskList().run();
15480
+ }
15481
+ },
15482
+ {
15483
+ icon: import_lucide_react33.Quote,
15484
+ title: "Quote",
15485
+ description: "Capture a quote",
15486
+ command: ({ editor, range }) => {
15487
+ editor.chain().focus().deleteRange(range).toggleBlockquote().run();
15488
+ }
15489
+ },
15490
+ {
15491
+ icon: import_lucide_react33.FileCode,
15492
+ title: "Code Block",
15493
+ description: "Display code with syntax highlighting",
15494
+ command: ({ editor, range }) => {
15495
+ editor.chain().focus().deleteRange(range).toggleCodeBlock().run();
15496
+ }
15497
+ },
15498
+ {
15499
+ icon: import_lucide_react33.Minus,
15500
+ title: "Divider",
15501
+ description: "Visually divide blocks",
15502
+ command: ({ editor, range }) => {
15503
+ editor.chain().focus().deleteRange(range).setHorizontalRule().run();
15504
+ }
15505
+ },
15506
+ {
15507
+ icon: import_lucide_react33.Table,
15508
+ title: "Table",
15509
+ description: "Insert a table",
15510
+ command: ({ editor, range }) => {
15511
+ editor.chain().focus().deleteRange(range).insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
15512
+ }
15513
+ }
15514
+ ].filter((item) => item.title.toLowerCase().includes(query.toLowerCase()));
15515
+ };
15516
+ var SlashCommand = import_core.Extension.create({
15517
+ name: "slashCommand",
15518
+ addProseMirrorPlugins() {
15519
+ return [
15520
+ (0, import_suggestion.default)({
15521
+ editor: this.editor,
15522
+ char: "/",
15523
+ command: ({ editor, range, props }) => {
15524
+ props.command({ editor, range });
15525
+ },
15526
+ items: getSuggestionItems,
15527
+ render: () => {
15528
+ let component;
15529
+ let popup;
15530
+ return {
15531
+ onStart: (props) => {
15532
+ component = new import_react38.ReactRenderer(CommandList, {
15533
+ props,
15534
+ editor: props.editor
15535
+ });
15536
+ if (!props.clientRect) {
15537
+ return;
15538
+ }
15539
+ popup = (0, import_tippy.default)("body", {
15540
+ getReferenceClientRect: props.clientRect,
15541
+ appendTo: () => document.body,
15542
+ content: component.element,
15543
+ showOnCreate: true,
15544
+ interactive: true,
15545
+ trigger: "manual",
15546
+ placement: "bottom-start"
15547
+ });
15548
+ },
15549
+ onUpdate(props) {
15550
+ component?.updateProps(props);
15551
+ if (!props.clientRect) {
15552
+ return;
15553
+ }
15554
+ popup?.[0]?.setProps({
15555
+ getReferenceClientRect: props.clientRect
15556
+ });
15557
+ },
15558
+ onKeyDown(props) {
15559
+ if (props.event.key === "Escape") {
15560
+ popup?.[0]?.hide();
15561
+ return true;
15562
+ }
15563
+ return component?.ref?.onKeyDown(props) ?? false;
15564
+ },
15565
+ onExit() {
15566
+ popup?.[0]?.destroy();
15567
+ component?.destroy();
15568
+ }
15569
+ };
15570
+ }
15571
+ })
15572
+ ];
15573
+ }
15574
+ });
15575
+
15576
+ // ../../components/ui/UEditor/extensions.ts
15577
+ var lowlight = (0, import_lowlight.createLowlight)(import_lowlight.common);
15578
+ function buildUEditorExtensions({ placeholder, maxCharacters }) {
15579
+ return [
15580
+ import_extension_document.default,
15581
+ import_extension_paragraph.default,
15582
+ import_extension_text.default,
15583
+ import_extension_bold.default,
15584
+ import_extension_italic.default,
15585
+ import_extension_strike.default,
15586
+ import_extension_underline.default,
15587
+ import_extension_subscript.default,
15588
+ import_extension_superscript.default,
15589
+ import_extension_heading.default.configure({
15590
+ levels: [1, 2, 3]
15591
+ }),
15592
+ import_extension_bullet_list.default.configure({
15593
+ HTMLAttributes: {
15594
+ class: "list-disc pl-6 my-2 space-y-1"
15595
+ }
15596
+ }),
15597
+ import_extension_ordered_list.default.configure({
15598
+ HTMLAttributes: {
15599
+ class: "list-decimal pl-6 my-2 space-y-1"
15600
+ }
15601
+ }),
15602
+ import_extension_list_item.default.configure({
15603
+ HTMLAttributes: {
15604
+ class: "pl-1"
15605
+ }
15606
+ }),
15607
+ import_extension_task_list.default,
15608
+ import_extension_task_item.default.configure({
15609
+ nested: true
15610
+ }),
15611
+ import_extension_blockquote.default.configure({
15612
+ HTMLAttributes: {
15613
+ class: "border-l-4 border-primary pl-4 py-2 my-4 bg-muted/30 rounded-r-lg italic text-muted-foreground"
15614
+ }
15615
+ }),
15616
+ import_extension_code.default.configure({
15617
+ HTMLAttributes: {
15618
+ class: "px-1.5 py-0.5 rounded bg-muted font-mono text-sm"
15619
+ }
15620
+ }),
15621
+ import_extension_code_block_lowlight.default.configure({
15622
+ lowlight,
15623
+ HTMLAttributes: {
15624
+ class: "rounded-lg bg-[#1e1e1e] p-4 font-mono text-sm overflow-x-auto"
15625
+ }
15626
+ }),
15627
+ import_extension_horizontal_rule.default,
15628
+ import_extension_link.default.configure({
15629
+ openOnClick: false,
15630
+ HTMLAttributes: {
15631
+ class: "text-primary underline underline-offset-2 hover:text-primary/80 cursor-pointer"
15632
+ }
15633
+ }),
15634
+ import_extension_image.default.configure({
15635
+ HTMLAttributes: {
15636
+ class: "rounded-lg max-w-full h-auto my-4"
15637
+ }
15638
+ }),
15639
+ import_extension_text_style.TextStyle,
15640
+ import_extension_color.default,
15641
+ import_extension_highlight.default.configure({
15642
+ multicolor: true
15643
+ }),
15644
+ import_extension_text_align.default.configure({
15645
+ types: ["heading", "paragraph"]
15646
+ }),
15647
+ import_extension_table.Table.configure({
15648
+ resizable: true,
15649
+ HTMLAttributes: {
15650
+ class: "border-collapse w-full my-4"
15651
+ }
15652
+ }),
15653
+ import_extension_table_row.default,
15654
+ import_extension_table_cell.default.configure({
15655
+ HTMLAttributes: {
15656
+ class: "border border-border p-2 min-w-[100px]"
15657
+ }
15658
+ }),
15659
+ import_extension_table_header.default.configure({
15660
+ HTMLAttributes: {
15661
+ class: "border border-border p-2 bg-muted font-semibold min-w-[100px]"
15662
+ }
15663
+ }),
15664
+ import_extension_character_count.default.configure({
15665
+ limit: maxCharacters
15666
+ }),
15667
+ import_extension_typography.default,
15668
+ import_extension_history.default,
15669
+ import_extension_placeholder.default.configure({
15670
+ placeholder,
15671
+ emptyEditorClass: "is-editor-empty",
15672
+ emptyNodeClass: "is-empty"
15673
+ }),
15674
+ SlashCommand
15675
+ ];
15676
+ }
15677
+
15678
+ // ../../components/ui/UEditor/toolbar.tsx
15679
+ var import_react42 = __toESM(require("react"), 1);
15680
+ var import_next_intl3 = require("next-intl");
15681
+ var import_lucide_react36 = require("lucide-react");
15682
+
15683
+ // ../../components/ui/UEditor/colors.tsx
15684
+ var import_react40 = require("react");
15685
+ var import_next_intl = require("next-intl");
15686
+ var import_lucide_react34 = require("lucide-react");
15687
+ var import_jsx_runtime69 = require("react/jsx-runtime");
15688
+ var useEditorColors = () => {
15689
+ const t = (0, import_next_intl.useTranslations)("UEditor");
15690
+ const textColors = (0, import_react40.useMemo)(
15691
+ () => [
15692
+ { name: t("colors.default"), color: "inherit", cssClass: "text-foreground" },
15693
+ { name: t("colors.muted"), color: "var(--muted-foreground)", cssClass: "text-muted-foreground" },
15694
+ { name: t("colors.primary"), color: "var(--primary)", cssClass: "text-primary" },
15695
+ { name: t("colors.secondary"), color: "var(--secondary)", cssClass: "text-secondary" },
15696
+ { name: t("colors.success"), color: "var(--success)", cssClass: "text-success" },
15697
+ { name: t("colors.warning"), color: "var(--warning)", cssClass: "text-warning" },
15698
+ { name: t("colors.destructive"), color: "var(--destructive)", cssClass: "text-destructive" },
15699
+ { name: t("colors.info"), color: "var(--info)", cssClass: "text-info" }
15700
+ ],
15701
+ [t]
15702
+ );
15703
+ const highlightColors = (0, import_react40.useMemo)(
15704
+ () => [
15705
+ { name: t("colors.default"), color: "", cssClass: "" },
15706
+ { name: t("colors.muted"), color: "var(--muted)", cssClass: "bg-muted" },
15707
+ { name: t("colors.primary"), color: "color-mix(in oklch, var(--primary) 20%, transparent)", cssClass: "bg-primary/20" },
15708
+ { name: t("colors.secondary"), color: "color-mix(in oklch, var(--secondary) 20%, transparent)", cssClass: "bg-secondary/20" },
15709
+ { name: t("colors.success"), color: "color-mix(in oklch, var(--success) 20%, transparent)", cssClass: "bg-success/20" },
15710
+ { name: t("colors.warning"), color: "color-mix(in oklch, var(--warning) 20%, transparent)", cssClass: "bg-warning/20" },
15711
+ { name: t("colors.destructive"), color: "color-mix(in oklch, var(--destructive) 20%, transparent)", cssClass: "bg-destructive/20" },
15712
+ { name: t("colors.info"), color: "color-mix(in oklch, var(--info) 20%, transparent)", cssClass: "bg-info/20" },
15713
+ { name: t("colors.accent"), color: "var(--accent)", cssClass: "bg-accent" }
15714
+ ],
15715
+ [t]
15716
+ );
15717
+ return { textColors, highlightColors };
15718
+ };
15719
+ var EditorColorPalette = ({
15720
+ colors,
15721
+ currentColor,
15722
+ onSelect,
15723
+ label
15724
+ }) => /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "p-2", children: [
15725
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider px-2", children: label }),
15726
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "grid grid-cols-4 gap-1.5 mt-2", children: colors.map((c) => /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
15727
+ "button",
15728
+ {
15729
+ type: "button",
15730
+ onMouseDown: (e) => e.preventDefault(),
15731
+ onClick: () => onSelect(c.color),
15732
+ className: cn(
15733
+ "flex items-center justify-center w-9 h-9 rounded-lg border-2 transition-all hover:scale-105",
15734
+ currentColor === c.color ? "border-primary ring-2 ring-primary/20" : "border-border/50 hover:border-primary/50"
15735
+ ),
15736
+ style: { backgroundColor: c.color || "transparent" },
15737
+ title: c.name,
15738
+ children: [
15739
+ c.color === "" && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react34.X, { className: "w-4 h-4 text-muted-foreground" }),
15740
+ c.color === "inherit" && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "text-xs font-medium", children: "A" })
15741
+ ]
15742
+ },
15743
+ c.name
15744
+ )) })
15745
+ ] });
15746
+
15747
+ // ../../components/ui/UEditor/inputs.tsx
15748
+ var import_react41 = require("react");
15749
+ var import_next_intl2 = require("next-intl");
15750
+ var import_lucide_react35 = require("lucide-react");
15751
+ var import_jsx_runtime70 = require("react/jsx-runtime");
15752
+ var LinkInput = ({
15753
+ onSubmit,
15754
+ onCancel,
15755
+ initialUrl = ""
15756
+ }) => {
15757
+ const t = (0, import_next_intl2.useTranslations)("UEditor");
15758
+ const [url, setUrl] = (0, import_react41.useState)(initialUrl);
15759
+ const inputRef = (0, import_react41.useRef)(null);
15760
+ (0, import_react41.useEffect)(() => {
15761
+ inputRef.current?.focus();
15762
+ inputRef.current?.select();
15763
+ }, []);
15764
+ const handleSubmit = (e) => {
15765
+ e.preventDefault();
15766
+ if (url) {
15767
+ onSubmit(url.startsWith("http") ? url : `https://${url}`);
15768
+ }
15769
+ };
15770
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("form", { onSubmit: handleSubmit, className: "flex items-center gap-2 p-2", children: [
15771
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
15772
+ "input",
15773
+ {
15774
+ ref: inputRef,
15775
+ type: "text",
15776
+ value: url,
15777
+ onChange: (e) => setUrl(e.target.value),
15778
+ placeholder: t("linkInput.placeholder"),
15779
+ className: "flex-1 px-3 py-2 text-sm bg-muted/50 border-0 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/20"
15780
+ }
15781
+ ),
15782
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("button", { type: "submit", className: "p-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_lucide_react35.Check, { className: "w-4 h-4" }) }),
15783
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("button", { type: "button", onClick: onCancel, className: "p-2 rounded-lg hover:bg-muted transition-colors text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_lucide_react35.X, { className: "w-4 h-4" }) })
15784
+ ] });
15785
+ };
15786
+ var ImageInput = ({ onSubmit, onCancel }) => {
15787
+ const t = (0, import_next_intl2.useTranslations)("UEditor");
15788
+ const [url, setUrl] = (0, import_react41.useState)("");
15789
+ const [alt, setAlt] = (0, import_react41.useState)("");
15790
+ const inputRef = (0, import_react41.useRef)(null);
15791
+ (0, import_react41.useEffect)(() => {
15792
+ inputRef.current?.focus();
15793
+ }, []);
15794
+ const handleSubmit = (e) => {
15795
+ e.preventDefault();
15796
+ if (url) {
15797
+ onSubmit(url, alt);
15798
+ }
15799
+ };
15800
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("form", { onSubmit: handleSubmit, className: "p-3 space-y-3", children: [
15801
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { children: [
15802
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("label", { className: "text-xs font-medium text-muted-foreground", children: t("imageInput.urlLabel") }),
15803
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
15804
+ "input",
15805
+ {
15806
+ ref: inputRef,
15807
+ type: "text",
15808
+ value: url,
15809
+ onChange: (e) => setUrl(e.target.value),
15810
+ placeholder: t("imageInput.urlPlaceholder"),
15811
+ className: "w-full mt-1 px-3 py-2 text-sm bg-muted/50 border-0 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/20"
15812
+ }
15813
+ )
15814
+ ] }),
15815
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { children: [
15816
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("label", { className: "text-xs font-medium text-muted-foreground", children: t("imageInput.altLabel") }),
15817
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
15818
+ "input",
15819
+ {
15820
+ type: "text",
15821
+ value: alt,
15822
+ onChange: (e) => setAlt(e.target.value),
15823
+ placeholder: t("imageInput.altPlaceholder"),
15824
+ className: "w-full mt-1 px-3 py-2 text-sm bg-muted/50 border-0 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/20"
15825
+ }
15826
+ )
15827
+ ] }),
15828
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "flex gap-2", children: [
15829
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
15830
+ "button",
15831
+ {
15832
+ type: "submit",
15833
+ disabled: !url,
15834
+ className: "flex-1 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50",
15835
+ children: t("imageInput.addBtn")
15836
+ }
15837
+ ),
15838
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("button", { type: "button", onClick: onCancel, className: "px-4 py-2 rounded-lg hover:bg-muted transition-colors text-muted-foreground", children: t("imageInput.cancelBtn") })
15839
+ ] })
15840
+ ] });
15841
+ };
15842
+
15843
+ // ../../components/ui/UEditor/toolbar.tsx
15844
+ var import_jsx_runtime71 = require("react/jsx-runtime");
15845
+ var ToolbarButton = import_react42.default.forwardRef(({ onClick, active, disabled, children, title, className }, ref) => {
15846
+ const button = /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
15847
+ "button",
15848
+ {
15849
+ ref,
15850
+ type: "button",
15851
+ onMouseDown: (e) => e.preventDefault(),
15852
+ onClick,
15853
+ disabled,
15854
+ className: cn(
15855
+ "flex items-center justify-center w-8 h-8 rounded-lg transition-all duration-200",
15856
+ "hover:bg-accent hover:scale-105",
15857
+ "focus:outline-none focus:ring-2 focus:ring-primary/20",
15858
+ "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:scale-100",
15859
+ active ? "bg-primary/10 text-primary shadow-sm" : "text-muted-foreground hover:text-foreground",
15860
+ className
15861
+ ),
15862
+ children
15863
+ }
15864
+ );
15865
+ if (title) {
15866
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Tooltip, { content: title, placement: "top", delay: { open: 500, close: 0 }, children: button });
15867
+ }
15868
+ return button;
15869
+ });
15870
+ ToolbarButton.displayName = "ToolbarButton";
15871
+ var ToolbarDivider = () => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" });
15872
+ var EditorToolbar = ({ editor, variant }) => {
15873
+ const t = (0, import_next_intl3.useTranslations)("UEditor");
15874
+ const { textColors, highlightColors } = useEditorColors();
15875
+ const [showImageInput, setShowImageInput] = (0, import_react42.useState)(false);
15876
+ if (variant === "minimal") {
15877
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "flex items-center gap-1 p-2 border-b bg-muted/30", children: [
15878
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Bold, { className: "w-4 h-4" }) }),
15879
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
15880
+ ToolbarButton,
15881
+ {
15882
+ onClick: () => editor.chain().focus().toggleItalic().run(),
15883
+ active: editor.isActive("italic"),
15884
+ title: t("toolbar.italic"),
15885
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Italic, { className: "w-4 h-4" })
15886
+ }
15887
+ ),
15888
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
15889
+ ToolbarButton,
15890
+ {
15891
+ onClick: () => editor.chain().focus().toggleBulletList().run(),
15892
+ active: editor.isActive("bulletList"),
15893
+ title: t("toolbar.bulletList"),
15894
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.List, { className: "w-4 h-4" })
15895
+ }
15896
+ )
15897
+ ] });
15898
+ }
15899
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "flex flex-wrap items-center gap-1 p-2 border-b bg-linear-to-r from-muted/30 to-transparent", children: [
15900
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
15901
+ DropdownMenu,
15902
+ {
15903
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(ToolbarButton, { onClick: () => {
15904
+ }, title: t("toolbar.textStyle"), className: "px-2 w-auto gap-1", children: [
15905
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Type, { className: "w-4 h-4" }),
15906
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.ChevronDown, { className: "w-3 h-3" })
15907
+ ] }),
15908
+ children: [
15909
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(DropdownMenuItem, { icon: import_lucide_react36.Type, label: t("toolbar.normal"), onClick: () => editor.chain().focus().setParagraph().run(), active: editor.isActive("paragraph") }),
15910
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
15911
+ DropdownMenuItem,
15912
+ {
15913
+ icon: import_lucide_react36.Heading1,
15914
+ label: t("toolbar.heading1"),
15915
+ onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
15916
+ active: editor.isActive("heading", { level: 1 }),
15917
+ shortcut: "Ctrl+Alt+1"
15918
+ }
15919
+ ),
15920
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
15921
+ DropdownMenuItem,
15922
+ {
15923
+ icon: import_lucide_react36.Heading2,
15924
+ label: t("toolbar.heading2"),
15925
+ onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
15926
+ active: editor.isActive("heading", { level: 2 }),
15927
+ shortcut: "Ctrl+Alt+2"
15928
+ }
15929
+ ),
15930
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
15931
+ DropdownMenuItem,
15932
+ {
15933
+ icon: import_lucide_react36.Heading3,
15934
+ label: t("toolbar.heading3"),
15935
+ onClick: () => editor.chain().focus().toggleHeading({ level: 3 }).run(),
15936
+ active: editor.isActive("heading", { level: 3 }),
15937
+ shortcut: "Ctrl+Alt+3"
15938
+ }
15939
+ )
15940
+ ]
15941
+ }
15942
+ ),
15943
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarDivider, {}),
15944
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Bold, { className: "w-4 h-4" }) }),
15945
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
15946
+ ToolbarButton,
15947
+ {
15948
+ onClick: () => editor.chain().focus().toggleItalic().run(),
15949
+ active: editor.isActive("italic"),
15950
+ title: t("toolbar.italic"),
15951
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Italic, { className: "w-4 h-4" })
15952
+ }
15953
+ ),
15954
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
15955
+ ToolbarButton,
15956
+ {
15957
+ onClick: () => editor.chain().focus().toggleUnderline().run(),
15958
+ active: editor.isActive("underline"),
15959
+ title: t("toolbar.underline"),
15960
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Underline, { className: "w-4 h-4" })
15961
+ }
15962
+ ),
15963
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
15964
+ ToolbarButton,
15965
+ {
15966
+ onClick: () => editor.chain().focus().toggleStrike().run(),
15967
+ active: editor.isActive("strike"),
15968
+ title: t("toolbar.strike"),
15969
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Strikethrough, { className: "w-4 h-4" })
15970
+ }
15971
+ ),
15972
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleCode().run(), active: editor.isActive("code"), title: t("toolbar.code"), children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Code, { className: "w-4 h-4" }) }),
15973
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarDivider, {}),
15974
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
15975
+ DropdownMenu,
15976
+ {
15977
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(ToolbarButton, { onClick: () => {
15978
+ }, title: t("colors.textColor"), children: [
15979
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Palette, { className: "w-4 h-4" }),
15980
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.ChevronDown, { className: "w-3 h-3" })
15981
+ ] }),
15982
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
15983
+ EditorColorPalette,
15984
+ {
15985
+ colors: textColors,
15986
+ currentColor: editor.getAttributes("textStyle").color || "inherit",
15987
+ onSelect: (color) => {
15988
+ if (color === "inherit") {
15989
+ editor.chain().focus().unsetColor().run();
15990
+ } else {
15991
+ editor.chain().focus().setColor(color).run();
15992
+ }
15993
+ },
15994
+ label: t("colors.textColor")
15995
+ }
15996
+ )
15997
+ }
15998
+ ),
15999
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16000
+ DropdownMenu,
16001
+ {
16002
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(ToolbarButton, { onClick: () => {
16003
+ }, active: editor.isActive("highlight"), title: t("colors.highlight"), children: [
16004
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Highlighter, { className: "w-4 h-4" }),
16005
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.ChevronDown, { className: "w-3 h-3" })
16006
+ ] }),
16007
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16008
+ EditorColorPalette,
16009
+ {
16010
+ colors: highlightColors,
16011
+ currentColor: editor.getAttributes("highlight").color || "",
16012
+ onSelect: (color) => {
16013
+ if (color === "") {
16014
+ editor.chain().focus().unsetHighlight().run();
16015
+ } else {
16016
+ editor.chain().focus().toggleHighlight({ color }).run();
16017
+ }
16018
+ },
16019
+ label: t("colors.highlight")
16020
+ }
16021
+ )
16022
+ }
16023
+ ),
16024
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarDivider, {}),
16025
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
16026
+ DropdownMenu,
16027
+ {
16028
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(ToolbarButton, { onClick: () => {
16029
+ }, title: t("toolbar.alignment"), children: [
16030
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.AlignLeft, { className: "w-4 h-4" }),
16031
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.ChevronDown, { className: "w-3 h-3" })
16032
+ ] }),
16033
+ children: [
16034
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16035
+ DropdownMenuItem,
16036
+ {
16037
+ icon: import_lucide_react36.AlignLeft,
16038
+ label: t("toolbar.alignLeft"),
16039
+ onClick: () => editor.chain().focus().setTextAlign("left").run(),
16040
+ active: editor.isActive({ textAlign: "left" })
16041
+ }
16042
+ ),
16043
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16044
+ DropdownMenuItem,
16045
+ {
16046
+ icon: import_lucide_react36.AlignCenter,
16047
+ label: t("toolbar.alignCenter"),
16048
+ onClick: () => editor.chain().focus().setTextAlign("center").run(),
16049
+ active: editor.isActive({ textAlign: "center" })
16050
+ }
16051
+ ),
16052
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16053
+ DropdownMenuItem,
16054
+ {
16055
+ icon: import_lucide_react36.AlignRight,
16056
+ label: t("toolbar.alignRight"),
16057
+ onClick: () => editor.chain().focus().setTextAlign("right").run(),
16058
+ active: editor.isActive({ textAlign: "right" })
16059
+ }
16060
+ ),
16061
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16062
+ DropdownMenuItem,
16063
+ {
16064
+ icon: import_lucide_react36.AlignJustify,
16065
+ label: t("toolbar.justify"),
16066
+ onClick: () => editor.chain().focus().setTextAlign("justify").run(),
16067
+ active: editor.isActive({ textAlign: "justify" })
16068
+ }
16069
+ )
16070
+ ]
16071
+ }
16072
+ ),
16073
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarDivider, {}),
16074
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
16075
+ DropdownMenu,
16076
+ {
16077
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(ToolbarButton, { onClick: () => {
16078
+ }, title: t("toolbar.bulletList"), children: [
16079
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.List, { className: "w-4 h-4" }),
16080
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.ChevronDown, { className: "w-3 h-3" })
16081
+ ] }),
16082
+ children: [
16083
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16084
+ DropdownMenuItem,
16085
+ {
16086
+ icon: import_lucide_react36.List,
16087
+ label: t("toolbar.bulletList"),
16088
+ onClick: () => editor.chain().focus().toggleBulletList().run(),
16089
+ active: editor.isActive("bulletList"),
16090
+ shortcut: "Ctrl+Shift+8"
16091
+ }
16092
+ ),
16093
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16094
+ DropdownMenuItem,
16095
+ {
16096
+ icon: import_lucide_react36.ListOrdered,
16097
+ label: t("toolbar.orderedList"),
16098
+ onClick: () => editor.chain().focus().toggleOrderedList().run(),
16099
+ active: editor.isActive("orderedList"),
16100
+ shortcut: "Ctrl+Shift+7"
16101
+ }
16102
+ ),
16103
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16104
+ DropdownMenuItem,
16105
+ {
16106
+ icon: import_lucide_react36.ListTodo,
16107
+ label: t("toolbar.taskList"),
16108
+ onClick: () => editor.chain().focus().toggleTaskList().run(),
16109
+ active: editor.isActive("taskList"),
16110
+ shortcut: "Ctrl+Shift+9"
16111
+ }
16112
+ )
16113
+ ]
16114
+ }
16115
+ ),
16116
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
16117
+ DropdownMenu,
16118
+ {
16119
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(ToolbarButton, { onClick: () => {
16120
+ }, title: t("toolbar.quote"), children: [
16121
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Quote, { className: "w-4 h-4" }),
16122
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.ChevronDown, { className: "w-3 h-3" })
16123
+ ] }),
16124
+ children: [
16125
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16126
+ DropdownMenuItem,
16127
+ {
16128
+ icon: import_lucide_react36.Quote,
16129
+ label: t("toolbar.quote"),
16130
+ onClick: () => editor.chain().focus().toggleBlockquote().run(),
16131
+ active: editor.isActive("blockquote"),
16132
+ shortcut: "Ctrl+Shift+B"
16133
+ }
16134
+ ),
16135
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16136
+ DropdownMenuItem,
16137
+ {
16138
+ icon: import_lucide_react36.FileCode,
16139
+ label: t("toolbar.codeBlock"),
16140
+ onClick: () => editor.chain().focus().toggleCodeBlock().run(),
16141
+ active: editor.isActive("codeBlock"),
16142
+ shortcut: "Ctrl+Alt+C"
16143
+ }
16144
+ )
16145
+ ]
16146
+ }
16147
+ ),
16148
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16149
+ DropdownMenu,
16150
+ {
16151
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(ToolbarButton, { onClick: () => {
16152
+ }, title: t("toolbar.image"), children: [
16153
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Image, { className: "w-4 h-4" }),
16154
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.ChevronDown, { className: "w-3 h-3" })
16155
+ ] }),
16156
+ children: showImageInput ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16157
+ ImageInput,
16158
+ {
16159
+ onSubmit: (url, alt) => {
16160
+ editor.chain().focus().setImage({ src: url, alt }).run();
16161
+ setShowImageInput(false);
16162
+ },
16163
+ onCancel: () => setShowImageInput(false)
16164
+ }
16165
+ ) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(DropdownMenuItem, { icon: import_lucide_react36.Link, label: t("imageInput.addFromUrl"), onClick: () => setShowImageInput(true) })
16166
+ }
16167
+ ),
16168
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
16169
+ DropdownMenu,
16170
+ {
16171
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(ToolbarButton, { onClick: () => {
16172
+ }, title: t("toolbar.table"), children: [
16173
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Table, { className: "w-4 h-4" }),
16174
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.ChevronDown, { className: "w-3 h-3" })
16175
+ ] }),
16176
+ children: [
16177
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(DropdownMenuItem, { icon: import_lucide_react36.Table, label: t("tableMenu.insert3x3"), onClick: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run() }),
16178
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "my-1 border-t" }),
16179
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16180
+ DropdownMenuItem,
16181
+ {
16182
+ icon: import_lucide_react36.ArrowDown,
16183
+ label: t("tableMenu.addColumnBefore"),
16184
+ onClick: () => editor.chain().focus().addColumnBefore().run(),
16185
+ disabled: !editor.can().addColumnBefore()
16186
+ }
16187
+ ),
16188
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16189
+ DropdownMenuItem,
16190
+ {
16191
+ icon: import_lucide_react36.ArrowDown,
16192
+ label: t("tableMenu.addColumnAfter"),
16193
+ onClick: () => editor.chain().focus().addColumnAfter().run(),
16194
+ disabled: !editor.can().addColumnAfter()
16195
+ }
16196
+ ),
16197
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16198
+ DropdownMenuItem,
16199
+ {
16200
+ icon: import_lucide_react36.ArrowRight,
16201
+ label: t("tableMenu.addRowBefore"),
16202
+ onClick: () => editor.chain().focus().addRowBefore().run(),
16203
+ disabled: !editor.can().addRowBefore()
16204
+ }
16205
+ ),
16206
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16207
+ DropdownMenuItem,
16208
+ {
16209
+ icon: import_lucide_react36.ArrowRight,
16210
+ label: t("tableMenu.addRowAfter"),
16211
+ onClick: () => editor.chain().focus().addRowAfter().run(),
16212
+ disabled: !editor.can().addRowAfter()
16213
+ }
16214
+ ),
16215
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "my-1 border-t" }),
16216
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16217
+ DropdownMenuItem,
16218
+ {
16219
+ icon: import_lucide_react36.Trash2,
16220
+ label: t("tableMenu.deleteColumn"),
16221
+ onClick: () => editor.chain().focus().deleteColumn().run(),
16222
+ disabled: !editor.can().deleteColumn()
16223
+ }
16224
+ ),
16225
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(DropdownMenuItem, { icon: import_lucide_react36.Trash2, label: t("tableMenu.deleteRow"), onClick: () => editor.chain().focus().deleteRow().run(), disabled: !editor.can().deleteRow() }),
16226
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
16227
+ DropdownMenuItem,
16228
+ {
16229
+ icon: import_lucide_react36.Trash2,
16230
+ label: t("tableMenu.deleteTable"),
16231
+ onClick: () => editor.chain().focus().deleteTable().run(),
16232
+ disabled: !editor.can().deleteTable()
16233
+ }
16234
+ )
16235
+ ]
16236
+ }
16237
+ ),
16238
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarDivider, {}),
16239
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleSubscript().run(), active: editor.isActive("subscript"), title: t("toolbar.subscript"), children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Subscript, { className: "w-4 h-4" }) }),
16240
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleSuperscript().run(), active: editor.isActive("superscript"), title: t("toolbar.superscript"), children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Superscript, { className: "w-4 h-4" }) }),
16241
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarDivider, {}),
16242
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().undo().run(), disabled: !editor.can().undo(), title: t("toolbar.undo"), children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Undo, { className: "w-4 h-4" }) }),
16243
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().redo().run(), disabled: !editor.can().redo(), title: t("toolbar.redo"), children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react36.Redo, { className: "w-4 h-4" }) })
16244
+ ] });
16245
+ };
16246
+
16247
+ // ../../components/ui/UEditor/menus.tsx
16248
+ var import_react43 = require("react");
16249
+ var import_react_dom9 = require("react-dom");
16250
+ var import_next_intl4 = require("next-intl");
16251
+ var import_lucide_react37 = require("lucide-react");
16252
+ var import_jsx_runtime72 = require("react/jsx-runtime");
16253
+ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
16254
+ const t = (0, import_next_intl4.useTranslations)("UEditor");
16255
+ const [selectedIndex, setSelectedIndex] = (0, import_react43.useState)(0);
16256
+ const menuRef = (0, import_react43.useRef)(null);
16257
+ const allCommands = (0, import_react43.useMemo)(
16258
+ () => [
16259
+ {
16260
+ icon: import_lucide_react37.Type,
16261
+ label: t("slashCommand.text"),
16262
+ description: t("slashCommand.textDesc"),
16263
+ action: () => editor.chain().focus().setParagraph().run()
16264
+ },
16265
+ {
16266
+ icon: import_lucide_react37.Heading1,
16267
+ label: t("slashCommand.heading1"),
16268
+ description: t("slashCommand.heading1Desc"),
16269
+ action: () => editor.chain().focus().toggleHeading({ level: 1 }).run()
16270
+ },
16271
+ {
16272
+ icon: import_lucide_react37.Heading2,
16273
+ label: t("slashCommand.heading2"),
16274
+ description: t("slashCommand.heading2Desc"),
16275
+ action: () => editor.chain().focus().toggleHeading({ level: 2 }).run()
16276
+ },
16277
+ {
16278
+ icon: import_lucide_react37.Heading3,
16279
+ label: t("slashCommand.heading3"),
16280
+ description: t("slashCommand.heading3Desc"),
16281
+ action: () => editor.chain().focus().toggleHeading({ level: 3 }).run()
16282
+ },
16283
+ {
16284
+ icon: import_lucide_react37.List,
16285
+ label: t("slashCommand.bulletList"),
16286
+ description: t("slashCommand.bulletListDesc"),
16287
+ action: () => editor.chain().focus().toggleBulletList().run()
16288
+ },
16289
+ {
16290
+ icon: import_lucide_react37.ListOrdered,
16291
+ label: t("slashCommand.orderedList"),
16292
+ description: t("slashCommand.orderedListDesc"),
16293
+ action: () => editor.chain().focus().toggleOrderedList().run()
16294
+ },
16295
+ {
16296
+ icon: import_lucide_react37.ListTodo,
16297
+ label: t("slashCommand.todoList"),
16298
+ description: t("slashCommand.todoListDesc"),
16299
+ action: () => editor.chain().focus().toggleTaskList().run()
16300
+ },
16301
+ {
16302
+ icon: import_lucide_react37.Quote,
16303
+ label: t("slashCommand.quote"),
16304
+ description: t("slashCommand.quoteDesc"),
16305
+ action: () => editor.chain().focus().toggleBlockquote().run()
16306
+ },
16307
+ {
16308
+ icon: import_lucide_react37.FileCode,
16309
+ label: t("slashCommand.codeBlock"),
16310
+ description: t("slashCommand.codeBlockDesc"),
16311
+ action: () => editor.chain().focus().toggleCodeBlock().run()
16312
+ },
16313
+ {
16314
+ icon: import_lucide_react37.Minus,
16315
+ label: t("slashCommand.divider"),
16316
+ description: t("slashCommand.dividerDesc"),
16317
+ action: () => editor.chain().focus().setHorizontalRule().run()
16318
+ },
16319
+ {
16320
+ icon: import_lucide_react37.Table,
16321
+ label: t("slashCommand.table"),
16322
+ description: t("slashCommand.tableDesc"),
16323
+ action: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()
16324
+ }
16325
+ ],
16326
+ [editor, t]
16327
+ );
16328
+ const commands = (0, import_react43.useMemo)(() => {
16329
+ if (!filterText) return allCommands;
16330
+ const lowerFilter = filterText.toLowerCase();
16331
+ return allCommands.filter((cmd) => cmd.label.toLowerCase().includes(lowerFilter) || cmd.description.toLowerCase().includes(lowerFilter));
16332
+ }, [allCommands, filterText]);
16333
+ (0, import_react43.useEffect)(() => {
16334
+ setSelectedIndex(0);
16335
+ }, [filterText]);
16336
+ (0, import_react43.useEffect)(() => {
16337
+ const selectedElement = menuRef.current?.querySelector(`[data-index="${selectedIndex}"]`);
16338
+ selectedElement?.scrollIntoView({ block: "nearest" });
16339
+ }, [selectedIndex]);
16340
+ const selectCommand = (0, import_react43.useCallback)(
16341
+ (index) => {
16342
+ const command = commands[index];
16343
+ if (command) {
16344
+ command.action();
16345
+ onClose();
16346
+ }
16347
+ },
16348
+ [commands, onClose]
16349
+ );
16350
+ (0, import_react43.useEffect)(() => {
16351
+ const handleKeyDown = (e) => {
16352
+ if (commands.length === 0) return;
16353
+ if (e.key === "ArrowDown") {
16354
+ e.preventDefault();
16355
+ setSelectedIndex((prev) => (prev + 1) % commands.length);
16356
+ } else if (e.key === "ArrowUp") {
16357
+ e.preventDefault();
16358
+ setSelectedIndex((prev) => (prev - 1 + commands.length) % commands.length);
16359
+ } else if (e.key === "Enter") {
16360
+ e.preventDefault();
16361
+ selectCommand(selectedIndex);
16362
+ } else if (e.key === "Escape") {
16363
+ e.preventDefault();
16364
+ onClose();
16365
+ }
16366
+ };
16367
+ document.addEventListener("keydown", handleKeyDown);
16368
+ return () => document.removeEventListener("keydown", handleKeyDown);
16369
+ }, [commands, selectedIndex, selectCommand, onClose]);
16370
+ if (commands.length === 0) {
16371
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "w-72 p-4 text-center text-muted-foreground text-sm", children: t("slashCommand.noResults") });
16372
+ }
16373
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { ref: menuRef, className: "w-72 max-h-80 overflow-y-auto", children: [
16374
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("span", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: t("slashCommand.basicBlocks") }) }),
16375
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "p-1", children: commands.map((cmd, index) => /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
16376
+ "button",
16377
+ {
16378
+ type: "button",
16379
+ "data-index": index,
16380
+ onMouseDown: (e) => e.preventDefault(),
16381
+ onClick: () => selectCommand(index),
16382
+ onMouseEnter: () => setSelectedIndex(index),
16383
+ className: cn(
16384
+ "flex items-center w-full px-3 py-2.5 rounded-lg transition-colors group",
16385
+ selectedIndex === index ? "bg-accent" : "hover:bg-accent/50"
16386
+ ),
16387
+ children: [
16388
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
16389
+ "div",
16390
+ {
16391
+ className: cn(
16392
+ "flex items-center justify-center w-10 h-10 rounded-lg mr-3 transition-colors",
16393
+ selectedIndex === index ? "bg-primary/10" : "bg-muted/50 group-hover:bg-muted"
16394
+ ),
16395
+ children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(cmd.icon, { className: cn("w-5 h-5", selectedIndex === index ? "text-primary" : "text-muted-foreground") })
16396
+ }
16397
+ ),
16398
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "text-left", children: [
16399
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: cn("text-sm font-medium", selectedIndex === index && "text-primary"), children: cmd.label }),
16400
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "text-xs text-muted-foreground", children: cmd.description })
16401
+ ] })
16402
+ ]
16403
+ },
16404
+ cmd.label
16405
+ )) })
16406
+ ] });
16407
+ };
16408
+ var FloatingMenuContent = ({ editor }) => {
16409
+ const t = (0, import_next_intl4.useTranslations)("UEditor");
16410
+ const [showCommands, setShowCommands] = (0, import_react43.useState)(false);
16411
+ if (showCommands) {
16412
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(SlashCommandMenu, { editor, onClose: () => setShowCommands(false) });
16413
+ }
16414
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
16415
+ "button",
16416
+ {
16417
+ type: "button",
16418
+ onClick: () => setShowCommands(true),
16419
+ className: "flex items-center gap-1 px-2 py-1.5 rounded-lg hover:bg-accent transition-all group",
16420
+ children: [
16421
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_lucide_react37.Plus, { className: "w-4 h-4 text-muted-foreground group-hover:text-foreground" }),
16422
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("span", { className: "text-sm text-muted-foreground group-hover:text-foreground", children: t("floatingMenu.addBlock") })
16423
+ ]
16424
+ }
16425
+ );
16426
+ };
16427
+ var BubbleMenuContent = ({ editor }) => {
16428
+ const t = (0, import_next_intl4.useTranslations)("UEditor");
16429
+ const { textColors, highlightColors } = useEditorColors();
16430
+ const [showLinkInput, setShowLinkInput] = (0, import_react43.useState)(false);
16431
+ const [showEditorColorPalette, setShowEditorColorPalette] = (0, import_react43.useState)(false);
16432
+ if (showLinkInput) {
16433
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
16434
+ LinkInput,
16435
+ {
16436
+ initialUrl: editor.getAttributes("link").href || "",
16437
+ onSubmit: (url) => {
16438
+ editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
16439
+ },
16440
+ onCancel: () => setShowLinkInput(false)
16441
+ }
16442
+ );
16443
+ }
16444
+ if (showEditorColorPalette) {
16445
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "w-48", children: [
16446
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
16447
+ EditorColorPalette,
16448
+ {
16449
+ colors: textColors,
16450
+ currentColor: editor.getAttributes("textStyle").color || "inherit",
16451
+ onSelect: (color) => {
16452
+ if (color === "inherit") {
16453
+ editor.chain().focus().unsetColor().run();
16454
+ } else {
16455
+ editor.chain().focus().setColor(color).run();
16456
+ }
16457
+ },
16458
+ label: t("colors.textColor")
16459
+ }
16460
+ ),
16461
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "border-t my-1" }),
16462
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
16463
+ EditorColorPalette,
16464
+ {
16465
+ colors: highlightColors,
16466
+ currentColor: editor.getAttributes("highlight").color || "",
16467
+ onSelect: (color) => {
16468
+ if (color === "") {
16469
+ editor.chain().focus().unsetHighlight().run();
16470
+ } else {
16471
+ editor.chain().focus().toggleHighlight({ color }).run();
16472
+ }
16473
+ },
16474
+ label: t("colors.highlight")
16475
+ }
16476
+ ),
16477
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "p-2 border-t", children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
16478
+ "button",
16479
+ {
16480
+ type: "button",
16481
+ onClick: () => setShowEditorColorPalette(false),
16482
+ className: "w-full py-1.5 text-sm rounded-lg hover:bg-muted transition-colors",
16483
+ children: t("colors.done")
16484
+ }
16485
+ ) })
16486
+ ] });
16487
+ }
16488
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "flex items-center gap-0.5 p-1", children: [
16489
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_lucide_react37.Bold, { className: "w-4 h-4" }) }),
16490
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_lucide_react37.Italic, { className: "w-4 h-4" }) }),
16491
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
16492
+ ToolbarButton,
16493
+ {
16494
+ onClick: () => editor.chain().focus().toggleUnderline().run(),
16495
+ active: editor.isActive("underline"),
16496
+ title: t("toolbar.underline"),
16497
+ children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_lucide_react37.Underline, { className: "w-4 h-4" })
16498
+ }
16499
+ ),
16500
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleStrike().run(), active: editor.isActive("strike"), title: t("toolbar.strike"), children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_lucide_react37.Strikethrough, { className: "w-4 h-4" }) }),
16501
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleCode().run(), active: editor.isActive("code"), title: t("toolbar.code"), children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_lucide_react37.Code, { className: "w-4 h-4" }) }),
16502
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" }),
16503
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ToolbarButton, { onClick: () => setShowLinkInput(true), active: editor.isActive("link"), title: t("toolbar.link"), children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_lucide_react37.Link, { className: "w-4 h-4" }) }),
16504
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ToolbarButton, { onClick: () => setShowEditorColorPalette(true), title: t("colors.textColor"), children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_lucide_react37.Palette, { className: "w-4 h-4" }) }),
16505
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" }),
16506
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
16507
+ ToolbarButton,
16508
+ {
16509
+ onClick: () => editor.chain().focus().toggleSubscript().run(),
16510
+ active: editor.isActive("subscript"),
16511
+ title: t("toolbar.subscript"),
16512
+ children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_lucide_react37.Subscript, { className: "w-4 h-4" })
16513
+ }
16514
+ ),
16515
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
16516
+ ToolbarButton,
16517
+ {
16518
+ onClick: () => editor.chain().focus().toggleSuperscript().run(),
16519
+ active: editor.isActive("superscript"),
16520
+ title: t("toolbar.superscript"),
16521
+ children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_lucide_react37.Superscript, { className: "w-4 h-4" })
16522
+ }
16523
+ )
16524
+ ] });
16525
+ };
16526
+ var CustomBubbleMenu = ({ editor }) => {
16527
+ const [isVisible, setIsVisible] = (0, import_react43.useState)(false);
16528
+ const [position, setPosition] = (0, import_react43.useState)({ top: 0, left: 0 });
16529
+ const menuRef = (0, import_react43.useRef)(null);
16530
+ (0, import_react43.useEffect)(() => {
16531
+ const updatePosition = () => {
16532
+ const { state, view } = editor;
16533
+ const { from, to, empty } = state.selection;
16534
+ if (empty || !view.hasFocus()) {
16535
+ setIsVisible(false);
16536
+ return;
16537
+ }
16538
+ const start = view.coordsAtPos(from);
16539
+ const end = view.coordsAtPos(to);
16540
+ const left = (start.left + end.left) / 2;
16541
+ const top = start.top - 10;
16542
+ setPosition({ top, left });
16543
+ setIsVisible(true);
16544
+ };
16545
+ const handleBlur = () => setIsVisible(false);
16546
+ editor.on("selectionUpdate", updatePosition);
16547
+ editor.on("focus", updatePosition);
16548
+ editor.on("blur", handleBlur);
16549
+ return () => {
16550
+ editor.off("selectionUpdate", updatePosition);
16551
+ editor.off("focus", updatePosition);
16552
+ editor.off("blur", handleBlur);
16553
+ };
16554
+ }, [editor]);
16555
+ if (!isVisible) return null;
16556
+ return (0, import_react_dom9.createPortal)(
16557
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
16558
+ "div",
16559
+ {
16560
+ ref: menuRef,
16561
+ className: "fixed z-50 flex rounded-2xl border border-border bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 zoom-in-95",
16562
+ style: {
16563
+ top: `${position.top}px`,
16564
+ left: `${position.left}px`,
16565
+ transform: "translate(-50%, -100%)"
16566
+ },
16567
+ onMouseDown: (e) => e.preventDefault(),
16568
+ children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(BubbleMenuContent, { editor })
16569
+ }
16570
+ ),
16571
+ document.body
16572
+ );
16573
+ };
16574
+ var CustomFloatingMenu = ({ editor }) => {
16575
+ const [isVisible, setIsVisible] = (0, import_react43.useState)(false);
16576
+ const [position, setPosition] = (0, import_react43.useState)({ top: 0, left: 0 });
16577
+ (0, import_react43.useEffect)(() => {
16578
+ const updatePosition = () => {
16579
+ const { state, view } = editor;
16580
+ const { $from, empty } = state.selection;
16581
+ const isEmptyTextBlock = $from.parent.isTextblock && $from.parent.type.name === "paragraph" && $from.parent.textContent === "" && empty;
16582
+ if (!isEmptyTextBlock || !view.hasFocus()) {
16583
+ setIsVisible(false);
16584
+ return;
16585
+ }
16586
+ const coords = view.coordsAtPos($from.pos);
16587
+ setPosition({ top: coords.top - 10, left: coords.left });
16588
+ setIsVisible(true);
16589
+ };
16590
+ const handleBlur = () => setIsVisible(false);
16591
+ editor.on("selectionUpdate", updatePosition);
16592
+ editor.on("focus", updatePosition);
16593
+ editor.on("blur", handleBlur);
16594
+ editor.on("update", updatePosition);
16595
+ return () => {
16596
+ editor.off("selectionUpdate", updatePosition);
16597
+ editor.off("focus", updatePosition);
16598
+ editor.off("blur", handleBlur);
16599
+ editor.off("update", updatePosition);
16600
+ };
16601
+ }, [editor]);
16602
+ if (!isVisible) return null;
16603
+ return (0, import_react_dom9.createPortal)(
16604
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
16605
+ "div",
16606
+ {
16607
+ className: "fixed z-50 rounded-2xl border border-border bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 slide-in-from-bottom-2",
16608
+ style: {
16609
+ top: `${position.top}px`,
16610
+ left: `${position.left}px`,
16611
+ transform: "translate(-50%, -100%)"
16612
+ },
16613
+ onMouseDown: (e) => e.preventDefault(),
16614
+ children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(FloatingMenuContent, { editor })
16615
+ }
16616
+ ),
16617
+ document.body
16618
+ );
16619
+ };
16620
+
16621
+ // ../../components/ui/UEditor/CharacterCount.tsx
16622
+ var import_next_intl5 = require("next-intl");
16623
+ var import_jsx_runtime73 = require("react/jsx-runtime");
16624
+ var CharacterCountDisplay = ({ editor, maxCharacters }) => {
16625
+ const t = (0, import_next_intl5.useTranslations)("UEditor");
16626
+ const storage = editor.storage;
16627
+ const characterCount = storage.characterCount?.characters?.() ?? 0;
16628
+ const wordCount = storage.characterCount?.words?.() ?? 0;
16629
+ const percentage = maxCharacters ? Math.round(characterCount / maxCharacters * 100) : 0;
16630
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "flex items-center gap-3 px-3 py-2 text-xs text-muted-foreground border-t bg-muted/20", children: [
16631
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("span", { children: [
16632
+ wordCount,
16633
+ " ",
16634
+ t("words")
16635
+ ] }),
16636
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("span", { children: [
16637
+ characterCount,
16638
+ " ",
16639
+ t("characters")
16640
+ ] }),
16641
+ maxCharacters && /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("span", { className: cn(percentage > 90 && "text-destructive", percentage > 100 && "font-bold"), children: [
16642
+ characterCount,
16643
+ "/",
16644
+ maxCharacters
16645
+ ] })
16646
+ ] });
16647
+ };
16648
+
16649
+ // ../../components/ui/UEditor/UEditor.tsx
16650
+ var import_jsx_runtime74 = require("react/jsx-runtime");
16651
+ var UEditor = ({
16652
+ content = "",
16653
+ onChange,
16654
+ onHtmlChange,
16655
+ onJsonChange,
16656
+ placeholder,
16657
+ className,
16658
+ editable = true,
16659
+ autofocus = false,
16660
+ showToolbar = true,
16661
+ showBubbleMenu = true,
16662
+ showFloatingMenu = false,
16663
+ showCharacterCount = true,
16664
+ maxCharacters,
16665
+ minHeight = "200px",
16666
+ maxHeight = "auto",
16667
+ variant = "default"
16668
+ }) => {
16669
+ const t = (0, import_next_intl6.useTranslations)("UEditor");
16670
+ const effectivePlaceholder = placeholder ?? t("placeholder");
16671
+ const extensions = (0, import_react44.useMemo)(
16672
+ () => buildUEditorExtensions({ placeholder: effectivePlaceholder, maxCharacters }),
16673
+ [effectivePlaceholder, maxCharacters]
16674
+ );
16675
+ const editor = (0, import_react45.useEditor)({
16676
+ immediatelyRender: false,
16677
+ extensions,
16678
+ content,
16679
+ editable,
16680
+ autofocus,
16681
+ editorProps: {
16682
+ handleDOMEvents: {
16683
+ keydown: (_view, event) => {
16684
+ if (!(event instanceof KeyboardEvent)) return false;
16685
+ if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
16686
+ event.stopPropagation();
16687
+ }
16688
+ return false;
16689
+ }
16690
+ },
16691
+ attributes: {
16692
+ class: cn(
16693
+ "prose prose-sm sm:prose dark:prose-invert max-w-none",
16694
+ "focus:outline-none",
16695
+ "px-4 py-4",
16696
+ "[&_.is-editor-empty]:before:content-[attr(data-placeholder)]",
16697
+ "[&_.is-editor-empty]:before:text-muted-foreground/50",
16698
+ "[&_.is-editor-empty]:before:float-left",
16699
+ "[&_.is-editor-empty]:before:pointer-events-none",
16700
+ "[&_.is-editor-empty]:before:h-0",
16701
+ "[&_ul[data-type='taskList']]:list-none",
16702
+ "[&_ul[data-type='taskList']]:pl-0",
16703
+ "[&_ul[data-type='taskList']_li]:flex",
16704
+ "[&_ul[data-type='taskList']_li]:items-start",
16705
+ "[&_ul[data-type='taskList']_li]:gap-2",
16706
+ "[&_ul[data-type='taskList']_li>label]:mt-0.5",
16707
+ "[&_ul[data-type='taskList']_li>label>input]:w-4",
16708
+ "[&_ul[data-type='taskList']_li>label>input]:h-4",
16709
+ "[&_ul[data-type='taskList']_li>label>input]:rounded",
16710
+ "[&_ul[data-type='taskList']_li>label>input]:border-2",
16711
+ "[&_ul[data-type='taskList']_li>label>input]:border-primary/50",
16712
+ "[&_ul[data-type='taskList']_li>label>input]:accent-primary",
16713
+ "[&_pre]:!bg-[#1e1e1e]",
16714
+ "[&_pre]:!text-[#d4d4d4]",
16715
+ "[&_pre_code]:!bg-transparent",
16716
+ "[&_hr]:border-t-2",
16717
+ "[&_hr]:border-primary/30",
16718
+ "[&_hr]:my-8",
16719
+ "[&_h1]:text-3xl",
16720
+ "[&_h1]:font-bold",
16721
+ "[&_h1]:mt-6",
16722
+ "[&_h1]:mb-4",
16723
+ "[&_h1]:text-foreground",
16724
+ "[&_h2]:text-2xl",
16725
+ "[&_h2]:font-semibold",
16726
+ "[&_h2]:mt-5",
16727
+ "[&_h2]:mb-3",
16728
+ "[&_h2]:text-foreground",
16729
+ "[&_h3]:text-xl",
16730
+ "[&_h3]:font-semibold",
16731
+ "[&_h3]:mt-4",
16732
+ "[&_h3]:mb-2",
16733
+ "[&_h3]:text-foreground",
16734
+ "[&_ul:not([data-type='taskList'])]:list-disc",
16735
+ "[&_ul:not([data-type='taskList'])]:pl-6",
16736
+ "[&_ul:not([data-type='taskList'])]:my-3",
16737
+ "[&_ol]:list-decimal",
16738
+ "[&_ol]:pl-6",
16739
+ "[&_ol]:my-3",
16740
+ "[&_li]:my-1",
16741
+ "[&_li]:pl-1",
16742
+ "[&_li_p]:my-0",
16743
+ "[&_blockquote]:border-l-4",
16744
+ "[&_blockquote]:border-primary",
16745
+ "[&_blockquote]:pl-4",
16746
+ "[&_blockquote]:py-2",
16747
+ "[&_blockquote]:my-4",
16748
+ "[&_blockquote]:bg-muted/30",
16749
+ "[&_blockquote]:rounded-r-lg",
16750
+ "[&_blockquote]:italic",
16751
+ "[&_blockquote]:text-muted-foreground",
16752
+ "[&_blockquote_p]:my-0"
16753
+ )
16754
+ }
16755
+ },
16756
+ onUpdate: ({ editor: editor2 }) => {
16757
+ const html = editor2.getHTML();
16758
+ onChange?.(html);
16759
+ onHtmlChange?.(html);
16760
+ onJsonChange?.(editor2.getJSON());
16761
+ }
16762
+ });
16763
+ (0, import_react44.useEffect)(() => {
16764
+ if (editor && content !== editor.getHTML()) {
16765
+ if (editor.isEmpty && content) {
16766
+ editor.commands.setContent(content);
16767
+ }
16768
+ }
16769
+ }, [content, editor]);
16770
+ if (!editor) {
16771
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
16772
+ "div",
16773
+ {
16774
+ className: cn("w-full rounded-lg border bg-background flex items-center justify-center text-muted-foreground", className),
16775
+ style: { minHeight },
16776
+ children: t("loading")
16777
+ }
16778
+ );
16779
+ }
16780
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
16781
+ "div",
16782
+ {
16783
+ className: cn(
16784
+ "group relative flex flex-col rounded-2xl md:rounded-3xl border border-border bg-card text-card-foreground overflow-hidden",
16785
+ "transition-[transform,box-shadow,border-color,background-color] duration-300 ease-soft",
16786
+ "shadow-sm focus-within:shadow-md focus-within:border-primary/15",
16787
+ "backdrop-blur-sm",
16788
+ variant === "notion" && "hover:shadow-md",
16789
+ className
16790
+ ),
16791
+ children: [
16792
+ editable && showToolbar && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(EditorToolbar, { editor, variant }),
16793
+ editable && showBubbleMenu && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(CustomBubbleMenu, { editor }),
16794
+ editable && showFloatingMenu && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(CustomFloatingMenu, { editor }),
16795
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
16796
+ import_react45.EditorContent,
16797
+ {
16798
+ editor,
16799
+ className: "flex-1 overflow-y-auto",
16800
+ style: {
16801
+ minHeight,
16802
+ maxHeight
16803
+ }
16804
+ }
16805
+ ),
16806
+ showCharacterCount && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(CharacterCountDisplay, { editor, maxCharacters })
16807
+ ]
16808
+ }
16809
+ );
16810
+ };
16811
+ var UEditor_default = UEditor;
16812
+
15060
16813
  // src/index.ts
15061
16814
  var underverseMessages = { en: en_default, vi: vi_default, ko: ko_default, ja: ja_default };
15062
16815
  function getUnderverseMessages(locale = "en") {
@@ -15193,6 +16946,7 @@ function getUnderverseMessages(locale = "en") {
15193
16946
  ToastProvider,
15194
16947
  Tooltip,
15195
16948
  TranslationProvider,
16949
+ UEditor,
15196
16950
  UnderverseProvider,
15197
16951
  VARIANT_STYLES_ALERT,
15198
16952
  VARIANT_STYLES_BTN,