@fluenti/react 0.3.3 → 0.4.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +1 -1
  2. package/dist/components/DateTime.d.ts +3 -3
  3. package/dist/components/DateTime.d.ts.map +1 -1
  4. package/dist/components/Number.d.ts +3 -3
  5. package/dist/components/Number.d.ts.map +1 -1
  6. package/dist/components/trans-core.d.ts.map +1 -1
  7. package/dist/components-entry.cjs +2 -0
  8. package/dist/components-entry.cjs.map +1 -0
  9. package/dist/components-entry.d.ts +12 -0
  10. package/dist/components-entry.d.ts.map +1 -0
  11. package/dist/components-entry.js +91 -0
  12. package/dist/components-entry.js.map +1 -0
  13. package/dist/context-DVbvrSE8.cjs +2 -0
  14. package/dist/context-DVbvrSE8.cjs.map +1 -0
  15. package/dist/context-DVudCV1o.js +7 -0
  16. package/dist/context-DVudCV1o.js.map +1 -0
  17. package/dist/create-fluenti.d.ts +12 -8
  18. package/dist/create-fluenti.d.ts.map +1 -1
  19. package/dist/{icu-rich-BOtj4Oxu.js → icu-rich-ChVWsA7C.js} +18 -11
  20. package/dist/icu-rich-ChVWsA7C.js.map +1 -0
  21. package/dist/icu-rich-CotMVC_x.cjs +2 -0
  22. package/dist/icu-rich-CotMVC_x.cjs.map +1 -0
  23. package/dist/index.cjs +1 -1
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.ts +0 -5
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +127 -288
  28. package/dist/index.js.map +1 -1
  29. package/dist/provider.d.ts +41 -0
  30. package/dist/provider.d.ts.map +1 -1
  31. package/dist/server.cjs +1 -1
  32. package/dist/server.cjs.map +1 -1
  33. package/dist/server.d.ts +24 -9
  34. package/dist/server.d.ts.map +1 -1
  35. package/dist/server.js +23 -22
  36. package/dist/server.js.map +1 -1
  37. package/dist/types.d.ts +5 -0
  38. package/dist/types.d.ts.map +1 -1
  39. package/llms-full.txt +2 -1
  40. package/llms-migration.txt +2 -2
  41. package/llms.txt +61 -0
  42. package/package.json +18 -4
  43. package/dist/icu-rich-BOtj4Oxu.js.map +0 -1
  44. package/dist/icu-rich-vPU-0wGQ.cjs +0 -2
  45. package/dist/icu-rich-vPU-0wGQ.cjs.map +0 -1
package/README.md CHANGED
@@ -172,7 +172,7 @@ export default async function Page() {
172
172
  <div>
173
173
  <Trans>Read the <a href="/docs">documentation</a>.</Trans>
174
174
  <Plural value={5} one="# item" other="# items" />
175
- <DateTime value={new Date()} style="long" />
175
+ <DateTime value={new Date()} format="long" />
176
176
  <NumberFormat value={1234.56} />
177
177
  </div>
178
178
  )
@@ -1,15 +1,15 @@
1
1
  export interface FluentiDateTimeProps {
2
2
  /** Date value to format */
3
3
  value: Date | number;
4
- /** Named format style */
5
- style?: string;
4
+ /** Named format key defined in dateFormats config */
5
+ format?: string;
6
6
  }
7
7
  /**
8
8
  * `<DateTime>` — formatting component using Intl APIs.
9
9
  *
10
10
  * @example
11
11
  * ```tsx
12
- * <DateTime value={new Date()} style="long" />
12
+ * <DateTime value={new Date()} format="long" />
13
13
  * ```
14
14
  */
15
15
  export declare const DateTime: import('react').NamedExoticComponent<FluentiDateTimeProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"DateTime.d.ts","sourceRoot":"","sources":["../../src/components/DateTime.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,2BAA2B;IAC3B,KAAK,EAAE,IAAI,GAAG,MAAM,CAAA;IACpB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,4DAMnB,CAAA"}
