@oslokommune/punkt-elements 16.19.0 → 16.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,40 @@ og skriver commits ca etter [Conventional Commits](https://conventionalcommits.o
5
5
 
6
6
  ---
7
7
 
8
+ ## [16.21.1](https://github.com/oslokommune/punkt/compare/16.21.0...16.21.1) (2026-05-29)
9
+
10
+ ### ⚠ BREAKING CHANGES
11
+ Ingen
12
+
13
+ ### Features
14
+ Ingen
15
+
16
+ ### Bug Fixes
17
+ Ingen
18
+
19
+ ### Chores
20
+ Ingen
21
+
22
+ ---
23
+
24
+
25
+ ## [16.21.0](https://github.com/oslokommune/punkt/compare/16.20.0...16.21.0) (2026-05-29)
26
+
27
+ ### ⚠ BREAKING CHANGES
28
+ Ingen
29
+
30
+ ### Features
31
+ Ingen
32
+
33
+ ### Bug Fixes
34
+ Ingen
35
+
36
+ ### Chores
37
+ Ingen
38
+
39
+ ---
40
+
41
+
8
42
  ## [16.19.0](https://github.com/oslokommune/punkt/compare/16.18.0...16.19.0) (2026-05-28)
9
43
 
10
44
  ### ⚠ BREAKING CHANGES
@@ -1,5 +1,27 @@
1
1
  import { PropertyValues } from 'lit';
2
2
  import { PktElement } from '../../base-elements/element';
3
+ interface ConsentItem {
4
+ name: string;
5
+ consent: boolean;
6
+ }
7
+ interface ConsentValue {
8
+ items: ConsentItem[];
9
+ }
10
+ interface CookieConsentEvent {
11
+ value: string | ConsentValue;
12
+ }
13
+ type CookieEventHandler = (consent: CookieConsentEvent) => void;
14
+ interface CookieEvents {
15
+ on(eventName: string, handler: CookieEventHandler): void;
16
+ off(eventName: string, handler: CookieEventHandler): void;
17
+ }
18
+ interface CookieBannerApi {
19
+ cookieConsent: {
20
+ validateConsentCookie(): Promise<boolean>;
21
+ getConsentCookie(): string | ConsentValue;
22
+ };
23
+ openCookieModal(): void;
24
+ }
3
25
  declare global {
4
26
  interface Window {
5
27
  cookieBanner_devMode?: boolean;
@@ -8,10 +30,11 @@ declare global {
8
30
  cookieBanner_cookieExpiryDays?: string | null;
9
31
  cookieBanner_googleAnalyticsId?: string | null;
10
32
  cookieBanner_hotjarId?: string | null;
11
- cookieBanner?: any;
12
- __cookieEvents?: any;
33
+ cookieBanner?: CookieBannerApi;
34
+ __cookieEvents?: CookieEvents;
13
35
  }
14
36
  }
37
+ export type TPktConsentTriggerType = 'button' | 'link' | 'footerlink' | 'icon';
15
38
  export interface IPktConsent {
16
39
  devMode?: boolean;
17
40
  cookieDomain?: string | null;
@@ -20,7 +43,7 @@ export interface IPktConsent {
20
43
  hotjarId?: string | null;
21
44
  googleAnalyticsId?: string | null;
22
45
  i18nLanguage?: string;
23
- triggerType?: 'button' | 'link' | 'footerlink' | 'icon' | null;
46
+ triggerType?: TPktConsentTriggerType | null;
24
47
  triggerText?: string | null;
25
48
  }
26
49
  export declare class PktConsent extends PktElement<IPktConsent> implements IPktConsent {
@@ -31,16 +54,21 @@ export declare class PktConsent extends PktElement<IPktConsent> implements IPktC
31
54
  cookieDomain: string | null;
32
55
  cookieSecure: string | null;
33
56
  cookieExpiryDays: string | null;
34
- triggerType: 'button' | 'link' | 'footerlink' | 'icon' | null;
57
+ triggerType: TPktConsentTriggerType | null;
35
58
  triggerText: string | null;
36
59
  i18nLanguage: string;
37
- constructor();
38
60
  connectedCallback(): void;
39
61
  disconnectedCallback(): void;
40
- returnJsonOrObject(obj: any): any;
41
- emitCookieConsents(consent: any): void;
62
+ /**
63
+ * Parses a JSON string when needed; returns the input unchanged when it's
64
+ * already a parsed object or when parsing fails.
65
+ * Exposed for backwards compatibility — tests still rely on it.
66
+ */
67
+ returnJsonOrObject<T>(obj: T | string): T;
68
+ emitCookieConsents(consent: CookieConsentEvent): void;
42
69
  protected firstUpdated(_changedProperties: PropertyValues): Promise<void>;
43
70
  triggerInit(): void;
44
71
  openModal(e: Event): void;
45
72
  render(): import('lit-html').TemplateResult<1>;
46
73
  }
74
+ export {};
@@ -124,29 +124,31 @@ function s() {
124
124
  r.href = "https://cdn.web.oslo.kommune.no/cb/cb-v1.1.0.css", r.type = "text/css", r.rel = "stylesheet", r.id = "oslo-consent-styles", document.head.appendChild(r);
125
125
  }), o);
126
126
  }
