@crystallize/design-system 1.9.0 → 1.11.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 (30) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/index.css +15 -17
  3. package/dist/index.d.ts +10 -3
  4. package/dist/index.js +528 -470
  5. package/dist/index.mjs +477 -423
  6. package/package.json +1 -1
  7. package/src/rich-text-editor/i18n/i18n.test.ts +14 -0
  8. package/src/rich-text-editor/i18n/index.tsx +64 -0
  9. package/src/rich-text-editor/i18n/translations/en.ts +66 -0
  10. package/src/rich-text-editor/i18n/types.ts +62 -0
  11. package/src/rich-text-editor/model/crystallize-to-lexical.ts +29 -1
  12. package/src/rich-text-editor/model/lexical-to-crystallize.ts +54 -29
  13. package/src/rich-text-editor/plugins/ActionsPlugin/index.tsx +5 -22
  14. package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/CopyButton/index.tsx +4 -1
  15. package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/PrettierButton/index.tsx +11 -1
  16. package/src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx +2 -1
  17. package/src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx +23 -5
  18. package/src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx +21 -10
  19. package/src/rich-text-editor/plugins/TabFocusPlugin/index.tsx +4 -12
  20. package/src/rich-text-editor/plugins/TableActionMenuPlugin/index.tsx +23 -14
  21. package/src/rich-text-editor/plugins/ToolbarPlugin/index.tsx +33 -33
  22. package/src/rich-text-editor/plugins/ToolbarPlugin/insert-table.tsx +6 -4
  23. package/src/rich-text-editor/rich-text-editor.css +6 -0
  24. package/src/rich-text-editor/rich-text-editor.stories.tsx +38 -0
  25. package/src/rich-text-editor/rich-text-editor.tsx +15 -9
  26. package/src/rich-text-editor/tests/rich-text-editor-model-conversions.test.tsx +23 -1
  27. package/src/rich-text-editor/types/crystallize-rich-text-types/index.ts +2 -4
  28. package/src/rich-text-editor/ui/LinkPreview.tsx +3 -1
  29. package/src/rich-text-editor/ui/ContentEditable.css +0 -13
  30. package/src/rich-text-editor/ui/ContentEditable.tsx +0 -15
package/dist/index.js CHANGED
@@ -3601,7 +3601,7 @@ function Tag({ children, className, variant, ...delegated }) {
3601
3601
  }
3602
3602
 
3603
3603
  // src/rich-text-editor/rich-text-editor.tsx
3604
- var import_react76 = require("react");
3604
+ var import_react77 = require("react");
3605
3605
  var import_LexicalAutoFocusPlugin = require("@lexical/react/LexicalAutoFocusPlugin");
3606
3606
  var import_LexicalClearEditorPlugin = require("@lexical/react/LexicalClearEditorPlugin");
3607
3607
  var import_LexicalComposer = require("@lexical/react/LexicalComposer");
@@ -3614,6 +3614,7 @@ var import_LexicalRichTextPlugin = require("@lexical/react/LexicalRichTextPlugin
3614
3614
  var import_LexicalTabIndentationPlugin = require("@lexical/react/LexicalTabIndentationPlugin");
3615
3615
  var import_LexicalTablePlugin = require("@lexical/react/LexicalTablePlugin");
3616
3616
  var import_LexicalComposerContext12 = require("@lexical/react/LexicalComposerContext");
3617
+ var import_LexicalContentEditable = require("@lexical/react/LexicalContentEditable");
3617
3618
 
3618
3619
  // src/rich-text-editor/context/SharedHistoryContext.tsx
3619
3620
  var import_react62 = require("react");
@@ -3631,6 +3632,54 @@ var useSharedHistoryContext = () => {
3631
3632
  return (0, import_react62.useContext)(Context);
3632
3633
  };
3633
3634
 
3635
+ // src/rich-text-editor/i18n/index.tsx
3636
+ var import_react63 = require("react");
3637
+ var import_jsx_runtime77 = require("react/jsx-runtime");
3638
+ var I18nContext = (0, import_react63.createContext)(null);
3639
+ function I18nProvider({
3640
+ language,
3641
+ labelTranslations,
3642
+ children
3643
+ }) {
3644
+ const [translations, setTranslations] = (0, import_react63.useState)(labelTranslations || null);
3645
+ (0, import_react63.useEffect)(() => {
3646
+ let unmounted = false;
3647
+ (async function load() {
3648
+ if (!labelTranslations) {
3649
+ const resource = await import(`./translations/${language}.ts`);
3650
+ if (!unmounted) {
3651
+ setTranslations(resource.default);
3652
+ }
3653
+ }
3654
+ })();
3655
+ return () => {
3656
+ unmounted = true;
3657
+ };
3658
+ }, [language, labelTranslations]);
3659
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(I18nContext.Provider, {
3660
+ value: translations,
3661
+ children
3662
+ });
3663
+ }
3664
+ function replaceI18nVariablesInString(str, replaceWith) {
3665
+ return str.replace(/({{[^}]+}})/g, replaceWith);
3666
+ }
3667
+ function useTr() {
3668
+ const context = (0, import_react63.useContext)(I18nContext);
3669
+ return (key, units) => {
3670
+ const thereAreUnits = typeof units === "number";
3671
+ const keyToUse = thereAreUnits && units > 1 ? `${key}_plural` : key;
3672
+ if (context && keyToUse in context) {
3673
+ const tr = context[keyToUse];
3674
+ if (thereAreUnits) {
3675
+ return replaceI18nVariablesInString(tr, units.toString());
3676
+ }
3677
+ return tr;
3678
+ }
3679
+ return "";
3680
+ };
3681
+ }
3682
+
3634
3683
  // src/rich-text-editor/model/crystallize-to-lexical.ts
3635
3684
  var import_lexical = require("lexical");
3636
3685
  var import_code = require("@lexical/code");
@@ -3761,7 +3810,25 @@ function composeInitialState({ richText }) {
3761
3810
  }
3762
3811
  if (lexicalNode) {
3763
3812
  if (Array.isArray(children)) {
3764
- children.forEach((n) => handleNode({ crystallizeContentNode: n, lexicalParent: lexicalNode }));
3813
+ if ((0, import_lexical.$isTextNode)(lexicalNode)) {
3814
+ const handleInlineTextChild = (child) => {
3815
+ if ((0, import_lexical.$isTextNode)(lexicalNode)) {
3816
+ const textFormat = getLexicalTextFormat(child);
3817
+ if (textFormat && !lexicalNode.hasFormat(textFormat)) {
3818
+ lexicalNode.toggleFormat(textFormat);
3819
+ }
3820
+ if (child.textContent) {
3821
+ lexicalNode.setTextContent(child.textContent);
3822
+ }
3823
+ }
3824
+ if ("children" in child) {
3825
+ child.children?.forEach(handleInlineTextChild);
3826
+ }
3827
+ };
3828
+ children.forEach(handleInlineTextChild);
3829
+ } else {
3830
+ children.forEach((n) => handleNode({ crystallizeContentNode: n, lexicalParent: lexicalNode }));
3831
+ }
3765
3832
  }
3766
3833
  lexicalParent.append(lexicalNode);
3767
3834
  }
@@ -3928,10 +3995,8 @@ function lexicalToCrystallizeRichText({
3928
3995
  kind: "block",
3929
3996
  type: "horizontal-line"
3930
3997
  });
3931
- } else {
3932
- if ((0, import_lexical2.$isTextNode)(childNode)) {
3933
- parentChildrenToUse.push(getTextChild(childNode));
3934
- }
3998
+ } else if ((0, import_lexical2.$isTextNode)(childNode)) {
3999
+ parentChildrenToUse.push(getTextChild(childNode));
3935
4000
  }
3936
4001
  });
3937
4002
  }
@@ -3941,32 +4006,47 @@ function lexicalToCrystallizeRichText({
3941
4006
  });
3942
4007
  return crystallizeRichText;
3943
4008
  }
4009
+ var lexicalFormatToCrystallizeType = {
4010
+ bold: "strong",
4011
+ italic: "emphasized",
4012
+ underline: "underlined",
4013
+ strikethrough: "deleted",
4014
+ subscript: "subscripted",
4015
+ superscript: "superscripted",
4016
+ highlight: "emphasized",
4017
+ code: "code"
4018
+ };
3944
4019
  function getTextChild(n) {
3945
- const textContent = n.getTextContent();
3946
- if (n.hasFormat("code")) {
3947
- return {
3948
- type: "code",
3949
- kind: "inline",
3950
- textContent
3951
- };
3952
- }
3953
- const textChild = {
3954
- kind: "inline",
3955
- textContent
4020
+ let currentChild = {
4021
+ kind: "inline"
3956
4022
  };
3957
- if (n.hasFormat("bold")) {
3958
- textChild.type = "strong";
3959
- } else if (n.hasFormat("italic")) {
3960
- textChild.type = "emphasized";
3961
- } else if (n.hasFormat("underline")) {
3962
- textChild.type = "underlined";
3963
- } else if (n.hasFormat("strikethrough")) {
3964
- textChild.type = "deleted";
3965
- } else if (n.hasFormat("subscript")) {
3966
- textChild.type = "subscripted";
3967
- } else if (n.hasFormat("superscript")) {
3968
- textChild.type = "superscripted";
4023
+ let textChild = null;
4024
+ function checkFormat(format) {
4025
+ const type = lexicalFormatToCrystallizeType[format];
4026
+ if (n.hasFormat(format) && type) {
4027
+ if (!textChild) {
4028
+ currentChild = textChild = {
4029
+ kind: "inline",
4030
+ type
4031
+ };
4032
+ } else {
4033
+ currentChild.children = [
4034
+ {
4035
+ kind: "inline",
4036
+ type
4037
+ }
4038
+ ];
4039
+ currentChild = currentChild.children[0];
4040
+ }
4041
+ }
3969
4042
  }
4043
+ Object.keys(lexicalFormatToCrystallizeType).forEach(checkFormat);
4044
+ if (!textChild) {
4045
+ currentChild = textChild = {
4046
+ kind: "inline"
4047
+ };
4048
+ }
4049
+ currentChild.textContent = n.getTextContent();
3970
4050
  return textChild;
3971
4051
  }
3972
4052
 
@@ -4001,7 +4081,7 @@ var BaseNodes = [
4001
4081
  // src/rich-text-editor/plugins/AutoLinkPlugin/index.tsx
4002
4082
  var import_LexicalAutoLinkPlugin = require("@lexical/react/LexicalAutoLinkPlugin");
4003
4083
  var React = require("react");
4004
- var import_jsx_runtime77 = require("react/jsx-runtime");
4084
+ var import_jsx_runtime78 = require("react/jsx-runtime");
4005
4085
  var URL_MATCHER = /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
4006
4086
  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,}))/;
4007
4087
  var MATCHERS = [
@@ -4029,13 +4109,13 @@ var MATCHERS = [
4029
4109
  }
4030
4110
  ];
