@sevenfold/setto-client 0.35.0 → 0.36.0
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/dist/blog/SettoBlog.d.ts +20 -0
- package/dist/blog/data.d.ts +36 -0
- package/dist/blog/render.d.ts +16 -0
- package/dist/blog/strings.d.ts +25 -0
- package/dist/index.d.ts +4 -1
- package/dist/pages/manifest.d.ts +18 -1
- package/dist/setto-client.js +735 -198
- package/dist/setto-client.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/vite/index.d.ts +6 -0
- package/dist/vite/plugin.d.ts +32 -0
- package/dist/vite/static.d.ts +78 -0
- package/dist/vite.js +550 -0
- package/dist/vite.js.map +1 -0
- package/package.json +10 -2
- package/virtual.d.ts +11 -0
package/dist/setto-client.js
CHANGED
|
@@ -21461,8 +21461,9 @@ class ThemeStore {
|
|
|
21461
21461
|
}
|
|
21462
21462
|
const PAGES_MANIFEST_VERSION = 1;
|
|
21463
21463
|
const PAGES_PATH = "src/content/pages.json";
|
|
21464
|
-
const BUILTIN_SECTION_TYPES = ["text"];
|
|
21464
|
+
const BUILTIN_SECTION_TYPES = ["text", "blog", "blog-latest"];
|
|
21465
21465
|
const ID = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
21466
|
+
const POST_SLUG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
21466
21467
|
const PATH = /^\/(?:[a-z0-9][a-z0-9-]*(?:\/[a-z0-9][a-z0-9-]*)*)?$/;
|
|
21467
21468
|
function isRecord$1(value) {
|
|
21468
21469
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -21529,6 +21530,15 @@ function parseManifest(input) {
|
|
|
21529
21530
|
sections
|
|
21530
21531
|
});
|
|
21531
21532
|
});
|
|
21533
|
+
const blogs = pages.flatMap(
|
|
21534
|
+
(p, i) => p.sections.flatMap((s, j) => s.type === "blog" ? [{ page: p, at: `pages[${i}].sections[${j}]` }] : [])
|
|
21535
|
+
);
|
|
21536
|
+
if (blogs.length > 1) {
|
|
21537
|
+
issues.push({ at: blogs[1].at, message: "a site has one blog; another blog section is already on a page" });
|
|
21538
|
+
}
|
|
21539
|
+
for (const blog of blogs) {
|
|
21540
|
+
if (blog.page.path === "/") issues.push({ at: blog.at, message: "the blog cannot be the front page" });
|
|
21541
|
+
}
|
|
21532
21542
|
const menu = parseMenu(input.menu, "menu", issues);
|
|
21533
21543
|
const footer2 = parseMenu(input.footer, "footer", issues);
|
|
21534
21544
|
if (issues.length > 0) return { ok: false, issues };
|
|
@@ -21572,7 +21582,23 @@ function normalisePath(path2) {
|
|
|
21572
21582
|
}
|
|
21573
21583
|
function pageForPath(manifest, path2) {
|
|
21574
21584
|
const wanted = normalisePath(path2);
|
|
21575
|
-
return manifest.pages.find((p) => p.path === wanted) ?? null;
|
|
21585
|
+
return manifest.pages.find((p) => p.path === wanted) ?? (blogSlugForPath(manifest, path2) ? blogPage(manifest).page : null);
|
|
21586
|
+
}
|
|
21587
|
+
function blogPage(manifest) {
|
|
21588
|
+
for (const page of manifest.pages) {
|
|
21589
|
+
const section = page.sections.find((s) => s.type === "blog");
|
|
21590
|
+
if (section) return { page, section };
|
|
21591
|
+
}
|
|
21592
|
+
return null;
|
|
21593
|
+
}
|
|
21594
|
+
function blogSlugForPath(manifest, path2) {
|
|
21595
|
+
const blog = blogPage(manifest);
|
|
21596
|
+
if (!blog || blog.page.path === "/") return null;
|
|
21597
|
+
const wanted = normalisePath(path2);
|
|
21598
|
+
const prefix = `${blog.page.path}/`;
|
|
21599
|
+
if (!wanted.startsWith(prefix)) return null;
|
|
21600
|
+
const slug = wanted.slice(prefix.length);
|
|
21601
|
+
return slug.length <= 80 && POST_SLUG.test(slug) ? slug : null;
|
|
21576
21602
|
}
|
|
21577
21603
|
function pageById(manifest, id) {
|
|
21578
21604
|
return manifest.pages.find((p) => p.id === id) ?? null;
|
|
@@ -22124,7 +22150,7 @@ function withoutCheckoutIntent() {
|
|
|
22124
22150
|
}
|
|
22125
22151
|
const FAB_SIZE = 52;
|
|
22126
22152
|
const FAB_INSET = 16;
|
|
22127
|
-
const STYLE_ID$
|
|
22153
|
+
const STYLE_ID$3 = "setto-edit-layout";
|
|
22128
22154
|
const HTML_CLASS = "setto-edit-mode";
|
|
22129
22155
|
function useSettoDocumentLayout(active) {
|
|
22130
22156
|
useEffect(() => {
|
|
@@ -22133,10 +22159,10 @@ function useSettoDocumentLayout(active) {
|
|
|
22133
22159
|
html2.classList.add(HTML_CLASS);
|
|
22134
22160
|
html2.style.setProperty("--setto-fab-size", `${FAB_SIZE}px`);
|
|
22135
22161
|
html2.style.setProperty("--setto-fab-inset", `${FAB_INSET}px`);
|
|
22136
|
-
let styleEl = document.getElementById(STYLE_ID$
|
|
22162
|
+
let styleEl = document.getElementById(STYLE_ID$3);
|
|
22137
22163
|
if (!styleEl) {
|
|
22138
22164
|
styleEl = document.createElement("style");
|
|
22139
|
-
styleEl.id = STYLE_ID$
|
|
22165
|
+
styleEl.id = STYLE_ID$3;
|
|
22140
22166
|
styleEl.textContent = `
|
|
22141
22167
|
html.setto-edit-mode {
|
|
22142
22168
|
width: 100%;
|
|
@@ -33040,7 +33066,7 @@ function formatHeadingAsSetext(node2, state) {
|
|
|
33040
33066
|
);
|
|
33041
33067
|
}
|
|
33042
33068
|
function heading(node2, _, state, info) {
|
|
33043
|
-
const
|
|
33069
|
+
const rank2 = Math.max(Math.min(6, node2.depth || 1), 1);
|
|
33044
33070
|
const tracker = state.createTracker(info);
|
|
33045
33071
|
if (formatHeadingAsSetext(node2, state)) {
|
|
33046
33072
|
const exit3 = state.enter("headingSetext");
|
|
@@ -33052,14 +33078,14 @@ function heading(node2, _, state, info) {
|
|
|
33052
33078
|
});
|
|
33053
33079
|
subexit2();
|
|
33054
33080
|
exit3();
|
|
33055
|
-
return value2 + "\n" + (
|
|
33081
|
+
return value2 + "\n" + (rank2 === 1 ? "=" : "-").repeat(
|
|
33056
33082
|
// The whole size…
|
|
33057
33083
|
value2.length - // Minus the position of the character after the last EOL (or
|
|
33058
33084
|
// 0 if there is none)…
|
|
33059
33085
|
(Math.max(value2.lastIndexOf("\r"), value2.lastIndexOf("\n")) + 1)
|
|
33060
33086
|
);
|
|
33061
33087
|
}
|
|
33062
|
-
const sequence = "#".repeat(
|
|
33088
|
+
const sequence = "#".repeat(rank2);
|
|
33063
33089
|
const exit2 = state.enter("headingAtx");
|
|
33064
33090
|
const subexit = state.enter("phrasing");
|
|
33065
33091
|
tracker.move(sequence + " ");
|
|
@@ -38003,12 +38029,12 @@ function SettoImage({ srcKey, alt, className, style, ...rest }) {
|
|
|
38003
38029
|
)
|
|
38004
38030
|
] });
|
|
38005
38031
|
}
|
|
38006
|
-
const STYLE_ID$
|
|
38032
|
+
const STYLE_ID$2 = "setto-repeater-styles";
|
|
38007
38033
|
function useRepeaterStyles() {
|
|
38008
38034
|
useEffect(() => {
|
|
38009
|
-
if (document.getElementById(STYLE_ID$
|
|
38035
|
+
if (document.getElementById(STYLE_ID$2)) return;
|
|
38010
38036
|
const el = document.createElement("style");
|
|
38011
|
-
el.id = STYLE_ID$
|
|
38037
|
+
el.id = STYLE_ID$2;
|
|
38012
38038
|
el.textContent = `
|
|
38013
38039
|
.setto-repeater-remove {
|
|
38014
38040
|
opacity: 0;
|
|
@@ -38134,6 +38160,695 @@ const removeBtnStyle = {
|
|
|
38134
38160
|
boxShadow: "0 1px 4px rgba(0,0,0,0.18)",
|
|
38135
38161
|
fontFamily: 'system-ui, -apple-system, "Segoe UI", sans-serif'
|
|
38136
38162
|
};
|
|
38163
|
+
function usePageManifest() {
|
|
38164
|
+
const { pageStore, config } = useSetto();
|
|
38165
|
+
const snap = useSyncExternalStore(
|
|
38166
|
+
(cb) => pageStore?.subscribe(() => cb()) ?? (() => {
|
|
38167
|
+
}),
|
|
38168
|
+
() => pageStore?.snapshot() ?? EMPTY_PAGE_STORE_SNAPSHOT,
|
|
38169
|
+
() => pageStore?.snapshot() ?? EMPTY_PAGE_STORE_SNAPSHOT
|
|
38170
|
+
);
|
|
38171
|
+
return pageStore ? snap.manifest : bundledManifest(config.pages);
|
|
38172
|
+
}
|
|
38173
|
+
function useSettoMenu(list2 = "menu") {
|
|
38174
|
+
const manifest = usePageManifest();
|
|
38175
|
+
return manifest ? visibleMenu(manifest, list2) : null;
|
|
38176
|
+
}
|
|
38177
|
+
function SettoPage({ pageId, path: path2, sections = {}, builtins, fallback = null }) {
|
|
38178
|
+
const manifest = usePageManifest();
|
|
38179
|
+
const { editMode } = useSetto();
|
|
38180
|
+
if (!manifest) {
|
|
38181
|
+
if (!pageId && path2 !== void 0 && path2 !== "/" && path2 !== "") return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
38182
|
+
return /* @__PURE__ */ jsx(Fragment, { children: Object.entries(sections).map(([id, Component]) => /* @__PURE__ */ jsx(Component, {}, id)) });
|
|
38183
|
+
}
|
|
38184
|
+
const page = pageId ? pageById(manifest, pageId) : pageForPath(manifest, path2 ?? "/");
|
|
38185
|
+
if (!page) {
|
|
38186
|
+
if (pageId) {
|
|
38187
|
+
return /* @__PURE__ */ jsx(Fragment, { children: Object.entries(sections).map(([id, Component]) => /* @__PURE__ */ jsx(Component, {}, id)) });
|
|
38188
|
+
}
|
|
38189
|
+
return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
38190
|
+
}
|
|
38191
|
+
if (page.hidden && !editMode) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
38192
|
+
return /* @__PURE__ */ jsx(PageBody, { page, sections, builtins, editMode, manifest });
|
|
38193
|
+
}
|
|
38194
|
+
function PageBody({
|
|
38195
|
+
page,
|
|
38196
|
+
sections,
|
|
38197
|
+
builtins,
|
|
38198
|
+
editMode,
|
|
38199
|
+
manifest
|
|
38200
|
+
}) {
|
|
38201
|
+
usePageTitle(page);
|
|
38202
|
+
const HiddenPageNote = useSettoChromeSlot("hidden-page");
|
|
38203
|
+
const listed = new Set(manifest.pages.flatMap((p) => p.sections.map((s) => s.id)));
|
|
38204
|
+
const unlisted = Object.keys(sections).filter((id) => !listed.has(id));
|
|
38205
|
+
const firstVisible = page.sections.find((s) => !s.hidden && (s.type || sections[s.id]))?.id;
|
|
38206
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
38207
|
+
page.hidden && editMode ? HiddenPageNote ? /* @__PURE__ */ jsx(HiddenPageNote, { pageId: page.id }) : /* @__PURE__ */ jsx(HiddenNote, { text: "Denne siden er skjult for besøkende." }) : null,
|
|
38208
|
+
page.sections.map((section) => /* @__PURE__ */ jsx(Fragment$1, { children: renderSection(section, sections, builtins, editMode, section.id === firstVisible) }, section.id)),
|
|
38209
|
+
unlisted.map((id) => {
|
|
38210
|
+
const Component = sections[id];
|
|
38211
|
+
return /* @__PURE__ */ jsx(Component, {}, id);
|
|
38212
|
+
})
|
|
38213
|
+
] });
|
|
38214
|
+
}
|
|
38215
|
+
function renderSection(section, sections, builtins, editMode, first) {
|
|
38216
|
+
if (section.hidden) {
|
|
38217
|
+
return editMode ? /* @__PURE__ */ jsx(HiddenSection, { section }) : null;
|
|
38218
|
+
}
|
|
38219
|
+
if (section.type) {
|
|
38220
|
+
const Builtin = builtins?.[section.type] ?? BUILTIN_RENDERERS[section.type];
|
|
38221
|
+
return /* @__PURE__ */ jsx(Builtin, { sectionId: section.id, first });
|
|
38222
|
+
}
|
|
38223
|
+
const Component = sections[section.id];
|
|
38224
|
+
if (!Component) {
|
|
38225
|
+
warnOnce(section.id);
|
|
38226
|
+
return null;
|
|
38227
|
+
}
|
|
38228
|
+
return /* @__PURE__ */ jsx(Component, {});
|
|
38229
|
+
}
|
|
38230
|
+
const warned = /* @__PURE__ */ new Set();
|
|
38231
|
+
function warnOnce(id) {
|
|
38232
|
+
if (warned.has(id)) return;
|
|
38233
|
+
warned.add(id);
|
|
38234
|
+
console.warn(`[setto] section "${id}" is in pages.json but the page does not provide it`);
|
|
38235
|
+
}
|
|
38236
|
+
function HiddenSection({ section }) {
|
|
38237
|
+
const { pageStore } = useSetto();
|
|
38238
|
+
const Offered = useSettoChromeSlot("hidden-section");
|
|
38239
|
+
const label = section.label ?? section.id;
|
|
38240
|
+
if (Offered) return /* @__PURE__ */ jsx(Offered, { sectionId: section.id, label });
|
|
38241
|
+
return /* @__PURE__ */ jsxs("div", { "data-setto-ui": true, style: hiddenBarStyle, children: [
|
|
38242
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
38243
|
+
"Skjult: ",
|
|
38244
|
+
label
|
|
38245
|
+
] }),
|
|
38246
|
+
pageStore ? /* @__PURE__ */ jsx(
|
|
38247
|
+
"button",
|
|
38248
|
+
{
|
|
38249
|
+
type: "button",
|
|
38250
|
+
"data-setto-ui": true,
|
|
38251
|
+
style: hiddenBtnStyle,
|
|
38252
|
+
onClick: () => pageStore.apply([{ op: "show_section", sectionId: section.id }]),
|
|
38253
|
+
children: "Vis"
|
|
38254
|
+
}
|
|
38255
|
+
) : null
|
|
38256
|
+
] });
|
|
38257
|
+
}
|
|
38258
|
+
function HiddenNote({ text: text2 }) {
|
|
38259
|
+
return /* @__PURE__ */ jsx("div", { "data-setto-ui": true, style: hiddenBarStyle, children: /* @__PURE__ */ jsx("span", { children: text2 }) });
|
|
38260
|
+
}
|
|
38261
|
+
function usePageTitle(page) {
|
|
38262
|
+
const { t } = useTranslation();
|
|
38263
|
+
const original = useRef(null);
|
|
38264
|
+
const title = page.path === "/" ? null : t(page.titleKey);
|
|
38265
|
+
useEffect(() => {
|
|
38266
|
+
if (!title || typeof document === "undefined") return;
|
|
38267
|
+
original.current ??= document.title;
|
|
38268
|
+
const base = original.current;
|
|
38269
|
+
document.title = base ? `${title} · ${base}` : title;
|
|
38270
|
+
return () => {
|
|
38271
|
+
document.title = base;
|
|
38272
|
+
};
|
|
38273
|
+
}, [title]);
|
|
38274
|
+
}
|
|
38275
|
+
function SettoTextSection({ sectionId, first }) {
|
|
38276
|
+
const keys2 = builtinKeys(sectionId);
|
|
38277
|
+
const { i18n } = useTranslation();
|
|
38278
|
+
const { store, editMode } = useSetto();
|
|
38279
|
+
const intro2 = store ? store.get(keys2.intro, i18n.language) : i18n.t(keys2.intro, { defaultValue: "" });
|
|
38280
|
+
const Heading = first ? "h1" : "h2";
|
|
38281
|
+
return /* @__PURE__ */ jsx(SettoSection, { sectionId, style: textSectionStyle, children: /* @__PURE__ */ jsxs("div", { style: textInnerStyle, children: [
|
|
38282
|
+
/* @__PURE__ */ jsx(Heading, { style: first ? textH1Style : textH2Style, children: /* @__PURE__ */ jsx(T, { k: keys2.heading }) }),
|
|
38283
|
+
intro2 || editMode ? /* @__PURE__ */ jsx("p", { style: textIntroStyle, children: /* @__PURE__ */ jsx(T, { k: keys2.intro }) }) : null,
|
|
38284
|
+
/* @__PURE__ */ jsx(
|
|
38285
|
+
SettoRepeater,
|
|
38286
|
+
{
|
|
38287
|
+
itemsKey: keys2.items,
|
|
38288
|
+
defaultItem: { heading: "Overskrift", text: "Tekst" },
|
|
38289
|
+
itemLabel: "avsnitt",
|
|
38290
|
+
children: (itemKey) => /* @__PURE__ */ jsx(TextItem, { sectionId, itemKey })
|
|
38291
|
+
}
|
|
38292
|
+
)
|
|
38293
|
+
] }) });
|
|
38294
|
+
}
|
|
38295
|
+
function TextItem({ sectionId, itemKey }) {
|
|
38296
|
+
const keys2 = builtinKeys(sectionId);
|
|
38297
|
+
const { i18n } = useTranslation();
|
|
38298
|
+
const { store, editMode } = useSetto();
|
|
38299
|
+
const heading2 = store ? store.get(keys2.itemHeading(itemKey), i18n.language) : i18n.t(keys2.itemHeading(itemKey), { defaultValue: "" });
|
|
38300
|
+
return /* @__PURE__ */ jsxs("div", { style: textItemStyle, children: [
|
|
38301
|
+
heading2 || editMode ? /* @__PURE__ */ jsx("h3", { style: textH3Style, children: /* @__PURE__ */ jsx(T, { k: keys2.itemHeading(itemKey) }) }) : null,
|
|
38302
|
+
/* @__PURE__ */ jsx("p", { style: textParagraphStyle, children: /* @__PURE__ */ jsx(T, { k: keys2.itemText(itemKey) }) })
|
|
38303
|
+
] });
|
|
38304
|
+
}
|
|
38305
|
+
const BUILTIN_RENDERERS = {
|
|
38306
|
+
text: SettoTextSection,
|
|
38307
|
+
blog: SettoBlogSection,
|
|
38308
|
+
"blog-latest": SettoBlogLatest
|
|
38309
|
+
};
|
|
38310
|
+
const textSectionStyle = { padding: "clamp(48px, 8vw, 96px) 16px" };
|
|
38311
|
+
const textInnerStyle = { maxWidth: "68ch", margin: "0 auto" };
|
|
38312
|
+
const textH1Style = {
|
|
38313
|
+
fontFamily: "var(--setto-display-font, inherit)",
|
|
38314
|
+
fontSize: "clamp(2rem, 4vw, 2.75rem)",
|
|
38315
|
+
lineHeight: 1.15,
|
|
38316
|
+
fontWeight: 600,
|
|
38317
|
+
margin: "0 0 0.75em"
|
|
38318
|
+
};
|
|
38319
|
+
const textH2Style = { ...textH1Style, fontSize: "clamp(1.5rem, 3vw, 2rem)" };
|
|
38320
|
+
const textH3Style = {
|
|
38321
|
+
fontFamily: "var(--setto-display-font, inherit)",
|
|
38322
|
+
fontSize: "1.125rem",
|
|
38323
|
+
lineHeight: 1.3,
|
|
38324
|
+
fontWeight: 600,
|
|
38325
|
+
margin: "0 0 0.4em"
|
|
38326
|
+
};
|
|
38327
|
+
const textIntroStyle = { fontSize: "1.125rem", lineHeight: 1.6, opacity: 0.85, margin: "0 0 2em" };
|
|
38328
|
+
const textItemStyle = { margin: "0 0 1.75em" };
|
|
38329
|
+
const textParagraphStyle = { lineHeight: 1.7, margin: 0, whiteSpace: "pre-line" };
|
|
38330
|
+
const hiddenBarStyle = {
|
|
38331
|
+
display: "flex",
|
|
38332
|
+
alignItems: "center",
|
|
38333
|
+
justifyContent: "center",
|
|
38334
|
+
gap: 12,
|
|
38335
|
+
padding: "10px 16px",
|
|
38336
|
+
margin: "4px 0",
|
|
38337
|
+
border: "1px dashed rgba(100, 10, 255, 0.45)",
|
|
38338
|
+
borderRadius: 8,
|
|
38339
|
+
background: "rgba(100, 10, 255, 0.05)",
|
|
38340
|
+
color: "#3b2a66",
|
|
38341
|
+
font: '500 13px system-ui, -apple-system, "Segoe UI", sans-serif'
|
|
38342
|
+
};
|
|
38343
|
+
const hiddenBtnStyle = {
|
|
38344
|
+
border: "none",
|
|
38345
|
+
borderRadius: 999,
|
|
38346
|
+
padding: "4px 12px",
|
|
38347
|
+
background: "#640AFF",
|
|
38348
|
+
color: "#fff",
|
|
38349
|
+
font: '600 12px system-ui, -apple-system, "Segoe UI", sans-serif',
|
|
38350
|
+
cursor: "pointer"
|
|
38351
|
+
};
|
|
38352
|
+
const BLOG_ROUTE = "/blogg";
|
|
38353
|
+
const BLOG_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
38354
|
+
const BLOG_SLUG_MAX = 80;
|
|
38355
|
+
const YOUTUBE_ID_PATTERN = /^[A-Za-z0-9_-]{11}$/;
|
|
38356
|
+
function isValidBlogSlug(slug) {
|
|
38357
|
+
return slug.length <= BLOG_SLUG_MAX && BLOG_SLUG_PATTERN.test(slug);
|
|
38358
|
+
}
|
|
38359
|
+
function byDateDesc(a, b) {
|
|
38360
|
+
return a.date === b.date ? a.slug.localeCompare(b.slug) : a.date < b.date ? 1 : -1;
|
|
38361
|
+
}
|
|
38362
|
+
function postsForLanguage(posts, language, fallbackLanguage) {
|
|
38363
|
+
const bySlug = /* @__PURE__ */ new Map();
|
|
38364
|
+
for (const post2 of posts) {
|
|
38365
|
+
const current = bySlug.get(post2.slug);
|
|
38366
|
+
if (!current || rank(post2, language, fallbackLanguage) < rank(current, language, fallbackLanguage)) {
|
|
38367
|
+
bySlug.set(post2.slug, post2);
|
|
38368
|
+
}
|
|
38369
|
+
}
|
|
38370
|
+
return [...bySlug.values()].sort(byDateDesc);
|
|
38371
|
+
}
|
|
38372
|
+
function postForSlug(posts, slug, language, fallbackLanguage) {
|
|
38373
|
+
return postsForLanguage(posts.filter((p) => p.slug === slug), language, fallbackLanguage)[0] ?? null;
|
|
38374
|
+
}
|
|
38375
|
+
function rank(post2, language, fallbackLanguage) {
|
|
38376
|
+
if (post2.locale === language) return 0;
|
|
38377
|
+
if (post2.locale === fallbackLanguage) return 1;
|
|
38378
|
+
return 2;
|
|
38379
|
+
}
|
|
38380
|
+
function formatPostDate(date, language) {
|
|
38381
|
+
const parsed = /* @__PURE__ */ new Date(`${date}T12:00:00Z`);
|
|
38382
|
+
if (Number.isNaN(parsed.getTime())) return date;
|
|
38383
|
+
const locale = language === "no" || language === "nb" || language === "nn" ? "nb-NO" : language;
|
|
38384
|
+
try {
|
|
38385
|
+
return new Intl.DateTimeFormat(locale, { day: "numeric", month: "long", year: "numeric", timeZone: "UTC" }).format(parsed);
|
|
38386
|
+
} catch {
|
|
38387
|
+
return date;
|
|
38388
|
+
}
|
|
38389
|
+
}
|
|
38390
|
+
const NO = {
|
|
38391
|
+
blog: "Blogg",
|
|
38392
|
+
latest: "Fra bloggen",
|
|
38393
|
+
allPosts: "Alle innlegg",
|
|
38394
|
+
readMore: "Les mer",
|
|
38395
|
+
back: "Alle innlegg",
|
|
38396
|
+
empty: "Ingen innlegg ennå.",
|
|
38397
|
+
notFound: "Fant ikke innlegget.",
|
|
38398
|
+
loading: "Henter innlegget …",
|
|
38399
|
+
share: "Del",
|
|
38400
|
+
moreShare: "Flere valg …",
|
|
38401
|
+
copyLink: "Kopier lenke",
|
|
38402
|
+
copied: "Lenken er kopiert",
|
|
38403
|
+
email: "E-post",
|
|
38404
|
+
video: "Video",
|
|
38405
|
+
play: "Spill av"
|
|
38406
|
+
};
|
|
38407
|
+
const EN = {
|
|
38408
|
+
blog: "Blog",
|
|
38409
|
+
latest: "From the blog",
|
|
38410
|
+
allPosts: "All posts",
|
|
38411
|
+
readMore: "Read more",
|
|
38412
|
+
back: "All posts",
|
|
38413
|
+
empty: "No posts yet.",
|
|
38414
|
+
notFound: "That post could not be found.",
|
|
38415
|
+
loading: "Loading the post …",
|
|
38416
|
+
share: "Share",
|
|
38417
|
+
moreShare: "More …",
|
|
38418
|
+
copyLink: "Copy link",
|
|
38419
|
+
copied: "Link copied",
|
|
38420
|
+
email: "Email",
|
|
38421
|
+
video: "Video",
|
|
38422
|
+
play: "Play"
|
|
38423
|
+
};
|
|
38424
|
+
function blogStrings(language) {
|
|
38425
|
+
return language === "no" || language === "nb" || language === "nn" ? NO : EN;
|
|
38426
|
+
}
|
|
38427
|
+
function BlogBody({ nodes, language }) {
|
|
38428
|
+
return /* @__PURE__ */ jsx(Fragment, { children: nodes.map((node2, i) => renderFlow(node2, i, language)) });
|
|
38429
|
+
}
|
|
38430
|
+
function renderFlow(node2, key, language) {
|
|
38431
|
+
switch (node2.type) {
|
|
38432
|
+
case "paragraph":
|
|
38433
|
+
return /* @__PURE__ */ jsx("p", { children: renderPhrasing(node2.children) }, key);
|
|
38434
|
+
case "heading": {
|
|
38435
|
+
const Tag = node2.depth === 2 ? "h2" : node2.depth === 3 ? "h3" : "h4";
|
|
38436
|
+
return /* @__PURE__ */ jsx(Tag, { children: renderPhrasing(node2.children) }, key);
|
|
38437
|
+
}
|
|
38438
|
+
case "list": {
|
|
38439
|
+
const items = node2.children.map((item, i) => /* @__PURE__ */ jsx("li", { children: item.children.map((child, j) => renderListChild(child, j, item.spread === true, language)) }, i));
|
|
38440
|
+
return node2.ordered ? /* @__PURE__ */ jsx("ol", { start: node2.start ?? void 0, children: items }, key) : /* @__PURE__ */ jsx("ul", { children: items }, key);
|
|
38441
|
+
}
|
|
38442
|
+
case "blockquote":
|
|
38443
|
+
return /* @__PURE__ */ jsx("blockquote", { children: node2.children.map((child, i) => renderFlow(child, i, language)) }, key);
|
|
38444
|
+
case "thematicBreak":
|
|
38445
|
+
return /* @__PURE__ */ jsx("hr", {}, key);
|
|
38446
|
+
case "code":
|
|
38447
|
+
return /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: node2.value }) }, key);
|
|
38448
|
+
case "table":
|
|
38449
|
+
return /* @__PURE__ */ jsx(BlogTable, { table: node2 }, key);
|
|
38450
|
+
case "mdxJsxFlowElement":
|
|
38451
|
+
return /* @__PURE__ */ jsx(BlogComponent, { element: node2, language }, key);
|
|
38452
|
+
default:
|
|
38453
|
+
return null;
|
|
38454
|
+
}
|
|
38455
|
+
}
|
|
38456
|
+
function renderListChild(child, key, spread, language) {
|
|
38457
|
+
if (child.type === "paragraph" && !spread) return /* @__PURE__ */ jsx("span", { children: renderPhrasing(child.children) }, key);
|
|
38458
|
+
return renderFlow(child, key, language);
|
|
38459
|
+
}
|
|
38460
|
+
function renderPhrasing(children) {
|
|
38461
|
+
return children.map((child, i) => {
|
|
38462
|
+
switch (child.type) {
|
|
38463
|
+
case "text":
|
|
38464
|
+
return child.value;
|
|
38465
|
+
case "emphasis":
|
|
38466
|
+
return /* @__PURE__ */ jsx("em", { children: renderPhrasing(child.children) }, i);
|
|
38467
|
+
case "strong":
|
|
38468
|
+
return /* @__PURE__ */ jsx("strong", { children: renderPhrasing(child.children) }, i);
|
|
38469
|
+
case "delete":
|
|
38470
|
+
return /* @__PURE__ */ jsx("del", { children: renderPhrasing(child.children) }, i);
|
|
38471
|
+
case "inlineCode":
|
|
38472
|
+
return /* @__PURE__ */ jsx("code", { children: child.value }, i);
|
|
38473
|
+
case "break":
|
|
38474
|
+
return /* @__PURE__ */ jsx("br", {}, i);
|
|
38475
|
+
case "link": {
|
|
38476
|
+
const safe = isSafeHref(child.url);
|
|
38477
|
+
if (!safe) return /* @__PURE__ */ jsx("span", { children: renderPhrasing(child.children) }, i);
|
|
38478
|
+
const external = /^https?:\/\//i.test(child.url);
|
|
38479
|
+
return /* @__PURE__ */ jsx("a", { href: child.url, ...external ? { rel: "noopener noreferrer" } : {}, children: renderPhrasing(child.children) }, i);
|
|
38480
|
+
}
|
|
38481
|
+
default:
|
|
38482
|
+
return null;
|
|
38483
|
+
}
|
|
38484
|
+
});
|
|
38485
|
+
}
|
|
38486
|
+
function BlogTable({ table: table2 }) {
|
|
38487
|
+
const [head2, ...rows] = table2.children;
|
|
38488
|
+
const align = (i) => table2.align?.[i] ?? void 0;
|
|
38489
|
+
return /* @__PURE__ */ jsx("div", { className: "setto-blog__table", children: /* @__PURE__ */ jsxs("table", { children: [
|
|
38490
|
+
head2 ? /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: head2.children.map((cell, i) => /* @__PURE__ */ jsx("th", { style: { textAlign: align(i) }, children: renderPhrasing(cell.children) }, i)) }) }) : null,
|
|
38491
|
+
/* @__PURE__ */ jsx("tbody", { children: rows.map((row, r) => /* @__PURE__ */ jsx("tr", { children: row.children.map((cell, i) => /* @__PURE__ */ jsx("td", { style: { textAlign: align(i) }, children: renderPhrasing(cell.children) }, i)) }, r)) })
|
|
38492
|
+
] }) });
|
|
38493
|
+
}
|
|
38494
|
+
function attrs(element2) {
|
|
38495
|
+
const out = {};
|
|
38496
|
+
for (const attribute of element2.attributes) {
|
|
38497
|
+
const a = attribute;
|
|
38498
|
+
if (a.type === "mdxJsxAttribute" && typeof a.value === "string") out[a.name] = a.value;
|
|
38499
|
+
}
|
|
38500
|
+
return out;
|
|
38501
|
+
}
|
|
38502
|
+
function BlogComponent({ element: element2, language }) {
|
|
38503
|
+
const props = attrs(element2);
|
|
38504
|
+
switch (element2.name) {
|
|
38505
|
+
case "Image":
|
|
38506
|
+
return props.src && props.alt !== void 0 ? /* @__PURE__ */ jsxs("figure", { className: "setto-blog__figure", children: [
|
|
38507
|
+
/* @__PURE__ */ jsx(BlogImg, { src: props.src, alt: props.alt, sizes: "(min-width: 760px) 720px, 100vw" }),
|
|
38508
|
+
props.caption ? /* @__PURE__ */ jsx("figcaption", { children: props.caption }) : null
|
|
38509
|
+
] }) : null;
|
|
38510
|
+
case "Gallery": {
|
|
38511
|
+
const images = element2.children.filter(
|
|
38512
|
+
(child) => child.type === "mdxJsxFlowElement" && child.name === "Image"
|
|
38513
|
+
);
|
|
38514
|
+
return /* @__PURE__ */ jsxs("figure", { className: "setto-blog__gallery", children: [
|
|
38515
|
+
/* @__PURE__ */ jsx("div", { className: "setto-blog__gallery-grid", children: images.map((image2, i) => {
|
|
38516
|
+
const a = attrs(image2);
|
|
38517
|
+
return a.src ? /* @__PURE__ */ jsxs("figure", { className: "setto-blog__gallery-item", children: [
|
|
38518
|
+
/* @__PURE__ */ jsx(BlogImg, { src: a.src, alt: a.alt ?? "", sizes: "(min-width: 760px) 360px, 50vw" }),
|
|
38519
|
+
a.caption ? /* @__PURE__ */ jsx("figcaption", { children: a.caption }) : null
|
|
38520
|
+
] }, i) : null;
|
|
38521
|
+
}) }),
|
|
38522
|
+
props.caption ? /* @__PURE__ */ jsx("figcaption", { children: props.caption }) : null
|
|
38523
|
+
] });
|
|
38524
|
+
}
|
|
38525
|
+
case "YouTube":
|
|
38526
|
+
return props.id && YOUTUBE_ID_PATTERN.test(props.id) ? /* @__PURE__ */ jsx(YouTubeEmbed, { id: props.id, title: props.title, language }) : null;
|
|
38527
|
+
case "Callout":
|
|
38528
|
+
return /* @__PURE__ */ jsx("aside", { className: "setto-blog__callout", "data-tone": props.tone ?? "info", children: element2.children.map((child, i) => renderFlow(child, i, language)) });
|
|
38529
|
+
default:
|
|
38530
|
+
return null;
|
|
38531
|
+
}
|
|
38532
|
+
}
|
|
38533
|
+
function BlogImg({ src, alt, sizes, className }) {
|
|
38534
|
+
const { config } = useSetto();
|
|
38535
|
+
const [failed, setFailed] = useState(false);
|
|
38536
|
+
const optimize = config.images?.optimize === true && !failed && isOptimizable(src) && !(typeof window !== "undefined" && hasNoOptimizer(window.location.hostname));
|
|
38537
|
+
if (!optimize) return /* @__PURE__ */ jsx("img", { src, alt, loading: "lazy", decoding: "async", className });
|
|
38538
|
+
return /* @__PURE__ */ jsx(
|
|
38539
|
+
"img",
|
|
38540
|
+
{
|
|
38541
|
+
src: optimizedUrl(src, 1080),
|
|
38542
|
+
srcSet: optimizedSrcSet(src),
|
|
38543
|
+
sizes,
|
|
38544
|
+
alt,
|
|
38545
|
+
loading: "lazy",
|
|
38546
|
+
decoding: "async",
|
|
38547
|
+
className,
|
|
38548
|
+
onError: () => setFailed(true)
|
|
38549
|
+
}
|
|
38550
|
+
);
|
|
38551
|
+
}
|
|
38552
|
+
function YouTubeEmbed({ id, title, language }) {
|
|
38553
|
+
const [playing, setPlaying] = useState(false);
|
|
38554
|
+
const strings = blogStrings(language);
|
|
38555
|
+
const label = title ?? strings.video;
|
|
38556
|
+
return /* @__PURE__ */ jsxs("figure", { className: "setto-blog__video", children: [
|
|
38557
|
+
/* @__PURE__ */ jsx("div", { className: "setto-blog__video-frame", children: playing ? /* @__PURE__ */ jsx(
|
|
38558
|
+
"iframe",
|
|
38559
|
+
{
|
|
38560
|
+
src: `https://www.youtube-nocookie.com/embed/${id}?autoplay=1&rel=0`,
|
|
38561
|
+
title: label,
|
|
38562
|
+
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
|
|
38563
|
+
allowFullScreen: true,
|
|
38564
|
+
referrerPolicy: "strict-origin-when-cross-origin"
|
|
38565
|
+
}
|
|
38566
|
+
) : /* @__PURE__ */ jsxs("button", { type: "button", className: "setto-blog__video-play", onClick: () => setPlaying(true), "aria-label": `${strings.play}: ${label}`, children: [
|
|
38567
|
+
/* @__PURE__ */ jsx("img", { src: `https://i.ytimg.com/vi/${id}/hqdefault.jpg`, alt: "", loading: "lazy", decoding: "async" }),
|
|
38568
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "setto-blog__video-icon", children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 68 48", width: "68", height: "48", children: [
|
|
38569
|
+
/* @__PURE__ */ jsx("path", { d: "M66.5 7.7A8.5 8.5 0 0 0 60.5 1.7C55.2.3 34 .3 34 .3s-21.2 0-26.5 1.4A8.5 8.5 0 0 0 1.5 7.7C.1 13 .1 24 .1 24s0 11 1.4 16.3a8.5 8.5 0 0 0 6 6c5.3 1.4 26.5 1.4 26.5 1.4s21.2 0 26.5-1.4a8.5 8.5 0 0 0 6-6C67.9 35 67.9 24 67.9 24s0-11-1.4-16.3z", fill: "#f00" }),
|
|
38570
|
+
/* @__PURE__ */ jsx("path", { d: "M45 24 27 14v20", fill: "#fff" })
|
|
38571
|
+
] }) })
|
|
38572
|
+
] }) }),
|
|
38573
|
+
title ? /* @__PURE__ */ jsx("figcaption", { children: title }) : null
|
|
38574
|
+
] });
|
|
38575
|
+
}
|
|
38576
|
+
const LATEST_COUNT = 3;
|
|
38577
|
+
function useBlogContext() {
|
|
38578
|
+
const { config } = useSetto();
|
|
38579
|
+
const { i18n, t } = useTranslation();
|
|
38580
|
+
const manifest = usePageManifest();
|
|
38581
|
+
const language = i18n.language || config.languages?.[0] || "no";
|
|
38582
|
+
const fallbackLanguage = config.languages?.[0] ?? "no";
|
|
38583
|
+
const route = typeof window === "undefined" ? { basename: "", rest: "/" } : languageFromPath(window.location.pathname, config.languages ?? [fallbackLanguage]);
|
|
38584
|
+
const href = (path2) => `${route.basename}${path2}`;
|
|
38585
|
+
return { config, t, manifest, language, fallbackLanguage, strings: blogStrings(language), path: route.rest, href };
|
|
38586
|
+
}
|
|
38587
|
+
function blogPathOf(manifest) {
|
|
38588
|
+
return manifest && blogPage(manifest)?.page.path || BLOG_ROUTE;
|
|
38589
|
+
}
|
|
38590
|
+
function SettoBlogSection({ sectionId, first }) {
|
|
38591
|
+
useBlogStyles();
|
|
38592
|
+
const ctx = useBlogContext();
|
|
38593
|
+
const slug = ctx.manifest ? blogSlugForPath(ctx.manifest, ctx.path) : null;
|
|
38594
|
+
const page = ctx.manifest ? findSection(ctx.manifest, sectionId)?.page : void 0;
|
|
38595
|
+
const title = page ? ctx.t(page.titleKey, { defaultValue: ctx.strings.blog }) : ctx.strings.blog;
|
|
38596
|
+
const blogPath = blogPathOf(ctx.manifest);
|
|
38597
|
+
const inner = useRef(null);
|
|
38598
|
+
const clear = useClearFixedHeader(inner, first);
|
|
38599
|
+
return /* @__PURE__ */ jsx(SettoSection, { sectionId, className: "setto-blog", children: /* @__PURE__ */ jsx("div", { className: "setto-blog__inner", ref: inner, style: clear ? { paddingTop: clear } : void 0, children: slug ? /* @__PURE__ */ jsx(BlogPostView, { slug, blogPath, ctx }) : /* @__PURE__ */ jsx(BlogIndexView, { title, first, blogPath, ctx }) }) });
|
|
38600
|
+
}
|
|
38601
|
+
function SettoBlog({ basePath = BLOG_ROUTE, title }) {
|
|
38602
|
+
useBlogStyles();
|
|
38603
|
+
const ctx = useBlogContext();
|
|
38604
|
+
const base = normalisePath(basePath);
|
|
38605
|
+
const here = normalisePath(ctx.path);
|
|
38606
|
+
const rest = here.startsWith(`${base}/`) ? here.slice(base.length + 1) : "";
|
|
38607
|
+
const slug = rest && isValidBlogSlug(rest) ? rest : null;
|
|
38608
|
+
const inner = useRef(null);
|
|
38609
|
+
const clear = useClearFixedHeader(inner, true);
|
|
38610
|
+
return /* @__PURE__ */ jsx("section", { className: "setto-blog", children: /* @__PURE__ */ jsx("div", { className: "setto-blog__inner", ref: inner, style: clear ? { paddingTop: clear } : void 0, children: slug ? /* @__PURE__ */ jsx(BlogPostView, { slug, blogPath: base, ctx }) : /* @__PURE__ */ jsx(BlogIndexView, { title: title ?? ctx.strings.blog, first: true, blogPath: base, ctx }) }) });
|
|
38611
|
+
}
|
|
38612
|
+
function useClearFixedHeader(ref, enabled) {
|
|
38613
|
+
const [clear, setClear] = useState(0);
|
|
38614
|
+
useLayoutEffect(() => {
|
|
38615
|
+
if (!enabled || typeof window === "undefined") return;
|
|
38616
|
+
const measure = () => {
|
|
38617
|
+
const el = ref.current;
|
|
38618
|
+
if (!el) return;
|
|
38619
|
+
const covering = document.elementsFromPoint(window.innerWidth / 2, 1).map((node2) => fixedAncestor(node2)).find((node2) => node2 !== null && !node2.contains(el));
|
|
38620
|
+
const headerBottom = covering ? covering.getBoundingClientRect().bottom : 0;
|
|
38621
|
+
const start = el.getBoundingClientRect().top + window.scrollY;
|
|
38622
|
+
const overlap = Math.ceil(headerBottom + 16 - start);
|
|
38623
|
+
setClear(overlap > 0 ? overlap : 0);
|
|
38624
|
+
};
|
|
38625
|
+
measure();
|
|
38626
|
+
window.addEventListener("resize", measure);
|
|
38627
|
+
return () => window.removeEventListener("resize", measure);
|
|
38628
|
+
}, [ref, enabled]);
|
|
38629
|
+
return clear;
|
|
38630
|
+
}
|
|
38631
|
+
function fixedAncestor(node2) {
|
|
38632
|
+
for (let at = node2; at && at !== document.body; at = at.parentElement) {
|
|
38633
|
+
if (getComputedStyle(at).position === "fixed") return at;
|
|
38634
|
+
}
|
|
38635
|
+
return null;
|
|
38636
|
+
}
|
|
38637
|
+
function BlogIndexView({ title, first, blogPath, ctx }) {
|
|
38638
|
+
const posts = ctx.config.blog ? postsForLanguage(ctx.config.blog.posts, ctx.language, ctx.fallbackLanguage) : [];
|
|
38639
|
+
const Heading = first ? "h1" : "h2";
|
|
38640
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
38641
|
+
/* @__PURE__ */ jsx(Heading, { className: "setto-blog__title", children: title }),
|
|
38642
|
+
posts.length === 0 ? /* @__PURE__ */ jsx("p", { className: "setto-blog__empty", children: ctx.strings.empty }) : /* @__PURE__ */ jsx("div", { className: "setto-blog__list", children: posts.map((post2) => /* @__PURE__ */ jsx(PostCard, { post: post2, blogPath, ctx, headingLevel: first ? "h2" : "h3" }, post2.slug)) })
|
|
38643
|
+
] });
|
|
38644
|
+
}
|
|
38645
|
+
function PostCard({
|
|
38646
|
+
post: post2,
|
|
38647
|
+
blogPath,
|
|
38648
|
+
ctx,
|
|
38649
|
+
headingLevel
|
|
38650
|
+
}) {
|
|
38651
|
+
const Heading = headingLevel;
|
|
38652
|
+
const href = ctx.href(`${blogPath}/${post2.slug}`);
|
|
38653
|
+
return /* @__PURE__ */ jsxs("article", { className: "setto-blog__card", children: [
|
|
38654
|
+
post2.cover ? /* @__PURE__ */ jsx("a", { href, className: "setto-blog__card-cover", tabIndex: -1, "aria-hidden": "true", children: /* @__PURE__ */ jsx(BlogImg, { src: post2.cover, alt: "", sizes: "(min-width: 960px) 360px, (min-width: 640px) 50vw, 100vw" }) }) : null,
|
|
38655
|
+
/* @__PURE__ */ jsxs("div", { className: "setto-blog__card-body", children: [
|
|
38656
|
+
/* @__PURE__ */ jsx("time", { className: "setto-blog__date", dateTime: post2.date, children: formatPostDate(post2.date, ctx.language) }),
|
|
38657
|
+
/* @__PURE__ */ jsx(Heading, { className: "setto-blog__card-title", children: /* @__PURE__ */ jsx("a", { href, children: post2.title }) }),
|
|
38658
|
+
/* @__PURE__ */ jsx("p", { className: "setto-blog__card-lead", children: post2.description }),
|
|
38659
|
+
/* @__PURE__ */ jsxs("a", { href, className: "setto-blog__more", "aria-label": `${ctx.strings.readMore}: ${post2.title}`, children: [
|
|
38660
|
+
ctx.strings.readMore,
|
|
38661
|
+
" ",
|
|
38662
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "→" })
|
|
38663
|
+
] })
|
|
38664
|
+
] })
|
|
38665
|
+
] });
|
|
38666
|
+
}
|
|
38667
|
+
function BlogPostView({ slug, blogPath, ctx }) {
|
|
38668
|
+
const blog = ctx.config.blog;
|
|
38669
|
+
const summary = blog ? postForSlug(blog.posts, slug, ctx.language, ctx.fallbackLanguage) : null;
|
|
38670
|
+
const [post2, setPost] = useState(null);
|
|
38671
|
+
const [state, setState] = useState(summary ? "loading" : "missing");
|
|
38672
|
+
useEffect(() => {
|
|
38673
|
+
if (!blog || !summary) {
|
|
38674
|
+
setState("missing");
|
|
38675
|
+
return;
|
|
38676
|
+
}
|
|
38677
|
+
let live = true;
|
|
38678
|
+
setState("loading");
|
|
38679
|
+
blog.load(summary.slug, summary.locale).then((loaded) => {
|
|
38680
|
+
if (!live) return;
|
|
38681
|
+
setPost(loaded);
|
|
38682
|
+
setState(loaded ? "ready" : "missing");
|
|
38683
|
+
}).catch(() => live && setState("missing"));
|
|
38684
|
+
return () => {
|
|
38685
|
+
live = false;
|
|
38686
|
+
};
|
|
38687
|
+
}, [blog, summary?.slug, summary?.locale]);
|
|
38688
|
+
usePostTitle(summary?.title ?? null, ctx.config.displayName);
|
|
38689
|
+
const back = /* @__PURE__ */ jsxs("a", { href: ctx.href(blogPath), className: "setto-blog__back", children: [
|
|
38690
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "←" }),
|
|
38691
|
+
" ",
|
|
38692
|
+
ctx.strings.back
|
|
38693
|
+
] });
|
|
38694
|
+
if (!summary || state === "missing") {
|
|
38695
|
+
return /* @__PURE__ */ jsxs("div", { className: "setto-blog__post", children: [
|
|
38696
|
+
back,
|
|
38697
|
+
/* @__PURE__ */ jsx("p", { className: "setto-blog__empty", children: ctx.strings.notFound })
|
|
38698
|
+
] });
|
|
38699
|
+
}
|
|
38700
|
+
const fm = post2?.frontmatter ?? summary;
|
|
38701
|
+
return /* @__PURE__ */ jsxs("article", { className: "setto-blog__post", lang: fm.locale, children: [
|
|
38702
|
+
back,
|
|
38703
|
+
/* @__PURE__ */ jsxs("header", { className: "setto-blog__post-header", children: [
|
|
38704
|
+
/* @__PURE__ */ jsx("time", { className: "setto-blog__date", dateTime: fm.date, children: formatPostDate(fm.date, ctx.language) }),
|
|
38705
|
+
/* @__PURE__ */ jsx("h1", { className: "setto-blog__post-title", children: fm.title }),
|
|
38706
|
+
/* @__PURE__ */ jsx("p", { className: "setto-blog__lead", children: fm.description })
|
|
38707
|
+
] }),
|
|
38708
|
+
fm.cover ? /* @__PURE__ */ jsx("figure", { className: "setto-blog__cover", children: /* @__PURE__ */ jsx(BlogImg, { src: fm.cover, alt: "", sizes: "(min-width: 1040px) 960px, 100vw" }) }) : null,
|
|
38709
|
+
state === "ready" && post2 ? /* @__PURE__ */ jsx("div", { className: "setto-blog__prose", children: /* @__PURE__ */ jsx(BlogBody, { nodes: post2.body.children, language: ctx.language }) }) : /* @__PURE__ */ jsx("p", { className: "setto-blog__loading", "aria-live": "polite", children: ctx.strings.loading }),
|
|
38710
|
+
/* @__PURE__ */ jsx(ShareBar, { title: fm.title, strings: ctx.strings })
|
|
38711
|
+
] });
|
|
38712
|
+
}
|
|
38713
|
+
function usePostTitle(title, siteName) {
|
|
38714
|
+
useEffect(() => {
|
|
38715
|
+
if (!title || typeof document === "undefined") return;
|
|
38716
|
+
const previous2 = document.title;
|
|
38717
|
+
const timer = window.setTimeout(() => {
|
|
38718
|
+
document.title = siteName ? `${title} · ${siteName}` : title;
|
|
38719
|
+
}, 0);
|
|
38720
|
+
return () => {
|
|
38721
|
+
window.clearTimeout(timer);
|
|
38722
|
+
document.title = previous2;
|
|
38723
|
+
};
|
|
38724
|
+
}, [title, siteName]);
|
|
38725
|
+
}
|
|
38726
|
+
function ShareBar({ title, strings }) {
|
|
38727
|
+
const [copied, setCopied] = useState(false);
|
|
38728
|
+
const [native, setNative] = useState(false);
|
|
38729
|
+
useEffect(() => setNative(typeof navigator !== "undefined" && typeof navigator.share === "function"), []);
|
|
38730
|
+
const url = typeof window === "undefined" ? "" : `${window.location.origin}${window.location.pathname}`;
|
|
38731
|
+
const u = encodeURIComponent(url);
|
|
38732
|
+
const t = encodeURIComponent(title);
|
|
38733
|
+
return /* @__PURE__ */ jsxs("div", { className: "setto-blog__share", "aria-label": strings.share, children: [
|
|
38734
|
+
/* @__PURE__ */ jsx("span", { className: "setto-blog__share-label", children: strings.share }),
|
|
38735
|
+
native ? /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void navigator.share({ title, url }).catch(() => void 0), children: strings.moreShare }) : null,
|
|
38736
|
+
/* @__PURE__ */ jsx("a", { href: `https://www.facebook.com/sharer/sharer.php?u=${u}`, target: "_blank", rel: "noopener noreferrer", children: "Facebook" }),
|
|
38737
|
+
/* @__PURE__ */ jsx("a", { href: `https://www.linkedin.com/sharing/share-offsite/?url=${u}`, target: "_blank", rel: "noopener noreferrer", children: "LinkedIn" }),
|
|
38738
|
+
/* @__PURE__ */ jsx("a", { href: `mailto:?subject=${t}&body=${u}`, children: strings.email }),
|
|
38739
|
+
/* @__PURE__ */ jsx(
|
|
38740
|
+
"button",
|
|
38741
|
+
{
|
|
38742
|
+
type: "button",
|
|
38743
|
+
onClick: () => {
|
|
38744
|
+
void navigator.clipboard?.writeText(url).then(() => {
|
|
38745
|
+
setCopied(true);
|
|
38746
|
+
window.setTimeout(() => setCopied(false), 2e3);
|
|
38747
|
+
});
|
|
38748
|
+
},
|
|
38749
|
+
children: copied ? strings.copied : strings.copyLink
|
|
38750
|
+
}
|
|
38751
|
+
)
|
|
38752
|
+
] });
|
|
38753
|
+
}
|
|
38754
|
+
function SettoBlogLatest({ sectionId, first }) {
|
|
38755
|
+
useBlogStyles();
|
|
38756
|
+
const ctx = useBlogContext();
|
|
38757
|
+
if (!ctx.config.blog) return null;
|
|
38758
|
+
const posts = postsForLanguage(ctx.config.blog.posts, ctx.language, ctx.fallbackLanguage).slice(0, LATEST_COUNT);
|
|
38759
|
+
if (posts.length === 0) return null;
|
|
38760
|
+
const blogPath = blogPathOf(ctx.manifest);
|
|
38761
|
+
const Heading = first ? "h1" : "h2";
|
|
38762
|
+
return /* @__PURE__ */ jsx(SettoSection, { sectionId, className: "setto-blog setto-blog--latest", children: /* @__PURE__ */ jsxs("div", { className: "setto-blog__inner setto-blog__inner--wide", children: [
|
|
38763
|
+
/* @__PURE__ */ jsxs("div", { className: "setto-blog__latest-head", children: [
|
|
38764
|
+
/* @__PURE__ */ jsx(Heading, { className: "setto-blog__title", children: ctx.strings.latest }),
|
|
38765
|
+
/* @__PURE__ */ jsxs("a", { href: ctx.href(blogPath), className: "setto-blog__more", children: [
|
|
38766
|
+
ctx.strings.allPosts,
|
|
38767
|
+
" ",
|
|
38768
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "→" })
|
|
38769
|
+
] })
|
|
38770
|
+
] }),
|
|
38771
|
+
/* @__PURE__ */ jsx("div", { className: "setto-blog__list", children: posts.map((post2) => /* @__PURE__ */ jsx(PostCard, { post: post2, blogPath, ctx, headingLevel: "h3" }, post2.slug)) })
|
|
38772
|
+
] }) });
|
|
38773
|
+
}
|
|
38774
|
+
const STYLE_ID$1 = "setto-blog-styles";
|
|
38775
|
+
const BLOG_CSS = `
|
|
38776
|
+
.setto-blog{padding:clamp(48px,8vw,96px) 16px}
|
|
38777
|
+
.setto-blog :where(.setto-blog__inner){max-width:68ch;margin:0 auto}
|
|
38778
|
+
.setto-blog :where(.setto-blog__inner--wide){max-width:1120px}
|
|
38779
|
+
.setto-blog :where(.setto-blog__title){font-family:var(--setto-display-font,inherit);font-size:clamp(2rem,4vw,2.75rem);line-height:1.15;font-weight:600;margin:0 0 .75em}
|
|
38780
|
+
.setto-blog :where(.setto-blog__list){display:grid;gap:clamp(1.5rem,3vw,2.5rem);grid-template-columns:repeat(auto-fill,minmax(min(100%,300px),1fr))}
|
|
38781
|
+
.setto-blog :where(.setto-blog__card){display:grid;gap:.9rem;align-content:start}
|
|
38782
|
+
.setto-blog :where(.setto-blog__card-cover){display:block;overflow:hidden;border-radius:.9rem;aspect-ratio:16/10}
|
|
38783
|
+
.setto-blog :where(.setto-blog__card-cover img,.setto-blog__cover img,.setto-blog__figure img,.setto-blog__gallery-item img){display:block;width:100%;height:100%;object-fit:cover}
|
|
38784
|
+
.setto-blog :where(.setto-blog__card-body){display:grid;gap:.45rem}
|
|
38785
|
+
.setto-blog :where(.setto-blog__card-title){font-family:var(--setto-display-font,inherit);font-size:1.3rem;line-height:1.25;font-weight:600;margin:0}
|
|
38786
|
+
.setto-blog :where(.setto-blog__card-lead){margin:0;line-height:1.55}
|
|
38787
|
+
.setto-blog :where(.setto-blog__date){font-size:.875rem;letter-spacing:.01em}
|
|
38788
|
+
.setto-blog :where(.setto-blog__more,.setto-blog__back){display:inline-flex;gap:.35em;align-items:center;font-weight:500;width:fit-content}
|
|
38789
|
+
.setto-blog :where(.setto-blog__back){margin-bottom:2rem}
|
|
38790
|
+
.setto-blog :where(.setto-blog__latest-head){display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:.5rem 1.5rem;margin-bottom:1.75rem}
|
|
38791
|
+
.setto-blog :where(.setto-blog__latest-head .setto-blog__title){margin:0}
|
|
38792
|
+
.setto-blog :where(.setto-blog__post-header){display:grid;gap:.6rem;margin-bottom:2rem}
|
|
38793
|
+
.setto-blog :where(.setto-blog__post-title){font-family:var(--setto-display-font,inherit);font-size:clamp(2rem,5vw,3rem);line-height:1.1;font-weight:600;margin:0}
|
|
38794
|
+
.setto-blog :where(.setto-blog__lead){font-size:1.2rem;line-height:1.5;margin:0}
|
|
38795
|
+
.setto-blog :where(.setto-blog__cover){margin:0 0 2.5rem;overflow:hidden;border-radius:1rem;aspect-ratio:16/9}
|
|
38796
|
+
.setto-blog :where(.setto-blog__prose){font-size:1.075rem;line-height:1.7}
|
|
38797
|
+
.setto-blog :where(.setto-blog__prose > * + *){margin-top:1.15em}
|
|
38798
|
+
.setto-blog :where(.setto-blog__prose h2,.setto-blog__prose h3,.setto-blog__prose h4){font-family:var(--setto-display-font,inherit);line-height:1.25;font-weight:600;margin:1.8em 0 0}
|
|
38799
|
+
.setto-blog :where(.setto-blog__prose h2){font-size:1.6rem}
|
|
38800
|
+
.setto-blog :where(.setto-blog__prose h3){font-size:1.3rem}
|
|
38801
|
+
.setto-blog :where(.setto-blog__prose h4){font-size:1.1rem}
|
|
38802
|
+
.setto-blog :where(.setto-blog__prose ul,.setto-blog__prose ol){padding-left:1.4em}
|
|
38803
|
+
.setto-blog :where(.setto-blog__prose ul){list-style:disc}
|
|
38804
|
+
.setto-blog :where(.setto-blog__prose ol){list-style:decimal}
|
|
38805
|
+
.setto-blog :where(.setto-blog__prose li + li){margin-top:.35em}
|
|
38806
|
+
.setto-blog :where(.setto-blog__prose blockquote){margin-left:0;padding-left:1.1em;border-left-width:3px;border-left-style:solid;font-style:italic}
|
|
38807
|
+
.setto-blog :where(.setto-blog__prose pre){overflow-x:auto;padding:1em;border-radius:.6rem;font-size:.9em}
|
|
38808
|
+
.setto-blog :where(.setto-blog__prose code){font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.92em}
|
|
38809
|
+
.setto-blog :where(.setto-blog__prose hr){border:0;border-top-width:1px;border-top-style:solid;margin:2.5em 0}
|
|
38810
|
+
.setto-blog :where(.setto-blog__prose a){text-decoration:underline;text-underline-offset:.18em}
|
|
38811
|
+
.setto-blog :where(.setto-blog__table){overflow-x:auto}
|
|
38812
|
+
.setto-blog :where(.setto-blog__table table){border-collapse:collapse;width:100%;font-size:.95em}
|
|
38813
|
+
.setto-blog :where(.setto-blog__table th,.setto-blog__table td){padding:.55em .8em;border-bottom-width:1px;border-bottom-style:solid;text-align:left}
|
|
38814
|
+
.setto-blog :where(.setto-blog__figure,.setto-blog__gallery,.setto-blog__video){margin:2em 0}
|
|
38815
|
+
.setto-blog :where(.setto-blog__figure img){border-radius:.8rem;height:auto}
|
|
38816
|
+
.setto-blog :where(figcaption){font-size:.9rem;margin-top:.6em;opacity:.75}
|
|
38817
|
+
.setto-blog :where(.setto-blog__gallery-grid){display:grid;gap:.6rem;grid-template-columns:repeat(auto-fit,minmax(min(100%,150px),1fr))}
|
|
38818
|
+
.setto-blog :where(.setto-blog__gallery-item){margin:0}
|
|
38819
|
+
.setto-blog :where(.setto-blog__gallery-item img){border-radius:.6rem;aspect-ratio:4/3}
|
|
38820
|
+
.setto-blog :where(.setto-blog__video-frame){position:relative;aspect-ratio:16/9;border-radius:.8rem;overflow:hidden}
|
|
38821
|
+
.setto-blog :where(.setto-blog__video-frame iframe){position:absolute;inset:0;width:100%;height:100%;border:0}
|
|
38822
|
+
.setto-blog :where(.setto-blog__video-play){position:absolute;inset:0;width:100%;height:100%;padding:0;border:0;cursor:pointer;display:grid;place-items:center}
|
|
38823
|
+
.setto-blog :where(.setto-blog__video-play img){position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
|
|
38824
|
+
.setto-blog :where(.setto-blog__video-icon){position:relative;display:block;line-height:0}
|
|
38825
|
+
.setto-blog :where(.setto-blog__callout){padding:1.1em 1.3em;border-radius:.8rem;border-left-width:4px;border-left-style:solid}
|
|
38826
|
+
.setto-blog :where(.setto-blog__callout > * + *){margin-top:.7em}
|
|
38827
|
+
.setto-blog :where(.setto-blog__callout ul,.setto-blog__callout ol){padding-left:1.3em;list-style:disc}
|
|
38828
|
+
.setto-blog :where(.setto-blog__share){display:flex;flex-wrap:wrap;gap:.5rem .9rem;align-items:center;margin-top:3rem;padding-top:1.5rem;border-top-width:1px;border-top-style:solid}
|
|
38829
|
+
.setto-blog :where(.setto-blog__share-label){font-weight:600}
|
|
38830
|
+
.setto-blog :where(.setto-blog__share a,.setto-blog__share button){font:inherit;padding:.35rem .85rem;border-radius:999px;border-width:1px;border-style:solid;cursor:pointer;text-decoration:none;line-height:1.4}
|
|
38831
|
+
.setto-blog :where(.setto-blog__empty,.setto-blog__loading){opacity:.75}
|
|
38832
|
+
:where(.setto-blog){color:inherit}
|
|
38833
|
+
:where(.setto-blog__date){opacity:.7}
|
|
38834
|
+
:where(.setto-blog a){color:inherit}
|
|
38835
|
+
:where(.setto-blog__prose blockquote,.setto-blog__prose hr,.setto-blog__table th,.setto-blog__table td,.setto-blog__share){border-color:color-mix(in srgb,currentColor 18%,transparent)}
|
|
38836
|
+
:where(.setto-blog__prose pre,.setto-blog__card-cover){background:color-mix(in srgb,currentColor 6%,transparent)}
|
|
38837
|
+
:where(.setto-blog__share a,.setto-blog__share button){border-color:color-mix(in srgb,currentColor 30%,transparent);background:transparent;color:inherit}
|
|
38838
|
+
:where(.setto-blog__callout){background:color-mix(in srgb,currentColor 5%,transparent);border-left-color:color-mix(in srgb,currentColor 40%,transparent)}
|
|
38839
|
+
:where(.setto-blog__callout[data-tone="tip"]){border-left-color:#0f7b4f}
|
|
38840
|
+
:where(.setto-blog__callout[data-tone="warning"]){border-left-color:#b54708}
|
|
38841
|
+
:where(.setto-blog__video-frame){background:#000}
|
|
38842
|
+
`;
|
|
38843
|
+
function useBlogStyles() {
|
|
38844
|
+
useInsertionEffect(() => {
|
|
38845
|
+
if (typeof document === "undefined" || document.getElementById(STYLE_ID$1)) return;
|
|
38846
|
+
const el = document.createElement("style");
|
|
38847
|
+
el.id = STYLE_ID$1;
|
|
38848
|
+
el.textContent = BLOG_CSS;
|
|
38849
|
+
document.head.appendChild(el);
|
|
38850
|
+
}, []);
|
|
38851
|
+
}
|
|
38137
38852
|
const FORM_FIELD_TYPES = [
|
|
38138
38853
|
"text",
|
|
38139
38854
|
"email",
|
|
@@ -39136,193 +39851,6 @@ const iframeStyle = {
|
|
|
39136
39851
|
height: "100%",
|
|
39137
39852
|
border: 0
|
|
39138
39853
|
};
|
|
39139
|
-
function usePageManifest() {
|
|
39140
|
-
const { pageStore, config } = useSetto();
|
|
39141
|
-
const snap = useSyncExternalStore(
|
|
39142
|
-
(cb) => pageStore?.subscribe(() => cb()) ?? (() => {
|
|
39143
|
-
}),
|
|
39144
|
-
() => pageStore?.snapshot() ?? EMPTY_PAGE_STORE_SNAPSHOT,
|
|
39145
|
-
() => pageStore?.snapshot() ?? EMPTY_PAGE_STORE_SNAPSHOT
|
|
39146
|
-
);
|
|
39147
|
-
return pageStore ? snap.manifest : bundledManifest(config.pages);
|
|
39148
|
-
}
|
|
39149
|
-
function useSettoMenu(list2 = "menu") {
|
|
39150
|
-
const manifest = usePageManifest();
|
|
39151
|
-
return manifest ? visibleMenu(manifest, list2) : null;
|
|
39152
|
-
}
|
|
39153
|
-
function SettoPage({ pageId, path: path2, sections = {}, builtins, fallback = null }) {
|
|
39154
|
-
const manifest = usePageManifest();
|
|
39155
|
-
const { editMode } = useSetto();
|
|
39156
|
-
if (!manifest) {
|
|
39157
|
-
if (!pageId && path2 !== void 0 && path2 !== "/" && path2 !== "") return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
39158
|
-
return /* @__PURE__ */ jsx(Fragment, { children: Object.entries(sections).map(([id, Component]) => /* @__PURE__ */ jsx(Component, {}, id)) });
|
|
39159
|
-
}
|
|
39160
|
-
const page = pageId ? pageById(manifest, pageId) : pageForPath(manifest, path2 ?? "/");
|
|
39161
|
-
if (!page) {
|
|
39162
|
-
if (pageId) {
|
|
39163
|
-
return /* @__PURE__ */ jsx(Fragment, { children: Object.entries(sections).map(([id, Component]) => /* @__PURE__ */ jsx(Component, {}, id)) });
|
|
39164
|
-
}
|
|
39165
|
-
return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
39166
|
-
}
|
|
39167
|
-
if (page.hidden && !editMode) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
39168
|
-
return /* @__PURE__ */ jsx(PageBody, { page, sections, builtins, editMode, manifest });
|
|
39169
|
-
}
|
|
39170
|
-
function PageBody({
|
|
39171
|
-
page,
|
|
39172
|
-
sections,
|
|
39173
|
-
builtins,
|
|
39174
|
-
editMode,
|
|
39175
|
-
manifest
|
|
39176
|
-
}) {
|
|
39177
|
-
usePageTitle(page);
|
|
39178
|
-
const HiddenPageNote = useSettoChromeSlot("hidden-page");
|
|
39179
|
-
const listed = new Set(manifest.pages.flatMap((p) => p.sections.map((s) => s.id)));
|
|
39180
|
-
const unlisted = Object.keys(sections).filter((id) => !listed.has(id));
|
|
39181
|
-
const firstVisible = page.sections.find((s) => !s.hidden && (s.type || sections[s.id]))?.id;
|
|
39182
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
39183
|
-
page.hidden && editMode ? HiddenPageNote ? /* @__PURE__ */ jsx(HiddenPageNote, { pageId: page.id }) : /* @__PURE__ */ jsx(HiddenNote, { text: "Denne siden er skjult for besøkende." }) : null,
|
|
39184
|
-
page.sections.map((section) => /* @__PURE__ */ jsx(Fragment$1, { children: renderSection(section, sections, builtins, editMode, section.id === firstVisible) }, section.id)),
|
|
39185
|
-
unlisted.map((id) => {
|
|
39186
|
-
const Component = sections[id];
|
|
39187
|
-
return /* @__PURE__ */ jsx(Component, {}, id);
|
|
39188
|
-
})
|
|
39189
|
-
] });
|
|
39190
|
-
}
|
|
39191
|
-
function renderSection(section, sections, builtins, editMode, first) {
|
|
39192
|
-
if (section.hidden) {
|
|
39193
|
-
return editMode ? /* @__PURE__ */ jsx(HiddenSection, { section }) : null;
|
|
39194
|
-
}
|
|
39195
|
-
if (section.type) {
|
|
39196
|
-
const Builtin = builtins?.[section.type] ?? BUILTIN_RENDERERS[section.type];
|
|
39197
|
-
return /* @__PURE__ */ jsx(Builtin, { sectionId: section.id, first });
|
|
39198
|
-
}
|
|
39199
|
-
const Component = sections[section.id];
|
|
39200
|
-
if (!Component) {
|
|
39201
|
-
warnOnce(section.id);
|
|
39202
|
-
return null;
|
|
39203
|
-
}
|
|
39204
|
-
return /* @__PURE__ */ jsx(Component, {});
|
|
39205
|
-
}
|
|
39206
|
-
const warned = /* @__PURE__ */ new Set();
|
|
39207
|
-
function warnOnce(id) {
|
|
39208
|
-
if (warned.has(id)) return;
|
|
39209
|
-
warned.add(id);
|
|
39210
|
-
console.warn(`[setto] section "${id}" is in pages.json but the page does not provide it`);
|
|
39211
|
-
}
|
|
39212
|
-
function HiddenSection({ section }) {
|
|
39213
|
-
const { pageStore } = useSetto();
|
|
39214
|
-
const Offered = useSettoChromeSlot("hidden-section");
|
|
39215
|
-
const label = section.label ?? section.id;
|
|
39216
|
-
if (Offered) return /* @__PURE__ */ jsx(Offered, { sectionId: section.id, label });
|
|
39217
|
-
return /* @__PURE__ */ jsxs("div", { "data-setto-ui": true, style: hiddenBarStyle, children: [
|
|
39218
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
39219
|
-
"Skjult: ",
|
|
39220
|
-
label
|
|
39221
|
-
] }),
|
|
39222
|
-
pageStore ? /* @__PURE__ */ jsx(
|
|
39223
|
-
"button",
|
|
39224
|
-
{
|
|
39225
|
-
type: "button",
|
|
39226
|
-
"data-setto-ui": true,
|
|
39227
|
-
style: hiddenBtnStyle,
|
|
39228
|
-
onClick: () => pageStore.apply([{ op: "show_section", sectionId: section.id }]),
|
|
39229
|
-
children: "Vis"
|
|
39230
|
-
}
|
|
39231
|
-
) : null
|
|
39232
|
-
] });
|
|
39233
|
-
}
|
|
39234
|
-
function HiddenNote({ text: text2 }) {
|
|
39235
|
-
return /* @__PURE__ */ jsx("div", { "data-setto-ui": true, style: hiddenBarStyle, children: /* @__PURE__ */ jsx("span", { children: text2 }) });
|
|
39236
|
-
}
|
|
39237
|
-
function usePageTitle(page) {
|
|
39238
|
-
const { t } = useTranslation();
|
|
39239
|
-
const original = useRef(null);
|
|
39240
|
-
const title = page.path === "/" ? null : t(page.titleKey);
|
|
39241
|
-
useEffect(() => {
|
|
39242
|
-
if (!title || typeof document === "undefined") return;
|
|
39243
|
-
original.current ??= document.title;
|
|
39244
|
-
const base = original.current;
|
|
39245
|
-
document.title = base ? `${title} · ${base}` : title;
|
|
39246
|
-
return () => {
|
|
39247
|
-
document.title = base;
|
|
39248
|
-
};
|
|
39249
|
-
}, [title]);
|
|
39250
|
-
}
|
|
39251
|
-
function SettoTextSection({ sectionId, first }) {
|
|
39252
|
-
const keys2 = builtinKeys(sectionId);
|
|
39253
|
-
const { i18n } = useTranslation();
|
|
39254
|
-
const { store, editMode } = useSetto();
|
|
39255
|
-
const intro2 = store ? store.get(keys2.intro, i18n.language) : i18n.t(keys2.intro, { defaultValue: "" });
|
|
39256
|
-
const Heading = first ? "h1" : "h2";
|
|
39257
|
-
return /* @__PURE__ */ jsx(SettoSection, { sectionId, style: textSectionStyle, children: /* @__PURE__ */ jsxs("div", { style: textInnerStyle, children: [
|
|
39258
|
-
/* @__PURE__ */ jsx(Heading, { style: first ? textH1Style : textH2Style, children: /* @__PURE__ */ jsx(T, { k: keys2.heading }) }),
|
|
39259
|
-
intro2 || editMode ? /* @__PURE__ */ jsx("p", { style: textIntroStyle, children: /* @__PURE__ */ jsx(T, { k: keys2.intro }) }) : null,
|
|
39260
|
-
/* @__PURE__ */ jsx(
|
|
39261
|
-
SettoRepeater,
|
|
39262
|
-
{
|
|
39263
|
-
itemsKey: keys2.items,
|
|
39264
|
-
defaultItem: { heading: "Overskrift", text: "Tekst" },
|
|
39265
|
-
itemLabel: "avsnitt",
|
|
39266
|
-
children: (itemKey) => /* @__PURE__ */ jsx(TextItem, { sectionId, itemKey })
|
|
39267
|
-
}
|
|
39268
|
-
)
|
|
39269
|
-
] }) });
|
|
39270
|
-
}
|
|
39271
|
-
function TextItem({ sectionId, itemKey }) {
|
|
39272
|
-
const keys2 = builtinKeys(sectionId);
|
|
39273
|
-
const { i18n } = useTranslation();
|
|
39274
|
-
const { store, editMode } = useSetto();
|
|
39275
|
-
const heading2 = store ? store.get(keys2.itemHeading(itemKey), i18n.language) : i18n.t(keys2.itemHeading(itemKey), { defaultValue: "" });
|
|
39276
|
-
return /* @__PURE__ */ jsxs("div", { style: textItemStyle, children: [
|
|
39277
|
-
heading2 || editMode ? /* @__PURE__ */ jsx("h3", { style: textH3Style, children: /* @__PURE__ */ jsx(T, { k: keys2.itemHeading(itemKey) }) }) : null,
|
|
39278
|
-
/* @__PURE__ */ jsx("p", { style: textParagraphStyle, children: /* @__PURE__ */ jsx(T, { k: keys2.itemText(itemKey) }) })
|
|
39279
|
-
] });
|
|
39280
|
-
}
|
|
39281
|
-
const BUILTIN_RENDERERS = {
|
|
39282
|
-
text: SettoTextSection
|
|
39283
|
-
};
|
|
39284
|
-
const textSectionStyle = { padding: "clamp(48px, 8vw, 96px) 16px" };
|
|
39285
|
-
const textInnerStyle = { maxWidth: "68ch", margin: "0 auto" };
|
|
39286
|
-
const textH1Style = {
|
|
39287
|
-
fontFamily: "var(--setto-display-font, inherit)",
|
|
39288
|
-
fontSize: "clamp(2rem, 4vw, 2.75rem)",
|
|
39289
|
-
lineHeight: 1.15,
|
|
39290
|
-
fontWeight: 600,
|
|
39291
|
-
margin: "0 0 0.75em"
|
|
39292
|
-
};
|
|
39293
|
-
const textH2Style = { ...textH1Style, fontSize: "clamp(1.5rem, 3vw, 2rem)" };
|
|
39294
|
-
const textH3Style = {
|
|
39295
|
-
fontFamily: "var(--setto-display-font, inherit)",
|
|
39296
|
-
fontSize: "1.125rem",
|
|
39297
|
-
lineHeight: 1.3,
|
|
39298
|
-
fontWeight: 600,
|
|
39299
|
-
margin: "0 0 0.4em"
|
|
39300
|
-
};
|
|
39301
|
-
const textIntroStyle = { fontSize: "1.125rem", lineHeight: 1.6, opacity: 0.85, margin: "0 0 2em" };
|
|
39302
|
-
const textItemStyle = { margin: "0 0 1.75em" };
|
|
39303
|
-
const textParagraphStyle = { lineHeight: 1.7, margin: 0, whiteSpace: "pre-line" };
|
|
39304
|
-
const hiddenBarStyle = {
|
|
39305
|
-
display: "flex",
|
|
39306
|
-
alignItems: "center",
|
|
39307
|
-
justifyContent: "center",
|
|
39308
|
-
gap: 12,
|
|
39309
|
-
padding: "10px 16px",
|
|
39310
|
-
margin: "4px 0",
|
|
39311
|
-
border: "1px dashed rgba(100, 10, 255, 0.45)",
|
|
39312
|
-
borderRadius: 8,
|
|
39313
|
-
background: "rgba(100, 10, 255, 0.05)",
|
|
39314
|
-
color: "#3b2a66",
|
|
39315
|
-
font: '500 13px system-ui, -apple-system, "Segoe UI", sans-serif'
|
|
39316
|
-
};
|
|
39317
|
-
const hiddenBtnStyle = {
|
|
39318
|
-
border: "none",
|
|
39319
|
-
borderRadius: 999,
|
|
39320
|
-
padding: "4px 12px",
|
|
39321
|
-
background: "#640AFF",
|
|
39322
|
-
color: "#fff",
|
|
39323
|
-
font: '600 12px system-ui, -apple-system, "Segoe UI", sans-serif',
|
|
39324
|
-
cursor: "pointer"
|
|
39325
|
-
};
|
|
39326
39854
|
const DEFAULT_DURATION = {
|
|
39327
39855
|
fadeIn: 600,
|
|
39328
39856
|
slideUp: 700,
|
|
@@ -40285,6 +40813,7 @@ export {
|
|
|
40285
40813
|
AuthGate,
|
|
40286
40814
|
BLOCK_REGISTRY,
|
|
40287
40815
|
BLOCK_TYPES,
|
|
40816
|
+
BLOG_CSS,
|
|
40288
40817
|
BUILTIN_SECTION_TYPES,
|
|
40289
40818
|
CHECKOUT_INTENT,
|
|
40290
40819
|
DEFAULT_LANGUAGE,
|
|
@@ -40309,6 +40838,9 @@ export {
|
|
|
40309
40838
|
SettoAnimation,
|
|
40310
40839
|
SettoBlock,
|
|
40311
40840
|
SettoBlockTree,
|
|
40841
|
+
SettoBlog,
|
|
40842
|
+
SettoBlogLatest,
|
|
40843
|
+
SettoBlogSection,
|
|
40312
40844
|
SettoChat,
|
|
40313
40845
|
SettoChrome,
|
|
40314
40846
|
SettoContext,
|
|
@@ -40330,6 +40862,8 @@ export {
|
|
|
40330
40862
|
alternateLinks,
|
|
40331
40863
|
applyOp,
|
|
40332
40864
|
applyOps,
|
|
40865
|
+
blogPage,
|
|
40866
|
+
blogSlugForPath,
|
|
40333
40867
|
builtinKeys,
|
|
40334
40868
|
checkoutIntentUrl,
|
|
40335
40869
|
countChanges,
|
|
@@ -40339,6 +40873,7 @@ export {
|
|
|
40339
40873
|
fieldTypeHasPlaceholder,
|
|
40340
40874
|
findSection,
|
|
40341
40875
|
formFieldsPrefix,
|
|
40876
|
+
formatPostDate,
|
|
40342
40877
|
isAdminDeploymentView,
|
|
40343
40878
|
isAdminPanelView,
|
|
40344
40879
|
isAdminRoute,
|
|
@@ -40360,6 +40895,8 @@ export {
|
|
|
40360
40895
|
parseManifest,
|
|
40361
40896
|
pathForLanguage,
|
|
40362
40897
|
pickInitialLanguage,
|
|
40898
|
+
postForSlug,
|
|
40899
|
+
postsForLanguage,
|
|
40363
40900
|
readLocaleFields,
|
|
40364
40901
|
redirectForVisitor,
|
|
40365
40902
|
serialiseManifest,
|