127
- var c = class extends i {
128
- constructor() {
129
- super(), this.devMode = !1, this.hotjarId = null, this.googleAnalyticsId = null, this.cookieDomain = null, this.cookieSecure = null, this.cookieExpiryDays = null, this.triggerType = "button", this.triggerText = null, this.i18nLanguage = "nb";
127
+ var c = (e) => {
128
+ if (typeof e != "string") return e;
129
+ try {
130
+ return JSON.parse(e);
131
+ } catch {
132
+ return e;
133
+ }
134
+ }, l = (e) => c(e.value).items.reduce((e, t) => (e[t.name] = t.consent, e), {}), u = class extends i {
135
+ constructor(...e) {
136
+ super(...e), this.devMode = !1, this.hotjarId = null, this.googleAnalyticsId = null, this.cookieDomain = null, this.cookieSecure = null, this.cookieExpiryDays = null, this.triggerType = "button", this.triggerText = null, this.i18nLanguage = "nb";
130
137
  }
131
138
  connectedCallback() {
132
- super.connectedCallback(), this.triggerText = this.triggerText || a.i18n[this.i18nLanguage].contentPresentation.buttons.settings;
139
+ super.connectedCallback();
140
+ let e = this.i18nLanguage;
141
+ this.triggerText = this.triggerText || a.i18n[e].contentPresentation.buttons.settings;
133
142
  }
134
143
  disconnectedCallback() {
135
144
  super.disconnectedCallback(), this._cookieEventHandler && window.__cookieEvents?.off("CookieManager.setCookie", this._cookieEventHandler);
136
145
  }
137
146
  returnJsonOrObject(e) {
138
- let t;
139
- try {
140
- t = JSON.parse(e);
141
- } catch {
142
- t = e;
143
- }
144
- return t;
147
+ return c(e);
145
148
  }
146
149
  emitCookieConsents(e) {
147
- let t = this.returnJsonOrObject(e.value).items.reduce((e, t) => (e[t.name] = t.consent, e), {});
148
150
  this.dispatchEvent(new CustomEvent("toggle-consent", {
149
- detail: t,
151
+ detail: l(e),
150
152
  bubbles: !0,
151
153
  cancelable: !1
152
154
  }));
@@ -158,17 +160,16 @@ var c = class extends i {
158
160
  window.document.dispatchEvent(new Event("CookieBannerReady", {
159
161
  bubbles: !0,
160
162
  cancelable: !0
161
- })), window.cookieBanner.cookieConsent.validateConsentCookie().then((e) => {
162
- if (e) {
163
- let e = { value: window.cookieBanner.cookieConsent.getConsentCookie() };
164
- window.setTimeout(() => this.emitCookieConsents(e), 0), this._cookieEventHandler && window.__cookieEvents.off("CookieManager.setCookie", this._cookieEventHandler), this._cookieEventHandler = (e) => {
165
- this.emitCookieConsents(e);
166
- }, window.__cookieEvents.on("CookieManager.setCookie", this._cookieEventHandler);
167
- }
163
+ }));
164
+ let e = window.cookieBanner, t = window.__cookieEvents;
165
+ !e || !t || e.cookieConsent.validateConsentCookie().then((n) => {
166
+ if (!n) return;
167
+ let r = e.cookieConsent.getConsentCookie();
168
+ window.setTimeout(() => this.emitCookieConsents({ value: r }), 0), this._cookieEventHandler && t.off("CookieManager.setCookie", this._cookieEventHandler), this._cookieEventHandler = (e) => this.emitCookieConsents(e), t.on("CookieManager.setCookie", this._cookieEventHandler);
168
169
  });
169
170
  }
170
171
  openModal(e) {
171
- e.preventDefault(), window.cookieBanner?.cookieConsent || this.triggerInit(), setTimeout(() => window.cookieBanner.openCookieModal());
172
+ e.preventDefault(), window.cookieBanner?.cookieConsent || this.triggerInit(), setTimeout(() => window.cookieBanner?.openCookieModal());
172
173
  }
173
174
  render() {
174
175
  return this.triggerType === "link" ? n`<a href="#" class="pkt-link" @click=${this.openModal}>${this.triggerText}</a>` : this.triggerType === "footerlink" ? n`<a href="#" class="pkt-footer__link" @click=${this.openModal}>
@@ -179,19 +180,18 @@ var c = class extends i {
179
180
  variant="icon-only"
180
181
  iconName="cookie"
181
182
  @click=${this.openModal}
182
- >
183
183
  >${this.triggerText}</pkt-button
184
184
  >` : n`<pkt-button @click=${this.openModal}>${this.triggerText}</pkt-button>`;
185
185
  }
186
186
  };
187
- e([t({ type: Boolean })], c.prototype, "devMode", void 0), e([t({ type: String })], c.prototype, "hotjarId", void 0), e([t({ type: String })], c.prototype, "googleAnalyticsId", void 0), e([t({ type: String })], c.prototype, "cookieDomain", void 0), e([t({ type: String })], c.prototype, "cookieSecure", void 0), e([t({ type: String })], c.prototype, "cookieExpiryDays", void 0), e([t({ type: String })], c.prototype, "triggerType", void 0), e([t({ type: String })], c.prototype, "triggerText", void 0), e([t({ type: String })], c.prototype, "i18nLanguage", void 0);
187
+ e([t({ type: Boolean })], u.prototype, "devMode", void 0), e([t({ type: String })], u.prototype, "hotjarId", void 0), e([t({ type: String })], u.prototype, "googleAnalyticsId", void 0), e([t({ type: String })], u.prototype, "cookieDomain", void 0), e([t({ type: String })], u.prototype, "cookieSecure", void 0), e([t({ type: String })], u.prototype, "cookieExpiryDays", void 0), e([t({ type: String })], u.prototype, "triggerType", void 0), e([t({ type: String })], u.prototype, "triggerText", void 0), e([t({ type: String })], u.prototype, "i18nLanguage", void 0);
188
188
  try {
189
- r("pkt-consent")(c);
189
+ r("pkt-consent")(u);
190
190
  } catch {
191
191
  console.warn("Forsøker å definere <pkt-consent>, men den er allerede definert");
192
192
  }
193
193
  //#endregion
194
194
  //#region src/components/consent/index.ts
195
- var l = c;
195
+ var d = u;
196
196
  //#endregion
197
- export { c as n, l as t };
197
+ export { u as n, d as t };
@@ -1,4 +1,4 @@
1
- const e=require(`./element-CXAtr6Gu.cjs`);require(`./icon-Dw6I0HDV.cjs`),require(`./button-Dwv11n6R.cjs`);var t={i18n:{nb:{contentPresentation:{title:`Oslo kommune bruker informasjonskapsler`,description:[`For at nettstedet skal fungere og være trygt, bruker Oslo kommune informasjonskapsler. Noen er teknisk nødvendige, mens andre sikrer ulik funksjonalitet.`,`Godtar du alle informasjonskapsler, tillater du også at vi samler inn data om statistikk og brukeradferd. Da hjelper du oss med å lage et bedre nettsted uten at du trenger å dele noe personlig informasjon med oss.`],buttons:{accept:`Godta alle`,reject:`Kun nødvendige`,settings:`Innstillinger for informasjonskapsler`}},contentSettings:{title:`Innstillinger for informasjonskapsler`,description:[`Her kan du velge hvilke typer informasjonskapsler du vil tillate. Tillatelsen gjelder i 90 dager. Husk at nødvendige informasjonskapsler ikke kan velges bort.`,`Du kan når som helst endre innstillingene og finne mer informasjon nederst på nettstedet under «Innstillinger for informasjonskapsler» og «Personvern og informasjonskapsler».`],buttons:{back:`Tilbake`,save:`Lagre innstillinger`}}},en:{contentPresentation:{title:`Before you visit Oslo kommune ...`,description:[`This website uses cookies to make improvements. In this context, we need your consent to measure the traffic on the website in relation to statistics and feedback.`,`To read more about what we use cookies for, go to our privacy declaration which you will find at the bottom of our websites.`],buttons:{accept:`Yes, I accept`,reject:`Only necessary`,settings:`Go to settings`}},contentSettings:{title:`Her kan du aktivt velge mellom ulike informasjonskapsler`,description:[`For å lese mer om hva vi bruker informasjonskapsler til gå til vår personvernserklering som du finner på våre nettsider`],buttons:{back:`Back`,save:`Save settings`}}}},cookies:[{name:`statistics`,defaultValue:null,i18n:{nb:{title:`Statistikk og analyse`,description:`Jeg godtar at Oslo kommune bruker informasjonskapsler til å innhente data om statistikk og brukeradferd.`,buttons:{yes:`Ja`,no:`Nei`}},en:{title:`Statistics and analytics`,description:`Select your preference for statistics and analytics`,buttons:{yes:`Yes`,no:`No`}}}},{name:`survey`,defaultValue:null,i18n:{nb:{title:`Skriftlige tilbakemeldinger`,description:`Jeg godtar at Oslo kommune bruker informasjonskapsler til å vise responsfelt og registrere tilbakemeldinger.`,buttons:{yes:`Ja`,no:`Nei`}},en:{title:`Survey`,description:`Select your preference for survey`,buttons:{yes:`Yes`,no:`No`}}}},{name:`functional`,defaultValue:!0,i18n:{nb:{title:`Funksjonelle informasjonskapsler`,description:`Jeg godtar at Oslo kommune bruker informasjonskapsler for å gjøre ulike funksjoner på nettstedet mulige (for eksempel skjemaer og barnehagevelger).`,buttons:{yes:`Ja`,no:`Nei`}},en:{title:`Functional cookies`,description:`For the website to function optimally, we recommend that you accept these cookies`,buttons:{yes:`Yes`,no:`No`}}}}]},n=null;function r(){return n||(n=new Promise((e,t)=>{if(document.querySelector(`#oslo-consent-script`)){e();return}let n=document.createElement(`script`);n.src=`https://cdn.web.oslo.kommune.no/cb/cb-v1.1.0.js`,n.id=`oslo-consent-script`,n.onload=()=>e(),n.onerror=t,document.head.appendChild(n);let r=document.createElement(`link`);r.href=`https://cdn.web.oslo.kommune.no/cb/cb-v1.1.0.css`,r.type=`text/css`,r.rel=`stylesheet`,r.id=`oslo-consent-styles`,document.head.appendChild(r)}),n)}var i=class extends e.t{constructor(){super(),this.devMode=!1,this.hotjarId=null,this.googleAnalyticsId=null,this.cookieDomain=null,this.cookieSecure=null,this.cookieExpiryDays=null,this.triggerType=`button`,this.triggerText=null,this.i18nLanguage=`nb`}connectedCallback(){super.connectedCallback(),this.triggerText=this.triggerText||t.i18n[this.i18nLanguage].contentPresentation.buttons.settings}disconnectedCallback(){super.disconnectedCallback(),this._cookieEventHandler&&window.__cookieEvents?.off(`CookieManager.setCookie`,this._cookieEventHandler)}returnJsonOrObject(e){let t;try{t=JSON.parse(e)}catch{t=e}return t}emitCookieConsents(e){let t=this.returnJsonOrObject(e.value).items.reduce((e,t)=>(e[t.name]=t.consent,e),{});this.dispatchEvent(new CustomEvent(`toggle-consent`,{detail:t,bubbles:!0,cancelable:!1}))}async firstUpdated(e){window.cookieBanner_googleAnalyticsId=this.googleAnalyticsId,window.cookieBanner_hotjarId=this.hotjarId,this.cookieDomain&&(window.cookieBanner_cookieDomain=this.cookieDomain),this.cookieSecure&&(window.cookieBanner_cookieSecure=this.cookieSecure),this.cookieExpiryDays&&(window.cookieBanner_cookieExpiryDays=this.cookieExpiryDays),this.devMode&&(window.cookieBanner_devMode=this.devMode),await r(),this.triggerInit()}triggerInit(){window.document.dispatchEvent(new Event(`CookieBannerReady`,{bubbles:!0,cancelable:!0})),window.cookieBanner.cookieConsent.validateConsentCookie().then(e=>{if(e){let e={value:window.cookieBanner.cookieConsent.getConsentCookie()};window.setTimeout(()=>this.emitCookieConsents(e),0),this._cookieEventHandler&&window.__cookieEvents.off(`CookieManager.setCookie`,this._cookieEventHandler),this._cookieEventHandler=e=>{this.emitCookieConsents(e)},window.__cookieEvents.on(`CookieManager.setCookie`,this._cookieEventHandler)}})}openModal(e){e.preventDefault(),window.cookieBanner?.cookieConsent||this.triggerInit(),setTimeout(()=>window.cookieBanner.openCookieModal())}render(){return this.triggerType===`link`?e.p`<a href="#" class="pkt-link" @click=${this.openModal}>${this.triggerText}</a>`:this.triggerType===`footerlink`?e.p`<a href="#" class="pkt-footer__link" @click=${this.openModal}>
1
+ const e=require(`./element-CXAtr6Gu.cjs`);require(`./icon-Dw6I0HDV.cjs`),require(`./button-Dwv11n6R.cjs`);var t={i18n:{nb:{contentPresentation:{title:`Oslo kommune bruker informasjonskapsler`,description:[`For at nettstedet skal fungere og være trygt, bruker Oslo kommune informasjonskapsler. Noen er teknisk nødvendige, mens andre sikrer ulik funksjonalitet.`,`Godtar du alle informasjonskapsler, tillater du også at vi samler inn data om statistikk og brukeradferd. Da hjelper du oss med å lage et bedre nettsted uten at du trenger å dele noe personlig informasjon med oss.`],buttons:{accept:`Godta alle`,reject:`Kun nødvendige`,settings:`Innstillinger for informasjonskapsler`}},contentSettings:{title:`Innstillinger for informasjonskapsler`,description:[`Her kan du velge hvilke typer informasjonskapsler du vil tillate. Tillatelsen gjelder i 90 dager. Husk at nødvendige informasjonskapsler ikke kan velges bort.`,`Du kan når som helst endre innstillingene og finne mer informasjon nederst på nettstedet under «Innstillinger for informasjonskapsler» og «Personvern og informasjonskapsler».`],buttons:{back:`Tilbake`,save:`Lagre innstillinger`}}},en:{contentPresentation:{title:`Before you visit Oslo kommune ...`,description:[`This website uses cookies to make improvements. In this context, we need your consent to measure the traffic on the website in relation to statistics and feedback.`,`To read more about what we use cookies for, go to our privacy declaration which you will find at the bottom of our websites.`],buttons:{accept:`Yes, I accept`,reject:`Only necessary`,settings:`Go to settings`}},contentSettings:{title:`Her kan du aktivt velge mellom ulike informasjonskapsler`,description:[`For å lese mer om hva vi bruker informasjonskapsler til gå til vår personvernserklering som du finner på våre nettsider`],buttons:{back:`Back`,save:`Save settings`}}}},cookies:[{name:`statistics`,defaultValue:null,i18n:{nb:{title:`Statistikk og analyse`,description:`Jeg godtar at Oslo kommune bruker informasjonskapsler til å innhente data om statistikk og brukeradferd.`,buttons:{yes:`Ja`,no:`Nei`}},en:{title:`Statistics and analytics`,description:`Select your preference for statistics and analytics`,buttons:{yes:`Yes`,no:`No`}}}},{name:`survey`,defaultValue:null,i18n:{nb:{title:`Skriftlige tilbakemeldinger`,description:`Jeg godtar at Oslo kommune bruker informasjonskapsler til å vise responsfelt og registrere tilbakemeldinger.`,buttons:{yes:`Ja`,no:`Nei`}},en:{title:`Survey`,description:`Select your preference for survey`,buttons:{yes:`Yes`,no:`No`}}}},{name:`functional`,defaultValue:!0,i18n:{nb:{title:`Funksjonelle informasjonskapsler`,description:`Jeg godtar at Oslo kommune bruker informasjonskapsler for å gjøre ulike funksjoner på nettstedet mulige (for eksempel skjemaer og barnehagevelger).`,buttons:{yes:`Ja`,no:`Nei`}},en:{title:`Functional cookies`,description:`For the website to function optimally, we recommend that you accept these cookies`,buttons:{yes:`Yes`,no:`No`}}}}]},n=null;function r(){return n||(n=new Promise((e,t)=>{if(document.querySelector(`#oslo-consent-script`)){e();return}let n=document.createElement(`script`);n.src=`https://cdn.web.oslo.kommune.no/cb/cb-v1.1.0.js`,n.id=`oslo-consent-script`,n.onload=()=>e(),n.onerror=t,document.head.appendChild(n);let r=document.createElement(`link`);r.href=`https://cdn.web.oslo.kommune.no/cb/cb-v1.1.0.css`,r.type=`text/css`,r.rel=`stylesheet`,r.id=`oslo-consent-styles`,document.head.appendChild(r)}),n)}var i=e=>{if(typeof e!=`string`)return e;try{return JSON.parse(e)}catch{return e}},a=e=>i(e.value).items.reduce((e,t)=>(e[t.name]=t.consent,e),{}),o=class extends e.t{constructor(...e){super(...e),this.devMode=!1,this.hotjarId=null,this.googleAnalyticsId=null,this.cookieDomain=null,this.cookieSecure=null,this.cookieExpiryDays=null,this.triggerType=`button`,this.triggerText=null,this.i18nLanguage=`nb`}connectedCallback(){super.connectedCallback();let e=this.i18nLanguage;this.triggerText=this.triggerText||t.i18n[e].contentPresentation.buttons.settings}disconnectedCallback(){super.disconnectedCallback(),this._cookieEventHandler&&window.__cookieEvents?.off(`CookieManager.setCookie`,this._cookieEventHandler)}returnJsonOrObject(e){return i(e)}emitCookieConsents(e){this.dispatchEvent(new CustomEvent(`toggle-consent`,{detail:a(e),bubbles:!0,cancelable:!1}))}async firstUpdated(e){window.cookieBanner_googleAnalyticsId=this.googleAnalyticsId,window.cookieBanner_hotjarId=this.hotjarId,this.cookieDomain&&(window.cookieBanner_cookieDomain=this.cookieDomain),this.cookieSecure&&(window.cookieBanner_cookieSecure=this.cookieSecure),this.cookieExpiryDays&&(window.cookieBanner_cookieExpiryDays=this.cookieExpiryDays),this.devMode&&(window.cookieBanner_devMode=this.devMode),await r(),this.triggerInit()}triggerInit(){window.document.dispatchEvent(new Event(`CookieBannerReady`,{bubbles:!0,cancelable:!0}));let e=window.cookieBanner,t=window.__cookieEvents;!e||!t||e.cookieConsent.validateConsentCookie().then(n=>{if(!n)return;let r=e.cookieConsent.getConsentCookie();window.setTimeout(()=>this.emitCookieConsents({value:r}),0),this._cookieEventHandler&&t.off(`CookieManager.setCookie`,this._cookieEventHandler),this._cookieEventHandler=e=>this.emitCookieConsents(e),t.on(`CookieManager.setCookie`,this._cookieEventHandler)})}openModal(e){e.preventDefault(),window.cookieBanner?.cookieConsent||this.triggerInit(),setTimeout(()=>window.cookieBanner?.openCookieModal())}render(){return this.triggerType===`link`?e.p`<a href="#" class="pkt-link" @click=${this.openModal}>${this.triggerText}</a>`:this.triggerType===`footerlink`?e.p`<a href="#" class="pkt-footer__link" @click=${this.openModal}>
2
2
  <pkt-icon name="chevron-right" class="pkt-footer__link-icon"></pkt-icon>
3
3
  ${this.triggerText}
4
4
  </a>`:this.triggerType===`icon`?e.p`<pkt-button
@@ -6,6 +6,5 @@ const e=require(`./element-CXAtr6Gu.cjs`);require(`./icon-Dw6I0HDV.cjs`),require
6
6
  variant="icon-only"
7
7
  iconName="cookie"
8
8
  @click=${this.openModal}
9
- >
10
9
  >${this.triggerText}</pkt-button
11
- >`:e.p`<pkt-button @click=${this.openModal}>${this.triggerText}</pkt-button>`}};e.n([e.o({type:Boolean})],i.prototype,`devMode`,void 0),e.n([e.o({type:String})],i.prototype,`hotjarId`,void 0),e.n([e.o({type:String})],i.prototype,`googleAnalyticsId`,void 0),e.n([e.o({type:String})],i.prototype,`cookieDomain`,void 0),e.n([e.o({type:String})],i.prototype,`cookieSecure`,void 0),e.n([e.o({type:String})],i.prototype,`cookieExpiryDays`,void 0),e.n([e.o({type:String})],i.prototype,`triggerType`,void 0),e.n([e.o({type:String})],i.prototype,`triggerText`,void 0),e.n([e.o({type:String})],i.prototype,`i18nLanguage`,void 0);try{e.s(`pkt-consent`)(i)}catch{console.warn(`Forsøker å definere <pkt-consent>, men den er allerede definert`)}var a=i;Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return a}});
10
+ >`:e.p`<pkt-button @click=${this.openModal}>${this.triggerText}</pkt-button>`}};e.n([e.o({type:Boolean})],o.prototype,`devMode`,void 0),e.n([e.o({type:String})],o.prototype,`hotjarId`,void 0),e.n([e.o({type:String})],o.prototype,`googleAnalyticsId`,void 0),e.n([e.o({type:String})],o.prototype,`cookieDomain`,void 0),e.n([e.o({type:String})],o.prototype,`cookieSecure`,void 0),e.n([e.o({type:String})],o.prototype,`cookieExpiryDays`,void 0),e.n([e.o({type:String})],o.prototype,`triggerType`,void 0),e.n([e.o({type:String})],o.prototype,`triggerText`,void 0),e.n([e.o({type:String})],o.prototype,`i18nLanguage`,void 0);try{e.s(`pkt-consent`)(o)}catch{console.warn(`Forsøker å definere <pkt-consent>, men den er allerede definert`)}var s=o;Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return s}});
@@ -1,4 +1,10 @@
1
1
  import { PktElement } from '../../base-elements/element';
