From ce77091e6cd0a1afdcc15777a1e211377ae6f6ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Thu, 16 Apr 2026 15:20:40 +0400 Subject: [PATCH] Add validation for preference panel and category template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validate that contains and , and that the category template includes and . Signed-off-by: Émile Ré --- .../src/components/category-list.ts | 20 ++++++++++++++++++- .../src/components/preference-panel.ts | 20 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/cookie-banner/src/components/category-list.ts b/packages/cookie-banner/src/components/category-list.ts index 0c77e9c31..f40e2bdfb 100644 --- a/packages/cookie-banner/src/components/category-list.ts +++ b/packages/cookie-banner/src/components/category-list.ts @@ -37,9 +37,11 @@ export class ProboCategoryList extends ProboElement { return; } - this.root = this.findAncestor("-root"); + this.root = this.findAncestor("probo-cookie-banner-root"); if (!this.root) return; + this.validateTemplate(); + try { const config = this.root.bannerConfig; this.stamp(config.categories); @@ -78,6 +80,22 @@ export class ProboCategoryList extends ProboElement { } } + private validateTemplate(): void { + if (!this.template) return; + const content = this.template.content; + const missing: string[] = []; + if (!content.querySelector("probo-category-toggle")) { + missing.push("probo-category-toggle"); + } + if (!content.querySelector("probo-cookie-list")) { + missing.push("probo-cookie-list"); + } + if (missing.length > 0) { + this.warn(` template is missing required elements: ${missing.join(", ")}`); + this.emitValidation(missing); + } + } + private fillSlots( fragment: DocumentFragment, data: Record, diff --git a/packages/cookie-banner/src/components/preference-panel.ts b/packages/cookie-banner/src/components/preference-panel.ts index c8bba21d9..7e28bc653 100644 --- a/packages/cookie-banner/src/components/preference-panel.ts +++ b/packages/cookie-banner/src/components/preference-panel.ts @@ -16,6 +16,11 @@ import { ProboElement } from "./base"; import type { ProboRootElement } from "./base"; import type { ProboCookieBannerRoot } from "./cookie-banner-root"; +const REQUIRED_CHILDREN = [ + "probo-category-list", + "probo-save-button", +] as const; + export class ProboPreferencePanel extends ProboElement { private root: ProboRootElement | null = null; private onStateChange = (e: Event): void => { @@ -44,6 +49,8 @@ export class ProboPreferencePanel extends ProboElement { } }); } + + this.scheduleValidation(() => this.validate()); } disconnectedCallback(): void { @@ -51,6 +58,19 @@ export class ProboPreferencePanel extends ProboElement { this.root.removeEventListener("probo-state", this.onStateChange); } } + + private validate(): void { + const missing: string[] = []; + for (const tag of REQUIRED_CHILDREN) { + if (!this.querySelector(tag)) { + missing.push(tag); + } + } + if (missing.length > 0) { + this.warn(` is missing required children: ${missing.join(", ")}`); + this.emitValidation(missing); + } + } } export class ProboSaveButton extends ProboElement {