@underverse-ui/underverse 1.0.50 → 1.0.51

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@underverse-ui/underverse",
3
- "version": "1.0.50",
3
+ "version": "1.0.51",
4
4
  "sourceEntry": "src/index.ts",
5
5
  "totalExports": 239,
6
6
  "exports": [
package/dist/index.cjs CHANGED
@@ -937,6 +937,11 @@ var en_default = {
937
937
  cancelBtn: "Cancel",
938
938
  addFromUrl: "Add from URL"
939
939
  },
940
+ emojiPicker: {
941
+ searchPlaceholder: "Search emoji",
942
+ noResults: "No emoji found",
943
+ tryDifferentSearch: "Try a different keyword"
944
+ },
940
945
  tableMenu: {
941
946
  insert3x3: "Insert 3\xD73 Table",
942
947
  addColumnBefore: "Add Column Before",
@@ -1156,6 +1161,11 @@ var vi_default = {
1156
1161
  cancelBtn: "H\u1EE7y",
1157
1162
  addFromUrl: "Th\xEAm t\u1EEB URL"
1158
1163
  },
1164
+ emojiPicker: {
1165
+ searchPlaceholder: "T\xECm ki\u1EBFm bi\u1EC3u t\u01B0\u1EE3ng c\u1EA3m x\xFAc",
1166
+ noResults: "Kh\xF4ng t\xECm th\u1EA5y emoji",
1167
+ tryDifferentSearch: "Th\u1EED t\u1EEB kh\xF3a kh\xE1c"
1168
+ },
1159
1169
  tableMenu: {
1160
1170
  insert3x3: "Ch\xE8n b\u1EA3ng 3\xD73",
1161
1171
  addColumnBefore: "Th\xEAm c\u1ED9t tr\u01B0\u1EDBc",
@@ -1374,6 +1384,11 @@ var ko_default = {
1374
1384
  cancelBtn: "\uCDE8\uC18C",
1375
1385
  addFromUrl: "URL\uC5D0\uC11C \uCD94\uAC00"
1376
1386
  },
1387
+ emojiPicker: {
1388
+ searchPlaceholder: "\uC774\uBAA8\uC9C0 \uAC80\uC0C9",
1389
+ noResults: "\uC774\uBAA8\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4",
1390
+ tryDifferentSearch: "\uB2E4\uB978 \uAC80\uC0C9\uC5B4\uB97C \uC2DC\uB3C4\uD574 \uBCF4\uC138\uC694"
1391
+ },
1377
1392
  tableMenu: {
1378
1393
  insert3x3: "3x3 \uD45C \uC0BD\uC785",
1379
1394
  addColumnBefore: "\uC55E\uC5D0 \uC5F4 \uCD94\uAC00",
@@ -1592,6 +1607,11 @@ var ja_default = {
1592
1607
  cancelBtn: "\u30AD\u30E3\u30F3\u30BB\u30EB",
1593
1608
  addFromUrl: "URL\u304B\u3089\u8FFD\u52A0"
1594
1609
  },
1610
+ emojiPicker: {
1611
+ searchPlaceholder: "\u7D75\u6587\u5B57\u3092\u691C\u7D22",
1612
+ noResults: "\u7D75\u6587\u5B57\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093",
1613
+ tryDifferentSearch: "\u5225\u306E\u30AD\u30FC\u30EF\u30FC\u30C9\u3067\u304A\u8A66\u3057\u304F\u3060\u3055\u3044"
1614
+ },
1595
1615
  tableMenu: {
1596
1616
  insert3x3: "3x3 \u8868\u3092\u633F\u5165",
1597
1617
  addColumnBefore: "\u524D\u306B\u5217\u3092\u8FFD\u52A0",
@@ -1613,6 +1633,25 @@ var defaultTranslations = {
1613
1633
  ko: ko_default,
1614
1634
  ja: ja_default
1615
1635
  };
1636
+ function resolveTranslationValue(translations, namespace, key) {
1637
+ const parts = namespace.split(".");
1638
+ let current = translations;
1639
+ for (const part of parts) {
1640
+ if (current && typeof current === "object" && part in current) {
1641
+ current = current[part];
1642
+ } else {
1643
+ return null;
1644
+ }
1645
+ }
1646
+ if (current && typeof current === "object" && key in current) {
1647
+ const value = current[key];
1648
+ return typeof value === "string" ? value : null;
1649
+ }
1650
+ return null;
1651
+ }
1652
+ function getUnderverseDefaultTranslation(locale, namespace, key) {
1653
+ return resolveTranslationValue(defaultTranslations[locale] ?? defaultTranslations.en, namespace, key) ?? resolveTranslationValue(defaultTranslations.en, namespace, key) ?? key;
1654
+ }
1616
1655
  var TranslationContext = React4.createContext(null);
1617
1656
  var TranslationProvider = ({ children, locale = "en", translations }) => {
1618
1657
  const t = React4.useCallback(
@@ -1622,20 +1661,7 @@ var TranslationProvider = ({ children, locale = "en", translations }) => {
1622
1661
  ...defaultTranslations[locale],
1623
1662
  ...translations?.[locale]
1624
1663
  };
1625
- const parts = namespace.split(".");
1626
- let current = mergedTranslations;
1627
- for (const part of parts) {
1628
- if (current && typeof current === "object" && part in current) {
1629
- current = current[part];
1630
- } else {
1631
- return key;
1632
- }
1633
- }
1634
- if (current && typeof current === "object" && key in current) {
1635
- const value = current[key];
1636
- return typeof value === "string" ? value : key;
1637
- }
1638
- return key;
1664
+ return resolveTranslationValue(mergedTranslations, namespace, key) ?? key;
1639
1665
  };
1640
1666
  },
1641
1667
  [locale, translations]
@@ -1646,20 +1672,7 @@ var useUnderverseTranslations = (namespace) => {
1646
1672
  const context = React4.useContext(TranslationContext);
1647
1673
  if (!context) {
1648
1674
  return (key) => {
1649
- const parts = namespace.split(".");
1650
- let current = defaultTranslations.en;
1651
- for (const part of parts) {
1652
- if (current && typeof current === "object" && part in current) {
1653
- current = current[part];
1654
- } else {
1655
- return key;
1656
- }
1657
- }
1658
- if (current && typeof current === "object" && key in current) {
1659
- const value = current[key];
1660
- return typeof value === "string" ? value : key;
1661
- }
1662
- return key;
1675
+ return getUnderverseDefaultTranslation("en", namespace, key);
1663
1676
  };
1664
1677
  }
1665
1678
  return context.t(namespace);
@@ -1685,17 +1698,53 @@ var ForceInternalContext = React5.createContext(false);
1685
1698
  var ForceInternalTranslationsProvider = ({ children }) => {
1686
1699
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ForceInternalContext.Provider, { value: true, children });
1687
1700
  };
1701
+ function normalizeLocale(locale, fallback) {
1702
+ const normalized = locale?.toLowerCase().split("-")[0];
1703
+ if (normalized === "en" || normalized === "vi" || normalized === "ko" || normalized === "ja") {
1704
+ return normalized;
1705
+ }
1706
+ return fallback;
1707
+ }
1708
+ function isUnresolvedTranslation(value, namespace, key) {
1709
+ return value === key || value === `${namespace}.${key}`;
1710
+ }
1688
1711
  function useSmartTranslations(namespace) {
1689
1712
  const forceInternal = React5.useContext(ForceInternalContext);
1690
1713
  const internalT = useUnderverseTranslations(namespace);
1714
+ const internalLocale = useUnderverseLocale();
1691
1715
  if (forceInternal || !nextIntlHooks?.useTranslations) {
1692
1716
  return internalT;
1693
1717
  }
1718
+ let resolvedLocale = internalLocale;
1719
+ try {
1720
+ resolvedLocale = normalizeLocale(nextIntlHooks.useLocale?.(), internalLocale);
1721
+ } catch {
1722
+ resolvedLocale = internalLocale;
1723
+ }
1694
1724
  try {
1695
1725
  const nextIntlT = nextIntlHooks.useTranslations(namespace);
1696
- return nextIntlT;
1726
+ return (key) => {
1727
+ try {
1728
+ const translated = nextIntlT(key);
1729
+ if (!isUnresolvedTranslation(translated, namespace, key)) {
1730
+ return translated;
1731
+ }
1732
+ } catch {
1733
+ }
1734
+ const internalValue = internalT(key);
1735
+ if (internalValue !== key) {
1736
+ return internalValue;
1737
+ }
1738
+ return getUnderverseDefaultTranslation(resolvedLocale, namespace, key);
1739
+ };
1697
1740
  } catch {
1698
- return internalT;
1741
+ return (key) => {
1742
+ const internalValue = internalT(key);
1743
+ if (internalValue !== key) {
1744
+ return internalValue;
1745
+ }
1746
+ return getUnderverseDefaultTranslation(resolvedLocale, namespace, key);
1747
+ };
1699
1748
  }
1700
1749
  }
1701
1750
  function useSmartLocale() {
@@ -22525,7 +22574,6 @@ var import_extension_blockquote = __toESM(require("@tiptap/extension-blockquote"
22525
22574
  var import_extension_code = __toESM(require("@tiptap/extension-code"), 1);
22526
22575
  var import_extension_code_block_lowlight = __toESM(require("@tiptap/extension-code-block-lowlight"), 1);
22527
22576
  var import_extension_history = __toESM(require("@tiptap/extension-history"), 1);
22528
- var import_extension_placeholder = __toESM(require("@tiptap/extension-placeholder"), 1);
22529
22577
  var import_extension_link = __toESM(require("@tiptap/extension-link"), 1);
22530
22578
  var import_extension_text_style = require("@tiptap/extension-text-style");
22531
22579
  var import_extension_color = __toESM(require("@tiptap/extension-color"), 1);
@@ -22550,6 +22598,32 @@ var import_react47 = require("react");
22550
22598
  var import_lucide_react39 = require("lucide-react");
22551
22599
  var import_tippy = __toESM(require("tippy.js"), 1);
22552
22600
  var import_jsx_runtime79 = require("react/jsx-runtime");
22601
+ var DEFAULT_MESSAGES = {
22602
+ noResults: "No results",
22603
+ basicBlocks: "Basic Blocks",
22604
+ text: "Text",
22605
+ textDesc: "Start writing with plain text",
22606
+ heading1: "Heading 1",
22607
+ heading1Desc: "Large section heading",
22608
+ heading2: "Heading 2",
22609
+ heading2Desc: "Medium section heading",
22610
+ heading3: "Heading 3",
22611
+ heading3Desc: "Small section heading",
22612
+ bulletList: "Bullet List",
22613
+ bulletListDesc: "Create a simple bullet list",
22614
+ orderedList: "Numbered List",
22615
+ orderedListDesc: "Create a list with numbering",
22616
+ todoList: "Todo List",
22617
+ todoListDesc: "Track tasks with a todo list",
22618
+ quote: "Quote",
22619
+ quoteDesc: "Capture a quote",
22620
+ codeBlock: "Code Block",
22621
+ codeBlockDesc: "Display code with syntax highlighting",
22622
+ divider: "Divider",
22623
+ dividerDesc: "Visually divide blocks",
22624
+ table: "Table",
22625
+ tableDesc: "Insert a table"
22626
+ };
22553
22627
  var CommandList = (0, import_react47.forwardRef)((props, ref) => {
22554
22628
  const [selectedIndex, setSelectedIndex] = (0, import_react47.useState)(0);
22555
22629
  const listRef = (0, import_react47.useRef)(null);
@@ -22581,10 +22655,10 @@ var CommandList = (0, import_react47.forwardRef)((props, ref) => {
22581
22655
  }
22582
22656
  }));
22583
22657
  if (props.items.length === 0) {
22584
- return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "w-72 p-4 text-center text-sm text-muted-foreground", children: "No results" });
22658
+ return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "w-72 p-4 text-center text-sm text-muted-foreground", children: props.messages.noResults });
22585
22659
  }
22586
22660
  return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { ref: listRef, className: "w-72 max-h-80 overflow-y-auto bg-card border border-border rounded-2xl shadow-lg", children: [
22587
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("span", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Basic Blocks" }) }),
22661
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("span", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: props.messages.basicBlocks }) }),
22588
22662
  /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "p-1", children: props.items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(
22589
22663
  "button",
22590
22664
  {
@@ -22617,92 +22691,92 @@ var CommandList = (0, import_react47.forwardRef)((props, ref) => {
22617
22691
  ] });
22618
22692
  });
22619
22693
  CommandList.displayName = "CommandList";
22620
- var getSuggestionItems = ({ query }) => {
22694
+ var getSuggestionItems = ({ query, messages }) => {
22621
22695
  return [
22622
22696
  {
22623
22697
  icon: import_lucide_react39.Type,
22624
- title: "Text",
22625
- description: "Start writing with plain text",
22698
+ title: messages.text,
22699
+ description: messages.textDesc,
22626
22700
  command: ({ editor, range }) => {
22627
22701
  editor.chain().focus().deleteRange(range).setParagraph().run();
22628
22702
  }
22629
22703
  },
22630
22704
  {
22631
22705
  icon: import_lucide_react39.Heading1,
22632
- title: "Heading 1",
22633
- description: "Large section heading",
22706
+ title: messages.heading1,
22707
+ description: messages.heading1Desc,
22634
22708
  command: ({ editor, range }) => {
22635
22709
  editor.chain().focus().deleteRange(range).setNode("heading", { level: 1 }).run();
22636
22710
  }
22637
22711
  },
22638
22712
  {
22639
22713
  icon: import_lucide_react39.Heading2,
22640
- title: "Heading 2",
22641
- description: "Medium section heading",
22714
+ title: messages.heading2,
22715
+ description: messages.heading2Desc,
22642
22716
  command: ({ editor, range }) => {
22643
22717
  editor.chain().focus().deleteRange(range).setNode("heading", { level: 2 }).run();
22644
22718
  }
22645
22719
  },
22646
22720
  {
22647
22721
  icon: import_lucide_react39.Heading3,
22648
- title: "Heading 3",
22649
- description: "Small section heading",
22722
+ title: messages.heading3,
22723
+ description: messages.heading3Desc,
22650
22724
  command: ({ editor, range }) => {
22651
22725
  editor.chain().focus().deleteRange(range).setNode("heading", { level: 3 }).run();
22652
22726
  }
22653
22727
  },
22654
22728
  {
22655
22729
  icon: import_lucide_react39.List,
22656
- title: "Bullet List",
22657
- description: "Create a simple bullet list",
22730
+ title: messages.bulletList,
22731
+ description: messages.bulletListDesc,
22658
22732
  command: ({ editor, range }) => {
22659
22733
  editor.chain().focus().deleteRange(range).toggleBulletList().run();
22660
22734
  }
22661
22735
  },
22662
22736
  {
22663
22737
  icon: import_lucide_react39.ListOrdered,
22664
- title: "Numbered List",
22665
- description: "Create a list with numbering",
22738
+ title: messages.orderedList,
22739
+ description: messages.orderedListDesc,
22666
22740
  command: ({ editor, range }) => {
22667
22741
  editor.chain().focus().deleteRange(range).toggleOrderedList().run();
22668
22742
  }
22669
22743
  },
22670
22744
  {
22671
22745
  icon: import_lucide_react39.ListTodo,
22672
- title: "Todo List",
22673
- description: "Track tasks with a todo list",
22746
+ title: messages.todoList,
22747
+ description: messages.todoListDesc,
22674
22748
  command: ({ editor, range }) => {
22675
22749
  editor.chain().focus().deleteRange(range).toggleTaskList().run();
22676
22750
  }
22677
22751
  },
22678
22752
  {
22679
22753
  icon: import_lucide_react39.Quote,
22680
- title: "Quote",
22681
- description: "Capture a quote",
22754
+ title: messages.quote,
22755
+ description: messages.quoteDesc,
22682
22756
  command: ({ editor, range }) => {
22683
22757
  editor.chain().focus().deleteRange(range).toggleBlockquote().run();
22684
22758
  }
22685
22759
  },
22686
22760
  {
22687
22761
  icon: import_lucide_react39.FileCode,
22688
- title: "Code Block",
22689
- description: "Display code with syntax highlighting",
22762
+ title: messages.codeBlock,
22763
+ description: messages.codeBlockDesc,
22690
22764
  command: ({ editor, range }) => {
22691
22765
  editor.chain().focus().deleteRange(range).toggleCodeBlock().run();
22692
22766
  }
22693
22767
  },
22694
22768
  {
22695
22769
  icon: import_lucide_react39.Minus,
22696
- title: "Divider",
22697
- description: "Visually divide blocks",
22770
+ title: messages.divider,
22771
+ description: messages.dividerDesc,
22698
22772
  command: ({ editor, range }) => {
22699
22773
  editor.chain().focus().deleteRange(range).setHorizontalRule().run();
22700
22774
  }
22701
22775
  },
22702
22776
  {
22703
22777
  icon: import_lucide_react39.Table,
22704
- title: "Table",
22705
- description: "Insert a table",
22778
+ title: messages.table,
22779
+ description: messages.tableDesc,
22706
22780
  command: ({ editor, range }) => {
22707
22781
  editor.chain().focus().deleteRange(range).insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
22708
22782
  }
@@ -22711,7 +22785,13 @@ var getSuggestionItems = ({ query }) => {
22711
22785
  };
22712
22786
  var SlashCommand = import_core.Extension.create({
22713
22787
  name: "slashCommand",
22788
+ addOptions() {
22789
+ return {
22790
+ messages: DEFAULT_MESSAGES
22791
+ };
22792
+ },
22714
22793
  addProseMirrorPlugins() {
22794
+ const messages = this.options.messages;
22715
22795
  return [
22716
22796
  (0, import_suggestion.default)({
22717
22797
  editor: this.editor,
@@ -22719,14 +22799,17 @@ var SlashCommand = import_core.Extension.create({
22719
22799
  command: ({ editor, range, props }) => {
22720
22800
  props.command({ editor, range });
22721
22801
  },
22722
- items: getSuggestionItems,
22802
+ items: ({ query, editor }) => getSuggestionItems({ query, editor, messages }),
22723
22803
  render: () => {
22724
22804
  let component;
22725
22805
  let popup;
22726
22806
  return {
22727
22807
  onStart: (props) => {
22728
22808
  component = new import_react46.ReactRenderer(CommandList, {
22729
- props,
22809
+ props: {
22810
+ ...props,
22811
+ messages
22812
+ },
22730
22813
  editor: props.editor
22731
22814
  });
22732
22815
  if (!props.clientRect) {
@@ -22743,7 +22826,10 @@ var SlashCommand = import_core.Extension.create({
22743
22826
  });
22744
22827
  },
22745
22828
  onUpdate(props) {
22746
- component?.updateProps(props);
22829
+ component?.updateProps({
22830
+ ...props,
22831
+ messages
22832
+ });
22747
22833
  if (!props.clientRect) {
22748
22834
  return;
22749
22835
  }
@@ -23776,10 +23862,83 @@ var EmojiSuggestion = import_core3.Extension.create({
23776
23862
  }
23777
23863
  });
23778
23864
 
23865
+ // src/components/UEditor/placeholder.ts
23866
+ var import_core4 = require("@tiptap/core");
23867
+ var import_state3 = require("@tiptap/pm/state");
23868
+ var import_view = require("@tiptap/pm/view");
23869
+ var UEditorPlaceholder = import_core4.Extension.create({
23870
+ name: "placeholder",
23871
+ addOptions() {
23872
+ return {
23873
+ emptyEditorClass: "is-editor-empty",
23874
+ emptyNodeClass: "is-empty",
23875
+ dataAttribute: "placeholder",
23876
+ placeholder: "Write something...",
23877
+ showOnlyWhenEditable: true,
23878
+ showOnlyCurrent: true,
23879
+ includeChildren: false,
23880
+ shouldShow: () => true
23881
+ };
23882
+ },
23883
+ addProseMirrorPlugins() {
23884
+ const dataAttribute = `data-${this.options.dataAttribute}`;
23885
+ return [
23886
+ new import_state3.Plugin({
23887
+ key: new import_state3.PluginKey("placeholder"),
23888
+ props: {
23889
+ decorations: ({ doc, selection }) => {
23890
+ const active = this.editor.isEditable || !this.options.showOnlyWhenEditable;
23891
+ const { anchor } = selection;
23892
+ const decorations = [];
23893
+ let hasTable = false;
23894
+ if (!active) {
23895
+ return null;
23896
+ }
23897
+ const isEmptyDoc = this.editor.isEmpty;
23898
+ doc.descendants((node) => {
23899
+ if (node.type.name === "table") {
23900
+ hasTable = true;
23901
+ return false;
23902
+ }
23903
+ return void 0;
23904
+ });
23905
+ doc.descendants((node, pos) => {
23906
+ const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
23907
+ const isEmpty = !node.isLeaf && (0, import_core4.isNodeEmpty)(node);
23908
+ if (!((hasAnchor || !this.options.showOnlyCurrent) && isEmpty)) {
23909
+ return this.options.includeChildren;
23910
+ }
23911
+ if (!this.options.shouldShow({ editor: this.editor, node, pos, hasAnchor, isEmptyDoc, hasTable })) {
23912
+ return this.options.includeChildren;
23913
+ }
23914
+ const placeholderValue = typeof this.options.placeholder === "function" ? this.options.placeholder({ editor: this.editor, node, pos, hasAnchor }) : this.options.placeholder;
23915
+ if (!placeholderValue) {
23916
+ return this.options.includeChildren;
23917
+ }
23918
+ const classes = [this.options.emptyNodeClass];
23919
+ if (isEmptyDoc) {
23920
+ classes.push(this.options.emptyEditorClass);
23921
+ }
23922
+ decorations.push(
23923
+ import_view.Decoration.node(pos, pos + node.nodeSize, {
23924
+ class: classes.join(" "),
23925
+ [dataAttribute]: placeholderValue
23926
+ })
23927
+ );
23928
+ return this.options.includeChildren;
23929
+ });
23930
+ return import_view.DecorationSet.create(doc, decorations);
23931
+ }
23932
+ }
23933
+ })
23934
+ ];
23935
+ }
23936
+ });
23937
+
23779
23938
  // src/components/UEditor/resizable-image.tsx
23780
23939
  var import_react50 = require("react");
23781
23940
  var import_extension_image = __toESM(require("@tiptap/extension-image"), 1);
23782
- var import_core4 = require("@tiptap/core");
23941
+ var import_core5 = require("@tiptap/core");
23783
23942
  var import_react51 = require("@tiptap/react");
23784
23943
  var import_jsx_runtime81 = require("react/jsx-runtime");
23785
23944
  var MIN_IMAGE_SIZE_PX = 40;
@@ -23978,7 +24137,7 @@ var ResizableImage = import_extension_image.default.extend({
23978
24137
  };
23979
24138
  },
23980
24139
  renderHTML({ HTMLAttributes }) {
23981
- return ["img", (0, import_core4.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes)];
24140
+ return ["img", (0, import_core5.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes)];
23982
24141
  },
23983
24142
  addNodeView() {
23984
24143
  return (0, import_react51.ReactNodeViewRenderer)(ResizableImageNodeView);
@@ -23995,6 +24154,7 @@ var resizable_image_default = ResizableImage;
23995
24154
  var lowlight = (0, import_lowlight.createLowlight)(import_lowlight.common);
23996
24155
  function buildUEditorExtensions({
23997
24156
  placeholder,
24157
+ translate,
23998
24158
  maxCharacters,
23999
24159
  uploadImage,
24000
24160
  imageInsertMode = "base64",
@@ -24087,12 +24247,49 @@ function buildUEditorExtensions({
24087
24247
  }),
24088
24248
  import_extension_typography.default,
24089
24249
  import_extension_history.default,
24090
- import_extension_placeholder.default.configure({
24250
+ UEditorPlaceholder.configure({
24091
24251
  placeholder,
24092
24252
  emptyEditorClass: "is-editor-empty",
24093
- emptyNodeClass: "is-empty"
24253
+ emptyNodeClass: "is-empty",
24254
+ shouldShow: ({ node, hasTable }) => {
24255
+ const nodeName = node.type.name;
24256
+ if (nodeName === "table" || nodeName === "tableCell" || nodeName === "tableHeader") {
24257
+ return false;
24258
+ }
24259
+ if (hasTable) {
24260
+ return false;
24261
+ }
24262
+ return true;
24263
+ }
24264
+ }),
24265
+ SlashCommand.configure({
24266
+ messages: {
24267
+ noResults: translate("slashCommand.noResults"),
24268
+ basicBlocks: translate("slashCommand.basicBlocks"),
24269
+ text: translate("slashCommand.text"),
24270
+ textDesc: translate("slashCommand.textDesc"),
24271
+ heading1: translate("slashCommand.heading1"),
24272
+ heading1Desc: translate("slashCommand.heading1Desc"),
24273
+ heading2: translate("slashCommand.heading2"),
24274
+ heading2Desc: translate("slashCommand.heading2Desc"),
24275
+ heading3: translate("slashCommand.heading3"),
24276
+ heading3Desc: translate("slashCommand.heading3Desc"),
24277
+ bulletList: translate("slashCommand.bulletList"),
24278
+ bulletListDesc: translate("slashCommand.bulletListDesc"),
24279
+ orderedList: translate("slashCommand.orderedList"),
24280
+ orderedListDesc: translate("slashCommand.orderedListDesc"),
24281
+ todoList: translate("slashCommand.todoList"),
24282
+ todoListDesc: translate("slashCommand.todoListDesc"),
24283
+ quote: translate("slashCommand.quote"),
24284
+ quoteDesc: translate("slashCommand.quoteDesc"),
24285
+ codeBlock: translate("slashCommand.codeBlock"),
24286
+ codeBlockDesc: translate("slashCommand.codeBlockDesc"),
24287
+ divider: translate("slashCommand.divider"),
24288
+ dividerDesc: translate("slashCommand.dividerDesc"),
24289
+ table: translate("slashCommand.table"),
24290
+ tableDesc: translate("slashCommand.tableDesc")
24291
+ }
24094
24292
  }),
24095
- SlashCommand,
24096
24293
  EmojiSuggestion
24097
24294
  ];
24098
24295
  }
@@ -24279,6 +24476,7 @@ var CATEGORY_ICONS = {
24279
24476
  "flags": import_lucide_react43.Flag
24280
24477
  };
24281
24478
  var EmojiPicker = ({ onSelect, onClose }) => {
24479
+ const t = useSmartTranslations("UEditor");
24282
24480
  const [search, setSearch] = (0, import_react54.useState)("");
24283
24481
  const [activeCategory, setActiveCategory] = (0, import_react54.useState)(EMOJI_LIST[0]?.id || "");
24284
24482
  const scrollContainerRef = (0, import_react54.useRef)(null);
@@ -24348,7 +24546,7 @@ var EmojiPicker = ({ onSelect, onClose }) => {
24348
24546
  "input",
24349
24547
  {
24350
24548
  type: "text",
24351
- placeholder: "T\xECm ki\u1EBFm bi\u1EC3u t\u01B0\u1EE3ng c\u1EA3m x\xFAc",
24549
+ placeholder: t("emojiPicker.searchPlaceholder"),
24352
24550
  value: search,
24353
24551
  onChange: (e) => setSearch(e.target.value),
24354
24552
  className: cn(
@@ -24394,8 +24592,8 @@ var EmojiPicker = ({ onSelect, onClose }) => {
24394
24592
  )) })
24395
24593
  ] }, category.id)) : /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "flex flex-col items-center justify-center h-full text-center", children: [
24396
24594
  /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "text-4xl mb-2", children: "\u{1F50D}" }),
24397
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "text-sm font-medium text-muted-foreground", children: "Kh\xF4ng t\xECm th\u1EA5y emoji" }),
24398
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "text-xs text-muted-foreground mt-1", children: "Th\u1EED t\u1EEB kh\xF3a kh\xE1c" })
24595
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "text-sm font-medium text-muted-foreground", children: t("emojiPicker.noResults") }),
24596
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "text-xs text-muted-foreground mt-1", children: t("emojiPicker.tryDifferentSearch") })
24399
24597
  ] })
24400
24598
  ) : (
24401
24599
  // All Categories - Messenger Style
@@ -25665,8 +25863,8 @@ var UEditor = import_react57.default.forwardRef(({
25665
25863
  const effectivePlaceholder = placeholder ?? t("placeholder");
25666
25864
  const inFlightPrepareRef = (0, import_react57.useRef)(null);
25667
25865
  const extensions = (0, import_react57.useMemo)(
25668
- () => buildUEditorExtensions({ placeholder: effectivePlaceholder, maxCharacters, uploadImage, imageInsertMode, editable }),
25669
- [effectivePlaceholder, maxCharacters, uploadImage, imageInsertMode, editable]
25866
+ () => buildUEditorExtensions({ placeholder: effectivePlaceholder, translate: t, maxCharacters, uploadImage, imageInsertMode, editable }),
25867
+ [effectivePlaceholder, t, maxCharacters, uploadImage, imageInsertMode, editable]
25670
25868
  );
25671
25869
  const editor = (0, import_react58.useEditor)({
25672
25870
  immediatelyRender: false,