UNPKG

@selfcommunity/react-core

Version:

React Core Components useful for integrating UI Community components (react-ui).

93 lines (91 loc) 3.56 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { createContext, useContext, useMemo, useState } from 'react'; import { useSCContext } from '../SCContextProvider'; import { loadLocaleData } from '../../../utils/locale'; import { DEFAULT_LANGUAGE_UI } from '../../../constants/Locale'; import { IntlProvider } from 'react-intl'; import { Logger } from '@selfcommunity/utils'; import { SCOPE_SC_CORE } from '../../../constants/Errors'; import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect'; /** * Creates Global Context * :::tip Context can be consumed in one of the following ways: ```jsx 1. <SCLocaleContext.Consumer>{(locale,) => (...)}</SCLocaleContext.Consumer> ``` ```jsx 2. const scLocaleContext: SCLocaleContextType = useContext(SCLocaleContext); ``` ```jsx 3. const scLocaleContext: SCLocaleContextType = useSCLocale(); ```` ::: */ export const SCLocaleContext = createContext({}); /** * #### Description: * This component makes the `intl` available down the React tree. * @param children * @return * ```jsx * <SCLocaleContext.Provider value={{locale, messages, selectLocale}}> * ``` */ export default function SCLocaleProvider({ children = null }) { var _a; const scContext = useSCContext(); const initialLocale = ((_a = scContext.settings.locale) === null || _a === void 0 ? void 0 : _a.default) ? scContext.settings.locale.default : DEFAULT_LANGUAGE_UI; const initial = loadLocaleData(initialLocale, scContext.settings); const [locale, setLocale] = useState(initial.locale); const [messages, setMessages] = useState(initial.messages); /** * Update current locale state * @param _intl */ const updateLocale = (_intl) => { setLocale(_intl.locale); setMessages(_intl.messages); }; /** * Select locale loading data */ const selectLocale = useMemo(() => (l) => { const { messages, locale } = loadLocaleData(l, scContext.settings); updateLocale({ messages, locale }); }, [locale]); /** * Update locale and messages if initial conf changes */ useDeepCompareEffectNoCheck(() => { var _a; selectLocale(((_a = scContext.settings.locale) === null || _a === void 0 ? void 0 : _a.default) ? scContext.settings.locale.default : DEFAULT_LANGUAGE_UI); }, [scContext.settings.locale]); /** * handleIntlError * @param error */ const handleIntlError = (error) => { if (error.code === 'MISSING_TRANSLATION') { Logger.warn(SCOPE_SC_CORE, `Missing translation: ${error.message}`); return; } throw error; }; return (_jsx(SCLocaleContext.Provider, Object.assign({ value: { locale, messages, selectLocale } }, { children: _jsx(IntlProvider, Object.assign({ locale: locale, messages: messages, onError: handleIntlError }, { children: children }), locale) }))); } /** * Export hoc to inject the base theme to components * @param Component */ export const withSCLocale = (Component) => (props) => { const scLocaleContext = useContext(SCLocaleContext); return (_jsx(IntlProvider, Object.assign({ locale: scLocaleContext.locale, messages: scLocaleContext.messages }, { children: _jsx(Component, Object.assign({ setLanguage: scLocaleContext.selectLocale }, props)) }))); }; /** * Let's only export the `useSCLocale` hook instead of the context. * We only want to use the hook directly and never the context component. */ export function useSCLocale() { return useContext(SCLocaleContext); }