@learncard/react 2.10.7 → 2.10.8

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 (46) hide show
  1. package/dist/cjs/{MeritBadgeDisplayCard-1de23221.js → MeritBadgeDisplayCard-15b85a79.js} +2 -2
  2. package/dist/cjs/{MeritBadgeDisplayCard-1de23221.js.map → MeritBadgeDisplayCard-15b85a79.js.map} +1 -1
  3. package/dist/cjs/{VCCard-b5d1ecb3.js → VCCard-4f02e2f4.js} +2 -2
  4. package/dist/cjs/{VCCard-b5d1ecb3.js.map → VCCard-4f02e2f4.js.map} +1 -1
  5. package/dist/cjs/{VCDisplayCard2-ede5a360.js → VCDisplayCard2-8517f419.js} +28 -13
  6. package/dist/cjs/VCDisplayCard2-8517f419.js.map +1 -0
  7. package/dist/cjs/i18n-cc7e34ec.js +55 -0
  8. package/dist/cjs/i18n-cc7e34ec.js.map +1 -0
  9. package/dist/cjs/index.js +7 -3
  10. package/dist/cjs/index.js.map +1 -1
  11. package/dist/cjs/index14.js +4 -3
  12. package/dist/cjs/index14.js.map +1 -1
  13. package/dist/cjs/index22.js +2 -1
  14. package/dist/cjs/index22.js.map +1 -1
  15. package/dist/cjs/index39.js +4 -3
  16. package/dist/cjs/index39.js.map +1 -1
  17. package/dist/cjs/index42.js +3 -2
  18. package/dist/cjs/index42.js.map +1 -1
  19. package/dist/esm/{MeritBadgeDisplayCard-a7a504e0.js → MeritBadgeDisplayCard-2029a552.js} +2 -2
  20. package/dist/esm/{MeritBadgeDisplayCard-a7a504e0.js.map → MeritBadgeDisplayCard-2029a552.js.map} +1 -1
  21. package/dist/esm/{VCCard-f017f1ee.js → VCCard-c0f6dff3.js} +2 -2
  22. package/dist/esm/{VCCard-f017f1ee.js.map → VCCard-c0f6dff3.js.map} +1 -1
  23. package/dist/esm/{VCDisplayCard2-72bed598.js → VCDisplayCard2-fc5c4225.js} +28 -13
  24. package/dist/esm/VCDisplayCard2-fc5c4225.js.map +1 -0
  25. package/dist/esm/i18n-8454d6ea.js +47 -0
  26. package/dist/esm/i18n-8454d6ea.js.map +1 -0
  27. package/dist/esm/index.js +4 -3
  28. package/dist/esm/index.js.map +1 -1
  29. package/dist/esm/index14.js +4 -3
  30. package/dist/esm/index14.js.map +1 -1
  31. package/dist/esm/index22.js +2 -1
  32. package/dist/esm/index22.js.map +1 -1
  33. package/dist/esm/index39.js +4 -3
  34. package/dist/esm/index39.js.map +1 -1
  35. package/dist/esm/index42.js +3 -2
  36. package/dist/esm/index42.js.map +1 -1
  37. package/dist/index.d.ts +37 -1
  38. package/package.json +2 -2
  39. package/src/components/MeritBadgeDisplayCard/MeritBadgeFrontFace.tsx +1 -1
  40. package/src/components/MeritBadgeDisplayCard/VerifierStateBadgeAndText.tsx +7 -5
  41. package/src/components/VCDisplayCard2/VerificationRow.tsx +27 -4
  42. package/src/components/VCDisplayCard2/VerificationsBox.tsx +4 -5
  43. package/src/i18n/index.tsx +87 -0
  44. package/src/index.ts +3 -0
  45. package/dist/cjs/VCDisplayCard2-ede5a360.js.map +0 -1
  46. package/dist/esm/VCDisplayCard2-72bed598.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n-8454d6ea.js","sources":["../../src/i18n/index.tsx"],"sourcesContent":["/**\n * Lightweight i18n adapter for `@learncard/react`.\n *\n * This is a PUBLISHED SDK consumed by external third parties who have no\n * Paraglide, no app providers, and no catalog. So the rule is: render English\n * with zero configuration, and only *optionally* accept translations.\n *\n * Components call `useT()`. With no provider mounted, `useT()` returns the\n * co-located English default (zero-config English for every consumer). A\n * consumer that wants localization mounts `<I18nProvider resolve={fn} locale={l}>`\n * where `fn` maps a key to a translated string using whatever i18n they use\n * (Paraglide, i18next, a static map — the SDK doesn't care).\n *\n * Kept intentionally dependency-free and self-contained (a ~40-line copy also\n * lives in learn-card-base) so the SDK pulls in no i18n runtime.\n */\nimport React, { createContext, useCallback, useContext, useMemo } from 'react';\n\nexport type I18nResolver = (key: string, params?: Record<string, unknown>) => string | undefined;\n\ntype I18nContextValue = { resolve: I18nResolver; locale: string };\n\nconst I18nContext = createContext<I18nContextValue | null>(null);\n\n/**\n * English defaults co-located with the SDK. One entry per extracted string.\n * Keys are unprefixed; a host app namespaces them (e.g. `sdk.`) in its catalog.\n */\nexport const EN_DEFAULTS: Record<string, string> = {\n 'verification.selfIssued': 'Self Issued',\n 'verification.trustedIssuer': 'Trusted Issuer',\n 'verification.unknownIssuer': 'Unknown Issuer',\n 'verification.appIssuer': 'Trusted App',\n 'verification.untrustedIssuer': 'Untrusted Issuer',\n 'credential.by': 'By',\n 'verification.title': 'Credential Verifications',\n 'verification.infoText':\n 'Credential verifications check the cryptographic proof of digital credentials to ensure their authenticity and accuracy.',\n 'verification.status.success': 'Success',\n 'verification.status.error': 'Error',\n 'verification.status.failed': 'Failed',\n 'verification.check.proof': 'Proof',\n 'verification.check.status': 'Status',\n 'verification.check.expiration': 'Expiration',\n 'verification.message.valid': 'Valid',\n 'verification.message.invalid': 'Invalid',\n 'verification.message.notRevoked': 'Not Revoked',\n 'verification.message.revoked': 'Revoked',\n 'verification.message.doesNotExpire': 'Does Not Expire',\n 'verification.message.expired': 'Expired',\n 'verification.message.active': 'Active',\n 'verification.message.couldNotVerify': 'Boost Credential could not be verified.',\n};\n\n/** Minimal `{var}` interpolation — no dependency. */\nconst interpolate = (str: string, params?: Record<string, unknown>): string =>\n params\n ? str.replace(/\\{(\\w+)\\}/g, (_, k) => (params[k] != null ? String(params[k]) : `{${k}}`))\n : str;\n\nexport const I18nProvider: React.FC<{\n resolve: I18nResolver;\n locale: string;\n children: React.ReactNode;\n}> = ({ resolve, locale, children }) => {\n const value = useMemo<I18nContextValue>(() => ({ resolve, locale }), [resolve, locale]);\n return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>;\n};\n\n/**\n * Returns a translate function. Resolution order:\n * 1. host resolver (consumer catalog) if a provider is mounted and has the key\n * 2. co-located English default (interpolated)\n * 3. the key itself (last-resort)\n */\nexport const useT = (): ((key: string, params?: Record<string, unknown>) => string) => {\n const ctx = useContext(I18nContext);\n return useCallback(\n (key: string, params?: Record<string, unknown>) => {\n const fromHost = ctx?.resolve(key, params);\n if (fromHost != null) return fromHost;\n const def = EN_DEFAULTS[key];\n return def != null ? interpolate(def, params) : key;\n },\n [ctx]\n );\n};\n"],"names":[],"mappings":";;AAsBA,MAAM,WAAA,GAAc,cAAuC,IAAI,CAAA,CAAA;AAMxD,MAAM,WAAsC,GAAA;AAAA,EAC/C,yBAA2B,EAAA,aAAA;AAAA,EAC3B,4BAA8B,EAAA,gBAAA;AAAA,EAC9B,4BAA8B,EAAA,gBAAA;AAAA,EAC9B,wBAA0B,EAAA,aAAA;AAAA,EAC1B,8BAAgC,EAAA,kBAAA;AAAA,EAChC,eAAiB,EAAA,IAAA;AAAA,EACjB,oBAAsB,EAAA,0BAAA;AAAA,EACtB,uBACI,EAAA,0HAAA;AAAA,EACJ,6BAA+B,EAAA,SAAA;AAAA,EAC/B,2BAA6B,EAAA,OAAA;AAAA,EAC7B,4BAA8B,EAAA,QAAA;AAAA,EAC9B,0BAA4B,EAAA,OAAA;AAAA,EAC5B,2BAA6B,EAAA,QAAA;AAAA,EAC7B,+BAAiC,EAAA,YAAA;AAAA,EACjC,4BAA8B,EAAA,OAAA;AAAA,EAC9B,8BAAgC,EAAA,SAAA;AAAA,EAChC,iCAAmC,EAAA,aAAA;AAAA,EACnC,8BAAgC,EAAA,SAAA;AAAA,EAChC,oCAAsC,EAAA,iBAAA;AAAA,EACtC,8BAAgC,EAAA,SAAA;AAAA,EAChC,6BAA+B,EAAA,QAAA;AAAA,EAC/B,qCAAuC,EAAA,yCAAA;AAC3C,EAAA;AAGA,MAAM,WAAA,GAAc,CAAC,GAAa,EAAA,MAAA,KAC9B,SACM,GAAI,CAAA,OAAA,CAAQ,YAAc,EAAA,CAAC,CAAG,EAAA,CAAA,KAAO,OAAO,CAAC,CAAA,IAAK,IAAO,GAAA,MAAA,CAAO,MAAO,CAAA,CAAC,CAAC,CAAI,GAAA,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAI,CACtF,GAAA,GAAA,CAAA;AAEH,MAAM,eAIR,CAAC,EAAE,OAAS,EAAA,MAAA,EAAQ,UAAe,KAAA;AACpC,EAAM,MAAA,KAAA,GAAQ,OAA0B,CAAA,OAAO,EAAE,OAAA,EAAS,QAAW,CAAA,EAAA,CAAC,OAAS,EAAA,MAAM,CAAC,CAAA,CAAA;AACtF,EAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,WAAA,CAAY,QAAZ,EAAA,EAAqB,SAAe,QAAS,CAAA,CAAA;AACzD,EAAA;AAQO,MAAM,OAAO,MAAmE;AACnF,EAAM,MAAA,GAAA,GAAM,WAAW,WAAW,CAAA,CAAA;AAClC,EAAO,OAAA,WAAA;AAAA,IACH,CAAC,KAAa,MAAqC,KAAA;AAC/C,MAAM,MAAA,QAAA,GAAW,GAAK,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,GAAA,CAAA,OAAA,CAAQ,GAAK,EAAA,MAAA,CAAA,CAAA;AACnC,MAAI,IAAA,QAAA,IAAY,MAAa,OAAA,QAAA,CAAA;AAC7B,MAAM,MAAA,GAAA,GAAM,YAAY,GAAG,CAAA,CAAA;AAC3B,MAAA,OAAO,GAAO,IAAA,IAAA,GAAO,WAAY,CAAA,GAAA,EAAK,MAAM,CAAI,GAAA,GAAA,CAAA;AAAA,KACpD;AAAA,IACA,CAAC,GAAG,CAAA;AAAA,GACR,CAAA;AACJ;;;;"}
