preact-intlayer 8.2.1 → 8.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/cjs/UI/ContentSelector.cjs.map +1 -1
  2. package/dist/cjs/client/IntlayerProvider.cjs.map +1 -1
  3. package/dist/cjs/editor/CommunicatorContext.cjs.map +1 -1
  4. package/dist/cjs/editor/ConfigurationContext.cjs.map +1 -1
  5. package/dist/cjs/editor/ContentSelectorWrapper.cjs.map +1 -1
  6. package/dist/cjs/editor/DictionariesRecordContext.cjs.map +1 -1
  7. package/dist/cjs/editor/EditedContentContext.cjs.map +1 -1
  8. package/dist/cjs/editor/EditorEnabledContext.cjs.map +1 -1
  9. package/dist/cjs/editor/EditorProvider.cjs.map +1 -1
  10. package/dist/cjs/editor/FocusDictionaryContext.cjs.map +1 -1
  11. package/dist/cjs/editor/IntlayerEditorProvider.cjs.map +1 -1
  12. package/dist/cjs/html/HTMLProvider.cjs.map +1 -1
  13. package/dist/cjs/markdown/MarkdownProvider.cjs.map +1 -1
  14. package/dist/cjs/markdown/MarkdownRenderer.cjs.map +1 -1
  15. package/dist/cjs/plugins.cjs.map +1 -1
  16. package/dist/esm/UI/ContentSelector.mjs.map +1 -1
  17. package/dist/esm/client/IntlayerProvider.mjs.map +1 -1
  18. package/dist/esm/editor/CommunicatorContext.mjs.map +1 -1
  19. package/dist/esm/editor/ConfigurationContext.mjs.map +1 -1
  20. package/dist/esm/editor/ContentSelectorWrapper.mjs.map +1 -1
  21. package/dist/esm/editor/DictionariesRecordContext.mjs.map +1 -1
  22. package/dist/esm/editor/EditedContentContext.mjs.map +1 -1
  23. package/dist/esm/editor/EditorEnabledContext.mjs.map +1 -1
  24. package/dist/esm/editor/EditorProvider.mjs.map +1 -1
  25. package/dist/esm/editor/FocusDictionaryContext.mjs.map +1 -1
  26. package/dist/esm/editor/IntlayerEditorProvider.mjs.map +1 -1
  27. package/dist/esm/html/HTMLProvider.mjs.map +1 -1
  28. package/dist/esm/markdown/MarkdownProvider.mjs.map +1 -1
  29. package/dist/esm/markdown/MarkdownRenderer.mjs.map +1 -1
  30. package/dist/esm/plugins.mjs.map +1 -1
  31. package/package.json +10 -10
