@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.mjs CHANGED
@@ -3541,7 +3541,7 @@ function Tag({ children, className, variant, ...delegated }) {
3541
3541
  }
3542
3542
 
3543
3543
  // src/rich-text-editor/rich-text-editor.tsx
3544
- import { useEffect as useEffect11, useRef as useRef5, useState as useState10 } from "react";
3544
+ import { useEffect as useEffect12, useRef as useRef5, useState as useState11 } from "react";
3545
3545
  import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
3546
3546
  import { ClearEditorPlugin } from "@lexical/react/LexicalClearEditorPlugin";
3547
3547
  import { LexicalComposer } from "@lexical/react/LexicalComposer";
@@ -3554,6 +3554,7 @@ import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
3554
3554
  import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin";
3555
3555
  import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
3556
3556
  import { useLexicalComposerContext as useLexicalComposerContext12 } from "@lexical/react/LexicalComposerContext";
3557
+ import { ContentEditable } from "@lexical/react/LexicalContentEditable";
3557
3558
 
3558
3559
  // src/rich-text-editor/context/SharedHistoryContext.tsx
3559
3560
  import { createContext, useContext, useMemo } from "react";
@@ -3571,6 +3572,54 @@ var useSharedHistoryContext = () => {
3571
3572
  return useContext(Context);
3572
3573
  };
3573
3574
 
3575
+ // src/rich-text-editor/i18n/index.tsx
3576
+ import { createContext as createContext2, useContext as useContext2, useEffect, useState } from "react";
3577
+ import { jsx as jsx77 } from "react/jsx-runtime";
3578
+ var I18nContext = createContext2(null);
3579
+ function I18nProvider({
3580
+ language,
3581
+ labelTranslations,
3582
+ children
3583
+ }) {
3584
+ const [translations, setTranslations] = useState(labelTranslations || null);
3585
+ useEffect(() => {
3586
+ let unmounted = false;
3587
+ (async function load() {
3588
+ if (!labelTranslations) {
3589
+ const resource = await import(`./translations/${language}.ts`);
3590
+ if (!unmounted) {
3591
+ setTranslations(resource.default);
3592
+ }
3593
+ }
3594
+ })();
3595
+ return () => {
3596
+ unmounted = true;
3597
+ };
3598
+ }, [language, labelTranslations]);
3599
+ return /* @__PURE__ */ jsx77(I18nContext.Provider, {
3600
+ value: translations,
3601
+ children
3602
+ });
3603
+ }
3604
+ function replaceI18nVariablesInString(str, replaceWith) {
3605
+ return str.replace(/({{[^}]+}})/g, replaceWith);
3606
+ }
3607
+ function useTr() {
3608
+ const context = useContext2(I18nContext);
3609
+ return (key, units) => {
3610
+ const thereAreUnits = typeof units === "number";
3611
+ const keyToUse = thereAreUnits && units > 1 ? `${key}_plural` : key;
3612
+ if (context && keyToUse in context) {
3613
+ const tr = context[keyToUse];
3614
+ if (thereAreUnits) {
3615
+ return replaceI18nVariablesInString(tr, units.toString());
3616
+ }
3617
+ return tr;
3618
+ }
3619
+ return "";
3620
+ };
3621
+ }
3622
+
3574
3623
  // src/rich-text-editor/model/crystallize-to-lexical.ts
