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

TCF experience design improvements #4222

Merged
merged 18 commits into from
Oct 10, 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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ The types of changes are:
- Update frontend to use new legal basis dimension on vendors [#4216](https://github.com/ethyca/fides/pull/4216)
- Updated privacy center patch preferences call to handle updated API response [#4235](https://github.com/ethyca/fides/pull/4235)
- Added our CMP ID [#4233](https://github.com/ethyca/fides/pull/4233)
- Allow admin-ui users to turn on Configure Consent flag [#4246](https://github.com/ethyca/fides/pull/4246)
- Allow Admin UI users to turn on Configure Consent flag [#4246](https://github.com/ethyca/fides/pull/4246)
- Styling improvements for the fides.js consent banners and modals [#4222](https://github.com/ethyca/fides/pull/4222)

### Fixed
- TCF overlay can initialize its consent preferences from a cookie [#4124](https://github.com/ethyca/fides/pull/4124)
Expand Down
2 changes: 1 addition & 1 deletion clients/fides-js/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import postcss from "rollup-plugin-postcss";

const NAME = "fides";
const IS_DEV = process.env.NODE_ENV === "development";
const GZIP_SIZE_ERROR_KB = 20; // fail build if bundle size exceeds this
const GZIP_SIZE_ERROR_KB = 22; // fail build if bundle size exceeds this
galvana marked this conversation as resolved.
Show resolved Hide resolved
const GZIP_SIZE_WARN_KB = 15; // log a warning if bundle size exceeds this

// TCF
Expand Down
56 changes: 36 additions & 20 deletions clients/fides-js/src/components/ConsentBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { h, FunctionComponent, ComponentChildren } from "preact";
import { h, FunctionComponent, ComponentChildren, VNode } from "preact";
import { getConsentContext } from "../lib/consent-context";
import { ExperienceConfig } from "../lib/consent-types";
import CloseButton from "./CloseButton";
Expand All @@ -9,8 +9,13 @@ interface BannerProps {
experience: ExperienceConfig;
onClose: () => void;
bannerIsOpen: boolean;
children: ComponentChildren;
/**
* Passing in children components will automatically set the container to be a 2x2 grid,
* it is up to the child components to specify how they'll be placed within the grid
* */
children?: ComponentChildren;
allisonking marked this conversation as resolved.
Show resolved Hide resolved
onVendorPageClick?: () => void;
buttonGroup: VNode;
}

const ConsentBanner: FunctionComponent<BannerProps> = ({
Expand All @@ -19,6 +24,7 @@ const ConsentBanner: FunctionComponent<BannerProps> = ({
bannerIsOpen,
children,
onVendorPageClick,
buttonGroup,
}) => {
const showGpcBadge = getConsentContext().globalPrivacyControl;
return (
Expand All @@ -31,27 +37,37 @@ const ConsentBanner: FunctionComponent<BannerProps> = ({
<div id="fides-banner">
<div id="fides-banner-inner">
<CloseButton ariaLabel="Close banner" onClick={onClose} />
<div id="fides-banner-heading">
<div id="fides-banner-title" className="fides-banner-title">
{experience.title}
</div>
{showGpcBadge ? (
<GpcBadge
label="Global Privacy Control Signal"
status="detected"
/>
) : null}
</div>
<div
id="fides-banner-description"
className="fides-banner-description"
id="fides-banner-inner-container"
style={{
gridTemplateColumns: children ? "1fr 1fr" : "1fr",
galvana marked this conversation as resolved.
Show resolved Hide resolved
}}
>
<ExperienceDescription
description={experience.description}
onVendorPageClick={onVendorPageClick}
/>
<div id="fides-banner-inner-description">
<div id="fides-banner-heading">
<div id="fides-banner-title" className="fides-banner-title">
{experience.title}
</div>
{showGpcBadge && (
<GpcBadge
label="Global Privacy Control Signal"
status="detected"
/>
)}
</div>
<div
id="fides-banner-description"
className="fides-banner-description"
>
<ExperienceDescription
description={experience.description}
onVendorPageClick={onVendorPageClick}
/>
</div>
</div>
{children}
{buttonGroup}
</div>
{children}
</div>
</div>
</div>
Expand Down
27 changes: 23 additions & 4 deletions clients/fides-js/src/components/ConsentButtons.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { h, VNode } from "preact";
import { ComponentChildren, h, VNode } from "preact";
import Button from "./Button";
import {
ButtonType,
Expand All @@ -12,26 +12,37 @@ export const ConsentButtons = ({
experienceConfig,
onManagePreferencesClick,
firstButton,
middleButton,
onAcceptAll,
onRejectAll,
children,
}: {
experienceConfig: ExperienceConfig;
onManagePreferencesClick?: () => void;
firstButton?: VNode;
/** Used to add a button between the "manage preferences" button and the "accept/reject" buttons */
middleButton?: VNode;
onAcceptAll: () => void;
onRejectAll: () => void;
/** Added as siblings to the button group after the "accept/reject" buttons */
children?: ComponentChildren;
}) => (
<div id="fides-button-group">
{onManagePreferencesClick ? (
<div>
<div style={{ display: "flex" }}>
<Button
buttonType={ButtonType.TERTIARY}
label={experienceConfig.privacy_preferences_link_label}
onClick={onManagePreferencesClick}
/>
</div>
) : null}
<div className={firstButton ? "fides-modal-button-group" : undefined}>
{middleButton || null}
<div
className={
firstButton ? "fides-modal-button-group" : "fides-banner-button-group"
}
>
{firstButton || null}
<Button
buttonType={ButtonType.PRIMARY}
Expand All @@ -44,6 +55,7 @@ export const ConsentButtons = ({
onClick={onAcceptAll}
/>
</div>
{children}
</div>
);

Expand All @@ -56,6 +68,8 @@ interface NoticeConsentButtonProps {
enabledKeys: NoticeKeys;
isAcknowledge: boolean;
isInModal?: boolean;
children?: ComponentChildren;
allisonking marked this conversation as resolved.
Show resolved Hide resolved
middleButton?: VNode;
}

export const NoticeConsentButtons = ({
Expand All @@ -65,6 +79,8 @@ export const NoticeConsentButtons = ({
enabledKeys,
isInModal,
isAcknowledge,
children,
middleButton,
}: NoticeConsentButtonProps) => {
if (!experience.experience_config || !experience.privacy_notices) {
return null;
Expand Down Expand Up @@ -118,6 +134,9 @@ export const NoticeConsentButtons = ({
/>
) : undefined
}
/>
middleButton={middleButton}
>
{children}
</ConsentButtons>
);
};
15 changes: 3 additions & 12 deletions clients/fides-js/src/components/ConsentModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ExperienceConfig } from "../lib/consent-types";
import CloseButton from "./CloseButton";
import GpcInfo from "./GpcInfo";
import ExperienceDescription from "./ExperienceDescription";
import { getConsentContext } from "../fides";

const ConsentModal = ({
attributes,
Expand All @@ -18,6 +19,7 @@ const ConsentModal = ({
onVendorPageClick?: () => void;
}) => {
const { container, overlay, dialog, title, closeButton } = attributes;
const showGpcBadge = getConsentContext().globalPrivacyControl;

return (
// @ts-ignore A11yDialog ref obj type isn't quite the same
Expand Down Expand Up @@ -49,19 +51,8 @@ const ConsentModal = ({
description={experience.description}
/>
</p>
<GpcInfo />
{showGpcBadge && <GpcInfo />}
{children}
{experience.privacy_policy_link_label &&
allisonking marked this conversation as resolved.
Show resolved Hide resolved
experience.privacy_policy_url ? (
<a
href={experience.privacy_policy_url}
rel="noopener noreferrer"
target="_blank"
className="fides-modal-privacy-policy"
>
{experience.privacy_policy_link_label}
</a>
) : null}
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion clients/fides-js/src/components/Overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const Overlay: FunctionComponent<Props> = ({

const { instance, attributes } = useA11yDialog({
id: "fides-modal",
role: "dialog",
role: "alertdialog",
galvana marked this conversation as resolved.
Show resolved Hide resolved
title: experience?.experience_config?.title || "",
onClose: dispatchCloseEvent,
});
Expand Down
36 changes: 36 additions & 0 deletions clients/fides-js/src/components/PrivacyPolicyLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { h } from "preact";
import { ExperienceConfig } from "../lib/consent-types";

const PrivacyPolicyLink = ({
experience,
}: {
experience?: ExperienceConfig;
}) => {
if (
!experience?.privacy_policy_link_label ||
!experience?.privacy_policy_url
) {
return null;
}

return (
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<a
href={experience.privacy_policy_url}
rel="noopener noreferrer"
target="_blank"
className="fides-privacy-policy"
>
{experience.privacy_policy_link_label}
</a>
</div>
);
};

export default PrivacyPolicyLink;
4 changes: 3 additions & 1 deletion clients/fides-js/src/components/Toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ const Toggle = ({
disabled={disabled}
/>
{/* Mark as `hidden` so it will fall back to a regular checkbox if CSS is not available */}
<span className="fides-toggle-display" hidden />
<span className="fides-toggle-display" hidden>
{checked ? "Opt-in" : "Opt-out"}
</span>
</label>
);
};
Expand Down
Loading