@fluenti/react 0.2.0 → 0.3.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 (59) hide show
  1. package/dist/components/DateTime.d.ts +2 -2
  2. package/dist/components/DateTime.d.ts.map +1 -1
  3. package/dist/components/Number.d.ts +2 -2
  4. package/dist/components/Number.d.ts.map +1 -1
  5. package/dist/components/Plural.d.ts +2 -2
  6. package/dist/components/Plural.d.ts.map +1 -1
  7. package/dist/components/Select.d.ts +5 -3
  8. package/dist/components/Select.d.ts.map +1 -1
  9. package/dist/components/Trans.d.ts +4 -2
  10. package/dist/components/Trans.d.ts.map +1 -1
  11. package/dist/components/icu-rich.d.ts +2 -9
  12. package/dist/components/icu-rich.d.ts.map +1 -1
  13. package/dist/components/plural-core.d.ts +2 -2
  14. package/dist/components/plural-core.d.ts.map +1 -1
  15. package/dist/components/trans-core.d.ts +1 -2
  16. package/dist/components/trans-core.d.ts.map +1 -1
  17. package/dist/context.d.ts +2 -2
  18. package/dist/context.d.ts.map +1 -1
  19. package/dist/create-fluenti.d.ts +87 -0
  20. package/dist/create-fluenti.d.ts.map +1 -0
  21. package/dist/global-registry.d.ts +4 -4
  22. package/dist/global-registry.d.ts.map +1 -1
  23. package/dist/hooks/__useI18n.d.ts +2 -2
  24. package/dist/hooks/__useI18n.d.ts.map +1 -1
  25. package/dist/hooks/useI18n.d.ts +2 -2
  26. package/dist/hooks/useI18n.d.ts.map +1 -1
  27. package/dist/icu-rich-BOtj4Oxu.js +71 -0
  28. package/dist/icu-rich-BOtj4Oxu.js.map +1 -0
  29. package/dist/icu-rich-vPU-0wGQ.cjs +2 -0
  30. package/dist/icu-rich-vPU-0wGQ.cjs.map +1 -0
  31. package/dist/index.cjs +1 -1
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.ts +8 -6
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +252 -107
  36. package/dist/index.js.map +1 -1
  37. package/dist/provider.d.ts +2 -2
  38. package/dist/provider.d.ts.map +1 -1
  39. package/dist/react-runtime.d.ts.map +1 -1
  40. package/dist/server.cjs +1 -1
  41. package/dist/server.cjs.map +1 -1
  42. package/dist/server.d.ts +13 -3
  43. package/dist/server.d.ts.map +1 -1
  44. package/dist/server.js +24 -13
  45. package/dist/server.js.map +1 -1
  46. package/dist/types.d.ts +17 -10
  47. package/dist/types.d.ts.map +1 -1
  48. package/dist/vite-plugin.cjs +1 -109
  49. package/dist/vite-plugin.cjs.map +1 -1
  50. package/dist/vite-plugin.js +13 -119
  51. package/dist/vite-plugin.js.map +1 -1
  52. package/llms-full.txt +185 -0
  53. package/llms-migration.txt +272 -0
  54. package/llms.txt +62 -0
  55. package/package.json +7 -5
  56. package/dist/icu-rich-DBeWY1k6.js +0 -108
  57. package/dist/icu-rich-DBeWY1k6.js.map +0 -1
  58. package/dist/icu-rich-XY1SdM5K.cjs +0 -2
  59. package/dist/icu-rich-XY1SdM5K.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- export interface DateTimeProps {
1
+ export interface FluentiDateTimeProps {
2
2
  /** Date value to format */
3
3
  value: Date | number;
4
4
  /** Named format style */
@@ -12,5 +12,5 @@ export interface DateTimeProps {
12
12
  * <DateTime value={new Date()} style="long" />
13
13
  * ```
14
14
  */
15
- export declare const DateTime: import('react').NamedExoticComponent<DateTimeProps>;
15
+ export declare const DateTime: import('react').NamedExoticComponent<FluentiDateTimeProps>;
16
16
  //# sourceMappingURL=DateTime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DateTime.d.ts","sourceRoot":"","sources":["../../src/components/DateTime.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,KAAK,EAAE,IAAI,GAAG,MAAM,CAAA;IACpB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,qDAMnB,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,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,4DAMnB,CAAA"}
@@ -1,4 +1,4 @@
1
- export interface NumberProps {
1
+ export interface NumberFormatProps {
2
2
  /** Number value to format */
3
3
  value: number;
4
4
  /** Named format style */
@@ -12,5 +12,5 @@ export interface NumberProps {
12
12
  * <Number value={1234.56} style="currency" />
13
13
  * ```
14
14
  */
15
- export declare const NumberFormat: import('react').NamedExoticComponent<NumberProps>;
15
+ export declare const NumberFormat: import('react').NamedExoticComponent<NumberFormatProps>;
16
16
  //# sourceMappingURL=Number.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Number.d.ts","sourceRoot":"","sources":["../../src/components/Number.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,mDAMvB,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,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,yDAMvB,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- export interface PluralProps {
2
+ export interface FluentiPluralProps {
3
3
  /** The count value */
4
4
  value: number;
5
5
  /** Override the auto-generated synthetic ICU message id */
@@ -31,5 +31,5 @@ export interface PluralProps {
31
31
  * <Plural value={count} zero="No messages" one="# message" other="# messages" />
32
32
  * ```
33
33
  */
34
- export declare const Plural: import('react').NamedExoticComponent<PluralProps>;
34
+ export declare const Plural: import('react').NamedExoticComponent<FluentiPluralProps>;
35
35
  //# sourceMappingURL=Plural.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Plural.d.ts","sourceRoot":"","sources":["../../src/components/Plural.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAMxD,MAAM,WAAW,WAAW;IAC1B,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,2DAA2D;IAC3D,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,6CAA6C;IAC7C,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,+BAA+B;IAC/B,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,wCAAwC;IACxC,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,gBAAgB;IAChB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,0BAA0B;IAC1B,KAAK,EAAE,SAAS,CAAA;IAChB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,mDA+CjB,CAAA"}
1
+ {"version":3,"file":"Plural.d.ts","sourceRoot":"","sources":["../../src/components/Plural.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAMxD,MAAM,WAAW,kBAAkB;IACjC,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,2DAA2D;IAC3D,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,6CAA6C;IAC7C,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,+BAA+B;IAC/B,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,wCAAwC;IACxC,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,gBAAgB;IAChB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,0BAA0B;IAC1B,KAAK,EAAE,SAAS,CAAA;IAChB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,0DA+CjB,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- export interface SelectProps {
2
+ export interface FluentiSelectProps {
3
3
  /** The selector value */
4
4
  value: string;
5
5
  /** Override the auto-generated synthetic ICU message id */
@@ -12,8 +12,10 @@ export interface SelectProps {
12
12
  other: ReactNode;
13
13
  /** Type-safe named options. Takes precedence over direct case props. */
14
14
  options?: Record<string, ReactNode>;
15
+ /** Wrapper element tag name (e.g. 'span', 'div'). Defaults to Fragment (no wrapper). */
16
+ tag?: keyof React.JSX.IntrinsicElements;
15
17
  /** Named cases — any string key maps to a ReactNode */
16
- [key: string]: ReactNode | Record<string, ReactNode> | undefined;
18
+ [key: string]: ReactNode | Record<string, ReactNode> | keyof React.JSX.IntrinsicElements | undefined;
17
19
  }
18
20
  /**
19
21
  * `<Select>` — ICU select for gender, role, or other categorical values.
@@ -28,5 +30,5 @@ export interface SelectProps {
28
30
  * />
29
31
  * ```
30
32
  */
31
- export declare const Select: import('react').NamedExoticComponent<SelectProps>;
33
+ export declare const Select: import('react').NamedExoticComponent<FluentiSelectProps>;
32
34
  //# sourceMappingURL=Select.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../src/components/Select.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAKxD,MAAM,WAAW,WAAW;IAC1B,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,2DAA2D;IAC3D,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mBAAmB;IACnB,KAAK,EAAE,SAAS,CAAA;IAChB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACnC,uDAAuD;IACvD,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,SAAS,CAAA;CACjE;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,MAAM,mDAyCjB,CAAA"}
1
+ {"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../src/components/Select.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAKvE,MAAM,WAAW,kBAAkB;IACjC,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,2DAA2D;IAC3D,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mBAAmB;IACnB,KAAK,EAAE,SAAS,CAAA;IAChB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACnC,wFAAwF;IACxF,GAAG,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAA;IACvC,uDAAuD;IACvD,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,iBAAiB,GAAG,SAAS,CAAA;CACrG;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,MAAM,0DA0CjB,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { ReactElement, ReactNode } from 'react';
2
- export interface TransProps {
2
+ export interface FluentiTransProps {
3
3
  /** Source text with embedded components */
4
4
  children: ReactNode;
5
5
  /** Override auto-generated hash ID */
@@ -8,6 +8,8 @@ export interface TransProps {
8
8
  context?: string;
9
9
  /** Context comment for translators */
10
10
  comment?: string;
11
+ /** Wrapper element tag name (e.g. 'span', 'div'). Defaults to Fragment (no wrapper). */
12
+ tag?: keyof React.JSX.IntrinsicElements;
11
13
  /** Custom render wrapper */
12
14
  render?: (translation: ReactNode) => ReactNode;
13
15
  /** @internal Pre-computed message ID from build plugin */
@@ -25,5 +27,5 @@ export interface TransProps {
25
27
  * <Trans>Read the <a href="/docs">documentation</a> for more info.</Trans>
26
28
  * ```
27
29
  */
28
- export declare const Trans: import('react').NamedExoticComponent<TransProps>;
30
+ export declare const Trans: import('react').NamedExoticComponent<FluentiTransProps>;
29
31
  //# sourceMappingURL=Trans.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Trans.d.ts","sourceRoot":"","sources":["../../src/components/Trans.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAA;AAId,MAAM,WAAW,UAAU;IACzB,2CAA2C;IAC3C,QAAQ,EAAE,SAAS,CAAA;IACnB,sCAAsC;IACtC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,SAAS,KAAK,SAAS,CAAA;IAC9C,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,YAAY,EAAE,CAAA;CAC9B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,kDAwChB,CAAA"}
1
+ {"version":3,"file":"Trans.d.ts","sourceRoot":"","sources":["../../src/components/Trans.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAA;AAId,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,QAAQ,EAAE,SAAS,CAAA;IACnB,sCAAsC;IACtC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wFAAwF;IACxF,GAAG,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAA;IACvC,4BAA4B;IAC5B,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,SAAS,KAAK,SAAS,CAAA;IAC9C,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,YAAY,EAAE,CAAA;CAC9B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,yDA0ChB,CAAA"}
@@ -1,18 +1,11 @@
1
1
  import { MessageDescriptor } from '@fluenti/core';
2
+ import { buildICUPluralMessage, buildICUSelectMessage, normalizeSelectForms } from '@fluenti/core/internal';
2
3
  import { ReactElement, ReactNode } from 'react';
3
- import { PluralCategory } from './plural-core';
4
+ export { buildICUPluralMessage, buildICUSelectMessage, normalizeSelectForms };
4
5
  export interface RichMessagePart {
5
6
  message: string;
6
7
  components: ReactElement[];
7
8
  }
8
- export declare function buildICUPluralMessage(forms: Partial<Record<PluralCategory, string>> & {
9
- other: string;
10
- }, offset?: number): string;
11
- export declare function buildICUSelectMessage(forms: Record<string, string>): string;
12
- export declare function normalizeSelectForms(forms: Record<string, string>): {
13
- forms: Record<string, string>;
14
- valueMap: Record<string, string>;
15
- };
16
9
  export declare function serializeRichNode(node: ReactNode): RichMessagePart;
17
10
  export declare function serializeRichForms<T extends string>(keys: readonly T[], forms: Partial<Record<T, ReactNode>> & Record<string, ReactNode | undefined>): {
18
11
  messages: Partial<Record<T, string>> & Record<string, string>;
@@ -1 +1 @@
1
- {"version":3,"file":"icu-rich.d.ts","sourceRoot":"","sources":["../../src/components/icu-rich.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEpD,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAEtE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,YAAY,EAAE,CAAA;CAC3B;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAClE,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CASR;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,MAAM,CAGR;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B;IACD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC,CAqBA;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,eAAe,CAMlE;AAED,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EACjD,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC,GAC3E;IACD,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7D,UAAU,EAAE,YAAY,EAAE,CAAA;CAC3B,CAoBA;AAED,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,iBAAiB,EAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC3C,SAAS,EAAE,CAAC,UAAU,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,EACtF,UAAU,EAAE,YAAY,EAAE,GACzB,SAAS,CAGX"}
1
+ {"version":3,"file":"icu-rich.d.ts","sourceRoot":"","sources":["../../src/components/icu-rich.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EAErB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGpD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,CAAA;AAE7E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,YAAY,EAAE,CAAA;CAC3B;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,eAAe,CAMlE;AAED,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EACjD,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC,GAC3E;IACD,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7D,UAAU,EAAE,YAAY,EAAE,CAAA;CAC3B,CAoBA;AAED,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,iBAAiB,EAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC3C,SAAS,EAAE,CAAC,UAAU,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,EACtF,UAAU,EAAE,YAAY,EAAE,GACzB,SAAS,CAGX"}
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
- export declare const PLURAL_CATEGORIES: readonly ["zero", "one", "two", "few", "many", "other"];
3
- export type PluralCategory = (typeof PLURAL_CATEGORIES)[number];
2
+ import { PluralCategory } from '@fluenti/core/internal';
3
+ export { PLURAL_CATEGORIES, type PluralCategory } from '@fluenti/core/internal';
4
4
  /**
5
5
  * Resolve which plural category to use.
6
6
  * Checks for exact =0 match first, then falls back to CLDR rules.
@@ -1 +1 @@
1
- {"version":3,"file":"plural-core.d.ts","sourceRoot":"","sources":["../../src/components/plural-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,eAAO,MAAM,iBAAiB,yDAA0D,CAAA;AACxF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE/D;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,cAAc,CAKhB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAKzE"}
1
+ {"version":3,"file":"plural-core.d.ts","sourceRoot":"","sources":["../../src/components/plural-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE/E;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,cAAc,CAKhB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAKzE"}
@@ -1,5 +1,5 @@
1
1
  import { ReactNode, ReactElement } from 'react';
2
- import { hashMessage } from '@fluenti/core';
2
+ import { hashMessage } from '@fluenti/core/internal';
3
3
  export { hashMessage };
4
4
  /**
5
5
  * Extract a message string and component list from React children.
@@ -16,7 +16,6 @@ export declare function extractMessage(children: ReactNode): {
16
16
  message: string;
17
17
  components: ReactElement[];
18
18
  };
19
- export declare function offsetIndices(message: string, offset: number): string;
20
19
  /**
21
20
  * Reconstruct a translated message string back into React elements.
22
21
  *
@@ -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,EAAE,MAAM,eAAe,CAAA;AAE3C,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,CAwBA;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,YAAY,EAAE,GACzB,SAAS,CAqCX"}
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"}
package/dist/context.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { I18nContextValue } from './types';
2
- export declare const I18nContext: import('react').Context<I18nContextValue | null>;
1
+ import { FluentiContext } from './types';
2
+ export declare const I18nContext: import('react').Context<FluentiContext | null>;
3
3
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,eAAO,MAAM,WAAW,kDAA+C,CAAA"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C,eAAO,MAAM,WAAW,gDAA6C,CAAA"}
@@ -0,0 +1,87 @@
1
+ import { FluentiCoreInstanceFull as FluentInstanceExtended, CompiledMessage, Locale, Messages, AllMessages, DateFormatOptions, NumberFormatOptions, LocalizedString, MessageDescriptor } from '@fluenti/core';
2
+ /**
3
+ * Configuration for `createFluenti()`.
4
+ */
5
+ export interface FluentiConfig {
6
+ /** Active locale code */
7
+ locale: string;
8
+ /** Static message catalogs keyed by locale */
9
+ messages?: AllMessages;
10
+ /** Async loader for lazy-loading locale messages */
11
+ loadMessages?: (locale: string) => Promise<Messages | {
12
+ default: Messages;
13
+ }>;
14
+ /** Fallback locale when a translation is missing */
15
+ fallbackLocale?: string;
16
+ /** Custom fallback chains per locale */
17
+ fallbackChain?: Record<string, string[]>;
18
+ /** Date format styles */
19
+ dateFormats?: DateFormatOptions;
20
+ /** Number format styles */
21
+ numberFormats?: NumberFormatOptions;
22
+ /** Missing message handler */
23
+ missing?: (locale: Locale, id: string) => string | undefined;
24
+ }
25
+ /**
26
+ * The object returned by `createFluenti()`.
27
+ *
28
+ * Contains all i18n state and methods. Pass to `<I18nProvider instance={...}>`
29
+ * or use directly in tests/non-React contexts.
30
+ */
31
+ export interface FluentiInstance {
32
+ /** Translate a message by id with optional interpolation values */
33
+ t: {
34
+ (id: string | MessageDescriptor, values?: Record<string, unknown>): LocalizedString;
35
+ (strings: TemplateStringsArray, ...exprs: unknown[]): LocalizedString;
36
+ };
37
+ /** Format a date value for the current locale */
38
+ d: (value: Date | number, style?: string) => LocalizedString;
39
+ /** Format a number value for the current locale */
40
+ n: (value: number, style?: string) => LocalizedString;
41
+ /** Current locale */
42
+ locale: string;
43
+ /** Change the active locale (async when lazy loading) */
44
+ setLocale: (locale: string) => Promise<void>;
45
+ /** Whether a locale is currently being loaded */
46
+ isLoading: boolean;
47
+ /** Preload a locale in the background without switching to it */
48
+ preloadLocale: (locale: string) => Promise<void>;
49
+ /** Check whether a translation key exists for the given or current locale */
50
+ te: (key: string, locale?: string) => boolean;
51
+ /** Get the raw compiled message for a key without interpolation */
52
+ tm: (key: string, locale?: string) => CompiledMessage | undefined;
53
+ /** The underlying Fluent instance (escape hatch for advanced use) */
54
+ i18n: FluentInstanceExtended;
55
+ /** Format an ICU message string directly (no catalog lookup) */
56
+ format: (message: string, values?: Record<string, unknown>) => LocalizedString;
57
+ /** Merge additional messages into a locale catalog at runtime */
58
+ loadMessages: (locale: string, messages: Messages) => void;
59
+ /** Return all locale codes that have loaded messages */
60
+ getLocales: () => string[];
61
+ /** Set of locales whose messages have been loaded */
62
+ loadedLocales: string[];
63
+ }
64
+ /**
65
+ * Create a standalone Fluenti i18n instance.
66
+ *
67
+ * This is a React hook that manages locale state, message loading, and
68
+ * provides all i18n methods. The returned instance can be passed to
69
+ * `<I18nProvider instance={...}>` to share it with the component tree.
70
+ *
71
+ * @example
72
+ * ```tsx
73
+ * function App() {
74
+ * const i18n = createFluenti({
75
+ * locale: 'en',
76
+ * messages: { en: enMessages, fr: frMessages },
77
+ * })
78
+ * return (
79
+ * <I18nProvider instance={i18n}>
80
+ * <MyApp />
81
+ * </I18nProvider>
82
+ * )
83
+ * }
84
+ * ```
85
+ */
86
+ export declare function createFluenti(config: FluentiConfig): FluentiInstance;
87
+ //# sourceMappingURL=create-fluenti.d.ts.map
@@ -0,0 +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,4 +1,4 @@
1
- import { FluentInstanceExtended } from '@fluenti/core';
1
+ import { FluentiCoreInstanceFull } from '@fluenti/core';
2
2
  /**
3
3
  * Global i18n instance registry.
4
4
  *
@@ -7,12 +7,12 @@ import { FluentInstanceExtended } from '@fluenti/core';
7
7
  * `<I18nProvider>` on mount.
8
8
  */
9
9
  declare global {
10
- var __fluenti_i18n: FluentInstanceExtended | undefined;
10
+ var __fluenti_i18n: FluentiCoreInstanceFull | undefined;
11
11
  }
12
12
  /** Get the global i18n instance (set by `<I18nProvider>`). */
13
- export declare function getGlobalI18n(): FluentInstanceExtended | undefined;
13
+ export declare function getGlobalI18n(): FluentiCoreInstanceFull | undefined;
14
14
  /** Set the global i18n instance. Called by `<I18nProvider>` on mount. */
15
- export declare function setGlobalI18n(instance: FluentInstanceExtended): void;
15
+ export declare function setGlobalI18n(instance: FluentiCoreInstanceFull): void;
16
16
  /** Clear the global i18n instance. Primarily for testing. */
17
17
  export declare function clearGlobalI18n(): void;
18
18
  //# sourceMappingURL=global-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"global-registry.d.ts","sourceRoot":"","sources":["../src/global-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAE3D;;;;;;GAMG;AAEH,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,cAAc,EAAE,sBAAsB,GAAG,SAAS,CAAA;CACvD;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,IAAI,sBAAsB,GAAG,SAAS,CAElE;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,sBAAsB,GAAG,IAAI,CAEpE;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
1
+ {"version":3,"file":"global-registry.d.ts","sourceRoot":"","sources":["../src/global-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAE5D;;;;;;GAMG;AAEH,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,cAAc,EAAE,uBAAuB,GAAG,SAAS,CAAA;CACxD;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,IAAI,uBAAuB,GAAG,SAAS,CAEnE;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,uBAAuB,GAAG,IAAI,CAErE;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
@@ -1,4 +1,4 @@
1
- import { FluentInstanceExtended } from '../types';
1
+ import { FluentiCoreInstanceFull } from '@fluenti/core';
2
2
  /**
3
3
  * Internal hook used by the Vite plugin's compiled output.
4
4
  * Returns the i18n instance for direct t() calls.
@@ -8,5 +8,5 @@ import { FluentInstanceExtended } from '../types';
8
8
  *
9
9
  * @internal
10
10
  */
11
- export declare function __useI18n(): FluentInstanceExtended;
11
+ export declare function __useI18n(): FluentiCoreInstanceFull;
12
12
  //# sourceMappingURL=__useI18n.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"__useI18n.d.ts","sourceRoot":"","sources":["../../src/hooks/__useI18n.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAEtD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,IAAI,sBAAsB,CASlD"}
1
+ {"version":3,"file":"__useI18n.d.ts","sourceRoot":"","sources":["../../src/hooks/__useI18n.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAE5D;;;;;;;;GAQG;AACH,wBAAgB,SAAS,IAAI,uBAAuB,CAUnD"}
@@ -1,4 +1,4 @@
1
- import { I18nContextValue } from '../types';
1
+ import { FluentiContext } from '../types';
2
2
  /**
3
3
  * Primary hook for accessing i18n functions.
4
4
  *
@@ -7,5 +7,5 @@ import { I18nContextValue } from '../types';
7
7
  *
8
8
  * @throws If used outside of `<I18nProvider>`
9
9
  */
10
- export declare function useI18n(): I18nContextValue;
10
+ export declare function useI18n(): FluentiContext;
11
11
  //# sourceMappingURL=useI18n.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useI18n.d.ts","sourceRoot":"","sources":["../../src/hooks/useI18n.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEhD;;;;;;;GAOG;AACH,wBAAgB,OAAO,IAAI,gBAAgB,CAS1C"}
1
+ {"version":3,"file":"useI18n.d.ts","sourceRoot":"","sources":["../../src/hooks/useI18n.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9C;;;;;;;GAOG;AACH,wBAAgB,OAAO,IAAI,cAAc,CASxC"}
@@ -0,0 +1,71 @@
1
+ import { Children as e, Fragment as t, cloneElement as n, createElement as r, isValidElement as i } from "react";
2
+ import { PLURAL_CATEGORIES as a, buildICUPluralMessage as o, buildICUSelectMessage as s, hashMessage as c, normalizeSelectForms as l, offsetIndices as u } from "@fluenti/core/internal";
3
+ //#region src/components/trans-core.ts
4
+ function d(n) {
5
+ let r = [], a = "";
6
+ return e.forEach(n, (e) => {
7
+ if (typeof e == "string" || typeof e == "number") a += String(e);
8
+ else if (i(e)) {
9
+ if (e.type === t) {
10
+ let t = d(e.props.children);
11
+ a += u(t.message, r.length), r.push(...t.components);
12
+ return;
13
+ }
14
+ let n = r.length, i = d(e.props.children);
15
+ r.push(e), r.push(...i.components), i.message === "" && i.components.length === 0 ? a += `<${n}/>` : a += `<${n}>${u(i.message, n + 1)}</${n}>`;
16
+ }
17
+ }), {
18
+ message: a,
19
+ components: r
20
+ };
21
+ }
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));
31
+ }
32
+ else o.push(l);
33
+ s = a.lastIndex, c = a.exec(e);
34
+ }
35
+ return s < e.length && o.push(e.slice(s)), o.length === 1 ? o[0] : r(t, null, ...o);
36
+ }
37
+ //#endregion
38
+ //#region src/components/icu-rich.tsx
39
+ function p(e) {
40
+ let t = d(e);
41
+ return {
42
+ message: t.message,
43
+ components: t.components
44
+ };
45
+ }
46
+ function m(e, t) {
47
+ let n = [], r = {};
48
+ for (let i of e) {
49
+ let e = t[i];
50
+ if (e === void 0) continue;
51
+ let a = p(e);
52
+ r[i] = u(a.message, n.length), n.push(...a.components);
53
+ }
54
+ for (let [i, a] of Object.entries(t)) {
55
+ if (e.includes(i) || a === void 0) continue;
56
+ let t = p(a);
57
+ r[i] = u(t.message, n.length), n.push(...t.components);
58
+ }
59
+ return {
60
+ messages: r,
61
+ components: n
62
+ };
63
+ }
64
+ function h(e, t, n, r) {
65
+ let i = n(e, t);
66
+ return r.length > 0 ? f(i, r) : i;
67
+ }
68
+ //#endregion
69
+ 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
+
71
+ //# sourceMappingURL=icu-rich-BOtj4Oxu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icu-rich-BOtj4Oxu.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 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 const component = components[idx]\n\n if (component) {\n if (isSelfClosing) {\n result.push(cloneElement(component, { key: `trans-${idx}` }))\n } else {\n const innerContent = reconstruct(innerText, components)\n result.push(\n cloneElement(component, { key: `trans-${idx}` }, innerContent),\n )\n }\n } else {\n 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":";;;AAwBA,SAAgB,EAAe,GAG7B;CACA,IAAM,IAA6B,EAAE,EACjC,IAAU;AAyBd,QAvBA,EAAS,QAAQ,IAAW,MAAU;AACpC,MAAI,OAAO,KAAU,YAAY,OAAO,KAAU,SAChD,MAAW,OAAO,EAAM;WACf,EAAe,EAAM,EAAE;AAChC,OAAI,EAAM,SAAS,GAAU;IAC3B,IAAM,IAAQ,EAAgB,EAAM,MAAmC,SAAS;AAEhF,IADA,KAAW,EAAc,EAAM,SAAS,EAAW,OAAO,EAC1D,EAAW,KAAK,GAAG,EAAM,WAAW;AACpC;;GAGF,IAAM,IAAM,EAAW,QACjB,IAAQ,EAAgB,EAAM,MAAmC,SAAS;AAGhF,GAFA,EAAW,KAAK,EAAM,EACtB,EAAW,KAAK,GAAG,EAAM,WAAW,EAChC,EAAM,YAAY,MAAM,EAAM,WAAW,WAAW,IACtD,KAAW,IAAI,EAAI,MAEnB,KAAW,IAAI,EAAI,GAAG,EAAc,EAAM,SAAS,IAAM,EAAE,CAAC,IAAI,EAAI;;GAGxE,EAEK;EAAE;EAAS;EAAY;;AAUhC,SAAgB,EACd,GACA,GACW;CACX,IAAM,IAAc,sCACd,IAAsB,EAAE,EAC1B,IAAY,GACZ;AAKJ,MAHA,EAAY,YAAY,GACxB,IAAQ,EAAY,KAAK,EAAW,EAE7B,MAAU,OAAM;AACrB,EAAI,EAAM,QAAQ,KAChB,EAAO,KAAK,EAAW,MAAM,GAAW,EAAM,MAAM,CAAC;EAGvD,IAAM,IAAM,OAAO,EAAM,GAAG,EACtB,IAAgB,EAAM,OAAO,KAAA,GAC7B,IAAY,EAAM,MAAM,IACxB,IAAY,EAAW;AAE7B,MAAI,EACF,KAAI,EACF,GAAO,KAAK,EAAa,GAAW,EAAE,KAAK,SAAS,KAAO,CAAC,CAAC;OACxD;GACL,IAAM,IAAe,EAAY,GAAW,EAAW;AACvD,KAAO,KACL,EAAa,GAAW,EAAE,KAAK,SAAS,KAAO,EAAE,EAAa,CAC/D;;MAGH,GAAO,KAAK,EAAU;AAIxB,EADA,IAAY,EAAY,WACxB,IAAQ,EAAY,KAAK,EAAW;;AAOtC,QAJI,IAAY,EAAW,UACzB,EAAO,KAAK,EAAW,MAAM,EAAU,CAAC,EAGnC,EAAO,WAAW,IAAI,EAAO,KAAM,EAAc,GAAU,MAAM,GAAG,EAAO;;;;AC1FpF,SAAgB,EAAkB,GAAkC;CAClE,IAAM,IAAY,EAAe,EAAK;AACtC,QAAO;EACL,SAAS,EAAU;EACnB,YAAY,EAAU;EACvB;;AAGH,SAAgB,EACd,GACA,GAIA;CACA,IAAM,IAA6B,EAAE,EAC/B,IAAmC,EAAE;AAE3C,MAAK,IAAM,KAAO,GAAM;EACtB,IAAM,IAAQ,EAAM;AACpB,MAAI,MAAU,KAAA,EAAW;EACzB,IAAM,IAAY,EAAkB,EAAM;AAE1C,EADA,EAAS,KAAO,EAAc,EAAU,SAAS,EAAW,OAAO,EACnE,EAAW,KAAK,GAAG,EAAU,WAAW;;AAG1C,MAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAAM,EAAE;AAChD,MAAI,EAAK,SAAS,EAAS,IAAI,MAAU,KAAA,EAAW;EACpD,IAAM,IAAY,EAAkB,EAAM;AAE1C,EADA,EAAS,KAAO,EAAc,EAAU,SAAS,EAAW,OAAO,EACnE,EAAW,KAAK,GAAG,EAAU,WAAW;;AAG1C,QAAO;EAAY;EAAiE;EAAY;;AAGlG,SAAgB,EACd,GACA,GACA,GACA,GACW;CACX,IAAM,IAAa,EAAU,GAAY,EAAO;AAChD,QAAO,EAAW,SAAS,IAAI,EAAY,GAAY,EAAW,GAAG"}
@@ -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;for(i.lastIndex=0,s=i.exec(t);s!==null;){s.index>o&&a.push(t.slice(o,s.index));let c=Number(s[1]),l=s[2]===void 0,u=s[3]??``,d=n[c];if(d)if(l)a.push((0,e.cloneElement)(d,{key:`trans-${c}`}));else{let t=r(u,n);a.push((0,e.cloneElement)(d,{key:`trans-${c}`},t))}else a.push(u);o=i.lastIndex,s=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-vPU-0wGQ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icu-rich-vPU-0wGQ.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 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 const component = components[idx]\n\n if (component) {\n if (isSelfClosing) {\n result.push(cloneElement(component, { key: `trans-${idx}` }))\n } else {\n const innerContent = reconstruct(innerText, components)\n result.push(\n cloneElement(component, { key: `trans-${idx}` }, innerContent),\n )\n }\n } else {\n 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":"2DAwBA,SAAgB,EAAe,EAG7B,CACA,IAAM,EAA6B,EAAE,CACjC,EAAU,GAyBd,OAvBA,EAAA,SAAS,QAAQ,EAAW,GAAU,CACpC,GAAI,OAAO,GAAU,UAAY,OAAO,GAAU,SAChD,GAAW,OAAO,EAAM,8BACA,EAAM,CAAE,CAChC,GAAI,EAAM,OAAS,EAAA,SAAU,CAC3B,IAAM,EAAQ,EAAgB,EAAM,MAAmC,SAAS,CAChF,IAAA,EAAA,EAAA,eAAyB,EAAM,QAAS,EAAW,OAAO,CAC1D,EAAW,KAAK,GAAG,EAAM,WAAW,CACpC,OAGF,IAAM,EAAM,EAAW,OACjB,EAAQ,EAAgB,EAAM,MAAmC,SAAS,CAChF,EAAW,KAAK,EAAM,CACtB,EAAW,KAAK,GAAG,EAAM,WAAW,CAChC,EAAM,UAAY,IAAM,EAAM,WAAW,SAAW,EACtD,GAAW,IAAI,EAAI,IAEnB,GAAW,IAAI,EAAI,IAAA,EAAA,EAAA,eAAiB,EAAM,QAAS,EAAM,EAAE,CAAC,IAAI,EAAI,KAGxE,CAEK,CAAE,UAAS,aAAY,CAUhC,SAAgB,EACd,EACA,EACW,CACX,IAAM,EAAc,qCACd,EAAsB,EAAE,CAC1B,EAAY,EACZ,EAKJ,IAHA,EAAY,UAAY,EACxB,EAAQ,EAAY,KAAK,EAAW,CAE7B,IAAU,MAAM,CACjB,EAAM,MAAQ,GAChB,EAAO,KAAK,EAAW,MAAM,EAAW,EAAM,MAAM,CAAC,CAGvD,IAAM,EAAM,OAAO,EAAM,GAAG,CACtB,EAAgB,EAAM,KAAO,IAAA,GAC7B,EAAY,EAAM,IAAM,GACxB,EAAY,EAAW,GAE7B,GAAI,EACF,GAAI,EACF,EAAO,MAAA,EAAA,EAAA,cAAkB,EAAW,CAAE,IAAK,SAAS,IAAO,CAAC,CAAC,KACxD,CACL,IAAM,EAAe,EAAY,EAAW,EAAW,CACvD,EAAO,MAAA,EAAA,EAAA,cACQ,EAAW,CAAE,IAAK,SAAS,IAAO,CAAE,EAAa,CAC/D,MAGH,EAAO,KAAK,EAAU,CAGxB,EAAY,EAAY,UACxB,EAAQ,EAAY,KAAK,EAAW,CAOtC,OAJI,EAAY,EAAW,QACzB,EAAO,KAAK,EAAW,MAAM,EAAU,CAAC,CAGnC,EAAO,SAAW,EAAI,EAAO,IAAA,EAAA,EAAA,eAAoB,EAAA,SAAU,KAAM,GAAG,EAAO,CC1FpF,SAAgB,EAAkB,EAAkC,CAClE,IAAM,EAAY,EAAe,EAAK,CACtC,MAAO,CACL,QAAS,EAAU,QACnB,WAAY,EAAU,WACvB,CAGH,SAAgB,EACd,EACA,EAIA,CACA,IAAM,EAA6B,EAAE,CAC/B,EAAmC,EAAE,CAE3C,IAAK,IAAM,KAAO,EAAM,CACtB,IAAM,EAAQ,EAAM,GACpB,GAAI,IAAU,IAAA,GAAW,SACzB,IAAM,EAAY,EAAkB,EAAM,CAC1C,EAAS,IAAA,EAAA,EAAA,eAAqB,EAAU,QAAS,EAAW,OAAO,CACnE,EAAW,KAAK,GAAG,EAAU,WAAW,CAG1C,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAM,CAAE,CAChD,GAAI,EAAK,SAAS,EAAS,EAAI,IAAU,IAAA,GAAW,SACpD,IAAM,EAAY,EAAkB,EAAM,CAC1C,EAAS,IAAA,EAAA,EAAA,eAAqB,EAAU,QAAS,EAAW,OAAO,CACnE,EAAW,KAAK,GAAG,EAAU,WAAW,CAG1C,MAAO,CAAY,WAAiE,aAAY,CAGlG,SAAgB,EACd,EACA,EACA,EACA,EACW,CACX,IAAM,EAAa,EAAU,EAAY,EAAO,CAChD,OAAO,EAAW,OAAS,EAAI,EAAY,EAAY,EAAW,CAAG"}
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-XY1SdM5K.cjs`);let t=require(`react`),n=require(`@fluenti/core`),r=require(`react/jsx-runtime`);var i=(0,t.createContext)(null);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}var o=Symbol.for(`fluenti.runtime.react`);function s(){let e=globalThis[o];return typeof e==`object`&&e?e:null}function c({locale:e,fallbackLocale:o,messages:c,loadMessages:l,fallbackChain:u,dateFormats:d,numberFormats:f,missing:p,children:m}){let[h,g]=(0,t.useState)(e),[_,v]=(0,t.useState)(!1),[y,b]=(0,t.useState)(c?a(c):{}),[x,S]=(0,t.useState)(c?Object.keys(c):[]),C=(0,t.useRef)(y);C.current=y;let w=(0,t.useRef)(0),T=(0,t.useMemo)(()=>{let e={locale:h,messages:y};return o!==void 0&&(e.fallbackLocale=o),u!==void 0&&(e.fallbackChain=u),d!==void 0&&(e.dateFormats=d),f!==void 0&&(e.numberFormats=f),p!==void 0&&(e.missing=p),(0,n.createFluent)(e)},[h,y,o,u,d,f,p]);(0,t.useEffect)(()=>{e!==h&&E(e)},[e]);let E=(0,t.useCallback)(async e=>{let t=++w.current;if(C.current[e]&&!l){g(e);return}let n=l?s():null;if(C.current[e]){n?.__switchLocale&&await n.__switchLocale(e),g(e);return}if(!l){console.warn(`[fluenti] No messages for locale "${e}" and no loadMessages function provided`);return}v(!0);try{let r=await l(e);if(t!==w.current)return;let i=typeof r==`object`&&r&&`default`in r?r.default:r;b(t=>({...t,[e]:i})),S(t=>[...new Set([...t,e])]),n?.__switchLocale&&await n.__switchLocale(e),g(e)}catch(n){t===w.current&&console.error(`[fluenti] Failed to load locale "${e}"`,n)}finally{t===w.current&&v(!1)}},[l]),D=(0,t.useCallback)(async e=>{let t=s();if(!(C.current[e]||!l))try{let n=await l(e),r=typeof n==`object`&&n&&`default`in n?n.default:n;b(t=>({...t,[e]:r})),S(t=>[...new Set([...t,e])]),t?.__preloadLocale&&await t.__preloadLocale(e)}catch{}},[l]),O=(0,t.useMemo)(()=>({i18n:T,t:T.t.bind(T),d:T.d.bind(T),n:T.n.bind(T),format:T.format.bind(T),loadMessages:T.loadMessages.bind(T),getLocales:T.getLocales.bind(T),locale:h,setLocale:E,isLoading:_,loadedLocales:x,preloadLocale:D}),[T,h,E,_,x,D]);return(0,r.jsx)(i.Provider,{value:O,children:m})}function l(){let e=(0,t.useContext)(i);if(!e)throw Error(`[fluenti] useI18n() must be used within an <I18nProvider>. Wrap your app with <I18nProvider> to provide i18n context.`);return e}var u=((...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(...).")}),d=(0,t.memo)(function({children:a,id:o,context:s,comment:c,render:l,__id:u,__message:d,__components:f}){let p=(0,t.useContext)(i);if(!p)throw Error(`[fluenti] <Trans> must be used within an <I18nProvider>`);let m=d!==void 0,{message:h,components:g}=(0,t.useMemo)(()=>m?{message:d,components:f??[]}:e.s(a),[m,d,f,a]),_=(0,t.useMemo)(()=>o??u??(0,n.hashMessage)(h,s),[o,u,h,s]),v=e.c(p.i18n.t({id:_,message:h,...s===void 0?{}:{context:s},...c===void 0?{}:{comment:c}}),g);return l?l(v):(0,r.jsx)(r.Fragment,{children:v})}),f=(0,t.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,t.useContext)(i);if(!g)throw Error(`[fluenti] <Plural> must be used within an <I18nProvider>`);let{messages:_,components:v}=e.a(e.o,{zero:l,one:u,two:d,few:f,many:p,other:m}),y=e.t({..._.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.i({id:o??(s===void 0?y:(0,n.hashMessage)(y,s)),message:y,...s===void 0?{}:{context:s},...c===void 0?{}:{comment:c}},{count:a},(e,t)=>g.i18n.t(e,t),v)})}),p=(0,t.memo)(function(a){let o=(0,t.useContext)(i);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,...p}=a,m=f===void 0?{...Object.fromEntries(Object.entries(p).filter(([e])=>![`value`,`id`,`context`,`comment`,`options`,`other`].includes(e))),other:d}:{...f,other:d},h=[...Object.keys(m).filter(e=>e!==`other`),`other`],{messages:g,components:_}=e.a(h,m),v=e.r(Object.fromEntries([...h].map(e=>[e,g[e]??``]))),y=e.n(v.forms);return(0,r.jsx)(r.Fragment,{children:e.i({id:c??(l===void 0?y:(0,n.hashMessage)(y,l)),message:y,...l===void 0?{}:{context:l},...u===void 0?{}:{comment:u}},{value:v.valueMap[s]??`other`},(e,t)=>o.i18n.t(e,t),_)})}),m=(0,t.memo)(function({value:e,style:n}){let a=(0,t.useContext)(i);if(!a)throw Error(`[fluenti] <DateTime> must be used within an <I18nProvider>`);return(0,r.jsx)(r.Fragment,{children:a.i18n.d(e,n)})}),h=(0,t.memo)(function({value:e,style:n}){let a=(0,t.useContext)(i);if(!a)throw Error(`[fluenti] <Number> must be used within an <I18nProvider>`);return(0,r.jsx)(r.Fragment,{children:a.i18n.n(e,n)})});exports.DateTime=m,exports.I18nContext=i,exports.I18nProvider=c,exports.NumberFormat=h,exports.Plural=f,exports.Select=p,exports.Trans=d,Object.defineProperty(exports,`msg`,{enumerable:!0,get:function(){return n.msg}}),exports.t=u,exports.useI18n=l;
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;
3
3
  //# sourceMappingURL=index.cjs.map