@oslokommune/punkt-elements
Version:
Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo
192 lines (167 loc) • 6 kB
text/typescript
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
}
('pkt-consent')
export class PktConsent extends PktElement<IPktConsent> implements IPktConsent {
private _cookieEventHandler?: (consent: any) => void
({ type: Boolean }) devMode: boolean = false
({ type: String }) hotjarId: string | null = null
({ type: String }) googleAnalyticsId: string | null = null
({ type: String }) cookieDomain: string | null = null
({ type: String }) cookieSecure: string | null = null
({ type: String }) cookieExpiryDays: string | null = null
({ type: String }) triggerType: 'button' | 'link' | 'footerlink' | 'icon' | null =
'button'
({ type: String }) triggerText: string | null = null
({ 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>`
}
}