@i18n-micro/preact 1.0.0 → 1.1.1

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 A=require("@i18n-micro/core"),c=require("preact"),R=require("preact/hooks"),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),G=()=>R.useContext(z),H=()=>R.useContext(q);function it({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=H(),e=V(),r=G(),[,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)}},ut=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)},dt=a=>{const t=N(),n=H(),{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)},ft=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=H(),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)},pt=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(),10);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),$=typeof E=="string"?E:String(E);return x&&!$.trim()?p?c.h(c.Fragment,null,p):null:P?b(o,{...u,dangerouslySetInnerHTML:{__html:$}},void 0):b(o,u,$)};class K extends A.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 ht(a){return new K(a)}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:()=>A.FormatService});Object.defineProperty(exports,"defaultPlural",{enumerable:!0,get:()=>A.defaultPlural});Object.defineProperty(exports,"interpolate",{enumerable:!0,get:()=>A.interpolate});exports.I18nContext=M;exports.I18nDefaultLocaleContext=z;exports.I18nGroup=ut;exports.I18nLink=dt;exports.I18nLocalesContext=W;exports.I18nProvider=it;exports.I18nRouterContext=q;exports.I18nSwitcher=ft;exports.I18nT=pt;exports.PreactI18n=K;exports.createBrowserHistoryAdapter=U;exports.createI18n=ht;exports.createPreactRouterAdapter=gt;exports.useI18n=N;exports.useI18nContext=F;exports.useI18nDefaultLocale=G;exports.useI18nLocales=V;exports.useI18nRouter=H;
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/injection.ts","../src/context.tsx","../src/components/I18nGroup.tsx","../src/components/I18nLink.tsx","../src/components/I18nSwitcher.tsx","../src/components/I18nT.tsx","../src/i18n.ts","../src/router/adapter.tsx"],"sourcesContent":["import type { Locale } from '@i18n-micro/types'\nimport { createContext } from 'preact'\nimport { useContext } from 'preact/hooks'\nimport type { PreactI18n } from './i18n'\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 type { CleanTranslation, Locale, Params, TranslationKey, Translations } from '@i18n-micro/types'\nimport type { ComponentChildren } from 'preact'\nimport { h } from 'preact'\nimport { useEffect, useState } from 'preact/hooks'\nimport type { PreactI18n } from './i18n'\nimport {\n I18nContext,\n I18nDefaultLocaleContext,\n I18nLocalesContext,\n I18nRouterContext,\n useI18nContext,\n useI18nDefaultLocale,\n useI18nLocales,\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 ? h(I18nRouterContext.Provider, { value: routingStrategy }, children) : 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 type { TranslationKey } from '@i18n-micro/types'\nimport type { ComponentChildren, JSX } from 'preact'\nimport { h } from 'preact'\nimport { useI18n } from '../context'\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' ? children({ prefix, t: translate }) : children\n\n return h('div', { ...restProps, className }, childrenContent) as JSX.Element\n}\n","import type { JSX } from 'preact'\nimport { h } 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(Component, componentProps, children) 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 type { Locale } from '@i18n-micro/types'\nimport type { JSX } from 'preact'\nimport { h } from 'preact'\nimport { useEffect, useRef, useState } from 'preact/hooks'\nimport { useI18n } from '../context'\nimport { useI18nContext, useI18nLocales, useI18nRouter } from '../injection'\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 type { PluralFunc, TranslationKey } from '@i18n-micro/types'\nimport type { JSX } from 'preact'\nimport { Fragment, h } from 'preact'\nimport { useI18n } from '../context'\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 = (elementTag: keyof JSX.IntrinsicElements, elementProps: JSX.HTMLAttributes<HTMLElement>, children?: string): 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(), 10)\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 } 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 { BaseI18n, type TranslationStorage } from '@i18n-micro/core'\nimport type { PluralFunc, Translations } 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(locale: string, routeName: string, translations: Translations, merge = true): 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 type { Locale } from '@i18n-micro/types'\nimport type { I18nRoutingStrategy } from './types'\n\n/**\n * Создает адаптер для работы с History API (универсальный для Pure Preact)\n * Работает с любым роутером, который использует History API (wouter, preact-router, и т.д.)\n */\nexport function createBrowserHistoryAdapter(locales: Locale[], defaultLocale: string): 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":["I18nContext","createContext","I18nLocalesContext","I18nDefaultLocaleContext","I18nRouterContext","useI18nContext","context","useContext","useI18nLocales","useI18nDefaultLocale","useI18nRouter","I18nProvider","i18n","locales","defaultLocale","routingStrategy","children","h","useI18n","options","router","injectedLocales","injectedDefaultLocale","forceUpdate","useState","useEffect","n","resolveLocalePath","to","localeCode","switchLocaleHelper","newLocale","currentPath","newPath","locale","l","res","I18nGroup","props","prefix","groupClass","restProps","t","getRoute","translate","key","params","result","className","childrenContent","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","I18nT","tc","tn","td","tdr","keypath","tag","plural","defaultValue","html","hideIfEmpty","customPluralRule","number","date","relativeDate","route","createElement","elementTag","elementProps","numberValue","formattedNumber","translation","content","formattedDate","formattedRelativeDate","count","k","p","dv","tResult","Fragment","PreactI18n","BaseI18n","storage","lang","msgs","listener","val","routeName","translations","merge","createI18n","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,93 +1,14 @@
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
- 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 {
6
- _locale;
7
- _fallbackLocale;
8
- _currentRoute = "general";
9
- listeners = /* @__PURE__ */ new Set();
10
- revision = 0;
11
- // Cache для Core (plain objects, не реактивные)
12
- cache;
13
- constructor(t) {
14
- const n = {
15
- generalLocaleCache: {},
16
- routeLocaleCache: {},
17
- dynamicTranslationsCaches: [],
18
- serverTranslationCache: {}
19
- };
20
- if (super({
21
- cache: n,
22
- plural: t.plural,
23
- missingWarn: t.missingWarn,
24
- 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);
28
- }
29
- // Для useSyncExternalStore
30
- subscribe = (t) => (this.listeners.add(t), () => {
31
- this.listeners.delete(t);
32
- });
33
- getSnapshot = () => `${this._locale}:${this._currentRoute}:${this.revision}`;
34
- notify() {
35
- this.revision++, this.listeners.forEach((t) => {
36
- t();
37
- });
38
- }
39
- // Геттер/Сеттер для локали
40
- get locale() {
41
- return this._locale;
42
- }
43
- set locale(t) {
44
- this._locale !== t && (this._locale = t, this.notify());
45
- }
46
- // Геттер/Сеттер для fallback локали
47
- get fallbackLocale() {
48
- return this._fallbackLocale;
49
- }
50
- set fallbackLocale(t) {
51
- this._fallbackLocale = t;
52
- }
53
- // Геттер/Сеттер для текущего роута
54
- get currentRoute() {
55
- return this._currentRoute;
56
- }
57
- setRoute(t) {
58
- this._currentRoute !== t && (this._currentRoute = t, this.notify());
59
- }
60
- // --- Implementation of abstract methods ---
61
- getLocale() {
62
- return this._locale;
63
- }
64
- getFallbackLocale() {
65
- return this._fallbackLocale;
66
- }
67
- getRoute() {
68
- return this._currentRoute;
69
- }
70
- // Translation management (uses protected methods from base class)
71
- addTranslations(t, n, e = !0) {
72
- super.loadTranslationsCore(t, n, e), this.notify();
73
- }
74
- addRouteTranslations(t, n, e, r = !0) {
75
- super.loadRouteTranslationsCore(t, n, e, r), this.notify();
76
- }
77
- clearCache() {
78
- super.clearCache(), this.notify();
79
- }
80
- }
81
- function yt(a) {
82
- return new dt(a);
83
- }
84
- const O = H(null), F = H(null), V = H(null), q = H(null), K = () => {
85
- const a = $(O);
3
+ import { createContext as $, h, Fragment as it } from "preact";
4
+ import { useContext as H, useState as W, useEffect as z, useRef as ut } from "preact/hooks";
5
+ const O = $(null), F = $(null), V = $(null), q = $(null), K = () => {
6
+ const a = H(O);
86
7
  if (!a)
87
8
  throw new Error("[i18n-micro] I18nContext not found. Make sure I18nProvider is used.");
88
9
  return a;
89
- }, U = () => $(F), ft = () => $(V), W = () => $(q);
90
- function bt({ i18n: a, locales: t, defaultLocale: n, routingStrategy: e, children: r }) {
10
+ }, U = () => H(F), dt = () => H(V), M = () => H(q);
11
+ function yt({ i18n: a, locales: t, defaultLocale: n, routingStrategy: e, children: o }) {
91
12
  return h(
92
13
  O.Provider,
93
14
  { value: a },
@@ -97,24 +18,20 @@ function bt({ i18n: a, locales: t, defaultLocale: n, routingStrategy: e, childre
97
18
  n ? h(
98
19
  V.Provider,
99
20
  { value: n },
100
- e ? h(
101
- q.Provider,
102
- { value: e },
103
- r
104
- ) : r
105
- ) : r
106
- ) : r
21
+ e ? h(q.Provider, { value: e }, o) : o
22
+ ) : o
23
+ ) : o
107
24
  );
108
25
  }
109
26
  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);
27
+ const t = K(), n = M(), e = U(), o = dt(), [, w] = W(0);
28
+ z(() => t.subscribe(() => {
29
+ w((d) => d + 1);
113
30
  }), [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 || "/" });
31
+ 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) => {
32
+ if (t.locale = r, n) {
33
+ const d = n.getCurrentPath(), f = u(d, r);
34
+ n.push(typeof f == "string" ? { path: f } : { path: f.path || "/" });
118
35
  }
119
36
  };
120
37
  return {
@@ -136,103 +53,62 @@ const j = (a) => {
136
53
  get currentRoute() {
137
54
  return t.currentRoute;
138
55
  },
139
- setLocale: (o) => {
140
- t.locale = o;
56
+ setLocale: (r) => {
57
+ t.locale = r;
141
58
  },
142
59
  // Route management
143
60
  setRoute: t.setRoute.bind(t),
144
61
  getRoute: t.getRoute.bind(t),
145
62
  getLocales: () => y,
146
- defaultLocale: () => g,
147
- getLocaleName: () => y.find((u) => u.code === t.locale)?.displayName || null,
63
+ defaultLocale: () => m,
64
+ getLocaleName: () => y.find((d) => d.code === t.locale)?.displayName || null,
148
65
  // 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 || "/";
66
+ switchLocale: l,
67
+ localeRoute: u,
68
+ localePath: (r, d) => {
69
+ const f = u(r, d);
70
+ return typeof f == "string" ? f : f.path || "/";
154
71
  },
155
72
  // Translation management
156
73
  addTranslations: t.addTranslations.bind(t),
157
74
  addRouteTranslations: t.addRouteTranslations.bind(t),
158
75
  clearCache: t.clearCache.bind(t)
159
76
  };
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,
167
- html: P = !1,
168
- hideIfEmpty: x = !1,
169
- customPluralRule: I,
170
- number: l,
171
- date: m,
172
- relativeDate: C,
173
- ...i
174
- } = a, R = g(), b = (L, p, v) => h(
175
- L,
176
- p,
177
- v
178
- );
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, _);
182
- }
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);
186
- }
187
- 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);
190
- }
191
- if (u !== void 0) {
192
- const L = Number.parseInt(u.toString());
193
- let p;
194
- return I ? p = I(
195
- c,
196
- L,
197
- f || {},
198
- y,
199
- (_, A, B) => {
200
- const E = t(_, A, B, R);
201
- return typeof E == "string" ? E : String(E);
202
- }
203
- ) || "" : p = n(c, { count: L, ...f || {} }, d), P ? b(o, { ...i, dangerouslySetInnerHTML: { __html: p } }, void 0) : b(o, i, p);
204
- }
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);
77
+ }, bt = (a) => {
78
+ const { prefix: t, groupClass: n, children: e, ...o } = a, { t: w, getRoute: y } = j(), m = (r, d) => {
79
+ const f = w(`${t}.${r}`, d, void 0, y());
80
+ return typeof f == "string" ? f : String(f);
81
+ }, u = ["i18n-group", n].filter(Boolean).join(" "), l = typeof e == "function" ? e({ prefix: t, t: m }) : e;
82
+ return h("div", { ...o, className: u }, l);
207
83
  }, 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")