@@ -1 +1 @@
1
- {"version":3,"file":"ContentSelector.cjs","names":[],"sources":["../../../src/UI/ContentSelector.tsx"],"sourcesContent":["'use client';\n\nimport type { FunctionalComponent, JSX } from 'preact';\nimport { useCallback, useEffect, useRef, useState } from 'preact/hooks';\n\nconst DEFAULT_PRESS_DETECT_DURATION = 250;\n\ntype ContentSelectorProps = {\n onPress: () => void;\n onHover?: () => void;\n onUnhover?: () => void;\n onClickOutside?: () => void;\n pressDuration?: number;\n isSelecting?: boolean;\n} & Omit<JSX.HTMLAttributes<HTMLDivElement>, 'content'>;\n\nexport const ContentSelector: FunctionalComponent<ContentSelectorProps> = ({\n children,\n onPress: onSelect,\n onHover,\n onUnhover,\n onClickOutside: onUnselect,\n pressDuration = DEFAULT_PRESS_DETECT_DURATION,\n isSelecting: isSelectingProp,\n ...props\n}) => {\n const divRef = useRef<HTMLDivElement>(null);\n const [isHovered, setIsHovered] = useState(false);\n const [isSelectingState, setIsSelectingState] = useState(isSelectingProp);\n const pressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isChildrenString = typeof children === 'string';\n\n const handleOnLongPress = () => {\n setIsSelectingState(true);\n onSelect();\n };\n\n const startPressTimer = () => {\n pressTimerRef.current = setTimeout(() => {\n handleOnLongPress();\n }, pressDuration);\n };\n\n const clearPressTimer = () => {\n if (pressTimerRef.current) {\n clearTimeout(pressTimerRef.current);\n pressTimerRef.current = null;\n }\n };\n\n const handleMouseDown = () => {\n clearPressTimer(); // Ensure any previous timer is cleared\n startPressTimer();\n };\n\n const handleMouseEnter = () => {\n setIsHovered(true);\n onHover?.();\n };\n\n const handleMouseUp = () => {\n if (isHovered) {\n setIsHovered(false);\n onUnhover?.();\n }\n clearPressTimer();\n };\n\n // Use useCallback to ensure the function identity remains stable\n const handleClickOutside = useCallback(\n (event: MouseEvent) => {\n if (divRef.current && !divRef.current.contains(event.target as Node)) {\n setIsSelectingState(false);\n onUnselect?.();\n }\n },\n [onUnselect]\n );\n\n useEffect(() => {\n // Attach click outside listener\n document.addEventListener('mousedown', handleClickOutside);\n\n return () => {\n // Cleanup\n document.removeEventListener('mousedown', handleClickOutside);\n // clearPressTimer(); // Ensure to clear the timer when component unmounts\n };\n }, [handleClickOutside]);\n\n const handleOnClick: JSX.MouseEventHandler<HTMLDivElement> = (e) => {\n if (isSelectingState) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleOnBlur = () => {\n // Stop editing when the element loses focus\n setIsSelectingState(false);\n };\n\n return (\n <span\n style={{\n display: isChildrenString ? 'inline' : 'inline-block',\n cursor: 'pointer',\n userSelect: 'none',\n borderRadius: '0.375rem',\n outlineWidth: '2px',\n outlineOffset: '4px',\n outlineStyle: 'solid',\n outlineColor:\n isSelectingProp || isSelectingState || isHovered\n ? 'inherit'\n : 'transparent',\n transition: 'all 100ms 50ms ease-in-out',\n }}\n role=\"button\"\n tabIndex={0}\n onKeyUp={() => null}\n onClick={handleOnClick}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleMouseDown}\n onTouchEnd={handleMouseUp}\n onTouchCancel={handleMouseUp}\n onBlur={handleOnBlur}\n onMouseEnter={handleMouseEnter}\n ref={divRef}\n {...props}\n >\n {children}\n </span>\n );\n};\n"],"mappings":"2LAKA,MAWa,GAA8D,CACzE,WACA,QAAS,EACT,UACA,YACA,eAAgB,EAChB,gBAAgB,IAChB,YAAa,EACb,GAAG,KACC,CACJ,IAAM,GAAA,EAAA,EAAA,QAAgC,KAAK,CACrC,CAAC,EAAW,IAAA,EAAA,EAAA,UAAyB,GAAM,CAC3C,CAAC,EAAkB,IAAA,EAAA,EAAA,UAAgC,EAAgB,CACnE,GAAA,EAAA,EAAA,QAA6D,KAAK,CAClE,EAAmB,OAAO,GAAa,SAEvC,MAA0B,CAC9B,EAAoB,GAAK,CACzB,GAAU,EAGN,MAAwB,CAC5B,EAAc,QAAU,eAAiB,CACvC,GAAmB,EAClB,EAAc,EAGb,MAAwB,CAC5B,AAEE,EAAc,WADd,aAAa,EAAc,QAAQ,CACX,OAItB,MAAwB,CAC5B,GAAiB,CACjB,GAAiB,EAGb,MAAyB,CAC7B,EAAa,GAAK,CAClB,KAAW,EAGP,MAAsB,CACtB,IACF,EAAa,GAAM,CACnB,KAAa,EAEf,GAAiB,EAIb,GAAA,EAAA,EAAA,aACH,GAAsB,CACjB,EAAO,SAAW,CAAC,EAAO,QAAQ,SAAS,EAAM,OAAe,GAClE,EAAoB,GAAM,CAC1B,KAAc,GAGlB,CAAC,EAAW,CACb,CAyBD,OAvBA,EAAA,EAAA,gBAEE,SAAS,iBAAiB,YAAa,EAAmB,KAE7C,CAEX,SAAS,oBAAoB,YAAa,EAAmB,GAG9D,CAAC,EAAmB,CAAC,EAetB,EAAA,EAAA,KAAC,OAAA,CACC,MAAO,CACL,QAAS,EAAmB,SAAW,eACvC,OAAQ,UACR,WAAY,OACZ,aAAc,WACd,aAAc,MACd,cAAe,MACf,aAAc,QACd,aACE,GAAmB,GAAoB,EACnC,UACA,cACN,WAAY,6BACb,CACD,KAAK,SACL,SAAU,EACV,YAAe,KACf,QA/B0D,GAAM,CAC9D,IACF,EAAE,gBAAgB,CAClB,EAAE,iBAAiB,GA6BnB,YAAa,EACb,UAAW,EACX,aAAc,EACd,aAAc,EACd,WAAY,EACZ,cAAe,EACf,WA/BuB,CAEzB,EAAoB,GAAM,EA8BxB,aAAc,EACd,IAAK,EACL,GAAI,EAEH,YACI"}
1
+ {"version":3,"file":"ContentSelector.cjs","names":[],"sources":["../../../src/UI/ContentSelector.tsx"],"sourcesContent":["'use client';\n\nimport type { FunctionalComponent, JSX } from 'preact';\nimport { useCallback, useEffect, useRef, useState } from 'preact/hooks';\n\nconst DEFAULT_PRESS_DETECT_DURATION = 250;\n\ntype ContentSelectorProps = {\n onPress: () => void;\n onHover?: () => void;\n onUnhover?: () => void;\n onClickOutside?: () => void;\n pressDuration?: number;\n isSelecting?: boolean;\n} & Omit<JSX.HTMLAttributes<HTMLDivElement>, 'content'>;\n\nexport const ContentSelector: FunctionalComponent<ContentSelectorProps> = ({\n children,\n onPress: onSelect,\n onHover,\n onUnhover,\n onClickOutside: onUnselect,\n pressDuration = DEFAULT_PRESS_DETECT_DURATION,\n isSelecting: isSelectingProp,\n ...props\n}) => {\n const divRef = useRef<HTMLDivElement>(null);\n const [isHovered, setIsHovered] = useState(false);\n const [isSelectingState, setIsSelectingState] = useState(isSelectingProp);\n const pressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isChildrenString = typeof children === 'string';\n\n const handleOnLongPress = () => {\n setIsSelectingState(true);\n onSelect();\n };\n\n const startPressTimer = () => {\n pressTimerRef.current = setTimeout(() => {\n handleOnLongPress();\n }, pressDuration);\n };\n\n const clearPressTimer = () => {\n if (pressTimerRef.current) {\n clearTimeout(pressTimerRef.current);\n pressTimerRef.current = null;\n }\n };\n\n const handleMouseDown = () => {\n clearPressTimer(); // Ensure any previous timer is cleared\n startPressTimer();\n };\n\n const handleMouseEnter = () => {\n setIsHovered(true);\n onHover?.();\n };\n\n const handleMouseUp = () => {\n if (isHovered) {\n setIsHovered(false);\n onUnhover?.();\n }\n clearPressTimer();\n };\n\n // Use useCallback to ensure the function identity remains stable\n const handleClickOutside = useCallback(\n (event: MouseEvent) => {\n if (divRef.current && !divRef.current.contains(event.target as Node)) {\n setIsSelectingState(false);\n onUnselect?.();\n }\n },\n [onUnselect]\n );\n\n useEffect(() => {\n // Attach click outside listener\n document.addEventListener('mousedown', handleClickOutside);\n\n return () => {\n // Cleanup\n document.removeEventListener('mousedown', handleClickOutside);\n // clearPressTimer(); // Ensure to clear the timer when component unmounts\n };\n }, [handleClickOutside]);\n\n const handleOnClick: JSX.MouseEventHandler<HTMLDivElement> = (e) => {\n if (isSelectingState) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleOnBlur = () => {\n // Stop editing when the element loses focus\n setIsSelectingState(false);\n };\n\n return (\n <span\n style={{\n display: isChildrenString ? 'inline' : 'inline-block',\n cursor: 'pointer',\n userSelect: 'none',\n borderRadius: '0.375rem',\n outlineWidth: '2px',\n outlineOffset: '4px',\n outlineStyle: 'solid',\n outlineColor:\n isSelectingProp || isSelectingState || isHovered\n ? 'inherit'\n : 'transparent',\n transition: 'all 100ms 50ms ease-in-out',\n }}\n role=\"button\"\n tabIndex={0}\n onKeyUp={() => null}\n onClick={handleOnClick}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleMouseDown}\n onTouchEnd={handleMouseUp}\n onTouchCancel={handleMouseUp}\n onBlur={handleOnBlur}\n onMouseEnter={handleMouseEnter}\n ref={divRef}\n {...props}\n >\n {children}\n </span>\n );\n};\n"],"mappings":"2LAKA,MAWa,GAA8D,CACzE,WACA,QAAS,EACT,UACA,YACA,eAAgB,EAChB,gBAAgB,IAChB,YAAa,EACb,GAAG,KACC,CACJ,IAAM,GAAA,EAAA,EAAA,QAAgC,KAAK,CACrC,CAAC,EAAW,IAAA,EAAA,EAAA,UAAyB,GAAM,CAC3C,CAAC,EAAkB,IAAA,EAAA,EAAA,UAAgC,EAAgB,CACnE,GAAA,EAAA,EAAA,QAA6D,KAAK,CAClE,EAAmB,OAAO,GAAa,SAEvC,MAA0B,CAC9B,EAAoB,GAAK,CACzB,GAAU,EAGN,MAAwB,CAC5B,EAAc,QAAU,eAAiB,CACvC,GAAmB,EAClB,EAAc,EAGb,MAAwB,CAC5B,AAEE,EAAc,WADd,aAAa,EAAc,QAAQ,CACX,OAItB,MAAwB,CAC5B,GAAiB,CACjB,GAAiB,EAGb,MAAyB,CAC7B,EAAa,GAAK,CAClB,KAAW,EAGP,MAAsB,CACtB,IACF,EAAa,GAAM,CACnB,KAAa,EAEf,GAAiB,EAIb,GAAA,EAAA,EAAA,aACH,GAAsB,CACjB,EAAO,SAAW,CAAC,EAAO,QAAQ,SAAS,EAAM,OAAe,GAClE,EAAoB,GAAM,CAC1B,KAAc,GAGlB,CAAC,EAAW,CACb,CAyBD,OAvBA,EAAA,EAAA,gBAEE,SAAS,iBAAiB,YAAa,EAAmB,KAE7C,CAEX,SAAS,oBAAoB,YAAa,EAAmB,GAG9D,CAAC,EAAmB,CAAC,EAetB,EAAA,EAAA,KAAC,OAAD,CACE,MAAO,CACL,QAAS,EAAmB,SAAW,eACvC,OAAQ,UACR,WAAY,OACZ,aAAc,WACd,aAAc,MACd,cAAe,MACf,aAAc,QACd,aACE,GAAmB,GAAoB,EACnC,UACA,cACN,WAAY,6BACb,CACD,KAAK,SACL,SAAU,EACV,YAAe,KACf,QA/B0D,GAAM,CAC9D,IACF,EAAE,gBAAgB,CAClB,EAAE,iBAAiB,GA6BnB,YAAa,EACb,UAAW,EACX,aAAc,EACd,aAAc,EACd,WAAY,EACZ,cAAe,EACf,WA/BuB,CAEzB,EAAoB,GAAM,EA8BxB,aAAc,EACd,IAAK,EACL,GAAI,EAEH,WACI,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"IntlayerProvider.cjs","names":["localeInStorage","configuration","useCrossFrameState","MessageKey","IntlayerEditorProvider"],"sources":["../../../src/client/IntlayerProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport { localeResolver } from '@intlayer/core/localization';\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, useEffect } 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 useEffect(() => {\n if (localeProp && localeProp !== currentLocale) {\n setCurrentLocale(localeProp);\n }\n }, [localeProp, currentLocale, setCurrentLocale]);\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\n/**\n * Main provider for Intlayer in Preact applications.\n *\n * It provides the Intlayer context to your application, allowing the use\n * of hooks like `useIntlayer` and `useLocale`.\n *\n * @param props - The provider props.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'preact-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider: FunctionComponent<IntlayerProviderProps> = (\n props\n) => (\n <IntlayerEditorProvider>\n <IntlayerProviderContent {...props} />\n </IntlayerEditorProvider>\n);\n"],"mappings":"ydA0BA,MAAa,GAAA,EAAA,EAAA,eAAqD,CAChE,OAAQA,EAAAA,iBAAmBC,EAAAA,SAAe,sBAAsB,cAChE,cAAiB,KACjB,cAAe,GAChB,CAAC,CAKW,OAAA,EAAA,EAAA,YAAsC,EAAsB,CAc5D,GAER,CACH,OAAQ,EACR,cAAe,EACf,WACA,UAAW,EACX,gBACA,qBACI,CACJ,GAAM,CAAE,wBAAyBA,EAAAA,SAAiB,EAAE,CAC9C,CAAE,cAAe,EAAqB,QAAS,GACnD,GAAwB,EAAE,CAEtB,EACJ,GAAcD,EAAAA,iBAAmB,GAAqB,EAElD,CAAC,EAAe,GAAoBE,EAAAA,mBACxCC,EAAAA,WAAW,wBACX,EACD,EAED,EAAA,EAAA,eAAgB,CACV,GAAc,IAAe,GAC/B,EAAiB,EAAW,EAE7B,CAAC,EAAY,EAAe,EAAiB,CAAC,CAcjD,IAAM,EAAY,IAZK,GAA6B,CAC9C,KAAc,UAAU,GAAK,EAAU,UAAU,CAErD,IAAI,CAAC,GAAkB,IAAI,OAAO,CAAC,SAAS,EAAU,CAAE,CACtD,QAAQ,MAAM,UAAU,EAAU,mBAAmB,CACrD,OAGF,EAAiB,EAAU,CAC3B,EAAA,mBAAmB,EAAW,GAAmB,GAAK,IAKlD,GAAA,EAAA,EAAA,gBAAgC,GAAc,EAAc,CAElE,OACE,EAAA,EAAA,KAAC,EAAsB,SAAA,CACrB,MAAO,CACL,OAAQ,EACR,YACA,gBACA,kBACD,CAEA,YAC8B,EAwBxB,EACX,IAEA,EAAA,EAAA,KAACC,EAAAA,uBAAAA,CAAAA,UACC,EAAA,EAAA,KAAC,EAAA,CAAwB,GAAI,EAAA,CAAS,CAAA,CACf"}
1
+ {"version":3,"file":"IntlayerProvider.cjs","names":["localeInStorage","configuration","useCrossFrameState","MessageKey","IntlayerEditorProvider"],"sources":["../../../src/client/IntlayerProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport { localeResolver } from '@intlayer/core/localization';\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, useEffect } 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 useEffect(() => {\n if (localeProp && localeProp !== currentLocale) {\n setCurrentLocale(localeProp);\n }\n }, [localeProp, currentLocale, setCurrentLocale]);\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\n/**\n * Main provider for Intlayer in Preact applications.\n *\n * It provides the Intlayer context to your application, allowing the use\n * of hooks like `useIntlayer` and `useLocale`.\n *\n * @param props - The provider props.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'preact-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider: FunctionComponent<IntlayerProviderProps> = (\n props\n) => (\n <IntlayerEditorProvider>\n <IntlayerProviderContent {...props} />\n </IntlayerEditorProvider>\n);\n"],"mappings":"ydA0BA,MAAa,GAAA,EAAA,EAAA,eAAqD,CAChE,OAAQA,EAAAA,iBAAmBC,EAAAA,SAAe,sBAAsB,cAChE,cAAiB,KACjB,cAAe,GAChB,CAAC,CAKW,OAAA,EAAA,EAAA,YAAsC,EAAsB,CAc5D,GAER,CACH,OAAQ,EACR,cAAe,EACf,WACA,UAAW,EACX,gBACA,qBACI,CACJ,GAAM,CAAE,wBAAyBA,EAAAA,SAAiB,EAAE,CAC9C,CAAE,cAAe,EAAqB,QAAS,GACnD,GAAwB,EAAE,CAEtB,EACJ,GAAcD,EAAAA,iBAAmB,GAAqB,EAElD,CAAC,EAAe,GAAoBE,EAAAA,mBACxCC,EAAAA,WAAW,wBACX,EACD,EAED,EAAA,EAAA,eAAgB,CACV,GAAc,IAAe,GAC/B,EAAiB,EAAW,EAE7B,CAAC,EAAY,EAAe,EAAiB,CAAC,CAcjD,IAAM,EAAY,IAZK,GAA6B,CAC9C,KAAc,UAAU,GAAK,EAAU,UAAU,CAErD,IAAI,CAAC,GAAkB,IAAI,OAAO,CAAC,SAAS,EAAU,CAAE,CACtD,QAAQ,MAAM,UAAU,EAAU,mBAAmB,CACrD,OAGF,EAAiB,EAAU,CAC3B,EAAA,mBAAmB,EAAW,GAAmB,GAAK,IAKlD,GAAA,EAAA,EAAA,gBAAgC,GAAc,EAAc,CAElE,OACE,EAAA,EAAA,KAAC,EAAsB,SAAvB,CACE,MAAO,CACL,OAAQ,EACR,YACA,gBACA,kBACD,CAEA,WAC8B,CAAA,EAwBxB,EACX,IAEA,EAAA,EAAA,KAACC,EAAAA,uBAAD,CAAA,UACE,EAAA,EAAA,KAAC,EAAD,CAAyB,GAAI,EAAS,CAAA,CACf,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"CommunicatorContext.cjs","names":["configuration"],"sources":["../../../src/editor/CommunicatorContext.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport {\n type ComponentChildren,\n createContext,\n type FunctionComponent,\n} from 'preact';\nimport { useContext, useMemo, useRef } from 'preact/hooks';\n\nconst randomUUID = () => Math.random().toString(36).slice(2);\n\nexport type UseCrossPlatformStateProps = {\n postMessage: typeof window.postMessage;\n allowedOrigins?: string[];\n senderId: string;\n};\n\nconst { editor } = configuration;\n\nconst CommunicatorContext = createContext<UseCrossPlatformStateProps>({\n postMessage: () => null,\n allowedOrigins: [\n editor?.applicationURL,\n editor?.editorURL,\n editor?.cmsURL,\n ] as string[],\n senderId: '',\n});\n\nexport type CommunicatorProviderProps = {\n children?: ComponentChildren;\n postMessage: typeof window.postMessage;\n allowedOrigins?: string[];\n};\n\nexport const CommunicatorProvider: FunctionComponent<\n CommunicatorProviderProps\n> = ({ children, allowedOrigins, postMessage }) => {\n // Create a stable, unique ID for the lifetime of this app/iframe instance.\n const senderIdRef = useRef(randomUUID());\n\n const value = useMemo(\n () => ({ postMessage, allowedOrigins, senderId: senderIdRef.current }),\n [postMessage, allowedOrigins] // senderIdRef.current is stable\n );\n\n return (\n <CommunicatorContext.Provider value={value}>\n {children}\n </CommunicatorContext.Provider>\n );\n};\n\nexport const useCommunicator = () => useContext(CommunicatorContext);\n"],"mappings":"8QAUA,MAAM,MAAmB,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CAQtD,CAAE,UAAWA,EAAAA,QAEb,GAAA,EAAA,EAAA,eAAgE,CACpE,gBAAmB,KACnB,eAAgB,CACd,GAAQ,eACR,GAAQ,UACR,GAAQ,OACT,CACD,SAAU,GACX,CAAC,CAQW,GAER,CAAE,WAAU,iBAAgB,iBAAkB,CAEjD,IAAM,GAAA,EAAA,EAAA,QAAqB,GAAY,CAAC,CAElC,GAAA,EAAA,EAAA,cACG,CAAE,cAAa,iBAAgB,SAAU,EAAY,QAAS,EACrE,CAAC,EAAa,EAAe,CAC9B,CAED,OACE,EAAA,EAAA,KAAC,EAAoB,SAAA,CAAgB,QAClC,YAC4B,EAItB,OAAA,EAAA,EAAA,YAAmC,EAAoB"}
1
+ {"version":3,"file":"CommunicatorContext.cjs","names":["configuration"],"sources":["../../../src/editor/CommunicatorContext.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport {\n type ComponentChildren,\n createContext,\n type FunctionComponent,\n} from 'preact';\nimport { useContext, useMemo, useRef } from 'preact/hooks';\n\nconst randomUUID = () => Math.random().toString(36).slice(2);\n\nexport type UseCrossPlatformStateProps = {\n postMessage: typeof window.postMessage;\n allowedOrigins?: string[];\n senderId: string;\n};\n\nconst { editor } = configuration;\n\nconst CommunicatorContext = createContext<UseCrossPlatformStateProps>({\n postMessage: () => null,\n allowedOrigins: [\n editor?.applicationURL,\n editor?.editorURL,\n editor?.cmsURL,\n ] as string[],\n senderId: '',\n});\n\nexport type CommunicatorProviderProps = {\n children?: ComponentChildren;\n postMessage: typeof window.postMessage;\n allowedOrigins?: string[];\n};\n\nexport const CommunicatorProvider: FunctionComponent<\n CommunicatorProviderProps\n> = ({ children, allowedOrigins, postMessage }) => {\n // Create a stable, unique ID for the lifetime of this app/iframe instance.\n const senderIdRef = useRef(randomUUID());\n\n const value = useMemo(\n () => ({ postMessage, allowedOrigins, senderId: senderIdRef.current }),\n [postMessage, allowedOrigins] // senderIdRef.current is stable\n );\n\n return (\n <CommunicatorContext.Provider value={value}>\n {children}\n </CommunicatorContext.Provider>\n );\n};\n\nexport const useCommunicator = () => useContext(CommunicatorContext);\n"],"mappings":"8QAUA,MAAM,MAAmB,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CAQtD,CAAE,UAAWA,EAAAA,QAEb,GAAA,EAAA,EAAA,eAAgE,CACpE,gBAAmB,KACnB,eAAgB,CACd,GAAQ,eACR,GAAQ,UACR,GAAQ,OACT,CACD,SAAU,GACX,CAAC,CAQW,GAER,CAAE,WAAU,iBAAgB,iBAAkB,CAEjD,IAAM,GAAA,EAAA,EAAA,QAAqB,GAAY,CAAC,CAElC,GAAA,EAAA,EAAA,cACG,CAAE,cAAa,iBAAgB,SAAU,EAAY,QAAS,EACrE,CAAC,EAAa,EAAe,CAC9B,CAED,OACE,EAAA,EAAA,KAAC,EAAoB,SAArB,CAAqC,QAClC,WAC4B,CAAA,EAItB,OAAA,EAAA,EAAA,YAAmC,EAAoB"}
@@ -1 +1 @@
1
- {"version":3,"file":"ConfigurationContext.cjs","names":["useCrossFrameState","MessageKey"],"sources":["../../../src/editor/ConfigurationContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { IntlayerConfig } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport { useCrossFrameState } from './useCrossFrameState';\n\nconst ConfigurationStatesContext = createContext<IntlayerConfig | undefined>(\n undefined\n);\n\nexport const useConfigurationState = () =>\n useCrossFrameState<IntlayerConfig>(\n MessageKey.INTLAYER_CONFIGURATION,\n undefined,\n {\n receive: false,\n emit: true,\n }\n );\n\nexport type ConfigurationProviderProps = {\n configuration?: IntlayerConfig;\n};\n\nexport const ConfigurationProvider: FunctionalComponent<\n RenderableProps<ConfigurationProviderProps>\n> = ({ children, configuration }) => (\n <ConfigurationStatesContext.Provider value={configuration}>\n {children}\n </ConfigurationStatesContext.Provider>\n);\n\nexport const useConfiguration = () => useContext(ConfigurationStatesContext);\n"],"mappings":"yRAYA,MAAM,GAAA,EAAA,EAAA,eACJ,IAAA,GACD,CAEY,MACXA,EAAAA,mBACEC,EAAAA,WAAW,uBACX,IAAA,GACA,CACE,QAAS,GACT,KAAM,GACP,CACF,CAMU,GAER,CAAE,WAAU,oBACf,EAAA,EAAA,KAAC,EAA2B,SAAA,CAAS,MAAO,EACzC,YACmC,CAG3B,OAAA,EAAA,EAAA,YAAoC,EAA2B"}
1
+ {"version":3,"file":"ConfigurationContext.cjs","names":["useCrossFrameState","MessageKey"],"sources":["../../../src/editor/ConfigurationContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { IntlayerConfig } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport { useCrossFrameState } from './useCrossFrameState';\n\nconst ConfigurationStatesContext = createContext<IntlayerConfig | undefined>(\n undefined\n);\n\nexport const useConfigurationState = () =>\n useCrossFrameState<IntlayerConfig>(\n MessageKey.INTLAYER_CONFIGURATION,\n undefined,\n {\n receive: false,\n emit: true,\n }\n );\n\nexport type ConfigurationProviderProps = {\n configuration?: IntlayerConfig;\n};\n\nexport const ConfigurationProvider: FunctionalComponent<\n RenderableProps<ConfigurationProviderProps>\n> = ({ children, configuration }) => (\n <ConfigurationStatesContext.Provider value={configuration}>\n {children}\n </ConfigurationStatesContext.Provider>\n);\n\nexport const useConfiguration = () => useContext(ConfigurationStatesContext);\n"],"mappings":"yRAYA,MAAM,GAAA,EAAA,EAAA,eACJ,IAAA,GACD,CAEY,MACXA,EAAAA,mBACEC,EAAAA,WAAW,uBACX,IAAA,GACA,CACE,QAAS,GACT,KAAM,GACP,CACF,CAMU,GAER,CAAE,WAAU,oBACf,EAAA,EAAA,KAAC,EAA2B,SAA5B,CAAqC,MAAO,EACzC,WACmC,CAAA,CAG3B,OAAA,EAAA,EAAA,YAAoC,EAA2B"}
@@ -1 +1 @@
1
- {"version":3,"file":"ContentSelectorWrapper.cjs","names":["useFocusDictionary","useCommunicator","NodeType","ContentSelector","MessageKey","useEditorEnabled","useIntlayerContext"],"sources":["../../../src/editor/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport type { NodeProps } from '@intlayer/core/interpreter';\nimport { isSameKeyPath } from '@intlayer/core/utils';\nimport { MessageKey } from '@intlayer/editor';\nimport { NodeType } from '@intlayer/types';\nimport type { FunctionalComponent, JSX } from 'preact';\nimport { useCallback, useMemo } from 'preact/hooks';\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<JSX.HTMLAttributes<HTMLDivElement>, 'children'>;\n\nconst ContentSelectorWrapperContent: FunctionalComponent<\n ContentSelectorWrapperProps\n> = ({ children, dictionaryKey, keyPath }) => {\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: FunctionalComponent<\n ContentSelectorWrapperProps\n> = ({ children, ...props }) => {\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":"0eAiBA,MAAM,GAED,CAAE,WAAU,gBAAe,aAAc,CAC5C,GAAM,CAAE,iBAAgB,qBAAsBA,EAAAA,oBAAoB,CAC5D,CAAE,cAAa,YAAaC,EAAAA,iBAAiB,CAG7C,GAAA,EAAA,EAAA,aACE,EAAQ,OAAQ,GAAQ,EAAI,OAASC,EAAAA,SAAS,YAAY,CAChE,CAAC,EAAQ,CACV,CA2CD,OACE,EAAA,EAAA,KAACC,EAAAA,gBAAAA,CACC,SAAA,EAAA,EAAA,iBAzCA,EAAkB,CAChB,gBACA,QAAS,EACV,CAAC,CACJ,CAAC,EAAe,EAAgB,CACjC,CAqCG,SAAA,EAAA,EAAA,iBAjCA,EAAY,CACV,KAAM,GAAGC,EAAAA,WAAW,iCAAiC,OACrD,KAAM,CACJ,gBACA,QAAS,EACV,CACD,WACD,CAAC,CACJ,CAAC,EAAe,EAAgB,CACjC,CAyBG,WAAA,EAAA,EAAA,iBArBA,EAAY,CACV,KAAM,GAAGA,EAAAA,WAAW,iCAAiC,OACrD,KAAM,KACN,WACD,CAAC,CACJ,CAAC,EAAS,CACX,CAgBG,aAAA,EAAA,EAAA,cAZC,GAAgB,gBAAkB,IAChC,GAAgB,SAAS,QAAU,GAAK,IAAA,EAAA,EAAA,eAC3B,GAAgB,SAAW,EAAE,CAAE,EAAgB,GAC/D,GACF,CAAC,EAAgB,EAAiB,EAAc,CACjD,CASI,YACe,EAIT,GAER,CAAE,WAAU,GAAG,KAAY,CAC9B,GAAM,CAAE,WAAYC,EAAAA,kBAAkB,CAChC,CAAE,iBAAkBC,EAAAA,oBAAoB,CAU9C,OARI,GAAW,CAAC,GAEZ,EAAA,EAAA,KAAC,EAAA,CAA8B,GAAI,EAChC,YAC6B,CAI7B"}
1
+ {"version":3,"file":"ContentSelectorWrapper.cjs","names":["useFocusDictionary","useCommunicator","NodeType","ContentSelector","MessageKey","useEditorEnabled","useIntlayerContext"],"sources":["../../../src/editor/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport type { NodeProps } from '@intlayer/core/interpreter';\nimport { isSameKeyPath } from '@intlayer/core/utils';\nimport { MessageKey } from '@intlayer/editor';\nimport { NodeType } from '@intlayer/types';\nimport type { FunctionalComponent, JSX } from 'preact';\nimport { useCallback, useMemo } from 'preact/hooks';\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<JSX.HTMLAttributes<HTMLDivElement>, 'children'>;\n\nconst ContentSelectorWrapperContent: FunctionalComponent<\n ContentSelectorWrapperProps\n> = ({ children, dictionaryKey, keyPath }) => {\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: FunctionalComponent<\n ContentSelectorWrapperProps\n> = ({ children, ...props }) => {\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":"0eAiBA,MAAM,GAED,CAAE,WAAU,gBAAe,aAAc,CAC5C,GAAM,CAAE,iBAAgB,qBAAsBA,EAAAA,oBAAoB,CAC5D,CAAE,cAAa,YAAaC,EAAAA,iBAAiB,CAG7C,GAAA,EAAA,EAAA,aACE,EAAQ,OAAQ,GAAQ,EAAI,OAASC,EAAAA,SAAS,YAAY,CAChE,CAAC,EAAQ,CACV,CA2CD,OACE,EAAA,EAAA,KAACC,EAAAA,gBAAD,CACE,SAAA,EAAA,EAAA,iBAzCA,EAAkB,CAChB,gBACA,QAAS,EACV,CAAC,CACJ,CAAC,EAAe,EAAgB,CACjC,CAqCG,SAAA,EAAA,EAAA,iBAjCA,EAAY,CACV,KAAM,GAAGC,EAAAA,WAAW,iCAAiC,OACrD,KAAM,CACJ,gBACA,QAAS,EACV,CACD,WACD,CAAC,CACJ,CAAC,EAAe,EAAgB,CACjC,CAyBG,WAAA,EAAA,EAAA,iBArBA,EAAY,CACV,KAAM,GAAGA,EAAAA,WAAW,iCAAiC,OACrD,KAAM,KACN,WACD,CAAC,CACJ,CAAC,EAAS,CACX,CAgBG,aAAA,EAAA,EAAA,cAZC,GAAgB,gBAAkB,IAChC,GAAgB,SAAS,QAAU,GAAK,IAAA,EAAA,EAAA,eAC3B,GAAgB,SAAW,EAAE,CAAE,EAAgB,GAC/D,GACF,CAAC,EAAgB,EAAiB,EAAc,CACjD,CASI,WACe,CAAA,EAIT,GAER,CAAE,WAAU,GAAG,KAAY,CAC9B,GAAM,CAAE,WAAYC,EAAAA,kBAAkB,CAChC,CAAE,iBAAkBC,EAAAA,oBAAoB,CAU9C,OARI,GAAW,CAAC,GAEZ,EAAA,EAAA,KAAC,EAAD,CAA+B,GAAI,EAChC,WAC6B,CAAA,CAI7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"DictionariesRecordContext.cjs","names":["useCrossFrameState","MessageKey"],"sources":["../../../src/editor/DictionariesRecordContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { Dictionary } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext, useMemo } from 'preact/hooks';\nimport {\n type CrossFrameStateUpdater,\n useCrossFrameState,\n} from './useCrossFrameState';\n\nexport type DictionaryContent = Record<Dictionary['key'], Dictionary>;\n\ntype DictionariesRecordStatesContextType = {\n localeDictionaries: DictionaryContent;\n};\ntype DictionariesRecordActionsContextType = {\n setLocaleDictionaries: CrossFrameStateUpdater<DictionaryContent>;\n setLocaleDictionary: (dictionary: Dictionary) => void;\n};\n\nconst DictionariesRecordStatesContext = createContext<\n DictionariesRecordStatesContextType | undefined\n>(undefined);\nconst DictionariesRecordActionsContext = createContext<\n DictionariesRecordActionsContextType | undefined\n>(undefined);\n\nexport const DictionariesRecordProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [localeDictionaries, setLocaleDictionaries] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED,\n undefined\n );\n\n const stateValue = useMemo(\n () => ({\n localeDictionaries: localeDictionaries ?? {},\n }),\n [localeDictionaries]\n );\n\n const actionValue = useMemo(\n () => ({\n setLocaleDictionaries,\n setLocaleDictionary: (dictionary: Dictionary) => {\n setLocaleDictionaries((dictionaries) => ({\n ...dictionaries,\n [String(dictionary.localId)]: dictionary,\n }));\n },\n }),\n [setLocaleDictionaries]\n );\n\n return (\n <DictionariesRecordStatesContext.Provider value={stateValue}>\n <DictionariesRecordActionsContext.Provider value={actionValue}>\n {children}\n </DictionariesRecordActionsContext.Provider>\n </DictionariesRecordStatesContext.Provider>\n );\n};\n\nexport const useDictionariesRecordActions = () =>\n useContext(DictionariesRecordActionsContext);\n\nexport const useDictionariesRecord = () => {\n const actionsContext = useDictionariesRecordActions();\n const statesContext = useContext(DictionariesRecordStatesContext);\n\n if (!statesContext) {\n throw new Error(\n 'useDictionariesRecordStates must be used within a DictionariesRecordProvider'\n );\n }\n\n return { ...statesContext, ...actionsContext };\n};\n"],"mappings":"yRAyBA,MAAM,GAAA,EAAA,EAAA,eAEJ,IAAA,GAAU,CACN,GAAA,EAAA,EAAA,eAEJ,IAAA,GAAU,CAEC,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,EAAoB,GACzBA,EAAAA,mBACEC,EAAAA,WAAW,qCACX,IAAA,GACD,CAEG,GAAA,EAAA,EAAA,cACG,CACL,mBAAoB,GAAsB,EAAE,CAC7C,EACD,CAAC,EAAmB,CACrB,CAEK,GAAA,EAAA,EAAA,cACG,CACL,wBACA,oBAAsB,GAA2B,CAC/C,EAAuB,IAAkB,CACvC,GAAG,GACF,OAAO,EAAW,QAAQ,EAAG,EAC/B,EAAE,EAEN,EACD,CAAC,EAAsB,CACxB,CAED,OACE,EAAA,EAAA,KAAC,EAAgC,SAAA,CAAS,MAAO,YAC/C,EAAA,EAAA,KAAC,EAAiC,SAAA,CAAS,MAAO,EAC/C,YACyC,EACH,EAIlC,OAAA,EAAA,EAAA,YACA,EAAiC,CAEjC,MAA8B,CACzC,IAAM,EAAiB,GAA8B,CAC/C,GAAA,EAAA,EAAA,YAA2B,EAAgC,CAEjE,GAAI,CAAC,EACH,MAAU,MACR,+EACD,CAGH,MAAO,CAAE,GAAG,EAAe,GAAG,EAAgB"}
1
+ {"version":3,"file":"DictionariesRecordContext.cjs","names":["useCrossFrameState","MessageKey"],"sources":["../../../src/editor/DictionariesRecordContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { Dictionary } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext, useMemo } from 'preact/hooks';\nimport {\n type CrossFrameStateUpdater,\n useCrossFrameState,\n} from './useCrossFrameState';\n\nexport type DictionaryContent = Record<Dictionary['key'], Dictionary>;\n\ntype DictionariesRecordStatesContextType = {\n localeDictionaries: DictionaryContent;\n};\ntype DictionariesRecordActionsContextType = {\n setLocaleDictionaries: CrossFrameStateUpdater<DictionaryContent>;\n setLocaleDictionary: (dictionary: Dictionary) => void;\n};\n\nconst DictionariesRecordStatesContext = createContext<\n DictionariesRecordStatesContextType | undefined\n>(undefined);\nconst DictionariesRecordActionsContext = createContext<\n DictionariesRecordActionsContextType | undefined\n>(undefined);\n\nexport const DictionariesRecordProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [localeDictionaries, setLocaleDictionaries] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED,\n undefined\n );\n\n const stateValue = useMemo(\n () => ({\n localeDictionaries: localeDictionaries ?? {},\n }),\n [localeDictionaries]\n );\n\n const actionValue = useMemo(\n () => ({\n setLocaleDictionaries,\n setLocaleDictionary: (dictionary: Dictionary) => {\n setLocaleDictionaries((dictionaries) => ({\n ...dictionaries,\n [String(dictionary.localId)]: dictionary,\n }));\n },\n }),\n [setLocaleDictionaries]\n );\n\n return (\n <DictionariesRecordStatesContext.Provider value={stateValue}>\n <DictionariesRecordActionsContext.Provider value={actionValue}>\n {children}\n </DictionariesRecordActionsContext.Provider>\n </DictionariesRecordStatesContext.Provider>\n );\n};\n\nexport const useDictionariesRecordActions = () =>\n useContext(DictionariesRecordActionsContext);\n\nexport const useDictionariesRecord = () => {\n const actionsContext = useDictionariesRecordActions();\n const statesContext = useContext(DictionariesRecordStatesContext);\n\n if (!statesContext) {\n throw new Error(\n 'useDictionariesRecordStates must be used within a DictionariesRecordProvider'\n );\n }\n\n return { ...statesContext, ...actionsContext };\n};\n"],"mappings":"yRAyBA,MAAM,GAAA,EAAA,EAAA,eAEJ,IAAA,GAAU,CACN,GAAA,EAAA,EAAA,eAEJ,IAAA,GAAU,CAEC,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,EAAoB,GACzBA,EAAAA,mBACEC,EAAAA,WAAW,qCACX,IAAA,GACD,CAEG,GAAA,EAAA,EAAA,cACG,CACL,mBAAoB,GAAsB,EAAE,CAC7C,EACD,CAAC,EAAmB,CACrB,CAEK,GAAA,EAAA,EAAA,cACG,CACL,wBACA,oBAAsB,GAA2B,CAC/C,EAAuB,IAAkB,CACvC,GAAG,GACF,OAAO,EAAW,QAAQ,EAAG,EAC/B,EAAE,EAEN,EACD,CAAC,EAAsB,CACxB,CAED,OACE,EAAA,EAAA,KAAC,EAAgC,SAAjC,CAA0C,MAAO,YAC/C,EAAA,EAAA,KAAC,EAAiC,SAAlC,CAA2C,MAAO,EAC/C,WACyC,CAAA,CACH,CAAA,EAIlC,OAAA,EAAA,EAAA,YACA,EAAiC,CAEjC,MAA8B,CACzC,IAAM,EAAiB,GAA8B,CAC/C,GAAA,EAAA,EAAA,YAA2B,EAAgC,CAEjE,GAAI,CAAC,EACH,MAAU,MACR,+EACD,CAGH,MAAO,CAAE,GAAG,EAAe,GAAG,EAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"EditedContentContext.cjs","names":["useCrossFrameMessageListener","MessageKey","useDictionariesRecord","useCrossFrameState","NodeType"],"sources":["../../../src/editor/EditedContentContext.tsx"],"sourcesContent":["'use client';\n\nimport {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core/dictionaryManipulator';\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 FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\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: CrossFrameStateUpdater<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,>(\n state?: S | ((prevState: S) => S),\n prevState?: S\n): S =>\n typeof state === 'function'\n ? (state as (prevState?: S) => S)(prevState)\n : (state as S);\n\nexport const EditedContentProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const { localeDictionaries } = useDictionariesRecord();\n\n const [editedContent, setEditedContentState] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED\n );\n\n const setEditedDictionary: CrossFrameStateUpdater<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\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 = { ...prev };\n delete filtered[dictionaryLocalId];\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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"}
1
+ {"version":3,"file":"EditedContentContext.cjs","names":["useCrossFrameMessageListener","MessageKey","useDictionariesRecord","useCrossFrameState","NodeType"],"sources":["../../../src/editor/EditedContentContext.tsx"],"sourcesContent":["'use client';\n\nimport {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core/dictionaryManipulator';\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 FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\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: CrossFrameStateUpdater<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,>(\n state?: S | ((prevState: S) => S),\n prevState?: S\n): S =>\n typeof state === 'function'\n ? (state as (prevState?: S) => S)(prevState)\n : (state as S);\n\nexport const EditedContentProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const { localeDictionaries } = useDictionariesRecord();\n\n const [editedContent, setEditedContentState] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED\n );\n\n const setEditedDictionary: CrossFrameStateUpdater<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\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 = { ...prev };\n delete filtered[dictionaryLocalId];\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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"EditorEnabledContext.cjs","names":["useCrossFrameState","MessageKey","useCrossFrameMessageListener"],"sources":["../../../src/editor/EditorEnabledContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\nimport {\n type CrossFrameStateOptions,\n useCrossFrameState,\n} from './useCrossFrameState';\n\nexport type EditorEnabledStateProps = {\n enabled: boolean;\n};\n\nconst EditorEnabledContext = createContext<EditorEnabledStateProps>({\n enabled: false,\n});\n\nexport const useEditorEnabledState = (options?: CrossFrameStateOptions) =>\n useCrossFrameState(MessageKey.INTLAYER_EDITOR_ENABLED, false, options);\n\nexport const usePostEditorEnabledState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITOR_ENABLED}/post`,\n onEventTriggered\n );\n\nexport const useGetEditorEnabledState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITOR_ENABLED}/get`,\n onEventTriggered\n );\n\nexport const EditorEnabledProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [isEnabled] = useEditorEnabledState({\n emit: false,\n receive: true,\n });\n\n return (\n <EditorEnabledContext.Provider value={{ enabled: isEnabled }}>\n {children}\n </EditorEnabledContext.Provider>\n );\n};\n\nexport const useEditorEnabled = () => useContext(EditorEnabledContext);\n"],"mappings":"yUAmBA,MAAM,GAAA,EAAA,EAAA,eAA8D,CAClE,QAAS,GACV,CAAC,CAEW,EAAyB,GACpCA,EAAAA,mBAAmBC,EAAAA,WAAW,wBAAyB,GAAO,EAAQ,CAE3D,EACX,GAEAC,EAAAA,6BACE,GAAGD,EAAAA,WAAW,wBAAwB,OACtC,EACD,CAEU,EACX,GAEAC,EAAAA,6BACE,GAAGD,EAAAA,WAAW,wBAAwB,MACtC,EACD,CAEU,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,GAAa,EAAsB,CACxC,KAAM,GACN,QAAS,GACV,CAAC,CAEF,OACE,EAAA,EAAA,KAAC,EAAqB,SAAA,CAAS,MAAO,CAAE,QAAS,EAAW,CACzD,YAC6B,EAIvB,OAAA,EAAA,EAAA,YAAoC,EAAqB"}
1
+ {"version":3,"file":"EditorEnabledContext.cjs","names":["useCrossFrameState","MessageKey","useCrossFrameMessageListener"],"sources":["../../../src/editor/EditorEnabledContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\nimport {\n type CrossFrameStateOptions,\n useCrossFrameState,\n} from './useCrossFrameState';\n\nexport type EditorEnabledStateProps = {\n enabled: boolean;\n};\n\nconst EditorEnabledContext = createContext<EditorEnabledStateProps>({\n enabled: false,\n});\n\nexport const useEditorEnabledState = (options?: CrossFrameStateOptions) =>\n useCrossFrameState(MessageKey.INTLAYER_EDITOR_ENABLED, false, options);\n\nexport const usePostEditorEnabledState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITOR_ENABLED}/post`,\n onEventTriggered\n );\n\nexport const useGetEditorEnabledState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITOR_ENABLED}/get`,\n onEventTriggered\n );\n\nexport const EditorEnabledProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [isEnabled] = useEditorEnabledState({\n emit: false,\n receive: true,\n });\n\n return (\n <EditorEnabledContext.Provider value={{ enabled: isEnabled }}>\n {children}\n </EditorEnabledContext.Provider>\n );\n};\n\nexport const useEditorEnabled = () => useContext(EditorEnabledContext);\n"],"mappings":"yUAmBA,MAAM,GAAA,EAAA,EAAA,eAA8D,CAClE,QAAS,GACV,CAAC,CAEW,EAAyB,GACpCA,EAAAA,mBAAmBC,EAAAA,WAAW,wBAAyB,GAAO,EAAQ,CAE3D,EACX,GAEAC,EAAAA,6BACE,GAAGD,EAAAA,WAAW,wBAAwB,OACtC,EACD,CAEU,EACX,GAEAC,EAAAA,6BACE,GAAGD,EAAAA,WAAW,wBAAwB,MACtC,EACD,CAEU,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,GAAa,EAAsB,CACxC,KAAM,GACN,QAAS,GACV,CAAC,CAEF,OACE,EAAA,EAAA,KAAC,EAAqB,SAAtB,CAA+B,MAAO,CAAE,QAAS,EAAW,CACzD,WAC6B,CAAA,EAIvB,OAAA,EAAA,EAAA,YAAoC,EAAqB"}
@@ -1 +1 @@
1
- {"version":3,"file":"EditorProvider.cjs","names":["useGetEditedContentState","DictionariesRecordProvider","EditedContentProvider","FocusDictionaryProvider","useGetEditorEnabledState","useEditorEnabled","EditorEnabledProvider","ConfigurationProvider","CommunicatorProvider"],"sources":["../../../src/editor/EditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport type {\n ComponentChildren,\n FunctionalComponent,\n RenderableProps,\n} from 'preact';\nimport { useEffect, useState } from 'preact/hooks';\nimport {\n CommunicatorProvider,\n type CommunicatorProviderProps,\n} from './CommunicatorContext';\nimport {\n ConfigurationProvider,\n type ConfigurationProviderProps,\n} from './ConfigurationContext';\nimport { DictionariesRecordProvider } from './DictionariesRecordContext';\nimport {\n EditedContentProvider,\n useGetEditedContentState,\n} from './EditedContentContext';\nimport {\n EditorEnabledProvider,\n useEditorEnabled,\n useGetEditorEnabledState,\n} from './EditorEnabledContext';\nimport { FocusDictionaryProvider } from './FocusDictionaryContext';\n\n/**\n * This component add all the providers needed by the editor.\n * It is used to wrap the application, or the editor to work together.\n */\nconst EditorProvidersWrapper: FunctionalComponent<RenderableProps<{}>> = ({\n children,\n}) => {\n const getEditedContentState = useGetEditedContentState();\n\n useEffect(() => {\n getEditedContentState();\n }, []);\n\n return (\n <DictionariesRecordProvider>\n <EditedContentProvider>\n <FocusDictionaryProvider>{children}</FocusDictionaryProvider>\n </EditedContentProvider>\n </DictionariesRecordProvider>\n );\n};\n\ntype FallbackProps = {\n fallback: ComponentChildren;\n};\n\n/**\n * This component check if the editor is enabled to render the editor providers.\n */\nconst EditorEnabledCheckRenderer: FunctionalComponent<\n RenderableProps<FallbackProps>\n> = ({ children, fallback }) => {\n const getEditorEnabled = useGetEditorEnabledState();\n\n const { enabled } = useEditorEnabled();\n\n useEffect(() => {\n if (enabled) return;\n\n // Check if the editor is wrapping the application\n getEditorEnabled();\n }, [enabled]);\n\n return enabled ? children : fallback;\n};\n\n/**\n * This component is used to check if the editor is wrapping the application.\n * It avoid to send window.postMessage to the application if the editor is not wrapping the application.\n */\nconst IframeCheckRenderer: FunctionalComponent<\n RenderableProps<FallbackProps>\n> = ({ children, fallback }) => {\n const [isInIframe, setIsInIframe] = useState(false);\n\n useEffect(() => {\n setIsInIframe(window.self !== window.top);\n }, []);\n\n return isInIframe ? children : fallback;\n};\n\nexport type EditorProviderProps = CommunicatorProviderProps &\n ConfigurationProviderProps;\n\nexport const EditorProvider: FunctionalComponent<\n RenderableProps<EditorProviderProps>\n> = ({ children, configuration, ...props }) => (\n <EditorEnabledProvider>\n <ConfigurationProvider configuration={configuration}>\n <IframeCheckRenderer fallback={children}>\n <CommunicatorProvider {...props}>\n <EditorEnabledCheckRenderer fallback={children}>\n <EditorProvidersWrapper>{children}</EditorProvidersWrapper>\n </EditorEnabledCheckRenderer>\n </CommunicatorProvider>\n </IframeCheckRenderer>\n </ConfigurationProvider>\n </EditorEnabledProvider>\n);\n"],"mappings":"ubAgCA,MAAM,GAAoE,CACxE,cACI,CACJ,IAAM,EAAwBA,EAAAA,0BAA0B,CAMxD,OAJA,EAAA,EAAA,eAAgB,CACd,GAAuB,EACtB,EAAE,CAAC,EAGJ,EAAA,EAAA,KAACC,EAAAA,2BAAAA,CAAAA,UACC,EAAA,EAAA,KAACC,EAAAA,sBAAAA,CAAAA,UACC,EAAA,EAAA,KAACC,EAAAA,wBAAAA,CAAyB,WAAA,CAAmC,CAAA,CACvC,CAAA,CACG,EAW3B,GAED,CAAE,WAAU,cAAe,CAC9B,IAAM,EAAmBC,EAAAA,0BAA0B,CAE7C,CAAE,WAAYC,EAAAA,kBAAkB,CAStC,OAPA,EAAA,EAAA,eAAgB,CACV,GAGJ,GAAkB,EACjB,CAAC,EAAQ,CAAC,CAEN,EAAU,EAAW,GAOxB,GAED,CAAE,WAAU,cAAe,CAC9B,GAAM,CAAC,EAAY,IAAA,EAAA,EAAA,UAA0B,GAAM,CAMnD,OAJA,EAAA,EAAA,eAAgB,CACd,EAAc,OAAO,OAAS,OAAO,IAAI,EACxC,EAAE,CAAC,CAEC,EAAa,EAAW,GAMpB,GAER,CAAE,WAAU,gBAAe,GAAG,MACjC,EAAA,EAAA,KAACC,EAAAA,sBAAAA,CAAAA,UACC,EAAA,EAAA,KAACC,EAAAA,sBAAAA,CAAqC,0BACpC,EAAA,EAAA,KAAC,EAAA,CAAoB,SAAU,YAC7B,EAAA,EAAA,KAACC,EAAAA,qBAAAA,CAAqB,GAAI,YACxB,EAAA,EAAA,KAAC,EAAA,CAA2B,SAAU,YACpC,EAAA,EAAA,KAAC,EAAA,CAAwB,WAAA,CAAkC,EAChC,EACR,EACH,EACA,CAAA,CACF"}
1
+ {"version":3,"file":"EditorProvider.cjs","names":["useGetEditedContentState","DictionariesRecordProvider","EditedContentProvider","FocusDictionaryProvider","useGetEditorEnabledState","useEditorEnabled","EditorEnabledProvider","ConfigurationProvider","CommunicatorProvider"],"sources":["../../../src/editor/EditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport type {\n ComponentChildren,\n FunctionalComponent,\n RenderableProps,\n} from 'preact';\nimport { useEffect, useState } from 'preact/hooks';\nimport {\n CommunicatorProvider,\n type CommunicatorProviderProps,\n} from './CommunicatorContext';\nimport {\n ConfigurationProvider,\n type ConfigurationProviderProps,\n} from './ConfigurationContext';\nimport { DictionariesRecordProvider } from './DictionariesRecordContext';\nimport {\n EditedContentProvider,\n useGetEditedContentState,\n} from './EditedContentContext';\nimport {\n EditorEnabledProvider,\n useEditorEnabled,\n useGetEditorEnabledState,\n} from './EditorEnabledContext';\nimport { FocusDictionaryProvider } from './FocusDictionaryContext';\n\n/**\n * This component add all the providers needed by the editor.\n * It is used to wrap the application, or the editor to work together.\n */\nconst EditorProvidersWrapper: FunctionalComponent<RenderableProps<{}>> = ({\n children,\n}) => {\n const getEditedContentState = useGetEditedContentState();\n\n useEffect(() => {\n getEditedContentState();\n }, []);\n\n return (\n <DictionariesRecordProvider>\n <EditedContentProvider>\n <FocusDictionaryProvider>{children}</FocusDictionaryProvider>\n </EditedContentProvider>\n </DictionariesRecordProvider>\n );\n};\n\ntype FallbackProps = {\n fallback: ComponentChildren;\n};\n\n/**\n * This component check if the editor is enabled to render the editor providers.\n */\nconst EditorEnabledCheckRenderer: FunctionalComponent<\n RenderableProps<FallbackProps>\n> = ({ children, fallback }) => {\n const getEditorEnabled = useGetEditorEnabledState();\n\n const { enabled } = useEditorEnabled();\n\n useEffect(() => {\n if (enabled) return;\n\n // Check if the editor is wrapping the application\n getEditorEnabled();\n }, [enabled]);\n\n return enabled ? children : fallback;\n};\n\n/**\n * This component is used to check if the editor is wrapping the application.\n * It avoid to send window.postMessage to the application if the editor is not wrapping the application.\n */\nconst IframeCheckRenderer: FunctionalComponent<\n RenderableProps<FallbackProps>\n> = ({ children, fallback }) => {\n const [isInIframe, setIsInIframe] = useState(false);\n\n useEffect(() => {\n setIsInIframe(window.self !== window.top);\n }, []);\n\n return isInIframe ? children : fallback;\n};\n\nexport type EditorProviderProps = CommunicatorProviderProps &\n ConfigurationProviderProps;\n\nexport const EditorProvider: FunctionalComponent<\n RenderableProps<EditorProviderProps>\n> = ({ children, configuration, ...props }) => (\n <EditorEnabledProvider>\n <ConfigurationProvider configuration={configuration}>\n <IframeCheckRenderer fallback={children}>\n <CommunicatorProvider {...props}>\n <EditorEnabledCheckRenderer fallback={children}>\n <EditorProvidersWrapper>{children}</EditorProvidersWrapper>\n </EditorEnabledCheckRenderer>\n </CommunicatorProvider>\n </IframeCheckRenderer>\n </ConfigurationProvider>\n </EditorEnabledProvider>\n);\n"],"mappings":"ubAgCA,MAAM,GAAoE,CACxE,cACI,CACJ,IAAM,EAAwBA,EAAAA,0BAA0B,CAMxD,OAJA,EAAA,EAAA,eAAgB,CACd,GAAuB,EACtB,EAAE,CAAC,EAGJ,EAAA,EAAA,KAACC,EAAAA,2BAAD,CAAA,UACE,EAAA,EAAA,KAACC,EAAAA,sBAAD,CAAA,UACE,EAAA,EAAA,KAACC,EAAAA,wBAAD,CAA0B,WAAmC,CAAA,CACvC,CAAA,CACG,CAAA,EAW3B,GAED,CAAE,WAAU,cAAe,CAC9B,IAAM,EAAmBC,EAAAA,0BAA0B,CAE7C,CAAE,WAAYC,EAAAA,kBAAkB,CAStC,OAPA,EAAA,EAAA,eAAgB,CACV,GAGJ,GAAkB,EACjB,CAAC,EAAQ,CAAC,CAEN,EAAU,EAAW,GAOxB,GAED,CAAE,WAAU,cAAe,CAC9B,GAAM,CAAC,EAAY,IAAA,EAAA,EAAA,UAA0B,GAAM,CAMnD,OAJA,EAAA,EAAA,eAAgB,CACd,EAAc,OAAO,OAAS,OAAO,IAAI,EACxC,EAAE,CAAC,CAEC,EAAa,EAAW,GAMpB,GAER,CAAE,WAAU,gBAAe,GAAG,MACjC,EAAA,EAAA,KAACC,EAAAA,sBAAD,CAAA,UACE,EAAA,EAAA,KAACC,EAAAA,sBAAD,CAAsC,0BACpC,EAAA,EAAA,KAAC,EAAD,CAAqB,SAAU,YAC7B,EAAA,EAAA,KAACC,EAAAA,qBAAD,CAAsB,GAAI,YACxB,EAAA,EAAA,KAAC,EAAD,CAA4B,SAAU,YACpC,EAAA,EAAA,KAAC,EAAD,CAAyB,WAAkC,CAAA,CAChC,CAAA,CACR,CAAA,CACH,CAAA,CACA,CAAA,CACF,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"FocusDictionaryContext.cjs","names":["useCrossFrameState","MessageKey"],"sources":["../../../src/editor/FocusDictionaryContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { KeyPath } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport {\n type CrossFrameStateUpdater,\n useCrossFrameState,\n} from './useCrossFrameState';\n\ntype DictionaryPath = string;\n\nexport type FileContent = {\n dictionaryKey: string;\n keyPath?: KeyPath[];\n dictionaryPath?: DictionaryPath;\n};\n\ntype FocusDictionaryState = {\n focusedContent: FileContent | null;\n};\n\ntype FocusDictionaryActions = {\n setFocusedContent: CrossFrameStateUpdater<FileContent | null>;\n setFocusedContentKeyPath: (keyPath: KeyPath[]) => void;\n};\n\nconst FocusDictionaryStateContext = createContext<\n FocusDictionaryState | undefined\n>(undefined);\nconst FocusDictionaryActionsContext = createContext<\n FocusDictionaryActions | undefined\n>(undefined);\n\nexport const FocusDictionaryProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [focusedContent, setFocusedContent] =\n useCrossFrameState<FileContent | null>(\n MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED,\n null\n );\n\n const setFocusedContentKeyPath = (keyPath: KeyPath[]) => {\n setFocusedContent((prev) => {\n if (!prev) {\n return prev; // nothing to update if there's no focused content\n }\n return { ...prev, keyPath };\n });\n };\n\n return (\n <FocusDictionaryStateContext.Provider value={{ focusedContent }}>\n <FocusDictionaryActionsContext.Provider\n value={{ setFocusedContent, setFocusedContentKeyPath }}\n >\n {children}\n </FocusDictionaryActionsContext.Provider>\n </FocusDictionaryStateContext.Provider>\n );\n};\n\nexport const useFocusDictionaryActions = () => {\n const context = useContext(FocusDictionaryActionsContext);\n if (context === undefined) {\n throw new Error(\n 'useFocusDictionaryActions must be used within a FocusDictionaryProvider'\n );\n }\n return context;\n};\n\nexport const useFocusDictionary = () => {\n const actionContext = useFocusDictionaryActions();\n const stateContext = useContext(FocusDictionaryStateContext);\n\n if (stateContext === undefined) {\n throw new Error(\n 'useFocusDictionaryState must be used within a FocusDictionaryProvider'\n );\n }\n\n return { ...stateContext, ...actionContext };\n};\n"],"mappings":"yRAgCA,MAAM,GAAA,EAAA,EAAA,eAEJ,IAAA,GAAU,CACN,GAAA,EAAA,EAAA,eAEJ,IAAA,GAAU,CAEC,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,EAAgB,GACrBA,EAAAA,mBACEC,EAAAA,WAAW,iCACX,KACD,CAWH,OACE,EAAA,EAAA,KAAC,EAA4B,SAAA,CAAS,MAAO,CAAE,iBAAgB,WAC7D,EAAA,EAAA,KAAC,EAA8B,SAAA,CAC7B,MAAO,CAAE,oBAAmB,yBAZA,GAAuB,CACvD,EAAmB,GACZ,GAGE,CAAE,GAAG,EAAM,UAAS,CAC3B,EAMwD,CAErD,YACsC,EACJ,EAI9B,MAAkC,CAC7C,IAAM,GAAA,EAAA,EAAA,YAAqB,EAA8B,CACzD,GAAI,IAAY,IAAA,GACd,MAAU,MACR,0EACD,CAEH,OAAO,GAGI,MAA2B,CACtC,IAAM,EAAgB,GAA2B,CAC3C,GAAA,EAAA,EAAA,YAA0B,EAA4B,CAE5D,GAAI,IAAiB,IAAA,GACnB,MAAU,MACR,wEACD,CAGH,MAAO,CAAE,GAAG,EAAc,GAAG,EAAe"}
1
+ {"version":3,"file":"FocusDictionaryContext.cjs","names":["useCrossFrameState","MessageKey"],"sources":["../../../src/editor/FocusDictionaryContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { KeyPath } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport {\n type CrossFrameStateUpdater,\n useCrossFrameState,\n} from './useCrossFrameState';\n\ntype DictionaryPath = string;\n\nexport type FileContent = {\n dictionaryKey: string;\n keyPath?: KeyPath[];\n dictionaryPath?: DictionaryPath;\n};\n\ntype FocusDictionaryState = {\n focusedContent: FileContent | null;\n};\n\ntype FocusDictionaryActions = {\n setFocusedContent: CrossFrameStateUpdater<FileContent | null>;\n setFocusedContentKeyPath: (keyPath: KeyPath[]) => void;\n};\n\nconst FocusDictionaryStateContext = createContext<\n FocusDictionaryState | undefined\n>(undefined);\nconst FocusDictionaryActionsContext = createContext<\n FocusDictionaryActions | undefined\n>(undefined);\n\nexport const FocusDictionaryProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [focusedContent, setFocusedContent] =\n useCrossFrameState<FileContent | null>(\n MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED,\n null\n );\n\n const setFocusedContentKeyPath = (keyPath: KeyPath[]) => {\n setFocusedContent((prev) => {\n if (!prev) {\n return prev; // nothing to update if there's no focused content\n }\n return { ...prev, keyPath };\n });\n };\n\n return (\n <FocusDictionaryStateContext.Provider value={{ focusedContent }}>\n <FocusDictionaryActionsContext.Provider\n value={{ setFocusedContent, setFocusedContentKeyPath }}\n >\n {children}\n </FocusDictionaryActionsContext.Provider>\n </FocusDictionaryStateContext.Provider>\n );\n};\n\nexport const useFocusDictionaryActions = () => {\n const context = useContext(FocusDictionaryActionsContext);\n if (context === undefined) {\n throw new Error(\n 'useFocusDictionaryActions must be used within a FocusDictionaryProvider'\n );\n }\n return context;\n};\n\nexport const useFocusDictionary = () => {\n const actionContext = useFocusDictionaryActions();\n const stateContext = useContext(FocusDictionaryStateContext);\n\n if (stateContext === undefined) {\n throw new Error(\n 'useFocusDictionaryState must be used within a FocusDictionaryProvider'\n );\n }\n\n return { ...stateContext, ...actionContext };\n};\n"],"mappings":"yRAgCA,MAAM,GAAA,EAAA,EAAA,eAEJ,IAAA,GAAU,CACN,GAAA,EAAA,EAAA,eAEJ,IAAA,GAAU,CAEC,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,EAAgB,GACrBA,EAAAA,mBACEC,EAAAA,WAAW,iCACX,KACD,CAWH,OACE,EAAA,EAAA,KAAC,EAA4B,SAA7B,CAAsC,MAAO,CAAE,iBAAgB,WAC7D,EAAA,EAAA,KAAC,EAA8B,SAA/B,CACE,MAAO,CAAE,oBAAmB,yBAZA,GAAuB,CACvD,EAAmB,GACZ,GAGE,CAAE,GAAG,EAAM,UAAS,CAC3B,EAMwD,CAErD,WACsC,CAAA,CACJ,CAAA,EAI9B,MAAkC,CAC7C,IAAM,GAAA,EAAA,EAAA,YAAqB,EAA8B,CACzD,GAAI,IAAY,IAAA,GACd,MAAU,MACR,0EACD,CAEH,OAAO,GAGI,MAA2B,CACtC,IAAM,EAAgB,GAA2B,CAC3C,GAAA,EAAA,EAAA,YAA0B,EAA4B,CAE5D,GAAI,IAAiB,IAAA,GACnB,MAAU,MACR,wEACD,CAGH,MAAO,CAAE,GAAG,EAAc,GAAG,EAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"IntlayerEditorProvider.cjs","names":["useDictionariesRecordActions","configuration","useEditorEnabled","EditorProvider"],"sources":["../../../src/editor/IntlayerEditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport type { ComponentChildren, FunctionComponent } from 'preact';\nimport { useEffect } from 'preact/hooks';\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 // Load dictionaries dynamically to do not impact the bundle, and send them to the editor\n import('@intlayer/unmerged-dictionaries-entry').then((mod) => {\n const unmergedDictionaries = mod.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\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":"scAWA,MAAM,MAAsD,CAI1D,EAAA,uBAAuB,CAKvB,EAAA,2BAA2B,CAK3B,GAAM,CAAE,yBAA0BA,EAAAA,8BAA8B,EAAI,EAAE,CAgBtE,OAdA,EAAA,EAAA,eAAgB,CAEd,OAAO,yCAAyC,KAAM,GAAQ,CAC5D,IAAM,EAAuB,EAAI,yBAAyB,CACpD,EAAmB,OAAO,YAC9B,OAAO,OAAO,EAAqB,CAChC,MAAM,CACN,IAAK,GAAe,CAAC,EAAW,QAAS,EAAW,CAAC,CACzD,CAED,IAAwB,EAAiB,EACzC,EACD,EAAE,CAAC,EAEC,EAAA,EAAA,KAAA,EAAA,SAAA,EAAA,CAAK,EAGR,CAAE,UAAWC,EAAAA,QAEb,MAA8C,CAClD,GAAM,CAAE,WAAYC,EAAAA,kBAAkB,CAEtC,OAAO,GAAU,EAAA,EAAA,KAAC,EAAA,EAAA,CAA6B,EAAG,EAAA,EAAA,KAAA,EAAA,SAAA,EAAA,CAAK,EAG5C,GAEP,CAAE,eAEJ,EAAA,EAAA,MAACC,EAAAA,eAAAA,CACC,YAAc,GAAc,CACtB,OAAO,OAAW,KAEH,OAAO,OAAS,OAAO,MAGtC,EAAO,eAAe,OAAS,GACjC,QAAQ,YACN,EAGA,EAAO,eACR,CAGC,EAAO,UAAU,OAAS,GAC5B,OAAO,QAAQ,YACb,EAGA,EAAO,UACR,CAGC,EAAO,OAAO,OAAS,GACzB,OAAO,QAAQ,YACb,EAGA,EAAO,OACR,GAGL,eAAgB,CACd,GAAQ,UACR,GAAQ,OACR,GAAQ,eACT,CACD,cAAeF,EAAAA,mBAEf,EAAA,EAAA,KAAC,EAAA,EAAA,CAAqB,CACrB,EAAA,EACc"}
1
+ {"version":3,"file":"IntlayerEditorProvider.cjs","names":["useDictionariesRecordActions","configuration","useEditorEnabled","EditorProvider"],"sources":["../../../src/editor/IntlayerEditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport type { ComponentChildren, FunctionComponent } from 'preact';\nimport { useEffect } from 'preact/hooks';\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 // Load dictionaries dynamically to do not impact the bundle, and send them to the editor\n import('@intlayer/unmerged-dictionaries-entry').then((mod) => {\n const unmergedDictionaries = mod.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\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":"scAWA,MAAM,MAAsD,CAI1D,EAAA,uBAAuB,CAKvB,EAAA,2BAA2B,CAK3B,GAAM,CAAE,yBAA0BA,EAAAA,8BAA8B,EAAI,EAAE,CAgBtE,OAdA,EAAA,EAAA,eAAgB,CAEd,OAAO,yCAAyC,KAAM,GAAQ,CAC5D,IAAM,EAAuB,EAAI,yBAAyB,CACpD,EAAmB,OAAO,YAC9B,OAAO,OAAO,EAAqB,CAChC,MAAM,CACN,IAAK,GAAe,CAAC,EAAW,QAAS,EAAW,CAAC,CACzD,CAED,IAAwB,EAAiB,EACzC,EACD,EAAE,CAAC,EAEC,EAAA,EAAA,KAAA,EAAA,SAAA,EAAK,CAAA,EAGR,CAAE,UAAWC,EAAAA,QAEb,MAA8C,CAClD,GAAM,CAAE,WAAYC,EAAAA,kBAAkB,CAEtC,OAAO,GAAU,EAAA,EAAA,KAAC,EAAD,EAA8B,CAAA,EAAG,EAAA,EAAA,KAAA,EAAA,SAAA,EAAK,CAAA,EAG5C,GAEP,CAAE,eAEJ,EAAA,EAAA,MAACC,EAAAA,eAAD,CACE,YAAc,GAAc,CACtB,OAAO,OAAW,KAEH,OAAO,OAAS,OAAO,MAGtC,EAAO,eAAe,OAAS,GACjC,QAAQ,YACN,EAGA,EAAO,eACR,CAGC,EAAO,UAAU,OAAS,GAC5B,OAAO,QAAQ,YACb,EAGA,EAAO,UACR,CAGC,EAAO,OAAO,OAAS,GACzB,OAAO,QAAQ,YACb,EAGA,EAAO,OACR,GAGL,eAAgB,CACd,GAAQ,UACR,GAAQ,OACR,GAAQ,eACT,CACD,cAAeF,EAAAA,iBAvCjB,EAyCE,EAAA,EAAA,KAAC,EAAD,EAAsB,CAAA,CACrB,EACc"}
@@ -1 +1 @@
1
- {"version":3,"file":"HTMLProvider.cjs","names":[],"sources":["../../../src/html/HTMLProvider.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport type { HTMLComponents } from './types';\n\ntype HTMLContextValue = {\n components?: HTMLComponents<'permissive', {}>;\n};\n\ntype HTMLProviderProps = RenderableProps<{\n /**\n * Component overrides for HTML tags.\n */\n components?: HTMLComponents<'permissive', {}>;\n}>;\n\nconst HTMLContext = createContext<HTMLContextValue | undefined>(undefined);\n\nexport const useHTMLContext = () => useContext(HTMLContext);\n\nexport const HTMLProvider: FunctionalComponent<HTMLProviderProps> = ({\n children,\n components,\n}) => (\n <HTMLContext.Provider value={{ components }}>{children}</HTMLContext.Provider>\n);\n"],"mappings":"+MAqBA,MAAM,GAAA,EAAA,EAAA,eAA0D,IAAA,GAAU,CAE7D,OAAA,EAAA,EAAA,YAAkC,EAAY,CAE9C,GAAwD,CACnE,WACA,iBAEA,EAAA,EAAA,KAAC,EAAY,SAAA,CAAS,MAAO,CAAE,aAAY,CAAG,YAAgC"}
1
+ {"version":3,"file":"HTMLProvider.cjs","names":[],"sources":["../../../src/html/HTMLProvider.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport type { HTMLComponents } from './types';\n\ntype HTMLContextValue = {\n components?: HTMLComponents<'permissive', {}>;\n};\n\ntype HTMLProviderProps = RenderableProps<{\n /**\n * Component overrides for HTML tags.\n */\n components?: HTMLComponents<'permissive', {}>;\n}>;\n\nconst HTMLContext = createContext<HTMLContextValue | undefined>(undefined);\n\nexport const useHTMLContext = () => useContext(HTMLContext);\n\nexport const HTMLProvider: FunctionalComponent<HTMLProviderProps> = ({\n children,\n components,\n}) => (\n <HTMLContext.Provider value={{ components }}>{children}</HTMLContext.Provider>\n);\n"],"mappings":"+MAqBA,MAAM,GAAA,EAAA,EAAA,eAA0D,IAAA,GAAU,CAE7D,OAAA,EAAA,EAAA,YAAkC,EAAY,CAE9C,GAAwD,CACnE,WACA,iBAEA,EAAA,EAAA,KAAC,EAAY,SAAb,CAAsB,MAAO,CAAE,aAAY,CAAG,WAAgC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownProvider.cjs","names":["compileMarkdown"],"sources":["../../../src/markdown/MarkdownProvider.tsx"],"sourcesContent":["import {\n type ComponentChildren,\n createContext,\n type FunctionComponent,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport type { HTMLComponents } from '../html/types';\nimport { compileMarkdown } from './compiler';\n\ntype PropsWithChildren<P = {}> = P & { children?: ComponentChildren };\n\n/**\n * Refined options for the MarkdownProvider.\n */\nexport type MarkdownProviderOptions = {\n /**\n * Forces the compiler to always output content with a block-level wrapper.\n */\n forceBlock?: boolean;\n /**\n * Forces the compiler to always output content with an inline wrapper.\n */\n forceInline?: boolean;\n /**\n * Whether to preserve frontmatter in the markdown content.\n */\n preserveFrontmatter?: boolean;\n /**\n * Whether to use the GitHub Tag Filter.\n */\n tagfilter?: boolean;\n};\n\ntype RenderMarkdownOptions = MarkdownProviderOptions & {\n components?: HTMLComponents<'permissive', {}>;\n wrapper?: any;\n};\n\ntype MarkdownContextValue = {\n renderMarkdown: (\n markdown: string,\n overrides?: HTMLComponents<'permissive', {}> | RenderMarkdownOptions\n ) => ComponentChildren;\n};\n\ntype MarkdownProviderProps = PropsWithChildren<\n MarkdownProviderOptions & {\n /**\n * Component overrides for HTML tags.\n */\n components?: HTMLComponents<'permissive', {}>;\n /**\n * Wrapper element or component to be used when there are multiple children.\n */\n wrapper?: any;\n /**\n * Custom render function for markdown.\n * If provided, it will overwrite all rules and default rendering.\n */\n renderMarkdown?: (\n markdown: string,\n overrides?: HTMLComponents<'permissive', {}> | RenderMarkdownOptions\n ) => ComponentChildren;\n }\n>;\n\nconst MarkdownContext = createContext<MarkdownContextValue | undefined>(\n undefined\n);\n\nexport const useMarkdownContext = () => useContext(MarkdownContext);\n\nexport const MarkdownProvider: FunctionComponent<MarkdownProviderProps> = ({\n children,\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n renderMarkdown,\n}) => {\n // Map public options to internal processor options\n const internalOptions: any = {\n components,\n forceBlock,\n forceInline,\n wrapper,\n forceWrapper: !!wrapper,\n preserveFrontmatter,\n tagfilter,\n };\n\n const finalRenderMarkdown = renderMarkdown\n ? (\n markdown: string,\n componentsOverride?:\n | HTMLComponents<'permissive', {}>\n | RenderMarkdownOptions\n ) => (\n <MarkdownContext.Provider value={undefined}>\n {renderMarkdown(markdown, componentsOverride)}\n </MarkdownContext.Provider>\n )\n : (\n markdown: string,\n componentsOverride?:\n | HTMLComponents<'permissive', {}>\n | RenderMarkdownOptions\n ) => {\n const {\n components: overrideComponents,\n wrapper: localWrapper,\n forceBlock: localForceBlock,\n forceInline: localForceInline,\n preserveFrontmatter: localPreserveFrontmatter,\n tagfilter: localTagfilter,\n ...componentsFromRest\n } = componentsOverride as RenderMarkdownOptions;\n\n const localComponents = (overrideComponents ||\n componentsFromRest) as HTMLComponents<'permissive', {}>;\n\n return compileMarkdown(markdown, {\n ...internalOptions,\n forceBlock: localForceBlock ?? internalOptions.forceBlock,\n forceInline: localForceInline ?? internalOptions.forceInline,\n preserveFrontmatter:\n localPreserveFrontmatter ?? internalOptions.preserveFrontmatter,\n tagfilter: localTagfilter ?? internalOptions.tagfilter,\n wrapper: localWrapper || wrapper || internalOptions.wrapper,\n forceWrapper: !!(localWrapper || wrapper),\n components: {\n ...internalOptions.components,\n ...localComponents,\n },\n }) as ComponentChildren;\n };\n\n return (\n <MarkdownContext.Provider value={{ renderMarkdown: finalRenderMarkdown }}>\n {children}\n </MarkdownContext.Provider>\n );\n};\n"],"mappings":"oOAkEA,MAAM,GAAA,EAAA,EAAA,eACJ,IAAA,GACD,CAEY,OAAA,EAAA,EAAA,YAAsC,EAAgB,CAEtD,GAA8D,CACzE,WACA,aACA,UACA,aACA,cACA,sBACA,YACA,oBACI,CAEJ,IAAM,EAAuB,CAC3B,aACA,aACA,cACA,UACA,aAAc,CAAC,CAAC,EAChB,sBACA,YACD,CAEK,EAAsB,GAEtB,EACA,KAIA,EAAA,EAAA,KAAC,EAAgB,SAAA,CAAS,MAAO,IAAA,YAC9B,EAAe,EAAU,EAAmB,EACpB,EAG3B,EACA,IAGG,CACH,GAAM,CACJ,WAAY,EACZ,QAAS,EACT,WAAY,EACZ,YAAa,EACb,oBAAqB,EACrB,UAAW,EACX,GAAG,GACD,EAEE,EAAmB,GACvB,EAEF,OAAOA,EAAAA,gBAAgB,EAAU,CAC/B,GAAG,EACH,WAAY,GAAmB,EAAgB,WAC/C,YAAa,GAAoB,EAAgB,YACjD,oBACE,GAA4B,EAAgB,oBAC9C,UAAW,GAAkB,EAAgB,UAC7C,QAAS,GAAgB,GAAW,EAAgB,QACpD,aAAc,CAAC,EAAE,GAAgB,GACjC,WAAY,CACV,GAAG,EAAgB,WACnB,GAAG,EACJ,CACF,CAAC,EAGR,OACE,EAAA,EAAA,KAAC,EAAgB,SAAA,CAAS,MAAO,CAAE,eAAgB,EAAqB,CACrE,YACwB"}
1
+ {"version":3,"file":"MarkdownProvider.cjs","names":["compileMarkdown"],"sources":["../../../src/markdown/MarkdownProvider.tsx"],"sourcesContent":["import {\n type ComponentChildren,\n createContext,\n type FunctionComponent,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport type { HTMLComponents } from '../html/types';\nimport { compileMarkdown } from './compiler';\n\ntype PropsWithChildren<P = {}> = P & { children?: ComponentChildren };\n\n/**\n * Refined options for the MarkdownProvider.\n */\nexport type MarkdownProviderOptions = {\n /**\n * Forces the compiler to always output content with a block-level wrapper.\n */\n forceBlock?: boolean;\n /**\n * Forces the compiler to always output content with an inline wrapper.\n */\n forceInline?: boolean;\n /**\n * Whether to preserve frontmatter in the markdown content.\n */\n preserveFrontmatter?: boolean;\n /**\n * Whether to use the GitHub Tag Filter.\n */\n tagfilter?: boolean;\n};\n\ntype RenderMarkdownOptions = MarkdownProviderOptions & {\n components?: HTMLComponents<'permissive', {}>;\n wrapper?: any;\n};\n\ntype MarkdownContextValue = {\n renderMarkdown: (\n markdown: string,\n overrides?: HTMLComponents<'permissive', {}> | RenderMarkdownOptions\n ) => ComponentChildren;\n};\n\ntype MarkdownProviderProps = PropsWithChildren<\n MarkdownProviderOptions & {\n /**\n * Component overrides for HTML tags.\n */\n components?: HTMLComponents<'permissive', {}>;\n /**\n * Wrapper element or component to be used when there are multiple children.\n */\n wrapper?: any;\n /**\n * Custom render function for markdown.\n * If provided, it will overwrite all rules and default rendering.\n */\n renderMarkdown?: (\n markdown: string,\n overrides?: HTMLComponents<'permissive', {}> | RenderMarkdownOptions\n ) => ComponentChildren;\n }\n>;\n\nconst MarkdownContext = createContext<MarkdownContextValue | undefined>(\n undefined\n);\n\nexport const useMarkdownContext = () => useContext(MarkdownContext);\n\nexport const MarkdownProvider: FunctionComponent<MarkdownProviderProps> = ({\n children,\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n renderMarkdown,\n}) => {\n // Map public options to internal processor options\n const internalOptions: any = {\n components,\n forceBlock,\n forceInline,\n wrapper,\n forceWrapper: !!wrapper,\n preserveFrontmatter,\n tagfilter,\n };\n\n const finalRenderMarkdown = renderMarkdown\n ? (\n markdown: string,\n componentsOverride?:\n | HTMLComponents<'permissive', {}>\n | RenderMarkdownOptions\n ) => (\n <MarkdownContext.Provider value={undefined}>\n {renderMarkdown(markdown, componentsOverride)}\n </MarkdownContext.Provider>\n )\n : (\n markdown: string,\n componentsOverride?:\n | HTMLComponents<'permissive', {}>\n | RenderMarkdownOptions\n ) => {\n const {\n components: overrideComponents,\n wrapper: localWrapper,\n forceBlock: localForceBlock,\n forceInline: localForceInline,\n preserveFrontmatter: localPreserveFrontmatter,\n tagfilter: localTagfilter,\n ...componentsFromRest\n } = componentsOverride as RenderMarkdownOptions;\n\n const localComponents = (overrideComponents ||\n componentsFromRest) as HTMLComponents<'permissive', {}>;\n\n return compileMarkdown(markdown, {\n ...internalOptions,\n forceBlock: localForceBlock ?? internalOptions.forceBlock,\n forceInline: localForceInline ?? internalOptions.forceInline,\n preserveFrontmatter:\n localPreserveFrontmatter ?? internalOptions.preserveFrontmatter,\n tagfilter: localTagfilter ?? internalOptions.tagfilter,\n wrapper: localWrapper || wrapper || internalOptions.wrapper,\n forceWrapper: !!(localWrapper || wrapper),\n components: {\n ...internalOptions.components,\n ...localComponents,\n },\n }) as ComponentChildren;\n };\n\n return (\n <MarkdownContext.Provider value={{ renderMarkdown: finalRenderMarkdown }}>\n {children}\n </MarkdownContext.Provider>\n );\n};\n"],"mappings":"oOAkEA,MAAM,GAAA,EAAA,EAAA,eACJ,IAAA,GACD,CAEY,OAAA,EAAA,EAAA,YAAsC,EAAgB,CAEtD,GAA8D,CACzE,WACA,aACA,UACA,aACA,cACA,sBACA,YACA,oBACI,CAEJ,IAAM,EAAuB,CAC3B,aACA,aACA,cACA,UACA,aAAc,CAAC,CAAC,EAChB,sBACA,YACD,CAEK,EAAsB,GAEtB,EACA,KAIA,EAAA,EAAA,KAAC,EAAgB,SAAjB,CAA0B,MAAO,IAAA,YAC9B,EAAe,EAAU,EAAmB,CACpB,CAAA,EAG3B,EACA,IAGG,CACH,GAAM,CACJ,WAAY,EACZ,QAAS,EACT,WAAY,EACZ,YAAa,EACb,oBAAqB,EACrB,UAAW,EACX,GAAG,GACD,EAEE,EAAmB,GACvB,EAEF,OAAOA,EAAAA,gBAAgB,EAAU,CAC/B,GAAG,EACH,WAAY,GAAmB,EAAgB,WAC/C,YAAa,GAAoB,EAAgB,YACjD,oBACE,GAA4B,EAAgB,oBAC9C,UAAW,GAAkB,EAAgB,UAC7C,QAAS,GAAgB,GAAW,EAAgB,QACpD,aAAc,CAAC,EAAE,GAAgB,GACjC,WAAY,CACV,GAAG,EAAgB,WACnB,GAAG,EACJ,CACF,CAAC,EAGR,OACE,EAAA,EAAA,KAAC,EAAgB,SAAjB,CAA0B,MAAO,CAAE,eAAgB,EAAqB,CACrE,WACwB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownRenderer.cjs","names":["compileMarkdown","useMarkdownContext"],"sources":["../../../src/markdown/MarkdownRenderer.tsx"],"sourcesContent":["import type { ComponentChildren, FunctionComponent, JSX } from 'preact';\nimport type { HTMLComponents } from '../html/types';\nimport { compileMarkdown, type MarkdownCompilerOptions } from './compiler';\nimport {\n type MarkdownProviderOptions,\n useMarkdownContext,\n} from './MarkdownProvider';\n\nexport type RenderMarkdownProps = MarkdownProviderOptions & {\n /**\n * Component overrides for HTML tags.\n * Only used if not wrapped in a MarkdownProvider.\n */\n components?: HTMLComponents<'permissive', {}>;\n /**\n * Wrapper element or component to be used when there are multiple children.\n * Only used if not wrapped in a MarkdownProvider.\n */\n wrapper?: FunctionComponent<any>;\n};\n\nexport const renderMarkdown = (\n content: string,\n {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n }: RenderMarkdownProps = {}\n): JSX.Element => {\n // Map public options to internal processor options\n const internalOptions: MarkdownCompilerOptions = {\n components,\n forceBlock,\n forceInline,\n wrapper: wrapper as any,\n forceWrapper: !!wrapper,\n preserveFrontmatter,\n tagfilter,\n };\n\n return compileMarkdown(content, internalOptions) as JSX.Element;\n};\n\nexport const useMarkdownRenderer = ({\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n}: RenderMarkdownProps = {}) => {\n const context = useMarkdownContext();\n\n return (content: string) => {\n if (context) {\n return context.renderMarkdown(content, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n }\n\n return renderMarkdown(content, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n };\n};\n\ntype MarkdownRendererProps = RenderMarkdownProps & {\n /**\n * The markdown content to render.\n */\n children: string;\n /**\n * Custom render function for markdown.\n * If provided, it will overwrite context and default rendering.\n */\n renderMarkdown?: (\n markdown: string,\n options?: {\n components?: HTMLComponents<'permissive', {}>;\n wrapper?: FunctionComponent<any>;\n forceBlock?: boolean;\n forceInline?: boolean;\n preserveFrontmatter?: boolean;\n tagfilter?: boolean;\n }\n ) => ComponentChildren;\n};\n\n/**\n * Preact component that renders markdown to JSX.\n *\n * It uses the renderMarkdown function from the MarkdownProvider context if available.\n * Otherwise, it falls back to the default compiler with provided components and options.\n */\nexport const MarkdownRenderer: FunctionComponent<MarkdownRendererProps> = ({\n children = '',\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n renderMarkdown: customRenderMarkdown,\n}) => {\n const context = useMarkdownContext();\n\n if (customRenderMarkdown) {\n return (\n <>\n {customRenderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n })}\n </>\n );\n }\n\n if (context) {\n return (\n <>\n {context.renderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n })}\n </>\n );\n }\n\n return renderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n};\n"],"mappings":"0NAqBA,MAAa,GACX,EACA,CACE,aACA,UACA,aACA,cACA,sBACA,aACuB,EAAE,GAapBA,EAAAA,gBAAgB,EAV0B,CAC/C,aACA,aACA,cACS,UACT,aAAc,CAAC,CAAC,EAChB,sBACA,YACD,CAE+C,CAGrC,GAAuB,CAClC,aACA,UACA,aACA,cACA,sBACA,aACuB,EAAE,GAAK,CAC9B,IAAM,EAAUC,EAAAA,oBAAoB,CAEpC,MAAQ,IACF,EACK,EAAQ,eAAe,EAAS,CACrC,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CAGG,EAAe,EAAS,CAC7B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,EAgCO,GAA8D,CACzE,WAAW,GACX,aACA,UACA,aACA,cACA,sBACA,YACA,eAAgB,KACZ,CACJ,IAAM,EAAUA,EAAAA,oBAAoB,CAgCpC,OA9BI,GAEA,EAAA,EAAA,KAAA,EAAA,SAAA,CAAA,SACG,EAAqB,EAAU,CAC9B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CAAA,CACD,CAIH,GAEA,EAAA,EAAA,KAAA,EAAA,SAAA,CAAA,SACG,EAAQ,eAAe,EAAU,CAChC,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CAAA,CACD,CAIA,EAAe,EAAU,CAC9B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC"}
1
+ {"version":3,"file":"MarkdownRenderer.cjs","names":["compileMarkdown","useMarkdownContext"],"sources":["../../../src/markdown/MarkdownRenderer.tsx"],"sourcesContent":["import type { ComponentChildren, FunctionComponent, JSX } from 'preact';\nimport type { HTMLComponents } from '../html/types';\nimport { compileMarkdown, type MarkdownCompilerOptions } from './compiler';\nimport {\n type MarkdownProviderOptions,\n useMarkdownContext,\n} from './MarkdownProvider';\n\nexport type RenderMarkdownProps = MarkdownProviderOptions & {\n /**\n * Component overrides for HTML tags.\n * Only used if not wrapped in a MarkdownProvider.\n */\n components?: HTMLComponents<'permissive', {}>;\n /**\n * Wrapper element or component to be used when there are multiple children.\n * Only used if not wrapped in a MarkdownProvider.\n */\n wrapper?: FunctionComponent<any>;\n};\n\nexport const renderMarkdown = (\n content: string,\n {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n }: RenderMarkdownProps = {}\n): JSX.Element => {\n // Map public options to internal processor options\n const internalOptions: MarkdownCompilerOptions = {\n components,\n forceBlock,\n forceInline,\n wrapper: wrapper as any,\n forceWrapper: !!wrapper,\n preserveFrontmatter,\n tagfilter,\n };\n\n return compileMarkdown(content, internalOptions) as JSX.Element;\n};\n\nexport const useMarkdownRenderer = ({\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n}: RenderMarkdownProps = {}) => {\n const context = useMarkdownContext();\n\n return (content: string) => {\n if (context) {\n return context.renderMarkdown(content, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n }\n\n return renderMarkdown(content, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n };\n};\n\ntype MarkdownRendererProps = RenderMarkdownProps & {\n /**\n * The markdown content to render.\n */\n children: string;\n /**\n * Custom render function for markdown.\n * If provided, it will overwrite context and default rendering.\n */\n renderMarkdown?: (\n markdown: string,\n options?: {\n components?: HTMLComponents<'permissive', {}>;\n wrapper?: FunctionComponent<any>;\n forceBlock?: boolean;\n forceInline?: boolean;\n preserveFrontmatter?: boolean;\n tagfilter?: boolean;\n }\n ) => ComponentChildren;\n};\n\n/**\n * Preact component that renders markdown to JSX.\n *\n * It uses the renderMarkdown function from the MarkdownProvider context if available.\n * Otherwise, it falls back to the default compiler with provided components and options.\n */\nexport const MarkdownRenderer: FunctionComponent<MarkdownRendererProps> = ({\n children = '',\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n renderMarkdown: customRenderMarkdown,\n}) => {\n const context = useMarkdownContext();\n\n if (customRenderMarkdown) {\n return (\n <>\n {customRenderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n })}\n </>\n );\n }\n\n if (context) {\n return (\n <>\n {context.renderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n })}\n </>\n );\n }\n\n return renderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n};\n"],"mappings":"0NAqBA,MAAa,GACX,EACA,CACE,aACA,UACA,aACA,cACA,sBACA,aACuB,EAAE,GAapBA,EAAAA,gBAAgB,EAV0B,CAC/C,aACA,aACA,cACS,UACT,aAAc,CAAC,CAAC,EAChB,sBACA,YACD,CAE+C,CAGrC,GAAuB,CAClC,aACA,UACA,aACA,cACA,sBACA,aACuB,EAAE,GAAK,CAC9B,IAAM,EAAUC,EAAAA,oBAAoB,CAEpC,MAAQ,IACF,EACK,EAAQ,eAAe,EAAS,CACrC,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CAGG,EAAe,EAAS,CAC7B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,EAgCO,GAA8D,CACzE,WAAW,GACX,aACA,UACA,aACA,cACA,sBACA,YACA,eAAgB,KACZ,CACJ,IAAM,EAAUA,EAAAA,oBAAoB,CAgCpC,OA9BI,GAEA,EAAA,EAAA,KAAA,EAAA,SAAA,CAAA,SACG,EAAqB,EAAU,CAC9B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CACD,CAAA,CAIH,GAEA,EAAA,EAAA,KAAA,EAAA,SAAA,CAAA,SACG,EAAQ,eAAe,EAAU,CAChC,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CACD,CAAA,CAIA,EAAe,EAAU,CAC9B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.cjs","names":["renderIntlayerNode","ContentSelectorRenderer","EditedContentRenderer","renderPreactElement","Fragment","NodeType","MarkdownMetadataRenderer","MarkdownRenderer","HTMLRenderer"],"sources":["../../src/plugins.tsx"],"sourcesContent":["import type {\n DeepTransformContent as DeepTransformContentCore,\n IInterpreterPluginState as IInterpreterPluginStateCore,\n Plugins,\n} from '@intlayer/core/interpreter';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\nimport type {\n HTMLContent,\n InsertionContent,\n MarkdownContent,\n} from '@intlayer/core/transpiler';\nimport type { DeclaredLocales, KeyPath, LocalesValues } from '@intlayer/types';\nimport { NodeType } from '@intlayer/types';\nimport { Fragment, h, type VNode } from 'preact';\nimport { ContentSelectorRenderer } from './editor';\nimport { EditedContentRenderer } from './editor/useEditedContentRenderer';\nimport { HTMLRenderer } from './html/HTMLRenderer';\nimport type { HTMLComponents } from './html/types';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { MarkdownMetadataRenderer, MarkdownRenderer } from './markdown';\nimport { renderPreactElement } from './preactElement/renderPreactElement';\n\n/** ---------------------------------------------\n * INTLAYER NODE PLUGIN\n * --------------------------------------------- */\n\nexport type IntlayerNodeCond<T> = T extends number | string\n ? IntlayerNode<T>\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const intlayerNodePlugins: Plugins = {\n id: 'intlayer-node-plugin',\n canHandle: (node) =>\n typeof node === 'bigint' ||\n typeof node === 'string' ||\n typeof node === 'number',\n transform: (\n _node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) =>\n renderIntlayerNode({\n ...rest,\n value: rest.children,\n children: (\n <ContentSelectorRenderer {...rest} key={rest.children}>\n <EditedContentRenderer {...rest}>\n {rest.children}\n </EditedContentRenderer>\n </ContentSelectorRenderer>\n ),\n }),\n};\n\n/** ---------------------------------------------\n * PREACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type PreactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? VNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const preactNodePlugins: Plugins = {\n id: 'preact-node-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n typeof node.props !== 'undefined' &&\n typeof node.key !== 'undefined',\n\n transform: (\n node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) =>\n renderIntlayerNode({\n ...rest,\n value: '[[preact-element]]',\n children: (\n <ContentSelectorRenderer {...rest}>\n {renderPreactElement(node)}\n </ContentSelectorRenderer>\n ),\n }),\n};\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, _S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Insertion]: string;\n fields: readonly string[];\n}\n ? <V extends { [K in T['fields'][number]]: VNode }>(\n values: V\n ) => V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<VNode>\n : never;\n\n/**\n * Check if a value is a Preact VNode\n */\nconst isVNode = (value: any): value is VNode => {\n return (\n value !== null &&\n value !== undefined &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n );\n};\n\n/**\n * Split insertion string and join with Preact VNodes\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | VNode>\n): VNode => {\n // Check if any value is a VNode\n const hasVNode = Object.values(values).some(isVNode);\n\n if (!hasVNode) {\n // Simple string replacement\n return template.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_, key) => {\n const trimmedKey = key.trim();\n return (values[trimmedKey] ?? '').toString();\n }) as any;\n }\n\n // Split the template by placeholders while keeping the structure\n const parts: (string | VNode)[] = [];\n let lastIndex = 0;\n const regex = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n let match: RegExpExecArray | null = regex.exec(template);\n\n while (match !== null) {\n // Add text before the placeholder\n if (match.index > lastIndex) {\n parts.push(template.substring(lastIndex, match.index));\n }\n\n // Add the replaced value\n const key = match[1].trim();\n const value = values[key];\n if (value !== undefined && value !== null) {\n parts.push(typeof value === 'number' ? String(value) : value);\n }\n\n lastIndex = match.index + match[0].length;\n match = regex.exec(template);\n }\n\n // Add remaining text\n if (lastIndex < template.length) {\n parts.push(template.substring(lastIndex));\n }\n\n // Return as Fragment\n return h(\n Fragment,\n null,\n ...parts.map((part, index) => h(Fragment, { key: index }, part))\n );\n};\n\n/** Insertion plugin for Preact. Handles component/node insertion. */\nexport const insertionPlugin: Plugins = {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Insertion,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Insertion,\n },\n ];\n\n const children = node[NodeType.Insertion];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number | VNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result as any,\n });\n };\n },\n };\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/**\n * MARKDOWN PLUGIN\n */\n\nexport type MarkdownStringCond<T> = T extends string\n ? IntlayerNode<\n string,\n {\n metadata: DeepTransformContent<string>;\n use: (components?: HTMLComponents<'permissive', {}>) => VNode;\n }\n >\n : never;\n\n/** Markdown string plugin. Replaces string node with a component that render the markdown. */\nexport const markdownStringPlugin: Plugins = {\n id: 'markdown-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, props, deepTransformNode) => {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n const metadata = getMarkdownMetadata(node);\n\n const metadataPlugins: Plugins = {\n id: 'markdown-metadata-plugin',\n canHandle: (metadataNode) =>\n typeof metadataNode === 'string' ||\n typeof metadataNode === 'number' ||\n typeof metadataNode === 'boolean' ||\n !metadataNode,\n transform: (metadataNode, props) =>\n renderIntlayerNode({\n ...props,\n value: metadataNode,\n children: (\n <ContentSelectorRenderer {...rest}>\n <MarkdownMetadataRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataRenderer>\n </ContentSelectorRenderer>\n ),\n }),\n };\n\n // Transform metadata while keeping the same structure\n const metadataNodes = deepTransformNode(metadata, {\n plugins: [metadataPlugins],\n dictionaryKey: rest.dictionaryKey,\n keyPath: [],\n });\n\n const render = (components?: any) =>\n renderIntlayerNode({\n ...props,\n value: node,\n children: (\n <ContentSelectorRenderer {...rest}>\n <MarkdownRenderer {...rest} {...components}>\n {node}\n </MarkdownRenderer>\n </ContentSelectorRenderer>\n ),\n additionalProps: {\n metadata: metadataNodes,\n },\n });\n\n const element = render() as any;\n\n return new Proxy(element, {\n get(target, prop) {\n if (prop === 'value') {\n return node;\n }\n if (prop === 'metadata') {\n return metadataNodes;\n }\n\n if (prop === 'use') {\n return (components?: any) => render(components);\n }\n\n return Reflect.get(target, prop);\n },\n }) as any;\n },\n};\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.Markdown]: infer _M;\n metadata?: infer U;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => VNode;\n metadata: DeepTransformContent<U>;\n }\n : never;\n\nexport const markdownPlugin: Plugins = {\n id: 'markdown-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Markdown,\n transform: (node: MarkdownContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Markdown,\n },\n ];\n\n const children = node[NodeType.Markdown];\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [markdownStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/** ---------------------------------------------\n * HTML PLUGIN\n * --------------------------------------------- */\n\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.HTML]: infer I;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => IntlayerNode<I>;\n }\n : never;\n\n/** HTML plugin. Replaces node with a function that takes components => VNode. */\nexport const htmlPlugin: Plugins = {\n id: 'html-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.HTML,\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeType.HTML];\n const _tags = node.tags ?? [];\n const { plugins, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): VNode =>\n h(HTMLRenderer as any, { ...rest, html, userComponents } as any);\n\n const element = render() as any;\n\n const proxy = new Proxy(element, {\n get(target, prop) {\n if (prop === 'value') {\n return html;\n }\n\n if (prop === 'use') {\n return (userComponents?: HTMLComponents) => render(userComponents);\n }\n\n return Reflect.get(target, prop);\n },\n });\n\n return proxy;\n },\n};\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport interface IInterpreterPluginPreact<T, _S, _L extends LocalesValues> {\n preactNode: PreactNodeCond<T>;\n preactIntlayerNode: IntlayerNodeCond<T>;\n preactInsertion: InsertionCond<T>;\n preactMarkdown: MarkdownCond<T>;\n preactHtml: HTMLPluginCond<T>;\n}\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `preact-intlayer` plugins will override the types of `intlayer` functions.\n */\nexport type IInterpreterPluginState = Omit<\n IInterpreterPluginStateCore,\n 'insertion' // Remove insertion type from core package\n> & {\n preactNode: true;\n preactIntlayerNode: true;\n preactInsertion: true;\n preactMarkdown: true;\n preactHtml: true;\n};\n\nexport type DeepTransformContent<\n T,\n L extends LocalesValues = DeclaredLocales,\n> = DeepTransformContentCore<T, IInterpreterPluginState, L>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugins.cjs","names":["renderIntlayerNode","ContentSelectorRenderer","EditedContentRenderer","renderPreactElement","Fragment","NodeType","MarkdownMetadataRenderer","MarkdownRenderer","HTMLRenderer"],"sources":["../../src/plugins.tsx"],"sourcesContent":["import type {\n DeepTransformContent as DeepTransformContentCore,\n IInterpreterPluginState as IInterpreterPluginStateCore,\n Plugins,\n} from '@intlayer/core/interpreter';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\nimport type {\n HTMLContent,\n InsertionContent,\n MarkdownContent,\n} from '@intlayer/core/transpiler';\nimport type { DeclaredLocales, KeyPath, LocalesValues } from '@intlayer/types';\nimport { NodeType } from '@intlayer/types';\nimport { Fragment, h, type VNode } from 'preact';\nimport { ContentSelectorRenderer } from './editor';\nimport { EditedContentRenderer } from './editor/useEditedContentRenderer';\nimport { HTMLRenderer } from './html/HTMLRenderer';\nimport type { HTMLComponents } from './html/types';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { MarkdownMetadataRenderer, MarkdownRenderer } from './markdown';\nimport { renderPreactElement } from './preactElement/renderPreactElement';\n\n/** ---------------------------------------------\n * INTLAYER NODE PLUGIN\n * --------------------------------------------- */\n\nexport type IntlayerNodeCond<T> = T extends number | string\n ? IntlayerNode<T>\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const intlayerNodePlugins: Plugins = {\n id: 'intlayer-node-plugin',\n canHandle: (node) =>\n typeof node === 'bigint' ||\n typeof node === 'string' ||\n typeof node === 'number',\n transform: (\n _node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) =>\n renderIntlayerNode({\n ...rest,\n value: rest.children,\n children: (\n <ContentSelectorRenderer {...rest} key={rest.children}>\n <EditedContentRenderer {...rest}>\n {rest.children}\n </EditedContentRenderer>\n </ContentSelectorRenderer>\n ),\n }),\n};\n\n/** ---------------------------------------------\n * PREACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type PreactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? VNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const preactNodePlugins: Plugins = {\n id: 'preact-node-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n typeof node.props !== 'undefined' &&\n typeof node.key !== 'undefined',\n\n transform: (\n node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) =>\n renderIntlayerNode({\n ...rest,\n value: '[[preact-element]]',\n children: (\n <ContentSelectorRenderer {...rest}>\n {renderPreactElement(node)}\n </ContentSelectorRenderer>\n ),\n }),\n};\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, _S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Insertion]: string;\n fields: readonly string[];\n}\n ? <V extends { [K in T['fields'][number]]: VNode }>(\n values: V\n ) => V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<VNode>\n : never;\n\n/**\n * Check if a value is a Preact VNode\n */\nconst isVNode = (value: any): value is VNode => {\n return (\n value !== null &&\n value !== undefined &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n );\n};\n\n/**\n * Split insertion string and join with Preact VNodes\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | VNode>\n): VNode => {\n // Check if any value is a VNode\n const hasVNode = Object.values(values).some(isVNode);\n\n if (!hasVNode) {\n // Simple string replacement\n return template.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_, key) => {\n const trimmedKey = key.trim();\n return (values[trimmedKey] ?? '').toString();\n }) as any;\n }\n\n // Split the template by placeholders while keeping the structure\n const parts: (string | VNode)[] = [];\n let lastIndex = 0;\n const regex = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n let match: RegExpExecArray | null = regex.exec(template);\n\n while (match !== null) {\n // Add text before the placeholder\n if (match.index > lastIndex) {\n parts.push(template.substring(lastIndex, match.index));\n }\n\n // Add the replaced value\n const key = match[1].trim();\n const value = values[key];\n if (value !== undefined && value !== null) {\n parts.push(typeof value === 'number' ? String(value) : value);\n }\n\n lastIndex = match.index + match[0].length;\n match = regex.exec(template);\n }\n\n // Add remaining text\n if (lastIndex < template.length) {\n parts.push(template.substring(lastIndex));\n }\n\n // Return as Fragment\n return h(\n Fragment,\n null,\n ...parts.map((part, index) => h(Fragment, { key: index }, part))\n );\n};\n\n/** Insertion plugin for Preact. Handles component/node insertion. */\nexport const insertionPlugin: Plugins = {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Insertion,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Insertion,\n },\n ];\n\n const children = node[NodeType.Insertion];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number | VNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result as any,\n });\n };\n },\n };\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/**\n * MARKDOWN PLUGIN\n */\n\nexport type MarkdownStringCond<T> = T extends string\n ? IntlayerNode<\n string,\n {\n metadata: DeepTransformContent<string>;\n use: (components?: HTMLComponents<'permissive', {}>) => VNode;\n }\n >\n : never;\n\n/** Markdown string plugin. Replaces string node with a component that render the markdown. */\nexport const markdownStringPlugin: Plugins = {\n id: 'markdown-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, props, deepTransformNode) => {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n const metadata = getMarkdownMetadata(node);\n\n const metadataPlugins: Plugins = {\n id: 'markdown-metadata-plugin',\n canHandle: (metadataNode) =>\n typeof metadataNode === 'string' ||\n typeof metadataNode === 'number' ||\n typeof metadataNode === 'boolean' ||\n !metadataNode,\n transform: (metadataNode, props) =>\n renderIntlayerNode({\n ...props,\n value: metadataNode,\n children: (\n <ContentSelectorRenderer {...rest}>\n <MarkdownMetadataRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataRenderer>\n </ContentSelectorRenderer>\n ),\n }),\n };\n\n // Transform metadata while keeping the same structure\n const metadataNodes = deepTransformNode(metadata, {\n plugins: [metadataPlugins],\n dictionaryKey: rest.dictionaryKey,\n keyPath: [],\n });\n\n const render = (components?: any) =>\n renderIntlayerNode({\n ...props,\n value: node,\n children: (\n <ContentSelectorRenderer {...rest}>\n <MarkdownRenderer {...rest} {...components}>\n {node}\n </MarkdownRenderer>\n </ContentSelectorRenderer>\n ),\n additionalProps: {\n metadata: metadataNodes,\n },\n });\n\n const element = render() as any;\n\n return new Proxy(element, {\n get(target, prop) {\n if (prop === 'value') {\n return node;\n }\n if (prop === 'metadata') {\n return metadataNodes;\n }\n\n if (prop === 'use') {\n return (components?: any) => render(components);\n }\n\n return Reflect.get(target, prop);\n },\n }) as any;\n },\n};\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.Markdown]: infer _M;\n metadata?: infer U;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => VNode;\n metadata: DeepTransformContent<U>;\n }\n : never;\n\nexport const markdownPlugin: Plugins = {\n id: 'markdown-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Markdown,\n transform: (node: MarkdownContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Markdown,\n },\n ];\n\n const children = node[NodeType.Markdown];\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [markdownStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/** ---------------------------------------------\n * HTML PLUGIN\n * --------------------------------------------- */\n\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.HTML]: infer I;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => IntlayerNode<I>;\n }\n : never;\n\n/** HTML plugin. Replaces node with a function that takes components => VNode. */\nexport const htmlPlugin: Plugins = {\n id: 'html-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.HTML,\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeType.HTML];\n const _tags = node.tags ?? [];\n const { plugins, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): VNode =>\n h(HTMLRenderer as any, { ...rest, html, userComponents } as any);\n\n const element = render() as any;\n\n const proxy = new Proxy(element, {\n get(target, prop) {\n if (prop === 'value') {\n return html;\n }\n\n if (prop === 'use') {\n return (userComponents?: HTMLComponents) => render(userComponents);\n }\n\n return Reflect.get(target, prop);\n },\n });\n\n return proxy;\n },\n};\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport interface IInterpreterPluginPreact<T, _S, _L extends LocalesValues> {\n preactNode: PreactNodeCond<T>;\n preactIntlayerNode: IntlayerNodeCond<T>;\n preactInsertion: InsertionCond<T>;\n preactMarkdown: MarkdownCond<T>;\n preactHtml: HTMLPluginCond<T>;\n}\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `preact-intlayer` plugins will override the types of `intlayer` functions.\n */\nexport type IInterpreterPluginState = Omit<\n IInterpreterPluginStateCore,\n 'insertion' // Remove insertion type from core package\n> & {\n preactNode: true;\n preactIntlayerNode: true;\n preactInsertion: true;\n preactMarkdown: true;\n preactHtml: true;\n};\n\nexport type DeepTransformContent<\n T,\n L extends LocalesValues = DeclaredLocales,\n> = DeepTransformContentCore<T, IInterpreterPluginState, L>;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ContentSelector.mjs","names":[],"sources":["../../../src/UI/ContentSelector.tsx"],"sourcesContent":["'use client';\n\nimport type { FunctionalComponent, JSX } from 'preact';\nimport { useCallback, useEffect, useRef, useState } from 'preact/hooks';\n\nconst DEFAULT_PRESS_DETECT_DURATION = 250;\n\ntype ContentSelectorProps = {\n onPress: () => void;\n onHover?: () => void;\n onUnhover?: () => void;\n onClickOutside?: () => void;\n pressDuration?: number;\n isSelecting?: boolean;\n} & Omit<JSX.HTMLAttributes<HTMLDivElement>, 'content'>;\n\nexport const ContentSelector: FunctionalComponent<ContentSelectorProps> = ({\n children,\n onPress: onSelect,\n onHover,\n onUnhover,\n onClickOutside: onUnselect,\n pressDuration = DEFAULT_PRESS_DETECT_DURATION,\n isSelecting: isSelectingProp,\n ...props\n}) => {\n const divRef = useRef<HTMLDivElement>(null);\n const [isHovered, setIsHovered] = useState(false);\n const [isSelectingState, setIsSelectingState] = useState(isSelectingProp);\n const pressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isChildrenString = typeof children === 'string';\n\n const handleOnLongPress = () => {\n setIsSelectingState(true);\n onSelect();\n };\n\n const startPressTimer = () => {\n pressTimerRef.current = setTimeout(() => {\n handleOnLongPress();\n }, pressDuration);\n };\n\n const clearPressTimer = () => {\n if (pressTimerRef.current) {\n clearTimeout(pressTimerRef.current);\n pressTimerRef.current = null;\n }\n };\n\n const handleMouseDown = () => {\n clearPressTimer(); // Ensure any previous timer is cleared\n startPressTimer();\n };\n\n const handleMouseEnter = () => {\n setIsHovered(true);\n onHover?.();\n };\n\n const handleMouseUp = () => {\n if (isHovered) {\n setIsHovered(false);\n onUnhover?.();\n }\n clearPressTimer();\n };\n\n // Use useCallback to ensure the function identity remains stable\n const handleClickOutside = useCallback(\n (event: MouseEvent) => {\n if (divRef.current && !divRef.current.contains(event.target as Node)) {\n setIsSelectingState(false);\n onUnselect?.();\n }\n },\n [onUnselect]\n );\n\n useEffect(() => {\n // Attach click outside listener\n document.addEventListener('mousedown', handleClickOutside);\n\n return () => {\n // Cleanup\n document.removeEventListener('mousedown', handleClickOutside);\n // clearPressTimer(); // Ensure to clear the timer when component unmounts\n };\n }, [handleClickOutside]);\n\n const handleOnClick: JSX.MouseEventHandler<HTMLDivElement> = (e) => {\n if (isSelectingState) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleOnBlur = () => {\n // Stop editing when the element loses focus\n setIsSelectingState(false);\n };\n\n return (\n <span\n style={{\n display: isChildrenString ? 'inline' : 'inline-block',\n cursor: 'pointer',\n userSelect: 'none',\n borderRadius: '0.375rem',\n outlineWidth: '2px',\n outlineOffset: '4px',\n outlineStyle: 'solid',\n outlineColor:\n isSelectingProp || isSelectingState || isHovered\n ? 'inherit'\n : 'transparent',\n transition: 'all 100ms 50ms ease-in-out',\n }}\n role=\"button\"\n tabIndex={0}\n onKeyUp={() => null}\n onClick={handleOnClick}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleMouseDown}\n onTouchEnd={handleMouseUp}\n onTouchCancel={handleMouseUp}\n onBlur={handleOnBlur}\n onMouseEnter={handleMouseEnter}\n ref={divRef}\n {...props}\n >\n {children}\n </span>\n );\n};\n"],"mappings":"0IAKA,MAWa,GAA8D,CACzE,WACA,QAAS,EACT,UACA,YACA,eAAgB,EAChB,gBAAgB,IAChB,YAAa,EACb,GAAG,KACC,CACJ,IAAM,EAAS,EAAuB,KAAK,CACrC,CAAC,EAAW,GAAgB,EAAS,GAAM,CAC3C,CAAC,EAAkB,GAAuB,EAAS,EAAgB,CACnE,EAAgB,EAA6C,KAAK,CAClE,EAAmB,OAAO,GAAa,SAEvC,MAA0B,CAC9B,EAAoB,GAAK,CACzB,GAAU,EAGN,MAAwB,CAC5B,EAAc,QAAU,eAAiB,CACvC,GAAmB,EAClB,EAAc,EAGb,MAAwB,CAC5B,AAEE,EAAc,WADd,aAAa,EAAc,QAAQ,CACX,OAItB,MAAwB,CAC5B,GAAiB,CACjB,GAAiB,EAGb,MAAyB,CAC7B,EAAa,GAAK,CAClB,KAAW,EAGP,MAAsB,CACtB,IACF,EAAa,GAAM,CACnB,KAAa,EAEf,GAAiB,EAIb,EAAqB,EACxB,GAAsB,CACjB,EAAO,SAAW,CAAC,EAAO,QAAQ,SAAS,EAAM,OAAe,GAClE,EAAoB,GAAM,CAC1B,KAAc,GAGlB,CAAC,EAAW,CACb,CAyBD,OAvBA,OAEE,SAAS,iBAAiB,YAAa,EAAmB,KAE7C,CAEX,SAAS,oBAAoB,YAAa,EAAmB,GAG9D,CAAC,EAAmB,CAAC,CAetB,EAAC,OAAA,CACC,MAAO,CACL,QAAS,EAAmB,SAAW,eACvC,OAAQ,UACR,WAAY,OACZ,aAAc,WACd,aAAc,MACd,cAAe,MACf,aAAc,QACd,aACE,GAAmB,GAAoB,EACnC,UACA,cACN,WAAY,6BACb,CACD,KAAK,SACL,SAAU,EACV,YAAe,KACf,QA/B0D,GAAM,CAC9D,IACF,EAAE,gBAAgB,CAClB,EAAE,iBAAiB,GA6BnB,YAAa,EACb,UAAW,EACX,aAAc,EACd,aAAc,EACd,WAAY,EACZ,cAAe,EACf,WA/BuB,CAEzB,EAAoB,GAAM,EA8BxB,aAAc,EACd,IAAK,EACL,GAAI,EAEH,YACI"}
1
+ {"version":3,"file":"ContentSelector.mjs","names":[],"sources":["../../../src/UI/ContentSelector.tsx"],"sourcesContent":["'use client';\n\nimport type { FunctionalComponent, JSX } from 'preact';\nimport { useCallback, useEffect, useRef, useState } from 'preact/hooks';\n\nconst DEFAULT_PRESS_DETECT_DURATION = 250;\n\ntype ContentSelectorProps = {\n onPress: () => void;\n onHover?: () => void;\n onUnhover?: () => void;\n onClickOutside?: () => void;\n pressDuration?: number;\n isSelecting?: boolean;\n} & Omit<JSX.HTMLAttributes<HTMLDivElement>, 'content'>;\n\nexport const ContentSelector: FunctionalComponent<ContentSelectorProps> = ({\n children,\n onPress: onSelect,\n onHover,\n onUnhover,\n onClickOutside: onUnselect,\n pressDuration = DEFAULT_PRESS_DETECT_DURATION,\n isSelecting: isSelectingProp,\n ...props\n}) => {\n const divRef = useRef<HTMLDivElement>(null);\n const [isHovered, setIsHovered] = useState(false);\n const [isSelectingState, setIsSelectingState] = useState(isSelectingProp);\n const pressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isChildrenString = typeof children === 'string';\n\n const handleOnLongPress = () => {\n setIsSelectingState(true);\n onSelect();\n };\n\n const startPressTimer = () => {\n pressTimerRef.current = setTimeout(() => {\n handleOnLongPress();\n }, pressDuration);\n };\n\n const clearPressTimer = () => {\n if (pressTimerRef.current) {\n clearTimeout(pressTimerRef.current);\n pressTimerRef.current = null;\n }\n };\n\n const handleMouseDown = () => {\n clearPressTimer(); // Ensure any previous timer is cleared\n startPressTimer();\n };\n\n const handleMouseEnter = () => {\n setIsHovered(true);\n onHover?.();\n };\n\n const handleMouseUp = () => {\n if (isHovered) {\n setIsHovered(false);\n onUnhover?.();\n }\n clearPressTimer();\n };\n\n // Use useCallback to ensure the function identity remains stable\n const handleClickOutside = useCallback(\n (event: MouseEvent) => {\n if (divRef.current && !divRef.current.contains(event.target as Node)) {\n setIsSelectingState(false);\n onUnselect?.();\n }\n },\n [onUnselect]\n );\n\n useEffect(() => {\n // Attach click outside listener\n document.addEventListener('mousedown', handleClickOutside);\n\n return () => {\n // Cleanup\n document.removeEventListener('mousedown', handleClickOutside);\n // clearPressTimer(); // Ensure to clear the timer when component unmounts\n };\n }, [handleClickOutside]);\n\n const handleOnClick: JSX.MouseEventHandler<HTMLDivElement> = (e) => {\n if (isSelectingState) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleOnBlur = () => {\n // Stop editing when the element loses focus\n setIsSelectingState(false);\n };\n\n return (\n <span\n style={{\n display: isChildrenString ? 'inline' : 'inline-block',\n cursor: 'pointer',\n userSelect: 'none',\n borderRadius: '0.375rem',\n outlineWidth: '2px',\n outlineOffset: '4px',\n outlineStyle: 'solid',\n outlineColor:\n isSelectingProp || isSelectingState || isHovered\n ? 'inherit'\n : 'transparent',\n transition: 'all 100ms 50ms ease-in-out',\n }}\n role=\"button\"\n tabIndex={0}\n onKeyUp={() => null}\n onClick={handleOnClick}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleMouseDown}\n onTouchEnd={handleMouseUp}\n onTouchCancel={handleMouseUp}\n onBlur={handleOnBlur}\n onMouseEnter={handleMouseEnter}\n ref={divRef}\n {...props}\n >\n {children}\n </span>\n );\n};\n"],"mappings":"0IAKA,MAWa,GAA8D,CACzE,WACA,QAAS,EACT,UACA,YACA,eAAgB,EAChB,gBAAgB,IAChB,YAAa,EACb,GAAG,KACC,CACJ,IAAM,EAAS,EAAuB,KAAK,CACrC,CAAC,EAAW,GAAgB,EAAS,GAAM,CAC3C,CAAC,EAAkB,GAAuB,EAAS,EAAgB,CACnE,EAAgB,EAA6C,KAAK,CAClE,EAAmB,OAAO,GAAa,SAEvC,MAA0B,CAC9B,EAAoB,GAAK,CACzB,GAAU,EAGN,MAAwB,CAC5B,EAAc,QAAU,eAAiB,CACvC,GAAmB,EAClB,EAAc,EAGb,MAAwB,CAC5B,AAEE,EAAc,WADd,aAAa,EAAc,QAAQ,CACX,OAItB,MAAwB,CAC5B,GAAiB,CACjB,GAAiB,EAGb,MAAyB,CAC7B,EAAa,GAAK,CAClB,KAAW,EAGP,MAAsB,CACtB,IACF,EAAa,GAAM,CACnB,KAAa,EAEf,GAAiB,EAIb,EAAqB,EACxB,GAAsB,CACjB,EAAO,SAAW,CAAC,EAAO,QAAQ,SAAS,EAAM,OAAe,GAClE,EAAoB,GAAM,CAC1B,KAAc,GAGlB,CAAC,EAAW,CACb,CAyBD,OAvBA,OAEE,SAAS,iBAAiB,YAAa,EAAmB,KAE7C,CAEX,SAAS,oBAAoB,YAAa,EAAmB,GAG9D,CAAC,EAAmB,CAAC,CAetB,EAAC,OAAD,CACE,MAAO,CACL,QAAS,EAAmB,SAAW,eACvC,OAAQ,UACR,WAAY,OACZ,aAAc,WACd,aAAc,MACd,cAAe,MACf,aAAc,QACd,aACE,GAAmB,GAAoB,EACnC,UACA,cACN,WAAY,6BACb,CACD,KAAK,SACL,SAAU,EACV,YAAe,KACf,QA/B0D,GAAM,CAC9D,IACF,EAAE,gBAAgB,CAClB,EAAE,iBAAiB,GA6BnB,YAAa,EACb,UAAW,EACX,aAAc,EACd,aAAc,EACd,WAAY,EACZ,cAAe,EACf,WA/BuB,CAEzB,EAAoB,GAAM,EA8BxB,aAAc,EACd,IAAK,EACL,GAAI,EAEH,WACI,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"IntlayerProvider.mjs","names":[],"sources":["../../../src/client/IntlayerProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport { localeResolver } from '@intlayer/core/localization';\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, useEffect } 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 useEffect(() => {\n if (localeProp && localeProp !== currentLocale) {\n setCurrentLocale(localeProp);\n }\n }, [localeProp, currentLocale, setCurrentLocale]);\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\n/**\n * Main provider for Intlayer in Preact applications.\n *\n * It provides the Intlayer context to your application, allowing the use\n * of hooks like `useIntlayer` and `useLocale`.\n *\n * @param props - The provider props.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'preact-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider: FunctionComponent<IntlayerProviderProps> = (\n props\n) => (\n <IntlayerEditorProvider>\n <IntlayerProviderContent {...props} />\n </IntlayerEditorProvider>\n);\n"],"mappings":"4gBA0BA,MAAa,EAAwB,EAA6B,CAChE,OAAQ,GAAmB,GAAe,sBAAsB,cAChE,cAAiB,KACjB,cAAe,GAChB,CAAC,CAKW,MAA2B,EAAW,EAAsB,CAc5D,GAER,CACH,OAAQ,EACR,cAAe,EACf,WACA,UAAW,EACX,gBACA,qBACI,CACJ,GAAM,CAAE,wBAAyB,GAAiB,EAAE,CAC9C,CAAE,cAAe,EAAqB,QAAS,GACnD,GAAwB,EAAE,CAEtB,EACJ,GAAc,GAAmB,GAAqB,EAElD,CAAC,EAAe,GAAoB,EACxC,EAAW,wBACX,EACD,CAED,MAAgB,CACV,GAAc,IAAe,GAC/B,EAAiB,EAAW,EAE7B,CAAC,EAAY,EAAe,EAAiB,CAAC,CAcjD,IAAM,EAAY,IAZK,GAA6B,CAC9C,KAAc,UAAU,GAAK,EAAU,UAAU,CAErD,IAAI,CAAC,GAAkB,IAAI,OAAO,CAAC,SAAS,EAAU,CAAE,CACtD,QAAQ,MAAM,UAAU,EAAU,mBAAmB,CACrD,OAGF,EAAiB,EAAU,CAC3B,EAAmB,EAAW,GAAmB,GAAK,IAKlD,EAAiB,EAAe,GAAc,EAAc,CAElE,OACE,EAAC,EAAsB,SAAA,CACrB,MAAO,CACL,OAAQ,EACR,YACA,gBACA,kBACD,CAEA,YAC8B,EAwBxB,EACX,GAEA,EAAC,EAAA,CAAA,SACC,EAAC,EAAA,CAAwB,GAAI,EAAA,CAAS,CAAA,CACf"}
1
+ {"version":3,"file":"IntlayerProvider.mjs","names":[],"sources":["../../../src/client/IntlayerProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport { localeResolver } from '@intlayer/core/localization';\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, useEffect } 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 useEffect(() => {\n if (localeProp && localeProp !== currentLocale) {\n setCurrentLocale(localeProp);\n }\n }, [localeProp, currentLocale, setCurrentLocale]);\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\n/**\n * Main provider for Intlayer in Preact applications.\n *\n * It provides the Intlayer context to your application, allowing the use\n * of hooks like `useIntlayer` and `useLocale`.\n *\n * @param props - The provider props.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'preact-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider: FunctionComponent<IntlayerProviderProps> = (\n props\n) => (\n <IntlayerEditorProvider>\n <IntlayerProviderContent {...props} />\n </IntlayerEditorProvider>\n);\n"],"mappings":"4gBA0BA,MAAa,EAAwB,EAA6B,CAChE,OAAQ,GAAmB,GAAe,sBAAsB,cAChE,cAAiB,KACjB,cAAe,GAChB,CAAC,CAKW,MAA2B,EAAW,EAAsB,CAc5D,GAER,CACH,OAAQ,EACR,cAAe,EACf,WACA,UAAW,EACX,gBACA,qBACI,CACJ,GAAM,CAAE,wBAAyB,GAAiB,EAAE,CAC9C,CAAE,cAAe,EAAqB,QAAS,GACnD,GAAwB,EAAE,CAEtB,EACJ,GAAc,GAAmB,GAAqB,EAElD,CAAC,EAAe,GAAoB,EACxC,EAAW,wBACX,EACD,CAED,MAAgB,CACV,GAAc,IAAe,GAC/B,EAAiB,EAAW,EAE7B,CAAC,EAAY,EAAe,EAAiB,CAAC,CAcjD,IAAM,EAAY,IAZK,GAA6B,CAC9C,KAAc,UAAU,GAAK,EAAU,UAAU,CAErD,IAAI,CAAC,GAAkB,IAAI,OAAO,CAAC,SAAS,EAAU,CAAE,CACtD,QAAQ,MAAM,UAAU,EAAU,mBAAmB,CACrD,OAGF,EAAiB,EAAU,CAC3B,EAAmB,EAAW,GAAmB,GAAK,IAKlD,EAAiB,EAAe,GAAc,EAAc,CAElE,OACE,EAAC,EAAsB,SAAvB,CACE,MAAO,CACL,OAAQ,EACR,YACA,gBACA,kBACD,CAEA,WAC8B,CAAA,EAwBxB,EACX,GAEA,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAyB,GAAI,EAAS,CAAA,CACf,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"CommunicatorContext.mjs","names":[],"sources":["../../../src/editor/CommunicatorContext.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport {\n type ComponentChildren,\n createContext,\n type FunctionComponent,\n} from 'preact';\nimport { useContext, useMemo, useRef } from 'preact/hooks';\n\nconst randomUUID = () => Math.random().toString(36).slice(2);\n\nexport type UseCrossPlatformStateProps = {\n postMessage: typeof window.postMessage;\n allowedOrigins?: string[];\n senderId: string;\n};\n\nconst { editor } = configuration;\n\nconst CommunicatorContext = createContext<UseCrossPlatformStateProps>({\n postMessage: () => null,\n allowedOrigins: [\n editor?.applicationURL,\n editor?.editorURL,\n editor?.cmsURL,\n ] as string[],\n senderId: '',\n});\n\nexport type CommunicatorProviderProps = {\n children?: ComponentChildren;\n postMessage: typeof window.postMessage;\n allowedOrigins?: string[];\n};\n\nexport const CommunicatorProvider: FunctionComponent<\n CommunicatorProviderProps\n> = ({ children, allowedOrigins, postMessage }) => {\n // Create a stable, unique ID for the lifetime of this app/iframe instance.\n const senderIdRef = useRef(randomUUID());\n\n const value = useMemo(\n () => ({ postMessage, allowedOrigins, senderId: senderIdRef.current }),\n [postMessage, allowedOrigins] // senderIdRef.current is stable\n );\n\n return (\n <CommunicatorContext.Provider value={value}>\n {children}\n </CommunicatorContext.Provider>\n );\n};\n\nexport const useCommunicator = () => useContext(CommunicatorContext);\n"],"mappings":"sMAUA,MAAM,MAAmB,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CAQtD,CAAE,UAAW,EAEb,EAAsB,EAA0C,CACpE,gBAAmB,KACnB,eAAgB,CACd,GAAQ,eACR,GAAQ,UACR,GAAQ,OACT,CACD,SAAU,GACX,CAAC,CAQW,GAER,CAAE,WAAU,iBAAgB,iBAAkB,CAEjD,IAAM,EAAc,EAAO,GAAY,CAAC,CAElC,EAAQ,OACL,CAAE,cAAa,iBAAgB,SAAU,EAAY,QAAS,EACrE,CAAC,EAAa,EAAe,CAC9B,CAED,OACE,EAAC,EAAoB,SAAA,CAAgB,QAClC,YAC4B,EAItB,MAAwB,EAAW,EAAoB"}
1
+ {"version":3,"file":"CommunicatorContext.mjs","names":[],"sources":["../../../src/editor/CommunicatorContext.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport {\n type ComponentChildren,\n createContext,\n type FunctionComponent,\n} from 'preact';\nimport { useContext, useMemo, useRef } from 'preact/hooks';\n\nconst randomUUID = () => Math.random().toString(36).slice(2);\n\nexport type UseCrossPlatformStateProps = {\n postMessage: typeof window.postMessage;\n allowedOrigins?: string[];\n senderId: string;\n};\n\nconst { editor } = configuration;\n\nconst CommunicatorContext = createContext<UseCrossPlatformStateProps>({\n postMessage: () => null,\n allowedOrigins: [\n editor?.applicationURL,\n editor?.editorURL,\n editor?.cmsURL,\n ] as string[],\n senderId: '',\n});\n\nexport type CommunicatorProviderProps = {\n children?: ComponentChildren;\n postMessage: typeof window.postMessage;\n allowedOrigins?: string[];\n};\n\nexport const CommunicatorProvider: FunctionComponent<\n CommunicatorProviderProps\n> = ({ children, allowedOrigins, postMessage }) => {\n // Create a stable, unique ID for the lifetime of this app/iframe instance.\n const senderIdRef = useRef(randomUUID());\n\n const value = useMemo(\n () => ({ postMessage, allowedOrigins, senderId: senderIdRef.current }),\n [postMessage, allowedOrigins] // senderIdRef.current is stable\n );\n\n return (\n <CommunicatorContext.Provider value={value}>\n {children}\n </CommunicatorContext.Provider>\n );\n};\n\nexport const useCommunicator = () => useContext(CommunicatorContext);\n"],"mappings":"sMAUA,MAAM,MAAmB,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CAQtD,CAAE,UAAW,EAEb,EAAsB,EAA0C,CACpE,gBAAmB,KACnB,eAAgB,CACd,GAAQ,eACR,GAAQ,UACR,GAAQ,OACT,CACD,SAAU,GACX,CAAC,CAQW,GAER,CAAE,WAAU,iBAAgB,iBAAkB,CAEjD,IAAM,EAAc,EAAO,GAAY,CAAC,CAElC,EAAQ,OACL,CAAE,cAAa,iBAAgB,SAAU,EAAY,QAAS,EACrE,CAAC,EAAa,EAAe,CAC9B,CAED,OACE,EAAC,EAAoB,SAArB,CAAqC,QAClC,WAC4B,CAAA,EAItB,MAAwB,EAAW,EAAoB"}
@@ -1 +1 @@
1
- {"version":3,"file":"ConfigurationContext.mjs","names":[],"sources":["../../../src/editor/ConfigurationContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { IntlayerConfig } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport { useCrossFrameState } from './useCrossFrameState';\n\nconst ConfigurationStatesContext = createContext<IntlayerConfig | undefined>(\n undefined\n);\n\nexport const useConfigurationState = () =>\n useCrossFrameState<IntlayerConfig>(\n MessageKey.INTLAYER_CONFIGURATION,\n undefined,\n {\n receive: false,\n emit: true,\n }\n );\n\nexport type ConfigurationProviderProps = {\n configuration?: IntlayerConfig;\n};\n\nexport const ConfigurationProvider: FunctionalComponent<\n RenderableProps<ConfigurationProviderProps>\n> = ({ children, configuration }) => (\n <ConfigurationStatesContext.Provider value={configuration}>\n {children}\n </ConfigurationStatesContext.Provider>\n);\n\nexport const useConfiguration = () => useContext(ConfigurationStatesContext);\n"],"mappings":"mPAYA,MAAM,EAA6B,EACjC,IAAA,GACD,CAEY,MACX,EACE,EAAW,uBACX,IAAA,GACA,CACE,QAAS,GACT,KAAM,GACP,CACF,CAMU,GAER,CAAE,WAAU,mBACf,EAAC,EAA2B,SAAA,CAAS,MAAO,EACzC,YACmC,CAG3B,MAAyB,EAAW,EAA2B"}
1
+ {"version":3,"file":"ConfigurationContext.mjs","names":[],"sources":["../../../src/editor/ConfigurationContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { IntlayerConfig } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport { useCrossFrameState } from './useCrossFrameState';\n\nconst ConfigurationStatesContext = createContext<IntlayerConfig | undefined>(\n undefined\n);\n\nexport const useConfigurationState = () =>\n useCrossFrameState<IntlayerConfig>(\n MessageKey.INTLAYER_CONFIGURATION,\n undefined,\n {\n receive: false,\n emit: true,\n }\n );\n\nexport type ConfigurationProviderProps = {\n configuration?: IntlayerConfig;\n};\n\nexport const ConfigurationProvider: FunctionalComponent<\n RenderableProps<ConfigurationProviderProps>\n> = ({ children, configuration }) => (\n <ConfigurationStatesContext.Provider value={configuration}>\n {children}\n </ConfigurationStatesContext.Provider>\n);\n\nexport const useConfiguration = () => useContext(ConfigurationStatesContext);\n"],"mappings":"mPAYA,MAAM,EAA6B,EACjC,IAAA,GACD,CAEY,MACX,EACE,EAAW,uBACX,IAAA,GACA,CACE,QAAS,GACT,KAAM,GACP,CACF,CAMU,GAER,CAAE,WAAU,mBACf,EAAC,EAA2B,SAA5B,CAAqC,MAAO,EACzC,WACmC,CAAA,CAG3B,MAAyB,EAAW,EAA2B"}
@@ -1 +1 @@
1
- {"version":3,"file":"ContentSelectorWrapper.mjs","names":[],"sources":["../../../src/editor/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport type { NodeProps } from '@intlayer/core/interpreter';\nimport { isSameKeyPath } from '@intlayer/core/utils';\nimport { MessageKey } from '@intlayer/editor';\nimport { NodeType } from '@intlayer/types';\nimport type { FunctionalComponent, JSX } from 'preact';\nimport { useCallback, useMemo } from 'preact/hooks';\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<JSX.HTMLAttributes<HTMLDivElement>, 'children'>;\n\nconst ContentSelectorWrapperContent: FunctionalComponent<\n ContentSelectorWrapperProps\n> = ({ children, dictionaryKey, keyPath }) => {\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: FunctionalComponent<\n ContentSelectorWrapperProps\n> = ({ children, ...props }) => {\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":"wjBAiBA,MAAM,GAED,CAAE,WAAU,gBAAe,aAAc,CAC5C,GAAM,CAAE,iBAAgB,qBAAsB,GAAoB,CAC5D,CAAE,cAAa,YAAa,GAAiB,CAG7C,EAAkB,MAChB,EAAQ,OAAQ,GAAQ,EAAI,OAAS,EAAS,YAAY,CAChE,CAAC,EAAQ,CACV,CA2CD,OACE,EAAC,EAAA,CACC,QA3CiB,MAEjB,EAAkB,CAChB,gBACA,QAAS,EACV,CAAC,CACJ,CAAC,EAAe,EAAgB,CACjC,CAqCG,QAnCgB,MAEhB,EAAY,CACV,KAAM,GAAG,EAAW,iCAAiC,OACrD,KAAM,CACJ,gBACA,QAAS,EACV,CACD,WACD,CAAC,CACJ,CAAC,EAAe,EAAgB,CACjC,CAyBG,UAvBkB,MAElB,EAAY,CACV,KAAM,GAAG,EAAW,iCAAiC,OACrD,KAAM,KACN,WACD,CAAC,CACJ,CAAC,EAAS,CACX,CAgBG,YAde,OAEd,GAAgB,gBAAkB,IAChC,GAAgB,SAAS,QAAU,GAAK,GACzC,EAAc,GAAgB,SAAW,EAAE,CAAE,EAAgB,GAC/D,GACF,CAAC,EAAgB,EAAiB,EAAc,CACjD,CASI,YACe,EAIT,GAER,CAAE,WAAU,GAAG,KAAY,CAC9B,GAAM,CAAE,WAAY,GAAkB,CAChC,CAAE,iBAAkB,GAAoB,CAU9C,OARI,GAAW,CAAC,EAEZ,EAAC,EAAA,CAA8B,GAAI,EAChC,YAC6B,CAI7B"}
1
+ {"version":3,"file":"ContentSelectorWrapper.mjs","names":[],"sources":["../../../src/editor/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport type { NodeProps } from '@intlayer/core/interpreter';\nimport { isSameKeyPath } from '@intlayer/core/utils';\nimport { MessageKey } from '@intlayer/editor';\nimport { NodeType } from '@intlayer/types';\nimport type { FunctionalComponent, JSX } from 'preact';\nimport { useCallback, useMemo } from 'preact/hooks';\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<JSX.HTMLAttributes<HTMLDivElement>, 'children'>;\n\nconst ContentSelectorWrapperContent: FunctionalComponent<\n ContentSelectorWrapperProps\n> = ({ children, dictionaryKey, keyPath }) => {\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: FunctionalComponent<\n ContentSelectorWrapperProps\n> = ({ children, ...props }) => {\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":"wjBAiBA,MAAM,GAED,CAAE,WAAU,gBAAe,aAAc,CAC5C,GAAM,CAAE,iBAAgB,qBAAsB,GAAoB,CAC5D,CAAE,cAAa,YAAa,GAAiB,CAG7C,EAAkB,MAChB,EAAQ,OAAQ,GAAQ,EAAI,OAAS,EAAS,YAAY,CAChE,CAAC,EAAQ,CACV,CA2CD,OACE,EAAC,EAAD,CACE,QA3CiB,MAEjB,EAAkB,CAChB,gBACA,QAAS,EACV,CAAC,CACJ,CAAC,EAAe,EAAgB,CACjC,CAqCG,QAnCgB,MAEhB,EAAY,CACV,KAAM,GAAG,EAAW,iCAAiC,OACrD,KAAM,CACJ,gBACA,QAAS,EACV,CACD,WACD,CAAC,CACJ,CAAC,EAAe,EAAgB,CACjC,CAyBG,UAvBkB,MAElB,EAAY,CACV,KAAM,GAAG,EAAW,iCAAiC,OACrD,KAAM,KACN,WACD,CAAC,CACJ,CAAC,EAAS,CACX,CAgBG,YAde,OAEd,GAAgB,gBAAkB,IAChC,GAAgB,SAAS,QAAU,GAAK,GACzC,EAAc,GAAgB,SAAW,EAAE,CAAE,EAAgB,GAC/D,GACF,CAAC,EAAgB,EAAiB,EAAc,CACjD,CASI,WACe,CAAA,EAIT,GAER,CAAE,WAAU,GAAG,KAAY,CAC9B,GAAM,CAAE,WAAY,GAAkB,CAChC,CAAE,iBAAkB,GAAoB,CAU9C,OARI,GAAW,CAAC,EAEZ,EAAC,EAAD,CAA+B,GAAI,EAChC,WAC6B,CAAA,CAI7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"DictionariesRecordContext.mjs","names":[],"sources":["../../../src/editor/DictionariesRecordContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { Dictionary } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext, useMemo } from 'preact/hooks';\nimport {\n type CrossFrameStateUpdater,\n useCrossFrameState,\n} from './useCrossFrameState';\n\nexport type DictionaryContent = Record<Dictionary['key'], Dictionary>;\n\ntype DictionariesRecordStatesContextType = {\n localeDictionaries: DictionaryContent;\n};\ntype DictionariesRecordActionsContextType = {\n setLocaleDictionaries: CrossFrameStateUpdater<DictionaryContent>;\n setLocaleDictionary: (dictionary: Dictionary) => void;\n};\n\nconst DictionariesRecordStatesContext = createContext<\n DictionariesRecordStatesContextType | undefined\n>(undefined);\nconst DictionariesRecordActionsContext = createContext<\n DictionariesRecordActionsContextType | undefined\n>(undefined);\n\nexport const DictionariesRecordProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [localeDictionaries, setLocaleDictionaries] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED,\n undefined\n );\n\n const stateValue = useMemo(\n () => ({\n localeDictionaries: localeDictionaries ?? {},\n }),\n [localeDictionaries]\n );\n\n const actionValue = useMemo(\n () => ({\n setLocaleDictionaries,\n setLocaleDictionary: (dictionary: Dictionary) => {\n setLocaleDictionaries((dictionaries) => ({\n ...dictionaries,\n [String(dictionary.localId)]: dictionary,\n }));\n },\n }),\n [setLocaleDictionaries]\n );\n\n return (\n <DictionariesRecordStatesContext.Provider value={stateValue}>\n <DictionariesRecordActionsContext.Provider value={actionValue}>\n {children}\n </DictionariesRecordActionsContext.Provider>\n </DictionariesRecordStatesContext.Provider>\n );\n};\n\nexport const useDictionariesRecordActions = () =>\n useContext(DictionariesRecordActionsContext);\n\nexport const useDictionariesRecord = () => {\n const actionsContext = useDictionariesRecordActions();\n const statesContext = useContext(DictionariesRecordStatesContext);\n\n if (!statesContext) {\n throw new Error(\n 'useDictionariesRecordStates must be used within a DictionariesRecordProvider'\n );\n }\n\n return { ...statesContext, ...actionsContext };\n};\n"],"mappings":"gQAyBA,MAAM,EAAkC,EAEtC,IAAA,GAAU,CACN,EAAmC,EAEvC,IAAA,GAAU,CAEC,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,EAAoB,GACzB,EACE,EAAW,qCACX,IAAA,GACD,CAEG,EAAa,OACV,CACL,mBAAoB,GAAsB,EAAE,CAC7C,EACD,CAAC,EAAmB,CACrB,CAEK,EAAc,OACX,CACL,wBACA,oBAAsB,GAA2B,CAC/C,EAAuB,IAAkB,CACvC,GAAG,GACF,OAAO,EAAW,QAAQ,EAAG,EAC/B,EAAE,EAEN,EACD,CAAC,EAAsB,CACxB,CAED,OACE,EAAC,EAAgC,SAAA,CAAS,MAAO,WAC/C,EAAC,EAAiC,SAAA,CAAS,MAAO,EAC/C,YACyC,EACH,EAIlC,MACX,EAAW,EAAiC,CAEjC,MAA8B,CACzC,IAAM,EAAiB,GAA8B,CAC/C,EAAgB,EAAW,EAAgC,CAEjE,GAAI,CAAC,EACH,MAAU,MACR,+EACD,CAGH,MAAO,CAAE,GAAG,EAAe,GAAG,EAAgB"}
1
+ {"version":3,"file":"DictionariesRecordContext.mjs","names":[],"sources":["../../../src/editor/DictionariesRecordContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { Dictionary } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext, useMemo } from 'preact/hooks';\nimport {\n type CrossFrameStateUpdater,\n useCrossFrameState,\n} from './useCrossFrameState';\n\nexport type DictionaryContent = Record<Dictionary['key'], Dictionary>;\n\ntype DictionariesRecordStatesContextType = {\n localeDictionaries: DictionaryContent;\n};\ntype DictionariesRecordActionsContextType = {\n setLocaleDictionaries: CrossFrameStateUpdater<DictionaryContent>;\n setLocaleDictionary: (dictionary: Dictionary) => void;\n};\n\nconst DictionariesRecordStatesContext = createContext<\n DictionariesRecordStatesContextType | undefined\n>(undefined);\nconst DictionariesRecordActionsContext = createContext<\n DictionariesRecordActionsContextType | undefined\n>(undefined);\n\nexport const DictionariesRecordProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [localeDictionaries, setLocaleDictionaries] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED,\n undefined\n );\n\n const stateValue = useMemo(\n () => ({\n localeDictionaries: localeDictionaries ?? {},\n }),\n [localeDictionaries]\n );\n\n const actionValue = useMemo(\n () => ({\n setLocaleDictionaries,\n setLocaleDictionary: (dictionary: Dictionary) => {\n setLocaleDictionaries((dictionaries) => ({\n ...dictionaries,\n [String(dictionary.localId)]: dictionary,\n }));\n },\n }),\n [setLocaleDictionaries]\n );\n\n return (\n <DictionariesRecordStatesContext.Provider value={stateValue}>\n <DictionariesRecordActionsContext.Provider value={actionValue}>\n {children}\n </DictionariesRecordActionsContext.Provider>\n </DictionariesRecordStatesContext.Provider>\n );\n};\n\nexport const useDictionariesRecordActions = () =>\n useContext(DictionariesRecordActionsContext);\n\nexport const useDictionariesRecord = () => {\n const actionsContext = useDictionariesRecordActions();\n const statesContext = useContext(DictionariesRecordStatesContext);\n\n if (!statesContext) {\n throw new Error(\n 'useDictionariesRecordStates must be used within a DictionariesRecordProvider'\n );\n }\n\n return { ...statesContext, ...actionsContext };\n};\n"],"mappings":"gQAyBA,MAAM,EAAkC,EAEtC,IAAA,GAAU,CACN,EAAmC,EAEvC,IAAA,GAAU,CAEC,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,EAAoB,GACzB,EACE,EAAW,qCACX,IAAA,GACD,CAEG,EAAa,OACV,CACL,mBAAoB,GAAsB,EAAE,CAC7C,EACD,CAAC,EAAmB,CACrB,CAEK,EAAc,OACX,CACL,wBACA,oBAAsB,GAA2B,CAC/C,EAAuB,IAAkB,CACvC,GAAG,GACF,OAAO,EAAW,QAAQ,EAAG,EAC/B,EAAE,EAEN,EACD,CAAC,EAAsB,CACxB,CAED,OACE,EAAC,EAAgC,SAAjC,CAA0C,MAAO,WAC/C,EAAC,EAAiC,SAAlC,CAA2C,MAAO,EAC/C,WACyC,CAAA,CACH,CAAA,EAIlC,MACX,EAAW,EAAiC,CAEjC,MAA8B,CACzC,IAAM,EAAiB,GAA8B,CAC/C,EAAgB,EAAW,EAAgC,CAEjE,GAAI,CAAC,EACH,MAAU,MACR,+EACD,CAGH,MAAO,CAAE,GAAG,EAAe,GAAG,EAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"EditedContentContext.mjs","names":[],"sources":["../../../src/editor/EditedContentContext.tsx"],"sourcesContent":["'use client';\n\nimport {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core/dictionaryManipulator';\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 FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\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: CrossFrameStateUpdater<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,>(\n state?: S | ((prevState: S) => S),\n prevState?: S\n): S =>\n typeof state === 'function'\n ? (state as (prevState?: S) => S)(prevState)\n : (state as S);\n\nexport const EditedContentProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const { localeDictionaries } = useDictionariesRecord();\n\n const [editedContent, setEditedContentState] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED\n );\n\n const setEditedDictionary: CrossFrameStateUpdater<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\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 = { ...prev };\n delete filtered[dictionaryLocalId];\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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"}
1
+ {"version":3,"file":"EditedContentContext.mjs","names":[],"sources":["../../../src/editor/EditedContentContext.tsx"],"sourcesContent":["'use client';\n\nimport {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core/dictionaryManipulator';\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 FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\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: CrossFrameStateUpdater<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,>(\n state?: S | ((prevState: S) => S),\n prevState?: S\n): S =>\n typeof state === 'function'\n ? (state as (prevState?: S) => S)(prevState)\n : (state as S);\n\nexport const EditedContentProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const { localeDictionaries } = useDictionariesRecord();\n\n const [editedContent, setEditedContentState] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED\n );\n\n const setEditedDictionary: CrossFrameStateUpdater<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\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 = { ...prev };\n delete filtered[dictionaryLocalId];\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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"EditorEnabledContext.mjs","names":[],"sources":["../../../src/editor/EditorEnabledContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\nimport {\n type CrossFrameStateOptions,\n useCrossFrameState,\n} from './useCrossFrameState';\n\nexport type EditorEnabledStateProps = {\n enabled: boolean;\n};\n\nconst EditorEnabledContext = createContext<EditorEnabledStateProps>({\n enabled: false,\n});\n\nexport const useEditorEnabledState = (options?: CrossFrameStateOptions) =>\n useCrossFrameState(MessageKey.INTLAYER_EDITOR_ENABLED, false, options);\n\nexport const usePostEditorEnabledState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITOR_ENABLED}/post`,\n onEventTriggered\n );\n\nexport const useGetEditorEnabledState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITOR_ENABLED}/get`,\n onEventTriggered\n );\n\nexport const EditorEnabledProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [isEnabled] = useEditorEnabledState({\n emit: false,\n receive: true,\n });\n\n return (\n <EditorEnabledContext.Provider value={{ enabled: isEnabled }}>\n {children}\n </EditorEnabledContext.Provider>\n );\n};\n\nexport const useEditorEnabled = () => useContext(EditorEnabledContext);\n"],"mappings":"qUAmBA,MAAM,EAAuB,EAAuC,CAClE,QAAS,GACV,CAAC,CAEW,EAAyB,GACpC,EAAmB,EAAW,wBAAyB,GAAO,EAAQ,CAE3D,EACX,GAEA,EACE,GAAG,EAAW,wBAAwB,OACtC,EACD,CAEU,EACX,GAEA,EACE,GAAG,EAAW,wBAAwB,MACtC,EACD,CAEU,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,GAAa,EAAsB,CACxC,KAAM,GACN,QAAS,GACV,CAAC,CAEF,OACE,EAAC,EAAqB,SAAA,CAAS,MAAO,CAAE,QAAS,EAAW,CACzD,YAC6B,EAIvB,MAAyB,EAAW,EAAqB"}
1
+ {"version":3,"file":"EditorEnabledContext.mjs","names":[],"sources":["../../../src/editor/EditorEnabledContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\nimport {\n type CrossFrameStateOptions,\n useCrossFrameState,\n} from './useCrossFrameState';\n\nexport type EditorEnabledStateProps = {\n enabled: boolean;\n};\n\nconst EditorEnabledContext = createContext<EditorEnabledStateProps>({\n enabled: false,\n});\n\nexport const useEditorEnabledState = (options?: CrossFrameStateOptions) =>\n useCrossFrameState(MessageKey.INTLAYER_EDITOR_ENABLED, false, options);\n\nexport const usePostEditorEnabledState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITOR_ENABLED}/post`,\n onEventTriggered\n );\n\nexport const useGetEditorEnabledState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITOR_ENABLED}/get`,\n onEventTriggered\n );\n\nexport const EditorEnabledProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [isEnabled] = useEditorEnabledState({\n emit: false,\n receive: true,\n });\n\n return (\n <EditorEnabledContext.Provider value={{ enabled: isEnabled }}>\n {children}\n </EditorEnabledContext.Provider>\n );\n};\n\nexport const useEditorEnabled = () => useContext(EditorEnabledContext);\n"],"mappings":"qUAmBA,MAAM,EAAuB,EAAuC,CAClE,QAAS,GACV,CAAC,CAEW,EAAyB,GACpC,EAAmB,EAAW,wBAAyB,GAAO,EAAQ,CAE3D,EACX,GAEA,EACE,GAAG,EAAW,wBAAwB,OACtC,EACD,CAEU,EACX,GAEA,EACE,GAAG,EAAW,wBAAwB,MACtC,EACD,CAEU,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,GAAa,EAAsB,CACxC,KAAM,GACN,QAAS,GACV,CAAC,CAEF,OACE,EAAC,EAAqB,SAAtB,CAA+B,MAAO,CAAE,QAAS,EAAW,CACzD,WAC6B,CAAA,EAIvB,MAAyB,EAAW,EAAqB"}
@@ -1 +1 @@
1
- {"version":3,"file":"EditorProvider.mjs","names":[],"sources":["../../../src/editor/EditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport type {\n ComponentChildren,\n FunctionalComponent,\n RenderableProps,\n} from 'preact';\nimport { useEffect, useState } from 'preact/hooks';\nimport {\n CommunicatorProvider,\n type CommunicatorProviderProps,\n} from './CommunicatorContext';\nimport {\n ConfigurationProvider,\n type ConfigurationProviderProps,\n} from './ConfigurationContext';\nimport { DictionariesRecordProvider } from './DictionariesRecordContext';\nimport {\n EditedContentProvider,\n useGetEditedContentState,\n} from './EditedContentContext';\nimport {\n EditorEnabledProvider,\n useEditorEnabled,\n useGetEditorEnabledState,\n} from './EditorEnabledContext';\nimport { FocusDictionaryProvider } from './FocusDictionaryContext';\n\n/**\n * This component add all the providers needed by the editor.\n * It is used to wrap the application, or the editor to work together.\n */\nconst EditorProvidersWrapper: FunctionalComponent<RenderableProps<{}>> = ({\n children,\n}) => {\n const getEditedContentState = useGetEditedContentState();\n\n useEffect(() => {\n getEditedContentState();\n }, []);\n\n return (\n <DictionariesRecordProvider>\n <EditedContentProvider>\n <FocusDictionaryProvider>{children}</FocusDictionaryProvider>\n </EditedContentProvider>\n </DictionariesRecordProvider>\n );\n};\n\ntype FallbackProps = {\n fallback: ComponentChildren;\n};\n\n/**\n * This component check if the editor is enabled to render the editor providers.\n */\nconst EditorEnabledCheckRenderer: FunctionalComponent<\n RenderableProps<FallbackProps>\n> = ({ children, fallback }) => {\n const getEditorEnabled = useGetEditorEnabledState();\n\n const { enabled } = useEditorEnabled();\n\n useEffect(() => {\n if (enabled) return;\n\n // Check if the editor is wrapping the application\n getEditorEnabled();\n }, [enabled]);\n\n return enabled ? children : fallback;\n};\n\n/**\n * This component is used to check if the editor is wrapping the application.\n * It avoid to send window.postMessage to the application if the editor is not wrapping the application.\n */\nconst IframeCheckRenderer: FunctionalComponent<\n RenderableProps<FallbackProps>\n> = ({ children, fallback }) => {\n const [isInIframe, setIsInIframe] = useState(false);\n\n useEffect(() => {\n setIsInIframe(window.self !== window.top);\n }, []);\n\n return isInIframe ? children : fallback;\n};\n\nexport type EditorProviderProps = CommunicatorProviderProps &\n ConfigurationProviderProps;\n\nexport const EditorProvider: FunctionalComponent<\n RenderableProps<EditorProviderProps>\n> = ({ children, configuration, ...props }) => (\n <EditorEnabledProvider>\n <ConfigurationProvider configuration={configuration}>\n <IframeCheckRenderer fallback={children}>\n <CommunicatorProvider {...props}>\n <EditorEnabledCheckRenderer fallback={children}>\n <EditorProvidersWrapper>{children}</EditorProvidersWrapper>\n </EditorEnabledCheckRenderer>\n </CommunicatorProvider>\n </IframeCheckRenderer>\n </ConfigurationProvider>\n </EditorEnabledProvider>\n);\n"],"mappings":"6lBAgCA,MAAM,GAAoE,CACxE,cACI,CACJ,IAAM,EAAwB,GAA0B,CAMxD,OAJA,MAAgB,CACd,GAAuB,EACtB,EAAE,CAAC,CAGJ,EAAC,EAAA,CAAA,SACC,EAAC,EAAA,CAAA,SACC,EAAC,EAAA,CAAyB,WAAA,CAAmC,CAAA,CACvC,CAAA,CACG,EAW3B,GAED,CAAE,WAAU,cAAe,CAC9B,IAAM,EAAmB,GAA0B,CAE7C,CAAE,WAAY,GAAkB,CAStC,OAPA,MAAgB,CACV,GAGJ,GAAkB,EACjB,CAAC,EAAQ,CAAC,CAEN,EAAU,EAAW,GAOxB,GAED,CAAE,WAAU,cAAe,CAC9B,GAAM,CAAC,EAAY,GAAiB,EAAS,GAAM,CAMnD,OAJA,MAAgB,CACd,EAAc,OAAO,OAAS,OAAO,IAAI,EACxC,EAAE,CAAC,CAEC,EAAa,EAAW,GAMpB,GAER,CAAE,WAAU,gBAAe,GAAG,KACjC,EAAC,EAAA,CAAA,SACC,EAAC,EAAA,CAAqC,yBACpC,EAAC,EAAA,CAAoB,SAAU,WAC7B,EAAC,EAAA,CAAqB,GAAI,WACxB,EAAC,EAAA,CAA2B,SAAU,WACpC,EAAC,EAAA,CAAwB,WAAA,CAAkC,EAChC,EACR,EACH,EACA,CAAA,CACF"}
1
+ {"version":3,"file":"EditorProvider.mjs","names":[],"sources":["../../../src/editor/EditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport type {\n ComponentChildren,\n FunctionalComponent,\n RenderableProps,\n} from 'preact';\nimport { useEffect, useState } from 'preact/hooks';\nimport {\n CommunicatorProvider,\n type CommunicatorProviderProps,\n} from './CommunicatorContext';\nimport {\n ConfigurationProvider,\n type ConfigurationProviderProps,\n} from './ConfigurationContext';\nimport { DictionariesRecordProvider } from './DictionariesRecordContext';\nimport {\n EditedContentProvider,\n useGetEditedContentState,\n} from './EditedContentContext';\nimport {\n EditorEnabledProvider,\n useEditorEnabled,\n useGetEditorEnabledState,\n} from './EditorEnabledContext';\nimport { FocusDictionaryProvider } from './FocusDictionaryContext';\n\n/**\n * This component add all the providers needed by the editor.\n * It is used to wrap the application, or the editor to work together.\n */\nconst EditorProvidersWrapper: FunctionalComponent<RenderableProps<{}>> = ({\n children,\n}) => {\n const getEditedContentState = useGetEditedContentState();\n\n useEffect(() => {\n getEditedContentState();\n }, []);\n\n return (\n <DictionariesRecordProvider>\n <EditedContentProvider>\n <FocusDictionaryProvider>{children}</FocusDictionaryProvider>\n </EditedContentProvider>\n </DictionariesRecordProvider>\n );\n};\n\ntype FallbackProps = {\n fallback: ComponentChildren;\n};\n\n/**\n * This component check if the editor is enabled to render the editor providers.\n */\nconst EditorEnabledCheckRenderer: FunctionalComponent<\n RenderableProps<FallbackProps>\n> = ({ children, fallback }) => {\n const getEditorEnabled = useGetEditorEnabledState();\n\n const { enabled } = useEditorEnabled();\n\n useEffect(() => {\n if (enabled) return;\n\n // Check if the editor is wrapping the application\n getEditorEnabled();\n }, [enabled]);\n\n return enabled ? children : fallback;\n};\n\n/**\n * This component is used to check if the editor is wrapping the application.\n * It avoid to send window.postMessage to the application if the editor is not wrapping the application.\n */\nconst IframeCheckRenderer: FunctionalComponent<\n RenderableProps<FallbackProps>\n> = ({ children, fallback }) => {\n const [isInIframe, setIsInIframe] = useState(false);\n\n useEffect(() => {\n setIsInIframe(window.self !== window.top);\n }, []);\n\n return isInIframe ? children : fallback;\n};\n\nexport type EditorProviderProps = CommunicatorProviderProps &\n ConfigurationProviderProps;\n\nexport const EditorProvider: FunctionalComponent<\n RenderableProps<EditorProviderProps>\n> = ({ children, configuration, ...props }) => (\n <EditorEnabledProvider>\n <ConfigurationProvider configuration={configuration}>\n <IframeCheckRenderer fallback={children}>\n <CommunicatorProvider {...props}>\n <EditorEnabledCheckRenderer fallback={children}>\n <EditorProvidersWrapper>{children}</EditorProvidersWrapper>\n </EditorEnabledCheckRenderer>\n </CommunicatorProvider>\n </IframeCheckRenderer>\n </ConfigurationProvider>\n </EditorEnabledProvider>\n);\n"],"mappings":"6lBAgCA,MAAM,GAAoE,CACxE,cACI,CACJ,IAAM,EAAwB,GAA0B,CAMxD,OAJA,MAAgB,CACd,GAAuB,EACtB,EAAE,CAAC,CAGJ,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAA0B,WAAmC,CAAA,CACvC,CAAA,CACG,CAAA,EAW3B,GAED,CAAE,WAAU,cAAe,CAC9B,IAAM,EAAmB,GAA0B,CAE7C,CAAE,WAAY,GAAkB,CAStC,OAPA,MAAgB,CACV,GAGJ,GAAkB,EACjB,CAAC,EAAQ,CAAC,CAEN,EAAU,EAAW,GAOxB,GAED,CAAE,WAAU,cAAe,CAC9B,GAAM,CAAC,EAAY,GAAiB,EAAS,GAAM,CAMnD,OAJA,MAAgB,CACd,EAAc,OAAO,OAAS,OAAO,IAAI,EACxC,EAAE,CAAC,CAEC,EAAa,EAAW,GAMpB,GAER,CAAE,WAAU,gBAAe,GAAG,KACjC,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAsC,yBACpC,EAAC,EAAD,CAAqB,SAAU,WAC7B,EAAC,EAAD,CAAsB,GAAI,WACxB,EAAC,EAAD,CAA4B,SAAU,WACpC,EAAC,EAAD,CAAyB,WAAkC,CAAA,CAChC,CAAA,CACR,CAAA,CACH,CAAA,CACA,CAAA,CACF,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"FocusDictionaryContext.mjs","names":[],"sources":["../../../src/editor/FocusDictionaryContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { KeyPath } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport {\n type CrossFrameStateUpdater,\n useCrossFrameState,\n} from './useCrossFrameState';\n\ntype DictionaryPath = string;\n\nexport type FileContent = {\n dictionaryKey: string;\n keyPath?: KeyPath[];\n dictionaryPath?: DictionaryPath;\n};\n\ntype FocusDictionaryState = {\n focusedContent: FileContent | null;\n};\n\ntype FocusDictionaryActions = {\n setFocusedContent: CrossFrameStateUpdater<FileContent | null>;\n setFocusedContentKeyPath: (keyPath: KeyPath[]) => void;\n};\n\nconst FocusDictionaryStateContext = createContext<\n FocusDictionaryState | undefined\n>(undefined);\nconst FocusDictionaryActionsContext = createContext<\n FocusDictionaryActions | undefined\n>(undefined);\n\nexport const FocusDictionaryProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [focusedContent, setFocusedContent] =\n useCrossFrameState<FileContent | null>(\n MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED,\n null\n );\n\n const setFocusedContentKeyPath = (keyPath: KeyPath[]) => {\n setFocusedContent((prev) => {\n if (!prev) {\n return prev; // nothing to update if there's no focused content\n }\n return { ...prev, keyPath };\n });\n };\n\n return (\n <FocusDictionaryStateContext.Provider value={{ focusedContent }}>\n <FocusDictionaryActionsContext.Provider\n value={{ setFocusedContent, setFocusedContentKeyPath }}\n >\n {children}\n </FocusDictionaryActionsContext.Provider>\n </FocusDictionaryStateContext.Provider>\n );\n};\n\nexport const useFocusDictionaryActions = () => {\n const context = useContext(FocusDictionaryActionsContext);\n if (context === undefined) {\n throw new Error(\n 'useFocusDictionaryActions must be used within a FocusDictionaryProvider'\n );\n }\n return context;\n};\n\nexport const useFocusDictionary = () => {\n const actionContext = useFocusDictionaryActions();\n const stateContext = useContext(FocusDictionaryStateContext);\n\n if (stateContext === undefined) {\n throw new Error(\n 'useFocusDictionaryState must be used within a FocusDictionaryProvider'\n );\n }\n\n return { ...stateContext, ...actionContext };\n};\n"],"mappings":"mPAgCA,MAAM,EAA8B,EAElC,IAAA,GAAU,CACN,EAAgC,EAEpC,IAAA,GAAU,CAEC,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,EAAgB,GACrB,EACE,EAAW,iCACX,KACD,CAWH,OACE,EAAC,EAA4B,SAAA,CAAS,MAAO,CAAE,iBAAgB,UAC7D,EAAC,EAA8B,SAAA,CAC7B,MAAO,CAAE,oBAAmB,yBAZA,GAAuB,CACvD,EAAmB,GACZ,GAGE,CAAE,GAAG,EAAM,UAAS,CAC3B,EAMwD,CAErD,YACsC,EACJ,EAI9B,MAAkC,CAC7C,IAAM,EAAU,EAAW,EAA8B,CACzD,GAAI,IAAY,IAAA,GACd,MAAU,MACR,0EACD,CAEH,OAAO,GAGI,MAA2B,CACtC,IAAM,EAAgB,GAA2B,CAC3C,EAAe,EAAW,EAA4B,CAE5D,GAAI,IAAiB,IAAA,GACnB,MAAU,MACR,wEACD,CAGH,MAAO,CAAE,GAAG,EAAc,GAAG,EAAe"}
1
+ {"version":3,"file":"FocusDictionaryContext.mjs","names":[],"sources":["../../../src/editor/FocusDictionaryContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { KeyPath } from '@intlayer/types';\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport {\n type CrossFrameStateUpdater,\n useCrossFrameState,\n} from './useCrossFrameState';\n\ntype DictionaryPath = string;\n\nexport type FileContent = {\n dictionaryKey: string;\n keyPath?: KeyPath[];\n dictionaryPath?: DictionaryPath;\n};\n\ntype FocusDictionaryState = {\n focusedContent: FileContent | null;\n};\n\ntype FocusDictionaryActions = {\n setFocusedContent: CrossFrameStateUpdater<FileContent | null>;\n setFocusedContentKeyPath: (keyPath: KeyPath[]) => void;\n};\n\nconst FocusDictionaryStateContext = createContext<\n FocusDictionaryState | undefined\n>(undefined);\nconst FocusDictionaryActionsContext = createContext<\n FocusDictionaryActions | undefined\n>(undefined);\n\nexport const FocusDictionaryProvider: FunctionalComponent<\n RenderableProps<{}>\n> = ({ children }) => {\n const [focusedContent, setFocusedContent] =\n useCrossFrameState<FileContent | null>(\n MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED,\n null\n );\n\n const setFocusedContentKeyPath = (keyPath: KeyPath[]) => {\n setFocusedContent((prev) => {\n if (!prev) {\n return prev; // nothing to update if there's no focused content\n }\n return { ...prev, keyPath };\n });\n };\n\n return (\n <FocusDictionaryStateContext.Provider value={{ focusedContent }}>\n <FocusDictionaryActionsContext.Provider\n value={{ setFocusedContent, setFocusedContentKeyPath }}\n >\n {children}\n </FocusDictionaryActionsContext.Provider>\n </FocusDictionaryStateContext.Provider>\n );\n};\n\nexport const useFocusDictionaryActions = () => {\n const context = useContext(FocusDictionaryActionsContext);\n if (context === undefined) {\n throw new Error(\n 'useFocusDictionaryActions must be used within a FocusDictionaryProvider'\n );\n }\n return context;\n};\n\nexport const useFocusDictionary = () => {\n const actionContext = useFocusDictionaryActions();\n const stateContext = useContext(FocusDictionaryStateContext);\n\n if (stateContext === undefined) {\n throw new Error(\n 'useFocusDictionaryState must be used within a FocusDictionaryProvider'\n );\n }\n\n return { ...stateContext, ...actionContext };\n};\n"],"mappings":"mPAgCA,MAAM,EAA8B,EAElC,IAAA,GAAU,CACN,EAAgC,EAEpC,IAAA,GAAU,CAEC,GAER,CAAE,cAAe,CACpB,GAAM,CAAC,EAAgB,GACrB,EACE,EAAW,iCACX,KACD,CAWH,OACE,EAAC,EAA4B,SAA7B,CAAsC,MAAO,CAAE,iBAAgB,UAC7D,EAAC,EAA8B,SAA/B,CACE,MAAO,CAAE,oBAAmB,yBAZA,GAAuB,CACvD,EAAmB,GACZ,GAGE,CAAE,GAAG,EAAM,UAAS,CAC3B,EAMwD,CAErD,WACsC,CAAA,CACJ,CAAA,EAI9B,MAAkC,CAC7C,IAAM,EAAU,EAAW,EAA8B,CACzD,GAAI,IAAY,IAAA,GACd,MAAU,MACR,0EACD,CAEH,OAAO,GAGI,MAA2B,CACtC,IAAM,EAAgB,GAA2B,CAC3C,EAAe,EAAW,EAA4B,CAE5D,GAAI,IAAiB,IAAA,GACnB,MAAU,MACR,wEACD,CAGH,MAAO,CAAE,GAAG,EAAc,GAAG,EAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"IntlayerEditorProvider.mjs","names":[],"sources":["../../../src/editor/IntlayerEditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport type { ComponentChildren, FunctionComponent } from 'preact';\nimport { useEffect } from 'preact/hooks';\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 // Load dictionaries dynamically to do not impact the bundle, and send them to the editor\n import('@intlayer/unmerged-dictionaries-entry').then((mod) => {\n const unmergedDictionaries = mod.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\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":"+eAWA,MAAM,MAAsD,CAI1D,GAAuB,CAKvB,GAA2B,CAK3B,GAAM,CAAE,yBAA0B,GAA8B,EAAI,EAAE,CAgBtE,OAdA,MAAgB,CAEd,OAAO,yCAAyC,KAAM,GAAQ,CAC5D,IAAM,EAAuB,EAAI,yBAAyB,CACpD,EAAmB,OAAO,YAC9B,OAAO,OAAO,EAAqB,CAChC,MAAM,CACN,IAAK,GAAe,CAAC,EAAW,QAAS,EAAW,CAAC,CACzD,CAED,IAAwB,EAAiB,EACzC,EACD,EAAE,CAAC,CAEC,EAAA,EAAA,EAAA,CAAK,EAGR,CAAE,UAAW,EAEb,MAA8C,CAClD,GAAM,CAAE,WAAY,GAAkB,CAEtC,OAAiB,EAAV,EAAW,EAAgC,EAAhC,EAAA,CAAqC,EAG5C,GAEP,CAAE,cAEJ,EAAC,EAAA,CACC,YAAc,GAAc,CACtB,OAAO,OAAW,KAEH,OAAO,OAAS,OAAO,MAGtC,EAAO,eAAe,OAAS,GACjC,QAAQ,YACN,EAGA,EAAO,eACR,CAGC,EAAO,UAAU,OAAS,GAC5B,OAAO,QAAQ,YACb,EAGA,EAAO,UACR,CAGC,EAAO,OAAO,OAAS,GACzB,OAAO,QAAQ,YACb,EAGA,EAAO,OACR,GAGL,eAAgB,CACd,GAAQ,UACR,GAAQ,OACR,GAAQ,eACT,CACc,0BAEf,EAAC,EAAA,EAAA,CAAqB,CACrB,EAAA,EACc"}
1
+ {"version":3,"file":"IntlayerEditorProvider.mjs","names":[],"sources":["../../../src/editor/IntlayerEditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport configuration from '@intlayer/config/built';\nimport type { ComponentChildren, FunctionComponent } from 'preact';\nimport { useEffect } from 'preact/hooks';\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 // Load dictionaries dynamically to do not impact the bundle, and send them to the editor\n import('@intlayer/unmerged-dictionaries-entry').then((mod) => {\n const unmergedDictionaries = mod.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\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":"+eAWA,MAAM,MAAsD,CAI1D,GAAuB,CAKvB,GAA2B,CAK3B,GAAM,CAAE,yBAA0B,GAA8B,EAAI,EAAE,CAgBtE,OAdA,MAAgB,CAEd,OAAO,yCAAyC,KAAM,GAAQ,CAC5D,IAAM,EAAuB,EAAI,yBAAyB,CACpD,EAAmB,OAAO,YAC9B,OAAO,OAAO,EAAqB,CAChC,MAAM,CACN,IAAK,GAAe,CAAC,EAAW,QAAS,EAAW,CAAC,CACzD,CAED,IAAwB,EAAiB,EACzC,EACD,EAAE,CAAC,CAEC,EAAA,EAAA,EAAK,CAAA,EAGR,CAAE,UAAW,EAEb,MAA8C,CAClD,GAAM,CAAE,WAAY,GAAkB,CAEtC,OAAiB,EAAV,EAAW,EAAgC,EAAjC,EAA8B,CAAQ,EAG5C,GAEP,CAAE,cAEJ,EAAC,EAAD,CACE,YAAc,GAAc,CACtB,OAAO,OAAW,KAEH,OAAO,OAAS,OAAO,MAGtC,EAAO,eAAe,OAAS,GACjC,QAAQ,YACN,EAGA,EAAO,eACR,CAGC,EAAO,UAAU,OAAS,GAC5B,OAAO,QAAQ,YACb,EAGA,EAAO,UACR,CAGC,EAAO,OAAO,OAAS,GACzB,OAAO,QAAQ,YACb,EAGA,EAAO,OACR,GAGL,eAAgB,CACd,GAAQ,UACR,GAAQ,OACR,GAAQ,eACT,CACc,yBAvCjB,CAyCE,EAAC,EAAD,EAAsB,CAAA,CACrB,EACc"}
@@ -1 +1 @@
1
- {"version":3,"file":"HTMLProvider.mjs","names":[],"sources":["../../../src/html/HTMLProvider.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport type { HTMLComponents } from './types';\n\ntype HTMLContextValue = {\n components?: HTMLComponents<'permissive', {}>;\n};\n\ntype HTMLProviderProps = RenderableProps<{\n /**\n * Component overrides for HTML tags.\n */\n components?: HTMLComponents<'permissive', {}>;\n}>;\n\nconst HTMLContext = createContext<HTMLContextValue | undefined>(undefined);\n\nexport const useHTMLContext = () => useContext(HTMLContext);\n\nexport const HTMLProvider: FunctionalComponent<HTMLProviderProps> = ({\n children,\n components,\n}) => (\n <HTMLContext.Provider value={{ components }}>{children}</HTMLContext.Provider>\n);\n"],"mappings":"uIAqBA,MAAM,EAAc,EAA4C,IAAA,GAAU,CAE7D,MAAuB,EAAW,EAAY,CAE9C,GAAwD,CACnE,WACA,gBAEA,EAAC,EAAY,SAAA,CAAS,MAAO,CAAE,aAAY,CAAG,YAAgC"}
1
+ {"version":3,"file":"HTMLProvider.mjs","names":[],"sources":["../../../src/html/HTMLProvider.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n type FunctionalComponent,\n type RenderableProps,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport type { HTMLComponents } from './types';\n\ntype HTMLContextValue = {\n components?: HTMLComponents<'permissive', {}>;\n};\n\ntype HTMLProviderProps = RenderableProps<{\n /**\n * Component overrides for HTML tags.\n */\n components?: HTMLComponents<'permissive', {}>;\n}>;\n\nconst HTMLContext = createContext<HTMLContextValue | undefined>(undefined);\n\nexport const useHTMLContext = () => useContext(HTMLContext);\n\nexport const HTMLProvider: FunctionalComponent<HTMLProviderProps> = ({\n children,\n components,\n}) => (\n <HTMLContext.Provider value={{ components }}>{children}</HTMLContext.Provider>\n);\n"],"mappings":"uIAqBA,MAAM,EAAc,EAA4C,IAAA,GAAU,CAE7D,MAAuB,EAAW,EAAY,CAE9C,GAAwD,CACnE,WACA,gBAEA,EAAC,EAAY,SAAb,CAAsB,MAAO,CAAE,aAAY,CAAG,WAAgC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownProvider.mjs","names":[],"sources":["../../../src/markdown/MarkdownProvider.tsx"],"sourcesContent":["import {\n type ComponentChildren,\n createContext,\n type FunctionComponent,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport type { HTMLComponents } from '../html/types';\nimport { compileMarkdown } from './compiler';\n\ntype PropsWithChildren<P = {}> = P & { children?: ComponentChildren };\n\n/**\n * Refined options for the MarkdownProvider.\n */\nexport type MarkdownProviderOptions = {\n /**\n * Forces the compiler to always output content with a block-level wrapper.\n */\n forceBlock?: boolean;\n /**\n * Forces the compiler to always output content with an inline wrapper.\n */\n forceInline?: boolean;\n /**\n * Whether to preserve frontmatter in the markdown content.\n */\n preserveFrontmatter?: boolean;\n /**\n * Whether to use the GitHub Tag Filter.\n */\n tagfilter?: boolean;\n};\n\ntype RenderMarkdownOptions = MarkdownProviderOptions & {\n components?: HTMLComponents<'permissive', {}>;\n wrapper?: any;\n};\n\ntype MarkdownContextValue = {\n renderMarkdown: (\n markdown: string,\n overrides?: HTMLComponents<'permissive', {}> | RenderMarkdownOptions\n ) => ComponentChildren;\n};\n\ntype MarkdownProviderProps = PropsWithChildren<\n MarkdownProviderOptions & {\n /**\n * Component overrides for HTML tags.\n */\n components?: HTMLComponents<'permissive', {}>;\n /**\n * Wrapper element or component to be used when there are multiple children.\n */\n wrapper?: any;\n /**\n * Custom render function for markdown.\n * If provided, it will overwrite all rules and default rendering.\n */\n renderMarkdown?: (\n markdown: string,\n overrides?: HTMLComponents<'permissive', {}> | RenderMarkdownOptions\n ) => ComponentChildren;\n }\n>;\n\nconst MarkdownContext = createContext<MarkdownContextValue | undefined>(\n undefined\n);\n\nexport const useMarkdownContext = () => useContext(MarkdownContext);\n\nexport const MarkdownProvider: FunctionComponent<MarkdownProviderProps> = ({\n children,\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n renderMarkdown,\n}) => {\n // Map public options to internal processor options\n const internalOptions: any = {\n components,\n forceBlock,\n forceInline,\n wrapper,\n forceWrapper: !!wrapper,\n preserveFrontmatter,\n tagfilter,\n };\n\n const finalRenderMarkdown = renderMarkdown\n ? (\n markdown: string,\n componentsOverride?:\n | HTMLComponents<'permissive', {}>\n | RenderMarkdownOptions\n ) => (\n <MarkdownContext.Provider value={undefined}>\n {renderMarkdown(markdown, componentsOverride)}\n </MarkdownContext.Provider>\n )\n : (\n markdown: string,\n componentsOverride?:\n | HTMLComponents<'permissive', {}>\n | RenderMarkdownOptions\n ) => {\n const {\n components: overrideComponents,\n wrapper: localWrapper,\n forceBlock: localForceBlock,\n forceInline: localForceInline,\n preserveFrontmatter: localPreserveFrontmatter,\n tagfilter: localTagfilter,\n ...componentsFromRest\n } = componentsOverride as RenderMarkdownOptions;\n\n const localComponents = (overrideComponents ||\n componentsFromRest) as HTMLComponents<'permissive', {}>;\n\n return compileMarkdown(markdown, {\n ...internalOptions,\n forceBlock: localForceBlock ?? internalOptions.forceBlock,\n forceInline: localForceInline ?? internalOptions.forceInline,\n preserveFrontmatter:\n localPreserveFrontmatter ?? internalOptions.preserveFrontmatter,\n tagfilter: localTagfilter ?? internalOptions.tagfilter,\n wrapper: localWrapper || wrapper || internalOptions.wrapper,\n forceWrapper: !!(localWrapper || wrapper),\n components: {\n ...internalOptions.components,\n ...localComponents,\n },\n }) as ComponentChildren;\n };\n\n return (\n <MarkdownContext.Provider value={{ renderMarkdown: finalRenderMarkdown }}>\n {children}\n </MarkdownContext.Provider>\n );\n};\n"],"mappings":"2KAkEA,MAAM,EAAkB,EACtB,IAAA,GACD,CAEY,MAA2B,EAAW,EAAgB,CAEtD,GAA8D,CACzE,WACA,aACA,UACA,aACA,cACA,sBACA,YACA,oBACI,CAEJ,IAAM,EAAuB,CAC3B,aACA,aACA,cACA,UACA,aAAc,CAAC,CAAC,EAChB,sBACA,YACD,CAEK,EAAsB,GAEtB,EACA,IAIA,EAAC,EAAgB,SAAA,CAAS,MAAO,IAAA,YAC9B,EAAe,EAAU,EAAmB,EACpB,EAG3B,EACA,IAGG,CACH,GAAM,CACJ,WAAY,EACZ,QAAS,EACT,WAAY,EACZ,YAAa,EACb,oBAAqB,EACrB,UAAW,EACX,GAAG,GACD,EAEE,EAAmB,GACvB,EAEF,OAAO,EAAgB,EAAU,CAC/B,GAAG,EACH,WAAY,GAAmB,EAAgB,WAC/C,YAAa,GAAoB,EAAgB,YACjD,oBACE,GAA4B,EAAgB,oBAC9C,UAAW,GAAkB,EAAgB,UAC7C,QAAS,GAAgB,GAAW,EAAgB,QACpD,aAAc,CAAC,EAAE,GAAgB,GACjC,WAAY,CACV,GAAG,EAAgB,WACnB,GAAG,EACJ,CACF,CAAC,EAGR,OACE,EAAC,EAAgB,SAAA,CAAS,MAAO,CAAE,eAAgB,EAAqB,CACrE,YACwB"}
1
+ {"version":3,"file":"MarkdownProvider.mjs","names":[],"sources":["../../../src/markdown/MarkdownProvider.tsx"],"sourcesContent":["import {\n type ComponentChildren,\n createContext,\n type FunctionComponent,\n} from 'preact';\nimport { useContext } from 'preact/hooks';\nimport type { HTMLComponents } from '../html/types';\nimport { compileMarkdown } from './compiler';\n\ntype PropsWithChildren<P = {}> = P & { children?: ComponentChildren };\n\n/**\n * Refined options for the MarkdownProvider.\n */\nexport type MarkdownProviderOptions = {\n /**\n * Forces the compiler to always output content with a block-level wrapper.\n */\n forceBlock?: boolean;\n /**\n * Forces the compiler to always output content with an inline wrapper.\n */\n forceInline?: boolean;\n /**\n * Whether to preserve frontmatter in the markdown content.\n */\n preserveFrontmatter?: boolean;\n /**\n * Whether to use the GitHub Tag Filter.\n */\n tagfilter?: boolean;\n};\n\ntype RenderMarkdownOptions = MarkdownProviderOptions & {\n components?: HTMLComponents<'permissive', {}>;\n wrapper?: any;\n};\n\ntype MarkdownContextValue = {\n renderMarkdown: (\n markdown: string,\n overrides?: HTMLComponents<'permissive', {}> | RenderMarkdownOptions\n ) => ComponentChildren;\n};\n\ntype MarkdownProviderProps = PropsWithChildren<\n MarkdownProviderOptions & {\n /**\n * Component overrides for HTML tags.\n */\n components?: HTMLComponents<'permissive', {}>;\n /**\n * Wrapper element or component to be used when there are multiple children.\n */\n wrapper?: any;\n /**\n * Custom render function for markdown.\n * If provided, it will overwrite all rules and default rendering.\n */\n renderMarkdown?: (\n markdown: string,\n overrides?: HTMLComponents<'permissive', {}> | RenderMarkdownOptions\n ) => ComponentChildren;\n }\n>;\n\nconst MarkdownContext = createContext<MarkdownContextValue | undefined>(\n undefined\n);\n\nexport const useMarkdownContext = () => useContext(MarkdownContext);\n\nexport const MarkdownProvider: FunctionComponent<MarkdownProviderProps> = ({\n children,\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n renderMarkdown,\n}) => {\n // Map public options to internal processor options\n const internalOptions: any = {\n components,\n forceBlock,\n forceInline,\n wrapper,\n forceWrapper: !!wrapper,\n preserveFrontmatter,\n tagfilter,\n };\n\n const finalRenderMarkdown = renderMarkdown\n ? (\n markdown: string,\n componentsOverride?:\n | HTMLComponents<'permissive', {}>\n | RenderMarkdownOptions\n ) => (\n <MarkdownContext.Provider value={undefined}>\n {renderMarkdown(markdown, componentsOverride)}\n </MarkdownContext.Provider>\n )\n : (\n markdown: string,\n componentsOverride?:\n | HTMLComponents<'permissive', {}>\n | RenderMarkdownOptions\n ) => {\n const {\n components: overrideComponents,\n wrapper: localWrapper,\n forceBlock: localForceBlock,\n forceInline: localForceInline,\n preserveFrontmatter: localPreserveFrontmatter,\n tagfilter: localTagfilter,\n ...componentsFromRest\n } = componentsOverride as RenderMarkdownOptions;\n\n const localComponents = (overrideComponents ||\n componentsFromRest) as HTMLComponents<'permissive', {}>;\n\n return compileMarkdown(markdown, {\n ...internalOptions,\n forceBlock: localForceBlock ?? internalOptions.forceBlock,\n forceInline: localForceInline ?? internalOptions.forceInline,\n preserveFrontmatter:\n localPreserveFrontmatter ?? internalOptions.preserveFrontmatter,\n tagfilter: localTagfilter ?? internalOptions.tagfilter,\n wrapper: localWrapper || wrapper || internalOptions.wrapper,\n forceWrapper: !!(localWrapper || wrapper),\n components: {\n ...internalOptions.components,\n ...localComponents,\n },\n }) as ComponentChildren;\n };\n\n return (\n <MarkdownContext.Provider value={{ renderMarkdown: finalRenderMarkdown }}>\n {children}\n </MarkdownContext.Provider>\n );\n};\n"],"mappings":"2KAkEA,MAAM,EAAkB,EACtB,IAAA,GACD,CAEY,MAA2B,EAAW,EAAgB,CAEtD,GAA8D,CACzE,WACA,aACA,UACA,aACA,cACA,sBACA,YACA,oBACI,CAEJ,IAAM,EAAuB,CAC3B,aACA,aACA,cACA,UACA,aAAc,CAAC,CAAC,EAChB,sBACA,YACD,CAEK,EAAsB,GAEtB,EACA,IAIA,EAAC,EAAgB,SAAjB,CAA0B,MAAO,IAAA,YAC9B,EAAe,EAAU,EAAmB,CACpB,CAAA,EAG3B,EACA,IAGG,CACH,GAAM,CACJ,WAAY,EACZ,QAAS,EACT,WAAY,EACZ,YAAa,EACb,oBAAqB,EACrB,UAAW,EACX,GAAG,GACD,EAEE,EAAmB,GACvB,EAEF,OAAO,EAAgB,EAAU,CAC/B,GAAG,EACH,WAAY,GAAmB,EAAgB,WAC/C,YAAa,GAAoB,EAAgB,YACjD,oBACE,GAA4B,EAAgB,oBAC9C,UAAW,GAAkB,EAAgB,UAC7C,QAAS,GAAgB,GAAW,EAAgB,QACpD,aAAc,CAAC,EAAE,GAAgB,GACjC,WAAY,CACV,GAAG,EAAgB,WACnB,GAAG,EACJ,CACF,CAAC,EAGR,OACE,EAAC,EAAgB,SAAjB,CAA0B,MAAO,CAAE,eAAgB,EAAqB,CACrE,WACwB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownRenderer.mjs","names":[],"sources":["../../../src/markdown/MarkdownRenderer.tsx"],"sourcesContent":["import type { ComponentChildren, FunctionComponent, JSX } from 'preact';\nimport type { HTMLComponents } from '../html/types';\nimport { compileMarkdown, type MarkdownCompilerOptions } from './compiler';\nimport {\n type MarkdownProviderOptions,\n useMarkdownContext,\n} from './MarkdownProvider';\n\nexport type RenderMarkdownProps = MarkdownProviderOptions & {\n /**\n * Component overrides for HTML tags.\n * Only used if not wrapped in a MarkdownProvider.\n */\n components?: HTMLComponents<'permissive', {}>;\n /**\n * Wrapper element or component to be used when there are multiple children.\n * Only used if not wrapped in a MarkdownProvider.\n */\n wrapper?: FunctionComponent<any>;\n};\n\nexport const renderMarkdown = (\n content: string,\n {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n }: RenderMarkdownProps = {}\n): JSX.Element => {\n // Map public options to internal processor options\n const internalOptions: MarkdownCompilerOptions = {\n components,\n forceBlock,\n forceInline,\n wrapper: wrapper as any,\n forceWrapper: !!wrapper,\n preserveFrontmatter,\n tagfilter,\n };\n\n return compileMarkdown(content, internalOptions) as JSX.Element;\n};\n\nexport const useMarkdownRenderer = ({\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n}: RenderMarkdownProps = {}) => {\n const context = useMarkdownContext();\n\n return (content: string) => {\n if (context) {\n return context.renderMarkdown(content, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n }\n\n return renderMarkdown(content, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n };\n};\n\ntype MarkdownRendererProps = RenderMarkdownProps & {\n /**\n * The markdown content to render.\n */\n children: string;\n /**\n * Custom render function for markdown.\n * If provided, it will overwrite context and default rendering.\n */\n renderMarkdown?: (\n markdown: string,\n options?: {\n components?: HTMLComponents<'permissive', {}>;\n wrapper?: FunctionComponent<any>;\n forceBlock?: boolean;\n forceInline?: boolean;\n preserveFrontmatter?: boolean;\n tagfilter?: boolean;\n }\n ) => ComponentChildren;\n};\n\n/**\n * Preact component that renders markdown to JSX.\n *\n * It uses the renderMarkdown function from the MarkdownProvider context if available.\n * Otherwise, it falls back to the default compiler with provided components and options.\n */\nexport const MarkdownRenderer: FunctionComponent<MarkdownRendererProps> = ({\n children = '',\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n renderMarkdown: customRenderMarkdown,\n}) => {\n const context = useMarkdownContext();\n\n if (customRenderMarkdown) {\n return (\n <>\n {customRenderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n })}\n </>\n );\n }\n\n if (context) {\n return (\n <>\n {context.renderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n })}\n </>\n );\n }\n\n return renderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n};\n"],"mappings":"oKAqBA,MAAa,GACX,EACA,CACE,aACA,UACA,aACA,cACA,sBACA,aACuB,EAAE,GAapB,EAAgB,EAV0B,CAC/C,aACA,aACA,cACS,UACT,aAAc,CAAC,CAAC,EAChB,sBACA,YACD,CAE+C,CAGrC,GAAuB,CAClC,aACA,UACA,aACA,cACA,sBACA,aACuB,EAAE,GAAK,CAC9B,IAAM,EAAU,GAAoB,CAEpC,MAAQ,IACF,EACK,EAAQ,eAAe,EAAS,CACrC,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CAGG,EAAe,EAAS,CAC7B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,EAgCO,GAA8D,CACzE,WAAW,GACX,aACA,UACA,aACA,cACA,sBACA,YACA,eAAgB,KACZ,CACJ,IAAM,EAAU,GAAoB,CAgCpC,OA9BI,EAEA,EAAA,EAAA,CAAA,SACG,EAAqB,EAAU,CAC9B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CAAA,CACD,CAIH,EAEA,EAAA,EAAA,CAAA,SACG,EAAQ,eAAe,EAAU,CAChC,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CAAA,CACD,CAIA,EAAe,EAAU,CAC9B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC"}
1
+ {"version":3,"file":"MarkdownRenderer.mjs","names":[],"sources":["../../../src/markdown/MarkdownRenderer.tsx"],"sourcesContent":["import type { ComponentChildren, FunctionComponent, JSX } from 'preact';\nimport type { HTMLComponents } from '../html/types';\nimport { compileMarkdown, type MarkdownCompilerOptions } from './compiler';\nimport {\n type MarkdownProviderOptions,\n useMarkdownContext,\n} from './MarkdownProvider';\n\nexport type RenderMarkdownProps = MarkdownProviderOptions & {\n /**\n * Component overrides for HTML tags.\n * Only used if not wrapped in a MarkdownProvider.\n */\n components?: HTMLComponents<'permissive', {}>;\n /**\n * Wrapper element or component to be used when there are multiple children.\n * Only used if not wrapped in a MarkdownProvider.\n */\n wrapper?: FunctionComponent<any>;\n};\n\nexport const renderMarkdown = (\n content: string,\n {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n }: RenderMarkdownProps = {}\n): JSX.Element => {\n // Map public options to internal processor options\n const internalOptions: MarkdownCompilerOptions = {\n components,\n forceBlock,\n forceInline,\n wrapper: wrapper as any,\n forceWrapper: !!wrapper,\n preserveFrontmatter,\n tagfilter,\n };\n\n return compileMarkdown(content, internalOptions) as JSX.Element;\n};\n\nexport const useMarkdownRenderer = ({\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n}: RenderMarkdownProps = {}) => {\n const context = useMarkdownContext();\n\n return (content: string) => {\n if (context) {\n return context.renderMarkdown(content, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n }\n\n return renderMarkdown(content, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n };\n};\n\ntype MarkdownRendererProps = RenderMarkdownProps & {\n /**\n * The markdown content to render.\n */\n children: string;\n /**\n * Custom render function for markdown.\n * If provided, it will overwrite context and default rendering.\n */\n renderMarkdown?: (\n markdown: string,\n options?: {\n components?: HTMLComponents<'permissive', {}>;\n wrapper?: FunctionComponent<any>;\n forceBlock?: boolean;\n forceInline?: boolean;\n preserveFrontmatter?: boolean;\n tagfilter?: boolean;\n }\n ) => ComponentChildren;\n};\n\n/**\n * Preact component that renders markdown to JSX.\n *\n * It uses the renderMarkdown function from the MarkdownProvider context if available.\n * Otherwise, it falls back to the default compiler with provided components and options.\n */\nexport const MarkdownRenderer: FunctionComponent<MarkdownRendererProps> = ({\n children = '',\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n renderMarkdown: customRenderMarkdown,\n}) => {\n const context = useMarkdownContext();\n\n if (customRenderMarkdown) {\n return (\n <>\n {customRenderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n })}\n </>\n );\n }\n\n if (context) {\n return (\n <>\n {context.renderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n })}\n </>\n );\n }\n\n return renderMarkdown(children, {\n components,\n wrapper,\n forceBlock,\n forceInline,\n preserveFrontmatter,\n tagfilter,\n });\n};\n"],"mappings":"oKAqBA,MAAa,GACX,EACA,CACE,aACA,UACA,aACA,cACA,sBACA,aACuB,EAAE,GAapB,EAAgB,EAV0B,CAC/C,aACA,aACA,cACS,UACT,aAAc,CAAC,CAAC,EAChB,sBACA,YACD,CAE+C,CAGrC,GAAuB,CAClC,aACA,UACA,aACA,cACA,sBACA,aACuB,EAAE,GAAK,CAC9B,IAAM,EAAU,GAAoB,CAEpC,MAAQ,IACF,EACK,EAAQ,eAAe,EAAS,CACrC,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CAGG,EAAe,EAAS,CAC7B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,EAgCO,GAA8D,CACzE,WAAW,GACX,aACA,UACA,aACA,cACA,sBACA,YACA,eAAgB,KACZ,CACJ,IAAM,EAAU,GAAoB,CAgCpC,OA9BI,EAEA,EAAA,EAAA,CAAA,SACG,EAAqB,EAAU,CAC9B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CACD,CAAA,CAIH,EAEA,EAAA,EAAA,CAAA,SACG,EAAQ,eAAe,EAAU,CAChC,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC,CACD,CAAA,CAIA,EAAe,EAAU,CAC9B,aACA,UACA,aACA,cACA,sBACA,YACD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.mjs","names":[],"sources":["../../src/plugins.tsx"],"sourcesContent":["import type {\n DeepTransformContent as DeepTransformContentCore,\n IInterpreterPluginState as IInterpreterPluginStateCore,\n Plugins,\n} from '@intlayer/core/interpreter';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\nimport type {\n HTMLContent,\n InsertionContent,\n MarkdownContent,\n} from '@intlayer/core/transpiler';\nimport type { DeclaredLocales, KeyPath, LocalesValues } from '@intlayer/types';\nimport { NodeType } from '@intlayer/types';\nimport { Fragment, h, type VNode } from 'preact';\nimport { ContentSelectorRenderer } from './editor';\nimport { EditedContentRenderer } from './editor/useEditedContentRenderer';\nimport { HTMLRenderer } from './html/HTMLRenderer';\nimport type { HTMLComponents } from './html/types';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { MarkdownMetadataRenderer, MarkdownRenderer } from './markdown';\nimport { renderPreactElement } from './preactElement/renderPreactElement';\n\n/** ---------------------------------------------\n * INTLAYER NODE PLUGIN\n * --------------------------------------------- */\n\nexport type IntlayerNodeCond<T> = T extends number | string\n ? IntlayerNode<T>\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const intlayerNodePlugins: Plugins = {\n id: 'intlayer-node-plugin',\n canHandle: (node) =>\n typeof node === 'bigint' ||\n typeof node === 'string' ||\n typeof node === 'number',\n transform: (\n _node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) =>\n renderIntlayerNode({\n ...rest,\n value: rest.children,\n children: (\n <ContentSelectorRenderer {...rest} key={rest.children}>\n <EditedContentRenderer {...rest}>\n {rest.children}\n </EditedContentRenderer>\n </ContentSelectorRenderer>\n ),\n }),\n};\n\n/** ---------------------------------------------\n * PREACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type PreactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? VNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const preactNodePlugins: Plugins = {\n id: 'preact-node-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n typeof node.props !== 'undefined' &&\n typeof node.key !== 'undefined',\n\n transform: (\n node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) =>\n renderIntlayerNode({\n ...rest,\n value: '[[preact-element]]',\n children: (\n <ContentSelectorRenderer {...rest}>\n {renderPreactElement(node)}\n </ContentSelectorRenderer>\n ),\n }),\n};\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, _S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Insertion]: string;\n fields: readonly string[];\n}\n ? <V extends { [K in T['fields'][number]]: VNode }>(\n values: V\n ) => V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<VNode>\n : never;\n\n/**\n * Check if a value is a Preact VNode\n */\nconst isVNode = (value: any): value is VNode => {\n return (\n value !== null &&\n value !== undefined &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n );\n};\n\n/**\n * Split insertion string and join with Preact VNodes\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | VNode>\n): VNode => {\n // Check if any value is a VNode\n const hasVNode = Object.values(values).some(isVNode);\n\n if (!hasVNode) {\n // Simple string replacement\n return template.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_, key) => {\n const trimmedKey = key.trim();\n return (values[trimmedKey] ?? '').toString();\n }) as any;\n }\n\n // Split the template by placeholders while keeping the structure\n const parts: (string | VNode)[] = [];\n let lastIndex = 0;\n const regex = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n let match: RegExpExecArray | null = regex.exec(template);\n\n while (match !== null) {\n // Add text before the placeholder\n if (match.index > lastIndex) {\n parts.push(template.substring(lastIndex, match.index));\n }\n\n // Add the replaced value\n const key = match[1].trim();\n const value = values[key];\n if (value !== undefined && value !== null) {\n parts.push(typeof value === 'number' ? String(value) : value);\n }\n\n lastIndex = match.index + match[0].length;\n match = regex.exec(template);\n }\n\n // Add remaining text\n if (lastIndex < template.length) {\n parts.push(template.substring(lastIndex));\n }\n\n // Return as Fragment\n return h(\n Fragment,\n null,\n ...parts.map((part, index) => h(Fragment, { key: index }, part))\n );\n};\n\n/** Insertion plugin for Preact. Handles component/node insertion. */\nexport const insertionPlugin: Plugins = {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Insertion,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Insertion,\n },\n ];\n\n const children = node[NodeType.Insertion];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number | VNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result as any,\n });\n };\n },\n };\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/**\n * MARKDOWN PLUGIN\n */\n\nexport type MarkdownStringCond<T> = T extends string\n ? IntlayerNode<\n string,\n {\n metadata: DeepTransformContent<string>;\n use: (components?: HTMLComponents<'permissive', {}>) => VNode;\n }\n >\n : never;\n\n/** Markdown string plugin. Replaces string node with a component that render the markdown. */\nexport const markdownStringPlugin: Plugins = {\n id: 'markdown-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, props, deepTransformNode) => {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n const metadata = getMarkdownMetadata(node);\n\n const metadataPlugins: Plugins = {\n id: 'markdown-metadata-plugin',\n canHandle: (metadataNode) =>\n typeof metadataNode === 'string' ||\n typeof metadataNode === 'number' ||\n typeof metadataNode === 'boolean' ||\n !metadataNode,\n transform: (metadataNode, props) =>\n renderIntlayerNode({\n ...props,\n value: metadataNode,\n children: (\n <ContentSelectorRenderer {...rest}>\n <MarkdownMetadataRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataRenderer>\n </ContentSelectorRenderer>\n ),\n }),\n };\n\n // Transform metadata while keeping the same structure\n const metadataNodes = deepTransformNode(metadata, {\n plugins: [metadataPlugins],\n dictionaryKey: rest.dictionaryKey,\n keyPath: [],\n });\n\n const render = (components?: any) =>\n renderIntlayerNode({\n ...props,\n value: node,\n children: (\n <ContentSelectorRenderer {...rest}>\n <MarkdownRenderer {...rest} {...components}>\n {node}\n </MarkdownRenderer>\n </ContentSelectorRenderer>\n ),\n additionalProps: {\n metadata: metadataNodes,\n },\n });\n\n const element = render() as any;\n\n return new Proxy(element, {\n get(target, prop) {\n if (prop === 'value') {\n return node;\n }\n if (prop === 'metadata') {\n return metadataNodes;\n }\n\n if (prop === 'use') {\n return (components?: any) => render(components);\n }\n\n return Reflect.get(target, prop);\n },\n }) as any;\n },\n};\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.Markdown]: infer _M;\n metadata?: infer U;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => VNode;\n metadata: DeepTransformContent<U>;\n }\n : never;\n\nexport const markdownPlugin: Plugins = {\n id: 'markdown-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Markdown,\n transform: (node: MarkdownContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Markdown,\n },\n ];\n\n const children = node[NodeType.Markdown];\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [markdownStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/** ---------------------------------------------\n * HTML PLUGIN\n * --------------------------------------------- */\n\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.HTML]: infer I;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => IntlayerNode<I>;\n }\n : never;\n\n/** HTML plugin. Replaces node with a function that takes components => VNode. */\nexport const htmlPlugin: Plugins = {\n id: 'html-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.HTML,\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeType.HTML];\n const _tags = node.tags ?? [];\n const { plugins, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): VNode =>\n h(HTMLRenderer as any, { ...rest, html, userComponents } as any);\n\n const element = render() as any;\n\n const proxy = new Proxy(element, {\n get(target, prop) {\n if (prop === 'value') {\n return html;\n }\n\n if (prop === 'use') {\n return (userComponents?: HTMLComponents) => render(userComponents);\n }\n\n return Reflect.get(target, prop);\n },\n });\n\n return proxy;\n },\n};\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport interface IInterpreterPluginPreact<T, _S, _L extends LocalesValues> {\n preactNode: PreactNodeCond<T>;\n preactIntlayerNode: IntlayerNodeCond<T>;\n preactInsertion: InsertionCond<T>;\n preactMarkdown: MarkdownCond<T>;\n preactHtml: HTMLPluginCond<T>;\n}\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `preact-intlayer` plugins will override the types of `intlayer` functions.\n */\nexport type IInterpreterPluginState = Omit<\n IInterpreterPluginStateCore,\n 'insertion' // Remove insertion type from core package\n> & {\n preactNode: true;\n preactIntlayerNode: true;\n preactInsertion: true;\n preactMarkdown: true;\n preactHtml: true;\n};\n\nexport type DeepTransformContent<\n T,\n L extends LocalesValues = DeclaredLocales,\n> = DeepTransformContentCore<T, IInterpreterPluginState, L>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugins.mjs","names":[],"sources":["../../src/plugins.tsx"],"sourcesContent":["import type {\n DeepTransformContent as DeepTransformContentCore,\n IInterpreterPluginState as IInterpreterPluginStateCore,\n Plugins,\n} from '@intlayer/core/interpreter';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\nimport type {\n HTMLContent,\n InsertionContent,\n MarkdownContent,\n} from '@intlayer/core/transpiler';\nimport type { DeclaredLocales, KeyPath, LocalesValues } from '@intlayer/types';\nimport { NodeType } from '@intlayer/types';\nimport { Fragment, h, type VNode } from 'preact';\nimport { ContentSelectorRenderer } from './editor';\nimport { EditedContentRenderer } from './editor/useEditedContentRenderer';\nimport { HTMLRenderer } from './html/HTMLRenderer';\nimport type { HTMLComponents } from './html/types';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { MarkdownMetadataRenderer, MarkdownRenderer } from './markdown';\nimport { renderPreactElement } from './preactElement/renderPreactElement';\n\n/** ---------------------------------------------\n * INTLAYER NODE PLUGIN\n * --------------------------------------------- */\n\nexport type IntlayerNodeCond<T> = T extends number | string\n ? IntlayerNode<T>\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const intlayerNodePlugins: Plugins = {\n id: 'intlayer-node-plugin',\n canHandle: (node) =>\n typeof node === 'bigint' ||\n typeof node === 'string' ||\n typeof node === 'number',\n transform: (\n _node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) =>\n renderIntlayerNode({\n ...rest,\n value: rest.children,\n children: (\n <ContentSelectorRenderer {...rest} key={rest.children}>\n <EditedContentRenderer {...rest}>\n {rest.children}\n </EditedContentRenderer>\n </ContentSelectorRenderer>\n ),\n }),\n};\n\n/** ---------------------------------------------\n * PREACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type PreactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? VNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const preactNodePlugins: Plugins = {\n id: 'preact-node-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n typeof node.props !== 'undefined' &&\n typeof node.key !== 'undefined',\n\n transform: (\n node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) =>\n renderIntlayerNode({\n ...rest,\n value: '[[preact-element]]',\n children: (\n <ContentSelectorRenderer {...rest}>\n {renderPreactElement(node)}\n </ContentSelectorRenderer>\n ),\n }),\n};\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, _S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Insertion]: string;\n fields: readonly string[];\n}\n ? <V extends { [K in T['fields'][number]]: VNode }>(\n values: V\n ) => V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<VNode>\n : never;\n\n/**\n * Check if a value is a Preact VNode\n */\nconst isVNode = (value: any): value is VNode => {\n return (\n value !== null &&\n value !== undefined &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n );\n};\n\n/**\n * Split insertion string and join with Preact VNodes\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | VNode>\n): VNode => {\n // Check if any value is a VNode\n const hasVNode = Object.values(values).some(isVNode);\n\n if (!hasVNode) {\n // Simple string replacement\n return template.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_, key) => {\n const trimmedKey = key.trim();\n return (values[trimmedKey] ?? '').toString();\n }) as any;\n }\n\n // Split the template by placeholders while keeping the structure\n const parts: (string | VNode)[] = [];\n let lastIndex = 0;\n const regex = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n let match: RegExpExecArray | null = regex.exec(template);\n\n while (match !== null) {\n // Add text before the placeholder\n if (match.index > lastIndex) {\n parts.push(template.substring(lastIndex, match.index));\n }\n\n // Add the replaced value\n const key = match[1].trim();\n const value = values[key];\n if (value !== undefined && value !== null) {\n parts.push(typeof value === 'number' ? String(value) : value);\n }\n\n lastIndex = match.index + match[0].length;\n match = regex.exec(template);\n }\n\n // Add remaining text\n if (lastIndex < template.length) {\n parts.push(template.substring(lastIndex));\n }\n\n // Return as Fragment\n return h(\n Fragment,\n null,\n ...parts.map((part, index) => h(Fragment, { key: index }, part))\n );\n};\n\n/** Insertion plugin for Preact. Handles component/node insertion. */\nexport const insertionPlugin: Plugins = {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Insertion,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Insertion,\n },\n ];\n\n const children = node[NodeType.Insertion];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number | VNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result as any,\n });\n };\n },\n };\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/**\n * MARKDOWN PLUGIN\n */\n\nexport type MarkdownStringCond<T> = T extends string\n ? IntlayerNode<\n string,\n {\n metadata: DeepTransformContent<string>;\n use: (components?: HTMLComponents<'permissive', {}>) => VNode;\n }\n >\n : never;\n\n/** Markdown string plugin. Replaces string node with a component that render the markdown. */\nexport const markdownStringPlugin: Plugins = {\n id: 'markdown-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, props, deepTransformNode) => {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n const metadata = getMarkdownMetadata(node);\n\n const metadataPlugins: Plugins = {\n id: 'markdown-metadata-plugin',\n canHandle: (metadataNode) =>\n typeof metadataNode === 'string' ||\n typeof metadataNode === 'number' ||\n typeof metadataNode === 'boolean' ||\n !metadataNode,\n transform: (metadataNode, props) =>\n renderIntlayerNode({\n ...props,\n value: metadataNode,\n children: (\n <ContentSelectorRenderer {...rest}>\n <MarkdownMetadataRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataRenderer>\n </ContentSelectorRenderer>\n ),\n }),\n };\n\n // Transform metadata while keeping the same structure\n const metadataNodes = deepTransformNode(metadata, {\n plugins: [metadataPlugins],\n dictionaryKey: rest.dictionaryKey,\n keyPath: [],\n });\n\n const render = (components?: any) =>\n renderIntlayerNode({\n ...props,\n value: node,\n children: (\n <ContentSelectorRenderer {...rest}>\n <MarkdownRenderer {...rest} {...components}>\n {node}\n </MarkdownRenderer>\n </ContentSelectorRenderer>\n ),\n additionalProps: {\n metadata: metadataNodes,\n },\n });\n\n const element = render() as any;\n\n return new Proxy(element, {\n get(target, prop) {\n if (prop === 'value') {\n return node;\n }\n if (prop === 'metadata') {\n return metadataNodes;\n }\n\n if (prop === 'use') {\n return (components?: any) => render(components);\n }\n\n return Reflect.get(target, prop);\n },\n }) as any;\n },\n};\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.Markdown]: infer _M;\n metadata?: infer U;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => VNode;\n metadata: DeepTransformContent<U>;\n }\n : never;\n\nexport const markdownPlugin: Plugins = {\n id: 'markdown-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Markdown,\n transform: (node: MarkdownContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Markdown,\n },\n ];\n\n const children = node[NodeType.Markdown];\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [markdownStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/** ---------------------------------------------\n * HTML PLUGIN\n * --------------------------------------------- */\n\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.HTML]: infer I;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => IntlayerNode<I>;\n }\n : never;\n\n/** HTML plugin. Replaces node with a function that takes components => VNode. */\nexport const htmlPlugin: Plugins = {\n id: 'html-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.HTML,\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeType.HTML];\n const _tags = node.tags ?? [];\n const { plugins, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): VNode =>\n h(HTMLRenderer as any, { ...rest, html, userComponents } as any);\n\n const element = render() as any;\n\n const proxy = new Proxy(element, {\n get(target, prop) {\n if (prop === 'value') {\n return html;\n }\n\n if (prop === 'use') {\n return (userComponents?: HTMLComponents) => render(userComponents);\n }\n\n return Reflect.get(target, prop);\n },\n });\n\n return proxy;\n },\n};\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport interface IInterpreterPluginPreact<T, _S, _L extends LocalesValues> {\n preactNode: PreactNodeCond<T>;\n preactIntlayerNode: IntlayerNodeCond<T>;\n preactInsertion: InsertionCond<T>;\n preactMarkdown: MarkdownCond<T>;\n preactHtml: HTMLPluginCond<T>;\n}\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `preact-intlayer` plugins will override the types of `intlayer` functions.\n */\nexport type IInterpreterPluginState = Omit<\n IInterpreterPluginStateCore,\n 'insertion' // Remove insertion type from core package\n> & {\n preactNode: true;\n preactIntlayerNode: true;\n preactInsertion: true;\n preactMarkdown: true;\n preactHtml: true;\n};\n\nexport type DeepTransformContent<\n T,\n L extends LocalesValues = DeclaredLocales,\n> = DeepTransformContentCore<T, IInterpreterPluginState, L>;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "preact-intlayer",
3
- "version": "8.2.1",
3
+ "version": "8.2.3",
4
4
  "private": false,
5
5
  "description": "Easily internationalize i18n your Preact applications with type-safe multilingual content management.",
6
6
  "keywords": [
@@ -92,21 +92,21 @@
92
92
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
93
93
  },
94
94
  "dependencies": {
95
- "@intlayer/api": "8.2.1",
96
- "@intlayer/chokidar": "8.2.1",
97
- "@intlayer/config": "8.2.1",
98
- "@intlayer/core": "8.2.1",
99
- "@intlayer/editor": "8.2.1",
100
- "@intlayer/types": "8.2.1",
101
- "@intlayer/unmerged-dictionaries-entry": "8.2.1"
95
+ "@intlayer/api": "8.2.3",
96
+ "@intlayer/chokidar": "8.2.3",
97
+ "@intlayer/config": "8.2.3",
98
+ "@intlayer/core": "8.2.3",
99
+ "@intlayer/editor": "8.2.3",
100
+ "@intlayer/types": "8.2.3",
101
+ "@intlayer/unmerged-dictionaries-entry": "8.2.3"
102
102
  },
103
103
  "devDependencies": {
104
- "@types/node": "25.3.3",
104
+ "@types/node": "25.3.5",
105
105
  "@utils/ts-config": "1.0.4",
106
106
  "@utils/ts-config-types": "1.0.4",
107
107
  "@utils/tsdown-config": "1.0.4",
108
108
  "rimraf": "6.1.3",
109
- "tsdown": "0.20.3",
109
+ "tsdown": "0.21.0",
110
110
  "typescript": "5.9.3",
111
111
  "vitest": "4.0.18"
112
112
  },