@crystallize/design-system 1.10.0 → 1.11.1

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/CHANGELOG.md +12 -0
  2. package/dist/index.css +15 -17
  3. package/dist/index.d.ts +8 -1
  4. package/dist/index.js +522 -444
  5. package/dist/index.mjs +377 -304
  6. package/package.json +1 -1
  7. package/src/iconography/info.tsx +2 -2
  8. package/src/rich-text-editor/i18n/i18n.test.ts +14 -0
  9. package/src/rich-text-editor/i18n/index.tsx +65 -0
  10. package/src/rich-text-editor/i18n/translations/en.ts +66 -0
  11. package/src/rich-text-editor/i18n/types.ts +62 -0
  12. package/src/rich-text-editor/plugins/ActionsPlugin/index.tsx +5 -22
  13. package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/CopyButton/index.tsx +4 -1
  14. package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/PrettierButton/index.tsx +11 -1
  15. package/src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx +2 -1
  16. package/src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx +23 -5
  17. package/src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx +21 -10
  18. package/src/rich-text-editor/plugins/TabFocusPlugin/index.tsx +4 -12
  19. package/src/rich-text-editor/plugins/TableActionMenuPlugin/index.tsx +23 -14
  20. package/src/rich-text-editor/plugins/ToolbarPlugin/index.tsx +33 -33
  21. package/src/rich-text-editor/plugins/ToolbarPlugin/insert-table.tsx +6 -4
  22. package/src/rich-text-editor/rich-text-editor.css +6 -0
  23. package/src/rich-text-editor/rich-text-editor.stories.tsx +10 -0
  24. package/src/rich-text-editor/rich-text-editor.tsx +15 -9
  25. package/src/rich-text-editor/ui/LinkPreview.tsx +3 -1
  26. package/src/rich-text-editor/ui/ContentEditable.css +0 -13
  27. package/src/rich-text-editor/ui/ContentEditable.tsx +0 -15
package/dist/index.mjs CHANGED
@@ -1503,7 +1503,7 @@ var Info = forwardRef28((delegated, ref) => {
1503
1503
  }),
1504
1504
  /* @__PURE__ */ jsx35("path", {
1505
1505
  fillRule: "evenodd",
1506
- "clip-rule": "evenodd",
1506
+ clipRule: "evenodd",
1507
1507
  d: "M18.253 3.85212C18.253 5.04383 17.2869 6.00991 16.0952 6.00991C14.9035 6.00991 13.9374 5.04383 13.9374 3.85212C13.9374 2.66041 14.9035 1.69434 16.0952 1.69434C17.2869 1.69434 18.253 2.66041 18.253 3.85212ZM16.0952 5.34999C16.9224 5.34999 17.5931 4.67937 17.5931 3.85212C17.5931 3.02487 16.9224 2.35425 16.0952 2.35425C15.2679 2.35425 14.5973 3.02487 14.5973 3.85212C14.5973 4.67937 15.2679 5.34999 16.0952 5.34999Z",
1508
1508
  fill: "#528693"
1509
1509
  }),
@@ -1513,7 +1513,7 @@ var Info = forwardRef28((delegated, ref) => {
1513
1513
  }),
1514
1514
  /* @__PURE__ */ jsx35("path", {
1515
1515
  fillRule: "evenodd",
1516
- "clip-rule": "evenodd",
1516
+ clipRule: "evenodd",
1517
1517
  d: "M11.2842 18.976L11.3049 18.9785C11.5112 19.0031 11.7201 18.9658 11.9049 18.8714C12.0891 18.7772 12.2409 18.6306 12.3411 18.4504C12.3471 18.4394 12.352 18.4277 12.3558 18.4158C12.3317 18.4124 12.3048 18.4091 12.2731 18.4053C12.0384 18.3881 11.8084 18.33 11.5936 18.2335C11.2334 18.0797 10.9456 17.7933 10.7906 17.433C10.6341 17.0694 10.6252 16.6594 10.7658 16.2894C10.9266 15.8663 11.1487 15.4689 11.4246 15.1101L11.6291 14.8181C11.6293 14.8178 11.629 14.8184 11.6291 14.8181C12.0038 14.2802 12.4092 13.763 12.8423 13.2707L12.9418 13.1535C12.9894 13.097 13.0361 13.0418 13.0821 12.9874C13.2314 12.8108 13.3734 12.6428 13.5141 12.4665L13.5237 12.4544L13.5339 12.4428C14.107 11.7899 14.5194 11.0128 14.7386 10.1733C14.8642 9.60674 14.7724 9.1134 14.5125 8.69961C14.2452 8.27422 13.7678 7.88337 13.0466 7.60647L13.0376 7.60304C12.2034 7.26882 11.3198 7.07373 10.4221 7.02572C10.2586 7.02444 10.0952 7.03841 9.93422 7.06745L9.91342 7.0712L9.89242 7.07362C9.77981 7.08656 9.67209 7.12639 9.57839 7.18964C9.48729 7.25113 9.41209 7.33296 9.35867 7.42842C9.35249 7.44171 9.33941 7.47402 9.32659 7.52286C9.31959 7.54951 9.31383 7.57671 9.30949 7.60325C9.36308 7.61115 9.41754 7.61364 9.47206 7.61055L9.51828 7.60793L9.63538 7.61773C9.79024 7.6263 9.94419 7.64682 10.0959 7.67913L10.1211 7.68451L10.1459 7.69185C10.6213 7.83272 11.1176 8.10198 11.3044 8.65041L11.3058 8.6547C11.4603 9.11879 11.309 9.5616 11.1547 9.87197C10.9947 10.194 10.7584 10.5161 10.546 10.7961C10.1932 11.2626 9.79323 11.726 9.4222 12.1559L9.4167 12.1622L9.30686 12.2896L9.29607 12.301C8.50411 13.1358 7.82119 14.0671 7.26353 15.0728C6.95101 15.7053 6.92585 16.2828 7.10297 16.7755C7.28379 17.2785 7.70442 17.772 8.42421 18.1631L8.42623 18.1642C9.29923 18.6426 10.2687 18.9197 11.2633 18.9749L11.2842 18.976ZM6.67909 14.7659C7.26511 13.7065 7.9836 12.7256 8.81732 11.8468L8.91693 11.7313C9.29243 11.2963 9.68044 10.8467 10.0199 10.3976C10.4486 9.83253 10.8215 9.28929 10.6797 8.86312C10.5968 8.6196 10.3605 8.44373 9.9584 8.32457C9.83715 8.29874 9.71404 8.28256 9.59022 8.27617L9.50938 8.26941C9.26232 8.2834 9.01575 8.23452 8.79281 8.12735C8.54248 7.93066 8.64731 7.36817 8.77404 7.12204C8.87835 6.92966 9.02762 6.76522 9.2092 6.64266C9.39077 6.5201 9.59929 6.44304 9.81707 6.41802C10.0235 6.38077 10.2331 6.36335 10.4429 6.36598C11.4176 6.41652 12.3773 6.6275 13.2831 6.9904C14.9259 7.62106 15.7097 8.86885 15.3801 10.3284C15.1357 11.2718 14.6733 12.1451 14.0299 12.8781C13.8828 13.0625 13.7326 13.2401 13.582 13.4182C13.5366 13.4719 13.4912 13.5256 13.4458 13.5795L13.3415 13.7024C12.9232 14.1775 12.5323 14.6759 12.1707 15.1952L11.9564 15.5012C11.7156 15.8119 11.5223 16.1565 11.3827 16.5237C11.303 16.7335 11.308 16.966 11.3968 17.1721C11.4855 17.3783 11.651 17.5421 11.8583 17.6289C12.0086 17.6973 12.1701 17.7377 12.335 17.748C12.5957 17.7793 12.8648 17.8126 12.9712 18.0603C13.0139 18.1752 13.0313 18.298 13.0223 18.4203C13.0133 18.5425 12.9781 18.6615 12.9191 18.769C12.7552 19.0647 12.5066 19.305 12.2052 19.459C11.9037 19.6131 11.563 19.6739 11.2267 19.6338C10.1339 19.5731 9.0685 19.2687 8.1091 18.743C6.45171 17.8422 5.90412 16.3181 6.67909 14.7659Z",
1518
1518
  fill: "#528693"
1519
1519
  })
@@ -3554,6 +3554,7 @@ import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
3554
3554
  import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin";
3555
3555
  import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
3556
3556
  import { useLexicalComposerContext as useLexicalComposerContext12 } from "@lexical/react/LexicalComposerContext";
3557
+ import { ContentEditable } from "@lexical/react/LexicalContentEditable";
3557
3558
 
3558
3559
  // src/rich-text-editor/context/SharedHistoryContext.tsx
3559
3560
  import { createContext, useContext, useMemo } from "react";
@@ -3571,6 +3572,105 @@ var useSharedHistoryContext = () => {
3571
3572
  return useContext(Context);
3572
3573
  };
3573
3574
 
