@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 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;cache;constructor(t){const n={generalLocaleCache:{},routeLocaleCache:{},dynamicTranslationsCaches:[],serverTranslationCache:{}};if(super({cache:n,plural:t.plural,missingWarn:t.missingWarn,missingHandler:t.missingHandler}),this.cache=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(d=>d+1)}),[t]);const m=a?.locales||e||[],g=a?.defaultLocale||r||t.locale,l=(o,d)=>n?.resolvePath?n.resolvePath(o,d||t.locale):o,p=o=>{if(t.locale=o,n){const d=n.getCurrentPath(),f=l(d,o);n.push(typeof f=="string"?{path:f}:{path:f.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:()=>g,getLocaleName:()=>m.find(d=>d.code===t.locale)?.displayName||null,switchLocale:p,localeRoute:l,localePath:(o,d)=>{const f=l(o,d);return typeof f=="string"?f:f.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:g}=N(),{keypath:l,params:p,tag:o="span",plural:d,defaultValue:f,html:P=!1,hideIfEmpty:x=!1,customPluralRule:_,number:i,date:y,relativeDate:k,...u}=a,I=g(),b=(L,h,v)=>c.h(L,h,v);if(i!==void 0){const L=Number(i),h=e(L),v=t(l,{number:h,...p||{}},void 0,I),T=typeof v=="string"?v:String(v);return P?b(o,{...u,dangerouslySetInnerHTML:{__html:T}},void 0):b(o,u,T)}if(y!==void 0){const L=r(y),h=t(l,{date:L,...p||{}},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(l,{relativeDate:L,...p||{}},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(d!==void 0){const L=Number.parseInt(d.toString());let h;return _?h=_(l,L,p||{},m,(T,O,B)=>{const j=t(T,O,B,I);return typeof j=="string"?j:String(j)})||"":h=n(l,{count:L,...p||{}},f),P?b(o,{...u,dangerouslySetInnerHTML:{__html:h}},void 0):b(o,u,h)}const E=t(l,p,f,I),A=typeof E=="string"?E:String(E);return x&&!A.trim()?f?c.h(c.Fragment,null,f):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,...g}=a,l=w||t.localeRoute,p=()=>typeof e=="string"?/^(?:https?:\/\/|\/\/|[a-zA-Z0-9-]+\.[a-zA-Z]{2,})|tel:|mailto:/.test(e):!1,o=()=>{if(p()&&typeof e=="string")return/^https?:\/\//.test(e)?e:`https://${e}`},d=()=>{if(p())return typeof e=="string"?e:e?.path||"/";if(l){const y=l(e);return typeof y=="string"?y:y.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(p()||!n)return!1;const i=n.getCurrentPath(),y=d(),k=i.replace(/\/$/,""),u=y.replace(/\/$/,"");return!!(k===u||k.startsWith(u+"/"))})()?r||{}:{},x=d(),_=i=>{a.onClick&&a.onClick(i),!i.defaultPrevented&&!i.button&&!i.metaKey&&!i.ctrlKey&&n&&!p()&&(i.preventDefault(),n.push({path:x}))};if(p())return c.h("a",{...g,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,{...g,href:x,style:P},m);const y=i,k={...g,href:x,style:P};return c.h(y,k,m)}return c.h("a",{...g,href:x,style:P,onClick:_},m)},pt=a=>{const{locales:t,currentLocale:n,getLocaleName:e,switchLocale:r,localeRoute:w,customLabels:m={},customWrapperStyle:g,customButtonStyle:l,customDropdownStyle:p,customItemStyle:o,customLinkStyle:d,customActiveLinkStyle:f,customIconStyle:P,...x}=a,_=N(),i=F(),y=$(),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)},T=s=>m[s.code]||s.displayName||s.code,O=()=>{const s=E.find(S=>S.code===L);return s?T(s):h||L},B=s=>{if(I(!1),r){r(s);return}if(i.locale=s,!y)return;const S=y.getCurrentPath(),D=a.localeRoute?(()=>{const C=a.localeRoute(S,s);return typeof C=="string"?C:C.path||"/"})():y?.resolvePath?(()=>{const C=y.resolvePath(S,s);return typeof C=="string"?C:C.path||"/"})():S;y.push({path:D})},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=S=>{if(!u)return;const D=S.target;if(!D||!b.current)return;const C=b.current.contains(D),lt=D.closest(".i18n-switcher-button")!==null;!C&&!lt&&I(!1)};return document.addEventListener("click",s),()=>{document.removeEventListener("click",s)}},[u]);const nt={...j,...g},rt={...Z,...l},ot={...J,...p},st={...Q,...o},at={...tt,...u?et:{},...P},ct=E.map(s=>{const S=s.code===L,D={...X,...S?Y:{},...d,...S?f:{},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:D,onClick:C=>{C.preventDefault(),C.stopPropagation(),B(s.code)}},T(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(),g=(o,d)=>{const f=w(`${t}.${o}`,d,void 0,m());return typeof f=="string"?f:String(f)},l=["i18n-group",n].filter(Boolean).join(" "),p=typeof e=="function"?e({prefix:t,t:g}):e;return c.h("div",{...r,className:l},p)};function U(a,t){const n=a.map(r=>r.code),e=(r,w)=>{const g=(typeof r=="string"?r:r.path||"/").split("/").filter(Boolean);g.length>0&&n.includes(g[0])&&g.shift();const l="/"+g.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=$;
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
@@ -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 cache: TranslationCache;
193
+ readonly storage: TranslationStorage;
204
194
  constructor(options: PreactI18nOptions);
205
- subscribe: (listener: () => void) => () => 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 lt } from "@i18n-micro/core";
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 z, useEffect as M, useRef as ut } from "preact/hooks";
5
- class dt extends lt {
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
- // Cache для Core (plain objects, не реактивные)
12
- cache;
11
+ storage;
13
12
  constructor(t) {
14
13
  const n = {
15
- generalLocaleCache: {},
16
- routeLocaleCache: {},
17
- dynamicTranslationsCaches: [],
18
- serverTranslationCache: {}
14
+ translations: /* @__PURE__ */ new Map()
19
15
  };
20
16
  if (super({
21
- cache: n,
17
+ storage: n,
22
18
  plural: t.plural,
23
19
  missingWarn: t.missingWarn,
24
20
  missingHandler: t.missingHandler
25
- }), this.cache = n, this._locale = t.locale, this._fallbackLocale = t.fallbackLocale || t.locale, t.messages)
26
- for (const [e, r] of Object.entries(t.messages))
27
- this.helper.loadTranslations(e, r);
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
- // Для useSyncExternalStore
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, r = !0) {
75
- super.loadRouteTranslationsCore(t, n, e, r), this.notify();
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), W = () => $(q);
90
- function bt({ i18n: a, locales: t, defaultLocale: n, routingStrategy: e, children: r }) {
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
- r
104
- ) : r
105
- ) : r
106
- ) : r
89
+ o
90
+ ) : o
91
+ ) : o
92
+ ) : o
107
93
  );