package/dist/esm/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import React, { useRef, useEffect, useMemo, useState } from 'react';
2
2
  export { S as SelectedSkills, V as VERIFIER_STATES, f as formatDidDisplayName, b as getAvatarColorFromString, g as getAvatarLetterFromDid, i as isDid, a as isLearnCardNetworkDid, r as resolveProfileDisplay } from './VerifierStateBadgeAndText-60b98d25.js';
3
+ export { E as EN_DEFAULTS, I as I18nProvider, u as useT } from './i18n-8454d6ea.js';
3
4
  export { A as AchievementCard } from './AchievementCard-c600788a.js';
4
5
  export { B as BoostGenericCard } from './BoostGenericCard-7dfcc887.js';
5
6
  export { B as BoostSmallCard } from './BoostSmallCard-a73b6800.js';
@@ -18,7 +19,7 @@ export { L as LearnCardCreditCardFrontFace } from './LearnCardCreditCardFrontFac
18
19
  export { L as LearnPill } from './LearnPill-e0720485.js';
19
20
  export { L as Lightbox } from './Lightbox-f0338a0c.js';
20
21
  export { C as CircleLoadingState } from './CircleSpinner-03a329fc.js';
21
- export { M as MeritBadgeBackFace, a as MeritBadgeDisplayCard, b as MeritBadgeFrontFace } from './MeritBadgeDisplayCard-a7a504e0.js';
22
+ export { M as MeritBadgeBackFace, a as MeritBadgeDisplayCard, b as MeritBadgeFrontFace } from './MeritBadgeDisplayCard-2029a552.js';
22
23
  export { M as MeritBadgeSkillsCount } from './MeritBadgeSkillsCount-c5271d7f.js';
23
24
  export { M as MiniVCThumbnail } from './MiniVCThumbnail-cc05e1f8.js';
24
25
  export { N as Notification } from './Notification-279ba207.js';
@@ -37,10 +38,10 @@ export { a as SkillsCard, S as SkillsMeterSegment } from './SkillsCard-5279aac9.
37
38
  export { S as SkillsStatsCard } from './SkillsStatsCard-e0cd6137.js';
38
39
  export { S as SmallAchievementCard } from './SmallAchievementCard-24dfa453.js';
39
40
  export { U as UserProfilePicture } from './UserProfilePicture-50c34186.js';
40
- export { V as VCCard } from './VCCard-f017f1ee.js';
41
+ export { V as VCCard } from './VCCard-c0f6dff3.js';
41
42
  export { V as VCDisplayBackFace } from './VCDisplayBackFace-bb60a881.js';
42
43
  export { V as VCDisplayCard } from './VCDisplayCard-9905d9d3.js';
43
- export { V as VCDisplayCard2, a as VCDisplayCardSkillsCount, b as VCIDDisplayCard } from './VCDisplayCard2-72bed598.js';
44
+ export { V as VCDisplayCard2, a as VCDisplayCardSkillsCount, b as VCIDDisplayCard } from './VCDisplayCard2-fc5c4225.js';
44
45
  export { V as VCThumbnail } from './VCThumbnail-835921dd.js';
