@i18n-micro/preact 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -13
- package/dist/index.mjs +138 -152
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const H=require("@i18n-micro/core"),c=require("preact"),R=require("preact/hooks");class G extends H.BaseI18n{_locale;_fallbackLocale;_currentRoute="general";listeners=new Set;revision=0;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const H=require("@i18n-micro/core"),c=require("preact"),R=require("preact/hooks");class G extends H.BaseI18n{_locale;_fallbackLocale;_currentRoute="general";listeners=new Set;revision=0;storage;constructor(t){const n={translations:new Map};if(super({storage:n,plural:t.plural,missingWarn:t.missingWarn,missingHandler:t.missingHandler}),this.storage=n,this._locale=t.locale,this._fallbackLocale=t.fallbackLocale||t.locale,t.messages)for(const[e,r]of Object.entries(t.messages))this.helper.loadTranslations(e,r)}subscribe=t=>(this.listeners.add(t),()=>this.listeners.delete(t));getSnapshot=()=>`${this._locale}:${this._currentRoute}:${this.revision}`;notify(){this.revision++,this.listeners.forEach(t=>t())}get locale(){return this._locale}set locale(t){this._locale!==t&&(this._locale=t,this.notify())}get fallbackLocale(){return this._fallbackLocale}set fallbackLocale(t){this._fallbackLocale=t}get currentRoute(){return this._currentRoute}setRoute(t){this._currentRoute!==t&&(this._currentRoute=t,this.notify())}getLocale(){return this._locale}getFallbackLocale(){return this._fallbackLocale}getRoute(){return this._currentRoute}addTranslations(t,n,e=!0){super.loadTranslationsCore(t,n,e),this.notify()}addRouteTranslations(t,n,e,r=!0){super.loadRouteTranslationsCore(t,n,e,r),this.notify()}clearCache(){super.clearCache(),this.notify()}}function it(a){return new G(a)}const M=c.createContext(null),W=c.createContext(null),z=c.createContext(null),q=c.createContext(null),F=()=>{const a=R.useContext(M);if(!a)throw new Error("[i18n-micro] I18nContext not found. Make sure I18nProvider is used.");return a},V=()=>R.useContext(W),K=()=>R.useContext(z),$=()=>R.useContext(q);function ut({i18n:a,locales:t,defaultLocale:n,routingStrategy:e,children:r}){return c.h(M.Provider,{value:a},t?c.h(W.Provider,{value:t},n?c.h(z.Provider,{value:n},e?c.h(q.Provider,{value:e},r):r):r):r)}const N=a=>{const t=F(),n=$(),e=V(),r=K(),[,w]=R.useState(0);R.useEffect(()=>t.subscribe(()=>{w(f=>f+1)}),[t]);const m=a?.locales||e||[],y=a?.defaultLocale||r||t.locale,d=(o,f)=>n?.resolvePath?n.resolvePath(o,f||t.locale):o,l=o=>{if(t.locale=o,n){const f=n.getCurrentPath(),p=d(f,o);n.push(typeof p=="string"?{path:p}:{path:p.path||"/"})}};return{t:t.t.bind(t),ts:t.ts.bind(t),tc:t.tc.bind(t),tn:t.tn.bind(t),td:t.td.bind(t),tdr:t.tdr.bind(t),has:t.has.bind(t),get locale(){return t.locale},get fallbackLocale(){return t.fallbackLocale},get currentRoute(){return t.currentRoute},setLocale:o=>{t.locale=o},setRoute:t.setRoute.bind(t),getRoute:t.getRoute.bind(t),getLocales:()=>m,defaultLocale:()=>y,getLocaleName:()=>m.find(f=>f.code===t.locale)?.displayName||null,switchLocale:l,localeRoute:d,localePath:(o,f)=>{const p=d(o,f);return typeof p=="string"?p:p.path||"/"},addTranslations:t.addTranslations.bind(t),addRouteTranslations:t.addRouteTranslations.bind(t),clearCache:t.clearCache.bind(t)}},dt=a=>{const{t,tc:n,tn:e,td:r,tdr:w,locale:m,getRoute:y}=N(),{keypath:d,params:l,tag:o="span",plural:f,defaultValue:p,html:P=!1,hideIfEmpty:x=!1,customPluralRule:_,number:i,date:g,relativeDate:k,...u}=a,I=y(),b=(L,h,v)=>c.h(L,h,v);if(i!==void 0){const L=Number(i),h=e(L),v=t(d,{number:h,...l||{}},void 0,I),D=typeof v=="string"?v:String(v);return P?b(o,{...u,dangerouslySetInnerHTML:{__html:D}},void 0):b(o,u,D)}if(g!==void 0){const L=r(g),h=t(d,{date:L,...l||{}},void 0,I),v=typeof h=="string"?h:String(h);return P?b(o,{...u,dangerouslySetInnerHTML:{__html:v}},void 0):b(o,u,v)}if(k!==void 0){const L=w(k),h=t(d,{relativeDate:L,...l||{}},void 0,I),v=typeof h=="string"?h:String(h);return P?b(o,{...u,dangerouslySetInnerHTML:{__html:v}},void 0):b(o,u,v)}if(f!==void 0){const L=Number.parseInt(f.toString());let h;return _?h=_(d,L,l||{},m,(D,O,B)=>{const j=t(D,O,B,I);return typeof j=="string"?j:String(j)})||"":h=n(d,{count:L,...l||{}},p),P?b(o,{...u,dangerouslySetInnerHTML:{__html:h}},void 0):b(o,u,h)}const E=t(d,l,p,I),A=typeof E=="string"?E:String(E);return x&&!A.trim()?p?c.h(c.Fragment,null,p):null:P?b(o,{...u,dangerouslySetInnerHTML:{__html:A}},void 0):b(o,u,A)},ft=a=>{const t=N(),n=$(),{to:e,activeStyle:r,localeRoute:w,children:m,...y}=a,d=w||t.localeRoute,l=()=>typeof e=="string"?/^(?:https?:\/\/|\/\/|[a-zA-Z0-9-]+\.[a-zA-Z]{2,})|tel:|mailto:/.test(e):!1,o=()=>{if(l()&&typeof e=="string")return/^https?:\/\//.test(e)?e:`https://${e}`},f=()=>{if(l())return typeof e=="string"?e:e?.path||"/";if(d){const g=d(e);return typeof g=="string"?g:g.path||"/"}if(!n?.resolvePath)return typeof e=="string"?e:e.path||"/";const i=n.resolvePath(e,t.locale);return typeof i=="string"?i:i.path||"/"},P=(()=>{if(l()||!n)return!1;const i=n.getCurrentPath(),g=f(),k=i.replace(/\/$/,""),u=g.replace(/\/$/,"");return!!(k===u||k.startsWith(u+"/"))})()?r||{}:{},x=f(),_=i=>{a.onClick&&a.onClick(i),!i.defaultPrevented&&!i.button&&!i.metaKey&&!i.ctrlKey&&n&&!l()&&(i.preventDefault(),n.push({path:x}))};if(l())return c.h("a",{...y,href:o(),style:P,target:"_blank",rel:"noopener noreferrer"},m);if(n?.linkComponent){const i=n.linkComponent;if(typeof i=="string")return c.h(i,{...y,href:x,style:P},m);const g=i,k={...y,href:x,style:P};return c.h(g,k,m)}return c.h("a",{...y,href:x,style:P,onClick:_},m)},pt=a=>{const{locales:t,currentLocale:n,getLocaleName:e,switchLocale:r,localeRoute:w,customLabels:m={},customWrapperStyle:y,customButtonStyle:d,customDropdownStyle:l,customItemStyle:o,customLinkStyle:f,customActiveLinkStyle:p,customIconStyle:P,...x}=a,_=N(),i=F(),g=$(),k=V(),[u,I]=R.useState(!1),b=R.useRef(null),E=t||k||_.getLocales()||[],L=typeof n=="function"?n():typeof n=="string"?n:_.locale,h=e?e():_.getLocaleName(),v=s=>{s&&(s.stopPropagation(),s.preventDefault()),I(!u)},D=s=>m[s.code]||s.displayName||s.code,O=()=>{const s=E.find(C=>C.code===L);return s?D(s):h||L},B=s=>{if(I(!1),r){r(s);return}if(i.locale=s,!g)return;const C=g.getCurrentPath(),T=a.localeRoute?(()=>{const S=a.localeRoute(C,s);return typeof S=="string"?S:S.path||"/"})():g?.resolvePath?(()=>{const S=g.resolvePath(C,s);return typeof S=="string"?S:S.path||"/"})():C;g.push({path:T})},j={position:"relative",display:"inline-block",verticalAlign:"middle"},Z={padding:"4px 12px",fontSize:"16px",cursor:"pointer",backgroundColor:"#fff",border:"1px solid #333",transition:"background-color 0.3s ease",display:"flex",alignItems:"center",justifyContent:"space-between"},J={position:"absolute",top:"100%",left:"0",zIndex:1e3,backgroundColor:"#fff",border:"1px solid #333",listStyle:"none",padding:"0",margin:"4px 0 0 0",minWidth:"150px",boxShadow:"0 2px 8px rgba(0,0,0,0.15)"},Q={margin:"0",padding:"0"},X={display:"block",padding:"8px 12px",color:"#333",textDecoration:"none",transition:"background-color 0.3s ease",cursor:"pointer"},Y={fontWeight:"bold",color:"#007bff"},tt={marginLeft:"8px",display:"inline-block",transition:"transform 0.3s ease"},et={transform:"rotate(180deg)"};R.useEffect(()=>{if(!u)return;const s=C=>{if(!u)return;const T=C.target;if(!T||!b.current)return;const S=b.current.contains(T),lt=T.closest(".i18n-switcher-button")!==null;!S&&!lt&&I(!1)};return document.addEventListener("click",s),()=>{document.removeEventListener("click",s)}},[u]);const nt={...j,...y},rt={...Z,...d},ot={...J,...l},st={...Q,...o},at={...tt,...u?et:{},...P},ct=E.map(s=>{const C=s.code===L,T={...X,...C?Y:{},...f,...C?p:{},width:"100%",textAlign:"left",border:"none",background:"transparent"};return c.h("li",{key:s.code,style:st},c.h("button",{type:"button",className:`switcher-locale-${s.code}`,style:T,onClick:S=>{S.preventDefault(),S.stopPropagation(),B(s.code)}},D(s)))});return c.h("div",{ref:b,className:"i18n-switcher-wrapper",style:nt,...x},c.h("button",{type:"button",className:"i18n-switcher-button",style:rt,onClick:s=>{s.preventDefault(),s.stopPropagation(),v(s)},ariaHaspopup:"true",ariaExpanded:u},c.h("span",null,O()),c.h("span",{style:at},"▼")),u?c.h("ul",{className:"i18n-switcher-dropdown",style:ot},...ct):null)},ht=a=>{const{prefix:t,groupClass:n,children:e,...r}=a,{t:w,getRoute:m}=N(),y=(o,f)=>{const p=w(`${t}.${o}`,f,void 0,m());return typeof p=="string"?p:String(p)},d=["i18n-group",n].filter(Boolean).join(" "),l=typeof e=="function"?e({prefix:t,t:y}):e;return c.h("div",{...r,className:d},l)};function U(a,t){const n=a.map(r=>r.code),e=(r,w)=>{const y=(typeof r=="string"?r:r.path||"/").split("/").filter(Boolean),d=y[0];d!==void 0&&n.includes(d)&&y.shift();const l="/"+y.join("/");return w===t?l:`/${w}${l==="/"?"":l}`};return{linkComponent:void 0,getCurrentPath:()=>typeof window<"u"?window.location.pathname:"/",push:r=>{typeof window<"u"&&(window.history.pushState({},"",r.path),window.dispatchEvent(new Event("popstate")))},replace:r=>{typeof window<"u"&&(window.history.replaceState({},"",r.path),window.dispatchEvent(new Event("popstate")))},resolvePath:(r,w)=>e(r,w),getRoute:()=>typeof window<"u"?{fullPath:window.location.pathname+window.location.search,query:Object.fromEntries(new URLSearchParams(window.location.search))}:{fullPath:"/",query:{}}}}const gt=U;Object.defineProperty(exports,"FormatService",{enumerable:!0,get:()=>H.FormatService});Object.defineProperty(exports,"defaultPlural",{enumerable:!0,get:()=>H.defaultPlural});Object.defineProperty(exports,"interpolate",{enumerable:!0,get:()=>H.interpolate});exports.I18nContext=M;exports.I18nDefaultLocaleContext=z;exports.I18nGroup=ht;exports.I18nLink=ft;exports.I18nLocalesContext=W;exports.I18nProvider=ut;exports.I18nRouterContext=q;exports.I18nSwitcher=pt;exports.I18nT=dt;exports.PreactI18n=G;exports.createBrowserHistoryAdapter=U;exports.createI18n=it;exports.createPreactRouterAdapter=gt;exports.useI18n=N;exports.useI18nContext=F;exports.useI18nDefaultLocale=K;exports.useI18nLocales=V;exports.useI18nRouter=$;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/i18n.ts","../src/injection.ts","../src/context.tsx","../src/components/I18nT.tsx","../src/components/I18nLink.tsx","../src/components/I18nSwitcher.tsx","../src/components/I18nGroup.tsx","../src/router/adapter.tsx"],"sourcesContent":["import {\n BaseI18n,\n type TranslationCache,\n} from '@i18n-micro/core'\nimport type {\n Translations,\n PluralFunc,\n} from '@i18n-micro/types'\n\nexport interface PreactI18nOptions {\n locale: string\n fallbackLocale?: string\n messages?: Record<string, Translations>\n plural?: PluralFunc\n missingWarn?: boolean\n missingHandler?: (locale: string, key: string, routeName: string) => void\n}\n\n/**\n * Preact I18n Adapter\n *\n * Provides a Preact-compatible i18n instance that uses the shared core logic.\n * Implements Observer pattern for reactivity with useSyncExternalStore.\n * Works with Preact through preact/compat for React compatibility.\n */\nexport class PreactI18n extends BaseI18n {\n private _locale: string\n private _fallbackLocale: string\n private _currentRoute: string = 'general'\n private listeners = new Set<() => void>()\n private revision = 0\n\n // Cache для Core (plain objects, не реактивные)\n public readonly cache: TranslationCache\n\n constructor(options: PreactI18nOptions) {\n // Create cache first\n const cache: TranslationCache = {\n generalLocaleCache: {},\n routeLocaleCache: {},\n dynamicTranslationsCaches: [],\n serverTranslationCache: {},\n }\n\n // Call parent constructor with options\n super({\n cache,\n plural: options.plural,\n missingWarn: options.missingWarn,\n missingHandler: options.missingHandler,\n })\n\n // Assign cache to public readonly property\n this.cache = cache\n\n this._locale = options.locale\n this._fallbackLocale = options.fallbackLocale || options.locale\n\n // Загружаем начальные сообщения\n if (options.messages) {\n for (const [lang, msgs] of Object.entries(options.messages)) {\n this.helper.loadTranslations(lang, msgs)\n }\n }\n }\n\n // Для useSyncExternalStore\n subscribe = (listener: () => void) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n getSnapshot = () => {\n // Возвращаем комбинированную строку локали и ревизии кэша\n // Это заставит компонент перерендериться при изменении\n return `${this._locale}:${this._currentRoute}:${this.revision}`\n }\n\n private notify() {\n this.revision++\n this.listeners.forEach((listener) => {\n listener()\n })\n }\n\n // Геттер/Сеттер для локали\n get locale(): string {\n return this._locale\n }\n\n set locale(val: string) {\n if (this._locale !== val) {\n this._locale = val\n this.notify()\n }\n }\n\n // Геттер/Сеттер для fallback локали\n get fallbackLocale(): string {\n return this._fallbackLocale\n }\n\n set fallbackLocale(val: string) {\n this._fallbackLocale = val\n }\n\n // Геттер/Сеттер для текущего роута\n get currentRoute(): string {\n return this._currentRoute\n }\n\n setRoute(routeName: string): void {\n if (this._currentRoute !== routeName) {\n this._currentRoute = routeName\n this.notify()\n }\n }\n\n // --- Implementation of abstract methods ---\n\n public getLocale(): string {\n return this._locale\n }\n\n public getFallbackLocale(): string {\n return this._fallbackLocale\n }\n\n public getRoute(): string {\n return this._currentRoute\n }\n\n // Translation management (uses protected methods from base class)\n public addTranslations(locale: string, translations: Translations, merge: boolean = true): void {\n super.loadTranslationsCore(locale, translations, merge)\n this.notify()\n }\n\n public addRouteTranslations(\n locale: string,\n routeName: string,\n translations: Translations,\n merge: boolean = true,\n ): void {\n super.loadRouteTranslationsCore(locale, routeName, translations, merge)\n this.notify()\n }\n\n public override clearCache(): void {\n super.clearCache()\n this.notify()\n }\n}\n\n/**\n * Create a new PreactI18n instance\n */\nexport function createI18n(options: PreactI18nOptions): PreactI18n {\n return new PreactI18n(options)\n}\n","import { createContext } from 'preact'\nimport { useContext } from 'preact/hooks'\nimport type { PreactI18n } from './i18n'\nimport type { Locale } from '@i18n-micro/types'\nimport type { I18nRoutingStrategy } from './router/types'\n\n// Context keys (analogous to Vue's InjectionKey)\nexport const I18nContext = createContext<PreactI18n | null>(null)\nexport const I18nLocalesContext = createContext<Locale[] | null>(null)\nexport const I18nDefaultLocaleContext = createContext<string | null>(null)\nexport const I18nRouterContext = createContext<I18nRoutingStrategy | null>(null)\n\n// Helper hooks (analogous to Vue's inject)\nexport const useI18nContext = () => {\n const context = useContext(I18nContext)\n if (!context) {\n throw new Error('[i18n-micro] I18nContext not found. Make sure I18nProvider is used.')\n }\n return context\n}\n\nexport const useI18nLocales = () => {\n return useContext(I18nLocalesContext)\n}\n\nexport const useI18nDefaultLocale = () => {\n return useContext(I18nDefaultLocaleContext)\n}\n\nexport const useI18nRouter = () => {\n return useContext(I18nRouterContext)\n}\n","import { h } from 'preact'\nimport { useEffect, useState } from 'preact/hooks'\nimport type { ComponentChildren } from 'preact'\nimport type { PreactI18n } from './i18n'\nimport type {\n Translations,\n Params,\n TranslationKey,\n CleanTranslation,\n Locale,\n} from '@i18n-micro/types'\nimport {\n I18nContext,\n I18nLocalesContext,\n I18nDefaultLocaleContext,\n I18nRouterContext,\n useI18nContext,\n useI18nLocales,\n useI18nDefaultLocale,\n useI18nRouter,\n} from './injection'\nimport type { I18nRoutingStrategy } from './router/types'\n\nexport interface I18nProviderProps {\n i18n: PreactI18n\n locales?: Locale[]\n defaultLocale?: string\n routingStrategy?: I18nRoutingStrategy\n children?: ComponentChildren\n}\n\nexport function I18nProvider({ i18n, locales, defaultLocale, routingStrategy, children }: I18nProviderProps) {\n return h(\n I18nContext.Provider,\n { value: i18n },\n locales\n ? h(\n I18nLocalesContext.Provider,\n { value: locales },\n defaultLocale\n ? h(\n I18nDefaultLocaleContext.Provider,\n { value: defaultLocale },\n routingStrategy\n ? h(\n I18nRouterContext.Provider,\n { value: routingStrategy },\n children,\n )\n : children,\n )\n : children,\n )\n : children,\n )\n}\n\nexport interface UseI18nOptions {\n locales?: Locale[]\n defaultLocale?: string\n}\n\nexport interface UseI18nReturn {\n // Translation methods\n t: (key: TranslationKey, params?: Params, defaultValue?: string | null, routeName?: string) => CleanTranslation\n ts: (key: TranslationKey, params?: Params, defaultValue?: string, routeName?: string) => string\n tc: (key: TranslationKey, count: number | Params, defaultValue?: string) => string\n tn: (value: number, options?: Intl.NumberFormatOptions) => string\n td: (value: Date | number | string, options?: Intl.DateTimeFormatOptions) => string\n tdr: (value: Date | number | string, options?: Intl.RelativeTimeFormatOptions) => string\n has: (key: TranslationKey, routeName?: string) => boolean\n\n // Locale management\n locale: string\n fallbackLocale: string\n currentRoute: string\n setLocale: (locale: string) => void\n\n // Route management\n setRoute: (routeName: string) => void\n getRoute: () => string\n getLocales: () => Locale[]\n defaultLocale: () => string\n getLocaleName: () => string | null\n\n // Router methods (if router is available)\n switchLocale?: (locale: string) => void\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n localePath?: (to: string | { path?: string }, locale?: string) => string\n\n // Translation management\n addTranslations: (locale: string, translations: Translations, merge?: boolean) => void\n addRouteTranslations: (locale: string, routeName: string, translations: Translations, merge?: boolean) => void\n clearCache: () => void\n}\n\nexport const useI18n = (options?: UseI18nOptions): UseI18nReturn => {\n const i18n = useI18nContext()\n const router = useI18nRouter()\n const injectedLocales = useI18nLocales()\n const injectedDefaultLocale = useI18nDefaultLocale()\n\n // --- Замена useSyncExternalStore для Pure Preact ---\n // Подписываемся на изменения в i18n и форсируем ре-рендер\n const [, forceUpdate] = useState(0)\n\n useEffect(() => {\n // subscribe возвращает функцию отписки\n const unsubscribe = i18n.subscribe(() => {\n forceUpdate(n => n + 1)\n })\n return unsubscribe\n }, [i18n])\n // ---------------------------------------------------\n\n const locales = options?.locales || injectedLocales || []\n const defaultLocale = options?.defaultLocale || injectedDefaultLocale || i18n.locale\n\n const resolveLocalePath = (to: string | { path?: string }, localeCode?: string): string | { path?: string } => {\n if (!router?.resolvePath) {\n return to\n }\n return router.resolvePath(to, localeCode || i18n.locale)\n }\n\n const switchLocaleHelper = (newLocale: string): void => {\n i18n.locale = newLocale\n if (router) {\n const currentPath = router.getCurrentPath()\n const newPath = resolveLocalePath(currentPath, newLocale)\n router.push(typeof newPath === 'string' ? { path: newPath } : { path: newPath.path || '/' })\n }\n }\n\n return {\n // Translation methods\n t: i18n.t.bind(i18n),\n ts: i18n.ts.bind(i18n),\n tc: i18n.tc.bind(i18n),\n tn: i18n.tn.bind(i18n),\n td: i18n.td.bind(i18n),\n tdr: i18n.tdr.bind(i18n),\n has: i18n.has.bind(i18n),\n\n // Locale management\n get locale() {\n return i18n.locale\n },\n get fallbackLocale() {\n return i18n.fallbackLocale\n },\n get currentRoute() {\n return i18n.currentRoute\n },\n setLocale: (locale: string) => {\n i18n.locale = locale\n },\n\n // Route management\n setRoute: i18n.setRoute.bind(i18n),\n getRoute: i18n.getRoute.bind(i18n),\n getLocales: () => locales,\n defaultLocale: () => defaultLocale,\n getLocaleName: () => {\n const current = locales.find(l => l.code === i18n.locale)\n return current?.displayName || null\n },\n\n // Router methods (always available, but navigation handled by components)\n switchLocale: switchLocaleHelper,\n localeRoute: resolveLocalePath,\n localePath: (to: string | { path?: string }, locale?: string) => {\n const res = resolveLocalePath(to, locale)\n return typeof res === 'string' ? res : (res.path || '/')\n },\n\n // Translation management\n addTranslations: i18n.addTranslations.bind(i18n),\n addRouteTranslations: i18n.addRouteTranslations.bind(i18n),\n clearCache: i18n.clearCache.bind(i18n),\n }\n}\n\n// Export context for advanced usage\nexport { I18nContext } from './injection'\n","import { h, Fragment } from 'preact'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport type { TranslationKey, PluralFunc } from '@i18n-micro/types'\n\nexport interface I18nTProps extends Omit<JSX.HTMLAttributes<HTMLElement>, 'children'> {\n keypath: TranslationKey\n params?: Record<string, string | number | boolean>\n tag?: keyof JSX.IntrinsicElements\n plural?: number | string\n defaultValue?: string\n html?: boolean\n hideIfEmpty?: boolean\n customPluralRule?: PluralFunc\n number?: number | string\n date?: Date | string | number\n relativeDate?: Date | string | number\n children?: never // I18nT doesn't support children - translation is rendered as content\n}\n\nexport const I18nT = (props: I18nTProps): JSX.Element | null => {\n const { t, tc, tn, td, tdr, locale, getRoute } = useI18n()\n const {\n keypath,\n params,\n tag = 'span',\n plural,\n defaultValue,\n html = false,\n hideIfEmpty = false,\n customPluralRule,\n number,\n date,\n relativeDate,\n ...restProps\n } = props\n\n const route = getRoute()\n\n // Helper function to create element with proper typing\n const createElement = (\n elementTag: keyof JSX.IntrinsicElements,\n elementProps: JSX.HTMLAttributes<HTMLElement>,\n children?: string,\n ): JSX.Element => {\n return h(\n elementTag as unknown as keyof JSX.IntrinsicElements,\n elementProps as unknown as JSX.HTMLAttributes<HTMLElement>,\n children,\n ) as JSX.Element\n }\n\n // Handle number formatting\n if (number !== undefined) {\n const numberValue = Number(number)\n const formattedNumber = tn(numberValue)\n const translation = t(keypath, { number: formattedNumber, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle date formatting\n if (date !== undefined) {\n const formattedDate = td(date)\n const translation = t(keypath, { date: formattedDate, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle relative date formatting\n if (relativeDate !== undefined) {\n const formattedRelativeDate = tdr(relativeDate)\n const translation = t(keypath, { relativeDate: formattedRelativeDate, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle pluralization\n if (plural !== undefined) {\n const count = Number.parseInt(plural.toString())\n let translation: string\n if (customPluralRule) {\n const result = customPluralRule(\n keypath,\n count,\n params || {},\n locale,\n (k: TranslationKey, p?: Record<string, string | number | boolean>, dv?: string) => {\n const tResult = t(k, p, dv, route)\n return typeof tResult === 'string' ? tResult : String(tResult)\n },\n )\n translation = result || ''\n }\n else {\n translation = tc(keypath, { count, ...(params || {}) }, defaultValue)\n }\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: translation } }, undefined)\n }\n return createElement(tag, restProps, translation)\n }\n\n // Regular translation\n const translation = t(keypath, params, defaultValue, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n\n if (hideIfEmpty && !content.trim()) {\n return defaultValue ? (h(Fragment, null, defaultValue) as JSX.Element) : null\n }\n\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n\n return createElement(tag, restProps, content)\n}\n","import { h } from 'preact'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport { useI18nRouter } from '../injection'\n\nexport interface I18nLinkProps extends JSX.AnchorHTMLAttributes<HTMLAnchorElement> {\n to: string | { path?: string }\n activeStyle?: Record<string, string | number>\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n}\n\nexport const I18nLink = (props: I18nLinkProps): JSX.Element => {\n const i18n = useI18n()\n const router = useI18nRouter()\n const { to, activeStyle, localeRoute: localeRouteProp, children, ...restProps } = props\n\n // Use prop if provided, otherwise fallback to useI18n\n const localeRoute = localeRouteProp || i18n.localeRoute\n\n const isExternalLink = (): boolean => {\n if (typeof to === 'string') {\n return /^(?:https?:\\/\\/|\\/\\/|[a-zA-Z0-9-]+\\.[a-zA-Z]{2,})|tel:|mailto:/.test(to)\n }\n return false\n }\n\n const externalHref = (): string | undefined => {\n if (isExternalLink() && typeof to === 'string') {\n if (!/^https?:\\/\\//.test(to)) {\n return `https://${to}`\n }\n return to\n }\n return undefined\n }\n\n const targetPath = (): string => {\n if (isExternalLink()) {\n if (typeof to === 'string') {\n return to\n }\n const toObj = to as { path?: string }\n return toObj?.path || '/'\n }\n\n if (localeRoute) {\n const res = localeRoute(to)\n return typeof res === 'string' ? res : (res.path || '/')\n }\n\n if (!router?.resolvePath) {\n return typeof to === 'string' ? to : (to.path || '/')\n }\n\n const res = router.resolvePath(to, i18n.locale)\n return typeof res === 'string' ? res : (res.path || '/')\n }\n\n const isActive = (): boolean => {\n if (isExternalLink() || !router) {\n return false\n }\n\n const currentPath = router.getCurrentPath()\n const linkPath = targetPath()\n\n // Normalize paths (remove trailing slashes)\n const normalizedCurrent = currentPath.replace(/\\/$/, '')\n const normalizedLink = linkPath.replace(/\\/$/, '')\n\n // Exact match (ignoring query params and hash)\n if (normalizedCurrent === normalizedLink) {\n return true\n }\n\n // Partial match: check if current path starts with link path\n // This allows parent routes to be marked as active\n if (normalizedCurrent.startsWith(normalizedLink + '/')) {\n return true\n }\n\n return false\n }\n\n const computedStyle: Record<string, string | number> = isActive() ? (activeStyle || {}) : {}\n const toValue = targetPath()\n\n const handleClick = (e: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {\n if (props.onClick) {\n props.onClick(e)\n }\n\n // Если это не внешний линк и нет модификаторов (ctrl/meta)\n if (!e.defaultPrevented && !e.button && !e.metaKey && !e.ctrlKey && router && !isExternalLink()) {\n e.preventDefault()\n router.push({ path: toValue })\n }\n }\n\n if (isExternalLink()) {\n return h(\n 'a',\n {\n ...restProps,\n href: externalHref(),\n style: computedStyle,\n target: '_blank',\n rel: 'noopener noreferrer',\n },\n children,\n ) as JSX.Element\n }\n\n // Use router linkComponent if available\n if (router?.linkComponent) {\n const LinkComponent = router.linkComponent\n if (typeof LinkComponent === 'string') {\n return h(\n LinkComponent,\n {\n ...restProps,\n href: toValue,\n style: computedStyle,\n },\n children,\n ) as JSX.Element\n }\n // Type assertion needed because React.ComponentType from I18nRoutingStrategy\n // is compatible with Preact components at runtime\n const Component = LinkComponent as unknown as (props: {\n href: string\n children?: JSX.Element | JSX.Element[]\n style?: Record<string, string | number>\n className?: string\n [key: string]: unknown\n }) => JSX.Element\n // Extract only the props that are compatible with the component type\n const componentProps = {\n ...restProps,\n href: toValue,\n style: computedStyle,\n } as {\n href: string\n children?: JSX.Element | JSX.Element[]\n style?: Record<string, string | number>\n className?: string\n [key: string]: unknown\n }\n return h(\n Component,\n componentProps,\n children,\n ) as JSX.Element\n }\n\n // Fallback to anchor with onClick handler\n return h(\n 'a',\n {\n ...restProps,\n href: toValue,\n style: computedStyle,\n onClick: handleClick,\n },\n children,\n ) as JSX.Element\n}\n","import { h } from 'preact'\nimport { useState, useEffect, useRef } from 'preact/hooks'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport { useI18nRouter, useI18nLocales, useI18nContext } from '../injection'\nimport type { Locale } from '@i18n-micro/types'\n\nexport interface I18nSwitcherProps extends JSX.HTMLAttributes<HTMLDivElement> {\n locales?: Locale[]\n currentLocale?: string | (() => string)\n getLocaleName?: () => string | null\n switchLocale?: (locale: string) => void\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n customLabels?: Record<string, string>\n customWrapperStyle?: Record<string, string | number>\n customButtonStyle?: Record<string, string | number>\n customDropdownStyle?: Record<string, string | number>\n customItemStyle?: Record<string, string | number>\n customLinkStyle?: Record<string, string | number>\n customActiveLinkStyle?: Record<string, string | number>\n customIconStyle?: Record<string, string | number>\n}\n\nexport const I18nSwitcher = (props: I18nSwitcherProps): JSX.Element => {\n const {\n locales: localesProp,\n currentLocale: currentLocaleProp,\n getLocaleName: getLocaleNameProp,\n switchLocale: switchLocaleProp,\n localeRoute: _localeRouteProp,\n customLabels = {},\n customWrapperStyle,\n customButtonStyle,\n customDropdownStyle,\n customItemStyle,\n customLinkStyle,\n customActiveLinkStyle,\n customIconStyle,\n ...restProps\n } = props\n\n const i18n = useI18n()\n const i18nInstance = useI18nContext()\n const router = useI18nRouter()\n const injectedLocales = useI18nLocales()\n const [dropdownOpen, setDropdownOpen] = useState(false)\n const wrapperRef = useRef<HTMLDivElement>(null)\n\n // Use props if provided, otherwise fallback to injected or useI18n\n const locales = localesProp || injectedLocales || i18n.getLocales() || []\n\n // Get current locale value (handle both string and function)\n const getCurrentLocale = (): string => {\n if (typeof currentLocaleProp === 'function') {\n return currentLocaleProp()\n }\n if (typeof currentLocaleProp === 'string') {\n return currentLocaleProp\n }\n return i18n.locale\n }\n\n const currentLocale = getCurrentLocale()\n const currentLocaleName = getLocaleNameProp ? getLocaleNameProp() : i18n.getLocaleName()\n\n const toggleDropdown = (event?: Event) => {\n if (event) {\n event.stopPropagation()\n event.preventDefault()\n }\n setDropdownOpen(!dropdownOpen)\n }\n\n const localeLabel = (localeItem: Locale): string => {\n const current = customLabels[localeItem.code] || localeItem.displayName\n return current || localeItem.code\n }\n\n const currentLocaleLabel = (): string => {\n const current = locales.find(l => l.code === currentLocale)\n return current ? localeLabel(current) : (currentLocaleName || currentLocale)\n }\n\n const handleSwitchLocale = (code: string) => {\n setDropdownOpen(false)\n if (switchLocaleProp) {\n switchLocaleProp(code)\n return\n }\n\n i18nInstance.locale = code\n\n if (!router) {\n return\n }\n\n const currentPath = router.getCurrentPath()\n const newPath = props.localeRoute\n ? (() => {\n const res = props.localeRoute(currentPath, code)\n return typeof res === 'string' ? res : (res.path || '/')\n })()\n : (router?.resolvePath\n ? (() => {\n const res = router.resolvePath(currentPath, code)\n return typeof res === 'string' ? res : (res.path || '/')\n })()\n : currentPath)\n\n router.push({ path: newPath })\n }\n\n // Default Styles\n const wrapperStyle: Record<string, string | number> = {\n position: 'relative',\n display: 'inline-block',\n verticalAlign: 'middle',\n }\n\n const buttonStyle: Record<string, string | number> = {\n padding: '4px 12px',\n fontSize: '16px',\n cursor: 'pointer',\n backgroundColor: '#fff',\n border: '1px solid #333',\n transition: 'background-color 0.3s ease',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n }\n\n const dropdownStyle: Record<string, string | number> = {\n position: 'absolute',\n top: '100%',\n left: '0',\n zIndex: 1000,\n backgroundColor: '#fff',\n border: '1px solid #333',\n listStyle: 'none',\n padding: '0',\n margin: '4px 0 0 0',\n minWidth: '150px',\n boxShadow: '0 2px 8px rgba(0,0,0,0.15)',\n }\n\n const itemStyle: Record<string, string | number> = {\n margin: '0',\n padding: '0',\n }\n\n const linkStyle: Record<string, string | number> = {\n display: 'block',\n padding: '8px 12px',\n color: '#333',\n textDecoration: 'none',\n transition: 'background-color 0.3s ease',\n cursor: 'pointer',\n }\n\n const activeLinkStyle: Record<string, string | number> = {\n fontWeight: 'bold',\n color: '#007bff',\n }\n\n const iconStyle: Record<string, string | number> = {\n marginLeft: '8px',\n display: 'inline-block',\n transition: 'transform 0.3s ease',\n }\n\n const openIconStyle: Record<string, string | number> = {\n transform: 'rotate(180deg)',\n }\n\n useEffect(() => {\n if (!dropdownOpen) return\n const handler = (event: MouseEvent) => {\n if (!dropdownOpen) return\n\n const target = event.target as HTMLElement\n if (!target || !wrapperRef.current) return\n\n const isClickInside = wrapperRef.current.contains(target)\n const isButtonClick = target.closest('.i18n-switcher-button') !== null\n\n if (!isClickInside && !isButtonClick) {\n setDropdownOpen(false)\n }\n }\n document.addEventListener('click', handler)\n return () => {\n document.removeEventListener('click', handler)\n }\n }, [dropdownOpen])\n\n const mergedWrapperStyle = { ...wrapperStyle, ...customWrapperStyle }\n const mergedButtonStyle = { ...buttonStyle, ...customButtonStyle }\n const mergedDropdownStyle = { ...dropdownStyle, ...customDropdownStyle }\n const mergedItemStyle = { ...itemStyle, ...customItemStyle }\n const mergedIconStyle = {\n ...iconStyle,\n ...(dropdownOpen ? openIconStyle : {}),\n ...customIconStyle,\n }\n\n const dropdownItems = locales.map((localeItem) => {\n const isActive = localeItem.code === currentLocale\n const mergedLinkStyle = {\n ...linkStyle,\n ...(isActive ? activeLinkStyle : {}),\n ...customLinkStyle,\n ...(isActive ? customActiveLinkStyle : {}),\n width: '100%',\n textAlign: 'left',\n border: 'none',\n background: 'transparent',\n }\n\n return h(\n 'li',\n {\n key: localeItem.code,\n style: mergedItemStyle,\n },\n h(\n 'button',\n {\n type: 'button',\n className: `switcher-locale-${localeItem.code}`,\n style: mergedLinkStyle,\n onClick: (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n handleSwitchLocale(localeItem.code)\n },\n },\n localeLabel(localeItem),\n ),\n )\n })\n\n return h(\n 'div',\n {\n ref: wrapperRef,\n className: 'i18n-switcher-wrapper',\n style: mergedWrapperStyle,\n ...restProps,\n },\n h(\n 'button',\n {\n type: 'button',\n className: 'i18n-switcher-button',\n style: mergedButtonStyle,\n onClick: (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n toggleDropdown(e)\n },\n ariaHaspopup: 'true',\n ariaExpanded: dropdownOpen,\n },\n h('span', null, currentLocaleLabel()),\n h('span', { style: mergedIconStyle }, '▼'),\n ),\n dropdownOpen\n ? h(\n 'ul',\n {\n className: 'i18n-switcher-dropdown',\n style: mergedDropdownStyle,\n },\n ...dropdownItems,\n )\n : null,\n ) as JSX.Element\n}\n","import { h } from 'preact'\nimport type { JSX, ComponentChildren } from 'preact'\nimport { useI18n } from '../context'\nimport type { TranslationKey } from '@i18n-micro/types'\n\nexport interface I18nGroupProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, 'children'> {\n prefix: string\n groupClass?: string\n children?: (props: { prefix: string, t: (key: string, params?: Record<string, string | number | boolean>) => string }) => ComponentChildren\n}\n\nexport const I18nGroup = (props: I18nGroupProps): JSX.Element => {\n const { prefix, groupClass, children, ...restProps } = props\n const { t, getRoute } = useI18n()\n\n const translate = (key: string, params?: Record<string, string | number | boolean>): string => {\n const result = t(`${prefix}.${key}` as TranslationKey, params, undefined, getRoute())\n return typeof result === 'string' ? result : String(result)\n }\n\n const className = ['i18n-group', groupClass].filter(Boolean).join(' ')\n\n const childrenContent: ComponentChildren = typeof children === 'function'\n ? children({ prefix, t: translate })\n : children\n\n return h(\n 'div',\n { ...restProps, className },\n childrenContent,\n ) as JSX.Element\n}\n","import type { I18nRoutingStrategy } from './types'\nimport type { Locale } from '@i18n-micro/types'\n\n/**\n * Создает адаптер для работы с History API (универсальный для Pure Preact)\n * Работает с любым роутером, который использует History API (wouter, preact-router, и т.д.)\n */\nexport function createBrowserHistoryAdapter(\n locales: Locale[],\n defaultLocale: string,\n): I18nRoutingStrategy {\n const localeCodes = locales.map(loc => loc.code)\n\n /**\n * Path resolution logic (add prefix or not)\n */\n const resolvePath = (to: string | { path?: string }, locale: string): string | { path?: string } => {\n const path = typeof to === 'string' ? to : (to.path || '/')\n const pathSegments = path.split('/').filter(Boolean)\n\n // If path already starts with a locale, remove it\n if (pathSegments.length > 0 && localeCodes.includes(pathSegments[0])) {\n pathSegments.shift()\n }\n\n const cleanPath = '/' + pathSegments.join('/')\n\n // If default locale - return clean path\n if (locale === defaultLocale) {\n return cleanPath\n }\n\n // Otherwise add prefix\n return `/${locale}${cleanPath === '/' ? '' : cleanPath}`\n }\n\n return {\n // Просто рендерим <a>, навигацию перехватит onClick в I18nLink\n linkComponent: undefined,\n\n getCurrentPath: () => {\n if (typeof window !== 'undefined') {\n return window.location.pathname\n }\n return '/'\n },\n\n push: (target) => {\n if (typeof window !== 'undefined') {\n window.history.pushState({}, '', target.path)\n // Вызываем событие, чтобы роутеры (wouter/preact-router) узнали об изменении\n window.dispatchEvent(new Event('popstate'))\n }\n },\n\n replace: (target) => {\n if (typeof window !== 'undefined') {\n window.history.replaceState({}, '', target.path)\n window.dispatchEvent(new Event('popstate'))\n }\n },\n\n resolvePath: (to, locale) => resolvePath(to, locale),\n\n getRoute: () => {\n if (typeof window !== 'undefined') {\n return {\n fullPath: window.location.pathname + window.location.search,\n query: Object.fromEntries(new URLSearchParams(window.location.search)),\n }\n }\n return {\n fullPath: '/',\n query: {},\n }\n },\n }\n}\n\n// Export for backward compatibility (old name)\nexport const createPreactRouterAdapter = createBrowserHistoryAdapter\n"],"names":["PreactI18n","BaseI18n","options","cache","lang","msgs","listener","val","routeName","locale","translations","merge","createI18n","I18nContext","createContext","I18nLocalesContext","I18nDefaultLocaleContext","I18nRouterContext","useI18nContext","context","useContext","useI18nLocales","useI18nDefaultLocale","useI18nRouter","I18nProvider","i18n","locales","defaultLocale","routingStrategy","children","h","useI18n","router","injectedLocales","injectedDefaultLocale","forceUpdate","useState","useEffect","n","resolveLocalePath","to","localeCode","switchLocaleHelper","newLocale","currentPath","newPath","l","res","I18nT","props","tc","tn","td","tdr","getRoute","keypath","params","tag","plural","defaultValue","html","hideIfEmpty","customPluralRule","number","date","relativeDate","restProps","route","createElement","elementTag","elementProps","numberValue","formattedNumber","translation","content","formattedDate","formattedRelativeDate","count","k","p","dv","tResult","Fragment","I18nLink","activeStyle","localeRouteProp","localeRoute","isExternalLink","externalHref","targetPath","computedStyle","linkPath","normalizedCurrent","normalizedLink","toValue","handleClick","e","LinkComponent","Component","componentProps","I18nSwitcher","localesProp","currentLocaleProp","getLocaleNameProp","switchLocaleProp","_localeRouteProp","customLabels","customWrapperStyle","customButtonStyle","customDropdownStyle","customItemStyle","customLinkStyle","customActiveLinkStyle","customIconStyle","i18nInstance","dropdownOpen","setDropdownOpen","wrapperRef","useRef","currentLocale","currentLocaleName","toggleDropdown","event","localeLabel","localeItem","currentLocaleLabel","current","handleSwitchLocale","code","wrapperStyle","buttonStyle","dropdownStyle","itemStyle","linkStyle","activeLinkStyle","iconStyle","openIconStyle","handler","target","isClickInside","isButtonClick","mergedWrapperStyle","mergedButtonStyle","mergedDropdownStyle","mergedItemStyle","mergedIconStyle","dropdownItems","isActive","mergedLinkStyle","I18nGroup","prefix","groupClass","t","translate","key","result","className","childrenContent","createBrowserHistoryAdapter","localeCodes","loc","resolvePath","pathSegments","cleanPath","createPreactRouterAdapter"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/i18n.ts","../src/injection.ts","../src/context.tsx","../src/components/I18nT.tsx","../src/components/I18nLink.tsx","../src/components/I18nSwitcher.tsx","../src/components/I18nGroup.tsx","../src/router/adapter.tsx"],"sourcesContent":["import { BaseI18n, type TranslationStorage } from '@i18n-micro/core'\nimport type { Translations, PluralFunc } from '@i18n-micro/types'\n\nexport interface PreactI18nOptions {\n locale: string\n fallbackLocale?: string\n messages?: Record<string, Translations>\n plural?: PluralFunc\n missingWarn?: boolean\n missingHandler?: (locale: string, key: string, routeName: string) => void\n}\n\nexport class PreactI18n extends BaseI18n {\n private _locale: string\n private _fallbackLocale: string\n private _currentRoute: string = 'general'\n private listeners = new Set<() => void>()\n private revision = 0\n\n public readonly storage: TranslationStorage\n\n constructor(options: PreactI18nOptions) {\n const storage: TranslationStorage = {\n translations: new Map<string, Translations>(),\n }\n\n super({\n storage,\n plural: options.plural,\n missingWarn: options.missingWarn,\n missingHandler: options.missingHandler,\n })\n\n this.storage = storage\n this._locale = options.locale\n this._fallbackLocale = options.fallbackLocale || options.locale\n\n if (options.messages) {\n for (const [lang, msgs] of Object.entries(options.messages)) {\n this.helper.loadTranslations(lang, msgs)\n }\n }\n }\n\n subscribe = (listener: () => void) => {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n getSnapshot = () => `${this._locale}:${this._currentRoute}:${this.revision}`\n\n private notify() {\n this.revision++\n this.listeners.forEach(listener => listener())\n }\n\n get locale(): string {\n return this._locale\n }\n\n set locale(val: string) {\n if (this._locale !== val) {\n this._locale = val\n this.notify()\n }\n }\n\n get fallbackLocale(): string {\n return this._fallbackLocale\n }\n\n set fallbackLocale(val: string) {\n this._fallbackLocale = val\n }\n\n get currentRoute(): string {\n return this._currentRoute\n }\n\n setRoute(routeName: string): void {\n if (this._currentRoute !== routeName) {\n this._currentRoute = routeName\n this.notify()\n }\n }\n\n public getLocale(): string {\n return this._locale\n }\n\n public getFallbackLocale(): string {\n return this._fallbackLocale\n }\n\n public getRoute(): string {\n return this._currentRoute\n }\n\n public addTranslations(locale: string, translations: Translations, merge = true): void {\n super.loadTranslationsCore(locale, translations, merge)\n this.notify()\n }\n\n public addRouteTranslations(\n locale: string,\n routeName: string,\n translations: Translations,\n merge = true,\n ): void {\n super.loadRouteTranslationsCore(locale, routeName, translations, merge)\n this.notify()\n }\n\n public override clearCache(): void {\n super.clearCache()\n this.notify()\n }\n}\n\nexport function createI18n(options: PreactI18nOptions): PreactI18n {\n return new PreactI18n(options)\n}\n","import { createContext } from 'preact'\nimport { useContext } from 'preact/hooks'\nimport type { PreactI18n } from './i18n'\nimport type { Locale } from '@i18n-micro/types'\nimport type { I18nRoutingStrategy } from './router/types'\n\n// Context keys (analogous to Vue's InjectionKey)\nexport const I18nContext = createContext<PreactI18n | null>(null)\nexport const I18nLocalesContext = createContext<Locale[] | null>(null)\nexport const I18nDefaultLocaleContext = createContext<string | null>(null)\nexport const I18nRouterContext = createContext<I18nRoutingStrategy | null>(null)\n\n// Helper hooks (analogous to Vue's inject)\nexport const useI18nContext = () => {\n const context = useContext(I18nContext)\n if (!context) {\n throw new Error('[i18n-micro] I18nContext not found. Make sure I18nProvider is used.')\n }\n return context\n}\n\nexport const useI18nLocales = () => {\n return useContext(I18nLocalesContext)\n}\n\nexport const useI18nDefaultLocale = () => {\n return useContext(I18nDefaultLocaleContext)\n}\n\nexport const useI18nRouter = () => {\n return useContext(I18nRouterContext)\n}\n","import { h } from 'preact'\nimport { useEffect, useState } from 'preact/hooks'\nimport type { ComponentChildren } from 'preact'\nimport type { PreactI18n } from './i18n'\nimport type {\n Translations,\n Params,\n TranslationKey,\n CleanTranslation,\n Locale,\n} from '@i18n-micro/types'\nimport {\n I18nContext,\n I18nLocalesContext,\n I18nDefaultLocaleContext,\n I18nRouterContext,\n useI18nContext,\n useI18nLocales,\n useI18nDefaultLocale,\n useI18nRouter,\n} from './injection'\nimport type { I18nRoutingStrategy } from './router/types'\n\nexport interface I18nProviderProps {\n i18n: PreactI18n\n locales?: Locale[]\n defaultLocale?: string\n routingStrategy?: I18nRoutingStrategy\n children?: ComponentChildren\n}\n\nexport function I18nProvider({ i18n, locales, defaultLocale, routingStrategy, children }: I18nProviderProps) {\n return h(\n I18nContext.Provider,\n { value: i18n },\n locales\n ? h(\n I18nLocalesContext.Provider,\n { value: locales },\n defaultLocale\n ? h(\n I18nDefaultLocaleContext.Provider,\n { value: defaultLocale },\n routingStrategy\n ? h(\n I18nRouterContext.Provider,\n { value: routingStrategy },\n children,\n )\n : children,\n )\n : children,\n )\n : children,\n )\n}\n\nexport interface UseI18nOptions {\n locales?: Locale[]\n defaultLocale?: string\n}\n\nexport interface UseI18nReturn {\n // Translation methods\n t: (key: TranslationKey, params?: Params, defaultValue?: string | null, routeName?: string) => CleanTranslation\n ts: (key: TranslationKey, params?: Params, defaultValue?: string, routeName?: string) => string\n tc: (key: TranslationKey, count: number | Params, defaultValue?: string) => string\n tn: (value: number, options?: Intl.NumberFormatOptions) => string\n td: (value: Date | number | string, options?: Intl.DateTimeFormatOptions) => string\n tdr: (value: Date | number | string, options?: Intl.RelativeTimeFormatOptions) => string\n has: (key: TranslationKey, routeName?: string) => boolean\n\n // Locale management\n locale: string\n fallbackLocale: string\n currentRoute: string\n setLocale: (locale: string) => void\n\n // Route management\n setRoute: (routeName: string) => void\n getRoute: () => string\n getLocales: () => Locale[]\n defaultLocale: () => string\n getLocaleName: () => string | null\n\n // Router methods (if router is available)\n switchLocale?: (locale: string) => void\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n localePath?: (to: string | { path?: string }, locale?: string) => string\n\n // Translation management\n addTranslations: (locale: string, translations: Translations, merge?: boolean) => void\n addRouteTranslations: (locale: string, routeName: string, translations: Translations, merge?: boolean) => void\n clearCache: () => void\n}\n\nexport const useI18n = (options?: UseI18nOptions): UseI18nReturn => {\n const i18n = useI18nContext()\n const router = useI18nRouter()\n const injectedLocales = useI18nLocales()\n const injectedDefaultLocale = useI18nDefaultLocale()\n\n // --- Замена useSyncExternalStore для Pure Preact ---\n // Подписываемся на изменения в i18n и форсируем ре-рендер\n const [, forceUpdate] = useState(0)\n\n useEffect(() => {\n // subscribe возвращает функцию отписки\n const unsubscribe = i18n.subscribe(() => {\n forceUpdate(n => n + 1)\n })\n return unsubscribe\n }, [i18n])\n // ---------------------------------------------------\n\n const locales = options?.locales || injectedLocales || []\n const defaultLocale = options?.defaultLocale || injectedDefaultLocale || i18n.locale\n\n const resolveLocalePath = (to: string | { path?: string }, localeCode?: string): string | { path?: string } => {\n if (!router?.resolvePath) {\n return to\n }\n return router.resolvePath(to, localeCode || i18n.locale)\n }\n\n const switchLocaleHelper = (newLocale: string): void => {\n i18n.locale = newLocale\n if (router) {\n const currentPath = router.getCurrentPath()\n const newPath = resolveLocalePath(currentPath, newLocale)\n router.push(typeof newPath === 'string' ? { path: newPath } : { path: newPath.path || '/' })\n }\n }\n\n return {\n // Translation methods\n t: i18n.t.bind(i18n),\n ts: i18n.ts.bind(i18n),\n tc: i18n.tc.bind(i18n),\n tn: i18n.tn.bind(i18n),\n td: i18n.td.bind(i18n),\n tdr: i18n.tdr.bind(i18n),\n has: i18n.has.bind(i18n),\n\n // Locale management\n get locale() {\n return i18n.locale\n },\n get fallbackLocale() {\n return i18n.fallbackLocale\n },\n get currentRoute() {\n return i18n.currentRoute\n },\n setLocale: (locale: string) => {\n i18n.locale = locale\n },\n\n // Route management\n setRoute: i18n.setRoute.bind(i18n),\n getRoute: i18n.getRoute.bind(i18n),\n getLocales: () => locales,\n defaultLocale: () => defaultLocale,\n getLocaleName: () => {\n const current = locales.find(l => l.code === i18n.locale)\n return current?.displayName || null\n },\n\n // Router methods (always available, but navigation handled by components)\n switchLocale: switchLocaleHelper,\n localeRoute: resolveLocalePath,\n localePath: (to: string | { path?: string }, locale?: string) => {\n const res = resolveLocalePath(to, locale)\n return typeof res === 'string' ? res : (res.path || '/')\n },\n\n // Translation management\n addTranslations: i18n.addTranslations.bind(i18n),\n addRouteTranslations: i18n.addRouteTranslations.bind(i18n),\n clearCache: i18n.clearCache.bind(i18n),\n }\n}\n\n// Export context for advanced usage\nexport { I18nContext } from './injection'\n","import { h, Fragment } from 'preact'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport type { TranslationKey, PluralFunc } from '@i18n-micro/types'\n\nexport interface I18nTProps extends Omit<JSX.HTMLAttributes<HTMLElement>, 'children'> {\n keypath: TranslationKey\n params?: Record<string, string | number | boolean>\n tag?: keyof JSX.IntrinsicElements\n plural?: number | string\n defaultValue?: string\n html?: boolean\n hideIfEmpty?: boolean\n customPluralRule?: PluralFunc\n number?: number | string\n date?: Date | string | number\n relativeDate?: Date | string | number\n children?: never // I18nT doesn't support children - translation is rendered as content\n}\n\nexport const I18nT = (props: I18nTProps): JSX.Element | null => {\n const { t, tc, tn, td, tdr, locale, getRoute } = useI18n()\n const {\n keypath,\n params,\n tag = 'span',\n plural,\n defaultValue,\n html = false,\n hideIfEmpty = false,\n customPluralRule,\n number,\n date,\n relativeDate,\n ...restProps\n } = props\n\n const route = getRoute()\n\n // Helper function to create element with proper typing\n const createElement = (\n elementTag: keyof JSX.IntrinsicElements,\n elementProps: JSX.HTMLAttributes<HTMLElement>,\n children?: string,\n ): JSX.Element => {\n return h(\n elementTag as unknown as keyof JSX.IntrinsicElements,\n elementProps as unknown as JSX.HTMLAttributes<HTMLElement>,\n children,\n ) as JSX.Element\n }\n\n // Handle number formatting\n if (number !== undefined) {\n const numberValue = Number(number)\n const formattedNumber = tn(numberValue)\n const translation = t(keypath, { number: formattedNumber, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle date formatting\n if (date !== undefined) {\n const formattedDate = td(date)\n const translation = t(keypath, { date: formattedDate, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle relative date formatting\n if (relativeDate !== undefined) {\n const formattedRelativeDate = tdr(relativeDate)\n const translation = t(keypath, { relativeDate: formattedRelativeDate, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle pluralization\n if (plural !== undefined) {\n const count = Number.parseInt(plural.toString())\n let translation: string\n if (customPluralRule) {\n const result = customPluralRule(\n keypath,\n count,\n params || {},\n locale,\n (k: TranslationKey, p?: Record<string, string | number | boolean>, dv?: string) => {\n const tResult = t(k, p, dv, route)\n return typeof tResult === 'string' ? tResult : String(tResult)\n },\n )\n translation = result || ''\n }\n else {\n translation = tc(keypath, { count, ...(params || {}) }, defaultValue)\n }\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: translation } }, undefined)\n }\n return createElement(tag, restProps, translation)\n }\n\n // Regular translation\n const translation = t(keypath, params, defaultValue, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n\n if (hideIfEmpty && !content.trim()) {\n return defaultValue ? (h(Fragment, null, defaultValue) as JSX.Element) : null\n }\n\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n\n return createElement(tag, restProps, content)\n}\n","import { h } from 'preact'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport { useI18nRouter } from '../injection'\n\nexport interface I18nLinkProps extends JSX.AnchorHTMLAttributes<HTMLAnchorElement> {\n to: string | { path?: string }\n activeStyle?: Record<string, string | number>\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n}\n\nexport const I18nLink = (props: I18nLinkProps): JSX.Element => {\n const i18n = useI18n()\n const router = useI18nRouter()\n const { to, activeStyle, localeRoute: localeRouteProp, children, ...restProps } = props\n\n // Use prop if provided, otherwise fallback to useI18n\n const localeRoute = localeRouteProp || i18n.localeRoute\n\n const isExternalLink = (): boolean => {\n if (typeof to === 'string') {\n return /^(?:https?:\\/\\/|\\/\\/|[a-zA-Z0-9-]+\\.[a-zA-Z]{2,})|tel:|mailto:/.test(to)\n }\n return false\n }\n\n const externalHref = (): string | undefined => {\n if (isExternalLink() && typeof to === 'string') {\n if (!/^https?:\\/\\//.test(to)) {\n return `https://${to}`\n }\n return to\n }\n return undefined\n }\n\n const targetPath = (): string => {\n if (isExternalLink()) {\n if (typeof to === 'string') {\n return to\n }\n const toObj = to as { path?: string }\n return toObj?.path || '/'\n }\n\n if (localeRoute) {\n const res = localeRoute(to)\n return typeof res === 'string' ? res : (res.path || '/')\n }\n\n if (!router?.resolvePath) {\n return typeof to === 'string' ? to : (to.path || '/')\n }\n\n const res = router.resolvePath(to, i18n.locale)\n return typeof res === 'string' ? res : (res.path || '/')\n }\n\n const isActive = (): boolean => {\n if (isExternalLink() || !router) {\n return false\n }\n\n const currentPath = router.getCurrentPath()\n const linkPath = targetPath()\n\n // Normalize paths (remove trailing slashes)\n const normalizedCurrent = currentPath.replace(/\\/$/, '')\n const normalizedLink = linkPath.replace(/\\/$/, '')\n\n // Exact match (ignoring query params and hash)\n if (normalizedCurrent === normalizedLink) {\n return true\n }\n\n // Partial match: check if current path starts with link path\n // This allows parent routes to be marked as active\n if (normalizedCurrent.startsWith(normalizedLink + '/')) {\n return true\n }\n\n return false\n }\n\n const computedStyle: Record<string, string | number> = isActive() ? (activeStyle || {}) : {}\n const toValue = targetPath()\n\n const handleClick = (e: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {\n if (props.onClick) {\n props.onClick(e)\n }\n\n // Если это не внешний линк и нет модификаторов (ctrl/meta)\n if (!e.defaultPrevented && !e.button && !e.metaKey && !e.ctrlKey && router && !isExternalLink()) {\n e.preventDefault()\n router.push({ path: toValue })\n }\n }\n\n if (isExternalLink()) {\n return h(\n 'a',\n {\n ...restProps,\n href: externalHref(),\n style: computedStyle,\n target: '_blank',\n rel: 'noopener noreferrer',\n },\n children,\n ) as JSX.Element\n }\n\n // Use router linkComponent if available\n if (router?.linkComponent) {\n const LinkComponent = router.linkComponent\n if (typeof LinkComponent === 'string') {\n return h(\n LinkComponent,\n {\n ...restProps,\n href: toValue,\n style: computedStyle,\n },\n children,\n ) as JSX.Element\n }\n // Type assertion needed because React.ComponentType from I18nRoutingStrategy\n // is compatible with Preact components at runtime\n const Component = LinkComponent as unknown as (props: {\n href: string\n children?: JSX.Element | JSX.Element[]\n style?: Record<string, string | number>\n className?: string\n [key: string]: unknown\n }) => JSX.Element\n // Extract only the props that are compatible with the component type\n const componentProps = {\n ...restProps,\n href: toValue,\n style: computedStyle,\n } as {\n href: string\n children?: JSX.Element | JSX.Element[]\n style?: Record<string, string | number>\n className?: string\n [key: string]: unknown\n }\n return h(\n Component,\n componentProps,\n children,\n ) as JSX.Element\n }\n\n // Fallback to anchor with onClick handler\n return h(\n 'a',\n {\n ...restProps,\n href: toValue,\n style: computedStyle,\n onClick: handleClick,\n },\n children,\n ) as JSX.Element\n}\n","import { h } from 'preact'\nimport { useState, useEffect, useRef } from 'preact/hooks'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport { useI18nRouter, useI18nLocales, useI18nContext } from '../injection'\nimport type { Locale } from '@i18n-micro/types'\n\nexport interface I18nSwitcherProps extends JSX.HTMLAttributes<HTMLDivElement> {\n locales?: Locale[]\n currentLocale?: string | (() => string)\n getLocaleName?: () => string | null\n switchLocale?: (locale: string) => void\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n customLabels?: Record<string, string>\n customWrapperStyle?: Record<string, string | number>\n customButtonStyle?: Record<string, string | number>\n customDropdownStyle?: Record<string, string | number>\n customItemStyle?: Record<string, string | number>\n customLinkStyle?: Record<string, string | number>\n customActiveLinkStyle?: Record<string, string | number>\n customIconStyle?: Record<string, string | number>\n}\n\nexport const I18nSwitcher = (props: I18nSwitcherProps): JSX.Element => {\n const {\n locales: localesProp,\n currentLocale: currentLocaleProp,\n getLocaleName: getLocaleNameProp,\n switchLocale: switchLocaleProp,\n localeRoute: _localeRouteProp,\n customLabels = {},\n customWrapperStyle,\n customButtonStyle,\n customDropdownStyle,\n customItemStyle,\n customLinkStyle,\n customActiveLinkStyle,\n customIconStyle,\n ...restProps\n } = props\n\n const i18n = useI18n()\n const i18nInstance = useI18nContext()\n const router = useI18nRouter()\n const injectedLocales = useI18nLocales()\n const [dropdownOpen, setDropdownOpen] = useState(false)\n const wrapperRef = useRef<HTMLDivElement>(null)\n\n // Use props if provided, otherwise fallback to injected or useI18n\n const locales = localesProp || injectedLocales || i18n.getLocales() || []\n\n // Get current locale value (handle both string and function)\n const getCurrentLocale = (): string => {\n if (typeof currentLocaleProp === 'function') {\n return currentLocaleProp()\n }\n if (typeof currentLocaleProp === 'string') {\n return currentLocaleProp\n }\n return i18n.locale\n }\n\n const currentLocale = getCurrentLocale()\n const currentLocaleName = getLocaleNameProp ? getLocaleNameProp() : i18n.getLocaleName()\n\n const toggleDropdown = (event?: Event) => {\n if (event) {\n event.stopPropagation()\n event.preventDefault()\n }\n setDropdownOpen(!dropdownOpen)\n }\n\n const localeLabel = (localeItem: Locale): string => {\n const current = customLabels[localeItem.code] || localeItem.displayName\n return current || localeItem.code\n }\n\n const currentLocaleLabel = (): string => {\n const current = locales.find(l => l.code === currentLocale)\n return current ? localeLabel(current) : (currentLocaleName || currentLocale)\n }\n\n const handleSwitchLocale = (code: string) => {\n setDropdownOpen(false)\n if (switchLocaleProp) {\n switchLocaleProp(code)\n return\n }\n\n i18nInstance.locale = code\n\n if (!router) {\n return\n }\n\n const currentPath = router.getCurrentPath()\n const newPath = props.localeRoute\n ? (() => {\n const res = props.localeRoute(currentPath, code)\n return typeof res === 'string' ? res : (res.path || '/')\n })()\n : (router?.resolvePath\n ? (() => {\n const res = router.resolvePath(currentPath, code)\n return typeof res === 'string' ? res : (res.path || '/')\n })()\n : currentPath)\n\n router.push({ path: newPath })\n }\n\n // Default Styles\n const wrapperStyle: Record<string, string | number> = {\n position: 'relative',\n display: 'inline-block',\n verticalAlign: 'middle',\n }\n\n const buttonStyle: Record<string, string | number> = {\n padding: '4px 12px',\n fontSize: '16px',\n cursor: 'pointer',\n backgroundColor: '#fff',\n border: '1px solid #333',\n transition: 'background-color 0.3s ease',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n }\n\n const dropdownStyle: Record<string, string | number> = {\n position: 'absolute',\n top: '100%',\n left: '0',\n zIndex: 1000,\n backgroundColor: '#fff',\n border: '1px solid #333',\n listStyle: 'none',\n padding: '0',\n margin: '4px 0 0 0',\n minWidth: '150px',\n boxShadow: '0 2px 8px rgba(0,0,0,0.15)',\n }\n\n const itemStyle: Record<string, string | number> = {\n margin: '0',\n padding: '0',\n }\n\n const linkStyle: Record<string, string | number> = {\n display: 'block',\n padding: '8px 12px',\n color: '#333',\n textDecoration: 'none',\n transition: 'background-color 0.3s ease',\n cursor: 'pointer',\n }\n\n const activeLinkStyle: Record<string, string | number> = {\n fontWeight: 'bold',\n color: '#007bff',\n }\n\n const iconStyle: Record<string, string | number> = {\n marginLeft: '8px',\n display: 'inline-block',\n transition: 'transform 0.3s ease',\n }\n\n const openIconStyle: Record<string, string | number> = {\n transform: 'rotate(180deg)',\n }\n\n useEffect(() => {\n if (!dropdownOpen) return\n const handler = (event: MouseEvent) => {\n if (!dropdownOpen) return\n\n const target = event.target as HTMLElement\n if (!target || !wrapperRef.current) return\n\n const isClickInside = wrapperRef.current.contains(target)\n const isButtonClick = target.closest('.i18n-switcher-button') !== null\n\n if (!isClickInside && !isButtonClick) {\n setDropdownOpen(false)\n }\n }\n document.addEventListener('click', handler)\n return () => {\n document.removeEventListener('click', handler)\n }\n }, [dropdownOpen])\n\n const mergedWrapperStyle = { ...wrapperStyle, ...customWrapperStyle }\n const mergedButtonStyle = { ...buttonStyle, ...customButtonStyle }\n const mergedDropdownStyle = { ...dropdownStyle, ...customDropdownStyle }\n const mergedItemStyle = { ...itemStyle, ...customItemStyle }\n const mergedIconStyle = {\n ...iconStyle,\n ...(dropdownOpen ? openIconStyle : {}),\n ...customIconStyle,\n }\n\n const dropdownItems = locales.map((localeItem) => {\n const isActive = localeItem.code === currentLocale\n const mergedLinkStyle = {\n ...linkStyle,\n ...(isActive ? activeLinkStyle : {}),\n ...customLinkStyle,\n ...(isActive ? customActiveLinkStyle : {}),\n width: '100%',\n textAlign: 'left',\n border: 'none',\n background: 'transparent',\n }\n\n return h(\n 'li',\n {\n key: localeItem.code,\n style: mergedItemStyle,\n },\n h(\n 'button',\n {\n type: 'button',\n className: `switcher-locale-${localeItem.code}`,\n style: mergedLinkStyle,\n onClick: (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n handleSwitchLocale(localeItem.code)\n },\n },\n localeLabel(localeItem),\n ),\n )\n })\n\n return h(\n 'div',\n {\n ref: wrapperRef,\n className: 'i18n-switcher-wrapper',\n style: mergedWrapperStyle,\n ...restProps,\n },\n h(\n 'button',\n {\n type: 'button',\n className: 'i18n-switcher-button',\n style: mergedButtonStyle,\n onClick: (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n toggleDropdown(e)\n },\n ariaHaspopup: 'true',\n ariaExpanded: dropdownOpen,\n },\n h('span', null, currentLocaleLabel()),\n h('span', { style: mergedIconStyle }, '▼'),\n ),\n dropdownOpen\n ? h(\n 'ul',\n {\n className: 'i18n-switcher-dropdown',\n style: mergedDropdownStyle,\n },\n ...dropdownItems,\n )\n : null,\n ) as JSX.Element\n}\n","import { h } from 'preact'\nimport type { JSX, ComponentChildren } from 'preact'\nimport { useI18n } from '../context'\nimport type { TranslationKey } from '@i18n-micro/types'\n\nexport interface I18nGroupProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, 'children'> {\n prefix: string\n groupClass?: string\n children?: (props: { prefix: string, t: (key: string, params?: Record<string, string | number | boolean>) => string }) => ComponentChildren\n}\n\nexport const I18nGroup = (props: I18nGroupProps): JSX.Element => {\n const { prefix, groupClass, children, ...restProps } = props\n const { t, getRoute } = useI18n()\n\n const translate = (key: string, params?: Record<string, string | number | boolean>): string => {\n const result = t(`${prefix}.${key}` as TranslationKey, params, undefined, getRoute())\n return typeof result === 'string' ? result : String(result)\n }\n\n const className = ['i18n-group', groupClass].filter(Boolean).join(' ')\n\n const childrenContent: ComponentChildren = typeof children === 'function'\n ? children({ prefix, t: translate })\n : children\n\n return h(\n 'div',\n { ...restProps, className },\n childrenContent,\n ) as JSX.Element\n}\n","import type { I18nRoutingStrategy } from './types'\nimport type { Locale } from '@i18n-micro/types'\n\n/**\n * Создает адаптер для работы с History API (универсальный для Pure Preact)\n * Работает с любым роутером, который использует History API (wouter, preact-router, и т.д.)\n */\nexport function createBrowserHistoryAdapter(\n locales: Locale[],\n defaultLocale: string,\n): I18nRoutingStrategy {\n const localeCodes = locales.map(loc => loc.code)\n\n /**\n * Path resolution logic (add prefix or not)\n */\n const resolvePath = (to: string | { path?: string }, locale: string): string | { path?: string } => {\n const path = typeof to === 'string' ? to : (to.path || '/')\n const pathSegments = path.split('/').filter(Boolean)\n\n // If path already starts with a locale, remove it\n const first = pathSegments[0]\n if (first !== undefined && localeCodes.includes(first)) {\n pathSegments.shift()\n }\n\n const cleanPath = '/' + pathSegments.join('/')\n\n // If default locale - return clean path\n if (locale === defaultLocale) {\n return cleanPath\n }\n\n // Otherwise add prefix\n return `/${locale}${cleanPath === '/' ? '' : cleanPath}`\n }\n\n return {\n // Просто рендерим <a>, навигацию перехватит onClick в I18nLink\n linkComponent: undefined,\n\n getCurrentPath: () => {\n if (typeof window !== 'undefined') {\n return window.location.pathname\n }\n return '/'\n },\n\n push: (target) => {\n if (typeof window !== 'undefined') {\n window.history.pushState({}, '', target.path)\n // Вызываем событие, чтобы роутеры (wouter/preact-router) узнали об изменении\n window.dispatchEvent(new Event('popstate'))\n }\n },\n\n replace: (target) => {\n if (typeof window !== 'undefined') {\n window.history.replaceState({}, '', target.path)\n window.dispatchEvent(new Event('popstate'))\n }\n },\n\n resolvePath: (to, locale) => resolvePath(to, locale),\n\n getRoute: () => {\n if (typeof window !== 'undefined') {\n return {\n fullPath: window.location.pathname + window.location.search,\n query: Object.fromEntries(new URLSearchParams(window.location.search)),\n }\n }\n return {\n fullPath: '/',\n query: {},\n }\n },\n }\n}\n\n// Export for backward compatibility (old name)\nexport const createPreactRouterAdapter = createBrowserHistoryAdapter\n"],"names":["PreactI18n","BaseI18n","options","storage","lang","msgs","listener","val","routeName","locale","translations","merge","createI18n","I18nContext","createContext","I18nLocalesContext","I18nDefaultLocaleContext","I18nRouterContext","useI18nContext","context","useContext","useI18nLocales","useI18nDefaultLocale","useI18nRouter","I18nProvider","i18n","locales","defaultLocale","routingStrategy","children","h","useI18n","router","injectedLocales","injectedDefaultLocale","forceUpdate","useState","useEffect","n","resolveLocalePath","to","localeCode","switchLocaleHelper","newLocale","currentPath","newPath","l","res","I18nT","props","tc","tn","td","tdr","getRoute","keypath","params","tag","plural","defaultValue","html","hideIfEmpty","customPluralRule","number","date","relativeDate","restProps","route","createElement","elementTag","elementProps","numberValue","formattedNumber","translation","content","formattedDate","formattedRelativeDate","count","k","p","dv","tResult","Fragment","I18nLink","activeStyle","localeRouteProp","localeRoute","isExternalLink","externalHref","targetPath","computedStyle","linkPath","normalizedCurrent","normalizedLink","toValue","handleClick","e","LinkComponent","Component","componentProps","I18nSwitcher","localesProp","currentLocaleProp","getLocaleNameProp","switchLocaleProp","_localeRouteProp","customLabels","customWrapperStyle","customButtonStyle","customDropdownStyle","customItemStyle","customLinkStyle","customActiveLinkStyle","customIconStyle","i18nInstance","dropdownOpen","setDropdownOpen","wrapperRef","useRef","currentLocale","currentLocaleName","toggleDropdown","event","localeLabel","localeItem","currentLocaleLabel","current","handleSwitchLocale","code","wrapperStyle","buttonStyle","dropdownStyle","itemStyle","linkStyle","activeLinkStyle","iconStyle","openIconStyle","handler","target","isClickInside","isButtonClick","mergedWrapperStyle","mergedButtonStyle","mergedDropdownStyle","mergedItemStyle","mergedIconStyle","dropdownItems","isActive","mergedLinkStyle","I18nGroup","prefix","groupClass","t","translate","key","result","className","childrenContent","createBrowserHistoryAdapter","localeCodes","loc","resolvePath","pathSegments","first","cleanPath","createPreactRouterAdapter"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,9 +14,9 @@ import { LocaleCode } from '@i18n-micro/types';
|
|
|
14
14
|
import { ModuleOptions } from '@i18n-micro/types';
|
|
15
15
|
import { Params } from '@i18n-micro/types';
|
|
16
16
|
import { PluralFunc } from '@i18n-micro/types';
|
|
17
|
-
import { TranslationCache } from '@i18n-micro/core';
|
|
18
17
|
import { TranslationKey } from '@i18n-micro/types';
|
|
19
18
|
import { Translations } from '@i18n-micro/types';
|
|
19
|
+
import { TranslationStorage } from '@i18n-micro/core';
|
|
20
20
|
import { VNode } from 'preact';
|
|
21
21
|
|
|
22
22
|
export { CleanTranslation }
|
|
@@ -27,9 +27,6 @@ export { CleanTranslation }
|
|
|
27
27
|
*/
|
|
28
28
|
export declare function createBrowserHistoryAdapter(locales: Locale[], defaultLocale: string): I18nRoutingStrategy;
|
|
29
29
|
|
|
30
|
-
/**
|
|
31
|
-
* Create a new PreactI18n instance
|
|
32
|
-
*/
|
|
33
30
|
export declare function createI18n(options: PreactI18nOptions): PreactI18n;
|
|
34
31
|
|
|
35
32
|
export declare const createPreactRouterAdapter: typeof createBrowserHistoryAdapter;
|
|
@@ -187,22 +184,15 @@ export { Params }
|
|
|
187
184
|
|
|
188
185
|
export { PluralFunc }
|
|
189
186
|
|
|
190
|
-
/**
|
|
191
|
-
* Preact I18n Adapter
|
|
192
|
-
*
|
|
193
|
-
* Provides a Preact-compatible i18n instance that uses the shared core logic.
|
|
194
|
-
* Implements Observer pattern for reactivity with useSyncExternalStore.
|
|
195
|
-
* Works with Preact through preact/compat for React compatibility.
|
|
196
|
-
*/
|
|
197
187
|
export declare class PreactI18n extends BaseI18n {
|
|
198
188
|
private _locale;
|
|
199
189
|
private _fallbackLocale;
|
|
200
190
|
private _currentRoute;
|
|
201
191
|
private listeners;
|
|
202
192
|
private revision;
|
|
203
|
-
readonly
|
|
193
|
+
readonly storage: TranslationStorage;
|
|
204
194
|
constructor(options: PreactI18nOptions);
|
|
205
|
-
subscribe: (listener: () => void) => () =>
|
|
195
|
+
subscribe: (listener: () => void) => () => boolean;
|
|
206
196
|
getSnapshot: () => string;
|
|
207
197
|
private notify;
|
|
208
198
|
get locale(): string;
|
package/dist/index.mjs
CHANGED
|
@@ -1,63 +1,50 @@
|
|
|
1
|
-
import { BaseI18n as
|
|
1
|
+
import { BaseI18n as ct } from "@i18n-micro/core";
|
|
2
2
|
import { FormatService as Rt, defaultPlural as xt, interpolate as It } from "@i18n-micro/core";
|
|
3
3
|
import { createContext as H, h, Fragment as it } from "preact";
|
|
4
|
-
import { useContext as $, useState as
|
|
5
|
-
class dt extends
|
|
4
|
+
import { useContext as $, useState as W, useEffect as z, useRef as ut } from "preact/hooks";
|
|
5
|
+
class dt extends ct {
|
|
6
6
|
_locale;
|
|
7
7
|
_fallbackLocale;
|
|
8
8
|
_currentRoute = "general";
|
|
9
9
|
listeners = /* @__PURE__ */ new Set();
|
|
10
10
|
revision = 0;
|
|
11
|
-
|
|
12
|
-
cache;
|
|
11
|
+
storage;
|
|
13
12
|
constructor(t) {
|
|
14
13
|
const n = {
|
|
15
|
-
|
|
16
|
-
routeLocaleCache: {},
|
|
17
|
-
dynamicTranslationsCaches: [],
|
|
18
|
-
serverTranslationCache: {}
|
|
14
|
+
translations: /* @__PURE__ */ new Map()
|
|
19
15
|
};
|
|
20
16
|
if (super({
|
|
21
|
-
|
|
17
|
+
storage: n,
|
|
22
18
|
plural: t.plural,
|
|
23
19
|
missingWarn: t.missingWarn,
|
|
24
20
|
missingHandler: t.missingHandler
|
|
25
|
-
}), this.
|
|
26
|
-
for (const [e,
|
|
27
|
-
this.helper.loadTranslations(e,
|
|
21
|
+
}), this.storage = n, this._locale = t.locale, this._fallbackLocale = t.fallbackLocale || t.locale, t.messages)
|
|
22
|
+
for (const [e, o] of Object.entries(t.messages))
|
|
23
|
+
this.helper.loadTranslations(e, o);
|
|
28
24
|
}
|
|
29
|
-
|
|
30
|
-
subscribe = (t) => (this.listeners.add(t), () => {
|
|
31
|
-
this.listeners.delete(t);
|
|
32
|
-
});
|
|
25
|
+
subscribe = (t) => (this.listeners.add(t), () => this.listeners.delete(t));
|
|
33
26
|
getSnapshot = () => `${this._locale}:${this._currentRoute}:${this.revision}`;
|
|
34
27
|
notify() {
|
|
35
|
-
this.revision++, this.listeners.forEach((t) =>
|
|
36
|
-
t();
|
|
37
|
-
});
|
|
28
|
+
this.revision++, this.listeners.forEach((t) => t());
|
|
38
29
|
}
|
|
39
|
-
// Геттер/Сеттер для локали
|
|
40
30
|
get locale() {
|
|
41
31
|
return this._locale;
|
|
42
32
|
}
|
|
43
33
|
set locale(t) {
|
|
44
34
|
this._locale !== t && (this._locale = t, this.notify());
|
|
45
35
|
}
|
|
46
|
-
// Геттер/Сеттер для fallback локали
|
|
47
36
|
get fallbackLocale() {
|
|
48
37
|
return this._fallbackLocale;
|
|
49
38
|
}
|
|
50
39
|
set fallbackLocale(t) {
|
|
51
40
|
this._fallbackLocale = t;
|
|
52
41
|
}
|
|
53
|
-
// Геттер/Сеттер для текущего роута
|
|
54
42
|
get currentRoute() {
|
|
55
43
|
return this._currentRoute;
|
|
56
44
|
}
|
|
57
45
|
setRoute(t) {
|
|
58
46
|
this._currentRoute !== t && (this._currentRoute = t, this.notify());
|
|
59
47
|
}
|
|
60
|
-
// --- Implementation of abstract methods ---
|
|
61
48
|
getLocale() {
|
|
62
49
|
return this._locale;
|
|
63
50
|
}
|
|
@@ -67,12 +54,11 @@ class dt extends lt {
|
|
|
67
54
|
getRoute() {
|
|
68
55
|
return this._currentRoute;
|
|
69
56
|
}
|
|
70
|
-
// Translation management (uses protected methods from base class)
|
|
71
57
|
addTranslations(t, n, e = !0) {
|
|
72
58
|
super.loadTranslationsCore(t, n, e), this.notify();
|
|
73
59
|
}
|
|
74
|
-
addRouteTranslations(t, n, e,
|
|
75
|
-
super.loadRouteTranslationsCore(t, n, e,
|
|
60
|
+
addRouteTranslations(t, n, e, o = !0) {
|
|
61
|
+
super.loadRouteTranslationsCore(t, n, e, o), this.notify();
|
|
76
62
|
}
|
|
77
63
|
clearCache() {
|
|
78
64
|
super.clearCache(), this.notify();
|
|
@@ -86,8 +72,8 @@ const O = H(null), F = H(null), V = H(null), q = H(null), K = () => {
|
|
|
86
72
|
if (!a)
|
|
87
73
|
throw new Error("[i18n-micro] I18nContext not found. Make sure I18nProvider is used.");
|
|
88
74
|
return a;
|
|
89
|
-
}, U = () => $(F), ft = () => $(V),
|
|
90
|
-
function bt({ i18n: a, locales: t, defaultLocale: n, routingStrategy: e, children:
|
|
75
|
+
}, U = () => $(F), ft = () => $(V), M = () => $(q);
|
|
76
|
+
function bt({ i18n: a, locales: t, defaultLocale: n, routingStrategy: e, children: o }) {
|
|
91
77
|
return h(
|
|
92
78
|
O.Provider,
|
|
93
79
|
{ value: a },
|
|
@@ -100,21 +86,21 @@ function bt({ i18n: a, locales: t, defaultLocale: n, routingStrategy: e, childre
|
|
|
100
86
|
e ? h(
|
|
101
87
|
q.Provider,
|
|
102
88
|
{ value: e },
|
|
103
|
-
|
|
104
|
-
) :
|
|
105
|
-
) :
|
|
106
|
-
) :
|
|
89
|
+
o
|
|
90
|
+
) : o
|
|
91
|
+
) : o
|
|
92
|
+
) : o
|
|
107
93
|
);
|
|
108
94
|
}
|
|
109
95
|
const j = (a) => {
|
|
110
|
-
const t = K(), n =
|
|
111
|
-
|
|
112
|
-
w((
|
|
96
|
+
const t = K(), n = M(), e = U(), o = ft(), [, w] = W(0);
|
|
97
|
+
z(() => t.subscribe(() => {
|
|
98
|
+
w((d) => d + 1);
|
|
113
99
|
}), [t]);
|
|
114
|
-
const y = a?.locales || e || [],
|
|
115
|
-
if (t.locale =
|
|
116
|
-
const
|
|
117
|
-
n.push(typeof
|
|
100
|
+
const y = a?.locales || e || [], m = a?.defaultLocale || o || t.locale, u = (r, d) => n?.resolvePath ? n.resolvePath(r, d || t.locale) : r, l = (r) => {
|
|
101
|
+
if (t.locale = r, n) {
|
|
102
|
+
const d = n.getCurrentPath(), f = u(d, r);
|
|
103
|
+
n.push(typeof f == "string" ? { path: f } : { path: f.path || "/" });
|
|
118
104
|
}
|
|
119
105
|
};
|
|
120
106
|
return {
|
|
@@ -136,103 +122,103 @@ const j = (a) => {
|
|
|
136
122
|
get currentRoute() {
|
|
137
123
|
return t.currentRoute;
|
|
138
124
|
},
|
|
139
|
-
setLocale: (
|
|
140
|
-
t.locale =
|
|
125
|
+
setLocale: (r) => {
|
|
126
|
+
t.locale = r;
|
|
141
127
|
},
|
|
142
128
|
// Route management
|
|
143
129
|
setRoute: t.setRoute.bind(t),
|
|
144
130
|
getRoute: t.getRoute.bind(t),
|
|
145
131
|
getLocales: () => y,
|
|
146
|
-
defaultLocale: () =>
|
|
147
|
-
getLocaleName: () => y.find((
|
|
132
|
+
defaultLocale: () => m,
|
|
133
|
+
getLocaleName: () => y.find((d) => d.code === t.locale)?.displayName || null,
|
|
148
134
|
// Router methods (always available, but navigation handled by components)
|
|
149
|
-
switchLocale:
|
|
150
|
-
localeRoute:
|
|
151
|
-
localePath: (
|
|
152
|
-
const
|
|
153
|
-
return typeof
|
|
135
|
+
switchLocale: l,
|
|
136
|
+
localeRoute: u,
|
|
137
|
+
localePath: (r, d) => {
|
|
138
|
+
const f = u(r, d);
|
|
139
|
+
return typeof f == "string" ? f : f.path || "/";
|
|
154
140
|
},
|
|
155
141
|
// Translation management
|
|
156
142
|
addTranslations: t.addTranslations.bind(t),
|
|
157
143
|
addRouteTranslations: t.addRouteTranslations.bind(t),
|
|
158
144
|
clearCache: t.clearCache.bind(t)
|
|
159
145
|
};
|
|
160
|
-
},
|
|
161
|
-
const { t, tc: n, tn: e, td:
|
|
162
|
-
keypath:
|
|
163
|
-
params:
|
|
164
|
-
tag:
|
|
165
|
-
plural:
|
|
166
|
-
defaultValue:
|
|
146
|
+
}, vt = (a) => {
|
|
147
|
+
const { t, tc: n, tn: e, td: o, tdr: w, locale: y, getRoute: m } = j(), {
|
|
148
|
+
keypath: u,
|
|
149
|
+
params: l,
|
|
150
|
+
tag: r = "span",
|
|
151
|
+
plural: d,
|
|
152
|
+
defaultValue: f,
|
|
167
153
|
html: P = !1,
|
|
168
154
|
hideIfEmpty: x = !1,
|
|
169
155
|
customPluralRule: I,
|
|
170
|
-
number:
|
|
171
|
-
date:
|
|
156
|
+
number: c,
|
|
157
|
+
date: g,
|
|
172
158
|
relativeDate: C,
|
|
173
159
|
...i
|
|
174
|
-
} = a, R =
|
|
175
|
-
|
|
160
|
+
} = a, R = m(), b = (v, p, L) => h(
|
|
161
|
+
v,
|
|
176
162
|
p,
|
|
177
|
-
|
|
163
|
+
L
|
|
178
164
|
);
|
|
179
|
-
if (
|
|
180
|
-
const
|
|
181
|
-
return P ? b(
|
|
165
|
+
if (c !== void 0) {
|
|
166
|
+
const v = Number(c), p = e(v), L = t(u, { number: p, ...l || {} }, void 0, R), _ = typeof L == "string" ? L : String(L);
|
|
167
|
+
return P ? b(r, { ...i, dangerouslySetInnerHTML: { __html: _ } }, void 0) : b(r, i, _);
|
|
182
168
|
}
|
|
183
|
-
if (
|
|
184
|
-
const
|
|
185
|
-
return P ? b(
|
|
169
|
+
if (g !== void 0) {
|
|
170
|
+
const v = o(g), p = t(u, { date: v, ...l || {} }, void 0, R), L = typeof p == "string" ? p : String(p);
|
|
171
|
+
return P ? b(r, { ...i, dangerouslySetInnerHTML: { __html: L } }, void 0) : b(r, i, L);
|
|
186
172
|
}
|
|
187
173
|
if (C !== void 0) {
|
|
188
|
-
const
|
|
189
|
-
return P ? b(
|
|
174
|
+
const v = w(C), p = t(u, { relativeDate: v, ...l || {} }, void 0, R), L = typeof p == "string" ? p : String(p);
|
|
175
|
+
return P ? b(r, { ...i, dangerouslySetInnerHTML: { __html: L } }, void 0) : b(r, i, L);
|
|
190
176
|
}
|
|
191
|
-
if (
|
|
192
|
-
const
|
|
177
|
+
if (d !== void 0) {
|
|
178
|
+
const v = Number.parseInt(d.toString());
|
|
193
179
|
let p;
|
|
194
180
|
return I ? p = I(
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
181
|
+
u,
|
|
182
|
+
v,
|
|
183
|
+
l || {},
|
|
198
184
|
y,
|
|
199
185
|
(_, A, B) => {
|
|
200
186
|
const E = t(_, A, B, R);
|
|
201
187
|
return typeof E == "string" ? E : String(E);
|
|
202
188
|
}
|
|
203
|
-
) || "" : p = n(
|
|
189
|
+
) || "" : p = n(u, { count: v, ...l || {} }, f), P ? b(r, { ...i, dangerouslySetInnerHTML: { __html: p } }, void 0) : b(r, i, p);
|
|
204
190
|
}
|
|
205
|
-
const
|
|
206
|
-
return x && !N.trim() ?
|
|
207
|
-
},
|
|
208
|
-
const t = j(), n =
|
|
209
|
-
if (
|
|
191
|
+
const T = t(u, l, f, R), N = typeof T == "string" ? T : String(T);
|
|
192
|
+
return x && !N.trim() ? f ? h(it, null, f) : null : P ? b(r, { ...i, dangerouslySetInnerHTML: { __html: N } }, void 0) : b(r, i, N);
|
|
193
|
+
}, Lt = (a) => {
|
|
194
|
+
const t = j(), n = M(), { to: e, activeStyle: o, localeRoute: w, children: y, ...m } = a, u = w || t.localeRoute, l = () => typeof e == "string" ? /^(?:https?:\/\/|\/\/|[a-zA-Z0-9-]+\.[a-zA-Z]{2,})|tel:|mailto:/.test(e) : !1, r = () => {
|
|
195
|
+
if (l() && typeof e == "string")
|
|
210
196
|
return /^https?:\/\//.test(e) ? e : `https://${e}`;
|
|
211
|
-
},
|
|
212
|
-
if (
|
|
197
|
+
}, d = () => {
|
|
198
|
+
if (l())
|
|
213
199
|
return typeof e == "string" ? e : e?.path || "/";
|
|
214
|
-
if (
|
|
215
|
-
const
|
|
216
|
-
return typeof
|
|
200
|
+
if (u) {
|
|
201
|
+
const g = u(e);
|
|
202
|
+
return typeof g == "string" ? g : g.path || "/";
|
|
217
203
|
}
|
|
218
204
|
if (!n?.resolvePath)
|
|
219
205
|
return typeof e == "string" ? e : e.path || "/";
|
|
220
|
-
const
|
|
221
|
-
return typeof
|
|
206
|
+
const c = n.resolvePath(e, t.locale);
|
|
207
|
+
return typeof c == "string" ? c : c.path || "/";
|
|
222
208
|
}, P = (() => {
|
|
223
|
-
if (
|
|
209
|
+
if (l() || !n)
|
|
224
210
|
return !1;
|
|
225
|
-
const
|
|
211
|
+
const c = n.getCurrentPath(), g = d(), C = c.replace(/\/$/, ""), i = g.replace(/\/$/, "");
|
|
226
212
|
return !!(C === i || C.startsWith(i + "/"));
|
|
227
|
-
})() ?
|
|
228
|
-
a.onClick && a.onClick(
|
|
213
|
+
})() ? o || {} : {}, x = d(), I = (c) => {
|
|
214
|
+
a.onClick && a.onClick(c), !c.defaultPrevented && !c.button && !c.metaKey && !c.ctrlKey && n && !l() && (c.preventDefault(), n.push({ path: x }));
|
|
229
215
|
};
|
|
230
|
-
if (
|
|
216
|
+
if (l())
|
|
231
217
|
return h(
|
|
232
218
|
"a",
|
|
233
219
|
{
|
|
234
|
-
...
|
|
235
|
-
href:
|
|
220
|
+
...m,
|
|
221
|
+
href: r(),
|
|
236
222
|
style: P,
|
|
237
223
|
target: "_blank",
|
|
238
224
|
rel: "noopener noreferrer"
|
|
@@ -240,24 +226,24 @@ const j = (a) => {
|
|
|
240
226
|
y
|
|
241
227
|
);
|
|
242
228
|
if (n?.linkComponent) {
|
|
243
|
-
const
|
|
244
|
-
if (typeof
|
|
229
|
+
const c = n.linkComponent;
|
|
230
|
+
if (typeof c == "string")
|
|
245
231
|
return h(
|
|
246
|
-
|
|
232
|
+
c,
|
|
247
233
|
{
|
|
248
|
-
...
|
|
234
|
+
...m,
|
|
249
235
|
href: x,
|
|
250
236
|
style: P
|
|
251
237
|
},
|
|
252
238
|
y
|
|
253
239
|
);
|
|
254
|
-
const
|
|
255
|
-
...
|
|
240
|
+
const g = c, C = {
|
|
241
|
+
...m,
|
|
256
242
|
href: x,
|
|
257
243
|
style: P
|
|
258
244
|
};
|
|
259
245
|
return h(
|
|
260
|
-
|
|
246
|
+
g,
|
|
261
247
|
C,
|
|
262
248
|
y
|
|
263
249
|
);
|
|
@@ -265,7 +251,7 @@ const j = (a) => {
|
|
|
265
251
|
return h(
|
|
266
252
|
"a",
|
|
267
253
|
{
|
|
268
|
-
...
|
|
254
|
+
...m,
|
|
269
255
|
href: x,
|
|
270
256
|
style: P,
|
|
271
257
|
onClick: I
|
|
@@ -277,37 +263,37 @@ const j = (a) => {
|
|
|
277
263
|
locales: t,
|
|
278
264
|
currentLocale: n,
|
|
279
265
|
getLocaleName: e,
|
|
280
|
-
switchLocale:
|
|
266
|
+
switchLocale: o,
|
|
281
267
|
localeRoute: w,
|
|
282
268
|
customLabels: y = {},
|
|
283
|
-
customWrapperStyle:
|
|
284
|
-
customButtonStyle:
|
|
285
|
-
customDropdownStyle:
|
|
286
|
-
customItemStyle:
|
|
287
|
-
customLinkStyle:
|
|
288
|
-
customActiveLinkStyle:
|
|
269
|
+
customWrapperStyle: m,
|
|
270
|
+
customButtonStyle: u,
|
|
271
|
+
customDropdownStyle: l,
|
|
272
|
+
customItemStyle: r,
|
|
273
|
+
customLinkStyle: d,
|
|
274
|
+
customActiveLinkStyle: f,
|
|
289
275
|
customIconStyle: P,
|
|
290
276
|
...x
|
|
291
|
-
} = a, I = j(),
|
|
277
|
+
} = a, I = j(), c = K(), g = M(), C = U(), [i, R] = W(!1), b = ut(null), T = t || C || I.getLocales() || [], v = typeof n == "function" ? n() : typeof n == "string" ? n : I.locale, p = e ? e() : I.getLocaleName(), L = (s) => {
|
|
292
278
|
s && (s.stopPropagation(), s.preventDefault()), R(!i);
|
|
293
279
|
}, _ = (s) => y[s.code] || s.displayName || s.code, A = () => {
|
|
294
|
-
const s =
|
|
295
|
-
return s ? _(s) : p ||
|
|
280
|
+
const s = T.find((k) => k.code === v);
|
|
281
|
+
return s ? _(s) : p || v;
|
|
296
282
|
}, B = (s) => {
|
|
297
|
-
if (R(!1),
|
|
298
|
-
|
|
283
|
+
if (R(!1), o) {
|
|
284
|
+
o(s);
|
|
299
285
|
return;
|
|
300
286
|
}
|
|
301
|
-
if (
|
|
287
|
+
if (c.locale = s, !g)
|
|
302
288
|
return;
|
|
303
|
-
const k =
|
|
289
|
+
const k = g.getCurrentPath(), D = a.localeRoute ? (() => {
|
|
304
290
|
const S = a.localeRoute(k, s);
|
|
305
291
|
return typeof S == "string" ? S : S.path || "/";
|
|
306
|
-
})() :
|
|
307
|
-
const S =
|
|
292
|
+
})() : g?.resolvePath ? (() => {
|
|
293
|
+
const S = g.resolvePath(k, s);
|
|
308
294
|
return typeof S == "string" ? S : S.path || "/";
|
|
309
295
|
})() : k;
|
|
310
|
-
|
|
296
|
+
g.push({ path: D });
|
|
311
297
|
}, E = {
|
|
312
298
|
position: "relative",
|
|
313
299
|
display: "inline-block",
|
|
@@ -354,29 +340,29 @@ const j = (a) => {
|
|
|
354
340
|
}, tt = {
|
|
355
341
|
transform: "rotate(180deg)"
|
|
356
342
|
};
|
|
357
|
-
|
|
343
|
+
z(() => {
|
|
358
344
|
if (!i) return;
|
|
359
345
|
const s = (k) => {
|
|
360
346
|
if (!i) return;
|
|
361
|
-
const
|
|
362
|
-
if (!
|
|
363
|
-
const S = b.current.contains(
|
|
364
|
-
!S && !
|
|
347
|
+
const D = k.target;
|
|
348
|
+
if (!D || !b.current) return;
|
|
349
|
+
const S = b.current.contains(D), lt = D.closest(".i18n-switcher-button") !== null;
|
|
350
|
+
!S && !lt && R(!1);
|
|
365
351
|
};
|
|
366
352
|
return document.addEventListener("click", s), () => {
|
|
367
353
|
document.removeEventListener("click", s);
|
|
368
354
|
};
|
|
369
355
|
}, [i]);
|
|
370
|
-
const et = { ...E, ...
|
|
356
|
+
const et = { ...E, ...m }, nt = { ...Z, ...u }, ot = { ...G, ...l }, rt = { ...J, ...r }, st = {
|
|
371
357
|
...Y,
|
|
372
358
|
...i ? tt : {},
|
|
373
359
|
...P
|
|
374
|
-
}, at =
|
|
375
|
-
const k = s.code ===
|
|
360
|
+
}, at = T.map((s) => {
|
|
361
|
+
const k = s.code === v, D = {
|
|
376
362
|
...Q,
|
|
377
363
|
...k ? X : {},
|
|
378
|
-
...
|
|
379
|
-
...k ?
|
|
364
|
+
...d,
|
|
365
|
+
...k ? f : {},
|
|
380
366
|
width: "100%",
|
|
381
367
|
textAlign: "left",
|
|
382
368
|
border: "none",
|
|
@@ -386,14 +372,14 @@ const j = (a) => {
|
|
|
386
372
|
"li",
|
|
387
373
|
{
|
|
388
374
|
key: s.code,
|
|
389
|
-
style:
|
|
375
|
+
style: rt
|
|
390
376
|
},
|
|
391
377
|
h(
|
|
392
378
|
"button",
|
|
393
379
|
{
|
|
394
380
|
type: "button",
|
|
395
381
|
className: `switcher-locale-${s.code}`,
|
|
396
|
-
style:
|
|
382
|
+
style: D,
|
|
397
383
|
onClick: (S) => {
|
|
398
384
|
S.preventDefault(), S.stopPropagation(), B(s.code);
|
|
399
385
|
}
|
|
@@ -417,7 +403,7 @@ const j = (a) => {
|
|
|
417
403
|
className: "i18n-switcher-button",
|
|
418
404
|
style: nt,
|
|
419
405
|
onClick: (s) => {
|
|
420
|
-
s.preventDefault(), s.stopPropagation(),
|
|
406
|
+
s.preventDefault(), s.stopPropagation(), L(s);
|
|
421
407
|
},
|
|
422
408
|
ariaHaspopup: "true",
|
|
423
409
|
ariaExpanded: i
|
|
@@ -429,40 +415,40 @@ const j = (a) => {
|
|
|
429
415
|
"ul",
|
|
430
416
|
{
|
|
431
417
|
className: "i18n-switcher-dropdown",
|
|
432
|
-
style:
|
|
418
|
+
style: ot
|
|
433
419
|
},
|
|
434
420
|
...at
|
|
435
421
|
) : null
|
|
436
422
|
);
|
|
437
423
|
}, Pt = (a) => {
|
|
438
|
-
const { prefix: t, groupClass: n, children: e, ...
|
|
439
|
-
const
|
|
440
|
-
return typeof
|
|
441
|
-
},
|
|
424
|
+
const { prefix: t, groupClass: n, children: e, ...o } = a, { t: w, getRoute: y } = j(), m = (r, d) => {
|
|
425
|
+
const f = w(`${t}.${r}`, d, void 0, y());
|
|
426
|
+
return typeof f == "string" ? f : String(f);
|
|
427
|
+
}, u = ["i18n-group", n].filter(Boolean).join(" "), l = typeof e == "function" ? e({ prefix: t, t: m }) : e;
|
|
442
428
|
return h(
|
|
443
429
|
"div",
|
|
444
|
-
{ ...
|
|
445
|
-
|
|
430
|
+
{ ...o, className: u },
|
|
431
|
+
l
|
|
446
432
|
);
|
|
447
433
|
};
|
|
448
434
|
function pt(a, t) {
|
|
449
|
-
const n = a.map((
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
const
|
|
453
|
-
return w === t ?
|
|
435
|
+
const n = a.map((o) => o.code), e = (o, w) => {
|
|
436
|
+
const m = (typeof o == "string" ? o : o.path || "/").split("/").filter(Boolean), u = m[0];
|
|
437
|
+
u !== void 0 && n.includes(u) && m.shift();
|
|
438
|
+
const l = "/" + m.join("/");
|
|
439
|
+
return w === t ? l : `/${w}${l === "/" ? "" : l}`;
|
|
454
440
|
};
|
|
455
441
|
return {
|
|
456
442
|
// Просто рендерим <a>, навигацию перехватит onClick в I18nLink
|
|
457
443
|
linkComponent: void 0,
|
|
458
444
|
getCurrentPath: () => typeof window < "u" ? window.location.pathname : "/",
|
|
459
|
-
push: (
|
|
460
|
-
typeof window < "u" && (window.history.pushState({}, "",
|
|
445
|
+
push: (o) => {
|
|
446
|
+
typeof window < "u" && (window.history.pushState({}, "", o.path), window.dispatchEvent(new Event("popstate")));
|
|
461
447
|
},
|
|
462
|
-
replace: (
|
|
463
|
-
typeof window < "u" && (window.history.replaceState({}, "",
|
|
448
|
+
replace: (o) => {
|
|
449
|
+
typeof window < "u" && (window.history.replaceState({}, "", o.path), window.dispatchEvent(new Event("popstate")));
|
|
464
450
|
},
|
|
465
|
-
resolvePath: (
|
|
451
|
+
resolvePath: (o, w) => e(o, w),
|
|
466
452
|
getRoute: () => typeof window < "u" ? {
|
|
467
453
|
fullPath: window.location.pathname + window.location.search,
|
|
468
454
|
query: Object.fromEntries(new URLSearchParams(window.location.search))
|
|
@@ -478,12 +464,12 @@ export {
|
|
|
478
464
|
O as I18nContext,
|
|
479
465
|
V as I18nDefaultLocaleContext,
|
|
480
466
|
Pt as I18nGroup,
|
|
481
|
-
|
|
467
|
+
Lt as I18nLink,
|
|
482
468
|
F as I18nLocalesContext,
|
|
483
469
|
bt as I18nProvider,
|
|
484
470
|
q as I18nRouterContext,
|
|
485
471
|
wt as I18nSwitcher,
|
|
486
|
-
|
|
472
|
+
vt as I18nT,
|
|
487
473
|
dt as PreactI18n,
|
|
488
474
|
pt as createBrowserHistoryAdapter,
|
|
489
475
|
yt as createI18n,
|
|
@@ -494,6 +480,6 @@ export {
|
|
|
494
480
|
K as useI18nContext,
|
|
495
481
|
ft as useI18nDefaultLocale,
|
|
496
482
|
U as useI18nLocales,
|
|
497
|
-
|
|
483
|
+
M as useI18nRouter
|
|
498
484
|
};
|
|
499
485
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/i18n.ts","../src/injection.ts","../src/context.tsx","../src/components/I18nT.tsx","../src/components/I18nLink.tsx","../src/components/I18nSwitcher.tsx","../src/components/I18nGroup.tsx","../src/router/adapter.tsx"],"sourcesContent":["import {\n BaseI18n,\n type TranslationCache,\n} from '@i18n-micro/core'\nimport type {\n Translations,\n PluralFunc,\n} from '@i18n-micro/types'\n\nexport interface PreactI18nOptions {\n locale: string\n fallbackLocale?: string\n messages?: Record<string, Translations>\n plural?: PluralFunc\n missingWarn?: boolean\n missingHandler?: (locale: string, key: string, routeName: string) => void\n}\n\n/**\n * Preact I18n Adapter\n *\n * Provides a Preact-compatible i18n instance that uses the shared core logic.\n * Implements Observer pattern for reactivity with useSyncExternalStore.\n * Works with Preact through preact/compat for React compatibility.\n */\nexport class PreactI18n extends BaseI18n {\n private _locale: string\n private _fallbackLocale: string\n private _currentRoute: string = 'general'\n private listeners = new Set<() => void>()\n private revision = 0\n\n // Cache для Core (plain objects, не реактивные)\n public readonly cache: TranslationCache\n\n constructor(options: PreactI18nOptions) {\n // Create cache first\n const cache: TranslationCache = {\n generalLocaleCache: {},\n routeLocaleCache: {},\n dynamicTranslationsCaches: [],\n serverTranslationCache: {},\n }\n\n // Call parent constructor with options\n super({\n cache,\n plural: options.plural,\n missingWarn: options.missingWarn,\n missingHandler: options.missingHandler,\n })\n\n // Assign cache to public readonly property\n this.cache = cache\n\n this._locale = options.locale\n this._fallbackLocale = options.fallbackLocale || options.locale\n\n // Загружаем начальные сообщения\n if (options.messages) {\n for (const [lang, msgs] of Object.entries(options.messages)) {\n this.helper.loadTranslations(lang, msgs)\n }\n }\n }\n\n // Для useSyncExternalStore\n subscribe = (listener: () => void) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n getSnapshot = () => {\n // Возвращаем комбинированную строку локали и ревизии кэша\n // Это заставит компонент перерендериться при изменении\n return `${this._locale}:${this._currentRoute}:${this.revision}`\n }\n\n private notify() {\n this.revision++\n this.listeners.forEach((listener) => {\n listener()\n })\n }\n\n // Геттер/Сеттер для локали\n get locale(): string {\n return this._locale\n }\n\n set locale(val: string) {\n if (this._locale !== val) {\n this._locale = val\n this.notify()\n }\n }\n\n // Геттер/Сеттер для fallback локали\n get fallbackLocale(): string {\n return this._fallbackLocale\n }\n\n set fallbackLocale(val: string) {\n this._fallbackLocale = val\n }\n\n // Геттер/Сеттер для текущего роута\n get currentRoute(): string {\n return this._currentRoute\n }\n\n setRoute(routeName: string): void {\n if (this._currentRoute !== routeName) {\n this._currentRoute = routeName\n this.notify()\n }\n }\n\n // --- Implementation of abstract methods ---\n\n public getLocale(): string {\n return this._locale\n }\n\n public getFallbackLocale(): string {\n return this._fallbackLocale\n }\n\n public getRoute(): string {\n return this._currentRoute\n }\n\n // Translation management (uses protected methods from base class)\n public addTranslations(locale: string, translations: Translations, merge: boolean = true): void {\n super.loadTranslationsCore(locale, translations, merge)\n this.notify()\n }\n\n public addRouteTranslations(\n locale: string,\n routeName: string,\n translations: Translations,\n merge: boolean = true,\n ): void {\n super.loadRouteTranslationsCore(locale, routeName, translations, merge)\n this.notify()\n }\n\n public override clearCache(): void {\n super.clearCache()\n this.notify()\n }\n}\n\n/**\n * Create a new PreactI18n instance\n */\nexport function createI18n(options: PreactI18nOptions): PreactI18n {\n return new PreactI18n(options)\n}\n","import { createContext } from 'preact'\nimport { useContext } from 'preact/hooks'\nimport type { PreactI18n } from './i18n'\nimport type { Locale } from '@i18n-micro/types'\nimport type { I18nRoutingStrategy } from './router/types'\n\n// Context keys (analogous to Vue's InjectionKey)\nexport const I18nContext = createContext<PreactI18n | null>(null)\nexport const I18nLocalesContext = createContext<Locale[] | null>(null)\nexport const I18nDefaultLocaleContext = createContext<string | null>(null)\nexport const I18nRouterContext = createContext<I18nRoutingStrategy | null>(null)\n\n// Helper hooks (analogous to Vue's inject)\nexport const useI18nContext = () => {\n const context = useContext(I18nContext)\n if (!context) {\n throw new Error('[i18n-micro] I18nContext not found. Make sure I18nProvider is used.')\n }\n return context\n}\n\nexport const useI18nLocales = () => {\n return useContext(I18nLocalesContext)\n}\n\nexport const useI18nDefaultLocale = () => {\n return useContext(I18nDefaultLocaleContext)\n}\n\nexport const useI18nRouter = () => {\n return useContext(I18nRouterContext)\n}\n","import { h } from 'preact'\nimport { useEffect, useState } from 'preact/hooks'\nimport type { ComponentChildren } from 'preact'\nimport type { PreactI18n } from './i18n'\nimport type {\n Translations,\n Params,\n TranslationKey,\n CleanTranslation,\n Locale,\n} from '@i18n-micro/types'\nimport {\n I18nContext,\n I18nLocalesContext,\n I18nDefaultLocaleContext,\n I18nRouterContext,\n useI18nContext,\n useI18nLocales,\n useI18nDefaultLocale,\n useI18nRouter,\n} from './injection'\nimport type { I18nRoutingStrategy } from './router/types'\n\nexport interface I18nProviderProps {\n i18n: PreactI18n\n locales?: Locale[]\n defaultLocale?: string\n routingStrategy?: I18nRoutingStrategy\n children?: ComponentChildren\n}\n\nexport function I18nProvider({ i18n, locales, defaultLocale, routingStrategy, children }: I18nProviderProps) {\n return h(\n I18nContext.Provider,\n { value: i18n },\n locales\n ? h(\n I18nLocalesContext.Provider,\n { value: locales },\n defaultLocale\n ? h(\n I18nDefaultLocaleContext.Provider,\n { value: defaultLocale },\n routingStrategy\n ? h(\n I18nRouterContext.Provider,\n { value: routingStrategy },\n children,\n )\n : children,\n )\n : children,\n )\n : children,\n )\n}\n\nexport interface UseI18nOptions {\n locales?: Locale[]\n defaultLocale?: string\n}\n\nexport interface UseI18nReturn {\n // Translation methods\n t: (key: TranslationKey, params?: Params, defaultValue?: string | null, routeName?: string) => CleanTranslation\n ts: (key: TranslationKey, params?: Params, defaultValue?: string, routeName?: string) => string\n tc: (key: TranslationKey, count: number | Params, defaultValue?: string) => string\n tn: (value: number, options?: Intl.NumberFormatOptions) => string\n td: (value: Date | number | string, options?: Intl.DateTimeFormatOptions) => string\n tdr: (value: Date | number | string, options?: Intl.RelativeTimeFormatOptions) => string\n has: (key: TranslationKey, routeName?: string) => boolean\n\n // Locale management\n locale: string\n fallbackLocale: string\n currentRoute: string\n setLocale: (locale: string) => void\n\n // Route management\n setRoute: (routeName: string) => void\n getRoute: () => string\n getLocales: () => Locale[]\n defaultLocale: () => string\n getLocaleName: () => string | null\n\n // Router methods (if router is available)\n switchLocale?: (locale: string) => void\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n localePath?: (to: string | { path?: string }, locale?: string) => string\n\n // Translation management\n addTranslations: (locale: string, translations: Translations, merge?: boolean) => void\n addRouteTranslations: (locale: string, routeName: string, translations: Translations, merge?: boolean) => void\n clearCache: () => void\n}\n\nexport const useI18n = (options?: UseI18nOptions): UseI18nReturn => {\n const i18n = useI18nContext()\n const router = useI18nRouter()\n const injectedLocales = useI18nLocales()\n const injectedDefaultLocale = useI18nDefaultLocale()\n\n // --- Замена useSyncExternalStore для Pure Preact ---\n // Подписываемся на изменения в i18n и форсируем ре-рендер\n const [, forceUpdate] = useState(0)\n\n useEffect(() => {\n // subscribe возвращает функцию отписки\n const unsubscribe = i18n.subscribe(() => {\n forceUpdate(n => n + 1)\n })\n return unsubscribe\n }, [i18n])\n // ---------------------------------------------------\n\n const locales = options?.locales || injectedLocales || []\n const defaultLocale = options?.defaultLocale || injectedDefaultLocale || i18n.locale\n\n const resolveLocalePath = (to: string | { path?: string }, localeCode?: string): string | { path?: string } => {\n if (!router?.resolvePath) {\n return to\n }\n return router.resolvePath(to, localeCode || i18n.locale)\n }\n\n const switchLocaleHelper = (newLocale: string): void => {\n i18n.locale = newLocale\n if (router) {\n const currentPath = router.getCurrentPath()\n const newPath = resolveLocalePath(currentPath, newLocale)\n router.push(typeof newPath === 'string' ? { path: newPath } : { path: newPath.path || '/' })\n }\n }\n\n return {\n // Translation methods\n t: i18n.t.bind(i18n),\n ts: i18n.ts.bind(i18n),\n tc: i18n.tc.bind(i18n),\n tn: i18n.tn.bind(i18n),\n td: i18n.td.bind(i18n),\n tdr: i18n.tdr.bind(i18n),\n has: i18n.has.bind(i18n),\n\n // Locale management\n get locale() {\n return i18n.locale\n },\n get fallbackLocale() {\n return i18n.fallbackLocale\n },\n get currentRoute() {\n return i18n.currentRoute\n },\n setLocale: (locale: string) => {\n i18n.locale = locale\n },\n\n // Route management\n setRoute: i18n.setRoute.bind(i18n),\n getRoute: i18n.getRoute.bind(i18n),\n getLocales: () => locales,\n defaultLocale: () => defaultLocale,\n getLocaleName: () => {\n const current = locales.find(l => l.code === i18n.locale)\n return current?.displayName || null\n },\n\n // Router methods (always available, but navigation handled by components)\n switchLocale: switchLocaleHelper,\n localeRoute: resolveLocalePath,\n localePath: (to: string | { path?: string }, locale?: string) => {\n const res = resolveLocalePath(to, locale)\n return typeof res === 'string' ? res : (res.path || '/')\n },\n\n // Translation management\n addTranslations: i18n.addTranslations.bind(i18n),\n addRouteTranslations: i18n.addRouteTranslations.bind(i18n),\n clearCache: i18n.clearCache.bind(i18n),\n }\n}\n\n// Export context for advanced usage\nexport { I18nContext } from './injection'\n","import { h, Fragment } from 'preact'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport type { TranslationKey, PluralFunc } from '@i18n-micro/types'\n\nexport interface I18nTProps extends Omit<JSX.HTMLAttributes<HTMLElement>, 'children'> {\n keypath: TranslationKey\n params?: Record<string, string | number | boolean>\n tag?: keyof JSX.IntrinsicElements\n plural?: number | string\n defaultValue?: string\n html?: boolean\n hideIfEmpty?: boolean\n customPluralRule?: PluralFunc\n number?: number | string\n date?: Date | string | number\n relativeDate?: Date | string | number\n children?: never // I18nT doesn't support children - translation is rendered as content\n}\n\nexport const I18nT = (props: I18nTProps): JSX.Element | null => {\n const { t, tc, tn, td, tdr, locale, getRoute } = useI18n()\n const {\n keypath,\n params,\n tag = 'span',\n plural,\n defaultValue,\n html = false,\n hideIfEmpty = false,\n customPluralRule,\n number,\n date,\n relativeDate,\n ...restProps\n } = props\n\n const route = getRoute()\n\n // Helper function to create element with proper typing\n const createElement = (\n elementTag: keyof JSX.IntrinsicElements,\n elementProps: JSX.HTMLAttributes<HTMLElement>,\n children?: string,\n ): JSX.Element => {\n return h(\n elementTag as unknown as keyof JSX.IntrinsicElements,\n elementProps as unknown as JSX.HTMLAttributes<HTMLElement>,\n children,\n ) as JSX.Element\n }\n\n // Handle number formatting\n if (number !== undefined) {\n const numberValue = Number(number)\n const formattedNumber = tn(numberValue)\n const translation = t(keypath, { number: formattedNumber, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle date formatting\n if (date !== undefined) {\n const formattedDate = td(date)\n const translation = t(keypath, { date: formattedDate, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle relative date formatting\n if (relativeDate !== undefined) {\n const formattedRelativeDate = tdr(relativeDate)\n const translation = t(keypath, { relativeDate: formattedRelativeDate, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle pluralization\n if (plural !== undefined) {\n const count = Number.parseInt(plural.toString())\n let translation: string\n if (customPluralRule) {\n const result = customPluralRule(\n keypath,\n count,\n params || {},\n locale,\n (k: TranslationKey, p?: Record<string, string | number | boolean>, dv?: string) => {\n const tResult = t(k, p, dv, route)\n return typeof tResult === 'string' ? tResult : String(tResult)\n },\n )\n translation = result || ''\n }\n else {\n translation = tc(keypath, { count, ...(params || {}) }, defaultValue)\n }\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: translation } }, undefined)\n }\n return createElement(tag, restProps, translation)\n }\n\n // Regular translation\n const translation = t(keypath, params, defaultValue, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n\n if (hideIfEmpty && !content.trim()) {\n return defaultValue ? (h(Fragment, null, defaultValue) as JSX.Element) : null\n }\n\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n\n return createElement(tag, restProps, content)\n}\n","import { h } from 'preact'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport { useI18nRouter } from '../injection'\n\nexport interface I18nLinkProps extends JSX.AnchorHTMLAttributes<HTMLAnchorElement> {\n to: string | { path?: string }\n activeStyle?: Record<string, string | number>\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n}\n\nexport const I18nLink = (props: I18nLinkProps): JSX.Element => {\n const i18n = useI18n()\n const router = useI18nRouter()\n const { to, activeStyle, localeRoute: localeRouteProp, children, ...restProps } = props\n\n // Use prop if provided, otherwise fallback to useI18n\n const localeRoute = localeRouteProp || i18n.localeRoute\n\n const isExternalLink = (): boolean => {\n if (typeof to === 'string') {\n return /^(?:https?:\\/\\/|\\/\\/|[a-zA-Z0-9-]+\\.[a-zA-Z]{2,})|tel:|mailto:/.test(to)\n }\n return false\n }\n\n const externalHref = (): string | undefined => {\n if (isExternalLink() && typeof to === 'string') {\n if (!/^https?:\\/\\//.test(to)) {\n return `https://${to}`\n }\n return to\n }\n return undefined\n }\n\n const targetPath = (): string => {\n if (isExternalLink()) {\n if (typeof to === 'string') {\n return to\n }\n const toObj = to as { path?: string }\n return toObj?.path || '/'\n }\n\n if (localeRoute) {\n const res = localeRoute(to)\n return typeof res === 'string' ? res : (res.path || '/')\n }\n\n if (!router?.resolvePath) {\n return typeof to === 'string' ? to : (to.path || '/')\n }\n\n const res = router.resolvePath(to, i18n.locale)\n return typeof res === 'string' ? res : (res.path || '/')\n }\n\n const isActive = (): boolean => {\n if (isExternalLink() || !router) {\n return false\n }\n\n const currentPath = router.getCurrentPath()\n const linkPath = targetPath()\n\n // Normalize paths (remove trailing slashes)\n const normalizedCurrent = currentPath.replace(/\\/$/, '')\n const normalizedLink = linkPath.replace(/\\/$/, '')\n\n // Exact match (ignoring query params and hash)\n if (normalizedCurrent === normalizedLink) {\n return true\n }\n\n // Partial match: check if current path starts with link path\n // This allows parent routes to be marked as active\n if (normalizedCurrent.startsWith(normalizedLink + '/')) {\n return true\n }\n\n return false\n }\n\n const computedStyle: Record<string, string | number> = isActive() ? (activeStyle || {}) : {}\n const toValue = targetPath()\n\n const handleClick = (e: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {\n if (props.onClick) {\n props.onClick(e)\n }\n\n // Если это не внешний линк и нет модификаторов (ctrl/meta)\n if (!e.defaultPrevented && !e.button && !e.metaKey && !e.ctrlKey && router && !isExternalLink()) {\n e.preventDefault()\n router.push({ path: toValue })\n }\n }\n\n if (isExternalLink()) {\n return h(\n 'a',\n {\n ...restProps,\n href: externalHref(),\n style: computedStyle,\n target: '_blank',\n rel: 'noopener noreferrer',\n },\n children,\n ) as JSX.Element\n }\n\n // Use router linkComponent if available\n if (router?.linkComponent) {\n const LinkComponent = router.linkComponent\n if (typeof LinkComponent === 'string') {\n return h(\n LinkComponent,\n {\n ...restProps,\n href: toValue,\n style: computedStyle,\n },\n children,\n ) as JSX.Element\n }\n // Type assertion needed because React.ComponentType from I18nRoutingStrategy\n // is compatible with Preact components at runtime\n const Component = LinkComponent as unknown as (props: {\n href: string\n children?: JSX.Element | JSX.Element[]\n style?: Record<string, string | number>\n className?: string\n [key: string]: unknown\n }) => JSX.Element\n // Extract only the props that are compatible with the component type\n const componentProps = {\n ...restProps,\n href: toValue,\n style: computedStyle,\n } as {\n href: string\n children?: JSX.Element | JSX.Element[]\n style?: Record<string, string | number>\n className?: string\n [key: string]: unknown\n }\n return h(\n Component,\n componentProps,\n children,\n ) as JSX.Element\n }\n\n // Fallback to anchor with onClick handler\n return h(\n 'a',\n {\n ...restProps,\n href: toValue,\n style: computedStyle,\n onClick: handleClick,\n },\n children,\n ) as JSX.Element\n}\n","import { h } from 'preact'\nimport { useState, useEffect, useRef } from 'preact/hooks'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport { useI18nRouter, useI18nLocales, useI18nContext } from '../injection'\nimport type { Locale } from '@i18n-micro/types'\n\nexport interface I18nSwitcherProps extends JSX.HTMLAttributes<HTMLDivElement> {\n locales?: Locale[]\n currentLocale?: string | (() => string)\n getLocaleName?: () => string | null\n switchLocale?: (locale: string) => void\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n customLabels?: Record<string, string>\n customWrapperStyle?: Record<string, string | number>\n customButtonStyle?: Record<string, string | number>\n customDropdownStyle?: Record<string, string | number>\n customItemStyle?: Record<string, string | number>\n customLinkStyle?: Record<string, string | number>\n customActiveLinkStyle?: Record<string, string | number>\n customIconStyle?: Record<string, string | number>\n}\n\nexport const I18nSwitcher = (props: I18nSwitcherProps): JSX.Element => {\n const {\n locales: localesProp,\n currentLocale: currentLocaleProp,\n getLocaleName: getLocaleNameProp,\n switchLocale: switchLocaleProp,\n localeRoute: _localeRouteProp,\n customLabels = {},\n customWrapperStyle,\n customButtonStyle,\n customDropdownStyle,\n customItemStyle,\n customLinkStyle,\n customActiveLinkStyle,\n customIconStyle,\n ...restProps\n } = props\n\n const i18n = useI18n()\n const i18nInstance = useI18nContext()\n const router = useI18nRouter()\n const injectedLocales = useI18nLocales()\n const [dropdownOpen, setDropdownOpen] = useState(false)\n const wrapperRef = useRef<HTMLDivElement>(null)\n\n // Use props if provided, otherwise fallback to injected or useI18n\n const locales = localesProp || injectedLocales || i18n.getLocales() || []\n\n // Get current locale value (handle both string and function)\n const getCurrentLocale = (): string => {\n if (typeof currentLocaleProp === 'function') {\n return currentLocaleProp()\n }\n if (typeof currentLocaleProp === 'string') {\n return currentLocaleProp\n }\n return i18n.locale\n }\n\n const currentLocale = getCurrentLocale()\n const currentLocaleName = getLocaleNameProp ? getLocaleNameProp() : i18n.getLocaleName()\n\n const toggleDropdown = (event?: Event) => {\n if (event) {\n event.stopPropagation()\n event.preventDefault()\n }\n setDropdownOpen(!dropdownOpen)\n }\n\n const localeLabel = (localeItem: Locale): string => {\n const current = customLabels[localeItem.code] || localeItem.displayName\n return current || localeItem.code\n }\n\n const currentLocaleLabel = (): string => {\n const current = locales.find(l => l.code === currentLocale)\n return current ? localeLabel(current) : (currentLocaleName || currentLocale)\n }\n\n const handleSwitchLocale = (code: string) => {\n setDropdownOpen(false)\n if (switchLocaleProp) {\n switchLocaleProp(code)\n return\n }\n\n i18nInstance.locale = code\n\n if (!router) {\n return\n }\n\n const currentPath = router.getCurrentPath()\n const newPath = props.localeRoute\n ? (() => {\n const res = props.localeRoute(currentPath, code)\n return typeof res === 'string' ? res : (res.path || '/')\n })()\n : (router?.resolvePath\n ? (() => {\n const res = router.resolvePath(currentPath, code)\n return typeof res === 'string' ? res : (res.path || '/')\n })()\n : currentPath)\n\n router.push({ path: newPath })\n }\n\n // Default Styles\n const wrapperStyle: Record<string, string | number> = {\n position: 'relative',\n display: 'inline-block',\n verticalAlign: 'middle',\n }\n\n const buttonStyle: Record<string, string | number> = {\n padding: '4px 12px',\n fontSize: '16px',\n cursor: 'pointer',\n backgroundColor: '#fff',\n border: '1px solid #333',\n transition: 'background-color 0.3s ease',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n }\n\n const dropdownStyle: Record<string, string | number> = {\n position: 'absolute',\n top: '100%',\n left: '0',\n zIndex: 1000,\n backgroundColor: '#fff',\n border: '1px solid #333',\n listStyle: 'none',\n padding: '0',\n margin: '4px 0 0 0',\n minWidth: '150px',\n boxShadow: '0 2px 8px rgba(0,0,0,0.15)',\n }\n\n const itemStyle: Record<string, string | number> = {\n margin: '0',\n padding: '0',\n }\n\n const linkStyle: Record<string, string | number> = {\n display: 'block',\n padding: '8px 12px',\n color: '#333',\n textDecoration: 'none',\n transition: 'background-color 0.3s ease',\n cursor: 'pointer',\n }\n\n const activeLinkStyle: Record<string, string | number> = {\n fontWeight: 'bold',\n color: '#007bff',\n }\n\n const iconStyle: Record<string, string | number> = {\n marginLeft: '8px',\n display: 'inline-block',\n transition: 'transform 0.3s ease',\n }\n\n const openIconStyle: Record<string, string | number> = {\n transform: 'rotate(180deg)',\n }\n\n useEffect(() => {\n if (!dropdownOpen) return\n const handler = (event: MouseEvent) => {\n if (!dropdownOpen) return\n\n const target = event.target as HTMLElement\n if (!target || !wrapperRef.current) return\n\n const isClickInside = wrapperRef.current.contains(target)\n const isButtonClick = target.closest('.i18n-switcher-button') !== null\n\n if (!isClickInside && !isButtonClick) {\n setDropdownOpen(false)\n }\n }\n document.addEventListener('click', handler)\n return () => {\n document.removeEventListener('click', handler)\n }\n }, [dropdownOpen])\n\n const mergedWrapperStyle = { ...wrapperStyle, ...customWrapperStyle }\n const mergedButtonStyle = { ...buttonStyle, ...customButtonStyle }\n const mergedDropdownStyle = { ...dropdownStyle, ...customDropdownStyle }\n const mergedItemStyle = { ...itemStyle, ...customItemStyle }\n const mergedIconStyle = {\n ...iconStyle,\n ...(dropdownOpen ? openIconStyle : {}),\n ...customIconStyle,\n }\n\n const dropdownItems = locales.map((localeItem) => {\n const isActive = localeItem.code === currentLocale\n const mergedLinkStyle = {\n ...linkStyle,\n ...(isActive ? activeLinkStyle : {}),\n ...customLinkStyle,\n ...(isActive ? customActiveLinkStyle : {}),\n width: '100%',\n textAlign: 'left',\n border: 'none',\n background: 'transparent',\n }\n\n return h(\n 'li',\n {\n key: localeItem.code,\n style: mergedItemStyle,\n },\n h(\n 'button',\n {\n type: 'button',\n className: `switcher-locale-${localeItem.code}`,\n style: mergedLinkStyle,\n onClick: (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n handleSwitchLocale(localeItem.code)\n },\n },\n localeLabel(localeItem),\n ),\n )\n })\n\n return h(\n 'div',\n {\n ref: wrapperRef,\n className: 'i18n-switcher-wrapper',\n style: mergedWrapperStyle,\n ...restProps,\n },\n h(\n 'button',\n {\n type: 'button',\n className: 'i18n-switcher-button',\n style: mergedButtonStyle,\n onClick: (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n toggleDropdown(e)\n },\n ariaHaspopup: 'true',\n ariaExpanded: dropdownOpen,\n },\n h('span', null, currentLocaleLabel()),\n h('span', { style: mergedIconStyle }, '▼'),\n ),\n dropdownOpen\n ? h(\n 'ul',\n {\n className: 'i18n-switcher-dropdown',\n style: mergedDropdownStyle,\n },\n ...dropdownItems,\n )\n : null,\n ) as JSX.Element\n}\n","import { h } from 'preact'\nimport type { JSX, ComponentChildren } from 'preact'\nimport { useI18n } from '../context'\nimport type { TranslationKey } from '@i18n-micro/types'\n\nexport interface I18nGroupProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, 'children'> {\n prefix: string\n groupClass?: string\n children?: (props: { prefix: string, t: (key: string, params?: Record<string, string | number | boolean>) => string }) => ComponentChildren\n}\n\nexport const I18nGroup = (props: I18nGroupProps): JSX.Element => {\n const { prefix, groupClass, children, ...restProps } = props\n const { t, getRoute } = useI18n()\n\n const translate = (key: string, params?: Record<string, string | number | boolean>): string => {\n const result = t(`${prefix}.${key}` as TranslationKey, params, undefined, getRoute())\n return typeof result === 'string' ? result : String(result)\n }\n\n const className = ['i18n-group', groupClass].filter(Boolean).join(' ')\n\n const childrenContent: ComponentChildren = typeof children === 'function'\n ? children({ prefix, t: translate })\n : children\n\n return h(\n 'div',\n { ...restProps, className },\n childrenContent,\n ) as JSX.Element\n}\n","import type { I18nRoutingStrategy } from './types'\nimport type { Locale } from '@i18n-micro/types'\n\n/**\n * Создает адаптер для работы с History API (универсальный для Pure Preact)\n * Работает с любым роутером, который использует History API (wouter, preact-router, и т.д.)\n */\nexport function createBrowserHistoryAdapter(\n locales: Locale[],\n defaultLocale: string,\n): I18nRoutingStrategy {\n const localeCodes = locales.map(loc => loc.code)\n\n /**\n * Path resolution logic (add prefix or not)\n */\n const resolvePath = (to: string | { path?: string }, locale: string): string | { path?: string } => {\n const path = typeof to === 'string' ? to : (to.path || '/')\n const pathSegments = path.split('/').filter(Boolean)\n\n // If path already starts with a locale, remove it\n if (pathSegments.length > 0 && localeCodes.includes(pathSegments[0])) {\n pathSegments.shift()\n }\n\n const cleanPath = '/' + pathSegments.join('/')\n\n // If default locale - return clean path\n if (locale === defaultLocale) {\n return cleanPath\n }\n\n // Otherwise add prefix\n return `/${locale}${cleanPath === '/' ? '' : cleanPath}`\n }\n\n return {\n // Просто рендерим <a>, навигацию перехватит onClick в I18nLink\n linkComponent: undefined,\n\n getCurrentPath: () => {\n if (typeof window !== 'undefined') {\n return window.location.pathname\n }\n return '/'\n },\n\n push: (target) => {\n if (typeof window !== 'undefined') {\n window.history.pushState({}, '', target.path)\n // Вызываем событие, чтобы роутеры (wouter/preact-router) узнали об изменении\n window.dispatchEvent(new Event('popstate'))\n }\n },\n\n replace: (target) => {\n if (typeof window !== 'undefined') {\n window.history.replaceState({}, '', target.path)\n window.dispatchEvent(new Event('popstate'))\n }\n },\n\n resolvePath: (to, locale) => resolvePath(to, locale),\n\n getRoute: () => {\n if (typeof window !== 'undefined') {\n return {\n fullPath: window.location.pathname + window.location.search,\n query: Object.fromEntries(new URLSearchParams(window.location.search)),\n }\n }\n return {\n fullPath: '/',\n query: {},\n }\n },\n }\n}\n\n// Export for backward compatibility (old name)\nexport const createPreactRouterAdapter = createBrowserHistoryAdapter\n"],"names":["PreactI18n","BaseI18n","options","cache","lang","msgs","listener","val","routeName","locale","translations","merge","createI18n","I18nContext","createContext","I18nLocalesContext","I18nDefaultLocaleContext","I18nRouterContext","useI18nContext","context","useContext","useI18nLocales","useI18nDefaultLocale","useI18nRouter","I18nProvider","i18n","locales","defaultLocale","routingStrategy","children","useI18n","router","injectedLocales","injectedDefaultLocale","forceUpdate","useState","useEffect","n","resolveLocalePath","to","localeCode","switchLocaleHelper","newLocale","currentPath","newPath","l","res","I18nT","props","tc","tn","td","tdr","getRoute","keypath","params","tag","plural","defaultValue","html","hideIfEmpty","customPluralRule","number","date","relativeDate","restProps","route","createElement","elementTag","elementProps","numberValue","formattedNumber","translation","content","formattedDate","formattedRelativeDate","count","k","p","dv","tResult","Fragment","I18nLink","activeStyle","localeRouteProp","localeRoute","isExternalLink","externalHref","targetPath","computedStyle","linkPath","normalizedCurrent","normalizedLink","toValue","handleClick","e","LinkComponent","Component","componentProps","I18nSwitcher","localesProp","currentLocaleProp","getLocaleNameProp","switchLocaleProp","_localeRouteProp","customLabels","customWrapperStyle","customButtonStyle","customDropdownStyle","customItemStyle","customLinkStyle","customActiveLinkStyle","customIconStyle","i18nInstance","dropdownOpen","setDropdownOpen","wrapperRef","useRef","currentLocale","currentLocaleName","toggleDropdown","event","localeLabel","localeItem","currentLocaleLabel","current","handleSwitchLocale","code","wrapperStyle","buttonStyle","dropdownStyle","itemStyle","linkStyle","activeLinkStyle","iconStyle","openIconStyle","handler","target","isClickInside","isButtonClick","mergedWrapperStyle","mergedButtonStyle","mergedDropdownStyle","mergedItemStyle","mergedIconStyle","dropdownItems","isActive","mergedLinkStyle","I18nGroup","prefix","groupClass","t","translate","key","result","className","childrenContent","createBrowserHistoryAdapter","localeCodes","loc","resolvePath","pathSegments","cleanPath","createPreactRouterAdapter"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/i18n.ts","../src/injection.ts","../src/context.tsx","../src/components/I18nT.tsx","../src/components/I18nLink.tsx","../src/components/I18nSwitcher.tsx","../src/components/I18nGroup.tsx","../src/router/adapter.tsx"],"sourcesContent":["import { BaseI18n, type TranslationStorage } from '@i18n-micro/core'\nimport type { Translations, PluralFunc } from '@i18n-micro/types'\n\nexport interface PreactI18nOptions {\n locale: string\n fallbackLocale?: string\n messages?: Record<string, Translations>\n plural?: PluralFunc\n missingWarn?: boolean\n missingHandler?: (locale: string, key: string, routeName: string) => void\n}\n\nexport class PreactI18n extends BaseI18n {\n private _locale: string\n private _fallbackLocale: string\n private _currentRoute: string = 'general'\n private listeners = new Set<() => void>()\n private revision = 0\n\n public readonly storage: TranslationStorage\n\n constructor(options: PreactI18nOptions) {\n const storage: TranslationStorage = {\n translations: new Map<string, Translations>(),\n }\n\n super({\n storage,\n plural: options.plural,\n missingWarn: options.missingWarn,\n missingHandler: options.missingHandler,\n })\n\n this.storage = storage\n this._locale = options.locale\n this._fallbackLocale = options.fallbackLocale || options.locale\n\n if (options.messages) {\n for (const [lang, msgs] of Object.entries(options.messages)) {\n this.helper.loadTranslations(lang, msgs)\n }\n }\n }\n\n subscribe = (listener: () => void) => {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n getSnapshot = () => `${this._locale}:${this._currentRoute}:${this.revision}`\n\n private notify() {\n this.revision++\n this.listeners.forEach(listener => listener())\n }\n\n get locale(): string {\n return this._locale\n }\n\n set locale(val: string) {\n if (this._locale !== val) {\n this._locale = val\n this.notify()\n }\n }\n\n get fallbackLocale(): string {\n return this._fallbackLocale\n }\n\n set fallbackLocale(val: string) {\n this._fallbackLocale = val\n }\n\n get currentRoute(): string {\n return this._currentRoute\n }\n\n setRoute(routeName: string): void {\n if (this._currentRoute !== routeName) {\n this._currentRoute = routeName\n this.notify()\n }\n }\n\n public getLocale(): string {\n return this._locale\n }\n\n public getFallbackLocale(): string {\n return this._fallbackLocale\n }\n\n public getRoute(): string {\n return this._currentRoute\n }\n\n public addTranslations(locale: string, translations: Translations, merge = true): void {\n super.loadTranslationsCore(locale, translations, merge)\n this.notify()\n }\n\n public addRouteTranslations(\n locale: string,\n routeName: string,\n translations: Translations,\n merge = true,\n ): void {\n super.loadRouteTranslationsCore(locale, routeName, translations, merge)\n this.notify()\n }\n\n public override clearCache(): void {\n super.clearCache()\n this.notify()\n }\n}\n\nexport function createI18n(options: PreactI18nOptions): PreactI18n {\n return new PreactI18n(options)\n}\n","import { createContext } from 'preact'\nimport { useContext } from 'preact/hooks'\nimport type { PreactI18n } from './i18n'\nimport type { Locale } from '@i18n-micro/types'\nimport type { I18nRoutingStrategy } from './router/types'\n\n// Context keys (analogous to Vue's InjectionKey)\nexport const I18nContext = createContext<PreactI18n | null>(null)\nexport const I18nLocalesContext = createContext<Locale[] | null>(null)\nexport const I18nDefaultLocaleContext = createContext<string | null>(null)\nexport const I18nRouterContext = createContext<I18nRoutingStrategy | null>(null)\n\n// Helper hooks (analogous to Vue's inject)\nexport const useI18nContext = () => {\n const context = useContext(I18nContext)\n if (!context) {\n throw new Error('[i18n-micro] I18nContext not found. Make sure I18nProvider is used.')\n }\n return context\n}\n\nexport const useI18nLocales = () => {\n return useContext(I18nLocalesContext)\n}\n\nexport const useI18nDefaultLocale = () => {\n return useContext(I18nDefaultLocaleContext)\n}\n\nexport const useI18nRouter = () => {\n return useContext(I18nRouterContext)\n}\n","import { h } from 'preact'\nimport { useEffect, useState } from 'preact/hooks'\nimport type { ComponentChildren } from 'preact'\nimport type { PreactI18n } from './i18n'\nimport type {\n Translations,\n Params,\n TranslationKey,\n CleanTranslation,\n Locale,\n} from '@i18n-micro/types'\nimport {\n I18nContext,\n I18nLocalesContext,\n I18nDefaultLocaleContext,\n I18nRouterContext,\n useI18nContext,\n useI18nLocales,\n useI18nDefaultLocale,\n useI18nRouter,\n} from './injection'\nimport type { I18nRoutingStrategy } from './router/types'\n\nexport interface I18nProviderProps {\n i18n: PreactI18n\n locales?: Locale[]\n defaultLocale?: string\n routingStrategy?: I18nRoutingStrategy\n children?: ComponentChildren\n}\n\nexport function I18nProvider({ i18n, locales, defaultLocale, routingStrategy, children }: I18nProviderProps) {\n return h(\n I18nContext.Provider,\n { value: i18n },\n locales\n ? h(\n I18nLocalesContext.Provider,\n { value: locales },\n defaultLocale\n ? h(\n I18nDefaultLocaleContext.Provider,\n { value: defaultLocale },\n routingStrategy\n ? h(\n I18nRouterContext.Provider,\n { value: routingStrategy },\n children,\n )\n : children,\n )\n : children,\n )\n : children,\n )\n}\n\nexport interface UseI18nOptions {\n locales?: Locale[]\n defaultLocale?: string\n}\n\nexport interface UseI18nReturn {\n // Translation methods\n t: (key: TranslationKey, params?: Params, defaultValue?: string | null, routeName?: string) => CleanTranslation\n ts: (key: TranslationKey, params?: Params, defaultValue?: string, routeName?: string) => string\n tc: (key: TranslationKey, count: number | Params, defaultValue?: string) => string\n tn: (value: number, options?: Intl.NumberFormatOptions) => string\n td: (value: Date | number | string, options?: Intl.DateTimeFormatOptions) => string\n tdr: (value: Date | number | string, options?: Intl.RelativeTimeFormatOptions) => string\n has: (key: TranslationKey, routeName?: string) => boolean\n\n // Locale management\n locale: string\n fallbackLocale: string\n currentRoute: string\n setLocale: (locale: string) => void\n\n // Route management\n setRoute: (routeName: string) => void\n getRoute: () => string\n getLocales: () => Locale[]\n defaultLocale: () => string\n getLocaleName: () => string | null\n\n // Router methods (if router is available)\n switchLocale?: (locale: string) => void\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n localePath?: (to: string | { path?: string }, locale?: string) => string\n\n // Translation management\n addTranslations: (locale: string, translations: Translations, merge?: boolean) => void\n addRouteTranslations: (locale: string, routeName: string, translations: Translations, merge?: boolean) => void\n clearCache: () => void\n}\n\nexport const useI18n = (options?: UseI18nOptions): UseI18nReturn => {\n const i18n = useI18nContext()\n const router = useI18nRouter()\n const injectedLocales = useI18nLocales()\n const injectedDefaultLocale = useI18nDefaultLocale()\n\n // --- Замена useSyncExternalStore для Pure Preact ---\n // Подписываемся на изменения в i18n и форсируем ре-рендер\n const [, forceUpdate] = useState(0)\n\n useEffect(() => {\n // subscribe возвращает функцию отписки\n const unsubscribe = i18n.subscribe(() => {\n forceUpdate(n => n + 1)\n })\n return unsubscribe\n }, [i18n])\n // ---------------------------------------------------\n\n const locales = options?.locales || injectedLocales || []\n const defaultLocale = options?.defaultLocale || injectedDefaultLocale || i18n.locale\n\n const resolveLocalePath = (to: string | { path?: string }, localeCode?: string): string | { path?: string } => {\n if (!router?.resolvePath) {\n return to\n }\n return router.resolvePath(to, localeCode || i18n.locale)\n }\n\n const switchLocaleHelper = (newLocale: string): void => {\n i18n.locale = newLocale\n if (router) {\n const currentPath = router.getCurrentPath()\n const newPath = resolveLocalePath(currentPath, newLocale)\n router.push(typeof newPath === 'string' ? { path: newPath } : { path: newPath.path || '/' })\n }\n }\n\n return {\n // Translation methods\n t: i18n.t.bind(i18n),\n ts: i18n.ts.bind(i18n),\n tc: i18n.tc.bind(i18n),\n tn: i18n.tn.bind(i18n),\n td: i18n.td.bind(i18n),\n tdr: i18n.tdr.bind(i18n),\n has: i18n.has.bind(i18n),\n\n // Locale management\n get locale() {\n return i18n.locale\n },\n get fallbackLocale() {\n return i18n.fallbackLocale\n },\n get currentRoute() {\n return i18n.currentRoute\n },\n setLocale: (locale: string) => {\n i18n.locale = locale\n },\n\n // Route management\n setRoute: i18n.setRoute.bind(i18n),\n getRoute: i18n.getRoute.bind(i18n),\n getLocales: () => locales,\n defaultLocale: () => defaultLocale,\n getLocaleName: () => {\n const current = locales.find(l => l.code === i18n.locale)\n return current?.displayName || null\n },\n\n // Router methods (always available, but navigation handled by components)\n switchLocale: switchLocaleHelper,\n localeRoute: resolveLocalePath,\n localePath: (to: string | { path?: string }, locale?: string) => {\n const res = resolveLocalePath(to, locale)\n return typeof res === 'string' ? res : (res.path || '/')\n },\n\n // Translation management\n addTranslations: i18n.addTranslations.bind(i18n),\n addRouteTranslations: i18n.addRouteTranslations.bind(i18n),\n clearCache: i18n.clearCache.bind(i18n),\n }\n}\n\n// Export context for advanced usage\nexport { I18nContext } from './injection'\n","import { h, Fragment } from 'preact'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport type { TranslationKey, PluralFunc } from '@i18n-micro/types'\n\nexport interface I18nTProps extends Omit<JSX.HTMLAttributes<HTMLElement>, 'children'> {\n keypath: TranslationKey\n params?: Record<string, string | number | boolean>\n tag?: keyof JSX.IntrinsicElements\n plural?: number | string\n defaultValue?: string\n html?: boolean\n hideIfEmpty?: boolean\n customPluralRule?: PluralFunc\n number?: number | string\n date?: Date | string | number\n relativeDate?: Date | string | number\n children?: never // I18nT doesn't support children - translation is rendered as content\n}\n\nexport const I18nT = (props: I18nTProps): JSX.Element | null => {\n const { t, tc, tn, td, tdr, locale, getRoute } = useI18n()\n const {\n keypath,\n params,\n tag = 'span',\n plural,\n defaultValue,\n html = false,\n hideIfEmpty = false,\n customPluralRule,\n number,\n date,\n relativeDate,\n ...restProps\n } = props\n\n const route = getRoute()\n\n // Helper function to create element with proper typing\n const createElement = (\n elementTag: keyof JSX.IntrinsicElements,\n elementProps: JSX.HTMLAttributes<HTMLElement>,\n children?: string,\n ): JSX.Element => {\n return h(\n elementTag as unknown as keyof JSX.IntrinsicElements,\n elementProps as unknown as JSX.HTMLAttributes<HTMLElement>,\n children,\n ) as JSX.Element\n }\n\n // Handle number formatting\n if (number !== undefined) {\n const numberValue = Number(number)\n const formattedNumber = tn(numberValue)\n const translation = t(keypath, { number: formattedNumber, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle date formatting\n if (date !== undefined) {\n const formattedDate = td(date)\n const translation = t(keypath, { date: formattedDate, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle relative date formatting\n if (relativeDate !== undefined) {\n const formattedRelativeDate = tdr(relativeDate)\n const translation = t(keypath, { relativeDate: formattedRelativeDate, ...(params || {}) }, undefined, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n return createElement(tag, restProps, content)\n }\n\n // Handle pluralization\n if (plural !== undefined) {\n const count = Number.parseInt(plural.toString())\n let translation: string\n if (customPluralRule) {\n const result = customPluralRule(\n keypath,\n count,\n params || {},\n locale,\n (k: TranslationKey, p?: Record<string, string | number | boolean>, dv?: string) => {\n const tResult = t(k, p, dv, route)\n return typeof tResult === 'string' ? tResult : String(tResult)\n },\n )\n translation = result || ''\n }\n else {\n translation = tc(keypath, { count, ...(params || {}) }, defaultValue)\n }\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: translation } }, undefined)\n }\n return createElement(tag, restProps, translation)\n }\n\n // Regular translation\n const translation = t(keypath, params, defaultValue, route)\n const content = typeof translation === 'string' ? translation : String(translation)\n\n if (hideIfEmpty && !content.trim()) {\n return defaultValue ? (h(Fragment, null, defaultValue) as JSX.Element) : null\n }\n\n if (html) {\n return createElement(tag, { ...restProps, dangerouslySetInnerHTML: { __html: content } }, undefined)\n }\n\n return createElement(tag, restProps, content)\n}\n","import { h } from 'preact'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport { useI18nRouter } from '../injection'\n\nexport interface I18nLinkProps extends JSX.AnchorHTMLAttributes<HTMLAnchorElement> {\n to: string | { path?: string }\n activeStyle?: Record<string, string | number>\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n}\n\nexport const I18nLink = (props: I18nLinkProps): JSX.Element => {\n const i18n = useI18n()\n const router = useI18nRouter()\n const { to, activeStyle, localeRoute: localeRouteProp, children, ...restProps } = props\n\n // Use prop if provided, otherwise fallback to useI18n\n const localeRoute = localeRouteProp || i18n.localeRoute\n\n const isExternalLink = (): boolean => {\n if (typeof to === 'string') {\n return /^(?:https?:\\/\\/|\\/\\/|[a-zA-Z0-9-]+\\.[a-zA-Z]{2,})|tel:|mailto:/.test(to)\n }\n return false\n }\n\n const externalHref = (): string | undefined => {\n if (isExternalLink() && typeof to === 'string') {\n if (!/^https?:\\/\\//.test(to)) {\n return `https://${to}`\n }\n return to\n }\n return undefined\n }\n\n const targetPath = (): string => {\n if (isExternalLink()) {\n if (typeof to === 'string') {\n return to\n }\n const toObj = to as { path?: string }\n return toObj?.path || '/'\n }\n\n if (localeRoute) {\n const res = localeRoute(to)\n return typeof res === 'string' ? res : (res.path || '/')\n }\n\n if (!router?.resolvePath) {\n return typeof to === 'string' ? to : (to.path || '/')\n }\n\n const res = router.resolvePath(to, i18n.locale)\n return typeof res === 'string' ? res : (res.path || '/')\n }\n\n const isActive = (): boolean => {\n if (isExternalLink() || !router) {\n return false\n }\n\n const currentPath = router.getCurrentPath()\n const linkPath = targetPath()\n\n // Normalize paths (remove trailing slashes)\n const normalizedCurrent = currentPath.replace(/\\/$/, '')\n const normalizedLink = linkPath.replace(/\\/$/, '')\n\n // Exact match (ignoring query params and hash)\n if (normalizedCurrent === normalizedLink) {\n return true\n }\n\n // Partial match: check if current path starts with link path\n // This allows parent routes to be marked as active\n if (normalizedCurrent.startsWith(normalizedLink + '/')) {\n return true\n }\n\n return false\n }\n\n const computedStyle: Record<string, string | number> = isActive() ? (activeStyle || {}) : {}\n const toValue = targetPath()\n\n const handleClick = (e: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {\n if (props.onClick) {\n props.onClick(e)\n }\n\n // Если это не внешний линк и нет модификаторов (ctrl/meta)\n if (!e.defaultPrevented && !e.button && !e.metaKey && !e.ctrlKey && router && !isExternalLink()) {\n e.preventDefault()\n router.push({ path: toValue })\n }\n }\n\n if (isExternalLink()) {\n return h(\n 'a',\n {\n ...restProps,\n href: externalHref(),\n style: computedStyle,\n target: '_blank',\n rel: 'noopener noreferrer',\n },\n children,\n ) as JSX.Element\n }\n\n // Use router linkComponent if available\n if (router?.linkComponent) {\n const LinkComponent = router.linkComponent\n if (typeof LinkComponent === 'string') {\n return h(\n LinkComponent,\n {\n ...restProps,\n href: toValue,\n style: computedStyle,\n },\n children,\n ) as JSX.Element\n }\n // Type assertion needed because React.ComponentType from I18nRoutingStrategy\n // is compatible with Preact components at runtime\n const Component = LinkComponent as unknown as (props: {\n href: string\n children?: JSX.Element | JSX.Element[]\n style?: Record<string, string | number>\n className?: string\n [key: string]: unknown\n }) => JSX.Element\n // Extract only the props that are compatible with the component type\n const componentProps = {\n ...restProps,\n href: toValue,\n style: computedStyle,\n } as {\n href: string\n children?: JSX.Element | JSX.Element[]\n style?: Record<string, string | number>\n className?: string\n [key: string]: unknown\n }\n return h(\n Component,\n componentProps,\n children,\n ) as JSX.Element\n }\n\n // Fallback to anchor with onClick handler\n return h(\n 'a',\n {\n ...restProps,\n href: toValue,\n style: computedStyle,\n onClick: handleClick,\n },\n children,\n ) as JSX.Element\n}\n","import { h } from 'preact'\nimport { useState, useEffect, useRef } from 'preact/hooks'\nimport type { JSX } from 'preact'\nimport { useI18n } from '../context'\nimport { useI18nRouter, useI18nLocales, useI18nContext } from '../injection'\nimport type { Locale } from '@i18n-micro/types'\n\nexport interface I18nSwitcherProps extends JSX.HTMLAttributes<HTMLDivElement> {\n locales?: Locale[]\n currentLocale?: string | (() => string)\n getLocaleName?: () => string | null\n switchLocale?: (locale: string) => void\n localeRoute?: (to: string | { path?: string }, locale?: string) => string | { path?: string }\n customLabels?: Record<string, string>\n customWrapperStyle?: Record<string, string | number>\n customButtonStyle?: Record<string, string | number>\n customDropdownStyle?: Record<string, string | number>\n customItemStyle?: Record<string, string | number>\n customLinkStyle?: Record<string, string | number>\n customActiveLinkStyle?: Record<string, string | number>\n customIconStyle?: Record<string, string | number>\n}\n\nexport const I18nSwitcher = (props: I18nSwitcherProps): JSX.Element => {\n const {\n locales: localesProp,\n currentLocale: currentLocaleProp,\n getLocaleName: getLocaleNameProp,\n switchLocale: switchLocaleProp,\n localeRoute: _localeRouteProp,\n customLabels = {},\n customWrapperStyle,\n customButtonStyle,\n customDropdownStyle,\n customItemStyle,\n customLinkStyle,\n customActiveLinkStyle,\n customIconStyle,\n ...restProps\n } = props\n\n const i18n = useI18n()\n const i18nInstance = useI18nContext()\n const router = useI18nRouter()\n const injectedLocales = useI18nLocales()\n const [dropdownOpen, setDropdownOpen] = useState(false)\n const wrapperRef = useRef<HTMLDivElement>(null)\n\n // Use props if provided, otherwise fallback to injected or useI18n\n const locales = localesProp || injectedLocales || i18n.getLocales() || []\n\n // Get current locale value (handle both string and function)\n const getCurrentLocale = (): string => {\n if (typeof currentLocaleProp === 'function') {\n return currentLocaleProp()\n }\n if (typeof currentLocaleProp === 'string') {\n return currentLocaleProp\n }\n return i18n.locale\n }\n\n const currentLocale = getCurrentLocale()\n const currentLocaleName = getLocaleNameProp ? getLocaleNameProp() : i18n.getLocaleName()\n\n const toggleDropdown = (event?: Event) => {\n if (event) {\n event.stopPropagation()\n event.preventDefault()\n }\n setDropdownOpen(!dropdownOpen)\n }\n\n const localeLabel = (localeItem: Locale): string => {\n const current = customLabels[localeItem.code] || localeItem.displayName\n return current || localeItem.code\n }\n\n const currentLocaleLabel = (): string => {\n const current = locales.find(l => l.code === currentLocale)\n return current ? localeLabel(current) : (currentLocaleName || currentLocale)\n }\n\n const handleSwitchLocale = (code: string) => {\n setDropdownOpen(false)\n if (switchLocaleProp) {\n switchLocaleProp(code)\n return\n }\n\n i18nInstance.locale = code\n\n if (!router) {\n return\n }\n\n const currentPath = router.getCurrentPath()\n const newPath = props.localeRoute\n ? (() => {\n const res = props.localeRoute(currentPath, code)\n return typeof res === 'string' ? res : (res.path || '/')\n })()\n : (router?.resolvePath\n ? (() => {\n const res = router.resolvePath(currentPath, code)\n return typeof res === 'string' ? res : (res.path || '/')\n })()\n : currentPath)\n\n router.push({ path: newPath })\n }\n\n // Default Styles\n const wrapperStyle: Record<string, string | number> = {\n position: 'relative',\n display: 'inline-block',\n verticalAlign: 'middle',\n }\n\n const buttonStyle: Record<string, string | number> = {\n padding: '4px 12px',\n fontSize: '16px',\n cursor: 'pointer',\n backgroundColor: '#fff',\n border: '1px solid #333',\n transition: 'background-color 0.3s ease',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n }\n\n const dropdownStyle: Record<string, string | number> = {\n position: 'absolute',\n top: '100%',\n left: '0',\n zIndex: 1000,\n backgroundColor: '#fff',\n border: '1px solid #333',\n listStyle: 'none',\n padding: '0',\n margin: '4px 0 0 0',\n minWidth: '150px',\n boxShadow: '0 2px 8px rgba(0,0,0,0.15)',\n }\n\n const itemStyle: Record<string, string | number> = {\n margin: '0',\n padding: '0',\n }\n\n const linkStyle: Record<string, string | number> = {\n display: 'block',\n padding: '8px 12px',\n color: '#333',\n textDecoration: 'none',\n transition: 'background-color 0.3s ease',\n cursor: 'pointer',\n }\n\n const activeLinkStyle: Record<string, string | number> = {\n fontWeight: 'bold',\n color: '#007bff',\n }\n\n const iconStyle: Record<string, string | number> = {\n marginLeft: '8px',\n display: 'inline-block',\n transition: 'transform 0.3s ease',\n }\n\n const openIconStyle: Record<string, string | number> = {\n transform: 'rotate(180deg)',\n }\n\n useEffect(() => {\n if (!dropdownOpen) return\n const handler = (event: MouseEvent) => {\n if (!dropdownOpen) return\n\n const target = event.target as HTMLElement\n if (!target || !wrapperRef.current) return\n\n const isClickInside = wrapperRef.current.contains(target)\n const isButtonClick = target.closest('.i18n-switcher-button') !== null\n\n if (!isClickInside && !isButtonClick) {\n setDropdownOpen(false)\n }\n }\n document.addEventListener('click', handler)\n return () => {\n document.removeEventListener('click', handler)\n }\n }, [dropdownOpen])\n\n const mergedWrapperStyle = { ...wrapperStyle, ...customWrapperStyle }\n const mergedButtonStyle = { ...buttonStyle, ...customButtonStyle }\n const mergedDropdownStyle = { ...dropdownStyle, ...customDropdownStyle }\n const mergedItemStyle = { ...itemStyle, ...customItemStyle }\n const mergedIconStyle = {\n ...iconStyle,\n ...(dropdownOpen ? openIconStyle : {}),\n ...customIconStyle,\n }\n\n const dropdownItems = locales.map((localeItem) => {\n const isActive = localeItem.code === currentLocale\n const mergedLinkStyle = {\n ...linkStyle,\n ...(isActive ? activeLinkStyle : {}),\n ...customLinkStyle,\n ...(isActive ? customActiveLinkStyle : {}),\n width: '100%',\n textAlign: 'left',\n border: 'none',\n background: 'transparent',\n }\n\n return h(\n 'li',\n {\n key: localeItem.code,\n style: mergedItemStyle,\n },\n h(\n 'button',\n {\n type: 'button',\n className: `switcher-locale-${localeItem.code}`,\n style: mergedLinkStyle,\n onClick: (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n handleSwitchLocale(localeItem.code)\n },\n },\n localeLabel(localeItem),\n ),\n )\n })\n\n return h(\n 'div',\n {\n ref: wrapperRef,\n className: 'i18n-switcher-wrapper',\n style: mergedWrapperStyle,\n ...restProps,\n },\n h(\n 'button',\n {\n type: 'button',\n className: 'i18n-switcher-button',\n style: mergedButtonStyle,\n onClick: (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n toggleDropdown(e)\n },\n ariaHaspopup: 'true',\n ariaExpanded: dropdownOpen,\n },\n h('span', null, currentLocaleLabel()),\n h('span', { style: mergedIconStyle }, '▼'),\n ),\n dropdownOpen\n ? h(\n 'ul',\n {\n className: 'i18n-switcher-dropdown',\n style: mergedDropdownStyle,\n },\n ...dropdownItems,\n )\n : null,\n ) as JSX.Element\n}\n","import { h } from 'preact'\nimport type { JSX, ComponentChildren } from 'preact'\nimport { useI18n } from '../context'\nimport type { TranslationKey } from '@i18n-micro/types'\n\nexport interface I18nGroupProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, 'children'> {\n prefix: string\n groupClass?: string\n children?: (props: { prefix: string, t: (key: string, params?: Record<string, string | number | boolean>) => string }) => ComponentChildren\n}\n\nexport const I18nGroup = (props: I18nGroupProps): JSX.Element => {\n const { prefix, groupClass, children, ...restProps } = props\n const { t, getRoute } = useI18n()\n\n const translate = (key: string, params?: Record<string, string | number | boolean>): string => {\n const result = t(`${prefix}.${key}` as TranslationKey, params, undefined, getRoute())\n return typeof result === 'string' ? result : String(result)\n }\n\n const className = ['i18n-group', groupClass].filter(Boolean).join(' ')\n\n const childrenContent: ComponentChildren = typeof children === 'function'\n ? children({ prefix, t: translate })\n : children\n\n return h(\n 'div',\n { ...restProps, className },\n childrenContent,\n ) as JSX.Element\n}\n","import type { I18nRoutingStrategy } from './types'\nimport type { Locale } from '@i18n-micro/types'\n\n/**\n * Создает адаптер для работы с History API (универсальный для Pure Preact)\n * Работает с любым роутером, который использует History API (wouter, preact-router, и т.д.)\n */\nexport function createBrowserHistoryAdapter(\n locales: Locale[],\n defaultLocale: string,\n): I18nRoutingStrategy {\n const localeCodes = locales.map(loc => loc.code)\n\n /**\n * Path resolution logic (add prefix or not)\n */\n const resolvePath = (to: string | { path?: string }, locale: string): string | { path?: string } => {\n const path = typeof to === 'string' ? to : (to.path || '/')\n const pathSegments = path.split('/').filter(Boolean)\n\n // If path already starts with a locale, remove it\n const first = pathSegments[0]\n if (first !== undefined && localeCodes.includes(first)) {\n pathSegments.shift()\n }\n\n const cleanPath = '/' + pathSegments.join('/')\n\n // If default locale - return clean path\n if (locale === defaultLocale) {\n return cleanPath\n }\n\n // Otherwise add prefix\n return `/${locale}${cleanPath === '/' ? '' : cleanPath}`\n }\n\n return {\n // Просто рендерим <a>, навигацию перехватит onClick в I18nLink\n linkComponent: undefined,\n\n getCurrentPath: () => {\n if (typeof window !== 'undefined') {\n return window.location.pathname\n }\n return '/'\n },\n\n push: (target) => {\n if (typeof window !== 'undefined') {\n window.history.pushState({}, '', target.path)\n // Вызываем событие, чтобы роутеры (wouter/preact-router) узнали об изменении\n window.dispatchEvent(new Event('popstate'))\n }\n },\n\n replace: (target) => {\n if (typeof window !== 'undefined') {\n window.history.replaceState({}, '', target.path)\n window.dispatchEvent(new Event('popstate'))\n }\n },\n\n resolvePath: (to, locale) => resolvePath(to, locale),\n\n getRoute: () => {\n if (typeof window !== 'undefined') {\n return {\n fullPath: window.location.pathname + window.location.search,\n query: Object.fromEntries(new URLSearchParams(window.location.search)),\n }\n }\n return {\n fullPath: '/',\n query: {},\n }\n },\n }\n}\n\n// Export for backward compatibility (old name)\nexport const createPreactRouterAdapter = createBrowserHistoryAdapter\n"],"names":["PreactI18n","BaseI18n","options","storage","lang","msgs","listener","val","routeName","locale","translations","merge","createI18n","I18nContext","createContext","I18nLocalesContext","I18nDefaultLocaleContext","I18nRouterContext","useI18nContext","context","useContext","useI18nLocales","useI18nDefaultLocale","useI18nRouter","I18nProvider","i18n","locales","defaultLocale","routingStrategy","children","useI18n","router","injectedLocales","injectedDefaultLocale","forceUpdate","useState","useEffect","n","resolveLocalePath","to","localeCode","switchLocaleHelper","newLocale","currentPath","newPath","l","res","I18nT","props","tc","tn","td","tdr","getRoute","keypath","params","tag","plural","defaultValue","html","hideIfEmpty","customPluralRule","number","date","relativeDate","restProps","route","createElement","elementTag","elementProps","numberValue","formattedNumber","translation","content","formattedDate","formattedRelativeDate","count","k","p","dv","tResult","Fragment","I18nLink","activeStyle","localeRouteProp","localeRoute","isExternalLink","externalHref","targetPath","computedStyle","linkPath","normalizedCurrent","normalizedLink","toValue","handleClick","e","LinkComponent","Component","componentProps","I18nSwitcher","localesProp","currentLocaleProp","getLocaleNameProp","switchLocaleProp","_localeRouteProp","customLabels","customWrapperStyle","customButtonStyle","customDropdownStyle","customItemStyle","customLinkStyle","customActiveLinkStyle","customIconStyle","i18nInstance","dropdownOpen","setDropdownOpen","wrapperRef","useRef","currentLocale","currentLocaleName","toggleDropdown","event","localeLabel","localeItem","currentLocaleLabel","current","handleSwitchLocale","code","wrapperStyle","buttonStyle","dropdownStyle","itemStyle","linkStyle","activeLinkStyle","iconStyle","openIconStyle","handler","target","isClickInside","isButtonClick","mergedWrapperStyle","mergedButtonStyle","mergedDropdownStyle","mergedItemStyle","mergedIconStyle","dropdownItems","isActive","mergedLinkStyle","I18nGroup","prefix","groupClass","t","translate","key","result","className","childrenContent","createBrowserHistoryAdapter","localeCodes","loc","resolvePath","pathSegments","first","cleanPath","createPreactRouterAdapter"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@i18n-micro/preact",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@i18n-micro/core": "1.0
|
|
23
|
-
"@i18n-micro/types": "1.0
|
|
22
|
+
"@i18n-micro/core": "1.1.0",
|
|
23
|
+
"@i18n-micro/types": "1.1.0"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"preact": "^10.0.0"
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"jest-environment-jsdom": "^29.7.0",
|
|
37
37
|
"preact": "^10.0.0",
|
|
38
38
|
"ts-jest": "^29.4.6",
|
|
39
|
-
"vite": "^7.
|
|
39
|
+
"vite": "^7.3.1",
|
|
40
40
|
"vite-plugin-dts": "^4.5.4"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|