diff --git a/.pnp.cjs b/.pnp.cjs index db37b28b..10c65c06 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -29,7 +29,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./",\ "packageDependencies": [\ ["@monaco-editor/react", "virtual:c76842a5689228a0ce1b65e064c1f5e0d5b61e442d08b6527a3b1f100ca1f2105e58f5f1435c5a59df3cce3338560737838d99dae36d25b47d20aa50c89d0539#npm:4.4.5"],\ - ["@transcend-io/airgap.js-types", "npm:10.0.0"],\ + ["@transcend-io/airgap.js-types", "npm:10.2.0"],\ ["@transcend-io/internationalization", "npm:1.5.1"],\ ["@transcend-io/logger", "npm:1.1.0"],\ ["@transcend-io/type-utils", "npm:1.0.7"],\ @@ -1728,10 +1728,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["@transcend-io/airgap.js-types", [\ - ["npm:10.0.0", {\ - "packageLocation": "./.yarn/cache/@transcend-io-airgap.js-types-npm-10.0.0-12b3cb654f-477c080bcc.zip/node_modules/@transcend-io/airgap.js-types/",\ + ["npm:10.2.0", {\ + "packageLocation": "./.yarn/cache/@transcend-io-airgap.js-types-npm-10.2.0-cffce5b53f-d50bde26f0.zip/node_modules/@transcend-io/airgap.js-types/",\ "packageDependencies": [\ - ["@transcend-io/airgap.js-types", "npm:10.0.0"],\ + ["@transcend-io/airgap.js-types", "npm:10.2.0"],\ ["@transcend-io/type-utils", "npm:1.0.5"],\ ["fp-ts", "npm:2.11.8"],\ ["io-ts", "virtual:53d562f9656f9223c4532e7e2b6feefabcf4bfa2c0659bc8d6557c1f9633b17688cca8b3d2effb8a926da81d6d2f2353092c812bd38f1a03f5ff9a9a3e1b3408#npm:2.2.16"]\ @@ -1756,7 +1756,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageDependencies": [\ ["@transcend-io/consent-manager-ui", "workspace:."],\ ["@monaco-editor/react", "virtual:c76842a5689228a0ce1b65e064c1f5e0d5b61e442d08b6527a3b1f100ca1f2105e58f5f1435c5a59df3cce3338560737838d99dae36d25b47d20aa50c89d0539#npm:4.4.5"],\ - ["@transcend-io/airgap.js-types", "npm:10.0.0"],\ + ["@transcend-io/airgap.js-types", "npm:10.2.0"],\ ["@transcend-io/internationalization", "npm:1.5.1"],\ ["@transcend-io/logger", "npm:1.1.0"],\ ["@transcend-io/type-utils", "npm:1.0.7"],\ diff --git a/.yarn/cache/@transcend-io-airgap.js-types-npm-10.0.0-12b3cb654f-477c080bcc.zip b/.yarn/cache/@transcend-io-airgap.js-types-npm-10.2.0-cffce5b53f-d50bde26f0.zip similarity index 81% rename from .yarn/cache/@transcend-io-airgap.js-types-npm-10.0.0-12b3cb654f-477c080bcc.zip rename to .yarn/cache/@transcend-io-airgap.js-types-npm-10.2.0-cffce5b53f-d50bde26f0.zip index 731236cb..3754b223 100644 Binary files a/.yarn/cache/@transcend-io-airgap.js-types-npm-10.0.0-12b3cb654f-477c080bcc.zip and b/.yarn/cache/@transcend-io-airgap.js-types-npm-10.2.0-cffce5b53f-d50bde26f0.zip differ diff --git a/package.json b/package.json index 2fe04a2c..40de2161 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "url": "https://github.com/transcend-io/consent-manager-ui.git" }, "homepage": "https://github.com/transcend-io/consent-manager-ui", - "version": "4.0.0", + "version": "4.1.0", "license": "MIT", "main": "build/ui", "files": [ @@ -44,7 +44,7 @@ }, "devDependencies": { "@monaco-editor/react": "^4.4.5", - "@transcend-io/airgap.js-types": "^10.0.0", + "@transcend-io/airgap.js-types": "^10.2.0", "@transcend-io/type-utils": "^1.0.7", "@types/node": "^17.0.21", "@typescript-eslint/eslint-plugin": "^5.12.1", diff --git a/src/api.ts b/src/api.ts index 98e6a0dc..2540ade3 100644 --- a/src/api.ts +++ b/src/api.ts @@ -7,7 +7,11 @@ import { isViewStateClosed } from './hooks'; import { logger } from './logger'; import { PRIVACY_SIGNAL_NAME } from './privacy-signals'; import { LOG_LEVELS } from './settings'; -import { HandleSetLanguage, HandleSetViewState } from './types'; +import { + HandleSetLanguage, + HandleChangePrivacyPolicy, + HandleSetViewState, +} from './types'; interface MakeConsentManagerAPIInput { /** The event target, where events as dispatched */ @@ -18,6 +22,10 @@ interface MakeConsentManagerAPIInput { handleChangeLanguage: HandleSetLanguage; /** Method to change view state */ handleSetViewState: HandleSetViewState; + /** Method to change the current privacy policy URL */ + handleChangePrivacyPolicy: HandleChangePrivacyPolicy; + /** Method to change the current secondary policy URL */ + handleChangeSecondaryPolicy: HandleChangePrivacyPolicy; /** Airgap.js */ airgap: AirgapAPI; } @@ -34,10 +42,16 @@ export function makeConsentManagerAPI({ eventTarget, viewState, handleChangeLanguage, + handleChangePrivacyPolicy, + handleChangeSecondaryPolicy, handleSetViewState, airgap, }: MakeConsentManagerAPIInput): ConsentManagerAPI { const consentManagerMethods: Omit = { + setPrivacyPolicy: (privacyPolicyLink) => + Promise.resolve(handleChangePrivacyPolicy(privacyPolicyLink)), + setSecondaryPolicy: (privacyPolicyLink) => + Promise.resolve(handleChangeSecondaryPolicy(privacyPolicyLink)), setActiveLocale: (locale) => Promise.resolve(handleChangeLanguage(locale)), getViewState: () => viewState, viewStates: new Set(Object.values(ViewState)), diff --git a/src/components/App.tsx b/src/components/App.tsx index a413c2ac..7017a265 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -5,12 +5,7 @@ import type { ConsentManagerAPI, } from '@transcend-io/airgap.js-types'; import { getMergedConfig } from '../config'; -import { - AirgapProvider, - ConfigProvider, - useLanguage, - useViewState, -} from '../hooks'; +import { AirgapProvider, useLanguage, useViewState } from '../hooks'; import { settings } from '../settings'; import { Main } from './Main'; import { getPrimaryRegime } from '../regimes'; @@ -20,13 +15,14 @@ import { ConsentManagerLanguageKey } from '@transcend-io/internationalization'; import { CONSENT_MANAGER_SUPPORTED_LANGUAGES } from '../i18n'; import { makeConsentManagerAPI } from '../api'; import { TranscendEventTarget } from '../event-target'; +import { useState } from 'preact/hooks'; // TODO: https://transcend.height.app/T-13483 // Fix IntlProvider JSX types // eslint-disable-next-line @typescript-eslint/no-explicit-any const IntlProvider = _IntlProvider as any; -// Create `transcend` eventTarget on the global scope so this isn't derefenced on the next render of App +// Create `transcend` eventTarget on the global scope so this isn't dereferenced on the next render of App const eventTarget = new TranscendEventTarget(); /** @@ -42,7 +38,8 @@ export function App({ callback: (finalizedConsentManagerAPI: ConsentManagerAPI) => void; }): JSX.Element { // Consent manager configuration - const config = getMergedConfig(); + const defaultConfig = getMergedConfig(); + const [config, setConfig] = useState(defaultConfig); // Get the active privacy regime const privacyRegime = getPrimaryRegime(airgap.getRegimes()); @@ -79,6 +76,16 @@ export function App({ viewState, handleChangeLanguage, handleSetViewState, + handleChangePrivacyPolicy: (privacyPolicyUrl) => + setConfig({ + ...config, + privacyPolicy: privacyPolicyUrl, + }), + handleChangeSecondaryPolicy: (privacyPolicyUrl) => + setConfig({ + ...config, + secondaryPolicy: privacyPolicyUrl, + }), airgap, }); @@ -92,22 +99,21 @@ export function App({ // messages.ts are translated in english defaultLocale={ConsentManagerLanguageKey.En} > - - - {/** Ensure messages are loaded before any UI is displayed */} - {messages ? ( -
- ) : null} - - + + {/** Ensure messages are loaded before any UI is displayed */} + {messages ? ( +
+ ) : null} + ); } diff --git a/src/components/BottomMenu.tsx b/src/components/BottomMenu.tsx index 58c4218f..c79e658c 100644 --- a/src/components/BottomMenu.tsx +++ b/src/components/BottomMenu.tsx @@ -1,7 +1,6 @@ import { h, JSX } from 'preact'; import { useIntl } from 'react-intl'; import type { ViewState } from '@transcend-io/airgap.js-types'; -import { useConfig } from '../hooks'; import { bottomMenuMessages, noticeAndDoNotSellMessages } from '../messages'; import type { HandleSetViewState } from '../types'; import { MenuItem } from './MenuItem'; @@ -13,6 +12,8 @@ export function BottomMenu({ viewState, handleSetViewState, firstSelectedViewState, + secondaryPolicy, + privacyPolicy, }: { /** The first view state when opening the modal */ firstSelectedViewState: ViewState | null; @@ -20,8 +21,11 @@ export function BottomMenu({ viewState: ViewState; /** Function to change viewState */ handleSetViewState: HandleSetViewState; + /** Privacy policy */ + privacyPolicy: string; + /** Secondary policy */ + secondaryPolicy: string; }): JSX.Element { - const { config } = useConfig(); const { formatMessage } = useIntl(); return ( @@ -77,14 +81,14 @@ export function BottomMenu({ )} - {config.secondaryPolicy && viewState === 'CompleteOptionsInverted' && ( + {secondaryPolicy && viewState === 'CompleteOptionsInverted' && (
@@ -97,7 +101,7 @@ export function BottomMenu({ diff --git a/src/components/DoNotSellExplainer.tsx b/src/components/DoNotSellExplainer.tsx index 37b94486..8120c7d0 100644 --- a/src/components/DoNotSellExplainer.tsx +++ b/src/components/DoNotSellExplainer.tsx @@ -2,7 +2,7 @@ import { h, JSX } from 'preact'; import { useState } from 'preact/hooks'; import { useIntl } from 'react-intl'; import { CONSENT_OPTIONS } from '../constants'; -import { useAirgap, useConfig } from '../hooks'; +import { useAirgap } from '../hooks'; import { messages } from '../messages'; import type { HandleSetViewState } from '../types'; import { GPCIndicator } from './GPCIndicator'; @@ -17,13 +17,15 @@ let savingTimeout: ReturnType; */ export function DoNotSellExplainer({ handleSetViewState, + fontColor, }: { /** Function to change viewState */ handleSetViewState: HandleSetViewState; + /** Font color */ + fontColor: string; }): JSX.Element { const { airgap } = useAirgap(); const { formatMessage } = useIntl(); - const { config } = useConfig(); const [saving, setSaving] = useState(null); const [consentLocal, setConsentLocal] = useState( !!airgap.getConsent().purposes.SaleOfInfo, @@ -59,7 +61,7 @@ export function DoNotSellExplainer({ >
- +
diff --git a/src/components/TranscendLogo.tsx b/src/components/TranscendLogo.tsx index 89e03d83..01a15a21 100644 --- a/src/components/TranscendLogo.tsx +++ b/src/components/TranscendLogo.tsx @@ -1,6 +1,5 @@ /* eslint max-len: 0 */ import { h, JSX } from 'preact'; -import { useConfig } from '../hooks'; /** * The Transcend square logo @@ -37,8 +36,12 @@ export function TranscendLogoLogomark(): JSX.Element { * The Transcend logo rendered as SVG. * On Desktop, hovering shows wordmark. On Mobile, only square logo is visible */ -export function TranscendLogo(): JSX.Element { - const { config } = useConfig(); +export function TranscendLogo({ + fontColor, +}: { + /** Font color */ + fontColor: string; +}): JSX.Element { return ( - + diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 287fdfd5..d32a18f0 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -1,5 +1,4 @@ export * from './useLanguage'; export * from './useStickyState'; export * from './useViewState'; -export * from './useConfig'; export * from './useAirgap'; diff --git a/src/hooks/useConfig.tsx b/src/hooks/useConfig.tsx deleted file mode 100644 index d8a149c6..00000000 --- a/src/hooks/useConfig.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { ComponentChildren, createContext, h, JSX } from 'preact'; -import { StateUpdater, useContext, useState } from 'preact/hooks'; -import type { ConsentManagerConfig } from '@transcend-io/airgap.js-types'; - -/** - * Config context - */ -interface TConfigContext { - /** The config */ - config: Required; - /** Set new config */ - setConfig: StateUpdater>; -} - -/** - * Context to pass Emotion through the app - */ -export const ConfigContext = createContext( - {} as TConfigContext, -); - -export const ConfigProvider = ({ - newConfig, - children, -}: { - /** The new configuration */ - newConfig: Required; - /** The children of this provider */ - children: ComponentChildren; -}): JSX.Element => { - const [config, setConfig] = - useState>(newConfig); - - return ( - - {children} - - ); -}; - -export const useConfig = (): TConfigContext => useContext(ConfigContext); diff --git a/src/types.ts b/src/types.ts index 79bbcd07..d6ced860 100644 --- a/src/types.ts +++ b/src/types.ts @@ -58,3 +58,13 @@ export type HandleSetViewState = ( * Handler for setting user language */ export type HandleSetLanguage = (language: ConsentManagerLanguageKey) => void; + +/** + * Handler for changing the privacy policy link + */ +export type HandleChangePrivacyPolicy = (privacyPolicyLink: string) => void; + +/** + * Handler for changing the font color used in the consent manager UI + */ +export type HandleChangeFontColor = (fontColor: string) => void; diff --git a/yarn.lock b/yarn.lock index 26fac348..e1ee9170 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1155,14 +1155,14 @@ __metadata: languageName: node linkType: hard -"@transcend-io/airgap.js-types@npm:^10.0.0": - version: 10.0.0 - resolution: "@transcend-io/airgap.js-types@npm:10.0.0" +"@transcend-io/airgap.js-types@npm:^10.2.0": + version: 10.2.0 + resolution: "@transcend-io/airgap.js-types@npm:10.2.0" dependencies: "@transcend-io/type-utils": ^1.0.5 fp-ts: ^2.11.8 io-ts: ^2.2.16 - checksum: 477c080bcce57d6db6dc3ba38adb03f60ab30bd44d62c0114f2cb8b5fcd677c63f260fdcc5117b27ceff1f226462fbd95e74d2e3a910f041d088bd7523590a66 + checksum: d50bde26f0c24f3a8815fee6b2940a3986011f5a82a323f9f48c12fec8a545b91bee19e9583b8c61886478b5071e5702a55d523fd538161612e9a1ba9de41ff9 languageName: node linkType: hard @@ -1183,7 +1183,7 @@ __metadata: resolution: "@transcend-io/consent-manager-ui@workspace:." dependencies: "@monaco-editor/react": ^4.4.5 - "@transcend-io/airgap.js-types": ^10.0.0 + "@transcend-io/airgap.js-types": ^10.2.0 "@transcend-io/internationalization": ^1.5.1 "@transcend-io/logger": ^1.0.14 "@transcend-io/type-utils": ^1.0.7