@crystallize/design-system 1.10.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 (26) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/index.css +15 -17
  3. package/dist/index.d.ts +8 -1
  4. package/dist/index.js +469 -442
  5. package/dist/index.mjs +407 -385
  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/plugins/ActionsPlugin/index.tsx +5 -22
  12. package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/CopyButton/index.tsx +4 -1
  13. package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/PrettierButton/index.tsx +11 -1
  14. package/src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx +2 -1
  15. package/src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx +23 -5
  16. package/src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx +21 -10
  17. package/src/rich-text-editor/plugins/TabFocusPlugin/index.tsx +4 -12
  18. package/src/rich-text-editor/plugins/TableActionMenuPlugin/index.tsx +23 -14
  19. package/src/rich-text-editor/plugins/ToolbarPlugin/index.tsx +33 -33
  20. package/src/rich-text-editor/plugins/ToolbarPlugin/insert-table.tsx +6 -4
  21. package/src/rich-text-editor/rich-text-editor.css +6 -0
  22. package/src/rich-text-editor/rich-text-editor.stories.tsx +10 -0
  23. package/src/rich-text-editor/rich-text-editor.tsx +15 -9
  24. package/src/rich-text-editor/ui/LinkPreview.tsx +3 -1
  25. package/src/rich-text-editor/ui/ContentEditable.css +0 -13
  26. 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");
@@ -4032,7 +4081,7 @@ var BaseNodes = [
4032
4081
  // src/rich-text-editor/plugins/AutoLinkPlugin/index.tsx
4033
4082
  var import_LexicalAutoLinkPlugin = require("@lexical/react/LexicalAutoLinkPlugin");
4034
4083
  var React = require("react");
4035
- var import_jsx_runtime77 = require("react/jsx-runtime");
4084
+ var import_jsx_runtime78 = require("react/jsx-runtime");
4036
4085
  var URL_MATCHER = /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
4037
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,}))/;
4038
4087
  var MATCHERS = [
@@ -4060,13 +4109,13 @@ var MATCHERS = [
4060
4109
  }
4061
4110
  ];