4031
4111
  function LexicalAutoLinkPlugin() {
4032
- return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(import_LexicalAutoLinkPlugin.AutoLinkPlugin, {
4112
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_LexicalAutoLinkPlugin.AutoLinkPlugin, {
4033
4113
  matchers: MATCHERS
4034
4114
  });
4035
4115
  }
4036
4116
 
4037
4117
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx
4038
- var import_react65 = require("react");
4118
+ var import_react66 = require("react");
4039
4119
  var import_lexical6 = require("lexical");
4040
4120
  var import_react_dom2 = require("react-dom");
4041
4121
  var import_use_debounce2 = require("use-debounce");
@@ -4044,13 +4124,14 @@ var import_LexicalComposerContext = require("@lexical/react/LexicalComposerConte
4044
4124
 
4045
4125
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/components/CopyButton/index.tsx
4046
4126
  var React2 = require("react");
4047
- var import_react63 = require("react");
4127
+ var import_react64 = require("react");
4048
4128
  var import_lexical4 = require("lexical");
4049
4129
  var import_use_debounce = require("use-debounce");
4050
4130
  var import_code4 = require("@lexical/code");
4051
- var import_jsx_runtime78 = require("react/jsx-runtime");
4131
+ var import_jsx_runtime79 = require("react/jsx-runtime");
4052
4132
  function CopyButton({ editor, getCodeDOMNode }) {
4053
- const [isCopyCompleted, setCopyCompleted] = (0, import_react63.useState)(false);
4133
+ const [isCopyCompleted, setCopyCompleted] = (0, import_react64.useState)(false);
4134
+ const tr = useTr();
4054
4135
  const removeSuccessIcon = (0, import_use_debounce.useDebouncedCallback)(() => {
4055
4136
  setCopyCompleted(false);
4056
4137
  }, 1e3);
@@ -4076,13 +4157,13 @@ function CopyButton({ editor, getCodeDOMNode }) {
4076
4157
  console.error("Failed to copy: ", err);
4077
4158
  }
4078
4159
  }
4079
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("button", {
4160
+ return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("button", {
4080
4161
  className: "menu-item",
4081
4162
  onClick: handleClick,
4082
- "aria-label": "copy",
4083
- children: isCopyCompleted ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("i", {
4163
+ "aria-label": tr("actionCopyCode"),
4164
+ children: isCopyCompleted ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("i", {
4084
4165
  className: "format success"
4085
- }) : /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("i", {
4166
+ }) : /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("i", {
4086
4167
  className: "format copy"
4087
4168
  })
4088
4169
  });
@@ -4090,10 +4171,10 @@ function CopyButton({ editor, getCodeDOMNode }) {
4090
4171
 
4091
4172
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/components/PrettierButton/index.tsx
4092
4173
  var React3 = require("react");
4093
- var import_react64 = require("react");
4174
+ var import_react65 = require("react");
4094
4175
  var import_lexical5 = require("lexical");
4095
4176
  var import_code5 = require("@lexical/code");
4096
- var import_jsx_runtime79 = require("react/jsx-runtime");
4177
+ var import_jsx_runtime80 = require("react/jsx-runtime");
4097
4178
  var PRETTIER_PARSER_MODULES = {
4098
4179
  css: () => import("prettier/parser-postcss"),
4099
4180
  html: () => import("prettier/parser-html"),
@@ -4133,8 +4214,9 @@ function getPrettierOptions(lang) {
4133
4214
  return options;
4134
4215
  }
4135
4216
  function PrettierButton({ lang, editor, getCodeDOMNode }) {
4136
- const [syntaxError, setSyntaxError] = (0, import_react64.useState)("");
4137
- const [tipsVisible, setTipsVisible] = (0, import_react64.useState)(false);
4217
+ const [syntaxError, setSyntaxError] = (0, import_react65.useState)("");
4218
+ const [tipsVisible, setTipsVisible] = (0, import_react65.useState)(false);
4219
+ const tr = useTr();
4138
4220
  async function handleClick() {
4139
4221
  const codeDOMNode = getCodeDOMNode();
4140
4222
  try {
@@ -4150,6 +4232,7 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4150
4232
  const content = codeNode.getTextContent();
4151
4233
  let parsed = "";
4152
4234
  parsed = format(content, options);
4235
+ parsed = parsed.replace(/[\r\n]+$/, "");
4153
4236
  if (parsed !== "") {
4154
4237
  const selection = codeNode.select(0);
4155
4238
  selection.insertText(parsed);
@@ -4177,22 +4260,22 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4177
4260
  setTipsVisible(false);
4178
4261
  }
4179
4262
  }
4180
- return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", {
4263
+ return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", {
4181
4264
  className: "prettier-wrapper",
4182
4265
  children: [
4183
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("button", {
4266
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("button", {
4184
4267
  className: "menu-item",
4185
4268
  onClick: handleClick,
4186
4269
  onMouseEnter: handleMouseEnter,
4187
4270
  onMouseLeave: handleMouseLeave,
4188
- "aria-label": "prettier",
4189
- children: syntaxError ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("i", {
4271
+ "aria-label": tr("actionFormatCode"),
4272
+ children: syntaxError ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("i", {
4190
4273
  className: "format prettier-error"
4191
- }) : /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("i", {
4274
+ }) : /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("i", {
4192
4275
  className: "format prettier"
4193
4276
  })
4194
4277
  }),
4195
- tipsVisible ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("pre", {
4278
+ tipsVisible ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("pre", {
4196
4279
  className: "code-error-tips",
4197
4280
  children: syntaxError
4198
4281
  }) : null
@@ -4201,19 +4284,19 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4201
4284
  }
4202
4285
 
4203
4286
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx
4204
- var import_jsx_runtime80 = require("react/jsx-runtime");
4287
+ var import_jsx_runtime81 = require("react/jsx-runtime");
4205
4288
  var CODE_PADDING = 8;
4206
4289
  function CodeActionMenuContainer({ anchorElem }) {
4207
4290
  const [editor] = (0, import_LexicalComposerContext.useLexicalComposerContext)();
4208
- const [lang, setLang] = (0, import_react65.useState)("");
4209
- const [isShown, setShown] = (0, import_react65.useState)(false);
4210
- const [shouldListenMouseMove, setShouldListenMouseMove] = (0, import_react65.useState)(false);
4211
- const [position, setPosition] = (0, import_react65.useState)({
4291
+ const [lang, setLang] = (0, import_react66.useState)("");
4292
+ const [isShown, setShown] = (0, import_react66.useState)(false);
4293
+ const [shouldListenMouseMove, setShouldListenMouseMove] = (0, import_react66.useState)(true);
4294
+ const [position, setPosition] = (0, import_react66.useState)({
4212
4295
  right: "0",
4213
4296
  top: "0"
4214
4297
  });
4215
- const codeSetRef = (0, import_react65.useRef)(/* @__PURE__ */ new Set());
4216
- const codeDOMNodeRef = (0, import_react65.useRef)(null);
4298
+ const codeSetRef = (0, import_react66.useRef)(/* @__PURE__ */ new Set());
4299
+ const codeDOMNodeRef = (0, import_react66.useRef)(null);
4217
4300
  function getCodeDOMNode() {
4218
4301
  return codeDOMNodeRef.current;
4219
4302
  }
@@ -4247,7 +4330,7 @@ function CodeActionMenuContainer({ anchorElem }) {
4247
4330
  });
4248
4331
  }
4249
4332
  }, 50);
4250
- (0, import_react65.useEffect)(() => {
4333
+ (0, import_react66.useEffect)(() => {
4251
4334
  if (!shouldListenMouseMove) {
4252
4335
  return;
4253
4336
  }
@@ -4278,20 +4361,20 @@ function CodeActionMenuContainer({ anchorElem }) {
4278
4361
  });
4279
4362
  const normalizedLang = (0, import_code6.normalizeCodeLang)(lang);
4280
4363
  const codeFriendlyName = (0, import_code6.getLanguageFriendlyName)(lang);
4281
- return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_jsx_runtime80.Fragment, {
4282
- children: isShown ? /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", {
4364
+ return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_jsx_runtime81.Fragment, {
4365
+ children: isShown ? /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", {
4283
4366
  className: "code-action-menu-container",
4284
4367
  style: { ...position },
4285
4368
  children: [
4286
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", {
4369
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", {
4287
4370
  className: "code-highlight-language",
4288
4371
  children: codeFriendlyName
4289
4372
  }),
4290
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(CopyButton, {
4373
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(CopyButton, {
4291
4374
  editor,
4292
4375
  getCodeDOMNode
4293
4376
  }),
4294
- canBePrettier(normalizedLang) ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(PrettierButton, {
4377
+ canBePrettier(normalizedLang) ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(PrettierButton, {
4295
4378
  editor,
4296
4379
  getCodeDOMNode,
4297
4380
  lang: normalizedLang
@@ -4313,25 +4396,25 @@ function getMouseInfo(event) {
4313
4396
  function CodeActionMenuPlugin({
4314
4397
  anchorElem = document.body
4315
4398
  }) {
4316
- return (0, import_react_dom2.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(CodeActionMenuContainer, {
4399
+ return (0, import_react_dom2.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime81.jsx)(CodeActionMenuContainer, {
4317
4400
  anchorElem
4318
4401
  }), anchorElem);
4319
4402
  }
4320
4403
 
4321
4404
  // src/rich-text-editor/plugins/CodeHighlightPlugin/index.ts
4322
- var import_react66 = require("react");
4405
+ var import_react67 = require("react");
4323
4406
  var import_code7 = require("@lexical/code");
4324
4407
  var import_LexicalComposerContext2 = require("@lexical/react/LexicalComposerContext");
4325
4408
  function CodeHighlightPlugin() {
4326
4409
  const [editor] = (0, import_LexicalComposerContext2.useLexicalComposerContext)();
4327
- (0, import_react66.useEffect)(() => {
4410
+ (0, import_react67.useEffect)(() => {
4328
4411
  return (0, import_code7.registerCodeHighlighting)(editor);
4329
4412
  }, [editor]);
4330
4413
  return null;
4331
4414
  }
4332
4415
 
4333
4416
  // src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx
4334
- var import_react68 = require("react");
4417
+ var import_react69 = require("react");
4335
4418
  var React4 = require("react");
4336
4419
  var import_lexical9 = require("lexical");
4337
4420
  var import_react_dom3 = require("react-dom");
@@ -4340,10 +4423,10 @@ var import_LexicalComposerContext4 = require("@lexical/react/LexicalComposerCont
4340
4423
  var import_utils = require("@lexical/utils");
4341
4424
 
4342
4425
  // src/rich-text-editor/ui/LinkPreview.tsx
4343
- var import_react67 = require("react");
4426
+ var import_react68 = require("react");
4344
4427
  var import_lexical7 = require("lexical");
4345
4428
  var import_LexicalComposerContext3 = require("@lexical/react/LexicalComposerContext");
4346
- var import_jsx_runtime81 = require("react/jsx-runtime");
4429
+ var import_jsx_runtime82 = require("react/jsx-runtime");
4347
4430
  var PREVIEW_CACHE = {};
4348
4431
  var URL_MATCHER2 = /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
4349
4432
  function useSuspenseRequest(url) {
@@ -4367,11 +4450,12 @@ function useSuspenseRequest(url) {
4367
4450
  function LinkPreviewContent({
4368
4451
  url
4369
4452
  }) {
4370
- const [textContent, setTextContent] = (0, import_react67.useState)("");
4453
+ const [textContent, setTextContent] = (0, import_react68.useState)("");
4371
4454
  const { preview } = useSuspenseRequest(url);
4372
4455
  const [editor] = (0, import_LexicalComposerContext3.useLexicalComposerContext)();
4456
+ const tr = useTr();
4373
4457
  const hasPreview = preview !== null && preview.google?.title;
4374
- (0, import_react67.useEffect)(() => {
4458
+ (0, import_react68.useEffect)(() => {
4375
4459
  editor.update(() => {
4376
4460
  const sel = (0, import_lexical7.$getSelection)();
4377
4461
  const nodes = sel?.getNodes();
@@ -4399,35 +4483,35 @@ function LinkPreviewContent({
4399
4483
  if (!hasPreview) {
4400
4484
  return null;
4401
4485
  }
4402
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", {
4486
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", {
4403
4487
  className: "LinkPreview__container",
4404
4488
  children: [
4405
- preview.google.image && /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", {
4489
+ preview.google.image && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4406
4490
  className: "LinkPreview__imageWrapper bg-purple-50-900",
4407
- children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("img", {
4491
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("img", {
4408
4492
  src: preview.google.image,
4409
4493
  alt: preview.google.title,
4410
4494
  className: "LinkPreview__image"
4411
4495
  })
4412
4496
  }),
4413
- preview.google.title && /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", {
4497
+ preview.google.title && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4414
4498
  className: "LinkPreview__title",
4415
4499
  children: preview.google.title
4416
4500
  }),
4417
- preview.google.description && /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", {
4501
+ preview.google.description && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4418
4502
  className: "LinkPreview__description",
4419
4503
  children: preview.google.description
4420
4504
  }),
4421
- textContent && textContent !== preview.google.title ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(Button, {
4505
+ textContent && textContent !== preview.google.title ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Button, {
4422
4506
  className: "mb-4 ml-5",
4423
4507
  onClick: useTitleForText,
4424
- children: "Replace link text with its title"
4508
+ children: tr("linkPreviewReplaceTextWithTitle")
4425
4509
  }) : null
4426
4510
  ]
4427
4511
  });
4428
4512
  }
4429
4513
  function Glimmer(props) {
4430
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", {
4514
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4431
4515
  className: "LinkPreview__glimmer",
4432
4516
  ...props,
4433
4517
  style: {
@@ -4439,24 +4523,24 @@ function Glimmer(props) {
4439
4523
  function LinkPreview({
4440
4524
  url
4441
4525
  }) {
4442
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react67.Suspense, {
4443
- fallback: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(import_jsx_runtime81.Fragment, {
4526
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_react68.Suspense, {
4527
+ fallback: /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, {
4444
4528
  children: [
4445
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(Glimmer, {
4529
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Glimmer, {
4446
4530
  style: { height: "80px" },
4447
4531
  index: 0
4448
4532
  }),
4449
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(Glimmer, {
4533
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Glimmer, {
4450
4534
  style: { width: "60%" },
4451
4535
  index: 1
4452
4536
  }),
4453
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(Glimmer, {
4537
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Glimmer, {
4454
4538
  style: { width: "80%" },
4455
4539
  index: 2
4456
4540
  })
4457
4541
  ]
4458
4542
  }),
4459
- children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(LinkPreviewContent, {
4543
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(LinkPreviewContent, {
4460
4544
  url
4461
4545
  })
4462
4546
  });
@@ -4525,21 +4609,22 @@ function validateUrl(url) {
4525
4609
  }
4526
4610
 
4527
4611
  // src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx
4528
- var import_jsx_runtime82 = require("react/jsx-runtime");
4612
+ var import_jsx_runtime83 = require("react/jsx-runtime");
4529
4613
  function FloatingLinkEditor({
4530
4614
  editor,
4531
4615
  isLink,
4532
4616
  setIsLink,
4533
4617
  anchorElem
4534
4618
  }) {
4535
- const editorRef = (0, import_react68.useRef)(null);
4536
- const inputRef = (0, import_react68.useRef)(null);
4537
- const [linkUrl, setLinkUrl] = (0, import_react68.useState)("");
4538
- const [rel, setRel] = (0, import_react68.useState)(null);
4539
- const [target, setTarget] = (0, import_react68.useState)(null);
4540
- const [isEditMode, setEditMode] = (0, import_react68.useState)(false);
4541
- const [lastSelection, setLastSelection] = (0, import_react68.useState)(null);
4542
- const updateLinkEditor = (0, import_react68.useCallback)(() => {
4619
+ const editorRef = (0, import_react69.useRef)(null);
4620
+ const inputRef = (0, import_react69.useRef)(null);
4621
+ const [linkUrl, setLinkUrl] = (0, import_react69.useState)("");
4622
+ const [rel, setRel] = (0, import_react69.useState)(null);
4623
+ const [target, setTarget] = (0, import_react69.useState)(null);
4624
+ const [isEditMode, setEditMode] = (0, import_react69.useState)(false);
4625
+ const [lastSelection, setLastSelection] = (0, import_react69.useState)(null);
4626
+ const tr = useTr();
4627
+ const updateLinkEditor = (0, import_react69.useCallback)(() => {
4543
4628
  const selection = (0, import_lexical9.$getSelection)();
4544
4629
  if ((0, import_lexical9.$isRangeSelection)(selection)) {
4545
4630
  const node = getSelectedNode(selection);
@@ -4589,7 +4674,7 @@ function FloatingLinkEditor({
4589
4674
  }
4590
4675
  return true;
4591
4676
  }, [anchorElem, editor]);
4592
- (0, import_react68.useEffect)(() => {
4677
+ (0, import_react69.useEffect)(() => {
4593
4678
  const scrollerElem = anchorElem.parentElement;
4594
4679
  const update = () => {
4595
4680
  editor.getEditorState().read(() => {
@@ -4607,7 +4692,7 @@ function FloatingLinkEditor({
4607
4692
  }
4608
4693
  };
4609
4694
  }, [anchorElem.parentElement, editor, updateLinkEditor]);
4610
- (0, import_react68.useEffect)(() => {
4695
+ (0, import_react69.useEffect)(() => {
4611
4696
  return (0, import_utils.mergeRegister)(
4612
4697
  editor.registerUpdateListener(({ editorState }) => {
4613
4698
  editorState.read(() => {
@@ -4635,51 +4720,51 @@ function FloatingLinkEditor({
4635
4720
  )
4636
4721
  );
4637
4722
  }, [editor, updateLinkEditor, setIsLink, isLink]);
4638
- (0, import_react68.useEffect)(() => {
4723
+ (0, import_react69.useEffect)(() => {
4639
4724
  editor.getEditorState().read(() => {
4640
4725
  updateLinkEditor();
4641
4726
  });
4642
4727
  }, [editor, updateLinkEditor]);
4643
- (0, import_react68.useEffect)(() => {
4728
+ (0, import_react69.useEffect)(() => {
4644
4729
  if (isEditMode && inputRef.current) {
4645
4730
  inputRef.current.focus();
4646
4731
  }
4647
4732
  }, [isEditMode]);
4648
- return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4733
+ return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4649
4734
  ref: editorRef,
4650
4735
  className: "link-editor",
4651
- children: isEditMode ? /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", {
4736
+ children: isEditMode ? /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", {
4652
4737
  children: [
4653
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4738
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4654
4739
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4655
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(InputWithLabel, {
4656
- label: "Link",
4740
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(InputWithLabel, {
4741
+ label: tr("linkEditorLink"),
4657
4742
  type: "text",
4658
4743
  value: linkUrl,
4659
4744
  onChange: (e) => setLinkUrl(e.target.value)
4660
4745
  })
4661
4746
  }),
4662
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4747
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4663
4748
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4664
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(InputWithLabel, {
4665
- label: "Rel",
4749
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(InputWithLabel, {
4750
+ label: tr("linkEditorRel"),
4666
4751
  type: "text",
4667
4752
  value: rel ?? "",
4668
4753
  onChange: (e) => setRel(e.target.value)
4669
4754
  })
4670
4755
  }),
4671
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4756
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4672
4757
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4673
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(InputWithLabel, {
4674
- label: "Target",
4758
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(InputWithLabel, {
4759
+ label: tr("linkEditorTarget"),
4675
4760
  type: "text",
4676
4761
  value: target ?? "",
4677
4762
  onChange: (e) => setTarget(e.target.value)
4678
4763
  })
4679
4764
  }),
4680
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4765
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4681
4766
  className: "flex px-6 py-2 justify-end",
4682
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Button, {
4767
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(Button, {
4683
4768
  onClick: () => {
4684
4769
  if (lastSelection !== null) {
4685
4770
  if (linkUrl !== "") {
@@ -4692,32 +4777,32 @@ function FloatingLinkEditor({
4692
4777
  setEditMode(false);
4693
4778
  }
4694
4779
  },
4695
- children: "Done"
4780
+ children: tr("linkEditorCommit")
4696
4781
  })
4697
4782
  })
4698
4783
  ]
4699
- }) : /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, {
4784
+ }) : /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(import_jsx_runtime83.Fragment, {
4700
4785
  children: [
4701
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", {
4786
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", {
4702
4787
  className: "link-input !flex flex-nowrap justify-between items-center max-w-full ",
4703
4788
  children: [
4704
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", {
4705
- className: " grid",
4789
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", {
4790
+ className: "grid",
4706
4791
  children: [
4707
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("a", {
4792
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("a", {
4708
4793
  href: linkUrl,
4709
4794
  target: "_blank",
4710
4795
  rel: "noopener noreferrer",
4711
4796
  children: linkUrl
4712
4797
  }),
4713
- rel || target ? /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", {
4798
+ rel || target ? /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", {
4714
4799
  className: "flex mt-1 gap-1",
4715
4800
  children: [
4716
- rel && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4801
+ rel && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4717
4802
  className: "text-[10px] text-gray-600-300 px-1 bg-purple-50-900 rounded-md py-0.5",
4718
4803
  children: rel
4719
4804
  }),
4720
- target && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4805
+ target && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4721
4806
  className: "text-[10px] text-gray-600-300 px-1 bg-purple-50-900 rounded-md py-0.5",
4722
4807
  children: target
4723
4808
  })
@@ -4725,19 +4810,20 @@ function FloatingLinkEditor({
4725
4810
  }) : null
4726
4811
  ]
4727
4812
  }),
4728
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4729
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(IconButton, {
4813
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4814
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
4730
4815
  size: "sm",
4731
4816
  tabIndex: 0,
4732
4817
  onMouseDown: (event) => event.preventDefault(),
4733
4818
  onClick: () => setEditMode(true),
4734
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Icon.Edit, {})
4819
+ "aria-label": tr("linkEditorEdit"),
4820
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(Icon.Edit, {})
4735
4821
  })
4736
4822
  })
4737
4823
  ]
4738
4824
  }),
4739
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4740
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(LinkPreview, {
4825
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4826
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(LinkPreview, {
4741
4827
  url: linkUrl
4742
4828
  })
4743
4829
  })
@@ -4746,9 +4832,9 @@ function FloatingLinkEditor({
4746
4832
  });
4747
4833
  }
4748
4834
  function useFloatingLinkEditorToolbar(editor, anchorElem) {
4749
- const [activeEditor, setActiveEditor] = (0, import_react68.useState)(editor);
4750
- const [isLink, setIsLink] = (0, import_react68.useState)(false);
4751
- const updateToolbar = (0, import_react68.useCallback)(() => {
4835
+ const [activeEditor, setActiveEditor] = (0, import_react69.useState)(editor);
4836
+ const [isLink, setIsLink] = (0, import_react69.useState)(false);
4837
+ const updateToolbar = (0, import_react69.useCallback)(() => {
4752
4838
  const selection = (0, import_lexical9.$getSelection)();
4753
4839
  if ((0, import_lexical9.$isRangeSelection)(selection)) {
4754
4840
  const node = getSelectedNode(selection);
@@ -4761,7 +4847,7 @@ function useFloatingLinkEditorToolbar(editor, anchorElem) {
4761
4847
  }
4762
4848
  }
4763
4849
  }, []);
4764
- (0, import_react68.useEffect)(() => {
4850
+ (0, import_react69.useEffect)(() => {
4765
4851
  return editor.registerCommand(
4766
4852
  import_lexical9.SELECTION_CHANGE_COMMAND,
4767
4853
  (_payload, newEditor) => {
@@ -4773,7 +4859,7 @@ function useFloatingLinkEditorToolbar(editor, anchorElem) {
4773
4859
  );
4774
4860
  }, [editor, updateToolbar]);
4775
4861
  return isLink ? (0, import_react_dom3.createPortal)(
4776
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(FloatingLinkEditor, {
4862
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(FloatingLinkEditor, {
4777
4863
  editor: activeEditor,
4778
4864
  isLink,
4779
4865
  anchorElem,
@@ -4790,7 +4876,7 @@ function FloatingLinkEditorPlugin({
4790
4876
  }
4791
4877
 
4792
4878
  // src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx
4793
- var import_react69 = require("react");
4879
+ var import_react70 = require("react");
4794
4880
  var React5 = require("react");
4795
4881
  var import_lexical10 = require("lexical");
4796
4882
  var import_react_dom4 = require("react-dom");
@@ -4799,6 +4885,9 @@ var import_link5 = require("@lexical/link");
4799
4885
  var import_LexicalComposerContext5 = require("@lexical/react/LexicalComposerContext");
4800
4886
  var import_utils2 = require("@lexical/utils");
4801
4887
 
4888
+ // src/rich-text-editor/utils/environment.ts
4889
+ var IS_APPLE = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
4890
+
4802
4891
  // src/rich-text-editor/utils/getDOMRangeRect.ts
4803
4892
  function getDOMRangeRect(nativeSelection, rootElement) {
4804
4893
  const domRange = nativeSelection.getRangeAt(0);
@@ -4829,7 +4918,7 @@ function getDOMRangeRect(nativeSelection, rootElement) {
4829
4918
  }
4830
4919
 
4831
4920
  // src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx
4832
- var import_jsx_runtime83 = require("react/jsx-runtime");
4921
+ var import_jsx_runtime84 = require("react/jsx-runtime");
4833
4922
  function TextFormatFloatingToolbar({
4834
4923
  editor,
4835
4924
  anchorElem,
@@ -4842,15 +4931,16 @@ function TextFormatFloatingToolbar({
4842
4931
  isSubscript,
4843
4932
  isSuperscript
4844
4933
  }) {
4845
- const popupCharStylesEditorRef = (0, import_react69.useRef)(null);
4846
- const insertLink = (0, import_react69.useCallback)(() => {
4934
+ const popupCharStylesEditorRef = (0, import_react70.useRef)(null);
4935
+ const tr = useTr();
4936
+ const insertLink = (0, import_react70.useCallback)(() => {
4847
4937
  if (!isLink) {
4848
4938
  editor.dispatchCommand(import_link5.TOGGLE_LINK_COMMAND, "https://");
4849
4939
  } else {
4850
4940
  editor.dispatchCommand(import_link5.TOGGLE_LINK_COMMAND, null);
4851
4941
  }
4852
4942
  }, [editor, isLink]);
4853
- const updateTextFormatFloatingToolbar = (0, import_react69.useCallback)(() => {
4943
+ const updateTextFormatFloatingToolbar = (0, import_react70.useCallback)(() => {
4854
4944
  const selection = (0, import_lexical10.$getSelection)();
4855
4945
  const popupCharStylesEditorElem = popupCharStylesEditorRef.current;
4856
4946
  const nativeSelection = window.getSelection();
@@ -4863,7 +4953,7 @@ function TextFormatFloatingToolbar({
4863
4953
  setFloatingElemPosition(rangeRect, popupCharStylesEditorElem, anchorElem);
4864
4954
  }
4865
4955
  }, [editor, anchorElem]);
4866
- (0, import_react69.useEffect)(() => {
4956
+ (0, import_react70.useEffect)(() => {
4867
4957
  const scrollerElem = anchorElem.parentElement;
4868
4958
  const update = () => {
4869
4959
  editor.getEditorState().read(() => {
@@ -4881,7 +4971,7 @@ function TextFormatFloatingToolbar({
4881
4971
  }
4882
4972
  };
4883
4973
  }, [editor, updateTextFormatFloatingToolbar, anchorElem]);
4884
- (0, import_react69.useEffect)(() => {
4974
+ (0, import_react70.useEffect)(() => {
4885
4975
  editor.getEditorState().read(() => {
4886
4976
  updateTextFormatFloatingToolbar();
4887
4977
  });
@@ -4901,88 +4991,92 @@ function TextFormatFloatingToolbar({
4901
4991
  )
4902
4992
  );
4903
4993
  }, [editor, updateTextFormatFloatingToolbar]);
4904
- return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4994
+ return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", {
4905
4995
  ref: popupCharStylesEditorRef,
4906
4996
  className: "c-floating-text-format-popup gap-0.5",
4907
- children: editor.isEditable() && /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(import_jsx_runtime83.Fragment, {
4997
+ children: editor.isEditable() && /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, {
4908
4998
  children: [
4909
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
4999
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4910
5000
  onClick: () => {
4911
5001
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "bold");
4912
5002
  },
4913
5003
  style: { padding: 0, overflow: "hidden" },
4914
- "aria-label": "Format text as bold",
4915
- children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("i", {
5004
+ title: tr(IS_APPLE ? "actionFormatAsStrongTitleApple" : "actionFormatAsStrongTitle"),
5005
+ "aria-label": tr("actionFormatAsStrongLabel"),
5006
+ children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("i", {
4916
5007
  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"}`
4917
5008
  })
4918
5009
  }),
4919
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5010
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4920
5011
  style: { padding: 0, overflow: "hidden" },
4921
5012
  onClick: () => {
4922
5013
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "italic");
4923
5014
  },
4924
- "aria-label": "Format text as italics",
4925
- children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("i", {
5015
+ title: tr("actionFormatAsEmphasizedTitle"),
5016
+ "aria-label": tr("actionFormatAsEmphasizedLabel"),
5017
+ children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("i", {
4926
5018
  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"}`
4927
5019
  })
4928
5020
  }),
4929
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5021
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4930
5022
  style: { padding: 0, overflow: "hidden" },
4931
5023
  onClick: () => {
4932
5024
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "underline");
4933
5025
  },
4934
- "aria-label": "Format text to underlined",
4935
- children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("i", {
5026
+ title: tr("actionFormatAsUnderlinedTitle"),
5027
+ "aria-label": tr("actionFormatAsUnderlinedLabel"),
5028
+ children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("i", {
4936
5029
  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"}`
4937
5030
  })
4938
5031
  }),
4939
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5032
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4940
5033
  style: { padding: 0, overflow: "hidden" },
4941
5034
  onClick: () => {
4942
5035
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "strikethrough");
4943
5036
  },
4944
- "aria-label": "Format text with a strikethrough",
4945
- children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("i", {
5037
+ title: tr("actionFormatWithStrikethroughTitle"),
5038
+ "aria-label": tr("actionFormatWithStrikethroughLabel"),
5039
+ children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("i", {
4946
5040
  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"}`
4947
5041
  })
4948
5042
  }),
4949
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5043
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4950
5044
  style: { padding: 0, overflow: "hidden" },
4951
5045
  onClick: () => {
4952
5046
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "subscript");
4953
5047
  },
4954
- title: "Subscript",
4955
- "aria-label": "Format Subscript",
4956
- children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("i", {
5048
+ title: tr("actionFormatWithSubscriptTitle"),
5049
+ "aria-label": tr("actionFormatWithSubscriptLabel"),
5050
+ children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("i", {
4957
5051
  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"}`
4958
5052
  })
4959
5053
  }),
4960
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5054
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4961
5055
  style: { padding: 0, overflow: "hidden" },
4962
5056
  onClick: () => {
4963
5057
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "superscript");
4964
5058
  },
4965
- title: "Superscript",
4966
- "aria-label": "Format Superscript",
4967
- children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("i", {
5059
+ title: tr("actionFormatWithSuperscriptTitle"),
5060
+ "aria-label": tr("actionFormatWithSuperscriptLabel"),
5061
+ children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("i", {
4968
5062
  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"}`
4969
5063
  })
4970
5064
  }),
4971
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5065
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4972
5066
  style: { padding: 0, overflow: "hidden" },
4973
5067
  onClick: () => {
4974
5068
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "code");
4975
5069
  },
4976
- "aria-label": "Insert code block",
4977
- children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("i", {
5070
+ "aria-label": tr("actionInsertCodeBlock"),
5071
+ children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("i", {
4978
5072
  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"}`
4979
5073
  })
4980
5074
  }),
4981
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5075
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4982
5076
  style: { padding: 0, overflow: "hidden" },
4983
5077
  onClick: insertLink,
4984
- "aria-label": "Insert link",
4985
- children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("i", {
5078
+ "aria-label": tr("actionInsertlink"),
5079
+ children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("i", {
4986
5080
  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"}`
4987
5081
  })
4988
5082
  })
@@ -4991,16 +5085,16 @@ function TextFormatFloatingToolbar({
4991
5085
  });
4992
5086
  }
4993
5087
  function useFloatingTextFormatToolbar(editor, anchorElem) {
4994
- const [isText, setIsText] = (0, import_react69.useState)(false);
4995
- const [isLink, setIsLink] = (0, import_react69.useState)(false);
4996
- const [isBold, setIsBold] = (0, import_react69.useState)(false);
4997
- const [isItalic, setIsItalic] = (0, import_react69.useState)(false);
4998
- const [isUnderline, setIsUnderline] = (0, import_react69.useState)(false);
4999
- const [isStrikethrough, setIsStrikethrough] = (0, import_react69.useState)(false);
5000
- const [isSubscript, setIsSubscript] = (0, import_react69.useState)(false);
5001
- const [isSuperscript, setIsSuperscript] = (0, import_react69.useState)(false);
5002
- const [isCode, setIsCode] = (0, import_react69.useState)(false);
5003
- const updatePopup = (0, import_react69.useCallback)(() => {
5088
+ const [isText, setIsText] = (0, import_react70.useState)(false);
5089
+ const [isLink, setIsLink] = (0, import_react70.useState)(false);
5090
+ const [isBold, setIsBold] = (0, import_react70.useState)(false);
5091
+ const [isItalic, setIsItalic] = (0, import_react70.useState)(false);
5092
+ const [isUnderline, setIsUnderline] = (0, import_react70.useState)(false);
5093
+ const [isStrikethrough, setIsStrikethrough] = (0, import_react70.useState)(false);
5094
+ const [isSubscript, setIsSubscript] = (0, import_react70.useState)(false);
5095
+ const [isSuperscript, setIsSuperscript] = (0, import_react70.useState)(false);
5096
+ const [isCode, setIsCode] = (0, import_react70.useState)(false);
5097
+ const updatePopup = (0, import_react70.useCallback)(() => {
5004
5098
  editor.getEditorState().read(() => {
5005
5099
  if (editor.isComposing()) {
5006
5100
  return;
@@ -5036,13 +5130,13 @@ function useFloatingTextFormatToolbar(editor, anchorElem) {
5036
5130
  }
5037
5131
  });
5038
5132
  }, [editor]);
5039
- (0, import_react69.useEffect)(() => {
5133
+ (0, import_react70.useEffect)(() => {
5040
5134
  document.addEventListener("selectionchange", updatePopup);
5041
5135
  return () => {
5042
5136
  document.removeEventListener("selectionchange", updatePopup);
5043
5137
  };
5044
5138
  }, [updatePopup]);
5045
- (0, import_react69.useEffect)(() => {
5139
+ (0, import_react70.useEffect)(() => {
5046
5140
  return (0, import_utils2.mergeRegister)(
5047
5141
  editor.registerUpdateListener(() => {
5048
5142
  updatePopup();
@@ -5058,7 +5152,7 @@ function useFloatingTextFormatToolbar(editor, anchorElem) {
5058
5152
  return null;
5059
5153
  }
5060
5154
  return (0, import_react_dom4.createPortal)(
5061
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(TextFormatFloatingToolbar, {
5155
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(TextFormatFloatingToolbar, {
5062
5156
  editor,
5063
5157
  anchorElem,
5064
5158
  isLink,
@@ -5083,9 +5177,9 @@ function FloatingTextFormatToolbarPlugin({
5083
5177
  // src/rich-text-editor/plugins/LinkPlugin/index.tsx
5084
5178
  var import_LexicalLinkPlugin = require("@lexical/react/LexicalLinkPlugin");
5085
5179
  var React6 = require("react");
5086
- var import_jsx_runtime84 = require("react/jsx-runtime");
5180
+ var import_jsx_runtime85 = require("react/jsx-runtime");
5087
5181
  function LinkPlugin() {
5088
- return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_LexicalLinkPlugin.LinkPlugin, {
5182
+ return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(import_LexicalLinkPlugin.LinkPlugin, {
5089
5183
  validateUrl
5090
5184
  });
5091
5185
  }
@@ -5094,7 +5188,7 @@ function LinkPlugin() {
5094
5188
  var import_list4 = require("@lexical/list");
5095
5189
  var import_LexicalComposerContext6 = require("@lexical/react/LexicalComposerContext");
5096
5190
  var import_lexical11 = require("lexical");
5097
- var import_react70 = require("react");
5191
+ var import_react71 = require("react");
5098
5192
  function getElementNodesInSelection(selection) {
5099
5193
  const nodesInSelection = selection.getNodes();
5100
5194
  if (nodesInSelection.length === 0) {
@@ -5131,7 +5225,7 @@ function isIndentPermitted(maxDepth) {
5131
5225
  }
5132
5226
  function ListMaxIndentLevelPlugin({ maxDepth }) {
5133
5227
  const [editor] = (0, import_LexicalComposerContext6.useLexicalComposerContext)();
5134
- (0, import_react70.useEffect)(() => {
5228
+ (0, import_react71.useEffect)(() => {
5135
5229
  return editor.registerCommand(
5136
5230
  import_lexical11.INDENT_CONTENT_COMMAND,
5137
5231
  () => !isIndentPermitted(maxDepth ?? 7),
@@ -5142,7 +5236,7 @@ function ListMaxIndentLevelPlugin({ maxDepth }) {
5142
5236
  }
5143
5237
 
5144
5238
  // src/rich-text-editor/plugins/MaxLengthPlugin/index.tsx
5145
- var import_react71 = require("react");
5239
+ var import_react72 = require("react");
5146
5240
  var import_lexical12 = require("lexical");
5147
5241
  var import_LexicalComposerContext7 = require("@lexical/react/LexicalComposerContext");
5148
5242
  var import_selection2 = require("@lexical/selection");
@@ -5184,7 +5278,7 @@ ${content}
5184
5278
  // src/rich-text-editor/plugins/MaxLengthPlugin/index.tsx
5185
5279
  function MaxLengthPlugin({ maxLength }) {
5186
5280
  const [editor] = (0, import_LexicalComposerContext7.useLexicalComposerContext)();
5187
- (0, import_react71.useEffect)(() => {
5281
+ (0, import_react72.useEffect)(() => {
5188
5282
  let lastRestoredEditorState = null;
5189
5283
  return editor.registerUpdateListener(({ editorState, prevEditorState }) => {
5190
5284
  editor.update(() => {
@@ -5214,9 +5308,9 @@ function MaxLengthPlugin({ maxLength }) {
5214
5308
  }
5215
5309
 
5216
5310
  // src/rich-text-editor/plugins/TabFocusPlugin/index.tsx
5217
- var import_LexicalComposerContext8 = require("@lexical/react/LexicalComposerContext");
5311
+ var import_react73 = require("react");
5218
5312
  var import_lexical13 = require("lexical");
5219
- var import_react72 = require("react");
5313
+ var import_LexicalComposerContext8 = require("@lexical/react/LexicalComposerContext");
5220
5314
  var COMMAND_PRIORITY_LOW3 = 1;
5221
5315
  var TAB_TO_FOCUS_INTERVAL = 100;
5222
5316
  var lastTabKeyDownTimestamp = 0;
@@ -5234,7 +5328,7 @@ function registerKeyTimeStampTracker() {
5234
5328
  }
5235
5329
  function TabFocusPlugin() {
5236
5330
  const [editor] = (0, import_LexicalComposerContext8.useLexicalComposerContext)();
5237
- (0, import_react72.useEffect)(() => {
5331
+ (0, import_react73.useEffect)(() => {
5238
5332
  if (!hasRegisteredKeyDownListener) {
5239
5333
  registerKeyTimeStampTracker();
5240
5334
  hasRegisteredKeyDownListener = true;
@@ -5257,21 +5351,22 @@ function TabFocusPlugin() {
5257
5351
  }
5258
5352
 
5259
5353
  // src/rich-text-editor/plugins/TableActionMenuPlugin/index.tsx
5260
- var import_react73 = require("react");
5354
+ var import_react74 = require("react");
5261
5355
  var import_lexical14 = require("lexical");
5262
5356
  var import_react_dom5 = require("react-dom");
5263
5357
  var import_LexicalComposerContext9 = require("@lexical/react/LexicalComposerContext");
5264
5358
  var import_useLexicalEditable = __toESM(require("@lexical/react/useLexicalEditable"));
5265
5359
  var import_table4 = require("@lexical/table");
5266
- var import_jsx_runtime85 = require("react/jsx-runtime");
5360
+ var import_jsx_runtime86 = require("react/jsx-runtime");
5267
5361
  function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5268
5362
  const [editor] = (0, import_LexicalComposerContext9.useLexicalComposerContext)();
5269
- const [tableCellNode, updateTableCellNode] = (0, import_react73.useState)(_tableCellNode);
5270
- const [selectionCounts, updateSelectionCounts] = (0, import_react73.useState)({
5363
+ const [tableCellNode, updateTableCellNode] = (0, import_react74.useState)(_tableCellNode);
5364
+ const [selectionCounts, updateSelectionCounts] = (0, import_react74.useState)({
5271
5365
  columns: 1,
5272
5366
  rows: 1
5273
5367
  });
5274
- (0, import_react73.useEffect)(() => {
5368
+ const tr = useTr();
5369
+ (0, import_react74.useEffect)(() => {
5275
5370
  return editor.registerMutationListener(import_table4.TableCellNode, (nodeMutations) => {
5276
5371
  const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === "updated";
5277
5372
  if (nodeUpdated) {
@@ -5281,7 +5376,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5281
5376
  }
5282
5377
  });
5283
5378
  }, [editor, tableCellNode]);
5284
- (0, import_react73.useEffect)(() => {
5379
+ (0, import_react74.useEffect)(() => {
5285
5380
  editor.getEditorState().read(() => {
5286
5381
  const selection = (0, import_lexical14.$getSelection)();
5287
5382
  if ((0, import_lexical14.DEPRECATED_$isGridSelection)(selection)) {
@@ -5293,7 +5388,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5293
5388
  }
5294
5389
  });
5295
5390
  }, [editor]);
5296
- const clearTableSelection = (0, import_react73.useCallback)(() => {
5391
+ const clearTableSelection = (0, import_react74.useCallback)(() => {
5297
5392
  editor.update(() => {
5298
5393
  if (tableCellNode.isAttached()) {
5299
5394
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
@@ -5312,7 +5407,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5312
5407
  rootNode.selectStart();
5313
5408
  });
5314
5409
  }, [editor, tableCellNode]);
5315
- const insertTableRowAtSelection = (0, import_react73.useCallback)(
5410
+ const insertTableRowAtSelection = (0, import_react74.useCallback)(
5316
5411
  (shouldInsertAfter) => {
5317
5412
  editor.update(() => {
5318
5413
  const selection = (0, import_lexical14.$getSelection)();
@@ -5331,7 +5426,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5331
5426
  },
5332
5427
  [editor, tableCellNode, selectionCounts.rows, clearTableSelection]
5333
5428
  );
5334
- const insertTableColumnAtSelection = (0, import_react73.useCallback)(
5429
+ const insertTableColumnAtSelection = (0, import_react74.useCallback)(
5335
5430
  (shouldInsertAfter) => {
5336
5431
  editor.update(() => {
5337
5432
  const selection = (0, import_lexical14.$getSelection)();
@@ -5350,7 +5445,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5350
5445
  },
5351
5446
  [editor, tableCellNode, selectionCounts.columns, clearTableSelection]
5352
5447
  );
5353
- const deleteTableRowAtSelection = (0, import_react73.useCallback)(() => {
5448
+ const deleteTableRowAtSelection = (0, import_react74.useCallback)(() => {
5354
5449
  editor.update(() => {
5355
5450
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
5356
5451
  const tableRowIndex = (0, import_table4.$getTableRowIndexFromTableCellNode)(tableCellNode);
@@ -5358,14 +5453,14 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5358
5453
  clearTableSelection();
5359
5454
  });
5360
5455
  }, [editor, tableCellNode, clearTableSelection]);
5361
- const deleteTableAtSelection = (0, import_react73.useCallback)(() => {
5456
+ const deleteTableAtSelection = (0, import_react74.useCallback)(() => {
5362
5457
  editor.update(() => {
5363
5458
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
5364
5459
  tableNode.remove();
5365
5460
  clearTableSelection();
5366
5461
  });
5367
5462
  }, [editor, tableCellNode, clearTableSelection]);
5368
- const deleteTableColumnAtSelection = (0, import_react73.useCallback)(() => {
5463
+ const deleteTableColumnAtSelection = (0, import_react74.useCallback)(() => {
5369
5464
  editor.update(() => {
5370
5465
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
5371
5466
  const tableColumnIndex = (0, import_table4.$getTableColumnIndexFromTableCellNode)(tableCellNode);
@@ -5373,7 +5468,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5373
5468
  clearTableSelection();
5374
5469
  });
5375
5470
  }, [editor, tableCellNode, clearTableSelection]);
5376
- const toggleTableRowIsHeader = (0, import_react73.useCallback)(() => {
5471
+ const toggleTableRowIsHeader = (0, import_react74.useCallback)(() => {
5377
5472
  editor.update(() => {
5378
5473
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
5379
5474
  const tableRowIndex = (0, import_table4.$getTableRowIndexFromTableCellNode)(tableCellNode);
@@ -5394,7 +5489,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5394
5489
  clearTableSelection();
5395
5490
  });
5396
5491
  }, [editor, tableCellNode, clearTableSelection]);
5397
- const toggleTableColumnIsHeader = (0, import_react73.useCallback)(() => {
5492
+ const toggleTableColumnIsHeader = (0, import_react74.useCallback)(() => {
5398
5493
  editor.update(() => {
5399
5494
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
5400
5495
  const tableColumnIndex = (0, import_table4.$getTableColumnIndexFromTableCellNode)(tableCellNode);
@@ -5417,78 +5512,60 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5417
5512
  clearTableSelection();
5418
5513
  });
5419
5514
  }, [editor, tableCellNode, clearTableSelection]);
5420
- return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, {
5515
+ return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(import_jsx_runtime86.Fragment, {
5421
5516
  children: [
5422
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5517
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5423
5518
  onSelect: () => insertTableRowAtSelection(false),
5424
- children: [
5425
- "Insert ",
5426
- selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
5427
- " above"
5428
- ]
5519
+ children: tr("actionTableInsertRowsAbove", selectionCounts.rows)
5429
5520
  }),
5430
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5521
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5431
5522
  onSelect: () => insertTableRowAtSelection(true),
5432
- children: [
5433
- "Insert ",
5434
- selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
5435
- " below"
5436
- ]
5523
+ children: tr("actionTableInsertRowsBelow", selectionCounts.rows)
5437
5524
  }),
5438
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5525
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5439
5526
  onSelect: () => insertTableColumnAtSelection(false),
5440
- children: [
5441
- "Insert ",
5442
- selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
5443
- " left"
5444
- ]
5527
+ children: tr("actionTableInsertColumnsBefore", selectionCounts.columns)
5445
5528
  }),
5446
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5529
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5447
5530
  onSelect: () => insertTableColumnAtSelection(true),
5448
- children: [
5449
- "Insert ",
5450
- selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
5451
- " right"
5452
- ]
5531
+ children: tr("actionTableInsertColumnsAfter", selectionCounts.columns)
5453
5532
  }),
5454
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5533
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5455
5534
  onSelect: () => toggleTableRowIsHeader(),
5456
- children: [
5457
- (tableCellNode.__headerState & import_table4.TableCellHeaderStates.ROW) === import_table4.TableCellHeaderStates.ROW ? "Remove" : "Add",
5458
- " row header"
5459
- ]
5535
+ children: tr(
5536
+ (tableCellNode.__headerState & import_table4.TableCellHeaderStates.ROW) === import_table4.TableCellHeaderStates.ROW ? "actionTableRemoveRowHeader" : "actionTableAddRowHeader"
5537
+ )
5460
5538
  }),
5461
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5539
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5462
5540
  onSelect: () => toggleTableColumnIsHeader(),
5463
- children: [
5464
- (tableCellNode.__headerState & import_table4.TableCellHeaderStates.COLUMN) === import_table4.TableCellHeaderStates.COLUMN ? "Remove" : "Add",
5465
- " ",
5466
- "column header"
5467
- ]
5541
+ children: tr(
5542
+ (tableCellNode.__headerState & import_table4.TableCellHeaderStates.COLUMN) === import_table4.TableCellHeaderStates.COLUMN ? "actionTableRemoveColumnHeader" : "actionTableAddColumnHeader"
5543
+ )
5468
5544
  }),
5469
- /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(DropdownMenu.Separator, {}),
5470
- tableStats.columns > 1 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(DropdownMenu.Item, {
5545
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Separator, {}),
5546
+ tableStats.columns > 1 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5471
5547
  onSelect: () => deleteTableColumnAtSelection(),
5472
- children: "Delete column"
5548
+ children: tr("actionTableDeleteColumn")
5473
5549
  }),
5474
- tableStats.rows > 1 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(DropdownMenu.Item, {
5550
+ tableStats.rows > 1 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5475
5551
  onSelect: () => deleteTableRowAtSelection(),
5476
- children: "Delete row"
5552
+ children: tr("actionTableDeleteRow")
5477
5553
  }),
5478
- /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(DropdownMenu.Item, {
5554
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5479
5555
  onSelect: () => deleteTableAtSelection(),
5480
- children: "Delete table"
5556
+ children: tr("actionTableDeleteTable")
5481
5557
  })
5482
5558
  ]
5483
5559
  });
5484
5560
  }
5485
5561
  function TableCellActionMenuContainer({ anchorElem }) {
5486
5562
  const [editor] = (0, import_LexicalComposerContext9.useLexicalComposerContext)();
5487
- const menuButtonRef = (0, import_react73.useRef)(null);
5488
- const [isMenuOpen, setIsMenuOpen] = (0, import_react73.useState)(false);
5489
- const [tableCellNode, setTableMenuCellNode] = (0, import_react73.useState)(null);
5490
- const [tableStats, setTablestats] = (0, import_react73.useState)({ rows: 1, columns: 1 });
5491
- const moveMenu = (0, import_react73.useCallback)(() => {
5563
+ const tr = useTr();
5564
+ const menuButtonRef = (0, import_react74.useRef)(null);
5565
+ const [isMenuOpen, setIsMenuOpen] = (0, import_react74.useState)(false);
5566
+ const [tableCellNode, setTableMenuCellNode] = (0, import_react74.useState)(null);
5567
+ const [tableStats, setTablestats] = (0, import_react74.useState)({ rows: 1, columns: 1 });
5568
+ const moveMenu = (0, import_react74.useCallback)(() => {
5492
5569
  if (isMenuOpen) {
5493
5570
  return;
5494
5571
  }
@@ -5531,14 +5608,14 @@ function TableCellActionMenuContainer({ anchorElem }) {
5531
5608
  setTableMenuCellNode(null);
5532
5609
  }
5533
5610
  }, [editor, isMenuOpen]);
5534
- (0, import_react73.useEffect)(() => {
5611
+ (0, import_react74.useEffect)(() => {
5535
5612
  return editor.registerUpdateListener(() => {
5536
5613
  editor.getEditorState().read(() => {
5537
5614
  moveMenu();
5538
5615
  });
5539
5616
  });
5540
5617
  });
5541
- (0, import_react73.useEffect)(() => {
5618
+ (0, import_react74.useEffect)(() => {
5542
5619
  const menuButtonDOM = menuButtonRef.current;
5543
5620
  if (menuButtonDOM != null && tableCellNode != null) {
5544
5621
  const tableCellNodeDOM = editor.getElementByKey(tableCellNode.getKey());
@@ -5556,19 +5633,20 @@ function TableCellActionMenuContainer({ anchorElem }) {
5556
5633
  }
5557
5634
  }
5558
5635
  }, [menuButtonRef, tableCellNode, editor, anchorElem]);
5559
- return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", {
5636
+ return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", {
5560
5637
  className: "table-cell-action-button-container",
5561
5638
  ref: menuButtonRef,
5562
- children: tableCellNode != null && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(DropdownMenu.Root, {
5639
+ children: tableCellNode != null && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Root, {
5563
5640
  onOpenChange: (isOpen) => setIsMenuOpen(isOpen),
5564
- content: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(TableActionMenu, {
5641
+ content: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(TableActionMenu, {
5565
5642
  tableCellNode,
5566
5643
  tableStats
5567
5644
  }),
5568
- children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(IconButton, {
5645
+ children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(IconButton, {
5569
5646
  size: "xs",
5570
5647
  className: "table-cell-action-button",
5571
- children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(Icon.Arrow, {})
5648
+ "aria-label": tr("actionTableOpenOptions"),
5649
+ children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(Icon.Arrow, {})
5572
5650
  })
5573
5651
  })
5574
5652
  });
@@ -5577,13 +5655,13 @@ function TableActionMenuPlugin({
5577
5655
  anchorElem = document.body
5578
5656
  }) {
5579
5657
  const isEditable = (0, import_useLexicalEditable.default)();
5580
- return (0, import_react_dom5.createPortal)(isEditable ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(TableCellActionMenuContainer, {
5658
+ return (0, import_react_dom5.createPortal)(isEditable ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(TableCellActionMenuContainer, {
5581
5659
  anchorElem
5582
5660
  }) : null, anchorElem);
5583
5661
  }
5584
5662
 
5585
5663
  // src/rich-text-editor/plugins/ToolbarPlugin/index.tsx
5586
- var import_react75 = require("react");
5664
+ var import_react76 = require("react");
5587
5665
  var import_lexical16 = require("lexical");
5588
5666
  var import_code9 = require("@lexical/code");
5589
5667
  var import_link6 = require("@lexical/link");
@@ -5595,13 +5673,10 @@ var import_rich_text4 = require("@lexical/rich-text");
5595
5673
  var import_selection3 = require("@lexical/selection");
5596
5674
  var import_utils4 = require("@lexical/utils");
5597
5675
 
5598
- // src/rich-text-editor/utils/environment.ts
5599
- var IS_APPLE = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
5600
-
5601
5676
  // src/rich-text-editor/plugins/ActionsPlugin/index.tsx
5602
5677
  var import_lexical15 = require("lexical");
5603
5678
  var import_LexicalComposerContext10 = require("@lexical/react/LexicalComposerContext");
5604
- var import_jsx_runtime86 = require("react/jsx-runtime");
5679
+ var import_jsx_runtime87 = require("react/jsx-runtime");
5605
5680
  async function copyJson(editor) {
5606
5681
  const json = lexicalToCrystallizeRichText({ editor, editorState: editor.getEditorState() });
5607
5682
  try {
@@ -5610,53 +5685,36 @@ async function copyJson(editor) {
5610
5685
  console.warn("Copy failed", error);
5611
5686
  }
5612
5687
  }
5613
- async function exportJson(editor) {
5614
- const json = lexicalToCrystallizeRichText({ editorState: editor.getEditorState() });
5615
- const blob = new Blob([JSON.stringify(json, null, 1)], {
5616
- type: "application/json"
5617
- });
5618
- const href = URL.createObjectURL(blob);
5619
- const link = document.createElement("a");
5620
- link.href = href;
5621
- link.download = "crystallizeRichText.json";
5622
- document.body.appendChild(link);
5623
- link.click();
5624
- document.body.removeChild(link);
5625
- URL.revokeObjectURL(href);
5626
- }
5627
5688
  function ActionsPlugin({
5628
5689
  append,
5629
5690
  prepend
5630
5691
  }) {
5631
5692
  const [editor] = (0, import_LexicalComposerContext10.useLexicalComposerContext)();
5632
- return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", {
5693
+ const tr = useTr();
5694
+ return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", {
5633
5695
  className: "z-50 flex items-center ",
5634
5696
  children: [
5635
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", {}),
5636
- /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(ActionMenu, {
5697
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", {}),
5698
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(ActionMenu, {
5637
5699
  children: [
5638
- !prepend ? null : prepend.map((actionItem) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(ActionMenu.Item, {
5700
+ !prepend ? null : prepend.map((actionItem) => /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ActionMenu.Item, {
5639
5701
  onSelect: actionItem.action,
5640
5702
  className: actionItem.type === "danger" ? "danger" : "",
5641
5703
  children: actionItem.title
5642
5704
  }, actionItem.title)),
5643
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(ActionMenu.Item, {
5705
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ActionMenu.Item, {
5644
5706
  onSelect: () => copyJson(editor),
5645
- children: "Copy JSON"
5707
+ children: tr("actionCopyJSON")
5646
5708
  }),
5647
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(ActionMenu.Item, {
5648
- onSelect: () => exportJson(editor),
5649
- children: "Export JSON"
5650
- }),
5651
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(ActionMenu.Item, {
5709
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ActionMenu.Item, {
5652
5710
  className: "danger",
5653
5711
  onSelect: () => {
5654
5712
  editor.dispatchCommand(import_lexical15.CLEAR_EDITOR_COMMAND, void 0);
5655
5713
  editor.focus();
5656
5714
  },
5657
- children: "Clear paragraph"
5715
+ children: tr("actionClear")
5658
5716
  }),
5659
- !append ? null : append.map((actionItem) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(ActionMenu.Item, {
5717
+ !append ? null : append.map((actionItem) => /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ActionMenu.Item, {
5660
5718
  onSelect: actionItem.action,
5661
5719
  className: actionItem.type === "danger" ? "danger" : "",
5662
5720
  children: actionItem.title
@@ -5668,12 +5726,13 @@ function ActionsPlugin({
5668
5726
  }
5669
5727
 
5670
5728
  // src/rich-text-editor/plugins/ToolbarPlugin/insert-table.tsx
5671
- var import_react74 = require("react");
5729
+ var import_react75 = require("react");
5672
5730
  var import_table5 = require("@lexical/table");
5673
- var import_jsx_runtime87 = require("react/jsx-runtime");
5731
+ var import_jsx_runtime88 = require("react/jsx-runtime");
5674
5732
  function InsertTableDialog({ activeEditor }) {
5675
- const [rows, setRows] = (0, import_react74.useState)("5");
5676
- const [columns, setColumns] = (0, import_react74.useState)("5");
5733
+ const [rows, setRows] = (0, import_react75.useState)("5");
5734
+ const [columns, setColumns] = (0, import_react75.useState)("5");
5735
+ const tr = useTr();
5677
5736
  const onClick = () => {
5678
5737
  if (parseInt(rows) < 1 || parseInt(columns) < 1) {
5679
5738
  return;
@@ -5687,25 +5746,25 @@ function InsertTableDialog({ activeEditor }) {
5687
5746
  }
5688
5747
  });
5689
5748
  };
5690
- return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(import_jsx_runtime87.Fragment, {
5749
+ return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, {
5691
5750
  children: [
5692
- /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", {
5751
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", {
5693
5752
  className: "grid grid-cols-[1fr_1px_1fr] border border-gray-100-800 border-solid shadow-sm rounded-md ",
5694
5753
  children: [
5695
- /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(InputWithLabel, {
5696
- label: "Rows",
5754
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(InputWithLabel, {
5755
+ label: tr("insertTableRows"),
5697
5756
  value: rows,
5698
5757
  placeholder: "0",
5699
5758
  type: "text",
5700
5759
  inputMode: "numeric",
5701
5760
  onChange: (e) => setRows(e.target.value)
5702
5761
  }),
5703
- /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", {
5762
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5704
5763
  className: "h-full bg-gray-100-800"
5705
5764
  }),
5706
- /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(InputWithLabel, {
5765
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(InputWithLabel, {
5707
5766
  type: "text",
5708
- label: "Columns",
5767
+ label: tr("insertTableColumns"),
5709
5768
  placeholder: "0",
5710
5769
  value: columns,
5711
5770
  inputMode: "numeric",
@@ -5713,15 +5772,15 @@ function InsertTableDialog({ activeEditor }) {
5713
5772
  })
5714
5773
  ]
5715
5774
  }),
5716
- /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", {
5775
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", {
5717
5776
  className: "flex justify-end mt-3",
5718
- children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(Button, {
5777
+ children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Button, {
5719
5778
  as: Dialog.Close,
5720
5779
  size: "sm",
5721
5780
  intent: "action",
5722
- "aria-label": "Confirm",
5781
+ "aria-label": tr("insertTableCommit"),
5723
5782
  onClick,
5724
- children: "Confirm"
5783
+ children: tr("insertTableCommit")
5725
5784
  })
5726
5785
  })
5727
5786
  ]
@@ -5729,7 +5788,7 @@ function InsertTableDialog({ activeEditor }) {
5729
5788
  }
5730
5789
 
5731
5790
  // src/rich-text-editor/plugins/ToolbarPlugin/index.tsx
5732
- var import_jsx_runtime88 = require("react/jsx-runtime");
5791
+ var import_jsx_runtime89 = require("react/jsx-runtime");
5733
5792
  var headingTypeToBlockName = {
5734
5793
  h1: "Heading 1",
5735
5794
  h2: "Heading 2",
@@ -5833,83 +5892,83 @@ function BlockFormatDropDown({
5833
5892
  });
5834
5893
  }
5835
5894
  };
5836
- return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Root, {
5895
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(DropdownMenu.Root, {
5837
5896
  disabled,
5838
5897
  style: { zIndex: 1 },
5839
- content: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, {
5898
+ content: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_jsx_runtime89.Fragment, {
5840
5899
  children: [
5841
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5900
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5842
5901
  onClick: formatParagraph,
5843
5902
  children: [
5844
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5903
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5845
5904
  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"}`
5846
5905
  }),
5847
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5906
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5848
5907
  className: "icon paragraph"
5849
5908
  }),
5850
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5909
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5851
5910
  className: `${blockType === "paragraph" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5852
5911
  children: "Normal"
5853
5912
  })
5854
5913
  ]
5855
5914
  }),
5856
- headings.map((headingSize) => /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5915
+ headings.map((headingSize) => /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5857
5916
  onClick: () => formatHeading(headingSize),
5858
5917
  children: [
5859
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5918
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5860
5919
  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"}`
5861
5920
  }),
5862
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5921
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5863
5922
  className: `${blockType === headingSize ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5864
5923
  children: headingTypeToBlockName[headingSize]
5865
5924
  })
5866
5925
  ]
5867
5926
  }, headingSize)),
5868
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5927
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5869
5928
  onClick: formatBulletList,
5870
5929
  children: [
5871
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5930
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5872
5931
  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"}`
5873
5932
  }),
5874
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5933
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5875
5934
  className: `${blockType === "bullet" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5876
5935
  children: "Bullet List"
5877
5936
  })
5878
5937
  ]
5879
5938
  }),
5880
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5939
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5881
5940
  onClick: formatNumberedList,
5882
5941
  children: [
5883
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5942
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5884
5943
  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"}`
5885
5944
  }),
5886
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5945
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5887
5946
  className: `${blockType === "number" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5888
5947
  children: "Numbered List"
5889
5948
  })
5890
5949
  ]
5891
5950
  }),
5892
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5951
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5893
5952
  onClick: formatQuote,
5894
5953
  "data-testid": "toggle-block-format-quote",
5895
5954
  children: [
5896
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5955
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5897
5956
  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"}`
5898
5957
  }),
5899
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5958
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5900
5959
  className: `${blockType === "quote" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5901
5960
  children: "Quote"
5902
5961
  })
5903
5962
  ]
5904
5963
  }),
5905
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5964
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5906
5965
  onClick: formatCode,
5907
5966
  "data-testid": "toggle-block-format-code",
5908
5967
  children: [
5909
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5968
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5910
5969
  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"}`
5911
5970
  }),
5912
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5971
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5913
5972
  className: `${blockType === "code" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5914
5973
  children: "Code block"
5915
5974
  })
@@ -5917,21 +5976,21 @@ function BlockFormatDropDown({
5917
5976
  })
5918
5977
  ]
5919
5978
  }),
5920
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(Button, {
5979
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(Button, {
5921
5980
  style: { backgroundColor: "transparent", padding: "0 8px" },
5922
5981
  "aria-label": "Formatting options for text style",
5923
5982
  "data-testid": "toggle-block-format",
5924
5983
  children: [
5925
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5984
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5926
5985
  className: `icon ${blockType} border bg-no-repeat bg-center bg-[length:18px_18px] w-6 h-6`
5927
5986
  }),
5928
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Icon.Arrow, {})
5987
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Icon.Arrow, {})
5929
5988
  ]
5930
5989
  })
5931
5990
  });
5932
5991
  }
5933
5992
  function Divider() {
5934
- return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", {
5993
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", {
5935
5994
  className: "divider"
5936
5995
  });
5937
5996
  }
@@ -5940,22 +5999,23 @@ function ToolbarPlugin({
5940
5999
  actionsMenuAppend
5941
6000
  }) {
5942
6001
  const [editor] = (0, import_LexicalComposerContext11.useLexicalComposerContext)();
5943
- const [activeEditor, setActiveEditor] = (0, import_react75.useState)(editor);
5944
- const [blockType, setBlockType] = (0, import_react75.useState)("paragraph");
5945
- const [selectedElementKey, setSelectedElementKey] = (0, import_react75.useState)(null);
5946
- const [isLink, setIsLink] = (0, import_react75.useState)(false);
5947
- const [isBold, setIsBold] = (0, import_react75.useState)(false);
5948
- const [isItalic, setIsItalic] = (0, import_react75.useState)(false);
5949
- const [isUnderline, setIsUnderline] = (0, import_react75.useState)(false);
5950
- const [isStrikethrough, setIsStrikethrough] = (0, import_react75.useState)(false);
5951
- const [isSubscript, setIsSubscript] = (0, import_react75.useState)(false);
5952
- const [isSuperscript, setIsSuperscript] = (0, import_react75.useState)(false);
5953
- const [isCode, setIsCode] = (0, import_react75.useState)(false);
5954
- const [canUndo, setCanUndo] = (0, import_react75.useState)(false);
5955
- const [canRedo, setCanRedo] = (0, import_react75.useState)(false);
5956
- const [codeLanguage, setCodeLanguage] = (0, import_react75.useState)("");
5957
- const [isEditable, setIsEditable] = (0, import_react75.useState)(() => editor.isEditable());
5958
- const updateToolbar = (0, import_react75.useCallback)(() => {
6002
+ const [activeEditor, setActiveEditor] = (0, import_react76.useState)(editor);
6003
+ const [blockType, setBlockType] = (0, import_react76.useState)("paragraph");
6004
+ const [selectedElementKey, setSelectedElementKey] = (0, import_react76.useState)(null);
6005
+ const [isLink, setIsLink] = (0, import_react76.useState)(false);
6006
+ const [isBold, setIsBold] = (0, import_react76.useState)(false);
6007
+ const [isItalic, setIsItalic] = (0, import_react76.useState)(false);
6008
+ const [isUnderline, setIsUnderline] = (0, import_react76.useState)(false);
6009
+ const [isStrikethrough, setIsStrikethrough] = (0, import_react76.useState)(false);
6010
+ const [isSubscript, setIsSubscript] = (0, import_react76.useState)(false);
6011
+ const [isSuperscript, setIsSuperscript] = (0, import_react76.useState)(false);
6012
+ const [isCode, setIsCode] = (0, import_react76.useState)(false);
6013
+ const [canUndo, setCanUndo] = (0, import_react76.useState)(false);
6014
+ const [canRedo, setCanRedo] = (0, import_react76.useState)(false);
6015
+ const tr = useTr();
6016
+ const [codeLanguage, setCodeLanguage] = (0, import_react76.useState)("");
6017
+ const [isEditable, setIsEditable] = (0, import_react76.useState)(() => editor.isEditable());
6018
+ const updateToolbar = (0, import_react76.useCallback)(() => {
5959
6019
  const selection = (0, import_lexical16.$getSelection)();
5960
6020
  if ((0, import_lexical16.$isRangeSelection)(selection)) {
5961
6021
  const anchorNode = selection.anchor.getNode();
@@ -6002,7 +6062,7 @@ function ToolbarPlugin({
6002
6062
  }
6003
6063
  }
6004
6064
  }, [activeEditor]);
6005
- (0, import_react75.useEffect)(() => {
6065
+ (0, import_react76.useEffect)(() => {
6006
6066
  return editor.registerCommand(
6007
6067
  import_lexical16.SELECTION_CHANGE_COMMAND,
6008
6068
  (_payload, newEditor) => {
@@ -6013,7 +6073,7 @@ function ToolbarPlugin({
6013
6073
  import_lexical16.COMMAND_PRIORITY_CRITICAL
6014
6074
  );
6015
6075
  }, [editor, updateToolbar]);
6016
- (0, import_react75.useEffect)(() => {
6076
+ (0, import_react76.useEffect)(() => {
6017
6077
  return (0, import_utils4.mergeRegister)(
6018
6078
  editor.registerEditableListener((editable) => {
6019
6079
  setIsEditable(editable);
@@ -6041,7 +6101,7 @@ function ToolbarPlugin({
6041
6101
  )
6042
6102
  );
6043
6103
  }, [activeEditor, editor, updateToolbar]);
6044
- const clearFormatting = (0, import_react75.useCallback)(() => {
6104
+ const clearFormatting = (0, import_react76.useCallback)(() => {
6045
6105
  activeEditor.update(() => {
6046
6106
  const selection = (0, import_lexical16.$getSelection)();
6047
6107
  if ((0, import_lexical16.$isRangeSelection)(selection)) {
@@ -6059,14 +6119,14 @@ function ToolbarPlugin({
6059
6119
  }
6060
6120
  });
6061
6121
  }, [activeEditor]);
6062
- const insertLink = (0, import_react75.useCallback)(() => {
6122
+ const insertLink = (0, import_react76.useCallback)(() => {
6063
6123
  if (!isLink) {
6064
6124
  editor.dispatchCommand(import_link6.TOGGLE_LINK_COMMAND, sanitizeUrl("https://"));
6065
6125
  } else {
6066
6126
  editor.dispatchCommand(import_link6.TOGGLE_LINK_COMMAND, null);
6067
6127
  }
6068
6128
  }, [editor, isLink]);
6069
- const onCodeLanguageSelect = (0, import_react75.useCallback)(
6129
+ const onCodeLanguageSelect = (0, import_react76.useCallback)(
6070
6130
  (value) => {
6071
6131
  activeEditor.update(() => {
6072
6132
  if (selectedElementKey !== null) {
@@ -6079,206 +6139,206 @@ function ToolbarPlugin({
6079
6139
  },
6080
6140
  [activeEditor, selectedElementKey]
6081
6141
  );
6082
- return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", {
6142
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", {
6083
6143
  className: "toolbar",
6084
6144
  children: [
6085
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", {
6145
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", {
6086
6146
  className: "flex",
6087
6147
  children: [
6088
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6148
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6089
6149
  disabled: !canUndo || !isEditable,
6090
6150
  onClick: () => {
6091
6151
  activeEditor.dispatchCommand(import_lexical16.UNDO_COMMAND, void 0);
6092
6152
  },
6093
- title: IS_APPLE ? "Undo (\u2318Z)" : "Undo (Ctrl+Z)",
6094
6153
  type: "button",
6095
- "aria-label": "Undo",
6096
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6154
+ title: tr(IS_APPLE ? "actionUndoTitleApple" : "actionUndoTitle"),
6155
+ "aria-label": tr("actionUndoLabel"),
6156
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6097
6157
  className: `format icon undo border w-4 h-6 bg-no-repeat bg-center bg-[length:17px_17px] ${canUndo ? "opacity-100" : "opacity-30"}
6098
6158
  `
6099
6159
  })
6100
6160
  }),
6101
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6161
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6102
6162
  disabled: !canRedo || !isEditable,
6103
6163
  onClick: () => {
6104
6164
  activeEditor.dispatchCommand(import_lexical16.REDO_COMMAND, void 0);
6105
6165
  },
6106
- title: IS_APPLE ? "Redo (\u2318Y)" : "Redo (Ctrl+Y)",
6107
6166
  type: "button",
6108
- "aria-label": "Redo",
6109
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6167
+ title: tr(IS_APPLE ? "actionRedoTitleApple" : "actionRedoTitle"),
6168
+ "aria-label": tr("actionRedoLabel"),
6169
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6110
6170
  className: `format icon redo border w-4 h-6 bg-no-repeat bg-center bg-[length:17px_17px] ${canRedo ? "opacity-100" : "opacity-30"}`
6111
6171
  })
6112
6172
  }),
6113
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Divider, {}),
6114
- blockType in blockTypeToBlockName && activeEditor === editor && /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, {
6173
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Divider, {}),
6174
+ blockType in blockTypeToBlockName && activeEditor === editor && /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_jsx_runtime89.Fragment, {
6115
6175
  children: [
6116
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(BlockFormatDropDown, {
6176
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(BlockFormatDropDown, {
6117
6177
  disabled: !isEditable,
6118
6178
  blockType,
6119
6179
  editor
6120
6180
  }),
6121
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Divider, {})
6181
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Divider, {})
6122
6182
  ]
6123
6183
  }),
6124
- blockType === "code" ? /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(import_jsx_runtime88.Fragment, {
6125
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Root, {
6184
+ blockType === "code" ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_jsx_runtime89.Fragment, {
6185
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(DropdownMenu.Root, {
6126
6186
  disabled: !isEditable,
6127
6187
  style: { zIndex: 1 },
6128
- content: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(import_jsx_runtime88.Fragment, {
6188
+ content: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_jsx_runtime89.Fragment, {
6129
6189
  children: CODE_LANGUAGE_OPTIONS.map(([value, name]) => {
6130
- return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Item, {
6190
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(DropdownMenu.Item, {
6131
6191
  className: `item ${dropDownActiveClass(value === codeLanguage)}`,
6132
6192
  onClick: () => onCodeLanguageSelect(value),
6133
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6193
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6134
6194
  className: `text min-w-[200px] block text-sm px-3 ${dropDownActiveClass(value === codeLanguage) ? "font-bold opacity-100" : "font-normal opacity-80"}`,
6135
6195
  children: name
6136
6196
  })
6137
6197
  }, value);
6138
6198
  })
6139
6199
  }),
6140
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Button, {
6141
- "aria-label": "Select language",
6142
- append: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Icon.Arrow, {}),
6143
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6200
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Button, {
6201
+ "aria-label": tr("codeSelectLanguage"),
6202
+ append: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Icon.Arrow, {}),
6203
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6144
6204
  className: "font-medium text-sm",
6145
6205
  children: (0, import_code9.getLanguageFriendlyName)(codeLanguage)
6146
6206
  })
6147
6207
  })
6148
6208
  })
6149
- }) : /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Dialog, {
6150
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", {
6209
+ }) : /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Dialog, {
6210
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", {
6151
6211
  className: "flex gap-1",
6152
6212
  children: [
6153
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6213
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6154
6214
  disabled: !isEditable,
6155
- title: IS_APPLE ? "Bold (\u2318B)" : "Bold (Ctrl+B)",
6156
6215
  className: `${isBold ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6157
6216
  type: "button",
6158
- "aria-label": `Format text as bold. Shortcut: ${IS_APPLE ? "\u2318B" : "Ctrl+B"}`,
6217
+ title: tr(IS_APPLE ? "actionFormatAsStrongTitleApple" : "actionFormatAsStrongTitle"),
6218
+ "aria-label": tr("actionFormatAsStrongLabel"),
6159
6219
  "data-testid": "toggle-format-bold",
6160
6220
  onClick: () => {
6161
6221
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "bold");
6162
6222
  },
6163
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6223
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6164
6224
  className: `format icon bold border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6165
6225
  })
6166
6226
  }),
6167
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6227
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6168
6228
  className: `${isItalic ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6169
6229
  disabled: !isEditable,
6170
6230
  onClick: () => {
6171
6231
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "italic");
6172
6232
  },
6173
- title: IS_APPLE ? "Italic (\u2318I)" : "Italic (Ctrl+I)",
6174
6233
  type: "button",
6175
- "aria-label": `Format text as italics. Shortcut: ${IS_APPLE ? "\u2318I" : "Ctrl+I"}`,
6234
+ title: tr(IS_APPLE ? "actionFormatAsEmphasizedTitleApple" : "actionFormatAsEmphasizedTitle"),
6235
+ "aria-label": tr("actionFormatAsEmphasizedLabel"),
6176
6236
  "data-testid": "toggle-format-emphasized",
6177
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6237
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6178
6238
  className: `format icon italic border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6179
6239
  })
6180
6240
  }),
6181
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6241
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6182
6242
  className: `${isUnderline ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6183
6243
  disabled: !isEditable,
6184
6244
  onClick: () => {
6185
6245
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "underline");
6186
6246
  },
6187
- title: IS_APPLE ? "Underline (\u2318U)" : "Underline (Ctrl+U)",
6188
6247
  type: "button",
6189
- "aria-label": `Format text to underlined. Shortcut: ${IS_APPLE ? "\u2318U" : "Ctrl+U"}`,
6248
+ title: tr(IS_APPLE ? "actionFormatAsUnderlinedTitleApple" : "actionFormatAsUnderlinedTitle"),
6249
+ "aria-label": tr("actionFormatAsUnderlinedLabel"),
6190
6250
  "data-testid": "toggle-format-underlined",
6191
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6251
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6192
6252
  className: `format icon underline border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6193
6253
  })
6194
6254
  }),
6195
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6255
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6196
6256
  className: `${isCode ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6197
6257
  disabled: !isEditable,
6198
6258
  onClick: () => {
6199
6259
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "code");
6200
6260
  },
6201
- title: "Insert code block",
6202
6261
  type: "button",
6203
- "aria-label": "Insert code block",
6204
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6262
+ title: tr("actionInsertCodeBlock"),
6263
+ "aria-label": tr("actionInsertCodeBlock"),
6264
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6205
6265
  className: `format icon code border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6206
6266
  })
6207
6267
  }),
6208
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6268
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6209
6269
  className: `${isLink ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6210
6270
  disabled: !isEditable,
6211
6271
  onClick: insertLink,
6212
- "aria-label": "Insert link",
6213
- title: "Insert link",
6214
6272
  type: "button",
6215
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6273
+ "aria-label": tr("actionInsertlink"),
6274
+ title: tr("actionInsertlink"),
6275
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6216
6276
  className: `format icon link border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6217
6277
  })
6218
6278
  }),
6219
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Root, {
6279
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(DropdownMenu.Root, {
6220
6280
  disabled: !isEditable,
6221
6281
  style: { zIndex: 1 },
6222
- content: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, {
6282
+ content: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_jsx_runtime89.Fragment, {
6223
6283
  children: [
6224
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
6284
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
6225
6285
  onClick: () => {
6226
6286
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "strikethrough");
6227
6287
  },
6228
- title: "Strikethrough",
6229
- "aria-label": "Format text with a strikethrough",
6288
+ title: tr("actionFormatWithStrikethroughTitle"),
6289
+ "aria-label": tr("actionFormatWithStrikethroughLabel"),
6230
6290
  children: [
6231
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6291
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6232
6292
  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"}`
6233
6293
  }),
6234
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6294
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6235
6295
  className: `px-3 text-sm font-sans ${isStrikethrough ? "font-medium" : "font-normal"}`,
6236
- children: "Strikethrough"
6296
+ children: tr("actionFormatAsStrongTitle")
6237
6297
  })
6238
6298
  ]
6239
6299
  }),
6240
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
6300
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
6241
6301
  onClick: () => {
6242
6302
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "subscript");
6243
6303
  },
6244
- title: "Subscript",
6245
- "aria-label": "Format text with a subscript",
6304
+ title: tr("actionFormatWithSubscriptTitle"),
6305
+ "aria-label": tr("actionFormatWithSubscriptLabel"),
6246
6306
  children: [
6247
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6307
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6248
6308
  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"}`
6249
6309
  }),
6250
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6310
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6251
6311
  className: `px-3 text-sm font-sans ${isSubscript ? "font-medium" : "font-normal"}`,
6252
- children: "Subscript"
6312
+ children: tr("actionFormatWithSubscriptTitle")
6253
6313
  })
6254
6314
  ]
6255
6315
  }),
6256
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
6316
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
6257
6317
  onClick: () => {
6258
6318
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "superscript");
6259
6319
  },
6260
- title: "Superscript",
6261
- "aria-label": "Format text with a superscript",
6320
+ title: tr("actionFormatWithSuperscriptTitle"),
6321
+ "aria-label": tr("actionFormatWithSuperscriptLabel"),
6262
6322
  children: [
6263
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6323
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6264
6324
  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"}`
6265
6325
  }),
6266
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6326
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6267
6327
  className: `px-3 text-sm font-sans ${isSuperscript ? "bg-purple-50-900" : "font-normal"}`,
6268
- children: "Superscript"
6328
+ children: tr("actionFormatWithSuperscriptTitle")
6269
6329
  })
6270
6330
  ]
6271
6331
  }),
6272
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
6332
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
6273
6333
  onClick: clearFormatting,
6274
6334
  className: "item",
6275
- title: "Clear text formatting",
6276
- "aria-label": "Clear all text formatting",
6335
+ title: tr("actionClearTextFormatting"),
6336
+ "aria-label": tr("actionClearTextFormatting"),
6277
6337
  children: [
6278
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6338
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6279
6339
  className: "icon w-6 h-6 clear border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6280
6340
  }),
6281
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6341
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6282
6342
  className: "px-3 text-sm text-pink-600-300 font-sans font-normal",
6283
6343
  children: "Clear Formatting"
6284
6344
  })
@@ -6286,52 +6346,52 @@ function ToolbarPlugin({
6286
6346
  })
6287
6347
  ]
6288
6348
  }),
6289
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(Button, {
6349
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(Button, {
6290
6350
  style: { backgroundColor: "transparent", padding: "0 8px" },
6291
- "aria-label": "Formatting options for additional text styles",
6351
+ "aria-label": tr("actionTextFormattingOptions"),
6292
6352
  children: [
6293
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6353
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6294
6354
  className: `icon dropdown-more border bg-no-repeat bg-center bg-[length:18px_18px] w-6 h-6`
6295
6355
  }),
6296
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Icon.Arrow, {})
6356
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Icon.Arrow, {})
6297
6357
  ]
6298
6358
  })
6299
6359
  }),
6300
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Divider, {}),
6301
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Root, {
6360
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Divider, {}),
6361
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(DropdownMenu.Root, {
6302
6362
  style: { zIndex: 1 },
6303
6363
  disabled: !isEditable,
6304
- content: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, {
6364
+ content: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_jsx_runtime89.Fragment, {
6305
6365
  children: [
6306
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Item, {
6366
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(DropdownMenu.Item, {
6307
6367
  onClick: () => {
6308
6368
  activeEditor.dispatchCommand(import_LexicalHorizontalRuleNode4.INSERT_HORIZONTAL_RULE_COMMAND, void 0);
6309
6369
  },
6310
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", {
6370
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", {
6311
6371
  className: "flex items-center font-sans font-normal",
6312
6372
  children: [
6313
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6373
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6314
6374
  className: "icon w-5 h-5 horizontal-rule border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6315
6375
  }),
6316
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6376
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6317
6377
  className: "px-3 text-sm",
6318
- children: "Horizontal rule"
6378
+ children: tr("horizontalRule")
6319
6379
  })
6320
6380
  ]
6321
6381
  })
6322
6382
  }),
6323
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Item, {
6324
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Dialog.Trigger, {
6383
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(DropdownMenu.Item, {
6384
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Dialog.Trigger, {
6325
6385
  asChild: true,
6326
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", {
6386
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", {
6327
6387
  className: "flex items-center font-sans font-normal",
6328
6388
  children: [
6329
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6389
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6330
6390
  className: "icon w-5 h-5 table border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6331
6391
  }),
6332
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6392
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6333
6393
  className: "px-3 text-sm",
6334
- children: "Table"
6394
+ children: tr("table")
6335
6395
  })
6336
6396
  ]
6337
6397
  })
@@ -6339,23 +6399,23 @@ function ToolbarPlugin({
6339
6399
  })
6340
6400
  ]
6341
6401
  }),
6342
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6343
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6402
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6403
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6344
6404
  className: "icon plus border w-full h-full bg-no-repeat bg-center bg-[length:20px_20px] "
6345
6405
  })
6346
6406
  })
6347
6407
  }),
6348
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(Dialog.Content, {
6408
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(Dialog.Content, {
6349
6409
  children: [
6350
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Dialog.Title, {
6351
- children: "Insert table"
6410
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Dialog.Title, {
6411
+ children: tr("insertTableTitle")
6352
6412
  }),
6353
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Dialog.Description, {
6354
- children: "Define your starting point of a table, you can add and remove columns and rows after creation."
6413
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Dialog.Description, {
6414
+ children: tr("insertTableDescription")
6355
6415
  }),
6356
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", {
6416
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", {
6357
6417
  className: "items-center justify-between",
6358
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(InsertTableDialog, {
6418
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(InsertTableDialog, {
6359
6419
  activeEditor
6360
6420
  })
6361
6421
  })
@@ -6366,7 +6426,7 @@ function ToolbarPlugin({
6366
6426
  })
6367
6427
  ]
6368
6428
  }),
6369
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(ActionsPlugin, {
6429
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(ActionsPlugin, {
6370
6430
  prepend: actionsMenuPrepend,
6371
6431
  append: actionsMenuAppend
6372
6432
  })
@@ -6476,21 +6536,13 @@ var theme = {
6476
6536
  };
6477
6537
  var CrystallizeRTEditorTheme_default = theme;
6478
6538
 
6479
- // src/rich-text-editor/ui/ContentEditable.tsx
6480
- var React7 = require("react");
6481
- var import_LexicalContentEditable = require("@lexical/react/LexicalContentEditable");
6482
- var import_jsx_runtime89 = require("react/jsx-runtime");
6483
- function LexicalContentEditable({ className }) {
6484
- return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_LexicalContentEditable.ContentEditable, {
6485
- className: className || "ContentEditable__root"
6486
- });
6487
- }
6488
-
6489
6539
  // src/rich-text-editor/rich-text-editor.tsx
6490
6540
  var import_jsx_runtime90 = require("react/jsx-runtime");
6491
6541
  function RichTextEditor({
6492
6542
  initialData,
6493
6543
  editable = true,
6544
+ language = "en",
6545
+ labelTranslations,
6494
6546
  ...rest
6495
6547
  }) {
6496
6548
  return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(import_LexicalComposer.LexicalComposer, {
@@ -6506,12 +6558,16 @@ function RichTextEditor({
6506
6558
  richText: initialData
6507
6559
  }) : void 0
6508
6560
  },
6509
- children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(SharedHistoryContext, {
6510
- children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", {
6511
- className: "c-rich-text-editor",
6512
- children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(RichTextEditorWithoutContext, {
6513
- ...rest,
6514
- editable
6561
+ children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(I18nProvider, {
6562
+ language,
6563
+ labelTranslations,
6564
+ children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(SharedHistoryContext, {
6565
+ children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", {
6566
+ className: "c-rich-text-editor",
6567
+ children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(RichTextEditorWithoutContext, {
6568
+ ...rest,
6569
+ editable
6570
+ })
6515
6571
  })
6516
6572
  })
6517
6573
  })
@@ -6534,18 +6590,18 @@ function RichTextEditorWithoutContext({
6534
6590
  children: placeholderText ?? ""
6535
6591
  });
6536
6592
  const [editor] = (0, import_LexicalComposerContext12.useLexicalComposerContext)();
6537
- const [floatingAnchorElem, setFloatingAnchorElem] = (0, import_react76.useState)(null);
6538
- const [isSmallWidthViewport, setIsSmallWidthViewport] = (0, import_react76.useState)(false);
6539
- const firstOnChangeTriggeredRef = (0, import_react76.useRef)(!autoFocus);
6593
+ const [floatingAnchorElem, setFloatingAnchorElem] = (0, import_react77.useState)(null);
6594
+ const [isSmallWidthViewport, setIsSmallWidthViewport] = (0, import_react77.useState)(false);
6595
+ const firstOnChangeTriggeredRef = (0, import_react77.useRef)(!autoFocus);
6540
6596
  const onRef = (_floatingAnchorElem) => {
6541
6597
  if (_floatingAnchorElem !== null) {
6542
6598
  setFloatingAnchorElem(_floatingAnchorElem);
6543
6599
  }
6544
6600
  };
6545
- (0, import_react76.useEffect)(() => {
6601
+ (0, import_react77.useEffect)(() => {
6546
6602
  editor.setEditable(editable || false);
6547
6603
  }, [editable, editor]);
6548
- (0, import_react76.useEffect)(() => {
6604
+ (0, import_react77.useEffect)(() => {
6549
6605
  const updateViewPortWidth = () => {
6550
6606
  const isNextSmallWidthViewport = window.matchMedia("(max-width: 1025px)").matches;
6551
6607
  if (isNextSmallWidthViewport !== isSmallWidthViewport) {
@@ -6594,7 +6650,9 @@ function RichTextEditorWithoutContext({
6594
6650
  children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", {
6595
6651
  className: "editor",
6596
6652
  ref: onRef,
6597
- children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(LexicalContentEditable, {})
6653
+ children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(import_LexicalContentEditable.ContentEditable, {
6654
+ className: "ContentEditable__root"
6655
+ })
6598
6656
  })
6599
6657
  }),
6600
6658
  placeholder,