@intlayer/design-system 9.3.0 → 9.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +22 -22
  2. package/dist/esm/api/hooks/utils.mjs +2 -1
  3. package/dist/esm/api/hooks/utils.mjs.map +1 -1
  4. package/dist/esm/api/index.mjs +2 -2
  5. package/dist/esm/api/useAuth/useOAuth2.mjs +13 -3
  6. package/dist/esm/api/useAuth/useOAuth2.mjs.map +1 -1
  7. package/dist/esm/api/useAuth/useSession.mjs +6 -4
  8. package/dist/esm/api/useAuth/useSession.mjs.map +1 -1
  9. package/dist/esm/components/Accordion/Accordion.mjs +1 -1
  10. package/dist/esm/components/Avatar/index.mjs +1 -1
  11. package/dist/esm/components/Badge/index.mjs +1 -1
  12. package/dist/esm/components/Breadcrumb/index.mjs +1 -1
  13. package/dist/esm/components/Browser/Browser.mjs +1 -1
  14. package/dist/esm/components/Button/Button.mjs +1 -1
  15. package/dist/esm/components/Carousel/index.mjs +1 -1
  16. package/dist/esm/components/CollapsibleTable/CollapsibleTable.mjs +1 -1
  17. package/dist/esm/components/Command/index.mjs +1 -1
  18. package/dist/esm/components/Container/index.mjs +1 -1
  19. package/dist/esm/components/ContentEditor/ContentEditor.mjs +1 -1
  20. package/dist/esm/components/ContentEditor/ContentEditorInput.mjs +1 -1
  21. package/dist/esm/components/ContentEditor/ContentEditorTextArea.mjs +2 -2
  22. package/dist/esm/components/CopyButton/index.mjs +1 -1
  23. package/dist/esm/components/CopyToClipboard/index.mjs +1 -1
  24. package/dist/esm/components/DictionaryEditor/NodeWrapper/BooleanWrapper.mjs +2 -1
  25. package/dist/esm/components/DictionaryEditor/NodeWrapper/BooleanWrapper.mjs.map +1 -1
  26. package/dist/esm/components/DictionaryEditor/NodeWrapper/NumberWrapper.mjs +2 -1
  27. package/dist/esm/components/DictionaryEditor/NodeWrapper/NumberWrapper.mjs.map +1 -1
  28. package/dist/esm/components/DictionaryFieldEditor/ContentEditor.mjs +2 -2
  29. package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs +3 -3
  30. package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs +1 -1
  31. package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs +7 -7
  32. package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs +2 -2
  33. package/dist/esm/components/DictionaryFieldEditor/KeyPathBreadcrumb.mjs +8 -7
  34. package/dist/esm/components/DictionaryFieldEditor/KeyPathBreadcrumb.mjs.map +1 -1
  35. package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs +8 -5
  36. package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs.map +1 -1
  37. package/dist/esm/components/DictionaryFieldEditor/NodeTypeSelector.mjs +2 -1
  38. package/dist/esm/components/DictionaryFieldEditor/NodeTypeSelector.mjs.map +1 -1
  39. package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs +3 -3
  40. package/dist/esm/components/DictionaryFieldEditor/StructureEditor.mjs +2 -1
  41. package/dist/esm/components/DictionaryFieldEditor/StructureEditor.mjs.map +1 -1
  42. package/dist/esm/components/DictionaryFieldEditor/StructureView/StructureView.mjs +2 -2
  43. package/dist/esm/components/DictionaryFieldEditor/VersionSwitcherDropDown/VersionSwitcher.mjs +1 -1
  44. package/dist/esm/components/EditableField/EditableFieldInput.mjs +6 -5
  45. package/dist/esm/components/EditableField/EditableFieldInput.mjs.map +1 -1
  46. package/dist/esm/components/EditableField/EditableFieldLayout.mjs +1 -1
  47. package/dist/esm/components/EditableField/EditableFieldTextArea.mjs +2 -1
  48. package/dist/esm/components/EditableField/EditableFieldTextArea.mjs.map +1 -1
  49. package/dist/esm/components/Form/elements/OTPElement.mjs +1 -1
  50. package/dist/esm/components/HTMLRender/HTMLRender.mjs +5 -3
  51. package/dist/esm/components/HTMLRender/HTMLRender.mjs.map +1 -1
  52. package/dist/esm/components/HideShow/index.mjs +1 -1
  53. package/dist/esm/components/IDE/Code.mjs.map +1 -1
  54. package/dist/esm/components/IDE/CodeBlockClient.mjs.map +1 -1
  55. package/dist/esm/components/IDE/CodeBlockHighlight.mjs +3 -14
  56. package/dist/esm/components/IDE/CodeBlockHighlight.mjs.map +1 -1
  57. package/dist/esm/components/IDE/CodeBlockServer.mjs +14 -12
  58. package/dist/esm/components/IDE/CodeBlockServer.mjs.map +1 -1
  59. package/dist/esm/components/IDE/CodeBlockShiki.mjs +32 -86
  60. package/dist/esm/components/IDE/CodeBlockShiki.mjs.map +1 -1
  61. package/dist/esm/components/IDE/FileTree.mjs +3 -2
  62. package/dist/esm/components/IDE/FileTree.mjs.map +1 -1
  63. package/dist/esm/components/IDE/MarkDownRender.mjs.map +1 -1
  64. package/dist/esm/components/IDE/shikiLanguages.mjs +122 -0
  65. package/dist/esm/components/IDE/shikiLanguages.mjs.map +1 -0
  66. package/dist/esm/components/Input/Checkbox.mjs +1 -1
  67. package/dist/esm/components/Input/Input.mjs +1 -1
  68. package/dist/esm/components/Input/InputPassword.mjs +1 -1
  69. package/dist/esm/components/Input/OTPInput.mjs +5 -4
  70. package/dist/esm/components/Input/OTPInput.mjs.map +1 -1
  71. package/dist/esm/components/Input/Radio.mjs +1 -1
  72. package/dist/esm/components/Input/SearchInput.mjs +1 -1
  73. package/dist/esm/components/LanguageBackground/LanguageBackground.mjs +2 -1
  74. package/dist/esm/components/LanguageBackground/LanguageBackground.mjs.map +1 -1
  75. package/dist/esm/components/Link/Link.mjs +1 -1
  76. package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs +7 -6
  77. package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs.map +1 -1
  78. package/dist/esm/components/LocaleSwitcherDropDown/LocaleSwitcher.mjs +1 -1
  79. package/dist/esm/components/MarkDownRender/MarkDownIframe.mjs +1 -1
  80. package/dist/esm/components/MarkDownRender/MarkDownRender.mjs +12 -7
  81. package/dist/esm/components/MarkDownRender/MarkDownRender.mjs.map +1 -1
  82. package/dist/esm/components/MarkdownEditor/generative/AICompletionCommands.mjs +1 -1
  83. package/dist/esm/components/MarkdownEditor/generative/AISelector.mjs +1 -1
  84. package/dist/esm/components/MarkdownEditor/generative/AISelectorCommands.mjs +1 -1
  85. package/dist/esm/components/MarkdownEditor/generative/GenerativeMenuSwitch.mjs +1 -1
  86. package/dist/esm/components/MarkdownEditor/selectors/ColorSelector.mjs +1 -1
  87. package/dist/esm/components/MarkdownEditor/selectors/LinkSelector.mjs +1 -1
  88. package/dist/esm/components/MarkdownEditor/selectors/NodeSelector.mjs +1 -1
  89. package/dist/esm/components/MarkdownEditor/selectors/TextButtons.mjs +1 -1
  90. package/dist/esm/components/MarkdownEditor/slashCommand.mjs +1 -1
  91. package/dist/esm/components/Modal/Modal.mjs +3 -3
  92. package/dist/esm/components/Navbar/MobileNavbar.mjs +1 -1
  93. package/dist/esm/components/Pagination/Pagination.mjs +2 -2
  94. package/dist/esm/components/PressableSpan/PressableSpan.mjs +0 -2
  95. package/dist/esm/components/PressableSpan/PressableSpan.mjs.map +1 -1
  96. package/dist/esm/components/RightDrawer/RightDrawer.mjs +4 -4
  97. package/dist/esm/components/Select/Multiselect.mjs +3 -5
  98. package/dist/esm/components/Select/Multiselect.mjs.map +1 -1
  99. package/dist/esm/components/Select/Select.mjs +1 -1
  100. package/dist/esm/components/SwitchSelector/SwitchSelector.mjs +1 -1
  101. package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs +1 -1
  102. package/dist/esm/components/Tab/Tab.mjs +2 -2
  103. package/dist/esm/components/TabSelector/TabSelector.mjs +1 -1
  104. package/dist/esm/components/Table/ExpandButton.mjs +1 -1
  105. package/dist/esm/components/Tag/index.mjs +1 -1
  106. package/dist/esm/components/Terminal/Terminal.mjs +7 -5
  107. package/dist/esm/components/Terminal/Terminal.mjs.map +1 -1
  108. package/dist/esm/components/TextArea/AutocompleteTextArea.mjs +6 -3
  109. package/dist/esm/components/TextArea/AutocompleteTextArea.mjs.map +1 -1
  110. package/dist/esm/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs +1 -1
  111. package/dist/esm/components/ThemeSwitcherDropDown/MobileThemeSwitcher.mjs +1 -1
  112. package/dist/esm/components/Toaster/Toast.mjs +1 -1
  113. package/dist/esm/components/Toaster/useToast.mjs +1 -1
  114. package/dist/esm/components/Toaster/useToast.mjs.map +1 -1
  115. package/dist/esm/hooks/index.mjs +8 -8
  116. package/dist/esm/hooks/useScrollDetection.mjs +4 -2
  117. package/dist/esm/hooks/useScrollDetection.mjs.map +1 -1
  118. package/dist/esm/providers/DeferredAuthProvider.mjs +75 -0
  119. package/dist/esm/providers/DeferredAuthProvider.mjs.map +1 -0
  120. package/dist/esm/providers/ReactQueryProvider.mjs +4 -4
  121. package/dist/esm/providers/ReactQueryProvider.mjs.map +1 -1
  122. package/dist/esm/providers/index.mjs +2 -1
  123. package/dist/esm/routes.mjs +12 -11
  124. package/dist/esm/routes.mjs.map +1 -1
  125. package/dist/esm/structured-data/buildAuthorJsonLd.mjs +6 -3
  126. package/dist/esm/structured-data/buildAuthorJsonLd.mjs.map +1 -1
  127. package/dist/esm/structured-data/buildBreadcrumbsJsonLd.mjs +4 -1
  128. package/dist/esm/structured-data/buildBreadcrumbsJsonLd.mjs.map +1 -1
  129. package/dist/esm/structured-data/buildCreativeWorkJsonLd.mjs +7 -5
  130. package/dist/esm/structured-data/buildCreativeWorkJsonLd.mjs.map +1 -1
  131. package/dist/esm/structured-data/buildOrganizationJsonLd.mjs +27 -21
  132. package/dist/esm/structured-data/buildOrganizationJsonLd.mjs.map +1 -1
  133. package/dist/esm/structured-data/buildProductJsonLd.mjs +5 -2
  134. package/dist/esm/structured-data/buildProductJsonLd.mjs.map +1 -1
  135. package/dist/esm/structured-data/buildSoftwareApplicationJsonLd.mjs +59 -51
  136. package/dist/esm/structured-data/buildSoftwareApplicationJsonLd.mjs.map +1 -1
  137. package/dist/esm/structured-data/buildWebsiteJsonLd.mjs +31 -25
  138. package/dist/esm/structured-data/buildWebsiteJsonLd.mjs.map +1 -1
  139. package/dist/esm/structured-data/index.mjs +2 -1
  140. package/dist/esm/structured-data/normalizeJsonLdUrl.mjs +34 -0
  141. package/dist/esm/structured-data/normalizeJsonLdUrl.mjs.map +1 -0
  142. package/dist/esm/tailwind.config.mjs +4 -2
  143. package/dist/esm/tailwind.config.mjs.map +1 -1
  144. package/dist/types/api/index.d.ts +2 -2
  145. package/dist/types/api/useAuth/index.d.ts +2 -2
  146. package/dist/types/api/useAuth/useOAuth2.d.ts +12 -3
  147. package/dist/types/api/useAuth/useOAuth2.d.ts.map +1 -1
  148. package/dist/types/api/useAuth/useSession.d.ts.map +1 -1
  149. package/dist/types/components/IDE/Code.d.ts +2 -2
  150. package/dist/types/components/IDE/CodeBlockClient.d.ts +2 -2
  151. package/dist/types/components/IDE/CodeBlockHighlight.d.ts +2 -2
  152. package/dist/types/components/IDE/CodeBlockHighlight.d.ts.map +1 -1
  153. package/dist/types/components/IDE/CodeBlockShiki.d.ts +2 -2
  154. package/dist/types/components/IDE/CodeBlockShiki.d.ts.map +1 -1
  155. package/dist/types/components/IDE/index.d.ts +2 -1
  156. package/dist/types/components/IDE/shikiLanguages.d.ts +138 -0
  157. package/dist/types/components/IDE/shikiLanguages.d.ts.map +1 -0
  158. package/dist/types/components/index.d.ts +2 -1
  159. package/dist/types/providers/DeferredAuthProvider.d.ts +33 -0
  160. package/dist/types/providers/DeferredAuthProvider.d.ts.map +1 -0
  161. package/dist/types/providers/index.d.ts +2 -1
  162. package/dist/types/routes.d.ts +17 -16
  163. package/dist/types/routes.d.ts.map +1 -1
  164. package/dist/types/structured-data/buildAuthorJsonLd.d.ts.map +1 -1
  165. package/dist/types/structured-data/buildBreadcrumbsJsonLd.d.ts.map +1 -1
  166. package/dist/types/structured-data/buildCreativeWorkJsonLd.d.ts.map +1 -1
  167. package/dist/types/structured-data/buildOrganizationJsonLd.d.ts.map +1 -1
  168. package/dist/types/structured-data/buildProductJsonLd.d.ts.map +1 -1
  169. package/dist/types/structured-data/buildSoftwareApplicationJsonLd.d.ts.map +1 -1
  170. package/dist/types/structured-data/buildWebsiteJsonLd.d.ts.map +1 -1
  171. package/dist/types/structured-data/index.d.ts +2 -1
  172. package/dist/types/structured-data/normalizeJsonLdUrl.d.ts +28 -0
  173. package/dist/types/structured-data/normalizeJsonLdUrl.d.ts.map +1 -0
  174. package/package.json +43 -43
@@ -1,16 +1,16 @@
1
1
  'use client';
2
2
 
3
3
  import { cn } from "../../../utils/cn.mjs";
4
- import { Loader } from "../../Loader/index.mjs";
5
- import { Button } from "../../Button/Button.mjs";
6
- import { Container } from "../../Container/index.mjs";
7
- import { Checkbox } from "../../Input/Checkbox.mjs";
8
- import { Input } from "../../Input/Input.mjs";
9
4
  import { useSession } from "../../../api/useAuth/useSession.mjs";
10
5
  import { useAuditContentDeclarationMetadata } from "../../../api/hooks/ai.mjs";
11
6
  import { useGetDictionaries } from "../../../api/hooks/dictionary.mjs";
12
7
  import { useGetProjects } from "../../../api/hooks/project.mjs";
13
8
  import { useGetTags } from "../../../api/hooks/tag.mjs";
9
+ import { Loader } from "../../Loader/index.mjs";
10
+ import { Button } from "../../Button/Button.mjs";
11
+ import { Container } from "../../Container/index.mjs";
12
+ import { Checkbox } from "../../Input/Checkbox.mjs";
13
+ import { Input } from "../../Input/Input.mjs";
14
14
  import { MultiSelect } from "../../Select/Multiselect.mjs";