2
2
  export declare class Loader extends PktElement {
3
+ private demoLoading;
4
+ private demoTimer;
5
+ connectedCallback(): void;
6
+ disconnectedCallback(): void;
7
+ private startDemoTimer;
8
+ private resetDemo;
3
9
  render(): import('lit-html').TemplateResult<1>;
4
10
  }
@@ -1 +1 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require(`./consent-BB3g_ByO.cjs`);exports.PktConsent=e.n,exports.default=e.t;
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require(`./consent-DVt6sMvB.cjs`);exports.PktConsent=e.n,exports.default=e.t;
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./consent-Y14WZ0JS.js";
1
+ import { n as e, t } from "./consent-BFdURuBl.js";
2
2
  export { e as PktConsent, t as default };
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./alert-D_45dWPn.cjs`),t=require(`./icon-Dw6I0HDV.cjs`),n=require(`./button-Dwv11n6R.cjs`),r=require(`./accordion-DaeWPWod.cjs`),i=require(`./backlink-C42-3OG3.cjs`),a=require(`./breadcrumbs-CkjeLh3U.cjs`),o=require(`./calendar-Buvxe4l_.cjs`),s=require(`./card-C__IlsUa.cjs`),c=require(`./tag-CBFz0R9N.cjs`),l=require(`./heading-C40-NX0r.cjs`),u=require(`./combobox-x4tBGP3F.cjs`),d=require(`./header-CjBip0zj.cjs`),f=require(`./header-menu-CnW7nzmF.cjs`),p=require(`./datepicker-BFI-3stE.cjs`),m=require(`./fileupload-YtsrgQTY.cjs`),h=require(`./helptext-DNLg43eI.cjs`),g=require(`./input-wrapper-Dhkt20WW.cjs`),_=require(`./consent-BB3g_ByO.cjs`),v=require(`./checkbox-DzMc0AJX.cjs`),y=require(`./modal-CrYHKOmr.cjs`),b=require(`./progressbar-DADdvDl5.cjs`),x=require(`./link-B5ur0Rym.cjs`),S=require(`./textinput-C_6kvf87.cjs`),C=require(`./linkcard-BIcCW-qw.cjs`),w=require(`./loader-Uap9qDsV.cjs`),T=require(`./messagebox-BqBxXK8c.cjs`),E=require(`./radiobutton-BfURufrZ.cjs`),D=require(`./tabs-DxQy8U-0.cjs`),O=require(`./textarea-M_S9WK7s.cjs`),k=require(`./select-DzZHv6Bz.cjs`),A=require(`./searchinput-BrxfRzez.cjs`),j=require(`./timepicker-WiYLAncb.cjs`);exports.PktAccordion=r.r,exports.PktAccordionItem=r.n,exports.PktAlert=e.n,exports.PktBackLink=i.n,exports.PktBreadcrumbs=a.t,exports.PktButton=n.n,exports.PktCalendar=o.n,exports.PktCard=s.n,exports.PktCheckbox=v.n,exports.PktCombobox=u.n,exports.PktConsent=_.n,exports.PktDateTags=p.a,exports.PktDatepicker=p.t,Object.defineProperty(exports,`PktFileUpload`,{enumerable:!0,get:function(){return m.n}}),exports.PktHeader=d.t,exports.PktHeaderMenu=f.n,exports.PktHeaderService=d.n,exports.PktHeaderUserMenu=d.r,exports.PktHeading=l.n,exports.PktHelptext=h.n,exports.PktIcon=t.n,exports.PktInputWrapper=g.n,exports.PktLink=x.n,exports.PktLinkCard=C.n,exports.PktLoader=w.n,exports.PktMessagebox=T.n,exports.PktModal=y.n,exports.PktProgressbar=b.n,exports.PktRadioButton=E.n,exports.PktRadiobutton=E.n,exports.PktSearchInput=A.n,exports.PktSelect=k.n,exports.PktTabItem=D.n,exports.PktTabs=D.r,exports.PktTag=c.n,exports.PktTextarea=O.n,exports.PktTextinput=S.n,exports.PktTimepicker=j.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./alert-D_45dWPn.cjs`),t=require(`./icon-Dw6I0HDV.cjs`),n=require(`./button-Dwv11n6R.cjs`),r=require(`./accordion-DaeWPWod.cjs`),i=require(`./backlink-C42-3OG3.cjs`),a=require(`./breadcrumbs-CkjeLh3U.cjs`),o=require(`./calendar-Buvxe4l_.cjs`),s=require(`./card-C__IlsUa.cjs`),c=require(`./tag-CBFz0R9N.cjs`),l=require(`./heading-C40-NX0r.cjs`),u=require(`./combobox-x4tBGP3F.cjs`),d=require(`./header-CjBip0zj.cjs`),f=require(`./header-menu-CnW7nzmF.cjs`),p=require(`./datepicker-BFI-3stE.cjs`),m=require(`./fileupload-YtsrgQTY.cjs`),h=require(`./helptext-DNLg43eI.cjs`),g=require(`./input-wrapper-Dhkt20WW.cjs`),_=require(`./consent-DVt6sMvB.cjs`),v=require(`./checkbox-DzMc0AJX.cjs`),y=require(`./modal-CrYHKOmr.cjs`),b=require(`./progressbar-DADdvDl5.cjs`),x=require(`./link-B5ur0Rym.cjs`),S=require(`./textinput-C_6kvf87.cjs`),C=require(`./linkcard-BIcCW-qw.cjs`),w=require(`./loader-Uap9qDsV.cjs`),T=require(`./messagebox-BqBxXK8c.cjs`),E=require(`./radiobutton-BfURufrZ.cjs`),D=require(`./tabs-DxQy8U-0.cjs`),O=require(`./textarea-M_S9WK7s.cjs`),k=require(`./select-DzZHv6Bz.cjs`),A=require(`./searchinput-BrxfRzez.cjs`),j=require(`./timepicker-WiYLAncb.cjs`);exports.PktAccordion=r.r,exports.PktAccordionItem=r.n,exports.PktAlert=e.n,exports.PktBackLink=i.n,exports.PktBreadcrumbs=a.t,exports.PktButton=n.n,exports.PktCalendar=o.n,exports.PktCard=s.n,exports.PktCheckbox=v.n,exports.PktCombobox=u.n,exports.PktConsent=_.n,exports.PktDateTags=p.a,exports.PktDatepicker=p.t,Object.defineProperty(exports,`PktFileUpload`,{enumerable:!0,get:function(){return m.n}}),exports.PktHeader=d.t,exports.PktHeaderMenu=f.n,exports.PktHeaderService=d.n,exports.PktHeaderUserMenu=d.r,exports.PktHeading=l.n,exports.PktHelptext=h.n,exports.PktIcon=t.n,exports.PktInputWrapper=g.n,exports.PktLink=x.n,exports.PktLinkCard=C.n,exports.PktLoader=w.n,exports.PktMessagebox=T.n,exports.PktModal=y.n,exports.PktProgressbar=b.n,exports.PktRadioButton=E.n,exports.PktRadiobutton=E.n,exports.PktSearchInput=A.n,exports.PktSelect=k.n,exports.PktTabItem=D.n,exports.PktTabs=D.r,exports.PktTag=c.n,exports.PktTextarea=O.n,exports.PktTextinput=S.n,exports.PktTimepicker=j.t;
package/dist/pkt-index.js CHANGED
@@ -15,7 +15,7 @@ import { a as g, t as _ } from "./datepicker-CRk7aiwH.js";
15
15
  import { n as v } from "./fileupload-C8muj8qd.js";