1
+ {"version":3,"file":"DateTime.d.ts","sourceRoot":"","sources":["../../src/components/DateTime.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,2BAA2B;IAC3B,KAAK,EAAE,IAAI,GAAG,MAAM,CAAA;IACpB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,4DAMnB,CAAA"}
@@ -1,8 +1,8 @@
1
1
  export interface NumberFormatProps {
2
2
  /** Number value to format */
3
3
  value: number;
4
- /** Named format style */
5
- style?: string;
4
+ /** Named format key defined in numberFormats config */
5
+ format?: string;
6
6
  }
7
7
  /** @alias NumberFormatProps */
8
8
  export type FluentiNumberFormatProps = NumberFormatProps;
@@ -11,7 +11,7 @@ export type FluentiNumberFormatProps = NumberFormatProps;
11
11
  *
12
12
  * @example
13
13
  * ```tsx
14
- * <Number value={1234.56} style="currency" />
14
+ * <Number value={1234.56} format="currency" />
15
15
  * ```
16
16
  */
17
17
  export declare const NumberFormat: import('react').NamedExoticComponent<NumberFormatProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"Number.d.ts","sourceRoot":"","sources":["../../src/components/Number.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,+BAA+B;AAC/B,MAAM,MAAM,wBAAwB,GAAG,iBAAiB,CAAA;AAExD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,yDAMvB,CAAA"}
1
+ {"version":3,"file":"Number.d.ts","sourceRoot":"","sources":["../../src/components/Number.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,+BAA+B;AAC/B,MAAM,MAAM,wBAAwB,GAAG,iBAAiB,CAAA;AAExD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,yDAMvB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"trans-core.d.ts","sourceRoot":"","sources":["../../src/components/trans-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EACd,KAAK,YAAY,EAClB,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,WAAW,EAAiB,MAAM,wBAAwB,CAAA;AAEnE,OAAO,EAAE,WAAW,EAAE,CAAA;AAEtB;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,GAAG;IACnD,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,YAAY,EAAE,CAAA;CAC3B,CA4BA;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,YAAY,EAAE,GACzB,SAAS,CAyCX"}
1
+ {"version":3,"file":"trans-core.d.ts","sourceRoot":"","sources":["../../src/components/trans-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EACd,KAAK,YAAY,EAClB,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,WAAW,EAAiB,MAAM,wBAAwB,CAAA;AAEnE,OAAO,EAAE,WAAW,EAAE,CAAA;AAEtB;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,GAAG;IACnD,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,YAAY,EAAE,CAAA;CAC3B,CA4BA;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,YAAY,EAAE,GACzB,SAAS,CAmDX"}
@@ -0,0 +1,2 @@
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./context-DVbvrSE8.cjs`),t=require(`./icu-rich-CotMVC_x.cjs`);let n=require(`react`),r=require(`react/jsx-runtime`),i=require(`@fluenti/core/internal`);var a=(0,n.memo)(function({children:a,id:o,context:s,comment:c,tag:l,render:u,__id:d,__message:f,__components:p}){let m=(0,n.useContext)(e.t);if(!m)throw Error(`[fluenti] <Trans> must be used within an <I18nProvider>`);let h=f!==void 0,{message:g,components:_}=(0,n.useMemo)(()=>h?{message:f,components:p??[]}:t.r(a),[h,f,p,a]),v=(0,n.useMemo)(()=>o??d??(0,i.hashMessage)(g,s),[o,d,g,s]),y=t.i(m.t({id:v,message:g,...s===void 0?{}:{context:s},...c===void 0?{}:{comment:c}}),_);return u?u(y):l?(0,n.createElement)(l,null,y):(0,r.jsx)(r.Fragment,{children:y})}),o=(0,n.memo)(function({value:a,id:o,context:s,comment:c,zero:l,one:u,two:d,few:f,many:p,other:m,offset:h}){let g=(0,n.useContext)(e.t);if(!g)throw Error(`[fluenti] <Plural> must be used within an <I18nProvider>`);let{messages:_,components:v}=t.n(i.PLURAL_CATEGORIES,{zero:l,one:u,two:d,few:f,many:p,other:m}),y=(0,i.buildICUPluralMessage)({..._.zero!==void 0&&{zero:_.zero},..._.one!==void 0&&{one:_.one},..._.two!==void 0&&{two:_.two},..._.few!==void 0&&{few:_.few},..._.many!==void 0&&{many:_.many},other:_.other??``},h);return(0,r.jsx)(r.Fragment,{children:t.t({id:o??(s===void 0?y:(0,i.hashMessage)(y,s)),message:y,...s===void 0?{}:{context:s},...c===void 0?{}:{comment:c}},{count:a},(e,t)=>g.t(e,t),v)})}),s=(0,n.memo)(function(a){let o=(0,n.useContext)(e.t);if(!o)throw Error(`[fluenti] <Select> must be used within an <I18nProvider>`);let{value:s,id:c,context:l,comment:u,other:d,options:f,tag:p,...m}=a,h=f===void 0?{...Object.fromEntries(Object.entries(m).filter(([e])=>![`value`,`id`,`context`,`comment`,`options`,`other`,`tag`].includes(e))),other:d}:{...f,other:d},g=[...Object.keys(h).filter(e=>e!==`other`),`other`],{messages:_,components:v}=t.n(g,h),y=(0,i.normalizeSelectForms)(Object.fromEntries([...g].map(e=>[e,_[e]??``]))),b=(0,i.buildICUSelectMessage)(y.forms),x=t.t({id:c??(l===void 0?b:(0,i.hashMessage)(b,l)),message:b,...l===void 0?{}:{context:l},...u===void 0?{}:{comment:u}},{value:y.valueMap[s]??`other`},(e,t)=>o.t(e,t),v);return p?(0,n.createElement)(p,null,x):(0,r.jsx)(r.Fragment,{children:x})}),c=(0,n.memo)(function({value:t,format:i}){let a=(0,n.useContext)(e.t);if(!a)throw Error(`[fluenti] <DateTime> must be used within an <I18nProvider>`);return(0,r.jsx)(r.Fragment,{children:a.d(t,i)})}),l=(0,n.memo)(function({value:t,format:i}){let a=(0,n.useContext)(e.t);if(!a)throw Error(`[fluenti] <Number> must be used within an <I18nProvider>`);return(0,r.jsx)(r.Fragment,{children:a.n(t,i)})});exports.DateTime=c,exports.NumberFormat=l,exports.Plural=o,exports.Select=s,exports.Trans=a,Object.defineProperty(exports,`interpolate`,{enumerable:!0,get:function(){return i.interpolate}});
2
+ //# sourceMappingURL=components-entry.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components-entry.cjs","names":[],"sources":["../src/components/Trans.tsx","../src/components/Plural.tsx","../src/components/Select.tsx","../src/components/DateTime.tsx","../src/components/Number.tsx"],"sourcesContent":["import {\n createElement,\n memo,\n useContext,\n useMemo,\n type ReactElement,\n type ReactNode,\n} from 'react'\nimport { I18nContext } from '../context'\nimport { hashMessage, extractMessage, reconstruct } from './trans-core'\n\nexport interface FluentiTransProps {\n /** Source text with embedded components */\n children: ReactNode\n /** Override auto-generated hash ID */\n id?: string\n /** Message context used for identity and translator disambiguation */\n context?: string\n /** Context comment for translators */\n comment?: string\n /** Wrapper element tag name (e.g. 'span', 'div'). Defaults to Fragment (no wrapper). */\n tag?: keyof React.JSX.IntrinsicElements\n /** Custom render wrapper */\n render?: (translation: ReactNode) => ReactNode\n /** @internal Pre-computed message ID from build plugin */\n __id?: string\n /** @internal Pre-computed ICU message from build plugin */\n __message?: string\n /** @internal Pre-computed component list from build plugin */\n __components?: ReactElement[]\n}\n\n/**\n * `<Trans>` component for rich-text translations containing nested React elements.\n *\n * @example\n * ```tsx\n * <Trans>Read the <a href=\"/docs\">documentation</a> for more info.</Trans>\n * ```\n */\nexport const Trans = memo(function Trans({\n children,\n id,\n context,\n comment,\n tag,\n render,\n __id,\n __message,\n __components,\n}: FluentiTransProps) {\n const ctx = useContext(I18nContext)\n if (!ctx) {\n throw new Error('[fluenti] <Trans> must be used within an <I18nProvider>')\n }\n\n // Fast path: build plugin pre-computed message and components\n const hasPrecomputed = __message !== undefined\n\n const { message, components } = useMemo(\n () => hasPrecomputed\n ? { message: __message!, components: __components ?? [] }\n : extractMessage(children),\n [hasPrecomputed, __message, __components, children],\n )\n const messageId = useMemo(\n () => id ?? __id ?? hashMessage(message, context),\n [id, __id, message, context],\n )\n\n const translated = ctx.t(\n {\n id: messageId,\n message,\n ...(context !== undefined ? { context } : {}),\n ...(comment !== undefined ? { comment } : {}),\n },\n )\n\n const result = reconstruct(translated, components)\n if (render) return render(result)\n return tag ? createElement(tag, null, result) : <>{result}</>\n})\n","import { memo, useContext, type ReactNode } from 'react'\nimport { hashMessage } from '@fluenti/core/internal'\nimport { I18nContext } from '../context'\nimport { PLURAL_CATEGORIES, type PluralCategory } from './plural-core'\nimport { buildICUPluralMessage, renderRichTranslation, serializeRichForms } from './icu-rich'\n\nexport interface FluentiPluralProps {\n /** The count value */\n value: number\n /** Override the auto-generated synthetic ICU message id */\n id?: string\n /** Message context used for identity and translator disambiguation */\n context?: string\n /** Translator-facing note preserved in extraction catalogs */\n comment?: string\n /** Text for zero (if language supports) */\n zero?: ReactNode\n /** Singular form. `#` replaced with value */\n one?: ReactNode\n /** Dual form (Arabic, etc.) */\n two?: ReactNode\n /** Few form (Slavic languages, etc.) */\n few?: ReactNode\n /** Many form */\n many?: ReactNode\n /** Default plural form */\n other: ReactNode\n /** Offset from value before selecting form */\n offset?: number\n}\n\n/**\n * `<Plural>` — ICU plural handling as a component.\n *\n * @example\n * ```tsx\n * <Plural value={count} zero=\"No messages\" one=\"# message\" other=\"# messages\" />\n * ```\n */\nexport const Plural = memo(function Plural({\n value,\n id,\n context,\n comment,\n zero,\n one,\n two,\n few,\n many,\n other,\n offset,\n}: FluentiPluralProps) {\n const ctx = useContext(I18nContext)\n if (!ctx) {\n throw new Error('[fluenti] <Plural> must be used within an <I18nProvider>')\n }\n\n const forms: Record<PluralCategory, ReactNode | undefined> = {\n zero,\n one,\n two,\n few,\n many,\n other,\n }\n const { messages, components } = serializeRichForms(PLURAL_CATEGORIES, forms)\n const icuMessage = buildICUPluralMessage(\n {\n ...(messages.zero !== undefined && { zero: messages.zero }),\n ...(messages.one !== undefined && { one: messages.one }),\n ...(messages.two !== undefined && { two: messages.two }),\n ...(messages.few !== undefined && { few: messages.few }),\n ...(messages.many !== undefined && { many: messages.many }),\n other: messages.other ?? '',\n },\n offset,\n )\n\n const descriptor = {\n id: id ?? (context === undefined ? icuMessage : hashMessage(icuMessage, context)),\n message: icuMessage,\n ...(context !== undefined ? { context } : {}),\n ...(comment !== undefined ? { comment } : {}),\n }\n\n return <>{renderRichTranslation(descriptor, { count: value }, (desc, values) => ctx.t(desc, values), components)}</>\n})\n","import { createElement, memo, useContext, type ReactNode } from 'react'\nimport { hashMessage } from '@fluenti/core/internal'\nimport { I18nContext } from '../context'\nimport { buildICUSelectMessage, normalizeSelectForms, renderRichTranslation, serializeRichForms } from './icu-rich'\n\nexport interface FluentiSelectProps {\n /** The selector value */\n value: string\n /** Override the auto-generated synthetic ICU message id */\n id?: string\n /** Message context used for identity and translator disambiguation */\n context?: string\n /** Translator-facing note preserved in extraction catalogs */\n comment?: string\n /** Default case */\n other: ReactNode\n /** Type-safe named options. Takes precedence over direct case props. */\n options?: Record<string, ReactNode>\n /** Wrapper element tag name (e.g. 'span', 'div'). Defaults to Fragment (no wrapper). */\n tag?: keyof React.JSX.IntrinsicElements\n /** Named cases — any string key maps to a ReactNode */\n [key: string]: ReactNode | Record<string, ReactNode> | keyof React.JSX.IntrinsicElements | undefined\n}\n\n/**\n * `<Select>` — ICU select for gender, role, or other categorical values.\n *\n * @example\n * ```tsx\n * <Select\n * value={gender}\n * male=\"He liked your post\"\n * female=\"She liked your post\"\n * other=\"They liked your post\"\n * />\n * ```\n */\nexport const Select = memo(function Select(props: FluentiSelectProps) {\n const ctx = useContext(I18nContext)\n if (!ctx) {\n throw new Error('[fluenti] <Select> must be used within an <I18nProvider>')\n }\n\n const { value, id, context, comment, other, options, tag, ...cases } = props\n const forms: Record<string, ReactNode | undefined> = options === undefined\n ? {\n ...Object.fromEntries(\n Object.entries(cases).filter(([key]) => !['value', 'id', 'context', 'comment', 'options', 'other', 'tag'].includes(key)),\n ),\n other,\n }\n : {\n ...options,\n other,\n }\n\n const orderedKeys = [...Object.keys(forms).filter(key => key !== 'other'), 'other'] as const\n const { messages, components } = serializeRichForms(orderedKeys, forms)\n const normalized = normalizeSelectForms(\n Object.fromEntries(\n [...orderedKeys].map((key) => [key, messages[key] ?? '']),\n ),\n )\n const icuMessage = buildICUSelectMessage(normalized.forms)\n\n const descriptor = {\n id: id ?? (context === undefined ? icuMessage : hashMessage(icuMessage, context)),\n message: icuMessage,\n ...(context !== undefined ? { context } : {}),\n ...(comment !== undefined ? { comment } : {}),\n }\n\n const result = renderRichTranslation(\n descriptor,\n { value: normalized.valueMap[value] ?? 'other' },\n (desc, values) => ctx.t(desc, values),\n components,\n )\n return tag ? createElement(tag, null, result) : <>{result}</>\n})\n","import { memo, useContext } from 'react'\nimport { I18nContext } from '../context'\n\nexport interface FluentiDateTimeProps {\n /** Date value to format */\n value: Date | number\n /** Named format key defined in dateFormats config */\n format?: string\n}\n\n/**\n * `<DateTime>` — formatting component using Intl APIs.\n *\n * @example\n * ```tsx\n * <DateTime value={new Date()} format=\"long\" />\n * ```\n */\nexport const DateTime = memo(function DateTime({ value, format }: FluentiDateTimeProps) {\n const ctx = useContext(I18nContext)\n if (!ctx) {\n throw new Error('[fluenti] <DateTime> must be used within an <I18nProvider>')\n }\n return <>{ctx.d(value, format)}</>\n})\n","import { memo, useContext } from 'react'\nimport { I18nContext } from '../context'\n\nexport interface NumberFormatProps {\n /** Number value to format */\n value: number\n /** Named format key defined in numberFormats config */\n format?: string\n}\n\n/** @alias NumberFormatProps */\nexport type FluentiNumberFormatProps = NumberFormatProps\n\n/**\n * `<Number>` — number formatting component using Intl APIs.\n *\n * @example\n * ```tsx\n * <Number value={1234.56} format=\"currency\" />\n * ```\n */\nexport const NumberFormat = memo(function NumberFormat({ value, format }: NumberFormatProps) {\n const ctx = useContext(I18nContext)\n if (!ctx) {\n throw new Error('[fluenti] <Number> must be used within an <I18nProvider>')\n }\n return <>{ctx.n(value, format)}</>\n})\n"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export { Trans } from './components/Trans';
2
+ export type { FluentiTransProps } from './components/Trans';
3
+ export { Plural } from './components/Plural';
4
+ export type { FluentiPluralProps } from './components/Plural';
5
+ export { Select } from './components/Select';
6
+ export type { FluentiSelectProps } from './components/Select';
7
+ export { DateTime } from './components/DateTime';
8
+ export type { FluentiDateTimeProps } from './components/DateTime';
9
+ export { NumberFormat } from './components/Number';
10
+ export type { NumberFormatProps, FluentiNumberFormatProps } from './components/Number';
11
+ export { interpolate } from '@fluenti/core/internal';
12
+ //# sourceMappingURL=components-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components-entry.d.ts","sourceRoot":"","sources":["../src/components-entry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAChD,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,YAAY,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAGtF,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA"}
@@ -0,0 +1,91 @@
1
+ "use client";
2
+ import { t as e } from "./context-DVudCV1o.js";
3
+ import { a as t, c as n, i as r, l as i, n as a, o, r as s, s as c, t as l } from "./icu-rich-ChVWsA7C.js";
4
+ import { createElement as u, memo as d, useContext as f, useMemo as p } from "react";
5
+ import { Fragment as m, jsx as h } from "react/jsx-runtime";
6
+ import { hashMessage as g, interpolate as _ } from "@fluenti/core/internal";
7
+ //#region src/components/Trans.tsx
8
+ var v = d(function({ children: t, id: r, context: a, comment: o, tag: s, render: l, __id: d, __message: g, __components: _ }) {
9
+ let v = f(e);
10
+ if (!v) throw Error("[fluenti] <Trans> must be used within an <I18nProvider>");
11
+ let y = g !== void 0, { message: b, components: x } = p(() => y ? {
12
+ message: g,
13
+ components: _ ?? []
14
+ } : c(t), [
15
+ y,
16
+ g,
17
+ _,
18
+ t
19
+ ]), S = p(() => r ?? d ?? n(b, a), [
20
+ r,
21
+ d,
22
+ b,
23
+ a
24
+ ]), C = i(v.t({
25
+ id: S,
26
+ message: b,
27
+ ...a === void 0 ? {} : { context: a },
28
+ ...o === void 0 ? {} : { comment: o }
29
+ }), x);
30
+ return l ? l(C) : s ? u(s, null, C) : /* @__PURE__ */ h(m, { children: C });
31
+ }), y = d(function({ value: n, id: i, context: a, comment: s, zero: c, one: u, two: d, few: p, many: _, other: v, offset: y }) {
32
+ let b = f(e);
33
+ if (!b) throw Error("[fluenti] <Plural> must be used within an <I18nProvider>");
34
+ let { messages: x, components: S } = t(o, {
35
+ zero: c,
36
+ one: u,
37
+ two: d,
38
+ few: p,
39
+ many: _,
40
+ other: v
41
+ }), C = l({
42
+ ...x.zero !== void 0 && { zero: x.zero },
43
+ ...x.one !== void 0 && { one: x.one },
44
+ ...x.two !== void 0 && { two: x.two },
45
+ ...x.few !== void 0 && { few: x.few },
46
+ ...x.many !== void 0 && { many: x.many },
47
+ other: x.other ?? ""
48
+ }, y);
49
+ return /* @__PURE__ */ h(m, { children: r({
50
+ id: i ?? (a === void 0 ? C : g(C, a)),
51
+ message: C,
52
+ ...a === void 0 ? {} : { context: a },
53
+ ...s === void 0 ? {} : { comment: s }
54
+ }, { count: n }, (e, t) => b.t(e, t), S) });
55
+ }), b = d(function(n) {
56
+ let i = f(e);
57
+ if (!i) throw Error("[fluenti] <Select> must be used within an <I18nProvider>");
58
+ let { value: o, id: c, context: l, comment: d, other: p, options: _, tag: v, ...y } = n, b = _ === void 0 ? {
59
+ ...Object.fromEntries(Object.entries(y).filter(([e]) => ![
60
+ "value",
61
+ "id",
62
+ "context",
63
+ "comment",
64
+ "options",
65
+ "other",
66
+ "tag"
67
+ ].includes(e))),
68
+ other: p
69
+ } : {
70
+ ..._,
71
+ other: p
72
+ }, x = [...Object.keys(b).filter((e) => e !== "other"), "other"], { messages: S, components: C } = t(x, b), w = s(Object.fromEntries([...x].map((e) => [e, S[e] ?? ""]))), T = a(w.forms), E = r({
73
+ id: c ?? (l === void 0 ? T : g(T, l)),
74
+ message: T,
75
+ ...l === void 0 ? {} : { context: l },
76
+ ...d === void 0 ? {} : { comment: d }
77
+ }, { value: w.valueMap[o] ?? "other" }, (e, t) => i.t(e, t), C);
78
+ return v ? u(v, null, E) : /* @__PURE__ */ h(m, { children: E });
79
+ }), x = d(function({ value: t, format: n }) {
80
+ let r = f(e);
81
+ if (!r) throw Error("[fluenti] <DateTime> must be used within an <I18nProvider>");
82
+ return /* @__PURE__ */ h(m, { children: r.d(t, n) });
83
+ }), S = d(function({ value: t, format: n }) {
84
+ let r = f(e);
85
+ if (!r) throw Error("[fluenti] <Number> must be used within an <I18nProvider>");
86
+ return /* @__PURE__ */ h(m, { children: r.n(t, n) });
87
+ });
88
+ //#endregion
89
+ export { x as DateTime, S as NumberFormat, y as Plural, b as Select, v as Trans, _ as interpolate };
90
+
91
+ //# sourceMappingURL=components-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components-entry.js","names":[],"sources":["../src/components/Trans.tsx","../src/components/Plural.tsx","../src/components/Select.tsx","../src/components/DateTime.tsx","../src/components/Number.tsx"],"sourcesContent":["import {\n createElement,\n memo,\n useContext,\n useMemo,\n type ReactElement,\n type ReactNode,\n} from 'react'\nimport { I18nContext } from '../context'\nimport { hashMessage, extractMessage, reconstruct } from './trans-core'\n\nexport interface FluentiTransProps {\n /** Source text with embedded components */\n children: ReactNode\n /** Override auto-generated hash ID */\n id?: string\n /** Message context used for identity and translator disambiguation */\n context?: string\n /** Context comment for translators */\n comment?: string\n /** Wrapper element tag name (e.g. 'span', 'div'). Defaults to Fragment (no wrapper). */\n tag?: keyof React.JSX.IntrinsicElements\n /** Custom render wrapper */\n render?: (translation: ReactNode) => ReactNode\n /** @internal Pre-computed message ID from build plugin */\n __id?: string\n /** @internal Pre-computed ICU message from build plugin */\n __message?: string\n /** @internal Pre-computed component list from build plugin */\n __components?: ReactElement[]\n}\n\n/**\n * `<Trans>` component for rich-text translations containing nested React elements.\n *\n * @example\n * ```tsx\n * <Trans>Read the <a href=\"/docs\">documentation</a> for more info.</Trans>\n * ```\n */\nexport const Trans = memo(function Trans({\n children,\n id,\n context,\n comment,\n tag,\n render,\n __id,\n __message,\n __components,\n}: FluentiTransProps) {\n const ctx = useContext(I18nContext)\n if (!ctx) {\n throw new Error('[fluenti] <Trans> must be used within an <I18nProvider>')\n }\n\n // Fast path: build plugin pre-computed message and components\n const hasPrecomputed = __message !== undefined\n\n const { message, components } = useMemo(\n () => hasPrecomputed\n ? { message: __message!, components: __components ?? [] }\n : extractMessage(children),\n [hasPrecomputed, __message, __components, children],\n )\n const messageId = useMemo(\n () => id ?? __id ?? hashMessage(message, context),\n [id, __id, message, context],\n )\n\n const translated = ctx.t(\n {\n id: messageId,\n message,\n ...(context !== undefined ? { context } : {}),\n ...(comment !== undefined ? { comment } : {}),\n },\n )\n\n const result = reconstruct(translated, components)\n if (render) return render(result)\n return tag ? createElement(tag, null, result) : <>{result}</>\n})\n","import { memo, useContext, type ReactNode } from 'react'\nimport { hashMessage } from '@fluenti/core/internal'\nimport { I18nContext } from '../context'\nimport { PLURAL_CATEGORIES, type PluralCategory } from './plural-core'\nimport { buildICUPluralMessage, renderRichTranslation, serializeRichForms } from './icu-rich'\n\nexport interface FluentiPluralProps {\n /** The count value */\n value: number\n /** Override the auto-generated synthetic ICU message id */\n id?: string\n /** Message context used for identity and translator disambiguation */\n context?: string\n /** Translator-facing note preserved in extraction catalogs */\n comment?: string\n /** Text for zero (if language supports) */\n zero?: ReactNode\n /** Singular form. `#` replaced with value */\n one?: ReactNode\n /** Dual form (Arabic, etc.) */\n two?: ReactNode\n /** Few form (Slavic languages, etc.) */\n few?: ReactNode\n /** Many form */\n many?: ReactNode\n /** Default plural form */\n other: ReactNode\n /** Offset from value before selecting form */\n offset?: number\n}\n\n/**\n * `<Plural>` — ICU plural handling as a component.\n *\n * @example\n * ```tsx\n * <Plural value={count} zero=\"No messages\" one=\"# message\" other=\"# messages\" />\n * ```\n */\nexport const Plural = memo(function Plural({\n value,\n id,\n context,\n comment,\n zero,\n one,\n two,\n few,\n many,\n other,\n offset,\n}: FluentiPluralProps) {\n const ctx = useContext(I18nContext)\n if (!ctx) {\n throw new Error('[fluenti] <Plural> must be used within an <I18nProvider>')\n }\n\n const forms: Record<PluralCategory, ReactNode | undefined> = {\n zero,\n one,\n two,\n few,\n many,\n other,\n }\n const { messages, components } = serializeRichForms(PLURAL_CATEGORIES, forms)\n const icuMessage = buildICUPluralMessage(\n {\n ...(messages.zero !== undefined && { zero: messages.zero }),\n ...(messages.one !== undefined && { one: messages.one }),\n ...(messages.two !== undefined && { two: messages.two }),\n ...(messages.few !== undefined && { few: messages.few }),\n ...(messages.many !== undefined && { many: messages.many }),\n other: messages.other ?? '',\n },\n offset,\n )\n\n const descriptor = {\n id: id ?? (context === undefined ? icuMessage : hashMessage(icuMessage, context)),\n message: icuMessage,\n ...(context !== undefined ? { context } : {}),\n ...(comment !== undefined ? { comment } : {}),\n }\n\n return <>{renderRichTranslation(descriptor, { count: value }, (desc, values) => ctx.t(desc, values), components)}</>\n})\n","import { createElement, memo, useContext, type ReactNode } from 'react'\nimport { hashMessage } from '@fluenti/core/internal'\nimport { I18nContext } from '../context'\nimport { buildICUSelectMessage, normalizeSelectForms, renderRichTranslation, serializeRichForms } from './icu-rich'\n\nexport interface FluentiSelectProps {\n /** The selector value */\n value: string\n /** Override the auto-generated synthetic ICU message id */\n id?: string\n /** Message context used for identity and translator disambiguation */\n context?: string\n /** Translator-facing note preserved in extraction catalogs */\n comment?: string\n /** Default case */\n other: ReactNode\n /** Type-safe named options. Takes precedence over direct case props. */\n options?: Record<string, ReactNode>\n /** Wrapper element tag name (e.g. 'span', 'div'). Defaults to Fragment (no wrapper). */\n tag?: keyof React.JSX.IntrinsicElements\n /** Named cases — any string key maps to a ReactNode */\n [key: string]: ReactNode | Record<string, ReactNode> | keyof React.JSX.IntrinsicElements | undefined\n}\n\n/**\n * `<Select>` — ICU select for gender, role, or other categorical values.\n *\n * @example\n * ```tsx\n * <Select\n * value={gender}\n * male=\"He liked your post\"\n * female=\"She liked your post\"\n * other=\"They liked your post\"\n * />\n * ```\n */\nexport const Select = memo(function Select(props: FluentiSelectProps) {\n const ctx = useContext(I18nContext)\n if (!ctx) {\n throw new Error('[fluenti] <Select> must be used within an <I18nProvider>')\n }\n\n const { value, id, context, comment, other, options, tag, ...cases } = props\n const forms: Record<string, ReactNode | undefined> = options === undefined\n ? {\n ...Object.fromEntries(\n Object.entries(cases).filter(([key]) => !['value', 'id', 'context', 'comment', 'options', 'other', 'tag'].includes(key)),\n ),\n other,\n }\n : {\n ...options,\n other,\n }\n\n const orderedKeys = [...Object.keys(forms).filter(key => key !== 'other'), 'other'] as const\n const { messages, components } = serializeRichForms(orderedKeys, forms)\n const normalized = normalizeSelectForms(\n Object.fromEntries(\n [...orderedKeys].map((key) => [key, messages[key] ?? '']),\n ),\n )\n const icuMessage = buildICUSelectMessage(normalized.forms)\n\n const descriptor = {\n id: id ?? (context === undefined ? icuMessage : hashMessage(icuMessage, context)),\n message: icuMessage,\n ...(context !== undefined ? { context } : {}),\n ...(comment !== undefined ? { comment } : {}),\n }\n\n const result = renderRichTranslation(\n descriptor,\n { value: normalized.valueMap[value] ?? 'other' },\n (desc, values) => ctx.t(desc, values),\n components,\n )\n return tag ? createElement(tag, null, result) : <>{result}</>\n})\n","import { memo, useContext } from 'react'\nimport { I18nContext } from '../context'\n\nexport interface FluentiDateTimeProps {\n /** Date value to format */\n value: Date | number\n /** Named format key defined in dateFormats config */\n format?: string\n}\n\n/**\n * `<DateTime>` — formatting component using Intl APIs.\n *\n * @example\n * ```tsx\n * <DateTime value={new Date()} format=\"long\" />\n * ```\n */\nexport const DateTime = memo(function DateTime({ value, format }: FluentiDateTimeProps) {\n const ctx = useContext(I18nContext)\n if (!ctx) {\n throw new Error('[fluenti] <DateTime> must be used within an <I18nProvider>')\n }\n return <>{ctx.d(value, format)}</>\n})\n","import { memo, useContext } from 'react'\nimport { I18nContext } from '../context'\n\nexport interface NumberFormatProps {\n /** Number value to format */\n value: number\n /** Named format key defined in numberFormats config */\n format?: string\n}\n\n/** @alias NumberFormatProps */\nexport type FluentiNumberFormatProps = NumberFormatProps\n\n/**\n * `<Number>` — number formatting component using Intl APIs.\n *\n * @example\n * ```tsx\n * <Number value={1234.56} format=\"currency\" />\n * ```\n */\nexport const NumberFormat = memo(function NumberFormat({ value, format }: NumberFormatProps) {\n const ctx = useContext(I18nContext)\n if (!ctx) {\n throw new Error('[fluenti] <Number> must be used within an <I18nProvider>')\n }\n return <>{ctx.n(value, format)}</>\n})\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ var e=(0,require(`react`).createContext)(null);Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return e}});
2
+ //# sourceMappingURL=context-DVbvrSE8.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-DVbvrSE8.cjs","names":[],"sources":["../src/context.ts"],"sourcesContent":["import { createContext } from 'react'\nimport type { FluentiContext } from './types'\n\nexport const I18nContext = createContext<FluentiContext | null>(null)\n"],"mappings":"AAGA,IAAa,GAAA,mBAAA,eAAmD,KAAK"}
@@ -0,0 +1,7 @@
1
+ import { createContext as e } from "react";
2
+ //#region src/context.ts
3
+ var t = e(null);
4
+ //#endregion
5
+ export { t };
6
+
7
+ //# sourceMappingURL=context-DVudCV1o.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-DVudCV1o.js","names":[],"sources":["../src/context.ts"],"sourcesContent":["import { createContext } from 'react'\nimport type { FluentiContext } from './types'\n\nexport const I18nContext = createContext<FluentiContext | null>(null)\n"],"mappings":";;AAGA,IAAa,IAAc,EAAqC,KAAK"}
@@ -6,21 +6,25 @@ export interface FluentiConfig {
6
6
  /** Active locale code */
7
7
  locale: string;
8
8
  /** Static message catalogs keyed by locale */
9
- messages?: AllMessages;
9
+ messages?: AllMessages | undefined;
10
10
  /** Async loader for lazy-loading locale messages */
11
- loadMessages?: (locale: string) => Promise<Messages | {
11
+ loadMessages?: ((locale: string) => Promise<Messages | {
12
12
  default: Messages;
13
- }>;
13
+ }>) | undefined;
14
14
  /** Fallback locale when a translation is missing */
15
- fallbackLocale?: string;
15
+ fallbackLocale?: string | undefined;
16
16
  /** Custom fallback chains per locale */
17
- fallbackChain?: Record<string, string[]>;
17
+ fallbackChain?: Record<string, string[]> | undefined;
18
18
  /** Date format styles */
19
- dateFormats?: DateFormatOptions;
19
+ dateFormats?: DateFormatOptions | undefined;
20
20
  /** Number format styles */
21
- numberFormats?: NumberFormatOptions;
21
+ numberFormats?: NumberFormatOptions | undefined;
22
22
  /** Missing message handler */
23
- missing?: (locale: Locale, id: string) => string | undefined;
23
+ missing?: ((locale: Locale, id: string) => string | undefined) | undefined;
24
+ /** Runtime diagnostics (pre-created instance or config) */
25
+ diagnostics?: unknown | undefined;
26
+ /** Custom interpolation function for full ICU support at runtime */
27
+ interpolate?: ((message: string, values: Record<string, unknown> | undefined, locale: string, formatters?: Record<string, unknown>) => string) | undefined;
24
28
  }
25
29
  /**
26
30
  * The object returned by `createFluenti()`.
@@ -1 +1 @@
1
- {"version":3,"file":"create-fluenti.d.ts","sourceRoot":"","sources":["../src/create-fluenti.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,IAAI,sBAAsB,EACjD,eAAe,EACf,MAAM,EACN,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EAClB,MAAM,eAAe,CAAA;AAEtB;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,WAAW,CAAA;IACtB,oDAAoD;IACpD,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG;QAAE,OAAO,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAA;IAC5E,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACxC,yBAAyB;IACzB,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,2BAA2B;IAC3B,aAAa,CAAC,EAAE,mBAAmB,CAAA;IACnC,8BAA8B;IAC9B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;CAC7D;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,CAAC,EAAE;QACD,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAAA;QACnF,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,eAAe,CAAA;KACtE,CAAA;IACD,iDAAiD;IACjD,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,eAAe,CAAA;IAC5D,mDAAmD;IACnD,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,eAAe,CAAA;IACrD,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,yDAAyD;IACzD,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5C,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAA;IAClB,iEAAiE;IACjE,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAChD,6EAA6E;IAC7E,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;IAC7C,mEAAmE;IACnE,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,eAAe,GAAG,SAAS,CAAA;IACjE,qEAAqE;IACrE,IAAI,EAAE,sBAAsB,CAAA;IAC5B,gEAAgE;IAChE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,eAAe,CAAA;IAC9E,iEAAiE;IACjE,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAA;IAC1D,wDAAwD;IACxD,UAAU,EAAE,MAAM,MAAM,EAAE,CAAA;IAC1B,qDAAqD;IACrD,aAAa,EAAE,MAAM,EAAE,CAAA;CACxB;AAYD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,CAmJpE"}
1
+ {"version":3,"file":"create-fluenti.d.ts","sourceRoot":"","sources":["../src/create-fluenti.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,IAAI,sBAAsB,EACjD,eAAe,EACf,MAAM,EACN,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EAClB,MAAM,eAAe,CAAA;AAEtB;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;IAClC,oDAAoD;IACpD,YAAY,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG;QAAE,OAAO,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAA;IAC1F,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,CAAA;IACpD,yBAAyB;IACzB,WAAW,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAA;IAC3C,2BAA2B;IAC3B,aAAa,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAA;IAC/C,8BAA8B;IAC9B,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;IAC1E,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACjC,oEAAoE;IACpE,WAAW,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;CAC3J;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,CAAC,EAAE;QACD,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAAA;QACnF,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,eAAe,CAAA;KACtE,CAAA;IACD,iDAAiD;IACjD,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,eAAe,CAAA;IAC5D,mDAAmD;IACnD,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,eAAe,CAAA;IACrD,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,yDAAyD;IACzD,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5C,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAA;IAClB,iEAAiE;IACjE,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAChD,6EAA6E;IAC7E,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;IAC7C,mEAAmE;IACnE,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,eAAe,GAAG,SAAS,CAAA;IACjE,qEAAqE;IACrE,IAAI,EAAE,sBAAsB,CAAA;IAC5B,gEAAgE;IAChE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,eAAe,CAAA;IAC9E,iEAAiE;IACjE,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAA;IAC1D,wDAAwD;IACxD,UAAU,EAAE,MAAM,MAAM,EAAE,CAAA;IAC1B,qDAAqD;IACrD,aAAa,EAAE,MAAM,EAAE,CAAA;CACxB;AAYD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,CA2KpE"}
@@ -20,17 +20,24 @@ function d(n) {
20
20
  };
21
21
  }
22
22
  function f(e, i) {
23
- let a = /<(\d+)(?:\/>|(>)([\s\S]*?)<\/\1>)/g, o = [], s = 0, c;
24
- for (a.lastIndex = 0, c = a.exec(e); c !== null;) {
25
- c.index > s && o.push(e.slice(s, c.index));
26
- let t = Number(c[1]), r = c[2] === void 0, l = c[3] ?? "", u = i[t];
27
- if (u) if (r) o.push(n(u, { key: `trans-${t}` }));
28
- else {
29
- let e = f(l, i);
30
- o.push(n(u, { key: `trans-${t}` }, e));
23
+ let a = /<(\d+)(?:\/>|(>)([\s\S]*?)<\/\1>)/g, o = [], s = 0, c = 0, l;
24
+ for (a.lastIndex = 0, l = a.exec(e); l !== null;) {
25
+ l.index > s && o.push(e.slice(s, l.index));
26
+ let t = Number(l[1]), r = l[2] === void 0, u = l[3] ?? "";
27
+ if (!Number.isInteger(t) || t < 0 || t >= i.length) {
28
+ u && o.push(u), s = a.lastIndex, l = a.exec(e);
29
+ continue;
31
30
  }
32
- else o.push(l);
33
- s = a.lastIndex, c = a.exec(e);
31
+ let d = i[t];
32
+ if (d) {
33
+ let e = `trans-${c++}`;
34
+ if (r) o.push(n(d, { key: e }));
35
+ else {
36
+ let t = f(u, i);
37
+ o.push(n(d, { key: e }, t));
38
+ }
39
+ } else u && o.push(u);
40
+ s = a.lastIndex, l = a.exec(e);
34
41
  }
35
42
  return s < e.length && o.push(e.slice(s)), o.length === 1 ? o[0] : r(t, null, ...o);
36
43
  }
@@ -68,4 +75,4 @@ function h(e, t, n, r) {
68
75
  //#endregion
69
76
  export { m as a, c, h as i, f as l, s as n, a as o, l as r, d as s, o as t };
70
77
 
71
- //# sourceMappingURL=icu-rich-BOtj4Oxu.js.map
78
+ //# sourceMappingURL=icu-rich-ChVWsA7C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icu-rich-ChVWsA7C.js","names":[],"sources":["../src/components/trans-core.ts","../src/components/icu-rich.tsx"],"sourcesContent":["import {\n Children,\n isValidElement,\n cloneElement,\n createElement,\n Fragment,\n type ReactNode,\n type ReactElement,\n} from 'react'\nimport { hashMessage, offsetIndices } from '@fluenti/core/internal'\n\nexport { hashMessage }\n\n/**\n * Extract a message string and component list from React children.\n *\n * Converts:\n * <Trans>Hello <b>{name}</b>, welcome!</Trans>\n * Into:\n * message: \"Hello <0>{name}</0>, welcome!\"\n * components: [<b>{name}</b>]\n *\n * @internal\n */\nexport function extractMessage(children: ReactNode): {\n message: string\n components: ReactElement[]\n} {\n const components: ReactElement[] = []\n let message = ''\n\n Children.forEach(children, (child) => {\n if (typeof child === 'string' || typeof child === 'number') {\n message += String(child)\n } else if (isValidElement(child)) {\n if (child.type === Fragment) {\n const inner = extractMessage((child.props as { children?: ReactNode }).children)\n message += offsetIndices(inner.message, components.length)\n components.push(...inner.components)\n return\n }\n\n const idx = components.length\n const inner = extractMessage((child.props as { children?: ReactNode }).children)\n components.push(child)\n components.push(...inner.components)\n if (inner.message === '' && inner.components.length === 0) {\n message += `<${idx}/>`\n } else {\n message += `<${idx}>${offsetIndices(inner.message, idx + 1)}</${idx}>`\n }\n }\n })\n\n return { message, components }\n}\n\n/**\n * Reconstruct a translated message string back into React elements.\n *\n * Parses \"<0>content</0>\" tags and replaces them with cloned components.\n *\n * @internal\n */\nexport function reconstruct(\n translated: string,\n components: ReactElement[],\n): ReactNode {\n const COMBINED_RE = /<(\\d+)(?:\\/>|(>)([\\s\\S]*?)<\\/\\1>)/g\n const result: ReactNode[] = []\n let lastIndex = 0\n let keyCounter = 0\n let match: RegExpExecArray | null\n\n COMBINED_RE.lastIndex = 0\n match = COMBINED_RE.exec(translated)\n\n while (match !== null) {\n if (match.index > lastIndex) {\n result.push(translated.slice(lastIndex, match.index))\n }\n\n const idx = Number(match[1])\n const isSelfClosing = match[2] === undefined\n const innerText = match[3] ?? ''\n\n if (!Number.isInteger(idx) || idx < 0 || idx >= components.length) {\n if (innerText) result.push(innerText)\n lastIndex = COMBINED_RE.lastIndex\n match = COMBINED_RE.exec(translated)\n continue\n }\n\n const component = components[idx]\n\n if (component) {\n // Use keyCounter (not idx) so duplicate component indices get unique keys\n const key = `trans-${keyCounter++}`\n if (isSelfClosing) {\n result.push(cloneElement(component, { key }))\n } else {\n const innerContent = reconstruct(innerText, components)\n result.push(cloneElement(component, { key }, innerContent))\n }\n } else {\n // Only push non-empty text to avoid inserting blank DOM nodes\n if (innerText) result.push(innerText)\n }\n\n lastIndex = COMBINED_RE.lastIndex\n match = COMBINED_RE.exec(translated)\n }\n\n if (lastIndex < translated.length) {\n result.push(translated.slice(lastIndex))\n }\n\n return result.length === 1 ? result[0]! : createElement(Fragment, null, ...result)\n}\n","import type { MessageDescriptor } from '@fluenti/core'\nimport {\n buildICUPluralMessage,\n buildICUSelectMessage,\n normalizeSelectForms,\n offsetIndices,\n} from '@fluenti/core/internal'\nimport type { ReactElement, ReactNode } from 'react'\nimport { extractMessage, reconstruct } from './trans-core'\n\nexport { buildICUPluralMessage, buildICUSelectMessage, normalizeSelectForms }\n\nexport interface RichMessagePart {\n message: string\n components: ReactElement[]\n}\n\nexport function serializeRichNode(node: ReactNode): RichMessagePart {\n const extracted = extractMessage(node)\n return {\n message: extracted.message,\n components: extracted.components,\n }\n}\n\nexport function serializeRichForms<T extends string>(\n keys: readonly T[],\n forms: Partial<Record<T, ReactNode>> & Record<string, ReactNode | undefined>,\n): {\n messages: Partial<Record<T, string>> & Record<string, string>\n components: ReactElement[]\n} {\n const components: ReactElement[] = []\n const messages: Record<string, string> = {}\n\n for (const key of keys) {\n const value = forms[key]\n if (value === undefined) continue\n const extracted = serializeRichNode(value)\n messages[key] = offsetIndices(extracted.message, components.length)\n components.push(...extracted.components)\n }\n\n for (const [key, value] of Object.entries(forms)) {\n if (keys.includes(key as T) || value === undefined) continue\n const extracted = serializeRichNode(value)\n messages[key] = offsetIndices(extracted.message, components.length)\n components.push(...extracted.components)\n }\n\n return { messages: messages as Partial<Record<T, string>> & Record<string, string>, components }\n}\n\nexport function renderRichTranslation(\n descriptor: MessageDescriptor,\n values: Record<string, unknown> | undefined,\n translate: (descriptor: MessageDescriptor, values?: Record<string, unknown>) => string,\n components: ReactElement[],\n): ReactNode {\n const translated = translate(descriptor, values)\n return components.length > 0 ? reconstruct(translated, components) : translated\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ let e=require(`react`),t=require(`@fluenti/core/internal`);function n(r){let i=[],a=``;return e.Children.forEach(r,r=>{if(typeof r==`string`||typeof r==`number`)a+=String(r);else if((0,e.isValidElement)(r)){if(r.type===e.Fragment){let e=n(r.props.children);a+=(0,t.offsetIndices)(e.message,i.length),i.push(...e.components);return}let o=i.length,s=n(r.props.children);i.push(r),i.push(...s.components),s.message===``&&s.components.length===0?a+=`<${o}/>`:a+=`<${o}>${(0,t.offsetIndices)(s.message,o+1)}</${o}>`}}),{message:a,components:i}}function r(t,n){let i=/<(\d+)(?:\/>|(>)([\s\S]*?)<\/\1>)/g,a=[],o=0,s=0,c;for(i.lastIndex=0,c=i.exec(t);c!==null;){c.index>o&&a.push(t.slice(o,c.index));let l=Number(c[1]),u=c[2]===void 0,d=c[3]??``;if(!Number.isInteger(l)||l<0||l>=n.length){d&&a.push(d),o=i.lastIndex,c=i.exec(t);continue}let f=n[l];if(f){let t=`trans-${s++}`;if(u)a.push((0,e.cloneElement)(f,{key:t}));else{let i=r(d,n);a.push((0,e.cloneElement)(f,{key:t},i))}}else d&&a.push(d);o=i.lastIndex,c=i.exec(t)}return o<t.length&&a.push(t.slice(o)),a.length===1?a[0]:(0,e.createElement)(e.Fragment,null,...a)}function i(e){let t=n(e);return{message:t.message,components:t.components}}function a(e,n){let r=[],a={};for(let o of e){let e=n[o];if(e===void 0)continue;let s=i(e);a[o]=(0,t.offsetIndices)(s.message,r.length),r.push(...s.components)}for(let[o,s]of Object.entries(n)){if(e.includes(o)||s===void 0)continue;let n=i(s);a[o]=(0,t.offsetIndices)(n.message,r.length),r.push(...n.components)}return{messages:a,components:r}}function o(e,t,n,i){let a=n(e,t);return i.length>0?r(a,i):a}Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return o}});
2
+ //# sourceMappingURL=icu-rich-CotMVC_x.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icu-rich-CotMVC_x.cjs","names":[],"sources":["../src/components/trans-core.ts","../src/components/icu-rich.tsx"],"sourcesContent":["import {\n Children,\n isValidElement,\n cloneElement,\n createElement,\n Fragment,\n type ReactNode,\n type ReactElement,\n} from 'react'\nimport { hashMessage, offsetIndices } from '@fluenti/core/internal'\n\nexport { hashMessage }\n\n/**\n * Extract a message string and component list from React children.\n *\n * Converts:\n * <Trans>Hello <b>{name}</b>, welcome!</Trans>\n * Into:\n * message: \"Hello <0>{name}</0>, welcome!\"\n * components: [<b>{name}</b>]\n *\n * @internal\n */\nexport function extractMessage(children: ReactNode): {\n message: string\n components: ReactElement[]\n} {\n const components: ReactElement[] = []\n let message = ''\n\n Children.forEach(children, (child) => {\n if (typeof child === 'string' || typeof child === 'number') {\n message += String(child)\n } else if (isValidElement(child)) {\n if (child.type === Fragment) {\n const inner = extractMessage((child.props as { children?: ReactNode }).children)\n message += offsetIndices(inner.message, components.length)\n components.push(...inner.components)\n return\n }\n\n const idx = components.length\n const inner = extractMessage((child.props as { children?: ReactNode }).children)\n components.push(child)\n components.push(...inner.components)\n if (inner.message === '' && inner.components.length === 0) {\n message += `<${idx}/>`\n } else {\n message += `<${idx}>${offsetIndices(inner.message, idx + 1)}</${idx}>`\n }\n }\n })\n\n return { message, components }\n}\n\n/**\n * Reconstruct a translated message string back into React elements.\n *\n * Parses \"<0>content</0>\" tags and replaces them with cloned components.\n *\n * @internal\n */\nexport function reconstruct(\n translated: string,\n components: ReactElement[],\n): ReactNode {\n const COMBINED_RE = /<(\\d+)(?:\\/>|(>)([\\s\\S]*?)<\\/\\1>)/g\n const result: ReactNode[] = []\n let lastIndex = 0\n let keyCounter = 0\n let match: RegExpExecArray | null\n\n COMBINED_RE.lastIndex = 0\n match = COMBINED_RE.exec(translated)\n\n while (match !== null) {\n if (match.index > lastIndex) {\n result.push(translated.slice(lastIndex, match.index))\n }\n\n const idx = Number(match[1])\n const isSelfClosing = match[2] === undefined\n const innerText = match[3] ?? ''\n\n if (!Number.isInteger(idx) || idx < 0 || idx >= components.length) {\n if (innerText) result.push(innerText)\n lastIndex = COMBINED_RE.lastIndex\n match = COMBINED_RE.exec(translated)\n continue\n }\n\n const component = components[idx]\n\n if (component) {\n // Use keyCounter (not idx) so duplicate component indices get unique keys\n const key = `trans-${keyCounter++}`\n if (isSelfClosing) {\n result.push(cloneElement(component, { key }))\n } else {\n const innerContent = reconstruct(innerText, components)\n result.push(cloneElement(component, { key }, innerContent))\n }\n } else {\n // Only push non-empty text to avoid inserting blank DOM nodes\n if (innerText) result.push(innerText)\n }\n\n lastIndex = COMBINED_RE.lastIndex\n match = COMBINED_RE.exec(translated)\n }\n\n if (lastIndex < translated.length) {\n result.push(translated.slice(lastIndex))\n }\n\n return result.length === 1 ? result[0]! : createElement(Fragment, null, ...result)\n}\n","import type { MessageDescriptor } from '@fluenti/core'\nimport {\n buildICUPluralMessage,\n buildICUSelectMessage,\n normalizeSelectForms,\n offsetIndices,\n} from '@fluenti/core/internal'\nimport type { ReactElement, ReactNode } from 'react'\nimport { extractMessage, reconstruct } from './trans-core'\n\nexport { buildICUPluralMessage, buildICUSelectMessage, normalizeSelectForms }\n\nexport interface RichMessagePart {\n message: string\n components: ReactElement[]\n}\n\nexport function serializeRichNode(node: ReactNode): RichMessagePart {\n const extracted = extractMessage(node)\n return {\n message: extracted.message,\n components: extracted.components,\n }\n}\n\nexport function serializeRichForms<T extends string>(\n keys: readonly T[],\n forms: Partial<Record<T, ReactNode>> & Record<string, ReactNode | undefined>,\n): {\n messages: Partial<Record<T, string>> & Record<string, string>\n components: ReactElement[]\n} {\n const components: ReactElement[] = []\n const messages: Record<string, string> = {}\n\n for (const key of keys) {\n const value = forms[key]\n if (value === undefined) continue\n const extracted = serializeRichNode(value)\n messages[key] = offsetIndices(extracted.message, components.length)\n components.push(...extracted.components)\n }\n\n for (const [key, value] of Object.entries(forms)) {\n if (keys.includes(key as T) || value === undefined) continue\n const extracted = serializeRichNode(value)\n messages[key] = offsetIndices(extracted.message, components.length)\n components.push(...extracted.components)\n }\n\n return { messages: messages as Partial<Record<T, string>> & Record<string, string>, components }\n}\n\nexport function renderRichTranslation(\n descriptor: MessageDescriptor,\n values: Record<string, unknown> | undefined,\n translate: (descriptor: MessageDescriptor, values?: Record<string, unknown>) => string,\n components: ReactElement[],\n): ReactNode {\n const translated = translate(descriptor, values)\n return components.length > 0 ? reconstruct(translated, components) : translated\n}\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./icu-rich-vPU-0wGQ.cjs`);let t=require(`react`),n=require(`@fluenti/core`),r=require(`react/jsx-runtime`),i=require(`@fluenti/core/internal`);function a(e){let t={};for(let[n,r]of Object.entries(e))t[n]=typeof r==`object`&&r&&`default`in r?r.default:r;return t}function o(e){let{locale:r,messages:i,loadMessages:o,fallbackLocale:s,fallbackChain:c,dateFormats:l,numberFormats:u,missing:d}=e,[f,p]=(0,t.useState)(r),[m,h]=(0,t.useState)(!1),[g,_]=(0,t.useState)(i?a(i):{}),[v,y]=(0,t.useState)(i?Object.keys(i):[]),b=(0,t.useRef)(g);b.current=g;let x=(0,t.useRef)(0),S=(0,t.useMemo)(()=>{let e={locale:f,messages:g};return s!==void 0&&(e.fallbackLocale=s),c!==void 0&&(e.fallbackChain=c),l!==void 0&&(e.dateFormats=l),u!==void 0&&(e.numberFormats=u),d!==void 0&&(e.missing=d),(0,n.createFluentiCore)(e)},[f,g,s,c,l,u,d]);(0,t.useEffect)(()=>{r!==f&&C(r)},[r]);let C=(0,t.useCallback)(async e=>{let t=++x.current;if(b.current[e]&&!o){p(e);return}if(b.current[e]){p(e);return}if(!o){console.warn(`[fluenti] No messages for locale "${e}" and no loadMessages function provided`);return}h(!0);try{let n=await o(e);if(t!==x.current)return;let r=typeof n==`object`&&n&&`default`in n?n.default:n;_(t=>({...t,[e]:r})),y(t=>[...new Set([...t,e])]),p(e)}catch(n){t===x.current&&console.error(`[fluenti] Failed to load locale "${e}"`,n)}finally{t===x.current&&h(!1)}},[o]),w=(0,t.useCallback)(async e=>{if(!(b.current[e]||!o))try{let t=await o(e),n=typeof t==`object`&&t&&`default`in t?t.default:t;_(t=>({...t,[e]:n})),y(t=>[...new Set([...t,e])])}catch{}},[o]),T=(0,t.useCallback)((e,t)=>{let n=g[t??f];return n!==void 0&&e in n},[g,f]),E=(0,t.useCallback)((e,t)=>{let n=g[t??f];if(n)return n[e]},[g,f]);return(0,t.useMemo)(()=>({t:S.t.bind(S),d:S.d.bind(S),n:S.n.bind(S),locale:f,setLocale:C,isLoading:m,preloadLocale:w,te:T,tm:E,i18n:S,format:S.format.bind(S),loadMessages:S.loadMessages.bind(S),getLocales:S.getLocales.bind(S),loadedLocales:v}),[S,f,C,m,w,T,E,v])}var s=(0,t.createContext)(null);function c(e){globalThis.__fluenti_i18n=e}function l(e){let t={};for(let[n,r]of Object.entries(e))t[n]=typeof r==`object`&&r&&`default`in r?r.default:r;return t}var u=Symbol.for(`fluenti.runtime.react.v1`);function d(){let e=globalThis[u];return typeof e==`object`&&e?e:null}function f({instance:e,children:n}){let i=(0,t.useMemo)(()=>({t:e.t,d:e.d,n:e.n,format:e.format,loadMessages:e.loadMessages,getLocales:e.getLocales,locale:e.locale,setLocale:e.setLocale,isLoading:e.isLoading,loadedLocales:e.loadedLocales,preloadLocale:e.preloadLocale,te:e.te,tm:e.tm,i18n:e.i18n}),[e]);return(0,r.jsx)(s.Provider,{value:i,children:n})}function p(e){return e.instance?(0,r.jsx)(f,{instance:e.instance,children:e.children}):(0,r.jsx)(m,{...e})}function m({locale:e,fallbackLocale:i,messages:a,loadMessages:o,fallbackChain:u,dateFormats:f,numberFormats:p,missing:m,diagnostics:h,children:g}){let _=e??`en`,[v,y]=(0,t.useState)(_),[b,x]=(0,t.useState)(!1),[S,C]=(0,t.useState)(a?l(a):{}),[w,T]=(0,t.useState)(a?Object.keys(a):[]),E=(0,t.useRef)(S);E.current=S;let D=(0,t.useRef)(0),O=(0,t.useMemo)(()=>{let e={locale:v,messages:S};return i!==void 0&&(e.fallbackLocale=i),u!==void 0&&(e.fallbackChain=u),f!==void 0&&(e.dateFormats=f),p!==void 0&&(e.numberFormats=p),m!==void 0&&(e.missing=m),h!==void 0&&(e.diagnostics=h),(0,n.createFluentiCore)(e)},[v,S,i,u,f,p,m,h]);(0,t.useEffect)(()=>{c(O)},[O]),(0,t.useEffect)(()=>{_!==v&&k(_)},[_]);let k=(0,t.useCallback)(async e=>{let t=++D.current;if(E.current[e]&&!o){y(e);return}let n=o?d():null;if(E.current[e]){n?.__switchLocale&&await n.__switchLocale(e),y(e);return}if(!o){console.warn(`[fluenti] No messages for locale "${e}" and no loadMessages function provided`);return}x(!0);try{let r=await o(e);if(t!==D.current)return;let i=typeof r==`object`&&r&&`default`in r?r.default:r;C(t=>({...t,[e]:i})),T(t=>[...new Set([...t,e])]),n?.__switchLocale&&await n.__switchLocale(e),y(e)}catch(n){t===D.current&&console.error(`[fluenti] Failed to load locale "${e}"`,n)}finally{t===D.current&&x(!1)}},[o]),A=(0,t.useCallback)(async e=>{let t=d();if(!(E.current[e]||!o))try{let n=await o(e),r=typeof n==`object`&&n&&`default`in n?n.default:n;C(t=>({...t,[e]:r})),T(t=>[...new Set([...t,e])]),t?.__preloadLocale&&await t.__preloadLocale(e)}catch{}},[o]),j=(0,t.useCallback)((e,t)=>{let n=E.current[t??v];return n!==void 0&&e in n},[v]),M=(0,t.useCallback)((e,t)=>{let n=E.current[t??v];if(n)return n[e]},[v]),N=(0,t.useMemo)(()=>({t:O.t.bind(O),d:O.d.bind(O),n:O.n.bind(O),format:O.format.bind(O),loadMessages:O.loadMessages.bind(O),getLocales:O.getLocales.bind(O),locale:v,setLocale:k,isLoading:b,loadedLocales:w,preloadLocale:A,te:j,tm:M,i18n:O}),[O,v,k,b,w,A,j,M]);return(0,r.jsx)(s.Provider,{value:N,children:g})}function h(){let e=(0,t.useContext)(s);if(!e)throw Error(`[fluenti] useI18n() must be used within an <I18nProvider>. Wrap your app with <I18nProvider> to provide i18n context.`);return e}var g=((...e)=>{throw Error("[fluenti] `t` imported from '@fluenti/react' is a compile-time API. Use it only with the Fluenti build transform inside a component or custom hook. For runtime lookups, use useI18n().t(...).")}),_=(0,t.memo)(function({children:n,id:a,context:o,comment:c,tag:l,render:u,__id:d,__message:f,__components:p}){let m=(0,t.useContext)(s);if(!m)throw Error(`[fluenti] <Trans> must be used within an <I18nProvider>`);let h=f!==void 0,{message:g,components:_}=(0,t.useMemo)(()=>h?{message:f,components:p??[]}:e.r(n),[h,f,p,n]),v=(0,t.useMemo)(()=>a??d??(0,i.hashMessage)(g,o),[a,d,g,o]),y=e.i(m.t({id:v,message:g,...o===void 0?{}:{context:o},...c===void 0?{}:{comment:c}}),_);return u?u(y):l?(0,t.createElement)(l,null,y):(0,r.jsx)(r.Fragment,{children:y})}),v=(0,t.memo)(function({value:n,id:a,context:o,comment:c,zero:l,one:u,two:d,few:f,many:p,other:m,offset:h}){let g=(0,t.useContext)(s);if(!g)throw Error(`[fluenti] <Plural> must be used within an <I18nProvider>`);let{messages:_,components:v}=e.n(i.PLURAL_CATEGORIES,{zero:l,one:u,two:d,few:f,many:p,other:m}),y=(0,i.buildICUPluralMessage)({..._.zero!==void 0&&{zero:_.zero},..._.one!==void 0&&{one:_.one},..._.two!==void 0&&{two:_.two},..._.few!==void 0&&{few:_.few},..._.many!==void 0&&{many:_.many},other:_.other??``},h);return(0,r.jsx)(r.Fragment,{children:e.t({id:a??(o===void 0?y:(0,i.hashMessage)(y,o)),message:y,...o===void 0?{}:{context:o},...c===void 0?{}:{comment:c}},{count:n},(e,t)=>g.t(e,t),v)})}),y=(0,t.memo)(function(n){let a=(0,t.useContext)(s);if(!a)throw Error(`[fluenti] <Select> must be used within an <I18nProvider>`);let{value:o,id:c,context:l,comment:u,other:d,options:f,tag:p,...m}=n,h=f===void 0?{...Object.fromEntries(Object.entries(m).filter(([e])=>![`value`,`id`,`context`,`comment`,`options`,`other`,`tag`].includes(e))),other:d}:{...f,other:d},g=[...Object.keys(h).filter(e=>e!==`other`),`other`],{messages:_,components:v}=e.n(g,h),y=(0,i.normalizeSelectForms)(Object.fromEntries([...g].map(e=>[e,_[e]??``]))),b=(0,i.buildICUSelectMessage)(y.forms),x=e.t({id:c??(l===void 0?b:(0,i.hashMessage)(b,l)),message:b,...l===void 0?{}:{context:l},...u===void 0?{}:{comment:u}},{value:y.valueMap[o]??`other`},(e,t)=>a.t(e,t),v);return p?(0,t.createElement)(p,null,x):(0,r.jsx)(r.Fragment,{children:x})}),b=(0,t.memo)(function({value:e,style:n}){let i=(0,t.useContext)(s);if(!i)throw Error(`[fluenti] <DateTime> must be used within an <I18nProvider>`);return(0,r.jsx)(r.Fragment,{children:i.d(e,n)})}),x=(0,t.memo)(function({value:e,style:n}){let i=(0,t.useContext)(s);if(!i)throw Error(`[fluenti] <Number> must be used within an <I18nProvider>`);return(0,r.jsx)(r.Fragment,{children:i.n(e,n)})});exports.DateTime=b,exports.I18nContext=s,exports.I18nProvider=p,exports.NumberFormat=x,exports.Plural=v,exports.Select=y,exports.Trans=_,exports.createFluenti=o,Object.defineProperty(exports,`msg`,{enumerable:!0,get:function(){return n.msg}}),exports.t=g,exports.useI18n=h;
2
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./context-DVbvrSE8.cjs`);let t=require(`react`),n=require(`@fluenti/core`),r=require(`react/jsx-runtime`);function i(e){let t={};for(let[n,r]of Object.entries(e))t[n]=typeof r==`object`&&r&&`default`in r?r.default:r;return t}function a(e){let{locale:r,messages:a,loadMessages:o,fallbackLocale:s,fallbackChain:c,dateFormats:l,numberFormats:u,missing:d,diagnostics:f,interpolate:p}=e,[m,h]=(0,t.useState)(r),[g,_]=(0,t.useState)(!1),[v,y]=(0,t.useState)(a?i(a):{}),[b,x]=(0,t.useState)(a?Object.keys(a):[]),S=(0,t.useRef)(v);S.current=v;let C=(0,t.useRef)(0),w=Symbol.for(`fluenti.runtime.react.v1`);function T(){let e=globalThis[w];return typeof e==`object`&&e?e:null}let E=(0,t.useMemo)(()=>{let e={locale:m,messages:v};return s!==void 0&&(e.fallbackLocale=s),c!==void 0&&(e.fallbackChain=c),l!==void 0&&(e.dateFormats=l),u!==void 0&&(e.numberFormats=u),d!==void 0&&(e.missing=d),f!==void 0&&(e.diagnostics=f),p!==void 0&&(e.interpolate=p),(0,n.createFluentiCore)(e)},[m,v,s,c,l,u,d,f,p]);(0,t.useEffect)(()=>{r!==m&&D(r)},[r]);let D=(0,t.useCallback)(async e=>{let t=++C.current,n=o?T():null;if(S.current[e]&&!o){h(e);return}if(S.current[e]){n?.__switchLocale&&await n.__switchLocale(e),h(e);return}if(!o){console.warn(`[fluenti] No messages for locale "${e}" and no loadMessages function provided`);return}_(!0);try{let r=await o(e);if(t!==C.current)return;let i=typeof r==`object`&&r&&`default`in r?r.default:r;if(n?.__switchLocale&&await n.__switchLocale(e),t!==C.current)return;y(t=>({...t,[e]:i})),x(t=>[...new Set([...t,e])]),h(e)}catch(n){t===C.current&&console.error(`[fluenti] Failed to load locale "${e}"`,n)}finally{t===C.current&&_(!1)}},[o]),O=(0,t.useCallback)(async e=>{if(!(S.current[e]||!o))try{let t=await o(e),n=typeof t==`object`&&t&&`default`in t?t.default:t;y(t=>({...t,[e]:n})),x(t=>[...new Set([...t,e])]);let r=T();r?.__preloadLocale&&await r.__preloadLocale(e)}catch{}},[o]),k=(0,t.useCallback)((e,t)=>{let n=v[t??m];return n!==void 0&&e in n},[v,m]),A=(0,t.useCallback)((e,t)=>{let n=v[t??m];if(n)return n[e]},[v,m]);return(0,t.useMemo)(()=>({t:E.t.bind(E),d:E.d.bind(E),n:E.n.bind(E),locale:m,setLocale:D,isLoading:g,preloadLocale:O,te:k,tm:A,i18n:E,format:E.format.bind(E),loadMessages:E.loadMessages.bind(E),getLocales:E.getLocales.bind(E),loadedLocales:b}),[E,m,D,g,O,k,A,b])}function o(e){globalThis.__fluenti_i18n=e}function s({instance:n,children:i}){let a=(0,t.useMemo)(()=>({t:n.t,d:n.d,n:n.n,format:n.format,loadMessages:n.loadMessages,getLocales:n.getLocales,locale:n.locale,setLocale:n.setLocale,isLoading:n.isLoading,loadedLocales:n.loadedLocales,preloadLocale:n.preloadLocale,te:n.te,tm:n.tm,i18n:n.i18n}),[n]);return(0,r.jsx)(e.t.Provider,{value:a,children:i})}function c(e){return e.instance?(0,r.jsx)(s,{instance:e.instance,children:e.children}):(0,r.jsx)(l,{...e})}function l({locale:e,fallbackLocale:n,messages:i,loadMessages:c,fallbackChain:l,dateFormats:u,numberFormats:d,missing:f,diagnostics:p,interpolate:m,children:h}){let g=a({locale:e??`en`,messages:i,loadMessages:c,fallbackLocale:n,fallbackChain:l,dateFormats:u,numberFormats:d,missing:f,diagnostics:p,interpolate:m});return(0,t.useEffect)(()=>{o(g.i18n)},[g.i18n]),(0,r.jsx)(s,{instance:g,children:h})}function u(){let n=(0,t.useContext)(e.t);if(!n)throw Error(`[fluenti] useI18n() must be used within an <I18nProvider>. Wrap your app with <I18nProvider> to provide i18n context.`);return n}var d=((...e)=>{throw Error("[fluenti] `t` imported from '@fluenti/react' is a compile-time API. Use it only with the Fluenti build transform inside a component or custom hook. For runtime lookups, use useI18n().t(...).")});exports.I18nContext=e.t,exports.I18nProvider=c,exports.createFluenti=a,Object.defineProperty(exports,`msg`,{enumerable:!0,get:function(){return n.msg}}),exports.t=d,exports.useI18n=u;
3
3
  //# sourceMappingURL=index.cjs.map