@mdxeditor/editor 2.9.0 → 2.10.0

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.
Files changed (27) hide show
  1. package/dist/MDXEditor.js +15 -10
  2. package/dist/index.d.ts +13 -1
  3. package/dist/index.js +5 -2
  4. package/dist/plugins/core/index.js +11 -2
  5. package/dist/plugins/frontmatter/FrontmatterEditor.js +7 -6
  6. package/dist/plugins/image/ImageDialog.js +26 -7
  7. package/dist/plugins/image/ImageEditor.js +3 -2
  8. package/dist/plugins/link-dialog/LinkDialog.js +46 -10
  9. package/dist/plugins/table/TableEditor.js +49 -10
  10. package/dist/plugins/toolbar/components/BlockTypeSelect.js +13 -6
  11. package/dist/plugins/toolbar/components/BoldItalicUnderlineToggles.js +5 -4
  12. package/dist/plugins/toolbar/components/ChangeAdmonitionType.js +17 -5
  13. package/dist/plugins/toolbar/components/ChangeCodeMirrorLanguage.js +5 -4
  14. package/dist/plugins/toolbar/components/CodeToggle.js +3 -2
  15. package/dist/plugins/toolbar/components/CreateLink.js +3 -2
  16. package/dist/plugins/toolbar/components/DiffSourceToggleWrapper.js +6 -5
  17. package/dist/plugins/toolbar/components/InsertAdmonition.js +8 -6
  18. package/dist/plugins/toolbar/components/InsertCodeBlock.js +3 -2
  19. package/dist/plugins/toolbar/components/InsertFrontmatter.js +3 -2
  20. package/dist/plugins/toolbar/components/InsertImage.js +3 -2
  21. package/dist/plugins/toolbar/components/InsertSandpack.js +3 -2
  22. package/dist/plugins/toolbar/components/InsertTable.js +3 -2
  23. package/dist/plugins/toolbar/components/InsertThematicBreak.js +3 -2
  24. package/dist/plugins/toolbar/components/ListsToggle.js +7 -6
  25. package/dist/plugins/toolbar/components/ShowSandpackInfo.js +3 -2
  26. package/dist/plugins/toolbar/components/UndoRedo.js +4 -3
  27. package/package.json +2 -1
package/dist/MDXEditor.js CHANGED
@@ -1,14 +1,14 @@
1
+ import { useCellValues, usePublisher, useRealm } from "@mdxeditor/gurx";
1
2
  import React__default from "react";
2
- import { corePlugin, initialRootEditorState$, usedLexicalNodes$, readOnly$, contentEditableClassName$, composerChildren$, topAreaChildren$, editorWrappers$, placeholder$, editorRootElementRef$, viewMode$, markdownSourceEditorValue$, markdown$, setMarkdown$, insertMarkdown$, rootEditor$ } from "./plugins/core/index.js";
3
3
  import { RealmWithPlugins } from "./RealmWithPlugins.js";
4
- import { useCellValues, usePublisher, useRealm } from "@mdxeditor/gurx";
5
- import { lexicalTheme } from "./styles/lexicalTheme.js";
4
+ import { corePlugin, initialRootEditorState$, usedLexicalNodes$, readOnly$, contentEditableClassName$, composerChildren$, topAreaChildren$, editorWrappers$, placeholder$, editorRootElementRef$, viewMode$, markdownSourceEditorValue$, markdown$, setMarkdown$, insertMarkdown$, rootEditor$ } from "./plugins/core/index.js";
6
5
  import { LexicalComposer } from "@lexical/react/LexicalComposer.js";
7
- import styles from "./styles/ui.module.css.js";
8
- import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin.js";
9
6
  import { ContentEditable } from "@lexical/react/LexicalContentEditable.js";
10
7
  import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary.js";
8
+ import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin.js";
11
9
  import classNames from "classnames";
10
+ import { lexicalTheme } from "./styles/lexicalTheme.js";
11
+ import styles from "./styles/ui.module.css.js";
12
12
  import { noop } from "./utils/fp.js";