3575
+ // src/rich-text-editor/i18n/index.tsx
3576
+ import { createContext as createContext2, useContext as useContext2 } from "react";
3577
+
3578
+ // src/rich-text-editor/i18n/translations/en.ts
3579
+ var translations = {
3580
+ actionClearTextFormatting: "Clear text formatting",
3581
+ actionTextFormattingOptions: "Formatting options for additional text styles",
3582
+ actionFormatAsStrongLabel: "Format text as bold",
3583
+ actionFormatAsStrongTitle: "Bold (Ctrl+B)",
3584
+ actionFormatAsStrongTitleApple: "Bold (\u2318B)",
3585
+ actionFormatAsEmphasizedLabel: "Format text as italics",
3586
+ actionFormatAsEmphasizedTitle: "Italic (Ctrl+I)",
3587
+ actionFormatAsEmphasizedTitleApple: "Italic (\u2318I)",
3588
+ actionFormatAsUnderlinedLabel: "Underline text",
3589
+ actionFormatAsUnderlinedTitle: "Underlined (Ctrl+U)",
3590
+ actionFormatAsUnderlinedTitleApple: "Underlined (\u2318U)",
3591
+ actionFormatWithStrikethroughLabel: "Format text with a strikethrough",
3592
+ actionFormatWithStrikethroughTitle: "Strikethrough",
3593
+ actionFormatWithSubscriptLabel: "Format text as subscript",
3594
+ actionFormatWithSubscriptTitle: "Subscript",
3595
+ actionFormatWithSuperscriptLabel: "Format text as superscript",
3596
+ actionFormatWithSuperscriptTitle: "Superscript",
3597
+ actionInsertCodeBlock: "Insert code block",
3598
+ actionInsertlink: "Insert link",
3599
+ actionCopyJSON: "Copy JSON",
3600
+ actionCopyCode: "Copy code",
3601
+ actionClear: "Clear editor",
3602
+ actionFormatCode: "Format code with Prettier",
3603
+ actionTableInsertRowsAbove: "Insert row above",
3604
+ actionTableInsertRowsAbove_plural: "Insert {{rows}} rows above",
3605
+ actionTableInsertRowsBelow: "Insert row above",
3606
+ actionTableInsertRowsBelow_plural: "Insert {{rows}} rows above",
3607
+ actionTableInsertColumnsBefore: "Insert column left",
3608
+ actionTableInsertColumnsBefore_plural: "Insert {{columns}} columns left",
3609
+ actionTableInsertColumnsAfter: "Insert column right",
3610
+ actionTableInsertColumnsAfter_plural: "Insert {{columns}} columns right",
3611
+ actionTableAddRowHeader: "Add row header",
3612
+ actionTableRemoveRowHeader: "Remove row header",
3613
+ actionTableAddColumnHeader: "Add column header",
3614
+ actionTableRemoveColumnHeader: "Remove column header",
3615
+ actionTableDeleteColumn: "Delete column",
3616
+ actionTableDeleteRow: "Delete row",
3617
+ actionTableDeleteTable: "Delete table",
3618
+ actionTableOpenOptions: "Open table options",
3619
+ actionUndoLabel: "Undo",
3620
+ actionUndoTitle: "Undo (Ctrl+Z)",
3621
+ actionUndoTitleApple: "Undo (\u2318Z)",
3622
+ actionRedoLabel: "Undo",
3623
+ actionRedoTitle: "Undo (Ctrl+Y)",
3624
+ actionRedoTitleApple: "Redo (\u2318Y)",
3625
+ codeSelectLanguage: "Select language",
3626
+ linkEditorLink: "Link",
3627
+ linkEditorRel: "Rel",
3628
+ linkEditorTarget: "Target",
3629
+ linkEditorCommit: "Done",
3630
+ linkEditorEdit: "Edit",
3631
+ linkPreviewReplaceTextWithTitle: "Replace link text with its title",
3632
+ horizontalRule: "Horizontal rule",
3633
+ table: "Table",
3634
+ insertTableTitle: "Insert table",
3635
+ insertTableDescription: "Define your starting point of a table, you can add and remove columns and rows after creation.",
3636
+ insertTableRows: "Rows",
3637
+ insertTableColumns: "Columns",
3638
+ insertTableCommit: "Insert table"
3639
+ };
3640
+ var en_default = translations;
3641
+
3642
+ // src/rich-text-editor/i18n/index.tsx
3643
+ import { jsx as jsx77 } from "react/jsx-runtime";
3644
+ var I18nContext = createContext2(null);
3645
+ function I18nProvider({
3646
+ labelTranslations,
3647
+ children
3648
+ }) {
3649
+ const translations2 = labelTranslations || en_default;
3650
+ return /* @__PURE__ */ jsx77(I18nContext.Provider, {
3651
+ value: translations2,
3652
+ children
3653
+ });
3654
+ }
3655
+ function replaceI18nVariablesInString(str, replaceWith) {
3656
+ return str.replace(/({{[^}]+}})/g, replaceWith);
3657
+ }
3658
+ function useTr() {
3659
+ const context = useContext2(I18nContext);
3660
+ return (key, units) => {
3661
+ const thereAreUnits = typeof units === "number";
3662
+ const keyToUse = thereAreUnits && units > 1 ? `${key}_plural` : key;
3663
+ if (context && keyToUse in context) {
3664
+ const tr = context[keyToUse];
3665
+ if (thereAreUnits) {
3666
+ return replaceI18nVariablesInString(tr, units.toString());
3667
+ }
3668
+ return tr;
3669
+ }
3670
+ return "";
3671
+ };
3672
+ }
3673
+
3574
3674
  // src/rich-text-editor/model/crystallize-to-lexical.ts