45
46
  export { V as VCVerificationCheck, a as VCVerificationCheckWithSpinner, b as VCVerificationCheckWithText } from './VCVerificationCheck-8b8b7a76.js';
46
47
  export { V as ValidationStateIndicator } from './VCVerificationPill-83eb61f4.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/helpers/useOnMomentumScrollEnd.ts","../../src/helpers/useScrollBorders.ts","../../src/hooks/useCredentialFormat.tsx","../../src/hooks/useParsedSdJwtVc.tsx","../../src/helpers/credentialFormat.helpers.ts"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\n\nexport const useOnMomentumScrollEnd = ({\n onScroll: _onScroll,\n onMomentumScrollEnd,\n debounceTime = 305,\n}: {\n onScroll?: React.UIEventHandler;\n onMomentumScrollEnd: React.UIEventHandler;\n debounceTime?: number;\n}) => {\n const momentumScrollEndTimer = useRef<NodeJS.Timeout>();\n\n useEffect(() => () => clearTimeout(momentumScrollEndTimer.current), []);\n\n const onScroll: React.UIEventHandler = (e) => {\n _onScroll?.(e);\n\n clearTimeout(momentumScrollEndTimer.current);\n momentumScrollEndTimer.current = setTimeout(() => {\n onMomentumScrollEnd(e);\n }, debounceTime);\n };\n\n return onScroll;\n};\n\nexport default useOnMomentumScrollEnd;\n","import React, { useEffect, type RefObject } from 'react';\n\nexport const useScrollBorders = <Ref extends HTMLElement>({\n ref,\n topShowClassName = 'border-t border-t-[--color-grayscale-line]',\n topHideClassName = 'border-t border-t-transparent',\n bottomShowClassName = 'border-b border-b-[--color-grayscale-line]',\n bottomHideClassName = 'border-b border-b-transparent',\n}: {\n ref?: RefObject<Ref>;\n topShowClassName?: string;\n topHideClassName?: string;\n bottomShowClassName?: string;\n bottomHideClassName?: string;\n} = {}) => {\n const internalRef = ref ?? React.createRef<Ref>();\n\n const updateBorderClasses = () => {\n if (\n !internalRef.current ||\n internalRef.current.scrollHeight <= internalRef.current.clientHeight\n )\n return;\n\n // Top border\n if (internalRef.current.scrollTop > 0) {\n internalRef.current.classList.remove(...topHideClassName.split(' '));\n internalRef.current.classList.add(...topShowClassName.split(' '));\n } else {\n internalRef.current.classList.remove(...topShowClassName.split(' '));\n internalRef.current.classList.add(...topHideClassName.split(' '));\n }\n\n // Bottom border\n if (\n internalRef.current.scrollTop <\n internalRef.current.scrollHeight - internalRef.current.clientHeight\n ) {\n internalRef.current.classList.remove(...bottomHideClassName.split(' '));\n internalRef.current.classList.add(...bottomShowClassName.split(' '));\n } else {\n internalRef.current.classList.remove(...bottomShowClassName.split(' '));\n internalRef.current.classList.add(...bottomHideClassName.split(' '));\n }\n };\n\n useEffect(() => {\n const element = internalRef.current;\n if (element) {\n updateBorderClasses();\n\n element.addEventListener('scroll', updateBorderClasses);\n\n return () => element.removeEventListener('scroll', updateBorderClasses);\n }\n }, [internalRef]); // Re-run when ref changes\n\n return internalRef;\n};\n","import { useMemo } from 'react';\n\nexport type CredentialFormat = 'dc+sd-jwt' | 'vc+sd-jwt' | 'jwt-vc-json' | 'ldp-vc' | 'unknown';\n\nexport const useCredentialFormat = (vc: unknown): CredentialFormat => {\n return useMemo(() => {\n if (!vc || typeof vc !== 'object') return 'unknown';\n const proof = (vc as any).proof;\n const proofs: any[] = Array.isArray(proof) ? proof : proof ? [proof] : [];\n\n const sdJwt = proofs.find(\n p => p?.type === 'SdJwtCompactProof' && typeof p?.jwt === 'string'\n );\n if (sdJwt) return 'dc+sd-jwt';\n\n const proofObj = proofs.find(p => p && typeof p === 'object');\n if (typeof proofObj?.jwt === 'string' || proofObj?.type === 'JwtProof2020') {\n return 'jwt-vc-json';\n }\n if (typeof proofObj?.type === 'string') return 'ldp-vc';\n return 'unknown';\n }, [vc]);\n};\n","import { useState, useEffect } from 'react';\nimport { LearnCard } from '@learncard/core';\n\nexport type ParsedSdJwtVc = {\n vct: string;\n issuer: string;\n issuedAt?: Date;\n expiresAt?: Date;\n notBefore?: Date;\n holderPublicKey?: Record<string, unknown>;\n claims: Record<string, unknown>;\n disclosureKeys: string[];\n header: Record<string, unknown>;\n rawPayload: Record<string, unknown>;\n rawSdJwt: string;\n format: 'dc+sd-jwt' | 'vc+sd-jwt';\n hasKeyBinding: boolean;\n};\n\nexport const useParsedSdJwtVc = (learnCard: LearnCard | undefined, compact: string | undefined) => {\n const [data, setData] = useState<ParsedSdJwtVc | undefined>(undefined);\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<Error | undefined>(undefined);\n\n useEffect(() => {\n let cancelled = false;\n\n if (!learnCard || !compact) {\n setData(undefined);\n setIsLoading(false);\n setError(undefined);\n return;\n }\n\n const parse = async () => {\n setIsLoading(true);\n setError(undefined);\n setData(undefined);\n try {\n const parsed = await (learnCard.invoke as any).parseSdJwtVc(compact);\n if (!cancelled) {\n setData(parsed as ParsedSdJwtVc);\n }\n } catch (err) {\n if (!cancelled) {\n setData(undefined);\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n } finally {\n if (!cancelled) {\n setIsLoading(false);\n }\n }\n };\n\n parse();\n\n return () => {\n cancelled = true;\n };\n }, [learnCard, compact]);\n\n return { data, isLoading, error };\n};\n","export const humanizeClaimLabel = (key: string): string => {\n if (!key) return '';\n\n // Preserve acronyms if all-caps\n if (/^[A-Z]+$/.test(key)) {\n return key;\n }\n\n // Convert snake_case and kebab-case to space-separated\n let humanized = key.replace(/[_-]/g, ' ');\n\n // Convert camelCase to space-separated\n humanized = humanized.replace(/([a-z])([A-Z])/g, '$1 $2');\n\n // Capitalize first letter of each word\n return humanized\n .split(' ')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n};\n\nconst LONG_DATE_FORMAT: Intl.DateTimeFormatOptions = {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n};\n\nexport const formatClaimValue = (value: unknown): string => {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (typeof value === 'boolean') {\n return value ? 'Yes' : 'No';\n }\n\n if (typeof value === 'string') {\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n const [y, m, d] = value.split('-').map(Number);\n const date = new Date(Date.UTC(y, m - 1, d));\n if (!isNaN(date.getTime())) {\n return date.toLocaleDateString(undefined, { ...LONG_DATE_FORMAT, timeZone: 'UTC' });\n }\n }\n if (/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) {\n const date = new Date(value);\n if (!isNaN(date.getTime())) {\n return date.toLocaleDateString(undefined, LONG_DATE_FORMAT);\n }\n }\n return value;\n }\n\n if (typeof value === 'object') {\n if (Array.isArray(value)) {\n const allPrimitive = value.every(v => v === null || typeof v !== 'object');\n if (allPrimitive) return value.map(formatClaimValue).filter(Boolean).join(', ');\n return value.length === 1 ? '1 item' : `${value.length} items`;\n }\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) return '';\n return entries\n .map(([k, v]) => `${humanizeClaimLabel(k)}: ${formatClaimValue(v)}`)\n .join('; ');\n }\n\n return String(value);\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/helpers/useOnMomentumScrollEnd.ts","../../src/helpers/useScrollBorders.ts","../../src/hooks/useCredentialFormat.tsx","../../src/hooks/useParsedSdJwtVc.tsx","../../src/helpers/credentialFormat.helpers.ts"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\n\nexport const useOnMomentumScrollEnd = ({\n onScroll: _onScroll,\n onMomentumScrollEnd,\n debounceTime = 305,\n}: {\n onScroll?: React.UIEventHandler;\n onMomentumScrollEnd: React.UIEventHandler;\n debounceTime?: number;\n}) => {\n const momentumScrollEndTimer = useRef<NodeJS.Timeout>();\n\n useEffect(() => () => clearTimeout(momentumScrollEndTimer.current), []);\n\n const onScroll: React.UIEventHandler = (e) => {\n _onScroll?.(e);\n\n clearTimeout(momentumScrollEndTimer.current);\n momentumScrollEndTimer.current = setTimeout(() => {\n onMomentumScrollEnd(e);\n }, debounceTime);\n };\n\n return onScroll;\n};\n\nexport default useOnMomentumScrollEnd;\n","import React, { useEffect, type RefObject } from 'react';\n\nexport const useScrollBorders = <Ref extends HTMLElement>({\n ref,\n topShowClassName = 'border-t border-t-[--color-grayscale-line]',\n topHideClassName = 'border-t border-t-transparent',\n bottomShowClassName = 'border-b border-b-[--color-grayscale-line]',\n bottomHideClassName = 'border-b border-b-transparent',\n}: {\n ref?: RefObject<Ref>;\n topShowClassName?: string;\n topHideClassName?: string;\n bottomShowClassName?: string;\n bottomHideClassName?: string;\n} = {}) => {\n const internalRef = ref ?? React.createRef<Ref>();\n\n const updateBorderClasses = () => {\n if (\n !internalRef.current ||\n internalRef.current.scrollHeight <= internalRef.current.clientHeight\n )\n return;\n\n // Top border\n if (internalRef.current.scrollTop > 0) {\n internalRef.current.classList.remove(...topHideClassName.split(' '));\n internalRef.current.classList.add(...topShowClassName.split(' '));\n } else {\n internalRef.current.classList.remove(...topShowClassName.split(' '));\n internalRef.current.classList.add(...topHideClassName.split(' '));\n }\n\n // Bottom border\n if (\n internalRef.current.scrollTop <\n internalRef.current.scrollHeight - internalRef.current.clientHeight\n ) {\n internalRef.current.classList.remove(...bottomHideClassName.split(' '));\n internalRef.current.classList.add(...bottomShowClassName.split(' '));\n } else {\n internalRef.current.classList.remove(...bottomShowClassName.split(' '));\n internalRef.current.classList.add(...bottomHideClassName.split(' '));\n }\n };\n\n useEffect(() => {\n const element = internalRef.current;\n if (element) {\n updateBorderClasses();\n\n element.addEventListener('scroll', updateBorderClasses);\n\n return () => element.removeEventListener('scroll', updateBorderClasses);\n }\n }, [internalRef]); // Re-run when ref changes\n\n return internalRef;\n};\n","import { useMemo } from 'react';\n\nexport type CredentialFormat = 'dc+sd-jwt' | 'vc+sd-jwt' | 'jwt-vc-json' | 'ldp-vc' | 'unknown';\n\nexport const useCredentialFormat = (vc: unknown): CredentialFormat => {\n return useMemo(() => {\n if (!vc || typeof vc !== 'object') return 'unknown';\n const proof = (vc as any).proof;\n const proofs: any[] = Array.isArray(proof) ? proof : proof ? [proof] : [];\n\n const sdJwt = proofs.find(\n p => p?.type === 'SdJwtCompactProof' && typeof p?.jwt === 'string'\n );\n if (sdJwt) return 'dc+sd-jwt';\n\n const proofObj = proofs.find(p => p && typeof p === 'object');\n if (typeof proofObj?.jwt === 'string' || proofObj?.type === 'JwtProof2020') {\n return 'jwt-vc-json';\n }\n if (typeof proofObj?.type === 'string') return 'ldp-vc';\n return 'unknown';\n }, [vc]);\n};\n","import { useState, useEffect } from 'react';\nimport { LearnCard } from '@learncard/core';\n\nexport type ParsedSdJwtVc = {\n vct: string;\n issuer: string;\n issuedAt?: Date;\n expiresAt?: Date;\n notBefore?: Date;\n holderPublicKey?: Record<string, unknown>;\n claims: Record<string, unknown>;\n disclosureKeys: string[];\n header: Record<string, unknown>;\n rawPayload: Record<string, unknown>;\n rawSdJwt: string;\n format: 'dc+sd-jwt' | 'vc+sd-jwt';\n hasKeyBinding: boolean;\n};\n\nexport const useParsedSdJwtVc = (learnCard: LearnCard | undefined, compact: string | undefined) => {\n const [data, setData] = useState<ParsedSdJwtVc | undefined>(undefined);\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<Error | undefined>(undefined);\n\n useEffect(() => {\n let cancelled = false;\n\n if (!learnCard || !compact) {\n setData(undefined);\n setIsLoading(false);\n setError(undefined);\n return;\n }\n\n const parse = async () => {\n setIsLoading(true);\n setError(undefined);\n setData(undefined);\n try {\n const parsed = await (learnCard.invoke as any).parseSdJwtVc(compact);\n if (!cancelled) {\n setData(parsed as ParsedSdJwtVc);\n }\n } catch (err) {\n if (!cancelled) {\n setData(undefined);\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n } finally {\n if (!cancelled) {\n setIsLoading(false);\n }\n }\n };\n\n parse();\n\n return () => {\n cancelled = true;\n };\n }, [learnCard, compact]);\n\n return { data, isLoading, error };\n};\n","export const humanizeClaimLabel = (key: string): string => {\n if (!key) return '';\n\n // Preserve acronyms if all-caps\n if (/^[A-Z]+$/.test(key)) {\n return key;\n }\n\n // Convert snake_case and kebab-case to space-separated\n let humanized = key.replace(/[_-]/g, ' ');\n\n // Convert camelCase to space-separated\n humanized = humanized.replace(/([a-z])([A-Z])/g, '$1 $2');\n\n // Capitalize first letter of each word\n return humanized\n .split(' ')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n};\n\nconst LONG_DATE_FORMAT: Intl.DateTimeFormatOptions = {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n};\n\nexport const formatClaimValue = (value: unknown): string => {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (typeof value === 'boolean') {\n return value ? 'Yes' : 'No';\n }\n\n if (typeof value === 'string') {\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n const [y, m, d] = value.split('-').map(Number);\n const date = new Date(Date.UTC(y, m - 1, d));\n if (!isNaN(date.getTime())) {\n return date.toLocaleDateString(undefined, { ...LONG_DATE_FORMAT, timeZone: 'UTC' });\n }\n }\n if (/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) {\n const date = new Date(value);\n if (!isNaN(date.getTime())) {\n return date.toLocaleDateString(undefined, LONG_DATE_FORMAT);\n }\n }\n return value;\n }\n\n if (typeof value === 'object') {\n if (Array.isArray(value)) {\n const allPrimitive = value.every(v => v === null || typeof v !== 'object');\n if (allPrimitive) return value.map(formatClaimValue).filter(Boolean).join(', ');\n return value.length === 1 ? '1 item' : `${value.length} items`;\n }\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) return '';\n return entries\n .map(([k, v]) => `${humanizeClaimLabel(k)}: ${formatClaimValue(v)}`)\n .join('; ');\n }\n\n return String(value);\n};\n"],"names":[],"mappings":"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"}