13
13
  const LexicalProvider = ({ children }) => {
14
14
  const [initialRootEditorState, nodes, readOnly] = useCellValues(initialRootEditorState$, usedLexicalNodes$, readOnly$);
@@ -56,10 +56,14 @@ const IconFallback = () => {
56
56
  const defaultIconComponentFor = (name) => {
57
57
  return /* @__PURE__ */ React__default.createElement(React__default.Suspense, { fallback: /* @__PURE__ */ React__default.createElement(IconFallback, null) }, /* @__PURE__ */ React__default.createElement(DefaultIcon, { name }));
58
58
  };
59
- const RenderRecursiveWrappers = ({
60
- wrappers,
61
- children
62
- }) => {
59
+ function defaultTranslation(key, defaultValue, interpolations = {}) {
60
+ let value = defaultValue;
61
+ for (const [k, v] of Object.entries(interpolations)) {
62
+ value = value.replaceAll(`{{${k}}}`, String(v));
63
+ }
64
+ return value;
65
+ }
66
+ const RenderRecursiveWrappers = ({ wrappers, children }) => {
63
67
  if (wrappers.length === 0) {
64
68
  return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, children);
65
69
  }
@@ -130,7 +134,8 @@ const MDXEditor = React__default.forwardRef((props, ref) => {
130
134
  readOnly: Boolean(props.readOnly),
131
135
  iconComponentFor: props.iconComponentFor ?? defaultIconComponentFor,
132
136
  suppressHtmlProcessing: props.suppressHtmlProcessing ?? false,
133
- onError: props.onError ?? noop
137
+ onError: props.onError ?? noop,
138
+ translation: props.translation ?? defaultTranslation
134
139
  }),
135
140
  ...props.plugins || []
136
141
  ]
package/dist/index.d.ts CHANGED
@@ -240,6 +240,8 @@ export declare const AdmonitionDirectiveDescriptor: DirectiveDescriptor;
240
240
 
241
241
  /* Excluded from this release type: AdmonitionKind */
242
242
 
243
+ export declare function admonitionLabelsMap(t: Translation): Record<(typeof ADMONITION_TYPES)[number], string>;
244
+
243
245
  /**
244
246
  * @group Headings
245
247
  */
@@ -1984,6 +1986,10 @@ export declare interface MDXEditorProps {
1984
1986
  * Set to false if you want to suppress the processing of HTML tags.
1985
1987
  */
1986
1988
  suppressHtmlProcessing?: boolean;
1989
+ /**
1990
+ * Pass your own translation function if you want to localize the editor.
1991
+ */
1992
+ translation?: Translation;
1987
1993
  }
1988
1994
 
1989
1995
  /**
@@ -2536,7 +2542,7 @@ export declare function thrush<I, K>(arg: I, proc: (arg: I) => K): K;
2536
2542
 
2537
2543
  /* Excluded from this release type: ToggleSingleGroupWithItem */
2538
2544
 
2539
- /* Excluded from this release type: ToMarkdownExtension */
2545
+ export declare type ToMarkdownExtension = NonNullable<ToMarkdownOptions['extensions']>[number];
2540
2546
 
2541
2547
  /* Excluded from this release type: toMarkdownExtensions$ */
2542
2548
 
@@ -2570,6 +2576,10 @@ export declare const TooltipWrap: React_2.ForwardRefExoticComponent<{
2570
2576
 
2571
2577
  /* Excluded from this release type: topAreaChildren$ */
2572
2578
 
2579
+ export declare const translation$: NodeRef<Translation>;
2580
+
2581
+ export declare type Translation = (key: string, defaultValue: string, interpolations?: Record<string, any>) => string;
2582
+
2573
2583
  /* Excluded from this release type: TYPE_NAME */
2574
2584
 
2575
2585
  /**
@@ -2621,6 +2631,8 @@ export declare function useMdastNodeUpdater<T extends Mdast.RootContent>(): (nod
2621
2631
  */
2622
2632
  export declare function useNestedEditorContext<T extends Mdast.RootContent>(): NestedEditorsContextValue<T>;
2623
2633
 
2634
+ export declare function useTranslation(): Translation;
2635
+
2624
2636
  /* Excluded from this release type: uuidv4 */
2625
2637
 
2626
2638
  /**
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ export * from "@mdxeditor/gurx";
3
3
  import { MDXEditor } from "./MDXEditor.js";
4
4
  import { MarkdownParseError, UnrecognizedMarkdownConstructError, importMarkdownToLexical, importMdastTreeToLexical } from "./importMarkdownToLexical.js";
5
5
  import { exportLexicalTreeToMdast, exportMarkdownFromLexical } from "./exportMarkdownFromLexical.js";
6
- import { Appender, NESTED_EDITOR_UPDATED_COMMAND, activeEditor$, activeEditorSubscriptions$, activePlugins$, addActivePlugin$, addComposerChild$, addEditorWrapper$, addExportVisitor$, addImportVisitor$, addLexicalNode$, addMdastExtension$, addNestedEditorChild$, addSyntaxExtension$, addToMarkdownExtension$, addTopAreaChild$, applyBlockType$, applyFormat$, autoFocus$, codeBlockEditorDescriptors$, composerChildren$, contentEditableClassName$, convertSelectionToNode$, corePlugin, createActiveEditorSubscription$, createRootEditorSubscription$, currentBlockType$, currentFormat$, currentSelection$, directiveDescriptors$, editorInFocus$, editorRootElementRef$, editorWrappers$, exportVisitors$, historyState$, iconComponentFor$, importVisitors$, inFocus$, initialMarkdown$, initialRootEditorState$, insertDecoratorNode$, insertMarkdown$, jsxComponentDescriptors$, jsxIsAvailable$, markdown$, markdownErrorSignal$, markdownProcessingError$, markdownSourceEditorValue$, mdastExtensions$, muteChange$, nestedEditorChildren$, onBlur$, placeholder$, readOnly$, rootEditor$, rootEditorSubscriptions$, setMarkdown$, syntaxExtensions$, toMarkdownExtensions$, toMarkdownOptions$, topAreaChildren$, usedLexicalNodes$, viewMode$ } from "./plugins/core/index.js";
6
+ import { Appender, NESTED_EDITOR_UPDATED_COMMAND, activeEditor$, activeEditorSubscriptions$, activePlugins$, addActivePlugin$, addComposerChild$, addEditorWrapper$, addExportVisitor$, addImportVisitor$, addLexicalNode$, addMdastExtension$, addNestedEditorChild$, addSyntaxExtension$, addToMarkdownExtension$, addTopAreaChild$, applyBlockType$, applyFormat$, autoFocus$, codeBlockEditorDescriptors$, composerChildren$, contentEditableClassName$, convertSelectionToNode$, corePlugin, createActiveEditorSubscription$, createRootEditorSubscription$, currentBlockType$, currentFormat$, currentSelection$, directiveDescriptors$, editorInFocus$, editorRootElementRef$, editorWrappers$, exportVisitors$, historyState$, iconComponentFor$, importVisitors$, inFocus$, initialMarkdown$, initialRootEditorState$, insertDecoratorNode$, insertMarkdown$, jsxComponentDescriptors$, jsxIsAvailable$, markdown$, markdownErrorSignal$, markdownProcessingError$, markdownSourceEditorValue$, mdastExtensions$, muteChange$, nestedEditorChildren$, onBlur$, placeholder$, readOnly$, rootEditor$, rootEditorSubscriptions$, setMarkdown$, syntaxExtensions$, toMarkdownExtensions$, toMarkdownOptions$, topAreaChildren$, translation$, useTranslation, usedLexicalNodes$, viewMode$ } from "./plugins/core/index.js";
7
7
  import { ALL_HEADING_LEVELS, allowedHeadingLevels$, headingsPlugin } from "./plugins/headings/index.js";
8
8
  import { insertThematicBreak$, thematicBreakPlugin } from "./plugins/thematic-break/index.js";
9
9
  import { applyListType$, currentListType$, listsPlugin } from "./plugins/lists/index.js";
@@ -28,7 +28,7 @@ import { cmExtensions$, diffMarkdown$, diffSourcePlugin } from "./plugins/diff-s
28
28
  import { markdownShortcutPlugin } from "./plugins/markdown-shortcut/index.js";
29
29
  import { BlockTypeSelect } from "./plugins/toolbar/components/BlockTypeSelect.js";
30
30
  import { BoldItalicUnderlineToggles } from "./plugins/toolbar/components/BoldItalicUnderlineToggles.js";
31
- import { ChangeAdmonitionType } from "./plugins/toolbar/components/ChangeAdmonitionType.js";
31
+ import { ChangeAdmonitionType, admonitionLabelsMap } from "./plugins/toolbar/components/ChangeAdmonitionType.js";
32
32
  import { ChangeCodeMirrorLanguage } from "./plugins/toolbar/components/ChangeCodeMirrorLanguage.js";
33
33
  import { CodeToggle } from "./plugins/toolbar/components/CodeToggle.js";
34
34
  import { CreateLink } from "./plugins/toolbar/components/CreateLink.js";
@@ -149,6 +149,7 @@ export {
149
149
  addSyntaxExtension$,
150
150
  addToMarkdownExtension$,
151
151
  addTopAreaChild$,
152
+ admonitionLabelsMap,
152
153
  allowedHeadingLevels$,
153
154
  always,
154
155
  appendCodeBlockEditorDescriptor$,
@@ -279,11 +280,13 @@ export {
279
280
  toolbarContents$,
280
281
  toolbarPlugin,
281
282
  topAreaChildren$,
283
+ translation$,
282
284
  updateLink$,
283
285
  useCodeBlockEditorContext,
284
286
  useLexicalNodeRemove,
285
287
  useMdastNodeUpdater,
286
288
  useNestedEditorContext,
289
+ useTranslation,
287
290
  usedLexicalNodes$,
288
291
  uuidv4,
289
292
  viewMode$,
@@ -3,7 +3,7 @@ import { createEmptyHistoryState } from "@lexical/react/LexicalHistoryPlugin.js"
3
3
  import { $isHeadingNode } from "@lexical/rich-text";
4
4
  import { $setBlocksType } from "@lexical/selection";
5
5
  import { $findMatchingParent, $wrapNodeInElement, $insertNodeToNearestRoot } from "@lexical/utils";
6
- import { Cell, withLatestFrom, Signal, filter, map, scan } from "@mdxeditor/gurx";
6
+ import { Cell, withLatestFrom, Signal, filter, map, useCellValue, scan } from "@mdxeditor/gurx";
7
7
  import { createCommand, FORMAT_TEXT_COMMAND, $isRootOrShadowRoot, $getRoot, $setSelection, $getSelection, $insertNodes, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_CRITICAL, FOCUS_COMMAND, KEY_DOWN_COMMAND, $isDecoratorNode, BLUR_COMMAND, $isRangeSelection, $createParagraphNode, ParagraphNode, TextNode } from "lexical";
8
8
  import { mdxJsxFromMarkdown, mdxJsxToMarkdown } from "mdast-util-mdx-jsx";
9
9
  import { mdxJsx } from "micromark-extension-mdx-jsx";
@@ -474,6 +474,9 @@ const markdownSourceEditorValue$ = Cell("", (r) => {
474
474
  });
475
475
  const activePlugins$ = Cell([]);
476
476
  const addActivePlugin$ = Appender(activePlugins$);
477
+ const translation$ = Cell(() => {
478
+ throw new Error("No translation function provided");
479
+ });
477
480
  const corePlugin = realmPlugin({
478
481
  init(r, params) {
479
482
  r.register(createRootEditorSubscription$);
@@ -503,7 +506,8 @@ const corePlugin = realmPlugin({
503
506
  [toMarkdownOptions$]: params == null ? void 0 : params.toMarkdownOptions,
504
507
  [autoFocus$]: params == null ? void 0 : params.autoFocus,
505
508
  [placeholder$]: params == null ? void 0 : params.placeholder,
506
- [readOnly$]: params == null ? void 0 : params.readOnly
509
+ [readOnly$]: params == null ? void 0 : params.readOnly,
510
+ [translation$]: params == null ? void 0 : params.translation
507
511
  });
508
512
  if (!(params == null ? void 0 : params.suppressHtmlProcessing)) {
509
513
  r.pubIn({
@@ -527,6 +531,9 @@ const corePlugin = realmPlugin({
527
531
  realm.singletonSub(markdownErrorSignal$, params == null ? void 0 : params.onError);
528
532
  }
529
533
  });
534
+ function useTranslation() {
535
+ return useCellValue(translation$);
536
+ }
530
537
  export {
531
538
  $createGenericHTMLNode,
532
539
  $isGenericHTMLNode,
@@ -593,6 +600,8 @@ export {
593
600
  toMarkdownExtensions$,
594
601
  toMarkdownOptions$,
595
602
  topAreaChildren$,
603
+ translation$,
604
+ useTranslation,
596
605
  usedLexicalNodes$,
597
606
  viewMode$
598
607
  };
@@ -5,7 +5,7 @@ import React__default from "react";
5
5
  import { useForm, useFieldArray } from "react-hook-form";
6
6
  import { frontmatterDialogOpen$, removeFrontmatter$ } from "./index.js";
7
7
  import styles from "../../styles/ui.module.css.js";
8
- import { readOnly$, editorRootElementRef$, iconComponentFor$ } from "../core/index.js";
8
+ import { readOnly$, editorRootElementRef$, iconComponentFor$, useTranslation } from "../core/index.js";
9
9
  import { useCellValues, usePublisher } from "@mdxeditor/gurx";
10
10
  const FrontmatterEditor = ({ yaml, onChange }) => {
11
11
  const [readOnly, editorRootElementRef, iconComponentFor, frontmatterDialogOpen] = useCellValues(
@@ -14,6 +14,7 @@ const FrontmatterEditor = ({ yaml, onChange }) => {
14
14
  iconComponentFor$,
15
15
  frontmatterDialogOpen$
16
16
  );
17
+ const t = useTranslation();
17
18
  const setFrontmatterDialogOpen = usePublisher(frontmatterDialogOpen$);
18
19
  const removeFrontmatter = usePublisher(removeFrontmatter$);
19
20
  const yamlConfig = React__default.useMemo(() => {
@@ -52,7 +53,7 @@ const FrontmatterEditor = ({ yaml, onChange }) => {
52
53
  },
53
54
  [onChange, setFrontmatterDialogOpen, removeFrontmatter]
54
55
  );
55
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(Dialog.Root, { open: frontmatterDialogOpen, onOpenChange: (open) => setFrontmatterDialogOpen(open) }, /* @__PURE__ */ React__default.createElement(Dialog.Portal, { container: editorRootElementRef == null ? void 0 : editorRootElementRef.current }, /* @__PURE__ */ React__default.createElement(Dialog.Overlay, { className: styles.dialogOverlay }), /* @__PURE__ */ React__default.createElement(Dialog.Content, { className: styles.largeDialogContent, "data-editor-type": "frontmatter" }, /* @__PURE__ */ React__default.createElement(Dialog.Title, { className: styles.dialogTitle }, "Edit document frontmatter"), /* @__PURE__ */ React__default.createElement(
56
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(Dialog.Root, { open: frontmatterDialogOpen, onOpenChange: (open) => setFrontmatterDialogOpen(open) }, /* @__PURE__ */ React__default.createElement(Dialog.Portal, { container: editorRootElementRef == null ? void 0 : editorRootElementRef.current }, /* @__PURE__ */ React__default.createElement(Dialog.Overlay, { className: styles.dialogOverlay }), /* @__PURE__ */ React__default.createElement(Dialog.Content, { className: styles.largeDialogContent, "data-editor-type": "frontmatter" }, /* @__PURE__ */ React__default.createElement(Dialog.Title, { className: styles.dialogTitle }, t("frontmatterEditor.title", "Edit document frontmatter")), /* @__PURE__ */ React__default.createElement(
56
57
  "form",
57
58
  {
58
59
  onSubmit: (e) => {
@@ -64,7 +65,7 @@ const FrontmatterEditor = ({ yaml, onChange }) => {
64
65
  setFrontmatterDialogOpen(false);
65
66
  }
66
67
  },
67
- /* @__PURE__ */ React__default.createElement("table", { className: styles.propertyEditorTable }, /* @__PURE__ */ React__default.createElement("colgroup", null, /* @__PURE__ */ React__default.createElement("col", null), /* @__PURE__ */ React__default.createElement("col", null), /* @__PURE__ */ React__default.createElement("col", null)), /* @__PURE__ */ React__default.createElement("thead", null, /* @__PURE__ */ React__default.createElement("tr", null, /* @__PURE__ */ React__default.createElement("th", null, "Key"), /* @__PURE__ */ React__default.createElement("th", null, "Value"), /* @__PURE__ */ React__default.createElement("th", null))), /* @__PURE__ */ React__default.createElement("tbody", null, fields.map((item, index) => {
68
+ /* @__PURE__ */ React__default.createElement("table", { className: styles.propertyEditorTable }, /* @__PURE__ */ React__default.createElement("colgroup", null, /* @__PURE__ */ React__default.createElement("col", null), /* @__PURE__ */ React__default.createElement("col", null), /* @__PURE__ */ React__default.createElement("col", null)), /* @__PURE__ */ React__default.createElement("thead", null, /* @__PURE__ */ React__default.createElement("tr", null, /* @__PURE__ */ React__default.createElement("th", null, t("frontmatterEditor.key", "Key")), /* @__PURE__ */ React__default.createElement("th", null, t("frontmatterEditor.value", "Value")), /* @__PURE__ */ React__default.createElement("th", null))), /* @__PURE__ */ React__default.createElement("tbody", null, fields.map((item, index) => {
68
69
  return /* @__PURE__ */ React__default.createElement("tr", { key: item.id }, /* @__PURE__ */ React__default.createElement("td", null, /* @__PURE__ */ React__default.createElement(TableInput, { ...register(`yamlConfig.${index}.key`, { required: true }), autofocusIfEmpty: true, readOnly })), /* @__PURE__ */ React__default.createElement("td", null, /* @__PURE__ */ React__default.createElement(TableInput, { ...register(`yamlConfig.${index}.value`, { required: true }), readOnly })), /* @__PURE__ */ React__default.createElement("td", null, /* @__PURE__ */ React__default.createElement("button", { type: "button", onClick: () => remove(index), className: styles.iconButton, disabled: readOnly }, iconComponentFor("delete_big"))));
69
70
  })), /* @__PURE__ */ React__default.createElement("tfoot", null, /* @__PURE__ */ React__default.createElement("tr", null, /* @__PURE__ */ React__default.createElement("td", null, /* @__PURE__ */ React__default.createElement(
70
71
  "button",
@@ -76,10 +77,10 @@ const FrontmatterEditor = ({ yaml, onChange }) => {
76
77
  append({ key: "", value: "" });
77
78
  }
78
79
  },
79
- "Add entry"
80
+ t("frontmatterEditor.addEntry", "Add entry")
80
81
  ))))),
81
- /* @__PURE__ */ React__default.createElement("div", { style: { display: "flex", justifyContent: "flex-end", gap: "var(--spacing-2)" } }, /* @__PURE__ */ React__default.createElement("button", { type: "submit", className: styles.primaryButton }, "Save"), /* @__PURE__ */ React__default.createElement("button", { type: "reset", className: styles.secondaryButton }, "Cancel"))
82
- ), /* @__PURE__ */ React__default.createElement(Dialog.Close, { asChild: true }, /* @__PURE__ */ React__default.createElement("button", { className: styles.dialogCloseButton, "aria-label": "Close" }, iconComponentFor("close")))))));
82
+ /* @__PURE__ */ React__default.createElement("div", { style: { display: "flex", justifyContent: "flex-end", gap: "var(--spacing-2)" } }, /* @__PURE__ */ React__default.createElement("button", { type: "submit", className: styles.primaryButton }, t("dialogControls.save", "Save")), /* @__PURE__ */ React__default.createElement("button", { type: "reset", className: styles.secondaryButton }, t("dialogControls.cancel", "Cancel")))
83
+ ), /* @__PURE__ */ React__default.createElement(Dialog.Close, { asChild: true }, /* @__PURE__ */ React__default.createElement("button", { className: styles.dialogCloseButton, "aria-label": t("dialogControls.cancel", "Cancel") }, iconComponentFor("close")))))));
83
84
  };
84
85
  const TableInput = React__default.forwardRef(({ className, autofocusIfEmpty: _, ...props }, ref) => {
85
86
  return /* @__PURE__ */ React__default.createElement("input", { className: classNames(styles.propertyEditorInput, className), ...props, ref });
@@ -3,7 +3,7 @@ import classNames from "classnames";
3
3
  import React__default from "react";
4
4
  import { useForm } from "react-hook-form";
5
5
  import styles from "../../styles/ui.module.css.js";
6
- import { editorRootElementRef$ } from "../core/index.js";
6
+ import { editorRootElementRef$, useTranslation } from "../core/index.js";
7
7
  import { imageAutocompleteSuggestions$, imageDialogState$, saveImage$, closeImageDialog$ } from "./index.js";
8
8
  import { DownshiftAutoComplete } from "../core/ui/DownshiftAutoComplete.js";
9
9
  import { useCellValues, usePublisher } from "@mdxeditor/gurx";
@@ -15,6 +15,7 @@ const ImageDialog = () => {
15
15
  );
16
16
  const saveImage = usePublisher(saveImage$);
17
17
  const closeImageDialog = usePublisher(closeImageDialog$);
18
+ const t = useTranslation();
18
19
  const { register, handleSubmit, control, setValue, reset } = useForm({
19
20
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
20
21
  values: state.type === "editing" ? state.initialValues : {}
@@ -49,8 +50,8 @@ const ImageDialog = () => {
49
50
  },
50
51
  className: styles.multiFieldForm
51
52
  },
52
- /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "file" }, "Upload an image from your device:"), /* @__PURE__ */ React__default.createElement("input", { type: "file", ...register("file") })),
53
- /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "src" }, "Or add an image from an URL:"), /* @__PURE__ */ React__default.createElement(
53
+ /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "file" }, t("uploadImage.uploadInstructions", "Upload an image from your device:")), /* @__PURE__ */ React__default.createElement("input", { type: "file", ...register("file") })),
54
+ /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "src" }, t("uploadImage.addViaUrlInstructions", "Or add an image from an URL:")), /* @__PURE__ */ React__default.createElement(
54
55
  DownshiftAutoComplete,
55
56
  {
56
57
  register,
@@ -59,12 +60,30 @@ const ImageDialog = () => {
59
60
  suggestions: imageAutocompleteSuggestions,
60
61
  setValue,
61
62
  control,
62
- placeholder: "Select or paste an image src"
63
+ placeholder: t("uploadImage.autoCompletePlaceholder", "Select or paste an image src")
63
64
  }
64
65
  )),
