diff --git a/.pnp.cjs b/.pnp.cjs index f6401dd..2b69e57 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -32,7 +32,7 @@ const RAW_RUNTIME_STATE = ["@prettier/sync", "virtual:c76842a5689228a0ce1b65e064c1f5e0d5b61e442d08b6527a3b1f100ca1f2105e58f5f1435c5a59df3cce3338560737838d99dae36d25b47d20aa50c89d0539#npm:0.5.2"],\ ["@testing-library/jest-dom", "npm:6.4.8"],\ ["@testing-library/preact", "virtual:c76842a5689228a0ce1b65e064c1f5e0d5b61e442d08b6527a3b1f100ca1f2105e58f5f1435c5a59df3cce3338560737838d99dae36d25b47d20aa50c89d0539#npm:3.2.4"],\ - ["@transcend-io/airgap.js-types", "npm:12.3.0"],\ + ["@transcend-io/airgap.js-types", "npm:12.6.0"],\ ["@transcend-io/internationalization", "npm:1.6.0"],\ ["@transcend-io/logger", "npm:1.1.0"],\ ["@transcend-io/type-utils", "npm:1.5.0"],\ @@ -1756,10 +1756,10 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@transcend-io/airgap.js-types", [\ - ["npm:12.3.0", {\ - "packageLocation": "./.yarn/cache/@transcend-io-airgap.js-types-npm-12.3.0-9a211835fa-f7a834296e.zip/node_modules/@transcend-io/airgap.js-types/",\ + ["npm:12.6.0", {\ + "packageLocation": "./.yarn/cache/@transcend-io-airgap.js-types-npm-12.6.0-6d4470c14e-4d22a5b1b7.zip/node_modules/@transcend-io/airgap.js-types/",\ "packageDependencies": [\ - ["@transcend-io/airgap.js-types", "npm:12.3.0"],\ + ["@transcend-io/airgap.js-types", "npm:12.6.0"],\ ["@transcend-io/type-utils", "npm:1.4.2"],\ ["fp-ts", "npm:2.16.9"],\ ["io-ts", "virtual:647270e91e7a3b3be8360975cf4b261fc37aa1becc6251358c91b0bf0733ffddc3f7d7b9c35550155c202696cf87b8999803730126a6d8c46e4270742d944b5d#npm:2.2.21"]\ @@ -1788,7 +1788,7 @@ const RAW_RUNTIME_STATE = ["@prettier/sync", "virtual:c76842a5689228a0ce1b65e064c1f5e0d5b61e442d08b6527a3b1f100ca1f2105e58f5f1435c5a59df3cce3338560737838d99dae36d25b47d20aa50c89d0539#npm:0.5.2"],\ ["@testing-library/jest-dom", "npm:6.4.8"],\ ["@testing-library/preact", "virtual:c76842a5689228a0ce1b65e064c1f5e0d5b61e442d08b6527a3b1f100ca1f2105e58f5f1435c5a59df3cce3338560737838d99dae36d25b47d20aa50c89d0539#npm:3.2.4"],\ - ["@transcend-io/airgap.js-types", "npm:12.3.0"],\ + ["@transcend-io/airgap.js-types", "npm:12.6.0"],\ ["@transcend-io/internationalization", "npm:1.6.0"],\ ["@transcend-io/logger", "npm:1.1.0"],\ ["@transcend-io/type-utils", "npm:1.5.0"],\ diff --git a/.yarn/cache/@transcend-io-airgap.js-types-npm-12.3.0-9a211835fa-f7a834296e.zip b/.yarn/cache/@transcend-io-airgap.js-types-npm-12.6.0-6d4470c14e-4d22a5b1b7.zip similarity index 61% rename from .yarn/cache/@transcend-io-airgap.js-types-npm-12.3.0-9a211835fa-f7a834296e.zip rename to .yarn/cache/@transcend-io-airgap.js-types-npm-12.6.0-6d4470c14e-4d22a5b1b7.zip index 7460e13..f1bc0d8 100644 Binary files a/.yarn/cache/@transcend-io-airgap.js-types-npm-12.3.0-9a211835fa-f7a834296e.zip and b/.yarn/cache/@transcend-io-airgap.js-types-npm-12.6.0-6d4470c14e-4d22a5b1b7.zip differ diff --git a/package.json b/package.json index 827c50d..f680502 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.22.4", + "version": "4.23.0", "license": "MIT", "main": "build/ui", "files": [ @@ -51,7 +51,7 @@ "@prettier/sync": "^0.5.2", "@testing-library/jest-dom": "^6.4.6", "@testing-library/preact": "^3.2.4", - "@transcend-io/airgap.js-types": "^12.3.0", + "@transcend-io/airgap.js-types": "^12.6.0", "@transcend-io/type-utils": "^1.5.0", "@types/jest": "^29.5.12", "@types/node": "^17.0.45", diff --git a/src/components/App.tsx b/src/components/App.tsx index 4dc0bcb..b3cae1b 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -49,7 +49,8 @@ export function App({ const [currentVariables, handleChangeUiVariables] = useState({}); // Get default view states - const { initialViewStateByPrivacyRegime, dismissedViewState } = config; + const { initialViewStateByPrivacyRegime, dismissedViewState, autofocus } = + config; const initialViewState = initialViewStateByPrivacyRegime[ privacyRegime as keyof typeof initialViewStateByPrivacyRegime @@ -66,6 +67,7 @@ export function App({ document.activeElement !== document.body ? document.activeElement : null, + autofocus, }); // Language setup diff --git a/src/components/CompleteOptionsToggles.tsx b/src/components/CompleteOptionsToggles.tsx index a939bdf..d999a0c 100644 --- a/src/components/CompleteOptionsToggles.tsx +++ b/src/components/CompleteOptionsToggles.tsx @@ -44,6 +44,7 @@ export function CompleteOptionsToggles({ consentSelection: initialConsentSelections, defaultPurposeToMessageKey: DEFAULT_PURPOSE_TO_MESSAGE_KEY, }); + // eslint-disable-next-line react-hooks/exhaustive-deps const purposeToDescription = useMemo(() => airgap.getPurposeTypes(), []); const purposeToDescriptionKey = useGetPurposeDescriptionKeys({ consentSelection: initialConsentSelections, diff --git a/src/components/DoNotSellDisclosure.tsx b/src/components/DoNotSellDisclosure.tsx index 5de6bff..579dad7 100644 --- a/src/components/DoNotSellDisclosure.tsx +++ b/src/components/DoNotSellDisclosure.tsx @@ -47,6 +47,7 @@ export function DoNotSellDisclosure({ useEffect(() => { handleOptOut(modalOpenAuth); setIsOptedOut(true); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // delay UI until opt out happens diff --git a/src/components/Main.tsx b/src/components/Main.tsx index 662869b..7c838e6 100644 --- a/src/components/Main.tsx +++ b/src/components/Main.tsx @@ -77,12 +77,15 @@ export function Main({ const dialogRef = useRef(null); useEffect(() => { if (!isViewStateClosed(viewState) && dialogRef.current) { + const shouldAutofocus = config.autofocus ?? true; // This setTimeout was necessary for the api triggered states, (DoNotSell|OptOut)Disclosure setTimeout(() => { - if (dialogRef.current) initialFocusElement(dialogRef.current); + if (dialogRef.current && shouldAutofocus) { + initialFocusElement(dialogRef.current); + } }, 0); } - }, [viewState, dialogRef]); + }, [viewState, dialogRef, config.autofocus]); // Modal open views if (!isViewStateClosed(viewState)) { diff --git a/src/components/OptOutDisclosure.tsx b/src/components/OptOutDisclosure.tsx index 44ec65c..80b7b29 100644 --- a/src/components/OptOutDisclosure.tsx +++ b/src/components/OptOutDisclosure.tsx @@ -48,6 +48,7 @@ export function OptOutDisclosure({ useEffect(() => { handleOptOut(modalOpenAuth); setIsOptedOut(true); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // delay UI until opt out happens diff --git a/src/hooks/useGetPurposeDescriptionKeys.ts b/src/hooks/useGetPurposeDescriptionKeys.ts index fd001a3..d9b2fbc 100644 --- a/src/hooks/useGetPurposeDescriptionKeys.ts +++ b/src/hooks/useGetPurposeDescriptionKeys.ts @@ -42,6 +42,7 @@ export const useGetPurposeDescriptionKeys = ({ }, defaultPurposeToDescriptionKey as Record, ), + // eslint-disable-next-line react-hooks/exhaustive-deps [consentSelection, defaultPurposeToDescriptionKey], ); diff --git a/src/hooks/useViewState.ts b/src/hooks/useViewState.ts index 5b5eb2b..2605099 100644 --- a/src/hooks/useViewState.ts +++ b/src/hooks/useViewState.ts @@ -53,6 +53,7 @@ export function useViewState({ dismissedViewState, eventTarget, savedActiveElement, + autofocus, }: { /** Which state this consent manager should go to when opened */ initialViewState: InitialViewState; @@ -62,6 +63,8 @@ export function useViewState({ eventTarget: EventTarget; /** Element previously focused before our ui modal was opened */ savedActiveElement: HTMLElement | null; + /** Whether to on last focused element on reopen */ + autofocus?: boolean; }): { /** The current view state */ viewState: ViewState; @@ -134,7 +137,8 @@ export function useViewState({ * very difficult to interact with. We create an element with maximum focus priority and * focus it so that when we delete it the user will be at the start of the focus order * just like if they had freshly loaded the page. */ - if (savedActiveElement !== null) { + const shouldFocus = autofocus ?? true; + if (savedActiveElement !== null && shouldFocus) { savedActiveElement.focus(); } else { const tempInteractiveEl = document.createElement('span'); @@ -159,7 +163,8 @@ export function useViewState({ break; } }, - [state, setState, initialViewState, dismissedViewState], + // eslint-disable-next-line react-hooks/exhaustive-deps + [state, setState, initialViewState, dismissedViewState, autofocus], ); // Now that the viewState has updated, dispatch an event on the `transcend` API / event target diff --git a/yarn.lock b/yarn.lock index 1df5bfb..ed6a693 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1123,14 +1123,14 @@ __metadata: languageName: node linkType: hard -"@transcend-io/airgap.js-types@npm:^12.3.0": - version: 12.3.0 - resolution: "@transcend-io/airgap.js-types@npm:12.3.0" +"@transcend-io/airgap.js-types@npm:^12.6.0": + version: 12.6.0 + resolution: "@transcend-io/airgap.js-types@npm:12.6.0" dependencies: "@transcend-io/type-utils": "npm:^1.2.0" fp-ts: "npm:^2.16.1" io-ts: "npm:^2.2.21" - checksum: 10/f7a834296ef20c7415adff5167f0a8c3a629b4fd9fe5cc66988f88641fc2d300f11eedfdac4e55e71a59aa996439a9f93426041977455cde839dbe8445483951 + checksum: 10/4d22a5b1b77c3b2d03995f142171d69664df31d6212bd2776762a5aa90cb6f2b0bfe44b8d00f3647be1558dab8080348d7cd6800aeee2d510de6b7aa2699a88a languageName: node linkType: hard @@ -1155,7 +1155,7 @@ __metadata: "@prettier/sync": "npm:^0.5.2" "@testing-library/jest-dom": "npm:^6.4.6" "@testing-library/preact": "npm:^3.2.4" - "@transcend-io/airgap.js-types": "npm:^12.3.0" + "@transcend-io/airgap.js-types": "npm:^12.6.0" "@transcend-io/internationalization": "npm:^1.6.0" "@transcend-io/logger": "npm:^1.1.0" "@transcend-io/type-utils": "npm:^1.5.0"