16
16
  import { n as y } from "./helptext-C2aQBBo_.js";
17
17
  import { n as b } from "./input-wrapper-B6WowlWG.js";
18
- import { n as x } from "./consent-Y14WZ0JS.js";
18
+ import { n as x } from "./consent-BFdURuBl.js";
19
19
  import { n as S } from "./checkbox-CC1X7fw4.js";
20
20
  import { n as C } from "./modal-CWgeT-RP.js";
21
21
  import { n as w } from "./progressbar-B0P_vmGD.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslokommune/punkt-elements",
3
- "version": "16.19.0",
3
+ "version": "16.21.1",
4
4
  "description": "Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo",
5
5
  "homepage": "https://punkt.oslo.kommune.no",
6
6
  "author": "Team Designsystem, Oslo Origo",
@@ -78,5 +78,5 @@
78
78
  "url": "https://github.com/oslokommune/punkt/issues"
79
79
  },
80
80
  "license": "MIT",
81
- "gitHead": "e90194e9a4c25a6b7a5370c05889e262b4e6cfb0"
81
+ "gitHead": "15799459d01ea67c7770b8603da84069a717a164"
82
82
  }
@@ -258,7 +258,7 @@ describe('PktConsent', () => {
258
258
  // Fast-forward time to trigger setTimeout
259
259
  vi.runAllTimers()
260
260
 
261
- expect(window.cookieBanner.openCookieModal).toHaveBeenCalled()
261
+ expect(window.cookieBanner?.openCookieModal).toHaveBeenCalled()
262
262
  })
