diff --git a/packages/javascript/src/i18n/models/i18n.ts b/packages/javascript/src/i18n/models/i18n.ts index bde69a62..d6733ab6 100644 --- a/packages/javascript/src/i18n/models/i18n.ts +++ b/packages/javascript/src/i18n/models/i18n.ts @@ -142,6 +142,18 @@ export interface I18nTranslations { 'messages.loading.placeholder': string; + /* |---------------------------------------------------------------| */ + /* | Consent | */ + /* |---------------------------------------------------------------| */ + + 'consent.required': string; + 'consent.essential_claims': string; + 'consent.optional_claims': string; + 'consent.authorize_scope': string; + 'consent.essential_claims.info': string; + 'consent.optional_claims.info': string; + 'consent.authorize_scope.info': string; + /* |---------------------------------------------------------------| */ /* | Errors | */ /* |---------------------------------------------------------------| */ diff --git a/packages/javascript/src/i18n/translations/en-US.ts b/packages/javascript/src/i18n/translations/en-US.ts index 408c9012..06e82e57 100644 --- a/packages/javascript/src/i18n/translations/en-US.ts +++ b/packages/javascript/src/i18n/translations/en-US.ts @@ -139,6 +139,18 @@ const translations: I18nTranslations = { 'messages.loading.placeholder': 'Loading...', + /* |---------------------------------------------------------------| */ + /* | Consent | */ + /* |---------------------------------------------------------------| */ + + 'consent.required': 'Required', + 'consent.essential_claims': 'Essential Attributes', + 'consent.optional_claims': 'Optional Attributes', + 'consent.authorize_scope': 'Permissions', + 'consent.essential_claims.info': 'These attributes are required for the service to function properly.', + 'consent.optional_claims.info': 'These attributes are optional and can be provided at your discretion.', + 'consent.authorize_scope.info': 'These permissions allow the service to access additional features.', + /* |---------------------------------------------------------------| */ /* | Errors | */ /* |---------------------------------------------------------------| */ diff --git a/packages/javascript/src/i18n/translations/fr-FR.ts b/packages/javascript/src/i18n/translations/fr-FR.ts index ceb8ccc7..3f6f26b6 100644 --- a/packages/javascript/src/i18n/translations/fr-FR.ts +++ b/packages/javascript/src/i18n/translations/fr-FR.ts @@ -141,6 +141,19 @@ const translations: I18nTranslations = { 'messages.loading.placeholder': 'Chargement...', + /* |---------------------------------------------------------------| */ + /* | Consent | */ + /* |---------------------------------------------------------------| */ + + 'consent.required': 'Obligatoire', + 'consent.essential_claims': 'Attributs essentiels', + 'consent.optional_claims': 'Attributs facultatifs', + 'consent.authorize_scope': 'Autorisations', + 'consent.essential_claims.info': 'Ces attributs sont nécessaires au bon fonctionnement du service.', + 'consent.optional_claims.info': 'Ces attributs sont facultatifs et peuvent être fournis à votre discrétion.', + 'consent.authorize_scope.info': + "Ces autorisations permettent au service d'accéder à des fonctionnalités supplémentaires.", + /* |---------------------------------------------------------------| */ /* | Errors | */ /* |---------------------------------------------------------------| */ diff --git a/packages/javascript/src/i18n/translations/hi-IN.ts b/packages/javascript/src/i18n/translations/hi-IN.ts index f7f252d8..44df23ed 100644 --- a/packages/javascript/src/i18n/translations/hi-IN.ts +++ b/packages/javascript/src/i18n/translations/hi-IN.ts @@ -139,6 +139,18 @@ const translations: I18nTranslations = { 'messages.loading.placeholder': 'लोड हो रहा है...', + /* |---------------------------------------------------------------| */ + /* | Consent | */ + /* |---------------------------------------------------------------| */ + + 'consent.required': 'आवश्यक', + 'consent.essential_claims': 'आवश्यक विशेषताएँ', + 'consent.optional_claims': 'वैकल्पिक विशेषताएँ', + 'consent.authorize_scope': 'अनुमतियाँ', + 'consent.essential_claims.info': 'सेवा के सही ढंग से कार्य करने के लिए ये विशेषताएँ आवश्यक हैं।', + 'consent.optional_claims.info': 'ये विशेषताएँ वैकल्पिक हैं और आपके विवेकानुसार प्रदान की जा सकती हैं।', + 'consent.authorize_scope.info': 'ये अनुमतियाँ सेवा को अतिरिक्त सुविधाओं तक पहुँचने की अनुमति देती हैं।', + /* |---------------------------------------------------------------| */ /* | Errors | */ /* |---------------------------------------------------------------| */ diff --git a/packages/javascript/src/i18n/translations/ja-JP.ts b/packages/javascript/src/i18n/translations/ja-JP.ts index 9df3da55..c8a58487 100644 --- a/packages/javascript/src/i18n/translations/ja-JP.ts +++ b/packages/javascript/src/i18n/translations/ja-JP.ts @@ -139,6 +139,18 @@ const translations: I18nTranslations = { 'messages.loading.placeholder': '読み込み中…', + /* |---------------------------------------------------------------| */ + /* | Consent | */ + /* |---------------------------------------------------------------| */ + + 'consent.required': '必須', + 'consent.essential_claims': '必須属性', + 'consent.optional_claims': '任意属性', + 'consent.authorize_scope': '権限', + 'consent.essential_claims.info': 'これらの属性は、サービスが正常に機能するために必要です。', + 'consent.optional_claims.info': 'これらの属性は任意であり、お客様の判断で提供できます。', + 'consent.authorize_scope.info': 'これらの権限により、サービスが追加機能にアクセスできるようになります。', + /* |---------------------------------------------------------------| */ /* | Errors | */ /* |---------------------------------------------------------------| */ diff --git a/packages/javascript/src/i18n/translations/pt-BR.ts b/packages/javascript/src/i18n/translations/pt-BR.ts index b7e39630..5b048033 100644 --- a/packages/javascript/src/i18n/translations/pt-BR.ts +++ b/packages/javascript/src/i18n/translations/pt-BR.ts @@ -139,6 +139,18 @@ const translations: I18nTranslations = { 'messages.loading.placeholder': 'Carregando...', + /* |---------------------------------------------------------------| */ + /* | Consent | */ + /* |---------------------------------------------------------------| */ + + 'consent.required': 'Obrigatório', + 'consent.essential_claims': 'Atributos essenciais', + 'consent.optional_claims': 'Atributos opcionais', + 'consent.authorize_scope': 'Permissões', + 'consent.essential_claims.info': 'Esses atributos são necessários para o funcionamento adequado do serviço.', + 'consent.optional_claims.info': 'Esses atributos são opcionais e podem ser fornecidos a seu critério.', + 'consent.authorize_scope.info': 'Essas permissões permitem que o serviço acesse recursos adicionais.', + /* |---------------------------------------------------------------| */ /* | Errors | */ /* |---------------------------------------------------------------| */ diff --git a/packages/javascript/src/i18n/translations/pt-PT.ts b/packages/javascript/src/i18n/translations/pt-PT.ts index 6580795c..4992fc2f 100644 --- a/packages/javascript/src/i18n/translations/pt-PT.ts +++ b/packages/javascript/src/i18n/translations/pt-PT.ts @@ -139,6 +139,18 @@ const translations: I18nTranslations = { 'messages.loading.placeholder': 'A carregar...', + /* |---------------------------------------------------------------| */ + /* | Consent | */ + /* |---------------------------------------------------------------| */ + + 'consent.required': 'Obrigatório', + 'consent.essential_claims': 'Atributos essenciais', + 'consent.optional_claims': 'Atributos opcionais', + 'consent.authorize_scope': 'Permissões', + 'consent.essential_claims.info': 'Estes atributos são necessários para o correto funcionamento do serviço.', + 'consent.optional_claims.info': 'Estes atributos são opcionais e podem ser fornecidos ao seu critério.', + 'consent.authorize_scope.info': 'Estas permissões permitem que o serviço aceda a funcionalidades adicionais.', + /* |---------------------------------------------------------------| */ /* | Errors | */ /* |---------------------------------------------------------------| */ diff --git a/packages/javascript/src/i18n/translations/si-LK.ts b/packages/javascript/src/i18n/translations/si-LK.ts index 16a9e117..dd4dc6c7 100644 --- a/packages/javascript/src/i18n/translations/si-LK.ts +++ b/packages/javascript/src/i18n/translations/si-LK.ts @@ -139,6 +139,18 @@ const translations: I18nTranslations = { 'messages.loading.placeholder': 'ලෝඩ් වෙමින්...', + /* |---------------------------------------------------------------| */ + /* | Consent | */ + /* |---------------------------------------------------------------| */ + + 'consent.required': 'අවශ්‍යයි', + 'consent.essential_claims': 'අත්‍යවශ්‍ය ගුණාංග', + 'consent.optional_claims': 'විකල්ප ගුණාංග', + 'consent.authorize_scope': 'අවසර', + 'consent.essential_claims.info': 'සේවාව නිසි ලෙස ක්‍රියාත්මක වීම සඳහා මෙම ගුණාංග අවශ්‍ය වේ.', + 'consent.optional_claims.info': 'මෙම ගුණාංග විකල්ප වන අතර ඔබේ අභිමතය පරිදි සැපයිය හැක.', + 'consent.authorize_scope.info': 'මෙම අවසරයන් මගින් සේවාවට අමතර විශේෂාංග වෙත ප්‍රවේශ වීමට ඉඩ සලසයි.', + /* |---------------------------------------------------------------| */ /* | Errors | */ /* |---------------------------------------------------------------| */ diff --git a/packages/javascript/src/i18n/translations/ta-IN.ts b/packages/javascript/src/i18n/translations/ta-IN.ts index 979f91ab..adee2f3e 100644 --- a/packages/javascript/src/i18n/translations/ta-IN.ts +++ b/packages/javascript/src/i18n/translations/ta-IN.ts @@ -140,6 +140,18 @@ const translations: I18nTranslations = { 'messages.loading.placeholder': 'ஏற்றப்படுகிறது...', + /* |---------------------------------------------------------------| */ + /* | Consent | */ + /* |---------------------------------------------------------------| */ + + 'consent.required': 'தேவையானது', + 'consent.essential_claims': 'அத்தியாவசிய பண்புகள்', + 'consent.optional_claims': 'விருப்பத் பண்புகள்', + 'consent.authorize_scope': 'அனுமதிகள்', + 'consent.essential_claims.info': 'சேவை சரியாக செயல்பட இந்த பண்புகள் தேவை.', + 'consent.optional_claims.info': 'இந்த பண்புகள் விருப்பத்தேர்வு மற்றும் உங்கள் விருப்பப்படி வழங்கப்படலாம்.', + 'consent.authorize_scope.info': 'இந்த அனுமதிகள் கூடுதல் அம்சங்களை அணுக சேவைக்கு உதவுகின்றன.', + /* |---------------------------------------------------------------| */ /* | Errors | */ /* |---------------------------------------------------------------| */ diff --git a/packages/javascript/src/i18n/translations/te-IN.ts b/packages/javascript/src/i18n/translations/te-IN.ts index 03c0639f..5716f9f2 100644 --- a/packages/javascript/src/i18n/translations/te-IN.ts +++ b/packages/javascript/src/i18n/translations/te-IN.ts @@ -140,6 +140,18 @@ const translations: I18nTranslations = { 'messages.loading.placeholder': 'లోడ్ అవుతోంది...', + /* |---------------------------------------------------------------| */ + /* | Consent | */ + /* |---------------------------------------------------------------| */ + + 'consent.required': 'తప్పనిసరి', + 'consent.essential_claims': 'ఆవశ్యక లక్షణాలు', + 'consent.optional_claims': 'ఐచ్ఛిక లక్షణాలు', + 'consent.authorize_scope': 'అనుమతులు', + 'consent.essential_claims.info': 'సేవ సరిగ్గా పనిచేయడానికి ఈ లక్షణాలు అవసరం.', + 'consent.optional_claims.info': 'ఈ లక్షణాలు ఐచ్ఛికం మరియు మీ విచక్షణ మేరకు అందించవచ్చు.', + 'consent.authorize_scope.info': 'ఈ అనుమతులు సేవను అదనపు ఫీచర్‌లను యాక్సెస్ చేయడానికి అనుమతిస్తాయి.', + /* |---------------------------------------------------------------| */ /* | Errors | */ /* |---------------------------------------------------------------| */ diff --git a/packages/react/src/components/adapters/Consent.tsx b/packages/react/src/components/adapters/Consent.tsx index fbe14bae..a188239b 100644 --- a/packages/react/src/components/adapters/Consent.tsx +++ b/packages/react/src/components/adapters/Consent.tsx @@ -1,12 +1,7 @@ // Copyright 2026 The ThunderID Authors // SPDX-License-Identifier: Apache-2.0 -import { - type ConsentPurposeData, - FlowMetadataResponse, - PromptElement, - resolveFlowTemplateLiterals, -} from '@thunderid/browser'; +import {type ConsentPurposeData, PromptElement} from '@thunderid/browser'; import {type ChangeEvent, FC, ReactNode} from 'react'; import ConsentCheckboxList, {getConsentOptionalKey} from './ConsentCheckboxList'; import Typography from '../primitives/Typography/Typography'; @@ -35,16 +30,6 @@ export interface ConsentRenderProps { purposes: ConsentPurposeData[]; } -/** - * Interface for consent configuration - */ -export interface ConsentConfig { - essential?: string; - optional?: string; - essentialInfo?: string; - optionalInfo?: string; -} - /** * Props for the Consent component. */ @@ -78,15 +63,6 @@ export interface ConsentProps { * Callback invoked when a user toggles an optional attribute. */ onInputChange: (name: string, value: string) => void; - /** - * Config to modified detail in consent page - */ - config?: Record; - - /** - * Config of meta response - */ - meta?: FlowMetadataResponse | null; /** * translation data @@ -94,25 +70,12 @@ export interface ConsentProps { t?: UseTranslation['t']; } -const defaultConfig: Required> = { - essential: 'Essential Attributtes', - optional: 'Optional Attributes', -}; - /** * Consent component renders the list of purposes and their associated attributes (essential and optional) * based on the data provided by the backend. It allows users to toggle optional attributes while essential * attributes are displayed as read-only. */ -const Consent: FC = ({ - consentData, - formValues, - config: suppliedConfig = {}, - onInputChange, - children, - meta, - t, -}: ConsentProps) => { +const Consent: FC = ({consentData, formValues, onInputChange, children, t}: ConsentProps) => { // Computed per render (not at module scope): a CSP nonce configured on // isn't known until the provider renders, and Emotion needs it applied before any style // insertion happens. These are static, so Emotion's own cache dedupes the repeat calls to a @@ -135,19 +98,24 @@ const Consent: FC = ({ }); const optionalSectionLabelClass: string = css({alignItems: 'center', display: 'flex', gap: '4px'}); - /** Resolve any remaining {{t()}} or {{meta()}} template expressions in a string at render time. */ + /** Resolve i18n keys */ const resolve = (text: string | undefined): string => { - if (!text || (!t && !meta)) { + if (!text || !t) { return text || ''; } - return resolveFlowTemplateLiterals(text, {meta, t: t || ((k: string): string => k)}); + return t(text); }; - const config: ConsentConfig = {...defaultConfig, ...suppliedConfig}; - const essentialInfo = typeof config.essentialInfo === 'string' ? resolve(config.essentialInfo.trim()) : ''; - const optionalInfo = typeof config.optionalInfo === 'string' ? resolve(config.optionalInfo.trim()) : ''; - const essentialLabel = resolve(config['essential']); - const optionalLabel = resolve(config['optional']); + const essentialInfo = resolve(`consent.essential_claims.info`); + const optionalInfo = resolve(`consent.optional_claims.info`); + const permissionInfo = resolve(`consent.authorize_scope.info`); + /** + * Falls back to default config values if essential/optional + * keys cannot be resolved via translation files . + */ + const essentialLabel = resolve(`consent.essential_claims`) || 'Essential Attributes'; + const optionalLabel = resolve(`consent.optional_claims`) || 'Optional Attributes'; + const permissionLabel = resolve(`consent.authorize_scope`) || 'Permissions'; /** * Method to check whether master toggle button is checked or not @@ -223,6 +191,7 @@ const Consent: FC = ({ purpose={purpose} formValues={formValues} onInputChange={onInputChange} + t={t} /> )} @@ -232,10 +201,11 @@ const Consent: FC = ({
- {purpose.type === 'permissions' ? 'Permissions' : optionalLabel} + {purpose.type === 'permissions' ? permissionLabel : optionalLabel} - {optionalInfo !== '' && ( - + {/* Show tooltip for optional claims/permissions according to their type */} + {Boolean(purpose.type === 'permissions' ? permissionInfo : optionalInfo) && ( + )} @@ -252,6 +222,7 @@ const Consent: FC = ({ purpose={purpose} formValues={formValues} onInputChange={onInputChange} + t={t} />
)} diff --git a/packages/react/src/components/adapters/ConsentCheckboxList.tsx b/packages/react/src/components/adapters/ConsentCheckboxList.tsx index 00d20040..798e4611 100644 --- a/packages/react/src/components/adapters/ConsentCheckboxList.tsx +++ b/packages/react/src/components/adapters/ConsentCheckboxList.tsx @@ -8,6 +8,7 @@ import useTheme from '../../contexts/Theme/useTheme'; import {cx} from '../../styles/emotion'; import Toggle from '../primitives/Toggle/Toggle'; import Typography from '../primitives/Typography/Typography'; +import {UseTranslation} from '../../hooks/useTranslation'; /** * Computes the form value key for tracking an optional attribute's consent state. @@ -78,6 +79,10 @@ export interface ConsentCheckboxListProps { purpose: ConsentPurposeData; /** Whether to render essential (disabled) or optional (toggleable) attributes */ variant: ConsentInputVariant; + /** + * translation data + */ + t?: UseTranslation['t']; } /** @@ -93,10 +98,21 @@ const ConsentCheckboxList: FC = ({ formValues, onInputChange, children, + t, }: ConsentCheckboxListProps) => { const {theme, colorScheme}: ReturnType = useTheme(); const styles: Record = useStyles(theme, colorScheme); + const resolve = (text: string | undefined): string => { + if (!text || !t) { + return text || ''; + } + + const key: string = `consent.${text}`; + const translated: string = t(key); + return translated === key ? text : translated; + }; + const attributes: string[] = (variant === 'ESSENTIAL' ? purpose.essential : purpose.optional).map( (e): string => e.name, ); @@ -153,11 +169,11 @@ const ConsentCheckboxList: FC = ({ styles['typography'], )} > - {attr} + {resolve(attr)}
{isEssential ? ( - Required + {resolve('required') || 'Required'} ) : ( );