From 7102c17b19766d4dc58375cc9981f25307da6d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Wed, 22 Apr 2026 13:02:07 +0400 Subject: [PATCH] Add "Powered by Probo" branding to cookie banner SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Renders a subtle branded link at the bottom of both the banner and preference panel, conditionally hidden via show_branding config flag. Extracts all icon and HTML template constants into a shared html.ts module. Signed-off-by: Émile Ré --- packages/cookie-banner/src/activation.ts | 3 +- packages/cookie-banner/src/client.ts | 1 + .../src/components/settings-button.ts | 3 +- packages/cookie-banner/src/html.ts | 25 +++++++++++++ .../cookie-banner/src/themed-banner/styles.ts | 37 +++++++++++++++++-- .../src/themed-banner/themed-banner.ts | 25 ++++++++----- 6 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 packages/cookie-banner/src/html.ts diff --git a/packages/cookie-banner/src/activation.ts b/packages/cookie-banner/src/activation.ts index 6416a8db2..5d64d9625 100644 --- a/packages/cookie-banner/src/activation.ts +++ b/packages/cookie-banner/src/activation.ts @@ -12,6 +12,8 @@ // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +import { LOCK_ICON } from "./html"; + const ATTR_CATEGORY = "data-cookie-consent"; const ATTR_SRC = "data-src"; const ATTR_HREF = "data-href"; @@ -39,7 +41,6 @@ const VISUAL_TAGS = new Set([ "OBJECT", ]); -const LOCK_ICON = ``; const PLACEHOLDER_STYLES = ` [${ATTR_HIDDEN}] { diff --git a/packages/cookie-banner/src/client.ts b/packages/cookie-banner/src/client.ts index 76284b3ea..008232980 100644 --- a/packages/cookie-banner/src/client.ts +++ b/packages/cookie-banner/src/client.ts @@ -43,6 +43,7 @@ export interface BannerConfig { privacy_policy_url: string; consent_expiry_days: number; consent_mode: "OPT_IN" | "OPT_OUT"; + show_branding: boolean; categories: Category[]; } diff --git a/packages/cookie-banner/src/components/settings-button.ts b/packages/cookie-banner/src/components/settings-button.ts index ab0f19f47..70e22bb0c 100644 --- a/packages/cookie-banner/src/components/settings-button.ts +++ b/packages/cookie-banner/src/components/settings-button.ts @@ -12,11 +12,10 @@ // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +import { COOKIE_ICON } from "../html"; import type { ProboRootElement } from "./base"; import type { ProboCookieBannerRoot } from "./cookie-banner-root"; -const COOKIE_ICON = ``; - export class ProboSettingsButton extends HTMLElement { private shadow: ShadowRoot; private root: ProboRootElement | null = null; diff --git a/packages/cookie-banner/src/html.ts b/packages/cookie-banner/src/html.ts new file mode 100644 index 000000000..190f79f48 --- /dev/null +++ b/packages/cookie-banner/src/html.ts @@ -0,0 +1,25 @@ +// Copyright (c) 2026 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +export const CLOSE_ICON = ``; + +export const CHEVRON_DOWN = ``; + +export const COOKIE_ICON = ``; + +export const LOCK_ICON = ``; + +const PROBO_LOGO = ``; + +export const BRANDING = ``; diff --git a/packages/cookie-banner/src/themed-banner/styles.ts b/packages/cookie-banner/src/themed-banner/styles.ts index 3ca2bf6cc..b01f56a95 100644 --- a/packages/cookie-banner/src/themed-banner/styles.ts +++ b/packages/cookie-banner/src/themed-banner/styles.ts @@ -84,12 +84,16 @@ export const THEMED_STYLES = ` border-radius: var(--_radius); box-shadow: var(--_shadow); width: 100%; - padding: 24px; pointer-events: auto; } probo-banner .card { max-width: 450px; + padding: 24px 24px 12px 24px; + } + + probo-banner .buttons { + padding-bottom: 12px; } probo-preference-panel .card { @@ -97,7 +101,6 @@ export const THEMED_STYLES = ` max-height: 75vh; display: flex; flex-direction: column; - padding: 0; } probo-preference-panel probo-category-list { @@ -188,9 +191,13 @@ export const THEMED_STYLES = ` flex-direction: column; } - probo-preference-panel .buttons { + probo-preference-panel .footer { border-top: 1px solid var(--_border); - padding: 20px 24px 24px; + padding: 10px 24px; + } + + probo-preference-panel .buttons { + padding: 10px 0; } probo-category { @@ -347,6 +354,28 @@ export const THEMED_STYLES = ` color: var(--_text); } + .branding { + text-align: center; + } + + .branding a { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: calc(var(--_font-size) - 2px); + font-weight: 400; + color: var(--_text-secondary); + text-decoration: none; + } + + .branding a:hover { + color: var(--_text); + } + + .branding svg { + flex-shrink: 0; + } + [hidden] { display: none !important; } diff --git a/packages/cookie-banner/src/themed-banner/themed-banner.ts b/packages/cookie-banner/src/themed-banner/themed-banner.ts index 6224f59df..ffe77d701 100644 --- a/packages/cookie-banner/src/themed-banner/themed-banner.ts +++ b/packages/cookie-banner/src/themed-banner/themed-banner.ts @@ -15,11 +15,9 @@ import { registerComponents } from "../components"; import type { ProboCookieBannerRoot } from "../components/cookie-banner-root"; import type { BannerConfig } from "../client"; +import { BRANDING, CHEVRON_DOWN, CLOSE_ICON } from "../html"; import { THEMED_STYLES } from "./styles"; -const CLOSE_ICON = ``; -const CHEVRON_DOWN = ``; - export class ProboThemedBanner extends HTMLElement { private shadow: ShadowRoot; @@ -62,6 +60,7 @@ export class ProboThemedBanner extends HTMLElement { + ${BRANDING} @@ -103,12 +102,15 @@ export class ProboThemedBanner extends HTMLElement { -
- - - - - +
@@ -123,6 +125,11 @@ export class ProboThemedBanner extends HTMLElement { root.addEventListener("probo-ready", (e: Event) => { const config = (e as CustomEvent).detail.config as BannerConfig; this.updateDescription(config); + if (!config.show_branding) { + this.shadow.querySelectorAll("[data-branding]").forEach(el => { + (el as HTMLElement).setAttribute("hidden", ""); + }); + } }); this.shadow.querySelector("[data-action=back]")?.addEventListener("click", () => {