@@ -17,7 +17,7 @@ export { L as LearnCardCreditCardFrontFace } from './LearnCardCreditCardFrontFac
17
17
  export { L as LearnPill } from './LearnPill-e0720485.js';
18
18
  export { L as Lightbox } from './Lightbox-f0338a0c.js';
19
19
  export { C as CircleLoadingState } from './CircleSpinner-03a329fc.js';
20
- export { M as MeritBadgeBackFace, a as MeritBadgeDisplayCard, b as MeritBadgeFrontFace } from './MeritBadgeDisplayCard-a7a504e0.js';
20
+ export { M as MeritBadgeBackFace, a as MeritBadgeDisplayCard, b as MeritBadgeFrontFace } from './MeritBadgeDisplayCard-2029a552.js';
21
21
  export { M as MeritBadgeSkillsCount } from './MeritBadgeSkillsCount-c5271d7f.js';
22
22
  export { M as MiniVCThumbnail } from './MiniVCThumbnail-cc05e1f8.js';
23
23
  export { N as Notification } from './Notification-279ba207.js';
@@ -36,10 +36,10 @@ export { a as SkillsCard, S as SkillsMeterSegment } from './SkillsCard-5279aac9.
36
36
  export { S as SkillsStatsCard } from './SkillsStatsCard-e0cd6137.js';