15
15
  import { Select } from "../../Select/Select.mjs";
16
16
  import { Pagination } from "../../Pagination/Pagination.mjs";
@@ -28,10 +28,10 @@ import { useForm as useForm$1 } from "../../Form/FormBase.mjs";
28
28
  import { Form } from "../../Form/Form.mjs";
29
29
  import { useDictionaryDetailsSchema } from "./useDictionaryDetailsSchema.mjs";
30
30
  import { useEffect, useMemo, useState } from "react";
31
- import { WandSparkles } from "lucide-react";
32
31
  import { jsx, jsxs } from "react/jsx-runtime";
33
- import { useIntlayer } from "react-intlayer";
32
+ import { WandSparkles } from "lucide-react";
34
33
  import { useEditedContent } from "@intlayer/editor-react";
34
+ import { useIntlayer } from "react-intlayer";
35
35
  import { useWatch } from "react-hook-form";
36
36
  import { AnimatePresence, motion } from "framer-motion";
37
37
 
@@ -11,10 +11,10 @@ import { JSONEditor } from "./JSONEditor.mjs";
11
11
  import { SaveForm } from "./SaveForm/SaveForm.mjs";
12
12
  import { StructureEditor } from "./StructureEditor.mjs";
13
13
  import { useEffect, useState } from "react";
14
- import { ArrowLeft } from "lucide-react";
15
14
  import { jsx, jsxs } from "react/jsx-runtime";
16
- import { useIntlayer } from "react-intlayer";
15
+ import { ArrowLeft } from "lucide-react";
17
16
  import { useConfiguration, useDictionariesRecordActions, useFocusUnmergedDictionary } from "@intlayer/editor-react";
17
+ import { useIntlayer } from "react-intlayer";
18
18
 
19
19
  //#region src/components/DictionaryFieldEditor/DictionaryFieldEditor.tsx
