@oslokommune/punkt-elements
Version:
Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo
320 lines (319 loc) • 10.4 kB
JavaScript
import { c as e, d as t, l as n, o as r, r as i, s as a, t as o } from "./element-cZ85T_aa.js";
import { t as s } from "./class-map-C8HuhNzZ.js";
import "./icon-Co72KtgF.js";
import "./accordion-CU2tJ5vn.js";
import { t as c } from "./booleanish-CRaKZ75t.js";
//#region ../../shared-types/header-menu.ts
var l = "https://cdn.web.oslo.kommune.no/header-footer/header-footer.json", u = {
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 d(e) {
return e && (u[e] ?? e);
}
var f = {
"facebook.com": "facebook",
"fb.com": "facebook",
"instagram.com": "instagram",
"linkedin.com": "linkedin",
"x.com": "x",
"github.com": "github"
};
function p(e) {
return e.toLowerCase().replace(/^(?:www|m)\./, "");
}
function m(e, t) {
if (e) try {
let t = f[p(new URL(e).hostname)];
if (t) return t;
} catch {}
if (t) {
let e = t.trim().toLowerCase().replace(/\s+/g, "-");
if (e) {
let t = d(e);
if (t) return t;
}
}
}
//#endregion
//#region ../../shared-utils/header-menu/select-megamenu.ts
var h = "nb-NO";
function g(e, t = h) {
if (e) return e[t] ?? e[h];
}
//#endregion
//#region ../../shared-utils/header-menu/fetch-header-footer-data.ts
async function _(e = l, t) {
let n = await fetch(e, { signal: t });
if (!n.ok) throw Error(`pkt-header-menu: failed to fetch ${e} (HTTP ${n.status})`);
let r = await n.json();
if (!r || typeof r != "object") throw Error(`pkt-header-menu: ${e} returned a non-object payload`);
return r;
}
//#endregion
//#region src/components/header-menu/header-menu.ts
var v = class extends o {
constructor(...e) {
super(...e), this.dataUrl = l, 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 _(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 g(this.effectiveData, this.locale);
}
render() {
if (this.loadState === "loading") return t`
<nav aria-busy="true">
<p class="pkt-header-menu__loading">Laster meny…</p>
</nav>
`;
if (this.loadState === "error" || !this.localeData) return t`
<nav aria-hidden=${!this.open}>
<p class="pkt-header-menu__error">Kunne ikke laste meny.</p>
</nav>
`;
let { megamenu: e, i18n: n } = this.localeData, r = n?.navAriaLabel || "Hovedmeny";
return this.isMobile ? t`
<nav aria-label=${r}>
${this.renderMobileAccordion(e.services, e.sections)}
${this.renderButtons(e.buttons, !0)}
${this.renderFooter(e.links, e.some)}
</nav>
` : t`
<nav aria-label=${r}>
${this.renderServices(e.services)} ${this.renderButtons(e.buttons, !1)}
${this.renderSections(e.sections)}
${this.renderFooter(e.links, e.some)}
</nav>
`;
}
renderMobileAccordion(e, n) {
return t`
<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=${e.title}
>
${this.renderServicesList(e)}
</pkt-accordion-item>
${n.map((e, n) => t`
<pkt-accordion-item
class="pkt-header-menu__section"
skin="plus-minus"
id=${`pkt-header-menu-section-${n}`}
title=${e.title}
>
${this.renderSectionList(e.links)}
</pkt-accordion-item>
`)}
</pkt-accordion>
</div>
`;
}
renderServicesList(e) {
return t`
<ul class="pkt-header-menu__services-list">
${e.links.map((e) => t`
<li class="pkt-header-menu__service">
<a class="pkt-header-menu__service-link" href=${e.url}>
<pkt-icon
class="pkt-header-menu__service-icon"
name=${d(e.icon)}
aria-hidden="true"
></pkt-icon>
<span class="pkt-header-menu__service-text">${e.text}</span>
</a>
</li>
`)}
</ul>
`;
}
renderServices(e) {
return t`
<div class="pkt-header-menu__services">
<h2 class="pkt-header-menu__services-title">${e.title}</h2>
${this.renderServicesList(e)}
</div>
`;
}
renderButtons(e, r) {
return !e || e.length === 0 ? n : t`
<div class=${s({
"pkt-header-menu__buttons": !0,
"pkt-header-menu__buttons--mobile": r
})}>
${e.map((e) => t`
<a
class="pkt-btn pkt-btn--secondary pkt-btn--icon-right pkt-btn--small"
href=${e.url}
>
<pkt-icon
class="pkt-btn__icon"
name=${e.iconName ? d(e.iconName) : "user"}
aria-hidden="true"
></pkt-icon>
<span class="pkt-btn__text">${e.text}</span>
</a>
`)}
</div>
`;
}
renderSections(e) {
return !e || e.length === 0 ? n : t`
<div class="pkt-header-menu__sections">
<div class="pkt-header-menu__sections-inner">
${e.map((e) => t`
<div class="pkt-header-menu__section">
<h2 class="pkt-header-menu__section-title">${e.title}</h2>
${this.renderSectionList(e.links)}
</div>
`)}
</div>
</div>
`;
}
renderSectionList(e) {
return t`
<ul class="pkt-header-menu__section-list">
${e.map((e) => t`
<li>
<a class="pkt-header-menu__section-link" href=${e.url}>${e.text}</a>
</li>
`)}
</ul>
`;
}
renderFooter(e, r) {
return (!e || e.length === 0) && (!r || r.length === 0) ? n : t`
<div class="pkt-header-menu__footer">
${e && e.length > 0 ? t`
<ul class="pkt-header-menu__footer-list">
${e.map((e) => t`
<li>
<a class="pkt-header-menu__footer-link" href=${e.url}>${e.text}</a>
</li>
`)}
</ul>
` : n}
${r && r.length > 0 ? t`
<ul class="pkt-header-menu__footer-list pkt-header-menu__footer-list--social">
${r.map((e) => this.renderSocialLink(e))}
</ul>
` : n}
</div>
`;
}
renderSocialLink(e) {
let n = m(e.url, e.text);
return t`
<li>
<a class="pkt-header-menu__social-link" href=${e.url} aria-label=${e.text}>
${n ? t`<pkt-icon name=${n} aria-hidden="true"></pkt-icon>` : t`<span>${e.text}</span>`}
</a>
</li>
`;
}
};
i([a({
type: String,
attribute: "data-url"
})], v.prototype, "dataUrl", void 0), i([a({
type: Object,
attribute: !1
})], v.prototype, "data", void 0), i([a({ type: String })], v.prototype, "locale", void 0), i([a({
type: Boolean,
reflect: !0,
converter: c
})], v.prototype, "open", void 0), i([a({
type: String,
attribute: "aria-labelledby",
reflect: !0
})], v.prototype, "ariaLabelledBy", void 0), i([a({
type: Number,
attribute: "mobile-breakpoint"
})], v.prototype, "mobileBreakpoint", void 0), i([r()], v.prototype, "loadState", void 0), i([r()], v.prototype, "fetchedData", void 0), i([r()], v.prototype, "isMobile", void 0);
try {
e("pkt-header-menu")(v);
} catch {
console.warn("Forsøker å definere <pkt-header-menu>, men den er allerede definert");
}
//#endregion
//#region src/components/header-menu/index.ts
var y = v;
//#endregion
export { v as n, y as t };