3575
3675
  import {
3576
3676
  $createLineBreakNode,
@@ -3984,7 +4084,7 @@ var BaseNodes = [
3984
4084
  // src/rich-text-editor/plugins/AutoLinkPlugin/index.tsx
3985
4085
  import { AutoLinkPlugin } from "@lexical/react/LexicalAutoLinkPlugin";
3986
4086
  import "react";
3987
- import { jsx as jsx77 } from "react/jsx-runtime";
4087
+ import { jsx as jsx78 } from "react/jsx-runtime";
3988
4088
  var URL_MATCHER = /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
3989
4089
  var EMAIL_MATCHER = /(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/;
3990
4090
  var MATCHERS = [
@@ -4012,7 +4112,7 @@ var MATCHERS = [
4012
4112
  }
4013
4113
  ];
4014
4114
  function LexicalAutoLinkPlugin() {
4015
- return /* @__PURE__ */ jsx77(AutoLinkPlugin, {
4115
+ return /* @__PURE__ */ jsx78(AutoLinkPlugin, {
4016
4116
  matchers: MATCHERS
4017
4117
  });
4018
4118
  }
@@ -4031,9 +4131,10 @@ import { useState } from "react";
4031
4131
  import { $getNearestNodeFromDOMNode, $getSelection, $setSelection } from "lexical";
4032
4132
  import { useDebouncedCallback } from "use-debounce";
4033
4133
  import { $isCodeNode as $isCodeNode2 } from "@lexical/code";
4034
- import { jsx as jsx78 } from "react/jsx-runtime";
4134
+ import { jsx as jsx79 } from "react/jsx-runtime";
4035
4135
  function CopyButton({ editor, getCodeDOMNode }) {
4036
4136
  const [isCopyCompleted, setCopyCompleted] = useState(false);
4137
+ const tr = useTr();
4037
4138
  const removeSuccessIcon = useDebouncedCallback(() => {
4038
4139
  setCopyCompleted(false);
4039
4140
  }, 1e3);
@@ -4059,13 +4160,13 @@ function CopyButton({ editor, getCodeDOMNode }) {
4059
4160
  console.error("Failed to copy: ", err);
4060
4161
  }
4061
4162
  }
4062
- return /* @__PURE__ */ jsx78("button", {
4163
+ return /* @__PURE__ */ jsx79("button", {
4063
4164
  className: "menu-item",
4064
4165
  onClick: handleClick,
4065
- "aria-label": "copy",
4066
- children: isCopyCompleted ? /* @__PURE__ */ jsx78("i", {
4166
+ "aria-label": tr("actionCopyCode"),
4167
+ children: isCopyCompleted ? /* @__PURE__ */ jsx79("i", {
4067
4168
  className: "format success"
4068
- }) : /* @__PURE__ */ jsx78("i", {
4169
+ }) : /* @__PURE__ */ jsx79("i", {
4069
4170
  className: "format copy"
4070
4171
  })
4071
4172
  });
@@ -4076,7 +4177,7 @@ import "react";
4076
4177
  import { useState as useState2 } from "react";
4077
4178
  import { $getNearestNodeFromDOMNode as $getNearestNodeFromDOMNode2 } from "lexical";
4078
4179
  import { $isCodeNode as $isCodeNode3 } from "@lexical/code";
4079
- import { jsx as jsx79, jsxs as jsxs58 } from "react/jsx-runtime";
4180
+ import { jsx as jsx80, jsxs as jsxs58 } from "react/jsx-runtime";
4080
4181
  var PRETTIER_PARSER_MODULES = {
4081
4182
  css: () => import("prettier/parser-postcss"),
4082
4183
  html: () => import("prettier/parser-html"),
@@ -4118,6 +4219,7 @@ function getPrettierOptions(lang) {
4118
4219
  function PrettierButton({ lang, editor, getCodeDOMNode }) {
4119
4220
  const [syntaxError, setSyntaxError] = useState2("");
4120
4221
  const [tipsVisible, setTipsVisible] = useState2(false);
4222
+ const tr = useTr();
4121
4223
  async function handleClick() {
4122
4224
  const codeDOMNode = getCodeDOMNode();
4123
4225
  try {
@@ -4133,6 +4235,7 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4133
4235
  const content = codeNode.getTextContent();
4134
4236
  let parsed = "";
4135
4237
  parsed = format(content, options);
4238
+ parsed = parsed.replace(/[\r\n]+$/, "");
4136
4239
  if (parsed !== "") {
4137
4240
  const selection = codeNode.select(0);
4138
4241
  selection.insertText(parsed);
@@ -4163,19 +4266,19 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4163
4266
  return /* @__PURE__ */ jsxs58("div", {
4164
4267
  className: "prettier-wrapper",
4165
4268
  children: [
4166
- /* @__PURE__ */ jsx79("button", {
4269
+ /* @__PURE__ */ jsx80("button", {
4167
4270
  className: "menu-item",
4168
4271
  onClick: handleClick,
4169
4272
  onMouseEnter: handleMouseEnter,
4170
4273
  onMouseLeave: handleMouseLeave,
4171
- "aria-label": "prettier",
4172
- children: syntaxError ? /* @__PURE__ */ jsx79("i", {
4274
+ "aria-label": tr("actionFormatCode"),
4275
+ children: syntaxError ? /* @__PURE__ */ jsx80("i", {
4173
4276
  className: "format prettier-error"
4174
- }) : /* @__PURE__ */ jsx79("i", {
4277
+ }) : /* @__PURE__ */ jsx80("i", {
4175
4278
  className: "format prettier"
4176
4279
  })
4177
4280
  }),
4178
- tipsVisible ? /* @__PURE__ */ jsx79("pre", {
4281
+ tipsVisible ? /* @__PURE__ */ jsx80("pre", {
4179
4282
  className: "code-error-tips",
4180
4283
  children: syntaxError
4181
4284
  }) : null
@@ -4184,13 +4287,13 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4184
4287
  }
4185
4288
 
4186
4289
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx
4187
- import { Fragment as Fragment2, jsx as jsx80, jsxs as jsxs59 } from "react/jsx-runtime";
4290
+ import { Fragment as Fragment2, jsx as jsx81, jsxs as jsxs59 } from "react/jsx-runtime";
4188
4291
  var CODE_PADDING = 8;
4189
4292
  function CodeActionMenuContainer({ anchorElem }) {
4190
4293
  const [editor] = useLexicalComposerContext();
4191
4294
  const [lang, setLang] = useState3("");
4192
4295
  const [isShown, setShown] = useState3(false);
4193
- const [shouldListenMouseMove, setShouldListenMouseMove] = useState3(false);
4296
+ const [shouldListenMouseMove, setShouldListenMouseMove] = useState3(true);
4194
4297
  const [position, setPosition] = useState3({
4195
4298
  right: "0",
4196
4299
  top: "0"
@@ -4261,20 +4364,20 @@ function CodeActionMenuContainer({ anchorElem }) {
4261
4364
  });
4262
4365
  const normalizedLang = normalizeCodeLang(lang);
4263
4366
  const codeFriendlyName = getLanguageFriendlyName(lang);
4264
- return /* @__PURE__ */ jsx80(Fragment2, {
4367
+ return /* @__PURE__ */ jsx81(Fragment2, {
4265
4368
  children: isShown ? /* @__PURE__ */ jsxs59("div", {
4266
4369
  className: "code-action-menu-container",
4267
4370
  style: { ...position },
4268
4371
  children: [
4269
- /* @__PURE__ */ jsx80("div", {
4372
+ /* @__PURE__ */ jsx81("div", {
4270
4373
  className: "code-highlight-language",
4271
4374
  children: codeFriendlyName
4272
4375
  }),
4273
- /* @__PURE__ */ jsx80(CopyButton, {
4376
+ /* @__PURE__ */ jsx81(CopyButton, {
4274
4377
  editor,
4275
4378
  getCodeDOMNode
4276
4379
  }),
4277
- canBePrettier(normalizedLang) ? /* @__PURE__ */ jsx80(PrettierButton, {
4380
+ canBePrettier(normalizedLang) ? /* @__PURE__ */ jsx81(PrettierButton, {
4278
4381
  editor,
4279
4382
  getCodeDOMNode,
4280
4383
  lang: normalizedLang
@@ -4296,7 +4399,7 @@ function getMouseInfo(event) {
4296
4399
  function CodeActionMenuPlugin({
4297
4400
  anchorElem = document.body
4298
4401
  }) {
4299
- return createPortal(/* @__PURE__ */ jsx80(CodeActionMenuContainer, {
4402
+ return createPortal(/* @__PURE__ */ jsx81(CodeActionMenuContainer, {
4300
4403
  anchorElem
4301
4404
  }), anchorElem);
4302
4405
  }
@@ -4334,7 +4437,7 @@ import { $findMatchingParent, mergeRegister } from "@lexical/utils";
4334
4437
  import { Suspense, useEffect as useEffect3, useState as useState4 } from "react";
4335
4438
  import { $getSelection as $getSelection2, $isTextNode as $isTextNode3 } from "lexical";
4336
4439
  import { useLexicalComposerContext as useLexicalComposerContext3 } from "@lexical/react/LexicalComposerContext";
4337
- import { Fragment as Fragment3, jsx as jsx81, jsxs as jsxs60 } from "react/jsx-runtime";
4440
+ import { Fragment as Fragment3, jsx as jsx82, jsxs as jsxs60 } from "react/jsx-runtime";
4338
4441
  var PREVIEW_CACHE = {};
4339
4442
  var URL_MATCHER2 = /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
4340
4443
  function useSuspenseRequest(url) {
@@ -4361,6 +4464,7 @@ function LinkPreviewContent({
4361
4464
  const [textContent, setTextContent] = useState4("");
4362
4465
  const { preview } = useSuspenseRequest(url);
4363
4466
  const [editor] = useLexicalComposerContext3();
4467
+ const tr = useTr();
4364
4468
  const hasPreview = preview !== null && preview.google?.title;
4365
4469
  useEffect3(() => {
4366
4470
  editor.update(() => {
@@ -4393,32 +4497,32 @@ function LinkPreviewContent({
4393
4497
  return /* @__PURE__ */ jsxs60("div", {
4394
4498
  className: "LinkPreview__container",
4395
4499
  children: [
4396
- preview.google.image && /* @__PURE__ */ jsx81("div", {
4500
+ preview.google.image && /* @__PURE__ */ jsx82("div", {
4397
4501
  className: "LinkPreview__imageWrapper bg-purple-50-900",
4398
- children: /* @__PURE__ */ jsx81("img", {
4502
+ children: /* @__PURE__ */ jsx82("img", {
4399
4503
  src: preview.google.image,
4400
4504
  alt: preview.google.title,
4401
4505
  className: "LinkPreview__image"
4402
4506
  })
4403
4507
  }),
4404
- preview.google.title && /* @__PURE__ */ jsx81("div", {
4508
+ preview.google.title && /* @__PURE__ */ jsx82("div", {
4405
4509
  className: "LinkPreview__title",
4406
4510
  children: preview.google.title
4407
4511
  }),
4408
- preview.google.description && /* @__PURE__ */ jsx81("div", {
4512
+ preview.google.description && /* @__PURE__ */ jsx82("div", {
4409
4513
  className: "LinkPreview__description",
4410
4514
  children: preview.google.description
4411
4515
  }),
4412
- textContent && textContent !== preview.google.title ? /* @__PURE__ */ jsx81(Button, {
4516
+ textContent && textContent !== preview.google.title ? /* @__PURE__ */ jsx82(Button, {
4413
4517
  className: "mb-4 ml-5",
4414
4518
  onClick: useTitleForText,
4415
- children: "Replace link text with its title"
4519
+ children: tr("linkPreviewReplaceTextWithTitle")
4416
4520
  }) : null
4417
4521
  ]
4418
4522
  });
4419
4523
  }
4420
4524
  function Glimmer(props) {
4421
- return /* @__PURE__ */ jsx81("div", {
4525
+ return /* @__PURE__ */ jsx82("div", {
4422
4526
  className: "LinkPreview__glimmer",
4423
4527
  ...props,
4424
4528
  style: {
@@ -4430,24 +4534,24 @@ function Glimmer(props) {
4430
4534
  function LinkPreview({
4431
4535
  url
4432
4536
  }) {
4433
- return /* @__PURE__ */ jsx81(Suspense, {
4537
+ return /* @__PURE__ */ jsx82(Suspense, {
4434
4538
  fallback: /* @__PURE__ */ jsxs60(Fragment3, {
4435
4539
  children: [
4436
- /* @__PURE__ */ jsx81(Glimmer, {
4540
+ /* @__PURE__ */ jsx82(Glimmer, {
4437
4541
  style: { height: "80px" },
4438
4542
  index: 0
4439
4543
  }),
4440
- /* @__PURE__ */ jsx81(Glimmer, {
4544
+ /* @__PURE__ */ jsx82(Glimmer, {
4441
4545
  style: { width: "60%" },
4442
4546
  index: 1
4443
4547
  }),
4444
- /* @__PURE__ */ jsx81(Glimmer, {
4548
+ /* @__PURE__ */ jsx82(Glimmer, {
4445
4549
  style: { width: "80%" },
4446
4550
  index: 2
4447
4551
  })
4448
4552
  ]
4449
4553
  }),
4450
- children: /* @__PURE__ */ jsx81(LinkPreviewContent, {
4554
+ children: /* @__PURE__ */ jsx82(LinkPreviewContent, {
4451
4555
  url
4452
4556
  })
4453
4557
  });
@@ -4516,7 +4620,7 @@ function validateUrl(url) {
4516
4620
  }
4517
4621
 
4518
4622
  // src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx
4519
- import { Fragment as Fragment4, jsx as jsx82, jsxs as jsxs61 } from "react/jsx-runtime";
4623
+ import { Fragment as Fragment4, jsx as jsx83, jsxs as jsxs61 } from "react/jsx-runtime";
4520
4624
  function FloatingLinkEditor({
4521
4625
  editor,
4522
4626
  isLink,
@@ -4530,6 +4634,7 @@ function FloatingLinkEditor({
4530
4634
  const [target, setTarget] = useState5(null);
4531
4635
  const [isEditMode, setEditMode] = useState5(false);
4532
4636
  const [lastSelection, setLastSelection] = useState5(null);
4637
+ const tr = useTr();
4533
4638
  const updateLinkEditor = useCallback(() => {
4534
4639
  const selection = $getSelection3();
4535
4640
  if ($isRangeSelection(selection)) {
@@ -4636,41 +4741,41 @@ function FloatingLinkEditor({
4636
4741
  inputRef.current.focus();
4637
4742
  }
4638
4743
  }, [isEditMode]);
4639
- return /* @__PURE__ */ jsx82("div", {
4744
+ return /* @__PURE__ */ jsx83("div", {
4640
4745
  ref: editorRef,
4641
4746
  className: "link-editor",
4642
4747
  children: isEditMode ? /* @__PURE__ */ jsxs61("div", {
4643
4748
  children: [
4644
- /* @__PURE__ */ jsx82("div", {
4749
+ /* @__PURE__ */ jsx83("div", {
4645
4750
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4646
- children: /* @__PURE__ */ jsx82(InputWithLabel, {
4647
- label: "Link",
4751
+ children: /* @__PURE__ */ jsx83(InputWithLabel, {
4752
+ label: tr("linkEditorLink"),
4648
4753
  type: "text",
4649
4754
  value: linkUrl,
4650
4755
  onChange: (e) => setLinkUrl(e.target.value)
4651
4756
  })
4652
4757
  }),
4653
- /* @__PURE__ */ jsx82("div", {
4758
+ /* @__PURE__ */ jsx83("div", {
4654
4759
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4655
- children: /* @__PURE__ */ jsx82(InputWithLabel, {
4656
- label: "Rel",
4760
+ children: /* @__PURE__ */ jsx83(InputWithLabel, {
4761
+ label: tr("linkEditorRel"),
4657
4762
  type: "text",
4658
4763
  value: rel ?? "",
4659
4764
  onChange: (e) => setRel(e.target.value)
4660
4765
  })
4661
4766
  }),
4662
- /* @__PURE__ */ jsx82("div", {
4767
+ /* @__PURE__ */ jsx83("div", {
4663
4768
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4664
- children: /* @__PURE__ */ jsx82(InputWithLabel, {
4665
- label: "Target",
4769
+ children: /* @__PURE__ */ jsx83(InputWithLabel, {
4770
+ label: tr("linkEditorTarget"),
4666
4771
  type: "text",
4667
4772
  value: target ?? "",
4668
4773
  onChange: (e) => setTarget(e.target.value)
4669
4774
  })
4670
4775
  }),
4671
- /* @__PURE__ */ jsx82("div", {
4776
+ /* @__PURE__ */ jsx83("div", {
4672
4777
  className: "flex px-6 py-2 justify-end",
4673
- children: /* @__PURE__ */ jsx82(Button, {
4778
+ children: /* @__PURE__ */ jsx83(Button, {
4674
4779
  onClick: () => {
4675
4780
  if (lastSelection !== null) {
4676
4781
  if (linkUrl !== "") {
@@ -4683,7 +4788,7 @@ function FloatingLinkEditor({
4683
4788
  setEditMode(false);
4684
4789
  }
4685
4790
  },
4686
- children: "Done"
4791
+ children: tr("linkEditorCommit")
4687
4792
  })
4688
4793
  })
4689
4794
  ]
@@ -4693,9 +4798,9 @@ function FloatingLinkEditor({
4693
4798
  className: "link-input !flex flex-nowrap justify-between items-center max-w-full ",
4694
4799
  children: [
4695
4800
  /* @__PURE__ */ jsxs61("div", {
4696
- className: " grid",
4801
+ className: "grid",
4697
4802
  children: [
4698
- /* @__PURE__ */ jsx82("a", {
4803
+ /* @__PURE__ */ jsx83("a", {
4699
4804
  href: linkUrl,
4700
4805
  target: "_blank",
4701
4806
  rel: "noopener noreferrer",
@@ -4704,11 +4809,11 @@ function FloatingLinkEditor({
4704
4809
  rel || target ? /* @__PURE__ */ jsxs61("div", {
4705
4810
  className: "flex mt-1 gap-1",
4706
4811
  children: [
4707
- rel && /* @__PURE__ */ jsx82("div", {
4812
+ rel && /* @__PURE__ */ jsx83("div", {
4708
4813
  className: "text-[10px] text-gray-600-300 px-1 bg-purple-50-900 rounded-md py-0.5",
4709
4814
  children: rel
4710
4815
  }),
4711
- target && /* @__PURE__ */ jsx82("div", {
4816
+ target && /* @__PURE__ */ jsx83("div", {
4712
4817
  className: "text-[10px] text-gray-600-300 px-1 bg-purple-50-900 rounded-md py-0.5",
4713
4818
  children: target
4714
4819
  })
@@ -4716,19 +4821,20 @@ function FloatingLinkEditor({
4716
4821
  }) : null
4717
4822
  ]
4718
4823
  }),
4719
- /* @__PURE__ */ jsx82("div", {
4720
- children: /* @__PURE__ */ jsx82(IconButton, {
4824
+ /* @__PURE__ */ jsx83("div", {
4825
+ children: /* @__PURE__ */ jsx83(IconButton, {
4721
4826
  size: "sm",
4722
4827
  tabIndex: 0,
4723
4828
  onMouseDown: (event) => event.preventDefault(),
4724
4829
  onClick: () => setEditMode(true),
4725
- children: /* @__PURE__ */ jsx82(Icon.Edit, {})
4830
+ "aria-label": tr("linkEditorEdit"),
4831
+ children: /* @__PURE__ */ jsx83(Icon.Edit, {})
4726
4832
  })
4727
4833
  })
4728
4834
  ]
4729
4835
  }),
4730
- /* @__PURE__ */ jsx82("div", {
4731
- children: /* @__PURE__ */ jsx82(LinkPreview, {
4836
+ /* @__PURE__ */ jsx83("div", {
4837
+ children: /* @__PURE__ */ jsx83(LinkPreview, {
4732
4838
  url: linkUrl
4733
4839
  })
4734
4840
  })
@@ -4764,7 +4870,7 @@ function useFloatingLinkEditorToolbar(editor, anchorElem) {
4764
4870
  );
4765
4871
  }, [editor, updateToolbar]);
4766
4872
  return isLink ? createPortal2(
4767
- /* @__PURE__ */ jsx82(FloatingLinkEditor, {
4873
+ /* @__PURE__ */ jsx83(FloatingLinkEditor, {
4768
4874
  editor: activeEditor,
4769
4875
  isLink,
4770
4876
  anchorElem,
@@ -4797,6 +4903,9 @@ import { $isLinkNode as $isLinkNode3, TOGGLE_LINK_COMMAND as TOGGLE_LINK_COMMAND
4797
4903
  import { useLexicalComposerContext as useLexicalComposerContext5 } from "@lexical/react/LexicalComposerContext";
4798
4904
  import { mergeRegister as mergeRegister2 } from "@lexical/utils";
4799
4905
 
4906
+ // src/rich-text-editor/utils/environment.ts
4907
+ var IS_APPLE = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
4908
+
4800
4909
  // src/rich-text-editor/utils/getDOMRangeRect.ts
4801
4910
  function getDOMRangeRect(nativeSelection, rootElement) {
4802
4911
  const domRange = nativeSelection.getRangeAt(0);
@@ -4827,7 +4936,7 @@ function getDOMRangeRect(nativeSelection, rootElement) {
4827
4936
  }
4828
4937
 
4829
4938
  // src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx
4830
- import { Fragment as Fragment5, jsx as jsx83, jsxs as jsxs62 } from "react/jsx-runtime";
4939
+ import { Fragment as Fragment5, jsx as jsx84, jsxs as jsxs62 } from "react/jsx-runtime";
4831
4940
  function TextFormatFloatingToolbar({
4832
4941
  editor,
4833
4942
  anchorElem,
@@ -4841,6 +4950,7 @@ function TextFormatFloatingToolbar({
4841
4950
  isSuperscript
4842
4951
  }) {
4843
4952
  const popupCharStylesEditorRef = useRef3(null);
4953
+ const tr = useTr();
4844
4954
  const insertLink = useCallback2(() => {
4845
4955
  if (!isLink) {
4846
4956
  editor.dispatchCommand(TOGGLE_LINK_COMMAND2, "https://");
@@ -4899,88 +5009,92 @@ function TextFormatFloatingToolbar({
4899
5009
  )
4900
5010
  );
4901
5011
  }, [editor, updateTextFormatFloatingToolbar]);
4902
- return /* @__PURE__ */ jsx83("div", {
5012
+ return /* @__PURE__ */ jsx84("div", {
4903
5013
  ref: popupCharStylesEditorRef,
4904
5014
  className: "c-floating-text-format-popup gap-0.5",
4905
5015
  children: editor.isEditable() && /* @__PURE__ */ jsxs62(Fragment5, {
4906
5016
  children: [
4907
- /* @__PURE__ */ jsx83(IconButton, {
5017
+ /* @__PURE__ */ jsx84(IconButton, {
4908
5018
  onClick: () => {
4909
5019
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "bold");
4910
5020
  },
4911
5021
  style: { padding: 0, overflow: "hidden" },
4912
- "aria-label": "Format text as bold",
4913
- children: /* @__PURE__ */ jsx83("i", {
5022
+ title: tr(IS_APPLE ? "actionFormatAsStrongTitleApple" : "actionFormatAsStrongTitle"),
5023
+ "aria-label": tr("actionFormatAsStrongLabel"),
5024
+ children: /* @__PURE__ */ jsx84("i", {
4914
5025
  className: `format bold w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isBold ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4915
5026
  })
4916
5027
  }),
4917
- /* @__PURE__ */ jsx83(IconButton, {
5028
+ /* @__PURE__ */ jsx84(IconButton, {
4918
5029
  style: { padding: 0, overflow: "hidden" },
4919
5030
  onClick: () => {
4920
5031
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "italic");
4921
5032
  },
4922
- "aria-label": "Format text as italics",
4923
- children: /* @__PURE__ */ jsx83("i", {
5033
+ title: tr("actionFormatAsEmphasizedTitle"),
5034
+ "aria-label": tr("actionFormatAsEmphasizedLabel"),
5035
+ children: /* @__PURE__ */ jsx84("i", {
4924
5036
  className: `format italic w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isItalic ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4925
5037
  })
4926
5038
  }),
4927
- /* @__PURE__ */ jsx83(IconButton, {
5039
+ /* @__PURE__ */ jsx84(IconButton, {
4928
5040
  style: { padding: 0, overflow: "hidden" },
4929
5041
  onClick: () => {
4930
5042
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "underline");
4931
5043
  },
4932
- "aria-label": "Format text to underlined",
4933
- children: /* @__PURE__ */ jsx83("i", {
5044
+ title: tr("actionFormatAsUnderlinedTitle"),
5045
+ "aria-label": tr("actionFormatAsUnderlinedLabel"),
5046
+ children: /* @__PURE__ */ jsx84("i", {
4934
5047
  className: `format underline w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isUnderline ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4935
5048
  })
4936
5049
  }),
4937
- /* @__PURE__ */ jsx83(IconButton, {
5050
+ /* @__PURE__ */ jsx84(IconButton, {
4938
5051
  style: { padding: 0, overflow: "hidden" },
4939
5052
  onClick: () => {
4940
5053
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "strikethrough");
4941
5054
  },
4942
- "aria-label": "Format text with a strikethrough",
4943
- children: /* @__PURE__ */ jsx83("i", {
5055
+ title: tr("actionFormatWithStrikethroughTitle"),
5056
+ "aria-label": tr("actionFormatWithStrikethroughLabel"),
5057
+ children: /* @__PURE__ */ jsx84("i", {
4944
5058
  className: `format strikethrough w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isStrikethrough ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4945
5059
  })
4946
5060
  }),
4947
- /* @__PURE__ */ jsx83(IconButton, {
5061
+ /* @__PURE__ */ jsx84(IconButton, {
4948
5062
  style: { padding: 0, overflow: "hidden" },
4949
5063
  onClick: () => {
4950
5064
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "subscript");
4951
5065
  },
4952
- title: "Subscript",
4953
- "aria-label": "Format Subscript",
4954
- children: /* @__PURE__ */ jsx83("i", {
5066
+ title: tr("actionFormatWithSubscriptTitle"),
5067
+ "aria-label": tr("actionFormatWithSubscriptLabel"),
5068
+ children: /* @__PURE__ */ jsx84("i", {
4955
5069
  className: `format subscript w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isSubscript ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4956
5070
  })
4957
5071
  }),
4958
- /* @__PURE__ */ jsx83(IconButton, {
5072
+ /* @__PURE__ */ jsx84(IconButton, {
4959
5073
  style: { padding: 0, overflow: "hidden" },
4960
5074
  onClick: () => {
4961
5075
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "superscript");
4962
5076
  },
4963
- title: "Superscript",
4964
- "aria-label": "Format Superscript",
4965
- children: /* @__PURE__ */ jsx83("i", {
5077
+ title: tr("actionFormatWithSuperscriptTitle"),
5078
+ "aria-label": tr("actionFormatWithSuperscriptLabel"),
5079
+ children: /* @__PURE__ */ jsx84("i", {
4966
5080
  className: `format superscript w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isSuperscript ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4967
5081
  })
4968
5082
  }),
4969
- /* @__PURE__ */ jsx83(IconButton, {
5083
+ /* @__PURE__ */ jsx84(IconButton, {
4970
5084
  style: { padding: 0, overflow: "hidden" },
4971
5085
  onClick: () => {
4972
5086
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "code");
4973
5087
  },
4974
- "aria-label": "Insert code block",
4975
- children: /* @__PURE__ */ jsx83("i", {
5088
+ "aria-label": tr("actionInsertCodeBlock"),
5089
+ children: /* @__PURE__ */ jsx84("i", {
4976
5090
  className: `format code w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isCode ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4977
5091
  })
4978
5092
  }),
4979
- /* @__PURE__ */ jsx83(IconButton, {
5093
+ /* @__PURE__ */ jsx84(IconButton, {
4980
5094
  style: { padding: 0, overflow: "hidden" },
4981
5095
  onClick: insertLink,
4982
- "aria-label": "Insert link",
4983
- children: /* @__PURE__ */ jsx83("i", {
5096
+ "aria-label": tr("actionInsertlink"),
5097
+ children: /* @__PURE__ */ jsx84("i", {
4984
5098
  className: `format link w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isLink ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4985
5099
  })
4986
5100
  })
@@ -5056,7 +5170,7 @@ function useFloatingTextFormatToolbar(editor, anchorElem) {
5056
5170
  return null;
5057
5171
  }
5058
5172
  return createPortal3(
5059
- /* @__PURE__ */ jsx83(TextFormatFloatingToolbar, {
5173
+ /* @__PURE__ */ jsx84(TextFormatFloatingToolbar, {
5060
5174
  editor,
5061
5175
  anchorElem,
5062
5176
  isLink,
@@ -5081,9 +5195,9 @@ function FloatingTextFormatToolbarPlugin({
5081
5195
  // src/rich-text-editor/plugins/LinkPlugin/index.tsx
5082
5196
  import { LinkPlugin as LexicalLinkPlugin } from "@lexical/react/LexicalLinkPlugin";
5083
5197
  import "react";
5084
- import { jsx as jsx84 } from "react/jsx-runtime";
5198
+ import { jsx as jsx85 } from "react/jsx-runtime";
5085
5199
  function LinkPlugin() {
5086
- return /* @__PURE__ */ jsx84(LexicalLinkPlugin, {
5200
+ return /* @__PURE__ */ jsx85(LexicalLinkPlugin, {
5087
5201
  validateUrl
5088
5202
  });
5089
5203
  }
@@ -5218,14 +5332,9 @@ function MaxLengthPlugin({ maxLength }) {
5218
5332
  }
5219
5333
 
5220
5334
  // src/rich-text-editor/plugins/TabFocusPlugin/index.tsx
5221
- import { useLexicalComposerContext as useLexicalComposerContext8 } from "@lexical/react/LexicalComposerContext";
5222
- import {
5223
- $getSelection as $getSelection7,
5224
- $isRangeSelection as $isRangeSelection5,
5225
- $setSelection as $setSelection2,
5226
- FOCUS_COMMAND
5227
- } from "lexical";
5228
5335
  import { useEffect as useEffect8 } from "react";
5336
+ import { $getSelection as $getSelection7, $isRangeSelection as $isRangeSelection5, $setSelection as $setSelection2, FOCUS_COMMAND } from "lexical";
5337
+ import { useLexicalComposerContext as useLexicalComposerContext8 } from "@lexical/react/LexicalComposerContext";
5229
5338
  var COMMAND_PRIORITY_LOW3 = 1;
5230
5339
  var TAB_TO_FOCUS_INTERVAL = 100;
5231
5340
  var lastTabKeyDownTimestamp = 0;
@@ -5288,7 +5397,7 @@ import {
5288
5397
  TableCellHeaderStates,
5289
5398
  TableCellNode as TableCellNode2
5290
5399
  } from "@lexical/table";
5291
- import { Fragment as Fragment6, jsx as jsx85, jsxs as jsxs63 } from "react/jsx-runtime";
5400
+ import { Fragment as Fragment6, jsx as jsx86, jsxs as jsxs63 } from "react/jsx-runtime";
5292
5401
  function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5293
5402
  const [editor] = useLexicalComposerContext9();
5294
5403
  const [tableCellNode, updateTableCellNode] = useState7(_tableCellNode);
@@ -5296,6 +5405,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5296
5405
  columns: 1,
5297
5406
  rows: 1
5298
5407
  });
5408
+ const tr = useTr();
5299
5409
  useEffect9(() => {
5300
5410
  return editor.registerMutationListener(TableCellNode2, (nodeMutations) => {
5301
5411
  const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === "updated";
@@ -5444,71 +5554,53 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5444
5554
  }, [editor, tableCellNode, clearTableSelection]);
5445
5555
  return /* @__PURE__ */ jsxs63(Fragment6, {
5446
5556
  children: [
5447
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5557
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5448
5558
  onSelect: () => insertTableRowAtSelection(false),
5449
- children: [
5450
- "Insert ",
5451
- selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
5452
- " above"
5453
- ]
5559
+ children: tr("actionTableInsertRowsAbove", selectionCounts.rows)
5454
5560
  }),
5455
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5561
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5456
5562
  onSelect: () => insertTableRowAtSelection(true),
5457
- children: [
5458
- "Insert ",
5459
- selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
5460
- " below"
5461
- ]
5563
+ children: tr("actionTableInsertRowsBelow", selectionCounts.rows)
5462
5564
  }),
5463
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5565
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5464
5566
  onSelect: () => insertTableColumnAtSelection(false),
5465
- children: [
5466
- "Insert ",
5467
- selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
5468
- " left"
5469
- ]
5567
+ children: tr("actionTableInsertColumnsBefore", selectionCounts.columns)
5470
5568
  }),
5471
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5569
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5472
5570
  onSelect: () => insertTableColumnAtSelection(true),
5473
- children: [
5474
- "Insert ",
5475
- selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
5476
- " right"
5477
- ]
5571
+ children: tr("actionTableInsertColumnsAfter", selectionCounts.columns)
5478
5572
  }),
5479
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5573
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5480
5574
  onSelect: () => toggleTableRowIsHeader(),
5481
- children: [
5482
- (tableCellNode.__headerState & TableCellHeaderStates.ROW) === TableCellHeaderStates.ROW ? "Remove" : "Add",
5483
- " row header"
5484
- ]
5575
+ children: tr(
5576
+ (tableCellNode.__headerState & TableCellHeaderStates.ROW) === TableCellHeaderStates.ROW ? "actionTableRemoveRowHeader" : "actionTableAddRowHeader"
5577
+ )
5485
5578
  }),
5486
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5579
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5487
5580
  onSelect: () => toggleTableColumnIsHeader(),
5488
- children: [
5489
- (tableCellNode.__headerState & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN ? "Remove" : "Add",
5490
- " ",
5491
- "column header"
5492
- ]
5581
+ children: tr(
5582
+ (tableCellNode.__headerState & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN ? "actionTableRemoveColumnHeader" : "actionTableAddColumnHeader"
5583
+ )
5493
5584
  }),
5494
- /* @__PURE__ */ jsx85(DropdownMenu.Separator, {}),
5495
- tableStats.columns > 1 && /* @__PURE__ */ jsx85(DropdownMenu.Item, {
5585
+ /* @__PURE__ */ jsx86(DropdownMenu.Separator, {}),
5586
+ tableStats.columns > 1 && /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5496
5587
  onSelect: () => deleteTableColumnAtSelection(),
5497
- children: "Delete column"
5588
+ children: tr("actionTableDeleteColumn")
5498
5589
  }),
5499
- tableStats.rows > 1 && /* @__PURE__ */ jsx85(DropdownMenu.Item, {
5590
+ tableStats.rows > 1 && /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5500
5591
  onSelect: () => deleteTableRowAtSelection(),
5501
- children: "Delete row"
5592
+ children: tr("actionTableDeleteRow")
5502
5593
  }),
5503
- /* @__PURE__ */ jsx85(DropdownMenu.Item, {
5594
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5504
5595
  onSelect: () => deleteTableAtSelection(),
5505
- children: "Delete table"
5596
+ children: tr("actionTableDeleteTable")
5506
5597
  })
5507
5598
  ]
5508
5599
  });
5509
5600
  }
5510
5601
  function TableCellActionMenuContainer({ anchorElem }) {
5511
5602
  const [editor] = useLexicalComposerContext9();
5603
+ const tr = useTr();
5512
5604
  const menuButtonRef = useRef4(null);
5513
5605
  const [isMenuOpen, setIsMenuOpen] = useState7(false);
5514
5606
  const [tableCellNode, setTableMenuCellNode] = useState7(null);
@@ -5581,19 +5673,20 @@ function TableCellActionMenuContainer({ anchorElem }) {
5581
5673
  }
5582
5674
  }
5583
5675
  }, [menuButtonRef, tableCellNode, editor, anchorElem]);
5584
- return /* @__PURE__ */ jsx85("div", {
5676
+ return /* @__PURE__ */ jsx86("div", {
5585
5677
  className: "table-cell-action-button-container",
5586
5678
  ref: menuButtonRef,
5587
- children: tableCellNode != null && /* @__PURE__ */ jsx85(DropdownMenu.Root, {
5679
+ children: tableCellNode != null && /* @__PURE__ */ jsx86(DropdownMenu.Root, {
5588
5680
  onOpenChange: (isOpen) => setIsMenuOpen(isOpen),
5589
- content: /* @__PURE__ */ jsx85(TableActionMenu, {
5681
+ content: /* @__PURE__ */ jsx86(TableActionMenu, {
5590
5682
  tableCellNode,
5591
5683
  tableStats
5592
5684
  }),
5593
- children: /* @__PURE__ */ jsx85(IconButton, {
5685
+ children: /* @__PURE__ */ jsx86(IconButton, {
5594
5686
  size: "xs",
5595
5687
  className: "table-cell-action-button",
5596
- children: /* @__PURE__ */ jsx85(Icon.Arrow, {})
5688
+ "aria-label": tr("actionTableOpenOptions"),
5689
+ children: /* @__PURE__ */ jsx86(Icon.Arrow, {})
5597
5690
  })
5598
5691
  })
5599
5692
  });
@@ -5602,7 +5695,7 @@ function TableActionMenuPlugin({
5602
5695
  anchorElem = document.body
5603
5696
  }) {
5604
5697
  const isEditable = useLexicalEditable();
5605
- return createPortal4(isEditable ? /* @__PURE__ */ jsx85(TableCellActionMenuContainer, {
5698
+ return createPortal4(isEditable ? /* @__PURE__ */ jsx86(TableCellActionMenuContainer, {
5606
5699
  anchorElem
5607
5700
  }) : null, anchorElem);
5608
5701
  }
@@ -5653,13 +5746,10 @@ import {
5653
5746
  mergeRegister as mergeRegister3
5654
5747
  } from "@lexical/utils";
5655
5748
 
5656
- // src/rich-text-editor/utils/environment.ts
5657
- var IS_APPLE = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
5658
-
5659
5749
  // src/rich-text-editor/plugins/ActionsPlugin/index.tsx
5660
5750
  import { CLEAR_EDITOR_COMMAND } from "lexical";
5661
5751
  import { useLexicalComposerContext as useLexicalComposerContext10 } from "@lexical/react/LexicalComposerContext";
5662
- import { jsx as jsx86, jsxs as jsxs64 } from "react/jsx-runtime";
5752
+ import { jsx as jsx87, jsxs as jsxs64 } from "react/jsx-runtime";
5663
5753
  async function copyJson(editor) {
5664
5754
  const json = lexicalToCrystallizeRichText({ editor, editorState: editor.getEditorState() });
5665
5755
  try {
@@ -5668,53 +5758,36 @@ async function copyJson(editor) {
5668
5758
  console.warn("Copy failed", error);
5669
5759
  }
5670
5760
  }
5671
- async function exportJson(editor) {
5672
- const json = lexicalToCrystallizeRichText({ editorState: editor.getEditorState() });
5673
- const blob = new Blob([JSON.stringify(json, null, 1)], {
5674
- type: "application/json"
5675
- });
5676
- const href = URL.createObjectURL(blob);
5677
- const link = document.createElement("a");
5678
- link.href = href;
5679
- link.download = "crystallizeRichText.json";
5680
- document.body.appendChild(link);
5681
- link.click();
5682
- document.body.removeChild(link);
5683
- URL.revokeObjectURL(href);
5684
- }
5685
5761
  function ActionsPlugin({
5686
5762
  append,
5687
5763
  prepend
5688
5764
  }) {
5689
5765
  const [editor] = useLexicalComposerContext10();
5766
+ const tr = useTr();
5690
5767
  return /* @__PURE__ */ jsxs64("div", {
5691
5768
  className: "z-50 flex items-center ",
5692
5769
  children: [
5693
- /* @__PURE__ */ jsx86("div", {}),
5770
+ /* @__PURE__ */ jsx87("div", {}),
5694
5771
  /* @__PURE__ */ jsxs64(ActionMenu, {
5695
5772
  children: [
5696
- !prepend ? null : prepend.map((actionItem) => /* @__PURE__ */ jsx86(ActionMenu.Item, {
5773
+ !prepend ? null : prepend.map((actionItem) => /* @__PURE__ */ jsx87(ActionMenu.Item, {
5697
5774
  onSelect: actionItem.action,
5698
5775
  className: actionItem.type === "danger" ? "danger" : "",
5699
5776
  children: actionItem.title
5700
5777
  }, actionItem.title)),
5701
- /* @__PURE__ */ jsx86(ActionMenu.Item, {
5778
+ /* @__PURE__ */ jsx87(ActionMenu.Item, {
5702
5779
  onSelect: () => copyJson(editor),
5703
- children: "Copy JSON"
5704
- }),
5705
- /* @__PURE__ */ jsx86(ActionMenu.Item, {
5706
- onSelect: () => exportJson(editor),
5707
- children: "Export JSON"
5780
+ children: tr("actionCopyJSON")
5708
5781
  }),
5709
- /* @__PURE__ */ jsx86(ActionMenu.Item, {
5782
+ /* @__PURE__ */ jsx87(ActionMenu.Item, {
5710
5783
  className: "danger",
5711
5784
  onSelect: () => {
5712
5785
  editor.dispatchCommand(CLEAR_EDITOR_COMMAND, void 0);
5713
5786
  editor.focus();
5714
5787
  },
5715
- children: "Clear paragraph"
5788
+ children: tr("actionClear")
5716
5789
  }),
5717
- !append ? null : append.map((actionItem) => /* @__PURE__ */ jsx86(ActionMenu.Item, {
5790
+ !append ? null : append.map((actionItem) => /* @__PURE__ */ jsx87(ActionMenu.Item, {
5718
5791
  onSelect: actionItem.action,
5719
5792
  className: actionItem.type === "danger" ? "danger" : "",
5720
5793
  children: actionItem.title
@@ -5728,10 +5801,11 @@ function ActionsPlugin({
5728
5801
  // src/rich-text-editor/plugins/ToolbarPlugin/insert-table.tsx
5729
5802
  import { useState as useState8 } from "react";
5730
5803
  import { INSERT_TABLE_COMMAND } from "@lexical/table";
5731
- import { Fragment as Fragment7, jsx as jsx87, jsxs as jsxs65 } from "react/jsx-runtime";
5804
+ import { Fragment as Fragment7, jsx as jsx88, jsxs as jsxs65 } from "react/jsx-runtime";
5732
5805
  function InsertTableDialog({ activeEditor }) {
5733
5806
  const [rows, setRows] = useState8("5");
5734
5807
  const [columns, setColumns] = useState8("5");
5808
+ const tr = useTr();
5735
5809
  const onClick = () => {
5736
5810
  if (parseInt(rows) < 1 || parseInt(columns) < 1) {
5737
5811
  return;
@@ -5750,20 +5824,20 @@ function InsertTableDialog({ activeEditor }) {
5750
5824
  /* @__PURE__ */ jsxs65("div", {
5751
5825
  className: "grid grid-cols-[1fr_1px_1fr] border border-gray-100-800 border-solid shadow-sm rounded-md ",
5752
5826
  children: [
5753
- /* @__PURE__ */ jsx87(InputWithLabel, {
5754
- label: "Rows",
5827
+ /* @__PURE__ */ jsx88(InputWithLabel, {
5828
+ label: tr("insertTableRows"),
5755
5829
  value: rows,
5756
5830
  placeholder: "0",
5757
5831
  type: "text",
5758
5832
  inputMode: "numeric",
5759
5833
  onChange: (e) => setRows(e.target.value)
5760
5834
  }),
5761
- /* @__PURE__ */ jsx87("span", {
5835
+ /* @__PURE__ */ jsx88("span", {
5762
5836
  className: "h-full bg-gray-100-800"
5763
5837
  }),
5764
- /* @__PURE__ */ jsx87(InputWithLabel, {
5838
+ /* @__PURE__ */ jsx88(InputWithLabel, {
5765
5839
  type: "text",
5766
- label: "Columns",
5840
+ label: tr("insertTableColumns"),
5767
5841
  placeholder: "0",
5768
5842
  value: columns,
5769
5843
  inputMode: "numeric",
@@ -5771,15 +5845,15 @@ function InsertTableDialog({ activeEditor }) {
5771
5845
  })
5772
5846
  ]
5773
5847
  }),
5774
- /* @__PURE__ */ jsx87("div", {
5848
+ /* @__PURE__ */ jsx88("div", {
5775
5849
  className: "flex justify-end mt-3",
5776
- children: /* @__PURE__ */ jsx87(Button, {
5850
+ children: /* @__PURE__ */ jsx88(Button, {
5777
5851
  as: Dialog.Close,
5778
5852
  size: "sm",
5779
5853
  intent: "action",
5780
- "aria-label": "Confirm",
5854
+ "aria-label": tr("insertTableCommit"),
5781
5855
  onClick,
5782
- children: "Confirm"
5856
+ children: tr("insertTableCommit")
5783
5857
  })
5784
5858
  })
5785
5859
  ]
@@ -5787,7 +5861,7 @@ function InsertTableDialog({ activeEditor }) {
5787
5861
  }
5788
5862
 
5789
5863
  // src/rich-text-editor/plugins/ToolbarPlugin/index.tsx
5790
- import { Fragment as Fragment8, jsx as jsx88, jsxs as jsxs66 } from "react/jsx-runtime";
5864
+ import { Fragment as Fragment8, jsx as jsx89, jsxs as jsxs66 } from "react/jsx-runtime";
5791
5865
  var headingTypeToBlockName = {
5792
5866
  h1: "Heading 1",
5793
5867
  h2: "Heading 2",
@@ -5891,7 +5965,7 @@ function BlockFormatDropDown({
5891
5965
  });
5892
5966
  }
5893
5967
  };
5894
- return /* @__PURE__ */ jsx88(DropdownMenu.Root, {
5968
+ return /* @__PURE__ */ jsx89(DropdownMenu.Root, {
5895
5969
  disabled,
5896
5970
  style: { zIndex: 1 },
5897
5971
  content: /* @__PURE__ */ jsxs66(Fragment8, {
@@ -5899,13 +5973,13 @@ function BlockFormatDropDown({
5899
5973
  /* @__PURE__ */ jsxs66(DropdownMenu.Item, {
5900
5974
  onClick: formatParagraph,
5901
5975
  children: [
5902
- /* @__PURE__ */ jsx88("i", {
5976
+ /* @__PURE__ */ jsx89("i", {
5903
5977
  className: `icon paragraph border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === "paragraph" ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5904
5978
  }),
5905
- /* @__PURE__ */ jsx88("i", {
5979
+ /* @__PURE__ */ jsx89("i", {
5906
5980
  className: "icon paragraph"
5907
5981
  }),
5908
- /* @__PURE__ */ jsx88("span", {
5982
+ /* @__PURE__ */ jsx89("span", {
5909
5983
  className: `${blockType === "paragraph" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5910
5984
  children: "Normal"
5911
5985
  })
@@ -5914,10 +5988,10 @@ function BlockFormatDropDown({
5914
5988
  headings.map((headingSize) => /* @__PURE__ */ jsxs66(DropdownMenu.Item, {
5915
5989
  onClick: () => formatHeading(headingSize),
5916
5990
  children: [
5917
- /* @__PURE__ */ jsx88("i", {
5991
+ /* @__PURE__ */ jsx89("i", {
5918
5992
  className: `icon ${headingSize} border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === headingSize ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5919
5993
  }),
5920
- /* @__PURE__ */ jsx88("span", {
5994
+ /* @__PURE__ */ jsx89("span", {
5921
5995
  className: `${blockType === headingSize ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5922
5996
  children: headingTypeToBlockName[headingSize]
5923
5997
  })
@@ -5926,10 +6000,10 @@ function BlockFormatDropDown({
5926
6000
  /* @__PURE__ */ jsxs66(DropdownMenu.Item, {
5927
6001
  onClick: formatBulletList,
5928
6002
  children: [
5929
- /* @__PURE__ */ jsx88("i", {
6003
+ /* @__PURE__ */ jsx89("i", {
5930
6004
  className: `icon bullet-list border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === "bullet" ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5931
6005
  }),
5932
- /* @__PURE__ */ jsx88("span", {
6006
+ /* @__PURE__ */ jsx89("span", {
5933
6007
  className: `${blockType === "bullet" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5934
6008
  children: "Bullet List"
5935
6009
  })
@@ -5938,10 +6012,10 @@ function BlockFormatDropDown({
5938
6012
  /* @__PURE__ */ jsxs66(DropdownMenu.Item, {
5939
6013
  onClick: formatNumberedList,
5940
6014
  children: [
5941
- /* @__PURE__ */ jsx88("i", {
6015
+ /* @__PURE__ */ jsx89("i", {
5942
6016
  className: `icon numbered-list border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === "number" ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5943
6017
  }),
5944
- /* @__PURE__ */ jsx88("span", {
6018
+ /* @__PURE__ */ jsx89("span", {
5945
6019
  className: `${blockType === "number" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5946
6020
  children: "Numbered List"
5947
6021
  })
@@ -5951,10 +6025,10 @@ function BlockFormatDropDown({
5951
6025
  onClick: formatQuote,
5952
6026
  "data-testid": "toggle-block-format-quote",
5953
6027
  children: [
5954
- /* @__PURE__ */ jsx88("i", {
6028
+ /* @__PURE__ */ jsx89("i", {
5955
6029
  className: `icon quote border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === "quote" ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5956
6030
  }),
5957
- /* @__PURE__ */ jsx88("span", {
6031
+ /* @__PURE__ */ jsx89("span", {
5958
6032
  className: `${blockType === "quote" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5959
6033
  children: "Quote"
5960
6034
  })
@@ -5964,10 +6038,10 @@ function BlockFormatDropDown({
5964
6038
  onClick: formatCode,
5965
6039
  "data-testid": "toggle-block-format-code",
5966
6040
  children: [
5967
- /* @__PURE__ */ jsx88("i", {
6041
+ /* @__PURE__ */ jsx89("i", {
5968
6042
  className: `icon code border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === "code" ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5969
6043
  }),
5970
- /* @__PURE__ */ jsx88("span", {
6044
+ /* @__PURE__ */ jsx89("span", {
5971
6045
  className: `${blockType === "code" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5972
6046
  children: "Code block"
5973
6047
  })
@@ -5980,16 +6054,16 @@ function BlockFormatDropDown({
5980
6054
  "aria-label": "Formatting options for text style",
5981
6055
  "data-testid": "toggle-block-format",
5982
6056
  children: [
5983
- /* @__PURE__ */ jsx88("i", {
6057
+ /* @__PURE__ */ jsx89("i", {
5984
6058
  className: `icon ${blockType} border bg-no-repeat bg-center bg-[length:18px_18px] w-6 h-6`
5985
6059
  }),
5986
- /* @__PURE__ */ jsx88(Icon.Arrow, {})
6060
+ /* @__PURE__ */ jsx89(Icon.Arrow, {})
5987
6061
  ]
5988
6062
  })
5989
6063
  });
5990
6064
  }
5991
6065
  function Divider() {
5992
- return /* @__PURE__ */ jsx88("div", {
6066
+ return /* @__PURE__ */ jsx89("div", {
5993
6067
  className: "divider"
5994
6068
  });
5995
6069
  }
@@ -6011,6 +6085,7 @@ function ToolbarPlugin({
6011
6085
  const [isCode, setIsCode] = useState9(false);
6012
6086
  const [canUndo, setCanUndo] = useState9(false);
6013
6087
  const [canRedo, setCanRedo] = useState9(false);
6088
+ const tr = useTr();
6014
6089
  const [codeLanguage, setCodeLanguage] = useState9("");
6015
6090
  const [isEditable, setIsEditable] = useState9(() => editor.isEditable());
6016
6091
  const updateToolbar = useCallback4(() => {
@@ -6143,138 +6218,138 @@ function ToolbarPlugin({
6143
6218
  /* @__PURE__ */ jsxs66("div", {
6144
6219
  className: "flex",
6145
6220
  children: [
6146
- /* @__PURE__ */ jsx88(IconButton, {
6221
+ /* @__PURE__ */ jsx89(IconButton, {
6147
6222
  disabled: !canUndo || !isEditable,
6148
6223
  onClick: () => {
6149
6224
  activeEditor.dispatchCommand(UNDO_COMMAND, void 0);
6150
6225
  },
6151
- title: IS_APPLE ? "Undo (\u2318Z)" : "Undo (Ctrl+Z)",
6152
6226
  type: "button",
6153
- "aria-label": "Undo",
6154
- children: /* @__PURE__ */ jsx88("i", {
6227
+ title: tr(IS_APPLE ? "actionUndoTitleApple" : "actionUndoTitle"),
6228
+ "aria-label": tr("actionUndoLabel"),
6229
+ children: /* @__PURE__ */ jsx89("i", {
6155
6230
  className: `format icon undo border w-4 h-6 bg-no-repeat bg-center bg-[length:17px_17px] ${canUndo ? "opacity-100" : "opacity-30"}
6156
6231
  `
6157
6232
  })
6158
6233
  }),
6159
- /* @__PURE__ */ jsx88(IconButton, {
6234
+ /* @__PURE__ */ jsx89(IconButton, {
6160
6235
  disabled: !canRedo || !isEditable,
6161
6236
  onClick: () => {
6162
6237
  activeEditor.dispatchCommand(REDO_COMMAND, void 0);
6163
6238
  },
6164
- title: IS_APPLE ? "Redo (\u2318Y)" : "Redo (Ctrl+Y)",
6165
6239
  type: "button",
6166
- "aria-label": "Redo",
6167
- children: /* @__PURE__ */ jsx88("i", {
6240
+ title: tr(IS_APPLE ? "actionRedoTitleApple" : "actionRedoTitle"),
6241
+ "aria-label": tr("actionRedoLabel"),
6242
+ children: /* @__PURE__ */ jsx89("i", {
6168
6243
  className: `format icon redo border w-4 h-6 bg-no-repeat bg-center bg-[length:17px_17px] ${canRedo ? "opacity-100" : "opacity-30"}`
6169
6244
  })
6170
6245
  }),
6171
- /* @__PURE__ */ jsx88(Divider, {}),
6246
+ /* @__PURE__ */ jsx89(Divider, {}),
6172
6247
  blockType in blockTypeToBlockName && activeEditor === editor && /* @__PURE__ */ jsxs66(Fragment8, {
6173
6248
  children: [
6174
- /* @__PURE__ */ jsx88(BlockFormatDropDown, {
6249
+ /* @__PURE__ */ jsx89(BlockFormatDropDown, {
6175
6250
  disabled: !isEditable,
6176
6251
  blockType,
6177
6252
  editor
6178
6253
  }),
6179
- /* @__PURE__ */ jsx88(Divider, {})
6254
+ /* @__PURE__ */ jsx89(Divider, {})
6180
6255
  ]
6181
6256
  }),
6182
- blockType === "code" ? /* @__PURE__ */ jsx88(Fragment8, {
6183
- children: /* @__PURE__ */ jsx88(DropdownMenu.Root, {
6257
+ blockType === "code" ? /* @__PURE__ */ jsx89(Fragment8, {
6258
+ children: /* @__PURE__ */ jsx89(DropdownMenu.Root, {
6184
6259
  disabled: !isEditable,
6185
6260
  style: { zIndex: 1 },
6186
- content: /* @__PURE__ */ jsx88(Fragment8, {
6261
+ content: /* @__PURE__ */ jsx89(Fragment8, {
6187
6262
  children: CODE_LANGUAGE_OPTIONS.map(([value, name]) => {
6188
- return /* @__PURE__ */ jsx88(DropdownMenu.Item, {
6263
+ return /* @__PURE__ */ jsx89(DropdownMenu.Item, {
6189
6264
  className: `item ${dropDownActiveClass(value === codeLanguage)}`,
6190
6265
  onClick: () => onCodeLanguageSelect(value),
6191
- children: /* @__PURE__ */ jsx88("span", {
6266
+ children: /* @__PURE__ */ jsx89("span", {
6192
6267
  className: `text min-w-[200px] block text-sm px-3 ${dropDownActiveClass(value === codeLanguage) ? "font-bold opacity-100" : "font-normal opacity-80"}`,
6193
6268
  children: name
6194
6269
  })
6195
6270
  }, value);
6196
6271
  })
6197
6272
  }),
6198
- children: /* @__PURE__ */ jsx88(Button, {
6199
- "aria-label": "Select language",
6200
- append: /* @__PURE__ */ jsx88(Icon.Arrow, {}),
6201
- children: /* @__PURE__ */ jsx88("span", {
6273
+ children: /* @__PURE__ */ jsx89(Button, {
6274
+ "aria-label": tr("codeSelectLanguage"),
6275
+ append: /* @__PURE__ */ jsx89(Icon.Arrow, {}),
6276
+ children: /* @__PURE__ */ jsx89("span", {
6202
6277
  className: "font-medium text-sm",
6203
6278
  children: getLanguageFriendlyName2(codeLanguage)
6204
6279
  })
6205
6280
  })
6206
6281
  })
6207
- }) : /* @__PURE__ */ jsx88(Dialog, {
6282
+ }) : /* @__PURE__ */ jsx89(Dialog, {
6208
6283
  children: /* @__PURE__ */ jsxs66("div", {
6209
6284
  className: "flex gap-1",
6210
6285
  children: [
6211
- /* @__PURE__ */ jsx88(IconButton, {
6286
+ /* @__PURE__ */ jsx89(IconButton, {
6212
6287
  disabled: !isEditable,
6213
- title: IS_APPLE ? "Bold (\u2318B)" : "Bold (Ctrl+B)",
6214
6288
  className: `${isBold ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6215
6289
  type: "button",
6216
- "aria-label": `Format text as bold. Shortcut: ${IS_APPLE ? "\u2318B" : "Ctrl+B"}`,
6290
+ title: tr(IS_APPLE ? "actionFormatAsStrongTitleApple" : "actionFormatAsStrongTitle"),
6291
+ "aria-label": tr("actionFormatAsStrongLabel"),
6217
6292
  "data-testid": "toggle-format-bold",
6218
6293
  onClick: () => {
6219
6294
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "bold");
6220
6295
  },
6221
- children: /* @__PURE__ */ jsx88("i", {
6296
+ children: /* @__PURE__ */ jsx89("i", {
6222
6297
  className: `format icon bold border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6223
6298
  })
6224
6299
  }),
6225
- /* @__PURE__ */ jsx88(IconButton, {
6300
+ /* @__PURE__ */ jsx89(IconButton, {
6226
6301
  className: `${isItalic ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6227
6302
  disabled: !isEditable,
6228
6303
  onClick: () => {
6229
6304
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "italic");
6230
6305
  },
6231
- title: IS_APPLE ? "Italic (\u2318I)" : "Italic (Ctrl+I)",
6232
6306
  type: "button",
6233
- "aria-label": `Format text as italics. Shortcut: ${IS_APPLE ? "\u2318I" : "Ctrl+I"}`,
6307
+ title: tr(IS_APPLE ? "actionFormatAsEmphasizedTitleApple" : "actionFormatAsEmphasizedTitle"),
6308
+ "aria-label": tr("actionFormatAsEmphasizedLabel"),
6234
6309
  "data-testid": "toggle-format-emphasized",
6235
- children: /* @__PURE__ */ jsx88("i", {
6310
+ children: /* @__PURE__ */ jsx89("i", {
6236
6311
  className: `format icon italic border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6237
6312
  })
6238
6313
  }),
6239
- /* @__PURE__ */ jsx88(IconButton, {
6314
+ /* @__PURE__ */ jsx89(IconButton, {
6240
6315
  className: `${isUnderline ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6241
6316
  disabled: !isEditable,
6242
6317
  onClick: () => {
6243
6318
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "underline");
6244
6319
  },
6245
- title: IS_APPLE ? "Underline (\u2318U)" : "Underline (Ctrl+U)",
6246
6320
  type: "button",
6247
- "aria-label": `Format text to underlined. Shortcut: ${IS_APPLE ? "\u2318U" : "Ctrl+U"}`,
6321
+ title: tr(IS_APPLE ? "actionFormatAsUnderlinedTitleApple" : "actionFormatAsUnderlinedTitle"),
6322
+ "aria-label": tr("actionFormatAsUnderlinedLabel"),
6248
6323
  "data-testid": "toggle-format-underlined",
6249
- children: /* @__PURE__ */ jsx88("i", {
6324
+ children: /* @__PURE__ */ jsx89("i", {
6250
6325
  className: `format icon underline border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6251
6326
  })
6252
6327
  }),
6253
- /* @__PURE__ */ jsx88(IconButton, {
6328
+ /* @__PURE__ */ jsx89(IconButton, {
6254
6329
  className: `${isCode ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6255
6330
  disabled: !isEditable,
6256
6331
  onClick: () => {
6257
6332
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "code");
6258
6333
  },
6259
- title: "Insert code block",
6260
6334
  type: "button",
6261
- "aria-label": "Insert code block",
6262
- children: /* @__PURE__ */ jsx88("i", {
6335
+ title: tr("actionInsertCodeBlock"),
6336
+ "aria-label": tr("actionInsertCodeBlock"),
6337
+ children: /* @__PURE__ */ jsx89("i", {
6263
6338
  className: `format icon code border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6264
6339
  })
6265
6340
  }),
6266
- /* @__PURE__ */ jsx88(IconButton, {
6341
+ /* @__PURE__ */ jsx89(IconButton, {
6267
6342
  className: `${isLink ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6268
6343
  disabled: !isEditable,
6269
6344
  onClick: insertLink,
6270
- "aria-label": "Insert link",
6271
- title: "Insert link",
6272
6345
  type: "button",
6273
- children: /* @__PURE__ */ jsx88("i", {
6346
+ "aria-label": tr("actionInsertlink"),
6347
+ title: tr("actionInsertlink"),
6348
+ children: /* @__PURE__ */ jsx89("i", {
6274
6349
  className: `format icon link border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6275
6350
  })
6276
6351
  }),
6277
- /* @__PURE__ */ jsx88(DropdownMenu.Root, {
6352
+ /* @__PURE__ */ jsx89(DropdownMenu.Root, {
6278
6353
  disabled: !isEditable,
6279
6354
  style: { zIndex: 1 },
6280
6355
  content: /* @__PURE__ */ jsxs66(Fragment8, {
@@ -6283,15 +6358,15 @@ function ToolbarPlugin({
6283
6358
  onClick: () => {
6284
6359
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "strikethrough");
6285
6360
  },
6286
- title: "Strikethrough",
6287
- "aria-label": "Format text with a strikethrough",
6361
+ title: tr("actionFormatWithStrikethroughTitle"),
6362
+ "aria-label": tr("actionFormatWithStrikethroughLabel"),
6288
6363
  children: [
6289
- /* @__PURE__ */ jsx88("i", {
6364
+ /* @__PURE__ */ jsx89("i", {
6290
6365
  className: `icon w-6 h-6 strikethrough border bg-no-repeat bg-center bg-[length:16px_16px] rounded-sm ${isStrikethrough ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`
6291
6366
  }),
6292
- /* @__PURE__ */ jsx88("span", {
6367
+ /* @__PURE__ */ jsx89("span", {
6293
6368
  className: `px-3 text-sm font-sans ${isStrikethrough ? "font-medium" : "font-normal"}`,
6294
- children: "Strikethrough"
6369
+ children: tr("actionFormatAsStrongTitle")
6295
6370
  })
6296
6371
  ]
6297
6372
  }),
@@ -6299,15 +6374,15 @@ function ToolbarPlugin({
6299
6374
  onClick: () => {
6300
6375
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "subscript");
6301
6376
  },
6302
- title: "Subscript",
6303
- "aria-label": "Format text with a subscript",
6377
+ title: tr("actionFormatWithSubscriptTitle"),
6378
+ "aria-label": tr("actionFormatWithSubscriptLabel"),
6304
6379
  children: [
6305
- /* @__PURE__ */ jsx88("i", {
6380
+ /* @__PURE__ */ jsx89("i", {
6306
6381
  className: `icon w-6 h-6 subscript border bg-no-repeat bg-center bg-[length:16px_16px] rounded-sm ${isSubscript ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`
6307
6382
  }),
6308
- /* @__PURE__ */ jsx88("span", {
6383
+ /* @__PURE__ */ jsx89("span", {
6309
6384
  className: `px-3 text-sm font-sans ${isSubscript ? "font-medium" : "font-normal"}`,
6310
- children: "Subscript"
6385
+ children: tr("actionFormatWithSubscriptTitle")
6311
6386
  })
6312
6387
  ]
6313
6388
  }),
@@ -6315,28 +6390,28 @@ function ToolbarPlugin({
6315
6390
  onClick: () => {
6316
6391
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "superscript");
6317
6392
  },
6318
- title: "Superscript",
6319
- "aria-label": "Format text with a superscript",
6393
+ title: tr("actionFormatWithSuperscriptTitle"),
6394
+ "aria-label": tr("actionFormatWithSuperscriptLabel"),
6320
6395
  children: [
6321
- /* @__PURE__ */ jsx88("i", {
6396
+ /* @__PURE__ */ jsx89("i", {
6322
6397
  className: `icon w-6 h-6 superscript border bg-no-repeat bg-center bg-[length:16px_16px] rounded-sm ${isSuperscript ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`
6323
6398
  }),
6324
- /* @__PURE__ */ jsx88("span", {
6399
+ /* @__PURE__ */ jsx89("span", {
6325
6400
  className: `px-3 text-sm font-sans ${isSuperscript ? "bg-purple-50-900" : "font-normal"}`,
6326
- children: "Superscript"
6401
+ children: tr("actionFormatWithSuperscriptTitle")
6327
6402
  })
6328
6403
  ]
6329
6404
  }),
6330
6405
  /* @__PURE__ */ jsxs66(DropdownMenu.Item, {
6331
6406
  onClick: clearFormatting,
6332
6407
  className: "item",
6333
- title: "Clear text formatting",
6334
- "aria-label": "Clear all text formatting",
6408
+ title: tr("actionClearTextFormatting"),
6409
+ "aria-label": tr("actionClearTextFormatting"),
6335
6410
  children: [
6336
- /* @__PURE__ */ jsx88("i", {
6411
+ /* @__PURE__ */ jsx89("i", {
6337
6412
  className: "icon w-6 h-6 clear border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6338
6413
  }),
6339
- /* @__PURE__ */ jsx88("span", {
6414
+ /* @__PURE__ */ jsx89("span", {
6340
6415
  className: "px-3 text-sm text-pink-600-300 font-sans font-normal",
6341
6416
  children: "Clear Formatting"
6342
6417
  })
@@ -6346,50 +6421,50 @@ function ToolbarPlugin({
6346
6421
  }),
6347
6422
  children: /* @__PURE__ */ jsxs66(Button, {
6348
6423
  style: { backgroundColor: "transparent", padding: "0 8px" },
6349
- "aria-label": "Formatting options for additional text styles",
6424
+ "aria-label": tr("actionTextFormattingOptions"),
6350
6425
  children: [
6351
- /* @__PURE__ */ jsx88("i", {
6426
+ /* @__PURE__ */ jsx89("i", {
6352
6427
  className: `icon dropdown-more border bg-no-repeat bg-center bg-[length:18px_18px] w-6 h-6`
6353
6428
  }),
6354
- /* @__PURE__ */ jsx88(Icon.Arrow, {})
6429
+ /* @__PURE__ */ jsx89(Icon.Arrow, {})
6355
6430
  ]
6356
6431
  })
6357
6432
  }),
6358
- /* @__PURE__ */ jsx88(Divider, {}),
6359
- /* @__PURE__ */ jsx88(DropdownMenu.Root, {
6433
+ /* @__PURE__ */ jsx89(Divider, {}),
6434
+ /* @__PURE__ */ jsx89(DropdownMenu.Root, {
6360
6435
  style: { zIndex: 1 },
6361
6436
  disabled: !isEditable,
6362
6437
  content: /* @__PURE__ */ jsxs66(Fragment8, {
6363
6438
  children: [
6364
- /* @__PURE__ */ jsx88(DropdownMenu.Item, {
6439
+ /* @__PURE__ */ jsx89(DropdownMenu.Item, {
6365
6440
  onClick: () => {
6366
6441
  activeEditor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, void 0);
6367
6442
  },
6368
6443
  children: /* @__PURE__ */ jsxs66("div", {
6369
6444
  className: "flex items-center font-sans font-normal",
6370
6445
  children: [
6371
- /* @__PURE__ */ jsx88("i", {
6446
+ /* @__PURE__ */ jsx89("i", {
6372
6447
  className: "icon w-5 h-5 horizontal-rule border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6373
6448
  }),
6374
- /* @__PURE__ */ jsx88("span", {
6449
+ /* @__PURE__ */ jsx89("span", {
6375
6450
  className: "px-3 text-sm",
6376
- children: "Horizontal rule"
6451
+ children: tr("horizontalRule")
6377
6452
  })
6378
6453
  ]
6379
6454
  })
6380
6455
  }),
6381
- /* @__PURE__ */ jsx88(DropdownMenu.Item, {
6382
- children: /* @__PURE__ */ jsx88(Dialog.Trigger, {
6456
+ /* @__PURE__ */ jsx89(DropdownMenu.Item, {
6457
+ children: /* @__PURE__ */ jsx89(Dialog.Trigger, {
6383
6458
  asChild: true,
6384
6459
  children: /* @__PURE__ */ jsxs66("div", {
6385
6460
  className: "flex items-center font-sans font-normal",
6386
6461
  children: [
6387
- /* @__PURE__ */ jsx88("i", {
6462
+ /* @__PURE__ */ jsx89("i", {
6388
6463
  className: "icon w-5 h-5 table border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6389
6464
  }),
6390
- /* @__PURE__ */ jsx88("span", {
6465
+ /* @__PURE__ */ jsx89("span", {
6391
6466
  className: "px-3 text-sm",
6392
- children: "Table"
6467
+ children: tr("table")
6393
6468
  })
6394
6469
  ]
6395
6470
  })
@@ -6397,23 +6472,23 @@ function ToolbarPlugin({
6397
6472
  })
6398
6473
  ]
6399
6474
  }),
6400
- children: /* @__PURE__ */ jsx88(IconButton, {
6401
- children: /* @__PURE__ */ jsx88("i", {
6475
+ children: /* @__PURE__ */ jsx89(IconButton, {
6476
+ children: /* @__PURE__ */ jsx89("i", {
6402
6477
  className: "icon plus border w-full h-full bg-no-repeat bg-center bg-[length:20px_20px] "
6403
6478
  })
6404
6479
  })
6405
6480
  }),
6406
6481
  /* @__PURE__ */ jsxs66(Dialog.Content, {
6407
6482
  children: [
6408
- /* @__PURE__ */ jsx88(Dialog.Title, {
6409
- children: "Insert table"
6483
+ /* @__PURE__ */ jsx89(Dialog.Title, {
6484
+ children: tr("insertTableTitle")
6410
6485
  }),
6411
- /* @__PURE__ */ jsx88(Dialog.Description, {
6412
- children: "Define your starting point of a table, you can add and remove columns and rows after creation."
6486
+ /* @__PURE__ */ jsx89(Dialog.Description, {
6487
+ children: tr("insertTableDescription")
6413
6488
  }),
6414
- /* @__PURE__ */ jsx88("div", {
6489
+ /* @__PURE__ */ jsx89("div", {
6415
6490
  className: "items-center justify-between",
6416
- children: /* @__PURE__ */ jsx88(InsertTableDialog, {
6491
+ children: /* @__PURE__ */ jsx89(InsertTableDialog, {
6417
6492
  activeEditor
6418
6493
  })
6419
6494
  })
@@ -6424,7 +6499,7 @@ function ToolbarPlugin({
6424
6499
  })
6425
6500
  ]
6426
6501
  }),
6427
- /* @__PURE__ */ jsx88(ActionsPlugin, {
6502
+ /* @__PURE__ */ jsx89(ActionsPlugin, {
6428
6503
  prepend: actionsMenuPrepend,
6429
6504
  append: actionsMenuAppend
6430
6505
  })
@@ -6534,21 +6609,13 @@ var theme = {
6534
6609
  };
6535
6610
  var CrystallizeRTEditorTheme_default = theme;
6536
6611
 
6537
- // src/rich-text-editor/ui/ContentEditable.tsx
6538
- import "react";
6539
- import { ContentEditable } from "@lexical/react/LexicalContentEditable";
6540
- import { jsx as jsx89 } from "react/jsx-runtime";
6541
- function LexicalContentEditable({ className }) {
6542
- return /* @__PURE__ */ jsx89(ContentEditable, {
6543
- className: className || "ContentEditable__root"
6544
- });
6545
- }
6546
-
6547
6612
  // src/rich-text-editor/rich-text-editor.tsx
6548
6613
  import { Fragment as Fragment9, jsx as jsx90, jsxs as jsxs67 } from "react/jsx-runtime";
6549
6614
  function RichTextEditor({
6550
6615
  initialData,
6551
6616
  editable = true,
6617
+ language = "en",
6618
+ labelTranslations,
6552
6619
  ...rest
6553
6620
  }) {
6554
6621
  return /* @__PURE__ */ jsx90(LexicalComposer, {
@@ -6564,12 +6631,16 @@ function RichTextEditor({
6564
6631
  richText: initialData
6565
6632
  }) : void 0
6566
6633
  },
6567
- children: /* @__PURE__ */ jsx90(SharedHistoryContext, {
6568
- children: /* @__PURE__ */ jsx90("div", {
6569
- className: "c-rich-text-editor",
6570
- children: /* @__PURE__ */ jsx90(RichTextEditorWithoutContext, {
6571
- ...rest,
6572
- editable
6634
+ children: /* @__PURE__ */ jsx90(I18nProvider, {
6635
+ language,
6636
+ labelTranslations,
6637
+ children: /* @__PURE__ */ jsx90(SharedHistoryContext, {
6638
+ children: /* @__PURE__ */ jsx90("div", {
6639
+ className: "c-rich-text-editor",
6640
+ children: /* @__PURE__ */ jsx90(RichTextEditorWithoutContext, {
6641
+ ...rest,
6642
+ editable
6643
+ })
6573
6644
  })
6574
6645
  })
6575
6646
  })
@@ -6652,7 +6723,9 @@ function RichTextEditorWithoutContext({
6652
6723
  children: /* @__PURE__ */ jsx90("div", {
6653
6724
  className: "editor",
6654
6725
  ref: onRef,
6655
- children: /* @__PURE__ */ jsx90(LexicalContentEditable, {})
6726
+ children: /* @__PURE__ */ jsx90(ContentEditable, {
6727
+ className: "ContentEditable__root"
6728
+ })
6656
6729
  })
6657
6730
  }),
6658
6731
  placeholder,