37
37
  export { S as SmallAchievementCard } from './SmallAchievementCard-24dfa453.js';
38
38
  export { U as UserProfilePicture } from './UserProfilePicture-50c34186.js';
39
- export { V as VCCard } from './VCCard-f017f1ee.js';
39
+ export { V as VCCard } from './VCCard-c0f6dff3.js';
40
40
  export { V as VCDisplayBackFace } from './VCDisplayBackFace-bb60a881.js';
41
41
  export { V as VCDisplayCard } from './VCDisplayCard-9905d9d3.js';
42
- export { V as VCDisplayCard2, a as VCDisplayCardSkillsCount, b as VCIDDisplayCard } from './VCDisplayCard2-72bed598.js';
42
+ export { V as VCDisplayCard2, a as VCDisplayCardSkillsCount, b as VCIDDisplayCard } from './VCDisplayCard2-fc5c4225.js';
43
43
  export { V as VCThumbnail } from './VCThumbnail-835921dd.js';
44
44
  export { V as VCVerificationCheck, a as VCVerificationCheckWithSpinner, b as VCVerificationCheckWithText } from './VCVerificationCheck-8b8b7a76.js';
45
45
  export { V as ValidationStateIndicator } from './VCVerificationPill-83eb61f4.js';
@@ -130,6 +130,7 @@ import './skillgraph.svg';
130
130
  import '@learncard/init';
131
131
  import './ArrowArcRight.svg';
132
132
  import './icon.green.fat-arrow.png';
133
+ import './i18n-8454d6ea.js';
133
134
  import './id-sleeve.png';
134
135
  import './vc.check.svg';
135
136
  import './RedXCircle.svg';
