Adapt cookie banner UI and texts per regulation
The server now resolves regulation-specific translations (opt-out notice for CCPA, simple notice when no regulation applies) and remaps text keys before returning the config. The client hides buttons whose text is empty, so the banner layout adapts without client-side consent-mode logic. Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
import type { CookieBannerClient } from "../client";
|
||||
import type { BannerConfig } from "../types";
|
||||
import type { BannerConfig, Regulation } from "../types";
|
||||
|
||||
export type ProboState = "loading" | "banner" | "panel" | "hidden";
|
||||
|
||||
@@ -68,6 +68,8 @@ export interface ProboRootElement extends ProboElement {
|
||||
readonly reopenWidget: string;
|
||||
readonly consentDraft: ConsentDraft;
|
||||
readonly gpcApplied: boolean;
|
||||
readonly regulation: Regulation | null;
|
||||
readonly consentMode: "OPT_IN" | "OPT_OUT" | null;
|
||||
setState(state: ProboState): void;
|
||||
updateDraft(category: string, value: boolean): void;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
import { CookieBannerClient } from "../client";
|
||||
import type { BannerConfig } from "../types";
|
||||
import type { BannerConfig, Regulation } from "../types";
|
||||
import { ProboElement } from "./base";
|
||||
import type { ProboState, ProboRootElement, ConsentDraft } from "./base";
|
||||
|
||||
@@ -57,6 +57,16 @@ export class ProboCookieBannerRoot extends ProboElement implements ProboRootElem
|
||||
return this._client?.gpcApplied ?? false;
|
||||
}
|
||||
|
||||
get regulation(): Regulation | null {
|
||||
return this._client?.regulation ?? null;
|
||||
}
|
||||
|
||||
get consentMode(): "OPT_IN" | "OPT_OUT" | null {
|
||||
const mode = this._config?.consent_mode;
|
||||
if (mode === "OPT_IN" || mode === "OPT_OUT") return mode;
|
||||
return null;
|
||||
}
|
||||
|
||||
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {
|
||||
if (name === "reopen-widget" && oldValue !== newValue) {
|
||||
this.dispatchEvent(
|
||||
|
||||
@@ -130,6 +130,7 @@ export class ProboThemedBanner extends HTMLElement {
|
||||
const detail = (e as CustomEvent).detail;
|
||||
const config = detail.config as BannerConfig;
|
||||
this.applyTexts(config);
|
||||
this.applyLayout(config);
|
||||
if (!config.show_branding) {
|
||||
this.shadow.querySelectorAll("[data-branding]").forEach(el => {
|
||||
(el as HTMLElement).setAttribute("hidden", "");
|
||||
@@ -224,6 +225,20 @@ export class ProboThemedBanner extends HTMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
private applyLayout(config: BannerConfig): void {
|
||||
const texts = config.texts ?? {};
|
||||
|
||||
const hideIfEmpty = (selector: string, textKey: string): void => {
|
||||
if (texts[textKey]) return;
|
||||
this.shadow.querySelectorAll(selector).forEach(el => {
|
||||
(el as HTMLElement).hidden = true;
|
||||
});
|
||||
};
|
||||
|
||||
hideIfEmpty("probo-banner probo-reject-button", "button_reject_all");
|
||||
hideIfEmpty("probo-banner probo-customize-button", "button_customize");
|
||||
}
|
||||
|
||||
private esc(str: string): string {
|
||||
return str.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user