263
263
 
264
264
  test('handles click event on link trigger', async () => {
@@ -274,7 +274,7 @@ describe('PktConsent', () => {
274
274
  // Fast-forward time to trigger setTimeout
275
275
  vi.runAllTimers()
276
276
 
277
- expect(window.cookieBanner.openCookieModal).toHaveBeenCalled()
277
+ expect(window.cookieBanner?.openCookieModal).toHaveBeenCalled()
278
278
  })
279
279
 
280
280
  test('dispatches toggle-consent event', async () => {
@@ -5,6 +5,49 @@ import { consentStrings } from './strings'
5
5
  import '../button'
6
6
  import '../icon'
7
7
 
8
+ interface ConsentItem {
9
+ name: string
10
+ consent: boolean
11
+ }
12
+
13
+ interface ConsentValue {
14
+ items: ConsentItem[]
15
+ }
16
+
17
+ interface CookieConsentEvent {
18
+ value: string | ConsentValue
19
+ }
20
+
21
+ type ConsentDetailsMap = Record<string, boolean>
22
+
23
+ type CookieEventHandler = (consent: CookieConsentEvent) => void
24
+
25
+ interface CookieEvents {
26
+ on(eventName: string, handler: CookieEventHandler): void
27
+ off(eventName: string, handler: CookieEventHandler): void
28
+ }
29
+
30
+ interface CookieBannerApi {
31
+ cookieConsent: {
32
+ validateConsentCookie(): Promise<boolean>
33
+ getConsentCookie(): string | ConsentValue
34
+ }
35
+ openCookieModal(): void
36
+ }
37
+
38
+ declare global {
39
+ interface Window {
40
+ cookieBanner_devMode?: boolean
41
+ cookieBanner_cookieDomain?: string | null
42
+ cookieBanner_cookieSecure?: string | null
43
+ cookieBanner_cookieExpiryDays?: string | null
44
+ cookieBanner_googleAnalyticsId?: string | null
45
+ cookieBanner_hotjarId?: string | null
46
+ cookieBanner?: CookieBannerApi
47
+ __cookieEvents?: CookieEvents
48
+ }
49
+ }
50
+
8
51
  let consentScriptPromise: Promise<void> | null = null
9
52
 
10
53
  function loadConsentScript(): Promise<void> {
@@ -32,20 +75,26 @@ function loadConsentScript(): Promise<void> {
32
75
 
33
76
  return consentScriptPromise
34
77
  }
35
- // Extend the Window interface to include googleAnalyticsId
36
- declare global {
37
- interface Window {
38
- cookieBanner_devMode?: boolean
39
- cookieBanner_cookieDomain?: string | null
40
- cookieBanner_cookieSecure?: string | null
41
- cookieBanner_cookieExpiryDays?: string | null
42
- cookieBanner_googleAnalyticsId?: string | null
43
- cookieBanner_hotjarId?: string | null
44
- cookieBanner?: any
45
- __cookieEvents?: any
78
+
79
+ const parseJsonOrPassThrough = <T>(value: T | string): T => {
80
+ if (typeof value !== 'string') return value
81
+ try {
82
+ return JSON.parse(value) as T
83
+ } catch {
84
+ return value as unknown as T
46
85
  }
47
86
  }
48
87
 
88
+ const toConsentDetails = (consent: CookieConsentEvent): ConsentDetailsMap => {
89
+ const parsed = parseJsonOrPassThrough<ConsentValue>(consent.value)
90
+ return parsed.items.reduce<ConsentDetailsMap>((acc, item) => {
91
+ acc[item.name] = item.consent
92
+ return acc
93
+ }, {})
94
+ }
95
+
96
+ export type TPktConsentTriggerType = 'button' | 'link' | 'footerlink' | 'icon'
97
+
49
98
  export interface IPktConsent {
50
99
  devMode?: boolean
51
100
  cookieDomain?: string | null
@@ -54,12 +103,12 @@ export interface IPktConsent {
54
103
  hotjarId?: string | null
55
104
  googleAnalyticsId?: string | null
56
105
  i18nLanguage?: string
57
- triggerType?: 'button' | 'link' | 'footerlink' | 'icon' | null
106
+ triggerType?: TPktConsentTriggerType | null
58
107
  triggerText?: string | null
59
108
  }
60
109
 
61
110
  export class PktConsent extends PktElement<IPktConsent> implements IPktConsent {
62
- private _cookieEventHandler?: (consent: any) => void
111
+ private _cookieEventHandler?: CookieEventHandler
63
112
 
64
113
  @property({ type: Boolean }) devMode: boolean = false
65
114
 
@@ -69,51 +118,37 @@ export class PktConsent extends PktElement<IPktConsent> implements IPktConsent {
69
118
  @property({ type: String }) cookieSecure: string | null = null
70
119
  @property({ type: String }) cookieExpiryDays: string | null = null
71
120
 
72
- @property({ type: String }) triggerType: 'button' | 'link' | 'footerlink' | 'icon' | null =
73
- 'button'
121
+ @property({ type: String }) triggerType: TPktConsentTriggerType | null = 'button'
74
122
  @property({ type: String }) triggerText: string | null = null
75
123
  @property({ type: String }) i18nLanguage: string = 'nb'
76
124
 
77
- constructor() {
78
- super()
79
- }
80
-
81
- connectedCallback() {
125
+ connectedCallback(): void {
82
126
  super.connectedCallback()
127
+ const language = this.i18nLanguage as keyof typeof consentStrings.i18n
83
128
  this.triggerText =
84
- this.triggerText ||
85
- consentStrings.i18n[this.i18nLanguage as keyof typeof consentStrings.i18n].contentPresentation
86
- .buttons.settings
129
+ this.triggerText || consentStrings.i18n[language].contentPresentation.buttons.settings
87
130
  }
88
131
 
89
- disconnectedCallback() {
132
+ disconnectedCallback(): void {
90
133
  super.disconnectedCallback()
91
134
  if (this._cookieEventHandler) {
92
135
  window.__cookieEvents?.off('CookieManager.setCookie', this._cookieEventHandler)
93
136
  }
94
137
  }
95
138
 
96
- returnJsonOrObject(obj: any) {
97
- let returnObj
98
- try {
99
- returnObj = JSON.parse(obj)
100
- } catch (e) {
101
- returnObj = obj
102
- }
103
- return returnObj
139
+ /**
140
+ * Parses a JSON string when needed; returns the input unchanged when it's
141
+ * already a parsed object or when parsing fails.
142
+ * Exposed for backwards compatibility — tests still rely on it.
143
+ */
144
+ returnJsonOrObject<T>(obj: T | string): T {
145
+ return parseJsonOrPassThrough(obj)
104
146
  }
105
147
 
106
- emitCookieConsents(consent: any) {
107
- const consents = this.returnJsonOrObject(consent.value)
108
-
109
- const consentDetails = consents.items.reduce((acc: any, item: any) => {
110
- acc[item.name] = item.consent
111
- return acc
112
- }, {})
113
-
148
+ emitCookieConsents(consent: CookieConsentEvent): void {
114
149
  this.dispatchEvent(
115
- new CustomEvent('toggle-consent', {
116
- detail: consentDetails,
150
+ new CustomEvent<ConsentDetailsMap>('toggle-consent', {
151
+ detail: toConsentDetails(consent),
117
152
  bubbles: true,
118
153
  cancelable: false,
119
154
  }),
@@ -121,18 +156,21 @@ export class PktConsent extends PktElement<IPktConsent> implements IPktConsent {
121
156
  }
122
157
 
123
158
  protected async firstUpdated(_changedProperties: PropertyValues): Promise<void> {
159
+ // cookieBanner_* identifiers are defined by the external cookie banner script
160
+ /* eslint-disable camelcase */
124
161
  window.cookieBanner_googleAnalyticsId = this.googleAnalyticsId
125
162
  window.cookieBanner_hotjarId = this.hotjarId
126
163
  if (this.cookieDomain) window.cookieBanner_cookieDomain = this.cookieDomain
127
164
  if (this.cookieSecure) window.cookieBanner_cookieSecure = this.cookieSecure
128
165
  if (this.cookieExpiryDays) window.cookieBanner_cookieExpiryDays = this.cookieExpiryDays
129
166
  if (this.devMode) window.cookieBanner_devMode = this.devMode
167
+ /* eslint-enable camelcase */
130
168
 
131
169
  await loadConsentScript()
132
170
  this.triggerInit()
133
171
  }
134
172
 
135
- triggerInit() {
173
+ triggerInit(): void {
136
174
  window.document.dispatchEvent(
137
175
  new Event('CookieBannerReady', {
138
176
  bubbles: true,
@@ -140,29 +178,30 @@ export class PktConsent extends PktElement<IPktConsent> implements IPktConsent {
140
178
  }),
141
179
  )
142
180
 
143
- window.cookieBanner.cookieConsent.validateConsentCookie().then((response: boolean) => {
144
- if (response) {
145
- const cookie = window.cookieBanner.cookieConsent.getConsentCookie()
146
- const consents = { value: cookie }
147
- window.setTimeout(() => this.emitCookieConsents(consents), 0)
148
-
149
- if (this._cookieEventHandler) {
150
- window.__cookieEvents.off('CookieManager.setCookie', this._cookieEventHandler)
151
- }
152
- this._cookieEventHandler = (consent: any) => {
153
- this.emitCookieConsents(consent)
154
- }
155
- window.__cookieEvents.on('CookieManager.setCookie', this._cookieEventHandler)
181
+ const banner = window.cookieBanner
182
+ const events = window.__cookieEvents
183
+ if (!banner || !events) return
184
+
185
+ banner.cookieConsent.validateConsentCookie().then((hasConsent) => {
186
+ if (!hasConsent) return
187
+
188
+ const cookie = banner.cookieConsent.getConsentCookie()
189
+ window.setTimeout(() => this.emitCookieConsents({ value: cookie }), 0)
190
+
191
+ if (this._cookieEventHandler) {
192
+ events.off('CookieManager.setCookie', this._cookieEventHandler)
156
193
  }
194
+ this._cookieEventHandler = (consent) => this.emitCookieConsents(consent)
195
+ events.on('CookieManager.setCookie', this._cookieEventHandler)
157
196
  })
158
197
  }
159
198
 
160
- openModal(e: Event) {
199
+ openModal(e: Event): void {
161
200
  e.preventDefault()
162
201
  if (!window.cookieBanner?.cookieConsent) {
163
202
  this.triggerInit()
164
203
  }
165
- setTimeout(() => window.cookieBanner.openCookieModal())
204
+ setTimeout(() => window.cookieBanner?.openCookieModal())
166
205
  }
167
206
 
168
207
  render() {
@@ -181,7 +220,6 @@ export class PktConsent extends PktElement<IPktConsent> implements IPktConsent {
181
220
  variant="icon-only"
182
221
  iconName="cookie"
183
222
  @click=${this.openModal}
184
- >
185
223
  >${this.triggerText}</pkt-button
186
224
  >`
187
225
  }