4062
4111
  function LexicalAutoLinkPlugin() {
4063
- return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(import_LexicalAutoLinkPlugin.AutoLinkPlugin, {
4112
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_LexicalAutoLinkPlugin.AutoLinkPlugin, {
4064
4113
  matchers: MATCHERS
4065
4114
  });
4066
4115
  }
4067
4116
 
4068
4117
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx
4069
- var import_react65 = require("react");
4118
+ var import_react66 = require("react");
4070
4119
  var import_lexical6 = require("lexical");
4071
4120
  var import_react_dom2 = require("react-dom");
4072
4121
  var import_use_debounce2 = require("use-debounce");
@@ -4075,13 +4124,14 @@ var import_LexicalComposerContext = require("@lexical/react/LexicalComposerConte
4075
4124
 
4076
4125
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/components/CopyButton/index.tsx
4077
4126
  var React2 = require("react");
4078
- var import_react63 = require("react");
4127
+ var import_react64 = require("react");
4079
4128
  var import_lexical4 = require("lexical");
4080
4129
  var import_use_debounce = require("use-debounce");
4081
4130
  var import_code4 = require("@lexical/code");
4082
- var import_jsx_runtime78 = require("react/jsx-runtime");
4131
+ var import_jsx_runtime79 = require("react/jsx-runtime");
4083
4132
  function CopyButton({ editor, getCodeDOMNode }) {
4084
- const [isCopyCompleted, setCopyCompleted] = (0, import_react63.useState)(false);
4133
+ const [isCopyCompleted, setCopyCompleted] = (0, import_react64.useState)(false);
4134
+ const tr = useTr();
4085
4135
  const removeSuccessIcon = (0, import_use_debounce.useDebouncedCallback)(() => {
4086
4136
  setCopyCompleted(false);
4087
4137
  }, 1e3);
@@ -4107,13 +4157,13 @@ function CopyButton({ editor, getCodeDOMNode }) {
4107
4157
  console.error("Failed to copy: ", err);
4108
4158
  }
4109
4159
  }
4110
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("button", {
4160
+ return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("button", {
4111
4161
  className: "menu-item",
4112
4162
  onClick: handleClick,
4113
- "aria-label": "copy",
4114
- children: isCopyCompleted ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("i", {
4163
+ "aria-label": tr("actionCopyCode"),
4164
+ children: isCopyCompleted ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("i", {
4115
4165
  className: "format success"
4116
- }) : /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("i", {
4166
+ }) : /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("i", {
4117
4167
  className: "format copy"
4118
4168
  })
4119
4169
  });
@@ -4121,10 +4171,10 @@ function CopyButton({ editor, getCodeDOMNode }) {
4121
4171
 
4122
4172
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/components/PrettierButton/index.tsx
4123
4173
  var React3 = require("react");
4124
- var import_react64 = require("react");
4174
+ var import_react65 = require("react");
4125
4175
  var import_lexical5 = require("lexical");
4126
4176
  var import_code5 = require("@lexical/code");
4127
- var import_jsx_runtime79 = require("react/jsx-runtime");
4177
+ var import_jsx_runtime80 = require("react/jsx-runtime");
4128
4178
  var PRETTIER_PARSER_MODULES = {
4129
4179
  css: () => import("prettier/parser-postcss"),
4130
4180
  html: () => import("prettier/parser-html"),
@@ -4164,8 +4214,9 @@ function getPrettierOptions(lang) {
4164
4214
  return options;
4165
4215
  }
4166
4216
  function PrettierButton({ lang, editor, getCodeDOMNode }) {
4167
- const [syntaxError, setSyntaxError] = (0, import_react64.useState)("");
4168
- 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();
4169
4220
  async function handleClick() {
4170
4221
  const codeDOMNode = getCodeDOMNode();
4171
4222
  try {
@@ -4181,6 +4232,7 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4181
4232
  const content = codeNode.getTextContent();
4182
4233
  let parsed = "";
4183
4234
  parsed = format(content, options);
4235
+ parsed = parsed.replace(/[\r\n]+$/, "");
4184
4236
  if (parsed !== "") {
4185
4237
  const selection = codeNode.select(0);
4186
4238
  selection.insertText(parsed);
@@ -4208,22 +4260,22 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4208
4260
  setTipsVisible(false);
4209
4261
  }
4210
4262
  }
4211
- return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", {
4263
+ return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", {
4212
4264
  className: "prettier-wrapper",
4213
4265
  children: [
4214
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("button", {
4266
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("button", {
4215
4267
  className: "menu-item",
4216
4268
  onClick: handleClick,
4217
4269
  onMouseEnter: handleMouseEnter,
4218
4270
  onMouseLeave: handleMouseLeave,
4219
- "aria-label": "prettier",
4220
- children: syntaxError ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("i", {
4271
+ "aria-label": tr("actionFormatCode"),
4272
+ children: syntaxError ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("i", {
4221
4273
  className: "format prettier-error"
4222
- }) : /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("i", {
4274
+ }) : /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("i", {
4223
4275
  className: "format prettier"
4224
4276
  })
4225
4277
  }),
4226
- tipsVisible ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("pre", {
4278
+ tipsVisible ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("pre", {
4227
4279
  className: "code-error-tips",
4228
4280
  children: syntaxError
4229
4281
  }) : null
@@ -4232,19 +4284,19 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4232
4284
  }
4233
4285
 
4234
4286
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx
4235
- var import_jsx_runtime80 = require("react/jsx-runtime");
4287
+ var import_jsx_runtime81 = require("react/jsx-runtime");
4236
4288
  var CODE_PADDING = 8;
4237
4289
  function CodeActionMenuContainer({ anchorElem }) {
4238
4290
  const [editor] = (0, import_LexicalComposerContext.useLexicalComposerContext)();
4239
- const [lang, setLang] = (0, import_react65.useState)("");
4240
- const [isShown, setShown] = (0, import_react65.useState)(false);
4241
- const [shouldListenMouseMove, setShouldListenMouseMove] = (0, import_react65.useState)(false);
4242
- 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)({
4243
4295
  right: "0",
4244
4296
  top: "0"
4245
4297
  });
4246
- const codeSetRef = (0, import_react65.useRef)(/* @__PURE__ */ new Set());
4247
- 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);
4248
4300
  function getCodeDOMNode() {
4249
4301
  return codeDOMNodeRef.current;
4250
4302
  }
@@ -4278,7 +4330,7 @@ function CodeActionMenuContainer({ anchorElem }) {
4278
4330
  });
4279
4331
  }
4280
4332
  }, 50);
4281
- (0, import_react65.useEffect)(() => {
4333
+ (0, import_react66.useEffect)(() => {
4282
4334
  if (!shouldListenMouseMove) {
4283
4335
  return;
4284
4336
  }
@@ -4309,20 +4361,20 @@ function CodeActionMenuContainer({ anchorElem }) {
4309
4361
  });
4310
4362
  const normalizedLang = (0, import_code6.normalizeCodeLang)(lang);
4311
4363
  const codeFriendlyName = (0, import_code6.getLanguageFriendlyName)(lang);
4312
- return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_jsx_runtime80.Fragment, {
4313
- 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", {
4314
4366
  className: "code-action-menu-container",
4315
4367
  style: { ...position },
4316
4368
  children: [
4317
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", {
4369
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", {
4318
4370
  className: "code-highlight-language",
4319
4371
  children: codeFriendlyName
4320
4372
  }),
4321
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(CopyButton, {
4373
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(CopyButton, {
4322
4374
  editor,
4323
4375
  getCodeDOMNode
4324
4376
  }),
4325
- canBePrettier(normalizedLang) ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(PrettierButton, {
4377
+ canBePrettier(normalizedLang) ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(PrettierButton, {
4326
4378
  editor,
4327
4379
  getCodeDOMNode,
4328
4380
  lang: normalizedLang
@@ -4344,25 +4396,25 @@ function getMouseInfo(event) {
4344
4396
  function CodeActionMenuPlugin({
4345
4397
  anchorElem = document.body
4346
4398
  }) {
4347
- 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, {
4348
4400
  anchorElem
4349
4401
  }), anchorElem);
4350
4402
  }
4351
4403
 
4352
4404
  // src/rich-text-editor/plugins/CodeHighlightPlugin/index.ts
4353
- var import_react66 = require("react");
4405
+ var import_react67 = require("react");
4354
4406
  var import_code7 = require("@lexical/code");
4355
4407
  var import_LexicalComposerContext2 = require("@lexical/react/LexicalComposerContext");
4356
4408
  function CodeHighlightPlugin() {
4357
4409
  const [editor] = (0, import_LexicalComposerContext2.useLexicalComposerContext)();
4358
- (0, import_react66.useEffect)(() => {
4410
+ (0, import_react67.useEffect)(() => {
4359
4411
  return (0, import_code7.registerCodeHighlighting)(editor);
4360
4412
  }, [editor]);
4361
4413
  return null;
4362
4414
  }
4363
4415
 
4364
4416
  // src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx
4365
- var import_react68 = require("react");
4417
+ var import_react69 = require("react");
4366
4418
  var React4 = require("react");
4367
4419
  var import_lexical9 = require("lexical");
4368
4420
  var import_react_dom3 = require("react-dom");
@@ -4371,10 +4423,10 @@ var import_LexicalComposerContext4 = require("@lexical/react/LexicalComposerCont
4371
4423
  var import_utils = require("@lexical/utils");
4372
4424
 
4373
4425
  // src/rich-text-editor/ui/LinkPreview.tsx
4374
- var import_react67 = require("react");
4426
+ var import_react68 = require("react");
4375
4427
  var import_lexical7 = require("lexical");
4376
4428
  var import_LexicalComposerContext3 = require("@lexical/react/LexicalComposerContext");
4377
- var import_jsx_runtime81 = require("react/jsx-runtime");
4429
+ var import_jsx_runtime82 = require("react/jsx-runtime");
4378
4430
  var PREVIEW_CACHE = {};
4379
4431
  var URL_MATCHER2 = /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
4380
4432
  function useSuspenseRequest(url) {
@@ -4398,11 +4450,12 @@ function useSuspenseRequest(url) {
4398
4450
  function LinkPreviewContent({
4399
4451
  url
4400
4452
  }) {
4401
- const [textContent, setTextContent] = (0, import_react67.useState)("");
4453
+ const [textContent, setTextContent] = (0, import_react68.useState)("");
4402
4454
  const { preview } = useSuspenseRequest(url);
4403
4455
  const [editor] = (0, import_LexicalComposerContext3.useLexicalComposerContext)();
4456
+ const tr = useTr();
4404
4457
  const hasPreview = preview !== null && preview.google?.title;
4405
- (0, import_react67.useEffect)(() => {
4458
+ (0, import_react68.useEffect)(() => {
4406
4459
  editor.update(() => {
4407
4460
  const sel = (0, import_lexical7.$getSelection)();
4408
4461
  const nodes = sel?.getNodes();
@@ -4430,35 +4483,35 @@ function LinkPreviewContent({
4430
4483
  if (!hasPreview) {
4431
4484
  return null;
4432
4485
  }
4433
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", {
4486
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", {
4434
4487
  className: "LinkPreview__container",
4435
4488
  children: [
4436
- preview.google.image && /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", {
4489
+ preview.google.image && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4437
4490
  className: "LinkPreview__imageWrapper bg-purple-50-900",
4438
- children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("img", {
4491
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("img", {
4439
4492
  src: preview.google.image,
4440
4493
  alt: preview.google.title,
4441
4494
  className: "LinkPreview__image"
4442
4495
  })
4443
4496
  }),
4444
- preview.google.title && /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", {
4497
+ preview.google.title && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4445
4498
  className: "LinkPreview__title",
4446
4499
  children: preview.google.title
4447
4500
  }),
4448
- preview.google.description && /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", {
4501
+ preview.google.description && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4449
4502
  className: "LinkPreview__description",
4450
4503
  children: preview.google.description
4451
4504
  }),
4452
- 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, {
4453
4506
  className: "mb-4 ml-5",
4454
4507
  onClick: useTitleForText,
4455
- children: "Replace link text with its title"
4508
+ children: tr("linkPreviewReplaceTextWithTitle")
4456
4509
  }) : null
4457
4510
  ]
4458
4511
  });
4459
4512
  }
4460
4513
  function Glimmer(props) {
4461
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", {
4514
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4462
4515
  className: "LinkPreview__glimmer",
4463
4516
  ...props,
4464
4517
  style: {
@@ -4470,24 +4523,24 @@ function Glimmer(props) {
4470
4523
  function LinkPreview({
4471
4524
  url
4472
4525
  }) {
4473
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react67.Suspense, {
4474
- 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, {
4475
4528
  children: [
4476
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(Glimmer, {
4529
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Glimmer, {
4477
4530
  style: { height: "80px" },
4478
4531
  index: 0
4479
4532
  }),
4480
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(Glimmer, {
4533
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Glimmer, {
4481
4534
  style: { width: "60%" },
4482
4535
  index: 1
4483
4536
  }),
4484
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(Glimmer, {
4537
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Glimmer, {
4485
4538
  style: { width: "80%" },
4486
4539
  index: 2
4487
4540
  })
4488
4541
  ]
4489
4542
  }),
4490
- children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(LinkPreviewContent, {
4543
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(LinkPreviewContent, {
4491
4544
  url
4492
4545
  })
4493
4546
  });
@@ -4556,21 +4609,22 @@ function validateUrl(url) {
4556
4609
  }
4557
4610
 
4558
4611
  // src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx
4559
- var import_jsx_runtime82 = require("react/jsx-runtime");
4612
+ var import_jsx_runtime83 = require("react/jsx-runtime");
4560
4613
  function FloatingLinkEditor({
4561
4614
  editor,
4562
4615
  isLink,
4563
4616
  setIsLink,
4564
4617
  anchorElem
4565
4618
  }) {
4566
- const editorRef = (0, import_react68.useRef)(null);
4567
- const inputRef = (0, import_react68.useRef)(null);
4568
- const [linkUrl, setLinkUrl] = (0, import_react68.useState)("");
4569
- const [rel, setRel] = (0, import_react68.useState)(null);
4570
- const [target, setTarget] = (0, import_react68.useState)(null);
4571
- const [isEditMode, setEditMode] = (0, import_react68.useState)(false);
4572
- const [lastSelection, setLastSelection] = (0, import_react68.useState)(null);
4573
- 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)(() => {
4574
4628
  const selection = (0, import_lexical9.$getSelection)();
4575
4629
  if ((0, import_lexical9.$isRangeSelection)(selection)) {
4576
4630
  const node = getSelectedNode(selection);
@@ -4620,7 +4674,7 @@ function FloatingLinkEditor({
4620
4674
  }
4621
4675
  return true;
4622
4676
  }, [anchorElem, editor]);
4623
- (0, import_react68.useEffect)(() => {
4677
+ (0, import_react69.useEffect)(() => {
4624
4678
  const scrollerElem = anchorElem.parentElement;
4625
4679
  const update = () => {
4626
4680
  editor.getEditorState().read(() => {
@@ -4638,7 +4692,7 @@ function FloatingLinkEditor({
4638
4692
  }
4639
4693
  };
4640
4694
  }, [anchorElem.parentElement, editor, updateLinkEditor]);
4641
- (0, import_react68.useEffect)(() => {
4695
+ (0, import_react69.useEffect)(() => {
4642
4696
  return (0, import_utils.mergeRegister)(
4643
4697
  editor.registerUpdateListener(({ editorState }) => {
4644
4698
  editorState.read(() => {
@@ -4666,51 +4720,51 @@ function FloatingLinkEditor({
4666
4720
  )
4667
4721
  );
4668
4722
  }, [editor, updateLinkEditor, setIsLink, isLink]);
4669
- (0, import_react68.useEffect)(() => {
4723
+ (0, import_react69.useEffect)(() => {
4670
4724
  editor.getEditorState().read(() => {
4671
4725
  updateLinkEditor();
4672
4726
  });
4673
4727
  }, [editor, updateLinkEditor]);
4674
- (0, import_react68.useEffect)(() => {
4728
+ (0, import_react69.useEffect)(() => {
4675
4729
  if (isEditMode && inputRef.current) {
4676
4730
  inputRef.current.focus();
4677
4731
  }
4678
4732
  }, [isEditMode]);
4679
- return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4733
+ return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4680
4734
  ref: editorRef,
4681
4735
  className: "link-editor",
4682
- children: isEditMode ? /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", {
4736
+ children: isEditMode ? /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", {
4683
4737
  children: [
4684
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4738
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4685
4739
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4686
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(InputWithLabel, {
4687
- label: "Link",
4740
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(InputWithLabel, {
4741
+ label: tr("linkEditorLink"),
4688
4742
  type: "text",
4689
4743
  value: linkUrl,
4690
4744
  onChange: (e) => setLinkUrl(e.target.value)
4691
4745
  })
4692
4746
  }),
4693
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4747
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4694
4748
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4695
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(InputWithLabel, {
4696
- label: "Rel",
4749
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(InputWithLabel, {
4750
+ label: tr("linkEditorRel"),
4697
4751
  type: "text",
4698
4752
  value: rel ?? "",
4699
4753
  onChange: (e) => setRel(e.target.value)
4700
4754
  })
4701
4755
  }),
4702
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4756
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4703
4757
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4704
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(InputWithLabel, {
4705
- label: "Target",
4758
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(InputWithLabel, {
4759
+ label: tr("linkEditorTarget"),
4706
4760
  type: "text",
4707
4761
  value: target ?? "",
4708
4762
  onChange: (e) => setTarget(e.target.value)
4709
4763
  })
4710
4764
  }),
4711
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4765
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4712
4766
  className: "flex px-6 py-2 justify-end",
4713
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Button, {
4767
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(Button, {
4714
4768
  onClick: () => {
4715
4769
  if (lastSelection !== null) {
4716
4770
  if (linkUrl !== "") {
@@ -4723,32 +4777,32 @@ function FloatingLinkEditor({
4723
4777
  setEditMode(false);
4724
4778
  }
4725
4779
  },
4726
- children: "Done"
4780
+ children: tr("linkEditorCommit")
4727
4781
  })
4728
4782
  })
4729
4783
  ]
4730
- }) : /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, {
4784
+ }) : /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(import_jsx_runtime83.Fragment, {
4731
4785
  children: [
4732
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", {
4786
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", {
4733
4787
  className: "link-input !flex flex-nowrap justify-between items-center max-w-full ",
4734
4788
  children: [
4735
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", {
4736
- className: " grid",
4789
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", {
4790
+ className: "grid",
4737
4791
  children: [
4738
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("a", {
4792
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("a", {
4739
4793
  href: linkUrl,
4740
4794
  target: "_blank",
4741
4795
  rel: "noopener noreferrer",
4742
4796
  children: linkUrl
4743
4797
  }),
4744
- rel || target ? /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", {
4798
+ rel || target ? /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", {
4745
4799
  className: "flex mt-1 gap-1",
4746
4800
  children: [
4747
- rel && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4801
+ rel && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4748
4802
  className: "text-[10px] text-gray-600-300 px-1 bg-purple-50-900 rounded-md py-0.5",
4749
4803
  children: rel
4750
4804
  }),
4751
- target && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4805
+ target && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4752
4806
  className: "text-[10px] text-gray-600-300 px-1 bg-purple-50-900 rounded-md py-0.5",
4753
4807
  children: target
4754
4808
  })
@@ -4756,19 +4810,20 @@ function FloatingLinkEditor({
4756
4810
  }) : null
4757
4811
  ]
4758
4812
  }),
4759
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4760
- 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, {
4761
4815
  size: "sm",
4762
4816
  tabIndex: 0,
4763
4817
  onMouseDown: (event) => event.preventDefault(),
4764
4818
  onClick: () => setEditMode(true),
4765
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Icon.Edit, {})
4819
+ "aria-label": tr("linkEditorEdit"),
4820
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(Icon.Edit, {})
4766
4821
  })
4767
4822
  })
4768
4823
  ]
4769
4824
  }),
4770
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", {
4771
- 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, {
4772
4827
  url: linkUrl
4773
4828
  })
4774
4829
  })
@@ -4777,9 +4832,9 @@ function FloatingLinkEditor({
4777
4832
  });
4778
4833
  }
4779
4834
  function useFloatingLinkEditorToolbar(editor, anchorElem) {
4780
- const [activeEditor, setActiveEditor] = (0, import_react68.useState)(editor);
4781
- const [isLink, setIsLink] = (0, import_react68.useState)(false);
4782
- 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)(() => {
4783
4838
  const selection = (0, import_lexical9.$getSelection)();
4784
4839
  if ((0, import_lexical9.$isRangeSelection)(selection)) {
4785
4840
  const node = getSelectedNode(selection);
@@ -4792,7 +4847,7 @@ function useFloatingLinkEditorToolbar(editor, anchorElem) {
4792
4847
  }
4793
4848
  }
4794
4849
  }, []);
4795
- (0, import_react68.useEffect)(() => {
4850
+ (0, import_react69.useEffect)(() => {
4796
4851
  return editor.registerCommand(
4797
4852
  import_lexical9.SELECTION_CHANGE_COMMAND,
4798
4853
  (_payload, newEditor) => {
@@ -4804,7 +4859,7 @@ function useFloatingLinkEditorToolbar(editor, anchorElem) {
4804
4859
  );
4805
4860
  }, [editor, updateToolbar]);
4806
4861
  return isLink ? (0, import_react_dom3.createPortal)(
4807
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(FloatingLinkEditor, {
4862
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(FloatingLinkEditor, {
4808
4863
  editor: activeEditor,
4809
4864
  isLink,
4810
4865
  anchorElem,
@@ -4821,7 +4876,7 @@ function FloatingLinkEditorPlugin({
4821
4876
  }
4822
4877
 
4823
4878
  // src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx
4824
- var import_react69 = require("react");
4879
+ var import_react70 = require("react");
4825
4880
  var React5 = require("react");
4826
4881
  var import_lexical10 = require("lexical");
4827
4882
  var import_react_dom4 = require("react-dom");
@@ -4830,6 +4885,9 @@ var import_link5 = require("@lexical/link");
4830
4885
  var import_LexicalComposerContext5 = require("@lexical/react/LexicalComposerContext");
4831
4886
  var import_utils2 = require("@lexical/utils");
4832
4887
 
4888
+ // src/rich-text-editor/utils/environment.ts
4889
+ var IS_APPLE = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
4890
+
4833
4891
  // src/rich-text-editor/utils/getDOMRangeRect.ts
4834
4892
  function getDOMRangeRect(nativeSelection, rootElement) {
4835
4893
  const domRange = nativeSelection.getRangeAt(0);
@@ -4860,7 +4918,7 @@ function getDOMRangeRect(nativeSelection, rootElement) {
4860
4918
  }
4861
4919
 
4862
4920
  // src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx
4863
- var import_jsx_runtime83 = require("react/jsx-runtime");
4921
+ var import_jsx_runtime84 = require("react/jsx-runtime");
4864
4922
  function TextFormatFloatingToolbar({
4865
4923
  editor,
4866
4924
  anchorElem,
@@ -4873,15 +4931,16 @@ function TextFormatFloatingToolbar({
4873
4931
  isSubscript,
4874
4932
  isSuperscript
4875
4933
  }) {
4876
- const popupCharStylesEditorRef = (0, import_react69.useRef)(null);
4877
- 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)(() => {
4878
4937
  if (!isLink) {
4879
4938
  editor.dispatchCommand(import_link5.TOGGLE_LINK_COMMAND, "https://");
4880
4939
  } else {
4881
4940
  editor.dispatchCommand(import_link5.TOGGLE_LINK_COMMAND, null);
4882
4941
  }
4883
4942
  }, [editor, isLink]);
4884
- const updateTextFormatFloatingToolbar = (0, import_react69.useCallback)(() => {
4943
+ const updateTextFormatFloatingToolbar = (0, import_react70.useCallback)(() => {
4885
4944
  const selection = (0, import_lexical10.$getSelection)();
4886
4945
  const popupCharStylesEditorElem = popupCharStylesEditorRef.current;
4887
4946
  const nativeSelection = window.getSelection();
@@ -4894,7 +4953,7 @@ function TextFormatFloatingToolbar({
4894
4953
  setFloatingElemPosition(rangeRect, popupCharStylesEditorElem, anchorElem);
4895
4954
  }
4896
4955
  }, [editor, anchorElem]);
4897
- (0, import_react69.useEffect)(() => {
4956
+ (0, import_react70.useEffect)(() => {
4898
4957
  const scrollerElem = anchorElem.parentElement;
4899
4958
  const update = () => {
4900
4959
  editor.getEditorState().read(() => {
@@ -4912,7 +4971,7 @@ function TextFormatFloatingToolbar({
4912
4971
  }
4913
4972
  };
4914
4973
  }, [editor, updateTextFormatFloatingToolbar, anchorElem]);
4915
- (0, import_react69.useEffect)(() => {
4974
+ (0, import_react70.useEffect)(() => {
4916
4975
  editor.getEditorState().read(() => {
4917
4976
  updateTextFormatFloatingToolbar();
4918
4977
  });
@@ -4932,88 +4991,92 @@ function TextFormatFloatingToolbar({
4932
4991
  )
4933
4992
  );
4934
4993
  }, [editor, updateTextFormatFloatingToolbar]);
4935
- return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", {
4994
+ return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", {
4936
4995
  ref: popupCharStylesEditorRef,
4937
4996
  className: "c-floating-text-format-popup gap-0.5",
4938
- 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, {
4939
4998
  children: [
4940
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
4999
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4941
5000
  onClick: () => {
4942
5001
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "bold");
4943
5002
  },
4944
5003
  style: { padding: 0, overflow: "hidden" },
4945
- "aria-label": "Format text as bold",
4946
- 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", {
4947
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"}`
4948
5008
  })
4949
5009
  }),
4950
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5010
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4951
5011
  style: { padding: 0, overflow: "hidden" },
4952
5012
  onClick: () => {
4953
5013
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "italic");
4954
5014
  },
4955
- "aria-label": "Format text as italics",
4956
- 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", {
4957
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"}`
4958
5019
  })
4959
5020
  }),
4960
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5021
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4961
5022
  style: { padding: 0, overflow: "hidden" },
4962
5023
  onClick: () => {
4963
5024
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "underline");
4964
5025
  },
4965
- "aria-label": "Format text to underlined",
4966
- 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", {
4967
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"}`
4968
5030
  })
4969
5031
  }),
4970
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5032
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4971
5033
  style: { padding: 0, overflow: "hidden" },
4972
5034
  onClick: () => {
4973
5035
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "strikethrough");
4974
5036
  },
4975
- "aria-label": "Format text with a strikethrough",
4976
- 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", {
4977
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"}`
4978
5041
  })
4979
5042
  }),
4980
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5043
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4981
5044
  style: { padding: 0, overflow: "hidden" },
4982
5045
  onClick: () => {
4983
5046
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "subscript");
4984
5047
  },
4985
- title: "Subscript",
4986
- "aria-label": "Format Subscript",
4987
- 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", {
4988
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"}`
4989
5052
  })
4990
5053
  }),
4991
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5054
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
4992
5055
  style: { padding: 0, overflow: "hidden" },
4993
5056
  onClick: () => {
4994
5057
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "superscript");
4995
5058
  },
4996
- title: "Superscript",
4997
- "aria-label": "Format Superscript",
4998
- 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", {
4999
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"}`
5000
5063
  })
5001
5064
  }),
5002
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5065
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
5003
5066
  style: { padding: 0, overflow: "hidden" },
5004
5067
  onClick: () => {
5005
5068
  editor.dispatchCommand(import_lexical10.FORMAT_TEXT_COMMAND, "code");
5006
5069
  },
5007
- "aria-label": "Insert code block",
5008
- children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("i", {
5070
+ "aria-label": tr("actionInsertCodeBlock"),
5071
+ children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("i", {
5009
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"}`
5010
5073
  })
5011
5074
  }),
5012
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconButton, {
5075
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconButton, {
5013
5076
  style: { padding: 0, overflow: "hidden" },
5014
5077
  onClick: insertLink,
5015
- "aria-label": "Insert link",
5016
- children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("i", {
5078
+ "aria-label": tr("actionInsertlink"),
5079
+ children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("i", {
5017
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"}`
5018
5081
  })
5019
5082
  })
@@ -5022,16 +5085,16 @@ function TextFormatFloatingToolbar({
5022
5085
  });
5023
5086
  }
5024
5087
  function useFloatingTextFormatToolbar(editor, anchorElem) {
5025
- const [isText, setIsText] = (0, import_react69.useState)(false);
5026
- const [isLink, setIsLink] = (0, import_react69.useState)(false);
5027
- const [isBold, setIsBold] = (0, import_react69.useState)(false);
5028
- const [isItalic, setIsItalic] = (0, import_react69.useState)(false);
5029
- const [isUnderline, setIsUnderline] = (0, import_react69.useState)(false);
5030
- const [isStrikethrough, setIsStrikethrough] = (0, import_react69.useState)(false);
5031
- const [isSubscript, setIsSubscript] = (0, import_react69.useState)(false);
5032
- const [isSuperscript, setIsSuperscript] = (0, import_react69.useState)(false);
5033
- const [isCode, setIsCode] = (0, import_react69.useState)(false);
5034
- 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)(() => {
5035
5098
  editor.getEditorState().read(() => {
5036
5099
  if (editor.isComposing()) {
5037
5100
  return;
@@ -5067,13 +5130,13 @@ function useFloatingTextFormatToolbar(editor, anchorElem) {
5067
5130
  }
5068
5131
  });
5069
5132
  }, [editor]);
5070
- (0, import_react69.useEffect)(() => {
5133
+ (0, import_react70.useEffect)(() => {
5071
5134
  document.addEventListener("selectionchange", updatePopup);
5072
5135
  return () => {
5073
5136
  document.removeEventListener("selectionchange", updatePopup);
5074
5137
  };
5075
5138
  }, [updatePopup]);
5076
- (0, import_react69.useEffect)(() => {
5139
+ (0, import_react70.useEffect)(() => {
5077
5140
  return (0, import_utils2.mergeRegister)(
5078
5141
  editor.registerUpdateListener(() => {
5079
5142
  updatePopup();
@@ -5089,7 +5152,7 @@ function useFloatingTextFormatToolbar(editor, anchorElem) {
5089
5152
  return null;
5090
5153
  }
5091
5154
  return (0, import_react_dom4.createPortal)(
5092
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(TextFormatFloatingToolbar, {
5155
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(TextFormatFloatingToolbar, {
5093
5156
  editor,
5094
5157
  anchorElem,
5095
5158
  isLink,
@@ -5114,9 +5177,9 @@ function FloatingTextFormatToolbarPlugin({
5114
5177
  // src/rich-text-editor/plugins/LinkPlugin/index.tsx
5115
5178
  var import_LexicalLinkPlugin = require("@lexical/react/LexicalLinkPlugin");
5116
5179
  var React6 = require("react");
5117
- var import_jsx_runtime84 = require("react/jsx-runtime");
5180
+ var import_jsx_runtime85 = require("react/jsx-runtime");
5118
5181
  function LinkPlugin() {
5119
- return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_LexicalLinkPlugin.LinkPlugin, {
5182
+ return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(import_LexicalLinkPlugin.LinkPlugin, {
5120
5183
  validateUrl
5121
5184
  });
5122
5185
  }
@@ -5125,7 +5188,7 @@ function LinkPlugin() {
5125
5188
  var import_list4 = require("@lexical/list");
5126
5189
  var import_LexicalComposerContext6 = require("@lexical/react/LexicalComposerContext");
5127
5190
  var import_lexical11 = require("lexical");
5128
- var import_react70 = require("react");
5191
+ var import_react71 = require("react");
5129
5192
  function getElementNodesInSelection(selection) {
5130
5193
  const nodesInSelection = selection.getNodes();
5131
5194
  if (nodesInSelection.length === 0) {
@@ -5162,7 +5225,7 @@ function isIndentPermitted(maxDepth) {
5162
5225
  }
5163
5226
  function ListMaxIndentLevelPlugin({ maxDepth }) {
5164
5227
  const [editor] = (0, import_LexicalComposerContext6.useLexicalComposerContext)();
5165
- (0, import_react70.useEffect)(() => {
5228
+ (0, import_react71.useEffect)(() => {
5166
5229
  return editor.registerCommand(
5167
5230
  import_lexical11.INDENT_CONTENT_COMMAND,
5168
5231
  () => !isIndentPermitted(maxDepth ?? 7),
@@ -5173,7 +5236,7 @@ function ListMaxIndentLevelPlugin({ maxDepth }) {
5173
5236
  }
5174
5237
 
5175
5238
  // src/rich-text-editor/plugins/MaxLengthPlugin/index.tsx
5176
- var import_react71 = require("react");
5239
+ var import_react72 = require("react");
5177
5240
  var import_lexical12 = require("lexical");
5178
5241
  var import_LexicalComposerContext7 = require("@lexical/react/LexicalComposerContext");
5179
5242
  var import_selection2 = require("@lexical/selection");
@@ -5215,7 +5278,7 @@ ${content}
5215
5278
  // src/rich-text-editor/plugins/MaxLengthPlugin/index.tsx
5216
5279
  function MaxLengthPlugin({ maxLength }) {
5217
5280
  const [editor] = (0, import_LexicalComposerContext7.useLexicalComposerContext)();
5218
- (0, import_react71.useEffect)(() => {
5281
+ (0, import_react72.useEffect)(() => {
5219
5282
  let lastRestoredEditorState = null;
5220
5283
  return editor.registerUpdateListener(({ editorState, prevEditorState }) => {
5221
5284
  editor.update(() => {
@@ -5245,9 +5308,9 @@ function MaxLengthPlugin({ maxLength }) {
5245
5308
  }
5246
5309
 
5247
5310
  // src/rich-text-editor/plugins/TabFocusPlugin/index.tsx
5248
- var import_LexicalComposerContext8 = require("@lexical/react/LexicalComposerContext");
5311
+ var import_react73 = require("react");
5249
5312
  var import_lexical13 = require("lexical");
5250
- var import_react72 = require("react");
5313
+ var import_LexicalComposerContext8 = require("@lexical/react/LexicalComposerContext");
5251
5314
  var COMMAND_PRIORITY_LOW3 = 1;
5252
5315
  var TAB_TO_FOCUS_INTERVAL = 100;
5253
5316
  var lastTabKeyDownTimestamp = 0;
@@ -5265,7 +5328,7 @@ function registerKeyTimeStampTracker() {
5265
5328
  }
5266
5329
  function TabFocusPlugin() {
5267
5330
  const [editor] = (0, import_LexicalComposerContext8.useLexicalComposerContext)();
5268
- (0, import_react72.useEffect)(() => {
5331
+ (0, import_react73.useEffect)(() => {
5269
5332
  if (!hasRegisteredKeyDownListener) {
5270
5333
  registerKeyTimeStampTracker();
5271
5334
  hasRegisteredKeyDownListener = true;
@@ -5288,21 +5351,22 @@ function TabFocusPlugin() {
5288
5351
  }
5289
5352
 
5290
5353
  // src/rich-text-editor/plugins/TableActionMenuPlugin/index.tsx
5291
- var import_react73 = require("react");
5354
+ var import_react74 = require("react");
5292
5355
  var import_lexical14 = require("lexical");
5293
5356
  var import_react_dom5 = require("react-dom");
5294
5357
  var import_LexicalComposerContext9 = require("@lexical/react/LexicalComposerContext");
5295
5358
  var import_useLexicalEditable = __toESM(require("@lexical/react/useLexicalEditable"));
5296
5359
  var import_table4 = require("@lexical/table");
5297
- var import_jsx_runtime85 = require("react/jsx-runtime");
5360
+ var import_jsx_runtime86 = require("react/jsx-runtime");
5298
5361
  function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5299
5362
  const [editor] = (0, import_LexicalComposerContext9.useLexicalComposerContext)();
5300
- const [tableCellNode, updateTableCellNode] = (0, import_react73.useState)(_tableCellNode);
5301
- const [selectionCounts, updateSelectionCounts] = (0, import_react73.useState)({
5363
+ const [tableCellNode, updateTableCellNode] = (0, import_react74.useState)(_tableCellNode);
5364
+ const [selectionCounts, updateSelectionCounts] = (0, import_react74.useState)({
5302
5365
  columns: 1,
5303
5366
  rows: 1
5304
5367
  });
5305
- (0, import_react73.useEffect)(() => {
5368
+ const tr = useTr();
5369
+ (0, import_react74.useEffect)(() => {
5306
5370
  return editor.registerMutationListener(import_table4.TableCellNode, (nodeMutations) => {
5307
5371
  const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === "updated";
5308
5372
  if (nodeUpdated) {
@@ -5312,7 +5376,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5312
5376
  }
5313
5377
  });
5314
5378
  }, [editor, tableCellNode]);
5315
- (0, import_react73.useEffect)(() => {
5379
+ (0, import_react74.useEffect)(() => {
5316
5380
  editor.getEditorState().read(() => {
5317
5381
  const selection = (0, import_lexical14.$getSelection)();
5318
5382
  if ((0, import_lexical14.DEPRECATED_$isGridSelection)(selection)) {
@@ -5324,7 +5388,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5324
5388
  }
5325
5389
  });
5326
5390
  }, [editor]);
5327
- const clearTableSelection = (0, import_react73.useCallback)(() => {
5391
+ const clearTableSelection = (0, import_react74.useCallback)(() => {
5328
5392
  editor.update(() => {
5329
5393
  if (tableCellNode.isAttached()) {
5330
5394
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
@@ -5343,7 +5407,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5343
5407
  rootNode.selectStart();
5344
5408
  });
5345
5409
  }, [editor, tableCellNode]);
5346
- const insertTableRowAtSelection = (0, import_react73.useCallback)(
5410
+ const insertTableRowAtSelection = (0, import_react74.useCallback)(
5347
5411
  (shouldInsertAfter) => {
5348
5412
  editor.update(() => {
5349
5413
  const selection = (0, import_lexical14.$getSelection)();
@@ -5362,7 +5426,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5362
5426
  },
5363
5427
  [editor, tableCellNode, selectionCounts.rows, clearTableSelection]
5364
5428
  );
5365
- const insertTableColumnAtSelection = (0, import_react73.useCallback)(
5429
+ const insertTableColumnAtSelection = (0, import_react74.useCallback)(
5366
5430
  (shouldInsertAfter) => {
5367
5431
  editor.update(() => {
5368
5432
  const selection = (0, import_lexical14.$getSelection)();
@@ -5381,7 +5445,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5381
5445
  },
5382
5446
  [editor, tableCellNode, selectionCounts.columns, clearTableSelection]
5383
5447
  );
5384
- const deleteTableRowAtSelection = (0, import_react73.useCallback)(() => {
5448
+ const deleteTableRowAtSelection = (0, import_react74.useCallback)(() => {
5385
5449
  editor.update(() => {
5386
5450
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
5387
5451
  const tableRowIndex = (0, import_table4.$getTableRowIndexFromTableCellNode)(tableCellNode);
@@ -5389,14 +5453,14 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5389
5453
  clearTableSelection();
5390
5454
  });
5391
5455
  }, [editor, tableCellNode, clearTableSelection]);
5392
- const deleteTableAtSelection = (0, import_react73.useCallback)(() => {
5456
+ const deleteTableAtSelection = (0, import_react74.useCallback)(() => {
5393
5457
  editor.update(() => {
5394
5458
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
5395
5459
  tableNode.remove();
5396
5460
  clearTableSelection();
5397
5461
  });
5398
5462
  }, [editor, tableCellNode, clearTableSelection]);
5399
- const deleteTableColumnAtSelection = (0, import_react73.useCallback)(() => {
5463
+ const deleteTableColumnAtSelection = (0, import_react74.useCallback)(() => {
5400
5464
  editor.update(() => {
5401
5465
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
5402
5466
  const tableColumnIndex = (0, import_table4.$getTableColumnIndexFromTableCellNode)(tableCellNode);
@@ -5404,7 +5468,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5404
5468
  clearTableSelection();
5405
5469
  });
5406
5470
  }, [editor, tableCellNode, clearTableSelection]);
5407
- const toggleTableRowIsHeader = (0, import_react73.useCallback)(() => {
5471
+ const toggleTableRowIsHeader = (0, import_react74.useCallback)(() => {
5408
5472
  editor.update(() => {
5409
5473
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
5410
5474
  const tableRowIndex = (0, import_table4.$getTableRowIndexFromTableCellNode)(tableCellNode);
@@ -5425,7 +5489,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5425
5489
  clearTableSelection();
5426
5490
  });
5427
5491
  }, [editor, tableCellNode, clearTableSelection]);
5428
- const toggleTableColumnIsHeader = (0, import_react73.useCallback)(() => {
5492
+ const toggleTableColumnIsHeader = (0, import_react74.useCallback)(() => {
5429
5493
  editor.update(() => {
5430
5494
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
5431
5495
  const tableColumnIndex = (0, import_table4.$getTableColumnIndexFromTableCellNode)(tableCellNode);
@@ -5448,78 +5512,60 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5448
5512
  clearTableSelection();
5449
5513
  });
5450
5514
  }, [editor, tableCellNode, clearTableSelection]);
5451
- return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, {
5515
+ return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(import_jsx_runtime86.Fragment, {
5452
5516
  children: [
5453
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5517
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5454
5518
  onSelect: () => insertTableRowAtSelection(false),
5455
- children: [
5456
- "Insert ",
5457
- selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
5458
- " above"
5459
- ]
5519
+ children: tr("actionTableInsertRowsAbove", selectionCounts.rows)
5460
5520
  }),
5461
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5521
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5462
5522
  onSelect: () => insertTableRowAtSelection(true),
5463
- children: [
5464
- "Insert ",
5465
- selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
5466
- " below"
5467
- ]
5523
+ children: tr("actionTableInsertRowsBelow", selectionCounts.rows)
5468
5524
  }),
5469
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5525
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5470
5526
  onSelect: () => insertTableColumnAtSelection(false),
5471
- children: [
5472
- "Insert ",
5473
- selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
5474
- " left"
5475
- ]
5527
+ children: tr("actionTableInsertColumnsBefore", selectionCounts.columns)
5476
5528
  }),
5477
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5529
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5478
5530
  onSelect: () => insertTableColumnAtSelection(true),
5479
- children: [
5480
- "Insert ",
5481
- selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
5482
- " right"
5483
- ]
5531
+ children: tr("actionTableInsertColumnsAfter", selectionCounts.columns)
5484
5532
  }),
5485
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5533
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5486
5534
  onSelect: () => toggleTableRowIsHeader(),
5487
- children: [
5488
- (tableCellNode.__headerState & import_table4.TableCellHeaderStates.ROW) === import_table4.TableCellHeaderStates.ROW ? "Remove" : "Add",
5489
- " row header"
5490
- ]
5535
+ children: tr(
5536
+ (tableCellNode.__headerState & import_table4.TableCellHeaderStates.ROW) === import_table4.TableCellHeaderStates.ROW ? "actionTableRemoveRowHeader" : "actionTableAddRowHeader"
5537
+ )
5491
5538
  }),
5492
- /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(DropdownMenu.Item, {
5539
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5493
5540
  onSelect: () => toggleTableColumnIsHeader(),
5494
- children: [
5495
- (tableCellNode.__headerState & import_table4.TableCellHeaderStates.COLUMN) === import_table4.TableCellHeaderStates.COLUMN ? "Remove" : "Add",
5496
- " ",
5497
- "column header"
5498
- ]
5541
+ children: tr(
5542
+ (tableCellNode.__headerState & import_table4.TableCellHeaderStates.COLUMN) === import_table4.TableCellHeaderStates.COLUMN ? "actionTableRemoveColumnHeader" : "actionTableAddColumnHeader"
5543
+ )
5499
5544
  }),
5500
- /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(DropdownMenu.Separator, {}),
5501
- 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, {
5502
5547
  onSelect: () => deleteTableColumnAtSelection(),
5503
- children: "Delete column"
5548
+ children: tr("actionTableDeleteColumn")
5504
5549
  }),
5505
- tableStats.rows > 1 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(DropdownMenu.Item, {
5550
+ tableStats.rows > 1 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5506
5551
  onSelect: () => deleteTableRowAtSelection(),
5507
- children: "Delete row"
5552
+ children: tr("actionTableDeleteRow")
5508
5553
  }),
5509
- /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(DropdownMenu.Item, {
5554
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Item, {
5510
5555
  onSelect: () => deleteTableAtSelection(),
5511
- children: "Delete table"
5556
+ children: tr("actionTableDeleteTable")
5512
5557
  })
5513
5558
  ]
5514
5559
  });
5515
5560
  }
5516
5561
  function TableCellActionMenuContainer({ anchorElem }) {
5517
5562
  const [editor] = (0, import_LexicalComposerContext9.useLexicalComposerContext)();
5518
- const menuButtonRef = (0, import_react73.useRef)(null);
5519
- const [isMenuOpen, setIsMenuOpen] = (0, import_react73.useState)(false);
5520
- const [tableCellNode, setTableMenuCellNode] = (0, import_react73.useState)(null);
5521
- const [tableStats, setTablestats] = (0, import_react73.useState)({ rows: 1, columns: 1 });
5522
- 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)(() => {
5523
5569
  if (isMenuOpen) {
5524
5570
  return;
5525
5571
  }
@@ -5562,14 +5608,14 @@ function TableCellActionMenuContainer({ anchorElem }) {
5562
5608
  setTableMenuCellNode(null);
5563
5609
  }
5564
5610
  }, [editor, isMenuOpen]);
5565
- (0, import_react73.useEffect)(() => {
5611
+ (0, import_react74.useEffect)(() => {
5566
5612
  return editor.registerUpdateListener(() => {
5567
5613
  editor.getEditorState().read(() => {
5568
5614
  moveMenu();
5569
5615
  });
5570
5616
  });
5571
5617
  });
5572
- (0, import_react73.useEffect)(() => {
5618
+ (0, import_react74.useEffect)(() => {
5573
5619
  const menuButtonDOM = menuButtonRef.current;
5574
5620
  if (menuButtonDOM != null && tableCellNode != null) {
5575
5621
  const tableCellNodeDOM = editor.getElementByKey(tableCellNode.getKey());
@@ -5587,19 +5633,20 @@ function TableCellActionMenuContainer({ anchorElem }) {
5587
5633
  }
5588
5634
  }
5589
5635
  }, [menuButtonRef, tableCellNode, editor, anchorElem]);
5590
- return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", {
5636
+ return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", {
5591
5637
  className: "table-cell-action-button-container",
5592
5638
  ref: menuButtonRef,
5593
- children: tableCellNode != null && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(DropdownMenu.Root, {
5639
+ children: tableCellNode != null && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(DropdownMenu.Root, {
5594
5640
  onOpenChange: (isOpen) => setIsMenuOpen(isOpen),
5595
- content: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(TableActionMenu, {
5641
+ content: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(TableActionMenu, {
5596
5642
  tableCellNode,
5597
5643
  tableStats
5598
5644
  }),
5599
- children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(IconButton, {
5645
+ children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(IconButton, {
5600
5646
  size: "xs",
5601
5647
  className: "table-cell-action-button",
5602
- children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(Icon.Arrow, {})
5648
+ "aria-label": tr("actionTableOpenOptions"),
5649
+ children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(Icon.Arrow, {})
5603
5650
  })
5604
5651
  })
5605
5652
  });
@@ -5608,13 +5655,13 @@ function TableActionMenuPlugin({
5608
5655
  anchorElem = document.body
5609
5656
  }) {
5610
5657
  const isEditable = (0, import_useLexicalEditable.default)();
5611
- 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, {
5612
5659
  anchorElem
5613
5660
  }) : null, anchorElem);
5614
5661
  }
5615
5662
 
5616
5663
  // src/rich-text-editor/plugins/ToolbarPlugin/index.tsx
5617
- var import_react75 = require("react");
5664
+ var import_react76 = require("react");
5618
5665
  var import_lexical16 = require("lexical");
5619
5666
  var import_code9 = require("@lexical/code");
5620
5667
  var import_link6 = require("@lexical/link");
@@ -5626,13 +5673,10 @@ var import_rich_text4 = require("@lexical/rich-text");
5626
5673
  var import_selection3 = require("@lexical/selection");
5627
5674
  var import_utils4 = require("@lexical/utils");
5628
5675
 
5629
- // src/rich-text-editor/utils/environment.ts
5630
- var IS_APPLE = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
5631
-
5632
5676
  // src/rich-text-editor/plugins/ActionsPlugin/index.tsx
5633
5677
  var import_lexical15 = require("lexical");
5634
5678
  var import_LexicalComposerContext10 = require("@lexical/react/LexicalComposerContext");
5635
- var import_jsx_runtime86 = require("react/jsx-runtime");
5679
+ var import_jsx_runtime87 = require("react/jsx-runtime");
5636
5680
  async function copyJson(editor) {
5637
5681
  const json = lexicalToCrystallizeRichText({ editor, editorState: editor.getEditorState() });
5638
5682
  try {
@@ -5641,53 +5685,36 @@ async function copyJson(editor) {
5641
5685
  console.warn("Copy failed", error);
5642
5686
  }
5643
5687
  }
5644
- async function exportJson(editor) {
5645
- const json = lexicalToCrystallizeRichText({ editorState: editor.getEditorState() });
5646
- const blob = new Blob([JSON.stringify(json, null, 1)], {
5647
- type: "application/json"
5648
- });
5649
- const href = URL.createObjectURL(blob);
5650
- const link = document.createElement("a");
5651
- link.href = href;
5652
- link.download = "crystallizeRichText.json";
5653
- document.body.appendChild(link);
5654
- link.click();
5655
- document.body.removeChild(link);
5656
- URL.revokeObjectURL(href);
5657
- }
5658
5688
  function ActionsPlugin({
5659
5689
  append,
5660
5690
  prepend
5661
5691
  }) {
5662
5692
  const [editor] = (0, import_LexicalComposerContext10.useLexicalComposerContext)();
5663
- return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", {
5693
+ const tr = useTr();
5694
+ return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", {
5664
5695
  className: "z-50 flex items-center ",
5665
5696
  children: [
5666
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", {}),
5667
- /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(ActionMenu, {
5697
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", {}),
5698
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(ActionMenu, {
5668
5699
  children: [
5669
- !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, {
5670
5701
  onSelect: actionItem.action,
5671
5702
  className: actionItem.type === "danger" ? "danger" : "",
5672
5703
  children: actionItem.title
5673
5704
  }, actionItem.title)),
5674
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(ActionMenu.Item, {
5705
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ActionMenu.Item, {
5675
5706
  onSelect: () => copyJson(editor),
5676
- children: "Copy JSON"
5707
+ children: tr("actionCopyJSON")
5677
5708
  }),
5678
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(ActionMenu.Item, {
5679
- onSelect: () => exportJson(editor),
5680
- children: "Export JSON"
5681
- }),
5682
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(ActionMenu.Item, {
5709
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ActionMenu.Item, {
5683
5710
  className: "danger",
5684
5711
  onSelect: () => {
5685
5712
  editor.dispatchCommand(import_lexical15.CLEAR_EDITOR_COMMAND, void 0);
5686
5713
  editor.focus();
5687
5714
  },
5688
- children: "Clear paragraph"
5715
+ children: tr("actionClear")
5689
5716
  }),
5690
- !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, {
5691
5718
  onSelect: actionItem.action,
5692
5719
  className: actionItem.type === "danger" ? "danger" : "",
5693
5720
  children: actionItem.title
@@ -5699,12 +5726,13 @@ function ActionsPlugin({
5699
5726
  }
5700
5727
 
5701
5728
  // src/rich-text-editor/plugins/ToolbarPlugin/insert-table.tsx
5702
- var import_react74 = require("react");
5729
+ var import_react75 = require("react");
5703
5730
  var import_table5 = require("@lexical/table");
5704
- var import_jsx_runtime87 = require("react/jsx-runtime");
5731
+ var import_jsx_runtime88 = require("react/jsx-runtime");
5705
5732
  function InsertTableDialog({ activeEditor }) {
5706
- const [rows, setRows] = (0, import_react74.useState)("5");
5707
- 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();
5708
5736
  const onClick = () => {
5709
5737
  if (parseInt(rows) < 1 || parseInt(columns) < 1) {
5710
5738
  return;
@@ -5718,25 +5746,25 @@ function InsertTableDialog({ activeEditor }) {
5718
5746
  }
5719
5747
  });
5720
5748
  };
5721
- return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(import_jsx_runtime87.Fragment, {
5749
+ return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, {
5722
5750
  children: [
5723
- /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", {
5751
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", {
5724
5752
  className: "grid grid-cols-[1fr_1px_1fr] border border-gray-100-800 border-solid shadow-sm rounded-md ",
5725
5753
  children: [
5726
- /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(InputWithLabel, {
5727
- label: "Rows",
5754
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(InputWithLabel, {
5755
+ label: tr("insertTableRows"),
5728
5756
  value: rows,
5729
5757
  placeholder: "0",
5730
5758
  type: "text",
5731
5759
  inputMode: "numeric",
5732
5760
  onChange: (e) => setRows(e.target.value)
5733
5761
  }),
5734
- /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", {
5762
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5735
5763
  className: "h-full bg-gray-100-800"
5736
5764
  }),
5737
- /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(InputWithLabel, {
5765
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(InputWithLabel, {
5738
5766
  type: "text",
5739
- label: "Columns",
5767
+ label: tr("insertTableColumns"),
5740
5768
  placeholder: "0",
5741
5769
  value: columns,
5742
5770
  inputMode: "numeric",
@@ -5744,15 +5772,15 @@ function InsertTableDialog({ activeEditor }) {
5744
5772
  })
5745
5773
  ]
5746
5774
  }),
5747
- /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", {
5775
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", {
5748
5776
  className: "flex justify-end mt-3",
5749
- children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(Button, {
5777
+ children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Button, {
5750
5778
  as: Dialog.Close,
5751
5779
  size: "sm",
5752
5780
  intent: "action",
5753
- "aria-label": "Confirm",
5781
+ "aria-label": tr("insertTableCommit"),
5754
5782
  onClick,
5755
- children: "Confirm"
5783
+ children: tr("insertTableCommit")
5756
5784
  })
5757
5785
  })
5758
5786
  ]
@@ -5760,7 +5788,7 @@ function InsertTableDialog({ activeEditor }) {
5760
5788
  }
5761
5789
 
5762
5790
  // src/rich-text-editor/plugins/ToolbarPlugin/index.tsx
5763
- var import_jsx_runtime88 = require("react/jsx-runtime");
5791
+ var import_jsx_runtime89 = require("react/jsx-runtime");
5764
5792
  var headingTypeToBlockName = {
5765
5793
  h1: "Heading 1",
5766
5794
  h2: "Heading 2",
@@ -5864,83 +5892,83 @@ function BlockFormatDropDown({
5864
5892
  });
5865
5893
  }
5866
5894
  };
5867
- return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Root, {
5895
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(DropdownMenu.Root, {
5868
5896
  disabled,
5869
5897
  style: { zIndex: 1 },
5870
- content: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, {
5898
+ content: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_jsx_runtime89.Fragment, {
5871
5899
  children: [
5872
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5900
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5873
5901
  onClick: formatParagraph,
5874
5902
  children: [
5875
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5903
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5876
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"}`
5877
5905
  }),
5878
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5906
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5879
5907
  className: "icon paragraph"
5880
5908
  }),
5881
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5909
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5882
5910
  className: `${blockType === "paragraph" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5883
5911
  children: "Normal"
5884
5912
  })
5885
5913
  ]
5886
5914
  }),
5887
- headings.map((headingSize) => /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5915
+ headings.map((headingSize) => /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5888
5916
  onClick: () => formatHeading(headingSize),
5889
5917
  children: [
5890
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5918
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5891
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"}`
5892
5920
  }),
5893
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5921
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5894
5922
  className: `${blockType === headingSize ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5895
5923
  children: headingTypeToBlockName[headingSize]
5896
5924
  })
5897
5925
  ]
5898
5926
  }, headingSize)),
5899
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5927
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5900
5928
  onClick: formatBulletList,
5901
5929
  children: [
5902
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5930
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5903
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"}`
5904
5932
  }),
5905
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5933
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5906
5934
  className: `${blockType === "bullet" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5907
5935
  children: "Bullet List"
5908
5936
  })
5909
5937
  ]
5910
5938
  }),
5911
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5939
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5912
5940
  onClick: formatNumberedList,
5913
5941
  children: [
5914
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5942
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5915
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"}`
5916
5944
  }),
5917
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5945
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5918
5946
  className: `${blockType === "number" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5919
5947
  children: "Numbered List"
5920
5948
  })
5921
5949
  ]
5922
5950
  }),
5923
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5951
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5924
5952
  onClick: formatQuote,
5925
5953
  "data-testid": "toggle-block-format-quote",
5926
5954
  children: [
5927
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5955
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5928
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"}`
5929
5957
  }),
5930
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5958
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5931
5959
  className: `${blockType === "quote" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5932
5960
  children: "Quote"
5933
5961
  })
5934
5962
  ]
5935
5963
  }),
5936
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
5964
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
5937
5965
  onClick: formatCode,
5938
5966
  "data-testid": "toggle-block-format-code",
5939
5967
  children: [
5940
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5968
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5941
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"}`
5942
5970
  }),
5943
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
5971
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
5944
5972
  className: `${blockType === "code" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5945
5973
  children: "Code block"
5946
5974
  })
@@ -5948,21 +5976,21 @@ function BlockFormatDropDown({
5948
5976
  })
5949
5977
  ]
5950
5978
  }),
5951
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(Button, {
5979
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(Button, {
5952
5980
  style: { backgroundColor: "transparent", padding: "0 8px" },
5953
5981
  "aria-label": "Formatting options for text style",
5954
5982
  "data-testid": "toggle-block-format",
5955
5983
  children: [
5956
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
5984
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
5957
5985
  className: `icon ${blockType} border bg-no-repeat bg-center bg-[length:18px_18px] w-6 h-6`
5958
5986
  }),
5959
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Icon.Arrow, {})
5987
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Icon.Arrow, {})
5960
5988
  ]
5961
5989
  })
5962
5990
  });
5963
5991
  }
5964
5992
  function Divider() {
5965
- return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", {
5993
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", {
5966
5994
  className: "divider"
5967
5995
  });
5968
5996
  }
@@ -5971,22 +5999,23 @@ function ToolbarPlugin({
5971
5999
  actionsMenuAppend
5972
6000
  }) {
5973
6001
  const [editor] = (0, import_LexicalComposerContext11.useLexicalComposerContext)();
5974
- const [activeEditor, setActiveEditor] = (0, import_react75.useState)(editor);
5975
- const [blockType, setBlockType] = (0, import_react75.useState)("paragraph");
5976
- const [selectedElementKey, setSelectedElementKey] = (0, import_react75.useState)(null);
5977
- const [isLink, setIsLink] = (0, import_react75.useState)(false);
5978
- const [isBold, setIsBold] = (0, import_react75.useState)(false);
5979
- const [isItalic, setIsItalic] = (0, import_react75.useState)(false);
5980
- const [isUnderline, setIsUnderline] = (0, import_react75.useState)(false);
5981
- const [isStrikethrough, setIsStrikethrough] = (0, import_react75.useState)(false);
5982
- const [isSubscript, setIsSubscript] = (0, import_react75.useState)(false);
5983
- const [isSuperscript, setIsSuperscript] = (0, import_react75.useState)(false);
5984
- const [isCode, setIsCode] = (0, import_react75.useState)(false);
5985
- const [canUndo, setCanUndo] = (0, import_react75.useState)(false);
5986
- const [canRedo, setCanRedo] = (0, import_react75.useState)(false);
5987
- const [codeLanguage, setCodeLanguage] = (0, import_react75.useState)("");
5988
- const [isEditable, setIsEditable] = (0, import_react75.useState)(() => editor.isEditable());
5989
- 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)(() => {
5990
6019
  const selection = (0, import_lexical16.$getSelection)();
5991
6020
  if ((0, import_lexical16.$isRangeSelection)(selection)) {
5992
6021
  const anchorNode = selection.anchor.getNode();
@@ -6033,7 +6062,7 @@ function ToolbarPlugin({
6033
6062
  }
6034
6063
  }
6035
6064
  }, [activeEditor]);
6036
- (0, import_react75.useEffect)(() => {
6065
+ (0, import_react76.useEffect)(() => {
6037
6066
  return editor.registerCommand(
6038
6067
  import_lexical16.SELECTION_CHANGE_COMMAND,
6039
6068
  (_payload, newEditor) => {
@@ -6044,7 +6073,7 @@ function ToolbarPlugin({
6044
6073
  import_lexical16.COMMAND_PRIORITY_CRITICAL
6045
6074
  );
6046
6075
  }, [editor, updateToolbar]);
6047
- (0, import_react75.useEffect)(() => {
6076
+ (0, import_react76.useEffect)(() => {
6048
6077
  return (0, import_utils4.mergeRegister)(
6049
6078
  editor.registerEditableListener((editable) => {
6050
6079
  setIsEditable(editable);
@@ -6072,7 +6101,7 @@ function ToolbarPlugin({
6072
6101
  )
6073
6102
  );
6074
6103
  }, [activeEditor, editor, updateToolbar]);
6075
- const clearFormatting = (0, import_react75.useCallback)(() => {
6104
+ const clearFormatting = (0, import_react76.useCallback)(() => {
6076
6105
  activeEditor.update(() => {
6077
6106
  const selection = (0, import_lexical16.$getSelection)();
6078
6107
  if ((0, import_lexical16.$isRangeSelection)(selection)) {
@@ -6090,14 +6119,14 @@ function ToolbarPlugin({
6090
6119
  }
6091
6120
  });
6092
6121
  }, [activeEditor]);
6093
- const insertLink = (0, import_react75.useCallback)(() => {
6122
+ const insertLink = (0, import_react76.useCallback)(() => {
6094
6123
  if (!isLink) {
6095
6124
  editor.dispatchCommand(import_link6.TOGGLE_LINK_COMMAND, sanitizeUrl("https://"));
6096
6125
  } else {
6097
6126
  editor.dispatchCommand(import_link6.TOGGLE_LINK_COMMAND, null);
6098
6127
  }
6099
6128
  }, [editor, isLink]);
6100
- const onCodeLanguageSelect = (0, import_react75.useCallback)(
6129
+ const onCodeLanguageSelect = (0, import_react76.useCallback)(
6101
6130
  (value) => {
6102
6131
  activeEditor.update(() => {
6103
6132
  if (selectedElementKey !== null) {
@@ -6110,206 +6139,206 @@ function ToolbarPlugin({
6110
6139
  },
6111
6140
  [activeEditor, selectedElementKey]
6112
6141
  );
6113
- return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", {
6142
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", {
6114
6143
  className: "toolbar",
6115
6144
  children: [
6116
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", {
6145
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", {
6117
6146
  className: "flex",
6118
6147
  children: [
6119
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6148
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6120
6149
  disabled: !canUndo || !isEditable,
6121
6150
  onClick: () => {
6122
6151
  activeEditor.dispatchCommand(import_lexical16.UNDO_COMMAND, void 0);
6123
6152
  },
6124
- title: IS_APPLE ? "Undo (\u2318Z)" : "Undo (Ctrl+Z)",
6125
6153
  type: "button",
6126
- "aria-label": "Undo",
6127
- 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", {
6128
6157
  className: `format icon undo border w-4 h-6 bg-no-repeat bg-center bg-[length:17px_17px] ${canUndo ? "opacity-100" : "opacity-30"}
6129
6158
  `
6130
6159
  })
6131
6160
  }),
6132
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6161
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6133
6162
  disabled: !canRedo || !isEditable,
6134
6163
  onClick: () => {
6135
6164
  activeEditor.dispatchCommand(import_lexical16.REDO_COMMAND, void 0);
6136
6165
  },
6137
- title: IS_APPLE ? "Redo (\u2318Y)" : "Redo (Ctrl+Y)",
6138
6166
  type: "button",
6139
- "aria-label": "Redo",
6140
- 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", {
6141
6170
  className: `format icon redo border w-4 h-6 bg-no-repeat bg-center bg-[length:17px_17px] ${canRedo ? "opacity-100" : "opacity-30"}`
6142
6171
  })
6143
6172
  }),
6144
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Divider, {}),
6145
- 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, {
6146
6175
  children: [
6147
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(BlockFormatDropDown, {
6176
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(BlockFormatDropDown, {
6148
6177
  disabled: !isEditable,
6149
6178
  blockType,
6150
6179
  editor
6151
6180
  }),
6152
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Divider, {})
6181
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Divider, {})
6153
6182
  ]
6154
6183
  }),
6155
- blockType === "code" ? /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(import_jsx_runtime88.Fragment, {
6156
- 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, {
6157
6186
  disabled: !isEditable,
6158
6187
  style: { zIndex: 1 },
6159
- content: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(import_jsx_runtime88.Fragment, {
6188
+ content: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_jsx_runtime89.Fragment, {
6160
6189
  children: CODE_LANGUAGE_OPTIONS.map(([value, name]) => {
6161
- return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Item, {
6190
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(DropdownMenu.Item, {
6162
6191
  className: `item ${dropDownActiveClass(value === codeLanguage)}`,
6163
6192
  onClick: () => onCodeLanguageSelect(value),
6164
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6193
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6165
6194
  className: `text min-w-[200px] block text-sm px-3 ${dropDownActiveClass(value === codeLanguage) ? "font-bold opacity-100" : "font-normal opacity-80"}`,
6166
6195
  children: name
6167
6196
  })
6168
6197
  }, value);
6169
6198
  })
6170
6199
  }),
6171
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Button, {
6172
- "aria-label": "Select language",
6173
- append: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Icon.Arrow, {}),
6174
- 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", {
6175
6204
  className: "font-medium text-sm",
6176
6205
  children: (0, import_code9.getLanguageFriendlyName)(codeLanguage)
6177
6206
  })
6178
6207
  })
6179
6208
  })
6180
- }) : /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Dialog, {
6181
- 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", {
6182
6211
  className: "flex gap-1",
6183
6212
  children: [
6184
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6213
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6185
6214
  disabled: !isEditable,
6186
- title: IS_APPLE ? "Bold (\u2318B)" : "Bold (Ctrl+B)",
6187
6215
  className: `${isBold ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6188
6216
  type: "button",
6189
- "aria-label": `Format text as bold. Shortcut: ${IS_APPLE ? "\u2318B" : "Ctrl+B"}`,
6217
+ title: tr(IS_APPLE ? "actionFormatAsStrongTitleApple" : "actionFormatAsStrongTitle"),
6218
+ "aria-label": tr("actionFormatAsStrongLabel"),
6190
6219
  "data-testid": "toggle-format-bold",
6191
6220
  onClick: () => {
6192
6221
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "bold");
6193
6222
  },
6194
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6223
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6195
6224
  className: `format icon bold border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6196
6225
  })
6197
6226
  }),
6198
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6227
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6199
6228
  className: `${isItalic ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6200
6229
  disabled: !isEditable,
6201
6230
  onClick: () => {
6202
6231
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "italic");
6203
6232
  },
6204
- title: IS_APPLE ? "Italic (\u2318I)" : "Italic (Ctrl+I)",
6205
6233
  type: "button",
6206
- "aria-label": `Format text as italics. Shortcut: ${IS_APPLE ? "\u2318I" : "Ctrl+I"}`,
6234
+ title: tr(IS_APPLE ? "actionFormatAsEmphasizedTitleApple" : "actionFormatAsEmphasizedTitle"),
6235
+ "aria-label": tr("actionFormatAsEmphasizedLabel"),
6207
6236
  "data-testid": "toggle-format-emphasized",
6208
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6237
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6209
6238
  className: `format icon italic border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6210
6239
  })
6211
6240
  }),
6212
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6241
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6213
6242
  className: `${isUnderline ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6214
6243
  disabled: !isEditable,
6215
6244
  onClick: () => {
6216
6245
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "underline");
6217
6246
  },
6218
- title: IS_APPLE ? "Underline (\u2318U)" : "Underline (Ctrl+U)",
6219
6247
  type: "button",
6220
- "aria-label": `Format text to underlined. Shortcut: ${IS_APPLE ? "\u2318U" : "Ctrl+U"}`,
6248
+ title: tr(IS_APPLE ? "actionFormatAsUnderlinedTitleApple" : "actionFormatAsUnderlinedTitle"),
6249
+ "aria-label": tr("actionFormatAsUnderlinedLabel"),
6221
6250
  "data-testid": "toggle-format-underlined",
6222
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6251
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6223
6252
  className: `format icon underline border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6224
6253
  })
6225
6254
  }),
6226
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6255
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6227
6256
  className: `${isCode ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6228
6257
  disabled: !isEditable,
6229
6258
  onClick: () => {
6230
6259
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "code");
6231
6260
  },
6232
- title: "Insert code block",
6233
6261
  type: "button",
6234
- "aria-label": "Insert code block",
6235
- 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", {
6236
6265
  className: `format icon code border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6237
6266
  })
6238
6267
  }),
6239
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6268
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconButton, {
6240
6269
  className: `${isLink ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6241
6270
  disabled: !isEditable,
6242
6271
  onClick: insertLink,
6243
- "aria-label": "Insert link",
6244
- title: "Insert link",
6245
6272
  type: "button",
6246
- 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", {
6247
6276
  className: `format icon link border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6248
6277
  })
6249
6278
  }),
6250
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Root, {
6279
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(DropdownMenu.Root, {
6251
6280
  disabled: !isEditable,
6252
6281
  style: { zIndex: 1 },
6253
- content: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, {
6282
+ content: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_jsx_runtime89.Fragment, {
6254
6283
  children: [
6255
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
6284
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
6256
6285
  onClick: () => {
6257
6286
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "strikethrough");
6258
6287
  },
6259
- title: "Strikethrough",
6260
- "aria-label": "Format text with a strikethrough",
6288
+ title: tr("actionFormatWithStrikethroughTitle"),
6289
+ "aria-label": tr("actionFormatWithStrikethroughLabel"),
6261
6290
  children: [
6262
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6291
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6263
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"}`
6264
6293
  }),
6265
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6294
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6266
6295
  className: `px-3 text-sm font-sans ${isStrikethrough ? "font-medium" : "font-normal"}`,
6267
- children: "Strikethrough"
6296
+ children: tr("actionFormatAsStrongTitle")
6268
6297
  })
6269
6298
  ]
6270
6299
  }),
6271
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
6300
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
6272
6301
  onClick: () => {
6273
6302
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "subscript");
6274
6303
  },
6275
- title: "Subscript",
6276
- "aria-label": "Format text with a subscript",
6304
+ title: tr("actionFormatWithSubscriptTitle"),
6305
+ "aria-label": tr("actionFormatWithSubscriptLabel"),
6277
6306
  children: [
6278
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6307
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6279
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"}`
6280
6309
  }),
6281
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6310
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6282
6311
  className: `px-3 text-sm font-sans ${isSubscript ? "font-medium" : "font-normal"}`,
6283
- children: "Subscript"
6312
+ children: tr("actionFormatWithSubscriptTitle")
6284
6313
  })
6285
6314
  ]
6286
6315
  }),
6287
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
6316
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
6288
6317
  onClick: () => {
6289
6318
  activeEditor.dispatchCommand(import_lexical16.FORMAT_TEXT_COMMAND, "superscript");
6290
6319
  },
6291
- title: "Superscript",
6292
- "aria-label": "Format text with a superscript",
6320
+ title: tr("actionFormatWithSuperscriptTitle"),
6321
+ "aria-label": tr("actionFormatWithSuperscriptLabel"),
6293
6322
  children: [
6294
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6323
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6295
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"}`
6296
6325
  }),
6297
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6326
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6298
6327
  className: `px-3 text-sm font-sans ${isSuperscript ? "bg-purple-50-900" : "font-normal"}`,
6299
- children: "Superscript"
6328
+ children: tr("actionFormatWithSuperscriptTitle")
6300
6329
  })
6301
6330
  ]
6302
6331
  }),
6303
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(DropdownMenu.Item, {
6332
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(DropdownMenu.Item, {
6304
6333
  onClick: clearFormatting,
6305
6334
  className: "item",
6306
- title: "Clear text formatting",
6307
- "aria-label": "Clear all text formatting",
6335
+ title: tr("actionClearTextFormatting"),
6336
+ "aria-label": tr("actionClearTextFormatting"),
6308
6337
  children: [
6309
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6338
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6310
6339
  className: "icon w-6 h-6 clear border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6311
6340
  }),
6312
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6341
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6313
6342
  className: "px-3 text-sm text-pink-600-300 font-sans font-normal",
6314
6343
  children: "Clear Formatting"
6315
6344
  })
@@ -6317,52 +6346,52 @@ function ToolbarPlugin({
6317
6346
  })
6318
6347
  ]
6319
6348
  }),
6320
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(Button, {
6349
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(Button, {
6321
6350
  style: { backgroundColor: "transparent", padding: "0 8px" },
6322
- "aria-label": "Formatting options for additional text styles",
6351
+ "aria-label": tr("actionTextFormattingOptions"),
6323
6352
  children: [
6324
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6353
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6325
6354
  className: `icon dropdown-more border bg-no-repeat bg-center bg-[length:18px_18px] w-6 h-6`
6326
6355
  }),
6327
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Icon.Arrow, {})
6356
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Icon.Arrow, {})
6328
6357
  ]
6329
6358
  })
6330
6359
  }),
6331
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Divider, {}),
6332
- /* @__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, {
6333
6362
  style: { zIndex: 1 },
6334
6363
  disabled: !isEditable,
6335
- content: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, {
6364
+ content: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_jsx_runtime89.Fragment, {
6336
6365
  children: [
6337
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Item, {
6366
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(DropdownMenu.Item, {
6338
6367
  onClick: () => {
6339
6368
  activeEditor.dispatchCommand(import_LexicalHorizontalRuleNode4.INSERT_HORIZONTAL_RULE_COMMAND, void 0);
6340
6369
  },
6341
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", {
6370
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", {
6342
6371
  className: "flex items-center font-sans font-normal",
6343
6372
  children: [
6344
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6373
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6345
6374
  className: "icon w-5 h-5 horizontal-rule border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6346
6375
  }),
6347
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6376
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6348
6377
  className: "px-3 text-sm",
6349
- children: "Horizontal rule"
6378
+ children: tr("horizontalRule")
6350
6379
  })
6351
6380
  ]
6352
6381
  })
6353
6382
  }),
6354
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(DropdownMenu.Item, {
6355
- 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, {
6356
6385
  asChild: true,
6357
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", {
6386
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", {
6358
6387
  className: "flex items-center font-sans font-normal",
6359
6388
  children: [
6360
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("i", {
6389
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("i", {
6361
6390
  className: "icon w-5 h-5 table border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6362
6391
  }),
6363
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", {
6392
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", {
6364
6393
  className: "px-3 text-sm",
6365
- children: "Table"
6394
+ children: tr("table")
6366
6395
  })
6367
6396
  ]
6368
6397
  })
@@ -6370,23 +6399,23 @@ function ToolbarPlugin({
6370
6399
  })
6371
6400
  ]
6372
6401
  }),
6373
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconButton, {
6374
- 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", {
6375
6404
  className: "icon plus border w-full h-full bg-no-repeat bg-center bg-[length:20px_20px] "
6376
6405
  })
6377
6406
  })
6378
6407
  }),
6379
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(Dialog.Content, {
6408
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(Dialog.Content, {
6380
6409
  children: [
6381
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Dialog.Title, {
6382
- children: "Insert table"
6410
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Dialog.Title, {
6411
+ children: tr("insertTableTitle")
6383
6412
  }),
6384
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Dialog.Description, {
6385
- 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")
6386
6415
  }),
6387
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", {
6416
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", {
6388
6417
  className: "items-center justify-between",
6389
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(InsertTableDialog, {
6418
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(InsertTableDialog, {
6390
6419
  activeEditor
6391
6420
  })
6392
6421
  })
@@ -6397,7 +6426,7 @@ function ToolbarPlugin({
6397
6426
  })
6398
6427
  ]
6399
6428
  }),
6400
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(ActionsPlugin, {
6429
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(ActionsPlugin, {
6401
6430
  prepend: actionsMenuPrepend,
6402
6431
  append: actionsMenuAppend
6403
6432
  })
@@ -6507,21 +6536,13 @@ var theme = {
6507
6536
  };
6508
6537
  var CrystallizeRTEditorTheme_default = theme;
6509
6538
 
6510
- // src/rich-text-editor/ui/ContentEditable.tsx
6511
- var React7 = require("react");
6512
- var import_LexicalContentEditable = require("@lexical/react/LexicalContentEditable");
6513
- var import_jsx_runtime89 = require("react/jsx-runtime");
6514
- function LexicalContentEditable({ className }) {
6515
- return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_LexicalContentEditable.ContentEditable, {
6516
- className: className || "ContentEditable__root"
6517
- });
6518
- }
6519
-
6520
6539
  // src/rich-text-editor/rich-text-editor.tsx
6521
6540
  var import_jsx_runtime90 = require("react/jsx-runtime");
6522
6541
  function RichTextEditor({
6523
6542
  initialData,
6524
6543
  editable = true,
6544
+ language = "en",
6545
+ labelTranslations,
6525
6546
  ...rest
6526
6547
  }) {
6527
6548
  return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(import_LexicalComposer.LexicalComposer, {
@@ -6537,12 +6558,16 @@ function RichTextEditor({
6537
6558
  richText: initialData
6538
6559
  }) : void 0
6539
6560
  },
6540
- children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(SharedHistoryContext, {
6541
- children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", {
6542
- className: "c-rich-text-editor",
6543
- children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(RichTextEditorWithoutContext, {
6544
- ...rest,
6545
- 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
+ })
6546
6571
  })
6547
6572
  })
6548
6573
  })
@@ -6565,18 +6590,18 @@ function RichTextEditorWithoutContext({
6565
6590
  children: placeholderText ?? ""
6566
6591
  });
6567
6592
  const [editor] = (0, import_LexicalComposerContext12.useLexicalComposerContext)();
6568
- const [floatingAnchorElem, setFloatingAnchorElem] = (0, import_react76.useState)(null);
6569
- const [isSmallWidthViewport, setIsSmallWidthViewport] = (0, import_react76.useState)(false);
6570
- 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);
6571
6596
  const onRef = (_floatingAnchorElem) => {
6572
6597
  if (_floatingAnchorElem !== null) {
6573
6598
  setFloatingAnchorElem(_floatingAnchorElem);
6574
6599
  }
6575
6600
  };
6576
- (0, import_react76.useEffect)(() => {
6601
+ (0, import_react77.useEffect)(() => {
6577
6602
  editor.setEditable(editable || false);
6578
6603
  }, [editable, editor]);
6579
- (0, import_react76.useEffect)(() => {
6604
+ (0, import_react77.useEffect)(() => {
6580
6605
  const updateViewPortWidth = () => {
6581
6606
  const isNextSmallWidthViewport = window.matchMedia("(max-width: 1025px)").matches;
6582
6607
  if (isNextSmallWidthViewport !== isSmallWidthViewport) {
@@ -6625,7 +6650,9 @@ function RichTextEditorWithoutContext({
6625
6650
  children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", {
6626
6651
  className: "editor",
6627
6652
  ref: onRef,
6628
- children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(LexicalContentEditable, {})
6653
+ children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(import_LexicalContentEditable.ContentEditable, {
6654
+ className: "ContentEditable__root"
6655
+ })
6629
6656
  })
6630
6657
  }),
6631
6658
  placeholder,