react-intlayer 1.2.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/dist/cjs/{ContentEditor/contentRender.cjs → client/ContentEditionLayout.cjs} +13 -14
  2. package/dist/cjs/client/ContentEditionLayout.cjs.map +1 -0
  3. package/dist/cjs/client/ContentEditionLayout.d.ts +6 -0
  4. package/dist/cjs/client/{IntlayerClientProvider.cjs → IntlayerProvider.cjs} +21 -10
  5. package/dist/cjs/client/IntlayerProvider.cjs.map +1 -0
  6. package/dist/{esm/client/IntlayerClientProvider.d.mts → cjs/client/IntlayerProvider.d.ts} +4 -3
  7. package/dist/cjs/client/index.cjs +6 -6
  8. package/dist/cjs/client/index.cjs.map +1 -1
  9. package/dist/cjs/client/index.d.ts +2 -1
  10. package/dist/cjs/client/useContent.d.ts +1 -2
  11. package/dist/cjs/client/useIntlayer.cjs +2 -2
  12. package/dist/cjs/client/useIntlayer.cjs.map +1 -1
  13. package/dist/cjs/client/useIntlayer.d.ts +2 -1
  14. package/dist/cjs/client/useLocale.cjs +2 -2
  15. package/dist/cjs/client/useLocale.cjs.map +1 -1
  16. package/dist/cjs/client/useLocaleBase.cjs +2 -2
  17. package/dist/cjs/client/useLocaleBase.cjs.map +1 -1
  18. package/dist/cjs/client/useTraduction.cjs +2 -2
  19. package/dist/cjs/client/useTraduction.cjs.map +1 -1
  20. package/dist/cjs/getEnumeration.cjs +0 -4
  21. package/dist/cjs/getEnumeration.cjs.map +1 -1
  22. package/dist/cjs/getTranslation.cjs +0 -4
  23. package/dist/cjs/getTranslation.cjs.map +1 -1
  24. package/dist/cjs/index.cjs +7 -4
  25. package/dist/cjs/index.cjs.map +1 -1
  26. package/dist/cjs/index.d.ts +3 -2
  27. package/dist/cjs/processDictionary/{contentDictionary.d.cjs → contentDictionary.cjs} +3 -3
  28. package/dist/cjs/processDictionary/contentDictionary.cjs.map +1 -0
  29. package/dist/cjs/processDictionary/contentDictionary.d.ts +16 -0
  30. package/dist/cjs/processDictionary/index.cjs +114 -33
  31. package/dist/cjs/processDictionary/index.cjs.map +1 -1
  32. package/dist/cjs/processDictionary/index.d.ts +5 -4
  33. package/dist/cjs/server/IntlayerServerProvider.cjs +3 -4
  34. package/dist/cjs/server/IntlayerServerProvider.cjs.map +1 -1
  35. package/dist/cjs/server/IntlayerServerProvider.d.ts +1 -1
  36. package/dist/cjs/server/index.d.ts +1 -0
  37. package/dist/cjs/server/useIntlayer.d.ts +2 -1
  38. package/dist/cjs/useIntlayerBase.cjs +48 -1
  39. package/dist/cjs/useIntlayerBase.cjs.map +1 -1
  40. package/dist/cjs/useIntlayerBase.d.ts +51 -4
  41. package/dist/cjs/vite/intlayerPlugin.cjs +1 -1
  42. package/dist/cjs/vite/intlayerPlugin.cjs.map +1 -1
  43. package/dist/esm/client/ContentEditionLayout.d.mts +6 -0
  44. package/dist/esm/client/ContentEditionLayout.mjs +15 -0
  45. package/dist/esm/client/ContentEditionLayout.mjs.map +1 -0
  46. package/dist/{cjs/client/IntlayerClientProvider.d.ts → esm/client/IntlayerProvider.d.mts} +4 -3
  47. package/dist/esm/client/{IntlayerClientProvider.mjs → IntlayerProvider.mjs} +17 -6
  48. package/dist/esm/client/IntlayerProvider.mjs.map +1 -0
  49. package/dist/esm/client/index.d.mts +2 -1
  50. package/dist/esm/client/index.mjs +4 -4
  51. package/dist/esm/client/index.mjs.map +1 -1
  52. package/dist/esm/client/useContent.d.mts +1 -2
  53. package/dist/esm/client/useIntlayer.d.mts +2 -1
  54. package/dist/esm/client/useIntlayer.mjs +1 -1
  55. package/dist/esm/client/useIntlayer.mjs.map +1 -1
  56. package/dist/esm/client/useLocale.mjs +1 -1
  57. package/dist/esm/client/useLocale.mjs.map +1 -1
  58. package/dist/esm/client/useLocaleBase.mjs +1 -1
  59. package/dist/esm/client/useLocaleBase.mjs.map +1 -1
  60. package/dist/esm/client/useTraduction.mjs +1 -1
  61. package/dist/esm/client/useTraduction.mjs.map +1 -1
  62. package/dist/esm/getEnumeration.mjs +0 -4
  63. package/dist/esm/getEnumeration.mjs.map +1 -1
  64. package/dist/esm/getTranslation.mjs +0 -4
  65. package/dist/esm/getTranslation.mjs.map +1 -1
  66. package/dist/esm/index.d.mts +3 -2
  67. package/dist/esm/index.mjs +6 -4
  68. package/dist/esm/index.mjs.map +1 -1
  69. package/dist/esm/processDictionary/contentDictionary.d.mts +16 -0
  70. package/dist/esm/processDictionary/contentDictionary.mjs +1 -0
  71. package/dist/esm/processDictionary/index.d.mts +5 -4
  72. package/dist/esm/processDictionary/index.mjs +116 -34
  73. package/dist/esm/processDictionary/index.mjs.map +1 -1
  74. package/dist/esm/server/IntlayerServerProvider.d.mts +1 -1
  75. package/dist/esm/server/IntlayerServerProvider.mjs +3 -4
  76. package/dist/esm/server/IntlayerServerProvider.mjs.map +1 -1
  77. package/dist/esm/server/index.d.mts +1 -0
  78. package/dist/esm/server/useIntlayer.d.mts +2 -1
  79. package/dist/esm/useIntlayerBase.d.mts +51 -4
  80. package/dist/esm/useIntlayerBase.mjs +46 -1
  81. package/dist/esm/useIntlayerBase.mjs.map +1 -1
  82. package/dist/esm/vite/intlayerPlugin.mjs +1 -1
  83. package/dist/esm/vite/intlayerPlugin.mjs.map +1 -1
  84. package/package.json +14 -9
  85. package/src/index.ts +4 -3
  86. package/dist/cjs/ContentEditor/ContentEditor.cjs +0 -110
  87. package/dist/cjs/ContentEditor/ContentEditor.cjs.map +0 -1
  88. package/dist/cjs/ContentEditor/ContentEditor.d.ts +0 -8
  89. package/dist/cjs/ContentEditor/contentRender.cjs.map +0 -1
  90. package/dist/cjs/ContentEditor/contentRender.d.ts +0 -3
  91. package/dist/cjs/ContentEditor/index.cjs +0 -25
  92. package/dist/cjs/ContentEditor/index.cjs.map +0 -1
  93. package/dist/cjs/ContentEditor/index.d.ts +0 -3
  94. package/dist/cjs/IntlayerProvider.cjs +0 -37
  95. package/dist/cjs/IntlayerProvider.cjs.map +0 -1
  96. package/dist/cjs/IntlayerProvider.d.ts +0 -9
  97. package/dist/cjs/client/IntlayerClientProvider.cjs.map +0 -1
  98. package/dist/cjs/processDictionary/contentDictionary.d.cjs.map +0 -1
  99. package/dist/cjs/processDictionary/contentDictionary.d.d.ts +0 -29
  100. package/dist/esm/ContentEditor/ContentEditor.d.mts +0 -8
  101. package/dist/esm/ContentEditor/ContentEditor.mjs +0 -92
  102. package/dist/esm/ContentEditor/ContentEditor.mjs.map +0 -1
  103. package/dist/esm/ContentEditor/contentRender.d.mts +0 -3
  104. package/dist/esm/ContentEditor/contentRender.mjs +0 -14
  105. package/dist/esm/ContentEditor/contentRender.mjs.map +0 -1
  106. package/dist/esm/ContentEditor/index.d.mts +0 -3
  107. package/dist/esm/ContentEditor/index.mjs +0 -3
  108. package/dist/esm/ContentEditor/index.mjs.map +0 -1
  109. package/dist/esm/IntlayerProvider.d.mts +0 -9
  110. package/dist/esm/IntlayerProvider.mjs +0 -18
  111. package/dist/esm/IntlayerProvider.mjs.map +0 -1
  112. package/dist/esm/client/IntlayerClientProvider.mjs.map +0 -1
  113. package/dist/esm/processDictionary/contentDictionary.d.d.mts +0 -29
  114. package/dist/esm/processDictionary/contentDictionary.d.mjs +0 -1
  115. package/src/ContentEditor/ContentEditor.tsx +0 -116
  116. package/src/ContentEditor/contentRender.tsx +0 -11
  117. package/src/ContentEditor/index.tsx +0 -2
  118. package/src/IntlayerProvider.tsx +0 -24
  119. package/src/cli/react-intlayer.ts +0 -60
  120. package/src/client/IntlayerClientProvider.tsx +0 -76
  121. package/src/client/getBrowserLocale.tsx +0 -192
  122. package/src/client/index.ts +0 -16
  123. package/src/client/useContent.ts +0 -20
  124. package/src/client/useIntlayer.ts +0 -25
  125. package/src/client/useLocale.ts +0 -23
  126. package/src/client/useLocaleBase.ts +0 -24
  127. package/src/client/useLocaleCookie.ts +0 -32
  128. package/src/client/useTraduction.ts +0 -33
  129. package/src/craco/craco.config.ts +0 -11
  130. package/src/craco/intlayerCracoPlugin.ts +0 -89
  131. package/src/getEnumeration.ts +0 -46
  132. package/src/getTranslation.ts +0 -42
  133. package/src/processDictionary/contentDictionary.d.ts +0 -27
  134. package/src/processDictionary/index.ts +0 -144
  135. package/src/server/IntlayerServerProvider.tsx +0 -36
  136. package/src/server/getLocaleTranslation.ts +0 -22
  137. package/src/server/index.ts +0 -8
  138. package/src/server/serverContext.ts +0 -85
  139. package/src/server/useIntlayer.ts +0 -23
  140. package/src/server/useTraduction.ts +0 -34
  141. package/src/useIntlayerBase.ts +0 -35
  142. package/src/vite/intlayerPlugin.ts +0 -59
  143. /package/dist/esm/processDictionary/{contentDictionary.d.mjs.map → contentDictionary.mjs.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/client/IntlayerClientProvider.tsx"],"sourcesContent":["'use client';\n\nimport { getConfiguration, type Locales } from '@intlayer/config/client';\nimport {\n type PropsWithChildren,\n createContext,\n useContext,\n useMemo,\n type FC,\n useState,\n useCallback,\n} from 'react';\nimport { localeCookie, setLocaleCookie } from './useLocaleCookie';\n\ntype IntlayerValue = {\n locale: Locales;\n setLocale: (newLocale: Locales) => void;\n};\n\n/**\n * Context that store the current locale on the client side\n */\nexport const IntlayerClientContext = createContext<IntlayerValue>({\n locale: localeCookie ?? getConfiguration().internationalization.defaultLocale,\n setLocale: () => null,\n});\n\n/**\n * Hook that provides the current locale\n */\nexport const useIntlayerContext = () => useContext(IntlayerClientContext);\n\nexport type IntlayerClientProviderProps = PropsWithChildren & {\n locale?: Locales;\n};\n\n/**\n * Provider that store the current locale on the client side\n */\nexport const IntlayerClientProvider: FC<IntlayerClientProviderProps> = ({\n locale,\n children,\n}) => {\n const { defaultLocale, locales: availableLocales } =\n getConfiguration().internationalization;\n\n const [currentLocale, setCurrentLocale] = useState(\n locale ?? localeCookie ?? defaultLocale\n );\n\n const setLocale = useCallback(\n (newLocale: Locales) => {\n if (currentLocale.toString() === newLocale.toString()) return;\n\n if (!availableLocales.includes(newLocale)) {\n console.error(`Locale ${locale} is not available`);\n return;\n }\n\n setCurrentLocale(newLocale); // Update state\n setLocaleCookie(newLocale); // Optionally set cookie for persistence\n },\n [availableLocales, currentLocale, locale]\n );\n\n const value: IntlayerValue = useMemo<IntlayerValue>(\n () => ({ locale: currentLocale, setLocale }),\n [currentLocale, setLocale]\n );\n\n return (\n <IntlayerClientContext.Provider value={value}>\n {children}\n </IntlayerClientContext.Provider>\n );\n};\n"],"mappings":";;AAuEI;AArEJ,SAAS,wBAAsC;AAC/C;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc,uBAAuB;AAUvC,MAAM,wBAAwB,cAA6B;AAAA,EAChE,QAAQ,gBAAgB,iBAAiB,EAAE,qBAAqB;AAAA,EAChE,WAAW,MAAM;AACnB,CAAC;AAKM,MAAM,qBAAqB,MAAM,WAAW,qBAAqB;AASjE,MAAM,yBAA0D,CAAC;AAAA,EACtE;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,eAAe,SAAS,iBAAiB,IAC/C,iBAAiB,EAAE;AAErB,QAAM,CAAC,eAAe,gBAAgB,IAAI;AAAA,IACxC,UAAU,gBAAgB;AAAA,EAC5B;AAEA,QAAM,YAAY;AAAA,IAChB,CAAC,cAAuB;AACtB,UAAI,cAAc,SAAS,MAAM,UAAU,SAAS;AAAG;AAEvD,UAAI,CAAC,iBAAiB,SAAS,SAAS,GAAG;AACzC,gBAAQ,MAAM,UAAU,MAAM,mBAAmB;AACjD;AAAA,MACF;AAEA,uBAAiB,SAAS;AAC1B,sBAAgB,SAAS;AAAA,IAC3B;AAAA,IACA,CAAC,kBAAkB,eAAe,MAAM;AAAA,EAC1C;AAEA,QAAM,QAAuB;AAAA,IAC3B,OAAO,EAAE,QAAQ,eAAe,UAAU;AAAA,IAC1C,CAAC,eAAe,SAAS;AAAA,EAC3B;AAEA,SACE,oBAAC,sBAAsB,UAAtB,EAA+B,OAC7B,UACH;AAEJ;","names":[]}
@@ -1,29 +0,0 @@
1
- import { TranslationContent } from '@intlayer/core';
2
-
3
- type ContentValue =
4
- | string
5
- | {
6
- [key: string]: ContentValue;
7
- }
8
- | TranslationContent<unknown>;
9
-
10
- type Content = Record<string, ContentValue | undefined>;
11
-
12
- type TransformedContentValue =
13
- | string
14
- | {
15
- [key: string]: TransformedContentValue;
16
- }
17
- | undefined
18
- | ((quantity: number) => TransformedContentValue);
19
-
20
- type TransformedContent = Record<
21
- string,
22
- TransformedContentValue | undefined
23
- >;
24
-
25
- type ContentDictionary = Content & {
26
- id: string;
27
- };
28
-
29
- export type { Content, ContentDictionary, ContentValue, TransformedContent, TransformedContentValue };
@@ -1 +0,0 @@
1
- //# sourceMappingURL=contentDictionary.d.mjs.map
@@ -1,116 +0,0 @@
1
- 'use client';
2
-
3
- import {
4
- useEffect,
5
- useState,
6
- useRef,
7
- useCallback,
8
- type FC,
9
- type MouseEventHandler,
10
- } from 'react';
11
-
12
- type ContentEditorProps = {
13
- children?: string;
14
- };
15
-
16
- const PRESS_DETECT_DURATION = 500;
17
-
18
- export const ContentEditor: FC<ContentEditorProps> = ({ children }) => {
19
- const divRef = useRef<HTMLDivElement>(null);
20
- const [isEditing, setIsEditing] = useState(false);
21
- const pressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
22
-
23
- const handleOnLongPress = () => {
24
- setIsEditing(true);
25
- };
26
-
27
- const startPressTimer = () => {
28
- pressTimerRef.current = setTimeout(() => {
29
- handleOnLongPress();
30
- }, PRESS_DETECT_DURATION);
31
- };
32
-
33
- const clearPressTimer = () => {
34
- if (pressTimerRef.current) {
35
- clearTimeout(pressTimerRef.current);
36
- pressTimerRef.current = null;
37
- }
38
- };
39
-
40
- const handleMouseDown = () => {
41
- clearPressTimer(); // Ensure any previous timer is cleared
42
- startPressTimer();
43
- };
44
-
45
- const handleMouseUp = () => {
46
- clearPressTimer();
47
- };
48
-
49
- // Use useCallback to ensure the function identity remains stable
50
- const handleClickOutside = useCallback(
51
- (event: MouseEvent) => {
52
- if (divRef.current && !divRef.current.contains(event.target as Node)) {
53
- setIsEditing(false);
54
- }
55
- },
56
- [divRef]
57
- );
58
-
59
- useEffect(() => {
60
- // Attach click outside listener
61
- document.addEventListener('mousedown', handleClickOutside);
62
-
63
- return () => {
64
- // Cleanup
65
- document.removeEventListener('mousedown', handleClickOutside);
66
- clearPressTimer(); // Ensure to clear the timer when component unmounts
67
- };
68
- }, [handleClickOutside]);
69
-
70
- const handleOnClick: MouseEventHandler<HTMLDivElement> = (e) => {
71
- if (isEditing) {
72
- e.preventDefault();
73
- e.stopPropagation();
74
- }
75
- };
76
-
77
- const handleOnBlur = () => {
78
- // Stop editing when the element loses focus
79
- setIsEditing(false);
80
- };
81
-
82
- const onContentChange = (_e: React.FormEvent<HTMLDivElement>) => {
83
- // console.log(e.currentTarget.textContent);
84
- };
85
-
86
- return (
87
- <div
88
- role="textbox"
89
- tabIndex={0}
90
- onKeyUp={() => null}
91
- contentEditable={isEditing}
92
- onInput={onContentChange}
93
- onClick={handleOnClick}
94
- onMouseDown={handleMouseDown}
95
- onMouseUp={handleMouseUp}
96
- onMouseLeave={handleMouseUp}
97
- onTouchStart={handleMouseDown}
98
- onTouchEnd={handleMouseUp}
99
- onTouchCancel={handleMouseUp}
100
- onBlur={handleOnBlur}
101
- suppressContentEditableWarning={true} // To suppress the warning for controlled components
102
- style={
103
- isEditing
104
- ? {
105
- backgroundColor: 'transparent',
106
- cursor: 'text',
107
- display: 'inline',
108
- }
109
- : { cursor: 'pointer', display: 'inline' }
110
- }
111
- ref={divRef}
112
- >
113
- {children}
114
- </div>
115
- );
116
- };
@@ -1,11 +0,0 @@
1
- import { ContentEditor } from './ContentEditor';
2
-
3
- export const contentRender = (content: string) => {
4
- const isEditable = process.env.NODE_ENV === 'development';
5
-
6
- if (isEditable && ContentEditor) {
7
- return (<ContentEditor>{content}</ContentEditor>) as unknown as string;
8
- }
9
-
10
- return content;
11
- };
@@ -1,2 +0,0 @@
1
- export * from './ContentEditor';
2
- export * from './contentRender';
@@ -1,24 +0,0 @@
1
- import { getConfiguration } from '@intlayer/config/client';
2
- import type { FC } from 'react';
3
- import {
4
- IntlayerClientProvider,
5
- type IntlayerClientProviderProps,
6
- } from './client/IntlayerClientProvider';
7
- import {
8
- IntlayerServerProvider,
9
- type IntlayerServerProviderProps,
10
- } from './server/IntlayerServerProvider';
11
-
12
- const { defaultLocale } = getConfiguration().internationalization;
13
-
14
- type IntlayerProviderProps = IntlayerClientProviderProps &
15
- IntlayerServerProviderProps;
16
-
17
- export const IntlayerProvider: FC<IntlayerProviderProps> = ({
18
- children,
19
- locale = defaultLocale,
20
- }) => (
21
- <IntlayerServerProvider locale={locale}>
22
- <IntlayerClientProvider locale={locale}>{children}</IntlayerClientProvider>
23
- </IntlayerServerProvider>
24
- );
@@ -1,60 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * To make the setup easier, we are using craco to override the webpack configuration.
5
- * This script is used to run the craco scripts with the custom configuration.
6
- *
7
- * The script is based on the original craco script from create-react-app.
8
- */
9
-
10
- import spawn from 'cross-spawn';
11
-
12
- const args = process.argv.slice(2);
13
- const scriptIndex = args.findIndex(
14
- (x) => x === 'build' || x === 'start' || x === 'test'
15
- );
16
- const script = scriptIndex === -1 ? args[0] : args[scriptIndex];
17
-
18
- switch (script) {
19
- case 'build':
20
- case 'start':
21
- case 'test': {
22
- const nodeArgs = scriptIndex > 0 ? args.slice(0, scriptIndex) : [];
23
- const scriptPath = require.resolve(`@craco/craco/dist/scripts/${script}`);
24
- const scriptArgs = args.slice(scriptIndex + 1);
25
- const processArgs = nodeArgs
26
- .concat(scriptPath)
27
- .concat([
28
- ...scriptArgs,
29
- '--config',
30
- './node_modules/react-intlayer/dist/cjs/craco/craco.config.cjs',
31
- ]);
32
-
33
- const child = spawn.sync('node', processArgs, { stdio: 'inherit' });
34
-
35
- if (child.signal) {
36
- if (child.signal === 'SIGKILL') {
37
- console.info(`
38
- The build failed because the process exited too early.
39
- This probably means the system ran out of memory or someone called
40
- \`kill -9\` on the process.
41
- `);
42
- } else if (child.signal === 'SIGTERM') {
43
- console.info(`
44
- The build failed because the process exited too early.
45
- Someone might have called \`kill\` or \`killall\`, or the system could
46
- be shutting down.
47
- `);
48
- }
49
-
50
- process.exit(1);
51
- }
52
-
53
- process.exit(child.status ?? undefined);
54
- break;
55
- }
56
- default:
57
- console.info(`Unknown script "${script}".`);
58
- console.info('Perhaps you need to update craco?');
59
- break;
60
- }
@@ -1,76 +0,0 @@
1
- 'use client';
2
-
3
- import { getConfiguration, type Locales } from '@intlayer/config/client';
4
- import {
5
- type PropsWithChildren,
6
- createContext,
7
- useContext,
8
- useMemo,
9
- type FC,
10
- useState,
11
- useCallback,
12
- } from 'react';
13
- import { localeCookie, setLocaleCookie } from './useLocaleCookie';
14
-
15
- type IntlayerValue = {
16
- locale: Locales;
17
- setLocale: (newLocale: Locales) => void;
18
- };
19
-
20
- /**
21
- * Context that store the current locale on the client side
22
- */
23
- export const IntlayerClientContext = createContext<IntlayerValue>({
24
- locale: localeCookie ?? getConfiguration().internationalization.defaultLocale,
25
- setLocale: () => null,
26
- });
27
-
28
- /**
29
- * Hook that provides the current locale
30
- */
31
- export const useIntlayerContext = () => useContext(IntlayerClientContext);
32
-
33
- export type IntlayerClientProviderProps = PropsWithChildren & {
34
- locale?: Locales;
35
- };
36
-
37
- /**
38
- * Provider that store the current locale on the client side
39
- */
40
- export const IntlayerClientProvider: FC<IntlayerClientProviderProps> = ({
41
- locale,
42
- children,
43
- }) => {
44
- const { defaultLocale, locales: availableLocales } =
45
- getConfiguration().internationalization;
46
-
47
- const [currentLocale, setCurrentLocale] = useState(
48
- locale ?? localeCookie ?? defaultLocale
49
- );
50
-
51
- const setLocale = useCallback(
52
- (newLocale: Locales) => {
53
- if (currentLocale.toString() === newLocale.toString()) return;
54
-
55
- if (!availableLocales.includes(newLocale)) {
56
- console.error(`Locale ${locale} is not available`);
57
- return;
58
- }
59
-
60
- setCurrentLocale(newLocale); // Update state
61
- setLocaleCookie(newLocale); // Optionally set cookie for persistence
62
- },
63
- [availableLocales, currentLocale, locale]
64
- );
65
-
66
- const value: IntlayerValue = useMemo<IntlayerValue>(
67
- () => ({ locale: currentLocale, setLocale }),
68
- [currentLocale, setLocale]
69
- );
70
-
71
- return (
72
- <IntlayerClientContext.Provider value={value}>
73
- {children}
74
- </IntlayerClientContext.Provider>
75
- );
76
- };
@@ -1,192 +0,0 @@
1
- import { getConfiguration, type Locales } from '@intlayer/config/client';
2
- import { localeList } from '@intlayer/core';
3
-
4
- export enum LanguageDetector {
5
- Querystring = 'querystring',
6
- Cookie = 'cookie',
7
- LocalStorage = 'localStorage',
8
- SessionStorage = 'sessionStorage',
9
- Navigator = 'navigator',
10
- HtmlTag = 'htmlTag',
11
- }
12
-
13
- // Default settings for the language detector
14
- type LanguageDetectorOptions = {
15
- order?: LanguageDetector[];
16
- lookupQuerystring?: string;
17
- lookupCookie?: string;
18
- lookupLocalStorage?: string;
19
- lookupSessionStorage?: string;
20
- excludeCacheFor?: string[];
21
- htmlTag?: HTMLElement | null;
22
- };
23
-
24
- const getDefaultsOptions = (): LanguageDetectorOptions => {
25
- const { middleware } = getConfiguration();
26
-
27
- return {
28
- order: [
29
- LanguageDetector.Querystring,
30
- LanguageDetector.Cookie,
31
- LanguageDetector.Navigator,
32
- LanguageDetector.HtmlTag,
33
- ],
34
- lookupQuerystring: 'locale',
35
- lookupCookie: middleware.cookieName,
36
- htmlTag: document.documentElement,
37
- };
38
- };
39
-
40
- // Helper functions for various checks and operations
41
- const isLocalStorageAvailable = (): boolean => {
42
- try {
43
- if (typeof window === 'undefined') return false;
44
- const testKey = 'intlayer.translate.boo';
45
- window.localStorage.setItem(testKey, 'foo');
46
- window.localStorage.removeItem(testKey);
47
- return true;
48
- } catch {
49
- return false;
50
- }
51
- };
52
-
53
- const isSessionStorageAvailable = (): boolean => {
54
- try {
55
- if (typeof window === 'undefined') return false;
56
- const testKey = 'intlayer.translate.boo';
57
- window.sessionStorage.setItem(testKey, 'foo');
58
- window.sessionStorage.removeItem(testKey);
59
- return true;
60
- } catch {
61
- return false;
62
- }
63
- };
64
-
65
- // Function to detect language using different detectors
66
- const detectLanguage = (
67
- order: string[],
68
- options: LanguageDetectorOptions
69
- ): Record<LanguageDetector, Locales | Locales[]> => {
70
- const detected: Record<LanguageDetector, Locales | Locales[]> = {} as Record<
71
- LanguageDetector,
72
- Locales | Locales[]
73
- >;
74
-
75
- const queryStringDetector = () => {
76
- if (typeof window === 'undefined') return;
77
- const search = window.location.search || '';
78
- const params = new URLSearchParams(search);
79
- const value = params.get(options.lookupQuerystring ?? '');
80
- if (value) {
81
- detected[LanguageDetector.Querystring] = value as Locales;
82
- }
83
- };
84
-
85
- const cookieDetector = () => {
86
- if (typeof document === 'undefined') return;
87
- const cookies = document.cookie.split(';');
88
- const cookieName = `${options.lookupCookie ?? ''}=`;
89
- const cookie = cookies.find((c) => c.trim().startsWith(cookieName));
90
- if (cookie) {
91
- const value = cookie.split('=')[1].trim();
92
-
93
- detected[LanguageDetector.Cookie] = value as Locales;
94
- }
95
- };
96
-
97
- const localStorageDetector = () => {
98
- if (!isLocalStorageAvailable()) return;
99
- const value = window.localStorage.getItem(options.lookupLocalStorage ?? '');
100
- if (value) {
101
- detected[LanguageDetector.LocalStorage] = value as Locales;
102
- }
103
- };
104
-
105
- const sessionStorageDetector = () => {
106
- if (!isSessionStorageAvailable()) return;
107
- const value = window.sessionStorage.getItem(
108
- options.lookupSessionStorage ?? ''
109
- );
110
- if (value) {
111
- detected[LanguageDetector.SessionStorage] = value as Locales;
112
- }
113
- };
114
-
115
- const navigatorDetector = () => {
116
- if (typeof navigator === 'undefined') return;
117
-
118
- if (navigator.language) {
119
- detected[LanguageDetector.Navigator] = navigator.language as Locales;
120
- }
121
- };
122
-
123
- const htmlTagDetector = () => {
124
- const htmlTag = options.htmlTag;
125
- if (htmlTag && typeof htmlTag.getAttribute === 'function') {
126
- const lang = htmlTag.getAttribute('lang');
127
- if (lang) {
128
- detected[LanguageDetector.HtmlTag] = lang as Locales;
129
- }
130
- }
131
- };
132
-
133
- // Map detector names to their corresponding functions
134
- const detectors: Record<string, () => void> = {
135
- [LanguageDetector.Querystring]: queryStringDetector,
136
- [LanguageDetector.Cookie]: cookieDetector,
137
- [LanguageDetector.LocalStorage]: localStorageDetector,
138
- [LanguageDetector.SessionStorage]: sessionStorageDetector,
139
- [LanguageDetector.Navigator]: navigatorDetector,
140
- [LanguageDetector.HtmlTag]: htmlTagDetector,
141
- };
142
-
143
- // Use the provided order to run each detector
144
- order.forEach((detectorName) => {
145
- detectors[detectorName]?.();
146
- });
147
-
148
- return detected;
149
- };
150
-
151
- const getFirstAvailableLocale = (
152
- locales: Record<LanguageDetector, Locales | Locales[]>,
153
- order: LanguageDetector[]
154
- ): Locales => {
155
- const { internationalization } = getConfiguration();
156
-
157
- for (const detector of order) {
158
- const localesArray = [locales[detector]].flat() as Locales[];
159
-
160
- for (const locale of localesArray) {
161
- if (
162
- locale &&
163
- (internationalization.locales ?? localeList).includes(locale)
164
- ) {
165
- return locale;
166
- } else if (
167
- locale?.includes('-') &&
168
- (internationalization.locales ?? localeList).includes(
169
- locale.split('-')[0] as Locales
170
- )
171
- ) {
172
- return locale.split('-')[0] as Locales;
173
- }
174
- }
175
- }
176
-
177
- return internationalization.defaultLocale;
178
- };
179
-
180
- /**
181
- * Core language detector function
182
- * const detectedLanguages = detectLanguage(['LanguageDetector.Cookie', 'LanguageDetector.LocalStorage'], { lookupCookie: 'myCookie' });
183
- */
184
- export const getBrowserLocale = (
185
- userOptions: LanguageDetectorOptions | undefined = {}
186
- ): Locales => {
187
- const options = { ...getDefaultsOptions(), ...userOptions };
188
-
189
- const locales = detectLanguage(options.order ?? [], options);
190
-
191
- return getFirstAvailableLocale(locales, options.order ?? []);
192
- };
@@ -1,16 +0,0 @@
1
- export type { IntlayerClientProviderProps } from './IntlayerClientProvider';
2
- export {
3
- IntlayerClientContext as IntlayerClient,
4
- useIntlayerContext,
5
- IntlayerClientProvider,
6
- } from './IntlayerClientProvider';
7
- export { useIntlayer } from './useIntlayer';
8
- export { useLocaleBase } from './useLocaleBase';
9
- export { useLocale } from './useLocale';
10
- export { useTraduction } from './useTraduction';
11
- export {
12
- useLocaleCookie,
13
- localeCookie,
14
- setLocaleCookie,
15
- } from './useLocaleCookie';
16
- export { getBrowserLocale } from './getBrowserLocale';
@@ -1,20 +0,0 @@
1
- import type { LanguageContent } from '@intlayer/core';
2
- import { useLocaleBase } from './useLocaleBase';
3
- import { useTraduction } from './useTraduction';
4
-
5
- /**
6
- * On the client side, hook to get the translation content based on the locale
7
- */
8
- export const useContent = <Content>(
9
- languageContent: LanguageContent<Content>
10
- ) => {
11
- const { locale } = useLocaleBase();
12
-
13
- const content = useTraduction(languageContent);
14
-
15
- return {
16
- locale,
17
- content,
18
- t: useTraduction,
19
- };
20
- };
@@ -1,25 +0,0 @@
1
- 'use client';
2
-
3
- import type { Locales } from '@intlayer/config/client';
4
- import { useContext } from 'react';
5
- import {
6
- type DictionaryKeys,
7
- useIntlayerBase,
8
- type UseIntlayer,
9
- } from '../useIntlayerBase';
10
- import { IntlayerClientContext } from './IntlayerClientProvider';
11
-
12
- /**
13
- * On the client side, Hook that picking one dictionary by its id and return the content
14
- *
15
- * If the locale is not provided, it will use the locale from the client context
16
- */
17
- export const useIntlayer: UseIntlayer = <T extends DictionaryKeys>(
18
- id: T,
19
- locale?: Locales
20
- ) => {
21
- const { locale: currentLocale } = useContext(IntlayerClientContext);
22
- const localeTarget = locale ?? currentLocale;
23
-
24
- return useIntlayerBase(id, localeTarget);
25
- };
@@ -1,23 +0,0 @@
1
- 'use client';
2
-
3
- import { getConfiguration } from '@intlayer/config/client';
4
- import { localeList } from '@intlayer/core';
5
- import { useContext } from 'react';
6
- import { IntlayerClientContext } from './IntlayerClientProvider';
7
-
8
- /**
9
- * On the client side, hook to get the current locale and all related fields
10
- */
11
- export const useLocale = () => {
12
- const { defaultLocale, locales: availableLocales } =
13
- getConfiguration().internationalization;
14
- const { locale, setLocale } = useContext(IntlayerClientContext);
15
-
16
- return {
17
- locale, // Current locale
18
- defaultLocale, // Principal locale defined in config
19
- availableLocales, // List of the available locales defined in config
20
- localeList, // List of all available locales
21
- setLocale, // Function to set the locale
22
- };
23
- };
@@ -1,24 +0,0 @@
1
- 'use client';
2
-
3
- import { getConfiguration } from '@intlayer/config/client';
4
- import { localeList } from '@intlayer/core';
5
- import { useContext } from 'react';
6
- import { IntlayerClientContext } from './IntlayerClientProvider';
7
-
8
- const { defaultLocale, locales: availableLocales } =
9
- getConfiguration().internationalization;
10
-
11
- /**
12
- * On the client side, hook to get the current locale and all related fields
13
- */
14
- export const useLocaleBase = () => {
15
- const { locale, setLocale } = useContext(IntlayerClientContext);
16
-
17
- return {
18
- locale, // Current locale
19
- defaultLocale, // Principal locale defined in config
20
- availableLocales, // List of the available locales defined in config
21
- localeList, // List of all available locales
22
- setLocale, // Function to set the locale
23
- };
24
- };
@@ -1,32 +0,0 @@
1
- import { type Locales, getConfiguration } from '@intlayer/config/client';
2
- import Cookies from 'js-cookie';
3
-
4
- const { cookieName } = getConfiguration().middleware;
5
-
6
- const cookieAttributes: Cookies.CookieAttributes = {
7
- path: '/',
8
- expires: undefined,
9
- domain: undefined,
10
- secure: false,
11
- sameSite: 'strict',
12
- };
13
-
14
- /**
15
- * Get the locale cookie
16
- */
17
- export const localeCookie = Cookies.get(cookieName) as Locales | undefined;
18
-
19
- /**
20
- * Set the locale cookie
21
- */
22
- export const setLocaleCookie = (locale: Locales) => {
23
- Cookies.set(cookieName, locale, cookieAttributes);
24
- };
25
-
26
- /**
27
- * Hook that provides the locale cookie and a function to set it
28
- */
29
- export const useLocaleCookie = () => ({
30
- localeCookie,
31
- setLocaleCookie,
32
- });