@restnfeel/agentc-starter-kit
Version:
한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템
122 lines (119 loc) • 4.57 kB
JavaScript
import { jsx } from 'react/jsx-runtime';
import React__default, { useReducer, useEffect, createContext, useContext } from 'react';
import { isRTL, translations, DEFAULT_LANGUAGE, t, adjustTextLength, detectBrowserLanguage } from './i18n-config.js';
// Create Context
const I18nContext = createContext(undefined);
// I18n Reducer
function i18nReducer(state, action) {
switch (action.type) {
case "SET_LANGUAGE":
return {
...state,
currentLanguage: action.payload,
translations: translations[action.payload],
isRTL: isRTL(action.payload),
isLoading: false,
};
case "SET_LOADING":
return {
...state,
isLoading: action.payload,
};
default:
return state;
}
}
// Storage Keys
const STORAGE_KEY = "chatbot-language";
// I18n Provider Component
function I18nProvider({ children, defaultLanguage, enableAutoDetect = true, enablePersistence = true, }) {
// Determine initial language
const getInitialLanguage = () => {
// 1. Check localStorage if persistence is enabled
if (enablePersistence && typeof window !== "undefined") {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored && Object.keys(translations).includes(stored)) {
return stored;
}
}
// 2. Use provided default language
if (defaultLanguage) {
return defaultLanguage;
}
// 3. Auto-detect browser language if enabled
if (enableAutoDetect) {
return detectBrowserLanguage();
}
// 4. Fall back to DEFAULT_LANGUAGE
return DEFAULT_LANGUAGE;
};
const initialLanguage = getInitialLanguage();
// Initialize state
const [state, dispatch] = useReducer(i18nReducer, {
currentLanguage: initialLanguage,
translations: translations[initialLanguage],
isRTL: isRTL(initialLanguage),
isLoading: false,
});
// Change language function
const changeLanguage = React__default.useCallback((language) => {
if (!Object.keys(translations).includes(language)) {
console.warn(`Language '${language}' is not supported. Falling back to '${DEFAULT_LANGUAGE}'.`);
language = DEFAULT_LANGUAGE;
}
dispatch({ type: "SET_LOADING", payload: true });
// Simulate loading time for language switching
setTimeout(() => {
dispatch({ type: "SET_LANGUAGE", payload: language });
// Persist language preference
if (enablePersistence && typeof window !== "undefined") {
try {
localStorage.setItem(STORAGE_KEY, language);
}
catch (error) {
console.warn("Failed to save language preference:", error);
}
}
}, 100);
}, [enablePersistence]);
// Translation function
const translate = React__default.useCallback((key) => {
return t(key, state.currentLanguage);
}, [state.currentLanguage]);
// Text formatting function
const formatText = React__default.useCallback((text) => {
return adjustTextLength(text, state.currentLanguage);
}, [state.currentLanguage]);
// Apply RTL direction to document
useEffect(() => {
if (typeof document !== "undefined") {
const chatbotElements = document.querySelectorAll("[data-chatbot]");
chatbotElements.forEach((element) => {
element.dir = state.isRTL ? "rtl" : "ltr";
});
}
}, [state.isRTL]);
// Context value
const contextValue = {
...state,
changeLanguage,
t: translate,
supportedLanguages: Object.keys(translations),
formatText,
};
return (jsx(I18nContext.Provider, { value: contextValue, children: children }));
}
// Custom hook to use I18n context
function useI18n() {
const context = useContext(I18nContext);
if (context === undefined) {
throw new Error("useI18n must be used within an I18nProvider");
}
return context;
}
function RTLText({ children, className = "", tag: Tag = "span", }) {
const { isRTL } = useI18n();
return (jsx(Tag, { className: `${className} ${isRTL ? "text-right" : "text-left"}`, dir: isRTL ? "rtl" : "ltr", children: children }));
}
export { I18nProvider, RTLText, useI18n };
//# sourceMappingURL=i18n-context.js.map