65
- /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "alt" }, "Alt:"), /* @__PURE__ */ React__default.createElement("input", { type: "text", ...register("altText"), className: styles.textInput })),
66
- /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "title" }, "Title:"), /* @__PURE__ */ React__default.createElement("input", { type: "text", ...register("title"), className: styles.textInput })),
67
- /* @__PURE__ */ React__default.createElement("div", { style: { display: "flex", justifyContent: "flex-end", gap: "var(--spacing-2)" } }, /* @__PURE__ */ React__default.createElement("button", { type: "submit", title: "Save", "aria-label": "Save", className: classNames(styles.primaryButton) }, "Save"), /* @__PURE__ */ React__default.createElement(Dialog.Close, { asChild: true }, /* @__PURE__ */ React__default.createElement("button", { type: "reset", title: "Cancel", "aria-label": "Cancel", className: classNames(styles.secondaryButton) }, "Cancel")))
66
+ /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "alt" }, t("uploadImage.alt", "Alt:")), /* @__PURE__ */ React__default.createElement("input", { type: "text", ...register("altText"), className: styles.textInput })),
67
+ /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "title" }, t("uploadImage.title", "Title:")), /* @__PURE__ */ React__default.createElement("input", { type: "text", ...register("title"), className: styles.textInput })),
68
+ /* @__PURE__ */ React__default.createElement("div", { style: { display: "flex", justifyContent: "flex-end", gap: "var(--spacing-2)" } }, /* @__PURE__ */ React__default.createElement(
69
+ "button",
70
+ {
71
+ type: "submit",
72
+ title: t("dialogControls.save", "Save"),
73
+ "aria-label": t("dialogControls.save", "Save"),
74
+ className: classNames(styles.primaryButton)
75
+ },
76
+ t("dialogControls.save", "Save")
77
+ ), /* @__PURE__ */ React__default.createElement(Dialog.Close, { asChild: true }, /* @__PURE__ */ React__default.createElement(
78
+ "button",
79
+ {
80
+ type: "reset",
81
+ title: t("dialogControls.cancel", "Cancel"),
82
+ "aria-label": t("dialogControls.cancel", "Cancel"),
83
+ className: classNames(styles.secondaryButton)
84
+ },
85
+ t("dialogControls.cancel", "Cancel")
86
+ )))
68
87
  )
69
88
  ))
70
89
  );
@@ -6,7 +6,7 @@ import classNames from "classnames";
6
6
  import { $isNodeSelection, $getSelection, $getNodeByKey, $setSelection, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_LOW, CLICK_COMMAND, DRAGSTART_COMMAND, KEY_DELETE_COMMAND, KEY_BACKSPACE_COMMAND, KEY_ENTER_COMMAND, KEY_ESCAPE_COMMAND } from "lexical";