84
+ 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 = () => {
85
+ if (l() && typeof e == "string")
210
86
  return /^https?:\/\//.test(e) ? e : `https://${e}`;
211
- }, u = () => {
212
- if (f())
87
+ }, d = () => {
88
+ if (l())
213
89
  return typeof e == "string" ? e : e?.path || "/";
214
- if (c) {
215
- const m = c(e);
216
- return typeof m == "string" ? m : m.path || "/";
90
+ if (u) {
91
+ const g = u(e);
92
+ return typeof g == "string" ? g : g.path || "/";
217
93
  }
218
94
  if (!n?.resolvePath)
219
95
  return typeof e == "string" ? e : e.path || "/";
220
- const l = n.resolvePath(e, t.locale);
221
- return typeof l == "string" ? l : l.path || "/";
96
+ const c = n.resolvePath(e, t.locale);
97
+ return typeof c == "string" ? c : c.path || "/";
222
98
  }, P = (() => {
223
- if (f() || !n)
99
+ if (l() || !n)
224
100
  return !1;
225
- const l = n.getCurrentPath(), m = u(), C = l.replace(/\/$/, ""), i = m.replace(/\/$/, "");
226
- 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 }));
101
+ const c = n.getCurrentPath(), g = d(), C = c.replace(/\/$/, ""), i = g.replace(/\/$/, "");
102
+ return !!(C === i || C.startsWith(`${i}/`));
103
+ })() ? o || {} : {}, x = d(), I = (c) => {
104
+ a.onClick && a.onClick(c), !c.defaultPrevented && !c.button && !c.metaKey && !c.ctrlKey && n && !l() && (c.preventDefault(), n.push({ path: x }));
229
105
  };
