diff --git a/README.md b/README.md index 2947af4..37ec1c4 100644 --- a/README.md +++ b/README.md @@ -137,13 +137,13 @@ Never pass raw internal IDs from the client. ### `` -| Prop | Type | Required | Description | -| -------------- | ----------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------- | -| `clientKey` | `string` | ✅ | Project client key. | -| `clientSecret` | `string` | ✅ | Project bearer token. | -| `environment` | `"production"` \| `"staging"` \| `string` | | Default `"production"`. Pass any custom URL to point at a self-hosted loader. | -| `dataLayer` | `string` | | Default `"stromCom"`. The global JS variable name. Change it if `stromCom` collides with something else on the page. | -| `language` | `string` | | UI language (e.g. `"cs"`, `"en"`, `"sk"`). Omit to auto-detect from the browser. | +| Prop | Type | Required | Description | +| -------------- | ----------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| `clientKey` | `string` | ✅ | Project client key. | +| `clientSecret` | `string` | ✅ | Project bearer token. | +| `environment` | `"production"` \| `"staging"` \| `string` | | Default `"production"`. Pass any custom URL to point at a self-hosted loader. | +| `dataLayer` | `string` | | Default `"stromCom"`. The global JS variable name. Change it if `stromCom` collides with something else on the page. | +| `language` | `string` | | Initial UI language (e.g. `"cs"`, `"en"`, `"sk"`). Omit to auto-detect from the browser. To change it at runtime, use ``. | ### `` @@ -191,6 +191,7 @@ Notable options: | `onNotification` | `Function` | Called when unread count changes. | | `pageCSSPath` | `string` | CSS file URL injected into the widget iframe. | | `notificationElementPosition` | `1\|2\|3\|4` | Icon position: 1=TL, 2=TR, 3=BR, 4=BL. | +| `language` | `"en"\|"cs"\|"sk"\|null` | UI language. `null` follows the browser, falling back to English. Overrides ``. | | `theme` | `"stromcom-light"\|"stromcom-dark"\|null` | Theme. `null` follows browser preference. | | `entityResolve` | `Function` | `async ({type, id}) => detail` — resolves business-entity detail (order, ticket…) for the message editor's chip hover-card. | diff --git a/src/StromcomConf.jsx b/src/StromcomConf.jsx index c778178..9a83d9f 100644 --- a/src/StromcomConf.jsx +++ b/src/StromcomConf.jsx @@ -21,6 +21,9 @@ import { useStromcom } from './StromcomProvider.jsx'; * @param {Function} [props.homeBeforeRender] - Callback before notification center opens * @param {Function} [props.notificationElementBeforeRender]- Callback before notification icon renders * @param {Function} [props.notificationElementAfterRender] - Callback after notification icon renders + * @param {('en'|'cs'|'sk'|null)} [props.language] - UI language. null follows the browser, falling back to English. + * Overrides the `language` prop on StromcomProvider, which is only + * the initial value; this one can be changed at runtime. * @param {('stromcom-light'|'stromcom-dark'|null)} [props.theme] - Theme. null follows browser preference. * @param {Function} [props.entityResolve] - async ({type, id}) => detail; resolves business-entity detail for the message editor's chip hover-card * @@ -43,6 +46,7 @@ export function StromcomConf({ homeBeforeRender, notificationElementBeforeRender, notificationElementAfterRender, + language, theme, entityResolve, }) { @@ -73,6 +77,7 @@ export function StromcomConf({ opts.notificationElementBeforeRender = notificationElementBeforeRender; if (notificationElementAfterRender !== undefined) opts.notificationElementAfterRender = notificationElementAfterRender; + if (language !== undefined) opts.language = language; if (theme !== undefined) opts.theme = theme; if (entityResolve !== undefined) opts.entityResolve = entityResolve; @@ -91,6 +96,7 @@ export function StromcomConf({ homeBeforeRender, notificationElementBeforeRender, notificationElementAfterRender, + language, theme, entityResolve, ]); diff --git a/src/StromcomProvider.jsx b/src/StromcomProvider.jsx index b87e72c..90c701a 100644 --- a/src/StromcomProvider.jsx +++ b/src/StromcomProvider.jsx @@ -58,7 +58,8 @@ function setupLayer(dataLayer) { * @param {string} props.clientSecret - Bearer token from the Stromcom dashboard * @param {string} [props.dataLayer] - Global JS variable name (default: "stromCom") * @param {string} [props.environment] - "production" | "staging" | full custom loader URL - * @param {string} [props.language] - UI language (e.g. "cs", "en", "sk"). Omit to auto-detect from the browser. + * @param {string} [props.language] - Initial UI language (e.g. "cs", "en", "sk"). Omit to auto-detect from the + * browser. Use StromcomConf's `language` prop to change it at runtime. * @param {React.ReactNode} props.children * * @example diff --git a/src/__tests__/StromcomConf.test.jsx b/src/__tests__/StromcomConf.test.jsx index 0009357..ae64a56 100644 --- a/src/__tests__/StromcomConf.test.jsx +++ b/src/__tests__/StromcomConf.test.jsx @@ -38,6 +38,34 @@ describe('StromcomConf', () => { expect(layer.conf).toHaveBeenCalledWith({ entityResolve }); }); + it('sends the language option', () => { + const layer = { conf: vi.fn() }; + renderWithLayer(layer, { language: 'cs' }); + + expect(layer.conf).toHaveBeenCalledWith({ language: 'cs' }); + }); + + it('sends language null to follow the browser', () => { + const layer = { conf: vi.fn() }; + renderWithLayer(layer, { language: null }); + + expect(layer.conf).toHaveBeenCalledWith({ language: null }); + }); + + it('re-sends conf when the language changes', () => { + const layer = { conf: vi.fn() }; + const { rerender } = renderWithLayer(layer, { language: 'cs' }); + + rerender( + + + , + ); + + expect(layer.conf).toHaveBeenCalledTimes(2); + expect(layer.conf).toHaveBeenLastCalledWith({ language: 'sk' }); + }); + it('re-sends conf when an option changes', () => { const layer = { conf: vi.fn() }; const { rerender } = renderWithLayer(layer, { theme: 'stromcom-light' }); diff --git a/src/index.d.ts b/src/index.d.ts index 3422282..6e84301 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -19,7 +19,10 @@ export interface StromcomProviderProps { dataLayer?: string; /** `"production"`, `"staging"`, or a full custom loader URL. Default `"production"`. */ environment?: StromcomEnvironment; - /** UI language (e.g. `"cs"`, `"en"`, `"sk"`). Omit to auto-detect from the browser. */ + /** + * Initial UI language (e.g. `"cs"`, `"en"`, `"sk"`). Omit to auto-detect from the browser. + * Use `StromcomConf`'s `language` prop to change it at runtime. + */ language?: string; children?: ReactNode; } @@ -80,6 +83,11 @@ export interface StromcomConfOptions { homeBeforeRender?: () => void | Promise; notificationElementBeforeRender?: () => void | Promise; notificationElementAfterRender?: () => void; + /** + * UI language, or `null` to follow the browser (falling back to English). + * Overrides `StromcomProviderProps.language`, which is only the initial value. + */ + language?: 'en' | 'cs' | 'sk' | null; /** Theme: `"stromcom-light"`, `"stromcom-dark"`, or `null` to follow browser preference. */ theme?: 'stromcom-light' | 'stromcom-dark' | null; /** Resolves business-entity detail (order, ticket…) for the message editor's chip hover-card. */