@intlayer/design-system 9.3.0 → 9.3.2
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.
- package/README.md +22 -22
- package/dist/esm/api/hooks/utils.mjs +2 -1
- package/dist/esm/api/hooks/utils.mjs.map +1 -1
- package/dist/esm/api/index.mjs +2 -2
- package/dist/esm/api/useAuth/useOAuth2.mjs +14 -4
- package/dist/esm/api/useAuth/useOAuth2.mjs.map +1 -1
- package/dist/esm/api/useAuth/useSession.mjs +7 -5
- package/dist/esm/api/useAuth/useSession.mjs.map +1 -1
- package/dist/esm/components/Accordion/Accordion.mjs +1 -1
- package/dist/esm/components/Avatar/index.mjs +1 -1
- package/dist/esm/components/Badge/index.mjs +1 -1
- package/dist/esm/components/Breadcrumb/index.mjs +1 -1
- package/dist/esm/components/Browser/Browser.mjs +1 -1
- package/dist/esm/components/Button/Button.mjs +1 -1
- package/dist/esm/components/Carousel/index.mjs +1 -1
- package/dist/esm/components/CollapsibleTable/CollapsibleTable.mjs +1 -1
- package/dist/esm/components/Command/index.mjs +1 -1
- package/dist/esm/components/Container/index.mjs +1 -1
- package/dist/esm/components/ContentEditor/ContentEditor.mjs +1 -1
- package/dist/esm/components/ContentEditor/ContentEditorInput.mjs +1 -1
- package/dist/esm/components/ContentEditor/ContentEditorTextArea.mjs +2 -2
- package/dist/esm/components/CopyButton/index.mjs +1 -1
- package/dist/esm/components/CopyToClipboard/index.mjs +1 -1
- package/dist/esm/components/DictionaryEditor/NodeWrapper/BooleanWrapper.mjs +2 -1
- package/dist/esm/components/DictionaryEditor/NodeWrapper/BooleanWrapper.mjs.map +1 -1
- package/dist/esm/components/DictionaryEditor/NodeWrapper/NumberWrapper.mjs +2 -1
- package/dist/esm/components/DictionaryEditor/NodeWrapper/NumberWrapper.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/ContentEditor.mjs +2 -2
- package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs +3 -3
- package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs +1 -1
- package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/useDictionaryFormSchema.mjs +1 -1
- package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/useDictionaryFormSchema.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs +7 -7
- package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/useDictionaryDetailsSchema.mjs +1 -1
- package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/useDictionaryDetailsSchema.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs +2 -2
- package/dist/esm/components/DictionaryFieldEditor/KeyPathBreadcrumb.mjs +8 -7
- package/dist/esm/components/DictionaryFieldEditor/KeyPathBreadcrumb.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs +8 -5
- package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/NodeTypeSelector.mjs +2 -1
- package/dist/esm/components/DictionaryFieldEditor/NodeTypeSelector.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs +3 -3
- package/dist/esm/components/DictionaryFieldEditor/StructureEditor.mjs +2 -1
- package/dist/esm/components/DictionaryFieldEditor/StructureEditor.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/StructureView/StructureView.mjs +2 -2
- package/dist/esm/components/DictionaryFieldEditor/VersionSwitcherDropDown/VersionSwitcher.mjs +1 -1
- package/dist/esm/components/EditableField/EditableFieldInput.mjs +6 -5
- package/dist/esm/components/EditableField/EditableFieldInput.mjs.map +1 -1
- package/dist/esm/components/EditableField/EditableFieldLayout.mjs +1 -1
- package/dist/esm/components/EditableField/EditableFieldTextArea.mjs +2 -1
- package/dist/esm/components/EditableField/EditableFieldTextArea.mjs.map +1 -1
- package/dist/esm/components/Form/FormBase.mjs.map +1 -1
- package/dist/esm/components/Form/elements/FormElementWrapper.mjs +1 -1
- package/dist/esm/components/Form/elements/FormElementWrapper.mjs.map +1 -1
- package/dist/esm/components/Form/elements/OTPElement.mjs +1 -1
- package/dist/esm/components/HTMLRender/HTMLRender.mjs +5 -3
- package/dist/esm/components/HTMLRender/HTMLRender.mjs.map +1 -1
- package/dist/esm/components/HideShow/index.mjs +1 -1
- package/dist/esm/components/IDE/Code.mjs.map +1 -1
- package/dist/esm/components/IDE/CodeBlockClient.mjs.map +1 -1
- package/dist/esm/components/IDE/CodeBlockHighlight.mjs +3 -14
- package/dist/esm/components/IDE/CodeBlockHighlight.mjs.map +1 -1
- package/dist/esm/components/IDE/CodeBlockServer.mjs +14 -12
- package/dist/esm/components/IDE/CodeBlockServer.mjs.map +1 -1
- package/dist/esm/components/IDE/CodeBlockShiki.mjs +32 -86
- package/dist/esm/components/IDE/CodeBlockShiki.mjs.map +1 -1
- package/dist/esm/components/IDE/FileTree.mjs +3 -2
- package/dist/esm/components/IDE/FileTree.mjs.map +1 -1
- package/dist/esm/components/IDE/MarkDownRender.mjs.map +1 -1
- package/dist/esm/components/IDE/shikiLanguages.mjs +122 -0
- package/dist/esm/components/IDE/shikiLanguages.mjs.map +1 -0
- package/dist/esm/components/Input/Checkbox.mjs +1 -1
- package/dist/esm/components/Input/Input.mjs +1 -1
- package/dist/esm/components/Input/InputPassword.mjs +1 -1
- package/dist/esm/components/Input/OTPInput.mjs +5 -4
- package/dist/esm/components/Input/OTPInput.mjs.map +1 -1
- package/dist/esm/components/Input/Radio.mjs +1 -1
- package/dist/esm/components/Input/SearchInput.mjs +1 -1
- package/dist/esm/components/LanguageBackground/LanguageBackground.mjs +2 -1
- package/dist/esm/components/LanguageBackground/LanguageBackground.mjs.map +1 -1
- package/dist/esm/components/Link/Link.mjs +1 -1
- package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs +7 -6
- package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs.map +1 -1
- package/dist/esm/components/LocaleSwitcherDropDown/LocaleSwitcher.mjs +1 -1
- package/dist/esm/components/MarkDownRender/MarkDownIframe.mjs +1 -1
- package/dist/esm/components/MarkDownRender/MarkDownRender.mjs +12 -7
- package/dist/esm/components/MarkDownRender/MarkDownRender.mjs.map +1 -1
- package/dist/esm/components/MarkdownEditor/generative/AICompletionCommands.mjs +1 -1
- package/dist/esm/components/MarkdownEditor/generative/AISelector.mjs +1 -1
- package/dist/esm/components/MarkdownEditor/generative/AISelectorCommands.mjs +1 -1
- package/dist/esm/components/MarkdownEditor/generative/GenerativeMenuSwitch.mjs +1 -1
- package/dist/esm/components/MarkdownEditor/selectors/ColorSelector.mjs +1 -1
- package/dist/esm/components/MarkdownEditor/selectors/LinkSelector.mjs +1 -1
- package/dist/esm/components/MarkdownEditor/selectors/NodeSelector.mjs +1 -1
- package/dist/esm/components/MarkdownEditor/selectors/TextButtons.mjs +1 -1
- package/dist/esm/components/MarkdownEditor/slashCommand.mjs +1 -1
- package/dist/esm/components/Modal/Modal.mjs +3 -3
- package/dist/esm/components/Navbar/MobileNavbar.mjs +1 -1
- package/dist/esm/components/Pagination/Pagination.mjs +2 -2
- package/dist/esm/components/PressableSpan/PressableSpan.mjs +0 -2
- package/dist/esm/components/PressableSpan/PressableSpan.mjs.map +1 -1
- package/dist/esm/components/RightDrawer/RightDrawer.mjs +4 -4
- package/dist/esm/components/Select/Multiselect.mjs +3 -5
- package/dist/esm/components/Select/Multiselect.mjs.map +1 -1
- package/dist/esm/components/Select/Select.mjs +1 -1
- package/dist/esm/components/SwitchSelector/SwitchSelector.mjs +1 -1
- package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs +1 -1
- package/dist/esm/components/Tab/Tab.mjs +2 -2
- package/dist/esm/components/TabSelector/TabSelector.mjs +1 -1
- package/dist/esm/components/Table/ExpandButton.mjs +1 -1
- package/dist/esm/components/Tag/index.mjs +1 -1
- package/dist/esm/components/Terminal/Terminal.mjs +7 -5
- package/dist/esm/components/Terminal/Terminal.mjs.map +1 -1
- package/dist/esm/components/TextArea/AutocompleteTextArea.mjs +6 -3
- package/dist/esm/components/TextArea/AutocompleteTextArea.mjs.map +1 -1
- package/dist/esm/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs +1 -1
- package/dist/esm/components/ThemeSwitcherDropDown/MobileThemeSwitcher.mjs +1 -1
- package/dist/esm/components/Toaster/Toast.mjs +1 -1
- package/dist/esm/components/Toaster/useToast.mjs +1 -1
- package/dist/esm/components/Toaster/useToast.mjs.map +1 -1
- package/dist/esm/hooks/index.mjs +8 -8
- package/dist/esm/hooks/useScrollDetection.mjs +4 -2
- package/dist/esm/hooks/useScrollDetection.mjs.map +1 -1
- package/dist/esm/providers/DeferredAuthProvider.mjs +75 -0
- package/dist/esm/providers/DeferredAuthProvider.mjs.map +1 -0
- package/dist/esm/providers/ReactQueryProvider.mjs +4 -4
- package/dist/esm/providers/ReactQueryProvider.mjs.map +1 -1
- package/dist/esm/providers/index.mjs +2 -1
- package/dist/esm/routes.mjs +12 -11
- package/dist/esm/routes.mjs.map +1 -1
- package/dist/esm/structured-data/buildAuthorJsonLd.mjs +6 -3
- package/dist/esm/structured-data/buildAuthorJsonLd.mjs.map +1 -1
- package/dist/esm/structured-data/buildBreadcrumbsJsonLd.mjs +4 -1
- package/dist/esm/structured-data/buildBreadcrumbsJsonLd.mjs.map +1 -1
- package/dist/esm/structured-data/buildCreativeWorkJsonLd.mjs +7 -5
- package/dist/esm/structured-data/buildCreativeWorkJsonLd.mjs.map +1 -1
- package/dist/esm/structured-data/buildOrganizationJsonLd.mjs +27 -21
- package/dist/esm/structured-data/buildOrganizationJsonLd.mjs.map +1 -1
- package/dist/esm/structured-data/buildProductJsonLd.mjs +5 -2
- package/dist/esm/structured-data/buildProductJsonLd.mjs.map +1 -1
- package/dist/esm/structured-data/buildSoftwareApplicationJsonLd.mjs +59 -51
- package/dist/esm/structured-data/buildSoftwareApplicationJsonLd.mjs.map +1 -1
- package/dist/esm/structured-data/buildWebsiteJsonLd.mjs +31 -25
- package/dist/esm/structured-data/buildWebsiteJsonLd.mjs.map +1 -1
- package/dist/esm/structured-data/index.mjs +2 -1
- package/dist/esm/structured-data/normalizeJsonLdUrl.mjs +34 -0
- package/dist/esm/structured-data/normalizeJsonLdUrl.mjs.map +1 -0
- package/dist/esm/tailwind.config.mjs +4 -2
- package/dist/esm/tailwind.config.mjs.map +1 -1
- package/dist/types/api/index.d.ts +2 -2
- package/dist/types/api/useAuth/index.d.ts +2 -2
- package/dist/types/api/useAuth/useOAuth2.d.ts +12 -3
- package/dist/types/api/useAuth/useOAuth2.d.ts.map +1 -1
- package/dist/types/api/useAuth/useSession.d.ts.map +1 -1
- package/dist/types/components/DictionaryFieldEditor/DictionaryCreationForm/useDictionaryFormSchema.d.ts +1 -1
- package/dist/types/components/DictionaryFieldEditor/DictionaryDetails/useDictionaryDetailsSchema.d.ts +1 -1
- package/dist/types/components/Form/FormBase.d.ts +1 -1
- package/dist/types/components/Form/elements/FormElementWrapper.d.ts +1 -1
- package/dist/types/components/IDE/Code.d.ts +2 -2
- package/dist/types/components/IDE/CodeBlockClient.d.ts +2 -2
- package/dist/types/components/IDE/CodeBlockHighlight.d.ts +2 -2
- package/dist/types/components/IDE/CodeBlockHighlight.d.ts.map +1 -1
- package/dist/types/components/IDE/CodeBlockShiki.d.ts +2 -2
- package/dist/types/components/IDE/CodeBlockShiki.d.ts.map +1 -1
- package/dist/types/components/IDE/index.d.ts +2 -1
- package/dist/types/components/IDE/shikiLanguages.d.ts +138 -0
- package/dist/types/components/IDE/shikiLanguages.d.ts.map +1 -0
- package/dist/types/components/index.d.ts +2 -1
- package/dist/types/providers/DeferredAuthProvider.d.ts +33 -0
- package/dist/types/providers/DeferredAuthProvider.d.ts.map +1 -0
- package/dist/types/providers/index.d.ts +2 -1
- package/dist/types/routes.d.ts +17 -16
- package/dist/types/routes.d.ts.map +1 -1
- package/dist/types/structured-data/buildAuthorJsonLd.d.ts.map +1 -1
- package/dist/types/structured-data/buildBreadcrumbsJsonLd.d.ts.map +1 -1
- package/dist/types/structured-data/buildCreativeWorkJsonLd.d.ts.map +1 -1
- package/dist/types/structured-data/buildOrganizationJsonLd.d.ts.map +1 -1
- package/dist/types/structured-data/buildProductJsonLd.d.ts.map +1 -1
- package/dist/types/structured-data/buildSoftwareApplicationJsonLd.d.ts.map +1 -1
- package/dist/types/structured-data/buildWebsiteJsonLd.d.ts.map +1 -1
- package/dist/types/structured-data/index.d.ts +2 -1
- package/dist/types/structured-data/normalizeJsonLdUrl.d.ts +28 -0
- package/dist/types/structured-data/normalizeJsonLdUrl.d.ts.map +1 -0
- package/package.json +43 -43
package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs
CHANGED
|
@@ -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 {
|
|
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
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryDetailsSchema.mjs","names":[],"sources":["../../../../../src/components/DictionaryFieldEditor/DictionaryDetails/useDictionaryDetailsSchema.ts"],"sourcesContent":["import { useIntlayer } from 'react-intlayer';\nimport { z } from 'zod
|
|
1
|
+
{"version":3,"file":"useDictionaryDetailsSchema.mjs","names":[],"sources":["../../../../../src/components/DictionaryFieldEditor/DictionaryDetails/useDictionaryDetailsSchema.ts"],"sourcesContent":["import { useIntlayer } from 'react-intlayer';\nimport { z } from 'zod';\n\nexport const useDictionaryDetailsSchema = (projectId: string) => {\n const {\n titleRequiredError,\n titleInvalidTypeError,\n titleMinLengthError,\n keyRequiredError,\n keyInvalidTypeError,\n keySpaceError,\n keyMinLengthError,\n descriptionRequiredError,\n descriptionInvalidTypeError,\n requiredErrorProjectId,\n invalidTypeErrorProjectId,\n invalidTypeErrorTags,\n locationRequiredError,\n locationInvalidTypeError,\n filePathRequiredError,\n filePathInvalidTypeError,\n } = useIntlayer('dictionary-detail-schema');\n\n return z.object({\n title: z\n .string({\n error: (issue) =>\n issue.input === undefined\n ? titleRequiredError.value\n : titleInvalidTypeError.value,\n })\n // Can be length of 0 or > 4\n .refine((val) => val.length === 0 || val.length >= 4, {\n error: titleMinLengthError.value,\n })\n .optional(),\n key: z\n .string({\n error: (issue) =>\n issue.input === undefined\n ? keyRequiredError.value\n : keyInvalidTypeError.value,\n })\n .min(4, { error: keyMinLengthError.value })\n /**\n * Valid :\n * my-key\n * my_key\n *\n * Invalid :\n * my key\n * my.key\n */\n .regex(/^[a-zA-Z0-9-_]+$/, { error: keySpaceError.value })\n .default(''),\n description: z\n .string({\n error: (issue) =>\n issue.input === undefined\n ? descriptionRequiredError.value\n : descriptionInvalidTypeError.value,\n })\n .optional(),\n projectIds: z\n .array(\n z.string({\n error: (issue) =>\n issue.input === undefined\n ? requiredErrorProjectId.value\n : invalidTypeErrorProjectId.value,\n })\n )\n .default([projectId]),\n tags: z\n .array(\n z.string({\n error: () => invalidTypeErrorTags.value,\n })\n )\n .default([]),\n location: z\n .enum(['local', 'remote', 'hybrid', 'plugin'], {\n error: (issue) =>\n issue.input === undefined\n ? locationRequiredError.value\n : locationInvalidTypeError.value,\n })\n .optional(),\n importMode: z.enum(['static', 'dynamic', 'fetch']).optional(),\n filePath: z\n .string({\n error: (issue) =>\n issue.input === undefined\n ? filePathRequiredError.value\n : filePathInvalidTypeError.value,\n })\n .optional(),\n });\n};\n\nexport type DictionaryDetailsFormData = z.infer<\n ReturnType<typeof useDictionaryDetailsSchema>\n>;\n"],"mappings":";;;;AAGA,MAAa,8BAA8B,cAAsB;CAC/D,MAAM,EACJ,oBACA,uBACA,qBACA,kBACA,qBACA,eACA,mBACA,0BACA,6BACA,wBACA,2BACA,sBACA,uBACA,0BACA,uBACA,6BACE,YAAY,0BAA0B;CAE1C,OAAO,EAAE,OAAO;EACd,OAAO,EACJ,OAAO,EACN,QAAQ,UACN,MAAM,UAAU,SACZ,mBAAmB,QACnB,sBAAsB,MAC9B,CAAC,CAAC,CAED,QAAQ,QAAQ,IAAI,WAAW,KAAK,IAAI,UAAU,GAAG,EACpD,OAAO,oBAAoB,MAC7B,CAAC,CAAC,CACD,SAAS;EACZ,KAAK,EACF,OAAO,EACN,QAAQ,UACN,MAAM,UAAU,SACZ,iBAAiB,QACjB,oBAAoB,MAC5B,CAAC,CAAC,CACD,IAAI,GAAG,EAAE,OAAO,kBAAkB,MAAM,CAAC,CAAC,CAU1C,MAAM,oBAAoB,EAAE,OAAO,cAAc,MAAM,CAAC,CAAC,CACzD,QAAQ,EAAE;EACb,aAAa,EACV,OAAO,EACN,QAAQ,UACN,MAAM,UAAU,SACZ,yBAAyB,QACzB,4BAA4B,MACpC,CAAC,CAAC,CACD,SAAS;EACZ,YAAY,EACT,MACC,EAAE,OAAO,EACP,QAAQ,UACN,MAAM,UAAU,SACZ,uBAAuB,QACvB,0BAA0B,MAClC,CAAC,CACH,CAAC,CACA,QAAQ,CAAC,SAAS,CAAC;EACtB,MAAM,EACH,MACC,EAAE,OAAO,EACP,aAAa,qBAAqB,MACpC,CAAC,CACH,CAAC,CACA,QAAQ,CAAC,CAAC;EACb,UAAU,EACP,KAAK;GAAC;GAAS;GAAU;GAAU;EAAQ,GAAG,EAC7C,QAAQ,UACN,MAAM,UAAU,SACZ,sBAAsB,QACtB,yBAAyB,MACjC,CAAC,CAAC,CACD,SAAS;EACZ,YAAY,EAAE,KAAK;GAAC;GAAU;GAAW;EAAO,CAAC,CAAC,CAAC,SAAS;EAC5D,UAAU,EACP,OAAO,EACN,QAAQ,UACN,MAAM,UAAU,SACZ,sBAAsB,QACtB,yBAAyB,MACjC,CAAC,CAAC,CACD,SAAS;CACd,CAAC;AACH"}
|
|
@@ -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 {
|
|
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:
|
|
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;
|
|
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 {
|
|
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
|
|
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:
|
|
146
|
+
children: sectionArray.map((key) => {
|
|
145
147
|
const childKeyPath = [...keyPath, {
|
|
146
148
|
type: NodeTypes.OBJECT,
|
|
147
149
|
key
|
|
148
150
|
}];
|
|
149
|
-
|
|
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":"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"}
|
|
@@ -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
|
|
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;
|
|
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 {
|
|
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:
|
|
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;
|
|
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 {
|
|
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";
|
package/dist/esm/components/DictionaryFieldEditor/VersionSwitcherDropDown/VersionSwitcher.mjs
CHANGED
|
@@ -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
|
|
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;
|
|
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:
|
|
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;
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormBase.mjs","names":["useFormReactHookForm"],"sources":["../../../../src/components/Form/FormBase.tsx"],"sourcesContent":["'use client';\n\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { cn } from '@utils/cn';\nimport type { HTMLAttributes, KeyboardEvent } from 'react';\nimport {\n FormProvider,\n type FormProviderProps,\n type UseFormProps,\n useForm as useFormReactHookForm,\n useFormState,\n} from 'react-hook-form';\nimport type { ZodObject, z } from 'zod
|
|
1
|
+
{"version":3,"file":"FormBase.mjs","names":["useFormReactHookForm"],"sources":["../../../../src/components/Form/FormBase.tsx"],"sourcesContent":["'use client';\n\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { cn } from '@utils/cn';\nimport type { HTMLAttributes, KeyboardEvent } from 'react';\nimport {\n FormProvider,\n type FormProviderProps,\n type UseFormProps,\n useForm as useFormReactHookForm,\n useFormState,\n} from 'react-hook-form';\nimport type { ZodObject, z } from 'zod';\n\ntype FormProps<T extends ZodObject> = HTMLAttributes<HTMLFormElement> &\n FormProviderProps<z.infer<T>> & {\n schema?: T;\n onSubmit?: (data: z.infer<T>) => void | Promise<void>;\n onSubmitSuccess?: (data: z.infer<T>) => void | Promise<void>;\n onSubmitError?: (error: Error) => void | Promise<void>;\n autoComplete?: boolean;\n };\n\nconst awaitFunction = async (fn: any) => {\n // Check if result is a Promise (Thenable)\n\n if (fn && typeof fn.then === 'function') {\n // It's a Promise, so wait for it to resolve\n return await fn;\n }\n // If not a Promise, it will just execute without awaiting\n return fn;\n};\n\nexport const Form = <T extends ZodObject>({\n schema,\n onSubmit: onSubmitProp,\n onSubmitSuccess: onSubmitSuccessProp,\n onSubmitError: onSubmitErrorProp,\n className,\n children,\n autoComplete,\n method,\n ...props\n}: FormProps<T> & { method?: string }) => {\n const onSubmit = async (values: z.infer<T>) => {\n const parsedValues = schema?.safeParse(values) ?? {\n success: true,\n data: undefined,\n };\n\n // onSubmitProp?.(values);\n await awaitFunction(onSubmitProp?.(values));\n\n if (parsedValues.success) {\n await awaitFunction(onSubmitSuccessProp?.(parsedValues.data!));\n } else {\n await awaitFunction(\n onSubmitErrorProp?.(\n new Error(\n parsedValues.error.issues.map((error) => error.message).join(', ')\n )\n )\n );\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLFormElement>) => {\n if (e.key !== 'Enter') return;\n const target = e.target as HTMLElement;\n if (target.tagName !== 'INPUT') return;\n e.preventDefault();\n const formEl = e.currentTarget;\n const focusable = Array.from(\n formEl.querySelectorAll<HTMLElement>(\n 'input:not([disabled]):not([type=\"hidden\"]), textarea:not([disabled])'\n )\n );\n const idx = focusable.indexOf(target);\n if (idx >= 0 && idx < focusable.length - 1) {\n focusable[idx + 1]?.focus();\n }\n };\n\n return (\n <FormProvider {...props}>\n <form\n className={cn('flex flex-col gap-y-6', className)}\n onSubmit={props.handleSubmit(onSubmit)}\n onKeyDown={handleKeyDown}\n autoComplete={autoComplete ? 'on' : 'off'}\n noValidate\n method={method}\n >\n {children}\n </form>\n </FormProvider>\n );\n};\n\nexport const useForm = <T extends ZodObject>(\n schema: T,\n props?: UseFormProps<z.infer<T>>\n) => {\n const form = useFormReactHookForm<z.infer<T>>({\n resolver: zodResolver(schema as any),\n ...props,\n });\n\n const { isSubmitting, isSubmitted, isLoading, isValid } = useFormState({\n control: form.control,\n });\n\n return {\n form,\n isSubmitting,\n isSubmitted,\n isLoading,\n isValid,\n };\n};\n"],"mappings":";;;;;;;;AAuBA,MAAM,gBAAgB,OAAO,OAAY;CAGvC,IAAI,MAAM,OAAO,GAAG,SAAS,YAE3B,OAAO,MAAM;CAGf,OAAO;AACT;AAEA,MAAa,QAA6B,EACxC,QACA,UAAU,cACV,iBAAiB,qBACjB,eAAe,mBACf,WACA,UACA,cACA,QACA,GAAG,YACqC;CACxC,MAAM,WAAW,OAAO,WAAuB;EAC7C,MAAM,eAAe,QAAQ,UAAU,MAAM,KAAK;GAChD,SAAS;GACT,MAAM;EACR;EAGA,MAAM,cAAc,eAAe,MAAM,CAAC;EAE1C,IAAI,aAAa,SACf,MAAM,cAAc,sBAAsB,aAAa,IAAK,CAAC;OAE7D,MAAM,cACJ,oBACE,IAAI,MACF,aAAa,MAAM,OAAO,KAAK,UAAU,MAAM,OAAO,CAAC,CAAC,KAAK,IAAI,CACnE,CACF,CACF;CAEJ;CAEA,MAAM,iBAAiB,MAAsC;EAC3D,IAAI,EAAE,QAAQ,SAAS;EACvB,MAAM,SAAS,EAAE;EACjB,IAAI,OAAO,YAAY,SAAS;EAChC,EAAE,eAAe;EACjB,MAAM,SAAS,EAAE;EACjB,MAAM,YAAY,MAAM,KACtB,OAAO,iBACL,wEACF,CACF;EACA,MAAM,MAAM,UAAU,QAAQ,MAAM;EACpC,IAAI,OAAO,KAAK,MAAM,UAAU,SAAS,GACvC,UAAU,MAAM,EAAE,EAAE,MAAM;CAE9B;CAEA,OACE,oBAAC,cAAD;EAAc,GAAI;YAChB,oBAAC,QAAD;GACE,WAAW,GAAG,yBAAyB,SAAS;GAChD,UAAU,MAAM,aAAa,QAAQ;GACrC,WAAW;GACX,cAAc,eAAe,OAAO;GACpC;GACQ;GAEP;EACG;CACM;AAElB;AAEA,MAAa,WACX,QACA,UACG;CACH,MAAM,OAAOA,UAAiC;EAC5C,UAAU,YAAY,MAAa;EACnC,GAAG;CACL,CAAC;CAED,MAAM,EAAE,cAAc,aAAa,WAAW,YAAY,aAAa,EACrE,SAAS,KAAK,QAChB,CAAC;CAED,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { FormProvider, useForm } from "react-hook-form";
|
|
5
5
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
6
|
-
import { z } from "zod
|
|
6
|
+
import { z } from "zod";
|
|
7
7
|
|
|
8
8
|
//#region src/components/Form/elements/FormElementWrapper.tsx
|
|
9
9
|
const Schema = z.object({ test: z.string().min(3, "test error") });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormElementWrapper.mjs","names":[],"sources":["../../../../../src/components/Form/elements/FormElementWrapper.tsx"],"sourcesContent":["'use client';\n\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport type { FC, HTMLProps, SubmitEvent } from 'react';\nimport { FormProvider, useForm } from 'react-hook-form';\nimport { z } from 'zod
|
|
1
|
+
{"version":3,"file":"FormElementWrapper.mjs","names":[],"sources":["../../../../../src/components/Form/elements/FormElementWrapper.tsx"],"sourcesContent":["'use client';\n\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport type { FC, HTMLProps, SubmitEvent } from 'react';\nimport { FormProvider, useForm } from 'react-hook-form';\nimport { z } from 'zod';\n\nconst Schema = z.object({\n test: z.string().min(3, 'test error'),\n});\n\ntype FormElementWrapperProps = HTMLProps<HTMLFormElement> & {\n schema?: z.ZodObject;\n values?: z.infer<z.ZodObject>;\n};\n\nexport const FormElementWrapper: FC<FormElementWrapperProps> = (props) => {\n const objectFormSchema = props.schema ?? Schema;\n\n const form = useForm<z.infer<typeof objectFormSchema>>({\n resolver: zodResolver(objectFormSchema as any),\n values: props.values,\n });\n\n const { children, onSubmit, ...rest } = props;\n\n const onSubmitForm = (\n values: z.infer<typeof objectFormSchema>,\n event: SubmitEvent<HTMLFormElement>\n ) => {\n const parsedValues = objectFormSchema.safeParse(values);\n if (parsedValues.success) {\n onSubmit?.(event);\n }\n };\n\n return (\n <FormProvider {...form}>\n <form\n {...rest}\n onSubmit={(e) => {\n e.preventDefault();\n form.handleSubmit((values) => onSubmitForm(values, e));\n }}\n >\n {children}\n </form>\n </FormProvider>\n );\n};\n"],"mappings":";;;;;;;;AAOA,MAAM,SAAS,EAAE,OAAO,EACtB,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,GAAG,YAAY,EACtC,CAAC;AAOD,MAAa,sBAAmD,UAAU;CACxE,MAAM,mBAAmB,MAAM,UAAU;CAEzC,MAAM,OAAO,QAA0C;EACrD,UAAU,YAAY,gBAAuB;EAC7C,QAAQ,MAAM;CAChB,CAAC;CAED,MAAM,EAAE,UAAU,UAAU,GAAG,SAAS;CAExC,MAAM,gBACJ,QACA,UACG;EAEH,IADqB,iBAAiB,UAAU,MACjC,CAAC,CAAC,SACf,WAAW,KAAK;CAEpB;CAEA,OACE,oBAAC,cAAD;EAAc,GAAI;YAChB,oBAAC,QAAD;GACE,GAAI;GACJ,WAAW,MAAM;IACf,EAAE,eAAe;IACjB,KAAK,cAAc,WAAW,aAAa,QAAQ,CAAC,CAAC;GACvD;GAEC;EACG;CACM;AAElB"}
|
|
@@ -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
|
-
|
|
53
|
-
|
|
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;
|
|
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"), "$&");
|