Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New view state for CompleteOptionsToggles #149

Merged
merged 3 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,20 @@ This option is similar to `CompleteOptions` but the checkboxes are inverted -- c
| See our Privacy Policy | Redirects to the privacy policy link specified in [Consent Display Settings](https://app.transcend.io/consent-manager/display-settings) or the [`data-privacy-policy`](https://docs.transcend.io/docs/consent/faq#how-can-i-customize-the-privacy-policy-link-when-hosting-on-multiple-domains?) data attribute. |
| Read more | Redirects to the secondary policy specified using the `data-secondary-policy` data attribute. |

### `CompleteOptionsToggles`

This is a good banner style when you are using Transcend for [Preference Management](https://docs.transcend.io/docs/consent/reference/managed-preferences).

![ViewState = CompleteOptionsToggles](https://github.com/transcend-io/consent-manager-ui/assets/10264973/94f85234-aad7-4596-969e-fd91af42f4ab)

#### Button Mapping

| Button Title | Callback Description |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Toggle Switch | Switching one of the toggles opts the user in or out of a purpose. Changes are applied immediately as the toggle is switched |
| X - Icon | Closes the modal with no changes to purposes and no changes to consent confirmation. |
| See our Privacy Policy | Redirects to the privacy policy link specified in [Consent Display Settings](https://app.transcend.io/consent-manager/display-settings) or the [`data-privacy-policy`](https://docs.transcend.io/docs/consent/faq#how-can-i-customize-the-privacy-policy-link-when-hosting-on-multiple-domains?) data attribute. |

### `DoNotSellDisclosure`

Unlike the other view states, this view state should be opened using `onClick={(event) => transcend.doNotSell(event)}`. Note: for React development, please use: `onClick={(event) => transcend.doNotSell(event.nativeEvent)}`. This view state will opt the user out upon opening of the modal, while the other view states require an additional button to be clicked to ensure compliance.
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.8.4",
"version": "4.9.0",
"license": "MIT",
"main": "build/ui",
"files": [
Expand Down Expand Up @@ -44,7 +44,7 @@
},
"devDependencies": {
"@monaco-editor/react": "^4.4.5",
"@transcend-io/airgap.js-types": "^10.6.2",
"@transcend-io/airgap.js-types": "^10.7.0",
"@transcend-io/type-utils": "^1.0.7",
"@types/node": "^17.0.21",
"@typescript-eslint/eslint-plugin": "^5.12.1",
Expand Down
38 changes: 38 additions & 0 deletions src/cm.css
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,44 @@ a:focus {
margin-top: 2em;
}

/***********************
* CompleteOptionsToggle
***********************/

/** Styles for button of X marker in top right corner */
.complete-options-toggle-close {
--squareDimension: 25px;
padding: 4px;
position: absolute;
top: 21px;
right: 21px;
border: none;
cursor: pointer;
background-color: #f2f2f2;
border-radius: 5px;
height: var(--squareDimension);
width: var(--squareDimension);
display: flex;
align-items: center;
justify-content: center;
transition: background-color 150ms;
}

/** Styles for button of X marker in top right corner on hover */
.complete-options-toggle-close:hover, .complete-options-toggle-close:focus {
background-color: #e2e2e2;
}

/** Outline for do not sell explainer */
.complete-options-toggle-interface {
margin-top: 2em;
}

/** Styles for complete options toggle description */
.complete-options-toggle-description {
padding-bottom: 2em;
}

/*******************
* GPC Indicator
*******************/
Expand Down
63 changes: 34 additions & 29 deletions src/components/BottomMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,39 @@ import { bottomMenuMessages, noticeAndDoNotSellMessages } from '../messages';
import type { HandleSetViewState } from '../types';
import { MenuItem } from './MenuItem';

const VIEW_STATE_TO_MESSAGE: { [k in ViewState]?: DefinedMessage } = {
LanguageOptions: bottomMenuMessages.showPolicyButtonLanguageOptions,
DoNotSellDisclosure: bottomMenuMessages.showPolicyButtonDoNotSellDisclosure,
OptOutDisclosure: bottomMenuMessages.showPolicyButtonOptOutDisclosure,
QuickOptions: bottomMenuMessages.showPolicyButtonQuickOptions,
QuickOptions3: bottomMenuMessages.showPolicyButtonQuickOptions3,
AcceptAll: bottomMenuMessages.showPolicyButtonAcceptAll,
AcceptAllOrMoreChoices:
bottomMenuMessages.showPolicyButtonAcceptAllOrMoreChoices,
AcceptOrRejectAll: bottomMenuMessages.showPolicyButtonAcceptOrRejectAll,
AcceptOrRejectAllOrMoreChoices:
bottomMenuMessages.showPolicyButtonAcceptOrRejectAllOrMoreChoices,
AcceptOrRejectAnalytics:
bottomMenuMessages.showPolicyButtonAcceptOrRejectAnalytics,
AcceptOrRejectAdvertising:
bottomMenuMessages.showPolicyButtonAcceptOrRejectAdvertising,
AcceptAllRejectAllToggle:
bottomMenuMessages.showPolicyButtonAcceptAllRejectAllToggle,
NoticeAndDoNotSell: bottomMenuMessages.showPolicyButtonNoticeAndDoNotSell,
DoNotSellExplainer: bottomMenuMessages.showPolicyButtonDoNotSellExplainer,
PrivacyPolicyNotice: bottomMenuMessages.showPolicyButtonPrivacyPolicyNotice,
CompleteOptions: bottomMenuMessages.showPolicyButtonCompleteOptions,
CompleteOptionsInverted:
bottomMenuMessages.showPolicyButtonCompleteOptionsInverted,
// These shouldn't require text for a policy link
Collapsed: bottomMenuMessages.showPolicyButtonCompleteOptionsInverted,
Closed: bottomMenuMessages.showPolicyButtonCompleteOptionsInverted,
Hidden: bottomMenuMessages.showPolicyButtonCompleteOptionsInverted,
};
const VIEW_STATE_TO_MESSAGE: { [k in ViewState]: DefinedMessage | undefined } =
{
LanguageOptions: bottomMenuMessages.showPolicyButtonLanguageOptions,
DoNotSellDisclosure: bottomMenuMessages.showPolicyButtonDoNotSellDisclosure,
OptOutDisclosure: bottomMenuMessages.showPolicyButtonOptOutDisclosure,
QuickOptions: bottomMenuMessages.showPolicyButtonQuickOptions,
QuickOptions3: bottomMenuMessages.showPolicyButtonQuickOptions3,
AcceptAll: bottomMenuMessages.showPolicyButtonAcceptAll,
AcceptAllOrMoreChoices:
bottomMenuMessages.showPolicyButtonAcceptAllOrMoreChoices,
AcceptOrRejectAll: bottomMenuMessages.showPolicyButtonAcceptOrRejectAll,
AcceptOrRejectAllOrMoreChoices:
bottomMenuMessages.showPolicyButtonAcceptOrRejectAllOrMoreChoices,
AcceptOrRejectAnalytics:
bottomMenuMessages.showPolicyButtonAcceptOrRejectAnalytics,
AcceptOrRejectAdvertising:
bottomMenuMessages.showPolicyButtonAcceptOrRejectAdvertising,
AcceptAllRejectAllToggle:
bottomMenuMessages.showPolicyButtonAcceptAllRejectAllToggle,
NoticeAndDoNotSell: bottomMenuMessages.showPolicyButtonNoticeAndDoNotSell,
DoNotSellExplainer: bottomMenuMessages.showPolicyButtonDoNotSellExplainer,
PrivacyPolicyNotice: bottomMenuMessages.showPolicyButtonPrivacyPolicyNotice,
CompleteOptions: bottomMenuMessages.showPolicyButtonCompleteOptions,
CompleteOptionsInverted:
bottomMenuMessages.showPolicyButtonCompleteOptionsInverted,
// These shouldn't require text for a policy link
Collapsed: bottomMenuMessages.showPolicyButtonCompleteOptionsInverted,
Closed: bottomMenuMessages.showPolicyButtonCompleteOptionsInverted,
Hidden: bottomMenuMessages.showPolicyButtonCompleteOptionsInverted,
TCF_EU: undefined,
CompleteOptionsToggles:
bottomMenuMessages.showPolicyButtonCompleteOptionsToggles,
};

/**
* Renders the menu for the bottom of the banner
Expand Down Expand Up @@ -83,6 +87,7 @@ export function BottomMenu({
'AcceptOrRejectAllOrMoreChoices',
'CompleteOptionsInverted',
'DoNotSellExplainer',
'CompleteOptionsToggles',
'LanguageOptions',
'AcceptAllRejectAllToggle',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
16 changes: 2 additions & 14 deletions src/components/CompleteOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,11 @@ import { useAirgap, useGetPurposeMessageKeys } from '../hooks';
import { messages, completeOptionsMessages } from '../messages';
import type { ConsentSelection, HandleSetViewState } from '../types';
import { getConsentSelections } from '../consent-selections';
import { DefinedMessage } from '@transcend-io/internationalization';
import { Button } from './Button';
import { GPCIndicator } from './GPCIndicator';
import { Toggle } from './Toggle';
import { CONSENT_OPTIONS } from '../constants';

// Mapping of purposes to the message translation key
const defaultPurposeToMessageKey: Record<string, DefinedMessage> = {
Essential: completeOptionsMessages.essentialLabel,
Functional: completeOptionsMessages.functionalLabel,
Analytics: completeOptionsMessages.analyticsLabel,
Advertising: completeOptionsMessages.advertisingLabel,
SaleOfInfo: completeOptionsMessages.saleOfInfoLabel,
};

// Encode the default purpose ordering
const ORDER_OF_PURPOSES = Object.keys(defaultPurposeToMessageKey);
import { DEFAULT_PURPOSE_TO_MESSAGE_KEY, ORDER_OF_PURPOSES } from './constants';

/**
* The model view for "More Choices" showing granular checkboxes and more info
Expand All @@ -39,7 +27,7 @@ export function CompleteOptions({
const initialConsentSelections = getConsentSelections(airgap);
const purposeToMessageKey = useGetPurposeMessageKeys({
consentSelection: initialConsentSelections,
defaultPurposeToMessageKey,
defaultPurposeToMessageKey: DEFAULT_PURPOSE_TO_MESSAGE_KEY,
});

// Set state on the currently selected toggles
Expand Down
21 changes: 3 additions & 18 deletions src/components/CompleteOptionsInverted.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,14 @@ import { h, JSX } from 'preact';
import { useState } from 'preact/hooks';
import { useIntl } from 'react-intl';
import { useAirgap, useGetPurposeMessageKeys } from '../hooks';
import {
messages,
completeOptionsInvertedMessages,
completeOptionsMessages,
} from '../messages';
import { messages, completeOptionsMessages } from '../messages';
import type { ConsentSelection, HandleSetViewState } from '../types';
import { getConsentSelections } from '../consent-selections';
import { DefinedMessage } from '@transcend-io/internationalization';
import { Button } from './Button';
import { GPCIndicator } from './GPCIndicator';
import { Toggle } from './Toggle';
import { CONSENT_OPTIONS } from '../constants';

// Mapping of purposes to the message translation key
const defaultPurposeToMessageKey: Record<string, DefinedMessage> = {
Functional: completeOptionsInvertedMessages.functionalLabel,
Analytics: completeOptionsInvertedMessages.analyticsLabel,
Advertising: completeOptionsInvertedMessages.advertisingLabel,
SaleOfInfo: completeOptionsInvertedMessages.saleOfInfoLabel,
};

// Encode the default purpose ordering
const ORDER_OF_PURPOSES = Object.keys(defaultPurposeToMessageKey);
import { DEFAULT_PURPOSE_TO_MESSAGE_KEY, ORDER_OF_PURPOSES } from './constants';

/**
* The model view where checking each checkbox represents an opt otu
Expand All @@ -42,7 +27,7 @@ export function CompleteOptionsInverted({
const initialConsentSelections = getConsentSelections(airgap);
const purposeToMessageKey = useGetPurposeMessageKeys({
consentSelection: initialConsentSelections,
defaultPurposeToMessageKey,
defaultPurposeToMessageKey: DEFAULT_PURPOSE_TO_MESSAGE_KEY,
});

// Set state on the currently selected toggles
Expand Down
Loading
Loading