108
94
  }
109
95
  const j = (a) => {
110
- const t = K(), n = W(), e = U(), r = ft(), [, w] = z(0);
111
- M(() => t.subscribe(() => {
112
- w((u) => u + 1);
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 || [], g = a?.defaultLocale || r || t.locale, c = (o, u) => n?.resolvePath ? n.resolvePath(o, u || t.locale) : o, f = (o) => {
115
- if (t.locale = o, n) {
116
- const u = n.getCurrentPath(), d = c(u, o);
117
- n.push(typeof d == "string" ? { path: d } : { path: d.path || "/" });
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: (o) => {
140
- t.locale = o;
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: () => g,
147
- getLocaleName: () => y.find((u) => u.code === t.locale)?.displayName || null,
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: f,
150
- localeRoute: c,
151
- localePath: (o, u) => {
152
- const d = c(o, u);
153
- return typeof d == "string" ? d : d.path || "/";
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
- }, Lt = (a) => {
161
- const { t, tc: n, tn: e, td: r, tdr: w, locale: y, getRoute: g } = j(), {
162
- keypath: c,
163
- params: f,
164
- tag: o = "span",
165
- plural: u,
166
- defaultValue: d,
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: l,
171
- date: m,
156
+ number: c,
157
+ date: g,
172
158
  relativeDate: C,
173
159
  ...i
174
- } = a, R = g(), b = (L, p, v) => h(
175
- L,
160
+ } = a, R = m(), b = (v, p, L) => h(
161
+ v,
176
162
  p,
177
- v
163
+ L
178
164
  );
179
- if (l !== void 0) {
180
- const L = Number(l), p = e(L), v = t(c, { number: p, ...f || {} }, void 0, R), _ = typeof v == "string" ? v : String(v);
181
- return P ? b(o, { ...i, dangerouslySetInnerHTML: { __html: _ } }, void 0) : b(o, i, _);
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 (m !== void 0) {
184
- const L = r(m), p = t(c, { date: L, ...f || {} }, void 0, R), v = typeof p == "string" ? p : String(p);
185
- return P ? b(o, { ...i, dangerouslySetInnerHTML: { __html: v } }, void 0) : b(o, i, v);
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 L = w(C), p = t(c, { relativeDate: L, ...f || {} }, void 0, R), v = typeof p == "string" ? p : String(p);
189
- return P ? b(o, { ...i, dangerouslySetInnerHTML: { __html: v } }, void 0) : b(o, i, v);
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 (u !== void 0) {
192
- const L = Number.parseInt(u.toString());
177
+ if (d !== void 0) {
178
+ const v = Number.parseInt(d.toString());
193
179
  let p;
194
180
  return I ? p = I(
195
- c,
196
- L,
197
- f || {},
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(c, { count: L, ...f || {} }, d), P ? b(o, { ...i, dangerouslySetInnerHTML: { __html: p } }, void 0) : b(o, i, p);
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 D = t(c, f, d, R), N = typeof D == "string" ? D : String(D);
206
- return x && !N.trim() ? d ? h(it, null, d) : null : P ? b(o, { ...i, dangerouslySetInnerHTML: { __html: N } }, void 0) : b(o, i, N);
207
- }, vt = (a) => {
208
- const t = j(), n = W(), { to: e, activeStyle: r, localeRoute: w, children: y, ...g } = a, c = w || t.localeRoute, f = () => typeof e == "string" ? /^(?:https?:\/\/|\/\/|[a-zA-Z0-9-]+\.[a-zA-Z]{2,})|tel:|mailto:/.test(e) : !1, o = () => {
209
- if (f() && typeof e == "string")
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
- }, u = () => {
212
- if (f())
197
+ }, d = () => {
198
+ if (l())
213
199
  return typeof e == "string" ? e : e?.path || "/";
214
- if (c) {
215
- const m = c(e);
216
- return typeof m == "string" ? m : m.path || "/";
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 l = n.resolvePath(e, t.locale);
221
- return typeof l == "string" ? l : l.path || "/";
206
+ const c = n.resolvePath(e, t.locale);
207
+ return typeof c == "string" ? c : c.path || "/";
222
208
  }, P = (() => {
223
- if (f() || !n)
209
+ if (l() || !n)
224
210
  return !1;
225
- const l = n.getCurrentPath(), m = u(), C = l.replace(/\/$/, ""), i = m.replace(/\/$/, "");
211
+ const c = n.getCurrentPath(), g = d(), C = c.replace(/\/$/, ""), i = g.replace(/\/$/, "");
226
212
  return !!(C === i || C.startsWith(i + "/"));
227
- })() ? r || {} : {}, x = u(), I = (l) => {
228
- a.onClick && a.onClick(l), !l.defaultPrevented && !l.button && !l.metaKey && !l.ctrlKey && n && !f() && (l.preventDefault(), n.push({ path: x }));
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 (f())
216
+ if (l())
231
217
  return h(
232
218
  "a",
233
219
  {
234
- ...g,
235
- href: o(),
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 l = n.linkComponent;
244
- if (typeof l == "string")
229
+ const c = n.linkComponent;
230
+ if (typeof c == "string")
245
231
  return h(
246
- l,
232
+ c,
247
233
  {
248
- ...g,
234
+ ...m,
249
235
  href: x,
250
236
  style: P
251
237
  },
252
238
  y
253
239
  );
254
- const m = l, C = {
255
- ...g,
240
+ const g = c, C = {
241
+ ...m,
256
242
  href: x,
257
243
  style: P
258
244
  };
259
245
  return h(
260
- m,
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
- ...g,
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: r,
266
+ switchLocale: o,
281
267
  localeRoute: w,
282
268
  customLabels: y = {},
283
- customWrapperStyle: g,
284
- customButtonStyle: c,
285
- customDropdownStyle: f,
286
- customItemStyle: o,
287
- customLinkStyle: u,
288
- customActiveLinkStyle: d,
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(), l = K(), m = W(), C = U(), [i, R] = z(!1), b = ut(null), D = t || C || I.getLocales() || [], L = typeof n == "function" ? n() : typeof n == "string" ? n : I.locale, p = e ? e() : I.getLocaleName(), v = (s) => {
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 = D.find((k) => k.code === L);
295
- return s ? _(s) : p || L;
280
+ const s = T.find((k) => k.code === v);
281
+ return s ? _(s) : p || v;
296
282
  }, B = (s) => {
297
- if (R(!1), r) {
298
- r(s);
283
+ if (R(!1), o) {
284
+ o(s);
299
285
  return;
300
286
  }
301
- if (l.locale = s, !m)
287
+ if (c.locale = s, !g)
302
288
  return;
303
- const k = m.getCurrentPath(), T = a.localeRoute ? (() => {
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
- })() : m?.resolvePath ? (() => {
307
- const S = m.resolvePath(k, s);
292
+ })() : g?.resolvePath ? (() => {
293
+ const S = g.resolvePath(k, s);
308
294
  return typeof S == "string" ? S : S.path || "/";
309
295
  })() : k;
310
- m.push({ path: T });
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
- M(() => {
343
+ z(() => {
358
344
  if (!i) return;
359
345
  const s = (k) => {
360
346
  if (!i) return;
361
- const T = k.target;
362
- if (!T || !b.current) return;
363
- const S = b.current.contains(T), ct = T.closest(".i18n-switcher-button") !== null;
364
- !S && !ct && R(!1);
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, ...g }, nt = { ...Z, ...c }, rt = { ...G, ...f }, ot = { ...J, ...o }, st = {
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 = D.map((s) => {
375
- const k = s.code === L, T = {
360
+ }, at = T.map((s) => {
361
+ const k = s.code === v, D = {
376
362
  ...Q,
377
363
  ...k ? X : {},
378
- ...u,
379
- ...k ? d : {},
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: ot
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: T,
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(), v(s);
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: rt
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, ...r } = a, { t: w, getRoute: y } = j(), g = (o, u) => {
439
- const d = w(`${t}.${o}`, u, void 0, y());
440
- return typeof d == "string" ? d : String(d);
441
- }, c = ["i18n-group", n].filter(Boolean).join(" "), f = typeof e == "function" ? e({ prefix: t, t: g }) : e;
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
- { ...r, className: c },
445
- f
430
+ { ...o, className: u },
431
+ l
446
432
  );
447
433
  };
448
434
  function pt(a, t) {
449
- const n = a.map((r) => r.code), e = (r, w) => {
450
- const g = (typeof r == "string" ? r : r.path || "/").split("/").filter(Boolean);
451
- g.length > 0 && n.includes(g[0]) && g.shift();
452
- const c = "/" + g.join("/");
453
- return w === t ? c : `/${w}${c === "/" ? "" : c}`;
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: (r) => {
460
- typeof window < "u" && (window.history.pushState({}, "", r.path), window.dispatchEvent(new Event("popstate")));
445
+ push: (o) => {
446
+ typeof window < "u" && (window.history.pushState({}, "", o.path), window.dispatchEvent(new Event("popstate")));
461
447
  },
462
- replace: (r) => {
463
- typeof window < "u" && (window.history.replaceState({}, "", r.path), window.dispatchEvent(new Event("popstate")));
448
+ replace: (o) => {
449
+ typeof window < "u" && (window.history.replaceState({}, "", o.path), window.dispatchEvent(new Event("popstate")));
464
450
  },
465
- resolvePath: (r, w) => e(r, w),
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
- vt as I18nLink,
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
- Lt as I18nT,
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
- W as useI18nRouter
483
+ M as useI18nRouter
498
484
  };
499
485
  //# sourceMappingURL=index.mjs.map
@@ -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.0.0",
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.28",
23
- "@i18n-micro/types": "1.0.16"
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.2.7",
39
+ "vite": "^7.3.1",
40
40
  "vite-plugin-dts": "^4.5.4"
41
41
  },
42
42
  "scripts": {