7
7
  import { disableImageResize$, imagePreviewHandler$, openEditImageDialog$ } from "./index.js";
8
8
  import styles from "../../styles/ui.module.css.js";
9
- import { iconComponentFor$, readOnly$ } from "../core/index.js";
9
+ import { iconComponentFor$, readOnly$, useTranslation } from "../core/index.js";
10
10
  import { $isImageNode } from "./ImageNode.js";
11
11
  import ImageResizer from "./ImageResizer.js";
12
12
  import { useCellValues, usePublisher } from "@mdxeditor/gurx";
@@ -64,6 +64,7 @@ function ImageEditor({ src, title, alt, nodeKey, width, height }) {
64
64
  const [isResizing, setIsResizing] = React__default.useState(false);
65
65
  const [imageSource, setImageSource] = React__default.useState(null);
66
66
  const [initialImagePath, setInitialImagePath] = React__default.useState(null);
67
+ const t = useTranslation();
67
68
  const onDelete = React__default.useCallback(
68
69
  (payload) => {
69
70
  if (isSelected && $isNodeSelection($getSelection())) {
@@ -214,7 +215,7 @@ function ImageEditor({ src, title, alt, nodeKey, width, height }) {
214
215
  {
215
216
  type: "button",
216
217
  className: classNames(styles.iconButton, styles.editImageButton),
217
- title: "Edit image",
218
+ title: t("imageEditor.editImage", "Edit image"),
218
219
  disabled: readOnly,
219
220
  onClick: () => {
220
221
  openEditImageDialog({
@@ -1,7 +1,7 @@
1
1
  import * as RadixPopover from "@radix-ui/react-popover";
2
2
  import * as Tooltip from "@radix-ui/react-tooltip";
3
3
  import React__default from "react";
4
- import { editorRootElementRef$, activeEditor$, iconComponentFor$ } from "../core/index.js";
4
+ import { editorRootElementRef$, activeEditor$, iconComponentFor$, useTranslation } from "../core/index.js";
5
5
  import { DownshiftAutoComplete } from "../core/ui/DownshiftAutoComplete.js";
6
6
  import styles from "../../styles/ui.module.css.js";
7
7
  import classNames from "classnames";
@@ -23,6 +23,7 @@ function LinkEditForm({ url, title, onSubmit, onCancel, linkAutocompleteSuggesti
23
23
  title
24
24
  }
25
25
  });
26
+ const t = useTranslation();
26
27
  return /* @__PURE__ */ React__default.createElement(
27
28
  "form",
28
29
  {
@@ -37,7 +38,7 @@ function LinkEditForm({ url, title, onSubmit, onCancel, linkAutocompleteSuggesti
37
38
  },
38
39
  className: classNames(styles.multiFieldForm, styles.linkDialogEditForm)
39
40
  },
40
- /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "link-url" }, "URL"), /* @__PURE__ */ React__default.createElement(
41
+ /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "link-url" }, t("createLink.url", "URL")), /* @__PURE__ */ React__default.createElement(
41
42
  DownshiftAutoComplete,
42
43
  {
43
44
  register,
@@ -46,12 +47,30 @@ function LinkEditForm({ url, title, onSubmit, onCancel, linkAutocompleteSuggesti
46
47
  suggestions: linkAutocompleteSuggestions,
47
48
  setValue,
48
49
  control,
49
- placeholder: "Select or paste an URL",
50
+ placeholder: t("createLink.urlPlaceholder", "Select or paste an URL"),
50
51
  autofocus: true
51
52
  }
52
53
  )),
53
- /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "link-title" }, "Title"), /* @__PURE__ */ React__default.createElement("input", { id: "link-title", className: styles.textInput, size: 40, ...register("title") })),
54
- /* @__PURE__ */ React__default.createElement("div", { style: { display: "flex", justifyContent: "flex-end", gap: "var(--spacing-2)" } }, /* @__PURE__ */ React__default.createElement("button", { type: "submit", title: "Set URL", "aria-label": "Set URL", className: classNames(styles.primaryButton) }, "Save"), /* @__PURE__ */ React__default.createElement("button", { type: "reset", title: "Cancel change", "aria-label": "Cancel change", className: classNames(styles.secondaryButton) }, "Cancel"))
54
+ /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "link-title" }, t("createLink.title", "Title")), /* @__PURE__ */ React__default.createElement("input", { id: "link-title", className: styles.textInput, size: 40, ...register("title") })),
55
+ /* @__PURE__ */ React__default.createElement("div", { style: { display: "flex", justifyContent: "flex-end", gap: "var(--spacing-2)" } }, /* @__PURE__ */ React__default.createElement(
56
+ "button",
57
+ {
58
+ type: "submit",
59
+ title: t("createLink.saveTooltip", "Set URL"),
60
+ "aria-label": t("createLink.saveTooltip", "Set URL"),
61
+ className: classNames(styles.primaryButton)
62
+ },
63
+ t("dialogControls.save", "Save")
64
+ ), /* @__PURE__ */ React__default.createElement(
65
+ "button",
66
+ {
67
+ type: "reset",
68
+ title: t("createLink.cancelTooltip", "Cancel change"),
69
+ "aria-label": t("createLink.cancelTooltip", "Cancel change"),
70
+ className: classNames(styles.secondaryButton)
71
+ },
72
+ t("dialogControls.cancel", "Cancel")
73
+ ))
55
74
  );
56
75
  }
57
76
  const LinkDialog = () => {
@@ -82,6 +101,7 @@ const LinkDialog = () => {
82
101
  };
83
102
  }, [activeEditor, publishWindowChange]);
84
103
  const [copyUrlTooltipOpen, setCopyUrlTooltipOpen] = React__default.useState(false);
104
+ const t = useTranslation();
85
105
  const theRect = linkDialogState == null ? void 0 : linkDialogState.rectangle;
86
106
  const urlIsExternal = linkDialogState.type === "preview" && linkDialogState.url.startsWith("http");
87
107
  return /* @__PURE__ */ React__default.createElement(RadixPopover.Root, { open: linkDialogState.type !== "inactive" }, /* @__PURE__ */ React__default.createElement(
@@ -126,15 +146,23 @@ const LinkDialog = () => {
126
146
  onClickLinkCallback(linkDialogState.url);
127
147
  }
128
148
  },
129
- title: urlIsExternal ? `Open ${linkDialogState.url} in new window` : linkDialogState.url
149
+ title: urlIsExternal ? t("linkPreview.open", `Open {{url}} in new window`, { url: linkDialogState.url }) : linkDialogState.url
130
150
  },
131
151
  /* @__PURE__ */ React__default.createElement("span", null, linkDialogState.url),
132
152
  urlIsExternal && iconComponentFor("open_in_new")
133
- ), /* @__PURE__ */ React__default.createElement(ActionButton, { onClick: () => switchFromPreviewToLinkEdit(), title: "Edit link URL", "aria-label": "Edit link URL" }, iconComponentFor("edit")), /* @__PURE__ */ React__default.createElement(Tooltip.Provider, null, /* @__PURE__ */ React__default.createElement(Tooltip.Root, { open: copyUrlTooltipOpen }, /* @__PURE__ */ React__default.createElement(Tooltip.Trigger, { asChild: true }, /* @__PURE__ */ React__default.createElement(
153
+ ), /* @__PURE__ */ React__default.createElement(
134
154
  ActionButton,
135
155
  {
136
- title: "Copy to clipboard",
137
- "aria-label": "Copy link URL",
156
+ onClick: () => switchFromPreviewToLinkEdit(),
157
+ title: t("linkPreview.edit", "Edit link URL"),
158
+ "aria-label": t("linkPreview.edit", "Edit link URL")
159
+ },
160
+ iconComponentFor("edit")
161
+ ), /* @__PURE__ */ React__default.createElement(Tooltip.Provider, null, /* @__PURE__ */ React__default.createElement(Tooltip.Root, { open: copyUrlTooltipOpen }, /* @__PURE__ */ React__default.createElement(Tooltip.Trigger, { asChild: true }, /* @__PURE__ */ React__default.createElement(
162
+ ActionButton,
163
+ {
164
+ title: t("linkPreview.copyToClipboard", "Copy to clipboard"),
165
+ "aria-label": t("linkPreview.copyToClipboard", "Copy to clipboard"),
138
166
  onClick: () => {
139
167
  void window.navigator.clipboard.writeText(linkDialogState.url).then(() => {
140
168
  setCopyUrlTooltipOpen(true);
@@ -143,7 +171,15 @@ const LinkDialog = () => {
143
171
  }
144
172
  },
145
173
  copyUrlTooltipOpen ? iconComponentFor("check") : iconComponentFor("content_copy")
146
- )), /* @__PURE__ */ React__default.createElement(Tooltip.Portal, { container: editorRootElementRef == null ? void 0 : editorRootElementRef.current }, /* @__PURE__ */ React__default.createElement(Tooltip.Content, { className: classNames(styles.tooltipContent), sideOffset: 5 }, "Copied!", /* @__PURE__ */ React__default.createElement(Tooltip.Arrow, null))))), /* @__PURE__ */ React__default.createElement(ActionButton, { title: "Remove link", "aria-label": "Remove link", onClick: () => removeLink() }, iconComponentFor("link_off"))),
174
+ )), /* @__PURE__ */ React__default.createElement(Tooltip.Portal, { container: editorRootElementRef == null ? void 0 : editorRootElementRef.current }, /* @__PURE__ */ React__default.createElement(Tooltip.Content, { className: classNames(styles.tooltipContent), sideOffset: 5 }, t("linkPreview.copied", "Copied!"), /* @__PURE__ */ React__default.createElement(Tooltip.Arrow, null))))), /* @__PURE__ */ React__default.createElement(
175
+ ActionButton,
176
+ {
177
+ title: t("linkPreview.remove", "Remove link"),
178
+ "aria-label": t("linkPreview.remove", "Remove link"),
179
+ onClick: () => removeLink()
180
+ },
181
+ iconComponentFor("link_off")
182
+ )),
147
183
  /* @__PURE__ */ React__default.createElement(RadixPopover.Arrow, { className: styles.popoverArrow })