20
20
  const DictionaryFieldEditor = ({ dictionary, onClickDictionaryList, isDarkMode, mode, onDelete, onSave, showReturnButton = true, rightContent }) => {
@@ -4,14 +4,15 @@ import { camelCaseToSentence } from "@intlayer/config/client";
4
4
 
5
5
  //#region src/components/DictionaryFieldEditor/KeyPathBreadcrumb.tsx
6
6
  const KeyPathBreadcrumb = ({ keyPath, dictionaryKey, onClickKeyPath, locale, color, showDictionaryKey = true }) => {
7
+ const formattedKeyPath = [...showDictionaryKey ? [{
8
+ text: camelCaseToSentence(dictionaryKey),
9
+ onClick: onClickKeyPath ? () => onClickKeyPath([]) : void 0
10
+ }] : [], ...keyPath.map((el, index) => ({
11
+ onClick: onClickKeyPath ? () => onClickKeyPath?.(keyPath.slice(0, index + 1)) : void 0,
12
+ text: camelCaseToSentence(el.key?.toString() ?? "")
13
+ }))];
7
14
  return /* @__PURE__ */ jsx(Breadcrumb, {
8
- links: [...showDictionaryKey ? [{
9
- text: camelCaseToSentence(dictionaryKey),
10
- onClick: onClickKeyPath ? () => onClickKeyPath([]) : void 0
11
- }] : [], ...keyPath.map((el, index) => ({
12
- onClick: onClickKeyPath ? () => onClickKeyPath?.(keyPath.slice(0, index + 1)) : void 0,
13
- text: camelCaseToSentence(el.key?.toString() ?? "")
14
- }))],
15
+ links: formattedKeyPath,
15
16
  locale,
16
17
  elementType: "location",
17
18
  color
@@ -1 +1 @@
1
- {"version":3,"file":"KeyPathBreadcrumb.mjs","names":[],"sources":["../../../../src/components/DictionaryFieldEditor/KeyPathBreadcrumb.tsx"],"sourcesContent":["import { camelCaseToSentence } from '@intlayer/config/client';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type { FC } from 'react';\nimport { Breadcrumb, type BreadcrumbLink } from '../Breadcrumb';\nimport type { LinkColor } from '../Link';\n\ntype KeyPathBreadcrumbProps = {\n dictionaryKey: string;\n keyPath: KeyPath[];\n onClickKeyPath?: (keyPath: KeyPath[]) => void;\n locale?: Locale;\n color?: LinkColor | `${LinkColor}`;\n showDictionaryKey?: boolean;\n};\n\nexport const KeyPathBreadcrumb: FC<KeyPathBreadcrumbProps> = ({\n keyPath,\n dictionaryKey,\n onClickKeyPath,\n locale,\n color,\n showDictionaryKey = true,\n}) => {\n const formattedKeyPath: BreadcrumbLink[] = [\n ...(showDictionaryKey\n ? [\n {\n text: camelCaseToSentence(dictionaryKey),\n onClick: onClickKeyPath ? () => onClickKeyPath([]) : undefined,\n },\n ]\n : []),\n ...keyPath.map((el, index) => ({\n onClick: onClickKeyPath\n ? () =>\n // With keyPath = [{type: NodeTypes.Object, key: '0'}, {type: NodeTypes.Array, key: '0'}, {type: NodeTypes.Object, key: '1'}]\n // If index is 0 -> onFocusKeyPath([{type: NodeTypes.Object, key: '0'}])\n // If index is 1 -> onFocusKeyPath([{type: NodeTypes.Object, key: '0'}, {type: NodeTypes.Array, key: '0'}])\n onClickKeyPath?.(keyPath.slice(0, index + 1))\n : undefined,\n\n text: camelCaseToSentence(el.key?.toString() ?? ''),\n })),\n ];\n\n return (\n <Breadcrumb\n links={formattedKeyPath}\n locale={locale}\n elementType=\"location\"\n color={color}\n />\n );\n};\n"],"mappings":";;;;;AAgBA,MAAa,qBAAiD,EAC5D,SACA,eACA,gBACA,QACA,OACA,oBAAoB,WAChB;CAuBJ,OACE,oBAAC,YAAD;EACE,OAAO,CAvBT,GAAI,oBACA,CACE;GACE,MAAM,oBAAoB,aAAa;GACvC,SAAS,uBAAuB,eAAe,CAAC,CAAC,IAAI;EACvD,CACF,IACA,CAAC,GACL,GAAG,QAAQ,KAAK,IAAI,WAAW;GAC7B,SAAS,uBAKH,iBAAiB,QAAQ,MAAM,GAAG,QAAQ,CAAC,CAAC,IAC9C;GAEJ,MAAM,oBAAoB,GAAG,KAAK,SAAS,KAAK,EAAE;EACpD,EAAE,CAKsB;EACd;EACR,aAAY;EACL;CACR;AAEL"}
1
+ {"version":3,"file":"KeyPathBreadcrumb.mjs","names":[],"sources":["../../../../src/components/DictionaryFieldEditor/KeyPathBreadcrumb.tsx"],"sourcesContent":["import { camelCaseToSentence } from '@intlayer/config/client';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type { FC } from 'react';\nimport { Breadcrumb, type BreadcrumbLink } from '../Breadcrumb';\nimport type { LinkColor } from '../Link';\n\ntype KeyPathBreadcrumbProps = {\n dictionaryKey: string;\n keyPath: KeyPath[];\n onClickKeyPath?: (keyPath: KeyPath[]) => void;\n locale?: Locale;\n color?: LinkColor | `${LinkColor}`;\n showDictionaryKey?: boolean;\n};\n\nexport const KeyPathBreadcrumb: FC<KeyPathBreadcrumbProps> = ({\n keyPath,\n dictionaryKey,\n onClickKeyPath,\n locale,\n color,\n showDictionaryKey = true,\n}) => {\n const formattedKeyPath: BreadcrumbLink[] = [\n ...(showDictionaryKey\n ? [\n {\n text: camelCaseToSentence(dictionaryKey),\n onClick: onClickKeyPath ? () => onClickKeyPath([]) : undefined,\n },\n ]\n : []),\n ...keyPath.map((el, index) => ({\n onClick: onClickKeyPath\n ? () =>\n // With keyPath = [{type: NodeTypes.Object, key: '0'}, {type: NodeTypes.Array, key: '0'}, {type: NodeTypes.Object, key: '1'}]\n // If index is 0 -> onFocusKeyPath([{type: NodeTypes.Object, key: '0'}])\n // If index is 1 -> onFocusKeyPath([{type: NodeTypes.Object, key: '0'}, {type: NodeTypes.Array, key: '0'}])\n onClickKeyPath?.(keyPath.slice(0, index + 1))\n : undefined,\n\n text: camelCaseToSentence(el.key?.toString() ?? ''),\n })),\n ];\n\n return (\n <Breadcrumb\n links={formattedKeyPath}\n locale={locale}\n elementType=\"location\"\n color={color}\n />\n );\n};\n"],"mappings":";;;;;AAgBA,MAAa,qBAAiD,EAC5D,SACA,eACA,gBACA,QACA,OACA,oBAAoB,WAChB;CACJ,MAAM,mBAAqC,CACzC,GAAI,oBACA,CACE;EACE,MAAM,oBAAoB,aAAa;EACvC,SAAS,uBAAuB,eAAe,CAAC,CAAC,IAAI;CACvD,CACF,IACA,CAAC,GACL,GAAG,QAAQ,KAAK,IAAI,WAAW;EAC7B,SAAS,uBAKH,iBAAiB,QAAQ,MAAM,GAAG,QAAQ,CAAC,CAAC,IAC9C;EAEJ,MAAM,oBAAoB,GAAG,KAAK,SAAS,KAAK,EAAE;CACpD,EAAE,CACJ;CAEA,OACE,oBAAC,YAAD;EACE,OAAO;EACC;EACR,aAAY;EACL;CACR;AAEL"}
@@ -3,10 +3,10 @@ import { Accordion } from "../../Accordion/Accordion.mjs";
3
3
  import { useLocaleSwitcherContent } from "../../LocaleSwitcherContentDropDown/LocaleSwitcherContentContext.mjs";
4
4
  import { getIsEditableSection } from "../getIsEditableSection.mjs";
5
5
  import { useState } from "react";
6
- import { ChevronRight, Plus } from "lucide-react";
7
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
- import { useIntlayer } from "react-intlayer";
7
+ import { ChevronRight, Plus } from "lucide-react";
9
8
  import { useEditedContentActions, useEditorLocale, useFocusUnmergedDictionary } from "@intlayer/editor-react";
9
+ import { useIntlayer } from "react-intlayer";
10
10
  import { getContentNodeByKeyPath, getEmptyNode, getNodeType } from "@intlayer/core/dictionaryManipulator";
11
11
  import * as NodeTypes from "@intlayer/types/nodeType";
12
12
  import { isSameKeyPath } from "@intlayer/core/utils";
@@ -31,7 +31,8 @@ const GatedAccordion = ({ children, onToggle, ...props }) => {
31
31
  };
32
32
  const NavigationViewNode = ({ section: sectionProp, keyPath, dictionary }) => {
33
33
  const { selectedLocales } = useLocaleSwitcherContent();
34
- const section = getContentNodeByKeyPath(sectionProp, keyPath, useEditorLocale());
34
+ const currentLocale = useEditorLocale();
35
+ const section = getContentNodeByKeyPath(sectionProp, keyPath, currentLocale);
35
36
  const { addEditedContent } = useEditedContentActions();
36
37
  const { setFocusedContentKeyPath, focusedContent } = useFocusUnmergedDictionary();
37
38
  const { addNewElement, goToField } = useIntlayer("navigation-view");
@@ -139,14 +140,16 @@ const NavigationViewNode = ({ section: sectionProp, keyPath, dictionary }) => {
139
140
  dictionary
140
141
  });
141
142
  }
143
+ const sectionArray = Object.keys(section);
142
144
  return /* @__PURE__ */ jsx("div", {
143
145
  className: "flex w-full max-w-full flex-col justify-between gap-2",
144
- children: Object.keys(section).map((key) => {
146
+ children: sectionArray.map((key) => {
145
147
  const childKeyPath = [...keyPath, {
146
148
  type: NodeTypes.OBJECT,
147
149
  key
148
150
  }];
149
- if (getIsEditableSection(getContentNodeByKeyPath(sectionProp, childKeyPath))) return /* @__PURE__ */ jsx(Button, {
151
+ const subSection = getContentNodeByKeyPath(sectionProp, childKeyPath);
152
+ if (getIsEditableSection(subSection)) return /* @__PURE__ */ jsx(Button, {
150
153
  label: `${goToField.label.value} ${key}`,
151
154
  isActive: getIsSelected(childKeyPath),
152
155
  variant: "hoverable",
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationViewNode.mjs","names":[],"sources":["../../../../../src/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.tsx"],"sourcesContent":["import { Accordion, type AccordionProps } from '@components/Accordion';\nimport { Button } from '@components/Button';\nimport { useLocaleSwitcherContent } from '@components/LocaleSwitcherContentDropDown';\nimport { camelCaseToSentence } from '@intlayer/config/client';\nimport {\n getContentNodeByKeyPath,\n getEmptyNode,\n getNodeType,\n} from '@intlayer/core/dictionaryManipulator';\nimport { isSameKeyPath } from '@intlayer/core/utils';\nimport {\n useEditedContentActions,\n useEditorLocale,\n useFocusUnmergedDictionary,\n} from '@intlayer/editor-react';\nimport type { LocalDictionaryId } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport type { ContentNode, Dictionary } from 'intlayer';\nimport { ChevronRight, Plus } from 'lucide-react';\nimport { type FC, type ReactNode, useState } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { getIsEditableSection } from '../getIsEditableSection';\n\nexport const traceKeys: string[] = ['filePath', 'id', 'nodeType'];\n\ntype GatedAccordionProps = AccordionProps & { children: ReactNode };\n\n// Renders children only after the accordion is first opened (mount-once pattern).\n// Prevents the entire recursive subtree from mounting on initial render.\nconst GatedAccordion: FC<GatedAccordionProps> = ({\n children,\n onToggle,\n ...props\n}) => {\n const [hasOpened, setHasOpened] = useState(false);\n return (\n <Accordion\n {...props}\n onToggle={(isOpen) => {\n if (isOpen && !hasOpened) setHasOpened(true);\n onToggle?.(isOpen);\n }}\n >\n {hasOpened ? children : null}\n </Accordion>\n );\n};\n\nexport type NodeWrapperProps = {\n keyPath: KeyPath[];\n section: ContentNode;\n dictionary: Dictionary;\n};\n\nexport const NavigationViewNode: FC<NodeWrapperProps> = ({\n section: sectionProp,\n keyPath,\n dictionary,\n}) => {\n const { selectedLocales } = useLocaleSwitcherContent();\n\n const currentLocale = useEditorLocale();\n const section = getContentNodeByKeyPath(sectionProp, keyPath, currentLocale);\n const { addEditedContent } = useEditedContentActions();\n const { setFocusedContentKeyPath, focusedContent } =\n useFocusUnmergedDictionary();\n const { addNewElement, goToField } = useIntlayer('navigation-view');\n const nodeType = getNodeType(section);\n const getIsSelected = (keyPath: KeyPath[]) =>\n (focusedContent?.keyPath?.length ?? 0) > 0 &&\n isSameKeyPath(keyPath, focusedContent?.keyPath ?? []);\n const isEditableSubSection = getIsEditableSection(section);\n\n if (!section) return <></>;\n\n if (isEditableSubSection) {\n return (\n <Button\n label={goToField.label.value}\n variant=\"hoverable\"\n color=\"text\"\n className=\"w-full\"\n onClick={() => setFocusedContentKeyPath(keyPath)}\n IconRight={ChevronRight}\n >\n {camelCaseToSentence(keyPath[keyPath.length - 1]?.key as string)}\n </Button>\n );\n }\n\n if (typeof section === 'object') {\n if (nodeType === NodeTypes.REACT_NODE) {\n return <>React Node</>;\n }\n\n if (nodeType === NodeTypes.TRANSLATION) {\n return (\n <div className=\"flex flex-col justify-between gap-2\">\n {selectedLocales.map((translationKey) => {\n const childKeyPath: KeyPath[] = [\n ...keyPath,\n { type: NodeTypes.TRANSLATION, key: translationKey },\n ];\n\n return (\n <NavigationViewNode\n key={translationKey}\n keyPath={childKeyPath}\n section={sectionProp}\n dictionary={dictionary}\n />\n );\n })}\n </div>\n );\n }\n\n if (\n nodeType === NodeTypes.ENUMERATION ||\n nodeType === NodeTypes.PLURAL ||\n nodeType === NodeTypes.CONDITION\n ) {\n return (\n <div className=\"flex flex-col justify-between gap-2\">\n {Object.keys(\n (section as any)[nodeType as unknown as keyof typeof section]\n ).map((key) => {\n const childKeyPath: KeyPath[] = [\n ...keyPath,\n { type: nodeType, key },\n ];\n\n return (\n <NavigationViewNode\n key={key}\n keyPath={childKeyPath}\n section={sectionProp}\n dictionary={dictionary}\n />\n );\n })}\n </div>\n );\n }\n\n if (nodeType === NodeTypes.ARRAY) {\n return (\n <div className=\"flex flex-col justify-between gap-2\">\n {(section as unknown as ContentNode[]).map((subSection, index) => {\n const childKeyPath: KeyPath[] = [\n ...keyPath,\n { type: NodeTypes.ARRAY, key: index },\n ];\n\n const isEditableSubSection = getIsEditableSection(subSection);\n\n if (isEditableSubSection) {\n return (\n <Button\n key={JSON.stringify(childKeyPath)}\n label={`${goToField.label.value} ${index}`}\n variant=\"hoverable\"\n color=\"text\"\n className=\"w-full\"\n onClick={() => setFocusedContentKeyPath(childKeyPath)}\n IconRight={ChevronRight}\n isActive={getIsSelected(childKeyPath)}\n >\n Item {index}\n </Button>\n );\n }\n\n return (\n <GatedAccordion\n key={JSON.stringify(childKeyPath)}\n label={`${goToField.label.value} ${index}`}\n header={`Item ${index}`}\n isActive={getIsSelected(childKeyPath)}\n onClick={() => setFocusedContentKeyPath(childKeyPath)}\n >\n <div className=\"mt-2 flex w-full max-w-full\">\n <div className=\"flex-1 pl-10\">\n <NavigationViewNode\n keyPath={childKeyPath}\n section={sectionProp}\n dictionary={dictionary}\n />\n </div>\n </div>\n </GatedAccordion>\n );\n })}\n\n <Button\n label={addNewElement.label.value}\n variant=\"hoverable\"\n color=\"neutral\"\n textAlign=\"left\"\n onClick={() => {\n const newKeyPath: KeyPath[] = [\n ...keyPath,\n {\n type: NodeTypes.ARRAY,\n key: (section as unknown as ContentNode[]).length,\n },\n ];\n const sectionArray = section as unknown as ContentNode[];\n const emptySectionEl =\n getEmptyNode(\n sectionArray[\n (sectionArray.length - 1) as keyof typeof sectionArray\n ] as ContentNode\n ) ?? '';\n addEditedContent(\n dictionary.localId as LocalDictionaryId,\n emptySectionEl,\n newKeyPath,\n false\n );\n setFocusedContentKeyPath(newKeyPath);\n }}\n Icon={Plus}\n >\n {addNewElement.text}\n </Button>\n </div>\n );\n }\n\n if (typeof section.nodeType === 'string') {\n const childKeyPath: KeyPath[] = [\n ...keyPath,\n { type: section.nodeType } as KeyPath,\n ];\n\n return (\n <NavigationViewNode\n keyPath={childKeyPath}\n section={sectionProp}\n dictionary={dictionary}\n />\n );\n }\n\n const sectionArray = Object.keys(section);\n return (\n <div className=\"flex w-full max-w-full flex-col justify-between gap-2\">\n {sectionArray.map((key) => {\n const childKeyPath: KeyPath[] = [\n ...keyPath,\n { type: NodeTypes.OBJECT, key },\n ];\n\n const subSection = getContentNodeByKeyPath(sectionProp, childKeyPath);\n const isEditableSubSection = getIsEditableSection(subSection);\n\n if (isEditableSubSection) {\n return (\n <Button\n label={`${goToField.label.value} ${key}`}\n key={key}\n isActive={getIsSelected(childKeyPath)}\n variant=\"hoverable\"\n color=\"text\"\n className=\"w-full\"\n onClick={() => setFocusedContentKeyPath(childKeyPath)}\n IconRight={ChevronRight}\n >\n {camelCaseToSentence(key)}\n </Button>\n );\n }\n\n return (\n <GatedAccordion\n key={key}\n label={`${goToField.label.value} ${key}`}\n isActive={getIsSelected(childKeyPath)}\n onClick={() => setFocusedContentKeyPath(childKeyPath)}\n header={camelCaseToSentence(key)}\n >\n <div className=\"mt-2 flex w-full max-w-full\">\n <div className=\"flex-1 pl-10\">\n <NavigationViewNode\n keyPath={childKeyPath}\n section={sectionProp}\n dictionary={dictionary}\n />\n </div>\n </div>\n </GatedAccordion>\n );\n })}\n </div>\n );\n }\n\n return (\n <>\n Error loading section --\n {nodeType}\n --\n {JSON.stringify(section)}\n --\n {JSON.stringify(keyPath)}\n </>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"NavigationViewNode.mjs","names":[],"sources":["../../../../../src/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.tsx"],"sourcesContent":["import { Accordion, type AccordionProps } from '@components/Accordion';\nimport { Button } from '@components/Button';\nimport { useLocaleSwitcherContent } from '@components/LocaleSwitcherContentDropDown';\nimport { camelCaseToSentence } from '@intlayer/config/client';\nimport {\n getContentNodeByKeyPath,\n getEmptyNode,\n getNodeType,\n} from '@intlayer/core/dictionaryManipulator';\nimport { isSameKeyPath } from '@intlayer/core/utils';\nimport {\n useEditedContentActions,\n useEditorLocale,\n useFocusUnmergedDictionary,\n} from '@intlayer/editor-react';\nimport type { LocalDictionaryId } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport type { ContentNode, Dictionary } from 'intlayer';\nimport { ChevronRight, Plus } from 'lucide-react';\nimport { type FC, type ReactNode, useState } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { getIsEditableSection } from '../getIsEditableSection';\n\nexport const traceKeys: string[] = ['filePath', 'id', 'nodeType'];\n\ntype GatedAccordionProps = AccordionProps & { children: ReactNode };\n\n// Renders children only after the accordion is first opened (mount-once pattern).\n// Prevents the entire recursive subtree from mounting on initial render.\nconst GatedAccordion: FC<GatedAccordionProps> = ({\n children,\n onToggle,\n ...props\n}) => {\n const [hasOpened, setHasOpened] = useState(false);\n return (\n <Accordion\n {...props}\n onToggle={(isOpen) => {\n if (isOpen && !hasOpened) setHasOpened(true);\n onToggle?.(isOpen);\n }}\n >\n {hasOpened ? children : null}\n </Accordion>\n );\n};\n\nexport type NodeWrapperProps = {\n keyPath: KeyPath[];\n section: ContentNode;\n dictionary: Dictionary;\n};\n\nexport const NavigationViewNode: FC<NodeWrapperProps> = ({\n section: sectionProp,\n keyPath,\n dictionary,\n}) => {\n const { selectedLocales } = useLocaleSwitcherContent();\n\n const currentLocale = useEditorLocale();\n const section = getContentNodeByKeyPath(sectionProp, keyPath, currentLocale);\n const { addEditedContent } = useEditedContentActions();\n const { setFocusedContentKeyPath, focusedContent } =\n useFocusUnmergedDictionary();\n const { addNewElement, goToField } = useIntlayer('navigation-view');\n const nodeType = getNodeType(section);\n const getIsSelected = (keyPath: KeyPath[]) =>\n (focusedContent?.keyPath?.length ?? 0) > 0 &&\n isSameKeyPath(keyPath, focusedContent?.keyPath ?? []);\n const isEditableSubSection = getIsEditableSection(section);\n\n if (!section) return <></>;\n\n if (isEditableSubSection) {\n return (\n <Button\n label={goToField.label.value}\n variant=\"hoverable\"\n color=\"text\"\n className=\"w-full\"\n onClick={() => setFocusedContentKeyPath(keyPath)}\n IconRight={ChevronRight}\n >\n {camelCaseToSentence(keyPath[keyPath.length - 1]?.key as string)}\n </Button>\n );\n }\n\n if (typeof section === 'object') {\n if (nodeType === NodeTypes.REACT_NODE) {\n return <>React Node</>;\n }\n\n if (nodeType === NodeTypes.TRANSLATION) {\n return (\n <div className=\"flex flex-col justify-between gap-2\">\n {selectedLocales.map((translationKey) => {\n const childKeyPath: KeyPath[] = [\n ...keyPath,\n { type: NodeTypes.TRANSLATION, key: translationKey },\n ];\n\n return (\n <NavigationViewNode\n key={translationKey}\n keyPath={childKeyPath}\n section={sectionProp}\n dictionary={dictionary}\n />\n );\n })}\n </div>\n );\n }\n\n if (\n nodeType === NodeTypes.ENUMERATION ||\n nodeType === NodeTypes.PLURAL ||\n nodeType === NodeTypes.CONDITION\n ) {\n return (\n <div className=\"flex flex-col justify-between gap-2\">\n {Object.keys(\n (section as any)[nodeType as unknown as keyof typeof section]\n ).map((key) => {\n const childKeyPath: KeyPath[] = [\n ...keyPath,\n { type: nodeType, key },\n ];\n\n return (\n <NavigationViewNode\n key={key}\n keyPath={childKeyPath}\n section={sectionProp}\n dictionary={dictionary}\n />\n );\n })}\n </div>\n );\n }\n\n if (nodeType === NodeTypes.ARRAY) {\n return (\n <div className=\"flex flex-col justify-between gap-2\">\n {(section as unknown as ContentNode[]).map((subSection, index) => {\n const childKeyPath: KeyPath[] = [\n ...keyPath,\n { type: NodeTypes.ARRAY, key: index },\n ];\n\n const isEditableSubSection = getIsEditableSection(subSection);\n\n if (isEditableSubSection) {\n return (\n <Button\n key={JSON.stringify(childKeyPath)}\n label={`${goToField.label.value} ${index}`}\n variant=\"hoverable\"\n color=\"text\"\n className=\"w-full\"\n onClick={() => setFocusedContentKeyPath(childKeyPath)}\n IconRight={ChevronRight}\n isActive={getIsSelected(childKeyPath)}\n >\n Item {index}\n </Button>\n );\n }\n\n return (\n <GatedAccordion\n key={JSON.stringify(childKeyPath)}\n label={`${goToField.label.value} ${index}`}\n header={`Item ${index}`}\n isActive={getIsSelected(childKeyPath)}\n onClick={() => setFocusedContentKeyPath(childKeyPath)}\n >\n <div className=\"mt-2 flex w-full max-w-full\">\n <div className=\"flex-1 pl-10\">\n <NavigationViewNode\n keyPath={childKeyPath}\n section={sectionProp}\n dictionary={dictionary}\n />\n </div>\n </div>\n </GatedAccordion>\n );\n })}\n\n <Button\n label={addNewElement.label.value}\n variant=\"hoverable\"\n color=\"neutral\"\n textAlign=\"left\"\n onClick={() => {\n const newKeyPath: KeyPath[] = [\n ...keyPath,\n {\n type: NodeTypes.ARRAY,\n key: (section as unknown as ContentNode[]).length,\n },\n ];\n const sectionArray = section as unknown as ContentNode[];\n const emptySectionEl =\n getEmptyNode(\n sectionArray[\n (sectionArray.length - 1) as keyof typeof sectionArray\n ] as ContentNode\n ) ?? '';\n addEditedContent(\n dictionary.localId as LocalDictionaryId,\n emptySectionEl,\n newKeyPath,\n false\n );\n setFocusedContentKeyPath(newKeyPath);\n }}\n Icon={Plus}\n >\n {addNewElement.text}\n </Button>\n </div>\n );\n }\n\n if (typeof section.nodeType === 'string') {\n const childKeyPath: KeyPath[] = [\n ...keyPath,\n { type: section.nodeType } as KeyPath,\n ];\n\n return (\n <NavigationViewNode\n keyPath={childKeyPath}\n section={sectionProp}\n dictionary={dictionary}\n />\n );\n }\n\n const sectionArray = Object.keys(section);\n return (\n <div className=\"flex w-full max-w-full flex-col justify-between gap-2\">\n {sectionArray.map((key) => {\n const childKeyPath: KeyPath[] = [\n ...keyPath,\n { type: NodeTypes.OBJECT, key },\n ];\n\n const subSection = getContentNodeByKeyPath(sectionProp, childKeyPath);\n const isEditableSubSection = getIsEditableSection(subSection);\n\n if (isEditableSubSection) {\n return (\n <Button\n label={`${goToField.label.value} ${key}`}\n key={key}\n isActive={getIsSelected(childKeyPath)}\n variant=\"hoverable\"\n color=\"text\"\n className=\"w-full\"\n onClick={() => setFocusedContentKeyPath(childKeyPath)}\n IconRight={ChevronRight}\n >\n {camelCaseToSentence(key)}\n </Button>\n );\n }\n\n return (\n <GatedAccordion\n key={key}\n label={`${goToField.label.value} ${key}`}\n isActive={getIsSelected(childKeyPath)}\n onClick={() => setFocusedContentKeyPath(childKeyPath)}\n header={camelCaseToSentence(key)}\n >\n <div className=\"mt-2 flex w-full max-w-full\">\n <div className=\"flex-1 pl-10\">\n <NavigationViewNode\n keyPath={childKeyPath}\n section={sectionProp}\n dictionary={dictionary}\n />\n </div>\n </div>\n </GatedAccordion>\n );\n })}\n </div>\n );\n }\n\n return (\n <>\n Error loading section --\n {nodeType}\n --\n {JSON.stringify(section)}\n --\n {JSON.stringify(keyPath)}\n </>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AAwBA,MAAa,YAAsB;CAAC;CAAY;CAAM;AAAU;AAMhE,MAAM,kBAA2C,EAC/C,UACA,UACA,GAAG,YACC;CACJ,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,OACE,oBAAC,WAAD;EACE,GAAI;EACJ,WAAW,WAAW;GACpB,IAAI,UAAU,CAAC,WAAW,aAAa,IAAI;GAC3C,WAAW,MAAM;EACnB;YAEC,YAAY,WAAW;CACf;AAEf;AAQA,MAAa,sBAA4C,EACvD,SAAS,aACT,SACA,iBACI;CACJ,MAAM,EAAE,oBAAoB,yBAAyB;CAErD,MAAM,gBAAgB,gBAAgB;CACtC,MAAM,UAAU,wBAAwB,aAAa,SAAS,aAAa;CAC3E,MAAM,EAAE,qBAAqB,wBAAwB;CACrD,MAAM,EAAE,0BAA0B,mBAChC,2BAA2B;CAC7B,MAAM,EAAE,eAAe,cAAc,YAAY,iBAAiB;CAClE,MAAM,WAAW,YAAY,OAAO;CACpC,MAAM,iBAAiB,aACpB,gBAAgB,SAAS,UAAU,KAAK,KACzC,cAAc,SAAS,gBAAgB,WAAW,CAAC,CAAC;CACtD,MAAM,uBAAuB,qBAAqB,OAAO;CAEzD,IAAI,CAAC,SAAS,OAAO,iCAAI;CAEzB,IAAI,sBACF,OACE,oBAAC,QAAD;EACE,OAAO,UAAU,MAAM;EACvB,SAAQ;EACR,OAAM;EACN,WAAU;EACV,eAAe,yBAAyB,OAAO;EAC/C,WAAW;YAEV,oBAAoB,QAAQ,QAAQ,SAAS,EAAE,EAAE,GAAa;CACzD;CAIZ,IAAI,OAAO,YAAY,UAAU;EAC/B,IAAI,aAAa,UAAU,YACzB,OAAO,4CAAE,aAAY;EAGvB,IAAI,aAAa,UAAU,aACzB,OACE,oBAAC,OAAD;GAAK,WAAU;aACZ,gBAAgB,KAAK,mBAAmB;IACvC,MAAM,eAA0B,CAC9B,GAAG,SACH;KAAE,MAAM,UAAU;KAAa,KAAK;IAAe,CACrD;IAEA,OACE,oBAAC,oBAAD;KAEE,SAAS;KACT,SAAS;KACG;IACb,GAJM,cAIN;GAEL,CAAC;EACE;EAIT,IACE,aAAa,UAAU,eACvB,aAAa,UAAU,UACvB,aAAa,UAAU,WAEvB,OACE,oBAAC,OAAD;GAAK,WAAU;aACZ,OAAO,KACL,QAAgB,SACnB,CAAC,CAAC,KAAK,QAAQ;IACb,MAAM,eAA0B,CAC9B,GAAG,SACH;KAAE,MAAM;KAAU;IAAI,CACxB;IAEA,OACE,oBAAC,oBAAD;KAEE,SAAS;KACT,SAAS;KACG;IACb,GAJM,GAIN;GAEL,CAAC;EACE;EAIT,IAAI,aAAa,UAAU,OACzB,OACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACI,QAAqC,KAAK,YAAY,UAAU;IAChE,MAAM,eAA0B,CAC9B,GAAG,SACH;KAAE,MAAM,UAAU;KAAO,KAAK;IAAM,CACtC;IAIA,IAF6B,qBAAqB,UAE3B,GACrB,OACE,qBAAC,QAAD;KAEE,OAAO,GAAG,UAAU,MAAM,MAAM,GAAG;KACnC,SAAQ;KACR,OAAM;KACN,WAAU;KACV,eAAe,yBAAyB,YAAY;KACpD,WAAW;KACX,UAAU,cAAc,YAAY;eARtC,CASC,SACO,KACA;OAVD,KAAK,UAAU,YAAY,CAU1B;IAIZ,OACE,oBAAC,gBAAD;KAEE,OAAO,GAAG,UAAU,MAAM,MAAM,GAAG;KACnC,QAAQ,QAAQ;KAChB,UAAU,cAAc,YAAY;KACpC,eAAe,yBAAyB,YAAY;eAEpD,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,OAAD;OAAK,WAAU;iBACb,oBAAC,oBAAD;QACE,SAAS;QACT,SAAS;QACG;OACb;MACE;KACF;IACS,GAfT,KAAK,UAAU,YAAY,CAelB;GAEpB,CAAC,GAED,oBAAC,QAAD;IACE,OAAO,cAAc,MAAM;IAC3B,SAAQ;IACR,OAAM;IACN,WAAU;IACV,eAAe;KACb,MAAM,aAAwB,CAC5B,GAAG,SACH;MACE,MAAM,UAAU;MAChB,KAAM,QAAqC;KAC7C,CACF;KACA,MAAM,eAAe;KACrB,MAAM,iBACJ,aACE,aACG,aAAa,SAAS,EAE3B,KAAK;KACP,iBACE,WAAW,SACX,gBACA,YACA,KACF;KACA,yBAAyB,UAAU;IACrC;IACA,MAAM;cAEL,cAAc;GACT,EACL;;EAIT,IAAI,OAAO,QAAQ,aAAa,UAAU;GACxC,MAAM,eAA0B,CAC9B,GAAG,SACH,EAAE,MAAM,QAAQ,SAAS,CAC3B;GAEA,OACE,oBAAC,oBAAD;IACE,SAAS;IACT,SAAS;IACG;GACb;EAEL;EAEA,MAAM,eAAe,OAAO,KAAK,OAAO;EACxC,OACE,oBAAC,OAAD;GAAK,WAAU;aACZ,aAAa,KAAK,QAAQ;IACzB,MAAM,eAA0B,CAC9B,GAAG,SACH;KAAE,MAAM,UAAU;KAAQ;IAAI,CAChC;IAEA,MAAM,aAAa,wBAAwB,aAAa,YAAY;IAGpE,IAF6B,qBAAqB,UAE3B,GACrB,OACE,oBAAC,QAAD;KACE,OAAO,GAAG,UAAU,MAAM,MAAM,GAAG;KAEnC,UAAU,cAAc,YAAY;KACpC,SAAQ;KACR,OAAM;KACN,WAAU;KACV,eAAe,yBAAyB,YAAY;KACpD,WAAW;eAEV,oBAAoB,GAAG;IAClB,GATD,GASC;IAIZ,OACE,oBAAC,gBAAD;KAEE,OAAO,GAAG,UAAU,MAAM,MAAM,GAAG;KACnC,UAAU,cAAc,YAAY;KACpC,eAAe,yBAAyB,YAAY;KACpD,QAAQ,oBAAoB,GAAG;eAE/B,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,OAAD;OAAK,WAAU;iBACb,oBAAC,oBAAD;QACE,SAAS;QACT,SAAS;QACG;OACb;MACE;KACF;IACS,GAfT,GAeS;GAEpB,CAAC;EACE;CAET;CAEA,OACE;EAAE;EAEC;EAAS;EAET,KAAK,UAAU,OAAO;EAAE;EAExB,KAAK,UAAU,OAAO;CACvB;AAEN"}
@@ -10,7 +10,8 @@ import * as NodeTypes from "@intlayer/types/nodeType";
10
10
  //#region src/components/DictionaryFieldEditor/NodeTypeSelector.tsx
11
11
  const NodeTypeSelector = ({ section, onValueChange: onValueChangeProp }) => {
12
12
  const { multilingual, text, number, boolean, node, array, enumeration, plural, triggerPlaceHolder, nest, gender, select, condition, markdown, insertion, reactNode, file } = useIntlayer("node-type-selector");
13
- const [keyType, setKeyType] = useState(getNodeType(section));
13
+ const nodeType = getNodeType(section);
14
+ const [keyType, setKeyType] = useState(nodeType);
14
15
  const onValueChange = (keyType) => {
15
16
  setKeyType(keyType);
16
17
  onValueChangeProp(keyType);
@@ -1 +1 @@
1
- {"version":3,"file":"NodeTypeSelector.mjs","names":[],"sources":["../../../../src/components/DictionaryFieldEditor/NodeTypeSelector.tsx"],"sourcesContent":["'use client';\n\nimport { getNodeType } from '@intlayer/core/dictionaryManipulator';\nimport type { ContentNode } from '@intlayer/types/dictionary';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { type FC, useState } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Select } from '../Select';\n\ntype NodeTypeSelectorProps = {\n section: ContentNode;\n onValueChange: (keyType: NodeType) => void;\n};\n\nexport const NodeTypeSelector: FC<NodeTypeSelectorProps> = ({\n section,\n onValueChange: onValueChangeProp,\n}) => {\n const {\n multilingual,\n text,\n number,\n boolean,\n node,\n array,\n enumeration,\n plural,\n triggerPlaceHolder,\n nest,\n gender,\n select,\n condition,\n markdown,\n insertion,\n reactNode,\n file,\n } = useIntlayer('node-type-selector');\n const nodeType = getNodeType(section);\n const [keyType, setKeyType] = useState<NodeType>(nodeType);\n\n const onValueChange = (keyType: NodeType) => {\n setKeyType(keyType);\n onValueChangeProp(keyType);\n };\n\n return (\n <Select value={keyType} onValueChange={onValueChange}>\n <Select.Trigger>\n <Select.Value placeholder={triggerPlaceHolder} />\n </Select.Trigger>\n <Select.Content>\n <Select.Item value={NodeTypes.TRANSLATION}>{multilingual}</Select.Item>\n <Select.Item value={NodeTypes.TEXT}>{text}</Select.Item>\n <Select.Item value={NodeTypes.NUMBER}>{number}</Select.Item>\n <Select.Item value={NodeTypes.BOOLEAN}>{boolean}</Select.Item>\n <Select.Item value={NodeTypes.OBJECT}>{node}</Select.Item>\n <Select.Item value={NodeTypes.ARRAY}>{array}</Select.Item>\n <Select.Item value={NodeTypes.ENUMERATION}>{enumeration}</Select.Item>\n <Select.Item value={NodeTypes.PLURAL}>{plural}</Select.Item>\n <Select.Item value={NodeTypes.GENDER}>{gender}</Select.Item>\n <Select.Item value={NodeTypes.SELECT}>{select}</Select.Item>\n <Select.Item value={NodeTypes.INSERTION}>{insertion}</Select.Item>\n <Select.Item value={NodeTypes.MARKDOWN}>{markdown}</Select.Item>\n <Select.Item value={NodeTypes.NESTED}>{nest}</Select.Item>\n <Select.Item value={NodeTypes.CONDITION}>{condition}</Select.Item>\n <Select.Item value={NodeTypes.REACT_NODE} disabled>\n {reactNode}\n </Select.Item>\n <Select.Item value={NodeTypes.FILE}>{file}</Select.Item>\n </Select.Content>\n </Select>\n );\n};\n"],"mappings":";;;;;;;;;;AAeA,MAAa,oBAA+C,EAC1D,SACA,eAAe,wBACX;CACJ,MAAM,EACJ,cACA,MACA,QACA,SACA,MACA,OACA,aACA,QACA,oBACA,MACA,QACA,QACA,WACA,UACA,WACA,WACA,SACE,YAAY,oBAAoB;CAEpC,MAAM,CAAC,SAAS,cAAc,SADb,YAAY,OAC2B,CAAC;CAEzD,MAAM,iBAAiB,YAAsB;EAC3C,WAAW,OAAO;EAClB,kBAAkB,OAAO;CAC3B;CAEA,OACE,qBAAC,QAAD;EAAQ,OAAO;EAAwB;YAAvC,CACE,oBAAC,OAAO,SAAR,YACE,oBAAC,OAAO,OAAR,EAAc,aAAa,mBAAqB,GAClC,IAChB,qBAAC,OAAO,SAAR;GACE,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAc;GAA0B;GACtE,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAO;GAAkB;GACvD,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAoB;GAC3D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAU;GAAqB;GAC7D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAkB;GACzD,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAQ;GAAmB;GACzD,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAc;GAAyB;GACrE,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAoB;GAC3D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAoB;GAC3D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAoB;GAC3D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAY;GAAuB;GACjE,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAW;GAAsB;GAC/D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAkB;GACzD,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAY;GAAuB;GACjE,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;IAAY;cACvC;GACU;GACb,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAO;GAAkB;EACzC,IACV;;AAEZ"}
1
+ {"version":3,"file":"NodeTypeSelector.mjs","names":[],"sources":["../../../../src/components/DictionaryFieldEditor/NodeTypeSelector.tsx"],"sourcesContent":["'use client';\n\nimport { getNodeType } from '@intlayer/core/dictionaryManipulator';\nimport type { ContentNode } from '@intlayer/types/dictionary';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { type FC, useState } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Select } from '../Select';\n\ntype NodeTypeSelectorProps = {\n section: ContentNode;\n onValueChange: (keyType: NodeType) => void;\n};\n\nexport const NodeTypeSelector: FC<NodeTypeSelectorProps> = ({\n section,\n onValueChange: onValueChangeProp,\n}) => {\n const {\n multilingual,\n text,\n number,\n boolean,\n node,\n array,\n enumeration,\n plural,\n triggerPlaceHolder,\n nest,\n gender,\n select,\n condition,\n markdown,\n insertion,\n reactNode,\n file,\n } = useIntlayer('node-type-selector');\n const nodeType = getNodeType(section);\n const [keyType, setKeyType] = useState<NodeType>(nodeType);\n\n const onValueChange = (keyType: NodeType) => {\n setKeyType(keyType);\n onValueChangeProp(keyType);\n };\n\n return (\n <Select value={keyType} onValueChange={onValueChange}>\n <Select.Trigger>\n <Select.Value placeholder={triggerPlaceHolder} />\n </Select.Trigger>\n <Select.Content>\n <Select.Item value={NodeTypes.TRANSLATION}>{multilingual}</Select.Item>\n <Select.Item value={NodeTypes.TEXT}>{text}</Select.Item>\n <Select.Item value={NodeTypes.NUMBER}>{number}</Select.Item>\n <Select.Item value={NodeTypes.BOOLEAN}>{boolean}</Select.Item>\n <Select.Item value={NodeTypes.OBJECT}>{node}</Select.Item>\n <Select.Item value={NodeTypes.ARRAY}>{array}</Select.Item>\n <Select.Item value={NodeTypes.ENUMERATION}>{enumeration}</Select.Item>\n <Select.Item value={NodeTypes.PLURAL}>{plural}</Select.Item>\n <Select.Item value={NodeTypes.GENDER}>{gender}</Select.Item>\n <Select.Item value={NodeTypes.SELECT}>{select}</Select.Item>\n <Select.Item value={NodeTypes.INSERTION}>{insertion}</Select.Item>\n <Select.Item value={NodeTypes.MARKDOWN}>{markdown}</Select.Item>\n <Select.Item value={NodeTypes.NESTED}>{nest}</Select.Item>\n <Select.Item value={NodeTypes.CONDITION}>{condition}</Select.Item>\n <Select.Item value={NodeTypes.REACT_NODE} disabled>\n {reactNode}\n </Select.Item>\n <Select.Item value={NodeTypes.FILE}>{file}</Select.Item>\n </Select.Content>\n </Select>\n );\n};\n"],"mappings":";;;;;;;;;;AAeA,MAAa,oBAA+C,EAC1D,SACA,eAAe,wBACX;CACJ,MAAM,EACJ,cACA,MACA,QACA,SACA,MACA,OACA,aACA,QACA,oBACA,MACA,QACA,QACA,WACA,UACA,WACA,WACA,SACE,YAAY,oBAAoB;CACpC,MAAM,WAAW,YAAY,OAAO;CACpC,MAAM,CAAC,SAAS,cAAc,SAAmB,QAAQ;CAEzD,MAAM,iBAAiB,YAAsB;EAC3C,WAAW,OAAO;EAClB,kBAAkB,OAAO;CAC3B;CAEA,OACE,qBAAC,QAAD;EAAQ,OAAO;EAAwB;YAAvC,CACE,oBAAC,OAAO,SAAR,YACE,oBAAC,OAAO,OAAR,EAAc,aAAa,mBAAqB,GAClC,IAChB,qBAAC,OAAO,SAAR;GACE,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAc;GAA0B;GACtE,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAO;GAAkB;GACvD,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAoB;GAC3D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAU;GAAqB;GAC7D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAkB;GACzD,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAQ;GAAmB;GACzD,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAc;GAAyB;GACrE,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAoB;GAC3D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAoB;GAC3D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAoB;GAC3D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAY;GAAuB;GACjE,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAW;GAAsB;GAC/D,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAS;GAAkB;GACzD,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAY;GAAuB;GACjE,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;IAAY;cACvC;GACU;GACb,oBAAC,OAAO,MAAR;IAAa,OAAO,UAAU;cAAO;GAAkB;EACzC,IACV;;AAEZ"}
@@ -1,17 +1,17 @@
1
1
  'use client';
2
2
 
3
3
  import { cn } from "../../../utils/cn.mjs";
4
- import { Button } from "../../Button/Button.mjs";
5
4
  import { useSession } from "../../../api/useAuth/useSession.mjs";
6
5
  import { useAuth } from "../../../api/useAuth/useAuth.mjs";
7
6
  import { useDeleteDictionary, usePushDictionaries } from "../../../api/hooks/dictionary.mjs";
8
7
  import { useWriteDictionary } from "../../../api/hooks/editor.mjs";
8
+ import { Button } from "../../Button/Button.mjs";
9
9
  import { Modal } from "../../Modal/Modal.mjs";
10
10
  import { useState } from "react";
11
- import { ArrowUpFromLine, Download, RotateCcw, Save, Trash } from "lucide-react";
12
11
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
13
- import { useIntlayer } from "react-intlayer";
12
+ import { ArrowUpFromLine, Download, RotateCcw, Save, Trash } from "lucide-react";
14
13
  import { useDictionariesRecordActions, useEditedContent } from "@intlayer/editor-react";
14
+ import { useIntlayer } from "react-intlayer";
15
15
 
16
16
  //#region src/components/DictionaryFieldEditor/SaveForm/SaveForm.tsx
17
17
  const SaveForm = ({ dictionary, mode, className, onDelete, onSave, ...props }) => {
@@ -8,8 +8,9 @@ import { useEditedContent } from "@intlayer/editor-react";
8
8
  const StructureEditor = ({ dictionary }) => {
9
9
  const { content, localId } = dictionary;
10
10
  const { editedContent } = useEditedContent();
11
+ const initialSection = typeof editedContent?.[localId]?.content === "undefined" ? content : editedContent?.[localId]?.content;
11
12
  return /* @__PURE__ */ jsx(NodeView, {
12
- section: typeof editedContent?.[localId]?.content === "undefined" ? content : editedContent?.[localId]?.content,
13
+ section: initialSection,
13
14
  keyPath: [],
14
15
  dictionaryLocalId: localId
15
16
  });
@@ -1 +1 @@
1
- {"version":3,"file":"StructureEditor.mjs","names":[],"sources":["../../../../src/components/DictionaryFieldEditor/StructureEditor.tsx"],"sourcesContent":["'use client';\n\nimport { useEditedContent } from '@intlayer/editor-react';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { FC } from 'react';\nimport { NodeView } from './StructureView/StructureView';\n\ntype NodeEditorProps = {\n dictionary: Dictionary;\n};\n\nexport const StructureEditor: FC<NodeEditorProps> = ({ dictionary }) => {\n const { content, localId } = dictionary;\n\n const { editedContent } = useEditedContent();\n const initialSection =\n typeof editedContent?.[localId!]?.content === 'undefined'\n ? content\n : editedContent?.[localId!]?.content;\n\n return (\n <NodeView\n section={initialSection}\n keyPath={[]}\n dictionaryLocalId={localId!}\n />\n );\n};\n"],"mappings":";;;;;;;AAWA,MAAa,mBAAwC,EAAE,iBAAiB;CACtE,MAAM,EAAE,SAAS,YAAY;CAE7B,MAAM,EAAE,kBAAkB,iBAAiB;CAM3C,OACE,oBAAC,UAAD;EACE,SANF,OAAO,gBAAgB,QAAS,EAAE,YAAY,cAC1C,UACA,gBAAgB,QAAS,EAAE;EAK7B,SAAS,CAAC;EACV,mBAAmB;CACpB;AAEL"}
1
+ {"version":3,"file":"StructureEditor.mjs","names":[],"sources":["../../../../src/components/DictionaryFieldEditor/StructureEditor.tsx"],"sourcesContent":["'use client';\n\nimport { useEditedContent } from '@intlayer/editor-react';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { FC } from 'react';\nimport { NodeView } from './StructureView/StructureView';\n\ntype NodeEditorProps = {\n dictionary: Dictionary;\n};\n\nexport const StructureEditor: FC<NodeEditorProps> = ({ dictionary }) => {\n const { content, localId } = dictionary;\n\n const { editedContent } = useEditedContent();\n const initialSection =\n typeof editedContent?.[localId!]?.content === 'undefined'\n ? content\n : editedContent?.[localId!]?.content;\n\n return (\n <NodeView\n section={initialSection}\n keyPath={[]}\n dictionaryLocalId={localId!}\n />\n );\n};\n"],"mappings":";;;;;;;AAWA,MAAa,mBAAwC,EAAE,iBAAiB;CACtE,MAAM,EAAE,SAAS,YAAY;CAE7B,MAAM,EAAE,kBAAkB,iBAAiB;CAC3C,MAAM,iBACJ,OAAO,gBAAgB,QAAS,EAAE,YAAY,cAC1C,UACA,gBAAgB,QAAS,EAAE;CAEjC,OACE,oBAAC,UAAD;EACE,SAAS;EACT,SAAS,CAAC;EACV,mBAAmB;CACpB;AAEL"}
@@ -4,10 +4,10 @@ import { Button } from "../../Button/Button.mjs";
4
4
  import { Container } from "../../Container/index.mjs";
5
5
  import { EditableFieldInput } from "../../EditableField/EditableFieldInput.mjs";
6
6
  import { NodeTypeSelector } from "../NodeTypeSelector.mjs";
7
- import { Plus, Trash } from "lucide-react";
8
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
- import { useIntlayer } from "react-intlayer";
8
+ import { Plus, Trash } from "lucide-react";
10
9
  import { useConfiguration, useEditedContentActions, useFocusUnmergedDictionary } from "@intlayer/editor-react";
10
+ import { useIntlayer } from "react-intlayer";
11
11
  import { getDefaultNode, getNodeChildren, getNodeType } from "@intlayer/core/dictionaryManipulator";
12
12
  import * as NodeTypes from "@intlayer/types/nodeType";
13
13
  import { isSameKeyPath } from "@intlayer/core/utils";
@@ -4,8 +4,8 @@ import { Button } from "../../Button/Button.mjs";
4
4
  import { Container } from "../../Container/index.mjs";
5
5
  import { DropDown } from "../../DropDown/index.mjs";
6
6
  import { useVersionSwitcher } from "./VersionSwitcherContext.mjs";
7
- import { MoveVertical } from "lucide-react";
8
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ import { MoveVertical } from "lucide-react";
9
9
  import { useIntlayer } from "react-intlayer";
10
10
 
11
11
  //#region src/components/DictionaryFieldEditor/VersionSwitcherDropDown/VersionSwitcher.tsx
@@ -49,12 +49,13 @@ const EditableFieldInput = ({ onSave, onCancel, ref, ...props }) => {
49
49
  onCancel?.();
50
50
  };
51
51
  useImperativeHandle(ref, () => inputRef.current);
52
+ const value = useMemo(() => props.value ?? inputRef.current?.value ?? props.defaultValue, [
53
+ props.value,
54
+ props.defaultValue,
55
+ inputRef.current?.value
56
+ ]);
52
57
  return /* @__PURE__ */ jsx(EditableFieldLayout, {
53
- value: useMemo(() => props.value ?? inputRef.current?.value ?? props.defaultValue, [
54
- props.value,
55
- props.defaultValue,
56
- inputRef.current?.value
57
- ]),
58
+ value,
58
59
  onCancel: handleCancel,
59
60
  onSave: handleSave,
60
61
  children: /* @__PURE__ */ jsx(Input, {
@@ -1 +1 @@
1
- {"version":3,"file":"EditableFieldInput.mjs","names":[],"sources":["../../../../src/components/EditableField/EditableFieldInput.tsx"],"sourcesContent":["'use client';\n\nimport { type FC, type Ref, useImperativeHandle, useMemo, useRef } from 'react';\nimport { Input, type InputProps } from '../Input';\nimport { EditableFieldLayout } from './EditableFieldLayout';\n\n/**\n * Props for the EditableFieldInput component, extending standard Input props\n */\ntype EditableFieldInputProps = InputProps & {\n /** Callback function called when the user saves the edited value */\n onSave?: (value: string) => void;\n /** Callback function called when the user cancels the edit operation */\n onCancel?: () => void;\n};\n\n/**\n * EditableFieldInput Component\n *\n * An inline editable input field that displays as read-only text until clicked.\n * When activated, it shows an input field with save and cancel buttons.\n *\n * @example\n * ```tsx\n * <EditableFieldInput\n * defaultValue=\"Edit me\"\n * placeholder=\"Click to edit...\"\n * onSave={(value) => console.log('Saved:', value)}\n * onCancel={() => console.log('Cancelled')}\n * />\n * ```\n *\n * ## Features\n * - **Inline Editing**: Click to edit, displays as text when not editing\n * - **Save/Cancel Actions**: Built-in save and cancel buttons with callbacks\n * - **Keyboard Support**: Accessible keyboard navigation\n * - **Input Variants**: Supports all Input component variants and sizes\n * - **Auto-save on Click Away**: Saves automatically when clicking outside\n * - **Ref Forwarding**: Exposes the underlying input element reference\n *\n * ## Accessibility\n * - Uses semantic HTML with proper ARIA attributes\n * - Keyboard accessible with tab navigation\n * - Screen reader friendly with descriptive labels\n * - Focus management for edit mode transitions\n *\n * @param props - EditableFieldInputProps extending InputProps\n * @returns React functional component\n */\nexport const EditableFieldInput: FC<EditableFieldInputProps> = ({\n onSave,\n onCancel,\n ref,\n ...props\n}) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleSave = () => {\n // Your save logic here\n onSave?.(inputRef.current?.value ?? '');\n };\n\n const handleCancel = () => {\n if (inputRef.current) {\n inputRef.current.value = inputRef.current.defaultValue ?? '';\n }\n onCancel?.();\n };\n\n // Expose the input ref to parent components\n useImperativeHandle(ref as Ref<HTMLElement>, () => inputRef.current!);\n\n const value = useMemo(\n () =>\n (props.value as string) ??\n inputRef.current?.value ??\n (props.defaultValue as string),\n\n [props.value, props.defaultValue, inputRef.current?.value]\n );\n\n return (\n <EditableFieldLayout\n value={value}\n onCancel={handleCancel}\n onSave={handleSave}\n >\n <Input ref={inputRef} {...props} />\n </EditableFieldLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,MAAa,sBAAmD,EAC9D,QACA,UACA,KACA,GAAG,YACC;CACJ,MAAM,WAAW,OAAyB,IAAI;CAE9C,MAAM,mBAAmB;EAEvB,SAAS,SAAS,SAAS,SAAS,EAAE;CACxC;CAEA,MAAM,qBAAqB;EACzB,IAAI,SAAS,SACX,SAAS,QAAQ,QAAQ,SAAS,QAAQ,gBAAgB;EAE5D,WAAW;CACb;CAGA,oBAAoB,WAA+B,SAAS,OAAQ;CAWpE,OACE,oBAAC,qBAAD;EACE,OAXU,cAET,MAAM,SACP,SAAS,SAAS,SACjB,MAAM,cAET;GAAC,MAAM;GAAO,MAAM;GAAc,SAAS,SAAS;EAAK,CAK5C;EACX,UAAU;EACV,QAAQ;YAER,oBAAC,OAAD;GAAO,KAAK;GAAU,GAAI;EAAQ;CACf;AAEzB"}
1
+ {"version":3,"file":"EditableFieldInput.mjs","names":[],"sources":["../../../../src/components/EditableField/EditableFieldInput.tsx"],"sourcesContent":["'use client';\n\nimport { type FC, type Ref, useImperativeHandle, useMemo, useRef } from 'react';\nimport { Input, type InputProps } from '../Input';\nimport { EditableFieldLayout } from './EditableFieldLayout';\n\n/**\n * Props for the EditableFieldInput component, extending standard Input props\n */\ntype EditableFieldInputProps = InputProps & {\n /** Callback function called when the user saves the edited value */\n onSave?: (value: string) => void;\n /** Callback function called when the user cancels the edit operation */\n onCancel?: () => void;\n};\n\n/**\n * EditableFieldInput Component\n *\n * An inline editable input field that displays as read-only text until clicked.\n * When activated, it shows an input field with save and cancel buttons.\n *\n * @example\n * ```tsx\n * <EditableFieldInput\n * defaultValue=\"Edit me\"\n * placeholder=\"Click to edit...\"\n * onSave={(value) => console.log('Saved:', value)}\n * onCancel={() => console.log('Cancelled')}\n * />\n * ```\n *\n * ## Features\n * - **Inline Editing**: Click to edit, displays as text when not editing\n * - **Save/Cancel Actions**: Built-in save and cancel buttons with callbacks\n * - **Keyboard Support**: Accessible keyboard navigation\n * - **Input Variants**: Supports all Input component variants and sizes\n * - **Auto-save on Click Away**: Saves automatically when clicking outside\n * - **Ref Forwarding**: Exposes the underlying input element reference\n *\n * ## Accessibility\n * - Uses semantic HTML with proper ARIA attributes\n * - Keyboard accessible with tab navigation\n * - Screen reader friendly with descriptive labels\n * - Focus management for edit mode transitions\n *\n * @param props - EditableFieldInputProps extending InputProps\n * @returns React functional component\n */\nexport const EditableFieldInput: FC<EditableFieldInputProps> = ({\n onSave,\n onCancel,\n ref,\n ...props\n}) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleSave = () => {\n // Your save logic here\n onSave?.(inputRef.current?.value ?? '');\n };\n\n const handleCancel = () => {\n if (inputRef.current) {\n inputRef.current.value = inputRef.current.defaultValue ?? '';\n }\n onCancel?.();\n };\n\n // Expose the input ref to parent components\n useImperativeHandle(ref as Ref<HTMLElement>, () => inputRef.current!);\n\n const value = useMemo(\n () =>\n (props.value as string) ??\n inputRef.current?.value ??\n (props.defaultValue as string),\n\n [props.value, props.defaultValue, inputRef.current?.value]\n );\n\n return (\n <EditableFieldLayout\n value={value}\n onCancel={handleCancel}\n onSave={handleSave}\n >\n <Input ref={inputRef} {...props} />\n </EditableFieldLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,MAAa,sBAAmD,EAC9D,QACA,UACA,KACA,GAAG,YACC;CACJ,MAAM,WAAW,OAAyB,IAAI;CAE9C,MAAM,mBAAmB;EAEvB,SAAS,SAAS,SAAS,SAAS,EAAE;CACxC;CAEA,MAAM,qBAAqB;EACzB,IAAI,SAAS,SACX,SAAS,QAAQ,QAAQ,SAAS,QAAQ,gBAAgB;EAE5D,WAAW;CACb;CAGA,oBAAoB,WAA+B,SAAS,OAAQ;CAEpE,MAAM,QAAQ,cAET,MAAM,SACP,SAAS,SAAS,SACjB,MAAM,cAET;EAAC,MAAM;EAAO,MAAM;EAAc,SAAS,SAAS;CAAK,CAC3D;CAEA,OACE,oBAAC,qBAAD;EACS;EACP,UAAU;EACV,QAAQ;YAER,oBAAC,OAAD;GAAO,KAAK;GAAU,GAAI;EAAQ;CACf;AAEzB"}
@@ -3,8 +3,8 @@
3
3
  import { cn } from "../../utils/cn.mjs";
4
4
  import { Button } from "../Button/Button.mjs";
5
5
  import { useCallback, useEffect, useRef, useState } from "react";
6
- import { Check, Pencil, X } from "lucide-react";
7
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Check, Pencil, X } from "lucide-react";
8
8
 
9
9
  //#region src/components/EditableField/EditableFieldLayout.tsx
10
10
  const EditableFieldLayout = ({ value = "", onCancel, onSave, onClick, children, isDisabled, ...props }) => {
@@ -53,8 +53,9 @@ const EditableFieldTextArea = ({ onSave, onCancel, ref, ...props }) => {
53
53
  if (textAreaRef.current) textAreaRef.current.value = textAreaRef.current.defaultValue ?? "";
54
54
  onCancel?.();
55
55
  };
56
+ const memoValue = props.value ?? textAreaRef.current?.value ?? props.defaultValue ?? "";
56
57
  return /* @__PURE__ */ jsx(EditableFieldLayout, {
57
- value: props.value ?? textAreaRef.current?.value ?? props.defaultValue ?? "",
58
+ value: memoValue,
58
59
  onCancel: handleCancel,
59
60
  onSave: handleSave,
60
61
  onClick: (e) => {
@@ -1 +1 @@
1
- {"version":3,"file":"EditableFieldTextArea.mjs","names":[],"sources":["../../../../src/components/EditableField/EditableFieldTextArea.tsx"],"sourcesContent":["'use client';\n\nimport { type FC, type Ref, useImperativeHandle, useRef } from 'react';\nimport { AutoSizedTextArea, type AutoSizedTextAreaProps } from '../TextArea';\nimport { EditableFieldLayout } from './EditableFieldLayout';\n\n/**\n * Props for the EditableFieldTextArea component, extending AutoSizedTextAreaProps\n */\ntype EditableFieldTextAreaProps = AutoSizedTextAreaProps & {\n /** Callback function called when the user saves the edited value */\n onSave?: (value: string) => void;\n /** Callback function called when the user cancels the edit operation */\n onCancel?: () => void;\n};\n\n/**\n * EditableFieldTextArea Component\n *\n * An inline editable textarea field that displays as read-only text until clicked.\n * When activated, it shows an auto-sized textarea with save and cancel buttons.\n * Perfect for multiline text editing with automatic height adjustment.\n *\n * @example\n * ```tsx\n * <EditableFieldTextArea\n * defaultValue=\"Multiline text content\"\n * placeholder=\"Click to edit...\"\n * maxRows={10}\n * onSave={(value) => console.log('Saved:', value)}\n * onCancel={() => console.log('Cancelled')}\n * />\n * ```\n *\n * ## Features\n * - **Inline Editing**: Click to edit, displays as formatted text when not editing\n * - **Auto-Sizing**: Automatically adjusts height to fit content\n * - **Save/Cancel Actions**: Built-in save and cancel buttons with callbacks\n * - **Multiline Support**: Preserves line breaks and formatting\n * - **Max Rows Control**: Configurable maximum height with scroll\n * - **Auto-save on Click Away**: Saves automatically when clicking outside\n * - **Ref Forwarding**: Exposes the underlying textarea element reference\n *\n * ## Accessibility\n * - Uses semantic HTML with proper ARIA attributes\n * - Keyboard accessible with tab navigation\n * - Screen reader friendly with descriptive labels\n * - Focus management for edit mode transitions\n * - Preserves whitespace and formatting for screen readers\n *\n * @param props - EditableFieldTextAreaProps extending AutoSizedTextAreaProps\n * @returns React functional component\n */\nexport const EditableFieldTextArea: FC<EditableFieldTextAreaProps> = ({\n onSave,\n onCancel,\n ref,\n ...props\n}) => {\n const textAreaRef = useRef<HTMLTextAreaElement>(null);\n\n // Expose the text area ref to parent components\n useImperativeHandle(ref as Ref<HTMLElement>, () => textAreaRef.current!);\n\n const handleSave = () => {\n // Your save logic here\n onSave?.(textAreaRef.current?.value ?? '');\n };\n\n const handleCancel = () => {\n if (textAreaRef.current) {\n textAreaRef.current.value = textAreaRef.current.defaultValue ?? '';\n }\n onCancel?.();\n };\n\n const memoValue =\n (props.value as string) ??\n textAreaRef.current?.value ??\n (props.defaultValue as string) ??\n '';\n\n return (\n <EditableFieldLayout\n value={memoValue}\n onCancel={handleCancel}\n onSave={handleSave}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n >\n <AutoSizedTextArea\n className=\"leading-6\"\n ref={textAreaRef}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n {...props}\n />\n </EditableFieldLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDA,MAAa,yBAAyD,EACpE,QACA,UACA,KACA,GAAG,YACC;CACJ,MAAM,cAAc,OAA4B,IAAI;CAGpD,oBAAoB,WAA+B,YAAY,OAAQ;CAEvE,MAAM,mBAAmB;EAEvB,SAAS,YAAY,SAAS,SAAS,EAAE;CAC3C;CAEA,MAAM,qBAAqB;EACzB,IAAI,YAAY,SACd,YAAY,QAAQ,QAAQ,YAAY,QAAQ,gBAAgB;EAElE,WAAW;CACb;CAQA,OACE,oBAAC,qBAAD;EACE,OAPD,MAAM,SACP,YAAY,SAAS,SACpB,MAAM,gBACP;EAKE,UAAU;EACV,QAAQ;EACR,UAAU,MAAM;GACd,EAAE,eAAe;GACjB,EAAE,gBAAgB;EACpB;YAEA,oBAAC,mBAAD;GACE,WAAU;GACV,KAAK;GACL,UAAU,MAAM;IACd,EAAE,eAAe;IACjB,EAAE,gBAAgB;GACpB;GACA,GAAI;EACL;CACkB;AAEzB"}
1
+ {"version":3,"file":"EditableFieldTextArea.mjs","names":[],"sources":["../../../../src/components/EditableField/EditableFieldTextArea.tsx"],"sourcesContent":["'use client';\n\nimport { type FC, type Ref, useImperativeHandle, useRef } from 'react';\nimport { AutoSizedTextArea, type AutoSizedTextAreaProps } from '../TextArea';\nimport { EditableFieldLayout } from './EditableFieldLayout';\n\n/**\n * Props for the EditableFieldTextArea component, extending AutoSizedTextAreaProps\n */\ntype EditableFieldTextAreaProps = AutoSizedTextAreaProps & {\n /** Callback function called when the user saves the edited value */\n onSave?: (value: string) => void;\n /** Callback function called when the user cancels the edit operation */\n onCancel?: () => void;\n};\n\n/**\n * EditableFieldTextArea Component\n *\n * An inline editable textarea field that displays as read-only text until clicked.\n * When activated, it shows an auto-sized textarea with save and cancel buttons.\n * Perfect for multiline text editing with automatic height adjustment.\n *\n * @example\n * ```tsx\n * <EditableFieldTextArea\n * defaultValue=\"Multiline text content\"\n * placeholder=\"Click to edit...\"\n * maxRows={10}\n * onSave={(value) => console.log('Saved:', value)}\n * onCancel={() => console.log('Cancelled')}\n * />\n * ```\n *\n * ## Features\n * - **Inline Editing**: Click to edit, displays as formatted text when not editing\n * - **Auto-Sizing**: Automatically adjusts height to fit content\n * - **Save/Cancel Actions**: Built-in save and cancel buttons with callbacks\n * - **Multiline Support**: Preserves line breaks and formatting\n * - **Max Rows Control**: Configurable maximum height with scroll\n * - **Auto-save on Click Away**: Saves automatically when clicking outside\n * - **Ref Forwarding**: Exposes the underlying textarea element reference\n *\n * ## Accessibility\n * - Uses semantic HTML with proper ARIA attributes\n * - Keyboard accessible with tab navigation\n * - Screen reader friendly with descriptive labels\n * - Focus management for edit mode transitions\n * - Preserves whitespace and formatting for screen readers\n *\n * @param props - EditableFieldTextAreaProps extending AutoSizedTextAreaProps\n * @returns React functional component\n */\nexport const EditableFieldTextArea: FC<EditableFieldTextAreaProps> = ({\n onSave,\n onCancel,\n ref,\n ...props\n}) => {\n const textAreaRef = useRef<HTMLTextAreaElement>(null);\n\n // Expose the text area ref to parent components\n useImperativeHandle(ref as Ref<HTMLElement>, () => textAreaRef.current!);\n\n const handleSave = () => {\n // Your save logic here\n onSave?.(textAreaRef.current?.value ?? '');\n };\n\n const handleCancel = () => {\n if (textAreaRef.current) {\n textAreaRef.current.value = textAreaRef.current.defaultValue ?? '';\n }\n onCancel?.();\n };\n\n const memoValue =\n (props.value as string) ??\n textAreaRef.current?.value ??\n (props.defaultValue as string) ??\n '';\n\n return (\n <EditableFieldLayout\n value={memoValue}\n onCancel={handleCancel}\n onSave={handleSave}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n >\n <AutoSizedTextArea\n className=\"leading-6\"\n ref={textAreaRef}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n {...props}\n />\n </EditableFieldLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDA,MAAa,yBAAyD,EACpE,QACA,UACA,KACA,GAAG,YACC;CACJ,MAAM,cAAc,OAA4B,IAAI;CAGpD,oBAAoB,WAA+B,YAAY,OAAQ;CAEvE,MAAM,mBAAmB;EAEvB,SAAS,YAAY,SAAS,SAAS,EAAE;CAC3C;CAEA,MAAM,qBAAqB;EACzB,IAAI,YAAY,SACd,YAAY,QAAQ,QAAQ,YAAY,QAAQ,gBAAgB;EAElE,WAAW;CACb;CAEA,MAAM,YACH,MAAM,SACP,YAAY,SAAS,SACpB,MAAM,gBACP;CAEF,OACE,oBAAC,qBAAD;EACE,OAAO;EACP,UAAU;EACV,QAAQ;EACR,UAAU,MAAM;GACd,EAAE,eAAe;GACjB,EAAE,gBAAgB;EACpB;YAEA,oBAAC,mBAAD;GACE,WAAU;GACV,KAAK;GACL,UAAU,MAAM;IACd,EAAE,eAAe;IACjB,EAAE,gBAAgB;GACpB;GACA,GAAI;EACL;CACkB;AAEzB"}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
- import { InputIndicator, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from "../../Input/OTPInput.mjs";
4
3
  import { useItemSelector } from "../../../hooks/useItemSelector.mjs";
4
+ import { InputIndicator, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from "../../Input/OTPInput.mjs";
5
5
  import { FormField, useFormField } from "../FormField.mjs";
6
6
  import { FormItemLayout } from "../layout/FormItemLayout.mjs";
7
7
  import { useEffect, useRef } from "react";
@@ -49,8 +49,9 @@ const getIntlayerHTMLOptions = () => ({ components: {
49
49
  * interactive content with custom styling and Intlayer integration.
50
50
  */
51
51
  const HTMLRenderer = ({ children, isDarkMode, locale, components: componentsProp }) => {
52
- return /* @__PURE__ */ jsx(Fragment, { children: renderHTML(children, { components: {
53
- ...getIntlayerHTMLOptions(isDarkMode ?? false).components,
52
+ const htmlOptions = getIntlayerHTMLOptions(isDarkMode ?? false);
53
+ const htmlContent = renderHTML(children, { components: {
54
+ ...htmlOptions.components,
54
55
  a: (props) => /* @__PURE__ */ jsx(Link, {
55
56
  isExternalLink: props.href?.startsWith("http"),
56
57
  underlined: true,
@@ -60,7 +61,8 @@ const HTMLRenderer = ({ children, isDarkMode, locale, components: componentsProp
60
61
  color: "neutral"
61
62
  }),
62
63
  ...componentsProp
63
- } }) });
64
+ } });
65
+ return /* @__PURE__ */ jsx(Fragment, { children: htmlContent });
64
66
  };
65
67
 
66
68
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"HTMLRender.mjs","names":[],"sources":["../../../../src/components/HTMLRender/HTMLRender.tsx"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport type { ComponentProps, FC } from 'react';\nimport {\n type HTMLRenderer as HTMLRendererIntlayer,\n type RenderHTMLProps,\n renderHTML,\n} from 'react-intlayer/html';\nimport { H1, H2, H3, H4, H5, H6 } from '../Headers';\nimport { Link } from '../Link';\n\ntype HTMLRendererProps = {\n children: string;\n isDarkMode?: boolean;\n locale?: LocalesValues;\n components?: ComponentProps<typeof HTMLRendererIntlayer>['components'];\n};\n\nexport const getIntlayerHTMLOptions: (isDarkMode: boolean) => RenderHTMLProps =\n () => ({\n components: {\n h1: (props) => <H1 isClickable={true} {...props} />,\n h2: (props) => <H2 isClickable={true} className=\"mt-16\" {...props} />,\n h3: (props) => <H3 isClickable={true} className=\"mt-5\" {...props} />,\n h4: (props) => <H4 isClickable={true} className=\"mt-3\" {...props} />,\n h5: (props) => <H5 isClickable={true} className=\"mt-3\" {...props} />,\n h6: (props) => <H6 isClickable={true} className=\"mt-3\" {...props} />,\n a: (props) => (\n <Link\n isExternalLink={props.href?.startsWith('http')}\n underlined={true}\n label=\"\"\n {...props}\n color=\"neutral\"\n />\n ),\n },\n });\n\n/**\n * HTMLRenderer Component\n *\n * A comprehensive HTML renderer that transforms HTML text into rich,\n * interactive content with custom styling and Intlayer integration.\n */\nexport const HTMLRenderer: FC<HTMLRendererProps> = ({\n children,\n isDarkMode,\n locale,\n components: componentsProp,\n}) => {\n const htmlOptions = getIntlayerHTMLOptions(isDarkMode ?? false);\n\n const htmlContent = renderHTML(children, {\n components: {\n ...htmlOptions.components,\n a: (props) => (\n <Link\n isExternalLink={props.href?.startsWith('http')}\n underlined={true}\n locale={locale}\n label=\"\"\n {...props}\n color=\"neutral\"\n />\n ),\n ...componentsProp,\n },\n });\n\n return <>{htmlContent}</>;\n};\n"],"mappings":";;;;;;AAiBA,MAAa,gCACJ,EACL,YAAY;CACV,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,GAAI;CAAQ;CAClD,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,WAAU;EAAQ,GAAI;CAAQ;CACpE,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,WAAU;EAAO,GAAI;CAAQ;CACnE,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,WAAU;EAAO,GAAI;CAAQ;CACnE,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,WAAU;EAAO,GAAI;CAAQ;CACnE,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,WAAU;EAAO,GAAI;CAAQ;CACnE,IAAI,UACF,oBAAC,MAAD;EACE,gBAAgB,MAAM,MAAM,WAAW,MAAM;EAC7C,YAAY;EACZ,OAAM;EACN,GAAI;EACJ,OAAM;CACP;AAEL,EACF;;;;;;;AAQF,MAAa,gBAAuC,EAClD,UACA,YACA,QACA,YAAY,qBACR;CAoBJ,OAAO,0CAjBa,WAAW,UAAU,EACvC,YAAY;EACV,GAJgB,uBAAuB,cAAc,KAIxC,CAAC,CAAC;EACf,IAAI,UACF,oBAAC,MAAD;GACE,gBAAgB,MAAM,MAAM,WAAW,MAAM;GAC7C,YAAY;GACJ;GACR,OAAM;GACN,GAAI;GACJ,OAAM;EACP;EAEH,GAAG;CACL,EACF,CAEoB,EAAI;AAC1B"}
1
+ {"version":3,"file":"HTMLRender.mjs","names":[],"sources":["../../../../src/components/HTMLRender/HTMLRender.tsx"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport type { ComponentProps, FC } from 'react';\nimport {\n type HTMLRenderer as HTMLRendererIntlayer,\n type RenderHTMLProps,\n renderHTML,\n} from 'react-intlayer/html';\nimport { H1, H2, H3, H4, H5, H6 } from '../Headers';\nimport { Link } from '../Link';\n\ntype HTMLRendererProps = {\n children: string;\n isDarkMode?: boolean;\n locale?: LocalesValues;\n components?: ComponentProps<typeof HTMLRendererIntlayer>['components'];\n};\n\nexport const getIntlayerHTMLOptions: (isDarkMode: boolean) => RenderHTMLProps =\n () => ({\n components: {\n h1: (props) => <H1 isClickable={true} {...props} />,\n h2: (props) => <H2 isClickable={true} className=\"mt-16\" {...props} />,\n h3: (props) => <H3 isClickable={true} className=\"mt-5\" {...props} />,\n h4: (props) => <H4 isClickable={true} className=\"mt-3\" {...props} />,\n h5: (props) => <H5 isClickable={true} className=\"mt-3\" {...props} />,\n h6: (props) => <H6 isClickable={true} className=\"mt-3\" {...props} />,\n a: (props) => (\n <Link\n isExternalLink={props.href?.startsWith('http')}\n underlined={true}\n label=\"\"\n {...props}\n color=\"neutral\"\n />\n ),\n },\n });\n\n/**\n * HTMLRenderer Component\n *\n * A comprehensive HTML renderer that transforms HTML text into rich,\n * interactive content with custom styling and Intlayer integration.\n */\nexport const HTMLRenderer: FC<HTMLRendererProps> = ({\n children,\n isDarkMode,\n locale,\n components: componentsProp,\n}) => {\n const htmlOptions = getIntlayerHTMLOptions(isDarkMode ?? false);\n\n const htmlContent = renderHTML(children, {\n components: {\n ...htmlOptions.components,\n a: (props) => (\n <Link\n isExternalLink={props.href?.startsWith('http')}\n underlined={true}\n locale={locale}\n label=\"\"\n {...props}\n color=\"neutral\"\n />\n ),\n ...componentsProp,\n },\n });\n\n return <>{htmlContent}</>;\n};\n"],"mappings":";;;;;;AAiBA,MAAa,gCACJ,EACL,YAAY;CACV,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,GAAI;CAAQ;CAClD,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,WAAU;EAAQ,GAAI;CAAQ;CACpE,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,WAAU;EAAO,GAAI;CAAQ;CACnE,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,WAAU;EAAO,GAAI;CAAQ;CACnE,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,WAAU;EAAO,GAAI;CAAQ;CACnE,KAAK,UAAU,oBAAC,IAAD;EAAI,aAAa;EAAM,WAAU;EAAO,GAAI;CAAQ;CACnE,IAAI,UACF,oBAAC,MAAD;EACE,gBAAgB,MAAM,MAAM,WAAW,MAAM;EAC7C,YAAY;EACZ,OAAM;EACN,GAAI;EACJ,OAAM;CACP;AAEL,EACF;;;;;;;AAQF,MAAa,gBAAuC,EAClD,UACA,YACA,QACA,YAAY,qBACR;CACJ,MAAM,cAAc,uBAAuB,cAAc,KAAK;CAE9D,MAAM,cAAc,WAAW,UAAU,EACvC,YAAY;EACV,GAAG,YAAY;EACf,IAAI,UACF,oBAAC,MAAD;GACE,gBAAgB,MAAM,MAAM,WAAW,MAAM;GAC7C,YAAY;GACJ;GACR,OAAM;GACN,GAAI;GACJ,OAAM;EACP;EAEH,GAAG;CACL,EACF,CAAC;CAED,OAAO,0CAAG,YAAc;AAC1B"}
@@ -2,8 +2,8 @@
2
2
 
3
3
  import { cn } from "../../utils/cn.mjs";
4
4
  import { useEffect, useMemo, useRef, useState } from "react";
5
- import { Eye, EyeOff } from "lucide-react";
6
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { Eye, EyeOff } from "lucide-react";
7
7
 
8
8
  //#region src/components/HideShow/index.tsx
9
9
  const insertBreaks = (str, groupSize = 6) => str.replace(new RegExp(`.{1,${groupSize}}`, "g"), "$&​");
@@ -1 +1 @@
1
- {"version":3,"file":"Code.mjs","names":[],"sources":["../../../../src/components/IDE/Code.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport type { FC, HTMLAttributes, ReactNode } from 'react';\nimport { useEffect, useMemo, useState } from 'react';\nimport type { BundledLanguage } from 'shiki/bundle/web';\nimport { Container } from '../Container';\nimport { ExpandCollapse } from '../ExpandCollapse';\nimport { CodeBlock } from './CodeBlockClient';\nimport { CodeBlockHighlight } from './CodeBlockHighlight';\nimport { CodeConditionalRender } from './CodeConditionalRenderer';\nimport type {\n CodeFormat,\n ContentDeclarationFormat,\n PackageManager,\n} from './CodeContext';\nimport { useCodeContext } from './CodeContext';\nimport { CodeFormatSelector } from './CodeFormatSelector';\nimport { ContentDeclarationFormatSelector } from './ContentDeclarationFormatSelector';\nimport { CopyCode } from './CopyCode';\nimport { PackageManagerSelector } from './PackageManagerSelector';\n\nexport type CodeCompAttributes = {\n fileName?: string;\n packageManager?: PackageManager;\n /** Single format, a JSON-array string, or an array of formats. */\n codeFormat?: CodeFormat | string | string[];\n contentDeclarationFormat?: ContentDeclarationFormat | string | string[];\n};\n\ntype CodeCompProps = {\n children: ReactNode;\n fileName?: string;\n language: BundledLanguage;\n isDarkMode?: boolean;\n showHeader?: boolean;\n showLineNumbers?: boolean;\n isRollable?: boolean;\n} & CodeCompAttributes &\n HTMLAttributes<HTMLDivElement>;\n\nconst MIN_HEIGHT = 700;\n\n/** Languages that use JSX syntax — CommonJS doesn't make sense for these. */\nconst JSX_LANGUAGES = new Set(['tsx', 'jsx']);\n\n/** Parse a codeFormat prop that may be a single value, a JSON-array string, or already an array. */\nconst parseFormats = (\n raw: string | string[] | undefined\n): CodeFormat[] | undefined => {\n if (!raw) return undefined;\n if (Array.isArray(raw)) return raw as CodeFormat[];\n if (typeof raw === 'string' && raw.startsWith('[')) {\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) return parsed as CodeFormat[];\n } catch {\n /* ignore */\n }\n }\n return [raw as CodeFormat];\n};\n\nexport const Code: FC<CodeCompProps> = ({\n children,\n language,\n isDarkMode,\n showHeader = true,\n showLineNumbers = true,\n className,\n fileName,\n packageManager,\n codeFormat: rawCodeFormat,\n contentDeclarationFormat: rawContentDeclarationFormat,\n isRollable = true,\n lang, // Destructure html lang prop to prevent passing invalid BCP-47 language tag to Code component\n ...props\n}) => {\n const {\n codeFormat: selectedCodeFormat,\n contentDeclarationFormat: selectedContentDeclarationFormat,\n } = useCodeContext();\n\n // Parse whichever attribute is present as an array of formats.\n const codeFormats = useMemo(\n () => parseFormats(rawCodeFormat as string | undefined),\n [rawCodeFormat]\n );\n const contentFormats = useMemo(\n () => parseFormats(rawContentDeclarationFormat as string | undefined),\n [rawContentDeclarationFormat]\n );\n\n // A block is \"multi-format\" when it has multiple formats including TypeScript\n // (the canonical source). Such blocks transform at runtime.\n const isMultiCodeFormat =\n codeFormats !== undefined &&\n codeFormats.length > 1 &&\n codeFormats.includes('typescript');\n\n const isMultiContentFormat =\n contentFormats !== undefined &&\n contentFormats.length > 1 &&\n contentFormats.includes('typescript');\n\n const isMultiFormat = isMultiCodeFormat || isMultiContentFormat;\n\n // Determine which context format drives this block's selection.\n // content declaration blocks use selectedContentDeclarationFormat;\n // regular code blocks use selectedCodeFormat.\n const selectedFormat: CodeFormat = isMultiContentFormat\n ? (selectedContentDeclarationFormat as CodeFormat)\n : selectedCodeFormat;\n\n // The formats actually relevant for transformation (no 'json', no 'commonjs' for JSX).\n const effectiveFormats = useMemo<CodeFormat[] | undefined>(() => {\n const base = isMultiContentFormat ? contentFormats : codeFormats;\n if (!base) return base;\n let filtered = base.filter((f) => f !== 'json') as CodeFormat[];\n if (JSX_LANGUAGES.has(language as string)) {\n filtered = filtered.filter((f) => f !== 'commonjs');\n }\n return filtered;\n }, [isMultiContentFormat, contentFormats, codeFormats, language]);\n\n // When the globally-selected format isn't valid for this block\n // (e.g. CJS selected but this is a JSX file), fall back to the last valid one.\n const resolvedFormat: Exclude<CodeFormat, 'json'> = useMemo(() => {\n if (!effectiveFormats || effectiveFormats.includes(selectedFormat)) {\n return selectedFormat as Exclude<CodeFormat, 'json'>;\n }\n return (effectiveFormats[effectiveFormats.length - 1] ??\n 'typescript') as Exclude<CodeFormat, 'json'>;\n }, [effectiveFormats, selectedFormat]);\n\n // ── Async filename derivation (dynamic import of transformer) ──────────────\n // We derive the displayed fileName so the header updates when format changes.\n // deriveFileName is tiny but it lives inside codeTransformer, which is only\n // imported when actually needed (non-TypeScript selection).\n const [displayedFileName, setDisplayedFileName] = useState<\n string | undefined\n >(fileName);\n\n useEffect(() => {\n if (!isMultiFormat || resolvedFormat === 'typescript') {\n setDisplayedFileName(fileName);\n return;\n }\n if (!fileName) return;\n\n let cancelled = false;\n (async () => {\n const { deriveFileName } = await import('./codeTransformer');\n if (!cancelled)\n setDisplayedFileName(deriveFileName(fileName, resolvedFormat));\n })();\n return () => {\n cancelled = true;\n };\n }, [fileName, isMultiFormat, resolvedFormat]);\n\n // ── Async copy text (transformed code for CopyCode) ───────────────────────\n const rawCode = useMemo(() => {\n const code = Array.isArray(children) ? children.join('') : String(children);\n return code.endsWith('\\n') ? code.slice(0, -1) : code;\n }, [children]);\n\n const [copyCode, setCopyCode] = useState<string>(rawCode);\n\n useEffect(() => {\n if (!isMultiFormat || resolvedFormat === 'typescript') {\n setCopyCode(rawCode);\n return;\n }\n let cancelled = false;\n (async () => {\n const { transformCode } = await import('./codeTransformer');\n if (!cancelled) setCopyCode(transformCode(rawCode, resolvedFormat));\n })();\n return () => {\n cancelled = true;\n };\n }, [rawCode, isMultiFormat, resolvedFormat]);\n\n const hadSelectInHeader =\n packageManager || rawCodeFormat || rawContentDeclarationFormat;\n\n return (\n <CodeConditionalRender\n packageManager={packageManager}\n codeFormat={rawCodeFormat as string | undefined}\n contentDeclarationFormat={\n rawContentDeclarationFormat as string | undefined\n }\n >\n <Container\n className={cn(\n 'relative min-w-0 max-w-full text-sm leading-6',\n showLineNumbers && 'with-line-number ml-0',\n className\n )}\n transparency=\"lg\"\n {...props}\n >\n {showHeader && (\n <>\n <div className=\"grid w-full grid-cols-[1fr_auto] items-center justify-between rounded-t-xl bg-card/50 py-1.5 pr-12 pl-4 text-neutral text-xs\">\n <span className=\"truncate\">{displayedFileName ?? language}</span>\n <div className=\"flex items-center gap-2\">\n {packageManager && <PackageManagerSelector />}\n {rawCodeFormat && (\n <CodeFormatSelector availableFormats={effectiveFormats} />\n )}\n {rawContentDeclarationFormat && (\n <ContentDeclarationFormatSelector />\n )}\n </div>\n </div>\n <div className=\"sticky top-46 z-20\">\n <div\n className={cn(\n 'absolute right-2 bottom-0 flex h-7 items-center',\n hadSelectInHeader && 'h-11'\n )}\n >\n <CopyCode code={copyCode} />\n </div>\n </div>\n </>\n )}\n <ExpandCollapse\n minHeight={MIN_HEIGHT}\n isRollable={isRollable}\n className=\"min-w-0 max-w-full overflow-x-auto p-2\"\n >\n {isMultiFormat ? (\n /*\n * Multi-format: CodeBlockHighlight manages both the transformation\n * (dynamic import of codeTransformer) and the Shiki highlighting in\n * a single useEffect. The previous highlighted output stays visible\n * while the new one loads — no white-text flash.\n */\n <CodeBlockHighlight\n originalLang={language}\n targetFormat={resolvedFormat}\n isDarkMode={isDarkMode}\n >\n {rawCode}\n </CodeBlockHighlight>\n ) : (\n /*\n * Single-format: use the original Suspense-based async Shiki renderer\n * (good for SSR / static content).\n */\n <CodeBlock lang={language} isDarkMode={isDarkMode}>\n {rawCode}\n </CodeBlock>\n )}\n </ExpandCollapse>\n </Container>\n </CodeConditionalRender>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"Code.mjs","names":[],"sources":["../../../../src/components/IDE/Code.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport type { FC, HTMLAttributes, ReactNode } from 'react';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Container } from '../Container';\nimport { ExpandCollapse } from '../ExpandCollapse';\nimport { CodeBlock } from './CodeBlockClient';\nimport { CodeBlockHighlight } from './CodeBlockHighlight';\nimport { CodeConditionalRender } from './CodeConditionalRenderer';\nimport type {\n CodeFormat,\n ContentDeclarationFormat,\n PackageManager,\n} from './CodeContext';\nimport { useCodeContext } from './CodeContext';\nimport { CodeFormatSelector } from './CodeFormatSelector';\nimport { ContentDeclarationFormatSelector } from './ContentDeclarationFormatSelector';\nimport { CopyCode } from './CopyCode';\nimport { PackageManagerSelector } from './PackageManagerSelector';\nimport type { CodeLanguage } from './shikiLanguages';\n\nexport type CodeCompAttributes = {\n fileName?: string;\n packageManager?: PackageManager;\n /** Single format, a JSON-array string, or an array of formats. */\n codeFormat?: CodeFormat | string | string[];\n contentDeclarationFormat?: ContentDeclarationFormat | string | string[];\n};\n\ntype CodeCompProps = {\n children: ReactNode;\n fileName?: string;\n language: CodeLanguage;\n isDarkMode?: boolean;\n showHeader?: boolean;\n showLineNumbers?: boolean;\n isRollable?: boolean;\n} & CodeCompAttributes &\n HTMLAttributes<HTMLDivElement>;\n\nconst MIN_HEIGHT = 700;\n\n/** Languages that use JSX syntax — CommonJS doesn't make sense for these. */\nconst JSX_LANGUAGES = new Set(['tsx', 'jsx']);\n\n/** Parse a codeFormat prop that may be a single value, a JSON-array string, or already an array. */\nconst parseFormats = (\n raw: string | string[] | undefined\n): CodeFormat[] | undefined => {\n if (!raw) return undefined;\n if (Array.isArray(raw)) return raw as CodeFormat[];\n if (typeof raw === 'string' && raw.startsWith('[')) {\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) return parsed as CodeFormat[];\n } catch {\n /* ignore */\n }\n }\n return [raw as CodeFormat];\n};\n\nexport const Code: FC<CodeCompProps> = ({\n children,\n language,\n isDarkMode,\n showHeader = true,\n showLineNumbers = true,\n className,\n fileName,\n packageManager,\n codeFormat: rawCodeFormat,\n contentDeclarationFormat: rawContentDeclarationFormat,\n isRollable = true,\n lang, // Destructure html lang prop to prevent passing invalid BCP-47 language tag to Code component\n ...props\n}) => {\n const {\n codeFormat: selectedCodeFormat,\n contentDeclarationFormat: selectedContentDeclarationFormat,\n } = useCodeContext();\n\n // Parse whichever attribute is present as an array of formats.\n const codeFormats = useMemo(\n () => parseFormats(rawCodeFormat as string | undefined),\n [rawCodeFormat]\n );\n const contentFormats = useMemo(\n () => parseFormats(rawContentDeclarationFormat as string | undefined),\n [rawContentDeclarationFormat]\n );\n\n // A block is \"multi-format\" when it has multiple formats including TypeScript\n // (the canonical source). Such blocks transform at runtime.\n const isMultiCodeFormat =\n codeFormats !== undefined &&\n codeFormats.length > 1 &&\n codeFormats.includes('typescript');\n\n const isMultiContentFormat =\n contentFormats !== undefined &&\n contentFormats.length > 1 &&\n contentFormats.includes('typescript');\n\n const isMultiFormat = isMultiCodeFormat || isMultiContentFormat;\n\n // Determine which context format drives this block's selection.\n // content declaration blocks use selectedContentDeclarationFormat;\n // regular code blocks use selectedCodeFormat.\n const selectedFormat: CodeFormat = isMultiContentFormat\n ? (selectedContentDeclarationFormat as CodeFormat)\n : selectedCodeFormat;\n\n // The formats actually relevant for transformation (no 'json', no 'commonjs' for JSX).\n const effectiveFormats = useMemo<CodeFormat[] | undefined>(() => {\n const base = isMultiContentFormat ? contentFormats : codeFormats;\n if (!base) return base;\n let filtered = base.filter((f) => f !== 'json') as CodeFormat[];\n if (JSX_LANGUAGES.has(language as string)) {\n filtered = filtered.filter((f) => f !== 'commonjs');\n }\n return filtered;\n }, [isMultiContentFormat, contentFormats, codeFormats, language]);\n\n // When the globally-selected format isn't valid for this block\n // (e.g. CJS selected but this is a JSX file), fall back to the last valid one.\n const resolvedFormat: Exclude<CodeFormat, 'json'> = useMemo(() => {\n if (!effectiveFormats || effectiveFormats.includes(selectedFormat)) {\n return selectedFormat as Exclude<CodeFormat, 'json'>;\n }\n return (effectiveFormats[effectiveFormats.length - 1] ??\n 'typescript') as Exclude<CodeFormat, 'json'>;\n }, [effectiveFormats, selectedFormat]);\n\n // ── Async filename derivation (dynamic import of transformer) ──────────────\n // We derive the displayed fileName so the header updates when format changes.\n // deriveFileName is tiny but it lives inside codeTransformer, which is only\n // imported when actually needed (non-TypeScript selection).\n const [displayedFileName, setDisplayedFileName] = useState<\n string | undefined\n >(fileName);\n\n useEffect(() => {\n if (!isMultiFormat || resolvedFormat === 'typescript') {\n setDisplayedFileName(fileName);\n return;\n }\n if (!fileName) return;\n\n let cancelled = false;\n (async () => {\n const { deriveFileName } = await import('./codeTransformer');\n if (!cancelled)\n setDisplayedFileName(deriveFileName(fileName, resolvedFormat));\n })();\n return () => {\n cancelled = true;\n };\n }, [fileName, isMultiFormat, resolvedFormat]);\n\n // ── Async copy text (transformed code for CopyCode) ───────────────────────\n const rawCode = useMemo(() => {\n const code = Array.isArray(children) ? children.join('') : String(children);\n return code.endsWith('\\n') ? code.slice(0, -1) : code;\n }, [children]);\n\n const [copyCode, setCopyCode] = useState<string>(rawCode);\n\n useEffect(() => {\n if (!isMultiFormat || resolvedFormat === 'typescript') {\n setCopyCode(rawCode);\n return;\n }\n let cancelled = false;\n (async () => {\n const { transformCode } = await import('./codeTransformer');\n if (!cancelled) setCopyCode(transformCode(rawCode, resolvedFormat));\n })();\n return () => {\n cancelled = true;\n };\n }, [rawCode, isMultiFormat, resolvedFormat]);\n\n const hadSelectInHeader =\n packageManager || rawCodeFormat || rawContentDeclarationFormat;\n\n return (\n <CodeConditionalRender\n packageManager={packageManager}\n codeFormat={rawCodeFormat as string | undefined}\n contentDeclarationFormat={\n rawContentDeclarationFormat as string | undefined\n }\n >\n <Container\n className={cn(\n 'relative min-w-0 max-w-full text-sm leading-6',\n showLineNumbers && 'with-line-number ml-0',\n className\n )}\n transparency=\"lg\"\n {...props}\n >\n {showHeader && (\n <>\n <div className=\"grid w-full grid-cols-[1fr_auto] items-center justify-between rounded-t-xl bg-card/50 py-1.5 pr-12 pl-4 text-neutral text-xs\">\n <span className=\"truncate\">{displayedFileName ?? language}</span>\n <div className=\"flex items-center gap-2\">\n {packageManager && <PackageManagerSelector />}\n {rawCodeFormat && (\n <CodeFormatSelector availableFormats={effectiveFormats} />\n )}\n {rawContentDeclarationFormat && (\n <ContentDeclarationFormatSelector />\n )}\n </div>\n </div>\n <div className=\"sticky top-46 z-20\">\n <div\n className={cn(\n 'absolute right-2 bottom-0 flex h-7 items-center',\n hadSelectInHeader && 'h-11'\n )}\n >\n <CopyCode code={copyCode} />\n </div>\n </div>\n </>\n )}\n <ExpandCollapse\n minHeight={MIN_HEIGHT}\n isRollable={isRollable}\n className=\"min-w-0 max-w-full overflow-x-auto p-2\"\n >\n {isMultiFormat ? (\n /*\n * Multi-format: CodeBlockHighlight manages both the transformation\n * (dynamic import of codeTransformer) and the Shiki highlighting in\n * a single useEffect. The previous highlighted output stays visible\n * while the new one loads — no white-text flash.\n */\n <CodeBlockHighlight\n originalLang={language}\n targetFormat={resolvedFormat}\n isDarkMode={isDarkMode}\n >\n {rawCode}\n </CodeBlockHighlight>\n ) : (\n /*\n * Single-format: use the original Suspense-based async Shiki renderer\n * (good for SSR / static content).\n */\n <CodeBlock lang={language} isDarkMode={isDarkMode}>\n {rawCode}\n </CodeBlock>\n )}\n </ExpandCollapse>\n </Container>\n </CodeConditionalRender>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CodeBlockClient.mjs","names":[],"sources":["../../../../src/components/IDE/CodeBlockClient.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport {\n type FC,\n type HTMLAttributes,\n lazy,\n type ReactNode,\n Suspense,\n} from 'react';\nimport type { BundledLanguage } from 'shiki/bundle/web';\n\nexport type { BundledLanguage as CodeLanguage } from 'shiki/bundle/web';\n\nexport const CodeDefault: FC<{ children: ReactNode }> = ({ children }) => (\n <div className=\"min-w-0 max-w-full overflow-x-auto\">\n <pre className=\"min-w-0 max-w-full overflow-x-auto [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\">\n <code>\n {typeof children === 'string'\n ? children.split('\\n').map((line, index) => (\n <span\n className=\"line block w-full\"\n key={`line-${index}-${line.slice(0, 10)}`}\n >\n {line}\n </span>\n ))\n : children}\n </code>\n </pre>\n </div>\n);\n\n// Lazy load the Shiki component\nconst CodeBlockShiki = lazy(() =>\n import('./CodeBlockShiki').then((mod) => ({\n default: mod.CodeBlockShiki,\n }))\n);\n\nexport type CodeBlockProps = {\n children: React.ReactNode;\n lang: BundledLanguage;\n isDarkMode?: boolean;\n isEditable?: boolean;\n onChange?: (content: string) => void;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange'>;\n\nexport const CodeBlock: FC<CodeBlockProps> = ({\n className,\n onChange,\n isEditable,\n children,\n lang,\n isDarkMode,\n ...props\n}) => (\n <div\n className={cn('flex w-full min-w-0 max-w-full overflow-x-auto', className)}\n {...props}\n >\n <Suspense fallback={<CodeDefault>{children}</CodeDefault>}>\n <CodeBlockShiki lang={lang} isDarkMode={isDarkMode}>\n {children}\n </CodeBlockShiki>\n </Suspense>\n </div>\n);\n"],"mappings":";;;;;AAYA,MAAa,eAA4C,EAAE,eACzD,oBAAC,OAAD;CAAK,WAAU;WACb,oBAAC,OAAD;EAAK,WAAU;YACb,oBAAC,QAAD,YACG,OAAO,aAAa,WACjB,SAAS,MAAM,IAAI,CAAC,CAAC,KAAK,MAAM,UAC9B,oBAAC,QAAD;GACE,WAAU;aAGT;EACG,GAHC,QAAQ,MAAM,GAAG,KAAK,MAAM,GAAG,EAAE,GAGlC,CACP,IACD,SACA;CACH;AACF;AAIP,MAAM,iBAAiB,WACrB,OAAO,uBAAmB,CAAC,MAAM,SAAS,EACxC,SAAS,IAAI,eACf,EAAE,CACJ;AAUA,MAAa,aAAiC,EAC5C,WACA,UACA,YACA,UACA,MACA,YACA,GAAG,YAEH,oBAAC,OAAD;CACE,WAAW,GAAG,kDAAkD,SAAS;CACzE,GAAI;WAEJ,oBAAC,UAAD;EAAU,UAAU,oBAAC,aAAD,EAAc,SAAsB;YACtD,oBAAC,gBAAD;GAAsB;GAAkB;GACrC;EACa;CACR;AACP"}
1
+ {"version":3,"file":"CodeBlockClient.mjs","names":[],"sources":["../../../../src/components/IDE/CodeBlockClient.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport {\n type FC,\n type HTMLAttributes,\n lazy,\n type ReactNode,\n Suspense,\n} from 'react';\nimport type { CodeLanguage } from './shikiLanguages';\n\nexport type { CodeLanguage } from './shikiLanguages';\n\nexport const CodeDefault: FC<{ children: ReactNode }> = ({ children }) => (\n <div className=\"min-w-0 max-w-full overflow-x-auto\">\n <pre className=\"min-w-0 max-w-full overflow-x-auto [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\">\n <code>\n {typeof children === 'string'\n ? children.split('\\n').map((line, index) => (\n <span\n className=\"line block w-full\"\n key={`line-${index}-${line.slice(0, 10)}`}\n >\n {line}\n </span>\n ))\n : children}\n </code>\n </pre>\n </div>\n);\n\n// Lazy load the Shiki component\nconst CodeBlockShiki = lazy(() =>\n import('./CodeBlockShiki').then((mod) => ({\n default: mod.CodeBlockShiki,\n }))\n);\n\nexport type CodeBlockProps = {\n children: React.ReactNode;\n lang: CodeLanguage;\n isDarkMode?: boolean;\n isEditable?: boolean;\n onChange?: (content: string) => void;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange'>;\n\nexport const CodeBlock: FC<CodeBlockProps> = ({\n className,\n onChange,\n isEditable,\n children,\n lang,\n isDarkMode,\n ...props\n}) => (\n <div\n className={cn('flex w-full min-w-0 max-w-full overflow-x-auto', className)}\n {...props}\n >\n <Suspense fallback={<CodeDefault>{children}</CodeDefault>}>\n <CodeBlockShiki lang={lang} isDarkMode={isDarkMode}>\n {children}\n </CodeBlockShiki>\n </Suspense>\n </div>\n);\n"],"mappings":";;;;;AAYA,MAAa,eAA4C,EAAE,eACzD,oBAAC,OAAD;CAAK,WAAU;WACb,oBAAC,OAAD;EAAK,WAAU;YACb,oBAAC,QAAD,YACG,OAAO,aAAa,WACjB,SAAS,MAAM,IAAI,CAAC,CAAC,KAAK,MAAM,UAC9B,oBAAC,QAAD;GACE,WAAU;aAGT;EACG,GAHC,QAAQ,MAAM,GAAG,KAAK,MAAM,GAAG,EAAE,GAGlC,CACP,IACD,SACA;CACH;AACF;AAIP,MAAM,iBAAiB,WACrB,OAAO,uBAAmB,CAAC,MAAM,SAAS,EACxC,SAAS,IAAI,eACf,EAAE,CACJ;AAUA,MAAa,aAAiC,EAC5C,WACA,UACA,YACA,UACA,MACA,YACA,GAAG,YAEH,oBAAC,OAAD;CACE,WAAW,GAAG,kDAAkD,SAAS;CACzE,GAAI;WAEJ,oBAAC,UAAD;EAAU,UAAU,oBAAC,aAAD,EAAc,SAAsB;YACtD,oBAAC,gBAAD;GAAsB;GAAkB;GACrC;EACa;CACR;AACP"}
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
 
3
+ import { resolveCodeLanguage } from "./shikiLanguages.mjs";
3
4
  import { useEffect, useRef, useState } from "react";
4
5
  import { jsx } from "react/jsx-runtime";
5
6
 
@@ -11,18 +12,6 @@ import { jsx } from "react/jsx-runtime";
11
12
  * - The transformer is only dynamically imported when a non-TypeScript format is selected.
12
13
  * - The previous highlighted HTML stays visible while the new one loads (no white-text flash).
13
14
  */
14
- /**
15
- * Map display language names to Shiki grammar identifiers.
16
- * Shiki's web bundle does not ship a separate 'jsx' grammar — tsx handles both.
17
- */
18
- const toShikiLang = (lang) => {
19
- switch (lang) {
20
- case "jsx": return "tsx";
21
- case "mjs":
22
- case "cjs": return "javascript";
23
- default: return lang;
24
- }
25
- };
26
15
  const CodeBlockHighlight = ({ children, originalLang, targetFormat, isDarkMode }) => {
27
16
  const [html, setHtml] = useState(null);
28
17
  const prevHtml = useRef(null);
@@ -31,12 +20,12 @@ const CodeBlockHighlight = ({ children, originalLang, targetFormat, isDarkMode }
31
20
  (async () => {
32
21
  try {
33
22
  let code = children;
34
- let shikiLang = toShikiLang(originalLang);
23
+ let shikiLang = resolveCodeLanguage(originalLang).id;
35
24
  if (targetFormat !== "typescript") {
36
25
  const { transformCode, deriveLanguage } = await import("./codeTransformer.mjs");
37
26
  if (cancelled) return;
38
27
  code = transformCode(String(children), targetFormat);
39
- shikiLang = toShikiLang(deriveLanguage(originalLang, targetFormat));
28
+ shikiLang = resolveCodeLanguage(deriveLanguage(originalLang, targetFormat)).id;
40
29
  }
41
30
  const { codeToHtml } = await import("shiki/bundle/web");
42
31
  if (cancelled) return;