diff --git a/README.md b/README.md index a24a8c5..2947af4 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,7 @@ Never pass raw internal IDs from the client. | `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. | ### `` @@ -184,13 +185,14 @@ Sends SDK configuration. Place once inside the provider, before threads. Notable options: -| Prop | Type | Description | -| ----------------------------- | ----------------------------------------- | --------------------------------------------- | -| `notificationRenderer` | `Function` | Custom notification rendering function. | -| `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. | -| `theme` | `"stromcom-light"\|"stromcom-dark"\|null` | Theme. `null` follows browser preference. | +| Prop | Type | Description | +| ----------------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `notificationRenderer` | `Function` | Custom notification rendering function. | +| `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. | +| `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. | See [`src/StromcomConf.jsx`](./src/StromcomConf.jsx) for the full list. diff --git a/src/StromcomConf.jsx b/src/StromcomConf.jsx index 8788e22..c778178 100644 --- a/src/StromcomConf.jsx +++ b/src/StromcomConf.jsx @@ -22,6 +22,7 @@ import { useStromcom } from './StromcomProvider.jsx'; * @param {Function} [props.notificationElementBeforeRender]- Callback before notification icon renders * @param {Function} [props.notificationElementAfterRender] - Callback after notification icon renders * @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 * * @example * script.remove(); - }, [clientKey, clientSecret, dataLayer, environment]); + }, [clientKey, clientSecret, dataLayer, environment, language]); return {children}; } diff --git a/src/__tests__/StromcomConf.test.jsx b/src/__tests__/StromcomConf.test.jsx index 6f5184c..0009357 100644 --- a/src/__tests__/StromcomConf.test.jsx +++ b/src/__tests__/StromcomConf.test.jsx @@ -30,6 +30,14 @@ describe('StromcomConf', () => { expect(layer.conf).toHaveBeenCalledWith({ onNotification }); }); + it('forwards entityResolve as-is (no string-wrapping)', () => { + const layer = { conf: vi.fn() }; + const entityResolve = vi.fn(); + renderWithLayer(layer, { entityResolve }); + + expect(layer.conf).toHaveBeenCalledWith({ entityResolve }); + }); + it('re-sends conf when an option changes', () => { const layer = { conf: vi.fn() }; const { rerender } = renderWithLayer(layer, { theme: 'stromcom-light' }); diff --git a/src/__tests__/StromcomProvider.test.jsx b/src/__tests__/StromcomProvider.test.jsx index 46df05a..d39e929 100644 --- a/src/__tests__/StromcomProvider.test.jsx +++ b/src/__tests__/StromcomProvider.test.jsx @@ -92,6 +92,26 @@ describe('StromcomProvider', () => { expect(scriptFor('ck_5')).toBeNull(); }); + it('sets data-lang when language is provided', () => { + render( + +
+ , + ); + + expect(scriptFor('ck_lang').dataset.lang).toBe('cs'); + }); + + it('omits data-lang when language is not provided', () => { + render( + +
+ , + ); + + expect(scriptFor('ck_nolang').dataset.lang).toBeUndefined(); + }); + it('respects a custom dataLayer name', () => { render( diff --git a/src/index.d.ts b/src/index.d.ts index 487931d..3422282 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -19,6 +19,8 @@ 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. */ + language?: string; children?: ReactNode; } @@ -80,6 +82,8 @@ export interface StromcomConfOptions { notificationElementAfterRender?: () => void; /** 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. */ + entityResolve?: (entity: { type: string; id: string }) => unknown | Promise; } export function StromcomConf(props: StromcomConfOptions): null;