148
184
  )));
149
185
  };
@@ -15,7 +15,7 @@ import classNames from "classnames";
15
15
  import styles from "../../styles/ui.module.css.js";
16
16
  import { isPartOftheEditorUI } from "../../utils/isPartOftheEditorUI.js";
17
17
  import { uuidv4 } from "../../utils/uuid4.js";
18
- import { iconComponentFor$, readOnly$, importVisitors$, exportVisitors$, usedLexicalNodes$, jsxComponentDescriptors$, directiveDescriptors$, codeBlockEditorDescriptors$, jsxIsAvailable$, rootEditor$, NESTED_EDITOR_UPDATED_COMMAND, editorRootElementRef$ } from "../core/index.js";
18
+ import { iconComponentFor$, readOnly$, useTranslation, importVisitors$, exportVisitors$, usedLexicalNodes$, jsxComponentDescriptors$, directiveDescriptors$, codeBlockEditorDescriptors$, jsxIsAvailable$, rootEditor$, NESTED_EDITOR_UPDATED_COMMAND, editorRootElementRef$ } from "../core/index.js";
19
19
  import { useCellValues } from "@mdxeditor/gurx";
20
20
  const AlignToTailwindClassMap = {
21
21
  center: styles.centeredCell,
@@ -115,6 +115,7 @@ const TableEditor = ({ mdastNode, parentEditor, lexicalTable }) => {
115
115
  const rowIndex = tableCell.tagName === "TH" ? -1 : Array.from(tableRow.parentElement.children).indexOf(tableRow);
116
116
  setHighlightedCoordinates([colIndex, rowIndex]);
117
117
  }, []);