230
- if (f())
106
+ if (l())
231
107
  return h(
232
108
  "a",
233
109
  {
234
- ...g,
235
- href: o(),
110
+ ...m,
111
+ href: r(),
236
112
  style: P,
237
113
  target: "_blank",
238
114
  rel: "noopener noreferrer"
@@ -240,74 +116,70 @@ const j = (a) => {
240
116
  y
241
117
  );
242
118
  if (n?.linkComponent) {
243
- const l = n.linkComponent;
244
- if (typeof l == "string")
119
+ const c = n.linkComponent;
120
+ if (typeof c == "string")
245
121
  return h(
246
- l,
122
+ c,
247
123
  {
248
- ...g,
124
+ ...m,
249
125
  href: x,
250
126
  style: P
251
127
  },
252
128
  y
253
129
  );
254
- const m = l, C = {
255
- ...g,
130
+ const g = c, C = {
131
+ ...m,
256
132
  href: x,
257
133
  style: P
258
134
  };
259
- return h(
260
- m,
261
- C,
262
- y
263
- );
135
+ return h(g, C, y);
264
136
  }
265
137
  return h(
266
138
  "a",
267
139
  {
268
- ...g,
140
+ ...m,
269
141
  href: x,
270
142
  style: P,
271
143
  onClick: I
272
144
  },
273
145
  y
274
146
  );
275
- }, wt = (a) => {
147
+ }, Lt = (a) => {
276
148
  const {
277
149
  locales: t,
278
150
  currentLocale: n,
279
151
  getLocaleName: e,
280
- switchLocale: r,
152
+ switchLocale: o,
281
153
  localeRoute: w,
282
154
  customLabels: y = {},
283
- customWrapperStyle: g,
284
- customButtonStyle: c,
285
- customDropdownStyle: f,
286
- customItemStyle: o,
287
- customLinkStyle: u,
288
- customActiveLinkStyle: d,
155
+ customWrapperStyle: m,
156
+ customButtonStyle: u,
157
+ customDropdownStyle: l,
158
+ customItemStyle: r,
159
+ customLinkStyle: d,
160
+ customActiveLinkStyle: f,
289
161
  customIconStyle: P,
290
162
  ...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) => {
163
+ } = 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
164
  s && (s.stopPropagation(), s.preventDefault()), R(!i);
293
165
  }, _ = (s) => y[s.code] || s.displayName || s.code, A = () => {
294
- const s = D.find((k) => k.code === L);
295
- return s ? _(s) : p || L;
166
+ const s = T.find((k) => k.code === v);
167
+ return s ? _(s) : p || v;
296
168
  }, B = (s) => {
297
- if (R(!1), r) {
298
- r(s);
169
+ if (R(!1), o) {
170
+ o(s);
299
171
  return;
300
172
  }
301
- if (l.locale = s, !m)
173
+ if (c.locale = s, !g)
302
174
  return;
303
- const k = m.getCurrentPath(), T = a.localeRoute ? (() => {
175
+ const k = g.getCurrentPath(), D = a.localeRoute ? (() => {
304
176
  const S = a.localeRoute(k, s);
305
177
  return typeof S == "string" ? S : S.path || "/";
306
- })() : m?.resolvePath ? (() => {
307
- const S = m.resolvePath(k, s);
178
+ })() : g?.resolvePath ? (() => {
179
+ const S = g.resolvePath(k, s);
308
180
  return typeof S == "string" ? S : S.path || "/";
309
181
  })() : k;
310
- m.push({ path: T });
182
+ g.push({ path: D });
311
183
  }, E = {
312
184
  position: "relative",
313
185
  display: "inline-block",
@@ -354,29 +226,29 @@ const j = (a) => {
354
226
  }, tt = {
355
227
  transform: "rotate(180deg)"
356
228
  };
357
- M(() => {
229
+ z(() => {
358
230
  if (!i) return;
359
231
  const s = (k) => {
360
232
  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);
233
+ const D = k.target;
234
+ if (!D || !b.current) return;
235
+ const S = b.current.contains(D), lt = D.closest(".i18n-switcher-button") !== null;
236
+ !S && !lt && R(!1);
365
237
  };
366
238
  return document.addEventListener("click", s), () => {
367
239
  document.removeEventListener("click", s);
368
240
  };
369
241
  }, [i]);
370
- const et = { ...E, ...g }, nt = { ...Z, ...c }, rt = { ...G, ...f }, ot = { ...J, ...o }, st = {
242
+ const et = { ...E, ...m }, nt = { ...Z, ...u }, ot = { ...G, ...l }, rt = { ...J, ...r }, st = {
371
243
  ...Y,
372
244
  ...i ? tt : {},
373
245
  ...P
374
- }, at = D.map((s) => {
375
- const k = s.code === L, T = {
246
+ }, at = T.map((s) => {
247
+ const k = s.code === v, D = {
376
248
  ...Q,
377
249
  ...k ? X : {},
378
- ...u,
379
- ...k ? d : {},
250
+ ...d,
251
+ ...k ? f : {},
380
252
  width: "100%",
381
253
  textAlign: "left",
382
254
  border: "none",
@@ -386,14 +258,14 @@ const j = (a) => {
386
258
  "li",
387
259
  {
388
260
  key: s.code,
389
- style: ot
261
+ style: rt
390
262
  },
391
263
  h(
392
264
  "button",
393
265
  {
394
266
  type: "button",
395
267
  className: `switcher-locale-${s.code}`,
396
- style: T,
268
+ style: D,
397
269
  onClick: (S) => {
398
270
  S.preventDefault(), S.stopPropagation(), B(s.code);
399
271
  }
@@ -417,7 +289,7 @@ const j = (a) => {
417
289
  className: "i18n-switcher-button",
418
290
  style: nt,
419
291
  onClick: (s) => {
420
- s.preventDefault(), s.stopPropagation(), v(s);
292
+ s.preventDefault(), s.stopPropagation(), L(s);
421
293
  },
422
294
  ariaHaspopup: "true",
423
295
  ariaExpanded: i
@@ -429,40 +301,142 @@ const j = (a) => {
429
301
  "ul",
430
302
  {
431
303
  className: "i18n-switcher-dropdown",
432
- style: rt
304
+ style: ot
433
305
  },
434
306
  ...at
435
307
  ) : null
436
308
  );
437
- }, 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;
442
- return h(
443
- "div",
444
- { ...r, className: c },
445
- f
309
+ }, wt = (a) => {
310
+ const { t, tc: n, tn: e, td: o, tdr: w, locale: y, getRoute: m } = j(), {
311
+ keypath: u,
312
+ params: l,
313
+ tag: r = "span",
314
+ plural: d,
315
+ defaultValue: f,
316
+ html: P = !1,
317
+ hideIfEmpty: x = !1,
318
+ customPluralRule: I,
319
+ number: c,
320
+ date: g,
321
+ relativeDate: C,
322
+ ...i
323
+ } = a, R = m(), b = (v, p, L) => h(
324
+ v,
325
+ p,
326
+ L
446
327
  );
328
+ if (c !== void 0) {
329
+ const v = Number(c), p = e(v), L = t(u, { number: p, ...l || {} }, void 0, R), _ = typeof L == "string" ? L : String(L);
330
+ return P ? b(r, { ...i, dangerouslySetInnerHTML: { __html: _ } }, void 0) : b(r, i, _);
331
+ }
332
+ if (g !== void 0) {
333
+ const v = o(g), p = t(u, { date: v, ...l || {} }, void 0, R), L = typeof p == "string" ? p : String(p);
334
+ return P ? b(r, { ...i, dangerouslySetInnerHTML: { __html: L } }, void 0) : b(r, i, L);
335
+ }
336
+ if (C !== void 0) {
337
+ const v = w(C), p = t(u, { relativeDate: v, ...l || {} }, void 0, R), L = typeof p == "string" ? p : String(p);
338
+ return P ? b(r, { ...i, dangerouslySetInnerHTML: { __html: L } }, void 0) : b(r, i, L);
339
+ }
340
+ if (d !== void 0) {
341
+ const v = Number.parseInt(d.toString(), 10);
342
+ let p;
343
+ return I ? p = I(
344
+ u,
345
+ v,
346
+ l || {},
347
+ y,
348
+ (_, A, B) => {
349
+ const E = t(_, A, B, R);
350
+ return typeof E == "string" ? E : String(E);
351
+ }
352
+ ) || "" : p = n(u, { count: v, ...l || {} }, f), P ? b(r, { ...i, dangerouslySetInnerHTML: { __html: p } }, void 0) : b(r, i, p);
353
+ }
354
+ const T = t(u, l, f, R), N = typeof T == "string" ? T : String(T);
355
+ return x && !N.trim() ? f ? h(it, null, f) : null : P ? b(r, { ...i, dangerouslySetInnerHTML: { __html: N } }, void 0) : b(r, i, N);
447
356
  };
357
+ class ft extends ct {
358
+ _locale;
359
+ _fallbackLocale;
360
+ _currentRoute = "general";
361
+ listeners = /* @__PURE__ */ new Set();
362
+ revision = 0;
363
+ storage;
364
+ constructor(t) {
365
+ const n = {
366
+ translations: /* @__PURE__ */ new Map()
367
+ };
368
+ if (super({
369
+ storage: n,
370
+ plural: t.plural,
371
+ missingWarn: t.missingWarn,
372
+ missingHandler: t.missingHandler
373
+ }), this.storage = n, this._locale = t.locale, this._fallbackLocale = t.fallbackLocale || t.locale, t.messages)
374
+ for (const [e, o] of Object.entries(t.messages))
375
+ this.helper.loadTranslations(e, o);
376
+ }
377
+ subscribe = (t) => (this.listeners.add(t), () => this.listeners.delete(t));
378
+ getSnapshot = () => `${this._locale}:${this._currentRoute}:${this.revision}`;
379
+ notify() {
380
+ this.revision++, this.listeners.forEach((t) => t());
381
+ }
382
+ get locale() {
383
+ return this._locale;
384
+ }
385
+ set locale(t) {
386
+ this._locale !== t && (this._locale = t, this.notify());
387
+ }
388
+ get fallbackLocale() {
389
+ return this._fallbackLocale;
390
+ }
391
+ set fallbackLocale(t) {
392
+ this._fallbackLocale = t;
393
+ }
394
+ get currentRoute() {
395
+ return this._currentRoute;
396
+ }
397
+ setRoute(t) {
398
+ this._currentRoute !== t && (this._currentRoute = t, this.notify());
399
+ }
400
+ getLocale() {
401
+ return this._locale;
402
+ }
403
+ getFallbackLocale() {
404
+ return this._fallbackLocale;
405
+ }
406
+ getRoute() {
407
+ return this._currentRoute;
408
+ }
409
+ addTranslations(t, n, e = !0) {
410
+ super.loadTranslationsCore(t, n, e), this.notify();
411
+ }
412
+ addRouteTranslations(t, n, e, o = !0) {
413
+ super.loadRouteTranslationsCore(t, n, e, o), this.notify();
414
+ }
415
+ clearCache() {
416
+ super.clearCache(), this.notify();
417
+ }
418
+ }
419
+ function Pt(a) {
420
+ return new ft(a);
421
+ }
448
422
  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}`;
423
+ const n = a.map((o) => o.code), e = (o, w) => {
424
+ const m = (typeof o == "string" ? o : o.path || "/").split("/").filter(Boolean), u = m[0];
425
+ u !== void 0 && n.includes(u) && m.shift();
426
+ const l = `/${m.join("/")}`;
427
+ return w === t ? l : `/${w}${l === "/" ? "" : l}`;
454
428
  };
455
429
  return {
456
430
  // Просто рендерим <a>, навигацию перехватит onClick в I18nLink
457
431
  linkComponent: void 0,
458
432
  getCurrentPath: () => typeof window < "u" ? window.location.pathname : "/",
459
- push: (r) => {
460
- typeof window < "u" && (window.history.pushState({}, "", r.path), window.dispatchEvent(new Event("popstate")));
433
+ push: (o) => {
434
+ typeof window < "u" && (window.history.pushState({}, "", o.path), window.dispatchEvent(new Event("popstate")));
461
435
  },
462
- replace: (r) => {
463
- typeof window < "u" && (window.history.replaceState({}, "", r.path), window.dispatchEvent(new Event("popstate")));
436
+ replace: (o) => {
437
+ typeof window < "u" && (window.history.replaceState({}, "", o.path), window.dispatchEvent(new Event("popstate")));
464
438
  },
465
- resolvePath: (r, w) => e(r, w),
439
+ resolvePath: (o, w) => e(o, w),
466
440
  getRoute: () => typeof window < "u" ? {
467
441
  fullPath: window.location.pathname + window.location.search,
468
442
  query: Object.fromEntries(new URLSearchParams(window.location.search))
@@ -477,23 +451,23 @@ export {
477
451
  Rt as FormatService,
478
452
  O as I18nContext,
479
453
  V as I18nDefaultLocaleContext,
480
- Pt as I18nGroup,
454
+ bt as I18nGroup,
481
455
  vt as I18nLink,
482
456
  F as I18nLocalesContext,
483
- bt as I18nProvider,
457
+ yt as I18nProvider,
484
458
  q as I18nRouterContext,
485
- wt as I18nSwitcher,
486
- Lt as I18nT,
487
- dt as PreactI18n,
459
+ Lt as I18nSwitcher,
460
+ wt as I18nT,
461
+ ft as PreactI18n,
488
462
  pt as createBrowserHistoryAdapter,
489
- yt as createI18n,
463
+ Pt as createI18n,
490
464
  St as createPreactRouterAdapter,
491
465
  xt as defaultPlural,
492
466
  It as interpolate,
493
467
  j as useI18n,
494
468
  K as useI18nContext,
495
- ft as useI18nDefaultLocale,
469
+ dt as useI18nDefaultLocale,
496
470
  U as useI18nLocales,
497
- W as useI18nRouter
471
+ M as useI18nRouter
498
472
  };
499
473
  //# 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/injection.ts","../src/context.tsx","../src/components/I18nGroup.tsx","../src/components/I18nLink.tsx","../src/components/I18nSwitcher.tsx","../src/components/I18nT.tsx","../src/i18n.ts","../src/router/adapter.tsx"],"sourcesContent":["import type { Locale } from '@i18n-micro/types'\nimport { createContext } from 'preact'\nimport { useContext } from 'preact/hooks'\nimport type { PreactI18n } from './i18n'\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 type { CleanTranslation, Locale, Params, TranslationKey, Translations } from '@i18n-micro/types'\nimport type { ComponentChildren } from 'preact'\nimport { h } from 'preact'\nimport { useEffect, useState } from 'preact/hooks'\nimport type { PreactI18n } from './i18n'\nimport {\n I18nContext,\n I18nDefaultLocaleContext,\n I18nLocalesContext,\n I18nRouterContext,\n useI18nContext,\n useI18nDefaultLocale,\n useI18nLocales,\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 ? h(I18nRouterContext.Provider, { value: routingStrategy }, children) : 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 type { TranslationKey } from '@i18n-micro/types'\nimport type { ComponentChildren, JSX } from 'preact'\nimport { h } from 'preact'\nimport { useI18n } from '../context'\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' ? children({ prefix, t: translate }) : children\n\n return h('div', { ...restProps, className }, childrenContent) as JSX.Element\n}\n","import type { JSX } from 'preact'\nimport { h } 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(Component, componentProps, children) 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 type { Locale } from '@i18n-micro/types'\nimport type { JSX } from 'preact'\nimport { h } from 'preact'\nimport { useEffect, useRef, useState } from 'preact/hooks'\nimport { useI18n } from '../context'\nimport { useI18nContext, useI18nLocales, useI18nRouter } from '../injection'\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 type { PluralFunc, TranslationKey } from '@i18n-micro/types'\nimport type { JSX } from 'preact'\nimport { Fragment, h } from 'preact'\nimport { useI18n } from '../context'\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 = (elementTag: keyof JSX.IntrinsicElements, elementProps: JSX.HTMLAttributes<HTMLElement>, children?: string): 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(), 10)\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 } 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 { BaseI18n, type TranslationStorage } from '@i18n-micro/core'\nimport type { PluralFunc, Translations } 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(locale: string, routeName: string, translations: Translations, merge = true): 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 type { Locale } from '@i18n-micro/types'\nimport type { I18nRoutingStrategy } from './types'\n\n/**\n * Создает адаптер для работы с History API (универсальный для Pure Preact)\n * Работает с любым роутером, который использует History API (wouter, preact-router, и т.д.)\n */\nexport function createBrowserHistoryAdapter(locales: Locale[], defaultLocale: string): 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":["I18nContext","createContext","I18nLocalesContext","I18nDefaultLocaleContext","I18nRouterContext","useI18nContext","context","useContext","useI18nLocales","useI18nDefaultLocale","useI18nRouter","I18nProvider","i18n","locales","defaultLocale","routingStrategy","children","useI18n","options","router","injectedLocales","injectedDefaultLocale","forceUpdate","useState","useEffect","n","resolveLocalePath","to","localeCode","switchLocaleHelper","newLocale","currentPath","newPath","locale","l","res","I18nGroup","props","prefix","groupClass","restProps","t","getRoute","translate","key","params","result","className","childrenContent","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","I18nT","tc","tn","td","tdr","keypath","tag","plural","defaultValue","html","hideIfEmpty","customPluralRule","number","date","relativeDate","route","createElement","elementTag","elementProps","numberValue","formattedNumber","translation","content","formattedDate","formattedRelativeDate","count","k","p","dv","tResult","Fragment","PreactI18n","BaseI18n","storage","lang","msgs","listener","val","routeName","translations","merge","createI18n","createBrowserHistoryAdapter","localeCodes","loc","resolvePath","pathSegments","first","cleanPath","createPreactRouterAdapter"],"mappings":";;;;AAOO,MAAMA,IAAcC,EAAiC,IAAI,GACnDC,IAAqBD,EAA+B,IAAI,GACxDE,IAA2BF,EAA6B,IAAI,GAC5DG,IAAoBH,EAA0C,IAAI,GAGlEI,IAAiB,MAAM;AAClC,QAAMC,IAAUC,EAAWP,CAAW;AACtC,MAAI,CAACM;AACH,UAAM,IAAI,MAAM,qEAAqE;AAEvF,SAAOA;AACT,GAEaE,IAAiB,MACrBD,EAAWL,CAAkB,GAGzBO,KAAuB,MAC3BF,EAAWJ,CAAwB,GAG/BO,IAAgB,MACpBH,EAAWH,CAAiB;ACL9B,SAASO,GAAa,EAAE,MAAAC,GAAM,SAAAC,GAAS,eAAAC,GAAe,iBAAAC,GAAiB,UAAAC,KAA+B;AAC3G,SAAO;AAAA,IACLhB,EAAY;AAAA,IACZ,EAAE,OAAOY,EAAA;AAAA,IACTC,IACI;AAAA,MACEX,EAAmB;AAAA,MACnB,EAAE,OAAOW,EAAA;AAAA,MACTC,IACI;AAAA,QACEX,EAAyB;AAAA,QACzB,EAAE,OAAOW,EAAA;AAAA,QACTC,IAAkB,EAAEX,EAAkB,UAAU,EAAE,OAAOW,EAAA,GAAmBC,CAAQ,IAAIA;AAAA,MAAA,IAE1FA;AAAA,IAAA,IAENA;AAAA,EAAA;AAER;AAyCO,MAAMC,IAAU,CAACC,MAA4C;AAClE,QAAMN,IAAOP,EAAA,GACPc,IAAST,EAAA,GACTU,IAAkBZ,EAAA,GAClBa,IAAwBZ,GAAA,GAIxB,GAAGa,CAAW,IAAIC,EAAS,CAAC;AAElC,EAAAC,EAAU,MAEYZ,EAAK,UAAU,MAAM;AACvC,IAAAU,EAAY,CAACG,MAAMA,IAAI,CAAC;AAAA,EAC1B,CAAC,GAEA,CAACb,CAAI,CAAC;AAGT,QAAMC,IAAUK,GAAS,WAAWE,KAAmB,CAAA,GACjDN,IAAgBI,GAAS,iBAAiBG,KAAyBT,EAAK,QAExEc,IAAoB,CAACC,GAAgCC,MACpDT,GAAQ,cAGNA,EAAO,YAAYQ,GAAIC,KAAchB,EAAK,MAAM,IAF9Ce,GAKLE,IAAqB,CAACC,MAA4B;AAEtD,QADAlB,EAAK,SAASkB,GACVX,GAAQ;AACV,YAAMY,IAAcZ,EAAO,eAAA,GACrBa,IAAUN,EAAkBK,GAAaD,CAAS;AACxD,MAAAX,EAAO,KAAK,OAAOa,KAAY,WAAW,EAAE,MAAMA,EAAA,IAAY,EAAE,MAAMA,EAAQ,QAAQ,KAAK;AAAA,IAC7F;AAAA,EACF;AAEA,SAAO;AAAA;AAAA,IAEL,GAAGpB,EAAK,EAAE,KAAKA,CAAI;AAAA,IACnB,IAAIA,EAAK,GAAG,KAAKA,CAAI;AAAA,IACrB,IAAIA,EAAK,GAAG,KAAKA,CAAI;AAAA,IACrB,IAAIA,EAAK,GAAG,KAAKA,CAAI;AAAA,IACrB,IAAIA,EAAK,GAAG,KAAKA,CAAI;AAAA,IACrB,KAAKA,EAAK,IAAI,KAAKA,CAAI;AAAA,IACvB,KAAKA,EAAK,IAAI,KAAKA,CAAI;AAAA;AAAA,IAGvB,IAAI,SAAS;AACX,aAAOA,EAAK;AAAA,IACd;AAAA,IACA,IAAI,iBAAiB;AACnB,aAAOA,EAAK;AAAA,IACd;AAAA,IACA,IAAI,eAAe;AACjB,aAAOA,EAAK;AAAA,IACd;AAAA,IACA,WAAW,CAACqB,MAAmB;AAC7B,MAAArB,EAAK,SAASqB;AAAA,IAChB;AAAA;AAAA,IAGA,UAAUrB,EAAK,SAAS,KAAKA,CAAI;AAAA,IACjC,UAAUA,EAAK,SAAS,KAAKA,CAAI;AAAA,IACjC,YAAY,MAAMC;AAAA,IAClB,eAAe,MAAMC;AAAA,IACrB,eAAe,MACGD,EAAQ,KAAK,CAACqB,MAAMA,EAAE,SAAStB,EAAK,MAAM,GAC1C,eAAe;AAAA;AAAA,IAIjC,cAAciB;AAAA,IACd,aAAaH;AAAA,IACb,YAAY,CAACC,GAAgCM,MAAoB;AAC/D,YAAME,IAAMT,EAAkBC,GAAIM,CAAM;AACxC,aAAO,OAAOE,KAAQ,WAAWA,IAAMA,EAAI,QAAQ;AAAA,IACrD;AAAA;AAAA,IAGA,iBAAiBvB,EAAK,gBAAgB,KAAKA,CAAI;AAAA,IAC/C,sBAAsBA,EAAK,qBAAqB,KAAKA,CAAI;AAAA,IACzD,YAAYA,EAAK,WAAW,KAAKA,CAAI;AAAA,EAAA;AAEzC,GC9JawB,KAAY,CAACC,MAAuC;AAC/D,QAAM,EAAE,QAAAC,GAAQ,YAAAC,GAAY,UAAAvB,GAAU,GAAGwB,MAAcH,GACjD,EAAE,GAAAI,GAAG,UAAAC,EAAA,IAAazB,EAAA,GAElB0B,IAAY,CAACC,GAAaC,MAA+D;AAC7F,UAAMC,IAASL,EAAE,GAAGH,CAAM,IAAIM,CAAG,IAAsBC,GAAQ,QAAWH,EAAA,CAAU;AACpF,WAAO,OAAOI,KAAW,WAAWA,IAAS,OAAOA,CAAM;AAAA,EAC5D,GAEMC,IAAY,CAAC,cAAcR,CAAU,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAE/DS,IAAqC,OAAOhC,KAAa,aAAaA,EAAS,EAAE,QAAAsB,GAAQ,GAAGK,EAAA,CAAW,IAAI3B;AAEjH,SAAO,EAAE,OAAO,EAAE,GAAGwB,GAAW,WAAAO,EAAA,GAAaC,CAAe;AAC9D,GCdaC,KAAW,CAACZ,MAAsC;AAC7D,QAAMzB,IAAOK,EAAA,GACPE,IAAST,EAAA,GACT,EAAE,IAAAiB,GAAI,aAAAuB,GAAa,aAAaC,GAAiB,UAAAnC,GAAU,GAAGwB,MAAcH,GAG5Ee,IAAcD,KAAmBvC,EAAK,aAEtCyC,IAAiB,MACjB,OAAO1B,KAAO,WACT,iEAAiE,KAAKA,CAAE,IAE1E,IAGH2B,IAAe,MAA0B;AAC7C,QAAID,EAAA,KAAoB,OAAO1B,KAAO;AACpC,aAAK,eAAe,KAAKA,CAAE,IAGpBA,IAFE,WAAWA,CAAE;AAAA,EAK1B,GAEM4B,IAAa,MAAc;AAC/B,QAAIF;AACF,aAAI,OAAO1B,KAAO,WACTA,IAEKA,GACA,QAAQ;AAGxB,QAAIyB,GAAa;AACf,YAAMjB,IAAMiB,EAAYzB,CAAE;AAC1B,aAAO,OAAOQ,KAAQ,WAAWA,IAAMA,EAAI,QAAQ;AAAA,IACrD;AAEA,QAAI,CAAChB,GAAQ;AACX,aAAO,OAAOQ,KAAO,WAAWA,IAAKA,EAAG,QAAQ;AAGlD,UAAMQ,IAAMhB,EAAO,YAAYQ,GAAIf,EAAK,MAAM;AAC9C,WAAO,OAAOuB,KAAQ,WAAWA,IAAMA,EAAI,QAAQ;AAAA,EACrD,GA4BMqB,KA1BW,MAAe;AAC9B,QAAIH,EAAA,KAAoB,CAAClC;AACvB,aAAO;AAGT,UAAMY,IAAcZ,EAAO,eAAA,GACrBsC,IAAWF,EAAA,GAGXG,IAAoB3B,EAAY,QAAQ,OAAO,EAAE,GACjD4B,IAAiBF,EAAS,QAAQ,OAAO,EAAE;AASjD,WANI,GAAAC,MAAsBC,KAMtBD,EAAkB,WAAW,GAAGC,CAAc,GAAG;AAAA,EAKvD,GAEuD,IAAaT,KAAe,CAAA,IAAK,CAAA,GAClFU,IAAUL,EAAA,GAEVM,IAAc,CAACC,MAAiD;AACpE,IAAIzB,EAAM,WACRA,EAAM,QAAQyB,CAAC,GAIb,CAACA,EAAE,oBAAoB,CAACA,EAAE,UAAU,CAACA,EAAE,WAAW,CAACA,EAAE,WAAW3C,KAAU,CAACkC,QAC7ES,EAAE,eAAA,GACF3C,EAAO,KAAK,EAAE,MAAMyC,EAAA,CAAS;AAAA,EAEjC;AAEA,MAAIP;AACF,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,GAAGb;AAAA,QACH,MAAMc,EAAA;AAAA,QACN,OAAOE;AAAA,QACP,QAAQ;AAAA,QACR,KAAK;AAAA,MAAA;AAAA,MAEPxC;AAAA,IAAA;AAKJ,MAAIG,GAAQ,eAAe;AACzB,UAAM4C,IAAgB5C,EAAO;AAC7B,QAAI,OAAO4C,KAAkB;AAC3B,aAAO;AAAA,QACLA;AAAA,QACA;AAAA,UACE,GAAGvB;AAAA,UACH,MAAMoB;AAAA,UACN,OAAOJ;AAAA,QAAA;AAAA,QAETxC;AAAA,MAAA;AAKJ,UAAMgD,IAAYD,GAQZE,IAAiB;AAAA,MACrB,GAAGzB;AAAA,MACH,MAAMoB;AAAA,MACN,OAAOJ;AAAA,IAAA;AAQT,WAAO,EAAEQ,GAAWC,GAAgBjD,CAAQ;AAAA,EAC9C;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,GAAGwB;AAAA,MACH,MAAMoB;AAAA,MACN,OAAOJ;AAAA,MACP,SAASK;AAAA,IAAA;AAAA,IAEX7C;AAAA,EAAA;AAEJ,GC3IakD,KAAe,CAAC7B,MAA0C;AACrE,QAAM;AAAA,IACJ,SAAS8B;AAAA,IACT,eAAeC;AAAA,IACf,eAAeC;AAAA,IACf,cAAcC;AAAA,IACd,aAAaC;AAAA,IACb,cAAAC,IAAe,CAAA;AAAA,IACf,oBAAAC;AAAA,IACA,mBAAAC;AAAA,IACA,qBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,uBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,GAAGvC;AAAA,EAAA,IACDH,GAEEzB,IAAOK,EAAA,GACP+D,IAAe3E,EAAA,GACfc,IAAST,EAAA,GACTU,IAAkBZ,EAAA,GAClB,CAACyE,GAAcC,CAAe,IAAI3D,EAAS,EAAK,GAChD4D,IAAaC,GAAuB,IAAI,GAGxCvE,IAAUsD,KAAe/C,KAAmBR,EAAK,WAAA,KAAgB,CAAA,GAajEyE,IATA,OAAOjB,KAAsB,aACxBA,EAAA,IAEL,OAAOA,KAAsB,WACxBA,IAEFxD,EAAK,QAIR0E,IAAoBjB,IAAoBA,EAAA,IAAsBzD,EAAK,cAAA,GAEnE2E,IAAiB,CAACC,MAAkB;AACxC,IAAIA,MACFA,EAAM,gBAAA,GACNA,EAAM,eAAA,IAERN,EAAgB,CAACD,CAAY;AAAA,EAC/B,GAEMQ,IAAc,CAACC,MACHlB,EAAakB,EAAW,IAAI,KAAKA,EAAW,eAC1CA,EAAW,MAGzBC,IAAqB,MAAc;AACvC,UAAMC,IAAU/E,EAAQ,KAAK,CAACqB,MAAMA,EAAE,SAASmD,CAAa;AAC5D,WAAOO,IAAUH,EAAYG,CAAO,IAAIN,KAAqBD;AAAA,EAC/D,GAEMQ,IAAqB,CAACC,MAAiB;AAE3C,QADAZ,EAAgB,EAAK,GACjBZ,GAAkB;AACpB,MAAAA,EAAiBwB,CAAI;AACrB;AAAA,IACF;AAIA,QAFAd,EAAa,SAASc,GAElB,CAAC3E;AACH;AAGF,UAAMY,IAAcZ,EAAO,eAAA,GACrBa,IAAUK,EAAM,eACjB,MAAM;AACL,YAAMF,IAAME,EAAM,YAAYN,GAAa+D,CAAI;AAC/C,aAAO,OAAO3D,KAAQ,WAAWA,IAAMA,EAAI,QAAQ;AAAA,IACrD,OACAhB,GAAQ,eACL,MAAM;AACL,YAAMgB,IAAMhB,EAAO,YAAYY,GAAa+D,CAAI;AAChD,aAAO,OAAO3D,KAAQ,WAAWA,IAAMA,EAAI,QAAQ;AAAA,IACrD,OACAJ;AAEN,IAAAZ,EAAO,KAAK,EAAE,MAAMa,EAAA,CAAS;AAAA,EAC/B,GAGM+D,IAAgD;AAAA,IACpD,UAAU;AAAA,IACV,SAAS;AAAA,IACT,eAAe;AAAA,EAAA,GAGXC,IAA+C;AAAA,IACnD,SAAS;AAAA,IACT,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,EAAA,GAGZC,IAAiD;AAAA,IACrD,UAAU;AAAA,IACV,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,WAAW;AAAA,EAAA,GAGPC,IAA6C;AAAA,IACjD,QAAQ;AAAA,IACR,SAAS;AAAA,EAAA,GAGLC,IAA6C;AAAA,IACjD,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,IACP,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,QAAQ;AAAA,EAAA,GAGJC,IAAmD;AAAA,IACvD,YAAY;AAAA,IACZ,OAAO;AAAA,EAAA,GAGHC,IAA6C;AAAA,IACjD,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,EAAA,GAGRC,KAAiD;AAAA,IACrD,WAAW;AAAA,EAAA;AAGb,EAAA9E,EAAU,MAAM;AACd,QAAI,CAACyD,EAAc;AACnB,UAAMsB,IAAU,CAACf,MAAsB;AACrC,UAAI,CAACP,EAAc;AAEnB,YAAMuB,IAAShB,EAAM;AACrB,UAAI,CAACgB,KAAU,CAACrB,EAAW,QAAS;AAEpC,YAAMsB,IAAgBtB,EAAW,QAAQ,SAASqB,CAAM,GAClDE,KAAgBF,EAAO,QAAQ,uBAAuB,MAAM;AAElE,MAAI,CAACC,KAAiB,CAACC,MACrBxB,EAAgB,EAAK;AAAA,IAEzB;AACA,oBAAS,iBAAiB,SAASqB,CAAO,GACnC,MAAM;AACX,eAAS,oBAAoB,SAASA,CAAO;AAAA,IAC/C;AAAA,EACF,GAAG,CAACtB,CAAY,CAAC;AAEjB,QAAM0B,KAAqB,EAAE,GAAGZ,GAAc,GAAGtB,EAAA,GAC3CmC,KAAoB,EAAE,GAAGZ,GAAa,GAAGtB,EAAA,GACzCmC,KAAsB,EAAE,GAAGZ,GAAe,GAAGtB,EAAA,GAC7CmC,KAAkB,EAAE,GAAGZ,GAAW,GAAGtB,EAAA,GACrCmC,KAAkB;AAAA,IACtB,GAAGV;AAAA,IACH,GAAIpB,IAAeqB,KAAgB,CAAA;AAAA,IACnC,GAAGvB;AAAA,EAAA,GAGCiC,KAAgBnG,EAAQ,IAAI,CAAC6E,MAAe;AAChD,UAAMuB,IAAWvB,EAAW,SAASL,GAC/B6B,IAAkB;AAAA,MACtB,GAAGf;AAAA,MACH,GAAIc,IAAWb,IAAkB,CAAA;AAAA,MACjC,GAAGvB;AAAA,MACH,GAAIoC,IAAWnC,IAAwB,CAAA;AAAA,MACvC,OAAO;AAAA,MACP,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,YAAY;AAAA,IAAA;AAGd,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,KAAKY,EAAW;AAAA,QAChB,OAAOoB;AAAA,MAAA;AAAA,MAET;AAAA,QACE;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,WAAW,mBAAmBpB,EAAW,IAAI;AAAA,UAC7C,OAAOwB;AAAA,UACP,SAAS,CAACpD,MAAa;AACrB,YAAAA,EAAE,eAAA,GACFA,EAAE,gBAAA,GACF+B,EAAmBH,EAAW,IAAI;AAAA,UACpC;AAAA,QAAA;AAAA,QAEFD,EAAYC,CAAU;AAAA,MAAA;AAAA,IACxB;AAAA,EAEJ,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,KAAKP;AAAA,MACL,WAAW;AAAA,MACX,OAAOwB;AAAA,MACP,GAAGnE;AAAA,IAAA;AAAA,IAEL;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,OAAOoE;AAAA,QACP,SAAS,CAAC9C,MAAa;AACrB,UAAAA,EAAE,eAAA,GACFA,EAAE,gBAAA,GACFyB,EAAezB,CAAC;AAAA,QAClB;AAAA,QACA,cAAc;AAAA,QACd,cAAcmB;AAAA,MAAA;AAAA,MAEhB,EAAE,QAAQ,MAAMU,GAAoB;AAAA,MACpC,EAAE,QAAQ,EAAE,OAAOoB,GAAA,GAAmB,GAAG;AAAA,IAAA;AAAA,IAE3C9B,IACI;AAAA,MACE;AAAA,MACA;AAAA,QACE,WAAW;AAAA,QACX,OAAO4B;AAAA,MAAA;AAAA,MAET,GAAGG;AAAA,IAAA,IAEL;AAAA,EAAA;AAER,GCjQaG,KAAQ,CAAC9E,MAA0C;AAC9D,QAAM,EAAE,GAAG,IAAA+E,GAAI,IAAAC,GAAI,IAAAC,GAAI,KAAAC,GAAK,QAAAtF,GAAQ,UAAAS,EAAA,IAAazB,EAAA,GAC3C;AAAA,IACJ,SAAAuG;AAAA,IACA,QAAA3E;AAAA,IACA,KAAA4E,IAAM;AAAA,IACN,QAAAC;AAAA,IACA,cAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,aAAAC,IAAc;AAAA,IACd,kBAAAC;AAAA,IACA,QAAAC;AAAA,IACA,MAAAC;AAAA,IACA,cAAAC;AAAA,IACA,GAAGzF;AAAA,EAAA,IACDH,GAEE6F,IAAQxF,EAAA,GAGRyF,IAAgB,CAACC,GAAyCC,GAA+CrH,MACtG;AAAA,IACLoH;AAAA,IACAC;AAAA,IACArH;AAAA,EAAA;AAKJ,MAAI+G,MAAW,QAAW;AACxB,UAAMO,IAAc,OAAOP,CAAM,GAC3BQ,IAAkBlB,EAAGiB,CAAW,GAChCE,IAAc,EAAEhB,GAAS,EAAE,QAAQe,GAAiB,GAAI1F,KAAU,CAAA,KAAO,QAAWqF,CAAK,GACzFO,IAAU,OAAOD,KAAgB,WAAWA,IAAc,OAAOA,CAAW;AAClF,WAAIZ,IACKO,EAAcV,GAAK,EAAE,GAAGjF,GAAW,yBAAyB,EAAE,QAAQiG,IAAQ,GAAK,MAAS,IAE9FN,EAAcV,GAAKjF,GAAWiG,CAAO;AAAA,EAC9C;AAGA,MAAIT,MAAS,QAAW;AACtB,UAAMU,IAAgBpB,EAAGU,CAAI,GACvBQ,IAAc,EAAEhB,GAAS,EAAE,MAAMkB,GAAe,GAAI7F,KAAU,CAAA,KAAO,QAAWqF,CAAK,GACrFO,IAAU,OAAOD,KAAgB,WAAWA,IAAc,OAAOA,CAAW;AAClF,WAAIZ,IACKO,EAAcV,GAAK,EAAE,GAAGjF,GAAW,yBAAyB,EAAE,QAAQiG,IAAQ,GAAK,MAAS,IAE9FN,EAAcV,GAAKjF,GAAWiG,CAAO;AAAA,EAC9C;AAGA,MAAIR,MAAiB,QAAW;AAC9B,UAAMU,IAAwBpB,EAAIU,CAAY,GACxCO,IAAc,EAAEhB,GAAS,EAAE,cAAcmB,GAAuB,GAAI9F,KAAU,CAAA,KAAO,QAAWqF,CAAK,GACrGO,IAAU,OAAOD,KAAgB,WAAWA,IAAc,OAAOA,CAAW;AAClF,WAAIZ,IACKO,EAAcV,GAAK,EAAE,GAAGjF,GAAW,yBAAyB,EAAE,QAAQiG,IAAQ,GAAK,MAAS,IAE9FN,EAAcV,GAAKjF,GAAWiG,CAAO;AAAA,EAC9C;AAGA,MAAIf,MAAW,QAAW;AACxB,UAAMkB,IAAQ,OAAO,SAASlB,EAAO,SAAA,GAAY,EAAE;AACnD,QAAIc;AAgBJ,WAfIV,IAWFU,IAVeV;AAAA,MACbN;AAAA,MACAoB;AAAA,MACA/F,KAAU,CAAA;AAAA,MACVZ;AAAA,MACA,CAAC4G,GAAmBC,GAA+CC,MAAgB;AACjF,cAAMC,IAAU,EAAEH,GAAGC,GAAGC,GAAIb,CAAK;AACjC,eAAO,OAAOc,KAAY,WAAWA,IAAU,OAAOA,CAAO;AAAA,MAC/D;AAAA,IAAA,KAEsB,KAExBR,IAAcpB,EAAGI,GAAS,EAAE,OAAAoB,GAAO,GAAI/F,KAAU,CAAA,EAAC,GAAM8E,CAAY,GAElEC,IACKO,EAAcV,GAAK,EAAE,GAAGjF,GAAW,yBAAyB,EAAE,QAAQgG,IAAY,GAAK,MAAS,IAElGL,EAAcV,GAAKjF,GAAWgG,CAAW;AAAA,EAClD;AAGA,QAAMA,IAAc,EAAEhB,GAAS3E,GAAQ8E,GAAcO,CAAK,GACpDO,IAAU,OAAOD,KAAgB,WAAWA,IAAc,OAAOA,CAAW;AAElF,SAAIX,KAAe,CAACY,EAAQ,SACnBd,IAAgB,EAAEsB,IAAU,MAAMtB,CAAY,IAAoB,OAGvEC,IACKO,EAAcV,GAAK,EAAE,GAAGjF,GAAW,yBAAyB,EAAE,QAAQiG,IAAQ,GAAK,MAAS,IAG9FN,EAAcV,GAAKjF,GAAWiG,CAAO;AAC9C;AC5GO,MAAMS,WAAmBC,GAAS;AAAA,EAC/B;AAAA,EACA;AAAA,EACA,gBAAwB;AAAA,EACxB,gCAAgB,IAAA;AAAA,EAChB,WAAW;AAAA,EAEH;AAAA,EAEhB,YAAYjI,GAA4B;AACtC,UAAMkI,IAA8B;AAAA,MAClC,kCAAkB,IAAA;AAAA,IAA0B;AAc9C,QAXA,MAAM;AAAA,MACJ,SAAAA;AAAA,MACA,QAAQlI,EAAQ;AAAA,MAChB,aAAaA,EAAQ;AAAA,MACrB,gBAAgBA,EAAQ;AAAA,IAAA,CACzB,GAED,KAAK,UAAUkI,GACf,KAAK,UAAUlI,EAAQ,QACvB,KAAK,kBAAkBA,EAAQ,kBAAkBA,EAAQ,QAErDA,EAAQ;AACV,iBAAW,CAACmI,GAAMC,CAAI,KAAK,OAAO,QAAQpI,EAAQ,QAAQ;AACxD,aAAK,OAAO,iBAAiBmI,GAAMC,CAAI;AAAA,EAG7C;AAAA,EAEA,YAAY,CAACC,OACX,KAAK,UAAU,IAAIA,CAAQ,GACpB,MAAM,KAAK,UAAU,OAAOA,CAAQ;AAAA,EAG7C,cAAc,MAAM,GAAG,KAAK,OAAO,IAAI,KAAK,aAAa,IAAI,KAAK,QAAQ;AAAA,EAElE,SAAS;AACf,SAAK,YACL,KAAK,UAAU,QAAQ,CAACA,MAAaA,GAAU;AAAA,EACjD;AAAA,EAEA,IAAI,SAAiB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,OAAOC,GAAa;AACtB,IAAI,KAAK,YAAYA,MACnB,KAAK,UAAUA,GACf,KAAK,OAAA;AAAA,EAET;AAAA,EAEA,IAAI,iBAAyB;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,eAAeA,GAAa;AAC9B,SAAK,kBAAkBA;AAAA,EACzB;AAAA,EAEA,IAAI,eAAuB;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,SAASC,GAAyB;AAChC,IAAI,KAAK,kBAAkBA,MACzB,KAAK,gBAAgBA,GACrB,KAAK,OAAA;AAAA,EAET;AAAA,EAEO,YAAoB;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,oBAA4B;AACjC,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,WAAmB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,gBAAgBxH,GAAgByH,GAA4BC,IAAQ,IAAY;AACrF,UAAM,qBAAqB1H,GAAQyH,GAAcC,CAAK,GACtD,KAAK,OAAA;AAAA,EACP;AAAA,EAEO,qBAAqB1H,GAAgBwH,GAAmBC,GAA4BC,IAAQ,IAAY;AAC7G,UAAM,0BAA0B1H,GAAQwH,GAAWC,GAAcC,CAAK,GACtE,KAAK,OAAA;AAAA,EACP;AAAA,EAEgB,aAAmB;AACjC,UAAM,WAAA,GACN,KAAK,OAAA;AAAA,EACP;AACF;AAEO,SAASC,GAAW1I,GAAwC;AACjE,SAAO,IAAIgI,GAAWhI,CAAO;AAC/B;AC7GO,SAAS2I,GAA4BhJ,GAAmBC,GAA4C;AACzG,QAAMgJ,IAAcjJ,EAAQ,IAAI,CAACkJ,MAAQA,EAAI,IAAI,GAK3CC,IAAc,CAACrI,GAAgCM,MAA+C;AAElG,UAAMgI,KADO,OAAOtI,KAAO,WAAWA,IAAKA,EAAG,QAAQ,KAC5B,MAAM,GAAG,EAAE,OAAO,OAAO,GAG7CuI,IAAQD,EAAa,CAAC;AAC5B,IAAIC,MAAU,UAAaJ,EAAY,SAASI,CAAK,KACnDD,EAAa,MAAA;AAGf,UAAME,IAAY,IAAIF,EAAa,KAAK,GAAG,CAAC;AAG5C,WAAIhI,MAAWnB,IACNqJ,IAIF,IAAIlI,CAAM,GAAGkI,MAAc,MAAM,KAAKA,CAAS;AAAA,EACxD;AAEA,SAAO;AAAA;AAAA,IAEL,eAAe;AAAA,IAEf,gBAAgB,MACV,OAAO,SAAW,MACb,OAAO,SAAS,WAElB;AAAA,IAGT,MAAM,CAAC3D,MAAW;AAChB,MAAI,OAAO,SAAW,QACpB,OAAO,QAAQ,UAAU,CAAA,GAAI,IAAIA,EAAO,IAAI,GAE5C,OAAO,cAAc,IAAI,MAAM,UAAU,CAAC;AAAA,IAE9C;AAAA,IAEA,SAAS,CAACA,MAAW;AACnB,MAAI,OAAO,SAAW,QACpB,OAAO,QAAQ,aAAa,CAAA,GAAI,IAAIA,EAAO,IAAI,GAC/C,OAAO,cAAc,IAAI,MAAM,UAAU,CAAC;AAAA,IAE9C;AAAA,IAEA,aAAa,CAAC7E,GAAIM,MAAW+H,EAAYrI,GAAIM,CAAM;AAAA,IAEnD,UAAU,MACJ,OAAO,SAAW,MACb;AAAA,MACL,UAAU,OAAO,SAAS,WAAW,OAAO,SAAS;AAAA,MACrD,OAAO,OAAO,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM,CAAC;AAAA,IAAA,IAGlE;AAAA,MACL,UAAU;AAAA,MACV,OAAO,CAAA;AAAA,IAAC;AAAA,EAEZ;AAEJ;AAGO,MAAMmI,KAA4BP;"}
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.1",
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.2",
23
+ "@i18n-micro/types": "1.1.1"
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": {