UNPKG

@oslokommune/punkt-elements

Version:

Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo

192 lines (167 loc) 6 kB
import { customElement, property } from 'lit/decorators.js' import { html, PropertyValues } from 'lit' import { PktElement } from '@/base-elements/element' import { consentStrings } from './strings' import '../button' import '../icon' let consentScriptPromise: Promise<void> | null = null function loadConsentScript(): Promise<void> { if (consentScriptPromise) return consentScriptPromise consentScriptPromise = new Promise((resolve, reject) => { if (document.querySelector('#oslo-consent-script')) { resolve() return } const script = document.createElement('script') script.src = 'https://cdn.web.oslo.kommune.no/cb/cb-v1.1.0.js' script.id = 'oslo-consent-script' script.onload = () => resolve() script.onerror = reject document.head.appendChild(script) const styles = document.createElement('link') styles.href = 'https://cdn.web.oslo.kommune.no/cb/cb-v1.1.0.css' styles.type = 'text/css' styles.rel = 'stylesheet' styles.id = 'oslo-consent-styles' document.head.appendChild(styles) }) return consentScriptPromise } // Extend the Window interface to include googleAnalyticsId declare global { interface Window { cookieBanner_devMode?: boolean cookieBanner_cookieDomain?: string | null cookieBanner_cookieSecure?: string | null cookieBanner_cookieExpiryDays?: string | null cookieBanner_googleAnalyticsId?: string | null cookieBanner_hotjarId?: string | null cookieBanner?: any __cookieEvents?: any } } export interface IPktConsent { devMode?: boolean cookieDomain?: string | null cookieSecure?: string | null cookieExpiryDays?: string | null hotjarId?: string | null googleAnalyticsId?: string | null i18nLanguage?: string triggerType?: 'button' | 'link' | 'footerlink' | 'icon' | null triggerText?: string | null } @customElement('pkt-consent') export class PktConsent extends PktElement<IPktConsent> implements IPktConsent { private _cookieEventHandler?: (consent: any) => void @property({ type: Boolean }) devMode: boolean = false @property({ type: String }) hotjarId: string | null = null @property({ type: String }) googleAnalyticsId: string | null = null @property({ type: String }) cookieDomain: string | null = null @property({ type: String }) cookieSecure: string | null = null @property({ type: String }) cookieExpiryDays: string | null = null @property({ type: String }) triggerType: 'button' | 'link' | 'footerlink' | 'icon' | null = 'button' @property({ type: String }) triggerText: string | null = null @property({ type: String }) i18nLanguage: string = 'nb' constructor() { super() } connectedCallback() { super.connectedCallback() this.triggerText = this.triggerText || consentStrings.i18n[this.i18nLanguage as keyof typeof consentStrings.i18n].contentPresentation .buttons.settings } disconnectedCallback() { super.disconnectedCallback() if (this._cookieEventHandler) { window.__cookieEvents?.off('CookieManager.setCookie', this._cookieEventHandler) } } returnJsonOrObject(obj: any) { let returnObj try { returnObj = JSON.parse(obj) } catch (e) { returnObj = obj } return returnObj } emitCookieConsents(consent: any) { const consents = this.returnJsonOrObject(consent.value) const consentDetails = consents.items.reduce((acc: any, item: any) => { acc[item.name] = item.consent return acc }, {}) this.dispatchEvent( new CustomEvent('toggle-consent', { detail: consentDetails, bubbles: true, cancelable: false, }), ) } protected async firstUpdated(_changedProperties: PropertyValues): Promise<void> { window.cookieBanner_googleAnalyticsId = this.googleAnalyticsId window.cookieBanner_hotjarId = this.hotjarId if (this.cookieDomain) window.cookieBanner_cookieDomain = this.cookieDomain if (this.cookieSecure) window.cookieBanner_cookieSecure = this.cookieSecure if (this.cookieExpiryDays) window.cookieBanner_cookieExpiryDays = this.cookieExpiryDays if (this.devMode) window.cookieBanner_devMode = this.devMode await loadConsentScript() this.triggerInit() } triggerInit() { window.document.dispatchEvent( new Event('CookieBannerReady', { bubbles: true, cancelable: true, }), ) window.cookieBanner.cookieConsent.validateConsentCookie().then((response: boolean) => { if (response) { const cookie = window.cookieBanner.cookieConsent.getConsentCookie() const consents = { value: cookie } window.setTimeout(() => this.emitCookieConsents(consents), 0) if (this._cookieEventHandler) { window.__cookieEvents.off('CookieManager.setCookie', this._cookieEventHandler) } this._cookieEventHandler = (consent: any) => { this.emitCookieConsents(consent) } window.__cookieEvents.on('CookieManager.setCookie', this._cookieEventHandler) } }) } openModal(e: Event) { e.preventDefault() if (!window.cookieBanner?.cookieConsent) { this.triggerInit() } setTimeout(() => window.cookieBanner.openCookieModal()) } render() { if (this.triggerType === 'link') { return html`<a href="#" class="pkt-link" @click=${this.openModal}>${this.triggerText}</a>` } if (this.triggerType === 'footerlink') { return html`<a href="#" class="pkt-footer__link" @click=${this.openModal}> <pkt-icon name="chevron-right" class="pkt-footer__link-icon"></pkt-icon> ${this.triggerText} </a>` } if (this.triggerType === 'icon') { return html`<pkt-button skin="tertiary" variant="icon-only" iconName="cookie" @click=${this.openModal} > >${this.triggerText}</pkt-button >` } return html`<pkt-button @click=${this.openModal}>${this.triggerText}</pkt-button>` } }