3575
3624
  import {
3576
3625
  $createLineBreakNode,
@@ -3984,7 +4033,7 @@ var BaseNodes = [
3984
4033
  // src/rich-text-editor/plugins/AutoLinkPlugin/index.tsx
3985
4034
  import { AutoLinkPlugin } from "@lexical/react/LexicalAutoLinkPlugin";
3986
4035
  import "react";
3987
- import { jsx as jsx77 } from "react/jsx-runtime";
4036
+ import { jsx as jsx78 } from "react/jsx-runtime";
3988
4037
  var URL_MATCHER = /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
3989
4038
  var EMAIL_MATCHER = /(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/;
3990
4039
  var MATCHERS = [
@@ -4012,13 +4061,13 @@ var MATCHERS = [
4012
4061
  }
4013
4062
  ];
4014
4063
  function LexicalAutoLinkPlugin() {
4015
- return /* @__PURE__ */ jsx77(AutoLinkPlugin, {
4064
+ return /* @__PURE__ */ jsx78(AutoLinkPlugin, {
4016
4065
  matchers: MATCHERS
4017
4066
  });
4018
4067
  }
4019
4068
 
4020
4069
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx
4021
- import { useEffect, useRef, useState as useState3 } from "react";
4070
+ import { useEffect as useEffect2, useRef, useState as useState4 } from "react";
4022
4071
  import { $getNearestNodeFromDOMNode as $getNearestNodeFromDOMNode3 } from "lexical";
4023
4072
  import { createPortal } from "react-dom";
4024
4073
  import { useDebouncedCallback as useDebouncedCallback2 } from "use-debounce";
@@ -4027,13 +4076,14 @@ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext
4027
4076
 
4028
4077
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/components/CopyButton/index.tsx
4029
4078
  import "react";
4030
- import { useState } from "react";
4079
+ import { useState as useState2 } from "react";
4031
4080
  import { $getNearestNodeFromDOMNode, $getSelection, $setSelection } from "lexical";
4032
4081
  import { useDebouncedCallback } from "use-debounce";
4033
4082
  import { $isCodeNode as $isCodeNode2 } from "@lexical/code";
4034
- import { jsx as jsx78 } from "react/jsx-runtime";
4083
+ import { jsx as jsx79 } from "react/jsx-runtime";
4035
4084
  function CopyButton({ editor, getCodeDOMNode }) {
4036
- const [isCopyCompleted, setCopyCompleted] = useState(false);
4085
+ const [isCopyCompleted, setCopyCompleted] = useState2(false);
4086
+ const tr = useTr();
4037
4087
  const removeSuccessIcon = useDebouncedCallback(() => {
4038
4088
  setCopyCompleted(false);
4039
4089
  }, 1e3);
@@ -4059,13 +4109,13 @@ function CopyButton({ editor, getCodeDOMNode }) {
4059
4109
  console.error("Failed to copy: ", err);
4060
4110
  }
4061
4111
  }
4062
- return /* @__PURE__ */ jsx78("button", {
4112
+ return /* @__PURE__ */ jsx79("button", {
4063
4113
  className: "menu-item",
4064
4114
  onClick: handleClick,
4065
- "aria-label": "copy",
4066
- children: isCopyCompleted ? /* @__PURE__ */ jsx78("i", {
4115
+ "aria-label": tr("actionCopyCode"),
4116
+ children: isCopyCompleted ? /* @__PURE__ */ jsx79("i", {
4067
4117
  className: "format success"
4068
- }) : /* @__PURE__ */ jsx78("i", {
4118
+ }) : /* @__PURE__ */ jsx79("i", {
4069
4119
  className: "format copy"
4070
4120
  })
4071
4121
  });
@@ -4073,10 +4123,10 @@ function CopyButton({ editor, getCodeDOMNode }) {
4073
4123
 
4074
4124
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/components/PrettierButton/index.tsx
4075
4125
  import "react";
4076
- import { useState as useState2 } from "react";
4126
+ import { useState as useState3 } from "react";
4077
4127
  import { $getNearestNodeFromDOMNode as $getNearestNodeFromDOMNode2 } from "lexical";
4078
4128
  import { $isCodeNode as $isCodeNode3 } from "@lexical/code";
4079
- import { jsx as jsx79, jsxs as jsxs58 } from "react/jsx-runtime";
4129
+ import { jsx as jsx80, jsxs as jsxs58 } from "react/jsx-runtime";
4080
4130
  var PRETTIER_PARSER_MODULES = {
4081
4131
  css: () => import("prettier/parser-postcss"),
4082
4132
  html: () => import("prettier/parser-html"),
@@ -4116,8 +4166,9 @@ function getPrettierOptions(lang) {
4116
4166
  return options;
4117
4167
  }
4118
4168
  function PrettierButton({ lang, editor, getCodeDOMNode }) {
4119
- const [syntaxError, setSyntaxError] = useState2("");
4120
- const [tipsVisible, setTipsVisible] = useState2(false);
4169
+ const [syntaxError, setSyntaxError] = useState3("");
4170
+ const [tipsVisible, setTipsVisible] = useState3(false);
4171
+ const tr = useTr();
4121
4172
  async function handleClick() {
4122
4173
  const codeDOMNode = getCodeDOMNode();
4123
4174
  try {
@@ -4133,6 +4184,7 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4133
4184
  const content = codeNode.getTextContent();
4134
4185
  let parsed = "";
4135
4186
  parsed = format(content, options);
4187
+ parsed = parsed.replace(/[\r\n]+$/, "");
4136
4188
  if (parsed !== "") {
4137
4189
  const selection = codeNode.select(0);
4138
4190
  selection.insertText(parsed);
@@ -4163,19 +4215,19 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4163
4215
  return /* @__PURE__ */ jsxs58("div", {
4164
4216
  className: "prettier-wrapper",
4165
4217
  children: [
4166
- /* @__PURE__ */ jsx79("button", {
4218
+ /* @__PURE__ */ jsx80("button", {
4167
4219
  className: "menu-item",
4168
4220
  onClick: handleClick,
4169
4221
  onMouseEnter: handleMouseEnter,
4170
4222
  onMouseLeave: handleMouseLeave,
4171
- "aria-label": "prettier",
4172
- children: syntaxError ? /* @__PURE__ */ jsx79("i", {
4223
+ "aria-label": tr("actionFormatCode"),
4224
+ children: syntaxError ? /* @__PURE__ */ jsx80("i", {
4173
4225
  className: "format prettier-error"
4174
- }) : /* @__PURE__ */ jsx79("i", {
4226
+ }) : /* @__PURE__ */ jsx80("i", {
4175
4227
  className: "format prettier"
4176
4228
  })
4177
4229
  }),
4178
- tipsVisible ? /* @__PURE__ */ jsx79("pre", {
4230
+ tipsVisible ? /* @__PURE__ */ jsx80("pre", {
4179
4231
  className: "code-error-tips",
4180
4232
  children: syntaxError
4181
4233
  }) : null
@@ -4184,14 +4236,14 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
4184
4236
  }
4185
4237
 
4186
4238
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx
4187
- import { Fragment as Fragment2, jsx as jsx80, jsxs as jsxs59 } from "react/jsx-runtime";
4239
+ import { Fragment as Fragment2, jsx as jsx81, jsxs as jsxs59 } from "react/jsx-runtime";
4188
4240
  var CODE_PADDING = 8;
4189
4241
  function CodeActionMenuContainer({ anchorElem }) {
4190
4242
  const [editor] = useLexicalComposerContext();
4191
- const [lang, setLang] = useState3("");
4192
- const [isShown, setShown] = useState3(false);
4193
- const [shouldListenMouseMove, setShouldListenMouseMove] = useState3(false);
4194
- const [position, setPosition] = useState3({
4243
+ const [lang, setLang] = useState4("");
4244
+ const [isShown, setShown] = useState4(false);
4245
+ const [shouldListenMouseMove, setShouldListenMouseMove] = useState4(true);
4246
+ const [position, setPosition] = useState4({
4195
4247
  right: "0",
4196
4248
  top: "0"
4197
4249
  });
@@ -4230,7 +4282,7 @@ function CodeActionMenuContainer({ anchorElem }) {
4230
4282
  });
4231
4283
  }
4232
4284
  }, 50);
4233
- useEffect(() => {
4285
+ useEffect2(() => {
4234
4286
  if (!shouldListenMouseMove) {
4235
4287
  return;
4236
4288
  }
@@ -4261,20 +4313,20 @@ function CodeActionMenuContainer({ anchorElem }) {
4261
4313
  });
4262
4314
  const normalizedLang = normalizeCodeLang(lang);
4263
4315
  const codeFriendlyName = getLanguageFriendlyName(lang);
4264
- return /* @__PURE__ */ jsx80(Fragment2, {
4316
+ return /* @__PURE__ */ jsx81(Fragment2, {
4265
4317
  children: isShown ? /* @__PURE__ */ jsxs59("div", {
4266
4318
  className: "code-action-menu-container",
4267
4319
  style: { ...position },
4268
4320
  children: [
4269
- /* @__PURE__ */ jsx80("div", {
4321
+ /* @__PURE__ */ jsx81("div", {
4270
4322
  className: "code-highlight-language",
4271
4323
  children: codeFriendlyName
4272
4324
  }),
4273
- /* @__PURE__ */ jsx80(CopyButton, {
4325
+ /* @__PURE__ */ jsx81(CopyButton, {
4274
4326
  editor,
4275
4327
  getCodeDOMNode
4276
4328
  }),
4277
- canBePrettier(normalizedLang) ? /* @__PURE__ */ jsx80(PrettierButton, {
4329
+ canBePrettier(normalizedLang) ? /* @__PURE__ */ jsx81(PrettierButton, {
4278
4330
  editor,
4279
4331
  getCodeDOMNode,
4280
4332
  lang: normalizedLang
@@ -4296,25 +4348,25 @@ function getMouseInfo(event) {
4296
4348
  function CodeActionMenuPlugin({
4297
4349
  anchorElem = document.body
4298
4350
  }) {
4299
- return createPortal(/* @__PURE__ */ jsx80(CodeActionMenuContainer, {
4351
+ return createPortal(/* @__PURE__ */ jsx81(CodeActionMenuContainer, {
4300
4352
  anchorElem
4301
4353
  }), anchorElem);
4302
4354
  }
4303
4355
 
4304
4356
  // src/rich-text-editor/plugins/CodeHighlightPlugin/index.ts
4305
- import { useEffect as useEffect2 } from "react";
4357
+ import { useEffect as useEffect3 } from "react";
4306
4358
  import { registerCodeHighlighting } from "@lexical/code";
4307
4359
  import { useLexicalComposerContext as useLexicalComposerContext2 } from "@lexical/react/LexicalComposerContext";
4308
4360
  function CodeHighlightPlugin() {
4309
4361
  const [editor] = useLexicalComposerContext2();
4310
- useEffect2(() => {
4362
+ useEffect3(() => {
4311
4363
  return registerCodeHighlighting(editor);
4312
4364
  }, [editor]);
4313
4365
  return null;
4314
4366
  }
4315
4367
 
4316
4368
  // src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx
4317
- import { useCallback, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
4369
+ import { useCallback, useEffect as useEffect5, useRef as useRef2, useState as useState6 } from "react";
4318
4370
  import "react";
4319
4371
  import {
4320
4372
  $getSelection as $getSelection3,
@@ -4331,10 +4383,10 @@ import { useLexicalComposerContext as useLexicalComposerContext4 } from "@lexica
4331
4383
  import { $findMatchingParent, mergeRegister } from "@lexical/utils";
4332
4384
 
4333
4385
  // src/rich-text-editor/ui/LinkPreview.tsx
4334
- import { Suspense, useEffect as useEffect3, useState as useState4 } from "react";
4386
+ import { Suspense, useEffect as useEffect4, useState as useState5 } from "react";
4335
4387
  import { $getSelection as $getSelection2, $isTextNode as $isTextNode3 } from "lexical";
4336
4388
  import { useLexicalComposerContext as useLexicalComposerContext3 } from "@lexical/react/LexicalComposerContext";
4337
- import { Fragment as Fragment3, jsx as jsx81, jsxs as jsxs60 } from "react/jsx-runtime";
4389
+ import { Fragment as Fragment3, jsx as jsx82, jsxs as jsxs60 } from "react/jsx-runtime";
4338
4390
  var PREVIEW_CACHE = {};
4339
4391
  var URL_MATCHER2 = /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
4340
4392
  function useSuspenseRequest(url) {
@@ -4358,11 +4410,12 @@ function useSuspenseRequest(url) {
4358
4410
  function LinkPreviewContent({
4359
4411
  url
4360
4412
  }) {
4361
- const [textContent, setTextContent] = useState4("");
4413
+ const [textContent, setTextContent] = useState5("");
4362
4414
  const { preview } = useSuspenseRequest(url);
4363
4415
  const [editor] = useLexicalComposerContext3();
4416
+ const tr = useTr();
4364
4417
  const hasPreview = preview !== null && preview.google?.title;
4365
- useEffect3(() => {
4418
+ useEffect4(() => {
4366
4419
  editor.update(() => {
4367
4420
  const sel = $getSelection2();
4368
4421
  const nodes = sel?.getNodes();
@@ -4393,32 +4446,32 @@ function LinkPreviewContent({
4393
4446
  return /* @__PURE__ */ jsxs60("div", {
4394
4447
  className: "LinkPreview__container",
4395
4448
  children: [
4396
- preview.google.image && /* @__PURE__ */ jsx81("div", {
4449
+ preview.google.image && /* @__PURE__ */ jsx82("div", {
4397
4450
  className: "LinkPreview__imageWrapper bg-purple-50-900",
4398
- children: /* @__PURE__ */ jsx81("img", {
4451
+ children: /* @__PURE__ */ jsx82("img", {
4399
4452
  src: preview.google.image,
4400
4453
  alt: preview.google.title,
4401
4454
  className: "LinkPreview__image"
4402
4455
  })
4403
4456
  }),
4404
- preview.google.title && /* @__PURE__ */ jsx81("div", {
4457
+ preview.google.title && /* @__PURE__ */ jsx82("div", {
4405
4458
  className: "LinkPreview__title",
4406
4459
  children: preview.google.title
4407
4460
  }),
4408
- preview.google.description && /* @__PURE__ */ jsx81("div", {
4461
+ preview.google.description && /* @__PURE__ */ jsx82("div", {
4409
4462
  className: "LinkPreview__description",
4410
4463
  children: preview.google.description
4411
4464
  }),
4412
- textContent && textContent !== preview.google.title ? /* @__PURE__ */ jsx81(Button, {
4465
+ textContent && textContent !== preview.google.title ? /* @__PURE__ */ jsx82(Button, {
4413
4466
  className: "mb-4 ml-5",
4414
4467
  onClick: useTitleForText,
4415
- children: "Replace link text with its title"
4468
+ children: tr("linkPreviewReplaceTextWithTitle")
4416
4469
  }) : null
4417
4470
  ]
4418
4471
  });
4419
4472
  }
4420
4473
  function Glimmer(props) {
4421
- return /* @__PURE__ */ jsx81("div", {
4474
+ return /* @__PURE__ */ jsx82("div", {
4422
4475
  className: "LinkPreview__glimmer",
4423
4476
  ...props,
4424
4477
  style: {
@@ -4430,24 +4483,24 @@ function Glimmer(props) {
4430
4483
  function LinkPreview({
4431
4484
  url
4432
4485
  }) {
4433
- return /* @__PURE__ */ jsx81(Suspense, {
4486
+ return /* @__PURE__ */ jsx82(Suspense, {
4434
4487
  fallback: /* @__PURE__ */ jsxs60(Fragment3, {
4435
4488
  children: [
4436
- /* @__PURE__ */ jsx81(Glimmer, {
4489
+ /* @__PURE__ */ jsx82(Glimmer, {
4437
4490
  style: { height: "80px" },
4438
4491
  index: 0
4439
4492
  }),
4440
- /* @__PURE__ */ jsx81(Glimmer, {
4493
+ /* @__PURE__ */ jsx82(Glimmer, {
4441
4494
  style: { width: "60%" },
4442
4495
  index: 1
4443
4496
  }),
4444
- /* @__PURE__ */ jsx81(Glimmer, {
4497
+ /* @__PURE__ */ jsx82(Glimmer, {
4445
4498
  style: { width: "80%" },
4446
4499
  index: 2
4447
4500
  })
4448
4501
  ]
4449
4502
  }),
4450
- children: /* @__PURE__ */ jsx81(LinkPreviewContent, {
4503
+ children: /* @__PURE__ */ jsx82(LinkPreviewContent, {
4451
4504
  url
4452
4505
  })
4453
4506
  });
@@ -4516,7 +4569,7 @@ function validateUrl(url) {
4516
4569
  }
4517
4570
 
4518
4571
  // src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx
4519
- import { Fragment as Fragment4, jsx as jsx82, jsxs as jsxs61 } from "react/jsx-runtime";
4572
+ import { Fragment as Fragment4, jsx as jsx83, jsxs as jsxs61 } from "react/jsx-runtime";
4520
4573
  function FloatingLinkEditor({
4521
4574
  editor,
4522
4575
  isLink,
@@ -4525,11 +4578,12 @@ function FloatingLinkEditor({
4525
4578
  }) {
4526
4579
  const editorRef = useRef2(null);
4527
4580
  const inputRef = useRef2(null);
4528
- const [linkUrl, setLinkUrl] = useState5("");
4529
- const [rel, setRel] = useState5(null);
4530
- const [target, setTarget] = useState5(null);
4531
- const [isEditMode, setEditMode] = useState5(false);
4532
- const [lastSelection, setLastSelection] = useState5(null);
4581
+ const [linkUrl, setLinkUrl] = useState6("");
4582
+ const [rel, setRel] = useState6(null);
4583
+ const [target, setTarget] = useState6(null);
4584
+ const [isEditMode, setEditMode] = useState6(false);
4585
+ const [lastSelection, setLastSelection] = useState6(null);
4586
+ const tr = useTr();
4533
4587
  const updateLinkEditor = useCallback(() => {
4534
4588
  const selection = $getSelection3();
4535
4589
  if ($isRangeSelection(selection)) {
@@ -4580,7 +4634,7 @@ function FloatingLinkEditor({
4580
4634
  }
4581
4635
  return true;
4582
4636
  }, [anchorElem, editor]);
4583
- useEffect4(() => {
4637
+ useEffect5(() => {
4584
4638
  const scrollerElem = anchorElem.parentElement;
4585
4639
  const update = () => {
4586
4640
  editor.getEditorState().read(() => {
@@ -4598,7 +4652,7 @@ function FloatingLinkEditor({
4598
4652
  }
4599
4653
  };
4600
4654
  }, [anchorElem.parentElement, editor, updateLinkEditor]);
4601
- useEffect4(() => {
4655
+ useEffect5(() => {
4602
4656
  return mergeRegister(
4603
4657
  editor.registerUpdateListener(({ editorState }) => {
4604
4658
  editorState.read(() => {
@@ -4626,51 +4680,51 @@ function FloatingLinkEditor({
4626
4680
  )
4627
4681
  );
4628
4682
  }, [editor, updateLinkEditor, setIsLink, isLink]);
4629
- useEffect4(() => {
4683
+ useEffect5(() => {
4630
4684
  editor.getEditorState().read(() => {
4631
4685
  updateLinkEditor();
4632
4686
  });
4633
4687
  }, [editor, updateLinkEditor]);
4634
- useEffect4(() => {
4688
+ useEffect5(() => {
4635
4689
  if (isEditMode && inputRef.current) {
4636
4690
  inputRef.current.focus();
4637
4691
  }
4638
4692
  }, [isEditMode]);
4639
- return /* @__PURE__ */ jsx82("div", {
4693
+ return /* @__PURE__ */ jsx83("div", {
4640
4694
  ref: editorRef,
4641
4695
  className: "link-editor",
4642
4696
  children: isEditMode ? /* @__PURE__ */ jsxs61("div", {
4643
4697
  children: [
4644
- /* @__PURE__ */ jsx82("div", {
4698
+ /* @__PURE__ */ jsx83("div", {
4645
4699
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4646
- children: /* @__PURE__ */ jsx82(InputWithLabel, {
4647
- label: "Link",
4700
+ children: /* @__PURE__ */ jsx83(InputWithLabel, {
4701
+ label: tr("linkEditorLink"),
4648
4702
  type: "text",
4649
4703
  value: linkUrl,
4650
4704
  onChange: (e) => setLinkUrl(e.target.value)
4651
4705
  })
4652
4706
  }),
4653
- /* @__PURE__ */ jsx82("div", {
4707
+ /* @__PURE__ */ jsx83("div", {
4654
4708
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4655
- children: /* @__PURE__ */ jsx82(InputWithLabel, {
4656
- label: "Rel",
4709
+ children: /* @__PURE__ */ jsx83(InputWithLabel, {
4710
+ label: tr("linkEditorRel"),
4657
4711
  type: "text",
4658
4712
  value: rel ?? "",
4659
4713
  onChange: (e) => setRel(e.target.value)
4660
4714
  })
4661
4715
  }),
4662
- /* @__PURE__ */ jsx82("div", {
4716
+ /* @__PURE__ */ jsx83("div", {
4663
4717
  className: "border-0 border-b border-gray-100-800 border-solid px-3",
4664
- children: /* @__PURE__ */ jsx82(InputWithLabel, {
4665
- label: "Target",
4718
+ children: /* @__PURE__ */ jsx83(InputWithLabel, {
4719
+ label: tr("linkEditorTarget"),
4666
4720
  type: "text",
4667
4721
  value: target ?? "",
4668
4722
  onChange: (e) => setTarget(e.target.value)
4669
4723
  })
4670
4724
  }),
4671
- /* @__PURE__ */ jsx82("div", {
4725
+ /* @__PURE__ */ jsx83("div", {
4672
4726
  className: "flex px-6 py-2 justify-end",
4673
- children: /* @__PURE__ */ jsx82(Button, {
4727
+ children: /* @__PURE__ */ jsx83(Button, {
4674
4728
  onClick: () => {
4675
4729
  if (lastSelection !== null) {
4676
4730
  if (linkUrl !== "") {
@@ -4683,7 +4737,7 @@ function FloatingLinkEditor({
4683
4737
  setEditMode(false);
4684
4738
  }
4685
4739
  },
4686
- children: "Done"
4740
+ children: tr("linkEditorCommit")
4687
4741
  })
4688
4742
  })
4689
4743
  ]
@@ -4693,9 +4747,9 @@ function FloatingLinkEditor({
4693
4747
  className: "link-input !flex flex-nowrap justify-between items-center max-w-full ",
4694
4748
  children: [
4695
4749
  /* @__PURE__ */ jsxs61("div", {
4696
- className: " grid",
4750
+ className: "grid",
4697
4751
  children: [
4698
- /* @__PURE__ */ jsx82("a", {
4752
+ /* @__PURE__ */ jsx83("a", {
4699
4753
  href: linkUrl,
4700
4754
  target: "_blank",
4701
4755
  rel: "noopener noreferrer",
@@ -4704,11 +4758,11 @@ function FloatingLinkEditor({
4704
4758
  rel || target ? /* @__PURE__ */ jsxs61("div", {
4705
4759
  className: "flex mt-1 gap-1",
4706
4760
  children: [
4707
- rel && /* @__PURE__ */ jsx82("div", {
4761
+ rel && /* @__PURE__ */ jsx83("div", {
4708
4762
  className: "text-[10px] text-gray-600-300 px-1 bg-purple-50-900 rounded-md py-0.5",
4709
4763
  children: rel
4710
4764
  }),
4711
- target && /* @__PURE__ */ jsx82("div", {
4765
+ target && /* @__PURE__ */ jsx83("div", {
4712
4766
  className: "text-[10px] text-gray-600-300 px-1 bg-purple-50-900 rounded-md py-0.5",
4713
4767
  children: target
4714
4768
  })
@@ -4716,19 +4770,20 @@ function FloatingLinkEditor({
4716
4770
  }) : null
4717
4771
  ]
4718
4772
  }),
4719
- /* @__PURE__ */ jsx82("div", {
4720
- children: /* @__PURE__ */ jsx82(IconButton, {
4773
+ /* @__PURE__ */ jsx83("div", {
4774
+ children: /* @__PURE__ */ jsx83(IconButton, {
4721
4775
  size: "sm",
4722
4776
  tabIndex: 0,
4723
4777
  onMouseDown: (event) => event.preventDefault(),
4724
4778
  onClick: () => setEditMode(true),
4725
- children: /* @__PURE__ */ jsx82(Icon.Edit, {})
4779
+ "aria-label": tr("linkEditorEdit"),
4780
+ children: /* @__PURE__ */ jsx83(Icon.Edit, {})
4726
4781
  })
4727
4782
  })
4728
4783
  ]
4729
4784
  }),
4730
- /* @__PURE__ */ jsx82("div", {
4731
- children: /* @__PURE__ */ jsx82(LinkPreview, {
4785
+ /* @__PURE__ */ jsx83("div", {
4786
+ children: /* @__PURE__ */ jsx83(LinkPreview, {
4732
4787
  url: linkUrl
4733
4788
  })
4734
4789
  })
@@ -4737,8 +4792,8 @@ function FloatingLinkEditor({
4737
4792
  });
4738
4793
  }
4739
4794
  function useFloatingLinkEditorToolbar(editor, anchorElem) {
4740
- const [activeEditor, setActiveEditor] = useState5(editor);
4741
- const [isLink, setIsLink] = useState5(false);
4795
+ const [activeEditor, setActiveEditor] = useState6(editor);
4796
+ const [isLink, setIsLink] = useState6(false);
4742
4797
  const updateToolbar = useCallback(() => {
4743
4798
  const selection = $getSelection3();
4744
4799
  if ($isRangeSelection(selection)) {
@@ -4752,7 +4807,7 @@ function useFloatingLinkEditorToolbar(editor, anchorElem) {
4752
4807
  }
4753
4808
  }
4754
4809
  }, []);
4755
- useEffect4(() => {
4810
+ useEffect5(() => {
4756
4811
  return editor.registerCommand(
4757
4812
  SELECTION_CHANGE_COMMAND,
4758
4813
  (_payload, newEditor) => {
@@ -4764,7 +4819,7 @@ function useFloatingLinkEditorToolbar(editor, anchorElem) {
4764
4819
  );
4765
4820
  }, [editor, updateToolbar]);
4766
4821
  return isLink ? createPortal2(
4767
- /* @__PURE__ */ jsx82(FloatingLinkEditor, {
4822
+ /* @__PURE__ */ jsx83(FloatingLinkEditor, {
4768
4823
  editor: activeEditor,
4769
4824
  isLink,
4770
4825
  anchorElem,
@@ -4781,7 +4836,7 @@ function FloatingLinkEditorPlugin({
4781
4836
  }
4782
4837
 
4783
4838
  // src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx
4784
- import { useCallback as useCallback2, useEffect as useEffect5, useRef as useRef3, useState as useState6 } from "react";
4839
+ import { useCallback as useCallback2, useEffect as useEffect6, useRef as useRef3, useState as useState7 } from "react";
4785
4840
  import "react";
4786
4841
  import {
4787
4842
  $getSelection as $getSelection4,
@@ -4797,6 +4852,9 @@ import { $isLinkNode as $isLinkNode3, TOGGLE_LINK_COMMAND as TOGGLE_LINK_COMMAND
4797
4852
  import { useLexicalComposerContext as useLexicalComposerContext5 } from "@lexical/react/LexicalComposerContext";
4798
4853
  import { mergeRegister as mergeRegister2 } from "@lexical/utils";
4799
4854
 
4855
+ // src/rich-text-editor/utils/environment.ts
4856
+ var IS_APPLE = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
4857
+
4800
4858
  // src/rich-text-editor/utils/getDOMRangeRect.ts
4801
4859
  function getDOMRangeRect(nativeSelection, rootElement) {
4802
4860
  const domRange = nativeSelection.getRangeAt(0);
@@ -4827,7 +4885,7 @@ function getDOMRangeRect(nativeSelection, rootElement) {
4827
4885
  }
4828
4886
 
4829
4887
  // src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx
4830
- import { Fragment as Fragment5, jsx as jsx83, jsxs as jsxs62 } from "react/jsx-runtime";
4888
+ import { Fragment as Fragment5, jsx as jsx84, jsxs as jsxs62 } from "react/jsx-runtime";
4831
4889
  function TextFormatFloatingToolbar({
4832
4890
  editor,
4833
4891
  anchorElem,
@@ -4841,6 +4899,7 @@ function TextFormatFloatingToolbar({
4841
4899
  isSuperscript
4842
4900
  }) {
4843
4901
  const popupCharStylesEditorRef = useRef3(null);
4902
+ const tr = useTr();
4844
4903
  const insertLink = useCallback2(() => {
4845
4904
  if (!isLink) {
4846
4905
  editor.dispatchCommand(TOGGLE_LINK_COMMAND2, "https://");
@@ -4861,7 +4920,7 @@ function TextFormatFloatingToolbar({
4861
4920
  setFloatingElemPosition(rangeRect, popupCharStylesEditorElem, anchorElem);
4862
4921
  }
4863
4922
  }, [editor, anchorElem]);
4864
- useEffect5(() => {
4923
+ useEffect6(() => {
4865
4924
  const scrollerElem = anchorElem.parentElement;
4866
4925
  const update = () => {
4867
4926
  editor.getEditorState().read(() => {
@@ -4879,7 +4938,7 @@ function TextFormatFloatingToolbar({
4879
4938
  }
4880
4939
  };
4881
4940
  }, [editor, updateTextFormatFloatingToolbar, anchorElem]);
4882
- useEffect5(() => {
4941
+ useEffect6(() => {
4883
4942
  editor.getEditorState().read(() => {
4884
4943
  updateTextFormatFloatingToolbar();
4885
4944
  });
@@ -4899,88 +4958,92 @@ function TextFormatFloatingToolbar({
4899
4958
  )
4900
4959
  );
4901
4960
  }, [editor, updateTextFormatFloatingToolbar]);
4902
- return /* @__PURE__ */ jsx83("div", {
4961
+ return /* @__PURE__ */ jsx84("div", {
4903
4962
  ref: popupCharStylesEditorRef,
4904
4963
  className: "c-floating-text-format-popup gap-0.5",
4905
4964
  children: editor.isEditable() && /* @__PURE__ */ jsxs62(Fragment5, {
4906
4965
  children: [
4907
- /* @__PURE__ */ jsx83(IconButton, {
4966
+ /* @__PURE__ */ jsx84(IconButton, {
4908
4967
  onClick: () => {
4909
4968
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "bold");
4910
4969
  },
4911
4970
  style: { padding: 0, overflow: "hidden" },
4912
- "aria-label": "Format text as bold",
4913
- children: /* @__PURE__ */ jsx83("i", {
4971
+ title: tr(IS_APPLE ? "actionFormatAsStrongTitleApple" : "actionFormatAsStrongTitle"),
4972
+ "aria-label": tr("actionFormatAsStrongLabel"),
4973
+ children: /* @__PURE__ */ jsx84("i", {
4914
4974
  className: `format bold w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isBold ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4915
4975
  })
4916
4976
  }),
4917
- /* @__PURE__ */ jsx83(IconButton, {
4977
+ /* @__PURE__ */ jsx84(IconButton, {
4918
4978
  style: { padding: 0, overflow: "hidden" },
4919
4979
  onClick: () => {
4920
4980
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "italic");
4921
4981
  },
4922
- "aria-label": "Format text as italics",
4923
- children: /* @__PURE__ */ jsx83("i", {
4982
+ title: tr("actionFormatAsEmphasizedTitle"),
4983
+ "aria-label": tr("actionFormatAsEmphasizedLabel"),
4984
+ children: /* @__PURE__ */ jsx84("i", {
4924
4985
  className: `format italic w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isItalic ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4925
4986
  })
4926
4987
  }),
4927
- /* @__PURE__ */ jsx83(IconButton, {
4988
+ /* @__PURE__ */ jsx84(IconButton, {
4928
4989
  style: { padding: 0, overflow: "hidden" },
4929
4990
  onClick: () => {
4930
4991
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "underline");
4931
4992
  },
4932
- "aria-label": "Format text to underlined",
4933
- children: /* @__PURE__ */ jsx83("i", {
4993
+ title: tr("actionFormatAsUnderlinedTitle"),
4994
+ "aria-label": tr("actionFormatAsUnderlinedLabel"),
4995
+ children: /* @__PURE__ */ jsx84("i", {
4934
4996
  className: `format underline w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isUnderline ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4935
4997
  })
4936
4998
  }),
4937
- /* @__PURE__ */ jsx83(IconButton, {
4999
+ /* @__PURE__ */ jsx84(IconButton, {
4938
5000
  style: { padding: 0, overflow: "hidden" },
4939
5001
  onClick: () => {
4940
5002
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "strikethrough");
4941
5003
  },
4942
- "aria-label": "Format text with a strikethrough",
4943
- children: /* @__PURE__ */ jsx83("i", {
5004
+ title: tr("actionFormatWithStrikethroughTitle"),
5005
+ "aria-label": tr("actionFormatWithStrikethroughLabel"),
5006
+ children: /* @__PURE__ */ jsx84("i", {
4944
5007
  className: `format strikethrough w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isStrikethrough ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4945
5008
  })
4946
5009
  }),
4947
- /* @__PURE__ */ jsx83(IconButton, {
5010
+ /* @__PURE__ */ jsx84(IconButton, {
4948
5011
  style: { padding: 0, overflow: "hidden" },
4949
5012
  onClick: () => {
4950
5013
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "subscript");
4951
5014
  },
4952
- title: "Subscript",
4953
- "aria-label": "Format Subscript",
4954
- children: /* @__PURE__ */ jsx83("i", {
5015
+ title: tr("actionFormatWithSubscriptTitle"),
5016
+ "aria-label": tr("actionFormatWithSubscriptLabel"),
5017
+ children: /* @__PURE__ */ jsx84("i", {
4955
5018
  className: `format subscript w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isSubscript ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4956
5019
  })
4957
5020
  }),
4958
- /* @__PURE__ */ jsx83(IconButton, {
5021
+ /* @__PURE__ */ jsx84(IconButton, {
4959
5022
  style: { padding: 0, overflow: "hidden" },
4960
5023
  onClick: () => {
4961
5024
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "superscript");
4962
5025
  },
4963
- title: "Superscript",
4964
- "aria-label": "Format Superscript",
4965
- children: /* @__PURE__ */ jsx83("i", {
5026
+ title: tr("actionFormatWithSuperscriptTitle"),
5027
+ "aria-label": tr("actionFormatWithSuperscriptLabel"),
5028
+ children: /* @__PURE__ */ jsx84("i", {
4966
5029
  className: `format superscript w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isSuperscript ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4967
5030
  })
4968
5031
  }),
4969
- /* @__PURE__ */ jsx83(IconButton, {
5032
+ /* @__PURE__ */ jsx84(IconButton, {
4970
5033
  style: { padding: 0, overflow: "hidden" },
4971
5034
  onClick: () => {
4972
5035
  editor.dispatchCommand(FORMAT_TEXT_COMMAND, "code");
4973
5036
  },
4974
- "aria-label": "Insert code block",
4975
- children: /* @__PURE__ */ jsx83("i", {
5037
+ "aria-label": tr("actionInsertCodeBlock"),
5038
+ children: /* @__PURE__ */ jsx84("i", {
4976
5039
  className: `format code w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isCode ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4977
5040
  })
4978
5041
  }),
4979
- /* @__PURE__ */ jsx83(IconButton, {
5042
+ /* @__PURE__ */ jsx84(IconButton, {
4980
5043
  style: { padding: 0, overflow: "hidden" },
4981
5044
  onClick: insertLink,
4982
- "aria-label": "Insert link",
4983
- children: /* @__PURE__ */ jsx83("i", {
5045
+ "aria-label": tr("actionInsertlink"),
5046
+ children: /* @__PURE__ */ jsx84("i", {
4984
5047
  className: `format link w-full h-full bg-[length:18px_18px] bg-no-repeat bg-center ${isLink ? "bg-purple-50-900 opacity-100" : "opacity-60"}`
4985
5048
  })
4986
5049
  })
@@ -4989,15 +5052,15 @@ function TextFormatFloatingToolbar({
4989
5052
  });
4990
5053
  }
4991
5054
  function useFloatingTextFormatToolbar(editor, anchorElem) {
4992
- const [isText, setIsText] = useState6(false);
4993
- const [isLink, setIsLink] = useState6(false);
4994
- const [isBold, setIsBold] = useState6(false);
4995
- const [isItalic, setIsItalic] = useState6(false);
4996
- const [isUnderline, setIsUnderline] = useState6(false);
4997
- const [isStrikethrough, setIsStrikethrough] = useState6(false);
4998
- const [isSubscript, setIsSubscript] = useState6(false);
4999
- const [isSuperscript, setIsSuperscript] = useState6(false);
5000
- const [isCode, setIsCode] = useState6(false);
5055
+ const [isText, setIsText] = useState7(false);
5056
+ const [isLink, setIsLink] = useState7(false);
5057
+ const [isBold, setIsBold] = useState7(false);
5058
+ const [isItalic, setIsItalic] = useState7(false);
5059
+ const [isUnderline, setIsUnderline] = useState7(false);
5060
+ const [isStrikethrough, setIsStrikethrough] = useState7(false);
5061
+ const [isSubscript, setIsSubscript] = useState7(false);
5062
+ const [isSuperscript, setIsSuperscript] = useState7(false);
5063
+ const [isCode, setIsCode] = useState7(false);
5001
5064
  const updatePopup = useCallback2(() => {
5002
5065
  editor.getEditorState().read(() => {
5003
5066
  if (editor.isComposing()) {
@@ -5034,13 +5097,13 @@ function useFloatingTextFormatToolbar(editor, anchorElem) {
5034
5097
  }
5035
5098
  });
5036
5099
  }, [editor]);
5037
- useEffect5(() => {
5100
+ useEffect6(() => {
5038
5101
  document.addEventListener("selectionchange", updatePopup);
5039
5102
  return () => {
5040
5103
  document.removeEventListener("selectionchange", updatePopup);
5041
5104
  };
5042
5105
  }, [updatePopup]);
5043
- useEffect5(() => {
5106
+ useEffect6(() => {
5044
5107
  return mergeRegister2(
5045
5108
  editor.registerUpdateListener(() => {
5046
5109
  updatePopup();
@@ -5056,7 +5119,7 @@ function useFloatingTextFormatToolbar(editor, anchorElem) {
5056
5119
  return null;
5057
5120
  }
5058
5121
  return createPortal3(
5059
- /* @__PURE__ */ jsx83(TextFormatFloatingToolbar, {
5122
+ /* @__PURE__ */ jsx84(TextFormatFloatingToolbar, {
5060
5123
  editor,
5061
5124
  anchorElem,
5062
5125
  isLink,
@@ -5081,9 +5144,9 @@ function FloatingTextFormatToolbarPlugin({
5081
5144
  // src/rich-text-editor/plugins/LinkPlugin/index.tsx
5082
5145
  import { LinkPlugin as LexicalLinkPlugin } from "@lexical/react/LexicalLinkPlugin";
5083
5146
  import "react";
5084
- import { jsx as jsx84 } from "react/jsx-runtime";
5147
+ import { jsx as jsx85 } from "react/jsx-runtime";
5085
5148
  function LinkPlugin() {
5086
- return /* @__PURE__ */ jsx84(LexicalLinkPlugin, {
5149
+ return /* @__PURE__ */ jsx85(LexicalLinkPlugin, {
5087
5150
  validateUrl
5088
5151
  });
5089
5152
  }
@@ -5098,7 +5161,7 @@ import {
5098
5161
  COMMAND_PRIORITY_CRITICAL as COMMAND_PRIORITY_CRITICAL2,
5099
5162
  INDENT_CONTENT_COMMAND
5100
5163
  } from "lexical";
5101
- import { useEffect as useEffect6 } from "react";
5164
+ import { useEffect as useEffect7 } from "react";
5102
5165
  function getElementNodesInSelection(selection) {
5103
5166
  const nodesInSelection = selection.getNodes();
5104
5167
  if (nodesInSelection.length === 0) {
@@ -5135,7 +5198,7 @@ function isIndentPermitted(maxDepth) {
5135
5198
  }
5136
5199
  function ListMaxIndentLevelPlugin({ maxDepth }) {
5137
5200
  const [editor] = useLexicalComposerContext6();
5138
- useEffect6(() => {
5201
+ useEffect7(() => {
5139
5202
  return editor.registerCommand(
5140
5203
  INDENT_CONTENT_COMMAND,
5141
5204
  () => !isIndentPermitted(maxDepth ?? 7),
@@ -5146,7 +5209,7 @@ function ListMaxIndentLevelPlugin({ maxDepth }) {
5146
5209
  }
5147
5210
 
5148
5211
  // src/rich-text-editor/plugins/MaxLengthPlugin/index.tsx
5149
- import { useEffect as useEffect7 } from "react";
5212
+ import { useEffect as useEffect8 } from "react";
5150
5213
  import { $getSelection as $getSelection6, $isRangeSelection as $isRangeSelection4 } from "lexical";
5151
5214
  import { useLexicalComposerContext as useLexicalComposerContext7 } from "@lexical/react/LexicalComposerContext";
5152
5215
  import { trimTextContentFromAnchor } from "@lexical/selection";
@@ -5188,7 +5251,7 @@ ${content}
5188
5251
  // src/rich-text-editor/plugins/MaxLengthPlugin/index.tsx
5189
5252
  function MaxLengthPlugin({ maxLength }) {
5190
5253
  const [editor] = useLexicalComposerContext7();
5191
- useEffect7(() => {
5254
+ useEffect8(() => {
5192
5255
  let lastRestoredEditorState = null;
5193
5256
  return editor.registerUpdateListener(({ editorState, prevEditorState }) => {
5194
5257
  editor.update(() => {
@@ -5218,14 +5281,9 @@ function MaxLengthPlugin({ maxLength }) {
5218
5281
  }
5219
5282
 
5220
5283
  // src/rich-text-editor/plugins/TabFocusPlugin/index.tsx
5284
+ import { useEffect as useEffect9 } from "react";
5285
+ import { $getSelection as $getSelection7, $isRangeSelection as $isRangeSelection5, $setSelection as $setSelection2, FOCUS_COMMAND } from "lexical";
5221
5286
  import { useLexicalComposerContext as useLexicalComposerContext8 } from "@lexical/react/LexicalComposerContext";
5222
- import {
5223
- $getSelection as $getSelection7,
5224
- $isRangeSelection as $isRangeSelection5,
5225
- $setSelection as $setSelection2,
5226
- FOCUS_COMMAND
5227
- } from "lexical";
5228
- import { useEffect as useEffect8 } from "react";
5229
5287
  var COMMAND_PRIORITY_LOW3 = 1;
5230
5288
  var TAB_TO_FOCUS_INTERVAL = 100;
5231
5289
  var lastTabKeyDownTimestamp = 0;
@@ -5243,7 +5301,7 @@ function registerKeyTimeStampTracker() {
5243
5301
  }
5244
5302
  function TabFocusPlugin() {
5245
5303
  const [editor] = useLexicalComposerContext8();
5246
- useEffect8(() => {
5304
+ useEffect9(() => {
5247
5305
  if (!hasRegisteredKeyDownListener) {
5248
5306
  registerKeyTimeStampTracker();
5249
5307
  hasRegisteredKeyDownListener = true;
@@ -5266,7 +5324,7 @@ function TabFocusPlugin() {
5266
5324
  }
5267
5325
 
5268
5326
  // src/rich-text-editor/plugins/TableActionMenuPlugin/index.tsx
5269
- import { useCallback as useCallback3, useEffect as useEffect9, useRef as useRef4, useState as useState7 } from "react";
5327
+ import { useCallback as useCallback3, useEffect as useEffect10, useRef as useRef4, useState as useState8 } from "react";
5270
5328
  import { $getRoot as $getRoot3, $getSelection as $getSelection8, $isRangeSelection as $isRangeSelection6, DEPRECATED_$isGridSelection } from "lexical";
5271
5329
  import { createPortal as createPortal4 } from "react-dom";
5272
5330
  import { useLexicalComposerContext as useLexicalComposerContext9 } from "@lexical/react/LexicalComposerContext";
@@ -5288,15 +5346,16 @@ import {
5288
5346
  TableCellHeaderStates,
5289
5347
  TableCellNode as TableCellNode2
5290
5348
  } from "@lexical/table";
5291
- import { Fragment as Fragment6, jsx as jsx85, jsxs as jsxs63 } from "react/jsx-runtime";
5349
+ import { Fragment as Fragment6, jsx as jsx86, jsxs as jsxs63 } from "react/jsx-runtime";
5292
5350
  function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5293
5351
  const [editor] = useLexicalComposerContext9();
5294
- const [tableCellNode, updateTableCellNode] = useState7(_tableCellNode);
5295
- const [selectionCounts, updateSelectionCounts] = useState7({
5352
+ const [tableCellNode, updateTableCellNode] = useState8(_tableCellNode);
5353
+ const [selectionCounts, updateSelectionCounts] = useState8({
5296
5354
  columns: 1,
5297
5355
  rows: 1
5298
5356
  });
5299
- useEffect9(() => {
5357
+ const tr = useTr();
5358
+ useEffect10(() => {
5300
5359
  return editor.registerMutationListener(TableCellNode2, (nodeMutations) => {
5301
5360
  const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === "updated";
5302
5361
  if (nodeUpdated) {
@@ -5306,7 +5365,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5306
5365
  }
5307
5366
  });
5308
5367
  }, [editor, tableCellNode]);
5309
- useEffect9(() => {
5368
+ useEffect10(() => {
5310
5369
  editor.getEditorState().read(() => {
5311
5370
  const selection = $getSelection8();
5312
5371
  if (DEPRECATED_$isGridSelection(selection)) {
@@ -5444,75 +5503,57 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
5444
5503
  }, [editor, tableCellNode, clearTableSelection]);
5445
5504
  return /* @__PURE__ */ jsxs63(Fragment6, {
5446
5505
  children: [
5447
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5506
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5448
5507
  onSelect: () => insertTableRowAtSelection(false),
5449
- children: [
5450
- "Insert ",
5451
- selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
5452
- " above"
5453
- ]
5508
+ children: tr("actionTableInsertRowsAbove", selectionCounts.rows)
5454
5509
  }),
5455
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5510
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5456
5511
  onSelect: () => insertTableRowAtSelection(true),
5457
- children: [
5458
- "Insert ",
5459
- selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
5460
- " below"
5461
- ]
5512
+ children: tr("actionTableInsertRowsBelow", selectionCounts.rows)
5462
5513
  }),
5463
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5514
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5464
5515
  onSelect: () => insertTableColumnAtSelection(false),
5465
- children: [
5466
- "Insert ",
5467
- selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
5468
- " left"
5469
- ]
5516
+ children: tr("actionTableInsertColumnsBefore", selectionCounts.columns)
5470
5517
  }),
5471
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5518
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5472
5519
  onSelect: () => insertTableColumnAtSelection(true),
5473
- children: [
5474
- "Insert ",
5475
- selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
5476
- " right"
5477
- ]
5520
+ children: tr("actionTableInsertColumnsAfter", selectionCounts.columns)
5478
5521
  }),
5479
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5522
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5480
5523
  onSelect: () => toggleTableRowIsHeader(),
5481
- children: [
5482
- (tableCellNode.__headerState & TableCellHeaderStates.ROW) === TableCellHeaderStates.ROW ? "Remove" : "Add",
5483
- " row header"
5484
- ]
5524
+ children: tr(
5525
+ (tableCellNode.__headerState & TableCellHeaderStates.ROW) === TableCellHeaderStates.ROW ? "actionTableRemoveRowHeader" : "actionTableAddRowHeader"
5526
+ )
5485
5527
  }),
5486
- /* @__PURE__ */ jsxs63(DropdownMenu.Item, {
5528
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5487
5529
  onSelect: () => toggleTableColumnIsHeader(),
5488
- children: [
5489
- (tableCellNode.__headerState & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN ? "Remove" : "Add",
5490
- " ",
5491
- "column header"
5492
- ]
5530
+ children: tr(
5531
+ (tableCellNode.__headerState & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN ? "actionTableRemoveColumnHeader" : "actionTableAddColumnHeader"
5532
+ )
5493
5533
  }),
5494
- /* @__PURE__ */ jsx85(DropdownMenu.Separator, {}),
5495
- tableStats.columns > 1 && /* @__PURE__ */ jsx85(DropdownMenu.Item, {
5534
+ /* @__PURE__ */ jsx86(DropdownMenu.Separator, {}),
5535
+ tableStats.columns > 1 && /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5496
5536
  onSelect: () => deleteTableColumnAtSelection(),
5497
- children: "Delete column"
5537
+ children: tr("actionTableDeleteColumn")
5498
5538
  }),
5499
- tableStats.rows > 1 && /* @__PURE__ */ jsx85(DropdownMenu.Item, {
5539
+ tableStats.rows > 1 && /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5500
5540
  onSelect: () => deleteTableRowAtSelection(),
5501
- children: "Delete row"
5541
+ children: tr("actionTableDeleteRow")
5502
5542
  }),
5503
- /* @__PURE__ */ jsx85(DropdownMenu.Item, {
5543
+ /* @__PURE__ */ jsx86(DropdownMenu.Item, {
5504
5544
  onSelect: () => deleteTableAtSelection(),
5505
- children: "Delete table"
5545
+ children: tr("actionTableDeleteTable")
5506
5546
  })
5507
5547
  ]
5508
5548
  });
5509
5549
  }
5510
5550
  function TableCellActionMenuContainer({ anchorElem }) {
5511
5551
  const [editor] = useLexicalComposerContext9();
5552
+ const tr = useTr();
5512
5553
  const menuButtonRef = useRef4(null);
5513
- const [isMenuOpen, setIsMenuOpen] = useState7(false);
5514
- const [tableCellNode, setTableMenuCellNode] = useState7(null);
5515
- const [tableStats, setTablestats] = useState7({ rows: 1, columns: 1 });
5554
+ const [isMenuOpen, setIsMenuOpen] = useState8(false);
5555
+ const [tableCellNode, setTableMenuCellNode] = useState8(null);
5556
+ const [tableStats, setTablestats] = useState8({ rows: 1, columns: 1 });
5516
5557
  const moveMenu = useCallback3(() => {
5517
5558
  if (isMenuOpen) {
5518
5559
  return;
@@ -5556,14 +5597,14 @@ function TableCellActionMenuContainer({ anchorElem }) {
5556
5597
  setTableMenuCellNode(null);
5557
5598
  }
5558
5599
  }, [editor, isMenuOpen]);
5559
- useEffect9(() => {
5600
+ useEffect10(() => {
5560
5601
  return editor.registerUpdateListener(() => {
5561
5602
  editor.getEditorState().read(() => {
5562
5603
  moveMenu();
5563
5604
  });
5564
5605
  });
5565
5606
  });
5566
- useEffect9(() => {
5607
+ useEffect10(() => {
5567
5608
  const menuButtonDOM = menuButtonRef.current;
5568
5609
  if (menuButtonDOM != null && tableCellNode != null) {
5569
5610
  const tableCellNodeDOM = editor.getElementByKey(tableCellNode.getKey());
@@ -5581,19 +5622,20 @@ function TableCellActionMenuContainer({ anchorElem }) {
5581
5622
  }
5582
5623
  }
5583
5624
  }, [menuButtonRef, tableCellNode, editor, anchorElem]);
5584
- return /* @__PURE__ */ jsx85("div", {
5625
+ return /* @__PURE__ */ jsx86("div", {
5585
5626
  className: "table-cell-action-button-container",
5586
5627
  ref: menuButtonRef,
5587
- children: tableCellNode != null && /* @__PURE__ */ jsx85(DropdownMenu.Root, {
5628
+ children: tableCellNode != null && /* @__PURE__ */ jsx86(DropdownMenu.Root, {
5588
5629
  onOpenChange: (isOpen) => setIsMenuOpen(isOpen),
5589
- content: /* @__PURE__ */ jsx85(TableActionMenu, {
5630
+ content: /* @__PURE__ */ jsx86(TableActionMenu, {
5590
5631
  tableCellNode,
5591
5632
  tableStats
5592
5633
  }),
5593
- children: /* @__PURE__ */ jsx85(IconButton, {
5634
+ children: /* @__PURE__ */ jsx86(IconButton, {
5594
5635
  size: "xs",
5595
5636
  className: "table-cell-action-button",
5596
- children: /* @__PURE__ */ jsx85(Icon.Arrow, {})
5637
+ "aria-label": tr("actionTableOpenOptions"),
5638
+ children: /* @__PURE__ */ jsx86(Icon.Arrow, {})
5597
5639
  })
5598
5640
  })
5599
5641
  });
@@ -5602,13 +5644,13 @@ function TableActionMenuPlugin({
5602
5644
  anchorElem = document.body
5603
5645
  }) {
5604
5646
  const isEditable = useLexicalEditable();
5605
- return createPortal4(isEditable ? /* @__PURE__ */ jsx85(TableCellActionMenuContainer, {
5647
+ return createPortal4(isEditable ? /* @__PURE__ */ jsx86(TableCellActionMenuContainer, {
5606
5648
  anchorElem
5607
5649
  }) : null, anchorElem);
5608
5650
  }
5609
5651
 
5610
5652
  // src/rich-text-editor/plugins/ToolbarPlugin/index.tsx
5611
- import { useCallback as useCallback4, useEffect as useEffect10, useState as useState9 } from "react";
5653
+ import { useCallback as useCallback4, useEffect as useEffect11, useState as useState10 } from "react";
5612
5654
  import {
5613
5655
  $createParagraphNode as $createParagraphNode2,
5614
5656
  $getNodeByKey,
@@ -5653,13 +5695,10 @@ import {
5653
5695
  mergeRegister as mergeRegister3
5654
5696
  } from "@lexical/utils";
5655
5697
 
5656
- // src/rich-text-editor/utils/environment.ts
5657
- var IS_APPLE = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
5658
-
5659
5698
  // src/rich-text-editor/plugins/ActionsPlugin/index.tsx
5660
5699
  import { CLEAR_EDITOR_COMMAND } from "lexical";
5661
5700
  import { useLexicalComposerContext as useLexicalComposerContext10 } from "@lexical/react/LexicalComposerContext";
5662
- import { jsx as jsx86, jsxs as jsxs64 } from "react/jsx-runtime";
5701
+ import { jsx as jsx87, jsxs as jsxs64 } from "react/jsx-runtime";
5663
5702
  async function copyJson(editor) {
5664
5703
  const json = lexicalToCrystallizeRichText({ editor, editorState: editor.getEditorState() });
5665
5704
  try {
@@ -5668,53 +5707,36 @@ async function copyJson(editor) {
5668
5707
  console.warn("Copy failed", error);
5669
5708
  }
5670
5709
  }
5671
- async function exportJson(editor) {
5672
- const json = lexicalToCrystallizeRichText({ editorState: editor.getEditorState() });
5673
- const blob = new Blob([JSON.stringify(json, null, 1)], {
5674
- type: "application/json"
5675
- });
5676
- const href = URL.createObjectURL(blob);
5677
- const link = document.createElement("a");
5678
- link.href = href;
5679
- link.download = "crystallizeRichText.json";
5680
- document.body.appendChild(link);
5681
- link.click();
5682
- document.body.removeChild(link);
5683
- URL.revokeObjectURL(href);
5684
- }
5685
5710
  function ActionsPlugin({
5686
5711
  append,
5687
5712
  prepend
5688
5713
  }) {
5689
5714
  const [editor] = useLexicalComposerContext10();
5715
+ const tr = useTr();
5690
5716
  return /* @__PURE__ */ jsxs64("div", {
5691
5717
  className: "z-50 flex items-center ",
5692
5718
  children: [
5693
- /* @__PURE__ */ jsx86("div", {}),
5719
+ /* @__PURE__ */ jsx87("div", {}),
5694
5720
  /* @__PURE__ */ jsxs64(ActionMenu, {
5695
5721
  children: [
5696
- !prepend ? null : prepend.map((actionItem) => /* @__PURE__ */ jsx86(ActionMenu.Item, {
5722
+ !prepend ? null : prepend.map((actionItem) => /* @__PURE__ */ jsx87(ActionMenu.Item, {
5697
5723
  onSelect: actionItem.action,
5698
5724
  className: actionItem.type === "danger" ? "danger" : "",
5699
5725
  children: actionItem.title
5700
5726
  }, actionItem.title)),
5701
- /* @__PURE__ */ jsx86(ActionMenu.Item, {
5727
+ /* @__PURE__ */ jsx87(ActionMenu.Item, {
5702
5728
  onSelect: () => copyJson(editor),
5703
- children: "Copy JSON"
5704
- }),
5705
- /* @__PURE__ */ jsx86(ActionMenu.Item, {
5706
- onSelect: () => exportJson(editor),
5707
- children: "Export JSON"
5729
+ children: tr("actionCopyJSON")
5708
5730
  }),
5709
- /* @__PURE__ */ jsx86(ActionMenu.Item, {
5731
+ /* @__PURE__ */ jsx87(ActionMenu.Item, {
5710
5732
  className: "danger",
5711
5733
  onSelect: () => {
5712
5734
  editor.dispatchCommand(CLEAR_EDITOR_COMMAND, void 0);
5713
5735
  editor.focus();
5714
5736
  },
5715
- children: "Clear paragraph"
5737
+ children: tr("actionClear")
5716
5738
  }),
5717
- !append ? null : append.map((actionItem) => /* @__PURE__ */ jsx86(ActionMenu.Item, {
5739
+ !append ? null : append.map((actionItem) => /* @__PURE__ */ jsx87(ActionMenu.Item, {
5718
5740
  onSelect: actionItem.action,
5719
5741
  className: actionItem.type === "danger" ? "danger" : "",
5720
5742
  children: actionItem.title
@@ -5726,12 +5748,13 @@ function ActionsPlugin({
5726
5748
  }
5727
5749
 
5728
5750
  // src/rich-text-editor/plugins/ToolbarPlugin/insert-table.tsx
5729
- import { useState as useState8 } from "react";
5751
+ import { useState as useState9 } from "react";
5730
5752
  import { INSERT_TABLE_COMMAND } from "@lexical/table";
5731
- import { Fragment as Fragment7, jsx as jsx87, jsxs as jsxs65 } from "react/jsx-runtime";
5753
+ import { Fragment as Fragment7, jsx as jsx88, jsxs as jsxs65 } from "react/jsx-runtime";
5732
5754
  function InsertTableDialog({ activeEditor }) {
5733
- const [rows, setRows] = useState8("5");
5734
- const [columns, setColumns] = useState8("5");
5755
+ const [rows, setRows] = useState9("5");
5756
+ const [columns, setColumns] = useState9("5");
5757
+ const tr = useTr();
5735
5758
  const onClick = () => {
5736
5759
  if (parseInt(rows) < 1 || parseInt(columns) < 1) {
5737
5760
  return;
@@ -5750,20 +5773,20 @@ function InsertTableDialog({ activeEditor }) {
5750
5773
  /* @__PURE__ */ jsxs65("div", {
5751
5774
  className: "grid grid-cols-[1fr_1px_1fr] border border-gray-100-800 border-solid shadow-sm rounded-md ",
5752
5775
  children: [
5753
- /* @__PURE__ */ jsx87(InputWithLabel, {
5754
- label: "Rows",
5776
+ /* @__PURE__ */ jsx88(InputWithLabel, {
5777
+ label: tr("insertTableRows"),
5755
5778
  value: rows,
5756
5779
  placeholder: "0",
5757
5780
  type: "text",
5758
5781
  inputMode: "numeric",
5759
5782
  onChange: (e) => setRows(e.target.value)
5760
5783
  }),
5761
- /* @__PURE__ */ jsx87("span", {
5784
+ /* @__PURE__ */ jsx88("span", {
5762
5785
  className: "h-full bg-gray-100-800"
5763
5786
  }),
5764
- /* @__PURE__ */ jsx87(InputWithLabel, {
5787
+ /* @__PURE__ */ jsx88(InputWithLabel, {
5765
5788
  type: "text",
5766
- label: "Columns",
5789
+ label: tr("insertTableColumns"),
5767
5790
  placeholder: "0",
5768
5791
  value: columns,
5769
5792
  inputMode: "numeric",
@@ -5771,15 +5794,15 @@ function InsertTableDialog({ activeEditor }) {
5771
5794
  })
5772
5795
  ]
5773
5796
  }),
5774
- /* @__PURE__ */ jsx87("div", {
5797
+ /* @__PURE__ */ jsx88("div", {
5775
5798
  className: "flex justify-end mt-3",
5776
- children: /* @__PURE__ */ jsx87(Button, {
5799
+ children: /* @__PURE__ */ jsx88(Button, {
5777
5800
  as: Dialog.Close,
5778
5801
  size: "sm",
5779
5802
  intent: "action",
5780
- "aria-label": "Confirm",
5803
+ "aria-label": tr("insertTableCommit"),
5781
5804
  onClick,
5782
- children: "Confirm"
5805
+ children: tr("insertTableCommit")
5783
5806
  })
5784
5807
  })
5785
5808
  ]
@@ -5787,7 +5810,7 @@ function InsertTableDialog({ activeEditor }) {
5787
5810
  }
5788
5811
 
5789
5812
  // src/rich-text-editor/plugins/ToolbarPlugin/index.tsx
5790
- import { Fragment as Fragment8, jsx as jsx88, jsxs as jsxs66 } from "react/jsx-runtime";
5813
+ import { Fragment as Fragment8, jsx as jsx89, jsxs as jsxs66 } from "react/jsx-runtime";
5791
5814
  var headingTypeToBlockName = {
5792
5815
  h1: "Heading 1",
5793
5816
  h2: "Heading 2",
@@ -5891,7 +5914,7 @@ function BlockFormatDropDown({
5891
5914
  });
5892
5915
  }
5893
5916
  };
5894
- return /* @__PURE__ */ jsx88(DropdownMenu.Root, {
5917
+ return /* @__PURE__ */ jsx89(DropdownMenu.Root, {
5895
5918
  disabled,
5896
5919
  style: { zIndex: 1 },
5897
5920
  content: /* @__PURE__ */ jsxs66(Fragment8, {
@@ -5899,13 +5922,13 @@ function BlockFormatDropDown({
5899
5922
  /* @__PURE__ */ jsxs66(DropdownMenu.Item, {
5900
5923
  onClick: formatParagraph,
5901
5924
  children: [
5902
- /* @__PURE__ */ jsx88("i", {
5925
+ /* @__PURE__ */ jsx89("i", {
5903
5926
  className: `icon paragraph border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === "paragraph" ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5904
5927
  }),
5905
- /* @__PURE__ */ jsx88("i", {
5928
+ /* @__PURE__ */ jsx89("i", {
5906
5929
  className: "icon paragraph"
5907
5930
  }),
5908
- /* @__PURE__ */ jsx88("span", {
5931
+ /* @__PURE__ */ jsx89("span", {
5909
5932
  className: `${blockType === "paragraph" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5910
5933
  children: "Normal"
5911
5934
  })
@@ -5914,10 +5937,10 @@ function BlockFormatDropDown({
5914
5937
  headings.map((headingSize) => /* @__PURE__ */ jsxs66(DropdownMenu.Item, {
5915
5938
  onClick: () => formatHeading(headingSize),
5916
5939
  children: [
5917
- /* @__PURE__ */ jsx88("i", {
5940
+ /* @__PURE__ */ jsx89("i", {
5918
5941
  className: `icon ${headingSize} border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === headingSize ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5919
5942
  }),
5920
- /* @__PURE__ */ jsx88("span", {
5943
+ /* @__PURE__ */ jsx89("span", {
5921
5944
  className: `${blockType === headingSize ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5922
5945
  children: headingTypeToBlockName[headingSize]
5923
5946
  })
@@ -5926,10 +5949,10 @@ function BlockFormatDropDown({
5926
5949
  /* @__PURE__ */ jsxs66(DropdownMenu.Item, {
5927
5950
  onClick: formatBulletList,
5928
5951
  children: [
5929
- /* @__PURE__ */ jsx88("i", {
5952
+ /* @__PURE__ */ jsx89("i", {
5930
5953
  className: `icon bullet-list border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === "bullet" ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5931
5954
  }),
5932
- /* @__PURE__ */ jsx88("span", {
5955
+ /* @__PURE__ */ jsx89("span", {
5933
5956
  className: `${blockType === "bullet" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5934
5957
  children: "Bullet List"
5935
5958
  })
@@ -5938,10 +5961,10 @@ function BlockFormatDropDown({
5938
5961
  /* @__PURE__ */ jsxs66(DropdownMenu.Item, {
5939
5962
  onClick: formatNumberedList,
5940
5963
  children: [
5941
- /* @__PURE__ */ jsx88("i", {
5964
+ /* @__PURE__ */ jsx89("i", {
5942
5965
  className: `icon numbered-list border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === "number" ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5943
5966
  }),
5944
- /* @__PURE__ */ jsx88("span", {
5967
+ /* @__PURE__ */ jsx89("span", {
5945
5968
  className: `${blockType === "number" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5946
5969
  children: "Numbered List"
5947
5970
  })
@@ -5951,10 +5974,10 @@ function BlockFormatDropDown({
5951
5974
  onClick: formatQuote,
5952
5975
  "data-testid": "toggle-block-format-quote",
5953
5976
  children: [
5954
- /* @__PURE__ */ jsx88("i", {
5977
+ /* @__PURE__ */ jsx89("i", {
5955
5978
  className: `icon quote border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === "quote" ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5956
5979
  }),
5957
- /* @__PURE__ */ jsx88("span", {
5980
+ /* @__PURE__ */ jsx89("span", {
5958
5981
  className: `${blockType === "quote" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5959
5982
  children: "Quote"
5960
5983
  })
@@ -5964,10 +5987,10 @@ function BlockFormatDropDown({
5964
5987
  onClick: formatCode,
5965
5988
  "data-testid": "toggle-block-format-code",
5966
5989
  children: [
5967
- /* @__PURE__ */ jsx88("i", {
5990
+ /* @__PURE__ */ jsx89("i", {
5968
5991
  className: `icon code border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${blockType === "code" ? "opacity-100 bg-purple-50-900" : "opacity-60"}`
5969
5992
  }),
5970
- /* @__PURE__ */ jsx88("span", {
5993
+ /* @__PURE__ */ jsx89("span", {
5971
5994
  className: `${blockType === "code" ? "font-bold" : "font-normal"} text-sm px-3 min-w-[150px]`,
5972
5995
  children: "Code block"
5973
5996
  })
@@ -5980,16 +6003,16 @@ function BlockFormatDropDown({
5980
6003
  "aria-label": "Formatting options for text style",
5981
6004
  "data-testid": "toggle-block-format",
5982
6005
  children: [
5983
- /* @__PURE__ */ jsx88("i", {
6006
+ /* @__PURE__ */ jsx89("i", {
5984
6007
  className: `icon ${blockType} border bg-no-repeat bg-center bg-[length:18px_18px] w-6 h-6`
5985
6008
  }),
5986
- /* @__PURE__ */ jsx88(Icon.Arrow, {})
6009
+ /* @__PURE__ */ jsx89(Icon.Arrow, {})
5987
6010
  ]
5988
6011
  })
5989
6012
  });
5990
6013
  }
5991
6014
  function Divider() {
5992
- return /* @__PURE__ */ jsx88("div", {
6015
+ return /* @__PURE__ */ jsx89("div", {
5993
6016
  className: "divider"
5994
6017
  });
5995
6018
  }
@@ -5998,21 +6021,22 @@ function ToolbarPlugin({
5998
6021
  actionsMenuAppend
5999
6022
  }) {
6000
6023
  const [editor] = useLexicalComposerContext11();
6001
- const [activeEditor, setActiveEditor] = useState9(editor);
6002
- const [blockType, setBlockType] = useState9("paragraph");
6003
- const [selectedElementKey, setSelectedElementKey] = useState9(null);
6004
- const [isLink, setIsLink] = useState9(false);
6005
- const [isBold, setIsBold] = useState9(false);
6006
- const [isItalic, setIsItalic] = useState9(false);
6007
- const [isUnderline, setIsUnderline] = useState9(false);
6008
- const [isStrikethrough, setIsStrikethrough] = useState9(false);
6009
- const [isSubscript, setIsSubscript] = useState9(false);
6010
- const [isSuperscript, setIsSuperscript] = useState9(false);
6011
- const [isCode, setIsCode] = useState9(false);
6012
- const [canUndo, setCanUndo] = useState9(false);
6013
- const [canRedo, setCanRedo] = useState9(false);
6014
- const [codeLanguage, setCodeLanguage] = useState9("");
6015
- const [isEditable, setIsEditable] = useState9(() => editor.isEditable());
6024
+ const [activeEditor, setActiveEditor] = useState10(editor);
6025
+ const [blockType, setBlockType] = useState10("paragraph");
6026
+ const [selectedElementKey, setSelectedElementKey] = useState10(null);
6027
+ const [isLink, setIsLink] = useState10(false);
6028
+ const [isBold, setIsBold] = useState10(false);
6029
+ const [isItalic, setIsItalic] = useState10(false);
6030
+ const [isUnderline, setIsUnderline] = useState10(false);
6031
+ const [isStrikethrough, setIsStrikethrough] = useState10(false);
6032
+ const [isSubscript, setIsSubscript] = useState10(false);
6033
+ const [isSuperscript, setIsSuperscript] = useState10(false);
6034
+ const [isCode, setIsCode] = useState10(false);
6035
+ const [canUndo, setCanUndo] = useState10(false);
6036
+ const [canRedo, setCanRedo] = useState10(false);
6037
+ const tr = useTr();
6038
+ const [codeLanguage, setCodeLanguage] = useState10("");
6039
+ const [isEditable, setIsEditable] = useState10(() => editor.isEditable());
6016
6040
  const updateToolbar = useCallback4(() => {
6017
6041
  const selection = $getSelection9();
6018
6042
  if ($isRangeSelection7(selection)) {
@@ -6060,7 +6084,7 @@ function ToolbarPlugin({
6060
6084
  }
6061
6085
  }
6062
6086
  }, [activeEditor]);
6063
- useEffect10(() => {
6087
+ useEffect11(() => {
6064
6088
  return editor.registerCommand(
6065
6089
  SELECTION_CHANGE_COMMAND3,
6066
6090
  (_payload, newEditor) => {
@@ -6071,7 +6095,7 @@ function ToolbarPlugin({
6071
6095
  COMMAND_PRIORITY_CRITICAL3
6072
6096
  );
6073
6097
  }, [editor, updateToolbar]);
6074
- useEffect10(() => {
6098
+ useEffect11(() => {
6075
6099
  return mergeRegister3(
6076
6100
  editor.registerEditableListener((editable) => {
6077
6101
  setIsEditable(editable);
@@ -6143,138 +6167,138 @@ function ToolbarPlugin({
6143
6167
  /* @__PURE__ */ jsxs66("div", {
6144
6168
  className: "flex",
6145
6169
  children: [
6146
- /* @__PURE__ */ jsx88(IconButton, {
6170
+ /* @__PURE__ */ jsx89(IconButton, {
6147
6171
  disabled: !canUndo || !isEditable,
6148
6172
  onClick: () => {
6149
6173
  activeEditor.dispatchCommand(UNDO_COMMAND, void 0);
6150
6174
  },
6151
- title: IS_APPLE ? "Undo (\u2318Z)" : "Undo (Ctrl+Z)",
6152
6175
  type: "button",
6153
- "aria-label": "Undo",
6154
- children: /* @__PURE__ */ jsx88("i", {
6176
+ title: tr(IS_APPLE ? "actionUndoTitleApple" : "actionUndoTitle"),
6177
+ "aria-label": tr("actionUndoLabel"),
6178
+ children: /* @__PURE__ */ jsx89("i", {
6155
6179
  className: `format icon undo border w-4 h-6 bg-no-repeat bg-center bg-[length:17px_17px] ${canUndo ? "opacity-100" : "opacity-30"}
6156
6180
  `
6157
6181
  })
6158
6182
  }),
6159
- /* @__PURE__ */ jsx88(IconButton, {
6183
+ /* @__PURE__ */ jsx89(IconButton, {
6160
6184
  disabled: !canRedo || !isEditable,
6161
6185
  onClick: () => {
6162
6186
  activeEditor.dispatchCommand(REDO_COMMAND, void 0);
6163
6187
  },
6164
- title: IS_APPLE ? "Redo (\u2318Y)" : "Redo (Ctrl+Y)",
6165
6188
  type: "button",
6166
- "aria-label": "Redo",
6167
- children: /* @__PURE__ */ jsx88("i", {
6189
+ title: tr(IS_APPLE ? "actionRedoTitleApple" : "actionRedoTitle"),
6190
+ "aria-label": tr("actionRedoLabel"),
6191
+ children: /* @__PURE__ */ jsx89("i", {
6168
6192
  className: `format icon redo border w-4 h-6 bg-no-repeat bg-center bg-[length:17px_17px] ${canRedo ? "opacity-100" : "opacity-30"}`
6169
6193
  })
6170
6194
  }),
6171
- /* @__PURE__ */ jsx88(Divider, {}),
6195
+ /* @__PURE__ */ jsx89(Divider, {}),
6172
6196
  blockType in blockTypeToBlockName && activeEditor === editor && /* @__PURE__ */ jsxs66(Fragment8, {
6173
6197
  children: [
6174
- /* @__PURE__ */ jsx88(BlockFormatDropDown, {
6198
+ /* @__PURE__ */ jsx89(BlockFormatDropDown, {
6175
6199
  disabled: !isEditable,
6176
6200
  blockType,
6177
6201
  editor
6178
6202
  }),
6179
- /* @__PURE__ */ jsx88(Divider, {})
6203
+ /* @__PURE__ */ jsx89(Divider, {})
6180
6204
  ]
6181
6205
  }),
6182
- blockType === "code" ? /* @__PURE__ */ jsx88(Fragment8, {
6183
- children: /* @__PURE__ */ jsx88(DropdownMenu.Root, {
6206
+ blockType === "code" ? /* @__PURE__ */ jsx89(Fragment8, {
6207
+ children: /* @__PURE__ */ jsx89(DropdownMenu.Root, {
6184
6208
  disabled: !isEditable,
6185
6209
  style: { zIndex: 1 },
6186
- content: /* @__PURE__ */ jsx88(Fragment8, {
6210
+ content: /* @__PURE__ */ jsx89(Fragment8, {
6187
6211
  children: CODE_LANGUAGE_OPTIONS.map(([value, name]) => {
6188
- return /* @__PURE__ */ jsx88(DropdownMenu.Item, {
6212
+ return /* @__PURE__ */ jsx89(DropdownMenu.Item, {
6189
6213
  className: `item ${dropDownActiveClass(value === codeLanguage)}`,
6190
6214
  onClick: () => onCodeLanguageSelect(value),
6191
- children: /* @__PURE__ */ jsx88("span", {
6215
+ children: /* @__PURE__ */ jsx89("span", {
6192
6216
  className: `text min-w-[200px] block text-sm px-3 ${dropDownActiveClass(value === codeLanguage) ? "font-bold opacity-100" : "font-normal opacity-80"}`,
6193
6217
  children: name
6194
6218
  })
6195
6219
  }, value);
6196
6220
  })
6197
6221
  }),
6198
- children: /* @__PURE__ */ jsx88(Button, {
6199
- "aria-label": "Select language",
6200
- append: /* @__PURE__ */ jsx88(Icon.Arrow, {}),
6201
- children: /* @__PURE__ */ jsx88("span", {
6222
+ children: /* @__PURE__ */ jsx89(Button, {
6223
+ "aria-label": tr("codeSelectLanguage"),
6224
+ append: /* @__PURE__ */ jsx89(Icon.Arrow, {}),
6225
+ children: /* @__PURE__ */ jsx89("span", {
6202
6226
  className: "font-medium text-sm",
6203
6227
  children: getLanguageFriendlyName2(codeLanguage)
6204
6228
  })
6205
6229
  })
6206
6230
  })
6207
- }) : /* @__PURE__ */ jsx88(Dialog, {
6231
+ }) : /* @__PURE__ */ jsx89(Dialog, {
6208
6232
  children: /* @__PURE__ */ jsxs66("div", {
6209
6233
  className: "flex gap-1",
6210
6234
  children: [
6211
- /* @__PURE__ */ jsx88(IconButton, {
6235
+ /* @__PURE__ */ jsx89(IconButton, {
6212
6236
  disabled: !isEditable,
6213
- title: IS_APPLE ? "Bold (\u2318B)" : "Bold (Ctrl+B)",
6214
6237
  className: `${isBold ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6215
6238
  type: "button",
6216
- "aria-label": `Format text as bold. Shortcut: ${IS_APPLE ? "\u2318B" : "Ctrl+B"}`,
6239
+ title: tr(IS_APPLE ? "actionFormatAsStrongTitleApple" : "actionFormatAsStrongTitle"),
6240
+ "aria-label": tr("actionFormatAsStrongLabel"),
6217
6241
  "data-testid": "toggle-format-bold",
6218
6242
  onClick: () => {
6219
6243
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "bold");
6220
6244
  },
6221
- children: /* @__PURE__ */ jsx88("i", {
6245
+ children: /* @__PURE__ */ jsx89("i", {
6222
6246
  className: `format icon bold border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6223
6247
  })
6224
6248
  }),
6225
- /* @__PURE__ */ jsx88(IconButton, {
6249
+ /* @__PURE__ */ jsx89(IconButton, {
6226
6250
  className: `${isItalic ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6227
6251
  disabled: !isEditable,
6228
6252
  onClick: () => {
6229
6253
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "italic");
6230
6254
  },
6231
- title: IS_APPLE ? "Italic (\u2318I)" : "Italic (Ctrl+I)",
6232
6255
  type: "button",
6233
- "aria-label": `Format text as italics. Shortcut: ${IS_APPLE ? "\u2318I" : "Ctrl+I"}`,
6256
+ title: tr(IS_APPLE ? "actionFormatAsEmphasizedTitleApple" : "actionFormatAsEmphasizedTitle"),
6257
+ "aria-label": tr("actionFormatAsEmphasizedLabel"),
6234
6258
  "data-testid": "toggle-format-emphasized",
6235
- children: /* @__PURE__ */ jsx88("i", {
6259
+ children: /* @__PURE__ */ jsx89("i", {
6236
6260
  className: `format icon italic border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6237
6261
  })
6238
6262
  }),
6239
- /* @__PURE__ */ jsx88(IconButton, {
6263
+ /* @__PURE__ */ jsx89(IconButton, {
6240
6264
  className: `${isUnderline ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6241
6265
  disabled: !isEditable,
6242
6266
  onClick: () => {
6243
6267
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "underline");
6244
6268
  },
6245
- title: IS_APPLE ? "Underline (\u2318U)" : "Underline (Ctrl+U)",
6246
6269
  type: "button",
6247
- "aria-label": `Format text to underlined. Shortcut: ${IS_APPLE ? "\u2318U" : "Ctrl+U"}`,
6270
+ title: tr(IS_APPLE ? "actionFormatAsUnderlinedTitleApple" : "actionFormatAsUnderlinedTitle"),
6271
+ "aria-label": tr("actionFormatAsUnderlinedLabel"),
6248
6272
  "data-testid": "toggle-format-underlined",
6249
- children: /* @__PURE__ */ jsx88("i", {
6273
+ children: /* @__PURE__ */ jsx89("i", {
6250
6274
  className: `format icon underline border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6251
6275
  })
6252
6276
  }),
6253
- /* @__PURE__ */ jsx88(IconButton, {
6277
+ /* @__PURE__ */ jsx89(IconButton, {
6254
6278
  className: `${isCode ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6255
6279
  disabled: !isEditable,
6256
6280
  onClick: () => {
6257
6281
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "code");
6258
6282
  },
6259
- title: "Insert code block",
6260
6283
  type: "button",
6261
- "aria-label": "Insert code block",
6262
- children: /* @__PURE__ */ jsx88("i", {
6284
+ title: tr("actionInsertCodeBlock"),
6285
+ "aria-label": tr("actionInsertCodeBlock"),
6286
+ children: /* @__PURE__ */ jsx89("i", {
6263
6287
  className: `format icon code border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6264
6288
  })
6265
6289
  }),
6266
- /* @__PURE__ */ jsx88(IconButton, {
6290
+ /* @__PURE__ */ jsx89(IconButton, {
6267
6291
  className: `${isLink ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`,
6268
6292
  disabled: !isEditable,
6269
6293
  onClick: insertLink,
6270
- "aria-label": "Insert link",
6271
- title: "Insert link",
6272
6294
  type: "button",
6273
- children: /* @__PURE__ */ jsx88("i", {
6295
+ "aria-label": tr("actionInsertlink"),
6296
+ title: tr("actionInsertlink"),
6297
+ children: /* @__PURE__ */ jsx89("i", {
6274
6298
  className: `format icon link border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`
6275
6299
  })
6276
6300
  }),
6277
- /* @__PURE__ */ jsx88(DropdownMenu.Root, {
6301
+ /* @__PURE__ */ jsx89(DropdownMenu.Root, {
6278
6302
  disabled: !isEditable,
6279
6303
  style: { zIndex: 1 },
6280
6304
  content: /* @__PURE__ */ jsxs66(Fragment8, {
@@ -6283,15 +6307,15 @@ function ToolbarPlugin({
6283
6307
  onClick: () => {
6284
6308
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "strikethrough");
6285
6309
  },
6286
- title: "Strikethrough",
6287
- "aria-label": "Format text with a strikethrough",
6310
+ title: tr("actionFormatWithStrikethroughTitle"),
6311
+ "aria-label": tr("actionFormatWithStrikethroughLabel"),
6288
6312
  children: [
6289
- /* @__PURE__ */ jsx88("i", {
6313
+ /* @__PURE__ */ jsx89("i", {
6290
6314
  className: `icon w-6 h-6 strikethrough border bg-no-repeat bg-center bg-[length:16px_16px] rounded-sm ${isStrikethrough ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`
6291
6315
  }),
6292
- /* @__PURE__ */ jsx88("span", {
6316
+ /* @__PURE__ */ jsx89("span", {
6293
6317
  className: `px-3 text-sm font-sans ${isStrikethrough ? "font-medium" : "font-normal"}`,
6294
- children: "Strikethrough"
6318
+ children: tr("actionFormatAsStrongTitle")
6295
6319
  })
6296
6320
  ]
6297
6321
  }),
@@ -6299,15 +6323,15 @@ function ToolbarPlugin({
6299
6323
  onClick: () => {
6300
6324
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "subscript");
6301
6325
  },
6302
- title: "Subscript",
6303
- "aria-label": "Format text with a subscript",
6326
+ title: tr("actionFormatWithSubscriptTitle"),
6327
+ "aria-label": tr("actionFormatWithSubscriptLabel"),
6304
6328
  children: [
6305
- /* @__PURE__ */ jsx88("i", {
6329
+ /* @__PURE__ */ jsx89("i", {
6306
6330
  className: `icon w-6 h-6 subscript border bg-no-repeat bg-center bg-[length:16px_16px] rounded-sm ${isSubscript ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`
6307
6331
  }),
6308
- /* @__PURE__ */ jsx88("span", {
6332
+ /* @__PURE__ */ jsx89("span", {
6309
6333
  className: `px-3 text-sm font-sans ${isSubscript ? "font-medium" : "font-normal"}`,
6310
- children: "Subscript"
6334
+ children: tr("actionFormatWithSubscriptTitle")
6311
6335
  })
6312
6336
  ]
6313
6337
  }),
@@ -6315,28 +6339,28 @@ function ToolbarPlugin({
6315
6339
  onClick: () => {
6316
6340
  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND2, "superscript");
6317
6341
  },
6318
- title: "Superscript",
6319
- "aria-label": "Format text with a superscript",
6342
+ title: tr("actionFormatWithSuperscriptTitle"),
6343
+ "aria-label": tr("actionFormatWithSuperscriptLabel"),
6320
6344
  children: [
6321
- /* @__PURE__ */ jsx88("i", {
6345
+ /* @__PURE__ */ jsx89("i", {
6322
6346
  className: `icon w-6 h-6 superscript border bg-no-repeat bg-center bg-[length:16px_16px] rounded-sm ${isSuperscript ? "opacity-100 !bg-purple-50-900" : "opacity-60"}`
6323
6347
  }),
6324
- /* @__PURE__ */ jsx88("span", {
6348
+ /* @__PURE__ */ jsx89("span", {
6325
6349
  className: `px-3 text-sm font-sans ${isSuperscript ? "bg-purple-50-900" : "font-normal"}`,
6326
- children: "Superscript"
6350
+ children: tr("actionFormatWithSuperscriptTitle")
6327
6351
  })
6328
6352
  ]
6329
6353
  }),
6330
6354
  /* @__PURE__ */ jsxs66(DropdownMenu.Item, {
6331
6355
  onClick: clearFormatting,
6332
6356
  className: "item",
6333
- title: "Clear text formatting",
6334
- "aria-label": "Clear all text formatting",
6357
+ title: tr("actionClearTextFormatting"),
6358
+ "aria-label": tr("actionClearTextFormatting"),
6335
6359
  children: [
6336
- /* @__PURE__ */ jsx88("i", {
6360
+ /* @__PURE__ */ jsx89("i", {
6337
6361
  className: "icon w-6 h-6 clear border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6338
6362
  }),
6339
- /* @__PURE__ */ jsx88("span", {
6363
+ /* @__PURE__ */ jsx89("span", {
6340
6364
  className: "px-3 text-sm text-pink-600-300 font-sans font-normal",
6341
6365
  children: "Clear Formatting"
6342
6366
  })
@@ -6346,50 +6370,50 @@ function ToolbarPlugin({
6346
6370
  }),
6347
6371
  children: /* @__PURE__ */ jsxs66(Button, {
6348
6372
  style: { backgroundColor: "transparent", padding: "0 8px" },
6349
- "aria-label": "Formatting options for additional text styles",
6373
+ "aria-label": tr("actionTextFormattingOptions"),
6350
6374
  children: [
6351
- /* @__PURE__ */ jsx88("i", {
6375
+ /* @__PURE__ */ jsx89("i", {
6352
6376
  className: `icon dropdown-more border bg-no-repeat bg-center bg-[length:18px_18px] w-6 h-6`
6353
6377
  }),
6354
- /* @__PURE__ */ jsx88(Icon.Arrow, {})
6378
+ /* @__PURE__ */ jsx89(Icon.Arrow, {})
6355
6379
  ]
6356
6380
  })
6357
6381
  }),
6358
- /* @__PURE__ */ jsx88(Divider, {}),
6359
- /* @__PURE__ */ jsx88(DropdownMenu.Root, {
6382
+ /* @__PURE__ */ jsx89(Divider, {}),
6383
+ /* @__PURE__ */ jsx89(DropdownMenu.Root, {
6360
6384
  style: { zIndex: 1 },
6361
6385
  disabled: !isEditable,
6362
6386
  content: /* @__PURE__ */ jsxs66(Fragment8, {
6363
6387
  children: [
6364
- /* @__PURE__ */ jsx88(DropdownMenu.Item, {
6388
+ /* @__PURE__ */ jsx89(DropdownMenu.Item, {
6365
6389
  onClick: () => {
6366
6390
  activeEditor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, void 0);
6367
6391
  },
6368
6392
  children: /* @__PURE__ */ jsxs66("div", {
6369
6393
  className: "flex items-center font-sans font-normal",
6370
6394
  children: [
6371
- /* @__PURE__ */ jsx88("i", {
6395
+ /* @__PURE__ */ jsx89("i", {
6372
6396
  className: "icon w-5 h-5 horizontal-rule border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6373
6397
  }),
6374
- /* @__PURE__ */ jsx88("span", {
6398
+ /* @__PURE__ */ jsx89("span", {
6375
6399
  className: "px-3 text-sm",
6376
- children: "Horizontal rule"
6400
+ children: tr("horizontalRule")
6377
6401
  })
6378
6402
  ]
6379
6403
  })
6380
6404
  }),
6381
- /* @__PURE__ */ jsx88(DropdownMenu.Item, {
6382
- children: /* @__PURE__ */ jsx88(Dialog.Trigger, {
6405
+ /* @__PURE__ */ jsx89(DropdownMenu.Item, {
6406
+ children: /* @__PURE__ */ jsx89(Dialog.Trigger, {
6383
6407
  asChild: true,
6384
6408
  children: /* @__PURE__ */ jsxs66("div", {
6385
6409
  className: "flex items-center font-sans font-normal",
6386
6410
  children: [
6387
- /* @__PURE__ */ jsx88("i", {
6411
+ /* @__PURE__ */ jsx89("i", {
6388
6412
  className: "icon w-5 h-5 table border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60"
6389
6413
  }),
6390
- /* @__PURE__ */ jsx88("span", {
6414
+ /* @__PURE__ */ jsx89("span", {
6391
6415
  className: "px-3 text-sm",
6392
- children: "Table"
6416
+ children: tr("table")
6393
6417
  })
6394
6418
  ]
6395
6419
  })
@@ -6397,23 +6421,23 @@ function ToolbarPlugin({
6397
6421
  })
6398
6422
  ]
6399
6423
  }),
6400
- children: /* @__PURE__ */ jsx88(IconButton, {
6401
- children: /* @__PURE__ */ jsx88("i", {
6424
+ children: /* @__PURE__ */ jsx89(IconButton, {
6425
+ children: /* @__PURE__ */ jsx89("i", {
6402
6426
  className: "icon plus border w-full h-full bg-no-repeat bg-center bg-[length:20px_20px] "
6403
6427
  })
6404
6428
  })
6405
6429
  }),
6406
6430
  /* @__PURE__ */ jsxs66(Dialog.Content, {
6407
6431
  children: [
6408
- /* @__PURE__ */ jsx88(Dialog.Title, {
6409
- children: "Insert table"
6432
+ /* @__PURE__ */ jsx89(Dialog.Title, {
6433
+ children: tr("insertTableTitle")
6410
6434
  }),
6411
- /* @__PURE__ */ jsx88(Dialog.Description, {
6412
- children: "Define your starting point of a table, you can add and remove columns and rows after creation."
6435
+ /* @__PURE__ */ jsx89(Dialog.Description, {
6436
+ children: tr("insertTableDescription")
6413
6437
  }),
6414
- /* @__PURE__ */ jsx88("div", {
6438
+ /* @__PURE__ */ jsx89("div", {
6415
6439
  className: "items-center justify-between",
6416
- children: /* @__PURE__ */ jsx88(InsertTableDialog, {
6440
+ children: /* @__PURE__ */ jsx89(InsertTableDialog, {
6417
6441
  activeEditor
6418
6442
  })
6419
6443
  })
@@ -6424,7 +6448,7 @@ function ToolbarPlugin({
6424
6448
  })
6425
6449
  ]
6426
6450
  }),
6427
- /* @__PURE__ */ jsx88(ActionsPlugin, {
6451
+ /* @__PURE__ */ jsx89(ActionsPlugin, {
6428
6452
  prepend: actionsMenuPrepend,
6429
6453
  append: actionsMenuAppend
6430
6454
  })
@@ -6534,21 +6558,13 @@ var theme = {
6534
6558
  };
6535
6559
  var CrystallizeRTEditorTheme_default = theme;
6536
6560
 
6537
- // src/rich-text-editor/ui/ContentEditable.tsx
6538
- import "react";
6539
- import { ContentEditable } from "@lexical/react/LexicalContentEditable";
6540
- import { jsx as jsx89 } from "react/jsx-runtime";
6541
- function LexicalContentEditable({ className }) {
6542
- return /* @__PURE__ */ jsx89(ContentEditable, {
6543
- className: className || "ContentEditable__root"
6544
- });
6545
- }
6546
-
6547
6561
  // src/rich-text-editor/rich-text-editor.tsx
6548
6562
  import { Fragment as Fragment9, jsx as jsx90, jsxs as jsxs67 } from "react/jsx-runtime";
6549
6563
  function RichTextEditor({
6550
6564
  initialData,
6551
6565
  editable = true,
6566
+ language = "en",
6567
+ labelTranslations,
6552
6568
  ...rest
6553
6569
  }) {
6554
6570
  return /* @__PURE__ */ jsx90(LexicalComposer, {
@@ -6564,12 +6580,16 @@ function RichTextEditor({
6564
6580
  richText: initialData
6565
6581
  }) : void 0
6566
6582
  },
6567
- children: /* @__PURE__ */ jsx90(SharedHistoryContext, {
6568
- children: /* @__PURE__ */ jsx90("div", {
6569
- className: "c-rich-text-editor",
6570
- children: /* @__PURE__ */ jsx90(RichTextEditorWithoutContext, {
6571
- ...rest,
6572
- editable
6583
+ children: /* @__PURE__ */ jsx90(I18nProvider, {
6584
+ language,
6585
+ labelTranslations,
6586
+ children: /* @__PURE__ */ jsx90(SharedHistoryContext, {
6587
+ children: /* @__PURE__ */ jsx90("div", {
6588
+ className: "c-rich-text-editor",
6589
+ children: /* @__PURE__ */ jsx90(RichTextEditorWithoutContext, {
6590
+ ...rest,
6591
+ editable
6592
+ })
6573
6593
  })
6574
6594
  })
6575
6595
  })
@@ -6592,18 +6612,18 @@ function RichTextEditorWithoutContext({
6592
6612
  children: placeholderText ?? ""
6593
6613
  });
6594
6614
  const [editor] = useLexicalComposerContext12();
6595
- const [floatingAnchorElem, setFloatingAnchorElem] = useState10(null);
6596
- const [isSmallWidthViewport, setIsSmallWidthViewport] = useState10(false);
6615
+ const [floatingAnchorElem, setFloatingAnchorElem] = useState11(null);
6616
+ const [isSmallWidthViewport, setIsSmallWidthViewport] = useState11(false);
6597
6617
  const firstOnChangeTriggeredRef = useRef5(!autoFocus);
6598
6618
  const onRef = (_floatingAnchorElem) => {
6599
6619
  if (_floatingAnchorElem !== null) {
6600
6620
  setFloatingAnchorElem(_floatingAnchorElem);
6601
6621
  }
6602
6622
  };
6603
- useEffect11(() => {
6623
+ useEffect12(() => {
6604
6624
  editor.setEditable(editable || false);
6605
6625
  }, [editable, editor]);
6606
- useEffect11(() => {
6626
+ useEffect12(() => {
6607
6627
  const updateViewPortWidth = () => {
6608
6628
  const isNextSmallWidthViewport = window.matchMedia("(max-width: 1025px)").matches;
6609
6629
  if (isNextSmallWidthViewport !== isSmallWidthViewport) {
@@ -6652,7 +6672,9 @@ function RichTextEditorWithoutContext({
6652
6672
  children: /* @__PURE__ */ jsx90("div", {
6653
6673
  className: "editor",
6654
6674
  ref: onRef,
6655
- children: /* @__PURE__ */ jsx90(LexicalContentEditable, {})
6675
+ children: /* @__PURE__ */ jsx90(ContentEditable, {
6676
+ className: "ContentEditable__root"
6677
+ })
6656
6678
  })
6657
6679
  }),
6658
6680
  placeholder,