preact-intlayer 7.0.1 → 7.0.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/dist/cjs/client/IntlayerProvider.cjs +2 -2
- package/dist/cjs/client/IntlayerProvider.cjs.map +1 -1
- package/dist/cjs/editor/ContentSelectorWrapper.cjs +9 -6
- package/dist/cjs/editor/ContentSelectorWrapper.cjs.map +1 -1
- package/dist/cjs/editor/EditedContentContext.cjs +5 -2
- package/dist/cjs/editor/EditedContentContext.cjs.map +1 -1
- package/dist/cjs/editor/EditorProvider.cjs +1 -1
- package/dist/cjs/editor/IntlayerEditorProvider.cjs +14 -0
- package/dist/cjs/editor/IntlayerEditorProvider.cjs.map +1 -1
- package/dist/cjs/editor/useCrossFrameMessageListener.cjs +6 -1
- package/dist/cjs/editor/useCrossFrameMessageListener.cjs.map +1 -1
- package/dist/esm/client/IntlayerProvider.mjs +3 -3
- package/dist/esm/client/IntlayerProvider.mjs.map +1 -1
- package/dist/esm/editor/ContentSelectorWrapper.mjs +8 -6
- package/dist/esm/editor/ContentSelectorWrapper.mjs.map +1 -1
- package/dist/esm/editor/EditedContentContext.mjs +4 -2
- package/dist/esm/editor/EditedContentContext.mjs.map +1 -1
- package/dist/esm/editor/EditorProvider.mjs +1 -1
- package/dist/esm/editor/IntlayerEditorProvider.mjs +12 -0
- package/dist/esm/editor/IntlayerEditorProvider.mjs.map +1 -1
- package/dist/esm/editor/useCrossFrameMessageListener.mjs +6 -1
- package/dist/esm/editor/useCrossFrameMessageListener.mjs.map +1 -1
- package/dist/types/client/format/useCompact.d.ts +2 -2
- package/dist/types/client/format/useCompact.d.ts.map +1 -1
- package/dist/types/client/format/useCurrency.d.ts +2 -2
- package/dist/types/client/format/useCurrency.d.ts.map +1 -1
- package/dist/types/client/format/useList.d.ts +2 -2
- package/dist/types/client/format/useNumber.d.ts +2 -2
- package/dist/types/client/format/usePercentage.d.ts +2 -2
- package/dist/types/client/format/usePercentage.d.ts.map +1 -1
- package/dist/types/client/format/useRelativeTime.d.ts +2 -2
- package/dist/types/client/format/useRelativeTime.d.ts.map +1 -1
- package/dist/types/client/format/useUnit.d.ts +2 -2
- package/dist/types/client/format/useUnit.d.ts.map +1 -1
- package/dist/types/client/useContent.d.ts +2 -2
- package/dist/types/client/useContent.d.ts.map +1 -1
- package/dist/types/client/useDictionary.d.ts +2 -2
- package/dist/types/client/useDictionaryDynamic.d.ts +2 -2
- package/dist/types/client/useDictionaryDynamic.d.ts.map +1 -1
- package/dist/types/client/useLocale.d.ts +3 -3
- package/dist/types/client/useLocaleBase.d.ts +5 -5
- package/dist/types/client/useLocaleBase.d.ts.map +1 -1
- package/dist/types/client/useLocaleStorage.d.ts +5 -5
- package/dist/types/editor/ConfigurationContext.d.ts +2 -2
- package/dist/types/editor/ContentSelectorWrapper.d.ts.map +1 -1
- package/dist/types/editor/EditedContentContext.d.ts.map +1 -1
- package/dist/types/editor/EditorEnabledContext.d.ts +2 -2
- package/dist/types/editor/IntlayerEditorProvider.d.ts.map +1 -1
- package/dist/types/editor/useCrossFrameMessageListener.d.ts.map +1 -1
- package/dist/types/editor/useCrossURLPathState.d.ts +3 -3
- package/package.json +18 -16
|
@@ -23,7 +23,7 @@ preact_jsx_runtime = require_rolldown_runtime.__toESM(preact_jsx_runtime);
|
|
|
23
23
|
* Context that store the current locale on the client side
|
|
24
24
|
*/
|
|
25
25
|
const IntlayerClientContext = (0, preact.createContext)({
|
|
26
|
-
locale: require_client_useLocaleStorage.
|
|
26
|
+
locale: require_client_useLocaleStorage.localeInStorage ?? __intlayer_config_built.default?.internationalization?.defaultLocale,
|
|
27
27
|
setLocale: () => null,
|
|
28
28
|
disableEditor: false
|
|
29
29
|
});
|
|
@@ -37,7 +37,7 @@ const useIntlayerContext = () => (0, preact_hooks.useContext)(IntlayerClientCont
|
|
|
37
37
|
const IntlayerProviderContent = ({ locale: localeProp, defaultLocale: defaultLocaleProp, children, setLocale: setLocaleProp, disableEditor, isCookieEnabled }) => {
|
|
38
38
|
const { internationalization } = __intlayer_config_built.default ?? {};
|
|
39
39
|
const { defaultLocale: defaultLocaleConfig, locales: availableLocales } = internationalization ?? {};
|
|
40
|
-
const defaultLocale = localeProp ?? require_client_useLocaleStorage.
|
|
40
|
+
const defaultLocale = localeProp ?? require_client_useLocaleStorage.localeInStorage ?? defaultLocaleProp ?? defaultLocaleConfig;
|
|
41
41
|
const [currentLocale, setCurrentLocale] = require_editor_useCrossFrameState.useCrossFrameState(__intlayer_editor.MessageKey.INTLAYER_CURRENT_LOCALE, defaultLocale);
|
|
42
42
|
const setLocaleBase = (newLocale) => {
|
|
43
43
|
if (currentLocale.toString() === newLocale.toString()) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntlayerProvider.cjs","names":["
|
|
1
|
+
{"version":3,"file":"IntlayerProvider.cjs","names":["localeInStorage","configuration","IntlayerProviderContent: FunctionComponent<\n IntlayerProviderProps\n>","useCrossFrameState","MessageKey","IntlayerProvider: FunctionComponent<IntlayerProviderProps>","IntlayerEditorProvider"],"sources":["../../../src/client/IntlayerProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport { localeResolver } from '@intlayer/core';\nimport { MessageKey } from '@intlayer/editor';\nimport type { LocalesValues } from '@intlayer/types';\nimport {\n type ComponentChild,\n createContext,\n type FunctionComponent,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport { IntlayerEditorProvider } from '../editor/IntlayerEditorProvider';\nimport { useCrossFrameState } from '../editor/useCrossFrameState';\nimport { localeInStorage, setLocaleInStorage } from './useLocaleStorage';\n\ntype IntlayerValue = {\n locale: LocalesValues;\n setLocale: (newLocale: LocalesValues) => void;\n disableEditor?: boolean;\n isCookieEnabled?: boolean;\n};\n\n/**\n * Context that store the current locale on the client side\n */\nexport const IntlayerClientContext = createContext<IntlayerValue>({\n locale: localeInStorage ?? configuration?.internationalization?.defaultLocale,\n setLocale: () => null,\n disableEditor: false,\n});\n\n/**\n * Hook that provides the current locale\n */\nexport const useIntlayerContext = () => useContext(IntlayerClientContext);\n\nexport type IntlayerProviderProps = {\n children?: ComponentChild;\n locale?: LocalesValues;\n defaultLocale?: LocalesValues;\n setLocale?: (locale: LocalesValues) => void;\n disableEditor?: boolean;\n isCookieEnabled?: boolean;\n};\n\n/**\n * Provider that store the current locale on the client side\n */\nexport const IntlayerProviderContent: FunctionComponent<\n IntlayerProviderProps\n> = ({\n locale: localeProp,\n defaultLocale: defaultLocaleProp,\n children,\n setLocale: setLocaleProp,\n disableEditor,\n isCookieEnabled,\n}) => {\n const { internationalization } = configuration ?? {};\n const { defaultLocale: defaultLocaleConfig, locales: availableLocales } =\n internationalization ?? {};\n\n const defaultLocale =\n localeProp ?? localeInStorage ?? defaultLocaleProp ?? defaultLocaleConfig;\n\n const [currentLocale, setCurrentLocale] = useCrossFrameState(\n MessageKey.INTLAYER_CURRENT_LOCALE,\n defaultLocale\n );\n\n const setLocaleBase = (newLocale: LocalesValues) => {\n if (currentLocale.toString() === newLocale.toString()) return;\n\n if (!availableLocales?.map(String).includes(newLocale)) {\n console.error(`Locale ${newLocale} is not available`);\n return;\n }\n\n setCurrentLocale(newLocale); // Update state\n setLocaleInStorage(newLocale, isCookieEnabled ?? true); // Optionally set cookie for persistence\n };\n\n const setLocale = setLocaleProp ?? setLocaleBase;\n\n const resolvedLocale = localeResolver(localeProp ?? currentLocale);\n\n return (\n <IntlayerClientContext.Provider\n value={{\n locale: resolvedLocale,\n setLocale,\n disableEditor,\n isCookieEnabled,\n }}\n >\n {children}\n </IntlayerClientContext.Provider>\n );\n};\n\nexport const IntlayerProvider: FunctionComponent<IntlayerProviderProps> = (\n props\n) => (\n <IntlayerEditorProvider>\n <IntlayerProviderContent {...props} />\n </IntlayerEditorProvider>\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAa,kDAAqD;CAChE,QAAQA,mDAAmBC,iCAAe,sBAAsB;CAChE,iBAAiB;CACjB,eAAe;CAChB,CAAC;;;;AAKF,MAAa,wDAAsC,sBAAsB;;;;AAczE,MAAaC,2BAER,EACH,QAAQ,YACR,eAAe,mBACf,UACA,WAAW,eACX,eACA,sBACI;CACJ,MAAM,EAAE,yBAAyBD,mCAAiB,EAAE;CACpD,MAAM,EAAE,eAAe,qBAAqB,SAAS,qBACnD,wBAAwB,EAAE;CAE5B,MAAM,gBACJ,cAAcD,mDAAmB,qBAAqB;CAExD,MAAM,CAAC,eAAe,oBAAoBG,qDACxCC,6BAAW,yBACX,cACD;CAED,MAAM,iBAAiB,cAA6B;AAClD,MAAI,cAAc,UAAU,KAAK,UAAU,UAAU,CAAE;AAEvD,MAAI,CAAC,kBAAkB,IAAI,OAAO,CAAC,SAAS,UAAU,EAAE;AACtD,WAAQ,MAAM,UAAU,UAAU,mBAAmB;AACrD;;AAGF,mBAAiB,UAAU;AAC3B,qDAAmB,WAAW,mBAAmB,KAAK;;CAGxD,MAAM,YAAY,iBAAiB;CAEnC,MAAM,qDAAgC,cAAc,cAAc;AAElE,QACE,4CAAC,sBAAsB;EACrB,OAAO;GACL,QAAQ;GACR;GACA;GACA;GACD;EAEA;GAC8B;;AAIrC,MAAaC,oBACX,UAEA,4CAACC,0EACC,4CAAC,2BAAwB,GAAI,QAAS,GACf"}
|
|
@@ -9,6 +9,8 @@ const require_client_IntlayerProvider = require('../client/IntlayerProvider.cjs'
|
|
|
9
9
|
const require_UI_ContentSelector = require('../UI/ContentSelector.cjs');
|
|
10
10
|
let __intlayer_core = require("@intlayer/core");
|
|
11
11
|
__intlayer_core = require_rolldown_runtime.__toESM(__intlayer_core);
|
|
12
|
+
let __intlayer_types = require("@intlayer/types");
|
|
13
|
+
__intlayer_types = require_rolldown_runtime.__toESM(__intlayer_types);
|
|
12
14
|
let __intlayer_editor = require("@intlayer/editor");
|
|
13
15
|
__intlayer_editor = require_rolldown_runtime.__toESM(__intlayer_editor);
|
|
14
16
|
let preact_compat = require("preact/compat");
|
|
@@ -20,27 +22,28 @@ preact_jsx_runtime = require_rolldown_runtime.__toESM(preact_jsx_runtime);
|
|
|
20
22
|
const ContentSelectorWrapperContent = ({ children, dictionaryKey, keyPath }) => {
|
|
21
23
|
const { focusedContent, setFocusedContent } = require_editor_FocusDictionaryContext.useFocusDictionary();
|
|
22
24
|
const { postMessage, senderId } = require_editor_CommunicatorContext.useCommunicator();
|
|
25
|
+
const filteredKeyPath = (0, preact_compat.useMemo)(() => keyPath.filter((key) => key.type !== __intlayer_types.NodeType.Translation), [keyPath]);
|
|
23
26
|
return /* @__PURE__ */ (0, preact_jsx_runtime.jsx)(require_UI_ContentSelector.ContentSelector, {
|
|
24
27
|
onPress: (0, preact_compat.useCallback)(() => setFocusedContent({
|
|
25
28
|
dictionaryKey,
|
|
26
|
-
keyPath
|
|
27
|
-
}), [dictionaryKey,
|
|
29
|
+
keyPath: filteredKeyPath
|
|
30
|
+
}), [dictionaryKey, filteredKeyPath]),
|
|
28
31
|
onHover: (0, preact_compat.useCallback)(() => postMessage({
|
|
29
32
|
type: `${__intlayer_editor.MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,
|
|
30
33
|
data: {
|
|
31
34
|
dictionaryKey,
|
|
32
|
-
keyPath
|
|
35
|
+
keyPath: filteredKeyPath
|
|
33
36
|
},
|
|
34
37
|
senderId
|
|
35
|
-
}), [dictionaryKey,
|
|
38
|
+
}), [dictionaryKey, filteredKeyPath]),
|
|
36
39
|
onUnhover: (0, preact_compat.useCallback)(() => postMessage({
|
|
37
40
|
type: `${__intlayer_editor.MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,
|
|
38
41
|
data: null,
|
|
39
42
|
senderId
|
|
40
43
|
}), [senderId]),
|
|
41
|
-
isSelecting: (0, preact_compat.useMemo)(() => (focusedContent?.dictionaryKey === dictionaryKey && (focusedContent?.keyPath?.length ?? 0) > 0 && (0, __intlayer_core.isSameKeyPath)(focusedContent?.keyPath ?? [],
|
|
44
|
+
isSelecting: (0, preact_compat.useMemo)(() => (focusedContent?.dictionaryKey === dictionaryKey && (focusedContent?.keyPath?.length ?? 0) > 0 && (0, __intlayer_core.isSameKeyPath)(focusedContent?.keyPath ?? [], filteredKeyPath)) ?? false, [
|
|
42
45
|
focusedContent,
|
|
43
|
-
|
|
46
|
+
filteredKeyPath,
|
|
44
47
|
dictionaryKey
|
|
45
48
|
]),
|
|
46
49
|
children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentSelectorWrapper.cjs","names":["ContentSelectorWrapperContent: FC<ContentSelectorWrapperProps>","useFocusDictionary","useCommunicator","ContentSelector","MessageKey","ContentSelectorRenderer: FC<ContentSelectorWrapperProps>","useEditorEnabled","useIntlayerContext"],"sources":["../../../src/editor/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport { isSameKeyPath, type NodeProps } from '@intlayer/core';\nimport { MessageKey } from '@intlayer/editor';\nimport {\n type FC,\n type HTMLAttributes,\n useCallback,\n useMemo,\n} from 'preact/compat';\nimport { useIntlayerContext } from '../client';\nimport { ContentSelector } from '../UI/ContentSelector';\nimport { useCommunicator } from './CommunicatorContext';\nimport { useEditorEnabled } from './EditorEnabledContext';\nimport { useFocusDictionary } from './FocusDictionaryContext';\n\nexport type ContentSelectorWrapperProps = NodeProps &\n Omit<HTMLAttributes<HTMLDivElement>, 'children'>;\n\nconst ContentSelectorWrapperContent: FC<ContentSelectorWrapperProps> = ({\n children,\n dictionaryKey,\n keyPath,\n}) => {\n const { focusedContent, setFocusedContent } = useFocusDictionary();\n const { postMessage, senderId } = useCommunicator();\n\n const handleSelect = useCallback(\n () =>\n setFocusedContent({\n dictionaryKey,\n keyPath,\n }),\n [dictionaryKey,
|
|
1
|
+
{"version":3,"file":"ContentSelectorWrapper.cjs","names":["ContentSelectorWrapperContent: FC<ContentSelectorWrapperProps>","useFocusDictionary","useCommunicator","NodeType","ContentSelector","MessageKey","ContentSelectorRenderer: FC<ContentSelectorWrapperProps>","useEditorEnabled","useIntlayerContext"],"sources":["../../../src/editor/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport { isSameKeyPath, type NodeProps } from '@intlayer/core';\nimport { MessageKey } from '@intlayer/editor';\nimport { NodeType } from '@intlayer/types';\nimport {\n type FC,\n type HTMLAttributes,\n useCallback,\n useMemo,\n} from 'preact/compat';\nimport { useIntlayerContext } from '../client';\nimport { ContentSelector } from '../UI/ContentSelector';\nimport { useCommunicator } from './CommunicatorContext';\nimport { useEditorEnabled } from './EditorEnabledContext';\nimport { useFocusDictionary } from './FocusDictionaryContext';\n\nexport type ContentSelectorWrapperProps = NodeProps &\n Omit<HTMLAttributes<HTMLDivElement>, 'children'>;\n\nconst ContentSelectorWrapperContent: FC<ContentSelectorWrapperProps> = ({\n children,\n dictionaryKey,\n keyPath,\n}) => {\n const { focusedContent, setFocusedContent } = useFocusDictionary();\n const { postMessage, senderId } = useCommunicator();\n\n // Filter out translation nodes for more flexibility with the editor that can have different format\n const filteredKeyPath = useMemo(\n () => keyPath.filter((key) => key.type !== NodeType.Translation),\n [keyPath]\n );\n\n const handleSelect = useCallback(\n () =>\n setFocusedContent({\n dictionaryKey,\n keyPath: filteredKeyPath,\n }),\n [dictionaryKey, filteredKeyPath]\n );\n\n const handleHover = useCallback(\n () =>\n postMessage({\n type: `${MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,\n data: {\n dictionaryKey,\n keyPath: filteredKeyPath,\n },\n senderId,\n }),\n [dictionaryKey, filteredKeyPath]\n );\n\n const handleUnhover = useCallback(\n () =>\n postMessage({\n type: `${MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,\n data: null,\n senderId,\n }),\n [senderId]\n );\n\n const isSelected = useMemo(\n () =>\n (focusedContent?.dictionaryKey === dictionaryKey &&\n (focusedContent?.keyPath?.length ?? 0) > 0 &&\n isSameKeyPath(focusedContent?.keyPath ?? [], filteredKeyPath)) ??\n false,\n [focusedContent, filteredKeyPath, dictionaryKey]\n );\n\n return (\n <ContentSelector\n onPress={handleSelect}\n onHover={handleHover}\n onUnhover={handleUnhover}\n isSelecting={isSelected}\n >\n {children}\n </ContentSelector>\n );\n};\n\nexport const ContentSelectorRenderer: FC<ContentSelectorWrapperProps> = ({\n children,\n ...props\n}) => {\n const { enabled } = useEditorEnabled();\n const { disableEditor } = useIntlayerContext();\n\n if (enabled && !disableEditor) {\n return (\n <ContentSelectorWrapperContent {...props}>\n {children}\n </ContentSelectorWrapperContent>\n );\n }\n\n return children;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,MAAMA,iCAAkE,EACtE,UACA,eACA,cACI;CACJ,MAAM,EAAE,gBAAgB,sBAAsBC,0DAAoB;CAClE,MAAM,EAAE,aAAa,aAAaC,oDAAiB;CAGnD,MAAM,mDACE,QAAQ,QAAQ,QAAQ,IAAI,SAASC,0BAAS,YAAY,EAChE,CAAC,QAAQ,CACV;AA2CD,QACE,4CAACC;EACC,8CAzCA,kBAAkB;GAChB;GACA,SAAS;GACV,CAAC,EACJ,CAAC,eAAe,gBAAgB,CACjC;EAqCG,8CAjCA,YAAY;GACV,MAAM,GAAGC,6BAAW,iCAAiC;GACrD,MAAM;IACJ;IACA,SAAS;IACV;GACD;GACD,CAAC,EACJ,CAAC,eAAe,gBAAgB,CACjC;EAyBG,gDArBA,YAAY;GACV,MAAM,GAAGA,6BAAW,iCAAiC;GACrD,MAAM;GACN;GACD,CAAC,EACJ,CAAC,SAAS,CACX;EAgBG,+CAZC,gBAAgB,kBAAkB,kBAChC,gBAAgB,SAAS,UAAU,KAAK,wCAC3B,gBAAgB,WAAW,EAAE,EAAE,gBAAgB,KAC/D,OACF;GAAC;GAAgB;GAAiB;GAAc,CACjD;EASI;GACe;;AAItB,MAAaC,2BAA4D,EACvE,SACA,GAAG,YACC;CACJ,MAAM,EAAE,YAAYC,sDAAkB;CACtC,MAAM,EAAE,kBAAkBC,oDAAoB;AAE9C,KAAI,WAAW,CAAC,cACd,QACE,4CAAC;EAA8B,GAAI;EAChC;GAC6B;AAIpC,QAAO"}
|
|
@@ -7,6 +7,8 @@ const require_editor_useCrossFrameState = require('./useCrossFrameState.cjs');
|
|
|
7
7
|
const require_editor_DictionariesRecordContext = require('./DictionariesRecordContext.cjs');
|
|
8
8
|
let __intlayer_core = require("@intlayer/core");
|
|
9
9
|
__intlayer_core = require_rolldown_runtime.__toESM(__intlayer_core);
|
|
10
|
+
let __intlayer_types = require("@intlayer/types");
|
|
11
|
+
__intlayer_types = require_rolldown_runtime.__toESM(__intlayer_types);
|
|
10
12
|
let __intlayer_editor = require("@intlayer/editor");
|
|
11
13
|
__intlayer_editor = require_rolldown_runtime.__toESM(__intlayer_editor);
|
|
12
14
|
let preact_compat = require("preact/compat");
|
|
@@ -121,10 +123,11 @@ const EditedContentProvider = ({ children }) => {
|
|
|
121
123
|
};
|
|
122
124
|
const getEditedContentValue = (localDictionaryIdOrKey, keyPath) => {
|
|
123
125
|
if (!editedContent) return void 0;
|
|
124
|
-
|
|
126
|
+
const filteredKeyPath = keyPath.filter((key) => key.type !== __intlayer_types.NodeType.Translation);
|
|
127
|
+
if (localDictionaryIdOrKey.includes(":local:") || localDictionaryIdOrKey.includes(":remote:")) return (0, __intlayer_core.getContentNodeByKeyPath)(editedContent?.[localDictionaryIdOrKey]?.content ?? {}, filteredKeyPath);
|
|
125
128
|
const filteredDictionariesLocalId = Object.keys(editedContent).filter((key) => key.startsWith(`${localDictionaryIdOrKey}:`));
|
|
126
129
|
for (const localDictionaryId of filteredDictionariesLocalId) {
|
|
127
|
-
const contentNode = (0, __intlayer_core.getContentNodeByKeyPath)(editedContent?.[localDictionaryId]?.content ?? {},
|
|
130
|
+
const contentNode = (0, __intlayer_core.getContentNodeByKeyPath)(editedContent?.[localDictionaryId]?.content ?? {}, filteredKeyPath);
|
|
128
131
|
if (contentNode) return contentNode;
|
|
129
132
|
}
|
|
130
133
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditedContentContext.cjs","names":["useCrossFrameMessageListener","MessageKey","EditedContentProvider: FC<PropsWithChildren>","useDictionariesRecord","useCrossFrameState","setEditedDictionary: Dispatch<SetStateAction<Dictionary>>","updatedDictionaries: Dictionary","lastKeyPath: KeyPath"],"sources":["../../../src/editor/EditedContentContext.tsx"],"sourcesContent":["'use client';\n\nimport {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core';\nimport { MessageKey } from '@intlayer/editor';\nimport type {\n ContentNode,\n Dictionary,\n KeyPath,\n LocalDictionaryId,\n} from '@intlayer/types';\nimport {\n createContext,\n type Dispatch,\n type FC,\n type PropsWithChildren,\n type SetStateAction,\n useContext,\n} from 'preact/compat';\nimport {\n type DictionaryContent,\n useDictionariesRecord,\n} from './DictionariesRecordContext';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\nimport { useCrossFrameState } from './useCrossFrameState';\n\ntype EditedContentStateContextType = {\n editedContent: Record<LocalDictionaryId, Dictionary> | undefined;\n};\n\nconst EditedContentStateContext = createContext<\n EditedContentStateContextType | undefined\n>(undefined);\n\nexport const usePostEditedContentState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/post`,\n onEventTriggered\n );\n\nexport const useGetEditedContentState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/get`,\n onEventTriggered\n );\n\ntype EditedContentActionsContextType = {\n setEditedContentState: (\n editedContent: Record<LocalDictionaryId, Dictionary>\n ) => void;\n setEditedDictionary: Dispatch<SetStateAction<Dictionary>>;\n setEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newValue: Dictionary['content']\n ) => void;\n addEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newValue: ContentNode<any>,\n keyPath?: KeyPath[],\n overwrite?: boolean\n ) => void;\n renameEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath?: KeyPath[]\n ) => void;\n removeEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n keyPath: KeyPath[]\n ) => void;\n restoreEditedContent: (dictionaryLocalId: LocalDictionaryId) => void;\n clearEditedDictionaryContent: (dictionaryLocalId: LocalDictionaryId) => void;\n clearEditedContent: () => void;\n getEditedContentValue: (\n localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string,\n keyPath: KeyPath[]\n ) => ContentNode | undefined;\n};\n\nconst EditedContentActionsContext = createContext<\n EditedContentActionsContextType | undefined\n>(undefined);\n\nconst resolveState = <S,>(state?: SetStateAction<S>, prevState?: S): S =>\n typeof state === 'function'\n ? (state as (prevState?: S) => S)(prevState)\n : (state as S);\n\nexport const EditedContentProvider: FC<PropsWithChildren> = ({ children }) => {\n const { localeDictionaries } = useDictionariesRecord();\n\n const [editedContent, setEditedContentState] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED\n );\n\n const setEditedDictionary: Dispatch<SetStateAction<Dictionary>> = (\n newValue\n ) => {\n let updatedDictionaries: Dictionary = resolveState(newValue);\n\n setEditedContentState((prev) => {\n updatedDictionaries = resolveState(\n newValue,\n prev?.[updatedDictionaries.key]\n );\n\n return {\n ...prev,\n [updatedDictionaries.key]: updatedDictionaries,\n };\n });\n\n return updatedDictionaries;\n };\n\n const setEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newValue: Dictionary['content']\n ) => {\n setEditedContentState((prev) => ({\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: newValue,\n },\n }));\n };\n\n const addEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newValue: ContentNode,\n keyPath: KeyPath[] = [],\n overwrite: boolean = true\n ) => {\n setEditedContentState((prev) => {\n // Get the starting content: edited version if available, otherwise a deep copy of the original\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n let newKeyPath = keyPath;\n if (!overwrite) {\n // Find a unique key based on the keyPath provided\n let index = 0;\n const otherKeyPath = keyPath.slice(0, -1);\n const lastKeyPath: KeyPath = keyPath[keyPath.length - 1];\n let finalKey = lastKeyPath.key;\n\n // Loop until we find a key that does not exist\n while (\n typeof getContentNodeByKeyPath(currentContent, newKeyPath) !==\n 'undefined'\n ) {\n index++;\n finalKey =\n index === 0 ? lastKeyPath.key : `${lastKeyPath.key} (${index})`;\n newKeyPath = [\n ...otherKeyPath,\n { ...lastKeyPath, key: finalKey } as KeyPath,\n ];\n }\n }\n\n const updatedContent = editDictionaryByKeyPath(\n currentContent,\n newKeyPath,\n newValue\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: updatedContent as Dictionary['content'],\n },\n };\n });\n };\n\n const renameEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath: KeyPath[] = []\n ) => {\n setEditedContentState((prev) => {\n // Retrieve the base content: use edited version if available, otherwise deep copy of original\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n const contentWithNewField = renameContentNodeByKeyPath(\n currentContent,\n newKey,\n keyPath\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: contentWithNewField as Dictionary['content'],\n },\n };\n });\n };\n\n const removeEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n keyPath: KeyPath[]\n ) => {\n setEditedContentState((prev) => {\n // Retrieve the original content as reference\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n // Get the initial value from the original dictionary content\n const initialContent = getContentNodeByKeyPath(originalContent, keyPath);\n\n // Restore the value at the given keyPath\n const restoredContent = editDictionaryByKeyPath(\n currentContent,\n keyPath,\n initialContent\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: restoredContent as Dictionary['content'],\n },\n };\n });\n };\n\n const restoreEditedContent = (dictionaryLocalId: LocalDictionaryId) => {\n setEditedContentState((prev) => {\n const updated = { ...prev };\n delete updated[dictionaryLocalId];\n return updated;\n });\n };\n\n const clearEditedDictionaryContent = (\n dictionaryLocalId: LocalDictionaryId\n ) => {\n setEditedContentState((prev) => {\n const filtered = Object.entries(prev).reduce((acc, [key, value]) => {\n if (key === dictionaryLocalId) {\n return acc;\n }\n return { ...acc, [key]: value };\n }, {} as DictionaryContent);\n return filtered;\n });\n };\n\n const clearEditedContent = () => {\n setEditedContentState({});\n };\n\n const getEditedContentValue = (\n localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string,\n keyPath: KeyPath[]\n ): ContentNode | undefined => {\n if (!editedContent) return undefined;\n\n const isDictionaryId =\n localDictionaryIdOrKey.includes(':local:') ||\n localDictionaryIdOrKey.includes(':remote:');\n\n if (isDictionaryId) {\n const currentContent =\n editedContent?.[localDictionaryIdOrKey as LocalDictionaryId]?.content ??\n {};\n\n const contentNode = getContentNodeByKeyPath(currentContent, keyPath);\n\n return contentNode;\n }\n\n const filteredDictionariesLocalId = Object.keys(editedContent).filter(\n (key) => key.startsWith(`${localDictionaryIdOrKey}:`)\n );\n\n for (const localDictionaryId of filteredDictionariesLocalId) {\n const currentContent =\n editedContent?.[localDictionaryId as LocalDictionaryId]?.content ?? {};\n const contentNode = getContentNodeByKeyPath(currentContent, keyPath);\n\n if (contentNode) return contentNode;\n }\n\n return undefined;\n };\n\n return (\n <EditedContentStateContext.Provider\n value={{\n editedContent,\n }}\n >\n <EditedContentActionsContext.Provider\n value={{\n setEditedContentState,\n setEditedDictionary,\n setEditedContent,\n addEditedContent,\n renameEditedContent,\n removeEditedContent,\n restoreEditedContent,\n clearEditedDictionaryContent,\n clearEditedContent,\n getEditedContentValue,\n }}\n >\n {children}\n </EditedContentActionsContext.Provider>\n </EditedContentStateContext.Provider>\n );\n};\n\nexport const useEditedContentActions = () =>\n useContext(EditedContentActionsContext);\n\nexport const useEditedContent = () => {\n const stateContext = useContext(EditedContentStateContext);\n const actionContext = useEditedContentActions();\n\n return { ...stateContext, ...actionContext };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EditedContentContext.cjs","names":["useCrossFrameMessageListener","MessageKey","EditedContentProvider: FC<PropsWithChildren>","useDictionariesRecord","useCrossFrameState","setEditedDictionary: Dispatch<SetStateAction<Dictionary>>","updatedDictionaries: Dictionary","lastKeyPath: KeyPath","NodeType"],"sources":["../../../src/editor/EditedContentContext.tsx"],"sourcesContent":["'use client';\n\nimport {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core';\nimport { MessageKey } from '@intlayer/editor';\nimport {\n type ContentNode,\n type Dictionary,\n type KeyPath,\n type LocalDictionaryId,\n NodeType,\n} from '@intlayer/types';\nimport {\n createContext,\n type Dispatch,\n type FC,\n type PropsWithChildren,\n type SetStateAction,\n useContext,\n} from 'preact/compat';\nimport {\n type DictionaryContent,\n useDictionariesRecord,\n} from './DictionariesRecordContext';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\nimport { useCrossFrameState } from './useCrossFrameState';\n\ntype EditedContentStateContextType = {\n editedContent: Record<LocalDictionaryId, Dictionary> | undefined;\n};\n\nconst EditedContentStateContext = createContext<\n EditedContentStateContextType | undefined\n>(undefined);\n\nexport const usePostEditedContentState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/post`,\n onEventTriggered\n );\n\nexport const useGetEditedContentState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/get`,\n onEventTriggered\n );\n\ntype EditedContentActionsContextType = {\n setEditedContentState: (\n editedContent: Record<LocalDictionaryId, Dictionary>\n ) => void;\n setEditedDictionary: Dispatch<SetStateAction<Dictionary>>;\n setEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newValue: Dictionary['content']\n ) => void;\n addEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newValue: ContentNode<any>,\n keyPath?: KeyPath[],\n overwrite?: boolean\n ) => void;\n renameEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath?: KeyPath[]\n ) => void;\n removeEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n keyPath: KeyPath[]\n ) => void;\n restoreEditedContent: (dictionaryLocalId: LocalDictionaryId) => void;\n clearEditedDictionaryContent: (dictionaryLocalId: LocalDictionaryId) => void;\n clearEditedContent: () => void;\n getEditedContentValue: (\n localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string,\n keyPath: KeyPath[]\n ) => ContentNode | undefined;\n};\n\nconst EditedContentActionsContext = createContext<\n EditedContentActionsContextType | undefined\n>(undefined);\n\nconst resolveState = <S,>(state?: SetStateAction<S>, prevState?: S): S =>\n typeof state === 'function'\n ? (state as (prevState?: S) => S)(prevState)\n : (state as S);\n\nexport const EditedContentProvider: FC<PropsWithChildren> = ({ children }) => {\n const { localeDictionaries } = useDictionariesRecord();\n\n const [editedContent, setEditedContentState] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED\n );\n\n const setEditedDictionary: Dispatch<SetStateAction<Dictionary>> = (\n newValue\n ) => {\n let updatedDictionaries: Dictionary = resolveState(newValue);\n\n setEditedContentState((prev) => {\n updatedDictionaries = resolveState(\n newValue,\n prev?.[updatedDictionaries.key]\n );\n\n return {\n ...prev,\n [updatedDictionaries.key]: updatedDictionaries,\n };\n });\n\n return updatedDictionaries;\n };\n\n const setEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newValue: Dictionary['content']\n ) => {\n setEditedContentState((prev) => ({\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: newValue,\n },\n }));\n };\n\n const addEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newValue: ContentNode,\n keyPath: KeyPath[] = [],\n overwrite: boolean = true\n ) => {\n setEditedContentState((prev) => {\n // Get the starting content: edited version if available, otherwise a deep copy of the original\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n let newKeyPath = keyPath;\n if (!overwrite) {\n // Find a unique key based on the keyPath provided\n let index = 0;\n const otherKeyPath = keyPath.slice(0, -1);\n const lastKeyPath: KeyPath = keyPath[keyPath.length - 1];\n let finalKey = lastKeyPath.key;\n\n // Loop until we find a key that does not exist\n while (\n typeof getContentNodeByKeyPath(currentContent, newKeyPath) !==\n 'undefined'\n ) {\n index++;\n finalKey =\n index === 0 ? lastKeyPath.key : `${lastKeyPath.key} (${index})`;\n newKeyPath = [\n ...otherKeyPath,\n { ...lastKeyPath, key: finalKey } as KeyPath,\n ];\n }\n }\n\n const updatedContent = editDictionaryByKeyPath(\n currentContent,\n newKeyPath,\n newValue\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: updatedContent as Dictionary['content'],\n },\n };\n });\n };\n\n const renameEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath: KeyPath[] = []\n ) => {\n setEditedContentState((prev) => {\n // Retrieve the base content: use edited version if available, otherwise deep copy of original\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n const contentWithNewField = renameContentNodeByKeyPath(\n currentContent,\n newKey,\n keyPath\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: contentWithNewField as Dictionary['content'],\n },\n };\n });\n };\n\n const removeEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n keyPath: KeyPath[]\n ) => {\n setEditedContentState((prev) => {\n // Retrieve the original content as reference\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n // Get the initial value from the original dictionary content\n const initialContent = getContentNodeByKeyPath(originalContent, keyPath);\n\n // Restore the value at the given keyPath\n const restoredContent = editDictionaryByKeyPath(\n currentContent,\n keyPath,\n initialContent\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: restoredContent as Dictionary['content'],\n },\n };\n });\n };\n\n const restoreEditedContent = (dictionaryLocalId: LocalDictionaryId) => {\n setEditedContentState((prev) => {\n const updated = { ...prev };\n delete updated[dictionaryLocalId];\n return updated;\n });\n };\n\n const clearEditedDictionaryContent = (\n dictionaryLocalId: LocalDictionaryId\n ) => {\n setEditedContentState((prev) => {\n const filtered = Object.entries(prev).reduce((acc, [key, value]) => {\n if (key === dictionaryLocalId) {\n return acc;\n }\n return { ...acc, [key]: value };\n }, {} as DictionaryContent);\n return filtered;\n });\n };\n\n const clearEditedContent = () => {\n setEditedContentState({});\n };\n\n const getEditedContentValue = (\n localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string,\n keyPath: KeyPath[]\n ): ContentNode | undefined => {\n if (!editedContent) return undefined;\n\n const filteredKeyPath = keyPath.filter(\n (key) => key.type !== NodeType.Translation\n );\n\n const isDictionaryId =\n localDictionaryIdOrKey.includes(':local:') ||\n localDictionaryIdOrKey.includes(':remote:');\n\n if (isDictionaryId) {\n const currentContent =\n editedContent?.[localDictionaryIdOrKey as LocalDictionaryId]?.content ??\n {};\n\n const contentNode = getContentNodeByKeyPath(\n currentContent,\n filteredKeyPath\n );\n\n return contentNode;\n }\n\n const filteredDictionariesLocalId = Object.keys(editedContent).filter(\n (key) => key.startsWith(`${localDictionaryIdOrKey}:`)\n );\n\n for (const localDictionaryId of filteredDictionariesLocalId) {\n const currentContent =\n editedContent?.[localDictionaryId as LocalDictionaryId]?.content ?? {};\n const contentNode = getContentNodeByKeyPath(\n currentContent,\n filteredKeyPath\n );\n\n if (contentNode) return contentNode;\n }\n\n return undefined;\n };\n\n return (\n <EditedContentStateContext.Provider\n value={{\n editedContent,\n }}\n >\n <EditedContentActionsContext.Provider\n value={{\n setEditedContentState,\n setEditedDictionary,\n setEditedContent,\n addEditedContent,\n renameEditedContent,\n removeEditedContent,\n restoreEditedContent,\n clearEditedDictionaryContent,\n clearEditedContent,\n getEditedContentValue,\n }}\n >\n {children}\n </EditedContentActionsContext.Provider>\n </EditedContentStateContext.Provider>\n );\n};\n\nexport const useEditedContentActions = () =>\n useContext(EditedContentActionsContext);\n\nexport const useEditedContent = () => {\n const stateContext = useContext(EditedContentStateContext);\n const actionContext = useEditedContentActions();\n\n return { ...stateContext, ...actionContext };\n};\n"],"mappings":"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"}
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
5
5
|
const require_editor_CommunicatorContext = require('./CommunicatorContext.cjs');
|
|
6
|
+
const require_editor_DictionariesRecordContext = require('./DictionariesRecordContext.cjs');
|
|
6
7
|
const require_editor_EditorEnabledContext = require('./EditorEnabledContext.cjs');
|
|
7
8
|
const require_editor_ConfigurationContext = require('./ConfigurationContext.cjs');
|
|
8
|
-
const require_editor_DictionariesRecordContext = require('./DictionariesRecordContext.cjs');
|
|
9
9
|
const require_editor_EditedContentContext = require('./EditedContentContext.cjs');
|
|
10
10
|
const require_editor_FocusDictionaryContext = require('./FocusDictionaryContext.cjs');
|
|
11
11
|
let preact_compat = require("preact/compat");
|
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
5
|
+
const require_editor_DictionariesRecordContext = require('./DictionariesRecordContext.cjs');
|
|
5
6
|
const require_editor_EditorEnabledContext = require('./EditorEnabledContext.cjs');
|
|
6
7
|
const require_editor_EditorProvider = require('./EditorProvider.cjs');
|
|
7
8
|
const require_editor_useCrossURLPathState = require('./useCrossURLPathState.cjs');
|
|
8
9
|
const require_editor_useIframeClickInterceptor = require('./useIframeClickInterceptor.cjs');
|
|
10
|
+
let preact_compat = require("preact/compat");
|
|
11
|
+
preact_compat = require_rolldown_runtime.__toESM(preact_compat);
|
|
9
12
|
let __intlayer_config_built = require("@intlayer/config/built");
|
|
10
13
|
__intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_built);
|
|
14
|
+
let __intlayer_unmerged_dictionaries_entry = require("@intlayer/unmerged-dictionaries-entry");
|
|
15
|
+
__intlayer_unmerged_dictionaries_entry = require_rolldown_runtime.__toESM(__intlayer_unmerged_dictionaries_entry);
|
|
11
16
|
let preact_jsx_runtime = require("preact/jsx-runtime");
|
|
12
17
|
preact_jsx_runtime = require_rolldown_runtime.__toESM(preact_jsx_runtime);
|
|
13
18
|
|
|
@@ -21,6 +26,15 @@ const IntlayerEditorHooksEnabled = () => {
|
|
|
21
26
|
* Click Messages
|
|
22
27
|
*/
|
|
23
28
|
require_editor_useIframeClickInterceptor.useIframeClickInterceptor();
|
|
29
|
+
/**
|
|
30
|
+
* Sent local dictionaries to editor
|
|
31
|
+
*/
|
|
32
|
+
const { setLocaleDictionaries } = require_editor_DictionariesRecordContext.useDictionariesRecordActions() ?? {};
|
|
33
|
+
(0, preact_compat.useEffect)(() => {
|
|
34
|
+
const unmergedDictionaries = (0, __intlayer_unmerged_dictionaries_entry.getUnmergedDictionaries)();
|
|
35
|
+
const dictionariesList = Object.fromEntries(Object.values(unmergedDictionaries).flat().map((dictionary) => [dictionary.localId, dictionary]));
|
|
36
|
+
setLocaleDictionaries?.(dictionariesList);
|
|
37
|
+
}, []);
|
|
24
38
|
return /* @__PURE__ */ (0, preact_jsx_runtime.jsx)(preact_jsx_runtime.Fragment, {});
|
|
25
39
|
};
|
|
26
40
|
const { editor } = __intlayer_config_built.default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntlayerEditorProvider.cjs","names":["IntlayerEditorHooksEnabled: FunctionComponent","configuration","IntlayerEditorHook: FunctionComponent","useEditorEnabled","IntlayerEditorProvider: FunctionComponent<{\n children?: ComponentChildren;\n}>","EditorProvider"],"sources":["../../../src/editor/IntlayerEditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport type { ComponentChildren, FunctionComponent } from 'preact';\nimport { useEditorEnabled } from './EditorEnabledContext';\nimport { EditorProvider } from './EditorProvider';\nimport { useCrossURLPathSetter } from './useCrossURLPathState';\nimport { useIframeClickInterceptor } from './useIframeClickInterceptor';\n\nconst IntlayerEditorHooksEnabled: FunctionComponent = () => {\n /**\n * URL Messages\n */\n useCrossURLPathSetter();\n\n /**\n * Click Messages\n */\n useIframeClickInterceptor();\n\n return <></>;\n};\n\nconst { editor } = configuration;\n\nconst IntlayerEditorHook: FunctionComponent = () => {\n const { enabled } = useEditorEnabled();\n\n return enabled ? <IntlayerEditorHooksEnabled /> : <></>;\n};\n\nexport const IntlayerEditorProvider: FunctionComponent<{\n children?: ComponentChildren;\n}> = ({ children }) => {\n return (\n <EditorProvider\n postMessage={(data: any) => {\n if (typeof window === 'undefined') return;\n\n const isInIframe = window.self !== window.top;\n if (!isInIframe) return;\n\n if (editor.applicationURL.length > 0) {\n window?.postMessage(\n data,\n // Use to restrict the origin of the editor for security reasons.\n // Correspond to the current application URL to synchronize the locales states.\n editor.applicationURL\n );\n }\n\n if (editor.editorURL.length > 0) {\n window.parent?.postMessage(\n data,\n // Use to restrict the origin of the editor for security reasons.\n // Correspond to the editor URL to synchronize the locales states.\n editor.editorURL\n );\n }\n\n if (editor.cmsURL.length > 0) {\n window.parent?.postMessage(\n data,\n // Use to restrict the origin of the CMS for security reasons.\n // Correspond to the CMS URL.\n editor.cmsURL\n );\n }\n }}\n allowedOrigins={[\n editor?.editorURL,\n editor?.cmsURL,\n editor?.applicationURL,\n ]}\n configuration={configuration}\n >\n <IntlayerEditorHook />\n {children}\n </EditorProvider>\n );\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"IntlayerEditorProvider.cjs","names":["IntlayerEditorHooksEnabled: FunctionComponent","useDictionariesRecordActions","configuration","IntlayerEditorHook: FunctionComponent","useEditorEnabled","IntlayerEditorProvider: FunctionComponent<{\n children?: ComponentChildren;\n}>","EditorProvider"],"sources":["../../../src/editor/IntlayerEditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport type { ComponentChildren, FunctionComponent } from 'preact';\nimport { useEffect } from 'preact/compat';\nimport { useDictionariesRecordActions } from './DictionariesRecordContext';\nimport { useEditorEnabled } from './EditorEnabledContext';\nimport { EditorProvider } from './EditorProvider';\nimport { useCrossURLPathSetter } from './useCrossURLPathState';\nimport { useIframeClickInterceptor } from './useIframeClickInterceptor';\n\nconst IntlayerEditorHooksEnabled: FunctionComponent = () => {\n /**\n * URL Messages\n */\n useCrossURLPathSetter();\n\n /**\n * Click Messages\n */\n useIframeClickInterceptor();\n\n /**\n * Sent local dictionaries to editor\n */\n const { setLocaleDictionaries } = useDictionariesRecordActions() ?? {};\n\n useEffect(() => {\n const unmergedDictionaries = getUnmergedDictionaries();\n const dictionariesList = Object.fromEntries(\n Object.values(unmergedDictionaries)\n .flat()\n .map((dictionary) => [dictionary.localId, dictionary])\n );\n\n setLocaleDictionaries?.(dictionariesList);\n }, []);\n\n return <></>;\n};\n\nconst { editor } = configuration;\n\nconst IntlayerEditorHook: FunctionComponent = () => {\n const { enabled } = useEditorEnabled();\n\n return enabled ? <IntlayerEditorHooksEnabled /> : <></>;\n};\n\nexport const IntlayerEditorProvider: FunctionComponent<{\n children?: ComponentChildren;\n}> = ({ children }) => {\n return (\n <EditorProvider\n postMessage={(data: any) => {\n if (typeof window === 'undefined') return;\n\n const isInIframe = window.self !== window.top;\n if (!isInIframe) return;\n\n if (editor.applicationURL.length > 0) {\n window?.postMessage(\n data,\n // Use to restrict the origin of the editor for security reasons.\n // Correspond to the current application URL to synchronize the locales states.\n editor.applicationURL\n );\n }\n\n if (editor.editorURL.length > 0) {\n window.parent?.postMessage(\n data,\n // Use to restrict the origin of the editor for security reasons.\n // Correspond to the editor URL to synchronize the locales states.\n editor.editorURL\n );\n }\n\n if (editor.cmsURL.length > 0) {\n window.parent?.postMessage(\n data,\n // Use to restrict the origin of the CMS for security reasons.\n // Correspond to the CMS URL.\n editor.cmsURL\n );\n }\n }}\n allowedOrigins={[\n editor?.editorURL,\n editor?.cmsURL,\n editor?.applicationURL,\n ]}\n configuration={configuration}\n >\n <IntlayerEditorHook />\n {children}\n </EditorProvider>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAYA,MAAMA,mCAAsD;;;;AAI1D,4DAAuB;;;;AAKvB,qEAA2B;;;;CAK3B,MAAM,EAAE,0BAA0BC,uEAA8B,IAAI,EAAE;AAEtE,oCAAgB;EACd,MAAM,4FAAgD;EACtD,MAAM,mBAAmB,OAAO,YAC9B,OAAO,OAAO,qBAAqB,CAChC,MAAM,CACN,KAAK,eAAe,CAAC,WAAW,SAAS,WAAW,CAAC,CACzD;AAED,0BAAwB,iBAAiB;IACxC,EAAE,CAAC;AAEN,QAAO,4EAAK;;AAGd,MAAM,EAAE,WAAWC;AAEnB,MAAMC,2BAA8C;CAClD,MAAM,EAAE,YAAYC,sDAAkB;AAEtC,QAAO,UAAU,4CAAC,+BAA6B,GAAG,4EAAK;;AAGzD,MAAaC,0BAEP,EAAE,eAAe;AACrB,QACE,6CAACC;EACC,cAAc,SAAc;AAC1B,OAAI,OAAO,WAAW,YAAa;AAGnC,OAAI,EADe,OAAO,SAAS,OAAO,KACzB;AAEjB,OAAI,OAAO,eAAe,SAAS,EACjC,SAAQ,YACN,MAGA,OAAO,eACR;AAGH,OAAI,OAAO,UAAU,SAAS,EAC5B,QAAO,QAAQ,YACb,MAGA,OAAO,UACR;AAGH,OAAI,OAAO,OAAO,SAAS,EACzB,QAAO,QAAQ,YACb,MAGA,OAAO,OACR;;EAGL,gBAAgB;GACd,QAAQ;GACR,QAAQ;GACR,QAAQ;GACT;EACD,eAAeJ;aAEf,4CAAC,uBAAqB,EACrB;GACc"}
|
|
@@ -41,7 +41,12 @@ const useCrossFrameMessageListener = (key, onEventTriggered, revalidator) => {
|
|
|
41
41
|
const { type, data, senderId: msgSenderId } = event.data;
|
|
42
42
|
if (type !== key) return;
|
|
43
43
|
if (msgSenderId === senderId) return;
|
|
44
|
-
if (typeof allowedOrigins === "undefined" || allowedOrigins?.
|
|
44
|
+
if (typeof allowedOrigins === "undefined" || allowedOrigins?.filter((url) => ![
|
|
45
|
+
null,
|
|
46
|
+
void 0,
|
|
47
|
+
"",
|
|
48
|
+
"*"
|
|
49
|
+
].includes(url)).some((url) => (0, __intlayer_editor.compareUrls)(url, event.origin)) || allowedOrigins?.includes("*")) onEventTriggered(data);
|
|
45
50
|
};
|
|
46
51
|
window.addEventListener("message", handleMessage);
|
|
47
52
|
return () => window.removeEventListener("message", handleMessage);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCrossFrameMessageListener.cjs","names":["useCommunicator","postMessageWrapper: (data?: S) => void"],"sources":["../../../src/editor/useCrossFrameMessageListener.tsx"],"sourcesContent":["'use client';\n\nimport { compareUrls, type MessageKey } from '@intlayer/editor';\nimport { useEffect } from 'preact/hooks';\nimport { useCommunicator } from './CommunicatorContext';\n\n/**\n * useCrossFrameMessageListener\n *\n * This React hook listens for messages sent via the `postMessage` API and triggers a callback\n * whenever a message of the specified type (`key`) is received. It is useful for synchronizing\n * state or events across different windows, iframes, or contexts.\n *\n * @template S - The type of the data payload in the message.\n * @param key - A unique identifier for the message type to listen for.\n * @param [onEventTriggered] - A callback function triggered when a message\n * @param [revalidator] - A function that re-suscribes the listener. Could be usefull if onEventTriggered depend of some state\n * with the specified key is received. The callback receives the message data as its argument.\n *\n * @returns {{ postMessage: (data: S) => void }} An object containing a `postMessage` function\n * that allows broadcasting messages with the specified key and data.\n */\nexport const useCrossFrameMessageListener = <S,>(\n key: `${MessageKey}` | `${MessageKey}/post` | `${MessageKey}/get`,\n onEventTriggered?: (data: S) => void,\n revalidator?: any\n) => {\n const { allowedOrigins, postMessage, senderId } = useCommunicator();\n\n useEffect(() => {\n if (onEventTriggered) {\n /**\n * Message handler to process incoming messages.\n *\n * - **Message Filtering:** Ensures only messages with the specified `key` are processed.\n * - **Origin Validation:** Checks that the origin of the message is within the allowed origins.\n *\n * @param {MessageEvent<{ type: string; data: S }>} event - The incoming message event object.\n */\n const handleMessage = (\n event: MessageEvent<{ type: string; data: S; senderId: string }>\n ) => {\n const { type, data, senderId: msgSenderId } = event.data;\n\n // Ignore messages that do not match the current key\n if (type !== key) return;\n\n // Ignore messages from myself\n if (msgSenderId === senderId) return;\n\n // Check if the message origin is allowed\n if (\n typeof allowedOrigins === 'undefined' ||\n allowedOrigins?.some((url) => compareUrls(url, event.origin)) ||\n allowedOrigins?.includes('*')\n ) {\n // Update the local state with the received data\n onEventTriggered(data);\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n // Clean up the event listener on unmount\n return () => window.removeEventListener('message', handleMessage);\n }\n }, [allowedOrigins, postMessage, senderId, revalidator]);\n\n /**\n * A wrapper function around the `postMessage` function to broadcast messages efficiently.\n *\n * - **Encapsulation:** Ensures the `postMessage` function is scoped to the provided key.\n * - **Ease of Use:** Simplifies broadcasting messages with consistent type and format.\n *\n * @param {S} data - The data payload to include in the message.\n * @returns {void}\n */\n const postMessageWrapper: (data?: S) => void = (data) => {\n postMessage({ type: key, data, senderId });\n };\n\n return postMessageWrapper;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,gCACX,KACA,kBACA,gBACG;CACH,MAAM,EAAE,gBAAgB,aAAa,aAAaA,oDAAiB;AAEnE,mCAAgB;AACd,MAAI,kBAAkB;;;;;;;;;GASpB,MAAM,iBACJ,UACG;IACH,MAAM,EAAE,MAAM,MAAM,UAAU,gBAAgB,MAAM;AAGpD,QAAI,SAAS,IAAK;AAGlB,QAAI,gBAAgB,SAAU;AAG9B,QACE,OAAO,mBAAmB,eAC1B,
|
|
1
|
+
{"version":3,"file":"useCrossFrameMessageListener.cjs","names":["useCommunicator","postMessageWrapper: (data?: S) => void"],"sources":["../../../src/editor/useCrossFrameMessageListener.tsx"],"sourcesContent":["'use client';\n\nimport { compareUrls, type MessageKey } from '@intlayer/editor';\nimport { useEffect } from 'preact/hooks';\nimport { useCommunicator } from './CommunicatorContext';\n\n/**\n * useCrossFrameMessageListener\n *\n * This React hook listens for messages sent via the `postMessage` API and triggers a callback\n * whenever a message of the specified type (`key`) is received. It is useful for synchronizing\n * state or events across different windows, iframes, or contexts.\n *\n * @template S - The type of the data payload in the message.\n * @param key - A unique identifier for the message type to listen for.\n * @param [onEventTriggered] - A callback function triggered when a message\n * @param [revalidator] - A function that re-suscribes the listener. Could be usefull if onEventTriggered depend of some state\n * with the specified key is received. The callback receives the message data as its argument.\n *\n * @returns {{ postMessage: (data: S) => void }} An object containing a `postMessage` function\n * that allows broadcasting messages with the specified key and data.\n */\nexport const useCrossFrameMessageListener = <S,>(\n key: `${MessageKey}` | `${MessageKey}/post` | `${MessageKey}/get`,\n onEventTriggered?: (data: S) => void,\n revalidator?: any\n) => {\n const { allowedOrigins, postMessage, senderId } = useCommunicator();\n\n useEffect(() => {\n if (onEventTriggered) {\n /**\n * Message handler to process incoming messages.\n *\n * - **Message Filtering:** Ensures only messages with the specified `key` are processed.\n * - **Origin Validation:** Checks that the origin of the message is within the allowed origins.\n *\n * @param {MessageEvent<{ type: string; data: S }>} event - The incoming message event object.\n */\n const handleMessage = (\n event: MessageEvent<{ type: string; data: S; senderId: string }>\n ) => {\n const { type, data, senderId: msgSenderId } = event.data;\n\n // Ignore messages that do not match the current key\n if (type !== key) return;\n\n // Ignore messages from myself\n if (msgSenderId === senderId) return;\n\n // Check if the message origin is allowed\n if (\n typeof allowedOrigins === 'undefined' ||\n allowedOrigins\n ?.filter((url) => ![null, undefined, '', '*'].includes(url))\n .some((url) => compareUrls(url, event.origin)) ||\n allowedOrigins?.includes('*')\n ) {\n // Update the local state with the received data\n onEventTriggered(data);\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n // Clean up the event listener on unmount\n return () => window.removeEventListener('message', handleMessage);\n }\n }, [allowedOrigins, postMessage, senderId, revalidator]);\n\n /**\n * A wrapper function around the `postMessage` function to broadcast messages efficiently.\n *\n * - **Encapsulation:** Ensures the `postMessage` function is scoped to the provided key.\n * - **Ease of Use:** Simplifies broadcasting messages with consistent type and format.\n *\n * @param {S} data - The data payload to include in the message.\n * @returns {void}\n */\n const postMessageWrapper: (data?: S) => void = (data) => {\n postMessage({ type: key, data, senderId });\n };\n\n return postMessageWrapper;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,gCACX,KACA,kBACA,gBACG;CACH,MAAM,EAAE,gBAAgB,aAAa,aAAaA,oDAAiB;AAEnE,mCAAgB;AACd,MAAI,kBAAkB;;;;;;;;;GASpB,MAAM,iBACJ,UACG;IACH,MAAM,EAAE,MAAM,MAAM,UAAU,gBAAgB,MAAM;AAGpD,QAAI,SAAS,IAAK;AAGlB,QAAI,gBAAgB,SAAU;AAG9B,QACE,OAAO,mBAAmB,eAC1B,gBACI,QAAQ,QAAQ,CAAC;KAAC;KAAM;KAAW;KAAI;KAAI,CAAC,SAAS,IAAI,CAAC,CAC3D,MAAM,2CAAoB,KAAK,MAAM,OAAO,CAAC,IAChD,gBAAgB,SAAS,IAAI,CAG7B,kBAAiB,KAAK;;AAI1B,UAAO,iBAAiB,WAAW,cAAc;AAGjD,gBAAa,OAAO,oBAAoB,WAAW,cAAc;;IAElE;EAAC;EAAgB;EAAa;EAAU;EAAY,CAAC;;;;;;;;;;CAWxD,MAAMC,sBAA0C,SAAS;AACvD,cAAY;GAAE,MAAM;GAAK;GAAM;GAAU,CAAC;;AAG5C,QAAO"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { useCrossFrameState } from "../editor/useCrossFrameState.mjs";
|
|
5
5
|
import { IntlayerEditorProvider } from "../editor/IntlayerEditorProvider.mjs";
|
|
6
|
-
import {
|
|
6
|
+
import { localeInStorage, setLocaleInStorage as setLocaleInStorage$1 } from "./useLocaleStorage.mjs";
|
|
7
7
|
import { createContext } from "preact";
|
|
8
8
|
import { localeResolver } from "@intlayer/core";
|
|
9
9
|
import { MessageKey } from "@intlayer/editor";
|
|
@@ -16,7 +16,7 @@ import { jsx } from "preact/jsx-runtime";
|
|
|
16
16
|
* Context that store the current locale on the client side
|
|
17
17
|
*/
|
|
18
18
|
const IntlayerClientContext = createContext({
|
|
19
|
-
locale:
|
|
19
|
+
locale: localeInStorage ?? configuration?.internationalization?.defaultLocale,
|
|
20
20
|
setLocale: () => null,
|
|
21
21
|
disableEditor: false
|
|
22
22
|
});
|
|
@@ -30,7 +30,7 @@ const useIntlayerContext = () => useContext(IntlayerClientContext);
|
|
|
30
30
|
const IntlayerProviderContent = ({ locale: localeProp, defaultLocale: defaultLocaleProp, children, setLocale: setLocaleProp, disableEditor, isCookieEnabled }) => {
|
|
31
31
|
const { internationalization } = configuration ?? {};
|
|
32
32
|
const { defaultLocale: defaultLocaleConfig, locales: availableLocales } = internationalization ?? {};
|
|
33
|
-
const defaultLocale = localeProp ??
|
|
33
|
+
const defaultLocale = localeProp ?? localeInStorage ?? defaultLocaleProp ?? defaultLocaleConfig;
|
|
34
34
|
const [currentLocale, setCurrentLocale] = useCrossFrameState(MessageKey.INTLAYER_CURRENT_LOCALE, defaultLocale);
|
|
35
35
|
const setLocaleBase = (newLocale) => {
|
|
36
36
|
if (currentLocale.toString() === newLocale.toString()) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntlayerProvider.mjs","names":["IntlayerProviderContent: FunctionComponent<\n IntlayerProviderProps\n>","IntlayerProvider: FunctionComponent<IntlayerProviderProps>"],"sources":["../../../src/client/IntlayerProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport { localeResolver } from '@intlayer/core';\nimport { MessageKey } from '@intlayer/editor';\nimport type { LocalesValues } from '@intlayer/types';\nimport {\n type ComponentChild,\n createContext,\n type FunctionComponent,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport { IntlayerEditorProvider } from '../editor/IntlayerEditorProvider';\nimport { useCrossFrameState } from '../editor/useCrossFrameState';\nimport {
|
|
1
|
+
{"version":3,"file":"IntlayerProvider.mjs","names":["IntlayerProviderContent: FunctionComponent<\n IntlayerProviderProps\n>","IntlayerProvider: FunctionComponent<IntlayerProviderProps>"],"sources":["../../../src/client/IntlayerProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport { localeResolver } from '@intlayer/core';\nimport { MessageKey } from '@intlayer/editor';\nimport type { LocalesValues } from '@intlayer/types';\nimport {\n type ComponentChild,\n createContext,\n type FunctionComponent,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport { IntlayerEditorProvider } from '../editor/IntlayerEditorProvider';\nimport { useCrossFrameState } from '../editor/useCrossFrameState';\nimport { localeInStorage, setLocaleInStorage } from './useLocaleStorage';\n\ntype IntlayerValue = {\n locale: LocalesValues;\n setLocale: (newLocale: LocalesValues) => void;\n disableEditor?: boolean;\n isCookieEnabled?: boolean;\n};\n\n/**\n * Context that store the current locale on the client side\n */\nexport const IntlayerClientContext = createContext<IntlayerValue>({\n locale: localeInStorage ?? configuration?.internationalization?.defaultLocale,\n setLocale: () => null,\n disableEditor: false,\n});\n\n/**\n * Hook that provides the current locale\n */\nexport const useIntlayerContext = () => useContext(IntlayerClientContext);\n\nexport type IntlayerProviderProps = {\n children?: ComponentChild;\n locale?: LocalesValues;\n defaultLocale?: LocalesValues;\n setLocale?: (locale: LocalesValues) => void;\n disableEditor?: boolean;\n isCookieEnabled?: boolean;\n};\n\n/**\n * Provider that store the current locale on the client side\n */\nexport const IntlayerProviderContent: FunctionComponent<\n IntlayerProviderProps\n> = ({\n locale: localeProp,\n defaultLocale: defaultLocaleProp,\n children,\n setLocale: setLocaleProp,\n disableEditor,\n isCookieEnabled,\n}) => {\n const { internationalization } = configuration ?? {};\n const { defaultLocale: defaultLocaleConfig, locales: availableLocales } =\n internationalization ?? {};\n\n const defaultLocale =\n localeProp ?? localeInStorage ?? defaultLocaleProp ?? defaultLocaleConfig;\n\n const [currentLocale, setCurrentLocale] = useCrossFrameState(\n MessageKey.INTLAYER_CURRENT_LOCALE,\n defaultLocale\n );\n\n const setLocaleBase = (newLocale: LocalesValues) => {\n if (currentLocale.toString() === newLocale.toString()) return;\n\n if (!availableLocales?.map(String).includes(newLocale)) {\n console.error(`Locale ${newLocale} is not available`);\n return;\n }\n\n setCurrentLocale(newLocale); // Update state\n setLocaleInStorage(newLocale, isCookieEnabled ?? true); // Optionally set cookie for persistence\n };\n\n const setLocale = setLocaleProp ?? setLocaleBase;\n\n const resolvedLocale = localeResolver(localeProp ?? currentLocale);\n\n return (\n <IntlayerClientContext.Provider\n value={{\n locale: resolvedLocale,\n setLocale,\n disableEditor,\n isCookieEnabled,\n }}\n >\n {children}\n </IntlayerClientContext.Provider>\n );\n};\n\nexport const IntlayerProvider: FunctionComponent<IntlayerProviderProps> = (\n props\n) => (\n <IntlayerEditorProvider>\n <IntlayerProviderContent {...props} />\n </IntlayerEditorProvider>\n);\n"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,MAAa,wBAAwB,cAA6B;CAChE,QAAQ,mBAAmB,eAAe,sBAAsB;CAChE,iBAAiB;CACjB,eAAe;CAChB,CAAC;;;;AAKF,MAAa,2BAA2B,WAAW,sBAAsB;;;;AAczE,MAAaA,2BAER,EACH,QAAQ,YACR,eAAe,mBACf,UACA,WAAW,eACX,eACA,sBACI;CACJ,MAAM,EAAE,yBAAyB,iBAAiB,EAAE;CACpD,MAAM,EAAE,eAAe,qBAAqB,SAAS,qBACnD,wBAAwB,EAAE;CAE5B,MAAM,gBACJ,cAAc,mBAAmB,qBAAqB;CAExD,MAAM,CAAC,eAAe,oBAAoB,mBACxC,WAAW,yBACX,cACD;CAED,MAAM,iBAAiB,cAA6B;AAClD,MAAI,cAAc,UAAU,KAAK,UAAU,UAAU,CAAE;AAEvD,MAAI,CAAC,kBAAkB,IAAI,OAAO,CAAC,SAAS,UAAU,EAAE;AACtD,WAAQ,MAAM,UAAU,UAAU,mBAAmB;AACrD;;AAGF,mBAAiB,UAAU;AAC3B,uBAAmB,WAAW,mBAAmB,KAAK;;CAGxD,MAAM,YAAY,iBAAiB;CAEnC,MAAM,iBAAiB,eAAe,cAAc,cAAc;AAElE,QACE,oBAAC,sBAAsB;EACrB,OAAO;GACL,QAAQ;GACR;GACA;GACA;GACD;EAEA;GAC8B;;AAIrC,MAAaC,oBACX,UAEA,oBAAC,oCACC,oBAAC,2BAAwB,GAAI,QAAS,GACf"}
|
|
@@ -7,6 +7,7 @@ import { useFocusDictionary } from "./FocusDictionaryContext.mjs";
|
|
|
7
7
|
import { useIntlayerContext } from "../client/IntlayerProvider.mjs";
|
|
8
8
|
import { ContentSelector } from "../UI/ContentSelector.mjs";
|
|
9
9
|
import { isSameKeyPath } from "@intlayer/core";
|
|
10
|
+
import { NodeType } from "@intlayer/types";
|
|
10
11
|
import { MessageKey } from "@intlayer/editor";
|
|
11
12
|
import { useCallback, useMemo } from "preact/compat";
|
|
12
13
|
import { jsx } from "preact/jsx-runtime";
|
|
@@ -15,27 +16,28 @@ import { jsx } from "preact/jsx-runtime";
|
|
|
15
16
|
const ContentSelectorWrapperContent = ({ children, dictionaryKey, keyPath }) => {
|
|
16
17
|
const { focusedContent, setFocusedContent } = useFocusDictionary();
|
|
17
18
|
const { postMessage, senderId } = useCommunicator();
|
|
19
|
+
const filteredKeyPath = useMemo(() => keyPath.filter((key) => key.type !== NodeType.Translation), [keyPath]);
|
|
18
20
|
return /* @__PURE__ */ jsx(ContentSelector, {
|
|
19
21
|
onPress: useCallback(() => setFocusedContent({
|
|
20
22
|
dictionaryKey,
|
|
21
|
-
keyPath
|
|
22
|
-
}), [dictionaryKey,
|
|
23
|
+
keyPath: filteredKeyPath
|
|
24
|
+
}), [dictionaryKey, filteredKeyPath]),
|
|
23
25
|
onHover: useCallback(() => postMessage({
|
|
24
26
|
type: `${MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,
|
|
25
27
|
data: {
|
|
26
28
|
dictionaryKey,
|
|
27
|
-
keyPath
|
|
29
|
+
keyPath: filteredKeyPath
|
|
28
30
|
},
|
|
29
31
|
senderId
|
|
30
|
-
}), [dictionaryKey,
|
|
32
|
+
}), [dictionaryKey, filteredKeyPath]),
|
|
31
33
|
onUnhover: useCallback(() => postMessage({
|
|
32
34
|
type: `${MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,
|
|
33
35
|
data: null,
|
|
34
36
|
senderId
|
|
35
37
|
}), [senderId]),
|
|
36
|
-
isSelecting: useMemo(() => (focusedContent?.dictionaryKey === dictionaryKey && (focusedContent?.keyPath?.length ?? 0) > 0 && isSameKeyPath(focusedContent?.keyPath ?? [],
|
|
38
|
+
isSelecting: useMemo(() => (focusedContent?.dictionaryKey === dictionaryKey && (focusedContent?.keyPath?.length ?? 0) > 0 && isSameKeyPath(focusedContent?.keyPath ?? [], filteredKeyPath)) ?? false, [
|
|
37
39
|
focusedContent,
|
|
38
|
-
|
|
40
|
+
filteredKeyPath,
|
|
39
41
|
dictionaryKey
|
|
40
42
|
]),
|
|
41
43
|
children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentSelectorWrapper.mjs","names":["ContentSelectorWrapperContent: FC<ContentSelectorWrapperProps>","ContentSelectorRenderer: FC<ContentSelectorWrapperProps>"],"sources":["../../../src/editor/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport { isSameKeyPath, type NodeProps } from '@intlayer/core';\nimport { MessageKey } from '@intlayer/editor';\nimport {\n type FC,\n type HTMLAttributes,\n useCallback,\n useMemo,\n} from 'preact/compat';\nimport { useIntlayerContext } from '../client';\nimport { ContentSelector } from '../UI/ContentSelector';\nimport { useCommunicator } from './CommunicatorContext';\nimport { useEditorEnabled } from './EditorEnabledContext';\nimport { useFocusDictionary } from './FocusDictionaryContext';\n\nexport type ContentSelectorWrapperProps = NodeProps &\n Omit<HTMLAttributes<HTMLDivElement>, 'children'>;\n\nconst ContentSelectorWrapperContent: FC<ContentSelectorWrapperProps> = ({\n children,\n dictionaryKey,\n keyPath,\n}) => {\n const { focusedContent, setFocusedContent } = useFocusDictionary();\n const { postMessage, senderId } = useCommunicator();\n\n const handleSelect = useCallback(\n () =>\n setFocusedContent({\n dictionaryKey,\n keyPath,\n }),\n [dictionaryKey,
|
|
1
|
+
{"version":3,"file":"ContentSelectorWrapper.mjs","names":["ContentSelectorWrapperContent: FC<ContentSelectorWrapperProps>","ContentSelectorRenderer: FC<ContentSelectorWrapperProps>"],"sources":["../../../src/editor/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport { isSameKeyPath, type NodeProps } from '@intlayer/core';\nimport { MessageKey } from '@intlayer/editor';\nimport { NodeType } from '@intlayer/types';\nimport {\n type FC,\n type HTMLAttributes,\n useCallback,\n useMemo,\n} from 'preact/compat';\nimport { useIntlayerContext } from '../client';\nimport { ContentSelector } from '../UI/ContentSelector';\nimport { useCommunicator } from './CommunicatorContext';\nimport { useEditorEnabled } from './EditorEnabledContext';\nimport { useFocusDictionary } from './FocusDictionaryContext';\n\nexport type ContentSelectorWrapperProps = NodeProps &\n Omit<HTMLAttributes<HTMLDivElement>, 'children'>;\n\nconst ContentSelectorWrapperContent: FC<ContentSelectorWrapperProps> = ({\n children,\n dictionaryKey,\n keyPath,\n}) => {\n const { focusedContent, setFocusedContent } = useFocusDictionary();\n const { postMessage, senderId } = useCommunicator();\n\n // Filter out translation nodes for more flexibility with the editor that can have different format\n const filteredKeyPath = useMemo(\n () => keyPath.filter((key) => key.type !== NodeType.Translation),\n [keyPath]\n );\n\n const handleSelect = useCallback(\n () =>\n setFocusedContent({\n dictionaryKey,\n keyPath: filteredKeyPath,\n }),\n [dictionaryKey, filteredKeyPath]\n );\n\n const handleHover = useCallback(\n () =>\n postMessage({\n type: `${MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,\n data: {\n dictionaryKey,\n keyPath: filteredKeyPath,\n },\n senderId,\n }),\n [dictionaryKey, filteredKeyPath]\n );\n\n const handleUnhover = useCallback(\n () =>\n postMessage({\n type: `${MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,\n data: null,\n senderId,\n }),\n [senderId]\n );\n\n const isSelected = useMemo(\n () =>\n (focusedContent?.dictionaryKey === dictionaryKey &&\n (focusedContent?.keyPath?.length ?? 0) > 0 &&\n isSameKeyPath(focusedContent?.keyPath ?? [], filteredKeyPath)) ??\n false,\n [focusedContent, filteredKeyPath, dictionaryKey]\n );\n\n return (\n <ContentSelector\n onPress={handleSelect}\n onHover={handleHover}\n onUnhover={handleUnhover}\n isSelecting={isSelected}\n >\n {children}\n </ContentSelector>\n );\n};\n\nexport const ContentSelectorRenderer: FC<ContentSelectorWrapperProps> = ({\n children,\n ...props\n}) => {\n const { enabled } = useEditorEnabled();\n const { disableEditor } = useIntlayerContext();\n\n if (enabled && !disableEditor) {\n return (\n <ContentSelectorWrapperContent {...props}>\n {children}\n </ContentSelectorWrapperContent>\n );\n }\n\n return children;\n};\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,MAAMA,iCAAkE,EACtE,UACA,eACA,cACI;CACJ,MAAM,EAAE,gBAAgB,sBAAsB,oBAAoB;CAClE,MAAM,EAAE,aAAa,aAAa,iBAAiB;CAGnD,MAAM,kBAAkB,cAChB,QAAQ,QAAQ,QAAQ,IAAI,SAAS,SAAS,YAAY,EAChE,CAAC,QAAQ,CACV;AA2CD,QACE,oBAAC;EACC,SA3CiB,kBAEjB,kBAAkB;GAChB;GACA,SAAS;GACV,CAAC,EACJ,CAAC,eAAe,gBAAgB,CACjC;EAqCG,SAnCgB,kBAEhB,YAAY;GACV,MAAM,GAAG,WAAW,iCAAiC;GACrD,MAAM;IACJ;IACA,SAAS;IACV;GACD;GACD,CAAC,EACJ,CAAC,eAAe,gBAAgB,CACjC;EAyBG,WAvBkB,kBAElB,YAAY;GACV,MAAM,GAAG,WAAW,iCAAiC;GACrD,MAAM;GACN;GACD,CAAC,EACJ,CAAC,SAAS,CACX;EAgBG,aAde,eAEd,gBAAgB,kBAAkB,kBAChC,gBAAgB,SAAS,UAAU,KAAK,KACzC,cAAc,gBAAgB,WAAW,EAAE,EAAE,gBAAgB,KAC/D,OACF;GAAC;GAAgB;GAAiB;GAAc,CACjD;EASI;GACe;;AAItB,MAAaC,2BAA4D,EACvE,SACA,GAAG,YACC;CACJ,MAAM,EAAE,YAAY,kBAAkB;CACtC,MAAM,EAAE,kBAAkB,oBAAoB;AAE9C,KAAI,WAAW,CAAC,cACd,QACE,oBAAC;EAA8B,GAAI;EAChC;GAC6B;AAIpC,QAAO"}
|
|
@@ -5,6 +5,7 @@ import { useCrossFrameMessageListener } from "./useCrossFrameMessageListener.mjs
|
|
|
5
5
|
import { useCrossFrameState } from "./useCrossFrameState.mjs";
|
|
6
6
|
import { useDictionariesRecord } from "./DictionariesRecordContext.mjs";
|
|
7
7
|
import { editDictionaryByKeyPath, getContentNodeByKeyPath, renameContentNodeByKeyPath } from "@intlayer/core";
|
|
8
|
+
import { NodeType } from "@intlayer/types";
|
|
8
9
|
import { MessageKey } from "@intlayer/editor";
|
|
9
10
|
import { createContext, useContext } from "preact/compat";
|
|
10
11
|
import { jsx } from "preact/jsx-runtime";
|
|
@@ -116,10 +117,11 @@ const EditedContentProvider = ({ children }) => {
|
|
|
116
117
|
};
|
|
117
118
|
const getEditedContentValue = (localDictionaryIdOrKey, keyPath) => {
|
|
118
119
|
if (!editedContent) return void 0;
|
|
119
|
-
|
|
120
|
+
const filteredKeyPath = keyPath.filter((key) => key.type !== NodeType.Translation);
|
|
121
|
+
if (localDictionaryIdOrKey.includes(":local:") || localDictionaryIdOrKey.includes(":remote:")) return getContentNodeByKeyPath(editedContent?.[localDictionaryIdOrKey]?.content ?? {}, filteredKeyPath);
|
|
120
122
|
const filteredDictionariesLocalId = Object.keys(editedContent).filter((key) => key.startsWith(`${localDictionaryIdOrKey}:`));
|
|
121
123
|
for (const localDictionaryId of filteredDictionariesLocalId) {
|
|
122
|
-
const contentNode = getContentNodeByKeyPath(editedContent?.[localDictionaryId]?.content ?? {},
|
|
124
|
+
const contentNode = getContentNodeByKeyPath(editedContent?.[localDictionaryId]?.content ?? {}, filteredKeyPath);
|
|
123
125
|
if (contentNode) return contentNode;
|
|
124
126
|
}
|
|
125
127
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditedContentContext.mjs","names":["EditedContentProvider: FC<PropsWithChildren>","setEditedDictionary: Dispatch<SetStateAction<Dictionary>>","updatedDictionaries: Dictionary","lastKeyPath: KeyPath"],"sources":["../../../src/editor/EditedContentContext.tsx"],"sourcesContent":["'use client';\n\nimport {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core';\nimport { MessageKey } from '@intlayer/editor';\nimport type {\n ContentNode,\n Dictionary,\n KeyPath,\n LocalDictionaryId,\n} from '@intlayer/types';\nimport {\n createContext,\n type Dispatch,\n type FC,\n type PropsWithChildren,\n type SetStateAction,\n useContext,\n} from 'preact/compat';\nimport {\n type DictionaryContent,\n useDictionariesRecord,\n} from './DictionariesRecordContext';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\nimport { useCrossFrameState } from './useCrossFrameState';\n\ntype EditedContentStateContextType = {\n editedContent: Record<LocalDictionaryId, Dictionary> | undefined;\n};\n\nconst EditedContentStateContext = createContext<\n EditedContentStateContextType | undefined\n>(undefined);\n\nexport const usePostEditedContentState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/post`,\n onEventTriggered\n );\n\nexport const useGetEditedContentState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/get`,\n onEventTriggered\n );\n\ntype EditedContentActionsContextType = {\n setEditedContentState: (\n editedContent: Record<LocalDictionaryId, Dictionary>\n ) => void;\n setEditedDictionary: Dispatch<SetStateAction<Dictionary>>;\n setEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newValue: Dictionary['content']\n ) => void;\n addEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newValue: ContentNode<any>,\n keyPath?: KeyPath[],\n overwrite?: boolean\n ) => void;\n renameEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath?: KeyPath[]\n ) => void;\n removeEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n keyPath: KeyPath[]\n ) => void;\n restoreEditedContent: (dictionaryLocalId: LocalDictionaryId) => void;\n clearEditedDictionaryContent: (dictionaryLocalId: LocalDictionaryId) => void;\n clearEditedContent: () => void;\n getEditedContentValue: (\n localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string,\n keyPath: KeyPath[]\n ) => ContentNode | undefined;\n};\n\nconst EditedContentActionsContext = createContext<\n EditedContentActionsContextType | undefined\n>(undefined);\n\nconst resolveState = <S,>(state?: SetStateAction<S>, prevState?: S): S =>\n typeof state === 'function'\n ? (state as (prevState?: S) => S)(prevState)\n : (state as S);\n\nexport const EditedContentProvider: FC<PropsWithChildren> = ({ children }) => {\n const { localeDictionaries } = useDictionariesRecord();\n\n const [editedContent, setEditedContentState] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED\n );\n\n const setEditedDictionary: Dispatch<SetStateAction<Dictionary>> = (\n newValue\n ) => {\n let updatedDictionaries: Dictionary = resolveState(newValue);\n\n setEditedContentState((prev) => {\n updatedDictionaries = resolveState(\n newValue,\n prev?.[updatedDictionaries.key]\n );\n\n return {\n ...prev,\n [updatedDictionaries.key]: updatedDictionaries,\n };\n });\n\n return updatedDictionaries;\n };\n\n const setEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newValue: Dictionary['content']\n ) => {\n setEditedContentState((prev) => ({\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: newValue,\n },\n }));\n };\n\n const addEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newValue: ContentNode,\n keyPath: KeyPath[] = [],\n overwrite: boolean = true\n ) => {\n setEditedContentState((prev) => {\n // Get the starting content: edited version if available, otherwise a deep copy of the original\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n let newKeyPath = keyPath;\n if (!overwrite) {\n // Find a unique key based on the keyPath provided\n let index = 0;\n const otherKeyPath = keyPath.slice(0, -1);\n const lastKeyPath: KeyPath = keyPath[keyPath.length - 1];\n let finalKey = lastKeyPath.key;\n\n // Loop until we find a key that does not exist\n while (\n typeof getContentNodeByKeyPath(currentContent, newKeyPath) !==\n 'undefined'\n ) {\n index++;\n finalKey =\n index === 0 ? lastKeyPath.key : `${lastKeyPath.key} (${index})`;\n newKeyPath = [\n ...otherKeyPath,\n { ...lastKeyPath, key: finalKey } as KeyPath,\n ];\n }\n }\n\n const updatedContent = editDictionaryByKeyPath(\n currentContent,\n newKeyPath,\n newValue\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: updatedContent as Dictionary['content'],\n },\n };\n });\n };\n\n const renameEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath: KeyPath[] = []\n ) => {\n setEditedContentState((prev) => {\n // Retrieve the base content: use edited version if available, otherwise deep copy of original\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n const contentWithNewField = renameContentNodeByKeyPath(\n currentContent,\n newKey,\n keyPath\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: contentWithNewField as Dictionary['content'],\n },\n };\n });\n };\n\n const removeEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n keyPath: KeyPath[]\n ) => {\n setEditedContentState((prev) => {\n // Retrieve the original content as reference\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n // Get the initial value from the original dictionary content\n const initialContent = getContentNodeByKeyPath(originalContent, keyPath);\n\n // Restore the value at the given keyPath\n const restoredContent = editDictionaryByKeyPath(\n currentContent,\n keyPath,\n initialContent\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: restoredContent as Dictionary['content'],\n },\n };\n });\n };\n\n const restoreEditedContent = (dictionaryLocalId: LocalDictionaryId) => {\n setEditedContentState((prev) => {\n const updated = { ...prev };\n delete updated[dictionaryLocalId];\n return updated;\n });\n };\n\n const clearEditedDictionaryContent = (\n dictionaryLocalId: LocalDictionaryId\n ) => {\n setEditedContentState((prev) => {\n const filtered = Object.entries(prev).reduce((acc, [key, value]) => {\n if (key === dictionaryLocalId) {\n return acc;\n }\n return { ...acc, [key]: value };\n }, {} as DictionaryContent);\n return filtered;\n });\n };\n\n const clearEditedContent = () => {\n setEditedContentState({});\n };\n\n const getEditedContentValue = (\n localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string,\n keyPath: KeyPath[]\n ): ContentNode | undefined => {\n if (!editedContent) return undefined;\n\n const isDictionaryId =\n localDictionaryIdOrKey.includes(':local:') ||\n localDictionaryIdOrKey.includes(':remote:');\n\n if (isDictionaryId) {\n const currentContent =\n editedContent?.[localDictionaryIdOrKey as LocalDictionaryId]?.content ??\n {};\n\n const contentNode = getContentNodeByKeyPath(currentContent, keyPath);\n\n return contentNode;\n }\n\n const filteredDictionariesLocalId = Object.keys(editedContent).filter(\n (key) => key.startsWith(`${localDictionaryIdOrKey}:`)\n );\n\n for (const localDictionaryId of filteredDictionariesLocalId) {\n const currentContent =\n editedContent?.[localDictionaryId as LocalDictionaryId]?.content ?? {};\n const contentNode = getContentNodeByKeyPath(currentContent, keyPath);\n\n if (contentNode) return contentNode;\n }\n\n return undefined;\n };\n\n return (\n <EditedContentStateContext.Provider\n value={{\n editedContent,\n }}\n >\n <EditedContentActionsContext.Provider\n value={{\n setEditedContentState,\n setEditedDictionary,\n setEditedContent,\n addEditedContent,\n renameEditedContent,\n removeEditedContent,\n restoreEditedContent,\n clearEditedDictionaryContent,\n clearEditedContent,\n getEditedContentValue,\n }}\n >\n {children}\n </EditedContentActionsContext.Provider>\n </EditedContentStateContext.Provider>\n );\n};\n\nexport const useEditedContentActions = () =>\n useContext(EditedContentActionsContext);\n\nexport const useEditedContent = () => {\n const stateContext = useContext(EditedContentStateContext);\n const actionContext = useEditedContentActions();\n\n return { ...stateContext, ...actionContext };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EditedContentContext.mjs","names":["EditedContentProvider: FC<PropsWithChildren>","setEditedDictionary: Dispatch<SetStateAction<Dictionary>>","updatedDictionaries: Dictionary","lastKeyPath: KeyPath"],"sources":["../../../src/editor/EditedContentContext.tsx"],"sourcesContent":["'use client';\n\nimport {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core';\nimport { MessageKey } from '@intlayer/editor';\nimport {\n type ContentNode,\n type Dictionary,\n type KeyPath,\n type LocalDictionaryId,\n NodeType,\n} from '@intlayer/types';\nimport {\n createContext,\n type Dispatch,\n type FC,\n type PropsWithChildren,\n type SetStateAction,\n useContext,\n} from 'preact/compat';\nimport {\n type DictionaryContent,\n useDictionariesRecord,\n} from './DictionariesRecordContext';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\nimport { useCrossFrameState } from './useCrossFrameState';\n\ntype EditedContentStateContextType = {\n editedContent: Record<LocalDictionaryId, Dictionary> | undefined;\n};\n\nconst EditedContentStateContext = createContext<\n EditedContentStateContextType | undefined\n>(undefined);\n\nexport const usePostEditedContentState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/post`,\n onEventTriggered\n );\n\nexport const useGetEditedContentState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/get`,\n onEventTriggered\n );\n\ntype EditedContentActionsContextType = {\n setEditedContentState: (\n editedContent: Record<LocalDictionaryId, Dictionary>\n ) => void;\n setEditedDictionary: Dispatch<SetStateAction<Dictionary>>;\n setEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newValue: Dictionary['content']\n ) => void;\n addEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newValue: ContentNode<any>,\n keyPath?: KeyPath[],\n overwrite?: boolean\n ) => void;\n renameEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath?: KeyPath[]\n ) => void;\n removeEditedContent: (\n dictionaryLocalId: LocalDictionaryId,\n keyPath: KeyPath[]\n ) => void;\n restoreEditedContent: (dictionaryLocalId: LocalDictionaryId) => void;\n clearEditedDictionaryContent: (dictionaryLocalId: LocalDictionaryId) => void;\n clearEditedContent: () => void;\n getEditedContentValue: (\n localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string,\n keyPath: KeyPath[]\n ) => ContentNode | undefined;\n};\n\nconst EditedContentActionsContext = createContext<\n EditedContentActionsContextType | undefined\n>(undefined);\n\nconst resolveState = <S,>(state?: SetStateAction<S>, prevState?: S): S =>\n typeof state === 'function'\n ? (state as (prevState?: S) => S)(prevState)\n : (state as S);\n\nexport const EditedContentProvider: FC<PropsWithChildren> = ({ children }) => {\n const { localeDictionaries } = useDictionariesRecord();\n\n const [editedContent, setEditedContentState] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED\n );\n\n const setEditedDictionary: Dispatch<SetStateAction<Dictionary>> = (\n newValue\n ) => {\n let updatedDictionaries: Dictionary = resolveState(newValue);\n\n setEditedContentState((prev) => {\n updatedDictionaries = resolveState(\n newValue,\n prev?.[updatedDictionaries.key]\n );\n\n return {\n ...prev,\n [updatedDictionaries.key]: updatedDictionaries,\n };\n });\n\n return updatedDictionaries;\n };\n\n const setEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newValue: Dictionary['content']\n ) => {\n setEditedContentState((prev) => ({\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: newValue,\n },\n }));\n };\n\n const addEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newValue: ContentNode,\n keyPath: KeyPath[] = [],\n overwrite: boolean = true\n ) => {\n setEditedContentState((prev) => {\n // Get the starting content: edited version if available, otherwise a deep copy of the original\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n let newKeyPath = keyPath;\n if (!overwrite) {\n // Find a unique key based on the keyPath provided\n let index = 0;\n const otherKeyPath = keyPath.slice(0, -1);\n const lastKeyPath: KeyPath = keyPath[keyPath.length - 1];\n let finalKey = lastKeyPath.key;\n\n // Loop until we find a key that does not exist\n while (\n typeof getContentNodeByKeyPath(currentContent, newKeyPath) !==\n 'undefined'\n ) {\n index++;\n finalKey =\n index === 0 ? lastKeyPath.key : `${lastKeyPath.key} (${index})`;\n newKeyPath = [\n ...otherKeyPath,\n { ...lastKeyPath, key: finalKey } as KeyPath,\n ];\n }\n }\n\n const updatedContent = editDictionaryByKeyPath(\n currentContent,\n newKeyPath,\n newValue\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: updatedContent as Dictionary['content'],\n },\n };\n });\n };\n\n const renameEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath: KeyPath[] = []\n ) => {\n setEditedContentState((prev) => {\n // Retrieve the base content: use edited version if available, otherwise deep copy of original\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n const contentWithNewField = renameContentNodeByKeyPath(\n currentContent,\n newKey,\n keyPath\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: contentWithNewField as Dictionary['content'],\n },\n };\n });\n };\n\n const removeEditedContent = (\n dictionaryLocalId: LocalDictionaryId,\n keyPath: KeyPath[]\n ) => {\n setEditedContentState((prev) => {\n // Retrieve the original content as reference\n const originalContent = localeDictionaries[dictionaryLocalId]?.content;\n const currentContent = structuredClone(\n prev?.[dictionaryLocalId]?.content ?? originalContent\n );\n\n // Get the initial value from the original dictionary content\n const initialContent = getContentNodeByKeyPath(originalContent, keyPath);\n\n // Restore the value at the given keyPath\n const restoredContent = editDictionaryByKeyPath(\n currentContent,\n keyPath,\n initialContent\n );\n\n return {\n ...prev,\n [dictionaryLocalId]: {\n ...prev?.[dictionaryLocalId],\n content: restoredContent as Dictionary['content'],\n },\n };\n });\n };\n\n const restoreEditedContent = (dictionaryLocalId: LocalDictionaryId) => {\n setEditedContentState((prev) => {\n const updated = { ...prev };\n delete updated[dictionaryLocalId];\n return updated;\n });\n };\n\n const clearEditedDictionaryContent = (\n dictionaryLocalId: LocalDictionaryId\n ) => {\n setEditedContentState((prev) => {\n const filtered = Object.entries(prev).reduce((acc, [key, value]) => {\n if (key === dictionaryLocalId) {\n return acc;\n }\n return { ...acc, [key]: value };\n }, {} as DictionaryContent);\n return filtered;\n });\n };\n\n const clearEditedContent = () => {\n setEditedContentState({});\n };\n\n const getEditedContentValue = (\n localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string,\n keyPath: KeyPath[]\n ): ContentNode | undefined => {\n if (!editedContent) return undefined;\n\n const filteredKeyPath = keyPath.filter(\n (key) => key.type !== NodeType.Translation\n );\n\n const isDictionaryId =\n localDictionaryIdOrKey.includes(':local:') ||\n localDictionaryIdOrKey.includes(':remote:');\n\n if (isDictionaryId) {\n const currentContent =\n editedContent?.[localDictionaryIdOrKey as LocalDictionaryId]?.content ??\n {};\n\n const contentNode = getContentNodeByKeyPath(\n currentContent,\n filteredKeyPath\n );\n\n return contentNode;\n }\n\n const filteredDictionariesLocalId = Object.keys(editedContent).filter(\n (key) => key.startsWith(`${localDictionaryIdOrKey}:`)\n );\n\n for (const localDictionaryId of filteredDictionariesLocalId) {\n const currentContent =\n editedContent?.[localDictionaryId as LocalDictionaryId]?.content ?? {};\n const contentNode = getContentNodeByKeyPath(\n currentContent,\n filteredKeyPath\n );\n\n if (contentNode) return contentNode;\n }\n\n return undefined;\n };\n\n return (\n <EditedContentStateContext.Provider\n value={{\n editedContent,\n }}\n >\n <EditedContentActionsContext.Provider\n value={{\n setEditedContentState,\n setEditedDictionary,\n setEditedContent,\n addEditedContent,\n renameEditedContent,\n removeEditedContent,\n restoreEditedContent,\n clearEditedDictionaryContent,\n clearEditedContent,\n getEditedContentValue,\n }}\n >\n {children}\n </EditedContentActionsContext.Provider>\n </EditedContentStateContext.Provider>\n );\n};\n\nexport const useEditedContentActions = () =>\n useContext(EditedContentActionsContext);\n\nexport const useEditedContent = () => {\n const stateContext = useContext(EditedContentStateContext);\n const actionContext = useEditedContentActions();\n\n return { ...stateContext, ...actionContext };\n};\n"],"mappings":"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"}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
import { CommunicatorProvider } from "./CommunicatorContext.mjs";
|
|
5
|
+
import { DictionariesRecordProvider } from "./DictionariesRecordContext.mjs";
|
|
5
6
|
import { EditorEnabledProvider, useEditorEnabled, useGetEditorEnabledState } from "./EditorEnabledContext.mjs";
|
|
6
7
|
import { ConfigurationProvider } from "./ConfigurationContext.mjs";
|
|
7
|
-
import { DictionariesRecordProvider } from "./DictionariesRecordContext.mjs";
|
|
8
8
|
import { EditedContentProvider, useGetEditedContentState } from "./EditedContentContext.mjs";
|
|
9
9
|
import { FocusDictionaryProvider } from "./FocusDictionaryContext.mjs";
|
|
10
10
|
import { useEffect, useState } from "preact/compat";
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
import { useDictionariesRecordActions } from "./DictionariesRecordContext.mjs";
|
|
4
5
|
import { useEditorEnabled } from "./EditorEnabledContext.mjs";
|
|
5
6
|
import { EditorProvider } from "./EditorProvider.mjs";
|
|
6
7
|
import { useCrossURLPathSetter } from "./useCrossURLPathState.mjs";
|
|
7
8
|
import { useIframeClickInterceptor } from "./useIframeClickInterceptor.mjs";
|
|
9
|
+
import { useEffect } from "preact/compat";
|
|
8
10
|
import configuration from "@intlayer/config/built";
|
|
11
|
+
import { getUnmergedDictionaries } from "@intlayer/unmerged-dictionaries-entry";
|
|
9
12
|
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
10
13
|
|
|
11
14
|
//#region src/editor/IntlayerEditorProvider.tsx
|
|
@@ -18,6 +21,15 @@ const IntlayerEditorHooksEnabled = () => {
|
|
|
18
21
|
* Click Messages
|
|
19
22
|
*/
|
|
20
23
|
useIframeClickInterceptor();
|
|
24
|
+
/**
|
|
25
|
+
* Sent local dictionaries to editor
|
|
26
|
+
*/
|
|
27
|
+
const { setLocaleDictionaries } = useDictionariesRecordActions() ?? {};
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const unmergedDictionaries = getUnmergedDictionaries();
|
|
30
|
+
const dictionariesList = Object.fromEntries(Object.values(unmergedDictionaries).flat().map((dictionary) => [dictionary.localId, dictionary]));
|
|
31
|
+
setLocaleDictionaries?.(dictionariesList);
|
|
32
|
+
}, []);
|
|
21
33
|
return /* @__PURE__ */ jsx(Fragment, {});
|
|
22
34
|
};
|
|
23
35
|
const { editor } = configuration;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntlayerEditorProvider.mjs","names":["IntlayerEditorHooksEnabled: FunctionComponent","IntlayerEditorHook: FunctionComponent","IntlayerEditorProvider: FunctionComponent<{\n children?: ComponentChildren;\n}>"],"sources":["../../../src/editor/IntlayerEditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport type { ComponentChildren, FunctionComponent } from 'preact';\nimport { useEditorEnabled } from './EditorEnabledContext';\nimport { EditorProvider } from './EditorProvider';\nimport { useCrossURLPathSetter } from './useCrossURLPathState';\nimport { useIframeClickInterceptor } from './useIframeClickInterceptor';\n\nconst IntlayerEditorHooksEnabled: FunctionComponent = () => {\n /**\n * URL Messages\n */\n useCrossURLPathSetter();\n\n /**\n * Click Messages\n */\n useIframeClickInterceptor();\n\n return <></>;\n};\n\nconst { editor } = configuration;\n\nconst IntlayerEditorHook: FunctionComponent = () => {\n const { enabled } = useEditorEnabled();\n\n return enabled ? <IntlayerEditorHooksEnabled /> : <></>;\n};\n\nexport const IntlayerEditorProvider: FunctionComponent<{\n children?: ComponentChildren;\n}> = ({ children }) => {\n return (\n <EditorProvider\n postMessage={(data: any) => {\n if (typeof window === 'undefined') return;\n\n const isInIframe = window.self !== window.top;\n if (!isInIframe) return;\n\n if (editor.applicationURL.length > 0) {\n window?.postMessage(\n data,\n // Use to restrict the origin of the editor for security reasons.\n // Correspond to the current application URL to synchronize the locales states.\n editor.applicationURL\n );\n }\n\n if (editor.editorURL.length > 0) {\n window.parent?.postMessage(\n data,\n // Use to restrict the origin of the editor for security reasons.\n // Correspond to the editor URL to synchronize the locales states.\n editor.editorURL\n );\n }\n\n if (editor.cmsURL.length > 0) {\n window.parent?.postMessage(\n data,\n // Use to restrict the origin of the CMS for security reasons.\n // Correspond to the CMS URL.\n editor.cmsURL\n );\n }\n }}\n allowedOrigins={[\n editor?.editorURL,\n editor?.cmsURL,\n editor?.applicationURL,\n ]}\n configuration={configuration}\n >\n <IntlayerEditorHook />\n {children}\n </EditorProvider>\n );\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"IntlayerEditorProvider.mjs","names":["IntlayerEditorHooksEnabled: FunctionComponent","IntlayerEditorHook: FunctionComponent","IntlayerEditorProvider: FunctionComponent<{\n children?: ComponentChildren;\n}>"],"sources":["../../../src/editor/IntlayerEditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport type { ComponentChildren, FunctionComponent } from 'preact';\nimport { useEffect } from 'preact/compat';\nimport { useDictionariesRecordActions } from './DictionariesRecordContext';\nimport { useEditorEnabled } from './EditorEnabledContext';\nimport { EditorProvider } from './EditorProvider';\nimport { useCrossURLPathSetter } from './useCrossURLPathState';\nimport { useIframeClickInterceptor } from './useIframeClickInterceptor';\n\nconst IntlayerEditorHooksEnabled: FunctionComponent = () => {\n /**\n * URL Messages\n */\n useCrossURLPathSetter();\n\n /**\n * Click Messages\n */\n useIframeClickInterceptor();\n\n /**\n * Sent local dictionaries to editor\n */\n const { setLocaleDictionaries } = useDictionariesRecordActions() ?? {};\n\n useEffect(() => {\n const unmergedDictionaries = getUnmergedDictionaries();\n const dictionariesList = Object.fromEntries(\n Object.values(unmergedDictionaries)\n .flat()\n .map((dictionary) => [dictionary.localId, dictionary])\n );\n\n setLocaleDictionaries?.(dictionariesList);\n }, []);\n\n return <></>;\n};\n\nconst { editor } = configuration;\n\nconst IntlayerEditorHook: FunctionComponent = () => {\n const { enabled } = useEditorEnabled();\n\n return enabled ? <IntlayerEditorHooksEnabled /> : <></>;\n};\n\nexport const IntlayerEditorProvider: FunctionComponent<{\n children?: ComponentChildren;\n}> = ({ children }) => {\n return (\n <EditorProvider\n postMessage={(data: any) => {\n if (typeof window === 'undefined') return;\n\n const isInIframe = window.self !== window.top;\n if (!isInIframe) return;\n\n if (editor.applicationURL.length > 0) {\n window?.postMessage(\n data,\n // Use to restrict the origin of the editor for security reasons.\n // Correspond to the current application URL to synchronize the locales states.\n editor.applicationURL\n );\n }\n\n if (editor.editorURL.length > 0) {\n window.parent?.postMessage(\n data,\n // Use to restrict the origin of the editor for security reasons.\n // Correspond to the editor URL to synchronize the locales states.\n editor.editorURL\n );\n }\n\n if (editor.cmsURL.length > 0) {\n window.parent?.postMessage(\n data,\n // Use to restrict the origin of the CMS for security reasons.\n // Correspond to the CMS URL.\n editor.cmsURL\n );\n }\n }}\n allowedOrigins={[\n editor?.editorURL,\n editor?.cmsURL,\n editor?.applicationURL,\n ]}\n configuration={configuration}\n >\n <IntlayerEditorHook />\n {children}\n </EditorProvider>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AAYA,MAAMA,mCAAsD;;;;AAI1D,wBAAuB;;;;AAKvB,4BAA2B;;;;CAK3B,MAAM,EAAE,0BAA0B,8BAA8B,IAAI,EAAE;AAEtE,iBAAgB;EACd,MAAM,uBAAuB,yBAAyB;EACtD,MAAM,mBAAmB,OAAO,YAC9B,OAAO,OAAO,qBAAqB,CAChC,MAAM,CACN,KAAK,eAAe,CAAC,WAAW,SAAS,WAAW,CAAC,CACzD;AAED,0BAAwB,iBAAiB;IACxC,EAAE,CAAC;AAEN,QAAO,iCAAK;;AAGd,MAAM,EAAE,WAAW;AAEnB,MAAMC,2BAA8C;CAClD,MAAM,EAAE,YAAY,kBAAkB;AAEtC,QAAO,UAAU,oBAAC,+BAA6B,GAAG,iCAAK;;AAGzD,MAAaC,0BAEP,EAAE,eAAe;AACrB,QACE,qBAAC;EACC,cAAc,SAAc;AAC1B,OAAI,OAAO,WAAW,YAAa;AAGnC,OAAI,EADe,OAAO,SAAS,OAAO,KACzB;AAEjB,OAAI,OAAO,eAAe,SAAS,EACjC,SAAQ,YACN,MAGA,OAAO,eACR;AAGH,OAAI,OAAO,UAAU,SAAS,EAC5B,QAAO,QAAQ,YACb,MAGA,OAAO,UACR;AAGH,OAAI,OAAO,OAAO,SAAS,EACzB,QAAO,QAAQ,YACb,MAGA,OAAO,OACR;;EAGL,gBAAgB;GACd,QAAQ;GACR,QAAQ;GACR,QAAQ;GACT;EACc;aAEf,oBAAC,uBAAqB,EACrB;GACc"}
|
|
@@ -38,7 +38,12 @@ const useCrossFrameMessageListener = (key, onEventTriggered, revalidator) => {
|
|
|
38
38
|
const { type, data, senderId: msgSenderId } = event.data;
|
|
39
39
|
if (type !== key) return;
|
|
40
40
|
if (msgSenderId === senderId) return;
|
|
41
|
-
if (typeof allowedOrigins === "undefined" || allowedOrigins?.
|
|
41
|
+
if (typeof allowedOrigins === "undefined" || allowedOrigins?.filter((url) => ![
|
|
42
|
+
null,
|
|
43
|
+
void 0,
|
|
44
|
+
"",
|
|
45
|
+
"*"
|
|
46
|
+
].includes(url)).some((url) => compareUrls(url, event.origin)) || allowedOrigins?.includes("*")) onEventTriggered(data);
|
|
42
47
|
};
|
|
43
48
|
window.addEventListener("message", handleMessage);
|
|
44
49
|
return () => window.removeEventListener("message", handleMessage);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCrossFrameMessageListener.mjs","names":["postMessageWrapper: (data?: S) => void"],"sources":["../../../src/editor/useCrossFrameMessageListener.tsx"],"sourcesContent":["'use client';\n\nimport { compareUrls, type MessageKey } from '@intlayer/editor';\nimport { useEffect } from 'preact/hooks';\nimport { useCommunicator } from './CommunicatorContext';\n\n/**\n * useCrossFrameMessageListener\n *\n * This React hook listens for messages sent via the `postMessage` API and triggers a callback\n * whenever a message of the specified type (`key`) is received. It is useful for synchronizing\n * state or events across different windows, iframes, or contexts.\n *\n * @template S - The type of the data payload in the message.\n * @param key - A unique identifier for the message type to listen for.\n * @param [onEventTriggered] - A callback function triggered when a message\n * @param [revalidator] - A function that re-suscribes the listener. Could be usefull if onEventTriggered depend of some state\n * with the specified key is received. The callback receives the message data as its argument.\n *\n * @returns {{ postMessage: (data: S) => void }} An object containing a `postMessage` function\n * that allows broadcasting messages with the specified key and data.\n */\nexport const useCrossFrameMessageListener = <S,>(\n key: `${MessageKey}` | `${MessageKey}/post` | `${MessageKey}/get`,\n onEventTriggered?: (data: S) => void,\n revalidator?: any\n) => {\n const { allowedOrigins, postMessage, senderId } = useCommunicator();\n\n useEffect(() => {\n if (onEventTriggered) {\n /**\n * Message handler to process incoming messages.\n *\n * - **Message Filtering:** Ensures only messages with the specified `key` are processed.\n * - **Origin Validation:** Checks that the origin of the message is within the allowed origins.\n *\n * @param {MessageEvent<{ type: string; data: S }>} event - The incoming message event object.\n */\n const handleMessage = (\n event: MessageEvent<{ type: string; data: S; senderId: string }>\n ) => {\n const { type, data, senderId: msgSenderId } = event.data;\n\n // Ignore messages that do not match the current key\n if (type !== key) return;\n\n // Ignore messages from myself\n if (msgSenderId === senderId) return;\n\n // Check if the message origin is allowed\n if (\n typeof allowedOrigins === 'undefined' ||\n allowedOrigins?.some((url) => compareUrls(url, event.origin)) ||\n allowedOrigins?.includes('*')\n ) {\n // Update the local state with the received data\n onEventTriggered(data);\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n // Clean up the event listener on unmount\n return () => window.removeEventListener('message', handleMessage);\n }\n }, [allowedOrigins, postMessage, senderId, revalidator]);\n\n /**\n * A wrapper function around the `postMessage` function to broadcast messages efficiently.\n *\n * - **Encapsulation:** Ensures the `postMessage` function is scoped to the provided key.\n * - **Ease of Use:** Simplifies broadcasting messages with consistent type and format.\n *\n * @param {S} data - The data payload to include in the message.\n * @returns {void}\n */\n const postMessageWrapper: (data?: S) => void = (data) => {\n postMessage({ type: key, data, senderId });\n };\n\n return postMessageWrapper;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,gCACX,KACA,kBACA,gBACG;CACH,MAAM,EAAE,gBAAgB,aAAa,aAAa,iBAAiB;AAEnE,iBAAgB;AACd,MAAI,kBAAkB;;;;;;;;;GASpB,MAAM,iBACJ,UACG;IACH,MAAM,EAAE,MAAM,MAAM,UAAU,gBAAgB,MAAM;AAGpD,QAAI,SAAS,IAAK;AAGlB,QAAI,gBAAgB,SAAU;AAG9B,QACE,OAAO,mBAAmB,eAC1B,
|
|
1
|
+
{"version":3,"file":"useCrossFrameMessageListener.mjs","names":["postMessageWrapper: (data?: S) => void"],"sources":["../../../src/editor/useCrossFrameMessageListener.tsx"],"sourcesContent":["'use client';\n\nimport { compareUrls, type MessageKey } from '@intlayer/editor';\nimport { useEffect } from 'preact/hooks';\nimport { useCommunicator } from './CommunicatorContext';\n\n/**\n * useCrossFrameMessageListener\n *\n * This React hook listens for messages sent via the `postMessage` API and triggers a callback\n * whenever a message of the specified type (`key`) is received. It is useful for synchronizing\n * state or events across different windows, iframes, or contexts.\n *\n * @template S - The type of the data payload in the message.\n * @param key - A unique identifier for the message type to listen for.\n * @param [onEventTriggered] - A callback function triggered when a message\n * @param [revalidator] - A function that re-suscribes the listener. Could be usefull if onEventTriggered depend of some state\n * with the specified key is received. The callback receives the message data as its argument.\n *\n * @returns {{ postMessage: (data: S) => void }} An object containing a `postMessage` function\n * that allows broadcasting messages with the specified key and data.\n */\nexport const useCrossFrameMessageListener = <S,>(\n key: `${MessageKey}` | `${MessageKey}/post` | `${MessageKey}/get`,\n onEventTriggered?: (data: S) => void,\n revalidator?: any\n) => {\n const { allowedOrigins, postMessage, senderId } = useCommunicator();\n\n useEffect(() => {\n if (onEventTriggered) {\n /**\n * Message handler to process incoming messages.\n *\n * - **Message Filtering:** Ensures only messages with the specified `key` are processed.\n * - **Origin Validation:** Checks that the origin of the message is within the allowed origins.\n *\n * @param {MessageEvent<{ type: string; data: S }>} event - The incoming message event object.\n */\n const handleMessage = (\n event: MessageEvent<{ type: string; data: S; senderId: string }>\n ) => {\n const { type, data, senderId: msgSenderId } = event.data;\n\n // Ignore messages that do not match the current key\n if (type !== key) return;\n\n // Ignore messages from myself\n if (msgSenderId === senderId) return;\n\n // Check if the message origin is allowed\n if (\n typeof allowedOrigins === 'undefined' ||\n allowedOrigins\n ?.filter((url) => ![null, undefined, '', '*'].includes(url))\n .some((url) => compareUrls(url, event.origin)) ||\n allowedOrigins?.includes('*')\n ) {\n // Update the local state with the received data\n onEventTriggered(data);\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n // Clean up the event listener on unmount\n return () => window.removeEventListener('message', handleMessage);\n }\n }, [allowedOrigins, postMessage, senderId, revalidator]);\n\n /**\n * A wrapper function around the `postMessage` function to broadcast messages efficiently.\n *\n * - **Encapsulation:** Ensures the `postMessage` function is scoped to the provided key.\n * - **Ease of Use:** Simplifies broadcasting messages with consistent type and format.\n *\n * @param {S} data - The data payload to include in the message.\n * @returns {void}\n */\n const postMessageWrapper: (data?: S) => void = (data) => {\n postMessage({ type: key, data, senderId });\n };\n\n return postMessageWrapper;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,gCACX,KACA,kBACA,gBACG;CACH,MAAM,EAAE,gBAAgB,aAAa,aAAa,iBAAiB;AAEnE,iBAAgB;AACd,MAAI,kBAAkB;;;;;;;;;GASpB,MAAM,iBACJ,UACG;IACH,MAAM,EAAE,MAAM,MAAM,UAAU,gBAAgB,MAAM;AAGpD,QAAI,SAAS,IAAK;AAGlB,QAAI,gBAAgB,SAAU;AAG9B,QACE,OAAO,mBAAmB,eAC1B,gBACI,QAAQ,QAAQ,CAAC;KAAC;KAAM;KAAW;KAAI;KAAI,CAAC,SAAS,IAAI,CAAC,CAC3D,MAAM,QAAQ,YAAY,KAAK,MAAM,OAAO,CAAC,IAChD,gBAAgB,SAAS,IAAI,CAG7B,kBAAiB,KAAK;;AAI1B,UAAO,iBAAiB,WAAW,cAAc;AAGjD,gBAAa,OAAO,oBAAoB,WAAW,cAAc;;IAElE;EAAC;EAAgB;EAAa;EAAU;EAAY,CAAC;;;;;;;;;;CAWxD,MAAMA,sBAA0C,SAAS;AACvD,cAAY;GAAE,MAAM;GAAK;GAAM;GAAU,CAAC;;AAG5C,QAAO"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _intlayer_types0 from "@intlayer/types";
|
|
2
2
|
|
|
3
3
|
//#region src/client/format/useCompact.d.ts
|
|
4
4
|
|
|
@@ -13,7 +13,7 @@ import * as _intlayer_types13 from "@intlayer/types";
|
|
|
13
13
|
* ```
|
|
14
14
|
*/
|
|
15
15
|
declare const useCompact: () => (value: string | number, options?: Intl.NumberFormatOptions & {
|
|
16
|
-
locale?:
|
|
16
|
+
locale?: _intlayer_types0.LocalesValues;
|
|
17
17
|
}) => string;
|
|
18
18
|
//#endregion
|
|
19
19
|
export { useCompact };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCompact.d.ts","names":[],"sources":["../../../../src/client/format/useCompact.ts"],"sourcesContent":[],"mappings":";;;;;;;AAgBA;;;;;;;cAAa,qDAAU,IAAA,CAAA;WAAA,
|
|
1
|
+
{"version":3,"file":"useCompact.d.ts","names":[],"sources":["../../../../src/client/format/useCompact.ts"],"sourcesContent":[],"mappings":";;;;;;;AAgBA;;;;;;;cAAa,qDAAU,IAAA,CAAA;WAAA,gBAAA,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _intlayer_types1 from "@intlayer/types";
|
|
2
2
|
|
|
3
3
|
//#region src/client/format/useCurrency.d.ts
|
|
4
4
|
|
|
@@ -27,7 +27,7 @@ import * as _intlayer_types18 from "@intlayer/types";
|
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
29
|
declare const useCurrency: () => (value: string | number, options?: Intl.NumberFormatOptions & {
|
|
30
|
-
locale?:
|
|
30
|
+
locale?: _intlayer_types1.LocalesValues;
|
|
31
31
|
}) => string;
|
|
32
32
|
//#endregion
|
|
33
33
|
export { useCurrency };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCurrency.d.ts","names":[],"sources":["../../../../src/client/format/useCurrency.ts"],"sourcesContent":[],"mappings":";;;;;;;AA8BA;;;;;;;;;;;;;;;;;;;;;cAAa,sDAAW,IAAA,CAAA;WAAA,
|
|
1
|
+
{"version":3,"file":"useCurrency.d.ts","names":[],"sources":["../../../../src/client/format/useCurrency.ts"],"sourcesContent":[],"mappings":";;;;;;;AA8BA;;;;;;;;;;;;;;;;;;;;;cAAa,sDAAW,IAAA,CAAA;WAAA,gBAAA,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _intlayer_types17 from "@intlayer/types";
|
|
2
2
|
|
|
3
3
|
//#region src/client/format/useList.d.ts
|
|
4
4
|
|
|
@@ -24,7 +24,7 @@ import * as _intlayer_types15 from "@intlayer/types";
|
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
|
26
26
|
declare const useList: () => (values: (string | number)[], options?: Intl.ListFormatOptions & {
|
|
27
|
-
locale?:
|
|
27
|
+
locale?: _intlayer_types17.LocalesValues;
|
|
28
28
|
}) => string;
|
|
29
29
|
//#endregion
|
|
30
30
|
export { useList };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _intlayer_types16 from "@intlayer/types";
|
|
2
2
|
|
|
3
3
|
//#region src/client/format/useNumber.d.ts
|
|
4
4
|
|
|
@@ -25,7 +25,7 @@ import * as _intlayer_types14 from "@intlayer/types";
|
|
|
25
25
|
* A number formatting function bound to the active locale.
|
|
26
26
|
*/
|
|
27
27
|
declare const useNumber: () => (value: string | number, options?: Intl.NumberFormatOptions & {
|
|
28
|
-
locale?:
|
|
28
|
+
locale?: _intlayer_types16.LocalesValues;
|
|
29
29
|
}) => string;
|
|
30
30
|
//#endregion
|
|
31
31
|
export { useNumber };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _intlayer_types2 from "@intlayer/types";
|
|
2
2
|
|
|
3
3
|
//#region src/client/format/usePercentage.d.ts
|
|
4
4
|
|
|
@@ -21,7 +21,7 @@ import * as _intlayer_types17 from "@intlayer/types";
|
|
|
21
21
|
* A function that formats numbers or numeric strings into localized percentages.
|
|
22
22
|
*/
|
|
23
23
|
declare const usePercentage: () => (value: string | number, options?: Intl.NumberFormatOptions & {
|
|
24
|
-
locale?:
|
|
24
|
+
locale?: _intlayer_types2.LocalesValues;
|
|
25
25
|
}) => string;
|
|
26
26
|
//#endregion
|
|
27
27
|
export { usePercentage };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePercentage.d.ts","names":[],"sources":["../../../../src/client/format/usePercentage.ts"],"sourcesContent":[],"mappings":";;;;;;;AAwBA;;;;;;;;;;;;;;;cAAa,wDAAa,IAAA,CAAA;WAAA,
|
|
1
|
+
{"version":3,"file":"usePercentage.d.ts","names":[],"sources":["../../../../src/client/format/usePercentage.ts"],"sourcesContent":[],"mappings":";;;;;;;AAwBA;;;;;;;;;;;;;;;cAAa,wDAAa,IAAA,CAAA;WAAA,gBAAA,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _intlayer_types3 from "@intlayer/types";
|
|
2
2
|
|
|
3
3
|
//#region src/client/format/useRelativeTime.d.ts
|
|
4
4
|
|
|
@@ -21,7 +21,7 @@ import * as _intlayer_types16 from "@intlayer/types";
|
|
|
21
21
|
* bound to the current client locale.
|
|
22
22
|
*/
|
|
23
23
|
declare const useRelativeTime: () => (from: string | number | Date, to?: string | number | Date, options?: Intl.RelativeTimeFormatOptions & {
|
|
24
|
-
locale?:
|
|
24
|
+
locale?: _intlayer_types3.LocalesValues;
|
|
25
25
|
unit?: Intl.RelativeTimeFormatUnit;
|
|
26
26
|
}) => string;
|
|
27
27
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRelativeTime.d.ts","names":[],"sources":["../../../../src/client/format/useRelativeTime.ts"],"sourcesContent":[],"mappings":";;;;;;;AAwBA;;;;;;;;;;;;;;;cAAa,gDAAe,6BAAA,gBAAA,IAAA,CAAA;WAAA,
|
|
1
|
+
{"version":3,"file":"useRelativeTime.d.ts","names":[],"sources":["../../../../src/client/format/useRelativeTime.ts"],"sourcesContent":[],"mappings":";;;;;;;AAwBA;;;;;;;;;;;;;;;cAAa,gDAAe,6BAAA,gBAAA,IAAA,CAAA;WAAA,gBAAA,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _intlayer_types0 from "@intlayer/types";
|
|
2
2
|
|
|
3
3
|
//#region src/client/format/useUnit.d.ts
|
|
4
4
|
|
|
@@ -20,7 +20,7 @@ import * as _intlayer_types12 from "@intlayer/types";
|
|
|
20
20
|
* @returns {Function} A unit formatting function that accepts a value and optional formatting options.
|
|
21
21
|
*/
|
|
22
22
|
declare const useUnit: () => (value: string | number, options?: Intl.NumberFormatOptions & {
|
|
23
|
-
locale?:
|
|
23
|
+
locale?: _intlayer_types0.LocalesValues;
|
|
24
24
|
}) => string;
|
|
25
25
|
//#endregion
|
|
26
26
|
export { useUnit };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUnit.d.ts","names":[],"sources":["../../../../src/client/format/useUnit.ts"],"sourcesContent":[],"mappings":";;;;;;;AAuBA;;;;;;;;;;;;;;cAAa,kDAAO,IAAA,CAAA;WAAA,
|
|
1
|
+
{"version":3,"file":"useUnit.d.ts","names":[],"sources":["../../../../src/client/format/useUnit.ts"],"sourcesContent":[],"mappings":";;;;;;;AAuBA;;;;;;;;;;;;;;cAAa,kDAAO,IAAA,CAAA;WAAA,gBAAA,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _intlayer_types15 from "@intlayer/types";
|
|
2
2
|
import { StrictModeLocaleMap } from "@intlayer/types";
|
|
3
3
|
|
|
4
4
|
//#region src/client/useContent.d.ts
|
|
@@ -6,7 +6,7 @@ import { StrictModeLocaleMap } from "@intlayer/types";
|
|
|
6
6
|
* On the client side, hook to get the translation content based on the locale
|
|
7
7
|
*/
|
|
8
8
|
declare const useContent: <Content>(languageContent: StrictModeLocaleMap<Content>) => {
|
|
9
|
-
locale:
|
|
9
|
+
locale: _intlayer_types15.LocalesValues;
|
|
10
10
|
content: Content;
|
|
11
11
|
t: <Content_1 = string>(languageContent: StrictModeLocaleMap<Content_1>) => Content_1;
|
|
12
12
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useContent.d.ts","names":[],"sources":["../../../src/client/useContent.ts"],"sourcesContent":[],"mappings":";;;;;;;AAOa,cAAA,UAYZ,EAAA,CAAA,OAAA,CAAA,CAAA,eAAA,EAXkB,mBAWlB,CAXsC,OAWtC,CAAA,EAAA,GAAA;EAXsC,MAAA,EAAD,
|
|
1
|
+
{"version":3,"file":"useContent.d.ts","names":[],"sources":["../../../src/client/useContent.ts"],"sourcesContent":[],"mappings":";;;;;;;AAOa,cAAA,UAYZ,EAAA,CAAA,OAAA,CAAA,CAAA,eAAA,EAXkB,mBAWlB,CAXsC,OAWtC,CAAA,EAAA,GAAA;EAXsC,MAAA,EAAD,iBAAA,CAAA,aAAC;EAApB,OAAA,SAAA;EAAmB,CAAA,EAAA,CAAA,YAAA,MAAA,CAAA,CAAA,eAAA,qBAAA,UAAA,CAAA,EAAA,YAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IInterpreterPluginState as IInterpreterPluginState$1 } from "../plugins.js";
|
|
2
2
|
import * as _intlayer_core0 from "@intlayer/core";
|
|
3
|
-
import * as
|
|
3
|
+
import * as _intlayer_types18 from "@intlayer/types";
|
|
4
4
|
import { DeclaredLocales, Dictionary, LocalesValues } from "@intlayer/types";
|
|
5
5
|
|
|
6
6
|
//#region src/client/useDictionary.d.ts
|
|
@@ -9,7 +9,7 @@ import { DeclaredLocales, Dictionary, LocalesValues } from "@intlayer/types";
|
|
|
9
9
|
*
|
|
10
10
|
* If the locale is not provided, it will use the locale from the client context
|
|
11
11
|
*/
|
|
12
|
-
declare const useDictionary: <T extends Dictionary, L extends LocalesValues = DeclaredLocales>(dictionary: T, locale?: L) => _intlayer_core0.DeepTransformContent<T["content"], IInterpreterPluginState$1,
|
|
12
|
+
declare const useDictionary: <T extends Dictionary, L extends LocalesValues = DeclaredLocales>(dictionary: T, locale?: L) => _intlayer_core0.DeepTransformContent<T["content"], IInterpreterPluginState$1, _intlayer_types18.Locale>;
|
|
13
13
|
//#endregion
|
|
14
14
|
export { useDictionary };
|
|
15
15
|
//# sourceMappingURL=useDictionary.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IInterpreterPluginState as IInterpreterPluginState$1 } from "../plugins.js";
|
|
2
2
|
import * as _intlayer_core0 from "@intlayer/core";
|
|
3
|
-
import * as
|
|
3
|
+
import * as _intlayer_types14 from "@intlayer/types";
|
|
4
4
|
import { Dictionary, DictionaryKeys, LocalesValues, StrictModeLocaleMap } from "@intlayer/types";
|
|
5
5
|
|
|
6
6
|
//#region src/client/useDictionaryDynamic.d.ts
|
|
@@ -9,7 +9,7 @@ import { Dictionary, DictionaryKeys, LocalesValues, StrictModeLocaleMap } from "
|
|
|
9
9
|
*
|
|
10
10
|
* If the locale is not provided, it will use the locale from the client context
|
|
11
11
|
*/
|
|
12
|
-
declare const useDictionaryDynamic: <T extends Dictionary, K extends DictionaryKeys>(dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>, key: K, locale?: LocalesValues) => _intlayer_core0.DeepTransformContent<T["content"], IInterpreterPluginState$1,
|
|
12
|
+
declare const useDictionaryDynamic: <T extends Dictionary, K extends DictionaryKeys>(dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>, key: K, locale?: LocalesValues) => _intlayer_core0.DeepTransformContent<T["content"], IInterpreterPluginState$1, _intlayer_types14.Locale>;
|
|
13
13
|
//#endregion
|
|
14
14
|
export { useDictionaryDynamic };
|
|
15
15
|
//# sourceMappingURL=useDictionaryDynamic.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryDynamic.d.ts","names":[],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AAkBa,cAAA,oBAoBZ,EAAA,CAAA,UAnBW,UAmBX,EAAA,UAlBW,cAkBX,CAAA,CAAA,iBAAA,EAhBoB,mBAgBpB,CAAA,GAAA,GAhB8C,OAgB9C,CAhBsD,CAgBtD,CAAA,CAAA,EAAA,GAAA,EAfM,CAeN,EAAA,MAAA,CAAA,EAdU,aAcV,EAAA,GAduB,eAAA,CAAA,oBAcvB,CAduB,CAcvB,CAAA,SAAA,CAAA,EAduB,yBAAA,EAAA,
|
|
1
|
+
{"version":3,"file":"useDictionaryDynamic.d.ts","names":[],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AAkBa,cAAA,oBAoBZ,EAAA,CAAA,UAnBW,UAmBX,EAAA,UAlBW,cAkBX,CAAA,CAAA,iBAAA,EAhBoB,mBAgBpB,CAAA,GAAA,GAhB8C,OAgB9C,CAhBsD,CAgBtD,CAAA,CAAA,EAAA,GAAA,EAfM,CAeN,EAAA,MAAA,CAAA,EAdU,aAcV,EAAA,GAduB,eAAA,CAAA,oBAcvB,CAduB,CAcvB,CAAA,SAAA,CAAA,EAduB,yBAAA,EAAA,iBAAA,CAAA,MAAA,CAcvB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _intlayer_types4 from "@intlayer/types";
|
|
2
2
|
import { LocalesValues } from "@intlayer/types";
|
|
3
3
|
|
|
4
4
|
//#region src/client/useLocale.d.ts
|
|
@@ -14,8 +14,8 @@ declare const useLocale: ({
|
|
|
14
14
|
onLocaleChange
|
|
15
15
|
}?: useLocaleProps) => {
|
|
16
16
|
locale: LocalesValues;
|
|
17
|
-
defaultLocale:
|
|
18
|
-
availableLocales:
|
|
17
|
+
defaultLocale: _intlayer_types4.Locale;
|
|
18
|
+
availableLocales: _intlayer_types4.Locale[];
|
|
19
19
|
setLocale: (locale: LocalesValues) => void;
|
|
20
20
|
};
|
|
21
21
|
//#endregion
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _intlayer_types10 from "@intlayer/types";
|
|
2
2
|
|
|
3
3
|
//#region src/client/useLocaleBase.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* On the client side, hook to get the current locale and all related fields
|
|
6
6
|
*/
|
|
7
7
|
declare const useLocaleBase: () => {
|
|
8
|
-
locale:
|
|
9
|
-
defaultLocale:
|
|
10
|
-
availableLocales:
|
|
11
|
-
setLocale: (newLocale:
|
|
8
|
+
locale: _intlayer_types10.LocalesValues;
|
|
9
|
+
defaultLocale: _intlayer_types10.Locale;
|
|
10
|
+
availableLocales: _intlayer_types10.Locale[];
|
|
11
|
+
setLocale: (newLocale: _intlayer_types10.LocalesValues) => void;
|
|
12
12
|
};
|
|
13
13
|
//#endregion
|
|
14
14
|
export { useLocaleBase };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLocaleBase.d.ts","names":[],"sources":["../../../src/client/useLocaleBase.ts"],"sourcesContent":[],"mappings":";;;;;;AAYa,cAAA,aASZ,EAAA,GAAA,GAAA;EAAA,MAAA,EAAA,
|
|
1
|
+
{"version":3,"file":"useLocaleBase.d.ts","names":[],"sources":["../../../src/client/useLocaleBase.ts"],"sourcesContent":[],"mappings":";;;;;;AAYa,cAAA,aASZ,EAAA,GAAA,GAAA;EAAA,MAAA,EAAA,iBAAA,CAAA,aAAA"}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _intlayer_types6 from "@intlayer/types";
|
|
2
2
|
import { LocalesValues } from "@intlayer/types";
|
|
3
3
|
|
|
4
4
|
//#region src/client/useLocaleStorage.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* Get the locale cookie
|
|
7
7
|
*/
|
|
8
|
-
declare const localeInStorage:
|
|
8
|
+
declare const localeInStorage: _intlayer_types6.Locale;
|
|
9
9
|
/**
|
|
10
10
|
* @deprecated Use localeInStorage instead
|
|
11
11
|
*
|
|
12
12
|
* Get the locale cookie
|
|
13
13
|
*/
|
|
14
|
-
declare const localeCookie:
|
|
14
|
+
declare const localeCookie: _intlayer_types6.Locale;
|
|
15
15
|
/**
|
|
16
16
|
* Set the locale cookie
|
|
17
17
|
*/
|
|
@@ -26,7 +26,7 @@ declare const setLocaleCookie: (locale: LocalesValues, isCookieEnabled: boolean)
|
|
|
26
26
|
* Hook that provides the locale storage and a function to set it
|
|
27
27
|
*/
|
|
28
28
|
declare const useLocaleStorage: (isCookieEnabled?: boolean) => {
|
|
29
|
-
getLocale: () =>
|
|
29
|
+
getLocale: () => _intlayer_types6.Locale;
|
|
30
30
|
setLocale: (locale: LocalesValues) => void;
|
|
31
31
|
};
|
|
32
32
|
/**
|
|
@@ -37,7 +37,7 @@ declare const useLocaleStorage: (isCookieEnabled?: boolean) => {
|
|
|
37
37
|
* Hook that provides the locale cookie and a function to set it
|
|
38
38
|
*/
|
|
39
39
|
declare const useLocaleCookie: (isCookieEnabled?: boolean) => {
|
|
40
|
-
localeCookie:
|
|
40
|
+
localeCookie: _intlayer_types6.Locale;
|
|
41
41
|
setLocaleCookie: (locale: LocalesValues) => void;
|
|
42
42
|
};
|
|
43
43
|
//#endregion
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { FC, PropsWithChildren } from "preact/compat";
|
|
2
2
|
import { IntlayerConfig } from "@intlayer/types";
|
|
3
|
-
import * as
|
|
3
|
+
import * as preact_hooks5 from "preact/hooks";
|
|
4
4
|
|
|
5
5
|
//#region src/editor/ConfigurationContext.d.ts
|
|
6
|
-
declare const useConfigurationState: () => [IntlayerConfig,
|
|
6
|
+
declare const useConfigurationState: () => [IntlayerConfig, preact_hooks5.Dispatch<preact_hooks5.StateUpdater<IntlayerConfig>>, () => void];
|
|
7
7
|
type ConfigurationProviderProps = {
|
|
8
8
|
configuration?: IntlayerConfig;
|
|
9
9
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentSelectorWrapper.d.ts","names":[],"sources":["../../../src/editor/ContentSelectorWrapper.tsx"],"sourcesContent":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"ContentSelectorWrapper.d.ts","names":[],"sources":["../../../src/editor/ContentSelectorWrapper.tsx"],"sourcesContent":[],"mappings":";;;;KAiBY,2BAAA,GAA8B,YACxC,KAAK,eAAe;cAqET,yBAAyB,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditedContentContext.d.ts","names":[],"sources":["../../../src/editor/EditedContentContext.tsx"],"sourcesContent":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"EditedContentContext.d.ts","names":[],"sources":["../../../src/editor/EditedContentContext.tsx"],"sourcesContent":[],"mappings":";;;;cAsCa,yDACe,uBAAU;cAOzB,wDACe,uBAAU;AATtC,KAgBK,+BAAA,GAVF;EAEU,qBAAA,EAAA,CAAA,aAMV,EAIgB,MATmB,CASZ,iBATY,EASO,UATP,CAAA,EAAA,GAAA,IAAA;EAOjC,mBAAA,EAIkB,QAJlB,CAI2B,cAJI,CAIW,UAJX,CAAA,CAAA;EAEV,gBAAA,EAAA,CAAA,iBAAA,EAIH,iBAJG,EAAA,QAAA,EAKZ,UALY,CAAA,SAAA,CAAA,EAAA,GAAA,IAAA;EAAmB,gBAAA,EAAA,CAAA,iBAAA,EAQtB,iBARsB,EAAA,QAAA,EAS/B,WAT+B,CAAA,GAAA,CAAA,EAAA,OAAA,CAAA,EAU/B,OAV+B,EAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,GAAA,IAAA;EAA1B,mBAAA,EAAA,CAAA,iBAAA,EAcI,iBAdJ,EAAA,MAAA,EAeP,OAfO,CAAA,KAAA,CAAA,EAAA,OAAA,CAAA,EAgBL,OAhBK,EAAA,EAAA,GAAA,IAAA;EAE4B,mBAAA,EAAA,CAAA,iBAAA,EAiBxB,iBAjBwB,EAAA,OAAA,EAkBlC,OAlBkC,EAAA,EAAA,GAAA,IAAA;EAAf,oBAAA,EAAA,CAAA,iBAAA,EAoBY,iBApBZ,EAAA,GAAA,IAAA;EAAT,4BAAA,EAAA,CAAA,iBAAA,EAqB6B,iBArB7B,EAAA,GAAA,IAAA;EAEA,kBAAA,EAAA,GAAA,GAAA,IAAA;EACT,qBAAA,EAAA,CAAA,sBAAA,EAqBc,iBArBd,GAqBkC,UArBlC,CAAA,KAAA,CAAA,GAAA,MAAA,EAAA,OAAA,EAsBD,OAtBC,EAAA,EAAA,GAuBP,WAvBO,GAAA,SAAA;CAGS;AACT,cA+BD,qBA/BC,EA+BsB,EA/BtB,CA+ByB,iBA/BzB,CAAA;AACA,cAuRD,uBAvRC,EAAA,GAAA,GAuRsB,+BAvRtB;AAIS,cAsRV,gBAtRU,EAAA,GAAA,GAAA;EACX,qBAAA,EAAA,CAAA,aAAA,EAfO,MAeP,CAfc,iBAed,EAfiC,UAejC,CAAA,EAAA,GAAA,IAAA;EACE,mBAAA,EAdS,QAcT,CAdkB,cAclB,CAdiC,UAcjC,CAAA,CAAA;EAGS,gBAAA,EAAA,CAAA,iBAAA,EAfA,iBAeA,EAAA,QAAA,EAdT,UAcS,CAAA,SAAA,CAAA,EAAA,GAAA,IAAA;EACV,gBAAA,EAAA,CAAA,iBAAA,EAZU,iBAYV,EAAA,QAAA,EAXC,WAWD,CAAA,GAAA,CAAA,EAAA,OAAA,CAAA,EAVC,OAUD,EAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,GAAA,IAAA;EAE+B,mBAAA,EAAA,CAAA,iBAAA,EARrB,iBAQqB,EAAA,MAAA,EAPhC,OAOgC,CAAA,KAAA,CAAA,EAAA,OAAA,CAAA,EAN9B,OAM8B,EAAA,EAAA,GAAA,IAAA;EACQ,mBAAA,EAAA,CAAA,iBAAA,EAJ7B,iBAI6B,EAAA,OAAA,EAHvC,OAGuC,EAAA,EAAA,GAAA,IAAA;EAGxB,oBAAA,EAAA,CAAA,iBAAA,EAJgB,iBAIhB,EAAA,GAAA,IAAA;EAAoB,4BAAA,EAAA,CAAA,iBAAA,EAHI,iBAGJ,EAAA,GAAA,IAAA;EACnC,kBAAA,EAAA,GAAA,GAAA,IAAA;EACN,qBAAA,EAAA,CAAA,sBAAA,EAFqB,iBAErB,GAFyC,UAEzC,CAAA,KAAA,CAAA,GAAA,MAAA,EAAA,OAAA,EADM,OACN,EAAA,EAAA,GAAA,WAAA,GAAA,SAAA;EAAW,aAAA,EArDD,MAqDC,CArDM,iBAqDN,EArDyB,UAqDzB,CAAA,GAAA,SAAA;AAYlB,CAAA"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { CrossFrameStateOptions } from "./useCrossFrameState.js";
|
|
2
2
|
import { FC, PropsWithChildren } from "preact/compat";
|
|
3
|
-
import * as
|
|
3
|
+
import * as preact_hooks0 from "preact/hooks";
|
|
4
4
|
|
|
5
5
|
//#region src/editor/EditorEnabledContext.d.ts
|
|
6
6
|
type EditorEnabledStateProps = {
|
|
7
7
|
enabled: boolean;
|
|
8
8
|
};
|
|
9
|
-
declare const useEditorEnabledState: (options?: CrossFrameStateOptions) => [boolean,
|
|
9
|
+
declare const useEditorEnabledState: (options?: CrossFrameStateOptions) => [boolean, preact_hooks0.Dispatch<preact_hooks0.StateUpdater<boolean>>, () => void];
|
|
10
10
|
declare const usePostEditorEnabledState: <S>(onEventTriggered?: (data: S) => void) => (data?: S) => void;
|
|
11
11
|
declare const useGetEditorEnabledState: <S>(onEventTriggered?: (data: S) => void) => (data?: S) => void;
|
|
12
12
|
declare const EditorEnabledProvider: FC<PropsWithChildren>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntlayerEditorProvider.d.ts","names":[],"sources":["../../../src/editor/IntlayerEditorProvider.tsx"],"sourcesContent":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"IntlayerEditorProvider.d.ts","names":[],"sources":["../../../src/editor/IntlayerEditorProvider.tsx"],"sourcesContent":[],"mappings":";;;cAkDa,wBAAwB;aACxB;AADb,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCrossFrameMessageListener.d.ts","names":[],"sources":["../../../src/editor/useCrossFrameMessageListener.tsx"],"sourcesContent":[],"mappings":";;;;;;AAsBA;;;;;;;;;;;;;;cAAa,0CACH,kBAAkB,uBAAuB,4CACvB,
|
|
1
|
+
{"version":3,"file":"useCrossFrameMessageListener.d.ts","names":[],"sources":["../../../src/editor/useCrossFrameMessageListener.tsx"],"sourcesContent":[],"mappings":";;;;;;AAsBA;;;;;;;;;;;;;;cAAa,0CACH,kBAAkB,uBAAuB,4CACvB,0CAuDQ"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CrossFrameStateOptions } from "./useCrossFrameState.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as preact_hooks1 from "preact/hooks";
|
|
3
3
|
|
|
4
4
|
//#region src/editor/useCrossURLPathState.d.ts
|
|
5
|
-
declare const useCrossURLPathState: (initialState?: string, options?: CrossFrameStateOptions) => [string,
|
|
6
|
-
declare const useCrossURLPathSetter: (initialState?: string) => [string,
|
|
5
|
+
declare const useCrossURLPathState: (initialState?: string, options?: CrossFrameStateOptions) => [string, preact_hooks1.Dispatch<preact_hooks1.StateUpdater<string>>, () => void];
|
|
6
|
+
declare const useCrossURLPathSetter: (initialState?: string) => [string, preact_hooks1.Dispatch<preact_hooks1.StateUpdater<string>>, () => void];
|
|
7
7
|
//#endregion
|
|
8
8
|
export { useCrossURLPathSetter, useCrossURLPathState };
|
|
9
9
|
//# sourceMappingURL=useCrossURLPathState.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "preact-intlayer",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Easily internationalize i18n your Preact applications with type-safe multilingual content management.",
|
|
6
6
|
"keywords": [
|
|
@@ -81,33 +81,35 @@
|
|
|
81
81
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@intlayer/api": "7.0.
|
|
85
|
-
"@intlayer/chokidar": "7.0.
|
|
86
|
-
"@intlayer/config": "7.0.
|
|
87
|
-
"@intlayer/core": "7.0.
|
|
88
|
-
"@intlayer/editor": "7.0.
|
|
89
|
-
"@intlayer/types": "7.0.
|
|
84
|
+
"@intlayer/api": "7.0.2",
|
|
85
|
+
"@intlayer/chokidar": "7.0.2",
|
|
86
|
+
"@intlayer/config": "7.0.2",
|
|
87
|
+
"@intlayer/core": "7.0.2",
|
|
88
|
+
"@intlayer/editor": "7.0.2",
|
|
89
|
+
"@intlayer/types": "7.0.2",
|
|
90
|
+
"@intlayer/unmerged-dictionaries-entry": "7.0.2",
|
|
90
91
|
"js-cookie": "3.0.5",
|
|
91
92
|
"uuid": "13.0.0"
|
|
92
93
|
},
|
|
93
94
|
"devDependencies": {
|
|
94
95
|
"@types/node": "24.9.1",
|
|
95
96
|
"@types/uuid": "10.0.0",
|
|
96
|
-
"@utils/ts-config": "7.0.
|
|
97
|
-
"@utils/ts-config-types": "7.0.
|
|
98
|
-
"@utils/tsdown-config": "7.0.
|
|
97
|
+
"@utils/ts-config": "7.0.2",
|
|
98
|
+
"@utils/ts-config-types": "7.0.2",
|
|
99
|
+
"@utils/tsdown-config": "7.0.2",
|
|
99
100
|
"rimraf": "6.0.1",
|
|
100
101
|
"tsdown": "0.15.9",
|
|
101
102
|
"typescript": "5.9.3",
|
|
102
103
|
"vitest": "4.0.3"
|
|
103
104
|
},
|
|
104
105
|
"peerDependencies": {
|
|
105
|
-
"@intlayer/api": "7.0.
|
|
106
|
-
"@intlayer/chokidar": "7.0.
|
|
107
|
-
"@intlayer/config": "7.0.
|
|
108
|
-
"@intlayer/core": "7.0.
|
|
109
|
-
"@intlayer/editor": "7.0.
|
|
110
|
-
"@intlayer/types": "7.0.
|
|
106
|
+
"@intlayer/api": "7.0.2",
|
|
107
|
+
"@intlayer/chokidar": "7.0.2",
|
|
108
|
+
"@intlayer/config": "7.0.2",
|
|
109
|
+
"@intlayer/core": "7.0.2",
|
|
110
|
+
"@intlayer/editor": "7.0.2",
|
|
111
|
+
"@intlayer/types": "7.0.2",
|
|
112
|
+
"@intlayer/unmerged-dictionaries-entry": "7.0.2",
|
|
111
113
|
"preact": "10.26.4"
|
|
112
114
|
},
|
|
113
115
|
"engines": {
|