118
+ const t = useTranslation();
118
119
  return /* @__PURE__ */ React__default.createElement("table", { className: styles.tableEditor, onMouseOver: onTableMouseOver, onMouseLeave: () => setHighlightedCoordinates([-1, -1]) }, /* @__PURE__ */ React__default.createElement("colgroup", null, readOnly ? null : /* @__PURE__ */ React__default.createElement("col", null), Array.from({ length: mdastNode.children[0].children.length }, (_, colIndex) => {
119
120
  const align = mdastNode.align || [];
120
121
  const currentColumnAlign = align[colIndex] || "left";
@@ -125,7 +126,7 @@ const TableEditor = ({ mdastNode, parentEditor, lexicalTable }) => {
125
126
  {
126
127
  className: styles.iconButton,
127
128
  type: "button",
128
- title: "Delete table",
129
+ title: t("table.deleteTable", "Delete table"),
129
130
  onClick: (e) => {
130
131
  e.preventDefault();
131
132
  parentEditor.update(() => {
@@ -332,12 +333,13 @@ const ColumnEditor = ({
332
333
  },
333
334
  [parentEditor, lexicalTable]
334
335
  );
336
+ const t = useTranslation();
335
337
  return /* @__PURE__ */ React__default.createElement(RadixPopover.Root, null, /* @__PURE__ */ React__default.createElement(
336
338
  RadixPopover.PopoverTrigger,
337
339
  {
338
340
  className: styles.tableColumnEditorTrigger,
339
341
  "data-active": highlightedCoordinates[0] === colIndex + 1,
340
- title: "Column menu"
342
+ title: t("table.columnMenu", "Column menu")
341
343
  },
342
344
  iconComponentFor("more_horiz")
343
345
  ), /* @__PURE__ */ React__default.createElement(RadixPopover.Portal, { container: editorRootElementRef == null ? void 0 : editorRootElementRef.current }, /* @__PURE__ */ React__default.createElement(
@@ -357,12 +359,26 @@ const ColumnEditor = ({
357
359
  },
358
360
  value: align || "left",
359
361
  type: "single",
360
- "aria-label": "Text alignment"
362
+ "aria-label": t("table.textAlignment", "Text alignment")
361
363
  },
362
- /* @__PURE__ */ React__default.createElement(RadixToolbar.ToggleItem, { value: "left", title: "Align left" }, iconComponentFor("format_align_left")),
363
- /* @__PURE__ */ React__default.createElement(RadixToolbar.ToggleItem, { value: "center", title: "Align center" }, iconComponentFor("format_align_center")),
364
- /* @__PURE__ */ React__default.createElement(RadixToolbar.ToggleItem, { value: "right", title: "Align right" }, iconComponentFor("format_align_right"))
365
- ), /* @__PURE__ */ React__default.createElement(RadixToolbar.Separator, null), /* @__PURE__ */ React__default.createElement(RadixToolbar.Button, { onClick: insertColumnAt.bind(null, colIndex), title: "Insert a column to the left of this one" }, iconComponentFor("insert_col_left")), /* @__PURE__ */ React__default.createElement(RadixToolbar.Button, { onClick: insertColumnAt.bind(null, colIndex + 1), title: "Insert a column to the right of this one" }, iconComponentFor("insert_col_right")), /* @__PURE__ */ React__default.createElement(RadixToolbar.Button, { onClick: deleteColumnAt.bind(null, colIndex), title: "Delete this column" }, iconComponentFor("delete_small"))),
364
+ /* @__PURE__ */ React__default.createElement(RadixToolbar.ToggleItem, { value: "left", title: t("table.alignLeft", "Align left") }, iconComponentFor("format_align_left")),
365
+ /* @__PURE__ */ React__default.createElement(RadixToolbar.ToggleItem, { value: "center", title: t("table.alignCenter", "Align center") }, iconComponentFor("format_align_center")),
366
+ /* @__PURE__ */ React__default.createElement(RadixToolbar.ToggleItem, { value: "right", title: t("table.alignRight", "Align right") }, iconComponentFor("format_align_right"))
367
+ ), /* @__PURE__ */ React__default.createElement(RadixToolbar.Separator, null), /* @__PURE__ */ React__default.createElement(
368
+ RadixToolbar.Button,
369
+ {
370
+ onClick: insertColumnAt.bind(null, colIndex),
371
+ title: t("table.insertColumnLeft", "Insert a column to the left of this one")
372
+ },
373
+ iconComponentFor("insert_col_left")
374
+ ), /* @__PURE__ */ React__default.createElement(
375
+ RadixToolbar.Button,
376
+ {
377
+ onClick: insertColumnAt.bind(null, colIndex + 1),
378
+ title: t("table.insertColumnRight", "Insert a column to the right of this one")
379
+ },
380
+ iconComponentFor("insert_col_right")
381
+ ), /* @__PURE__ */ React__default.createElement(RadixToolbar.Button, { onClick: deleteColumnAt.bind(null, colIndex), title: t("table.deleteColumn", "Delete this column") }, iconComponentFor("delete_small"))),
366
382
  /* @__PURE__ */ React__default.createElement(RadixPopover.Arrow, { className: styles.popoverArrow })
367
383
  )));
368
384
  };
@@ -391,7 +407,16 @@ const RowEditor = ({
391
407
  },
392
408
  [parentEditor, lexicalTable]
393
409
  );
394
- return /* @__PURE__ */ React__default.createElement(RadixPopover.Root, null, /* @__PURE__ */ React__default.createElement(RadixPopover.PopoverTrigger, { className: styles.tableColumnEditorTrigger, "data-active": highlightedCoordinates[1] === rowIndex }, iconComponentFor("more_horiz")), /* @__PURE__ */ React__default.createElement(RadixPopover.Portal, { container: editorRootElementRef == null ? void 0 : editorRootElementRef.current }, /* @__PURE__ */ React__default.createElement(
410
+ const t = useTranslation();
411
+ return /* @__PURE__ */ React__default.createElement(RadixPopover.Root, null, /* @__PURE__ */ React__default.createElement(
412
+ RadixPopover.PopoverTrigger,
413
+ {
414
+ className: styles.tableColumnEditorTrigger,
415
+ "data-active": highlightedCoordinates[1] === rowIndex,
416
+ title: t("table.rowMenu", "Row menu")
417
+ },
418
+ iconComponentFor("more_horiz")
419
+ ), /* @__PURE__ */ React__default.createElement(RadixPopover.Portal, { container: editorRootElementRef == null ? void 0 : editorRootElementRef.current }, /* @__PURE__ */ React__default.createElement(
395
420
  RadixPopover.PopoverContent,
396
421
  {
397
422
  className: classNames(styles.tableColumnEditorPopoverContent),
@@ -399,7 +424,21 @@ const RowEditor = ({
399
424
  sideOffset: 5,
400
425
  side: "bottom"
401
426
  },
402
- /* @__PURE__ */ React__default.createElement(RadixToolbar.Root, { className: styles.tableColumnEditorToolbar }, /* @__PURE__ */ React__default.createElement(RadixToolbar.Button, { onClick: insertRowAt.bind(null, rowIndex), title: "Insert a row above this one" }, iconComponentFor("insert_row_above")), /* @__PURE__ */ React__default.createElement(RadixToolbar.Button, { onClick: insertRowAt.bind(null, rowIndex + 1), title: "Insert a row below this one" }, iconComponentFor("insert_row_below")), /* @__PURE__ */ React__default.createElement(RadixToolbar.Button, { onClick: deleteRowAt.bind(null, rowIndex), title: "Delete this row" }, iconComponentFor("delete_small"))),
427
+ /* @__PURE__ */ React__default.createElement(RadixToolbar.Root, { className: styles.tableColumnEditorToolbar }, /* @__PURE__ */ React__default.createElement(
428
+ RadixToolbar.Button,
429
+ {
430
+ onClick: insertRowAt.bind(null, rowIndex),
431
+ title: t("table.insertRowAbove", "Insert a row above this one")
432
+ },
433
+ iconComponentFor("insert_row_above")
434
+ ), /* @__PURE__ */ React__default.createElement(
435
+ RadixToolbar.Button,
436
+ {
437
+ onClick: insertRowAt.bind(null, rowIndex + 1),
438
+ title: t("table.insertRowBelow", "Insert a row below this one")
439
+ },
440
+ iconComponentFor("insert_row_below")
441
+ ), /* @__PURE__ */ React__default.createElement(RadixToolbar.Button, { onClick: deleteRowAt.bind(null, rowIndex), title: t("table.deleteRow", "Delete this row") }, iconComponentFor("delete_small"))),
403
442
  /* @__PURE__ */ React__default.createElement(RadixPopover.Arrow, { className: styles.popoverArrow })
404
443
  )));
405
444
  };
@@ -2,7 +2,7 @@ import { $createHeadingNode, $createQuoteNode } from "@lexical/rich-text";
2
2
  import { usePublisher, useCellValue } from "@mdxeditor/gurx";
3
3
  import { $createParagraphNode } from "lexical";
4
4
  import React__default from "react";
5
- import { convertSelectionToNode$, currentBlockType$, activePlugins$ } from "../../core/index.js";
5
+ import { convertSelectionToNode$, currentBlockType$, activePlugins$, useTranslation } from "../../core/index.js";
6
6
  import { allowedHeadingLevels$ } from "../../headings/index.js";
7
7
  import { Select } from "../primitives/select.js";
8
8
  const BlockTypeSelect = () => {
@@ -11,16 +11,23 @@ const BlockTypeSelect = () => {
11
11
  const activePlugins = useCellValue(activePlugins$);
12
12
  const hasQuote = activePlugins.includes("quote");
13
13
  const hasHeadings = activePlugins.includes("headings");
14
+ const t = useTranslation();
14
15
  if (!hasQuote && !hasHeadings) {
15
16
  return null;
16
17
  }
17
- const items = [{ label: "Paragraph", value: "paragraph" }];
18
+ const items = [
19
+ { label: t("toolbar.blockTypes.paragraph", "Paragraph"), value: "paragraph" }
20
+ ];
18
21
  if (hasQuote) {
19
- items.push({ label: "Quote", value: "quote" });
22
+ items.push({ label: t("toolbar.blockTypes.quote", "Quote"), value: "quote" });
20
23
  }
21
24
  if (hasHeadings) {
22
25
  const allowedHeadingLevels = useCellValue(allowedHeadingLevels$);
23
- items.push(...allowedHeadingLevels.map((n) => ({ label: `Heading ${n}`, value: `h${n}` })));
26
+ items.push(
27
+ ...allowedHeadingLevels.map(
28
+ (n) => ({ label: t("toolbar.blockTypes.heading", "Heading {{level}}", { level: n }), value: `h${n}` })
29
+ )
30
+ );
24
31
  }
25
32
  return /* @__PURE__ */ React__default.createElement(
26
33
  Select,
@@ -44,8 +51,8 @@ const BlockTypeSelect = () => {
44
51
  }
45
52
  }
46
53
  },
47
- triggerTitle: "Select block type",
48
- placeholder: "Block type",
54
+ triggerTitle: t("toolbar.blockTypeSelect.selectBlockTypeTooltip", "Select block type"),
55
+ placeholder: t("toolbar.blockTypeSelect.placeholder", "Block type"),
49
56
  items
50
57
  }
51
58
  );
@@ -1,4 +1,4 @@
1
- import { currentFormat$, iconComponentFor$, applyFormat$ } from "../../core/index.js";
1
+ import { currentFormat$, iconComponentFor$, applyFormat$, useTranslation } from "../../core/index.js";
2
2
  import { useCellValues, usePublisher } from "@mdxeditor/gurx";
3
3
  import React__default from "react";
4
4
  import { IS_BOLD, IS_ITALIC, IS_UNDERLINE } from "../../../FormatConstants.js";
@@ -6,12 +6,13 @@ import { MultipleChoiceToggleGroup } from "../primitives/toolbar.js";
6
6
  const BoldItalicUnderlineToggles = () => {
7
7
  const [currentFormat, iconComponentFor] = useCellValues(currentFormat$, iconComponentFor$);
8
8
  const applyFormat = usePublisher(applyFormat$);
9
+ const t = useTranslation();
9
10
  const boldIsOn = (currentFormat & IS_BOLD) !== 0;
10
11
  const italicIsOn = (currentFormat & IS_ITALIC) !== 0;
11
12
  const underlineIsOn = (currentFormat & IS_UNDERLINE) !== 0;
12
- const boldTitle = boldIsOn ? "Remove bold" : "Bold";
13
- const italicTitle = italicIsOn ? "Remove italic" : "Italic";
14
- const underlineTitle = underlineIsOn ? "Remove underline" : "Underline";
13
+ const boldTitle = boldIsOn ? t("toolbar.removeBold", "Remove bold") : t("toolbar.bold", "Bold");
14
+ const italicTitle = italicIsOn ? t("toolbar.removeItalic", "Remove italic") : t("toolbar.italic", "Italic");
15
+ const underlineTitle = underlineIsOn ? t("toolbar.underline", "Remove underline") : t("toolbar.removeUnderline", "Underline");
15
16
  return /* @__PURE__ */ React__default.createElement(
16
17
  MultipleChoiceToggleGroup,
17
18
  {
@@ -1,11 +1,22 @@
1
1
  import React__default from "react";
2
- import { editorInFocus$, rootEditor$ } from "../../core/index.js";
2
+ import { editorInFocus$, rootEditor$, useTranslation } from "../../core/index.js";
3
3
  import { Select } from "../primitives/select.js";
4
4
  import { ADMONITION_TYPES } from "../../../directive-editors/AdmonitionDirectiveDescriptor.js";
5
5
  import { useCellValues } from "@mdxeditor/gurx";
6
+ function admonitionLabelsMap(t) {
7
+ return {
8
+ note: t("admonitions.note", "Note"),
9
+ tip: t("admonitions.tip", "Tip"),
10
+ danger: t("admonitions.danger", "Danger"),
11
+ info: t("admonitions.info", "Info"),
12
+ caution: t("admonitions.caution", "Caution")
13
+ };
14
+ }
6
15
  const ChangeAdmonitionType = () => {
7
16
  const [editorInFocus, rootEditor] = useCellValues(editorInFocus$, rootEditor$);
8
17
  const admonitionNode = editorInFocus.rootNode;
18
+ const t = useTranslation();
19
+ const labels = admonitionLabelsMap(t);
9
20
  return /* @__PURE__ */ React__default.createElement(
10
21
  Select,
11
22
  {
@@ -20,12 +31,13 @@ const ChangeAdmonitionType = () => {
20
31
  }, 80);
21
32
  });
22
33
  },
23
- triggerTitle: "Select admonition type",
24
- placeholder: "Admonition type",
25
- items: ADMONITION_TYPES.map((type) => ({ label: type.replace(/^./, (l) => l.toUpperCase()), value: type }))
34
+ triggerTitle: t("admonitions.changeType", "Select admonition type"),
35
+ placeholder: t("admonitions.placeholder", "Admonition type"),
36
+ items: ADMONITION_TYPES.map((type) => ({ label: labels[type], value: type }))
26
37
  }
27
38
  );
28
39
  };
29
40
  export {
30
- ChangeAdmonitionType
41
+ ChangeAdmonitionType,
42
+ admonitionLabelsMap
31
43
  };
@@ -2,17 +2,18 @@ import { useCellValues } from "@mdxeditor/gurx";
2
2
  import React__default from "react";
3
3
  import styles from "../../../styles/ui.module.css.js";
4
4
  import { codeBlockLanguages$ } from "../../codemirror/index.js";
5
- import { editorInFocus$, activeEditor$ } from "../../core/index.js";
5
+ import { editorInFocus$, activeEditor$, useTranslation } from "../../core/index.js";
6
6
  import { Select } from "../primitives/select.js";
7
7
  const EMPTY_VALUE = "__EMPTY_VALUE__";
8
8
  const ChangeCodeMirrorLanguage = () => {
9
9
  const [editorInFocus, theEditor, codeBlockLanguages] = useCellValues(editorInFocus$, activeEditor$, codeBlockLanguages$);
10
10
  const codeBlockNode = editorInFocus.rootNode;
11
+ const t = useTranslation();
11
12
  let currentLanguage = codeBlockNode.getLanguage();
12
13
  if (currentLanguage === "") {
13
14
  currentLanguage = EMPTY_VALUE;
14
15
  }
15
- return /* @__PURE__ */ React__default.createElement("div", { className: styles.selectWithLabel }, /* @__PURE__ */ React__default.createElement("label", null, "Code block language:"), /* @__PURE__ */ React__default.createElement(
16
+ return /* @__PURE__ */ React__default.createElement("div", { className: styles.selectWithLabel }, /* @__PURE__ */ React__default.createElement("label", null, t("codeBlock.language", "Code block language")), /* @__PURE__ */ React__default.createElement(
16
17
  Select,
17
18
  {
18
19
  value: currentLanguage,
@@ -26,8 +27,8 @@ const ChangeCodeMirrorLanguage = () => {
26
27
  });
27
28
  });
28
29
  },
29
- triggerTitle: "Select code block language",
30
- placeholder: "Code block language",
30
+ triggerTitle: t("codeBlock.selectLanguage", "Select code block language"),
31
+ placeholder: t("codeBlock.language", "Code block language"),
31
32
  items: Object.entries(codeBlockLanguages).map(([value, label]) => ({ value: value ? value : EMPTY_VALUE, label }))
32
33
  }
33
34
  ));
@@ -1,13 +1,14 @@
1
1
  import React__default from "react";
2
2
  import { IS_CODE } from "../../../FormatConstants.js";
3
- import { currentFormat$, iconComponentFor$, applyFormat$ } from "../../core/index.js";
3
+ import { currentFormat$, iconComponentFor$, applyFormat$, useTranslation } from "../../core/index.js";
4
4
  import { MultipleChoiceToggleGroup } from "../primitives/toolbar.js";
5
5
  import { useCellValues, usePublisher } from "@mdxeditor/gurx";
6
6
  const CodeToggle = () => {
7
7
  const [currentFormat, iconComponentFor] = useCellValues(currentFormat$, iconComponentFor$);
8
8
  const applyFormat = usePublisher(applyFormat$);
9
+ const t = useTranslation();
9
10
  const codeIsOn = (currentFormat & IS_CODE) !== 0;
10
- const title = codeIsOn ? "Remove code format" : "Inline code format";
11
+ const title = codeIsOn ? t("toolbar.removeInlineCode", "Remove code format") : t("toolbar.inlineCode", "Inline code format");
11
12
  return /* @__PURE__ */ React__default.createElement(
12
13
  MultipleChoiceToggleGroup,
13
14
  {
@@ -2,14 +2,15 @@ import React__default from "react";
2
2
  import { ButtonWithTooltip } from "../primitives/toolbar.js";
3
3
  import { openLinkEditDialog$ } from "../../link-dialog/index.js";
4
4
  import { usePublisher, useCellValue } from "@mdxeditor/gurx";
5
- import { iconComponentFor$ } from "../../core/index.js";
5
+ import { iconComponentFor$, useTranslation } from "../../core/index.js";
6
6
  const CreateLink = () => {
7
7
  const openLinkDialog = usePublisher(openLinkEditDialog$);
8
8
  const iconComponentFor = useCellValue(iconComponentFor$);
9
+ const t = useTranslation();
9
10
  return /* @__PURE__ */ React__default.createElement(
10
11
  ButtonWithTooltip,
11
12
  {
12
- title: "Create link",
13
+ title: t("toolbar.link", "Create link"),
13
14
  onClick: (_) => {
14
15
  openLinkDialog();
15
16
  }
@@ -1,4 +1,4 @@
1
- import { viewMode$, iconComponentFor$ } from "../../core/index.js";
1
+ import { viewMode$, iconComponentFor$, useTranslation } from "../../core/index.js";
2
2
  import { useCellValues, usePublisher } from "@mdxeditor/gurx";
3
3
  import React__default from "react";
4
4
  import styles from "../../../styles/ui.module.css.js";
@@ -9,17 +9,18 @@ const DiffSourceToggleWrapper = ({
9
9
  }) => {
10
10
  const [viewMode, iconComponentFor] = useCellValues(viewMode$, iconComponentFor$);
11
11
  const changeViewMode = usePublisher(viewMode$);
12
+ const t = useTranslation();
12
13
  const toggleGroupItems = [];
13
14
  if (options.includes("rich-text")) {
14
- toggleGroupItems.push({ title: "Rich text", contents: iconComponentFor("rich_text"), value: "rich-text" });
15
+ toggleGroupItems.push({ title: t("toolbar.richText", "Rich text"), contents: iconComponentFor("rich_text"), value: "rich-text" });
15
16
  }
16
17
  if (options.includes("diff")) {
17
- toggleGroupItems.push({ title: "Diff mode", contents: iconComponentFor("difference"), value: "diff" });
18
+ toggleGroupItems.push({ title: t("toolbar.diffMode", "Diff mode"), contents: iconComponentFor("difference"), value: "diff" });
18
19
  }
19
20
  if (options.includes("source")) {
20
- toggleGroupItems.push({ title: "Source", contents: iconComponentFor("markdown"), value: "source" });
21
+ toggleGroupItems.push({ title: t("toolbar.source", "Source mode"), contents: iconComponentFor("markdown"), value: "source" });
21
22
  }
22
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, viewMode === "rich-text" ? children : viewMode === "diff" ? /* @__PURE__ */ React__default.createElement("span", { className: styles.toolbarTitleMode }, "Diff mode") : /* @__PURE__ */ React__default.createElement("span", { className: styles.toolbarTitleMode }, "Source mode"), /* @__PURE__ */ React__default.createElement("div", { style: { marginLeft: "auto", pointerEvents: "auto", opacity: 1 } }, /* @__PURE__ */ React__default.createElement(
23
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, viewMode === "rich-text" ? children : viewMode === "diff" ? /* @__PURE__ */ React__default.createElement("span", { className: styles.toolbarTitleMode }, t("toolbar.diffMode", "Diff mode")) : /* @__PURE__ */ React__default.createElement("span", { className: styles.toolbarTitleMode }, t("toolbar.source", "Source mode")), /* @__PURE__ */ React__default.createElement("div", { style: { marginLeft: "auto", pointerEvents: "auto", opacity: 1 } }, /* @__PURE__ */ React__default.createElement(
23
24
  SingleChoiceToggleGroup,
24
25
  {
25
26
  className: styles.diffSourceToggle,
@@ -3,18 +3,20 @@ import { ButtonOrDropdownButton } from "../primitives/toolbar.js";
3
3
  import { insertDirective$ } from "../../directives/index.js";
4
4
  import { ADMONITION_TYPES } from "../../../directive-editors/AdmonitionDirectiveDescriptor.js";
5
5
  import { usePublisher, useCellValue } from "@mdxeditor/gurx";
6
- import { iconComponentFor$ } from "../../core/index.js";
6
+ import { iconComponentFor$, useTranslation } from "../../core/index.js";
7
+ import { admonitionLabelsMap } from "./ChangeAdmonitionType.js";
7
8
  const InsertAdmonition = () => {
8
9
  const insertDirective = usePublisher(insertDirective$);
9
10
  const iconComponentFor = useCellValue(iconComponentFor$);
10
- const items = React__default.useMemo(
11
- () => ADMONITION_TYPES.map((type) => ({ value: type, label: type.replace(/^./, (l) => l.toUpperCase()) })),
12
- []
13
- );
11
+ const t = useTranslation();
12
+ const items = React__default.useMemo(() => {
13
+ const labels = admonitionLabelsMap(t);
14
+ return ADMONITION_TYPES.map((type) => ({ value: type, label: labels[type] }));
15
+ }, [t]);
14
16
  return /* @__PURE__ */ React__default.createElement(
15
17
  ButtonOrDropdownButton,
16
18
  {
17
- title: "Insert admonition",
19
+ title: t("toolbar.admonition", "Insert Admonition"),
18
20
  onChoose: (admonitionName) => {
19
21
  insertDirective({
20
22
  type: "containerDirective",
@@ -2,14 +2,15 @@ import React__default from "react";
2
2
  import { ButtonWithTooltip } from "../primitives/toolbar.js";
3
3
  import { insertCodeBlock$ } from "../../codeblock/index.js";
4
4
  import { usePublisher, useCellValue } from "@mdxeditor/gurx";
5
- import { iconComponentFor$ } from "../../core/index.js";
5
+ import { iconComponentFor$, useTranslation } from "../../core/index.js";
6
6
  const InsertCodeBlock = () => {
7
7
  const insertCodeBlock = usePublisher(insertCodeBlock$);
8
8
  const iconComponentFor = useCellValue(iconComponentFor$);
9
+ const t = useTranslation();
9
10
  return /* @__PURE__ */ React__default.createElement(
10
11
  ButtonWithTooltip,
11
12
  {
12
- title: "Insert code block",
13
+ title: t("toolbar.codeBlock", "Insert Code Block"),
13
14
  onClick: () => {
14
15
  insertCodeBlock({});
15
16
  }
@@ -4,14 +4,15 @@ import { insertFrontmatter$, hasFrontmatter$ } from "../../frontmatter/index.js"
4
4
  import styles from "../../../styles/ui.module.css.js";
5
5
  import classNames from "classnames";
6
6
  import { usePublisher, useCellValues } from "@mdxeditor/gurx";
7
- import { iconComponentFor$ } from "../../core/index.js";
7
+ import { iconComponentFor$, useTranslation } from "../../core/index.js";
8
8
  const InsertFrontmatter = () => {
9
9
  const insertFrontmatter = usePublisher(insertFrontmatter$);
10
10
  const [hasFrontmatter, iconComponentFor] = useCellValues(hasFrontmatter$, iconComponentFor$);
11
+ const t = useTranslation();
11
12
  return /* @__PURE__ */ React__default.createElement(
12
13
  ButtonWithTooltip,
13
14
  {
14
- title: hasFrontmatter ? "Edit frontmatter" : "Insert frontmatter",
15
+ title: hasFrontmatter ? t("toolbar.editFrontmatter", "Edit frontmatter") : t("toolbar.insertFrontmatter", "Insert frontmatter"),
15
16
  className: classNames({
16
17
  [styles.activeToolbarButton]: hasFrontmatter
17
18
  }),
@@ -2,13 +2,14 @@ import React__default from "react";
2
2
  import { openNewImageDialog$ } from "../../image/index.js";
3
3
  import * as RadixToolbar from "@radix-ui/react-toolbar";
4
4
  import styles from "../../../styles/ui.module.css.js";
5
- import { readOnly$, iconComponentFor$ } from "../../core/index.js";
5
+ import { readOnly$, iconComponentFor$, useTranslation } from "../../core/index.js";
6
6
  import { TooltipWrap } from "../primitives/TooltipWrap.js";
7
7
  import { usePublisher, useCellValues } from "@mdxeditor/gurx";
8
8
  const InsertImage = React__default.forwardRef((_, forwardedRef) => {
9
9
  const openNewImageDialog = usePublisher(openNewImageDialog$);
10
10
  const [readOnly, iconComponentFor] = useCellValues(readOnly$, iconComponentFor$);
11
- return /* @__PURE__ */ React__default.createElement(RadixToolbar.Button, { className: styles.toolbarButton, ref: forwardedRef, disabled: readOnly, onClick: () => openNewImageDialog() }, /* @__PURE__ */ React__default.createElement(TooltipWrap, { title: "Insert image" }, iconComponentFor("add_photo")));
11
+ const t = useTranslation();
12
+ return /* @__PURE__ */ React__default.createElement(RadixToolbar.Button, { className: styles.toolbarButton, ref: forwardedRef, disabled: readOnly, onClick: () => openNewImageDialog() }, /* @__PURE__ */ React__default.createElement(TooltipWrap, { title: t("toolbar.image", "Insert image") }, iconComponentFor("add_photo")));
12
13
  });
13
14
  export {
14
15
  InsertImage
@@ -2,12 +2,13 @@ import React__default from "react";
2
2
  import { ButtonOrDropdownButton } from "../primitives/toolbar.js";
3
3
  import { sandpackConfig$, insertSandpack$ } from "../../sandpack/index.js";
4
4
  import { useCellValues, usePublisher } from "@mdxeditor/gurx";
5
- import { iconComponentFor$ } from "../../core/index.js";
5
+ import { iconComponentFor$, useTranslation } from "../../core/index.js";
6
6
  const InsertSandpack = () => {
7
7
  const [sandpackConfig, iconComponentFor] = useCellValues(sandpackConfig$, iconComponentFor$);
8
8
  const insertSandpack = usePublisher(insertSandpack$);
9
9
  const items = React__default.useMemo(() => sandpackConfig.presets.map((preset) => ({ value: preset.name, label: preset.label })), [sandpackConfig]);
10
- return /* @__PURE__ */ React__default.createElement(ButtonOrDropdownButton, { title: "Insert Sandpack", onChoose: insertSandpack, items }, iconComponentFor("sandpack"));
10
+ const t = useTranslation();
11
+ return /* @__PURE__ */ React__default.createElement(ButtonOrDropdownButton, { title: t("toolbar.insertSandpack", "Insert Sandpack"), onChoose: insertSandpack, items }, iconComponentFor("sandpack"));
11
12
  };
12
13
  export {
13
14
  InsertSandpack
@@ -2,14 +2,15 @@ import { ButtonWithTooltip } from "../primitives/toolbar.js";
2
2
  import React__default from "react";
3
3
  import { insertTable$ } from "../../table/index.js";
4
4
  import { useCellValue, usePublisher } from "@mdxeditor/gurx";
5
- import { iconComponentFor$ } from "../../core/index.js";
5
+ import { iconComponentFor$, useTranslation } from "../../core/index.js";
6
6
  const InsertTable = () => {
7
7
  const iconComponentFor = useCellValue(iconComponentFor$);
8
8
  const insertTable = usePublisher(insertTable$);
9
+ const t = useTranslation();
9
10
  return /* @__PURE__ */ React__default.createElement(
10
11
  ButtonWithTooltip,
11
12
  {
12
- title: "Insert table",
13
+ title: t("toolbar.table", "Insert Table"),
13
14
  onClick: () => {
14
15
  insertTable({ rows: 3, columns: 3 });
15
16
  }
@@ -2,11 +2,12 @@ import React__default from "react";
2
2
  import { insertThematicBreak$ } from "../../thematic-break/index.js";
3
3
  import { ButtonWithTooltip } from "../primitives/toolbar.js";
4
4
  import { usePublisher, useCellValue } from "@mdxeditor/gurx";
5
- import { iconComponentFor$ } from "../../core/index.js";
5
+ import { iconComponentFor$, useTranslation } from "../../core/index.js";
6
6
  const InsertThematicBreak = () => {
7
7
  const insertThematicBreak = usePublisher(insertThematicBreak$);
8
8
  const iconComponentFor = useCellValue(iconComponentFor$);
9
- return /* @__PURE__ */ React__default.createElement(ButtonWithTooltip, { title: "Insert thematic break", onClick: () => insertThematicBreak() }, iconComponentFor("horizontal_rule"));
9
+ const t = useTranslation();
10
+ return /* @__PURE__ */ React__default.createElement(ButtonWithTooltip, { title: t("toolbar.thematicBreak", "Insert thematic break"), onClick: () => insertThematicBreak() }, iconComponentFor("horizontal_rule"));
10
11
  };
11
12
  export {
12
13
  InsertThematicBreak
@@ -2,12 +2,7 @@ import React__default from "react";
2
2
  import { currentListType$, applyListType$ } from "../../lists/index.js";
3
3
  import { SingleChoiceToggleGroup } from "../primitives/toolbar.js";
4
4
  import { useCellValues, usePublisher } from "@mdxeditor/gurx";
5
- import { iconComponentFor$ } from "../../core/index.js";
6
- const LIST_TITLE_MAP = {
7
- bullet: "Bulleted list",
8
- number: "Numbered list",
9
- check: "Check list"
10
- };
5
+ import { iconComponentFor$, useTranslation } from "../../core/index.js";
11
6
  const ICON_NAME_MAP = {
12
7
  bullet: "format_list_bulleted",
13
8
  number: "format_list_numbered",
@@ -16,6 +11,12 @@ const ICON_NAME_MAP = {
16
11
  const ListsToggle = ({ options = ["bullet", "number", "check"] }) => {
17
12
  const [currentListType, iconComponentFor] = useCellValues(currentListType$, iconComponentFor$);
18
13
  const applyListType = usePublisher(applyListType$);
14
+ const t = useTranslation();
15
+ const LIST_TITLE_MAP = {
16
+ bullet: t("toolbar.bulletedList", "Bulleted list"),
17
+ number: t("toolbar.numberedList", "Numbered list"),
18
+ check: t("toolbar.checkList", "Check list")
19
+ };
19
20
  const items = options.map((type) => ({
20
21
  value: type,
21
22
  title: LIST_TITLE_MAP[type],
@@ -1,6 +1,6 @@
1
1
  import React__default from "react";
2
2
  import styles from "../../../styles/ui.module.css.js";
3
- import { editorInFocus$, activeEditor$, iconComponentFor$ } from "../../core/index.js";
3
+ import { editorInFocus$, activeEditor$, iconComponentFor$, useTranslation } from "../../core/index.js";
4
4
  import { sandpackConfig$ } from "../../sandpack/index.js";
5
5
  import { ButtonWithTooltip } from "../primitives/toolbar.js";
6
6
  import { useCellValues } from "@mdxeditor/gurx";
@@ -12,11 +12,12 @@ const ShowSandpackInfo = () => {
12
12
  sandpackConfig$
13
13
  );
14
14
  const sandpackNode = editorInFocus.rootNode;
15
+ const t = useTranslation();
15
16
  const preset = sandpackConfig.presets.find((preset2) => preset2.meta === sandpackNode.getMeta());
16
17
  return /* @__PURE__ */ React__default.createElement("div", { className: styles.selectWithLabel }, /* @__PURE__ */ React__default.createElement(
17
18
  ButtonWithTooltip,
18
19
  {
19
- title: "Delete this code block",
20
+ title: t("toolbar.deleteSandpack", "Delete this code block"),
20
21
  onClick: () => {
21
22
  theEditor == null ? void 0 : theEditor.update(() => {
22
23
  if (sandpackNode.getNextSibling()) {
@@ -3,12 +3,13 @@ import { useCellValues } from "@mdxeditor/gurx";
3
3
  import { CAN_UNDO_COMMAND, COMMAND_PRIORITY_CRITICAL, CAN_REDO_COMMAND, UNDO_COMMAND, REDO_COMMAND } from "lexical";
4
4
  import React__default from "react";
5
5
  import { IS_APPLE } from "../../../utils/detectMac.js";
6
- import { iconComponentFor$, activeEditor$ } from "../../core/index.js";
6
+ import { iconComponentFor$, activeEditor$, useTranslation } from "../../core/index.js";
7
7
  import { MultipleChoiceToggleGroup } from "../primitives/toolbar.js";
8
8
  const UndoRedo = () => {
9
9
  const [iconComponentFor, activeEditor] = useCellValues(iconComponentFor$, activeEditor$);
10
10
  const [canUndo, setCanUndo] = React__default.useState(false);
11
11
  const [canRedo, setCanRedo] = React__default.useState(false);
12
+ const t = useTranslation();
12
13
  React__default.useEffect(() => {
13
14
  if (activeEditor) {
14
15
  return mergeRegister(
@@ -36,14 +37,14 @@ const UndoRedo = () => {
36
37
  {
37
38
  items: [
38
39
  {
39
- title: IS_APPLE ? "Undo (⌘Z)" : "Undo (Ctrl+Z)",
40
+ title: t("toolbar.undo", "Undo {{shortcut}}", { shortcut: IS_APPLE ? "⌘Z" : "Ctrl+Z" }),
40
41
  disabled: !canUndo,
41
42
  contents: iconComponentFor("undo"),
42
43
  active: false,
43
44
  onChange: () => activeEditor == null ? void 0 : activeEditor.dispatchCommand(UNDO_COMMAND, void 0)
44
45
  },
45
46
  {
46
- title: IS_APPLE ? "Redo (⌘Y)" : "Redo (Ctrl+Y)",
47
+ title: t("toolbar.redo", "Redo {{shortcut}}", { shortcut: IS_APPLE ? "⌘Y" : "Ctrl+Y" }),
47
48
  disabled: !canRedo,
48
49
  contents: iconComponentFor("redo"),
49
50
  active: false,
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "*.css"
12
12
  ],
13
13
  "type": "module",
14
- "version": "2.9.0",
14
+ "version": "2.10.0",
15
15
  "description": "React component for rich text markdown editing",
16
16
  "scripts": {
17
17
  "build": "vite build",
@@ -126,6 +126,7 @@
126
126
  "eslint-plugin-react": "^7.33.2",
127
127
  "eslint-plugin-react-hooks": "^4.6.0",
128
128
  "express": "^4.18.2",
129
+ "i18next": "^23.10.0",
129
130
  "jsdom": "^23.0.1",
130
131
  "mermaid": "^10.6.1",
131
132
  "micromark-util-types": "^2.0.0",