@@ -1 +1 @@
1
- {"version":3,"file":"index14.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index14.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,8 +1,9 @@
1
1
  import 'react';
2
- export { M as MeritBadgeBackFace, a as MeritBadgeDisplayCard, b as MeritBadgeFrontFace } from './MeritBadgeDisplayCard-a7a504e0.js';
2
+ export { M as MeritBadgeBackFace, a as MeritBadgeDisplayCard, b as MeritBadgeFrontFace } from './MeritBadgeDisplayCard-2029a552.js';
3
3
  import './index-cb3a593b.js';
4
4
  import './types.esm-d6b48609.js';
5
5
  export { M as MeritBadgeSkillsCount } from './MeritBadgeSkillsCount-c5271d7f.js';
6
+ import './i18n-8454d6ea.js';
6
7
  import './VerifierStateBadgeAndText-60b98d25.js';
7
8
  import './athletics.png';
8
9
  import './business.png';
@@ -1 +1 @@
1
- {"version":3,"file":"index22.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index22.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- export { V as VCCard } from './VCCard-f017f1ee.js';
1
+ export { V as VCCard } from './VCCard-c0f6dff3.js';
2
2
  import 'react';
3
3
  import '@learncard/init';
4
4
  import './VCDisplayCard-9905d9d3.js';
@@ -21,7 +21,7 @@ import './RedXCircle.svg';
21
21
  import './GreenCheckCircle.svg';
22
22
  import './YellowWarningCircle.svg';
23
23
  import './ArrowArcRight.svg';
24
- import './VCDisplayCard2-72bed598.js';
24
+ import './VCDisplayCard2-fc5c4225.js';
25
25
  import './VerifierStateBadgeAndText-60b98d25.js';
26
26
  import './athletics.png';
27
27
  import './business.png';
@@ -34,9 +34,10 @@ import './stem.png';
34
34
  import './trade.png';
35
35
  import './Lightbox-f0338a0c.js';
36
36
  import 'react-dom';
37
+ import './i18n-8454d6ea.js';
37
38
  import './CertificateDisplayCard-4e9254e0.js';
38
39
  import './DotsThreeOutline.svg';
39
40
  import './QRCodeIcon-8eef4f7c.js';
40
41
  import './id-sleeve.png';
41
- import './MeritBadgeDisplayCard-a7a504e0.js';
42
+ import './MeritBadgeDisplayCard-2029a552.js';
42
43
  //# sourceMappingURL=index39.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index39.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index39.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -10,8 +10,9 @@ import './social.png';
10
10
  import './stem.png';
11
11
  import './trade.png';
12
12
  import './index-cb3a593b.js';
13
- export { V as VCDisplayCard2, a as VCDisplayCardSkillsCount, b as VCIDDisplayCard } from './VCDisplayCard2-72bed598.js';
13
+ export { V as VCDisplayCard2, a as VCDisplayCardSkillsCount, b as VCIDDisplayCard } from './VCDisplayCard2-fc5c4225.js';
14
14
  import './types.esm-d6b48609.js';
15
+ import './i18n-8454d6ea.js';
15
16
  import './id-sleeve.png';
16
17
  import './PuzzlePiece-a3d9cc62.js';
17
18
  import './VCVerificationCheck-8b8b7a76.js';
@@ -27,5 +28,5 @@ import 'react-dom';
27
28
  import './CertificateDisplayCard-4e9254e0.js';
28
29
  import './DotsThreeOutline.svg';
29
30
  import './QRCodeIcon-8eef4f7c.js';
30
- import './MeritBadgeDisplayCard-a7a504e0.js';
31
+ import './MeritBadgeDisplayCard-2029a552.js';
31
32
  //# sourceMappingURL=index42.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index42.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index42.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -1614,4 +1614,40 @@ declare const useParsedSdJwtVc: (learnCard: LearnCard | undefined, compact: stri
1614
1614
  declare const humanizeClaimLabel: (key: string) => string;
1615
1615
  declare const formatClaimValue: (value: unknown) => string;
1616
1616
 
1617
- export { AchievementCard, AwardDisplayIcon, AwardRibbon, BadgeDisplayIcon, BoostGenericCard, BoostSmallCard, Briefcase, Button, ButtonProps, CertDisplayCardSkillsCount, CertificateBackFace, CertificateDisplayCard, CertificateDisplayIcon, CertificateFrontFace, Checkmark, CheckmarkSvg, CircleCheckButton, CircleIcon, CircleIconProps, CircleLoadingState, CircleSpinnerProps, Coins, CountCircle, CountCircleProps, CourseCard, CourseDisplayIcon, CourseVerticalCard, CredentialFormat, CredentialIconType, FlippyCard, FlippyCardProps, GenericArrow, GenericCard, Graduation, IDDisplayIcon, IDIcon, IDSleeve, JobHistoryCard, JobListCard, JobListingBubble, LearnCardCreditCardBackFace, LearnCardCreditCardBackFaceProps, LearnCardCreditCardFrontFace, LearnCardCreditCardFrontFaceProps, LearnCardCreditCardProps, LearnCardCreditCardUserProps, LearnPill, Lightbox, LightboxImage, LightboxItem, LightboxItemType, LightboxProps, LightboxVideo, Lightbulb, MeritBadgeBackFace, MeritBadgeDisplayCard, MeritBadgeFrontFace, MeritBadgeSkillsCount, MiniVCThumbnail, MiniVCThumbnailProps, Notification, NotificationBoostCard, NotificationBoostCardProps, NotificationIssuerMeta, NotificationProps, NotificationTypeStyles, NotificationUserAcceptedBoostCard, NotificationUserAcceptedBoostCardProps, NotificationUserCard, NotificationUserCardProps, ParsedSdJwtVc, QRCodeCard, QRCodeCardProps, QRCodeIcon, RoundedPill, RoundedSquare, RoundedSquareProps, SchoolIDCard, SchoolIDCardProps, SelectedSkills, SkillTabCard, SkillVerticalCard, SkillsCard, SkillsMeterSegment, SkillsStatsCard, SmallAchievementCard, TYPE_TO_IMG_SRC, TYPE_TO_MINI_ICON, TYPE_TO_WALLET_COLOR, ThreeDotVertical, Trophy, User, UserNotificationTypeStyles, UserProfilePicture, VCCard, VCCardProps, VCDisplayBackFace, VCDisplayCard, VCDisplayCard2, VCDisplayCard2Props, VCDisplayCardPropsReal, VCDisplayCardSkillsCount, VCIDDisplayCard, VCIDDisplayCardProps, VCThumbnail, VCThumbnailProps, VCVerificationCheck, VCVerificationCheckProps, VCVerificationCheckWithSpinner, VCVerificationCheckWithText, VERIFIER_STATES, ValidationStateIndicator, VerifierState, VerifierStateBadgeAndTextProps, WALLET_SUBTYPES, formatClaimValue, formatDidDisplayName, getAvatarColorFromString, getAvatarLetterFromDid, humanizeClaimLabel, isDid, isLearnCardNetworkDid, resolveProfileDisplay, useCredentialFormat, useOnMomentumScrollEnd, useParsedSdJwtVc, useScrollBorders };
1617
+ /**
1618
+ * Lightweight i18n adapter for `@learncard/react`.
1619
+ *
1620
+ * This is a PUBLISHED SDK consumed by external third parties who have no
1621
+ * Paraglide, no app providers, and no catalog. So the rule is: render English
1622
+ * with zero configuration, and only *optionally* accept translations.
1623
+ *
1624
+ * Components call `useT()`. With no provider mounted, `useT()` returns the
1625
+ * co-located English default (zero-config English for every consumer). A
1626
+ * consumer that wants localization mounts `<I18nProvider resolve={fn} locale={l}>`
1627
+ * where `fn` maps a key to a translated string using whatever i18n they use
1628
+ * (Paraglide, i18next, a static map — the SDK doesn't care).
1629
+ *
1630
+ * Kept intentionally dependency-free and self-contained (a ~40-line copy also
1631
+ * lives in learn-card-base) so the SDK pulls in no i18n runtime.
1632
+ */
1633
+
1634
+ type I18nResolver = (key: string, params?: Record<string, unknown>) => string | undefined;
1635
+ /**
1636
+ * English defaults co-located with the SDK. One entry per extracted string.
1637
+ * Keys are unprefixed; a host app namespaces them (e.g. `sdk.`) in its catalog.
1638
+ */
1639
+ declare const EN_DEFAULTS: Record<string, string>;
1640
+ declare const I18nProvider: React$1.FC<{
1641
+ resolve: I18nResolver;
1642
+ locale: string;
1643
+ children: React$1.ReactNode;
1644
+ }>;
1645
+ /**
1646
+ * Returns a translate function. Resolution order:
1647
+ * 1. host resolver (consumer catalog) if a provider is mounted and has the key
1648
+ * 2. co-located English default (interpolated)
1649
+ * 3. the key itself (last-resort)
1650
+ */
1651
+ declare const useT: () => ((key: string, params?: Record<string, unknown>) => string);
1652
+
1653
+ export { AchievementCard, AwardDisplayIcon, AwardRibbon, BadgeDisplayIcon, BoostGenericCard, BoostSmallCard, Briefcase, Button, ButtonProps, CertDisplayCardSkillsCount, CertificateBackFace, CertificateDisplayCard, CertificateDisplayIcon, CertificateFrontFace, Checkmark, CheckmarkSvg, CircleCheckButton, CircleIcon, CircleIconProps, CircleLoadingState, CircleSpinnerProps, Coins, CountCircle, CountCircleProps, CourseCard, CourseDisplayIcon, CourseVerticalCard, CredentialFormat, CredentialIconType, EN_DEFAULTS, FlippyCard, FlippyCardProps, GenericArrow, GenericCard, Graduation, I18nProvider, I18nResolver, IDDisplayIcon, IDIcon, IDSleeve, JobHistoryCard, JobListCard, JobListingBubble, LearnCardCreditCardBackFace, LearnCardCreditCardBackFaceProps, LearnCardCreditCardFrontFace, LearnCardCreditCardFrontFaceProps, LearnCardCreditCardProps, LearnCardCreditCardUserProps, LearnPill, Lightbox, LightboxImage, LightboxItem, LightboxItemType, LightboxProps, LightboxVideo, Lightbulb, MeritBadgeBackFace, MeritBadgeDisplayCard, MeritBadgeFrontFace, MeritBadgeSkillsCount, MiniVCThumbnail, MiniVCThumbnailProps, Notification, NotificationBoostCard, NotificationBoostCardProps, NotificationIssuerMeta, NotificationProps, NotificationTypeStyles, NotificationUserAcceptedBoostCard, NotificationUserAcceptedBoostCardProps, NotificationUserCard, NotificationUserCardProps, ParsedSdJwtVc, QRCodeCard, QRCodeCardProps, QRCodeIcon, RoundedPill, RoundedSquare, RoundedSquareProps, SchoolIDCard, SchoolIDCardProps, SelectedSkills, SkillTabCard, SkillVerticalCard, SkillsCard, SkillsMeterSegment, SkillsStatsCard, SmallAchievementCard, TYPE_TO_IMG_SRC, TYPE_TO_MINI_ICON, TYPE_TO_WALLET_COLOR, ThreeDotVertical, Trophy, User, UserNotificationTypeStyles, UserProfilePicture, VCCard, VCCardProps, VCDisplayBackFace, VCDisplayCard, VCDisplayCard2, VCDisplayCard2Props, VCDisplayCardPropsReal, VCDisplayCardSkillsCount, VCIDDisplayCard, VCIDDisplayCardProps, VCThumbnail, VCThumbnailProps, VCVerificationCheck, VCVerificationCheckProps, VCVerificationCheckWithSpinner, VCVerificationCheckWithText, VERIFIER_STATES, ValidationStateIndicator, VerifierState, VerifierStateBadgeAndTextProps, WALLET_SUBTYPES, formatClaimValue, formatDidDisplayName, getAvatarColorFromString, getAvatarLetterFromDid, humanizeClaimLabel, isDid, isLearnCardNetworkDid, resolveProfileDisplay, useCredentialFormat, useOnMomentumScrollEnd, useParsedSdJwtVc, useScrollBorders, useT };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@learncard/react",
3
- "version": "2.10.7",
3
+ "version": "2.10.8",
4
4
  "description": "",
5
5
  "main": "dist/cjs",
6
6
  "module": "dist/esm",
@@ -66,7 +66,7 @@
66
66
  "vite": "^6.4.2"
67
67
  },
68
68
  "dependencies": {
69
- "@learncard/init": "2.4.7",
69
+ "@learncard/init": "2.4.8",
70
70
  "date-fns": "^2.28.0",
71
71
  "numeral": "^2.0.6",
72
72
  "pretty-bytes": "^6.0.0",
@@ -159,7 +159,7 @@ export const MeritBadgeFrontFace: React.FC<MeritBadgeFrontFaceProps> = ({
159
159
  >
160
160
  <div className="flex flex-col gap-[5px] w-full">
161
161
  <div className="flex flex-col items-center text-grayscale-900">
162
- {issueeName && (
162
+ {issueeName && !customBodyCardComponent && (
163
163
  <>
164
164
  <span className="flex flex-wrap items-baseline justify-center gap-1 text-[16px] leading-[150%] font-jacques max-w-full overflow-hidden text-ellipsis whitespace-nowrap">
165
165
  {!issueeDisplay.isMissing && issueeDisplay.isDidValue ? (
@@ -3,6 +3,7 @@ import UnknownVerifierBadge from '../svgs/UnknownVerifierBadge';
3
3
  import VerifiedBadge from '../svgs/VerifiedBadge';
4
4
  import PersonBadge from '../svgs/PersonBadge';
5
5
  import RedFlag from '../svgs/RedFlag';
6
+ import { useT } from '../../i18n';
6
7
 
7
8
  const VERIFIER_STATES = {
8
9
  selfVerified: 'Self Issued',
@@ -18,36 +19,37 @@ type VerifierStateBadgeAndTextProps = {
18
19
  };
19
20
 
20
21
  const VerifierStateBadgeAndText: React.FC<VerifierStateBadgeAndTextProps> = ({ verifierState }) => {
22
+ const t = useT();
21
23
  return (
22
24
  <div className="flex justify-center">
23
25
  {verifierState === VERIFIER_STATES.selfVerified && (
24
26
  <span className="uppercase font-poppins text-[12px] font-[500] text-green-dark flex gap-[3px] items-center">
25
27
  <PersonBadge />
26
- Self Issued
28
+ {t('verification.selfIssued')}
27
29
  </span>
28
30
  )}
29
31
  {verifierState === VERIFIER_STATES.trustedVerifier && (
30
32
  <span className="uppercase font-poppins text-[12px] font-[500] text-blue-light flex gap-[3px] items-center">
31
33
  <VerifiedBadge />
32
- Trusted Issuer
34
+ {t('verification.trustedIssuer')}
33
35
  </span>
34
36
  )}
35
37
  {verifierState === VERIFIER_STATES.unknownVerifier && (
36
38
  <span className="uppercase font-poppins text-[12px] font-[500] text-orange-500 flex gap-[3px] items-center">
37
39
  <UnknownVerifierBadge />
38
- Unknown Issuer
40
+ {t('verification.unknownIssuer')}
39
41
  </span>
40
42
  )}
41
43
  {verifierState === VERIFIER_STATES.appIssuer && (
42
44
  <span className="uppercase font-poppins text-[12px] font-[500] text-cyan-600 flex gap-[3px] items-center">
43
45
  <UnknownVerifierBadge />
44
- Trusted App
46
+ {t('verification.appIssuer')}
45
47
  </span>
46
48
  )}
47
49
  {verifierState === VERIFIER_STATES.untrustedVerifier && (
48
50
  <span className="uppercase font-poppins text-[12px] font-[500] text-red-mastercard flex gap-[3px] items-center">
49
51
  <RedFlag />
50
- Untrusted Issuer
52
+ {t('verification.untrustedIssuer')}
51
53
  </span>
52
54
  )}
53
55
  </div>
@@ -8,13 +8,28 @@ import AcuteCheckmark from '../svgs/AcuteCheckmark';
8
8
  import ExclamationPoint from '../svgs/ExclamationPoint';
9
9
  import X from '../svgs/X';
10
10
  import { capitalize } from '../../helpers/string.helpers';
11
+ import { useT } from '../../i18n';
11
12
 
12
13
  type VerificationRowProps = {
13
14
  verification: VerificationItem;
14
15
  };
15
16
 
17
+ /** Map the SDK's English verification messages to i18n keys; unknown messages pass through. */
18
+ const MESSAGE_KEYS: Record<string, string> = {
19
+ Valid: 'valid',
20
+ Invalid: 'invalid',
21
+ 'Not Revoked': 'notRevoked',
22
+ Revoked: 'revoked',
23
+ 'Does Not Expire': 'doesNotExpire',
24
+ Expired: 'expired',
25
+ Active: 'active',
26
+ 'Boost Credential could not be verified.': 'couldNotVerify',
27
+ 'Boost Credential could not be verified': 'couldNotVerify',
28
+ };
29
+
16
30
  const VerificationRow: React.FC<VerificationRowProps> = ({ verification }) => {
17
31
  const [showInfo, setShowInfo] = useState(false);
32
+ const t = useT();
18
33
  const statusColor = getColorForVerificationStatus(verification.status);
19
34
 
20
35
  const getIcon = () => {
@@ -28,11 +43,19 @@ const VerificationRow: React.FC<VerificationRowProps> = ({ verification }) => {
28
43
  }
29
44
  };
30
45
 
46
+ const statusText = t(`verification.status.${String(verification.status).toLowerCase()}`);
47
+ const translateMessage = (msg?: string): string => {
48
+ if (!msg) return '';
49
+ const key = MESSAGE_KEYS[msg];
50
+ return key ? t(`verification.message.${key}`) : msg;
51
+ };
52
+ const checkLabel = verification.check ? t(`verification.check.${verification.check}`) : '';
53
+
31
54
  let primaryText = verification.check
32
- ? `${verification.check}: ${verification.message}`
33
- : verification.message;
55
+ ? `${checkLabel}: ${translateMessage(verification.message)}`
56
+ : translateMessage(verification.message);
34
57
  if (verification.status === VerificationStatusEnum.Failed) {
35
- primaryText = verification.message ?? verification.details ?? '';
58
+ primaryText = translateMessage(verification.message ?? verification.details ?? '');
36
59
  }
37
60
  primaryText = capitalize(primaryText);
38
61
 
@@ -45,7 +68,7 @@ const VerificationRow: React.FC<VerificationRowProps> = ({ verification }) => {
45
68
  style={{ color: statusColor }}
46
69
  >
47
70
  {getIcon()}
48
- {verification.status}
71
+ {statusText}
49
72
  {infoText && (
50
73
  <button className="ml-auto" onClick={() => setShowInfo(!showInfo)}>
51
74
  <InfoIcon color={statusColor} />
@@ -5,6 +5,7 @@ import InfoIcon from '../svgs/InfoIcon';
5
5
  import InfoBox from './InfoBox';
6
6
 
7
7
  import { VerificationItem } from '@learncard/types';
8
+ import { useT } from '../../i18n';
8
9
 
9
10
  type VerificationsBoxProps = {
10
11
  verificationItems: VerificationItem[];
@@ -12,11 +13,12 @@ type VerificationsBoxProps = {
12
13
 
13
14
  const VerificationsBox: React.FC<VerificationsBoxProps> = ({ verificationItems }) => {
14
15
  const [showInfo, setShowInfo] = useState(false);
16
+ const t = useT();
15
17
 
16
18
  return (
17
19
  <div className="verifications-box bg-white flex flex-col items-start gap-[10px] rounded-[20px] shadow-bottom px-[15px] py-[20px] w-full relative">
18
20
  <h3 className="text-[20px] leading-[20px] text-grayscale-900">
19
- Credential Verifications
21
+ {t('verification.title')}
20
22
  </h3>
21
23
  <button
22
24
  className="absolute top-[17px] right-[17px]"
@@ -28,10 +30,7 @@ const VerificationsBox: React.FC<VerificationsBoxProps> = ({ verificationItems }
28
30
  <InfoIcon color={showInfo ? '#6366F1' : undefined} />
29
31
  </button>
30
32
  {showInfo && (
31
- <InfoBox
32
- text="Credential verifications check the cryptographic proof of digital credentials to ensure their authenticity and accuracy."
33
- handleClose={() => setShowInfo(false)}
34
- />
33
+ <InfoBox text={t('verification.infoText')} handleClose={() => setShowInfo(false)} />
35
34
  )}
36
35
 
37
36
  {verificationItems.map((verification, index) => (
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Lightweight i18n adapter for `@learncard/react`.
3
+ *
4
+ * This is a PUBLISHED SDK consumed by external third parties who have no
5
+ * Paraglide, no app providers, and no catalog. So the rule is: render English
6
+ * with zero configuration, and only *optionally* accept translations.
7
+ *
8
+ * Components call `useT()`. With no provider mounted, `useT()` returns the
9
+ * co-located English default (zero-config English for every consumer). A
10
+ * consumer that wants localization mounts `<I18nProvider resolve={fn} locale={l}>`
11
+ * where `fn` maps a key to a translated string using whatever i18n they use
12
+ * (Paraglide, i18next, a static map — the SDK doesn't care).
13
+ *
14
+ * Kept intentionally dependency-free and self-contained (a ~40-line copy also
15
+ * lives in learn-card-base) so the SDK pulls in no i18n runtime.
16
+ */
17
+ import React, { createContext, useCallback, useContext, useMemo } from 'react';
18
+
19
+ export type I18nResolver = (key: string, params?: Record<string, unknown>) => string | undefined;
20
+
21
+ type I18nContextValue = { resolve: I18nResolver; locale: string };
22
+
23
+ const I18nContext = createContext<I18nContextValue | null>(null);
24
+
25
+ /**
26
+ * English defaults co-located with the SDK. One entry per extracted string.
27
+ * Keys are unprefixed; a host app namespaces them (e.g. `sdk.`) in its catalog.
28
+ */
29
+ export const EN_DEFAULTS: Record<string, string> = {
30
+ 'verification.selfIssued': 'Self Issued',
31
+ 'verification.trustedIssuer': 'Trusted Issuer',
32
+ 'verification.unknownIssuer': 'Unknown Issuer',
33
+ 'verification.appIssuer': 'Trusted App',
34
+ 'verification.untrustedIssuer': 'Untrusted Issuer',
35
+ 'credential.by': 'By',
36
+ 'verification.title': 'Credential Verifications',
37
+ 'verification.infoText':
38
+ 'Credential verifications check the cryptographic proof of digital credentials to ensure their authenticity and accuracy.',
39
+ 'verification.status.success': 'Success',
40
+ 'verification.status.error': 'Error',
41
+ 'verification.status.failed': 'Failed',
42
+ 'verification.check.proof': 'Proof',
43
+ 'verification.check.status': 'Status',
44
+ 'verification.check.expiration': 'Expiration',
45
+ 'verification.message.valid': 'Valid',
46
+ 'verification.message.invalid': 'Invalid',
47
+ 'verification.message.notRevoked': 'Not Revoked',
48
+ 'verification.message.revoked': 'Revoked',
49
+ 'verification.message.doesNotExpire': 'Does Not Expire',
50
+ 'verification.message.expired': 'Expired',
51
+ 'verification.message.active': 'Active',
52
+ 'verification.message.couldNotVerify': 'Boost Credential could not be verified.',
53
+ };
54
+
55
+ /** Minimal `{var}` interpolation — no dependency. */
56
+ const interpolate = (str: string, params?: Record<string, unknown>): string =>
57
+ params
58
+ ? str.replace(/\{(\w+)\}/g, (_, k) => (params[k] != null ? String(params[k]) : `{${k}}`))
59
+ : str;
60
+
61
+ export const I18nProvider: React.FC<{
62
+ resolve: I18nResolver;
63
+ locale: string;
64
+ children: React.ReactNode;
65
+ }> = ({ resolve, locale, children }) => {
66
+ const value = useMemo<I18nContextValue>(() => ({ resolve, locale }), [resolve, locale]);
67
+ return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>;
68
+ };
69
+
70
+ /**
71
+ * Returns a translate function. Resolution order:
72
+ * 1. host resolver (consumer catalog) if a provider is mounted and has the key
73
+ * 2. co-located English default (interpolated)
74
+ * 3. the key itself (last-resort)
75
+ */
76
+ export const useT = (): ((key: string, params?: Record<string, unknown>) => string) => {
77
+ const ctx = useContext(I18nContext);
78
+ return useCallback(
79
+ (key: string, params?: Record<string, unknown>) => {
80
+ const fromHost = ctx?.resolve(key, params);
81
+ if (fromHost != null) return fromHost;
82
+ const def = EN_DEFAULTS[key];
83
+ return def != null ? interpolate(def, params) : key;
84
+ },
85
+ [ctx]
86
+ );
87
+ };
package/src/index.ts CHANGED
@@ -14,3 +14,6 @@ export * from './helpers/did-display.helpers';
14
14
  export * from './hooks/useCredentialFormat';
15
15
  export * from './hooks/useParsedSdJwtVc';
16
16
  export * from './helpers/credentialFormat.helpers';
17
+
18
+ // Optional i18n adapter (English by default; consumers may inject a resolver)
19
+ export * from './i18n';