@oslokommune/punkt-elements
Version:
Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo
126 lines • 9.29 kB
JavaScript
const e=require(`./element-DjtxO-1r.cjs`),t=require(`./class-map-CJ-msbHs.cjs`);require(`./icon-Dr8sfT2X.cjs`),require(`./accordion-DDZkjXFb.cjs`);const n=require(`./booleanish-B5EFqFpJ.cjs`);var r=`https://cdn.web.oslo.kommune.no/header-footer/header-footer.json`,i={automat:`parking-meter`,bike:`bicycle`,corona:`virus`,directions:`arrow-directions`,document:`document-plain`,"download-document":`document-download`,elcar:`electric-car`,"error-hexa":`alert-error`,"fire-emblem":`shield-fire`,"link-arrow":`arrow-link`,"linked-in":`linkedin`,"map-layer":`map-layers`,mobile:`mobile-phone`,neutral:`smiley-neutral`,placeholder:`placeholder-icon`,sad:`smiley-sad`,signing:`signature`,sky:`cloud`,smile:`smiley-smile`,"success-square":`alert-success`,trash:`trash-can`,treatment:`processing`,"warning-triangle":`alert-warning`};function a(e){return e&&(i[e]??e)}var o={"facebook.com":`facebook`,"fb.com":`facebook`,"instagram.com":`instagram`,"linkedin.com":`linkedin`,"x.com":`x`,"github.com":`github`};function s(e){return e.toLowerCase().replace(/^(?:www|m)\./,``)}function c(e,t){if(e)try{let t=o[s(new URL(e).hostname)];if(t)return t}catch{}if(t){let e=t.trim().toLowerCase().replace(/\s+/g,`-`);if(e){let t=a(e);if(t)return t}}}var l=`nb-NO`;function u(e,t=l){if(e)return e[t]??e[l]}async function d(e=r,t){let n=await fetch(e,{signal:t});if(!n.ok)throw Error(`pkt-header-menu: failed to fetch ${e} (HTTP ${n.status})`);let i=await n.json();if(!i||typeof i!=`object`)throw Error(`pkt-header-menu: ${e} returned a non-object payload`);return i}var f=class extends e.t{constructor(...e){super(...e),this.dataUrl=r,this.locale=`nb-NO`,this.open=!1,this.ariaLabelledBy=``,this.mobileBreakpoint=768,this.loadState=`idle`,this.isMobile=!1,this.handleMediaChange=e=>{this.isMobile=e.matches}}connectedCallback(){super.connectedCallback(),this.classList.add(`pkt-header-menu`),this.updateOpenClass(),this.setupMediaQuery(),this.data?(this.loadState=`ready`,this.dispatchEvent(new CustomEvent(`data-loaded`,{detail:{data:this.data},bubbles:!0,composed:!0}))):this.loadData()}updateOpenClass(){this.classList.toggle(`pkt-header-menu--open`,!!this.open)}disconnectedCallback(){super.disconnectedCallback(),this.abortController?.abort(),this.teardownMediaQuery()}updated(e){super.updated(e),e.has(`open`)&&this.updateOpenClass(),e.has(`mobileBreakpoint`)&&e.get(`mobileBreakpoint`)!==void 0&&this.setupMediaQuery(),e.has(`dataUrl`)&&e.get(`dataUrl`)!==void 0&&!this.data&&this.loadData(),e.has(`data`)&&e.get(`data`)!==void 0&&this.data&&(this.loadState=`ready`,this.dispatchEvent(new CustomEvent(`data-loaded`,{detail:{data:this.data},bubbles:!0,composed:!0})))}setupMediaQuery(){this.teardownMediaQuery(),!(typeof window>`u`||typeof window.matchMedia!=`function`)&&(this.mediaQuery=window.matchMedia(`(max-width: ${this.mobileBreakpoint-1}px)`),this.isMobile=this.mediaQuery.matches,this.mediaQuery.addEventListener(`change`,this.handleMediaChange))}teardownMediaQuery(){this.mediaQuery?.removeEventListener(`change`,this.handleMediaChange),this.mediaQuery=void 0}async loadData(){this.abortController?.abort(),this.abortController=new AbortController,this.loadState=`loading`;try{let e=await d(this.dataUrl,this.abortController.signal);this.fetchedData=e,this.loadState=`ready`,this.dispatchEvent(new CustomEvent(`data-loaded`,{detail:{data:e},bubbles:!0,composed:!0}))}catch(e){if(e.name===`AbortError`)return;this.loadState=`error`,this.dispatchEvent(new CustomEvent(`data-error`,{detail:{error:e},bubbles:!0,composed:!0}))}}get effectiveData(){return this.data??this.fetchedData}get localeData(){return u(this.effectiveData,this.locale)}render(){if(this.loadState===`loading`)return e.d`
<nav aria-busy="true">
<p class="pkt-header-menu__loading">Laster meny…</p>
</nav>
`;if(this.loadState===`error`||!this.localeData)return e.d`
<nav aria-hidden=${!this.open}>
<p class="pkt-header-menu__error">Kunne ikke laste meny.</p>
</nav>
`;let{megamenu:t,i18n:n}=this.localeData,r=n?.navAriaLabel||`Hovedmeny`;return this.isMobile?e.d`
<nav aria-label=${r}>
${this.renderMobileAccordion(t.services,t.sections)}
${this.renderButtons(t.buttons,!0)}
${this.renderFooter(t.links,t.some)}
</nav>
`:e.d`
<nav aria-label=${r}>
${this.renderServices(t.services)} ${this.renderButtons(t.buttons,!1)}
${this.renderSections(t.sections)}
${this.renderFooter(t.links,t.some)}
</nav>
`}renderMobileAccordion(t,n){return e.d`
<div class="pkt-header-menu__sections">
<pkt-accordion
class="pkt-header-menu__sections-inner"
skin="plus-minus"
name="header-menu-accordion"
>
<pkt-accordion-item
class="pkt-header-menu__section"
skin="plus-minus"
id="pkt-header-menu-services"
title=${t.title}
>
${this.renderServicesList(t)}
</pkt-accordion-item>
${n.map((t,n)=>e.d`
<pkt-accordion-item
class="pkt-header-menu__section"
skin="plus-minus"
id=${`pkt-header-menu-section-${n}`}
title=${t.title}
>
${this.renderSectionList(t.links)}
</pkt-accordion-item>
`)}
</pkt-accordion>
</div>
`}renderServicesList(t){return e.d`
<ul class="pkt-header-menu__services-list">
${t.links.map(t=>e.d`
<li class="pkt-header-menu__service">
<a class="pkt-header-menu__service-link" href=${t.url}>
<pkt-icon
class="pkt-header-menu__service-icon"
name=${a(t.icon)}
aria-hidden="true"
></pkt-icon>
<span class="pkt-header-menu__service-text">${t.text}</span>
</a>
</li>
`)}
</ul>
`}renderServices(t){return e.d`
<div class="pkt-header-menu__services">
<h2 class="pkt-header-menu__services-title">${t.title}</h2>
${this.renderServicesList(t)}
</div>
`}renderButtons(n,r){return!n||n.length===0?e.l:e.d`
<div class=${t.t({"pkt-header-menu__buttons":!0,"pkt-header-menu__buttons--mobile":r})}>
${n.map(t=>e.d`
<a
class="pkt-btn pkt-btn--secondary pkt-btn--icon-right pkt-btn--small"
href=${t.url}
>
<pkt-icon
class="pkt-btn__icon"
name=${t.iconName?a(t.iconName):`user`}
aria-hidden="true"
></pkt-icon>
<span class="pkt-btn__text">${t.text}</span>
</a>
`)}
</div>
`}renderSections(t){return!t||t.length===0?e.l:e.d`
<div class="pkt-header-menu__sections">
<div class="pkt-header-menu__sections-inner">
${t.map(t=>e.d`
<div class="pkt-header-menu__section">
<h2 class="pkt-header-menu__section-title">${t.title}</h2>
${this.renderSectionList(t.links)}
</div>
`)}
</div>
</div>
`}renderSectionList(t){return e.d`
<ul class="pkt-header-menu__section-list">
${t.map(t=>e.d`
<li>
<a class="pkt-header-menu__section-link" href=${t.url}>${t.text}</a>
</li>
`)}
</ul>
`}renderFooter(t,n){return(!t||t.length===0)&&(!n||n.length===0)?e.l:e.d`
<div class="pkt-header-menu__footer">
${t&&t.length>0?e.d`
<ul class="pkt-header-menu__footer-list">
${t.map(t=>e.d`
<li>
<a class="pkt-header-menu__footer-link" href=${t.url}>${t.text}</a>
</li>
`)}
</ul>
`:e.l}
${n&&n.length>0?e.d`
<ul class="pkt-header-menu__footer-list pkt-header-menu__footer-list--social">
${n.map(e=>this.renderSocialLink(e))}
</ul>
`:e.l}
</div>
`}renderSocialLink(t){let n=c(t.url,t.text);return e.d`
<li>
<a class="pkt-header-menu__social-link" href=${t.url} aria-label=${t.text}>
${n?e.d`<pkt-icon name=${n} aria-hidden="true"></pkt-icon>`:e.d`<span>${t.text}</span>`}
</a>
</li>
`}};e.r([e.s({type:String,attribute:`data-url`})],f.prototype,`dataUrl`,void 0),e.r([e.s({type:Object,attribute:!1})],f.prototype,`data`,void 0),e.r([e.s({type:String})],f.prototype,`locale`,void 0),e.r([e.s({type:Boolean,reflect:!0,converter:n.t})],f.prototype,`open`,void 0),e.r([e.s({type:String,attribute:`aria-labelledby`,reflect:!0})],f.prototype,`ariaLabelledBy`,void 0),e.r([e.s({type:Number,attribute:`mobile-breakpoint`})],f.prototype,`mobileBreakpoint`,void 0),e.r([e.o()],f.prototype,`loadState`,void 0),e.r([e.o()],f.prototype,`fetchedData`,void 0),e.r([e.o()],f.prototype,`isMobile`,void 0);try{e.c(`pkt-header-menu`)(f)}catch{console.warn(`Forsøker å definere <pkt-header-menu>, men den er allerede definert`)}var p=f;Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return p}});